func (self *ApierV1) AddAccountActionTriggers(attr AttrAddAccountActionTriggers, reply *string) error { if missing := utils.MissingStructFields(&attr, []string{"Tenant", "Account"}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } actTime, err := utils.ParseTimeDetectLayout(attr.ActivationDate, self.Config.DefaultTimezone) if err != nil { *reply = err.Error() return err } accID := utils.AccountKey(attr.Tenant, attr.Account) var account *engine.Account _, err = engine.Guardian.Guard(func() (interface{}, error) { if acc, err := self.AccountDb.GetAccount(accID); err == nil { account = acc } else { return 0, err } if attr.ActionTriggerIDs != nil { if attr.ActionTriggerOverwrite { account.ActionTriggers = make(engine.ActionTriggers, 0) } for _, actionTriggerID := range *attr.ActionTriggerIDs { atrs, err := self.RatingDb.GetActionTriggers(actionTriggerID, false, utils.NonTransactional) if err != nil { return 0, err } for _, at := range atrs { var found bool for _, existingAt := range account.ActionTriggers { if existingAt.Equals(at) { found = true break } } at.ActivationDate = actTime at.Executed = attr.Executed if !found { account.ActionTriggers = append(account.ActionTriggers, at) } } } } account.InitCounters() if err := self.AccountDb.SetAccount(account); err != nil { return 0, err } return 0, nil }, 0, accID) if err != nil { *reply = err.Error() return err } *reply = utils.OK return nil }
func (self *ApierV1) RemoveAccountActionTriggers(attr AttrRemoveAccountActionTriggers, reply *string) error { if missing := utils.MissingStructFields(&attr, []string{"Tenant", "Account"}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } accID := utils.AccountKey(attr.Tenant, attr.Account) _, err := engine.Guardian.Guard(func() (interface{}, error) { var account *engine.Account if acc, err := self.AccountDb.GetAccount(accID); err == nil { account = acc } else { return 0, err } var newActionTriggers engine.ActionTriggers for _, at := range account.ActionTriggers { if (attr.UniqueID == "" || at.UniqueID == attr.UniqueID) && (attr.GroupID == "" || at.ID == attr.GroupID) { // remove action trigger continue } newActionTriggers = append(newActionTriggers, at) } account.ActionTriggers = newActionTriggers account.InitCounters() if err := self.AccountDb.SetAccount(account); err != nil { return 0, err } return 0, nil }, 0, accID) if err != nil { *reply = err.Error() return err } *reply = utils.OK return nil }
// SetAccountActionTriggers Updates or Creates ActionTriggers for an Account func (self *ApierV2) SetAccountActionTriggers(attr AttrSetAccountActionTriggers, reply *string) error { if missing := utils.MissingStructFields(&attr, []string{"Tenant", "Account"}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } accID := utils.AccountKey(attr.Tenant, attr.Account) var account *engine.Account _, err := engine.Guardian.Guard(func() (interface{}, error) { if acc, err := self.AccountDb.GetAccount(accID); err == nil { account = acc } else { return 0, err } var foundOne bool for _, at := range account.ActionTriggers { if updated, err := attr.UpdateActionTrigger(at, self.Config.DefaultTimezone); err != nil { return 0, err } else if updated && !foundOne { foundOne = true } } if !foundOne { // Did not find one to update, create a new AT at := new(engine.ActionTrigger) if updated, err := attr.UpdateActionTrigger(at, self.Config.DefaultTimezone); err != nil { return 0, err } else if updated { // Adding a new AT account.ActionTriggers = append(account.ActionTriggers, at) } } account.ExecuteActionTriggers(nil) if err := self.AccountDb.SetAccount(account); err != nil { return 0, err } return 0, nil }, 0, accID) if err != nil { *reply = err.Error() return err } *reply = utils.OK return nil }
func (self *ApierV2) SetAccount(attr AttrSetAccount, reply *string) error { if missing := utils.MissingStructFields(&attr, []string{"Tenant", "Account"}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } accID := utils.AccountKey(attr.Tenant, attr.Account) dirtyActionPlans := make(map[string]*engine.ActionPlan) var ub *engine.Account _, err := engine.Guardian.Guard(func() (interface{}, error) { if bal, _ := self.AccountDb.GetAccount(accID); bal != nil { ub = bal } else { // Not found in db, create it here ub = &engine.Account{ ID: accID, } } if attr.ActionPlanIDs != nil { _, err := engine.Guardian.Guard(func() (interface{}, error) { actionPlansMap, err := self.RatingDb.GetAllActionPlans() if err != nil { if err == utils.ErrNotFound { // if no action plans just continue return 0, nil } return 0, err } if attr.ActionPlansOverwrite { // clean previous action plans for actionPlanID, ap := range actionPlansMap { if _, exists := ap.AccountIDs[accID]; exists { delete(ap.AccountIDs, accID) dirtyActionPlans[actionPlanID] = ap } } } for _, actionPlanID := range *attr.ActionPlanIDs { ap, ok := actionPlansMap[actionPlanID] if !ok { return 0, utils.ErrNotFound } if _, exists := ap.AccountIDs[accID]; !exists { if ap.AccountIDs == nil { ap.AccountIDs = make(utils.StringMap) } ap.AccountIDs[accID] = true dirtyActionPlans[actionPlanID] = ap // create tasks for _, at := range ap.ActionTimings { if at.IsASAP() { t := &engine.Task{ Uuid: utils.GenUUID(), AccountID: accID, ActionsID: at.ActionsID, } if err = self.RatingDb.PushTask(t); err != nil { return 0, err } } } } } apIDs := make([]string, len(dirtyActionPlans)) i := 0 for actionPlanID, ap := range dirtyActionPlans { if err := self.RatingDb.SetActionPlan(actionPlanID, ap, true, utils.NonTransactional); err != nil { return 0, err } apIDs[i] = actionPlanID i++ } if err := self.RatingDb.CacheDataFromDB(utils.ACTION_PLAN_PREFIX, apIDs, true); err != nil { return 0, err } return 0, nil }, 0, utils.ACTION_PLAN_PREFIX) if err != nil { return 0, err } } if attr.ActionTriggerIDs != nil { if attr.ActionTriggerOverwrite { ub.ActionTriggers = make(engine.ActionTriggers, 0) } for _, actionTriggerID := range *attr.ActionTriggerIDs { atrs, err := self.RatingDb.GetActionTriggers(actionTriggerID, false, utils.NonTransactional) if err != nil { return 0, err } for _, at := range atrs { var found bool for _, existingAt := range ub.ActionTriggers { if existingAt.Equals(at) { found = true break } } if !found { ub.ActionTriggers = append(ub.ActionTriggers, at) } } } } ub.InitCounters() if attr.AllowNegative != nil { ub.AllowNegative = *attr.AllowNegative } if attr.Disabled != nil { ub.Disabled = *attr.Disabled } // All prepared, save account if err := self.AccountDb.SetAccount(ub); err != nil { return 0, err } return 0, nil }, 0, accID) if err != nil { return utils.NewErrServerError(err) } if attr.ReloadScheduler && len(dirtyActionPlans) > 0 { sched := self.ServManager.GetScheduler() if sched == nil { return errors.New(utils.SchedulerNotRunningCaps) } sched.Reload() } *reply = utils.OK // This will mark saving of the account, error still can show up in actionTimingsId return nil }
// Ads a new account into dataDb. If already defined, returns success. func (self *ApierV1) SetAccount(attr utils.AttrSetAccount, reply *string) error { if missing := utils.MissingStructFields(&attr, []string{"Tenant", "Account"}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } balanceId := utils.AccountKey(attr.Tenant, attr.Account) var ub *engine.Account var ats engine.ActionPlans _, err := engine.Guardian.Guard(func() (interface{}, error) { if bal, _ := self.AccountDb.GetAccount(balanceId); bal != nil { ub = bal } else { // Not found in db, create it here ub = &engine.Account{ Id: balanceId, } } if len(attr.ActionPlanId) != 0 { var err error ats, err = self.RatingDb.GetActionPlans(attr.ActionPlanId, false) if err != nil { return 0, err } for _, at := range ats { at.AccountIds = append(at.AccountIds, balanceId) } } if len(attr.ActionTriggersId) != 0 { atrs, err := self.RatingDb.GetActionTriggers(attr.ActionTriggersId) if err != nil { return 0, err } ub.ActionTriggers = atrs ub.InitCounters() } if attr.AllowNegative != nil { ub.AllowNegative = *attr.AllowNegative } if attr.Disabled != nil { ub.Disabled = *attr.Disabled } // All prepared, save account if err := self.AccountDb.SetAccount(ub); err != nil { return 0, err } return 0, nil }, 0, balanceId) if err != nil { return utils.NewErrServerError(err) } if len(ats) != 0 { _, err := engine.Guardian.Guard(func() (interface{}, error) { // ToDo: Try locking it above on read somehow if err := self.RatingDb.SetActionPlans(attr.ActionPlanId, ats); err != nil { return 0, err } return 0, nil }, 0, utils.ACTION_PLAN_PREFIX) if err != nil { return utils.NewErrServerError(err) } if self.Sched != nil { self.Sched.LoadActionPlans(self.RatingDb) self.Sched.Restart() } } *reply = OK // This will mark saving of the account, error still can show up in actionTimingsId return nil }
// Ads a new account into dataDb. If already defined, returns success. func (self *ApierV1) SetAccount(attr utils.AttrSetAccount, reply *string) 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 := engine.Guardian.Guard(func() (interface{}, error) { if bal, _ := self.AccountDb.GetAccount(accID); bal != nil { ub = bal } else { // Not found in db, create it here ub = &engine.Account{ ID: accID, } } if len(attr.ActionPlanId) != 0 { _, err := engine.Guardian.Guard(func() (interface{}, error) { var ap *engine.ActionPlan ap, err := self.RatingDb.GetActionPlan(attr.ActionPlanId, false, utils.NonTransactional) if err != nil { return 0, err } if _, exists := ap.AccountIDs[accID]; !exists { if ap.AccountIDs == nil { ap.AccountIDs = make(utils.StringMap) } ap.AccountIDs[accID] = true schedulerReloadNeeded = true // create tasks for _, at := range ap.ActionTimings { if at.IsASAP() { t := &engine.Task{ Uuid: utils.GenUUID(), AccountID: accID, ActionsID: at.ActionsID, } if err = self.RatingDb.PushTask(t); err != nil { return 0, err } } } if err := self.RatingDb.SetActionPlan(attr.ActionPlanId, ap, true, utils.NonTransactional); err != nil { 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 == 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, true, utils.NonTransactional) } } return 0, nil }, 0, utils.ACTION_PLAN_PREFIX) if err != nil { return 0, err } } if len(attr.ActionTriggersId) != 0 { atrs, err := self.RatingDb.GetActionTriggers(attr.ActionTriggersId, false, utils.NonTransactional) if err != nil { return 0, err } ub.ActionTriggers = atrs ub.InitCounters() } if attr.AllowNegative != nil { ub.AllowNegative = *attr.AllowNegative } if attr.Disabled != nil { ub.Disabled = *attr.Disabled } // All prepared, save account if err := self.AccountDb.SetAccount(ub); err != nil { return 0, err } return 0, nil }, 0, accID) if err != nil { return utils.NewErrServerError(err) } if attr.ReloadScheduler && schedulerReloadNeeded { // reload scheduler if self.Sched != nil { self.Sched.Reload(true) } } *reply = OK // This will mark saving of the account, error still can show up in actionTimingsId return nil }