diff --git a/apier/v1/accounts.go b/apier/v1/accounts.go index 470d82a5c..5f33c27fe 100644 --- a/apier/v1/accounts.go +++ b/apier/v1/accounts.go @@ -155,29 +155,10 @@ func (self *ApierV1) SetAccount(attr utils.AttrSetAccount, reply *string) error } } if len(attr.ActionPlanId) != 0 { - _, err := engine.Guardian.Guard(func() (interface{}, error) { - // clean previous action plans - actionPlansMap, err := self.RatingDb.GetAllActionPlans() - if err != nil { - if err == utils.ErrNotFound { // if no action plans just continue - return 0, nil - } - return 0, err - } - for actionPlanID, ap := range actionPlansMap { - if actionPlanID == attr.ActionPlanId { - // don't remove it if it's the current one - continue - } - if _, exists := ap.AccountIDs[accID]; exists { - delete(ap.AccountIDs, accID) - // clean from cache - cache2go.RemKey(utils.ACTION_PLAN_PREFIX + actionPlanID) - } - } + _, err := engine.Guardian.Guard(func() (interface{}, error) { var ap *engine.ActionPlan - ap, err = self.RatingDb.GetActionPlan(attr.ActionPlanId, false) + ap, err := self.RatingDb.GetActionPlan(attr.ActionPlanId, false) if err != nil { return 0, err } @@ -204,6 +185,26 @@ func (self *ApierV1) SetAccount(attr utils.AttrSetAccount, reply *string) error return 0, err } } + // clean previous action plans + actionPlansMap, err := self.RatingDb.GetAllActionPlans() + if err != nil { + if err == utils.ErrNotFound { // if no action plans just continue + return 0, nil + } + return 0, err + } + for actionPlanID, ap := range actionPlansMap { + if actionPlanID[len(utils.ACTION_PLAN_PREFIX):] == attr.ActionPlanId { + // don't remove it if it's the current one + continue + } + if _, exists := ap.AccountIDs[accID]; exists { + delete(ap.AccountIDs, accID) + // clean from cache + cache2go.RemKey(utils.ACTION_PLAN_PREFIX + actionPlanID) + } + } + return 0, nil }, 0, utils.ACTION_PLAN_PREFIX) if err != nil { diff --git a/apier/v1/aliases.go b/apier/v1/aliases.go index 7800b6d72..4f8c9b193 100644 --- a/apier/v1/aliases.go +++ b/apier/v1/aliases.go @@ -20,6 +20,7 @@ package v1 import ( "errors" + "log" "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" @@ -74,6 +75,7 @@ func (self *ApierV1) RemRatingSubjectAliases(tenantRatingSubject engine.TenantRa return utils.NewErrServerError(err) } var ignr string + log.Print("RVAL: ", reverseAliases) for _, aliass := range reverseAliases { for _, alias := range aliass { if alias.Tenant != tenantRatingSubject.Tenant { diff --git a/apier/v1/apier.go b/apier/v1/apier.go index 2107d9346..b31888976 100644 --- a/apier/v1/apier.go +++ b/apier/v1/apier.go @@ -436,7 +436,8 @@ func (self *ApierV1) SetRatingProfile(attrs AttrSetRatingProfile, reply *string) if err := self.RatingDb.SetRatingProfile(rpfl); err != nil { return utils.NewErrServerError(err) } - + cache2go.RemPrefixKey(utils.RATING_PLAN_PREFIX) + self.RatingDb.PreloadCacheForPrefix(utils.RATING_PLAN_PREFIX) *reply = OK return nil } diff --git a/apier/v1/apier_local_test.go b/apier/v1/apier_local_test.go index 44a3a2b5a..e44a0e8e9 100644 --- a/apier/v1/apier_local_test.go +++ b/apier/v1/apier_local_test.go @@ -110,7 +110,7 @@ func TestApierInitStorDb(t *testing.T) { } // Finds cgr-engine executable and starts it with default configuration -/*func TestApierStartEngine(t *testing.T) { +func TestApierStartEngine(t *testing.T) { if !*testLocal { return } @@ -126,7 +126,7 @@ func TestApierInitStorDb(t *testing.T) { t.Fatal("Cannot start cgr-engine: ", err.Error()) } time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time to rater to fire up -}*/ +} // Connect rpc client to rater func TestApierRpcConn(t *testing.T) { @@ -828,7 +828,7 @@ func TestApierGetCacheStats(t *testing.T) { var rcvStats *utils.CacheStats var args utils.AttrCacheStats err := rater.Call("ApierV1.GetCacheStats", args, &rcvStats) - expectedStats := &utils.CacheStats{Destinations: 3, RatingPlans: 1, RatingProfiles: 2, Actions: 2, ActionPlans: 1, LastLoadID: "ReloadCacheAPI", LastRatingLoadID: rcvStats.LastRatingLoadID, LastAccountingLoadID: rcvStats.LastAccountingLoadID, LastLoadTime: rcvStats.LastLoadTime} + expectedStats := &utils.CacheStats{Destinations: 0, RatingPlans: 1, RatingProfiles: 0, Actions: 0, ActionPlans: 0, LastLoadID: utils.NOT_AVAILABLE, LastRatingLoadID: utils.NOT_AVAILABLE, LastAccountingLoadID: utils.NOT_AVAILABLE, LastLoadTime: utils.NOT_AVAILABLE} if err != nil { t.Error("Got error on ApierV1.GetCacheStats: ", err.Error()) } else if !reflect.DeepEqual(expectedStats, rcvStats) { @@ -1142,7 +1142,7 @@ func TestApierGetAccountActionPlan(t *testing.T) { if err := rater.Call("ApierV1.GetAccountActionPlan", req, &reply); err != nil { t.Error("Got error on ApierV1.GetAccountActionPlan: ", err.Error()) } else if len(reply) != 1 { - t.Error("Unexpected action plan received") + t.Error("Unexpected action plan received: ", utils.ToJSON(reply)) } else { if reply[0].ActionPlanId != "ATMS_1" { t.Errorf("Unexpected ActionoveAccountPlanId received") @@ -1296,11 +1296,11 @@ func TestApierResetDataAfterLoadFromFolder(t *testing.T) { if err := rater.Call("ApierV1.GetCacheStats", args, &rcvStats); err != nil { t.Error("Got error on ApierV1.GetCacheStats: ", err.Error()) } else { - if rcvStats.Destinations != 5 || + if rcvStats.Destinations != 0 || rcvStats.RatingPlans != 5 || - rcvStats.RatingProfiles != 5 || - rcvStats.Actions != 13 || - rcvStats.DerivedChargers != 3 { + rcvStats.RatingProfiles != 0 || + rcvStats.Actions != 0 || + rcvStats.DerivedChargers != 0 { t.Errorf("Calling ApierV1.GetCacheStats received: %+v", rcvStats) } } diff --git a/apier/v1/smgenericv1_it_test.go b/apier/v1/smgenericv1_it_test.go index 5ccc39b6e..eebc2947d 100644 --- a/apier/v1/smgenericv1_it_test.go +++ b/apier/v1/smgenericv1_it_test.go @@ -103,8 +103,8 @@ func TestSMGV1LoadTariffPlanFromFolder(t *testing.T) { attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "tutorial")} if err := smgV1Rpc.Call("ApierV2.LoadTariffPlanFromFolder", attrs, &smgV1LoadInst); err != nil { t.Error(err) - } else if smgV1LoadInst.RatingLoadID == "" && smgV1LoadInst.AccountingLoadID == "" { - t.Error("Empty loadId received, loadInstance: ", smgV1LoadInst) + } else if smgV1LoadInst.RatingLoadID != "" && smgV1LoadInst.AccountingLoadID != "" { + t.Error("Non Empty loadId received, loadInstance: ", smgV1LoadInst) } time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for scheduler to execute topups } @@ -116,9 +116,9 @@ func TestSMGV1CacheStats(t *testing.T) { } var rcvStats *utils.CacheStats - expectedStats := &utils.CacheStats{Destinations: 7, RatingPlans: 4, RatingProfiles: 9, Actions: 8, ActionPlans: 4, SharedGroups: 1, Aliases: 1, ResourceLimits: 0, - DerivedChargers: 1, LcrProfiles: 5, CdrStats: 6, Users: 3, - LastLoadID: smgV1LoadInst.LoadID, LastRatingLoadID: smgV1LoadInst.RatingLoadID, LastAccountingLoadID: smgV1LoadInst.AccountingLoadID, LastLoadTime: smgV1LoadInst.LoadTime.Format(time.RFC3339)} + expectedStats := &utils.CacheStats{Destinations: 0, RatingPlans: 4, RatingProfiles: 0, Actions: 7, ActionPlans: 4, SharedGroups: 0, Aliases: 0, ResourceLimits: 0, + DerivedChargers: 0, LcrProfiles: 0, CdrStats: 6, Users: 3, + LastLoadID: utils.NOT_AVAILABLE, LastRatingLoadID: utils.NOT_AVAILABLE, LastAccountingLoadID: utils.NOT_AVAILABLE, LastLoadTime: utils.NOT_AVAILABLE} var args utils.AttrCacheStats if err := smgV1Rpc.Call("ApierV2.GetCacheStats", args, &rcvStats); err != nil { t.Error("Got error on ApierV2.GetCacheStats: ", err.Error()) diff --git a/engine/calldesc.go b/engine/calldesc.go index 91c36f59b..063c0e946 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -526,6 +526,7 @@ func (cd *CallDescriptor) getCost() (*CallCost, error) { cd.TOR = utils.VOICE } err := cd.LoadRatingPlans() + //log.Print("ERR: ", err) //log.Print("RI: ", utils.ToJSON(cd.RatingInfos)) if err != nil { //utils.Logger.Err(fmt.Sprintf("error getting cost for key <%s>: %s", cd.GetKey(cd.Subject), err.Error())) diff --git a/engine/ratingprofile.go b/engine/ratingprofile.go index 394636b98..41091567b 100644 --- a/engine/ratingprofile.go +++ b/engine/ratingprofile.go @@ -163,7 +163,6 @@ func (rpf *RatingProfile) GetRatingPlansForPrefix(cd *CallDescriptor) (err error prefix := "" destinationId := "" var rps RateIntervalList - //log.Printf("RPA: %+v", rpa) if cd.Destination == utils.ANY || cd.Destination == "" { cd.Destination = utils.ANY if _, ok := rpl.DestinationRates[utils.ANY]; ok { diff --git a/engine/storage_map.go b/engine/storage_map.go index a5e4b0971..bae6cd484 100644 --- a/engine/storage_map.go +++ b/engine/storage_map.go @@ -924,14 +924,18 @@ func (ms *MapStorage) SetActionPlan(key string, ats *ActionPlan, overwrite bool) } func (ms *MapStorage) GetAllActionPlans() (ats map[string]*ActionPlan, err error) { - ms.mu.RLock() - defer ms.mu.RUnlock() - apls := cache2go.GetAllEntries(utils.ACTION_PLAN_PREFIX) + keys, err := ms.GetKeysForPrefix(utils.ACTION_PLAN_PREFIX) + if err != nil { + return nil, err + } - ats = make(map[string]*ActionPlan, len(apls)) - for key, value := range apls { - apl := value.(*ActionPlan) - ats[key] = apl + ats = make(map[string]*ActionPlan, len(keys)) + for _, key := range keys { + ap, err := ms.GetActionPlan(key[len(utils.ACTION_PLAN_PREFIX):], false) + if err != nil { + return nil, err + } + ats[key] = ap } return diff --git a/engine/storage_mongo_datadb.go b/engine/storage_mongo_datadb.go index fed5bd8ff..862ae85ca 100644 --- a/engine/storage_mongo_datadb.go +++ b/engine/storage_mongo_datadb.go @@ -34,7 +34,7 @@ import ( const ( colDst = "destinations" - colRst = "reverse_destinations" + colRds = "reverse_destinations" colAct = "actions" colApl = "action_plans" colTsk = "tasks" @@ -135,7 +135,7 @@ func NewMongoStorage(host, port, db, user, pass string, cdrsIndexes []string, ca Background: false, // Build index in background and return immediately Sparse: false, // Only index documents containing the Key fields } - collections := []string{colAct, colApl, colAtr, colDcs, colAls, colRls, colUsr, colLcr, colLht, colRpl, colDst, colRst} + collections := []string{colAct, colApl, colAtr, colDcs, colAls, colRls, colUsr, colLcr, colLht, colRpl, colDst, colRds} for _, col := range collections { if err = ndb.C(col).EnsureIndex(index); err != nil { return nil, err @@ -293,7 +293,7 @@ func NewMongoStorage(host, port, db, user, pass string, cdrsIndexes []string, ca func (ms *MongoStorage) getColNameForPrefix(prefix string) (name string, ok bool) { colMap := map[string]string{ utils.DESTINATION_PREFIX: colDst, - utils.REVERSE_DESTINATION_PREFIX: colRst, + utils.REVERSE_DESTINATION_PREFIX: colRds, utils.ACTION_PREFIX: colAct, utils.ACTION_PLAN_PREFIX: colApl, utils.TASKS_KEY: colTsk, @@ -740,7 +740,7 @@ func (ms *MongoStorage) GetReverseDestination(prefix string, skipCache bool) (id Key string Value []string } - session, col := ms.conn(colRst) + session, col := ms.conn(colRds) defer session.Close() err = col.Find(bson.M{"key": prefix}).One(&result) if err == nil { @@ -751,7 +751,7 @@ func (ms *MongoStorage) GetReverseDestination(prefix string, skipCache bool) (id } func (ms *MongoStorage) SetReverseDestination(dest *Destination) (err error) { - session, col := ms.conn(colRst) + session, col := ms.conn(colRds) defer session.Close() for _, p := range dest.Prefixes { _, err = col.Upsert(bson.M{"key": p}, bson.M{"$addToSet": bson.M{"value": dest.Id}}) @@ -778,7 +778,7 @@ func (ms *MongoStorage) RemoveDestination(destID string) (err error) { cache2go.RemKey(key) session.Close() - session, col = ms.conn(colRst) + session, col = ms.conn(colRds) defer session.Close() for _, prefix := range d.Prefixes { err = col.Update(bson.M{"key": prefix}, bson.M{"$pull": bson.M{"value": destID}}) @@ -791,7 +791,7 @@ func (ms *MongoStorage) RemoveDestination(destID string) (err error) { } func (ms *MongoStorage) UpdateReverseDestination(oldDest, newDest *Destination) error { - session, col := ms.conn(colRst) + session, col := ms.conn(colRds) defer session.Close() //log.Printf("Old: %+v, New: %+v", oldDest, newDest) var obsoletePrefixes []string @@ -1393,12 +1393,18 @@ func (ms *MongoStorage) SetActionPlan(key string, ats *ActionPlan, overwrite boo } func (ms *MongoStorage) GetAllActionPlans() (ats map[string]*ActionPlan, err error) { - apls := cache2go.GetAllEntries(utils.ACTION_PLAN_PREFIX) + keys, err := ms.GetKeysForPrefix(utils.ACTION_PLAN_PREFIX) + if err != nil { + return nil, err + } - ats = make(map[string]*ActionPlan, len(apls)) - for key, value := range apls { - apl := value.(*ActionPlan) - ats[key] = apl + ats = make(map[string]*ActionPlan, len(keys)) + for _, key := range keys { + ap, err := ms.GetActionPlan(key[len(utils.ACTION_PLAN_PREFIX):], false) + if err != nil { + return nil, err + } + ats[key] = ap } return diff --git a/engine/storage_redis.go b/engine/storage_redis.go index bd8e17097..4af98318c 100644 --- a/engine/storage_redis.go +++ b/engine/storage_redis.go @@ -203,7 +203,6 @@ func (rs *RedisStorage) HasData(category, subject string) (bool, error) { func (rs *RedisStorage) GetRatingPlan(key string, skipCache bool) (rp *RatingPlan, err error) { key = utils.RATING_PLAN_PREFIX + key - if !skipCache { if x, ok := cache2go.Get(key); ok { if x != nil { @@ -408,7 +407,7 @@ func (rs *RedisStorage) SetReverseDestination(dest *Destination) (err error) { if err != nil { break } - cache2go.RemKey(utils.REVERSE_DESTINATION_PREFIX + p) + cache2go.RemKey(key) } return } @@ -983,7 +982,7 @@ func (rs *RedisStorage) GetAllActionPlans() (ats map[string]*ActionPlan, err err ats = make(map[string]*ActionPlan, len(keys)) for _, key := range keys { - ap, err := rs.GetActionPlan(key, false) + ap, err := rs.GetActionPlan(key[len(utils.ACTION_PLAN_PREFIX):], false) if err != nil { return nil, err } diff --git a/engine/tp_reader.go b/engine/tp_reader.go index 8de449b74..a5c7f7dc8 100644 --- a/engine/tp_reader.go +++ b/engine/tp_reader.go @@ -97,6 +97,7 @@ func (tpr *TpReader) LoadDestinationsFiltered(tag string) (bool, error) { dest.AddPrefix(tpDest.Prefix) } tpr.ratingStorage.SetDestination(dest) + tpr.ratingStorage.SetReverseDestination(dest) return len(tpDests) > 0, err } @@ -249,6 +250,7 @@ func (tpr *TpReader) LoadRatingPlansFiltered(tag string) (bool, error) { } for _, destination := range dms { tpr.ratingStorage.SetDestination(destination) + tpr.ratingStorage.SetReverseDestination(destination) } } } @@ -1498,6 +1500,7 @@ func (tpr *TpReader) LoadAliasesFiltered(filter *TpAlias) (bool, error) { } tpr.accountingStorage.SetAlias(alias) + tpr.accountingStorage.SetReverseAlias(alias) return len(tpAliases) > 0, err }