From 2dd3f6527d0caddfc9abaae3352ca8c8e110fd97 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Thu, 4 Dec 2014 19:37:47 +0200 Subject: [PATCH] added balance tag for action triggers also chenged the names of direction and destination params (prefixxed with balance) --- apier/v1/apier.go | 20 ++++--- apier/v1/apier_local_test.go | 6 +- engine/account.go | 4 +- engine/account_test.go | 6 +- engine/action_trigger.go | 21 +++---- engine/actions_test.go | 92 +++++++++++++++--------------- engine/balances.go | 13 ++++- engine/balances_test.go | 25 +++++++- engine/loader_csv.go | 7 ++- engine/loader_csv_test.go | 56 +++++++++--------- engine/loader_db.go | 28 +++++---- engine/loader_helpers.go | 1 + engine/models.go | 39 +++++++------ engine/storage_mysql_local_test.go | 16 +++--- engine/storage_psql_local_test.go | 16 +++--- engine/storage_sql.go | 44 +++++++------- engine/storage_test.go | 14 ++--- engine/tpimporter_csv.go | 9 +-- utils/apitpdata.go | 13 +++-- utils/apitpdata_test.go | 18 +++--- utils/consts.go | 2 +- 21 files changed, 249 insertions(+), 201 deletions(-) diff --git a/apier/v1/apier.go b/apier/v1/apier.go index 0a04b5f08..faf556dc8 100644 --- a/apier/v1/apier.go +++ b/apier/v1/apier.go @@ -565,11 +565,12 @@ func (self *ApierV1) SetActionPlan(attrs AttrSetActionPlan, reply *string) error type AttrAddActionTrigger struct { Tenant string Account string - Direction string - BalanceType string ThresholdType string ThresholdValue float64 - DestinationId string + BalanceId string + BalanceType string + BalanceDirection string + BalanceDestinationId string BalanceRatingSubject string //ToDo BalanceWeight float64 BalanceExpiryTime string @@ -579,8 +580,8 @@ type AttrAddActionTrigger struct { } func (self *ApierV1) AddTriggeredAction(attr AttrAddActionTrigger, reply *string) error { - if attr.Direction == "" { - attr.Direction = engine.OUTBOUND + if attr.BalanceDirection == "" { + attr.BalanceDirection = engine.OUTBOUND } balExpiryTime, err := utils.ParseTimeDetectLayout(attr.BalanceExpiryTime) if err != nil { @@ -588,11 +589,12 @@ func (self *ApierV1) AddTriggeredAction(attr AttrAddActionTrigger, reply *string } at := &engine.ActionTrigger{ Id: utils.GenUUID(), - BalanceType: attr.BalanceType, - Direction: attr.Direction, ThresholdType: attr.ThresholdType, ThresholdValue: attr.ThresholdValue, - DestinationId: attr.DestinationId, + BalanceId: attr.BalanceId, + BalanceType: attr.BalanceType, + BalanceDirection: attr.BalanceDirection, + BalanceDestinationId: attr.BalanceDestinationId, BalanceWeight: attr.BalanceWeight, BalanceExpirationDate: balExpiryTime, Weight: attr.Weight, @@ -600,7 +602,7 @@ func (self *ApierV1) AddTriggeredAction(attr AttrAddActionTrigger, reply *string Executed: false, } - tag := utils.AccountKey(attr.Tenant, attr.Account, attr.Direction) + tag := utils.AccountKey(attr.Tenant, attr.Account, attr.BalanceDirection) _, err = engine.AccLock.Guard(tag, func() (float64, error) { userBalance, err := self.AccountDb.GetAccount(tag) if err != nil { diff --git a/apier/v1/apier_local_test.go b/apier/v1/apier_local_test.go index 9b77d30d0..618fea66e 100644 --- a/apier/v1/apier_local_test.go +++ b/apier/v1/apier_local_test.go @@ -621,7 +621,7 @@ func TestApierTPActionTriggers(t *testing.T) { } reply := "" at := &utils.TPActionTriggers{TPid: engine.TEST_SQL, ActionTriggersId: "STANDARD_TRIGGERS", ActionTriggers: []*utils.TPActionTrigger{ - &utils.TPActionTrigger{BalanceType: "*monetary", Direction: "*out", ThresholdType: "*min_balance", ThresholdValue: 2, ActionsId: "LOG_BALANCE", Weight: 10}, + &utils.TPActionTrigger{BalanceType: "*monetary", BalanceDirection: "*out", ThresholdType: "*min_balance", ThresholdValue: 2, ActionsId: "LOG_BALANCE", Weight: 10}, }} atTst := new(utils.TPActionTriggers) *atTst = *at @@ -1049,8 +1049,8 @@ func TestApierAddTriggeredAction(t *testing.T) { } reply := "" // Add balance to a previously known account - attrs := &AttrAddActionTrigger{Tenant: "cgrates.org", Account: "dan2", Direction: "*out", BalanceType: "*monetary", - ThresholdType: "*min_balance", ThresholdValue: 2, DestinationId: "*any", Weight: 10, ActionsId: "WARN_VIA_HTTP"} + attrs := &AttrAddActionTrigger{Tenant: "cgrates.org", Account: "dan2", BalanceDirection: "*out", BalanceType: "*monetary", + ThresholdType: "*min_balance", ThresholdValue: 2, BalanceDestinationId: "*any", Weight: 10, ActionsId: "WARN_VIA_HTTP"} if err := rater.Call("ApierV1.AddTriggeredAction", attrs, &reply); err != nil { t.Error("Got error on ApierV1.AddTriggeredAction: ", err.Error()) } else if reply != "OK" { diff --git a/engine/account.go b/engine/account.go index 4cff41e34..657b31360 100644 --- a/engine/account.go +++ b/engine/account.go @@ -363,7 +363,7 @@ func (ub *Account) executeActionTriggers(a *Action) { } } } else { // BALANCE - for _, b := range ub.BalanceMap[at.BalanceType+at.Direction] { + for _, b := range ub.BalanceMap[at.BalanceType+at.BalanceDirection] { if !b.dirty { // do not check clean balances continue } @@ -447,7 +447,7 @@ func (ub *Account) initCounters() { } for _, a := range acs { if a.Balance != nil { - direction := at.Direction + direction := at.BalanceDirection if direction == "" { direction = OUTBOUND } diff --git a/engine/account_test.go b/engine/account_test.go index 12a73efd0..1129ec08f 100644 --- a/engine/account_test.go +++ b/engine/account_test.go @@ -835,7 +835,7 @@ func TestAccountExecuteTriggeredActions(t *testing.T) { Id: "TEST_UB", BalanceMap: map[string]BalanceChain{CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 100}}, MINUTES + OUTBOUND: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationId: "NAT"}, &Balance{Weight: 10, DestinationId: "RET"}}}, UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceType: CREDIT, Direction: OUTBOUND, Balances: BalanceChain{&Balance{Value: 1}}}}, - ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ThresholdType: TRIGGER_MAX_COUNTER, ActionsId: "TEST_ACTIONS"}}, + ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: CREDIT, BalanceDirection: OUTBOUND, ThresholdValue: 2, ThresholdType: TRIGGER_MAX_COUNTER, ActionsId: "TEST_ACTIONS"}}, } ub.countUnits(&Action{BalanceType: CREDIT, Balance: &Balance{Value: 1}}) if ub.BalanceMap[CREDIT+OUTBOUND][0].Value != 110 || ub.BalanceMap[MINUTES+OUTBOUND][0].Value != 20 { @@ -859,7 +859,7 @@ func TestAccountExecuteTriggeredActionsBalance(t *testing.T) { Id: "TEST_UB", BalanceMap: map[string]BalanceChain{CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 100}}, MINUTES + OUTBOUND: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationId: "NAT"}, &Balance{Weight: 10, DestinationId: "RET"}}}, UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceType: CREDIT, Direction: OUTBOUND, Balances: BalanceChain{&Balance{Value: 1}}}}, - ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: CREDIT, Direction: OUTBOUND, ThresholdValue: 100, ThresholdType: TRIGGER_MIN_COUNTER, ActionsId: "TEST_ACTIONS"}}, + ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: CREDIT, BalanceDirection: OUTBOUND, ThresholdValue: 100, ThresholdType: TRIGGER_MIN_COUNTER, ActionsId: "TEST_ACTIONS"}}, } ub.countUnits(&Action{BalanceType: CREDIT, Balance: &Balance{Value: 1}}) if ub.BalanceMap[CREDIT+OUTBOUND][0].Value != 110 || ub.BalanceMap[MINUTES+OUTBOUND][0].Value != 20 { @@ -872,7 +872,7 @@ func TestAccountExecuteTriggeredActionsOrder(t *testing.T) { Id: "TEST_UB_OREDER", BalanceMap: map[string]BalanceChain{CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 100}}}, UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceType: CREDIT, Direction: OUTBOUND, Balances: BalanceChain{&Balance{Value: 1}}}}, - ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ThresholdType: TRIGGER_MAX_COUNTER, ActionsId: "TEST_ACTIONS_ORDER"}}, + ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: CREDIT, BalanceDirection: OUTBOUND, ThresholdValue: 2, ThresholdType: TRIGGER_MAX_COUNTER, ActionsId: "TEST_ACTIONS_ORDER"}}, } ub.countUnits(&Action{BalanceType: CREDIT, Direction: OUTBOUND, Balance: &Balance{Value: 1}}) if len(ub.BalanceMap[CREDIT+OUTBOUND]) != 1 || ub.BalanceMap[CREDIT+OUTBOUND][0].Value != 10 { diff --git a/engine/action_trigger.go b/engine/action_trigger.go index 1acacabe2..059558593 100644 --- a/engine/action_trigger.go +++ b/engine/action_trigger.go @@ -29,19 +29,20 @@ import ( type ActionTrigger struct { Id string // uniquely identify the trigger - BalanceType string - Direction string ThresholdType string //*min_counter, *max_counter, *min_balance, *max_balance // stats: *min_asr, *max_asr, *min_acd, *max_acd, *min_acc, *max_acc ThresholdValue float64 Recurrent bool // reset eexcuted flag each run MinSleep time.Duration // Minimum duration between two executions in case of recurrent triggers - DestinationId string // filter for balance - BalanceWeight float64 // filter for balance - BalanceExpirationDate time.Time // filter for balance - BalanceRatingSubject string // filter for balance - BalanceCategory string // filter for balance - BalanceSharedGroup string // filter for balance + BalanceId string + BalanceType string + BalanceDirection string + BalanceDestinationId string // filter for balance + BalanceWeight float64 // filter for balance + BalanceExpirationDate time.Time // filter for balance + BalanceRatingSubject string // filter for balance + BalanceCategory string // filter for balance + BalanceSharedGroup string // filter for balance Weight float64 ActionsId string MinQueuedItems int // Trigger actions only if this number is hit (stats only) @@ -101,7 +102,7 @@ func (at *ActionTrigger) Match(a *Action) bool { return true } id := a.BalanceType == "" || at.BalanceType == a.BalanceType - direction := a.Direction == "" || at.Direction == a.Direction + direction := a.Direction == "" || at.BalanceDirection == a.Direction thresholdType, thresholdValue, destinationId, weight, ratingSubject, category, sharedGroup := true, true, true, true, true, true, true if a.ExtraParameters != "" { t := struct { @@ -116,7 +117,7 @@ func (at *ActionTrigger) Match(a *Action) bool { json.Unmarshal([]byte(a.ExtraParameters), &t) thresholdType = t.ThresholdType == "" || at.ThresholdType == t.ThresholdType thresholdValue = t.ThresholdValue == 0 || at.ThresholdValue == t.ThresholdValue - destinationId = t.DestinationId == "" || at.DestinationId == t.DestinationId + destinationId = t.DestinationId == "" || at.BalanceDestinationId == t.DestinationId weight = t.BalanceWeight == 0 || at.BalanceWeight == t.BalanceWeight ratingSubject = t.BalanceRatingSubject == "" || at.BalanceRatingSubject == t.BalanceRatingSubject category = t.BalanceCategory == "" || at.BalanceCategory == t.BalanceCategory diff --git a/engine/actions_test.go b/engine/actions_test.go index 15c88a518..694586cc9 100644 --- a/engine/actions_test.go +++ b/engine/actions_test.go @@ -513,10 +513,10 @@ func TestActionTimingsRemoveMember(t *testing.T) { func TestActionTriggerMatchNil(t *testing.T) { at := &ActionTrigger{ - Direction: OUTBOUND, - BalanceType: CREDIT, - ThresholdType: TRIGGER_MAX_BALANCE, - ThresholdValue: 2, + BalanceDirection: OUTBOUND, + BalanceType: CREDIT, + ThresholdType: TRIGGER_MAX_BALANCE, + ThresholdValue: 2, } var a *Action if !at.Match(a) { @@ -526,10 +526,10 @@ func TestActionTriggerMatchNil(t *testing.T) { func TestActionTriggerMatchAllBlank(t *testing.T) { at := &ActionTrigger{ - Direction: OUTBOUND, - BalanceType: CREDIT, - ThresholdType: TRIGGER_MAX_BALANCE, - ThresholdValue: 2, + BalanceDirection: OUTBOUND, + BalanceType: CREDIT, + ThresholdType: TRIGGER_MAX_BALANCE, + ThresholdValue: 2, } a := &Action{} if !at.Match(a) { @@ -539,10 +539,10 @@ func TestActionTriggerMatchAllBlank(t *testing.T) { func TestActionTriggerMatchMinuteBucketBlank(t *testing.T) { at := &ActionTrigger{ - Direction: OUTBOUND, - BalanceType: CREDIT, - ThresholdType: TRIGGER_MAX_BALANCE, - ThresholdValue: 2, + BalanceDirection: OUTBOUND, + BalanceType: CREDIT, + ThresholdType: TRIGGER_MAX_BALANCE, + ThresholdValue: 2, } a := &Action{Direction: OUTBOUND, BalanceType: CREDIT} if !at.Match(a) { @@ -552,10 +552,10 @@ func TestActionTriggerMatchMinuteBucketBlank(t *testing.T) { func TestActionTriggerMatchMinuteBucketFull(t *testing.T) { at := &ActionTrigger{ - Direction: OUTBOUND, - BalanceType: CREDIT, - ThresholdType: TRIGGER_MAX_BALANCE, - ThresholdValue: 2, + BalanceDirection: OUTBOUND, + BalanceType: CREDIT, + ThresholdType: TRIGGER_MAX_BALANCE, + ThresholdValue: 2, } a := &Action{ExtraParameters: fmt.Sprintf(`{"ThresholdType":"%v", "ThresholdValue": %v}`, TRIGGER_MAX_BALANCE, 2)} if !at.Match(a) { @@ -565,10 +565,10 @@ func TestActionTriggerMatchMinuteBucketFull(t *testing.T) { func TestActionTriggerMatchAllFull(t *testing.T) { at := &ActionTrigger{ - Direction: OUTBOUND, - BalanceType: CREDIT, - ThresholdType: TRIGGER_MAX_BALANCE, - ThresholdValue: 2, + BalanceDirection: OUTBOUND, + BalanceType: CREDIT, + ThresholdType: TRIGGER_MAX_BALANCE, + ThresholdValue: 2, } a := &Action{Direction: OUTBOUND, BalanceType: CREDIT, ExtraParameters: fmt.Sprintf(`{"ThresholdType":"%v", "ThresholdValue": %v}`, TRIGGER_MAX_BALANCE, 2)} if !at.Match(a) { @@ -578,10 +578,10 @@ func TestActionTriggerMatchAllFull(t *testing.T) { func TestActionTriggerMatchSomeFalse(t *testing.T) { at := &ActionTrigger{ - Direction: OUTBOUND, - BalanceType: CREDIT, - ThresholdType: TRIGGER_MAX_BALANCE, - ThresholdValue: 2, + BalanceDirection: OUTBOUND, + BalanceType: CREDIT, + ThresholdType: TRIGGER_MAX_BALANCE, + ThresholdValue: 2, } a := &Action{Direction: INBOUND, BalanceType: CREDIT, ExtraParameters: fmt.Sprintf(`{"ThresholdType":"%v", "ThresholdValue": %v}`, TRIGGER_MAX_BALANCE, 2)} if at.Match(a) { @@ -591,10 +591,10 @@ func TestActionTriggerMatchSomeFalse(t *testing.T) { func TestActionTriggerMatcBalanceFalse(t *testing.T) { at := &ActionTrigger{ - Direction: OUTBOUND, - BalanceType: CREDIT, - ThresholdType: TRIGGER_MAX_BALANCE, - ThresholdValue: 2, + BalanceDirection: OUTBOUND, + BalanceType: CREDIT, + ThresholdType: TRIGGER_MAX_BALANCE, + ThresholdValue: 2, } a := &Action{Direction: OUTBOUND, BalanceType: CREDIT, ExtraParameters: fmt.Sprintf(`{"ThresholdType":"%v", "ThresholdValue": %v}`, TRIGGER_MAX_BALANCE, 3.0)} if at.Match(a) { @@ -604,10 +604,10 @@ func TestActionTriggerMatcBalanceFalse(t *testing.T) { func TestActionTriggerMatcAllFalse(t *testing.T) { at := &ActionTrigger{ - Direction: OUTBOUND, - BalanceType: CREDIT, - ThresholdType: TRIGGER_MAX_BALANCE, - ThresholdValue: 2, + BalanceDirection: OUTBOUND, + BalanceType: CREDIT, + ThresholdType: TRIGGER_MAX_BALANCE, + ThresholdValue: 2, } a := &Action{Direction: INBOUND, BalanceType: MINUTES, ExtraParameters: fmt.Sprintf(`{"ThresholdType":"%v", "ThresholdValue": %v}`, TRIGGER_MAX_COUNTER, 3)} if at.Match(a) { @@ -617,11 +617,11 @@ func TestActionTriggerMatcAllFalse(t *testing.T) { func TestActionTriggerMatchAll(t *testing.T) { at := &ActionTrigger{ - Direction: OUTBOUND, + BalanceDirection: OUTBOUND, BalanceType: CREDIT, ThresholdType: TRIGGER_MAX_BALANCE, ThresholdValue: 2, - DestinationId: "NAT", + BalanceDestinationId: "NAT", BalanceWeight: 1.0, BalanceRatingSubject: "test1", BalanceSharedGroup: "test2", @@ -750,7 +750,7 @@ func TestActionTopupResetCredit(t *testing.T) { Id: "TEST_UB", BalanceMap: map[string]BalanceChain{CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 100}}, MINUTES + OUTBOUND: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationId: "NAT"}, &Balance{Weight: 10, DestinationId: "RET"}}}, UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceType: CREDIT, Direction: OUTBOUND, Balances: BalanceChain{&Balance{Value: 1}}}}, - ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, + ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: CREDIT, BalanceDirection: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: CREDIT, BalanceDirection: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } a := &Action{BalanceType: CREDIT, Direction: OUTBOUND, Balance: &Balance{Value: 10}} topupResetAction(ub, nil, a) @@ -770,7 +770,7 @@ func TestActionTopupResetMinutes(t *testing.T) { CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 100}}, MINUTES + OUTBOUND: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationId: "NAT"}, &Balance{Weight: 10, DestinationId: "RET"}}}, UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceType: CREDIT, Direction: OUTBOUND, Balances: BalanceChain{&Balance{Value: 1}}}}, - ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, + ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: CREDIT, BalanceDirection: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: CREDIT, BalanceDirection: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } a := &Action{BalanceType: MINUTES, Direction: OUTBOUND, Balance: &Balance{Value: 5, Weight: 20, DestinationId: "NAT"}} topupResetAction(ub, nil, a) @@ -789,7 +789,7 @@ func TestActionTopupCredit(t *testing.T) { Id: "TEST_UB", BalanceMap: map[string]BalanceChain{CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 100}}, MINUTES + OUTBOUND: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationId: "NAT"}, &Balance{Weight: 10, DestinationId: "RET"}}}, UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceType: CREDIT, Direction: OUTBOUND, Balances: BalanceChain{&Balance{Value: 1}}}}, - ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, + ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: CREDIT, BalanceDirection: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: CREDIT, BalanceDirection: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } a := &Action{BalanceType: CREDIT, Direction: OUTBOUND, Balance: &Balance{Value: 10}} topupAction(ub, nil, a) @@ -826,7 +826,7 @@ func TestActionDebitCredit(t *testing.T) { Id: "TEST_UB", BalanceMap: map[string]BalanceChain{CREDIT + OUTBOUND: BalanceChain{&Balance{Value: 100}}, MINUTES + OUTBOUND: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationId: "NAT"}, &Balance{Weight: 10, DestinationId: "RET"}}}, UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceType: CREDIT, Direction: OUTBOUND, Balances: BalanceChain{&Balance{Value: 1}}}}, - ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, + ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: CREDIT, BalanceDirection: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: CREDIT, BalanceDirection: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } a := &Action{BalanceType: CREDIT, Direction: OUTBOUND, Balance: &Balance{Value: 10}} debitAction(ub, nil, a) @@ -926,7 +926,7 @@ func TestActionResetCounterCREDIT(t *testing.T) { AllowNegative: true, BalanceMap: map[string]BalanceChain{CREDIT: BalanceChain{&Balance{Value: 100}}, MINUTES + OUTBOUND: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationId: "NAT"}, &Balance{Weight: 10, DestinationId: "RET"}}}, UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceType: CREDIT, Direction: OUTBOUND, Balances: BalanceChain{&Balance{Value: 1}}}, &UnitsCounter{BalanceType: SMS, Direction: OUTBOUND, Balances: BalanceChain{&Balance{Value: 1}}}}, - ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: CREDIT, Direction: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, + ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: CREDIT, BalanceDirection: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } a := &Action{BalanceType: CREDIT, Direction: OUTBOUND} resetCounterAction(ub, nil, a) @@ -941,13 +941,13 @@ func TestActionResetCounterCREDIT(t *testing.T) { func TestActionTriggerLogging(t *testing.T) { at := &ActionTrigger{ - Id: "some_uuid", - BalanceType: CREDIT, - Direction: OUTBOUND, - ThresholdValue: 100.0, - DestinationId: "NAT", - Weight: 10.0, - ActionsId: "TEST_ACTIONS", + Id: "some_uuid", + BalanceType: CREDIT, + BalanceDirection: OUTBOUND, + ThresholdValue: 100.0, + BalanceDestinationId: "NAT", + Weight: 10.0, + ActionsId: "TEST_ACTIONS", } as, err := accountingStorage.GetActions(at.ActionsId, false) if err != nil { diff --git a/engine/balances.go b/engine/balances.go index 86b64674e..fb931d54d 100644 --- a/engine/balances.go +++ b/engine/balances.go @@ -28,7 +28,8 @@ import ( // Can hold different units as seconds or monetary type Balance struct { - Uuid string + Uuid string //system wide unique + Id string // account wide unique Value float64 ExpirationDate time.Time Weight float64 @@ -42,6 +43,9 @@ type Balance struct { } func (b *Balance) Equal(o *Balance) bool { + if b.Id != "" || o.Id != "" { + return b.Id == o.Id + } if b.DestinationId == "" { b.DestinationId = utils.ANY } @@ -82,9 +86,12 @@ func (b *Balance) MatchDestination(destinationId string) bool { } func (b *Balance) MatchActionTrigger(at *ActionTrigger) bool { + if at.BalanceId != "" { + return b.Id == at.BalanceId + } matchesDestination := true - if at.DestinationId != "" { - matchesDestination = (at.DestinationId == b.DestinationId) + if at.BalanceDestinationId != "" { + matchesDestination = (at.BalanceDestinationId == b.DestinationId) } matchesExpirationDate := true if !at.BalanceExpirationDate.IsZero() { diff --git a/engine/balances_test.go b/engine/balances_test.go index 577c26d3b..de41086ff 100644 --- a/engine/balances_test.go +++ b/engine/balances_test.go @@ -95,8 +95,29 @@ func TestBalanceClone(t *testing.T) { } } +func TestBalanceMatchActionTriggerId(t *testing.T) { + at := &ActionTrigger{BalanceId: "test"} + b := &Balance{Id: "test"} + if !b.MatchActionTrigger(at) { + t.Errorf("Error matching action trigger: %+v %+v", b, at) + } + b.Id = "test1" + if b.MatchActionTrigger(at) { + t.Errorf("Error matching action trigger: %+v %+v", b, at) + } + b.Id = "" + if b.MatchActionTrigger(at) { + t.Errorf("Error matching action trigger: %+v %+v", b, at) + } + b.Id = "test" + at.BalanceId = "" + if !b.MatchActionTrigger(at) { + t.Errorf("Error matching action trigger: %+v %+v", b, at) + } +} + func TestBalanceMatchActionTriggerDestination(t *testing.T) { - at := &ActionTrigger{DestinationId: "test"} + at := &ActionTrigger{BalanceDestinationId: "test"} b := &Balance{DestinationId: "test"} if !b.MatchActionTrigger(at) { t.Errorf("Error matching action trigger: %+v %+v", b, at) @@ -110,7 +131,7 @@ func TestBalanceMatchActionTriggerDestination(t *testing.T) { t.Errorf("Error matching action trigger: %+v %+v", b, at) } b.DestinationId = "test" - at.DestinationId = "" + at.BalanceDestinationId = "" if !b.MatchActionTrigger(at) { t.Errorf("Error matching action trigger: %+v %+v", b, at) } diff --git a/engine/loader_csv.go b/engine/loader_csv.go index b87c3500a..97ff1903f 100644 --- a/engine/loader_csv.go +++ b/engine/loader_csv.go @@ -796,13 +796,14 @@ func (csvr *CSVReader) LoadActionTriggers() (err error) { at := &ActionTrigger{ Id: utils.GenUUID(), - BalanceType: record[ATRIGCSVIDX_BAL_TYPE], - Direction: record[ATRIGCSVIDX_BAL_DIRECTION], ThresholdType: record[ATRIGCSVIDX_THRESHOLD_TYPE], ThresholdValue: value, Recurrent: recurrent, MinSleep: minSleep, - DestinationId: record[ATRIGCSVIDX_BAL_DESTINATION_TAG], + BalanceId: record[ATRIGCSVIDX_BAL_TAG], + BalanceType: record[ATRIGCSVIDX_BAL_TYPE], + BalanceDirection: record[ATRIGCSVIDX_BAL_DIRECTION], + BalanceDestinationId: record[ATRIGCSVIDX_BAL_DESTINATION_TAG], BalanceWeight: balanceWeight, BalanceExpirationDate: balanceExp, BalanceRatingSubject: record[ATRIGCSVIDX_BAL_RATING_SUBJECT], diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 0966f3e9b..666eadf8b 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -162,16 +162,16 @@ TOPUP_EMPTY_AT,EE0,ASAP,10 ` actionTriggers = ` -STANDARD_TRIGGER,*min_counter,10,false,0,*voice,*out,,GERMANY_O2,,,,,,SOME_1,10 -STANDARD_TRIGGER,*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_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,*min_counter,10,false,0,,*voice,*out,,GERMANY_O2,,,,,,SOME_1,10 +STANDARD_TRIGGER,*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_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;a1;a2,*out,MORE_MINUTES,STANDARD_TRIGGER @@ -867,30 +867,30 @@ func TestLoadActionTriggers(t *testing.T) { } atr := csvr.actionsTriggers["STANDARD_TRIGGER"][0] expected := &ActionTrigger{ - Id: atr.Id, - BalanceType: MINUTES, - Direction: OUTBOUND, - ThresholdType: TRIGGER_MIN_COUNTER, - ThresholdValue: 10, - DestinationId: "GERMANY_O2", - Weight: 10, - ActionsId: "SOME_1", - Executed: false, + Id: atr.Id, + BalanceType: MINUTES, + BalanceDirection: OUTBOUND, + ThresholdType: TRIGGER_MIN_COUNTER, + ThresholdValue: 10, + BalanceDestinationId: "GERMANY_O2", + Weight: 10, + ActionsId: "SOME_1", + Executed: false, } if !reflect.DeepEqual(atr, expected) { t.Error("Error loading action trigger: ", atr) } atr = csvr.actionsTriggers["STANDARD_TRIGGER"][1] expected = &ActionTrigger{ - Id: atr.Id, - BalanceType: MINUTES, - Direction: OUTBOUND, - ThresholdType: TRIGGER_MAX_BALANCE, - ThresholdValue: 200, - DestinationId: "GERMANY", - Weight: 10, - ActionsId: "SOME_2", - Executed: false, + Id: atr.Id, + BalanceType: MINUTES, + BalanceDirection: OUTBOUND, + ThresholdType: TRIGGER_MAX_BALANCE, + ThresholdValue: 200, + BalanceDestinationId: "GERMANY", + Weight: 10, + ActionsId: "SOME_2", + Executed: false, } if !reflect.DeepEqual(atr, expected) { t.Error("Error loading action trigger: ", atr) diff --git a/engine/loader_db.go b/engine/loader_db.go index 265c9a035..329a2245d 100644 --- a/engine/loader_db.go +++ b/engine/loader_db.go @@ -631,13 +631,14 @@ func (dbr *DbReader) LoadActionTriggers() (err error) { balance_expiration_date, _ := utils.ParseTimeDetectLayout(apiAtr.BalanceExpirationDate) atrs[idx] = &ActionTrigger{ Id: utils.GenUUID(), - BalanceType: apiAtr.BalanceType, - Direction: apiAtr.Direction, ThresholdType: apiAtr.ThresholdType, ThresholdValue: apiAtr.ThresholdValue, Recurrent: apiAtr.Recurrent, MinSleep: apiAtr.MinSleep, - DestinationId: apiAtr.DestinationId, + BalanceId: apiAtr.BalanceId, + BalanceType: apiAtr.BalanceType, + BalanceDirection: apiAtr.BalanceDirection, + BalanceDestinationId: apiAtr.BalanceDestinationId, BalanceWeight: apiAtr.BalanceWeight, BalanceExpirationDate: balance_expiration_date, BalanceRatingSubject: apiAtr.BalanceRatingSubject, @@ -782,14 +783,21 @@ func (dbr *DbReader) LoadAccountActionsFiltered(qriedAA *utils.TPAccountActions) for key, atrsLst := range apiAtrsMap { atrs := make([]*ActionTrigger, len(atrsLst)) for idx, apiAtr := range atrsLst { + expTime, _ := utils.ParseDate(apiAtr.BalanceExpirationDate) atrs[idx] = &ActionTrigger{Id: utils.GenUUID(), - BalanceType: apiAtr.BalanceType, - Direction: apiAtr.Direction, - ThresholdType: apiAtr.ThresholdType, - ThresholdValue: apiAtr.ThresholdValue, - DestinationId: apiAtr.DestinationId, - Weight: apiAtr.Weight, - ActionsId: apiAtr.ActionsId, + ThresholdType: apiAtr.ThresholdType, + ThresholdValue: apiAtr.ThresholdValue, + BalanceId: apiAtr.BalanceId, + BalanceType: apiAtr.BalanceType, + BalanceDirection: apiAtr.BalanceDirection, + BalanceDestinationId: apiAtr.BalanceDestinationId, + BalanceWeight: apiAtr.BalanceWeight, + BalanceExpirationDate: expTime, + BalanceRatingSubject: apiAtr.BalanceRatingSubject, + BalanceCategory: apiAtr.BalanceCategory, + BalanceSharedGroup: apiAtr.BalanceSharedGroup, + Weight: apiAtr.Weight, + ActionsId: apiAtr.ActionsId, } } atrsMap[key] = atrs diff --git a/engine/loader_helpers.go b/engine/loader_helpers.go index cda15f142..3c6fb04a9 100644 --- a/engine/loader_helpers.go +++ b/engine/loader_helpers.go @@ -58,6 +58,7 @@ const ( ATRIGCSVIDX_THRESHOLD_VALUE ATRIGCSVIDX_RECURRENT ATRIGCSVIDX_MIN_SLEEP + ATRIGCSVIDX_BAL_TAG ATRIGCSVIDX_BAL_TYPE ATRIGCSVIDX_BAL_DIRECTION ATRIGCSVIDX_BAL_CATEGORY diff --git a/engine/models.go b/engine/models.go index 158ca59dd..387982681 100644 --- a/engine/models.go +++ b/engine/models.go @@ -154,25 +154,26 @@ type TpActionPlan struct { } type TpActionTrigger struct { - Id int64 - Tpid string - Tag string - BalanceType string - Direction string - ThresholdType string - ThresholdValue float64 - Recurrent bool - MinSleep int64 - DestinationTag string - BalanceWeight float64 - BalanceExpiryTime string - BalanceRatingSubject string - BalanceCategory string - BalanceSharedGroup string - MinQueuedItems int - ActionsTag string - Weight float64 - CreatedAt time.Time + Id int64 + Tpid string + Tag string + ThresholdType string + ThresholdValue float64 + Recurrent bool + MinSleep int64 + BalanceId string + BalanceType string + BalanceDirection string + BalanceDestinationTag string + BalanceWeight float64 + BalanceExpiryTime string + BalanceRatingSubject string + BalanceCategory string + BalanceSharedGroup string + MinQueuedItems int + ActionsTag string + Weight float64 + CreatedAt time.Time } type TpAccountAction struct { diff --git a/engine/storage_mysql_local_test.go b/engine/storage_mysql_local_test.go index 20aef2b71..abc8e8b61 100644 --- a/engine/storage_mysql_local_test.go +++ b/engine/storage_mysql_local_test.go @@ -266,14 +266,14 @@ func TestMySQLSetGetTPActionTriggers(t *testing.T) { return } atrg := &utils.TPActionTrigger{ - BalanceType: "*monetary", - Direction: "*out", - ThresholdType: "*min_balance", - ThresholdValue: 2.0, - Recurrent: true, - DestinationId: "*any", - Weight: 10.0, - ActionsId: "LOG_BALANCE", + BalanceType: "*monetary", + BalanceDirection: "*out", + ThresholdType: "*min_balance", + ThresholdValue: 2.0, + Recurrent: true, + BalanceDestinationId: "*any", + Weight: 10.0, + ActionsId: "LOG_BALANCE", } mpAtrgs := map[string][]*utils.TPActionTrigger{TEST_SQL: []*utils.TPActionTrigger{atrg}} if err := mysqlDb.SetTPActionTriggers(TEST_SQL+"1", mpAtrgs); err != nil { diff --git a/engine/storage_psql_local_test.go b/engine/storage_psql_local_test.go index c241c64a7..e3912fcf2 100644 --- a/engine/storage_psql_local_test.go +++ b/engine/storage_psql_local_test.go @@ -268,14 +268,14 @@ func TestPSQLSetGetTPActionTriggers(t *testing.T) { return } atrg := &utils.TPActionTrigger{ - BalanceType: "*monetary", - Direction: "*out", - ThresholdType: "*min_balance", - ThresholdValue: 2.0, - Recurrent: true, - DestinationId: "*any", - Weight: 10.0, - ActionsId: "LOG_BALANCE", + BalanceType: "*monetary", + BalanceDirection: "*out", + ThresholdType: "*min_balance", + ThresholdValue: 2.0, + Recurrent: true, + BalanceDestinationId: "*any", + Weight: 10.0, + ActionsId: "LOG_BALANCE", } mpAtrgs := map[string][]*utils.TPActionTrigger{TEST_SQL: []*utils.TPActionTrigger{atrg}} if err := psqlDb.SetTPActionTriggers(TEST_SQL+"1", mpAtrgs); err != nil { diff --git a/engine/storage_sql.go b/engine/storage_sql.go index 9fe7df71d..0caee2e7d 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -607,24 +607,25 @@ func (self *SQLStorage) SetTPActionTriggers(tpid string, ats map[string][]*utils } for _, at := range aTriggers { saved := tx.Save(TpActionTrigger{ - Tpid: tpid, - Tag: atId, - BalanceType: at.BalanceType, - Direction: at.Direction, - ThresholdType: at.ThresholdType, - ThresholdValue: at.ThresholdValue, - Recurrent: at.Recurrent, - MinSleep: int64(at.MinSleep), - DestinationTag: at.DestinationId, - BalanceWeight: at.BalanceWeight, - BalanceExpiryTime: at.BalanceExpirationDate, - BalanceRatingSubject: at.BalanceRatingSubject, - BalanceCategory: at.BalanceCategory, - BalanceSharedGroup: at.BalanceSharedGroup, - MinQueuedItems: at.MinQueuedItems, - ActionsTag: at.ActionsId, - Weight: at.Weight, - CreatedAt: time.Now(), + Tpid: tpid, + Tag: atId, + ThresholdType: at.ThresholdType, + ThresholdValue: at.ThresholdValue, + Recurrent: at.Recurrent, + MinSleep: int64(at.MinSleep), + BalanceId: at.BalanceId, + BalanceType: at.BalanceType, + BalanceDirection: at.BalanceDirection, + BalanceDestinationTag: at.BalanceDestinationId, + BalanceWeight: at.BalanceWeight, + BalanceExpiryTime: at.BalanceExpirationDate, + BalanceRatingSubject: at.BalanceRatingSubject, + BalanceCategory: at.BalanceCategory, + BalanceSharedGroup: at.BalanceSharedGroup, + MinQueuedItems: at.MinQueuedItems, + ActionsTag: at.ActionsId, + Weight: at.Weight, + CreatedAt: time.Now(), }) if saved.Error != nil { tx.Rollback() @@ -1420,13 +1421,14 @@ func (self *SQLStorage) GetTpActionTriggers(tpid, tag string) (map[string][]*uti } for _, tpAt := range tpActionTriggers { at := &utils.TPActionTrigger{ - BalanceType: tpAt.BalanceType, - Direction: tpAt.Direction, ThresholdType: tpAt.ThresholdType, ThresholdValue: tpAt.ThresholdValue, Recurrent: tpAt.Recurrent, MinSleep: time.Duration(tpAt.MinSleep), - DestinationId: tpAt.DestinationTag, + BalanceId: tpAt.BalanceId, + BalanceType: tpAt.BalanceType, + BalanceDirection: tpAt.BalanceDirection, + BalanceDestinationId: tpAt.BalanceDestinationTag, BalanceWeight: tpAt.BalanceWeight, BalanceExpirationDate: tpAt.BalanceExpiryTime, BalanceRatingSubject: tpAt.BalanceRatingSubject, diff --git a/engine/storage_test.go b/engine/storage_test.go index f82f7a9ab..50c084ce5 100644 --- a/engine/storage_test.go +++ b/engine/storage_test.go @@ -209,13 +209,13 @@ func GetUB() *Account { Balances: BalanceChain{&Balance{Value: 1}, &Balance{Weight: 20, DestinationId: "NAT"}, &Balance{Weight: 10, DestinationId: "RET"}}, } at := &ActionTrigger{ - Id: "some_uuid", - BalanceType: CREDIT, - Direction: OUTBOUND, - ThresholdValue: 100.0, - DestinationId: "NAT", - Weight: 10.0, - ActionsId: "Commando", + Id: "some_uuid", + BalanceType: CREDIT, + BalanceDirection: OUTBOUND, + ThresholdValue: 100.0, + BalanceDestinationId: "NAT", + Weight: 10.0, + ActionsId: "Commando", } var zeroTime time.Time zeroTime = zeroTime.UTC() // for deep equal to find location diff --git a/engine/tpimporter_csv.go b/engine/tpimporter_csv.go index f54318e07..028fbaa90 100644 --- a/engine/tpimporter_csv.go +++ b/engine/tpimporter_csv.go @@ -493,7 +493,7 @@ func (self *TPCSVImporter) importActionTriggers(fn string) error { } continue } - tag, balanceType, direction, thresholdType, destinationTag, balanceExpirationDate, balanceRatingSubject, balanceCategory, balanceSharedGroup, actionsTag := record[ATRIGCSVIDX_TAG], record[ATRIGCSVIDX_BAL_TYPE], + tag, balanceId, balanceType, direction, thresholdType, destinationTag, balanceExpirationDate, balanceRatingSubject, balanceCategory, balanceSharedGroup, actionsTag := record[ATRIGCSVIDX_TAG], record[ATRIGCSVIDX_BAL_TAG], record[ATRIGCSVIDX_BAL_TYPE], record[ATRIGCSVIDX_BAL_DIRECTION], record[ATRIGCSVIDX_THRESHOLD_TYPE], record[ATRIGCSVIDX_BAL_DESTINATION_TAG], record[ATRIGCSVIDX_BAL_EXPIRY_TIME], record[ATRIGCSVIDX_BAL_RATING_SUBJECT], record[ATRIGCSVIDX_BAL_CATEGORY], record[ATRIGCSVIDX_BAL_SHARED_GROUP], record[ATRIGCSVIDX_ACTIONS_TAG] threshold, err := strconv.ParseFloat(record[ATRIGCSVIDX_THRESHOLD_VALUE], 64) @@ -536,13 +536,14 @@ func (self *TPCSVImporter) importActionTriggers(fn string) error { atrs[tag] = make([]*utils.TPActionTrigger, 0) } atrs[tag] = append(atrs[tag], &utils.TPActionTrigger{ - BalanceType: balanceType, - Direction: direction, ThresholdType: thresholdType, ThresholdValue: threshold, Recurrent: recurrent, MinSleep: minSleep, - DestinationId: destinationTag, + BalanceId: balanceId, + BalanceType: balanceType, + BalanceDirection: direction, + BalanceDestinationId: destinationTag, BalanceWeight: balanceWeight, BalanceExpirationDate: balanceExpirationDate, BalanceRatingSubject: balanceRatingSubject, diff --git a/utils/apitpdata.go b/utils/apitpdata.go index 02ec7ceb5..328e43a45 100644 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -515,26 +515,27 @@ type TPActionTriggers struct { ActionTriggers []*TPActionTrigger // Set of triggers grouped in this profile } -// TPid,Tag[0],ThresholdType[1],ThresholdValue[2],Recurrent[3],MinSleep[4],BalanceType[5],BalanceDirection[6],BalanceCategory[7],BalanceDestinationTag[8], -// BalanceRatingSubject[9],BalanceSharedGroup[10],BalanceExpiryTime[11],BalanceWeight[12],StatsMinQueuedItems[13],ActionsTag[14],Weight[15] +// TPid,Tag[0],ThresholdType[1],ThresholdValue[2],Recurrent[3],MinSleep[4],BalanceId[5],BalanceType[6],BalanceDirection[7],BalanceCategory[8],BalanceDestinationTag[9], +// BalanceRatingSubject[10],BalanceSharedGroup[11],BalanceExpiryTime[12],BalanceWeight[13],StatsMinQueuedItems[14],ActionsTag[15],Weight[16] func (self *TPActionTriggers) AsExportSlice() [][]string { retSlice := make([][]string, len(self.ActionTriggers)) for idx, at := range self.ActionTriggers { retSlice[idx] = []string{self.ActionTriggersId, at.ThresholdType, strconv.FormatFloat(at.ThresholdValue, 'f', -1, 64), strconv.FormatBool(at.Recurrent), strconv.FormatFloat(at.MinSleep.Seconds(), 'f', -1, 64), - at.BalanceType, at.Direction, at.BalanceCategory, at.DestinationId, at.BalanceRatingSubject, at.BalanceSharedGroup, at.BalanceExpirationDate, + at.BalanceId, at.BalanceType, at.BalanceDirection, at.BalanceCategory, at.BalanceDestinationId, at.BalanceRatingSubject, at.BalanceSharedGroup, at.BalanceExpirationDate, strconv.FormatFloat(at.BalanceWeight, 'f', -1, 64), strconv.Itoa(at.MinQueuedItems), at.ActionsId, strconv.FormatFloat(at.Weight, 'f', -1, 64)} } return retSlice } type TPActionTrigger struct { - BalanceType string // Type of balance this trigger monitors - Direction string // Traffic direction ThresholdType string // This threshold type ThresholdValue float64 // Threshold Recurrent bool // reset executed flag each run MinSleep time.Duration // Minimum duration between two executions in case of recurrent triggers - DestinationId string // filter for balance + BalanceId string // The id of the balance in the account + BalanceType string // Type of balance this trigger monitors + BalanceDirection string // Traffic direction + BalanceDestinationId string // filter for balance BalanceWeight float64 // filter for balance BalanceExpirationDate string // filter for balance BalanceRatingSubject string // filter for balance diff --git a/utils/apitpdata_test.go b/utils/apitpdata_test.go index 8bddc9ae8..46498dd0e 100644 --- a/utils/apitpdata_test.go +++ b/utils/apitpdata_test.go @@ -412,13 +412,14 @@ func TestTPActionPlanAsExportSlice(t *testing.T) { ActionTriggersId: "STANDARD_TRIGGERS", ActionTriggers: []*TPActionTrigger{ &TPActionTrigger{ - BalanceType: "*monetary", - Direction: "*out", ThresholdType: "*min_balance", ThresholdValue: 2.0, Recurrent: false, MinSleep: time.Duration(0), - DestinationId: "", + BalanceId: "b1", + BalanceType: "*monetary", + BalanceDirection: "*out", + BalanceDestinationId: "", BalanceWeight: 0.0, BalanceExpirationDate: "*never", BalanceRatingSubject: "special1", @@ -428,13 +429,14 @@ func TestTPActionPlanAsExportSlice(t *testing.T) { ActionsId: "LOG_WARNING", Weight: 10}, &TPActionTrigger{ - BalanceType: "*monetary", - Direction: "*out", ThresholdType: "*max_counter", ThresholdValue: 5.0, Recurrent: false, MinSleep: time.Duration(0), - DestinationId: "FS_USERS", + BalanceId: "b2", + BalanceType: "*monetary", + BalanceDirection: "*out", + BalanceDestinationId: "FS_USERS", BalanceWeight: 0.0, BalanceExpirationDate: "*never", BalanceRatingSubject: "special1", @@ -446,8 +448,8 @@ func TestTPActionPlanAsExportSlice(t *testing.T) { }, } expectedSlc := [][]string{ - []string{"STANDARD_TRIGGERS", "*min_balance", "2", "false", "0", "*monetary", "*out", "call", "", "special1", "SHARED_1", "*never", "0", "0", "LOG_WARNING", "10"}, - []string{"STANDARD_TRIGGERS", "*max_counter", "5", "false", "0", "*monetary", "*out", "call", "FS_USERS", "special1", "SHARED_1", "*never", "0", "0", "LOG_WARNING", "10"}, + []string{"STANDARD_TRIGGERS", "*min_balance", "2", "false", "0", "b1", "*monetary", "*out", "call", "", "special1", "SHARED_1", "*never", "0", "0", "LOG_WARNING", "10"}, + []string{"STANDARD_TRIGGERS", "*max_counter", "5", "false", "0", "b2", "*monetary", "*out", "call", "FS_USERS", "special1", "SHARED_1", "*never", "0", "0", "LOG_WARNING", "10"}, } if slc := at.AsExportSlice(); !reflect.DeepEqual(expectedSlc, slc) { t.Errorf("Expecting: %+v, received: %+v", expectedSlc, slc) diff --git a/utils/consts.go b/utils/consts.go index b2d8704da..6ffbffc41 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -63,7 +63,7 @@ const ( LCRS_NRCOLS = 9 ACTIONS_NRCOLS = 13 ACTION_PLANS_NRCOLS = 4 - ACTION_TRIGGERS_NRCOLS = 16 + ACTION_TRIGGERS_NRCOLS = 17 ACCOUNT_ACTIONS_NRCOLS = 5 DERIVED_CHARGERS_NRCOLS = 17 CDR_STATS_NRCOLS = 21