diff --git a/engine/storage_map.go b/engine/storage_map.go index 1982b2b9a..d1b1c933a 100644 --- a/engine/storage_map.go +++ b/engine/storage_map.go @@ -579,12 +579,14 @@ func (ms *MapStorage) GetAlias(key string, skipCache bool) (al *Alias, err error if err == nil { cache2go.Cache(key, al.Values) for _, v := range al.Values { - var existingKeys []string - rKey := utils.REVERSE_ALIASES_PREFIX + v.Alias + var existingKeys map[string]bool + rKey := utils.REVERSE_ALIASES_PREFIX + v.Alias + al.Group if x, err := cache2go.GetCached(rKey); err == nil { - existingKeys = x.([]string) + existingKeys = x.(map[string]bool) + } else { + existingKeys = make(map[string]bool) } - existingKeys = append(existingKeys, key) + existingKeys[key] = true cache2go.Cache(rKey, existingKeys) } } @@ -595,7 +597,28 @@ func (ms *MapStorage) GetAlias(key string, skipCache bool) (al *Alias, err error } func (ms *MapStorage) RemoveAlias(key string) error { - delete(ms.dict, utils.ALIASES_PREFIX+key) + al := &Alias{} + al.SetId(key) + key = utils.ALIASES_PREFIX + key + aliasValues := make(AliasValues, 0) + if values, ok := ms.dict[key]; ok { + ms.ms.Unmarshal(values, &aliasValues) + } + delete(ms.dict, key) + for _, v := range aliasValues { + var existingKeys map[string]bool + rKey := utils.REVERSE_ALIASES_PREFIX + v.Alias + al.Group + if x, err := cache2go.GetCached(rKey); err == nil { + existingKeys = x.(map[string]bool) + } + if len(existingKeys) == 1 { + cache2go.RemKey(rKey) + } else { + delete(existingKeys, key) + cache2go.Cache(rKey, existingKeys) + } + } + cache2go.RemKey(key) return nil } diff --git a/engine/storage_redis.go b/engine/storage_redis.go index 92e37a2e9..263d3da0e 100644 --- a/engine/storage_redis.go +++ b/engine/storage_redis.go @@ -684,12 +684,14 @@ func (rs *RedisStorage) GetAlias(key string, skipCache bool) (al *Alias, err err cache2go.Cache(key, al.Values) // cache reverse alias for _, v := range al.Values { - var existingKeys []string - rKey := utils.REVERSE_ALIASES_PREFIX + v.Alias + var existingKeys map[string]bool + rKey := utils.REVERSE_ALIASES_PREFIX + v.Alias + al.Group if x, err := cache2go.GetCached(rKey); err == nil { - existingKeys = x.([]string) + existingKeys = x.(map[string]bool) + } else { + existingKeys = make(map[string]bool) } - existingKeys = append(existingKeys, key) + existingKeys[key] = true cache2go.Cache(rKey, existingKeys) } } @@ -698,9 +700,28 @@ func (rs *RedisStorage) GetAlias(key string, skipCache bool) (al *Alias, err err } func (rs *RedisStorage) RemoveAlias(key string) (err error) { + al := &Alias{} + al.SetId(key) key = utils.ALIASES_PREFIX + key + aliasValues := make(AliasValues, 0) + if values, err := rs.db.Get(key); err == nil { + rs.ms.Unmarshal(values, &aliasValues) + } _, err = rs.db.Del(key) if err == nil { + for _, v := range aliasValues { + var existingKeys map[string]bool + rKey := utils.REVERSE_ALIASES_PREFIX + v.Alias + al.Group + if x, err := cache2go.GetCached(rKey); err == nil { + existingKeys = x.(map[string]bool) + } + if len(existingKeys) == 1 { + cache2go.RemKey(rKey) + } else { + delete(existingKeys, key) + cache2go.Cache(rKey, existingKeys) + } + } cache2go.RemKey(key) } return diff --git a/engine/storage_test.go b/engine/storage_test.go index 3bc437a1b..8ed787a31 100644 --- a/engine/storage_test.go +++ b/engine/storage_test.go @@ -22,6 +22,7 @@ import ( "testing" "time" + "github.com/cgrates/cgrates/cache2go" "github.com/cgrates/cgrates/utils" ) @@ -97,7 +98,7 @@ func TestStorageDestinationContainsPrefixNotExisting(t *testing.T) { } } -func TestCacheRefresh(t *testing.T) { +func TestStorageCacheRefresh(t *testing.T) { ratingStorage.SetDestination(&Destination{"T11", []string{"0"}}) ratingStorage.GetDestination("T11") ratingStorage.SetDestination(&Destination{"T11", []string{"1"}}) @@ -110,6 +111,129 @@ func TestCacheRefresh(t *testing.T) { } } +func TestStorageGetAliases(t *testing.T) { + ala := &Alias{ + Direction: "*out", + Tenant: "vdf", + Category: "0", + Account: "b1", + Subject: "b1", + Group: utils.ALIAS_GROUP_RP, + Values: AliasValues{ + &AliasValue{ + Alias: "aaa", + Weight: 10, + DestinationId: utils.ANY, + }, + }, + } + alb := &Alias{ + Direction: "*out", + Tenant: "vdf", + Category: "0", + Account: "b1", + Subject: "b1", + Group: utils.ALIAS_GROUP_ACC, + Values: AliasValues{ + &AliasValue{ + Alias: "aaa", + Weight: 10, + DestinationId: utils.ANY, + }, + }, + } + accountingStorage.SetAlias(ala) + accountingStorage.SetAlias(alb) + foundAlias, err := accountingStorage.GetAlias(ala.GetId(), true) + if err != nil || len(foundAlias.Values) != 1 { + t.Errorf("Alias get error %+v, %v: ", foundAlias, err) + } + foundAlias, err = accountingStorage.GetAlias(alb.GetId(), true) + if err != nil || len(foundAlias.Values) != 1 { + t.Errorf("Alias get error %+v, %v: ", foundAlias, err) + } + foundAlias, err = accountingStorage.GetAlias(ala.GetId(), false) + if err != nil || len(foundAlias.Values) != 1 { + t.Errorf("Alias get error %+v, %v: ", foundAlias, err) + } + foundAlias, err = accountingStorage.GetAlias(alb.GetId(), false) + if err != nil || len(foundAlias.Values) != 1 { + t.Errorf("Alias get error %+v, %v: ", foundAlias, err) + } +} + +func TestStorageCacheGetReverseAliases(t *testing.T) { + ala := &Alias{ + Direction: "*out", + Tenant: "vdf", + Category: "0", + Account: "b1", + Subject: "b1", + Group: utils.ALIAS_GROUP_RP, + } + alb := &Alias{ + Direction: "*out", + Tenant: "vdf", + Category: "0", + Account: "b1", + Subject: "b1", + Group: utils.ALIAS_GROUP_ACC, + } + if x, err := cache2go.GetCached(utils.REVERSE_ALIASES_PREFIX + "aaa" + utils.ALIAS_GROUP_RP); err == nil { + aliasKeys := x.(map[string]bool) + _, found := aliasKeys[utils.ALIASES_PREFIX+ala.GetId()] + if !found { + t.Error("Error getting reverse alias: ", aliasKeys) + } + } else { + t.Error("Error getting reverse alias: ", err) + } + if x, err := cache2go.GetCached(utils.REVERSE_ALIASES_PREFIX + "aaa" + utils.ALIAS_GROUP_ACC); err == nil { + aliasKeys := x.(map[string]bool) + _, found := aliasKeys[utils.ALIASES_PREFIX+alb.GetId()] + if !found { + t.Error("Error getting reverse alias: ", aliasKeys) + } + } else { + t.Error("Error getting reverse alias: ", err) + } +} + +func TestStorageCacheRemoveCachedAliases(t *testing.T) { + ala := &Alias{ + Direction: "*out", + Tenant: "vdf", + Category: "0", + Account: "b1", + Subject: "b1", + Group: utils.ALIAS_GROUP_RP, + } + alb := &Alias{ + Direction: "*out", + Tenant: "vdf", + Category: "0", + Account: "b1", + Subject: "b1", + Group: utils.ALIAS_GROUP_ACC, + } + accountingStorage.RemoveAlias(ala.GetId()) + accountingStorage.RemoveAlias(alb.GetId()) + + if _, err := cache2go.GetCached(utils.ALIASES_PREFIX + ala.GetId()); err == nil { + t.Error("Error removing cached alias: ", err) + } + if _, err := cache2go.GetCached(utils.ALIASES_PREFIX + alb.GetId()); err == nil { + t.Error("Error removing cached alias: ", err) + } + + if _, err := cache2go.GetCached(utils.REVERSE_ALIASES_PREFIX + "aaa" + utils.ALIAS_GROUP_RP); err == nil { + t.Error("Error removing cached reverse alias: ", err) + } + if _, err := cache2go.GetCached(utils.REVERSE_ALIASES_PREFIX + "aaa" + utils.ALIAS_GROUP_ACC); err == nil { + t.Error("Error removing cached reverse alias: ", err) + } +} + // Install fails to detect them and starting server will panic, these tests will fix this func TestStoreInterfaces(t *testing.T) { rds := new(RedisStorage)