diff --git a/apier/v1/tpaliases.go b/apier/v1/tpaliases.go new file mode 100644 index 000000000..05ced89e7 --- /dev/null +++ b/apier/v1/tpaliases.go @@ -0,0 +1,108 @@ +/* +Real-time Charging System for Telecom & ISP environments +Copyright (C) 2012-2015 ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package v1 + +import ( + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +// Creates a new alias within a tariff plan +func (self *ApierV1) SetTPAlias(attrs utils.AttrSetTPAlias, reply *string) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "Direction", "Tenant", "Category", "Account", "Subject", "Group"}); len(missing) != 0 { + return utils.NewErrMandatoryIeMissing(missing...) + } + tm := engine.APItoModelAliases(&attrs) + if err := self.StorDb.SetTpAliases([]engine.TpAlias{*tm}); err != nil { + return utils.NewErrServerError(err) + } + *reply = "OK" + return nil +} + +type AttrGetTPAlias struct { + TPid string // Tariff plan id + Direction string + Tenant string + Category string + Account string + Subject string + Group string +} + +// Queries specific Alias on Tariff plan +func (self *ApierV1) GetTPAlias(attr AttrGetTPAlias, reply *engine.Alias) error { + if missing := utils.MissingStructFields(&attr, []string{"TPid"}); len(missing) != 0 { //Params missing + return utils.NewErrMandatoryIeMissing(missing...) + } + al := &engine.TpAlias{ + Tpid: attr.TPid, + Direction: attr.Direction, + Tenant: attr.Tenant, + Category: attr.Category, + Account: attr.Account, + Subject: attr.Subject, + Group: attr.Group, + } + if tms, err := self.StorDb.GetTpAliases(al); err != nil { + return utils.NewErrServerError(err) + } else if len(tms) == 0 { + return utils.ErrNotFound + } else { + tmMap, err := engine.TpAliases(tms).GetAliases() + if err != nil { + return err + } + *reply = *tmMap[al.GetId()] + } + return nil +} + +type AttrGetTPAliasIds struct { + TPid string // Tariff plan id + utils.Paginator +} + +// Queries alias identities on specific tariff plan. +func (self *ApierV1) GetTPAliasIds(attrs AttrGetTPAliasIds, reply *[]string) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid"}); len(missing) != 0 { //Params missing + return utils.NewErrMandatoryIeMissing(missing...) + } + if ids, err := self.StorDb.GetTpTableIds(attrs.TPid, utils.TBL_TP_ALIASES, utils.TPDistinctIds{"tag"}, nil, &attrs.Paginator); err != nil { + return utils.NewErrServerError(err) + } else if ids == nil { + return utils.ErrNotFound + } else { + *reply = ids + } + return nil +} + +// Removes specific Alias on Tariff plan +func (self *ApierV1) RemTPAlias(attrs AttrGetTPAlias, reply *string) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "AliasId"}); len(missing) != 0 { //Params missing + return utils.NewErrMandatoryIeMissing(missing...) + } + if err := self.StorDb.RemTpData(utils.TBL_TP_ALIASES, attrs.TPid); err != nil { + return utils.NewErrServerError(err) + } else { + *reply = "OK" + } + return nil +} diff --git a/apier/v1/tpusers.go b/apier/v1/tpusers.go new file mode 100644 index 000000000..dfc12be00 --- /dev/null +++ b/apier/v1/tpusers.go @@ -0,0 +1,100 @@ +/* +Real-time Charging System for Telecom & ISP environments +Copyright (C) 2012-2015 ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package v1 + +import ( + "github.com/cgrates/cgrates/engine" + "github.com/cgrates/cgrates/utils" +) + +// Creates a new alias within a tariff plan +func (self *ApierV1) SetTPUser(attrs utils.AttrSetTPUser, reply *string) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "Direction", "Tenant", "Category", "Account", "Subject", "Group"}); len(missing) != 0 { + return utils.NewErrMandatoryIeMissing(missing...) + } + tm := engine.APItoModelUsers(&attrs) + if err := self.StorDb.SetTpUsers([]engine.TpUser{*tm}); err != nil { + return utils.NewErrServerError(err) + } + *reply = "OK" + return nil +} + +type AttrGetTPUser struct { + TPid string // Tariff plan id + Tenant string + UserName string +} + +// Queries specific User on Tariff plan +func (self *ApierV1) GetTPUser(attr AttrGetTPUser, reply *engine.UserProfile) error { + if missing := utils.MissingStructFields(&attr, []string{"TPid"}); len(missing) != 0 { //Params missing + return utils.NewErrMandatoryIeMissing(missing...) + } + usr := &engine.TpUser{ + Tpid: attr.TPid, + Tenant: attr.Tenant, + UserName: attr.UserName, + } + if tms, err := self.StorDb.GetTpUsers(usr); err != nil { + return utils.NewErrServerError(err) + } else if len(tms) == 0 { + return utils.ErrNotFound + } else { + tmMap, err := engine.TpUsers(tms).GetUsers() + if err != nil { + return err + } + *reply = *tmMap[usr.GetId()] + } + return nil +} + +type AttrGetTPUserIds struct { + TPid string // Tariff plan id + utils.Paginator +} + +// Queries alias identities on specific tariff plan. +func (self *ApierV1) GetTPUserIds(attrs AttrGetTPUserIds, reply *[]string) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid"}); len(missing) != 0 { //Params missing + return utils.NewErrMandatoryIeMissing(missing...) + } + if ids, err := self.StorDb.GetTpTableIds(attrs.TPid, utils.TBL_TP_USERS, utils.TPDistinctIds{"tag"}, nil, &attrs.Paginator); err != nil { + return utils.NewErrServerError(err) + } else if ids == nil { + return utils.ErrNotFound + } else { + *reply = ids + } + return nil +} + +// Removes specific User on Tariff plan +func (self *ApierV1) RemTPUser(attrs AttrGetTPUser, reply *string) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "UserId"}); len(missing) != 0 { //Params missing + return utils.NewErrMandatoryIeMissing(missing...) + } + if err := self.StorDb.RemTpData(utils.TBL_TP_USERS, attrs.TPid); err != nil { + return utils.NewErrServerError(err) + } else { + *reply = "OK" + } + return nil +} diff --git a/cmd/cgr-engine/cgr-engine.go b/cmd/cgr-engine/cgr-engine.go index 58a6b7f9d..0923a8c70 100644 --- a/cmd/cgr-engine/cgr-engine.go +++ b/cmd/cgr-engine/cgr-engine.go @@ -56,26 +56,27 @@ const ( ) var ( - cfgDir = flag.String("config_dir", utils.CONFIG_DIR, "Configuration directory path.") - version = flag.Bool("version", false, "Prints the application version.") - raterEnabled = flag.Bool("rater", false, "Enforce starting of the rater daemon overwriting config") - schedEnabled = flag.Bool("scheduler", false, "Enforce starting of the scheduler daemon .overwriting config") - cdrsEnabled = flag.Bool("cdrs", false, "Enforce starting of the cdrs daemon overwriting config") - pidFile = flag.String("pid", "", "Write pid file") - cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file") - singlecpu = flag.Bool("singlecpu", false, "Run on single CPU core") - bal = balancer2go.NewBalancer() - exitChan = make(chan bool) - server = &engine.Server{} - cdrServer *engine.CdrServer - cdrStats engine.StatsInterface - scribeServer history.Scribe - pubSubServer engine.PublisherSubscriber - userServer engine.UserService - cfg *config.CGRConfig - sms []sessionmanager.SessionManager - smRpc *v1.SessionManagerV1 - err error + cfgDir = flag.String("config_dir", utils.CONFIG_DIR, "Configuration directory path.") + version = flag.Bool("version", false, "Prints the application version.") + raterEnabled = flag.Bool("rater", false, "Enforce starting of the rater daemon overwriting config") + schedEnabled = flag.Bool("scheduler", false, "Enforce starting of the scheduler daemon .overwriting config") + cdrsEnabled = flag.Bool("cdrs", false, "Enforce starting of the cdrs daemon overwriting config") + pidFile = flag.String("pid", "", "Write pid file") + cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file") + singlecpu = flag.Bool("singlecpu", false, "Run on single CPU core") + bal = balancer2go.NewBalancer() + exitChan = make(chan bool) + server = &engine.Server{} + cdrServer *engine.CdrServer + cdrStats engine.StatsInterface + scribeServer history.Scribe + pubSubServer engine.PublisherSubscriber + aliasesServer engine.AliasService + userServer engine.UserService + cfg *config.CGRConfig + sms []sessionmanager.SessionManager + smRpc *v1.SessionManagerV1 + err error ) func cacheData(ratingDb engine.RatingStorage, accountDb engine.AccountingStorage, doneChan chan struct{}) { @@ -479,6 +480,11 @@ func main() { server.RpcRegisterName("PubSubV1", pubSubServer) } + if cfg.AliasesServerEnabled { + aliasesServer = engine.NewAliasHandler(accountDb) + server.RpcRegisterName("AliasesV1", aliasesServer) + } + if cfg.HistoryServerEnabled { scribeServer, err = history.NewFileScribe(cfg.HistoryDir, cfg.HistorySaveInterval) if err != nil { @@ -540,6 +546,18 @@ func main() { engine.SetPubSub(pubSubServer) }() wg.Add(1) + go func() { + defer wg.Done() + if cfg.RaterAliasesServer != "" && cfg.RaterAliasesServer != utils.INTERNAL { + if aliasesServer, err = engine.NewProxyAliasService(cfg.RaterAliasesServer, cfg.ConnectAttempts, -1); err != nil { + engine.Logger.Crit(fmt.Sprintf(" Could not connect to the server, error: %s", err.Error())) + exitChan <- true + return + } + } + engine.SetAliasService(aliasesServer) + }() + wg.Add(1) go func() { defer wg.Done() if cfg.RaterUserServer != "" && cfg.RaterUserServer != utils.INTERNAL { diff --git a/config/config.go b/config/config.go index 944062405..a6da8fa9b 100644 --- a/config/config.go +++ b/config/config.go @@ -198,6 +198,7 @@ type CGRConfig struct { RaterHistoryServer string RaterPubSubServer string RaterUserServer string + RaterAliasesServer string BalancerEnabled bool SchedulerEnabled bool CDRSEnabled bool // Enable CDR Server service @@ -219,8 +220,8 @@ type CGRConfig struct { HistoryServerEnabled bool // Starts History as server: . HistoryDir string // Location on disk where to store history files. HistorySaveInterval time.Duration // The timout duration between pubsub writes - PubSubServer string // Address where to reach the master pubsub server: PubSubServerEnabled bool // Starts PubSub as server: . + AliasesServerEnabled bool // Starts PubSub as server: . UserServerEnabled bool // Starts User as server: UserServerIndexes []string // List of user profile field indexes MailerServer string // The server to use when sending emails out @@ -250,6 +251,9 @@ func (self *CGRConfig) checkConfigSanity() error { if self.RaterPubSubServer == utils.INTERNAL && !self.PubSubServerEnabled { return errors.New("PubSub server not enabled but requested by Rater component.") } + if self.RaterAliasesServer == utils.INTERNAL && !self.AliasesServerEnabled { + return errors.New("Aliases server not enabled but requested by Rater component.") + } if self.RaterUserServer == utils.INTERNAL && !self.UserServerEnabled { return errors.New("Users service not enabled but requested by Rater component.") } @@ -425,6 +429,11 @@ func (self *CGRConfig) loadFromJsonCfg(jsnCfg *CgrJsonCfg) error { return err } + jsnAliasesServCfg, err := jsnCfg.AliasesServJsonCfg() + if err != nil { + return err + } + jsnUserServCfg, err := jsnCfg.UserServJsonCfg() if err != nil { return err @@ -566,6 +575,9 @@ func (self *CGRConfig) loadFromJsonCfg(jsnCfg *CgrJsonCfg) error { if jsnRaterCfg.Pubsubs != nil { self.RaterPubSubServer = *jsnRaterCfg.Pubsubs } + if jsnRaterCfg.Aliases != nil { + self.RaterAliasesServer = *jsnRaterCfg.Aliases + } if jsnRaterCfg.Users != nil { self.RaterUserServer = *jsnRaterCfg.Users } @@ -709,6 +721,12 @@ func (self *CGRConfig) loadFromJsonCfg(jsnCfg *CgrJsonCfg) error { } } + if jsnAliasesServCfg != nil { + if jsnAliasesServCfg.Enabled != nil { + self.AliasesServerEnabled = *jsnAliasesServCfg.Enabled + } + } + if jsnUserServCfg != nil { if jsnUserServCfg.Enabled != nil { self.UserServerEnabled = *jsnUserServCfg.Enabled diff --git a/config/config_defaults.go b/config/config_defaults.go index 8a1a51427..d1aa047c0 100644 --- a/config/config_defaults.go +++ b/config/config_defaults.go @@ -93,6 +93,7 @@ const CGRATES_CFG_JSON = ` "historys": "", // address where to reach the history service, empty to disable history functionality: <""|internal|x.y.z.y:1234> "pubsubs": "", // address where to reach the pubusb service, empty to disable pubsub functionality: <""|internal|x.y.z.y:1234> "users": "", // address where to reach the user service, empty to disable user profile functionality: <""|internal|x.y.z.y:1234> + "aliases": "", // address where to reach the aliases service, empty to disable aliases functionality: <""|internal|x.y.z.y:1234> }, @@ -254,6 +255,9 @@ const CGRATES_CFG_JSON = ` "enabled": false, // starts PubSub service: . }, +"aliases": { + "enabled": false, // starts Aliases service: . +}, "users": { "enabled": false, // starts User service: . diff --git a/config/config_json.go b/config/config_json.go index 58fcb8a66..353ec4a8a 100644 --- a/config/config_json.go +++ b/config/config_json.go @@ -27,30 +27,31 @@ import ( ) const ( - GENERAL_JSN = "general" - LISTEN_JSN = "listen" - TPDB_JSN = "tariffplan_db" - DATADB_JSN = "data_db" - STORDB_JSN = "stor_db" - BALANCER_JSN = "balancer" - RATER_JSN = "rater" - SCHEDULER_JSN = "scheduler" - CDRS_JSN = "cdrs" - MEDIATOR_JSN = "mediator" - CDRSTATS_JSN = "cdrstats" - CDRE_JSN = "cdre" - CDRC_JSN = "cdrc" - SMFS_JSN = "sm_freeswitch" - SMKAM_JSN = "sm_kamailio" - SMOSIPS_JSN = "sm_opensips" - SM_JSN = "session_manager" - FS_JSN = "freeswitch" - KAMAILIO_JSN = "kamailio" - OSIPS_JSN = "opensips" - HISTSERV_JSN = "historys" - PUBSUBSERV_JSN = "pubsubs" - USERSERV_JSN = "users" - MAILER_JSN = "mailer" + GENERAL_JSN = "general" + LISTEN_JSN = "listen" + TPDB_JSN = "tariffplan_db" + DATADB_JSN = "data_db" + STORDB_JSN = "stor_db" + BALANCER_JSN = "balancer" + RATER_JSN = "rater" + SCHEDULER_JSN = "scheduler" + CDRS_JSN = "cdrs" + MEDIATOR_JSN = "mediator" + CDRSTATS_JSN = "cdrstats" + CDRE_JSN = "cdre" + CDRC_JSN = "cdrc" + SMFS_JSN = "sm_freeswitch" + SMKAM_JSN = "sm_kamailio" + SMOSIPS_JSN = "sm_opensips" + SM_JSN = "session_manager" + FS_JSN = "freeswitch" + KAMAILIO_JSN = "kamailio" + OSIPS_JSN = "opensips" + HISTSERV_JSN = "historys" + PUBSUBSERV_JSN = "pubsubs" + ALIASESSERV_JSN = "aliases" + USERSERV_JSN = "users" + MAILER_JSN = "mailer" ) // Loads the json config out of io.Reader, eg other sources than file, maybe over http @@ -256,6 +257,18 @@ func (self CgrJsonCfg) PubSubServJsonCfg() (*PubSubServJsonCfg, error) { return cfg, nil } +func (self CgrJsonCfg) AliasesServJsonCfg() (*AliasesServJsonCfg, error) { + rawCfg, hasKey := self[ALIASESSERV_JSN] + if !hasKey { + return nil, nil + } + cfg := new(AliasesServJsonCfg) + if err := json.Unmarshal(*rawCfg, cfg); err != nil { + return nil, err + } + return cfg, nil +} + func (self CgrJsonCfg) UserServJsonCfg() (*UserServJsonCfg, error) { rawCfg, hasKey := self[USERSERV_JSN] if !hasKey { diff --git a/config/config_json_test.go b/config/config_json_test.go index eac1e82b3..83ab592de 100644 --- a/config/config_json_test.go +++ b/config/config_json_test.go @@ -123,11 +123,11 @@ func TestDfBalancerJsonCfg(t *testing.T) { func TestDfRaterJsonCfg(t *testing.T) { eCfg := &RaterJsonCfg{Enabled: utils.BoolPointer(false), Balancer: utils.StringPointer(""), Cdrstats: utils.StringPointer(""), - Historys: utils.StringPointer(""), Pubsubs: utils.StringPointer(""), Users: utils.StringPointer("")} + Historys: utils.StringPointer(""), Pubsubs: utils.StringPointer(""), Users: utils.StringPointer(""), Aliases: utils.StringPointer("")} if cfg, err := dfCgrJsonCfg.RaterJsonCfg(); err != nil { t.Error(err) } else if !reflect.DeepEqual(eCfg, cfg) { - t.Error("Received: ", cfg) + t.Errorf("Received: %+v", cfg) } } @@ -417,6 +417,17 @@ func TestDfPubSubServJsonCfg(t *testing.T) { } } +func TestDfAliasesServJsonCfg(t *testing.T) { + eCfg := &AliasesServJsonCfg{ + Enabled: utils.BoolPointer(false), + } + if cfg, err := dfCgrJsonCfg.AliasesServJsonCfg(); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(eCfg, cfg) { + t.Error("Received: ", cfg) + } +} + func TestDfUserServJsonCfg(t *testing.T) { eCfg := &UserServJsonCfg{ Enabled: utils.BoolPointer(false), diff --git a/config/libconfig_json.go b/config/libconfig_json.go index 7c285bb3a..9fd57e8ec 100644 --- a/config/libconfig_json.go +++ b/config/libconfig_json.go @@ -64,6 +64,7 @@ type RaterJsonCfg struct { Cdrstats *string Historys *string Pubsubs *string + Aliases *string Users *string } @@ -230,7 +231,12 @@ type PubSubServJsonCfg struct { Enabled *bool } -// PubSub server config section +// Aliases server config section +type AliasesServJsonCfg struct { + Enabled *bool +} + +// Users server config section type UserServJsonCfg struct { Enabled *bool Indexes *[]string diff --git a/data/conf/cgrates/cgrates.json b/data/conf/cgrates/cgrates.json index 96ada26d6..f00547b68 100644 --- a/data/conf/cgrates/cgrates.json +++ b/data/conf/cgrates/cgrates.json @@ -72,6 +72,7 @@ // "historys": "", // address where to reach the history service, empty to disable history functionality: <""|internal|x.y.z.y:1234> // "pubsubs": "", // address where to reach the pubusb service, empty to disable pubsub functionality: <""|internal|x.y.z.y:1234> // "users": "", // address where to reach the user service, empty to disable user profile functionality: <""|internal|x.y.z.y:1234> +// "aliases": "", // address where to reach the aliases service, empty to disable aliases functionality: <""|internal|x.y.z.y:1234> //}, @@ -238,6 +239,9 @@ // "indexes": [], // user profile field indexes //}, +//"aliases": { +// "enabled": false, // starts Aliases service: . +//}, //"mailer": { // "server": "localhost", // the server to use when sending emails out diff --git a/engine/model_converters.go b/engine/model_converters.go index 356ae8758..5f61cf7d4 100644 --- a/engine/model_converters.go +++ b/engine/model_converters.go @@ -358,14 +358,23 @@ func APItoModelCdrStat(stats *utils.TPCdrStats) (result []TpCdrstat) { return } -func APItoModelApierAlias(t *utils.ApierTPTiming) (result *TpTiming) { - return &TpTiming{ - Tpid: t.TPid, - Tag: t.TimingId, - Years: t.Years, - Months: t.Months, - MonthDays: t.MonthDays, - WeekDays: t.WeekDays, - Time: t.Time, +func APItoModelAliases(attr *utils.AttrSetTPAlias) (result *TpAlias) { + return &TpAlias{ + Tpid: attr.TPid, + Direction: attr.Direction, + Tenant: attr.Tenant, + Category: attr.Category, + Account: attr.Account, + Subject: attr.Subject, + Group: attr.Group, + } +} + +func APItoModelUsers(attr *utils.AttrSetTPUser) (result *TpUser) { + return &TpUser{ + Tpid: attr.TPid, + Tenant: attr.Tenant, + AttributeName: attr.AttributeName, + AttributeValue: attr.AttributeValue, } } diff --git a/engine/storage_sql.go b/engine/storage_sql.go index 826a62409..8c24cc692 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -163,7 +163,7 @@ func (self *SQLStorage) RemTpData(table, tpid string, args ...string) error { tx := self.db.Begin() if len(table) == 0 { // Remove tpid out of all tables for _, tblName := range []string{utils.TBL_TP_TIMINGS, utils.TBL_TP_DESTINATIONS, utils.TBL_TP_RATES, utils.TBL_TP_DESTINATION_RATES, utils.TBL_TP_RATING_PLANS, utils.TBL_TP_RATE_PROFILES, - utils.TBL_TP_SHARED_GROUPS, utils.TBL_TP_CDR_STATS, utils.TBL_TP_LCRS, utils.TBL_TP_ACTIONS, utils.TBL_TP_ACTION_PLANS, utils.TBL_TP_ACTION_TRIGGERS, utils.TBL_TP_ACCOUNT_ACTIONS, utils.TBL_TP_DERIVED_CHARGERS} { + utils.TBL_TP_SHARED_GROUPS, utils.TBL_TP_CDR_STATS, utils.TBL_TP_LCRS, utils.TBL_TP_ACTIONS, utils.TBL_TP_ACTION_PLANS, utils.TBL_TP_ACTION_TRIGGERS, utils.TBL_TP_ACCOUNT_ACTIONS, utils.TBL_TP_DERIVED_CHARGERS, utils.TBL_TP_ALIASES} { if err := tx.Table(tblName).Where("tpid = ?", tpid).Delete(nil).Error; err != nil { tx.Rollback() return err diff --git a/utils/apitpdata.go b/utils/apitpdata.go index d98e5274a..e557a0aa8 100644 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -519,6 +519,24 @@ type AttrGetAccounts struct { Limit int // Limit number of items retrieved } +type AttrSetTPAlias struct { + TPid string + Direction string + Tenant string + Category string + Account string + Subject string + Group string +} + +type AttrSetTPUser struct { + TPid string + Tenant string + UserName string + AttributeName string + AttributeValue string +} + // Data used to do remote cache reloads via api type ApiReloadCache struct { DestinationIds []string @@ -1095,3 +1113,19 @@ type AttrGetCallCost struct { CgrId string // Unique id of the CDR RunId string // Run Id } + +type TpAlias struct { + Direction string + Tenant string + Category string + Account string + Subject string + Group string + Values []*AliasValue +} + +type AliasValue struct { + DestinationId string + Alias string + Weight float64 +} diff --git a/utils/consts.go b/utils/consts.go index 48907e625..ce9685d57 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -60,6 +60,8 @@ const ( TBL_TP_ACTION_TRIGGERS = "tp_action_triggers" TBL_TP_ACCOUNT_ACTIONS = "tp_account_actions" TBL_TP_DERIVED_CHARGERS = "tp_derived_chargers" + TBL_TP_USERS = "tp_users" + TBL_TP_ALIASES = "tp_aliases" TBL_CDRS_PRIMARY = "cdrs_primary" TBL_CDRS_EXTRA = "cdrs_extra" TBL_COST_DETAILS = "cost_details"