updated apis

This commit is contained in:
Radu Ioan Fericean
2015-12-18 10:26:41 +02:00
parent 65516e201e
commit a250fc668f
10 changed files with 265 additions and 300 deletions

View File

@@ -45,17 +45,24 @@ func (self *ApierV1) GetAccountActionPlan(attrs AttrAcntAction, reply *[]*Accoun
if missing := utils.MissingStructFields(&attrs, []string{"Tenant", "Account"}); len(missing) != 0 {
return utils.NewErrMandatoryIeMissing(strings.Join(missing, ","), "")
}
accountATs := make([]*AccountActionTiming, 0)
allATs, err := self.RatingDb.GetAllActionPlans()
accountATs := make([]*AccountActionTiming, 0) // needs to be initialized if remains empty
allAPs, err := self.RatingDb.GetAllActionPlans()
if err != nil {
return utils.NewErrServerError(err)
}
for _, ats := range allATs {
for _, at := range ats {
if utils.IsSliceMember(at.AccountIds, utils.AccountKey(attrs.Tenant, attrs.Account)) {
accountATs = append(accountATs, &AccountActionTiming{Uuid: at.Uuid, ActionPlanId: at.Id, ActionsId: at.ActionsId, NextExecTime: at.GetNextStartTime(time.Now())})
accID := utils.AccountKey(attrs.Tenant, attrs.Account)
for _, ap := range allAPs {
if _, exists := ap.AccountIDs[accID]; exists {
for _, at := range ap.ActionTimings {
accountATs = append(accountATs, &AccountActionTiming{
ActionPlanId: ap.Id,
Uuid: at.Uuid,
ActionsId: at.ActionsID,
NextExecTime: at.GetNextStartTime(time.Now()),
})
}
}
}
*reply = accountATs
return nil
@@ -80,22 +87,41 @@ func (self *ApierV1) RemActionTiming(attrs AttrRemActionTiming, reply *string) e
}
}
_, err := engine.Guardian.Guard(func() (interface{}, error) {
ats, err := self.RatingDb.GetActionPlans(attrs.ActionPlanId, false)
ap, err := self.RatingDb.GetActionPlan(attrs.ActionPlanId, false)
if err != nil {
return 0, err
} else if len(ats) == 0 {
} else if ap == nil {
return 0, utils.ErrNotFound
}
ats = engine.RemActionPlan(ats, attrs.ActionTimingId, utils.AccountKey(attrs.Tenant, attrs.Account))
if err := self.RatingDb.SetActionPlans(attrs.ActionPlanId, ats); err != nil {
return 0, err
if attrs.ActionPlanId != "" { // delete the entire action plan
ap.ActionTimings = nil // will delete the action plan
return 0, self.RatingDb.SetActionPlan(ap.Id, ap)
}
if len(ats) > 0 { // update cache
self.RatingDb.CacheRatingPrefixValues(map[string][]string{utils.ACTION_PLAN_PREFIX: []string{utils.ACTION_PLAN_PREFIX + attrs.ActionPlanId}})
if attrs.ActionTimingId != "" { // delete only a action timing from action plan
for i, at := range ap.ActionTimings {
if at.Uuid == attrs.ActionTimingId {
ap.ActionTimings[i] = ap.ActionTimings[len(ap.ActionTimings)-1]
ap.ActionTimings = ap.ActionTimings[:len(ap.ActionTimings)-1]
break
}
}
return 0, self.RatingDb.SetActionPlan(ap.Id, ap)
}
if attrs.Tenant != "" && attrs.Account != "" {
accID := utils.AccountKey(attrs.Tenant, attrs.Account)
delete(ap.AccountIDs, accID)
return 0, self.RatingDb.SetActionPlan(ap.Id, ap)
}
// update cache
self.RatingDb.CacheRatingPrefixValues(map[string][]string{utils.ACTION_PLAN_PREFIX: []string{utils.ACTION_PLAN_PREFIX + attrs.ActionPlanId}})
return 0, nil
}, 0, utils.ACTION_PLAN_PREFIX)
if err != nil {
*reply = err.Error()
return utils.NewErrServerError(err)
}
if attrs.ReloadScheduler && self.Sched != nil {
@@ -130,9 +156,9 @@ func (self *ApierV1) RemAccountActionTriggers(attrs AttrRemAcntActionTriggers, r
if missing := utils.MissingStructFields(&attrs, []string{"Tenant", "Account"}); len(missing) != 0 {
return utils.NewErrMandatoryIeMissing(missing...)
}
accId := utils.AccountKey(attrs.Tenant, attrs.Account)
accID := utils.AccountKey(attrs.Tenant, attrs.Account)
_, err := engine.Guardian.Guard(func() (interface{}, error) {
ub, err := self.AccountDb.GetAccount(accId)
ub, err := self.AccountDb.GetAccount(accID)
if err != nil {
return 0, err
}
@@ -152,7 +178,7 @@ func (self *ApierV1) RemAccountActionTriggers(attrs AttrRemAcntActionTriggers, r
return 0, err
}
return 0, nil
}, 0, accId)
}, 0, accID)
if err != nil {
return utils.NewErrServerError(err)
}
@@ -166,30 +192,28 @@ func (self *ApierV1) SetAccount(attr utils.AttrSetAccount, reply *string) error
return utils.NewErrMandatoryIeMissing(missing...)
}
var schedulerReloadNeeded = false
accId := utils.AccountKey(attr.Tenant, attr.Account)
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 {
if bal, _ := self.AccountDb.GetAccount(accID); bal != nil {
ub = bal
} else { // Not found in db, create it here
ub = &engine.Account{
Id: accId,
Id: accID,
}
}
if len(attr.ActionPlanId) != 0 {
_, err := engine.Guardian.Guard(func() (interface{}, error) {
var ats engine.ActionPlans
var ap *engine.ActionPlan
var err error
ats, err = self.RatingDb.GetActionPlans(attr.ActionPlanId, false)
ap, err = self.RatingDb.GetActionPlan(attr.ActionPlanId, false)
if err != nil {
return 0, err
}
for _, at := range ats {
at.AccountIds = append(at.AccountIds, accId)
}
if len(ats) != 0 {
if _, exists := ap.AccountIDs[accID]; !exists {
ap.AccountIDs[accID] = struct{}{}
schedulerReloadNeeded = true
if err := self.RatingDb.SetActionPlans(attr.ActionPlanId, ats); err != nil {
if err := self.RatingDb.SetActionPlan(attr.ActionPlanId, ap); err != nil {
return 0, err
}
// update cache
@@ -221,11 +245,11 @@ func (self *ApierV1) SetAccount(attr utils.AttrSetAccount, reply *string) error
return 0, err
}
return 0, nil
}, 0, accId)
}, 0, accID)
if err != nil {
return utils.NewErrServerError(err)
}
if schedulerReloadNeeded {
if attr.ReloadScheduler && schedulerReloadNeeded {
// reload scheduler
if self.Sched != nil {
self.Sched.Reload(true)
@@ -239,32 +263,20 @@ func (self *ApierV1) RemoveAccount(attr utils.AttrRemoveAccount, reply *string)
if missing := utils.MissingStructFields(&attr, []string{"Tenant", "Account"}); len(missing) != 0 {
return utils.NewErrMandatoryIeMissing(missing...)
}
accountId := utils.AccountKey(attr.Tenant, attr.Account)
accID := utils.AccountKey(attr.Tenant, attr.Account)
var schedulerReloadNeeded bool
_, err := engine.Guardian.Guard(func() (interface{}, error) {
// remove it from all action plans
allATs, err := self.RatingDb.GetAllActionPlans()
allAPs, err := self.RatingDb.GetAllActionPlans()
if err != nil && err != utils.ErrNotFound {
return 0, err
}
for key, ats := range allATs {
changed := false
for _, at := range ats {
for i := 0; i < len(at.AccountIds); i++ {
if at.AccountIds[i] == accountId {
// delete without preserving order
at.AccountIds[i] = at.AccountIds[len(at.AccountIds)-1]
at.AccountIds = at.AccountIds[:len(at.AccountIds)-1]
i--
changed = true
}
}
}
if changed {
for key, ap := range allAPs {
if _, exists := ap.AccountIDs[accID]; !exists {
schedulerReloadNeeded = true
_, err := engine.Guardian.Guard(func() (interface{}, error) {
// save action plan
self.RatingDb.SetActionPlans(key, ats)
self.RatingDb.SetActionPlan(key, ap)
// cache
self.RatingDb.CacheRatingPrefixValues(map[string][]string{utils.ACTION_PLAN_PREFIX: []string{utils.ACTION_PLAN_PREFIX + key}})
return 0, nil
@@ -274,11 +286,11 @@ func (self *ApierV1) RemoveAccount(attr utils.AttrRemoveAccount, reply *string)
}
}
}
if err := self.AccountDb.RemoveAccount(accountId); err != nil {
if err := self.AccountDb.RemoveAccount(accID); err != nil {
return 0, err
}
return 0, nil
}, 0, accountId)
}, 0, accID)
// FIXME: remove from all actionplans?
if err != nil {
return utils.NewErrServerError(err)
@@ -344,3 +356,153 @@ func (self *ApierV1) GetAccount(attr *utils.AttrGetAccount, reply *interface{})
*reply = userBalance.AsOldStructure()
return nil
}
type AttrAddBalance struct {
Tenant string
Account string
BalanceUuid string
BalanceId string
BalanceType string
Directions string
Value float64
ExpiryTime string
RatingSubject string
Categories string
DestinationIds string
Weight float64
SharedGroups string
Overwrite bool // When true it will reset if the balance is already there
Disabled bool
}
func (self *ApierV1) AddBalance(attr *AttrAddBalance, reply *string) error {
expTime, err := utils.ParseTimeDetectLayout(attr.ExpiryTime, self.Config.DefaultTimezone)
if err != nil {
*reply = err.Error()
return err
}
accID := utils.AccountKey(attr.Tenant, attr.Account)
if _, err := self.AccountDb.GetAccount(accID); err != nil {
// create account if not exists
account := &engine.Account{
Id: accID,
}
if err := self.AccountDb.SetAccount(account); err != nil {
*reply = err.Error()
return err
}
}
at := &engine.ActionTiming{}
at.SetAccountIDs(map[string]struct{}{accID: struct{}{}})
aType := engine.DEBIT
// reverse the sign as it is a debit
attr.Value = -attr.Value
if attr.Overwrite {
aType = engine.DEBIT_RESET
}
at.SetActions(engine.Actions{
&engine.Action{
ActionType: aType,
BalanceType: attr.BalanceType,
Balance: &engine.Balance{
Uuid: attr.BalanceUuid,
Id: attr.BalanceId,
Value: attr.Value,
ExpirationDate: expTime,
RatingSubject: attr.RatingSubject,
Directions: utils.ParseStringMap(attr.Directions),
DestinationIds: utils.ParseStringMap(attr.DestinationIds),
Categories: utils.ParseStringMap(attr.Categories),
Weight: attr.Weight,
SharedGroups: utils.ParseStringMap(attr.SharedGroups),
Disabled: attr.Disabled,
},
},
})
if err := at.Execute(); err != nil {
*reply = err.Error()
return err
}
*reply = OK
return nil
}
func (self *ApierV1) EnableDisableBalance(attr *AttrAddBalance, reply *string) error {
expTime, err := utils.ParseDate(attr.ExpiryTime)
if err != nil {
*reply = err.Error()
return err
}
accID := utils.ConcatenatedKey(attr.Tenant, attr.Account)
if _, err := self.AccountDb.GetAccount(accID); err != nil {
return utils.ErrNotFound
}
at := &engine.ActionTiming{}
at.SetAccountIDs(map[string]struct{}{accID: struct{}{}})
at.SetActions(engine.Actions{
&engine.Action{
ActionType: engine.ENABLE_DISABLE_BALANCE,
BalanceType: attr.BalanceType,
Balance: &engine.Balance{
Uuid: attr.BalanceUuid,
Id: attr.BalanceId,
Value: attr.Value,
ExpirationDate: expTime,
RatingSubject: attr.RatingSubject,
Directions: utils.ParseStringMap(attr.Directions),
DestinationIds: utils.ParseStringMap(attr.DestinationIds),
Weight: attr.Weight,
SharedGroups: utils.ParseStringMap(attr.SharedGroups),
Disabled: attr.Disabled,
},
},
})
if err := at.Execute(); err != nil {
*reply = err.Error()
return err
}
*reply = OK
return nil
}
func (self *ApierV1) RemoveBalances(attr *AttrAddBalance, reply *string) error {
expTime, err := utils.ParseDate(attr.ExpiryTime)
if err != nil {
*reply = err.Error()
return err
}
accID := utils.AccountKey(attr.Tenant, attr.Account)
if _, err := self.AccountDb.GetAccount(accID); err != nil {
return utils.ErrNotFound
}
at := &engine.ActionTiming{}
at.SetAccountIDs(map[string]struct{}{accID: struct{}{}})
at.SetActions(engine.Actions{
&engine.Action{
ActionType: engine.REMOVE_BALANCE,
BalanceType: attr.BalanceType,
Balance: &engine.Balance{
Uuid: attr.BalanceUuid,
Id: attr.BalanceId,
Value: attr.Value,
ExpirationDate: expTime,
RatingSubject: attr.RatingSubject,
Directions: utils.ParseStringMap(attr.Directions),
DestinationIds: utils.ParseStringMap(attr.DestinationIds),
Weight: attr.Weight,
SharedGroups: utils.ParseStringMap(attr.SharedGroups),
Disabled: attr.Disabled,
},
},
})
if err := at.Execute(); err != nil {
*reply = err.Error()
return err
}
*reply = OK
return nil
}

View File

@@ -102,162 +102,12 @@ func (self *ApierV1) GetRatingPlan(rplnId string, reply *engine.RatingPlan) erro
return nil
}
type AttrAddBalance struct {
Tenant string
Account string
BalanceUuid string
BalanceId string
BalanceType string
Directions string
Value float64
ExpiryTime string
RatingSubject string
Categories string
DestinationIds string
Weight float64
SharedGroups string
Overwrite bool // When true it will reset if the balance is already there
Disabled bool
}
func (self *ApierV1) AddBalance(attr *AttrAddBalance, reply *string) error {
expTime, err := utils.ParseTimeDetectLayout(attr.ExpiryTime, self.Config.DefaultTimezone)
if err != nil {
*reply = err.Error()
return err
}
tag := utils.ConcatenatedKey(attr.Tenant, attr.Account)
if _, err := self.AccountDb.GetAccount(tag); err != nil {
// create account if not exists
account := &engine.Account{
Id: tag,
}
if err := self.AccountDb.SetAccount(account); err != nil {
*reply = err.Error()
return err
}
}
at := &engine.ActionPlan{
AccountIds: []string{tag},
}
aType := engine.DEBIT
// reverse the sign as it is a debit
attr.Value = -attr.Value
if attr.Overwrite {
aType = engine.DEBIT_RESET
}
at.SetActions(engine.Actions{
&engine.Action{
ActionType: aType,
BalanceType: attr.BalanceType,
Balance: &engine.Balance{
Uuid: attr.BalanceUuid,
Id: attr.BalanceId,
Value: attr.Value,
ExpirationDate: expTime,
RatingSubject: attr.RatingSubject,
Directions: utils.ParseStringMap(attr.Directions),
DestinationIds: utils.ParseStringMap(attr.DestinationIds),
Categories: utils.ParseStringMap(attr.Categories),
Weight: attr.Weight,
SharedGroups: utils.ParseStringMap(attr.SharedGroups),
Disabled: attr.Disabled,
},
},
})
if err := at.Execute(); err != nil {
*reply = err.Error()
return err
}
*reply = OK
return nil
}
func (self *ApierV1) EnableDisableBalance(attr *AttrAddBalance, reply *string) error {
expTime, err := utils.ParseDate(attr.ExpiryTime)
if err != nil {
*reply = err.Error()
return err
}
tag := utils.ConcatenatedKey(attr.Tenant, attr.Account)
if _, err := self.AccountDb.GetAccount(tag); err != nil {
return utils.ErrNotFound
}
at := &engine.ActionPlan{
AccountIds: []string{tag},
}
at.SetActions(engine.Actions{
&engine.Action{
ActionType: engine.ENABLE_DISABLE_BALANCE,
BalanceType: attr.BalanceType,
Balance: &engine.Balance{
Uuid: attr.BalanceUuid,
Id: attr.BalanceId,
Value: attr.Value,
ExpirationDate: expTime,
RatingSubject: attr.RatingSubject,
Directions: utils.ParseStringMap(attr.Directions),
DestinationIds: utils.ParseStringMap(attr.DestinationIds),
Weight: attr.Weight,
SharedGroups: utils.ParseStringMap(attr.SharedGroups),
Disabled: attr.Disabled,
},
},
})
if err := at.Execute(); err != nil {
*reply = err.Error()
return err
}
*reply = OK
return nil
}
func (self *ApierV1) RemoveBalances(attr *AttrAddBalance, reply *string) error {
expTime, err := utils.ParseDate(attr.ExpiryTime)
if err != nil {
*reply = err.Error()
return err
}
accId := utils.ConcatenatedKey(attr.Tenant, attr.Account)
if _, err := self.AccountDb.GetAccount(accId); err != nil {
return utils.ErrNotFound
}
at := &engine.ActionPlan{
AccountIds: []string{accId},
}
at.SetActions(engine.Actions{
&engine.Action{
ActionType: engine.REMOVE_BALANCE,
BalanceType: attr.BalanceType,
Balance: &engine.Balance{
Uuid: attr.BalanceUuid,
Id: attr.BalanceId,
Value: attr.Value,
ExpirationDate: expTime,
RatingSubject: attr.RatingSubject,
Directions: utils.ParseStringMap(attr.Directions),
DestinationIds: utils.ParseStringMap(attr.DestinationIds),
Weight: attr.Weight,
SharedGroups: utils.ParseStringMap(attr.SharedGroups),
Disabled: attr.Disabled,
},
},
})
if err := at.Execute(); err != nil {
*reply = err.Error()
return err
}
*reply = OK
return nil
}
func (self *ApierV1) ExecuteAction(attr *utils.AttrExecuteAction, reply *string) error {
accId := utils.AccountKey(attr.Tenant, attr.Account)
at := &engine.ActionPlan{
AccountIds: []string{accId},
ActionsId: attr.ActionsId,
accID := utils.AccountKey(attr.Tenant, attr.Account)
at := &engine.ActionTiming{
ActionsID: attr.ActionsId,
}
at.SetAccountIDs(map[string]struct{}{accID: struct{}{}})
if err := at.Execute(); err != nil {
*reply = err.Error()
return err
@@ -745,8 +595,10 @@ func (self *ApierV1) SetActionPlan(attrs AttrSetActionPlan, reply *string) error
return utils.ErrExists
}
}
storeAtms := make(engine.ActionPlans, len(attrs.ActionPlan))
for idx, apiAtm := range attrs.ActionPlan {
ap := &engine.ActionPlan{
Id: attrs.Id,
}
for _, apiAtm := range attrs.ActionPlan {
if exists, err := self.RatingDb.HasData(utils.ACTION_PREFIX, apiAtm.ActionsId); err != nil {
return utils.NewErrServerError(err)
} else if !exists {
@@ -758,16 +610,14 @@ func (self *ApierV1) SetActionPlan(attrs AttrSetActionPlan, reply *string) error
timing.MonthDays.Parse(apiAtm.MonthDays, ";")
timing.WeekDays.Parse(apiAtm.WeekDays, ";")
timing.StartTime = apiAtm.Time
at := &engine.ActionPlan{
ap.ActionTimings = append(ap.ActionTimings, &engine.ActionTiming{
Uuid: utils.GenUUID(),
Id: attrs.Id,
Weight: apiAtm.Weight,
Timing: &engine.RateInterval{Timing: timing},
ActionsId: apiAtm.ActionsId,
}
storeAtms[idx] = at
ActionsID: apiAtm.ActionsId,
})
}
if err := self.RatingDb.SetActionPlans(attrs.Id, storeAtms); err != nil {
if err := self.RatingDb.SetActionPlan(ap.Id, ap); err != nil {
return utils.NewErrServerError(err)
}
self.RatingDb.CacheRatingPrefixValues(map[string][]string{utils.ACTION_PLAN_PREFIX: []string{utils.ACTION_PLAN_PREFIX + attrs.Id}})
@@ -785,8 +635,8 @@ type AttrGetActionPlan struct {
Id string
}
func (self *ApierV1) GetActionPlan(attr AttrGetActionPlan, reply *[]engine.ActionPlans) error {
var result []engine.ActionPlans
func (self *ApierV1) GetActionPlan(attr AttrGetActionPlan, reply *[]*engine.ActionPlan) error {
var result []*engine.ActionPlan
if attr.Id == "" || attr.Id == "*" {
aplsMap, err := self.RatingDb.GetAllActionPlans()
if err != nil {
@@ -796,7 +646,7 @@ func (self *ApierV1) GetActionPlan(attr AttrGetActionPlan, reply *[]engine.Actio
result = append(result, apls)
}
} else {
apls, err := self.RatingDb.GetActionPlans(attr.Id, false)
apls, err := self.RatingDb.GetActionPlan(attr.Id, false)
if err != nil {
return err
}

View File

@@ -104,9 +104,9 @@ type AttrsGetScheduledActions struct {
}
type ScheduledActions struct {
NextRunTime time.Time
Accounts int
ActionsId, ActionPlanId, ActionPlanUuid string
NextRunTime time.Time
Accounts int
ActionsId, ActionPlanId, ActionTimingUuid string
}
func (self *ApierV1) GetScheduledActions(attrs AttrsGetScheduledActions, reply *[]*ScheduledActions) error {
@@ -116,7 +116,7 @@ func (self *ApierV1) GetScheduledActions(attrs AttrsGetScheduledActions, reply *
schedActions := make([]*ScheduledActions, 0) // needs to be initialized if remains empty
scheduledActions := self.Sched.GetQueue()
for _, qActions := range scheduledActions {
sas := &ScheduledActions{ActionsId: qActions.ActionsId, ActionPlanId: qActions.Id, ActionPlanUuid: qActions.Uuid, Accounts: len(qActions.AccountIds)}
sas := &ScheduledActions{ActionsId: qActions.ActionsID, ActionPlanId: qActions.GetActionPlanID(), ActionTimingUuid: qActions.Uuid, Accounts: len(qActions.GetAccountIDs())}
if attrs.SearchTerm != "" &&
!(strings.Contains(sas.ActionPlanId, attrs.SearchTerm) ||
strings.Contains(sas.ActionsId, attrs.SearchTerm)) {
@@ -132,7 +132,7 @@ func (self *ApierV1) GetScheduledActions(attrs AttrsGetScheduledActions, reply *
// filter on account
if attrs.Tenant != "" || attrs.Account != "" {
found := false
for _, accID := range qActions.AccountIds {
for accID := range qActions.GetAccountIDs() {
split := strings.Split(accID, utils.CONCATENATED_KEY_SEP)
if len(split) != 2 {
continue // malformed account id

View File

@@ -61,6 +61,6 @@ func (self *CmdGetActionPlan) PostprocessRpcParams() error {
}
func (self *CmdGetActionPlan) RpcResult() interface{} {
s := make([]*engine.ActionPlans, 0)
s := make([]*engine.ActionPlan, 0)
return &s
}

View File

@@ -32,13 +32,14 @@ const (
)
type ActionTiming struct {
Uuid string
Timing *RateInterval
ActionsID string
Weight float64
actions Actions
accountIDs map[string]struct{} // copy of action plans accounts
stCache time.Time // cached time of the next start
Uuid string
Timing *RateInterval
ActionsID string
Weight float64
actions Actions
accountIDs map[string]struct{} // copy of action plans accounts
actionPlanID string // the id of the belonging action plan (info only)
stCache time.Time // cached time of the next start
}
type Task struct {
@@ -48,7 +49,6 @@ type Task struct {
}
type ActionPlan struct {
Uuid string // uniquely identify the timing
Id string // informative purpose only
AccountIDs map[string]struct{}
ActionTimings []*ActionTiming
@@ -254,6 +254,18 @@ func (at *ActionTiming) SetAccountIDs(accIDs map[string]struct{}) {
at.accountIDs = accIDs
}
func (at *ActionTiming) GetAccountIDs() map[string]struct{} {
return at.accountIDs
}
func (at *ActionTiming) SetActionPlanID(id string) {
at.actionPlanID = id
}
func (at *ActionTiming) GetActionPlanID() string {
return at.actionPlanID
}
func (at *ActionTiming) getActions() (as []*Action, err error) {
if at.actions == nil {
at.actions, err = ratingStorage.GetActions(at.ActionsID, false)
@@ -364,34 +376,3 @@ func (atpl ActionTimingPriorityList) Less(i, j int) bool {
func (atpl ActionTimingPriorityList) Sort() {
sort.Sort(atpl)
}
// Helper to remove ActionPlan members based on specific filters, empty data means no always match
/*func RemActionPlan(apl ActionPlan, actionTimingId, accountId string) ActionPlan {
if len(actionTimingId) != 0 && apl.Uuid != actionTimingId { // No Match for ActionPlanId, no need to move further
continue
}
for idx, ats := range apl.ActionTimings {
if len(accountId) == 0 { // No account defined, considered match for complete removal
if len(ats) == 1 { // Removing last item, by init empty
return make([]*ActionPlan, 0)
}
ats[idx], ats = ats[len(ats)-1], ats[:len(ats)-1]
continue
}
for iAcc, accID := range at.AccountIds {
if accID == accountId {
if len(at.AccountIds) == 1 { // Only one balance, remove complete at
if len(ats) == 1 { // Removing last item, by init empty
return make([]*ActionPlan, 0)
}
ats[idx], ats = ats[len(ats)-1], ats[:len(ats)-1]
} else {
at.AccountIds[iAcc], at.AccountIds = at.AccountIds[len(at.AccountIds)-1], at.AccountIds[:len(at.AccountIds)-1]
}
// only remove the first one matching
break
}
}
}
return ats
}*/

View File

@@ -987,7 +987,6 @@ func TestLoadActionTimings(t *testing.T) {
}
atm := csvr.actionPlans["MORE_MINUTES"]
expected := &ActionPlan{
Uuid: atm.Uuid,
Id: "MORE_MINUTES",
AccountIDs: map[string]struct{}{"vdf:minitsboy": struct{}{}},
ActionTimings: []*ActionTiming{

View File

@@ -578,8 +578,7 @@ func (tpr *TpReader) LoadActionPlans() (err error) {
var actPln *ActionPlan
if actPln, exists = tpr.actionPlans[atId]; !exists {
actPln = &ActionPlan{
Uuid: utils.GenUUID(),
Id: atId,
Id: atId,
}
}
actPln.ActionTimings = append(actPln.ActionTimings, &ActionTiming{
@@ -710,8 +709,7 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error
}
if actionPlan == nil {
actionPlan = &ActionPlan{
Uuid: utils.GenUUID(),
Id: accountAction.ActionPlanId,
Id: accountAction.ActionPlanId,
}
}
actionPlan.ActionTimings = append(actionPlan.ActionTimings, &ActionTiming{

View File

@@ -74,10 +74,10 @@ ENABLE_ACNT,*enable_account,,,,,,,,,,,,,false,10`
func TestAcntActsDisableAcnt(t *testing.T) {
acnt1Tag := "cgrates.org:1"
at := &engine.ActionPlan{
AccountIds: []string{acnt1Tag},
ActionsId: "DISABLE_ACNT",
at := &engine.ActionTiming{
ActionsID: "DISABLE_ACNT",
}
at.SetAccountIDs(map[string]struct{}{acnt1Tag: struct{}{}})
if err := at.Execute(); err != nil {
t.Error(err)
}
@@ -92,9 +92,9 @@ func TestAcntActsDisableAcnt(t *testing.T) {
func TestAcntActsEnableAcnt(t *testing.T) {
acnt1Tag := "cgrates.org:1"
at := &engine.ActionPlan{
AccountIds: []string{acnt1Tag},
ActionsId: "ENABLE_ACNT",
ActionsID: "ENABLE_ACNT",
}
at.SetAccountIDs(map[string]struct{}{acnt1Tag: struct{}{}})
if err := at.Execute(); err != nil {
t.Error(err)
}

View File

@@ -34,8 +34,6 @@ type Scheduler struct {
restartLoop chan bool
sync.Mutex
storage engine.RatingStorage
waitingReload bool
loopChecker chan int
schedulerStarted bool
}
@@ -43,7 +41,6 @@ func NewScheduler(storage engine.RatingStorage) *Scheduler {
return &Scheduler{
restartLoop: make(chan bool),
storage: storage,
loopChecker: make(chan int),
}
}
@@ -91,35 +88,13 @@ func (s *Scheduler) Loop() {
}
func (s *Scheduler) Reload(protect bool) {
s.Lock()
defer s.Unlock()
if protect {
if s.waitingReload {
s.loopChecker <- 1
}
s.waitingReload = true
go func() {
t := time.NewTicker(100 * time.Millisecond) // wait for loops before start
select {
case <-s.loopChecker:
t.Stop() // cancel reload
case <-t.C:
s.loadActionPlans()
s.restart()
t.Stop()
s.waitingReload = false
}
}()
} else {
go func() {
s.loadActionPlans()
s.restart()
}()
}
s.loadActionPlans()
s.restart()
}
func (s *Scheduler) loadActionPlans() {
s.Lock()
defer s.Unlock()
// limit the number of concurrent tasks
var limit = make(chan bool, 10)
// execute existing tasks
@@ -141,8 +116,6 @@ func (s *Scheduler) loadActionPlans() {
}
utils.Logger.Info(fmt.Sprintf("<Scheduler> processing %d action plans", len(actionPlans)))
// recreate the queue
s.Lock()
defer s.Unlock()
s.queue = engine.ActionTimingPriorityList{}
for _, actionPlan := range actionPlans {
for _, at := range actionPlan.ActionTimings {

View File

@@ -1099,11 +1099,13 @@ type AttrSetAccount struct {
ActionTriggersId string
AllowNegative *bool
Disabled *bool
ReloadScheduler bool
}
type AttrRemoveAccount struct {
Tenant string
Account string
Tenant string
Account string
ReloadScheduler bool
}
type AttrGetSMASessions struct {