diff --git a/engine/onstor_it_test.go b/engine/onstor_it_test.go index 0d3c190e1..645043323 100644 --- a/engine/onstor_it_test.go +++ b/engine/onstor_it_test.go @@ -61,6 +61,7 @@ var sTestsOnStorIT = []func(t *testing.T){ testOnStorITCacheReverseAlias, testOnStorITCacheResourceLimit, // ToDo: test cache flush for a prefix + // ToDo: testOnStorITLoadAccountingCache testOnStorITHasData, testOnStorITPushPop, testOnStorITCRUDRatingPlan, @@ -82,6 +83,7 @@ var sTestsOnStorIT = []func(t *testing.T){ testOnStorITCRUDReverseAlias, testOnStorITCRUDResourceLimit, testOnStorITCRUDHistory, + testOnStorITCRUDStructVersion, } func TestOnStorITRedisConnect(t *testing.T) { @@ -933,31 +935,31 @@ func testOnStorITCRUDDestination(t *testing.T) { } func testOnStorITCRUDReverseDestination(t *testing.T) { - dst := &Destination{Id: "CRUDReverseDestination", Prefixes: []string{"+491", "+492", "+493"}} - dst2 := &Destination{Id: "CRUDReverseDestination2", Prefixes: []string{"+491", "+492", "+493"}} + dst := &Destination{Id: "CRUDReverseDestination", Prefixes: []string{"+494", "+495", "+496"}} + dst2 := &Destination{Id: "CRUDReverseDestination2", Prefixes: []string{"+497", "+498", "+499"}} if _, rcvErr := onStor.GetReverseDestination(dst.Id, true, utils.NonTransactional); rcvErr != utils.ErrNotFound { t.Error(rcvErr) } if err := onStor.SetReverseDestination(dst, utils.NonTransactional); err != nil { t.Error(err) } - /* FixMe @Edwardo22 - if rcv, err := onStor.GetReverseDestination(dst.Id, true, utils.NonTransactional); err != nil { - t.Error(err) - } else if !reflect.DeepEqual([]string{dst.Id}, rcv) { - t.Errorf("Expecting: %v, received: %v", dst, rcv) //Expecting: CRUDReverseDestination: +491, +492, +493, received: [] - } - */ + for i, _ := range dst.Prefixes { + if rcv, err := onStor.GetReverseDestination(dst.Prefixes[i], true, utils.NonTransactional); err != nil { + t.Error(err) + } else if !reflect.DeepEqual([]string{dst.Id}, rcv) { + t.Errorf("Expecting: %v, received: %v", []string{dst.Id}, rcv) + } + } if err := onStor.UpdateReverseDestination(dst, dst2, utils.NonTransactional); err != nil { t.Error(err) } - /* FixMe @Edwardo22 - if rcv, err := onStor.GetReverseDestination(dst2.Id, true, utils.NonTransactional); err != nil { - t.Error(err) - } else if !reflect.DeepEqual([]string{dst2.Id}, rcv) { - t.Errorf("Expecting: %v, received: %v", dst2, rcv) //Expecting: CRUDReverseDestination2: +491, +492, +493, received: [] + for i, _ := range dst.Prefixes { + if rcv, err := onStor.GetReverseDestination(dst2.Prefixes[i], true, utils.NonTransactional); err != nil { + t.Error(err) + } else if !reflect.DeepEqual([]string{dst2.Id}, rcv) { + t.Errorf("Expecting: %v, received: %v", []string{dst.Id}, rcv) + } } - */ } func testOnStorITCRUDLCR(t *testing.T) { @@ -1483,3 +1485,37 @@ func testOnStorITCRUDHistory(t *testing.T) { t.Errorf("Expecting: %v, received: %v", ist, rcv[0]) } } + +func testOnStorITCRUDStructVersion(t *testing.T) { + cv := &StructVersion{ + Destinations: "1", + RatingPlans: "1", + RatingProfiles: "1", + Lcrs: "1", + DerivedChargers: "1", + Actions: "1", + ActionPlans: "1", + ActionTriggers: "1", + SharedGroups: "1", + Accounts: "1", + CdrStats: "1", + Users: "1", + Alias: "1", + PubSubs: "1", + LoadHistory: "1", + Cdrs: "1", + SMCosts: "1", + ResourceLimits: "1", + } + if _, rcvErr := onStor.GetStructVersion(); rcvErr != utils.ErrNotFound { + t.Error(rcvErr) + } + if err := onStor.SetStructVersion(CurrentVersion); err != nil { + t.Error(err) + } + if rcv, err := onStor.GetStructVersion(); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(cv, rcv) { + t.Errorf("Expecting: %v, received: %v", cv, rcv) + } +} diff --git a/engine/storage_map.go b/engine/storage_map.go index 0cdbc0685..015a3723c 100644 --- a/engine/storage_map.go +++ b/engine/storage_map.go @@ -1011,7 +1011,6 @@ func (ms *MapStorage) GetAllActionPlans() (ats map[string]*ActionPlan, err error if err != nil { return nil, err } - ats = make(map[string]*ActionPlan, len(keys)) for _, key := range keys { ap, err := ms.GetActionPlan(key[len(utils.ACTION_PLAN_PREFIX):], false, utils.NonTransactional) @@ -1020,17 +1019,79 @@ func (ms *MapStorage) GetAllActionPlans() (ats map[string]*ActionPlan, err error } ats[key[len(utils.ACTION_PLAN_PREFIX):]] = ap } - return } func (ms *MapStorage) GetAccountActionPlans(acntID string, skipCache bool, transactionID string) (apIDs []string, err error) { - return + ms.mu.RLock() + defer ms.mu.RUnlock() + key := utils.AccountActionPlansPrefix + acntID + var values []byte + if !skipCache { + if ap, ok := cache.Get(key); !ok { + return nil, utils.ErrNotFound + } else { + return ap.([]string), nil + } + } + if _, ok := ms.dict[key]; !ok { + cache.Set(key, nil, cacheCommit(transactionID), transactionID) + return nil, utils.ErrNotFound + } + + if err = ms.ms.Unmarshal(values, &apIDs); err != nil { + return nil, err + } + + cache.Set(key, apIDs, cacheCommit(transactionID), transactionID) + return //apIDs, nil } + func (ms *MapStorage) SetAccountActionPlans(acntID string, apIDs []string, overwrite bool) (err error) { + if !overwrite { + oldaPlIDs, err := ms.GetAccountActionPlans(acntID, true, utils.NonTransactional) + if err != nil { + return err + } else { + for _, oldAPid := range oldaPlIDs { + if !utils.IsSliceMember(apIDs, oldAPid) { + apIDs = append(apIDs, oldAPid) + } + } + } + } + + ms.mu.Lock() + defer ms.mu.Unlock() + if _, err = ms.ms.Marshal(&apIDs); err != nil { + return err + } return } + func (ms *MapStorage) RemAccountActionPlans(acntID string, apIDs []string) (err error) { + ms.mu.Lock() + defer ms.mu.Unlock() + key := utils.AccountActionPlansPrefix + acntID + if len(apIDs) == 0 { + delete(ms.dict, key) + return + } + oldaPlIDs, err := ms.GetAccountActionPlans(acntID, true, utils.NonTransactional) + if err != nil { + return err + } + for i := 0; i < len(oldaPlIDs); { + if utils.IsSliceMember(apIDs, oldaPlIDs[i]) { + oldaPlIDs = append(oldaPlIDs[:i], oldaPlIDs[i+1:]...) + continue + } + i++ + } + if len(oldaPlIDs) == 0 { + delete(ms.dict, key) + return + } return }