From 3ba64f365dfd30f4cd04120db6dfec192dc8be94 Mon Sep 17 00:00:00 2001 From: DanB Date: Wed, 11 Jan 2017 16:09:52 +0100 Subject: [PATCH] AccountActionPlans processed in TPReader --- apier/v1/accounts.go | 38 +++++++++++++++++++++++++++++-------- apier/v1/apier.go | 12 ++++++++++++ apier/v1/apier_it_test.go | 8 ++++---- apier/v2/accounts.go | 6 ++++++ engine/storage_interface.go | 2 +- engine/tp_reader.go | 10 +++++++--- 6 files changed, 60 insertions(+), 16 deletions(-) diff --git a/apier/v1/accounts.go b/apier/v1/accounts.go index 3532c9125..e16b50f46 100644 --- a/apier/v1/accounts.go +++ b/apier/v1/accounts.go @@ -85,10 +85,12 @@ func (self *ApierV1) RemActionTiming(attrs AttrRemActionTiming, reply *string) ( if missing := utils.MissingStructFields(&attrs, []string{"ActionPlanId"}); len(missing) != 0 { // Only mandatory ActionPlanId return utils.NewErrMandatoryIeMissing(missing...) } + var accID string if len(attrs.Account) != 0 { // Presence of Account requires complete account details to be provided if missing := utils.MissingStructFields(&attrs, []string{"Tenant", "Account"}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } + accID = utils.AccountKey(attrs.Tenant, attrs.Account) } _, err = guardian.Guardian.Guard(func() (interface{}, error) { ap, err := self.RatingDb.GetActionPlan(attrs.ActionPlanId, false, utils.NonTransactional) @@ -98,8 +100,7 @@ func (self *ApierV1) RemActionTiming(attrs AttrRemActionTiming, reply *string) ( return 0, utils.ErrNotFound } - if attrs.Tenant != "" && attrs.Account != "" { - accID := utils.AccountKey(attrs.Tenant, attrs.Account) + if accID != "" { delete(ap.AccountIDs, accID) if err = self.RatingDb.SetActionPlan(ap.Id, ap, true, utils.NonTransactional); err != nil { return 0, err @@ -131,6 +132,14 @@ func (self *ApierV1) RemActionTiming(attrs AttrRemActionTiming, reply *string) ( } return 0, nil }, 0, utils.ACTION_PLAN_PREFIX) + if accID != "" && attrs.ActionTimingId != "" { // Rebuild index for accounts pointing towards ActionPlans + if err = self.RatingDb.RemAccountActionPlans(accID, []string{attrs.ActionTimingId}); err != nil { + return + } + if err = self.RatingDb.CacheDataFromDB(utils.AccountActionPlansPrefix, []string{accID}, true); err != nil { + return + } + } if err != nil { *reply = err.Error() return utils.NewErrServerError(err) @@ -147,14 +156,14 @@ func (self *ApierV1) RemActionTiming(attrs AttrRemActionTiming, reply *string) ( } // Ads a new account into dataDb. If already defined, returns success. -func (self *ApierV1) SetAccount(attr utils.AttrSetAccount, reply *string) error { +func (self *ApierV1) SetAccount(attr utils.AttrSetAccount, reply *string) (err error) { if missing := utils.MissingStructFields(&attr, []string{"Tenant", "Account"}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } var schedulerReloadNeeded = false accID := utils.AccountKey(attr.Tenant, attr.Account) var ub *engine.Account - _, err := guardian.Guardian.Guard(func() (interface{}, error) { + _, err = guardian.Guardian.Guard(func() (interface{}, error) { if bal, _ := self.AccountDb.GetAccount(accID); bal != nil { ub = bal } else { // Not found in db, create it here @@ -219,7 +228,6 @@ func (self *ApierV1) SetAccount(attr utils.AttrSetAccount, reply *string) error return 0, err } } - if len(attr.ActionTriggersId) != 0 { atrs, err := self.RatingDb.GetActionTriggers(attr.ActionTriggersId, false, utils.NonTransactional) if err != nil { @@ -243,6 +251,15 @@ func (self *ApierV1) SetAccount(attr utils.AttrSetAccount, reply *string) error if err != nil { return utils.NewErrServerError(err) } + if attr.ActionPlanId != "" { + if err = self.RatingDb.SetAccountActionPlans(accID, []string{attr.ActionPlanId}, false); err != nil { + return + } + if err = self.RatingDb.CacheDataFromDB(utils.AccountActionPlansPrefix, []string{accID}, true); err != nil { + return + } + + } if attr.ReloadScheduler && schedulerReloadNeeded { sched := self.ServManager.GetScheduler() if sched == nil { @@ -254,13 +271,13 @@ func (self *ApierV1) SetAccount(attr utils.AttrSetAccount, reply *string) error return nil } -func (self *ApierV1) RemoveAccount(attr utils.AttrRemoveAccount, reply *string) error { +func (self *ApierV1) RemoveAccount(attr utils.AttrRemoveAccount, reply *string) (err error) { if missing := utils.MissingStructFields(&attr, []string{"Tenant", "Account"}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } dirtyActionPlans := make(map[string]*engine.ActionPlan) accID := utils.AccountKey(attr.Tenant, attr.Account) - _, err := guardian.Guardian.Guard(func() (interface{}, error) { + _, err = guardian.Guardian.Guard(func() (interface{}, error) { // remove it from all action plans _, err := guardian.Guardian.Guard(func() (interface{}, error) { actionPlansMap, err := self.RatingDb.GetAllActionPlans() @@ -298,7 +315,12 @@ func (self *ApierV1) RemoveAccount(attr utils.AttrRemoveAccount, reply *string) if err != nil { return utils.NewErrServerError(err) } - + if err = self.RatingDb.RemAccountActionPlans(accID, nil); err != nil { + return + } + if err = self.RatingDb.CacheDataFromDB(utils.AccountActionPlansPrefix, []string{accID}, true); err != nil { + return + } *reply = OK return nil } diff --git a/apier/v1/apier.go b/apier/v1/apier.go index 96f50acd1..8d5bca27d 100644 --- a/apier/v1/apier.go +++ b/apier/v1/apier.go @@ -803,6 +803,18 @@ func (self *ApierV1) ReloadCache(attrs utils.AttrReloadCache, reply *string) (er if err = self.RatingDb.CacheDataFromDB(utils.ACTION_PLAN_PREFIX, dataIDs, true); err != nil { return } + // AccountActionPlans + if attrs.AccountActionPlanIDs == nil { + dataIDs = nil // Reload all + } else if len(*attrs.AccountActionPlanIDs) > 0 { + dataIDs = make([]string, len(*attrs.AccountActionPlanIDs)) + for idx, dId := range *attrs.AccountActionPlanIDs { + dataIDs[idx] = dId + } + } + if err = self.RatingDb.CacheDataFromDB(utils.AccountActionPlansPrefix, dataIDs, true); err != nil { + return + } // ActionTriggers if attrs.ActionTriggerIDs == nil { dataIDs = nil // Reload all diff --git a/apier/v1/apier_it_test.go b/apier/v1/apier_it_test.go index 938d5b436..4a679cf4f 100644 --- a/apier/v1/apier_it_test.go +++ b/apier/v1/apier_it_test.go @@ -693,7 +693,7 @@ func TestApierLoadAccountActions(t *testing.T) { t.Error("Calling ApierV1.LoadAccountActions got reply: ", reply) } time.Sleep(10 * time.Millisecond) - expectedStats = &utils.CacheStats{Actions: 1, ActionPlans: 1} + expectedStats = &utils.CacheStats{Actions: 1, ActionPlans: 1, AccountActionPlans: 1} if err := rater.Call("ApierV1.GetCacheStats", args, &rcvStats); err != nil { t.Error("Got error on ApierV1.GetCacheStats: ", err.Error()) } else if !reflect.DeepEqual(expectedStats, rcvStats) { @@ -724,7 +724,7 @@ func TestApierSetRatingProfile(t *testing.T) { } var rcvStats *utils.CacheStats var args utils.AttrCacheStats - expectedStats := &utils.CacheStats{RatingProfiles: 1, Actions: 1, ActionPlans: 1} + expectedStats := &utils.CacheStats{RatingProfiles: 1, Actions: 1, ActionPlans: 1, AccountActionPlans: 1} if err := rater.Call("ApierV1.GetCacheStats", args, &rcvStats); err != nil { t.Error("Got error on ApierV1.GetCacheStats: ", err.Error()) } else if !reflect.DeepEqual(expectedStats, rcvStats) { @@ -756,7 +756,7 @@ func TestApierSetRatingProfile(t *testing.T) { } else if cc.Cost != 0 { t.Errorf("Calling Responder.GetCost got callcost: %v", cc.Cost) } - expectedStats = &utils.CacheStats{ReverseDestinations: 10, RatingPlans: 1, RatingProfiles: 1, Actions: 1, ActionPlans: 1} + expectedStats = &utils.CacheStats{ReverseDestinations: 10, RatingPlans: 1, RatingProfiles: 1, Actions: 1, ActionPlans: 1, AccountActionPlans: 1} if err := rater.Call("ApierV1.GetCacheStats", args, &rcvStats); err != nil { t.Error("Got error on ApierV1.GetCacheStats: ", err.Error()) } else if !reflect.DeepEqual(expectedStats, rcvStats) { @@ -776,7 +776,7 @@ func TestApierReloadCache(t *testing.T) { } var rcvStats *utils.CacheStats var args utils.AttrCacheStats - expectedStats := &utils.CacheStats{ReverseDestinations: 10, RatingPlans: 1, RatingProfiles: 1, Actions: 1, ActionPlans: 1} + expectedStats := &utils.CacheStats{ReverseDestinations: 10, RatingPlans: 1, RatingProfiles: 1, Actions: 1, ActionPlans: 1, AccountActionPlans: 1} if err := rater.Call("ApierV1.GetCacheStats", args, &rcvStats); err != nil { t.Error("Got error on ApierV1.GetCacheStats: ", err.Error()) } else if !reflect.DeepEqual(expectedStats, rcvStats) { diff --git a/apier/v2/accounts.go b/apier/v2/accounts.go index ed6ea522f..b3d356636 100644 --- a/apier/v2/accounts.go +++ b/apier/v2/accounts.go @@ -174,6 +174,12 @@ func (self *ApierV2) SetAccount(attr AttrSetAccount, reply *string) error { if err != nil { return 0, err } + if err = self.RatingDb.SetAccountActionPlans(accID, *attr.ActionPlanIDs, attr.ActionPlansOverwrite); err != nil { + return 0, err + } + if err = self.RatingDb.CacheDataFromDB(utils.AccountActionPlansPrefix, []string{accID}, true); err != nil { + return 0, err + } } if attr.ActionTriggerIDs != nil { diff --git a/engine/storage_interface.go b/engine/storage_interface.go index 921736143..0a290e49e 100644 --- a/engine/storage_interface.go +++ b/engine/storage_interface.go @@ -74,7 +74,7 @@ type RatingStorage interface { GetAllActionPlans() (map[string]*ActionPlan, error) GetAccountActionPlans(acntID string, skipCache bool, transactionID string) (apIDs []string, err error) SetAccountActionPlans(acntID string, apIDs []string, overwrite bool) (err error) - + 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 diff --git a/engine/tp_reader.go b/engine/tp_reader.go index 9acce3488..3d24cb3ad 100644 --- a/engine/tp_reader.go +++ b/engine/tp_reader.go @@ -885,7 +885,6 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error exitingAccountIds[id] = true actionPlan.AccountIDs = exitingAccountIds } - // write tasks for _, at := range actionPlan.ActionTimings { if at.IsASAP() { @@ -902,10 +901,15 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error } } // write action plan - err = tpr.ratingStorage.SetActionPlan(accountAction.ActionPlanId, actionPlan, false, utils.NonTransactional) - if err != nil { + if err = tpr.ratingStorage.SetActionPlan(accountAction.ActionPlanId, actionPlan, false, utils.NonTransactional); err != nil { return errors.New(err.Error() + " (SetActionPlan): " + accountAction.ActionPlanId) } + if err = tpr.ratingStorage.SetAccountActionPlans(id, []string{accountAction.ActionPlanId}, false); err != nil { + return err + } + if err = tpr.ratingStorage.CacheDataFromDB(utils.AccountActionPlansPrefix, []string{id}, true); err != nil { + return err + } } // action triggers var actionTriggers ActionTriggers