diff --git a/engine/onstor_it_test.go b/engine/onstor_it_test.go index 32a032509..8b312822d 100644 --- a/engine/onstor_it_test.go +++ b/engine/onstor_it_test.go @@ -48,6 +48,7 @@ var sTestsOnStorIT = []func(t *testing.T){ testOnStorITCacheReverseDestinations, testOnStorITCacheRatingPlan, testOnStorITCacheRatingProfile, + testOnStorITCacheActions, } func TestOnStorITRedisConnect(t *testing.T) { @@ -314,12 +315,13 @@ func testOnStorITCacheRatingPlan(t *testing.T) { func testOnStorITCacheRatingProfile(t *testing.T) { rpf := &RatingProfile{ Id: "*out:test:0:trp", - RatingPlanActivations: RatingPlanActivations{&RatingPlanActivation{ - ActivationTime: time.Date(2013, 10, 1, 0, 0, 0, 0, time.UTC), - RatingPlanId: "TDRT", - FallbackKeys: []string{"*out:test:0:danb", "*out:test:0:rif"}, - CdrStatQueueIds: []string{}, - }}, + RatingPlanActivations: RatingPlanActivations{ + &RatingPlanActivation{ + ActivationTime: time.Date(2013, 10, 1, 0, 0, 0, 0, time.UTC).Local(), + RatingPlanId: "TDRT", + FallbackKeys: []string{"*out:test:0:danb", "*out:test:0:rif"}, + CdrStatQueueIds: []string{}, + }}, } if err := onStor.SetRatingProfile(rpf, utils.NonTransactional); err != nil { t.Error(err) @@ -332,7 +334,62 @@ func testOnStorITCacheRatingProfile(t *testing.T) { } if itm, hasIt := cache.Get(utils.RATING_PROFILE_PREFIX + rpf.Id); !hasIt { t.Error("Did not cache") - } else if rcvRp := itm.(*RatingProfile); !reflect.DeepEqual(rpf.Id, rcvRp.Id) { // fixme - t.Error("Wrong item in the cache", rcvRp) + } else if rcvRp := itm.(*RatingProfile); !reflect.DeepEqual(rpf, rcvRp) { + t.Errorf("Expecting: %+v, received: %+v", rpf, rcvRp) + } +} + +func testOnStorITCacheActions(t *testing.T) { + acts := Actions{ + &Action{ + Id: "MINI", + ActionType: TOPUP_RESET, + ExpirationString: UNLIMITED, + Weight: 10, + Balance: &BalanceFilter{ + Type: utils.StringPointer(utils.MONETARY), + Uuid: utils.StringPointer(utils.GenUUID()), + Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)), + Value: &utils.ValueFormula{Static: 10, + Params: make(map[string]interface{})}, + Weight: utils.Float64Pointer(10), + Disabled: utils.BoolPointer(false), + Timings: make([]*RITiming, 0), + Blocker: utils.BoolPointer(false), + }, + }, + &Action{ + Id: "MINI", + ActionType: TOPUP, + ExpirationString: UNLIMITED, + Weight: 10, + Balance: &BalanceFilter{ + Type: utils.StringPointer(utils.VOICE), + Uuid: utils.StringPointer(utils.GenUUID()), + Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)), + Value: &utils.ValueFormula{Static: 100, + Params: make(map[string]interface{})}, + Weight: utils.Float64Pointer(10), + RatingSubject: utils.StringPointer("test"), + DestinationIDs: utils.StringMapPointer(utils.NewStringMap("NAT")), + Disabled: utils.BoolPointer(false), + Timings: make([]*RITiming, 0), + Blocker: utils.BoolPointer(false), + }, + }, + } + if err := onStor.SetActions(acts[0].Id, acts, utils.NonTransactional); err != nil { + t.Error(err) + } + if _, hasIt := cache.Get(utils.ACTION_PREFIX + acts[0].Id); hasIt { + t.Error("Already in cache") + } + if err := onStor.CacheDataFromDB(utils.ACTION_PREFIX, []string{acts[0].Id}, false); err != nil { + t.Error(err) + } + if itm, hasIt := cache.Get(utils.ACTION_PREFIX + acts[0].Id); !hasIt { + t.Error("Did not cache") + } else if rcv := itm.(Actions); !reflect.DeepEqual(acts, rcv) { + t.Errorf("Expecting: %+v, received: %+v", acts, rcv) } } diff --git a/engine/storage_mongo_datadb.go b/engine/storage_mongo_datadb.go index f19f1a159..a0bd70dcf 100644 --- a/engine/storage_mongo_datadb.go +++ b/engine/storage_mongo_datadb.go @@ -476,7 +476,8 @@ func (ms *MongoStorage) CacheDataFromDB(prfx string, ids []string, mustBeCached if !utils.IsSliceMember([]string{utils.DESTINATION_PREFIX, utils.REVERSE_DESTINATION_PREFIX, utils.RATING_PLAN_PREFIX, - utils.RATING_PROFILE_PREFIX}, prfx) { + utils.RATING_PROFILE_PREFIX, + utils.ACTION_PREFIX}, prfx) { return utils.NewCGRError(utils.REDIS, utils.MandatoryIEMissingCaps, utils.UnsupportedCachePrefix, @@ -484,7 +485,7 @@ func (ms *MongoStorage) CacheDataFromDB(prfx string, ids []string, mustBeCached } if ids == nil { if ids, err = ms.GetKeysForPrefix(prfx); err != nil { - return utils.NewCGRError(utils.REDIS, + return utils.NewCGRError(utils.MONGO, utils.ServerErrorCaps, err.Error(), fmt.Sprintf("redis error <%s> querying keys for prefix: <%s>", prfx)) @@ -505,9 +506,11 @@ func (ms *MongoStorage) CacheDataFromDB(prfx string, ids []string, mustBeCached _, err = ms.GetRatingPlan(dataID, false, utils.NonTransactional) case utils.RATING_PROFILE_PREFIX: _, err = ms.GetRatingProfile(dataID, false, utils.NonTransactional) + case utils.ACTION_PREFIX: + _, err = ms.GetActions(dataID, false, utils.NonTransactional) } if err != nil { - return utils.NewCGRError(utils.REDIS, + return utils.NewCGRError(utils.MONGO, utils.ServerErrorCaps, err.Error(), fmt.Sprintf("error <%s> querying mongo for category: <%s>, dataID: <%s>", prfx, dataID)) @@ -671,7 +674,8 @@ func (ms *MongoStorage) SetRatingPlan(rp *RatingPlan, transactionID string) erro var response int historyScribe.Call("HistoryV1.Record", rp.GetHistoryRecord(), &response) } - //cache.Set(utils.RATING_PLAN_PREFIX+rp.Id, rp, cacheCommit(transactionID), transactionID) + cache.RemKey(utils.RATING_PLAN_PREFIX+rp.Id, + cacheCommit(transactionID), transactionID) return err } @@ -709,8 +713,9 @@ func (ms *MongoStorage) SetRatingProfile(rp *RatingProfile, transactionID string var response int historyScribe.Call("HistoryV1.Record", rp.GetHistoryRecord(false), &response) } - cache.RemKey(utils.RATING_PROFILE_PREFIX+rp.Id, cacheCommit(transactionID), transactionID) - return err + cache.RemKey(utils.RATING_PROFILE_PREFIX+rp.Id, + cacheCommit(transactionID), transactionID) + return } func (ms *MongoStorage) RemoveRatingProfile(key, transactionID string) error { @@ -960,8 +965,9 @@ func (ms *MongoStorage) UpdateReverseDestination(oldDest, newDest *Destination, } func (ms *MongoStorage) GetActions(key string, skipCache bool, transactionID string) (as Actions, err error) { + cacheKey := utils.ACTION_PREFIX + key if !skipCache { - if x, err := cache.GetCloned(utils.ACTION_PREFIX + key); err != nil { + if x, err := cache.GetCloned(cacheKey); err != nil { if err.Error() != utils.ItemNotFound { return nil, err } @@ -977,10 +983,14 @@ func (ms *MongoStorage) GetActions(key string, skipCache bool, transactionID str } session, col := ms.conn(colAct) defer session.Close() - err = col.Find(bson.M{"key": key}).One(&result) - if err == nil { - as = result.Value + if err = col.Find(bson.M{"key": key}).One(&result); err != nil { + if err == mgo.ErrNotFound { + cache.Set(cacheKey, nil, cacheCommit(transactionID), transactionID) + err = utils.ErrNotFound + } + return } + as = result.Value cache.Set(utils.ACTION_PREFIX+key, as, cacheCommit(transactionID), transactionID) return } diff --git a/engine/storage_redis.go b/engine/storage_redis.go index 0bc615bcc..ec3e4fc3e 100644 --- a/engine/storage_redis.go +++ b/engine/storage_redis.go @@ -276,7 +276,8 @@ func (rs *RedisStorage) CacheDataFromDB(prfx string, ids []string, mustBeCached if !utils.IsSliceMember([]string{utils.DESTINATION_PREFIX, utils.REVERSE_DESTINATION_PREFIX, utils.RATING_PLAN_PREFIX, - utils.RATING_PROFILE_PREFIX}, prfx) { + utils.RATING_PROFILE_PREFIX, + utils.ACTION_PREFIX}, prfx) { return utils.NewCGRError(utils.REDIS, utils.MandatoryIEMissingCaps, utils.UnsupportedCachePrefix, @@ -305,6 +306,8 @@ func (rs *RedisStorage) CacheDataFromDB(prfx string, ids []string, mustBeCached _, err = rs.GetRatingPlan(dataID, false, utils.NonTransactional) case utils.RATING_PROFILE_PREFIX: _, err = rs.GetRatingProfile(dataID, false, utils.NonTransactional) + case utils.ACTION_PREFIX: + _, err = rs.GetActions(dataID, false, utils.NonTransactional) } if err != nil { return utils.NewCGRError(utils.REDIS, @@ -657,8 +660,15 @@ func (rs *RedisStorage) GetActions(key string, skipCache bool, transactionID str } } var values []byte - if values, err = rs.Cmd("GET", key).Bytes(); err == nil { - err = rs.ms.Unmarshal(values, &as) + if values, err = rs.Cmd("GET", key).Bytes(); err != nil { + if err.Error() == "wrong type" { // did not find the destination + cache.Set(key, nil, cacheCommit(transactionID), transactionID) + err = utils.ErrNotFound + } + return + } + if err = rs.ms.Unmarshal(values, &as); err != nil { + return } cache.Set(key, as, cacheCommit(transactionID), transactionID) return