mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-21 07:08:45 +05:00
Aliases now with multi-tenant support, ApierV1.GetRatingSubjectAliases, ApierV1.GetAccountAliases RPC commands implementation
This commit is contained in:
@@ -1458,6 +1458,32 @@ func TestLocalRemDC(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLocalGetRatingSubjectAliases(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
attrs := utils.AttrGetRatingSubjectAliases{Tenant: "cgrates.org", Subject: "1001"}
|
||||
var subjAliases []string
|
||||
if err := rater.Call("ApierV1.GetRatingSubjectAliases", attrs, &subjAliases); err != nil {
|
||||
t.Error("Unexpected error", err.Error())
|
||||
} else if len(subjAliases) != 0 {
|
||||
t.Error("Unexpected subject aliases returned", subjAliases)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLocalAccountAliases(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
}
|
||||
attrs := utils.AttrGetAccountAliases{Tenant: "cgrates.org", Account: "1001"}
|
||||
var acntAliases []string
|
||||
if err := rater.Call("ApierV1.GetAccountAliases", attrs, &acntAliases); err != nil {
|
||||
t.Error("Unexpected error", err.Error())
|
||||
} else if len(acntAliases) != 0 {
|
||||
t.Error("Unexpected subject aliases returned", acntAliases)
|
||||
}
|
||||
}
|
||||
|
||||
// Simply kill the engine after we are done with tests within this file
|
||||
func TestStopEngine(t *testing.T) {
|
||||
if !*testLocal {
|
||||
|
||||
@@ -277,7 +277,7 @@ 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(RP_ALIAS_PREFIX + subject); err == nil {
|
||||
if rs, err := cache2go.GetCached(RP_ALIAS_PREFIX + utils.RatingProfileAliasKey(cd.Tenant,subject)); err == nil {
|
||||
realSubject := rs.(string)
|
||||
subject = realSubject
|
||||
cd.Subject = realSubject
|
||||
@@ -290,7 +290,7 @@ func (cd *CallDescriptor) GetAccountKey() string {
|
||||
subj := cd.Subject
|
||||
if cd.Account != "" {
|
||||
// check if subject is alias
|
||||
if realSubject, err := cache2go.GetCached(ACC_ALIAS_PREFIX + subj); err == nil {
|
||||
if realSubject, err := cache2go.GetCached(ACC_ALIAS_PREFIX + utils.AccountAliasKey(cd.Tenant,subj)); err == nil {
|
||||
cd.Account = realSubject.(string)
|
||||
}
|
||||
subj = cd.Account
|
||||
|
||||
@@ -518,7 +518,7 @@ func (csvr *CSVReader) LoadRatingProfiles() (err error) {
|
||||
if len(aliases) > 1 {
|
||||
subject = aliases[0]
|
||||
for _, alias := range aliases[1:] {
|
||||
csvr.rpAliases[alias] = subject
|
||||
csvr.rpAliases[utils.RatingProfileAliasKey(tenant, alias)] = subject
|
||||
}
|
||||
}
|
||||
key := fmt.Sprintf("%s:%s:%s:%s", direction, tenant, tor, subject)
|
||||
@@ -796,7 +796,7 @@ func (csvr *CSVReader) LoadAccountActions() (err error) {
|
||||
if len(aliases) > 1 {
|
||||
account = aliases[0]
|
||||
for _, alias := range aliases[1:] {
|
||||
csvr.accAliases[alias] = account
|
||||
csvr.accAliases[utils.AccountAliasKey(tenant, alias)] = account
|
||||
}
|
||||
}
|
||||
tag := fmt.Sprintf("%s:%s:%s", direction, tenant, account)
|
||||
|
||||
@@ -911,9 +911,9 @@ func TestLoadRpAliases(t *testing.T) {
|
||||
if len(csvr.rpAliases) != 3 {
|
||||
t.Error("Failed to load rp aliases: ", csvr.rpAliases)
|
||||
}
|
||||
if csvr.rpAliases["a1"] != "minu" ||
|
||||
csvr.rpAliases["a2"] != "minu" ||
|
||||
csvr.rpAliases["a3"] != "minu" {
|
||||
if csvr.rpAliases[utils.RatingProfileAliasKey("vdf", "a1")] != "minu" ||
|
||||
csvr.rpAliases[utils.RatingProfileAliasKey("vdf", "a2")] != "minu" ||
|
||||
csvr.rpAliases[utils.RatingProfileAliasKey("vdf", "a3")] != "minu" {
|
||||
t.Error("Error loading rp aliases: ", csvr.rpAliases)
|
||||
}
|
||||
}
|
||||
@@ -922,8 +922,8 @@ func TestLoadAccAliases(t *testing.T) {
|
||||
if len(csvr.accAliases) != 2 {
|
||||
t.Error("Failed to load acc aliases: ", csvr.accAliases)
|
||||
}
|
||||
if csvr.accAliases["a1"] != "minitsboy" ||
|
||||
csvr.accAliases["a2"] != "minitsboy" {
|
||||
if csvr.accAliases[utils.AccountAliasKey("vdf", "a1")] != "minitsboy" ||
|
||||
csvr.accAliases[utils.AccountAliasKey("vdf", "a2")] != "minitsboy" {
|
||||
t.Error("Error loading acc aliases: ", csvr.accAliases)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,7 +348,7 @@ func (dbr *DbReader) LoadRatingProfiles() error {
|
||||
if len(aliases) > 1 {
|
||||
tpRpf.Subject = aliases[0]
|
||||
for _, alias := range aliases[1:] {
|
||||
dbr.rpAliases[alias] = tpRpf.Subject
|
||||
dbr.rpAliases[utils.RatingProfileAliasKey(tpRpf.Tenant, alias)] = tpRpf.Subject
|
||||
}
|
||||
}
|
||||
rpf := &RatingProfile{Id: tpRpf.KeyId()}
|
||||
@@ -584,7 +584,7 @@ func (dbr *DbReader) LoadAccountActions() (err error) {
|
||||
if len(aliases) > 1 {
|
||||
aa.Account = aliases[0]
|
||||
for _, alias := range aliases[1:] {
|
||||
dbr.accAliases[alias] = aa.Account
|
||||
dbr.accAliases[utils.AccountAliasKey(aa.Tenant, alias)] = aa.Account
|
||||
}
|
||||
}
|
||||
aTriggers, exists := dbr.actionsTriggers[aa.ActionTriggersId]
|
||||
|
||||
@@ -80,6 +80,7 @@ type RatingStorage interface {
|
||||
GetRpAlias(string, bool) (string, error)
|
||||
SetRpAlias(string, string) error
|
||||
RemoveRpAliases([]string) error
|
||||
GetRPAliases(string, string) ([]string, error)
|
||||
GetDestination(string) (*Destination, error)
|
||||
SetDestination(*Destination) error
|
||||
GetLCR(string, bool) (*LCR, error)
|
||||
@@ -99,6 +100,7 @@ type AccountingStorage interface {
|
||||
GetAccAlias(string, bool) (string, error)
|
||||
SetAccAlias(string, string) error
|
||||
RemoveAccAliases([]string) error
|
||||
GetAccountAliases(string, string) ([]string, error)
|
||||
GetActionTimings(string) (ActionPlan, error)
|
||||
SetActionTimings(string, ActionPlan) error
|
||||
GetAllActionTimings() (map[string]ActionPlan, error)
|
||||
|
||||
@@ -288,6 +288,16 @@ func (ms *MapStorage) RemoveRpAliases(accounts []string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (ms *MapStorage) GetRPAliases(tenant, subject string) (aliases []string, err error) {
|
||||
for key, value := range ms.dict {
|
||||
tenantPrfx := RP_ALIAS_PREFIX + tenant + utils.CONCATENATED_KEY_SEP
|
||||
if strings.HasPrefix(key, 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, checkDb bool) (alias string, err error) {
|
||||
key = ACC_ALIAS_PREFIX + key
|
||||
if x, err := cache2go.GetCached(key); err == nil {
|
||||
@@ -320,6 +330,16 @@ func (ms *MapStorage) RemoveAccAliases(accounts []string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (ms *MapStorage) GetAccountAliases(tenant, account string) (aliases []string, err error) {
|
||||
for key, value := range ms.dict {
|
||||
tenantPrfx := ACC_ALIAS_PREFIX + tenant + utils.CONCATENATED_KEY_SEP
|
||||
if strings.HasPrefix(key, 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 = DESTINATION_PREFIX + key
|
||||
if values, ok := ms.dict[key]; ok {
|
||||
|
||||
@@ -343,6 +343,7 @@ func (rs *RedisStorage) SetRpAlias(key, alias string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Returns the aliases of one specific rating profile subject on a tenant
|
||||
func (rs *RedisStorage) RemoveRpAliases(accounts []string) (err error) {
|
||||
if alsKeys, err := rs.db.Keys(RP_ALIAS_PREFIX + "*"); err != nil {
|
||||
return err
|
||||
@@ -363,6 +364,26 @@ func (rs *RedisStorage) RemoveRpAliases(accounts []string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) GetRPAliases(tenant, subject string) (aliases []string, err error) {
|
||||
alsKeys, err := rs.db.Keys(RP_ALIAS_PREFIX + "*")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, key := range alsKeys {
|
||||
tenantPrfx := RP_ALIAS_PREFIX + tenant + utils.CONCATENATED_KEY_SEP
|
||||
if len(key) < len(tenantPrfx) || tenantPrfx != key[:len(tenantPrfx)] { // filter out the tenant for accounts
|
||||
continue
|
||||
}
|
||||
if alsSubj, err := rs.GetRpAlias(key[len(ACC_ALIAS_PREFIX):], true); 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, checkDb bool) (lcr *LCR, err error) {
|
||||
key = LCR_PREFIX + key
|
||||
if x, err := cache2go.GetCached(key); err == nil {
|
||||
@@ -402,6 +423,7 @@ func (rs *RedisStorage) GetAccAlias(key string, checkDb bool) (alias string, err
|
||||
return
|
||||
}
|
||||
|
||||
// Adds one alias for one account
|
||||
func (rs *RedisStorage) SetAccAlias(key, alias string) (err error) {
|
||||
err = rs.db.Set(ACC_ALIAS_PREFIX+key, []byte(alias))
|
||||
//cache2go.Cache(ALIAS_PREFIX+key, alias)
|
||||
@@ -428,6 +450,27 @@ func (rs *RedisStorage) RemoveAccAliases(accounts []string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Returns the aliases of one specific account on a tenant
|
||||
func (rs *RedisStorage) GetAccountAliases(tenant, account string) (aliases []string, err error) {
|
||||
alsKeys, err := rs.db.Keys(ACC_ALIAS_PREFIX + "*")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, key := range alsKeys {
|
||||
tenantPrfx := ACC_ALIAS_PREFIX + tenant + utils.CONCATENATED_KEY_SEP
|
||||
if len(key) < len(tenantPrfx) || tenantPrfx != key[:len(tenantPrfx)] { // filter out the tenant for accounts
|
||||
continue
|
||||
}
|
||||
if alsAcnt, err := rs.GetAccAlias(key[len(ACC_ALIAS_PREFIX):], true); 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 = DESTINATION_PREFIX + key
|
||||
var values []byte
|
||||
|
||||
@@ -19,10 +19,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package engine
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/cache2go"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
func TestMsgpackStructsAdded(t *testing.T) {
|
||||
@@ -110,7 +113,7 @@ func TestCacheRefresh(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCacheAliases(t *testing.T) {
|
||||
if subj, err := cache2go.GetCached(RP_ALIAS_PREFIX + "a3"); err != nil || subj != "minu" {
|
||||
if subj, err := cache2go.GetCached(RP_ALIAS_PREFIX + utils.RatingProfileAliasKey("vdf", "a3")); err != nil || subj != "minu" {
|
||||
t.Error("Error caching alias: ", subj, err)
|
||||
}
|
||||
}
|
||||
@@ -125,6 +128,52 @@ func TestStoreInterfaces(t *testing.T) {
|
||||
var _ LogStorage = sql
|
||||
}
|
||||
|
||||
func TestGetRPAliases(t *testing.T) {
|
||||
if err := dataStorage.SetRpAlias(utils.RatingProfileAliasKey("cgrates.org", "2001"), "1001"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if err := dataStorage.SetRpAlias(utils.RatingProfileAliasKey("cgrates.org", "2002"), "1001"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if err := dataStorage.SetRpAlias(utils.RatingProfileAliasKey("itsyscom.com", "2003"), "1001"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
expectAliases := sort.StringSlice([]string{"2001", "2002"})
|
||||
expectAliases.Sort()
|
||||
if aliases, err := dataStorage.GetRPAliases("cgrates.org", "1001"); 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 TestGetAccountAliases(t *testing.T) {
|
||||
if err := accountingStorage.SetAccAlias(utils.AccountAliasKey("cgrates.org", "2001"), "1001"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if err := accountingStorage.SetAccAlias(utils.AccountAliasKey("cgrates.org", "2002"), "1001"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if err := accountingStorage.SetAccAlias(utils.AccountAliasKey("itsyscom.com", "2003"), "1001"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
expectAliases := sort.StringSlice([]string{"2001", "2002"})
|
||||
expectAliases.Sort()
|
||||
if aliases, err := accountingStorage.GetAccountAliases("cgrates.org", "1001"); 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/************************** Benchmarks *****************************/
|
||||
|
||||
func GetUB() *Account {
|
||||
|
||||
@@ -8,5 +8,5 @@ The Debian packaging is:
|
||||
Copyright (C) 2011 Canonical Ltd.
|
||||
|
||||
Further development:
|
||||
Copyright (C) 2014 ITsysCOM
|
||||
Copyright (C) 2014 ITsysCOM GmbH
|
||||
|
||||
|
||||
@@ -384,3 +384,29 @@ type AttrGetDestination struct {
|
||||
type AttrDerivedChargers struct {
|
||||
Direction, Tenant, Category, Account, Subject string
|
||||
}
|
||||
|
||||
type AttrGetRatingSubjectAliases struct {
|
||||
Tenant, Subject string
|
||||
}
|
||||
|
||||
type AttrRemRatingSubjectAliases struct {
|
||||
Tenant, Subject string
|
||||
}
|
||||
|
||||
type AttrAddRatingSubjectAliases struct {
|
||||
Tenant, Subject string
|
||||
Aliases []string
|
||||
}
|
||||
|
||||
type AttrGetAccountAliases struct {
|
||||
Tenant, Account string
|
||||
}
|
||||
|
||||
type AttrRemAccountAliases struct {
|
||||
Tenant, Account string
|
||||
}
|
||||
|
||||
type AttrAddAccountAliases struct {
|
||||
Tenant, Account string
|
||||
Aliases []string
|
||||
}
|
||||
|
||||
@@ -234,3 +234,11 @@ func ConcatenatedKey(keyVals ...string) string {
|
||||
}
|
||||
return resKey
|
||||
}
|
||||
|
||||
func RatingProfileAliasKey(tenant, subject string) string {
|
||||
return ConcatenatedKey(tenant, subject)
|
||||
}
|
||||
|
||||
func AccountAliasKey(tenant, account string) string {
|
||||
return ConcatenatedKey(tenant, account)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user