action triggers expiration and activation times

This commit is contained in:
Radu Ioan Fericean
2016-02-04 18:46:06 +02:00
parent c0dd58c438
commit b2a39ed867
18 changed files with 266 additions and 75 deletions

View File

@@ -572,6 +572,11 @@ func (ub *Account) refundIncrement(increment *Increment, cd *CallDescriptor, cou
func (acc *Account) ExecuteActionTriggers(a *Action) {
acc.ActionTriggers.Sort()
for _, at := range acc.ActionTriggers {
// check is effective
if at.IsExpired(time.Now()) || !at.IsActive(time.Now()) {
continue
}
// sanity check
if !strings.Contains(at.ThresholdType, "counter") && !strings.Contains(at.ThresholdType, "balance") {
continue
@@ -623,7 +628,7 @@ func (acc *Account) ExecuteActionTriggers(a *Action) {
}
}
}
acc.CleanExpiredBalances()
acc.CleanExpiredStuff()
}
// Mark all action trigers as ready for execution
@@ -693,7 +698,7 @@ func (acc *Account) InitCounters() {
}
}
func (acc *Account) CleanExpiredBalances() {
func (acc *Account) CleanExpiredStuff() {
for key, bm := range acc.BalanceMap {
for i := 0; i < len(bm); i++ {
if bm[i].IsExpired() {
@@ -703,6 +708,12 @@ func (acc *Account) CleanExpiredBalances() {
}
acc.BalanceMap[key] = bm
}
for i := 0; i < len(acc.ActionTriggers); i++ {
if acc.ActionTriggers[i].IsExpired(time.Now()) {
acc.ActionTriggers = append(acc.ActionTriggers[:i], acc.ActionTriggers[i+1:]...)
}
}
}
func (acc *Account) allBalancesExpired() bool {

View File

@@ -997,7 +997,7 @@ func TestCleanExpired(t *testing.T) {
&Balance{ExpirationDate: time.Now().Add(10 * time.Second)},
}},
}
ub.CleanExpiredBalances()
ub.CleanExpiredStuff()
if len(ub.BalanceMap[utils.MONETARY]) != 2 {
t.Error("Error cleaning expired balances!")
}

View File

@@ -36,6 +36,8 @@ type ActionTrigger struct {
ThresholdValue float64
Recurrent bool // reset excuted flag each run
MinSleep time.Duration // Minimum duration between two executions in case of recurrent triggers
ExpirationDate time.Time
ActivationDate time.Time
BalanceId string
BalanceType string // *monetary/*voice etc
BalanceDirections utils.StringMap // filter for balance
@@ -188,6 +190,14 @@ func (at *ActionTrigger) Equals(oat *ActionTrigger) bool {
return at.ID == oat.ID && at.UniqueID == oat.UniqueID
}
func (at *ActionTrigger) IsActive(t time.Time) bool {
return at.ActivationDate.IsZero() || t.After(at.ActivationDate)
}
func (at *ActionTrigger) IsExpired(t time.Time) bool {
return !at.ExpirationDate.IsZero() && t.After(at.ExpirationDate)
}
// Structure to store actions according to weight
type ActionTriggers []*ActionTrigger

View File

@@ -189,16 +189,16 @@ BLOCK_AT,BLOCK,*asap,10
`
actionTriggers = `
STANDARD_TRIGGER,st0,*min_event_counter,10,false,0,,*voice,*out,,GERMANY_O2,,,,,,,,,SOME_1,10
STANDARD_TRIGGER,st1,*max_balance,200,false,0,,*voice,*out,,GERMANY,,,,,,,,,SOME_2,10
STANDARD_TRIGGERS,,*min_balance,2,false,0,,*monetary,*out,,,,,,,,,,,LOG_WARNING,10
STANDARD_TRIGGERS,,*max_balance,20,false,0,,*monetary,*out,,,,,,,,,,,LOG_WARNING,10
STANDARD_TRIGGERS,,*max_event_counter,5,false,0,,*monetary,*out,,FS_USERS,,,,,,,,,LOG_WARNING,10
CDRST1_WARN_ASR,,*min_asr,45,true,1h,,,,,,,,,,,,,3,CDRST_WARN_HTTP,10
CDRST1_WARN_ACD,,*min_acd,10,true,1h,,,,,,,,,,,,,5,CDRST_WARN_HTTP,10
CDRST1_WARN_ACC,,*max_acc,10,true,10m,,,,,,,,,,,,,5,CDRST_WARN_HTTP,10
CDRST2_WARN_ASR,,*min_asr,30,true,0,,,,,,,,,,,,,5,CDRST_WARN_HTTP,10
CDRST2_WARN_ACD,,*min_acd,3,true,0,,,,,,,,,,,,,5,CDRST_WARN_HTTP,10
STANDARD_TRIGGER,st0,*min_event_counter,10,false,0,,,,*voice,*out,,GERMANY_O2,,,,,,,,,SOME_1,10
STANDARD_TRIGGER,st1,*max_balance,200,false,0,,,,*voice,*out,,GERMANY,,,,,,,,,SOME_2,10
STANDARD_TRIGGERS,,*min_balance,2,false,0,,,,*monetary,*out,,,,,,,,,,,LOG_WARNING,10
STANDARD_TRIGGERS,,*max_balance,20,false,0,,,,*monetary,*out,,,,,,,,,,,LOG_WARNING,10
STANDARD_TRIGGERS,,*max_event_counter,5,false,0,,,,*monetary,*out,,FS_USERS,,,,,,,,,LOG_WARNING,10
CDRST1_WARN_ASR,,*min_asr,45,true,1h,,,,,,,,,,,,,,,3,CDRST_WARN_HTTP,10
CDRST1_WARN_ACD,,*min_acd,10,true,1h,,,,,,,,,,,,,,,5,CDRST_WARN_HTTP,10
CDRST1_WARN_ACC,,*max_acc,10,true,10m,,,,,,,,,,,,,,,5,CDRST_WARN_HTTP,10
CDRST2_WARN_ASR,,*min_asr,30,true,0,,,,,,,,,,,,,,,5,CDRST_WARN_HTTP,10
CDRST2_WARN_ACD,,*min_acd,3,true,0,,,,,,,,,,,,,,,5,CDRST_WARN_HTTP,10
`
accountActions = `
vdf,minitsboy,MORE_MINUTES,STANDARD_TRIGGER,,

View File

@@ -224,6 +224,8 @@ func APItoModelActionTrigger(ats *utils.TPActionTriggers) (result []TpActionTrig
ThresholdValue: at.ThresholdValue,
Recurrent: at.Recurrent,
MinSleep: at.MinSleep,
ExpiryTime: at.ExpirationDate,
ActivationTime: at.ActivationDate,
BalanceTag: at.BalanceId,
BalanceType: at.BalanceType,
BalanceDirections: at.BalanceDirections,

View File

@@ -430,6 +430,8 @@ func (tps TpActionTriggers) GetActionTriggers() (map[string][]*utils.TPActionTri
ThresholdValue: tpAt.ThresholdValue,
Recurrent: tpAt.Recurrent,
MinSleep: tpAt.MinSleep,
ExpirationDate: tpAt.ExpiryTime,
ActivationDate: tpAt.ActivationTime,
BalanceId: tpAt.BalanceTag,
BalanceType: tpAt.BalanceType,
BalanceDirections: tpAt.BalanceDirections,

View File

@@ -597,8 +597,8 @@ func TestTPActionPlanAsExportSlice(t *testing.T) {
},
}
expectedSlc := [][]string{
[]string{"STANDARD_TRIGGERS", "1", "*min_balance", "2", "false", "0", "b1", "*monetary", "*out", "call", "", "special1", "SHARED_1", "*never", "T1", "0", "false", "false", "0", "LOG_WARNING", "10"},
[]string{"STANDARD_TRIGGERS", "2", "*max_event_counter", "5", "false", "0", "b2", "*monetary", "*out", "call", "FS_USERS", "special1", "SHARED_1", "*never", "T1", "0", "false", "false", "0", "LOG_WARNING", "10"},
[]string{"STANDARD_TRIGGERS", "1", "*min_balance", "2", "false", "0", "", "", "b1", "*monetary", "*out", "call", "", "special1", "SHARED_1", "*never", "T1", "0", "false", "false", "0", "LOG_WARNING", "10"},
[]string{"STANDARD_TRIGGERS", "2", "*max_event_counter", "5", "false", "0", "", "", "b2", "*monetary", "*out", "call", "FS_USERS", "special1", "SHARED_1", "*never", "T1", "0", "false", "false", "0", "LOG_WARNING", "10"},
}
ms := APItoModelActionTrigger(at)
var slc [][]string

View File

@@ -193,21 +193,23 @@ type TpActionTrigger struct {
ThresholdValue float64 `index:"3" re:"\d+\.?\d*"`
Recurrent bool `index:"4" re:"true|false"`
MinSleep string `index:"5" re:"\d+[smh]?"`
BalanceTag string `index:"6" re:"\w+\s*"`
BalanceType string `index:"7" re:"\*\w+"`
BalanceDirections string `index:"8" re:"\*out"`
BalanceCategories string `index:"9" re:""`
BalanceDestinationTags string `index:"10" re:"\w+|\*any"`
BalanceRatingSubject string `index:"11" re:"\w+|\*any"`
BalanceSharedGroups string `index:"12" re:"\w+|\*any"`
BalanceExpiryTime string `index:"13" re:"\*\w+\s*|\+\d+[smh]\s*|\d+\s*"`
BalanceTimingTags string `index:"14" re:"[0-9A-Za-z_;]*|\*any"`
BalanceWeight float64 `index:"15" re:"\d+\.?\d*"`
BalanceBlocker bool `index:"16" re:""`
BalanceDisabled bool `index:"17" re:""`
MinQueuedItems int `index:"18" re:"\d+"`
ActionsTag string `index:"19" re:"\w+"`
Weight float64 `index:"20" re:"\d+\.?\d*"`
ExpiryTime string `index:"6" re:""`
ActivationTime string `index:"7" re:""`
BalanceTag string `index:"8" re:"\w+\s*"`
BalanceType string `index:"9" re:"\*\w+"`
BalanceDirections string `index:"10" re:"\*out"`
BalanceCategories string `index:"11" re:""`
BalanceDestinationTags string `index:"12" re:"\w+|\*any"`
BalanceRatingSubject string `index:"13" re:"\w+|\*any"`
BalanceSharedGroups string `index:"14" re:"\w+|\*any"`
BalanceExpiryTime string `index:"15" re:"\*\w+\s*|\+\d+[smh]\s*|\d+\s*"`
BalanceTimingTags string `index:"16" re:"[0-9A-Za-z_;]*|\*any"`
BalanceWeight float64 `index:"17" re:"\d+\.?\d*"`
BalanceBlocker bool `index:"18" re:""`
BalanceDisabled bool `index:"19" re:""`
MinQueuedItems int `index:"20" re:"\d+"`
ActionsTag string `index:"21" re:"\w+"`
Weight float64 `index:"22" re:"\d+\.?\d*"`
CreatedAt time.Time
}

View File

@@ -625,7 +625,18 @@ func (tpr *TpReader) LoadActionTriggers() (err error) {
for key, atrsLst := range storAts {
atrs := make([]*ActionTrigger, len(atrsLst))
for idx, atr := range atrsLst {
balanceExpirationDate, _ := utils.ParseTimeDetectLayout(atr.BalanceExpirationDate, tpr.timezone)
balanceExpirationDate, err := utils.ParseTimeDetectLayout(atr.BalanceExpirationDate, tpr.timezone)
if err != nil {
return err
}
expirationDate, err := utils.ParseTimeDetectLayout(atr.ExpirationDate, tpr.timezone)
if err != nil {
return err
}
activationDate, err := utils.ParseTimeDetectLayout(atr.ActivationDate, tpr.timezone)
if err != nil {
return err
}
minSleep, err := utils.ParseDurationWithSecs(atr.MinSleep)
if err != nil {
return err
@@ -640,6 +651,8 @@ func (tpr *TpReader) LoadActionTriggers() (err error) {
ThresholdValue: atr.ThresholdValue,
Recurrent: atr.Recurrent,
MinSleep: minSleep,
ExpirationDate: expirationDate,
ActivationDate: activationDate,
BalanceId: atr.BalanceId,
BalanceType: atr.BalanceType,
BalanceDirections: utils.ParseStringMap(atr.BalanceDirections),
@@ -783,7 +796,9 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error
atrs := make([]*ActionTrigger, len(atrsLst))
for idx, apiAtr := range atrsLst {
minSleep, _ := utils.ParseDurationWithSecs(apiAtr.MinSleep)
expTime, _ := utils.ParseDate(apiAtr.BalanceExpirationDate)
balanceExpTime, _ := utils.ParseDate(apiAtr.BalanceExpirationDate)
expTime, _ := utils.ParseDate(apiAtr.ExpirationDate)
actTime, _ := utils.ParseDate(apiAtr.ActivationDate)
if apiAtr.UniqueID == "" {
apiAtr.UniqueID = utils.GenUUID()
}
@@ -794,12 +809,14 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error
ThresholdValue: apiAtr.ThresholdValue,
Recurrent: apiAtr.Recurrent,
MinSleep: minSleep,
ExpirationDate: expTime,
ActivationDate: actTime,
BalanceId: apiAtr.BalanceId,
BalanceType: apiAtr.BalanceType,
BalanceDirections: utils.ParseStringMap(apiAtr.BalanceDirections),
BalanceDestinationIds: utils.ParseStringMap(apiAtr.BalanceDestinationIds),
BalanceWeight: apiAtr.BalanceWeight,
BalanceExpirationDate: expTime,
BalanceExpirationDate: balanceExpTime,
BalanceTimingTags: utils.ParseStringMap(apiAtr.BalanceTimingTags),
BalanceRatingSubject: apiAtr.BalanceRatingSubject,
BalanceCategories: utils.ParseStringMap(apiAtr.BalanceCategories),
@@ -1012,7 +1029,9 @@ func (tpr *TpReader) LoadCdrStatsFiltered(tag string, save bool) (err error) {
atrs := make([]*ActionTrigger, len(atrsLst))
for idx, apiAtr := range atrsLst {
minSleep, _ := utils.ParseDurationWithSecs(apiAtr.MinSleep)
expTime, _ := utils.ParseDate(apiAtr.BalanceExpirationDate)
balanceExpTime, _ := utils.ParseDate(apiAtr.BalanceExpirationDate)
expTime, _ := utils.ParseDate(apiAtr.ExpirationDate)
actTime, _ := utils.ParseDate(apiAtr.ActivationDate)
if apiAtr.UniqueID == "" {
apiAtr.UniqueID = utils.GenUUID()
}
@@ -1023,12 +1042,14 @@ func (tpr *TpReader) LoadCdrStatsFiltered(tag string, save bool) (err error) {
ThresholdValue: apiAtr.ThresholdValue,
Recurrent: apiAtr.Recurrent,
MinSleep: minSleep,
ExpirationDate: expTime,
ActivationDate: actTime,
BalanceId: apiAtr.BalanceId,
BalanceType: apiAtr.BalanceType,
BalanceDirections: utils.ParseStringMap(apiAtr.BalanceDirections),
BalanceDestinationIds: utils.ParseStringMap(apiAtr.BalanceDestinationIds),
BalanceWeight: apiAtr.BalanceWeight,
BalanceExpirationDate: expTime,
BalanceExpirationDate: balanceExpTime,
BalanceRatingSubject: apiAtr.BalanceRatingSubject,
BalanceCategories: utils.ParseStringMap(apiAtr.BalanceCategories),
BalanceSharedGroups: utils.ParseStringMap(apiAtr.BalanceSharedGroups),