mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 10:06:24 +05:00
updated apis
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}*/
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user