diff --git a/data/storage/mysql/create_tariffplan_tables.sql b/data/storage/mysql/create_tariffplan_tables.sql index 7393fcd6f..cc84861aa 100644 --- a/data/storage/mysql/create_tariffplan_tables.sql +++ b/data/storage/mysql/create_tariffplan_tables.sql @@ -336,7 +336,7 @@ CREATE TABLE tp_cdr_stats ( KEY `tpid` (`tpid`) ); - -- +-- -- Table structure for table `tp_users` -- @@ -352,3 +352,25 @@ CREATE TABLE tp_users ( PRIMARY KEY (`id`), KEY `tpid` (`tpid`) ); + +-- +-- Table structure for table `tp_aliases` +-- + +DROP TABLE IF EXISTS tp_aliases; +CREATE TABLE tp_aliases ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `tpid` varchar(64) NOT NULL, + `direction` varchar(8) NOT NULL, + `tenant` varchar(64) NOT NULL, + `category` varchar(64) NOT NULL, + `account` varchar(64) NOT NULL, + `subject` varchar(64) NOT NULL, + `group` varchar(64) NOT NULL, + `destionation_id` varchar(64) NOT NULL, + `alias` varchar(64) NOT NULL, + `weight` decimal(8,2) NOT NULL, + `created_at` TIMESTAMP, + PRIMARY KEY (`id`), + KEY `tpid` (`tpid`) +); diff --git a/data/storage/postgres/create_tariffplan_tables.sql b/data/storage/postgres/create_tariffplan_tables.sql index 8a15d5ade..ce1975f37 100644 --- a/data/storage/postgres/create_tariffplan_tables.sql +++ b/data/storage/postgres/create_tariffplan_tables.sql @@ -347,3 +347,26 @@ CREATE TABLE tp_users ( ); CREATE INDEX tpusers_tpid_idx ON tp_users (tpid); CREATE INDEX tpusers_idx ON tp_users (tpid,tenant,user_name); + + +-- +-- Table structure for table `tp_aliases` +-- + +DROP TABLE IF EXISTS tp_aliases; +CREATE TABLE tp_aliases ( + id SERIAL PRIMARY KEY, + tpid VARCHAR(64) NOT NULL, + direction VARCHAR(8) NOT NULL, + tenant VARCHAR(64) NOT NULL, + category VARCHAR(32) NOT NULL, + account VARCHAR(64) NOT NULL, + subject VARCHAR(64) NOT NULL, + group VARCHAR(64) NOT NULL, + destionation_id VARCHAR(64) NOT NULL, + alias VARCHAR(64) NOT NULL, + weight NUMERIC(8,2) NOT NULL, + created_at TIMESTAMP +); +CREATE INDEX tpaliases_tpid_idx ON tp_aliases (tpid); +CREATE INDEX tpaliases_idx ON tp_aliases (tpid,direction,tenant,category,account,subject,group); diff --git a/data/tariffplans/tutorial/Aliases.csv b/data/tariffplans/tutorial/Aliases.csv new file mode 100644 index 000000000..ec75fa58b --- /dev/null +++ b/data/tariffplans/tutorial/Aliases.csv @@ -0,0 +1,5 @@ +Direction,Tenant,Category,Account,Subject,DestinationId,Group,Alias,Weight +*out,cgrates.org,call,dan,dan,EU_LANDLINE,*rating_profile,dan1,10 +*out,cgrates.org,call,dan,dan,GLOBAL1,*rating_profile,dan2,20 +*any,*any,*any,*any,*any,*any,*rating_profile,rif1,20 +*any,*any,*any,*any,*any,*any,*account,dan1,10 \ No newline at end of file diff --git a/engine/aliases.go b/engine/aliases.go index 4b67f81f2..f812efba9 100644 --- a/engine/aliases.go +++ b/engine/aliases.go @@ -10,42 +10,57 @@ import ( ) type Alias struct { - Direction string - Tenant string - Category string - Account string - Subject string + Direction string + Tenant string + Category string + Account string + Subject string + Group string + Values AliasValues +} + +type AliasValue struct { DestinationId string - Group string Alias string Weight float64 } -type Aliases []*Alias +type AliasValues []*AliasValue -func (ups Aliases) Len() int { - return len(ups) +func (avs AliasValues) Len() int { + return len(avs) } -func (ups Aliases) Swap(i, j int) { - ups[i], ups[j] = ups[j], ups[i] +func (avs AliasValues) Swap(i, j int) { + avs[i], avs[j] = avs[j], avs[i] } -func (ups Aliases) Less(j, i int) bool { // get higher ponder in front - return ups[i].ponder < ups[j].ponder +func (avs AliasValues) Less(j, i int) bool { // get higher ponder in front + return avs[i].Weight < avs[j].Weight } -func (ups Aliases) Sort() { - sort.Sort(ups) +func (avs AliasValues) Sort() { + sort.Sort(avs) } func (al *Alias) GetId() string { - return utils.ConcatenatedKey(al.Direction, al.Tenant, al.Category, al.Account, al.Subject, al.DestinationId, al.Group) + return utils.ConcatenatedKey(al.Direction, al.Tenant, al.Category, al.Account, al.Subject, al.Group) +} + +func (al *Alias) GenerateIds() []string { + var result []string + result = append(result, utils.ConcatenatedKey(al.Direction, al.Tenant, al.Category, al.Account, al.Subject, al.Group)) + result = append(result, utils.ConcatenatedKey(al.Direction, al.Tenant, al.Category, al.Account, utils.ANY, al.Group)) + result = append(result, utils.ConcatenatedKey(al.Direction, al.Tenant, al.Category, utils.ANY, utils.ANY, al.Group)) + result = append(result, utils.ConcatenatedKey(al.Direction, al.Tenant, utils.ANY, utils.ANY, utils.ANY, al.Group)) + result = append(result, utils.ConcatenatedKey(al.Direction, utils.ANY, utils.ANY, utils.ANY, utils.ANY, al.Group)) + result = append(result, utils.ConcatenatedKey(utils.ANY, utils.ANY, utils.ANY, utils.ANY, al.Group)) + return result } func (al *Alias) SetId(id string) error { vals := strings.Split(id, utils.CONCATENATED_KEY_SEP) - if len(vals) != 7 { + if len(vals) != 6 { return utils.ErrInvalidKey } al.Direction = vals[0] @@ -53,20 +68,19 @@ func (al *Alias) SetId(id string) error { al.Category = vals[2] al.Account = vals[3] al.Subject = vals[4] - al.DestinationId = vals[5] - al.Group = vals[6] + al.Group = vals[5] return nil } type AliasService interface { SetAlias(Alias, *string) error - AliasAlias(Alias, *string) error - GetAliases(Alias, *Aliases) error + RemoveAlias(Alias, *string) error + GetAliases(Alias, *[]*Alias) error ReloadAliases(string, *string) error } type AliasMap struct { - table map[string]string + table map[string]AliasValues accountingDb AccountingStorage mu sync.RWMutex } @@ -82,7 +96,7 @@ func NewAliasMap(accountingDb AccountingStorage) (*AliasMap, error) { func newAliasMap(accountingDb AccountingStorage) *AliasMap { return &AliasMap{ - table: make(map[string]string), + table: make(map[string]AliasValues), accountingDb: accountingDb, } } @@ -93,12 +107,12 @@ func (am *AliasMap) ReloadAliases(in string, reply *string) error { // backup old data oldTable := am.table - am.table = make(map[string]string) + am.table = make(map[string]AliasValues) - // load from rating db + // load from db if ups, err := am.accountingDb.GetAliases(); err == nil { for _, up := range ups { - am.table[up.GetId()] = up.Profile + am.table[up.GetId()] = up.Values } } else { // restore old data before return @@ -119,7 +133,7 @@ func (am *AliasMap) SetAlias(al Alias, reply *string) error { *reply = err.Error() return err } - am.table[al.GetId()] = al.Alias + am.table[al.GetId()] = al.Values *reply = utils.OK return nil } @@ -132,17 +146,22 @@ func (am *AliasMap) RemoveAlias(al Alias, reply *string) error { return err } delete(am.table, al.GetId()) - am.deleteIndex(&al) *reply = utils.OK return nil } -func (am *AliasMap) GetAliases(al Alias, results *Aliases) error { +func (am *AliasMap) GetAlias(al Alias, result *Alias) error { am.mu.RLock() defer am.mu.RUnlock() - - *results = am.table[al.GetId()] - return nil + variants := al.GenerateIds() + for _, variant := range variants { + if r, ok := am.table[variant]; ok { + al.Values = r + *result = al + return nil + } + } + return utils.ErrNotFound } type ProxyAliasService struct { @@ -165,7 +184,7 @@ func (ps *ProxyAliasService) RemoveAlias(al Alias, reply *string) error { return ps.Client.Call("AliasV1.RemoveAlias", al, reply) } -func (ps *ProxyAliasService) GetAliases(al Alias, aliases *Aliases) error { +func (ps *ProxyAliasService) GetAlias(al Alias, aliases *Alias) error { return ps.Client.Call("AliasV1.GetAliases", al, aliases) } diff --git a/engine/calldesc.go b/engine/calldesc.go index 026a02c57..b73d46410 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -297,11 +297,11 @@ func (cd *CallDescriptor) addRatingInfos(ris RatingInfos) bool { // The prefixLen is limiting the length of the destination prefix. func (cd *CallDescriptor) GetKey(subject string) string { // check if subject is alias - if rs, err := cache2go.GetCached(utils.RP_ALIAS_PREFIX + utils.RatingSubjectAliasKey(cd.Tenant, subject)); err == nil { + /*if rs, err := cache2go.GetCached(utils.RP_ALIAS_PREFIX + utils.RatingSubjectAliasKey(cd.Tenant, subject)); err == nil { realSubject := rs.(string) subject = realSubject cd.Subject = realSubject - } + }*/ return utils.ConcatenatedKey(cd.Direction, cd.Tenant, cd.Category, subject) } @@ -310,9 +310,9 @@ func (cd *CallDescriptor) GetAccountKey() string { subj := cd.Subject if cd.Account != "" { // check if subject is alias - if realSubject, err := cache2go.GetCached(utils.ACC_ALIAS_PREFIX + utils.AccountAliasKey(cd.Tenant, subj)); err == nil { + /*if realSubject, err := cache2go.GetCached(utils.ACC_ALIAS_PREFIX + utils.AccountAliasKey(cd.Tenant, subj)); err == nil { cd.Account = realSubject.(string) - } + }*/ subj = cd.Account } return utils.ConcatenatedKey(cd.Direction, cd.Tenant, subj) diff --git a/engine/libtest.go b/engine/libtest.go index 6511eabd3..b09790446 100644 --- a/engine/libtest.go +++ b/engine/libtest.go @@ -106,7 +106,9 @@ func LoadTariffPlanFromFolder(tpPath string, ratingDb RatingStorage, accountingD path.Join(tpPath, utils.ACCOUNT_ACTIONS_CSV), path.Join(tpPath, utils.DERIVED_CHARGERS_CSV), path.Join(tpPath, utils.CDR_STATS_CSV), - path.Join(tpPath, utils.USERS_CSV)), "") + path.Join(tpPath, utils.USERS_CSV), + path.Join(tpPath, utils.ALIASES_CSV), + ), "") if err := loader.LoadAll(); err != nil { return utils.NewErrServerError(err) } diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 957537cdc..88f40a90c 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -216,6 +216,13 @@ CDRST2,,,,ACD,,,,,,,,,,,,,,,,,,,, cgrates.org,rif,test0,val0 cgrates.org,rif,test1,val1 cgrates.org,dan,another,value +` + aliases = ` +#Direction[0],Tenant[1],Category[2],Account[3],Subject[4],DestinationId[5],Group[6],Alias[7],Weight[8] +*out,cgrates.org,call,dan,dan,EU_LANDLINE,*rating_profile,dan1,10 +*out,cgrates.org,call,dan,dan,GLOBAL1,*rating_profile,dan2,20 +*any,*any,*any,*any,*any,*any,*rating_profile,rif1,20 +*any,*any,*any,*any,*any,*any,*account,dan1,10 ` ) @@ -223,7 +230,7 @@ var csvr *TpReader func init() { csvr = NewTpReader(ratingStorage, accountingStorage, NewStringCSVStorage(',', destinations, timings, rates, destinationRates, ratingPlans, ratingProfiles, - sharedGroups, lcrs, actions, actionTimings, actionTriggers, accountActions, derivedCharges, cdrStats, users), "") + sharedGroups, lcrs, actions, actionTimings, actionTriggers, accountActions, derivedCharges, cdrStats, users, aliases), "") if err := csvr.LoadDestinations(); err != nil { log.Print("error in LoadDestinations:", err) } @@ -269,6 +276,9 @@ func init() { if err := csvr.LoadUsers(); err != nil { log.Print("error in LoadUsers:", err) } + if err := csvr.LoadAliases(); err != nil { + log.Print("error in LoadAliases:", err) + } csvr.WriteToDatabase(false, false) ratingStorage.CacheAll() } @@ -1027,27 +1037,6 @@ func TestLoadAccountActions(t *testing.T) { } } -func TestLoadRpAliases(t *testing.T) { - if len(csvr.rpAliases) != 3 { - t.Error("Failed to load rp aliases: ", csvr.rpAliases) - } - if csvr.rpAliases[utils.RatingSubjectAliasKey("vdf", "a1")] != "minu" || - csvr.rpAliases[utils.RatingSubjectAliasKey("vdf", "a2")] != "minu" || - csvr.rpAliases[utils.RatingSubjectAliasKey("vdf", "a3")] != "minu" { - t.Error("Error loading rp aliases: ", csvr.rpAliases) - } -} - -func TestLoadAccAliases(t *testing.T) { - if len(csvr.accAliases) != 2 { - t.Error("Failed to load acc aliases: ", csvr.accAliases) - } - if csvr.accAliases[utils.AccountAliasKey("vdf", "a1")] != "minitsboy" || - csvr.accAliases[utils.AccountAliasKey("vdf", "a2")] != "minitsboy" { - t.Error("Error loading acc aliases: ", csvr.accAliases) - } -} - func TestLoadDerivedChargers(t *testing.T) { if len(csvr.derivedChargers) != 2 { t.Error("Failed to load derivedChargers: ", csvr.derivedChargers) @@ -1133,3 +1122,28 @@ func TestLoadUsers(t *testing.T) { t.Errorf("Unexpected user %+v", csvr.users[user1.GetId()]) } } + +func TestLoadAliases(t *testing.T) { + if len(csvr.aliases) != 2 { + t.Error("Failed to load aliases: ", csvr.aliases) + } + alias1 := &Alias{ + Direction: "*out", + Tenant: "cgrates.org", + Category: "call", + Account: "dan", + Subject: "dan", + Group: "*rating_profile", + Values: AliasValues{ + &AliasValue{ + DestinationId: "EU_LANDLINE", + Alias: "dan1", + Weight: 10, + }, + }, + } + + if !reflect.DeepEqual(csvr.users[alias1.GetId()], alias1) { + t.Errorf("Unexpected alias %+v", csvr.aliases[alias1.GetId()]) + } +} diff --git a/engine/loader_local_test.go b/engine/loader_local_test.go index 393832d0e..f20a720e3 100644 --- a/engine/loader_local_test.go +++ b/engine/loader_local_test.go @@ -131,7 +131,9 @@ func TestLoadFromCSV(t *testing.T) { path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.ACCOUNT_ACTIONS_CSV), path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.DERIVED_CHARGERS_CSV), path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.CDR_STATS_CSV), - path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.USERS_CSV)), "") + path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.USERS_CSV), + path.Join(*dataDir, "tariffplans", *tpCsvScenario, utils.ALIASES_CSV), + ), "") if err = loader.LoadDestinations(); err != nil { t.Error("Failed loading destinations: ", err.Error()) @@ -169,6 +171,9 @@ func TestLoadFromCSV(t *testing.T) { if err = loader.LoadUsers(); err != nil { t.Error("Failed loading users: ", err.Error()) } + if err = loader.LoadAliases(); err != nil { + t.Error("Failed loading aliases: ", err.Error()) + } if err := loader.WriteToDatabase(true, false); err != nil { t.Error("Could not write data into ratingDb: ", err.Error()) } diff --git a/engine/model_helpers.go b/engine/model_helpers.go index c7ef2c0d6..efcfc5a77 100644 --- a/engine/model_helpers.go +++ b/engine/model_helpers.go @@ -734,3 +734,31 @@ func (tps TpUsers) GetUsers() (map[string]*UserProfile, error) { } return users, nil } + +type TpAliases []TpAlias + +func (tps TpAliases) GetAliases() (map[string]*Alias, error) { + als := make(map[string]*Alias) + for _, tp := range tps { + var al *Alias + var found bool + if al, found = als[tp.GetId()]; !found { + al = &Alias{ + Direction: tp.Direction, + Tenant: tp.Tenant, + Category: tp.Category, + Account: tp.Account, + Subject: tp.Subject, + Group: tp.Group, + Values: make(AliasValues, 0), + } + als[tp.GetId()] = al + } + al.Values = append(al.Values, &AliasValue{ + DestinationId: tp.DestinationId, + Alias: tp.Alias, + Weight: tp.Weight, + }) + } + return als, nil +} diff --git a/engine/models.go b/engine/models.go index 65362c161..ebbd73584 100644 --- a/engine/models.go +++ b/engine/models.go @@ -337,6 +337,24 @@ func (tu *TpUser) GetId() string { return utils.ConcatenatedKey(tu.Tenant, tu.UserName) } +type TpAlias struct { + Id int64 + Tpid string + Direction string `index:"0" re:""` + Tenant string `index:"1" re:""` + Category string `index:"2" re:""` + Account string `index:"3" re:""` + Subject string `index:"4" re:""` + Group string `index:"5" re:""` + DestinationId string `index:"6" re:""` + Alias string `index:"7" re:""` + Weight float64 `index:"8" re:""` +} + +func (ta *TpAlias) GetId() string { + return utils.ConcatenatedKey(ta.Direction, ta.Tenant, ta.Category, ta.Account, ta.Subject, ta.Group) +} + type TblCdrsPrimary struct { Id int64 Cgrid string diff --git a/engine/storage_csv.go b/engine/storage_csv.go index 55b8fc421..be9f8d471 100644 --- a/engine/storage_csv.go +++ b/engine/storage_csv.go @@ -15,26 +15,26 @@ type CSVStorage struct { readerFunc func(string, rune, int) (*csv.Reader, *os.File, error) // file names destinationsFn, ratesFn, destinationratesFn, timingsFn, destinationratetimingsFn, ratingprofilesFn, - sharedgroupsFn, lcrFn, actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn, usersFn string + sharedgroupsFn, lcrFn, actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn, usersFn, aliasesFn string } func NewFileCSVStorage(sep rune, destinationsFn, timingsFn, ratesFn, destinationratesFn, destinationratetimingsFn, ratingprofilesFn, sharedgroupsFn, lcrFn, - actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn, usersFn string) *CSVStorage { + actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn, usersFn, aliasesFn string) *CSVStorage { c := new(CSVStorage) c.sep = sep c.readerFunc = openFileCSVStorage c.destinationsFn, c.timingsFn, c.ratesFn, c.destinationratesFn, c.destinationratetimingsFn, c.ratingprofilesFn, - c.sharedgroupsFn, c.lcrFn, c.actionsFn, c.actiontimingsFn, c.actiontriggersFn, c.accountactionsFn, c.derivedChargersFn, c.cdrStatsFn, c.usersFn = destinationsFn, timingsFn, - ratesFn, destinationratesFn, destinationratetimingsFn, ratingprofilesFn, sharedgroupsFn, lcrFn, actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn, usersFn + c.sharedgroupsFn, c.lcrFn, c.actionsFn, c.actiontimingsFn, c.actiontriggersFn, c.accountactionsFn, c.derivedChargersFn, c.cdrStatsFn, c.usersFn, aliasesFn = destinationsFn, timingsFn, + ratesFn, destinationratesFn, destinationratetimingsFn, ratingprofilesFn, sharedgroupsFn, lcrFn, actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn, usersFn, aliasesFn return c } func NewStringCSVStorage(sep rune, destinationsFn, timingsFn, ratesFn, destinationratesFn, destinationratetimingsFn, ratingprofilesFn, sharedgroupsFn, lcrFn, - actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn, usersFn string) *CSVStorage { + actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn, usersFn, aliasesFn string) *CSVStorage { c := NewFileCSVStorage(sep, destinationsFn, timingsFn, ratesFn, destinationratesFn, destinationratetimingsFn, - ratingprofilesFn, sharedgroupsFn, lcrFn, actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn, usersFn) + ratingprofilesFn, sharedgroupsFn, lcrFn, actionsFn, actiontimingsFn, actiontriggersFn, accountactionsFn, derivedChargersFn, cdrStatsFn, usersFn, aliasesFn) c.readerFunc = openStringCSVStorage return c } @@ -488,6 +488,36 @@ func (csvs *CSVStorage) GetTpUsers(filter *TpUser) ([]TpUser, error) { return tpUsers, nil } +func (csvs *CSVStorage) GetTpAliases(filter *TpAlias) ([]TpAlias, error) { + csvReader, fp, err := csvs.readerFunc(csvs.aliasesFn, csvs.sep, getColumnCount(TpAlias{})) + if err != nil { + log.Print("Could not load aliases file: ", err) + // allow writing of the other values + return nil, nil + } + if fp != nil { + defer fp.Close() + } + var tpAliases []TpAlias + for record, err := csvReader.Read(); err != io.EOF; record, err = csvReader.Read() { + if err != nil { + log.Print("bad line in aliases csv: ", err) + return nil, err + } + if tpAlias, err := csvLoad(TpAlias{}, record); err != nil { + log.Print("error loading alias: ", err) + return nil, err + } else { + u := tpAlias.(TpAlias) + if filter != nil { + u.Tpid = filter.Tpid + } + tpAliases = append(tpAliases, u) + } + } + return tpAliases, nil +} + func (csvs *CSVStorage) GetTpIds() ([]string, error) { return nil, utils.ErrNotImplemented } diff --git a/engine/storage_interface.go b/engine/storage_interface.go index f06851e87..9592eb493 100644 --- a/engine/storage_interface.go +++ b/engine/storage_interface.go @@ -41,16 +41,12 @@ type RatingStorage interface { CacheAll() error CachePrefixes(...string) error CachePrefixValues(map[string][]string) error - Cache([]string, []string, []string, []string, []string, []string, []string, []string, []string) error + Cache([]string, []string, []string, []string, []string, []string, []string) error HasData(string, string) (bool, error) GetRatingPlan(string, bool) (*RatingPlan, error) SetRatingPlan(*RatingPlan) error GetRatingProfile(string, bool) (*RatingProfile, error) SetRatingProfile(*RatingProfile) error - GetRpAlias(string, bool) (string, error) - SetRpAlias(string, string) error - RemoveRpAliases([]*TenantRatingSubject, bool) error - GetRPAliases(string, string, bool) ([]string, error) GetDestination(string) (*Destination, error) SetDestination(*Destination) error GetLCR(string, bool) (*LCR, error) @@ -67,10 +63,6 @@ type RatingStorage interface { GetActionPlans(string) (ActionPlans, error) SetActionPlans(string, ActionPlans) error GetAllActionPlans() (map[string]ActionPlans, error) - GetAccAlias(string, bool) (string, error) - SetAccAlias(string, string) error - RemoveAccAliases([]*TenantAccount, bool) error - GetAccountAliases(string, string, bool) ([]string, error) } type AccountingStorage interface { @@ -87,6 +79,10 @@ type AccountingStorage interface { GetUser(string) (*UserProfile, error) GetUsers() ([]*UserProfile, error) RemoveUser(string) error + SetAlias(*Alias) error + GetAlias(string) (*Alias, error) + GetAliases() ([]*Alias, error) + RemoveAlias(string) error } type CdrStorage interface { @@ -125,6 +121,7 @@ type LoadReader interface { GetTpSharedGroups(string, string) ([]TpSharedGroup, error) GetTpCdrStats(string, string) ([]TpCdrstat, error) GetTpUsers(*TpUser) ([]TpUser, error) + GetTpAliases(*TpAlias) ([]TpAlias, error) GetTpDerivedChargers(*TpDerivedCharger) ([]TpDerivedCharger, error) GetTpLCRs(string, string) ([]TpLcrRule, error) GetTpActions(string, string) ([]TpAction, error) @@ -144,6 +141,7 @@ type LoadWriter interface { SetTpSharedGroups([]TpSharedGroup) error SetTpCdrStats([]TpCdrstat) error SetTpUsers([]TpUser) error + SetTpAlias([]TpAlias) error SetTpDerivedChargers([]TpDerivedCharger) error SetTpLCRs([]TpLcrRule) error SetTpActions([]TpAction) error diff --git a/engine/storage_map.go b/engine/storage_map.go index 09ca2539b..1ea963e76 100644 --- a/engine/storage_map.go +++ b/engine/storage_map.go @@ -63,7 +63,7 @@ func (ms *MapStorage) GetKeysForPrefix(prefix string) ([]string, error) { } func (ms *MapStorage) CacheAll() error { - return ms.Cache(nil, nil, nil, nil, nil, nil, nil, nil, nil) + return ms.Cache(nil, nil, nil, nil, nil, nil, nil) } func (ms *MapStorage) CachePrefixes(prefixes ...string) error { @@ -71,12 +71,10 @@ func (ms *MapStorage) CachePrefixes(prefixes ...string) error { utils.DESTINATION_PREFIX: []string{}, utils.RATING_PLAN_PREFIX: []string{}, utils.RATING_PROFILE_PREFIX: []string{}, - utils.RP_ALIAS_PREFIX: []string{}, utils.LCR_PREFIX: []string{}, utils.DERIVEDCHARGERS_PREFIX: []string{}, utils.ACTION_PREFIX: []string{}, utils.SHARED_GROUP_PREFIX: []string{}, - utils.ACC_ALIAS_PREFIX: []string{}, } for _, prefix := range prefixes { if _, found := pm[prefix]; !found { @@ -84,7 +82,7 @@ func (ms *MapStorage) CachePrefixes(prefixes ...string) error { } pm[prefix] = nil } - return ms.Cache(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.RP_ALIAS_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX], pm[utils.ACC_ALIAS_PREFIX]) + return ms.Cache(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX]) } func (ms *MapStorage) CachePrefixValues(prefixes map[string][]string) error { @@ -92,12 +90,10 @@ func (ms *MapStorage) CachePrefixValues(prefixes map[string][]string) error { utils.DESTINATION_PREFIX: []string{}, utils.RATING_PLAN_PREFIX: []string{}, utils.RATING_PROFILE_PREFIX: []string{}, - utils.RP_ALIAS_PREFIX: []string{}, utils.LCR_PREFIX: []string{}, utils.DERIVEDCHARGERS_PREFIX: []string{}, utils.ACTION_PREFIX: []string{}, utils.SHARED_GROUP_PREFIX: []string{}, - utils.ACC_ALIAS_PREFIX: []string{}, } for prefix, ids := range prefixes { if _, found := pm[prefix]; !found { @@ -105,10 +101,10 @@ func (ms *MapStorage) CachePrefixValues(prefixes map[string][]string) error { } pm[prefix] = ids } - return ms.Cache(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.RP_ALIAS_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX], pm[utils.ACC_ALIAS_PREFIX]) + return ms.Cache(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX]) } -func (ms *MapStorage) Cache(dKeys, rpKeys, rpfKeys, plsKeys, lcrKeys, dcsKeys, actKeys, shgKeys, alsKeys []string) error { +func (ms *MapStorage) Cache(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, actKeys, shgKeys []string) error { cache2go.BeginTransaction() if dKeys == nil || (float64(cache2go.CountEntries(utils.DESTINATION_PREFIX))*utils.DESTINATIONS_LOAD_THRESHOLD < float64(len(dKeys))) { cache2go.RemPrefixKey(utils.DESTINATION_PREFIX) @@ -121,9 +117,6 @@ func (ms *MapStorage) Cache(dKeys, rpKeys, rpfKeys, plsKeys, lcrKeys, dcsKeys, a if rpfKeys == nil { cache2go.RemPrefixKey(utils.RATING_PROFILE_PREFIX) } - if plsKeys == nil { - cache2go.RemPrefixKey(utils.RP_ALIAS_PREFIX) - } if lcrKeys == nil { cache2go.RemPrefixKey(utils.LCR_PREFIX) } @@ -136,9 +129,6 @@ func (ms *MapStorage) Cache(dKeys, rpKeys, rpfKeys, plsKeys, lcrKeys, dcsKeys, a if shgKeys == nil { cache2go.RemPrefixKey(utils.SHARED_GROUP_PREFIX) // Forced until we can fine tune it } - if alsKeys == nil { - cache2go.RemPrefixKey(utils.ACC_ALIAS_PREFIX) - } for k, _ := range ms.dict { if strings.HasPrefix(k, utils.DESTINATION_PREFIX) { if _, err := ms.GetDestination(k[len(utils.DESTINATION_PREFIX):]); err != nil { @@ -160,13 +150,6 @@ func (ms *MapStorage) Cache(dKeys, rpKeys, rpfKeys, plsKeys, lcrKeys, dcsKeys, a return err } } - if strings.HasPrefix(k, utils.RP_ALIAS_PREFIX) { - cache2go.RemKey(k) - if _, err := ms.GetRpAlias(k[len(utils.RP_ALIAS_PREFIX):], true); err != nil { - cache2go.RollbackTransaction() - return err - } - } if strings.HasPrefix(k, utils.LCR_PREFIX) { cache2go.RemKey(k) if _, err := ms.GetLCR(k[len(utils.LCR_PREFIX):], true); err != nil { @@ -197,13 +180,6 @@ func (ms *MapStorage) Cache(dKeys, rpKeys, rpfKeys, plsKeys, lcrKeys, dcsKeys, a return err } } - if strings.HasPrefix(k, utils.ACC_ALIAS_PREFIX) { - cache2go.RemKey(k) - if _, err := ms.GetAccAlias(k[len(utils.ACC_ALIAS_PREFIX):], true); err != nil { - cache2go.RollbackTransaction() - return err - } - } } cache2go.CommitTransaction() return nil @@ -319,148 +295,6 @@ func (ms *MapStorage) SetLCR(lcr *LCR) (err error) { return } -func (ms *MapStorage) GetRpAlias(key string, skipCache bool) (alias string, err error) { - key = utils.RP_ALIAS_PREFIX + key - if !skipCache { - if x, err := cache2go.GetCached(key); err == nil { - return x.(string), nil - } else { - return "", err - } - } - if values, ok := ms.dict[key]; ok { - alias = string(values) - cache2go.Cache(key, alias) - } else { - return "", utils.ErrNotFound - } - return -} - -func (ms *MapStorage) SetRpAlias(key, alias string) (err error) { - ms.dict[utils.RP_ALIAS_PREFIX+key] = []byte(alias) - return -} - -func (ms *MapStorage) RemoveRpAliases(tenantRtSubjects []*TenantRatingSubject, skipCache bool) (err error) { - if skipCache { - for key, value := range ms.dict { - for _, tenantRtSubj := range tenantRtSubjects { - tenantPrfx := utils.RP_ALIAS_PREFIX + tenantRtSubj.Tenant + utils.CONCATENATED_KEY_SEP - if strings.HasPrefix(key, utils.RP_ALIAS_PREFIX) && len(key) >= len(tenantPrfx) && key[:len(tenantPrfx)] == tenantPrfx && tenantRtSubj.Subject == string(value) { - delete(ms.dict, key) - cache2go.RemKey(key) - } - } - } - } else { - alsMap, err := cache2go.GetAllEntries(utils.RP_ALIAS_PREFIX) - if err != nil { - return err - } - - for key, aliasInterface := range alsMap { - alias := aliasInterface.Value().(string) - for _, tenantRtSubj := range tenantRtSubjects { - tenantPrfx := tenantRtSubj.Tenant + utils.CONCATENATED_KEY_SEP - if len(key) >= len(tenantPrfx) && key[:len(tenantPrfx)] == tenantPrfx && tenantRtSubj.Subject == alias { - delete(ms.dict, utils.RP_ALIAS_PREFIX+key) - cache2go.RemKey(utils.RP_ALIAS_PREFIX + key) - } - } - } - } - return -} - -func (ms *MapStorage) GetRPAliases(tenant, subject string, skipCache bool) (aliases []string, err error) { - tenantPrfx := utils.RP_ALIAS_PREFIX + tenant + utils.CONCATENATED_KEY_SEP - var alsKeys []string - if !skipCache { - alsKeys = cache2go.GetEntriesKeys(tenantPrfx) - } - for _, key := range alsKeys { - if alsSubj, err := ms.GetRpAlias(key[len(utils.RP_ALIAS_PREFIX):], skipCache); err != nil { - return nil, err - } else if alsSubj == subject { - alsFromKey := key[len(tenantPrfx):] // take out the alias out of key+tenant - aliases = append(aliases, alsFromKey) - } - } - if len(alsKeys) == 0 { - for key, value := range ms.dict { - if strings.HasPrefix(key, utils.RP_ALIAS_PREFIX) && len(key) >= len(tenantPrfx) && key[:len(tenantPrfx)] == tenantPrfx && subject == string(value) { - aliases = append(aliases, key[len(tenantPrfx):]) - } - } - } - return aliases, nil -} - -func (ms *MapStorage) GetAccAlias(key string, skipCache bool) (alias string, err error) { - key = utils.ACC_ALIAS_PREFIX + key - if !skipCache { - if x, err := cache2go.GetCached(key); err == nil { - return x.(string), nil - } else { - return "", err - } - } - if values, ok := ms.dict[key]; ok { - alias = string(values) - cache2go.Cache(key, alias) - } else { - return "", utils.ErrNotFound - } - return -} - -func (ms *MapStorage) SetAccAlias(key, alias string) (err error) { - ms.dict[utils.ACC_ALIAS_PREFIX+key] = []byte(alias) - return -} - -func (ms *MapStorage) RemoveAccAliases(tenantAccounts []*TenantAccount, skipCache bool) (err error) { - if skipCache { - for key, value := range ms.dict { - for _, tntAcnt := range tenantAccounts { - tenantPrfx := utils.ACC_ALIAS_PREFIX + tntAcnt.Tenant + utils.CONCATENATED_KEY_SEP - if strings.HasPrefix(key, utils.ACC_ALIAS_PREFIX) && len(key) >= len(tenantPrfx) && key[:len(tenantPrfx)] == tenantPrfx && tntAcnt.Account == string(value) { - delete(ms.dict, key) - cache2go.RemKey(key) - } - } - } - } else { - alsMap, err := cache2go.GetAllEntries(utils.ACC_ALIAS_PREFIX) - if err != nil { - return err - } - - for key, aliasInterface := range alsMap { - alias := aliasInterface.Value().(string) - for _, tntAcnt := range tenantAccounts { - tenantPrfx := tntAcnt.Tenant + utils.CONCATENATED_KEY_SEP - if len(key) >= len(tenantPrfx) && key[:len(tenantPrfx)] == tenantPrfx && tntAcnt.Account == alias { - delete(ms.dict, utils.ACC_ALIAS_PREFIX+key) - cache2go.RemKey(utils.ACC_ALIAS_PREFIX + key) - } - } - } - } - return -} - -func (ms *MapStorage) GetAccountAliases(tenant, account string, skipCache bool) (aliases []string, err error) { - for key, value := range ms.dict { - tenantPrfx := utils.ACC_ALIAS_PREFIX + tenant + utils.CONCATENATED_KEY_SEP - if strings.HasPrefix(key, utils.ACC_ALIAS_PREFIX) && len(key) >= len(tenantPrfx) && key[:len(tenantPrfx)] == tenantPrfx && account == string(value) { - aliases = append(aliases, key[len(tenantPrfx):]) - } - } - return aliases, nil -} - func (ms *MapStorage) GetDestination(key string) (dest *Destination, err error) { key = utils.DESTINATION_PREFIX + key if values, ok := ms.dict[key]; ok { @@ -655,6 +489,42 @@ func (ms *MapStorage) RemoveUser(key string) error { return nil } +func (ms *MapStorage) SetAlias(al *Alias) error { + result, err := ms.ms.Marshal(al.Values) + if err != nil { + return err + } + ms.dict[utils.ALIASES_PREFIX+al.GetId()] = result + return nil +} + +func (ms *MapStorage) GetAlias(key string) (al *Alias, err error) { + if values, ok := ms.dict[utils.ALIASES_PREFIX+key]; ok { + al = &Alias{Values: make(AliasValues, 0)} + err = ms.ms.Unmarshal(values, al.Values) + } else { + return nil, utils.ErrNotFound + } + return al, nil +} + +func (ms *MapStorage) GetAliases() (als []*Alias, err error) { + for key, value := range ms.dict { + if strings.HasPrefix(key, utils.ALIASES_PREFIX) { + al := &Alias{Values: make(AliasValues, 0)} + if err = ms.ms.Unmarshal(value, al.Values); err == nil { + al.SetId(key) + als = append(als, al) + } + } + } + return +} +func (ms *MapStorage) RemoveAlias(key string) error { + delete(ms.dict, utils.ALIASES_PREFIX+key) + return nil +} + func (ms *MapStorage) GetActionPlans(key string) (ats ActionPlans, err error) { if values, ok := ms.dict[utils.ACTION_TIMING_PREFIX+key]; ok { err = ms.ms.Unmarshal(values, &ats) diff --git a/engine/storage_redis.go b/engine/storage_redis.go index 2900c645d..bf2cc3e77 100644 --- a/engine/storage_redis.go +++ b/engine/storage_redis.go @@ -23,8 +23,6 @@ import ( "compress/zlib" "errors" "fmt" - "log" - "strings" "github.com/cgrates/cgrates/cache2go" "github.com/cgrates/cgrates/utils" @@ -69,7 +67,7 @@ func (rs *RedisStorage) GetKeysForPrefix(prefix string) ([]string, error) { } func (rs *RedisStorage) CacheAll() error { - return rs.Cache(nil, nil, nil, nil, nil, nil, nil, nil, nil) + return rs.Cache(nil, nil, nil, nil, nil, nil, nil) } func (rs *RedisStorage) CachePrefixes(prefixes ...string) error { @@ -77,12 +75,10 @@ func (rs *RedisStorage) CachePrefixes(prefixes ...string) error { utils.DESTINATION_PREFIX: []string{}, utils.RATING_PLAN_PREFIX: []string{}, utils.RATING_PROFILE_PREFIX: []string{}, - utils.RP_ALIAS_PREFIX: []string{}, utils.LCR_PREFIX: []string{}, utils.DERIVEDCHARGERS_PREFIX: []string{}, utils.ACTION_PREFIX: []string{}, utils.SHARED_GROUP_PREFIX: []string{}, - utils.ACC_ALIAS_PREFIX: []string{}, } for _, prefix := range prefixes { if _, found := pm[prefix]; !found { @@ -90,7 +86,7 @@ func (rs *RedisStorage) CachePrefixes(prefixes ...string) error { } pm[prefix] = nil } - return rs.Cache(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.RP_ALIAS_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX], pm[utils.ACC_ALIAS_PREFIX]) + return rs.Cache(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX]) } func (rs *RedisStorage) CachePrefixValues(prefixes map[string][]string) error { @@ -98,11 +94,10 @@ func (rs *RedisStorage) CachePrefixValues(prefixes map[string][]string) error { utils.DESTINATION_PREFIX: []string{}, utils.RATING_PLAN_PREFIX: []string{}, utils.RATING_PROFILE_PREFIX: []string{}, - utils.RP_ALIAS_PREFIX: []string{}, utils.LCR_PREFIX: []string{}, - utils.DERIVEDCHARGERS_PREFIX: []string{}, utils.ACTION_PREFIX: []string{}, - utils.SHARED_GROUP_PREFIX: []string{}, - utils.ACC_ALIAS_PREFIX: []string{}, + utils.DERIVEDCHARGERS_PREFIX: []string{}, + utils.ACTION_PREFIX: []string{}, + utils.SHARED_GROUP_PREFIX: []string{}, } for prefix, ids := range prefixes { if _, found := pm[prefix]; !found { @@ -110,10 +105,10 @@ func (rs *RedisStorage) CachePrefixValues(prefixes map[string][]string) error { } pm[prefix] = ids } - return rs.Cache(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.RP_ALIAS_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX], pm[utils.ACC_ALIAS_PREFIX]) + return rs.Cache(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX]) } -func (rs *RedisStorage) Cache(dKeys, rpKeys, rpfKeys, plsKeys, lcrKeys, dcsKeys, actKeys, shgKeys, alsKeys []string) (err error) { +func (rs *RedisStorage) Cache(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, actKeys, shgKeys []string) (err error) { cache2go.BeginTransaction() if dKeys == nil || (float64(cache2go.CountEntries(utils.DESTINATION_PREFIX))*utils.DESTINATIONS_LOAD_THRESHOLD < float64(len(dKeys))) { // if need to load more than a half of exiting keys load them all @@ -200,26 +195,6 @@ func (rs *RedisStorage) Cache(dKeys, rpKeys, rpfKeys, plsKeys, lcrKeys, dcsKeys, if len(lcrKeys) != 0 { Logger.Info("Finished LCR rules caching.") } - if plsKeys == nil { - Logger.Info("Caching all rating subject aliases.") - if plsKeys, err = rs.db.Keys(utils.RP_ALIAS_PREFIX + "*"); err != nil { - cache2go.RollbackTransaction() - return err - } - cache2go.RemPrefixKey(utils.RP_ALIAS_PREFIX) - } else if len(plsKeys) != 0 { - Logger.Info(fmt.Sprintf("Caching rating subject aliases: %v", plsKeys)) - } - for _, key := range plsKeys { - cache2go.RemKey(key) - if _, err = rs.GetRpAlias(key[len(utils.RP_ALIAS_PREFIX):], true); err != nil { - cache2go.RollbackTransaction() - return err - } - } - if len(plsKeys) != 0 { - Logger.Info("Finished rating profile aliases caching.") - } // DerivedChargers caching if dcsKeys == nil { Logger.Info("Caching all derived chargers") @@ -285,26 +260,6 @@ func (rs *RedisStorage) Cache(dKeys, rpKeys, rpfKeys, plsKeys, lcrKeys, dcsKeys, if len(shgKeys) != 0 { Logger.Info("Finished shared groups caching.") } - if alsKeys == nil { - Logger.Info("Caching all account aliases.") - if alsKeys, err = rs.db.Keys(utils.ACC_ALIAS_PREFIX + "*"); err != nil { - cache2go.RollbackTransaction() - return err - } - cache2go.RemPrefixKey(utils.ACC_ALIAS_PREFIX) - } else if len(alsKeys) != 0 { - Logger.Info(fmt.Sprintf("Caching account aliases: %v", alsKeys)) - } - for _, key := range alsKeys { - cache2go.RemKey(key) - if _, err = rs.GetAccAlias(key[len(utils.ACC_ALIAS_PREFIX):], true); err != nil { - cache2go.RollbackTransaction() - return err - } - } - if len(alsKeys) != 0 { - Logger.Info("Finished account aliases caching.") - } cache2go.CommitTransaction() return nil } @@ -389,105 +344,6 @@ func (rs *RedisStorage) SetRatingProfile(rpf *RatingProfile) (err error) { return } -func (rs *RedisStorage) GetRpAlias(key string, skipCache bool) (alias string, err error) { - key = utils.RP_ALIAS_PREFIX + key - if !skipCache { - if x, err := cache2go.GetCached(key); err == nil { - return x.(string), nil - } else { - return "", err - } - } - var values []byte - if values, err = rs.db.Get(key); err == nil { - alias = string(values) - cache2go.Cache(key, alias) - } - return -} - -func (rs *RedisStorage) SetRpAlias(key, alias string) (err error) { - err = rs.db.Set(utils.RP_ALIAS_PREFIX+key, []byte(alias)) - return -} - -// Removes the aliases of a specific account, on a tenant -func (rs *RedisStorage) RemoveRpAliases(tenantRtSubjects []*TenantRatingSubject, skipCache bool) (err error) { - if skipCache { - alsKeys, err := rs.db.Keys(utils.RP_ALIAS_PREFIX + "*") - if err != nil { - return err - } - for _, key := range alsKeys { - for _, tntRSubj := range tenantRtSubjects { - tenantPrfx := utils.RP_ALIAS_PREFIX + tntRSubj.Tenant + utils.CONCATENATED_KEY_SEP - if len(key) < len(tenantPrfx) || tenantPrfx != key[:len(tenantPrfx)] { // filter out the tenant for accounts - continue - } - alias, err := rs.GetRpAlias(key[len(utils.RP_ALIAS_PREFIX):], true) - if err != nil { - return err - } - if tntRSubj.Subject != alias { - continue - } - if _, err = rs.db.Del(key); err != nil { - return err - } - cache2go.RemKey(key) - break - } - } - } else { - alsMap, err := cache2go.GetAllEntries(utils.RP_ALIAS_PREFIX) - if err != nil { - return err - } - - for key, aliasInterface := range alsMap { - alias := aliasInterface.Value().(string) - for _, tntRSubj := range tenantRtSubjects { - tenantPrfx := tntRSubj.Tenant + utils.CONCATENATED_KEY_SEP - if len(key) < len(tenantPrfx) || !strings.HasPrefix(key, tenantPrfx) { // filter out the tenant for accounts - continue - } - if tntRSubj.Subject != alias { - continue - } - if _, err = rs.db.Del(utils.RP_ALIAS_PREFIX + key); err != nil { - return err - } - cache2go.RemKey(utils.RP_ALIAS_PREFIX + key) - break - } - } - - } - return -} - -func (rs *RedisStorage) GetRPAliases(tenant, subject string, skipCache bool) (aliases []string, err error) { - tenantPrfx := utils.RP_ALIAS_PREFIX + tenant + utils.CONCATENATED_KEY_SEP - var alsKeys []string - if !skipCache { - alsKeys = cache2go.GetEntriesKeys(tenantPrfx) - } - if len(alsKeys) == 0 { - if alsKeys, err = rs.db.Keys(tenantPrfx + "*"); err != nil { - return nil, err - } - } - for _, key := range alsKeys { - if alsSubj, err := rs.GetRpAlias(key[len(utils.RP_ALIAS_PREFIX):], skipCache); err != nil { - return nil, err - } else if alsSubj == subject { - alsFromKey := key[len(tenantPrfx):] // take out the alias out of key+tenant - aliases = append(aliases, alsFromKey) - } - } - return aliases, nil -} - func (rs *RedisStorage) GetLCR(key string, skipCache bool) (lcr *LCR, err error) { key = utils.LCR_PREFIX + key if !skipCache { @@ -512,107 +368,6 @@ func (rs *RedisStorage) SetLCR(lcr *LCR) (err error) { return } -func (rs *RedisStorage) GetAccAlias(key string, skipCache bool) (alias string, err error) { - key = utils.ACC_ALIAS_PREFIX + key - if !skipCache { - if x, err := cache2go.GetCached(key); err == nil { - return x.(string), nil - } else { - return "", err - } - } - var values []byte - if values, err = rs.db.Get(key); err == nil { - alias = string(values) - cache2go.Cache(key, alias) - } - return -} - -// Adds one alias for one account -func (rs *RedisStorage) SetAccAlias(key, alias string) (err error) { - err = rs.db.Set(utils.ACC_ALIAS_PREFIX+key, []byte(alias)) - return -} - -func (rs *RedisStorage) RemoveAccAliases(tenantAccounts []*TenantAccount, skipCache bool) (err error) { - if skipCache { - alsKeys, err := rs.db.Keys(utils.ACC_ALIAS_PREFIX + "*") - if err != nil { - return err - } - for _, key := range alsKeys { - for _, tntAcnt := range tenantAccounts { - tenantPrfx := utils.ACC_ALIAS_PREFIX + tntAcnt.Tenant + utils.CONCATENATED_KEY_SEP - if len(key) < len(tenantPrfx) || tenantPrfx != key[:len(tenantPrfx)] { // filter out the tenant for accounts - continue - } - alias, err := rs.GetAccAlias(key[len(utils.ACC_ALIAS_PREFIX):], true) - if err != nil { - return err - } - if tntAcnt.Account != alias { - continue - } - if _, err = rs.db.Del(key); err != nil { - log.Print("") - return err - } - cache2go.RemKey(key) - break - } - } - - } else { - alsMap, err := cache2go.GetAllEntries(utils.ACC_ALIAS_PREFIX) - if err != nil { - return err - } - - for key, aliasInterface := range alsMap { - alias := aliasInterface.Value().(string) - for _, tntAcnt := range tenantAccounts { - tenantPrfx := tntAcnt.Tenant + utils.CONCATENATED_KEY_SEP - if len(key) < len(tenantPrfx) || !strings.HasPrefix(key, tenantPrfx) { // filter out the tenant for accounts - continue - } - if tntAcnt.Account != alias { - continue - } - if _, err = rs.db.Del(utils.ACC_ALIAS_PREFIX + key); err != nil { - return err - } - cache2go.RemKey(utils.ACC_ALIAS_PREFIX + key) - break - } - } - } - return -} - -// Returns the aliases of one specific account on a tenant -func (rs *RedisStorage) GetAccountAliases(tenant, account string, skipCache bool) (aliases []string, err error) { - tenantPrfx := utils.ACC_ALIAS_PREFIX + tenant + utils.CONCATENATED_KEY_SEP - var alsKeys []string - if !skipCache { - alsKeys = cache2go.GetEntriesKeys(tenantPrfx) - } - if len(alsKeys) == 0 { - if alsKeys, err = rs.db.Keys(tenantPrfx + "*"); err != nil { - return nil, err - } - } - for _, key := range alsKeys { - if alsAcnt, err := rs.GetAccAlias(key[len(utils.ACC_ALIAS_PREFIX):], skipCache); err != nil { - return nil, err - } else if alsAcnt == account { - alsFromKey := key[len(tenantPrfx):] // take out the alias out of key+tenant - aliases = append(aliases, alsFromKey) - } - } - return aliases, nil -} - func (rs *RedisStorage) GetDestination(key string) (dest *Destination, err error) { key = utils.DESTINATION_PREFIX + key var values []byte @@ -769,6 +524,23 @@ func (rs *RedisStorage) GetSubscribers() (result map[string]*SubscriberData, err return } +func (rs *RedisStorage) SetSubscriber(key string, sub *SubscriberData) (err error) { + result, err := rs.ms.Marshal(sub) + rs.db.Set(utils.PUBSUB_SUBSCRIBERS_PREFIX+key, result) + return +} + +func (rs *RedisStorage) RemoveSubscriber(key string) (err error) { + _, err = rs.db.Del(utils.PUBSUB_SUBSCRIBERS_PREFIX + key) + return +} + +func (rs *RedisStorage) SetUser(up *UserProfile) (err error) { + result, err := rs.ms.Marshal(up) + rs.db.Set(utils.USERS_PREFIX+up.GetId(), result) + return +} + func (rs *RedisStorage) GetUser(key string) (up *UserProfile, err error) { var values []byte if values, err = rs.db.Get(utils.USERS_PREFIX + key); err == nil { @@ -795,28 +567,49 @@ func (rs *RedisStorage) GetUsers() (result []*UserProfile, err error) { return } -func (rs *RedisStorage) SetSubscriber(key string, sub *SubscriberData) (err error) { - result, err := rs.ms.Marshal(sub) - rs.db.Set(utils.PUBSUB_SUBSCRIBERS_PREFIX+key, result) - return -} - -func (rs *RedisStorage) RemoveSubscriber(key string) (err error) { - _, err = rs.db.Del(utils.PUBSUB_SUBSCRIBERS_PREFIX + key) - return -} - -func (rs *RedisStorage) SetUser(up *UserProfile) (err error) { - result, err := rs.ms.Marshal(up) - rs.db.Set(utils.USERS_PREFIX+up.GetId(), result) - return -} - func (rs *RedisStorage) RemoveUser(key string) (err error) { _, err = rs.db.Del(utils.USERS_PREFIX + key) return } +func (rs *RedisStorage) SetAlias(al *Alias) (err error) { + result, err := rs.ms.Marshal(al.Values) + rs.db.Set(utils.ALIASES_PREFIX+al.GetId(), result) + return +} + +func (rs *RedisStorage) GetAlias(key string) (al *Alias, err error) { + var values []byte + if values, err = rs.db.Get(utils.ALIASES_PREFIX + key); err == nil { + al = &Alias{Values: make(AliasValues, 0)} + al.SetId(key) + err = rs.ms.Unmarshal(values, al.Values) + } + return +} + +func (rs *RedisStorage) GetAliases() (result []*Alias, err error) { + keys, err := rs.db.Keys(utils.ALIASES_PREFIX + "*") + if err != nil { + return nil, err + } + for _, key := range keys { + if values, err := rs.db.Get(key); err == nil { + al := &Alias{Values: make(AliasValues, 0)} + err = rs.ms.Unmarshal(values, al.Values) + result = append(result, al) + } else { + return nil, utils.ErrNotFound + } + } + return +} + +func (rs *RedisStorage) RemoveAlias(key string) (err error) { + _, err = rs.db.Del(utils.ALIASES_PREFIX + key) + return +} + func (rs *RedisStorage) GetActionPlans(key string) (ats ActionPlans, err error) { var values []byte if values, err = rs.db.Get(utils.ACTION_TIMING_PREFIX + key); err == nil { diff --git a/engine/storage_sql.go b/engine/storage_sql.go index 467df30e8..0c06507e1 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -1352,3 +1352,65 @@ func (self *SQLStorage) GetTpUsers(filter *TpUser) ([]TpUser, error) { return tpUsers, nil } + +func (self *SQLStorage) SetTpAliases(aliases []TpAlias) error { + if len(aliases) == 0 { + return nil + } + m := make(map[string]bool) + + tx := self.db.Begin() + for _, alias := range aliases { + if found, _ := m[alias.GetId()]; !found { + m[alias.GetId()] = true + if err := tx.Where(&TpAlias{ + Tpid: alias.Tpid, + Direction: alias.Direction, + Tenant: alias.Tenant, + Category: alias.Category, + Account: alias.Account, + Subject: alias.Subject, + Group: alias.Group, + }).Delete(TpAlias{}).Error; err != nil { + tx.Rollback() + return err + } + } + save := tx.Save(&alias) + if save.Error != nil { + tx.Rollback() + return save.Error + } + } + tx.Commit() + return nil +} + +func (self *SQLStorage) GetTpAliases(filter *TpAlias) ([]TpAlias, error) { + var tpAliases []TpAlias + q := self.db.Where("tpid = ?", filter.Tpid) + if len(filter.Direction) != 0 { + q = q.Where("direction = ?", filter.Direction) + } + if len(filter.Tenant) != 0 { + q = q.Where("tenant = ?", filter.Tenant) + } + if len(filter.Category) != 0 { + q = q.Where("category = ?", filter.Category) + } + if len(filter.Account) != 0 { + q = q.Where("account = ?", filter.Account) + } + if len(filter.Subject) != 0 { + q = q.Where("subject = ?", filter.Subject) + } + if len(filter.Group) != 0 { + q = q.Where("group = ?", filter.Group) + } + + if err := q.Find(&tpAliases).Error; err != nil { + return nil, err + } + + return tpAliases, nil +} diff --git a/engine/storage_test.go b/engine/storage_test.go index faa089e75..0be845daf 100644 --- a/engine/storage_test.go +++ b/engine/storage_test.go @@ -19,12 +19,9 @@ along with this program. If not, see package engine import ( - "reflect" - "sort" "testing" "time" - "github.com/cgrates/cgrates/cache2go" "github.com/cgrates/cgrates/utils" ) @@ -113,12 +110,6 @@ func TestCacheRefresh(t *testing.T) { } } -func TestCacheAliases(t *testing.T) { - if subj, err := cache2go.GetCached(utils.RP_ALIAS_PREFIX + utils.RatingSubjectAliasKey("vdf", "a3")); err == nil && subj != "minu" { - t.Error("Error caching alias: ", subj, err) - } -} - // Install fails to detect them and starting server will panic, these tests will fix this func TestStoreInterfaces(t *testing.T) { rds := new(RedisStorage) @@ -129,110 +120,6 @@ func TestStoreInterfaces(t *testing.T) { var _ LogStorage = sql } -func TestGetRPAliases(t *testing.T) { - if err := ratingStorage.SetRpAlias(utils.RatingSubjectAliasKey("cgrates.org", "2001"), "1001"); err != nil { - t.Error(err) - } - if err := ratingStorage.SetRpAlias(utils.RatingSubjectAliasKey("cgrates.org", "2002"), "1001"); err != nil { - t.Error(err) - } - if err := ratingStorage.SetRpAlias(utils.RatingSubjectAliasKey("itsyscom.com", "2003"), "1001"); err != nil { - t.Error(err) - } - expectAliases := sort.StringSlice([]string{"2001", "2002"}) - expectAliases.Sort() - if aliases, err := ratingStorage.GetRPAliases("cgrates.org", "1001", true); err != nil { - t.Error(err) - } else { - aliases := sort.StringSlice(aliases) - aliases.Sort() - if !reflect.DeepEqual(aliases, expectAliases) { - t.Errorf("Expecting: %v, received: %v", expectAliases, aliases) - } - } -} - -func TestRemRSubjAliases(t *testing.T) { - if err := ratingStorage.SetRpAlias(utils.RatingSubjectAliasKey("cgrates.org", "2002"), "1001"); err != nil { - t.Error(err) - } - if err := ratingStorage.SetRpAlias(utils.RatingSubjectAliasKey("itsyscom.com", "2003"), "1001"); err != nil { - t.Error(err) - } - if err := ratingStorage.RemoveRpAliases([]*TenantRatingSubject{&TenantRatingSubject{Tenant: "cgrates.org", Subject: "1001"}}, true); err != nil { - t.Error(err) - } - if cgrAliases, err := ratingStorage.GetRPAliases("cgrates.org", "1001", true); err != nil { - t.Error(err) - } else if len(cgrAliases) != 0 { - t.Error("Subject aliases not removed: ", cgrAliases) - } - if iscAliases, err := ratingStorage.GetRPAliases("itsyscom.com", "1001", true); err != nil { // Make sure the aliases were removed at tenant level - t.Error(err) - } else if !reflect.DeepEqual(iscAliases, []string{"2003"}) { - t.Errorf("Unexpected aliases: %v", iscAliases) - } -} - -func TestStorageRpAliases(t *testing.T) { - if _, err := ratingStorage.GetRpAlias("cgrates.org:1991", true); err == nil { - t.Error("Found alias before setting") - } - if err := ratingStorage.SetRpAlias(utils.RatingSubjectAliasKey("cgrates.org", "1991"), "1991"); err != nil { - t.Error(err) - } - if _, err := ratingStorage.GetRpAlias("cgrates.org:1991", true); err != nil { - t.Error("Alias not found after setting") - } - if err := ratingStorage.RemoveRpAliases([]*TenantRatingSubject{&TenantRatingSubject{Tenant: "cgrates.org", Subject: "1991"}}, true); err != nil { - t.Error(err) - } - if _, err := ratingStorage.GetRpAlias("cgrates.org:1991", true); err == nil { - t.Error("Found alias after removing") - } -} - -func TestGetAccountAliases(t *testing.T) { - if err := ratingStorage.SetAccAlias(utils.AccountAliasKey("cgrates.org", "2001"), "1001"); err != nil { - t.Error(err) - } - if err := ratingStorage.SetAccAlias(utils.AccountAliasKey("cgrates.org", "2002"), "1001"); err != nil { - t.Error(err) - } - if err := ratingStorage.SetAccAlias(utils.AccountAliasKey("itsyscom.com", "2003"), "1001"); err != nil { - t.Error(err) - } - expectAliases := sort.StringSlice([]string{"2001", "2002"}) - expectAliases.Sort() - if aliases, err := ratingStorage.GetAccountAliases("cgrates.org", "1001", true); err != nil { - t.Error(err) - } else { - aliases := sort.StringSlice(aliases) - aliases.Sort() - if !reflect.DeepEqual(aliases, expectAliases) { - t.Errorf("Expecting: %v, received: %v", expectAliases, aliases) - } - } -} - -func TestStorageAccAliases(t *testing.T) { - if _, err := ratingStorage.GetAccAlias("cgrates.org:1991", true); err == nil { - t.Error("Found alias before setting") - } - if err := ratingStorage.SetAccAlias(utils.AccountAliasKey("cgrates.org", "1991"), "1991"); err != nil { - t.Error(err) - } - if _, err := ratingStorage.GetAccAlias("cgrates.org:1991", true); err != nil { - t.Error("Alias not found after setting") - } - if err := ratingStorage.RemoveAccAliases([]*TenantAccount{&TenantAccount{Tenant: "cgrates.org", Account: "1991"}}, true); err != nil { - t.Error(err) - } - if _, err := ratingStorage.GetAccAlias("cgrates.org:1991", true); err == nil { - t.Error("Found alias after removing") - } -} - /************************** Benchmarks *****************************/ func GetUB() *Account { diff --git a/engine/tp_reader.go b/engine/tp_reader.go index e6ca07d64..b41e1eeed 100644 --- a/engine/tp_reader.go +++ b/engine/tp_reader.go @@ -22,8 +22,6 @@ type TpReader struct { dirtyRpAliases []*TenantRatingSubject // used to clean aliases that might have changed dirtyAccAliases []*TenantAccount // used to clean aliases that might have changed destinations map[string]*Destination - rpAliases map[string]string - accAliases map[string]string timings map[string]*utils.TPTiming rates map[string]*utils.TPRate destinationRates map[string]*utils.TPDestinationRate @@ -34,6 +32,7 @@ type TpReader struct { derivedChargers map[string]utils.DerivedChargers cdrStats map[string]*CdrStats users map[string]*UserProfile + aliases map[string]*Alias } func NewTpReader(rs RatingStorage, as AccountingStorage, lr LoadReader, tpid string) *TpReader { @@ -53,11 +52,10 @@ func NewTpReader(rs RatingStorage, as AccountingStorage, lr LoadReader, tpid str ratingProfiles: make(map[string]*RatingProfile), sharedGroups: make(map[string]*SharedGroup), lcrs: make(map[string]*LCR), - rpAliases: make(map[string]string), - accAliases: make(map[string]string), accountActions: make(map[string]*Account), cdrStats: make(map[string]*CdrStats), users: make(map[string]*UserProfile), + aliases: make(map[string]*Alias), derivedChargers: make(map[string]utils.DerivedChargers), } //add *any and *asap timing tag (in case of no timings file) @@ -340,15 +338,6 @@ func (tpr *TpReader) LoadRatingProfiles() (err error) { return err } for _, tpRpf := range mpTpRpfs { - // extract aliases from subject - aliases := strings.Split(tpRpf.Subject, ";") - tpr.dirtyRpAliases = append(tpr.dirtyRpAliases, &TenantRatingSubject{Tenant: tpRpf.Tenant, Subject: aliases[0]}) - if len(aliases) > 1 { - tpRpf.Subject = aliases[0] - for _, alias := range aliases[1:] { - tpr.rpAliases[utils.RatingSubjectAliasKey(tpRpf.Tenant, alias)] = tpRpf.Subject - } - } rpf := &RatingProfile{Id: tpRpf.KeyId()} for _, tpRa := range tpRpf.RatingPlanActivations { at, err := utils.ParseDate(tpRa.ActivationTime) @@ -853,16 +842,6 @@ func (tpr *TpReader) LoadAccountActions() (err error) { if _, alreadyDefined := tpr.accountActions[aa.KeyId()]; alreadyDefined { return fmt.Errorf("duplicate account action found: %s", aa.KeyId()) } - - // extract aliases from subject - aliases := strings.Split(aa.Account, ";") - tpr.dirtyAccAliases = append(tpr.dirtyAccAliases, &TenantAccount{Tenant: aa.Tenant, Account: aliases[0]}) - if len(aliases) > 1 { - aa.Account = aliases[0] - for _, alias := range aliases[1:] { - tpr.accAliases[utils.AccountAliasKey(aa.Tenant, alias)] = aa.Account - } - } var aTriggers []*ActionTrigger if aa.ActionTriggersId != "" { var exists bool @@ -1076,6 +1055,38 @@ func (tpr *TpReader) LoadUsers() error { return err } +func (tpr *TpReader) LoadAliasesFiltered(filter *TpAlias) (bool, error) { + tpAliases, err := tpr.lr.GetTpAliases(filter) + + alias := &Alias{ + Direction: filter.Direction, + Tenant: filter.Tenant, + Category: filter.Category, + Account: filter.Account, + Subject: filter.Subject, + Group: filter.Group, + Values: make(AliasValues, 0), + } + for _, tpAlias := range tpAliases { + alias.Values = append(alias.Values, &AliasValue{ + DestinationId: tpAlias.DestinationId, + Alias: tpAlias.Alias, + Weight: tpAlias.Weight, + }) + } + tpr.accountingStorage.SetAlias(alias) + return len(tpAliases) > 0, err +} + +func (tpr *TpReader) LoadAliases() error { + tps, err := tpr.lr.GetTpAliases(&TpAlias{Tpid: tpr.tpid}) + if err != nil { + return err + } + tpr.aliases, err = TpAliases(tps).GetAliases() + return err +} + func (tpr *TpReader) LoadAll() error { var err error if err = tpr.LoadDestinations(); err != nil { @@ -1123,6 +1134,9 @@ func (tpr *TpReader) LoadAll() error { if err = tpr.LoadUsers(); err != nil { return err } + if err = tpr.LoadAliases(); err != nil { + return err + } return nil } @@ -1248,36 +1262,6 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose bool) (err error) { log.Println("\t", ub.Id) } } - if verbose { - log.Print("Rating Profile Aliases:") - } - if err := tpr.ratingStorage.RemoveRpAliases(tpr.dirtyRpAliases, true); err != nil { - return err - } - for key, alias := range tpr.rpAliases { - err = tpr.ratingStorage.SetRpAlias(key, alias) - if err != nil { - return err - } - if verbose { - log.Print("\t", key) - } - } - if verbose { - log.Print("Account Aliases:") - } - if err := tpr.ratingStorage.RemoveAccAliases(tpr.dirtyAccAliases, true); err != nil { - return err - } - for key, alias := range tpr.accAliases { - err = tpr.ratingStorage.SetAccAlias(key, alias) - if err != nil { - return err - } - if verbose { - log.Print("\t", key) - } - } if verbose { log.Print("Derived Chargers:") } @@ -1314,6 +1298,18 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose bool) (err error) { log.Print("\t", u.GetId()) } } + if verbose { + log.Print("Aliases:") + } + for _, al := range tpr.aliases { + err = tpr.accountingStorage.SetAlias(al) + if err != nil { + return err + } + if verbose { + log.Print("\t", al.GetId()) + } + } return } @@ -1419,22 +1415,6 @@ func (tpr *TpReader) GetLoadedIds(categ string) ([]string, error) { i++ } return keys, nil - case utils.RP_ALIAS_PREFIX: // aliases - keys := make([]string, len(tpr.rpAliases)) - i := 0 - for k := range tpr.rpAliases { - keys[i] = k - i++ - } - return keys, nil - case utils.ACC_ALIAS_PREFIX: // aliases - keys := make([]string, len(tpr.accAliases)) - i := 0 - for k := range tpr.accAliases { - keys[i] = k - i++ - } - return keys, nil case utils.DERIVEDCHARGERS_PREFIX: // derived chargers keys := make([]string, len(tpr.derivedChargers)) i := 0 @@ -1467,6 +1447,14 @@ func (tpr *TpReader) GetLoadedIds(categ string) ([]string, error) { i++ } return keys, nil + case utils.ALIASES_PREFIX: + keys := make([]string, len(tpr.aliases)) + i := 0 + for k := range tpr.aliases { + keys[i] = k + i++ + } + return keys, nil } return nil, errors.New("Unsupported category") } diff --git a/engine/tpimporter_csv.go b/engine/tpimporter_csv.go index 565681eb0..a9473cac4 100644 --- a/engine/tpimporter_csv.go +++ b/engine/tpimporter_csv.go @@ -73,7 +73,9 @@ func (self *TPCSVImporter) Run() error { path.Join(self.DirPath, utils.ACCOUNT_ACTIONS_CSV), path.Join(self.DirPath, utils.DERIVED_CHARGERS_CSV), path.Join(self.DirPath, utils.CDR_STATS_CSV), - path.Join(self.DirPath, utils.USERS_CSV)) + path.Join(self.DirPath, utils.USERS_CSV), + path.Join(self.DirPath, utils.ALIASES_CSV), + ) files, _ := ioutil.ReadDir(self.DirPath) for _, f := range files { fHandler, hasName := fileHandlers[f.Name()] diff --git a/engine/users.go b/engine/users.go index 6129646c8..8cf8d2adf 100644 --- a/engine/users.go +++ b/engine/users.go @@ -94,7 +94,7 @@ func (um *UserMap) ReloadUsers(in string, reply *string) error { um.table = make(map[string]map[string]string) um.index = make(map[string]map[string]bool) - // load from rating db + // load from db if ups, err := um.accountingDb.GetUsers(); err == nil { for _, up := range ups { um.table[up.GetId()] = up.Profile diff --git a/utils/consts.go b/utils/consts.go index 5262882aa..279c1d4e1 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -78,6 +78,7 @@ const ( DERIVED_CHARGERS_CSV = "DerivedChargers.csv" CDR_STATS_CSV = "CdrStats.csv" USERS_CSV = "Users.csv" + ALIASES_CSV = "Aliases.csv" ROUNDING_UP = "*up" ROUNDING_MIDDLE = "*middle" ROUNDING_DOWN = "*down" @@ -160,8 +161,6 @@ const ( ACTION_TIMING_PREFIX = "apl_" RATING_PLAN_PREFIX = "rpl_" RATING_PROFILE_PREFIX = "rpf_" - RP_ALIAS_PREFIX = "ral_" - ACC_ALIAS_PREFIX = "aal_" ACTION_PREFIX = "act_" SHARED_GROUP_PREFIX = "shg_" ACCOUNT_PREFIX = "ubl_" @@ -171,6 +170,7 @@ const ( CDR_STATS_QUEUE_PREFIX = "csq_" PUBSUB_SUBSCRIBERS_PREFIX = "pss_" USERS_PREFIX = "usr_" + ALIASES_PREFIX = "als_" CDR_STATS_PREFIX = "cst_" TEMP_DESTINATION_PREFIX = "tmp_" LOG_CALL_COST_PREFIX = "cco_"