diff --git a/engine/action.go b/engine/action.go index fcabe7f4b..e4d83ba4f 100644 --- a/engine/action.go +++ b/engine/action.go @@ -761,5 +761,15 @@ func (apl Actions) Clone() (interface{}, error) { if err := utils.Clone(apl, &cln); err != nil { return nil, err } + for i, act := range apl { // Fix issues with gob cloning nil pointer towards false value + if act.Balance != nil { + if act.Balance.Disabled != nil && !*act.Balance.Disabled { + cln[i].Balance.Disabled = utils.BoolPointer(*act.Balance.Disabled) + } + if act.Balance.Blocker != nil && !*act.Balance.Blocker { + cln[i].Balance.Blocker = utils.BoolPointer(*act.Balance.Blocker) + } + } + } return cln, nil } diff --git a/engine/actions_test.go b/engine/actions_test.go index 0c0e46433..118cda4a2 100644 --- a/engine/actions_test.go +++ b/engine/actions_test.go @@ -2387,14 +2387,23 @@ func TestCacheGetClonedActions(t *testing.T) { Weight: float64(30), }, &Action{ - Id: "RECUR_FOR_V3HSILLMILLD5G", - ActionType: DEBIT, + Id: "REACT_FOR_V3HSILLMILL", + ActionType: SET_BALANCE, Balance: &BalanceFilter{ - ID: utils.StringPointer("*default"), - Value: &utils.ValueFormula{Static: 2}, - Type: utils.StringPointer(utils.MONETARY), + ID: utils.StringPointer("for_v3hsillmill_sms_ill"), + Type: utils.StringPointer(utils.SMS), + Value: &utils.ValueFormula{Static: 20000}, + DestinationIDs: &utils.StringMap{ + "FRANCE_NATIONAL": true, + "FRANCE_NATIONAL_FREE": false, + "ZONE1": false}, + Categories: &utils.StringMap{ + "sms_eurotarif": true, + "sms_france": true}, + Disabled: utils.BoolPointer(false), + Blocker: utils.BoolPointer(false), }, - Weight: float64(20), + Weight: float64(10), }, } cache.Set("MYTEST", actions, true, "") @@ -2404,7 +2413,7 @@ func TestCacheGetClonedActions(t *testing.T) { } aCloned := clned.(Actions) if !reflect.DeepEqual(actions, aCloned) { - t.Errorf("Expecting: %+v, received: %+v", actions, aCloned) + t.Errorf("Expecting: %+v, received: %+v", actions[1].Balance, aCloned[1].Balance) } } diff --git a/engine/storage_interface.go b/engine/storage_interface.go index 482b76072..4aab3a610 100644 --- a/engine/storage_interface.go +++ b/engine/storage_interface.go @@ -36,6 +36,7 @@ type Storage interface { GetVersions(itm string) (vrs Versions, err error) SetVersions(vrs Versions) (err error) RemoveVersions(vrs Versions) (err error) + SelectDatabase(dbName string) (err error) } // Interface for storage providers. @@ -77,8 +78,7 @@ type RatingStorage interface { RemAccountActionPlans(acntID string, aPlIDs []string) (err error) PushTask(*Task) error PopTask() (*Task, error) - // CacheDataFromDB loads data to cache, prefix represents the cache prefix, IDs should be nil if all available data should be loaded - CacheDataFromDB(prefix string, IDs []string, mustBeCached bool) error // ToDo: Move this to dataManager + CacheDataFromDB(prefix string, IDs []string, mustBeCached bool) error } type AccountingStorage interface { @@ -111,7 +111,6 @@ type AccountingStorage interface { GetReqFilterIndexes(dbKey string) (indexes map[string]map[string]utils.StringMap, err error) SetReqFilterIndexes(dbKey string, indexes map[string]map[string]utils.StringMap) (err error) MatchReqFilterIndex(dbKey, fieldValKey string) (itemIDs utils.StringMap, err error) - // CacheDataFromDB loads data to cache, prefix represents the cache prefix, IDs should be nil if all available data should be loaded CacheDataFromDB(prefix string, IDs []string, mustBeCached bool) error } diff --git a/engine/storage_map.go b/engine/storage_map.go index f4441be7b..015a3723c 100644 --- a/engine/storage_map.go +++ b/engine/storage_map.go @@ -86,6 +86,10 @@ func (ms *MapStorage) Flush(ignore string) error { return nil } +func (ms *MapStorage) SelectDatabase(dbName string) (err error) { + return +} + func (ms *MapStorage) RebuildReverseForPrefix(prefix string) error { // FIXME: should do transaction keys, err := ms.GetKeysForPrefix(prefix) diff --git a/engine/storage_mongo_datadb.go b/engine/storage_mongo_datadb.go index e65f58799..8e54ad5be 100644 --- a/engine/storage_mongo_datadb.go +++ b/engine/storage_mongo_datadb.go @@ -322,6 +322,11 @@ func (ms *MongoStorage) Flush(ignore string) (err error) { return dbSession.DB(ms.db).DropDatabase() } +func (ms *MongoStorage) SelectDatabase(dbName string) (err error) { + ms.db = dbName + return +} + func (ms *MongoStorage) RebuildReverseForPrefix(prefix string) (err error) { if !utils.IsSliceMember([]string{utils.REVERSE_DESTINATION_PREFIX, utils.REVERSE_ALIASES_PREFIX, utils.AccountActionPlansPrefix}, prefix) { return utils.ErrInvalidKey diff --git a/engine/storage_redis.go b/engine/storage_redis.go index 9ee96ec88..2dd9188cc 100644 --- a/engine/storage_redis.go +++ b/engine/storage_redis.go @@ -109,6 +109,10 @@ func (rs *RedisStorage) Flush(ignore string) error { return rs.Cmd("FLUSHDB").Err } +func (rs *RedisStorage) SelectDatabase(dbName string) (err error) { + return rs.Cmd("SELECT", dbName).Err +} + func (rs *RedisStorage) LoadRatingCache(dstIDs, rvDstIDs, rplIDs, rpfIDs, actIDs, aplIDs, aaPlIDs, atrgIDs, sgIDs, lcrIDs, dcIDs []string) (err error) { for key, ids := range map[string][]string{ utils.DESTINATION_PREFIX: dstIDs, diff --git a/engine/storage_sql.go b/engine/storage_sql.go index a6a3fb6bb..73972156f 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -53,6 +53,10 @@ func (self *SQLStorage) Flush(scriptsPath string) (err error) { return nil } +func (rs *SQLStorage) SelectDatabase(dbName string) (err error) { + return +} + func (self *SQLStorage) GetKeysForPrefix(prefix string) ([]string, error) { return nil, utils.ErrNotImplemented } diff --git a/engine/users.go b/engine/users.go index 67aa50951..0950dc933 100644 --- a/engine/users.go +++ b/engine/users.go @@ -112,9 +112,8 @@ func newUserMap(accountingDb AccountingStorage, indexes []string) *UserMap { } } -func (um *UserMap) ReloadUsers(in string, reply *string) error { +func (um *UserMap) ReloadUsers(in string, reply *string) (err error) { um.mu.Lock() - // backup old data oldTable := um.table oldIndex := um.index @@ -124,34 +123,33 @@ func (um *UserMap) ReloadUsers(in string, reply *string) error { um.properties = make(map[string]*prop) // load from db - if ups, err := um.accountingDb.GetUsers(); err == nil { - for _, up := range ups { - um.table[up.GetId()] = up.Profile - um.properties[up.GetId()] = &prop{weight: up.Weight, masked: up.Masked} - } - } else { - // restore old data before return + ups, err := um.accountingDb.GetUsers() + if err != nil { // restore old data before return um.table = oldTable um.index = oldIndex um.properties = oldProperties - - *reply = err.Error() + um.mu.Unlock() return err } + for _, up := range ups { + um.table[up.GetId()] = up.Profile + um.properties[up.GetId()] = &prop{weight: up.Weight, masked: up.Masked} + } um.mu.Unlock() if len(um.indexKeys) != 0 { var s string if err := um.AddIndex(um.indexKeys, &s); err != nil { utils.Logger.Err(fmt.Sprintf("Error adding %v indexes to user profile service: %v", um.indexKeys, err)) + um.mu.Lock() um.table = oldTable um.index = oldIndex um.properties = oldProperties - - *reply = err.Error() + um.mu.Unlock() return err } } + *reply = utils.OK return nil } @@ -320,15 +318,20 @@ func (um *UserMap) GetUsers(up *UserProfile, results *UserProfiles) error { return nil } +// AddIndex is a method to dynamically add indexes to already existing ones func (um *UserMap) AddIndex(indexes []string, reply *string) error { um.mu.Lock() defer um.mu.Unlock() - um.indexKeys = append(um.indexKeys, indexes...) for key, values := range um.table { up := &UserProfile{Profile: values} up.SetId(key) um.addIndex(up, indexes) } + for _, idxKey := range indexes { + if !utils.IsSliceMember(um.indexKeys, idxKey) { + um.indexKeys = append(um.indexKeys, idxKey) + } + } *reply = utils.OK return nil }