engine compiling

This commit is contained in:
Radu Ioan Fericean
2016-02-11 10:26:43 +02:00
parent 8a24738b85
commit 7bf15bf825
16 changed files with 1157 additions and 778 deletions

View File

@@ -111,7 +111,7 @@ func (ub *Account) setBalanceAction(a *Action) error {
ub.BalanceMap = make(map[string]BalanceChain, 1)
}
found := false
balanceType := a.BalanceType
balanceType := a.Balance.GetType()
var previousSharedGroups utils.StringMap // kept for comparison
for _, b := range ub.BalanceMap[balanceType] {
if b.IsExpired() {
@@ -190,7 +190,7 @@ func (ub *Account) debitBalanceAction(a *Action, reset bool) error {
ub.BalanceMap = make(map[string]BalanceChain, 1)
}
found := false
balanceType := a.BalanceType
balanceType := a.Balance.GetType()
for _, b := range ub.BalanceMap[balanceType] {
if b.IsExpired() {
continue // just to be safe (cleaned expired balances above)
@@ -592,7 +592,7 @@ func (acc *Account) ExecuteActionTriggers(a *Action) {
}
if strings.Contains(at.ThresholdType, "counter") {
for _, uc := range acc.UnitCounters {
if uc.BalanceType == at.BalanceType &&
if uc.BalanceType == at.Balance.GetType() &&
strings.Contains(at.ThresholdType, uc.CounterType[1:]) {
for _, b := range uc.Balances {
if strings.HasPrefix(at.ThresholdType, "*max") {
@@ -608,7 +608,7 @@ func (acc *Account) ExecuteActionTriggers(a *Action) {
}
}
} else { // BALANCE
for _, b := range acc.BalanceMap[at.BalanceType] {
for _, b := range acc.BalanceMap[at.Balance.GetType()] {
if !b.dirty && at.ThresholdType != utils.TRIGGER_BALANCE_EXPIRED { // do not check clean balances
continue
}
@@ -674,17 +674,17 @@ func (acc *Account) InitCounters() {
ct = utils.COUNTER_BALANCE
}
uc, exists := ucTempMap[at.BalanceType+ct]
uc, exists := ucTempMap[at.Balance.GetType()+ct]
if !exists {
uc = &UnitCounter{
BalanceType: at.BalanceType,
BalanceType: at.Balance.GetType(),
CounterType: ct,
}
ucTempMap[at.BalanceType+ct] = uc
ucTempMap[at.Balance.GetType()+ct] = uc
uc.Balances = BalanceChain{}
acc.UnitCounters = append(acc.UnitCounters, uc)
}
b := at.CreateBalance()
b := at.Balance.CreateBalance()
if !uc.Balances.HasBalance(b) {
uc.Balances = append(uc.Balances, b)
}
@@ -941,7 +941,7 @@ func (acc *Account) AsOldStructure() interface{} {
ThresholdValue: at.ThresholdValue,
Recurrent: at.Recurrent,
MinSleep: at.MinSleep,
BalanceType: at.BalanceType,
BalanceType: at.Balance.GetType(),
BalanceId: b.Id,
BalanceDirection: b.Directions.String(),
BalanceDestinationIds: b.DestinationIds.String(),

View File

@@ -814,22 +814,32 @@ func TestAccountdebitBalance(t *testing.T) {
AllowNegative: true,
BalanceMap: map[string]BalanceChain{utils.SMS: BalanceChain{&Balance{Value: 14}}, utils.DATA: BalanceChain{&Balance{Value: 1204}}, utils.VOICE: BalanceChain{&Balance{Weight: 20, DestinationIds: utils.StringMap{"NAT": true}}, &Balance{Weight: 10, DestinationIds: utils.StringMap{"RET": true}}}},
}
newMb := &Balance{Weight: 20, DestinationIds: utils.StringMap{"NEW": true}, Directions: utils.NewStringMap(utils.OUT)}
a := &Action{BalanceType: utils.VOICE, Balance: newMb}
newMb := &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Weight: utils.Float64Pointer(20),
DestinationIds: utils.StringMapPointer(utils.StringMap{"NEW": true}),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
}
a := &Action{Balance: newMb}
ub.debitBalanceAction(a, false)
if len(ub.BalanceMap[utils.VOICE]) != 3 || !ub.BalanceMap[utils.VOICE][2].DestinationIds.Equal(newMb.DestinationIds) {
if len(ub.BalanceMap[utils.VOICE]) != 3 || !ub.BalanceMap[utils.VOICE][2].DestinationIds.Equal(*newMb.DestinationIds) {
t.Errorf("Error adding minute bucket! %d %+v %+v", len(ub.BalanceMap[utils.VOICE]), ub.BalanceMap[utils.VOICE][2], newMb)
}
}
func TestAccountDisableBalance(t *testing.T) {
/*func TestAccountDisableBalance(t *testing.T) {
ub := &Account{
Id: "rif",
AllowNegative: true,
BalanceMap: map[string]BalanceChain{utils.SMS: BalanceChain{&Balance{Value: 14}}, utils.DATA: BalanceChain{&Balance{Value: 1204}}, utils.VOICE: BalanceChain{&Balance{Weight: 20, DestinationIds: utils.StringMap{"NAT": true}, Directions: utils.NewStringMap(utils.OUT)}, &Balance{Weight: 10, DestinationIds: utils.StringMap{"RET": true}}}},
}
newMb := &Balance{Weight: 20, DestinationIds: utils.StringMap{"NAT": true}, Directions: utils.NewStringMap(utils.OUT), Disabled: true}
a := &Action{BalanceType: utils.VOICE, Balance: newMb}
newMb := &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Weight: utils.Float64Pointer(20),
DestinationIds: utils.StringMapPointer(utils.StringMap{"NAT": true}),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
}
a := &Action{Balance: newMb}
ub.enableDisableBalanceAction(a)
if len(ub.BalanceMap[utils.VOICE]) != 2 || ub.BalanceMap[utils.VOICE][0].Disabled != true {
for _, b := range ub.BalanceMap[utils.VOICE] {
@@ -837,7 +847,7 @@ func TestAccountDisableBalance(t *testing.T) {
}
t.Errorf("Error disabling balance! %d %+v %+v", len(ub.BalanceMap[utils.VOICE]), ub.BalanceMap[utils.VOICE][0], newMb)
}
}
}*/
func TestAccountdebitBalanceExists(t *testing.T) {
@@ -846,8 +856,14 @@ func TestAccountdebitBalanceExists(t *testing.T) {
AllowNegative: true,
BalanceMap: map[string]BalanceChain{utils.SMS: BalanceChain{&Balance{Value: 14}}, utils.DATA: BalanceChain{&Balance{Value: 1024}}, utils.VOICE: BalanceChain{&Balance{Value: 15, Weight: 20, DestinationIds: utils.StringMap{"NAT": true}, Directions: utils.NewStringMap(utils.OUT)}, &Balance{Weight: 10, DestinationIds: utils.StringMap{"RET": true}}}},
}
newMb := &Balance{Value: -10, Weight: 20, DestinationIds: utils.StringMap{"NAT": true}, Directions: utils.NewStringMap(utils.OUT)}
a := &Action{BalanceType: utils.VOICE, Balance: newMb}
newMb := &BalancePointer{
Value: utils.Float64Pointer(-10),
Type: utils.StringPointer(utils.VOICE),
Weight: utils.Float64Pointer(20),
DestinationIds: utils.StringMapPointer(utils.StringMap{"NAT": true}),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
}
a := &Action{Balance: newMb}
ub.debitBalanceAction(a, false)
if len(ub.BalanceMap[utils.VOICE]) != 2 || ub.BalanceMap[utils.VOICE][0].GetValue() != 25 {
t.Error("Error adding minute bucket!")
@@ -867,21 +883,36 @@ func TestAccountAddMinuteNil(t *testing.T) {
}
func TestAccountAddMinutBucketEmpty(t *testing.T) {
mb1 := &Balance{Value: -10, DestinationIds: utils.StringMap{"NAT": true}, Directions: utils.NewStringMap(utils.OUT)}
mb2 := &Balance{Value: -10, DestinationIds: utils.StringMap{"NAT": true}, Directions: utils.NewStringMap(utils.OUT)}
mb3 := &Balance{Value: -10, DestinationIds: utils.StringMap{"OTHER": true}, Directions: utils.NewStringMap(utils.OUT)}
mb1 := &BalancePointer{
Value: utils.Float64Pointer(-10),
Type: utils.StringPointer(utils.VOICE),
DestinationIds: utils.StringMapPointer(utils.StringMap{"NAT": true}),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
}
mb2 := &BalancePointer{
Value: utils.Float64Pointer(-10),
Type: utils.StringPointer(utils.VOICE),
DestinationIds: utils.StringMapPointer(utils.StringMap{"NAT": true}),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
}
mb3 := &BalancePointer{
Value: utils.Float64Pointer(-10),
Type: utils.StringPointer(utils.VOICE),
DestinationIds: utils.StringMapPointer(utils.StringMap{"OTHER": true}),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
}
ub := &Account{}
a := &Action{BalanceType: utils.VOICE, Balance: mb1}
a := &Action{Balance: mb1}
ub.debitBalanceAction(a, false)
if len(ub.BalanceMap[utils.VOICE]) != 1 {
t.Error("Error adding minute bucket: ", ub.BalanceMap[utils.VOICE])
}
a = &Action{BalanceType: utils.VOICE, Balance: mb2}
a = &Action{Balance: mb2}
ub.debitBalanceAction(a, false)
if len(ub.BalanceMap[utils.VOICE]) != 1 || ub.BalanceMap[utils.VOICE][0].GetValue() != 20 {
t.Error("Error adding minute bucket: ", ub.BalanceMap[utils.VOICE])
}
a = &Action{BalanceType: utils.VOICE, Balance: mb3}
a = &Action{Balance: mb3}
ub.debitBalanceAction(a, false)
if len(ub.BalanceMap[utils.VOICE]) != 2 {
t.Error("Error adding minute bucket: ", ub.BalanceMap[utils.VOICE])
@@ -893,7 +924,7 @@ func TestAccountExecuteTriggeredActions(t *testing.T) {
Id: "TEST_UB",
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Directions: utils.NewStringMap(utils.OUT), Value: 100}}, utils.VOICE: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationIds: utils.StringMap{"NAT": true}, Directions: utils.StringMap{utils.OUT: true}}, &Balance{Weight: 10, DestinationIds: utils.StringMap{"RET": true}}}},
UnitCounters: UnitCounters{&UnitCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1, Directions: utils.StringMap{utils.OUT: true}}}}},
ActionTriggers: ActionTriggers{&ActionTrigger{BalanceType: utils.MONETARY, BalanceDirections: utils.StringMap{utils.OUT: true}, ThresholdValue: 2, ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER, ActionsId: "TEST_ACTIONS"}},
ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 2, ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER, ActionsId: "TEST_ACTIONS"}},
}
ub.countUnits(1, utils.MONETARY, &CallCost{Direction: utils.OUT}, nil)
if ub.BalanceMap[utils.MONETARY][0].GetValue() != 110 || ub.BalanceMap[utils.VOICE][0].GetValue() != 20 {
@@ -917,7 +948,7 @@ func TestAccountExecuteTriggeredActionsBalance(t *testing.T) {
Id: "TEST_UB",
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Directions: utils.NewStringMap(utils.OUT), Value: 100}}, utils.VOICE: BalanceChain{&Balance{Directions: utils.NewStringMap(utils.OUT), Value: 10, Weight: 20, DestinationIds: utils.StringMap{"NAT": true}}, &Balance{Directions: utils.NewStringMap(utils.OUT), Weight: 10, DestinationIds: utils.StringMap{"RET": true}}}},
UnitCounters: UnitCounters{&UnitCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Directions: utils.NewStringMap(utils.OUT), Value: 1}}}},
ActionTriggers: ActionTriggers{&ActionTrigger{BalanceType: utils.MONETARY, BalanceDirections: utils.NewStringMap(utils.OUT), ThresholdValue: 100, ThresholdType: utils.TRIGGER_MIN_EVENT_COUNTER, ActionsId: "TEST_ACTIONS"}},
ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 100, ThresholdType: utils.TRIGGER_MIN_EVENT_COUNTER, ActionsId: "TEST_ACTIONS"}},
}
ub.countUnits(1, utils.MONETARY, nil, nil)
if ub.BalanceMap[utils.MONETARY][0].GetValue() != 110 || ub.BalanceMap[utils.VOICE][0].GetValue() != 20 {
@@ -930,7 +961,7 @@ func TestAccountExecuteTriggeredActionsOrder(t *testing.T) {
Id: "TEST_UB_OREDER",
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Directions: utils.NewStringMap(utils.OUT), Value: 100}}},
UnitCounters: UnitCounters{&UnitCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1, Directions: utils.NewStringMap(utils.OUT)}}}},
ActionTriggers: ActionTriggers{&ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER, ActionsId: "TEST_ACTIONS_ORDER"}},
ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ThresholdValue: 2, ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER, ActionsId: "TEST_ACTIONS_ORDER"}},
}
ub.countUnits(1, utils.MONETARY, &CallCost{Direction: utils.OUT}, nil)
@@ -945,8 +976,8 @@ func TestAccountExecuteTriggeredDayWeek(t *testing.T) {
Id: "TEST_UB",
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Directions: utils.NewStringMap(utils.OUT), Value: 100}}, utils.VOICE: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationIds: utils.StringMap{"NAT": true}, Directions: utils.StringMap{utils.OUT: true}}, &Balance{Weight: 10, DestinationIds: utils.StringMap{"RET": true}}}},
ActionTriggers: ActionTriggers{
&ActionTrigger{UniqueID: "day_trigger", BalanceType: utils.MONETARY, BalanceDirections: utils.StringMap{utils.OUT: true}, ThresholdValue: 10, ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER, ActionsId: "TEST_ACTIONS"},
&ActionTrigger{UniqueID: "week_trigger", BalanceType: utils.MONETARY, BalanceDirections: utils.StringMap{utils.OUT: true}, ThresholdValue: 100, ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER, ActionsId: "TEST_ACTIONS"},
&ActionTrigger{UniqueID: "day_trigger", Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 10, ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER, ActionsId: "TEST_ACTIONS"},
&ActionTrigger{UniqueID: "week_trigger", Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 100, ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER, ActionsId: "TEST_ACTIONS"},
},
}
ub.InitCounters()
@@ -961,7 +992,7 @@ func TestAccountExecuteTriggeredDayWeek(t *testing.T) {
}
// we can reset them
resetCountersAction(ub, nil, &Action{BalanceType: utils.MONETARY, Balance: &Balance{Id: "day_trigger"}}, nil)
resetCountersAction(ub, nil, &Action{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Id: utils.StringPointer("day_trigger")}}, nil)
if ub.UnitCounters[0].Balances[0].Value != 0 ||
ub.UnitCounters[0].Balances[1].Value != 1 {
t.Error("Error reseting both counters", ub.UnitCounters[0].Balances[0].Value, ub.UnitCounters[0].Balances[1].Value)
@@ -973,7 +1004,7 @@ func TestAccountExpActionTrigger(t *testing.T) {
Id: "TEST_UB",
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Directions: utils.NewStringMap(utils.OUT), Value: 100, ExpirationDate: time.Date(2015, time.November, 9, 9, 48, 0, 0, time.UTC)}}, utils.VOICE: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationIds: utils.StringMap{"NAT": true}, Directions: utils.StringMap{utils.OUT: true}}, &Balance{Weight: 10, DestinationIds: utils.StringMap{"RET": true}}}},
ActionTriggers: ActionTriggers{
&ActionTrigger{ID: "check expired balances", BalanceType: utils.MONETARY, BalanceDirections: utils.StringMap{utils.OUT: true}, ThresholdValue: 10, ThresholdType: utils.TRIGGER_BALANCE_EXPIRED, ActionsId: "TEST_ACTIONS"},
&ActionTrigger{ID: "check expired balances", Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 10, ThresholdType: utils.TRIGGER_BALANCE_EXPIRED, ActionsId: "TEST_ACTIONS"},
},
}
ub.ExecuteActionTriggers(nil)
@@ -991,7 +1022,7 @@ func TestAccountExpActionTriggerNotActivated(t *testing.T) {
Id: "TEST_UB",
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Directions: utils.NewStringMap(utils.OUT), Value: 100}}, utils.VOICE: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationIds: utils.StringMap{"NAT": true}, Directions: utils.StringMap{utils.OUT: true}}, &Balance{Weight: 10, DestinationIds: utils.StringMap{"RET": true}}}},
ActionTriggers: ActionTriggers{
&ActionTrigger{ID: "check expired balances", ActivationDate: time.Date(2116, 2, 5, 18, 0, 0, 0, time.UTC), BalanceType: utils.MONETARY, BalanceDirections: utils.StringMap{utils.OUT: true}, ThresholdValue: 10, ThresholdType: utils.TRIGGER_BALANCE_EXPIRED, ActionsId: "TEST_ACTIONS"},
&ActionTrigger{ID: "check expired balances", ActivationDate: time.Date(2116, 2, 5, 18, 0, 0, 0, time.UTC), Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 10, ThresholdType: utils.TRIGGER_BALANCE_EXPIRED, ActionsId: "TEST_ACTIONS"},
},
}
ub.ExecuteActionTriggers(nil)
@@ -1009,7 +1040,7 @@ func TestAccountExpActionTriggerExpired(t *testing.T) {
Id: "TEST_UB",
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Directions: utils.NewStringMap(utils.OUT), Value: 100}}, utils.VOICE: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationIds: utils.StringMap{"NAT": true}, Directions: utils.StringMap{utils.OUT: true}}, &Balance{Weight: 10, DestinationIds: utils.StringMap{"RET": true}}}},
ActionTriggers: ActionTriggers{
&ActionTrigger{ID: "check expired balances", ExpirationDate: time.Date(2016, 2, 4, 18, 0, 0, 0, time.UTC), BalanceType: utils.MONETARY, BalanceDirections: utils.StringMap{utils.OUT: true}, ThresholdValue: 10, ThresholdType: utils.TRIGGER_BALANCE_EXPIRED, ActionsId: "TEST_ACTIONS"},
&ActionTrigger{ID: "check expired balances", ExpirationDate: time.Date(2016, 2, 4, 18, 0, 0, 0, time.UTC), Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 10, ThresholdType: utils.TRIGGER_BALANCE_EXPIRED, ActionsId: "TEST_ACTIONS"},
},
}
ub.ExecuteActionTriggers(nil)
@@ -1565,46 +1596,58 @@ func TestAccountInitCounters(t *testing.T) {
a := &Account{
ActionTriggers: ActionTriggers{
&ActionTrigger{
UniqueID: "TestTR1",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
BalanceType: utils.MONETARY,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR1",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR11",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
BalanceType: utils.MONETARY,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR11",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR2",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
BalanceType: utils.VOICE,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR2",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR3",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.VOICE,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR3",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR4",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.SMS,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR4",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.SMS),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR5",
ThresholdType: utils.TRIGGER_MAX_BALANCE,
BalanceType: utils.SMS,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR5",
ThresholdType: utils.TRIGGER_MAX_BALANCE,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.SMS),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
},
}
@@ -1628,46 +1671,58 @@ func TestAccountDoubleInitCounters(t *testing.T) {
a := &Account{
ActionTriggers: ActionTriggers{
&ActionTrigger{
UniqueID: "TestTR1",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
BalanceType: utils.MONETARY,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR1",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR11",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
BalanceType: utils.MONETARY,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR11",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR2",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
BalanceType: utils.VOICE,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR2",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR3",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.VOICE,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR3",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR4",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.SMS,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR4",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.SMS),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR5",
ThresholdType: utils.TRIGGER_MAX_BALANCE,
BalanceType: utils.SMS,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR5",
ThresholdType: utils.TRIGGER_MAX_BALANCE,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.SMS),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
},
}

View File

@@ -38,9 +38,9 @@ import (
Structure to be filled for each tariff plan with the bonus value for received calls minutes.
*/
type Action struct {
Id string
ActionType string
BalanceType string
Id string
ActionType string
//BalanceType string
ExtraParameters string
Filter string
ExpirationString string // must stay as string because it can have relative values like 1month
@@ -51,6 +51,7 @@ type Action struct {
type BalancePointer struct {
Uuid *string
Id *string
Type *string
Value *float64
Directions *utils.StringMap
ExpirationDate *time.Time
@@ -113,6 +114,61 @@ func (bp *BalancePointer) CreateBalance() *Balance {
return b.Clone()
}
func (bp *BalancePointer) LoadFromBalance(b *Balance) {
if b.Uuid != "" {
bp.Uuid = &b.Uuid
}
if b.Id != "" {
bp.Id = &b.Id
}
if b.Value != 0 {
bp.Value = &b.Value
}
if len(b.Directions) != 0 {
bp.Directions = &b.Directions
}
if !b.ExpirationDate.IsZero() {
bp.ExpirationDate = &b.ExpirationDate
}
if b.Weight != 0 {
bp.Weight = &b.Weight
}
if len(b.DestinationIds) != 0 {
bp.DestinationIds = &b.DestinationIds
}
if b.RatingSubject != "" {
bp.RatingSubject = &b.RatingSubject
}
if len(b.Categories) != 0 {
bp.Categories = &b.Categories
}
if len(b.SharedGroups) != 0 {
bp.SharedGroups = &b.SharedGroups
}
if len(b.TimingIDs) != 0 {
bp.TimingIDs = &b.TimingIDs
}
if len(b.Factor) != 0 {
bp.Factor = &b.Factor
}
bp.Disabled = &b.Disabled
bp.Blocker = &b.Blocker
}
func (bp *BalancePointer) GetType() string {
if bp.Type == nil {
return ""
}
return *bp.Type
}
func (bp *BalancePointer) GetValue() float64 {
if bp.Value == nil {
return 0.0
}
return *bp.Value
}
const (
LOG = "*log"
RESET_TRIGGERS = "*reset_triggers"
@@ -143,9 +199,9 @@ const (
func (a *Action) Clone() *Action {
return &Action{
Id: a.Id,
ActionType: a.ActionType,
BalanceType: a.BalanceType,
Id: a.Id,
ActionType: a.ActionType,
//BalanceType: a.BalanceType,
ExtraParameters: a.ExtraParameters,
ExpirationString: a.ExpirationString,
Weight: a.Weight,
@@ -248,7 +304,7 @@ func parseTemplateValue(rsrFlds utils.RSRFields, acnt *Account, action *Action)
case "ActionType":
parsedValue += rsrFld.ParseValue(action.ActionType)
case "BalanceType":
parsedValue += rsrFld.ParseValue(action.BalanceType)
parsedValue += rsrFld.ParseValue(action.Balance.GetType())
case "BalanceUUID":
parsedValue += rsrFld.ParseValue(b.Uuid)
case "BalanceID":
@@ -651,10 +707,10 @@ func removeAccountAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Ac
}
func removeBalanceAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) error {
if _, exists := ub.BalanceMap[a.BalanceType]; !exists {
if _, exists := ub.BalanceMap[a.Balance.GetType()]; !exists {
return utils.ErrNotFound
}
bChain := ub.BalanceMap[a.BalanceType]
bChain := ub.BalanceMap[a.Balance.GetType()]
found := false
for i := 0; i < len(bChain); i++ {
if bChain[i].MatchFilter(a.Balance, false) {
@@ -665,7 +721,7 @@ func removeBalanceAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Ac
found = true
}
}
ub.BalanceMap[a.BalanceType] = bChain
ub.BalanceMap[a.Balance.GetType()] = bChain
if !found {
return utils.ErrNotFound
}

View File

@@ -19,9 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package engine
import (
"encoding/json"
"fmt"
"regexp"
"sort"
"time"
@@ -33,12 +31,12 @@ type ActionTrigger struct {
UniqueID string // individual id
ThresholdType string //*min_event_counter, *max_event_counter, *min_balance_counter, *max_balance_counter, *min_balance, *max_balance, *exp_balance
// stats: *min_asr, *max_asr, *min_acd, *max_acd, *min_tcd, *max_tcd, *min_acc, *max_acc, *min_tcc, *max_tcc, *min_ddc, *max_ddc
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
BalanceType string // *monetary/*voice etc
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
//BalanceType string // *monetary/*voice etc
Balance *BalancePointer
Weight float64
ActionsId string
@@ -118,41 +116,7 @@ func (at *ActionTrigger) Match(a *Action) bool {
if a == nil {
return true
}
// if we have Id than we can draw an early conclusion
if a.Id != "" {
match, _ := regexp.MatchString(a.Id, at.ID)
return match
}
id := a.BalanceType == "" || at.BalanceType == a.BalanceType
thresholdType, thresholdValue, direction, destinationID, weight, ratingSubject, categories, sharedGroup, timings, blocker, disabled := true, true, true, true, true, true, true, true, true, true, true
if a.ExtraParameters != "" {
t := struct {
ThresholdType string
ThresholdValue float64
DestinationIds string
BalanceDirections string
BalanceWeight float64
BalanceRatingSubject string
BalanceCategories string
BalanceSharedGroups string
BalanceTimingTags string
BalanceBlocker bool
BalanceDisabled bool
}{}
json.Unmarshal([]byte(a.ExtraParameters), &t)
thresholdType = t.ThresholdType == "" || at.ThresholdType == t.ThresholdType
thresholdValue = t.ThresholdValue == 0 || at.ThresholdValue == t.ThresholdValue
direction = t.Balance.Directions == nil || at.Balance.Directions.Equal(utils.ParseStringMap(t.BalanceDirections))
destinationID = len(t.DestinationIds) == 0 || at.BalanceDestinationIds.Equal(utils.ParseStringMap(t.DestinationIds))
categories = len(t.BalanceCategories) == 0 || at.BalanceCategories.Equal(utils.ParseStringMap(t.BalanceCategories))
timings = len(t.BalanceTimingTags) == 0 || at.BalanceTimingTags.Equal(utils.ParseStringMap(t.BalanceTimingTags))
sharedGroup = len(t.BalanceSharedGroups) == 0 || at.BalanceSharedGroups.Equal(utils.ParseStringMap(t.BalanceSharedGroups))
weight = t.BalanceWeight == 0 || at.BalanceWeight == t.BalanceWeight
ratingSubject = t.BalanceRatingSubject == "" || at.BalanceRatingSubject == t.BalanceRatingSubject
blocker = at.BalanceBlocker == t.BalanceBlocker
disabled = at.BalanceDisabled == t.BalanceDisabled
}
return id && direction && thresholdType && thresholdValue && destinationID && weight && ratingSubject && categories && sharedGroup && timings && blocker && disabled
return at.Balance.CreateBalance().MatchFilter(a.Balance, false)
}
// makes a shallow copy of the receiver
@@ -162,22 +126,6 @@ func (at *ActionTrigger) Clone() *ActionTrigger {
return clone
}
func (at *ActionTrigger) CreateBalance() *Balance {
return &Balance{
Id: at.UniqueID,
Directions: at.BalanceDirections,
ExpirationDate: at.BalanceExpirationDate,
DestinationIds: at.BalanceDestinationIds,
RatingSubject: at.BalanceRatingSubject,
Categories: at.BalanceCategories,
SharedGroups: at.BalanceSharedGroups,
TimingIDs: at.BalanceTimingTags,
Blocker: at.BalanceBlocker,
Disabled: at.BalanceDisabled,
Weight: at.BalanceWeight,
}
}
func (at *ActionTrigger) Equals(oat *ActionTrigger) bool {
// ids only
return at.ID == oat.ID && at.UniqueID == oat.UniqueID

View File

@@ -23,6 +23,7 @@ import (
"net/rpc"
"net/rpc/jsonrpc"
"path"
"strconv"
"testing"
"time"
@@ -94,7 +95,7 @@ func TestActionsLocalSetCdrlogDebit(t *testing.T) {
t.Errorf("Calling ApierV1.SetAccount received: %s", reply)
}
attrsAA := &utils.AttrSetActions{ActionsId: "ACTS_1", Actions: []*utils.TPAction{
&utils.TPAction{Identifier: DEBIT, BalanceType: utils.MONETARY, Units: 5.0, ExpiryTime: UNLIMITED, Weight: 20.0},
&utils.TPAction{Identifier: DEBIT, BalanceType: utils.MONETARY, Units: "5.0", ExpiryTime: UNLIMITED, Weight: 20.0},
&utils.TPAction{Identifier: CDRLOG},
}}
if err := actsLclRpc.Call("ApierV1.SetActions", attrsAA, &reply); err != nil && err.Error() != utils.ErrExists.Error() {
@@ -122,7 +123,7 @@ func TestActionsLocalSetCdrlogDebit(t *testing.T) {
rcvedCdrs[0].Subject != "dan2904" ||
rcvedCdrs[0].Usage != "1" ||
rcvedCdrs[0].RunID != DEBIT ||
rcvedCdrs[0].Cost != attrsAA.Actions[0].Units {
strconv.FormatFloat(rcvedCdrs[0].Cost, 'f', -1, 64) != attrsAA.Actions[0].Units {
t.Errorf("Received: %+v", rcvedCdrs[0])
}
}
@@ -139,7 +140,7 @@ func TestActionsLocalSetCdrlogTopup(t *testing.T) {
t.Errorf("Calling ApierV1.SetAccount received: %s", reply)
}
attrsAA := &utils.AttrSetActions{ActionsId: "ACTS_2", Actions: []*utils.TPAction{
&utils.TPAction{Identifier: TOPUP, BalanceType: utils.MONETARY, Units: 5.0, ExpiryTime: UNLIMITED, Weight: 20.0},
&utils.TPAction{Identifier: TOPUP, BalanceType: utils.MONETARY, Units: "5.0", ExpiryTime: UNLIMITED, Weight: 20.0},
&utils.TPAction{Identifier: CDRLOG},
}}
if err := actsLclRpc.Call("ApierV1.SetActions", attrsAA, &reply); err != nil && err.Error() != utils.ErrExists.Error() {
@@ -167,7 +168,7 @@ func TestActionsLocalSetCdrlogTopup(t *testing.T) {
rcvedCdrs[0].Subject != "dan2905" ||
rcvedCdrs[0].Usage != "1" ||
rcvedCdrs[0].RunID != TOPUP ||
rcvedCdrs[0].Cost != attrsAA.Actions[0].Units {
strconv.FormatFloat(rcvedCdrs[0].Cost, 'f', -1, 64) != attrsAA.Actions[0].Units {
t.Errorf("Received: %+v", rcvedCdrs[0])
}
}

View File

@@ -409,9 +409,11 @@ func TestActionPlanCheckForASAP(t *testing.T) {
func TestActionPlanLogFunction(t *testing.T) {
a := &Action{
ActionType: "*log",
BalanceType: "test",
Balance: &Balance{Value: 1.1},
ActionType: "*log",
Balance: &BalancePointer{
Type: utils.StringPointer("test"),
Value: utils.Float64Pointer(1.1),
},
}
at := &ActionTiming{
actions: []*Action{a},
@@ -424,9 +426,11 @@ func TestActionPlanLogFunction(t *testing.T) {
func TestActionPlanFunctionNotAvailable(t *testing.T) {
a := &Action{
ActionType: "VALID_FUNCTION_TYPE",
BalanceType: "test",
Balance: &Balance{Value: 1.1},
ActionType: "VALID_FUNCTION_TYPE",
Balance: &BalancePointer{
Type: utils.StringPointer("test"),
Value: utils.Float64Pointer(1.1),
},
}
at := &ActionTiming{
accountIDs: utils.StringMap{"cgrates.org:dy": true},
@@ -527,10 +531,12 @@ func TestActionPlansRemoveMember(t *testing.T) {
func TestActionTriggerMatchNil(t *testing.T) {
at := &ActionTrigger{
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceType: utils.MONETARY,
ThresholdType: utils.TRIGGER_MAX_BALANCE,
ThresholdValue: 2,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
},
ThresholdType: utils.TRIGGER_MAX_BALANCE,
ThresholdValue: 2,
}
var a *Action
if !at.Match(a) {
@@ -540,10 +546,12 @@ func TestActionTriggerMatchNil(t *testing.T) {
func TestActionTriggerMatchAllBlank(t *testing.T) {
at := &ActionTrigger{
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceType: utils.MONETARY,
ThresholdType: utils.TRIGGER_MAX_BALANCE,
ThresholdValue: 2,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
},
ThresholdType: utils.TRIGGER_MAX_BALANCE,
ThresholdValue: 2,
}
a := &Action{}
if !at.Match(a) {
@@ -553,12 +561,14 @@ func TestActionTriggerMatchAllBlank(t *testing.T) {
func TestActionTriggerMatchMinuteBucketBlank(t *testing.T) {
at := &ActionTrigger{
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceType: utils.MONETARY,
ThresholdType: utils.TRIGGER_MAX_BALANCE,
ThresholdValue: 2,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
},
ThresholdType: utils.TRIGGER_MAX_BALANCE,
ThresholdValue: 2,
}
a := &Action{BalanceType: utils.MONETARY, ExtraParameters: `{"BalanceDirections":"*out"}`}
a := &Action{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ExtraParameters: `{"BalanceDirections":"*out"}`}
if !at.Match(a) {
t.Errorf("Action trigger [%v] does not match action [%v]", at, a)
}
@@ -566,10 +576,12 @@ func TestActionTriggerMatchMinuteBucketBlank(t *testing.T) {
func TestActionTriggerMatchMinuteBucketFull(t *testing.T) {
at := &ActionTrigger{
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceType: utils.MONETARY,
ThresholdType: utils.TRIGGER_MAX_BALANCE,
ThresholdValue: 2,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
},
ThresholdType: utils.TRIGGER_MAX_BALANCE,
ThresholdValue: 2,
}
a := &Action{ExtraParameters: fmt.Sprintf(`{"ThresholdType":"%v", "ThresholdValue": %v}`, utils.TRIGGER_MAX_BALANCE, 2)}
if !at.Match(a) {
@@ -579,12 +591,14 @@ func TestActionTriggerMatchMinuteBucketFull(t *testing.T) {
func TestActionTriggerMatchAllFull(t *testing.T) {
at := &ActionTrigger{
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceType: utils.MONETARY,
ThresholdType: utils.TRIGGER_MAX_BALANCE,
ThresholdValue: 2,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
},
ThresholdType: utils.TRIGGER_MAX_BALANCE,
ThresholdValue: 2,
}
a := &Action{BalanceType: utils.MONETARY, ExtraParameters: fmt.Sprintf(`{"ThresholdType":"%v", "ThresholdValue": %v, "BalanceDirections":"*out"}`, utils.TRIGGER_MAX_BALANCE, 2)}
a := &Action{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ExtraParameters: fmt.Sprintf(`{"ThresholdType":"%v", "ThresholdValue": %v, "BalanceDirections":"*out"}`, utils.TRIGGER_MAX_BALANCE, 2)}
if !at.Match(a) {
t.Errorf("Action trigger [%v] does not match action [%v]", at, a)
}
@@ -592,12 +606,14 @@ func TestActionTriggerMatchAllFull(t *testing.T) {
func TestActionTriggerMatchSomeFalse(t *testing.T) {
at := &ActionTrigger{
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceType: utils.MONETARY,
ThresholdType: utils.TRIGGER_MAX_BALANCE,
ThresholdValue: 2,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
},
ThresholdType: utils.TRIGGER_MAX_BALANCE,
ThresholdValue: 2,
}
a := &Action{BalanceType: utils.MONETARY, ExtraParameters: fmt.Sprintf(`{"ThresholdType":"%v", "ThresholdValue": %v, "BalanceDirections":"*in"}`, utils.TRIGGER_MAX_BALANCE, 2)}
a := &Action{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ExtraParameters: fmt.Sprintf(`{"ThresholdType":"%v", "ThresholdValue": %v, "BalanceDirections":"*in"}`, utils.TRIGGER_MAX_BALANCE, 2)}
if at.Match(a) {
t.Errorf("Action trigger [%v] does not match action [%v]", at, a)
}
@@ -605,12 +621,14 @@ func TestActionTriggerMatchSomeFalse(t *testing.T) {
func TestActionTriggerMatcBalanceFalse(t *testing.T) {
at := &ActionTrigger{
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceType: utils.MONETARY,
ThresholdType: utils.TRIGGER_MAX_BALANCE,
ThresholdValue: 2,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
},
ThresholdType: utils.TRIGGER_MAX_BALANCE,
ThresholdValue: 2,
}
a := &Action{BalanceType: utils.MONETARY, ExtraParameters: fmt.Sprintf(`{"ThresholdType":"%v", "ThresholdValue": %v, "BalanceDirections":"*out"}`, utils.TRIGGER_MAX_BALANCE, 3.0)}
a := &Action{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ExtraParameters: fmt.Sprintf(`{"ThresholdType":"%v", "ThresholdValue": %v, "BalanceDirections":"*out"}`, utils.TRIGGER_MAX_BALANCE, 3.0)}
if at.Match(a) {
t.Errorf("Action trigger [%v] does not match action [%v]", at, a)
}
@@ -618,12 +636,14 @@ func TestActionTriggerMatcBalanceFalse(t *testing.T) {
func TestActionTriggerMatcAllFalse(t *testing.T) {
at := &ActionTrigger{
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceType: utils.MONETARY,
ThresholdType: utils.TRIGGER_MAX_BALANCE,
ThresholdValue: 2,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
},
ThresholdType: utils.TRIGGER_MAX_BALANCE,
ThresholdValue: 2,
}
a := &Action{BalanceType: utils.VOICE, ExtraParameters: fmt.Sprintf(`{"ThresholdType":"%v", "ThresholdValue": %v, "BalanceDirections":"*in"}`, utils.TRIGGER_MAX_EVENT_COUNTER, 3)}
a := &Action{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ExtraParameters: fmt.Sprintf(`{"ThresholdType":"%v", "ThresholdValue": %v, "BalanceDirections":"*in"}`, utils.TRIGGER_MAX_EVENT_COUNTER, 3)}
if at.Match(a) {
t.Errorf("Action trigger [%v] does not match action [%v]", at, a)
}
@@ -631,16 +651,18 @@ func TestActionTriggerMatcAllFalse(t *testing.T) {
func TestActionTriggerMatchAll(t *testing.T) {
at := &ActionTrigger{
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceType: utils.MONETARY,
ThresholdType: utils.TRIGGER_MAX_BALANCE,
ThresholdValue: 2,
BalanceDestinationIds: utils.NewStringMap("NAT"),
BalanceWeight: 1.0,
BalanceRatingSubject: "test1",
BalanceSharedGroups: utils.NewStringMap("test2"),
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
RatingSubject: utils.StringPointer("test1"),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
Value: utils.Float64Pointer(2),
Weight: utils.Float64Pointer(1.0),
DestinationIds: utils.StringMapPointer(utils.NewStringMap("NAT")),
SharedGroups: utils.StringMapPointer(utils.NewStringMap("test2")),
},
ThresholdType: utils.TRIGGER_MAX_BALANCE,
}
a := &Action{BalanceType: utils.MONETARY, ExtraParameters: fmt.Sprintf(`{"BalanceDirections":"*out", "ThresholdType":"%v", "ThresholdValue": %v, "DestinationIds": "%v", "BalanceWeight": %v, "BalanceRatingSubject": "%v", "BalanceSharedGroup": "%v"}`, utils.TRIGGER_MAX_BALANCE, 2, "NAT", 1.0, "test1", "test2")}
a := &Action{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ExtraParameters: fmt.Sprintf(`{"BalanceDirections":"*out", "ThresholdType":"%v", "ThresholdValue": %v, "DestinationIds": "%v", "BalanceWeight": %v, "BalanceRatingSubject": "%v", "BalanceSharedGroup": "%v"}`, utils.TRIGGER_MAX_BALANCE, 2, "NAT", 1.0, "test1", "test2")}
if !at.Match(a) {
t.Errorf("Action trigger [%v] does not match action [%v]", at, a)
}
@@ -663,7 +685,7 @@ func TestActionResetTriggres(t *testing.T) {
Id: "TEST_UB",
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Value: 10}}, utils.VOICE: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationIds: utils.NewStringMap("NAT")}, &Balance{Weight: 10, DestinationIds: utils.NewStringMap("RET")}}},
UnitCounters: UnitCounters{&UnitCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1}}}},
ActionTriggers: ActionTriggers{&ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
}
resetTriggersAction(ub, nil, nil, nil)
if ub.ActionTriggers[0].Executed == true || ub.ActionTriggers[1].Executed == true {
@@ -676,7 +698,7 @@ func TestActionResetTriggresExecutesThem(t *testing.T) {
Id: "TEST_UB",
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Value: 10}}},
UnitCounters: UnitCounters{&UnitCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1}}}},
ActionTriggers: ActionTriggers{&ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
}
resetTriggersAction(ub, nil, nil, nil)
if ub.ActionTriggers[0].Executed == true || ub.BalanceMap[utils.MONETARY][0].GetValue() == 12 {
@@ -689,9 +711,9 @@ func TestActionResetTriggresActionFilter(t *testing.T) {
Id: "TEST_UB",
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Value: 10}}, utils.VOICE: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationIds: utils.NewStringMap("NAT")}, &Balance{Weight: 10, DestinationIds: utils.NewStringMap("RET")}}},
UnitCounters: UnitCounters{&UnitCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1}}}},
ActionTriggers: ActionTriggers{&ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
}
resetTriggersAction(ub, nil, &Action{BalanceType: utils.SMS}, nil)
resetTriggersAction(ub, nil, &Action{Balance: &BalancePointer{Type: utils.StringPointer(utils.SMS)}}, nil)
if ub.ActionTriggers[0].Executed == false || ub.ActionTriggers[1].Executed == false {
t.Error("Reset triggers action failed!")
}
@@ -702,7 +724,7 @@ func TestActionSetPostpaid(t *testing.T) {
Id: "TEST_UB",
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Value: 100}}, utils.VOICE: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationIds: utils.NewStringMap("NAT")}, &Balance{Weight: 10, DestinationIds: utils.NewStringMap("RET")}}},
UnitCounters: UnitCounters{&UnitCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1}}}},
ActionTriggers: ActionTriggers{&ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
}
allowNegativeAction(ub, nil, nil, nil)
if !ub.AllowNegative {
@@ -716,7 +738,7 @@ func TestActionSetPrepaid(t *testing.T) {
AllowNegative: true,
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Value: 100}}, utils.VOICE: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationIds: utils.NewStringMap("NAT")}, &Balance{Weight: 10, DestinationIds: utils.NewStringMap("RET")}}},
UnitCounters: UnitCounters{&UnitCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1}}}},
ActionTriggers: ActionTriggers{&ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
}
denyNegativeAction(ub, nil, nil, nil)
if ub.AllowNegative {
@@ -730,7 +752,7 @@ func TestActionResetPrepaid(t *testing.T) {
AllowNegative: true,
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Value: 100}}, utils.VOICE: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationIds: utils.NewStringMap("NAT")}, &Balance{Weight: 10, DestinationIds: utils.NewStringMap("RET")}}},
UnitCounters: UnitCounters{&UnitCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1}}}},
ActionTriggers: ActionTriggers{&ActionTrigger{BalanceType: utils.SMS, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.SMS, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.SMS)}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.SMS)}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
}
resetAccountAction(ub, nil, nil, nil)
if !ub.AllowNegative ||
@@ -748,7 +770,7 @@ func TestActionResetPostpaid(t *testing.T) {
Id: "TEST_UB",
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Value: 100}}, utils.VOICE: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationIds: utils.NewStringMap("NAT")}, &Balance{Weight: 10, DestinationIds: utils.NewStringMap("RET")}}},
UnitCounters: UnitCounters{&UnitCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1}}}},
ActionTriggers: ActionTriggers{&ActionTrigger{BalanceType: utils.SMS, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.SMS, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.SMS)}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.SMS)}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
}
resetAccountAction(ub, nil, nil, nil)
if ub.BalanceMap[utils.MONETARY].GetTotalValue() != 0 ||
@@ -764,9 +786,9 @@ func TestActionTopupResetCredit(t *testing.T) {
Id: "TEST_UB",
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Directions: utils.NewStringMap(utils.OUT), Value: 100}}, utils.VOICE: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationIds: utils.NewStringMap("NAT")}, &Balance{Weight: 10, DestinationIds: utils.NewStringMap("RET")}}},
UnitCounters: UnitCounters{&UnitCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1, Directions: utils.NewStringMap(utils.OUT)}}}},
ActionTriggers: ActionTriggers{&ActionTrigger{BalanceType: utils.MONETARY, BalanceDirections: utils.NewStringMap(utils.OUT), ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, BalanceDirections: utils.NewStringMap(utils.OUT), ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
}
a := &Action{BalanceType: utils.MONETARY, Balance: &Balance{Value: 10, Directions: utils.NewStringMap(utils.OUT)}}
a := &Action{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Value: utils.Float64Pointer(10), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}}
topupResetAction(ub, nil, a, nil)
if ub.AllowNegative ||
ub.BalanceMap[utils.MONETARY].GetTotalValue() != 10 ||
@@ -783,10 +805,10 @@ func TestActionTopupValueFactor(t *testing.T) {
BalanceMap: map[string]BalanceChain{},
}
a := &Action{
BalanceType: utils.MONETARY,
Balance: &Balance{
Value: 10,
Directions: utils.NewStringMap(utils.OUT),
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Value: utils.Float64Pointer(10),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
},
ExtraParameters: `{"*monetary":2.0}`,
}
@@ -806,7 +828,7 @@ func TestActionTopupResetCreditId(t *testing.T) {
},
},
}
a := &Action{BalanceType: utils.MONETARY, Balance: &Balance{Id: "TEST_B", Value: 10, Directions: utils.NewStringMap(utils.OUT)}}
a := &Action{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Id: utils.StringPointer("TEST_B"), Value: utils.Float64Pointer(10), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}}
topupResetAction(ub, nil, a, nil)
if ub.AllowNegative ||
ub.BalanceMap[utils.MONETARY].GetTotalValue() != 110 ||
@@ -825,7 +847,7 @@ func TestActionTopupResetCreditNoId(t *testing.T) {
},
},
}
a := &Action{BalanceType: utils.MONETARY, Balance: &Balance{Value: 10, Directions: utils.NewStringMap(utils.OUT)}}
a := &Action{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Value: utils.Float64Pointer(10), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}}
topupResetAction(ub, nil, a, nil)
if ub.AllowNegative ||
ub.BalanceMap[utils.MONETARY].GetTotalValue() != 20 ||
@@ -841,9 +863,9 @@ func TestActionTopupResetMinutes(t *testing.T) {
utils.MONETARY: BalanceChain{&Balance{Value: 100}},
utils.VOICE: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationIds: utils.NewStringMap("NAT"), Directions: utils.NewStringMap(utils.OUT)}, &Balance{Weight: 10, DestinationIds: utils.NewStringMap("RET")}}},
UnitCounters: UnitCounters{&UnitCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1, Directions: utils.NewStringMap(utils.OUT)}}}},
ActionTriggers: ActionTriggers{&ActionTrigger{BalanceType: utils.MONETARY, BalanceDirections: utils.NewStringMap(utils.OUT), ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, BalanceDirections: utils.NewStringMap(utils.OUT), ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
}
a := &Action{BalanceType: utils.VOICE, Balance: &Balance{Value: 5, Weight: 20, DestinationIds: utils.NewStringMap("NAT"), Directions: utils.NewStringMap(utils.OUT)}}
a := &Action{Balance: &BalancePointer{Type: utils.StringPointer(utils.VOICE), Value: utils.Float64Pointer(5), Weight: utils.Float64Pointer(20), DestinationIds: utils.StringMapPointer(utils.NewStringMap("NAT")), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}}
topupResetAction(ub, nil, a, nil)
if ub.AllowNegative ||
ub.BalanceMap[utils.VOICE].GetTotalValue() != 5 ||
@@ -860,9 +882,9 @@ func TestActionTopupCredit(t *testing.T) {
Id: "TEST_UB",
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Value: 100}}, utils.VOICE: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationIds: utils.NewStringMap("NAT"), Directions: utils.NewStringMap(utils.OUT)}, &Balance{Weight: 10, DestinationIds: utils.NewStringMap("RET")}}},
UnitCounters: UnitCounters{&UnitCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1, Directions: utils.NewStringMap(utils.OUT)}}}},
ActionTriggers: ActionTriggers{&ActionTrigger{BalanceType: utils.MONETARY, BalanceDirections: utils.NewStringMap(utils.OUT), ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, BalanceDirections: utils.NewStringMap(utils.OUT), ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
}
a := &Action{BalanceType: utils.MONETARY, Balance: &Balance{Value: 10, Directions: utils.NewStringMap(utils.OUT)}}
a := &Action{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Value: utils.Float64Pointer(10), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}}
topupAction(ub, nil, a, nil)
if ub.AllowNegative ||
ub.BalanceMap[utils.MONETARY].GetTotalValue() != 110 ||
@@ -878,9 +900,9 @@ func TestActionTopupMinutes(t *testing.T) {
Id: "TEST_UB",
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Value: 100}}, utils.VOICE: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationIds: utils.NewStringMap("NAT"), Directions: utils.NewStringMap(utils.OUT)}, &Balance{Weight: 10, DestinationIds: utils.NewStringMap("RET")}}},
UnitCounters: UnitCounters{&UnitCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1}}}},
ActionTriggers: ActionTriggers{&ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
}
a := &Action{BalanceType: utils.VOICE, Balance: &Balance{Value: 5, Weight: 20, DestinationIds: utils.NewStringMap("NAT"), Directions: utils.NewStringMap(utils.OUT)}}
a := &Action{Balance: &BalancePointer{Type: utils.StringPointer(utils.VOICE), Value: utils.Float64Pointer(5), Weight: utils.Float64Pointer(20), DestinationIds: utils.StringMapPointer(utils.NewStringMap("NAT")), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}}
topupAction(ub, nil, a, nil)
if ub.AllowNegative ||
ub.BalanceMap[utils.VOICE].GetTotalValue() != 15 ||
@@ -897,9 +919,9 @@ func TestActionDebitCredit(t *testing.T) {
Id: "TEST_UB",
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Value: 100}}, utils.VOICE: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationIds: utils.NewStringMap("NAT")}, &Balance{Weight: 10, DestinationIds: utils.NewStringMap("RET")}}},
UnitCounters: UnitCounters{&UnitCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1, Directions: utils.NewStringMap(utils.OUT)}}}},
ActionTriggers: ActionTriggers{&ActionTrigger{BalanceType: utils.MONETARY, BalanceDirections: utils.NewStringMap(utils.OUT), ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, BalanceDirections: utils.NewStringMap(utils.OUT), ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
}
a := &Action{BalanceType: utils.MONETARY, Balance: &Balance{Value: 10, Directions: utils.NewStringMap(utils.OUT)}}
a := &Action{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Value: utils.Float64Pointer(10), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}}
debitAction(ub, nil, a, nil)
if ub.AllowNegative ||
ub.BalanceMap[utils.MONETARY].GetTotalValue() != 90 ||
@@ -915,9 +937,9 @@ func TestActionDebitMinutes(t *testing.T) {
Id: "TEST_UB",
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Value: 100}}, utils.VOICE: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationIds: utils.NewStringMap("NAT"), Directions: utils.NewStringMap(utils.OUT)}, &Balance{Weight: 10, DestinationIds: utils.NewStringMap("RET")}}},
UnitCounters: UnitCounters{&UnitCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1}}}},
ActionTriggers: ActionTriggers{&ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
}
a := &Action{BalanceType: utils.VOICE, Balance: &Balance{Value: 5, Weight: 20, DestinationIds: utils.NewStringMap("NAT"), Directions: utils.NewStringMap(utils.OUT)}}
a := &Action{Balance: &BalancePointer{Type: utils.StringPointer(utils.VOICE), Value: utils.Float64Pointer(5), Weight: utils.Float64Pointer(20), DestinationIds: utils.StringMapPointer(utils.NewStringMap("NAT")), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}}
debitAction(ub, nil, a, nil)
if ub.AllowNegative ||
ub.BalanceMap[utils.VOICE][0].GetValue() != 5 ||
@@ -939,7 +961,7 @@ func TestActionResetAllCounters(t *testing.T) {
&Balance{Value: 10, Weight: 20, DestinationIds: utils.NewStringMap("NAT"), Directions: utils.NewStringMap(utils.OUT)},
&Balance{Weight: 10, DestinationIds: utils.NewStringMap("RET"), Directions: utils.NewStringMap(utils.OUT)}}},
ActionTriggers: ActionTriggers{&ActionTrigger{ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER, BalanceType: utils.MONETARY, ThresholdValue: 2, BalanceDestinationIds: utils.NewStringMap("NAT"), BalanceWeight: 20, ActionsId: "TEST_ACTIONS", Executed: true}},
ActionTriggers: ActionTriggers{&ActionTrigger{ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER, ThresholdValue: 2, Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), DestinationIds: utils.StringMapPointer(utils.NewStringMap("NAT")), Weight: utils.Float64Pointer(20)}, ActionsId: "TEST_ACTIONS", Executed: true}},
}
ub.InitCounters()
resetCountersAction(ub, nil, nil, nil)
@@ -967,9 +989,9 @@ func TestActionResetCounterOnlyDefault(t *testing.T) {
BalanceMap: map[string]BalanceChain{
utils.MONETARY: BalanceChain{&Balance{Value: 100}},
utils.VOICE: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationIds: utils.NewStringMap("NAT")}, &Balance{Weight: 10, DestinationIds: utils.NewStringMap("RET")}}},
ActionTriggers: ActionTriggers{&ActionTrigger{BalanceType: utils.MONETARY, ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}, ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
}
a := &Action{BalanceType: utils.MONETARY}
a := &Action{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}}
ub.InitCounters()
resetCountersAction(ub, nil, a, nil)
if !ub.AllowNegative ||
@@ -998,9 +1020,9 @@ func TestActionResetCounterCredit(t *testing.T) {
AllowNegative: true,
BalanceMap: map[string]BalanceChain{utils.MONETARY: BalanceChain{&Balance{Value: 100}}, utils.VOICE: BalanceChain{&Balance{Value: 10, Weight: 20, DestinationIds: utils.NewStringMap("NAT")}, &Balance{Weight: 10, DestinationIds: utils.NewStringMap("RET")}}},
UnitCounters: UnitCounters{&UnitCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1, Directions: utils.NewStringMap(utils.OUT)}}}, &UnitCounter{BalanceType: utils.SMS, Balances: BalanceChain{&Balance{Value: 1, Directions: utils.NewStringMap(utils.OUT)}}}},
ActionTriggers: ActionTriggers{&ActionTrigger{BalanceType: utils.MONETARY, BalanceDirections: utils.NewStringMap(utils.OUT), ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
ActionTriggers: ActionTriggers{&ActionTrigger{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT))}, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}},
}
a := &Action{BalanceType: utils.MONETARY}
a := &Action{Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY)}}
resetCountersAction(ub, nil, a, nil)
if !ub.AllowNegative ||
ub.BalanceMap[utils.MONETARY].GetTotalValue() != 100 ||
@@ -1013,13 +1035,15 @@ func TestActionResetCounterCredit(t *testing.T) {
func TestActionTriggerLogging(t *testing.T) {
at := &ActionTrigger{
ID: "some_uuid",
BalanceType: utils.MONETARY,
BalanceDirections: utils.NewStringMap(utils.OUT),
ThresholdValue: 100.0,
BalanceDestinationIds: utils.NewStringMap("NAT"),
Weight: 10.0,
ActionsId: "TEST_ACTIONS",
ID: "some_uuid",
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
DestinationIds: utils.StringMapPointer(utils.NewStringMap("NAT")),
},
ThresholdValue: 100.0,
Weight: 10.0,
ActionsId: "TEST_ACTIONS",
}
as, err := ratingStorage.GetActions(at.ActionsId, false)
if err != nil {
@@ -1084,7 +1108,7 @@ func TestActionPlanLogging(t *testing.T) {
}
func TestActionMakeNegative(t *testing.T) {
a := &Action{Balance: &Balance{Value: 10}}
a := &Action{Balance: &BalancePointer{Value: utils.Float64Pointer(10)}}
genericMakeNegative(a)
if a.Balance.GetValue() > 0 {
t.Error("Failed to make negative: ", a)
@@ -1117,9 +1141,8 @@ func TestRemoveAction(t *testing.T) {
func TestTopupAction(t *testing.T) {
initialUb, _ := accountingStorage.GetAccount("vdf:minu")
a := &Action{
ActionType: TOPUP,
BalanceType: utils.MONETARY,
Balance: &Balance{Value: 25, DestinationIds: utils.NewStringMap("RET"), Directions: utils.NewStringMap(utils.OUT), Weight: 20},
ActionType: TOPUP,
Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Value: utils.Float64Pointer(25), DestinationIds: utils.StringMapPointer(utils.NewStringMap("RET")), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)), Weight: utils.Float64Pointer(20)},
}
at := &ActionTiming{
@@ -1139,9 +1162,8 @@ func TestTopupAction(t *testing.T) {
func TestTopupActionLoaded(t *testing.T) {
initialUb, _ := accountingStorage.GetAccount("vdf:minitsboy")
a := &Action{
ActionType: TOPUP,
BalanceType: utils.MONETARY,
Balance: &Balance{Value: 25, DestinationIds: utils.NewStringMap("RET"), Directions: utils.NewStringMap(utils.OUT), Weight: 20},
ActionType: TOPUP,
Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Value: utils.Float64Pointer(25), DestinationIds: utils.StringMapPointer(utils.NewStringMap("RET")), Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)), Weight: utils.Float64Pointer(20)},
}
at := &ActionTiming{
@@ -1168,7 +1190,7 @@ func TestActionCdrlogEmpty(t *testing.T) {
err := cdrLogAction(acnt, nil, cdrlog, Actions{
&Action{
ActionType: DEBIT,
Balance: &Balance{Value: 25, DestinationIds: utils.NewStringMap("RET"), Weight: 20},
Balance: &BalancePointer{Value: utils.Float64Pointer(25), DestinationIds: utils.StringMapPointer(utils.NewStringMap("RET")), Weight: utils.Float64Pointer(20)},
},
})
if err != nil {
@@ -1190,11 +1212,11 @@ func TestActionCdrlogWithParams(t *testing.T) {
err := cdrLogAction(acnt, nil, cdrlog, Actions{
&Action{
ActionType: DEBIT,
Balance: &Balance{Value: 25, DestinationIds: utils.NewStringMap("RET"), Weight: 20},
Balance: &BalancePointer{Value: utils.Float64Pointer(25), DestinationIds: utils.StringMapPointer(utils.NewStringMap("RET")), Weight: utils.Float64Pointer(20)},
},
&Action{
ActionType: DEBIT_RESET,
Balance: &Balance{Value: 25, DestinationIds: utils.NewStringMap("RET"), Weight: 20},
Balance: &BalancePointer{Value: utils.Float64Pointer(25), DestinationIds: utils.StringMapPointer(utils.NewStringMap("RET")), Weight: utils.Float64Pointer(20)},
},
})
if err != nil {
@@ -1217,11 +1239,11 @@ func TestActionCdrLogParamsWithOverload(t *testing.T) {
err := cdrLogAction(acnt, nil, cdrlog, Actions{
&Action{
ActionType: DEBIT,
Balance: &Balance{Value: 25, DestinationIds: utils.NewStringMap("RET"), Weight: 20},
Balance: &BalancePointer{Value: utils.Float64Pointer(25), DestinationIds: utils.StringMapPointer(utils.NewStringMap("RET")), Weight: utils.Float64Pointer(20)},
},
&Action{
ActionType: DEBIT_RESET,
Balance: &Balance{Value: 25, DestinationIds: utils.NewStringMap("RET"), Weight: 20},
Balance: &BalancePointer{Value: utils.Float64Pointer(25), DestinationIds: utils.StringMapPointer(utils.NewStringMap("RET")), Weight: utils.Float64Pointer(20)},
},
})
if err != nil {
@@ -1301,14 +1323,12 @@ func TestActionTransactionFuncType(t *testing.T) {
Timing: &RateInterval{},
actions: []*Action{
&Action{
ActionType: TOPUP,
BalanceType: utils.MONETARY,
Balance: &Balance{Value: 1.1},
ActionType: TOPUP,
Balance: &BalancePointer{Value: utils.Float64Pointer(1.1), Type: utils.StringPointer(utils.MONETARY)},
},
&Action{
ActionType: "VALID_FUNCTION_TYPE",
BalanceType: "test",
Balance: &Balance{Value: 1.1},
ActionType: "VALID_FUNCTION_TYPE",
Balance: &BalancePointer{Value: utils.Float64Pointer(1.1), Type: utils.StringPointer("test")},
},
},
}
@@ -1339,14 +1359,12 @@ func TestActionTransactionBalanceType(t *testing.T) {
Timing: &RateInterval{},
actions: []*Action{
&Action{
ActionType: TOPUP,
BalanceType: utils.MONETARY,
Balance: &Balance{Value: 1.1},
ActionType: TOPUP,
Balance: &BalancePointer{Value: utils.Float64Pointer(1.1), Type: utils.StringPointer(utils.MONETARY)},
},
&Action{
ActionType: TOPUP,
BalanceType: "test",
Balance: nil,
ActionType: TOPUP,
Balance: &BalancePointer{Type: utils.StringPointer("test")},
},
},
}
@@ -1377,18 +1395,18 @@ func TestActionWithExpireWithoutExpire(t *testing.T) {
Timing: &RateInterval{},
actions: []*Action{
&Action{
ActionType: TOPUP,
BalanceType: utils.VOICE,
Balance: &Balance{
Value: 15,
ActionType: TOPUP,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Value: utils.Float64Pointer(15),
},
},
&Action{
ActionType: TOPUP,
BalanceType: utils.VOICE,
Balance: &Balance{
Value: 30,
ExpirationDate: time.Date(2025, time.November, 11, 22, 39, 0, 0, time.UTC),
ActionType: TOPUP,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Value: utils.Float64Pointer(30),
ExpirationDate: utils.TimePointer(time.Date(2025, time.November, 11, 22, 39, 0, 0, time.UTC)),
},
},
},
@@ -1432,10 +1450,10 @@ func TestActionRemoveBalance(t *testing.T) {
Timing: &RateInterval{},
actions: []*Action{
&Action{
ActionType: REMOVE_BALANCE,
BalanceType: utils.MONETARY,
Balance: &Balance{
DestinationIds: utils.NewStringMap("NAT", "RET"),
ActionType: REMOVE_BALANCE,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
DestinationIds: utils.StringMapPointer(utils.NewStringMap("NAT", "RET")),
},
},
},
@@ -1543,7 +1561,7 @@ func TestActionTransferMonetaryDefaultFilter(t *testing.T) {
a := &Action{
ActionType: TRANSFER_MONETARY_DEFAULT,
Balance: &Balance{Weight: 20},
Balance: &BalancePointer{Weight: utils.Float64Pointer(20)},
}
at := &ActionTiming{
@@ -1603,12 +1621,12 @@ func TestActionConditionalTopup(t *testing.T) {
}
a := &Action{
ActionType: TOPUP,
BalanceType: utils.MONETARY,
Filter: `{"Type":"*monetary","Value":1,"Weight":10}`,
Balance: &Balance{
Value: 11,
Weight: 30,
ActionType: TOPUP,
Filter: `{"Type":"*monetary","Value":1,"Weight":10}`,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Value: utils.Float64Pointer(11),
Weight: utils.Float64Pointer(30),
},
}
@@ -1667,12 +1685,12 @@ func TestActionConditionalTopupNoMatch(t *testing.T) {
}
a := &Action{
ActionType: TOPUP,
BalanceType: utils.MONETARY,
Filter: `{"Type":"*monetary","Value":2,"Weight":10}`,
Balance: &Balance{
Value: 11,
Weight: 30,
ActionType: TOPUP,
Filter: `{"Type":"*monetary","Value":2,"Weight":10}`,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Value: utils.Float64Pointer(11),
Weight: utils.Float64Pointer(30),
},
}
@@ -1731,12 +1749,12 @@ func TestActionConditionalTopupExistingBalance(t *testing.T) {
}
a := &Action{
ActionType: TOPUP,
BalanceType: utils.MONETARY,
Filter: `{"Type":"*voice","Value":{"*gte":100}}`,
Balance: &Balance{
Value: 11,
Weight: 10,
ActionType: TOPUP,
Filter: `{"Type":"*voice","Value":{"*gte":100}}`,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Value: utils.Float64Pointer(11),
Weight: utils.Float64Pointer(10),
},
}
@@ -1832,45 +1850,45 @@ func TestActionConditionalDisabledIfNegative(t *testing.T) {
}
a1 := &Action{
ActionType: "*enable_disable_balance",
BalanceType: "*sms",
Filter: "{\"*and\":[{\"Value\":{\"*lt\":0}},{\"Id\":{\"*eq\":\"*default\"}}]}",
Balance: &Balance{
Weight: 10,
Disabled: true,
ActionType: "*enable_disable_balance",
Filter: "{\"*and\":[{\"Value\":{\"*lt\":0}},{\"Id\":{\"*eq\":\"*default\"}}]}",
Balance: &BalancePointer{
Type: utils.StringPointer("*sms"),
Weight: utils.Float64Pointer(10),
Disabled: utils.BoolPointer(true),
},
Weight: 9,
}
a2 := &Action{
ActionType: "*enable_disable_balance",
BalanceType: "*sms",
Filter: "{\"*and\":[{\"Value\":{\"*lt\":0}},{\"Id\":{\"*eq\":\"*default\"}}]}",
Balance: &Balance{
DestinationIds: utils.NewStringMap("FRANCE_NATIONAL"),
Weight: 10,
Disabled: true,
ActionType: "*enable_disable_balance",
Filter: "{\"*and\":[{\"Value\":{\"*lt\":0}},{\"Id\":{\"*eq\":\"*default\"}}]}",
Balance: &BalancePointer{
Type: utils.StringPointer("*sms"),
DestinationIds: utils.StringMapPointer(utils.NewStringMap("FRANCE_NATIONAL")),
Weight: utils.Float64Pointer(10),
Disabled: utils.BoolPointer(true),
},
Weight: 8,
}
a3 := &Action{
ActionType: "*enable_disable_balance",
BalanceType: "*data",
Filter: "{\"*and\":[{\"Value\":{\"*lt\":0}},{\"Id\":{\"*eq\":\"*default\"}}]}",
Balance: &Balance{
RatingSubject: "for_v3hsillmilld500m_data_forfait",
Weight: 10,
Disabled: true,
ActionType: "*enable_disable_balance",
Filter: "{\"*and\":[{\"Value\":{\"*lt\":0}},{\"Id\":{\"*eq\":\"*default\"}}]}",
Balance: &BalancePointer{
Type: utils.StringPointer("*data"),
RatingSubject: utils.StringPointer("for_v3hsillmilld500m_data_forfait"),
Weight: utils.Float64Pointer(10),
Disabled: utils.BoolPointer(true),
},
Weight: 7,
}
a4 := &Action{
ActionType: "*enable_disable_balance",
BalanceType: "*voice",
Filter: "{\"*and\":[{\"Value\":{\"*lt\":0}},{\"Id\":{\"*eq\":\"*default\"}}]}",
Balance: &Balance{
DestinationIds: utils.NewStringMap("FRANCE_NATIONAL"),
Weight: 10,
Disabled: true,
ActionType: "*enable_disable_balance",
Filter: "{\"*and\":[{\"Value\":{\"*lt\":0}},{\"Id\":{\"*eq\":\"*default\"}}]}",
Balance: &BalancePointer{
Type: utils.StringPointer("*voice"),
DestinationIds: utils.StringMapPointer(utils.NewStringMap("FRANCE_NATIONAL")),
Weight: utils.Float64Pointer(10),
Disabled: utils.BoolPointer(true),
},
Weight: 6,
}
@@ -1937,12 +1955,12 @@ func TestActionSetBalance(t *testing.T) {
}
a := &Action{
ActionType: SET_BALANCE,
BalanceType: utils.MONETARY,
Balance: &Balance{
Id: "m2",
Value: 11,
Weight: 10,
ActionType: SET_BALANCE,
Balance: &BalancePointer{
Id: utils.StringPointer("m2"),
Type: utils.StringPointer(utils.MONETARY),
Value: utils.Float64Pointer(11),
Weight: utils.Float64Pointer(10),
},
}

View File

@@ -94,6 +94,28 @@ func (b *Balance) MatchFilter(o *BalancePointer, skipIds bool) bool {
(o.RatingSubject == nil || b.RatingSubject == *o.RatingSubject)
}
func (b *Balance) HardMatchFilter(o *BalancePointer, skipIds bool) bool {
if o == nil {
return true
}
if !skipIds && o.Uuid != nil && *o.Uuid != "" {
return b.Uuid == *o.Uuid
}
if !skipIds && o.Id != nil && *o.Id != "" {
return b.Id == *o.Id
}
return (o.ExpirationDate == nil || b.ExpirationDate.Equal(*o.ExpirationDate)) &&
(o.Weight == nil || b.Weight == *o.Weight) &&
(o.Blocker != nil || b.Blocker == *o.Blocker) &&
(o.Disabled == nil || b.Disabled == *o.Disabled) &&
(o.DestinationIds == nil || b.DestinationIds.Equal(*o.DestinationIds)) &&
(o.Directions == nil || b.Directions.Equal(*o.Directions)) &&
(o.Categories == nil || b.Categories.Equal(*o.Categories)) &&
(o.TimingIDs == nil || b.TimingIDs.Equal(*o.TimingIDs)) &&
(o.SharedGroups == nil || b.SharedGroups.Equal(*o.SharedGroups)) &&
(o.RatingSubject == nil || b.RatingSubject == *o.RatingSubject)
}
func (b *Balance) MatchCCFilter(cc *CallCost) bool {
if len(b.Categories) > 0 && cc.Category != "" && b.Categories[cc.Category] == false {
return false
@@ -174,47 +196,7 @@ 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 len(at.BalanceDestinationIds) != 0 {
matchesDestination = (b.DestinationIds.Equal(at.BalanceDestinationIds))
}
matchesDirection := true
if len(at.BalanceDirections) != 0 {
matchesDirection = (b.Directions.Equal(at.BalanceDirections))
}
matchesExpirationDate := true
if !at.BalanceExpirationDate.IsZero() {
matchesExpirationDate = (at.BalanceExpirationDate.Equal(b.ExpirationDate))
}
matchesWeight := true
if at.BalanceWeight > 0 {
matchesWeight = (at.BalanceWeight == b.Weight)
}
matchesRatingSubject := true
if at.BalanceRatingSubject != "" {
matchesRatingSubject = (at.BalanceRatingSubject == b.RatingSubject)
}
matchesSharedGroup := true
if len(at.BalanceSharedGroups) != 0 {
matchesSharedGroup = at.BalanceSharedGroups.Equal(b.SharedGroups)
}
matchesTiming := true
if len(at.BalanceTimingTags) != 0 {
matchesTiming = at.BalanceTimingTags.Equal(b.TimingIDs)
}
return matchesDestination &&
matchesDirection &&
matchesExpirationDate &&
matchesWeight &&
matchesRatingSubject &&
matchesSharedGroup &&
matchesTiming
return b.HardMatchFilter(at.Balance, false)
}
func (b *Balance) Clone() *Balance {

View File

@@ -90,7 +90,7 @@ func TestBalanceEqual(t *testing.T) {
func TestBalanceMatchFilter(t *testing.T) {
mb1 := &Balance{Weight: 1, precision: 1, RatingSubject: "1", DestinationIds: utils.StringMap{}}
mb2 := &Balance{Weight: 1, precision: 1, RatingSubject: "", DestinationIds: utils.StringMap{}}
mb2 := &BalancePointer{Weight: utils.Float64Pointer(1), RatingSubject: nil, DestinationIds: nil}
if !mb1.MatchFilter(mb2, false) {
t.Errorf("Match filter failure: %+v == %+v", mb1, mb2)
}
@@ -98,7 +98,7 @@ func TestBalanceMatchFilter(t *testing.T) {
func TestBalanceMatchFilterEmpty(t *testing.T) {
mb1 := &Balance{Weight: 1, precision: 1, RatingSubject: "1", DestinationIds: utils.StringMap{}}
mb2 := &Balance{}
mb2 := &BalancePointer{}
if !mb1.MatchFilter(mb2, false) {
t.Errorf("Match filter failure: %+v == %+v", mb1, mb2)
}
@@ -106,7 +106,7 @@ func TestBalanceMatchFilterEmpty(t *testing.T) {
func TestBalanceMatchFilterId(t *testing.T) {
mb1 := &Balance{Id: "T1", Weight: 2, precision: 2, RatingSubject: "2", DestinationIds: utils.NewStringMap("NAT")}
mb2 := &Balance{Id: "T1", Weight: 1, precision: 1, RatingSubject: "1", DestinationIds: utils.StringMap{}}
mb2 := &BalancePointer{Id: utils.StringPointer("T1"), Weight: utils.Float64Pointer(1), RatingSubject: utils.StringPointer("1"), DestinationIds: nil}
if !mb1.MatchFilter(mb2, false) {
t.Errorf("Match filter failure: %+v == %+v", mb1, mb2)
}
@@ -114,7 +114,7 @@ func TestBalanceMatchFilterId(t *testing.T) {
func TestBalanceMatchFilterDiffId(t *testing.T) {
mb1 := &Balance{Id: "T1", Weight: 1, precision: 1, RatingSubject: "1", DestinationIds: utils.StringMap{}}
mb2 := &Balance{Id: "T2", Weight: 1, precision: 1, RatingSubject: "1", DestinationIds: utils.StringMap{}}
mb2 := &BalancePointer{Id: utils.StringPointer("T2"), Weight: utils.Float64Pointer(1), RatingSubject: utils.StringPointer("1"), DestinationIds: nil}
if mb1.MatchFilter(mb2, false) {
t.Errorf("Match filter failure: %+v != %+v", mb1, mb2)
}
@@ -129,7 +129,7 @@ func TestBalanceClone(t *testing.T) {
}
func TestBalanceMatchActionTriggerId(t *testing.T) {
at := &ActionTrigger{BalanceId: "test"}
at := &ActionTrigger{Balance: &BalancePointer{Id: utils.StringPointer("test")}}
b := &Balance{Id: "test"}
if !b.MatchActionTrigger(at) {
t.Errorf("Error matching action trigger: %+v %+v", b, at)
@@ -143,14 +143,14 @@ func TestBalanceMatchActionTriggerId(t *testing.T) {
t.Errorf("Error matching action trigger: %+v %+v", b, at)
}
b.Id = "test"
at.BalanceId = ""
at.Balance.Id = nil
if !b.MatchActionTrigger(at) {
t.Errorf("Error matching action trigger: %+v %+v", b, at)
}
}
func TestBalanceMatchActionTriggerDestination(t *testing.T) {
at := &ActionTrigger{BalanceDestinationIds: utils.NewStringMap("test")}
at := &ActionTrigger{Balance: &BalancePointer{DestinationIds: utils.StringMapPointer(utils.NewStringMap("test"))}}
b := &Balance{DestinationIds: utils.NewStringMap("test")}
if !b.MatchActionTrigger(at) {
t.Errorf("Error matching action trigger: %+v %+v", b, at)
@@ -164,14 +164,14 @@ func TestBalanceMatchActionTriggerDestination(t *testing.T) {
t.Errorf("Error matching action trigger: %+v %+v", b, at)
}
b.DestinationIds = utils.NewStringMap("test")
at.BalanceDestinationIds = utils.NewStringMap("")
at.Balance.DestinationIds = nil
if !b.MatchActionTrigger(at) {
t.Errorf("Error matching action trigger: %+v %+v", b, at)
}
}
func TestBalanceMatchActionTriggerWeight(t *testing.T) {
at := &ActionTrigger{BalanceWeight: 1}
at := &ActionTrigger{Balance: &BalancePointer{Weight: utils.Float64Pointer(1)}}
b := &Balance{Weight: 1}
if !b.MatchActionTrigger(at) {
t.Errorf("Error matching action trigger: %+v %+v", b, at)
@@ -185,14 +185,14 @@ func TestBalanceMatchActionTriggerWeight(t *testing.T) {
t.Errorf("Error matching action trigger: %+v %+v", b, at)
}
b.Weight = 1
at.BalanceWeight = 0
at.Balance.Weight = nil
if !b.MatchActionTrigger(at) {
t.Errorf("Error matching action trigger: %+v %+v", b, at)
}
}
func TestBalanceMatchActionTriggerRatingSubject(t *testing.T) {
at := &ActionTrigger{BalanceRatingSubject: "test"}
at := &ActionTrigger{Balance: &BalancePointer{RatingSubject: utils.StringPointer("test")}}
b := &Balance{RatingSubject: "test"}
if !b.MatchActionTrigger(at) {
t.Errorf("Error matching action trigger: %+v %+v", b, at)
@@ -206,14 +206,14 @@ func TestBalanceMatchActionTriggerRatingSubject(t *testing.T) {
t.Errorf("Error matching action trigger: %+v %+v", b, at)
}
b.RatingSubject = "test"
at.BalanceRatingSubject = ""
at.Balance.RatingSubject = nil
if !b.MatchActionTrigger(at) {
t.Errorf("Error matching action trigger: %+v %+v", b, at)
}
}
func TestBalanceMatchActionTriggerSharedGroup(t *testing.T) {
at := &ActionTrigger{BalanceSharedGroups: utils.NewStringMap("test")}
at := &ActionTrigger{Balance: &BalancePointer{SharedGroups: utils.StringMapPointer(utils.NewStringMap("test"))}}
b := &Balance{SharedGroups: utils.NewStringMap("test")}
if !b.MatchActionTrigger(at) {
t.Errorf("Error matching action trigger: %+v %+v", b, at)
@@ -227,7 +227,7 @@ func TestBalanceMatchActionTriggerSharedGroup(t *testing.T) {
t.Errorf("Error matching action trigger: %+v %+v", b, at)
}
b.SharedGroups = utils.NewStringMap("test")
at.BalanceSharedGroups = utils.NewStringMap("")
at.Balance.SharedGroups = nil
if !b.MatchActionTrigger(at) {
t.Errorf("Error matching action trigger: %+v %+v", b, at)
}

View File

@@ -41,12 +41,12 @@ func init() {
func populateDB() {
ats := []*Action{
&Action{ActionType: "*topup", BalanceType: utils.MONETARY, Balance: &Balance{Value: 10}},
&Action{ActionType: "*topup", BalanceType: utils.VOICE, Balance: &Balance{Weight: 20, Value: 10, DestinationIds: utils.NewStringMap("NAT")}},
&Action{ActionType: "*topup", Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Value: utils.Float64Pointer(10)}},
&Action{ActionType: "*topup", Balance: &BalancePointer{Type: utils.StringPointer(utils.VOICE), Weight: utils.Float64Pointer(20), Value: utils.Float64Pointer(10), DestinationIds: utils.StringMapPointer(utils.NewStringMap("NAT"))}},
}
ats1 := []*Action{
&Action{ActionType: "*topup", BalanceType: utils.MONETARY, Balance: &Balance{Value: 10}, Weight: 10},
&Action{ActionType: "*topup", Balance: &BalancePointer{Type: utils.StringPointer(utils.MONETARY), Value: utils.Float64Pointer(10)}, Weight: 10},
&Action{ActionType: "*reset_account", Weight: 20},
}

View File

@@ -823,38 +823,38 @@ func TestLoadActions(t *testing.T) {
&Action{
Id: "MINI0",
ActionType: TOPUP_RESET,
BalanceType: utils.MONETARY,
ExpirationString: UNLIMITED,
ExtraParameters: "",
Weight: 10,
Balance: &Balance{
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Uuid: as1[0].Balance.Uuid,
Directions: utils.NewStringMap(utils.OUT),
Value: 10,
Weight: 10,
DestinationIds: utils.StringMap{},
TimingIDs: utils.StringMap{},
SharedGroups: utils.StringMap{},
Categories: utils.StringMap{},
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
Value: utils.Float64Pointer(10),
Weight: utils.Float64Pointer(10),
DestinationIds: nil,
TimingIDs: nil,
SharedGroups: nil,
Categories: nil,
},
},
&Action{
Id: "MINI1",
ActionType: TOPUP,
BalanceType: utils.VOICE,
ExpirationString: UNLIMITED,
ExtraParameters: "",
Weight: 10,
Balance: &Balance{
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Uuid: as1[1].Balance.Uuid,
Directions: utils.NewStringMap(utils.OUT),
Value: 100,
Weight: 10,
RatingSubject: "test",
DestinationIds: utils.NewStringMap("NAT"),
TimingIDs: utils.StringMap{},
SharedGroups: utils.StringMap{},
Categories: utils.StringMap{},
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
Value: utils.Float64Pointer(100),
Weight: utils.Float64Pointer(10),
RatingSubject: utils.StringPointer("test"),
DestinationIds: utils.StringMapPointer(utils.NewStringMap("NAT")),
TimingIDs: nil,
SharedGroups: nil,
Categories: nil,
},
},
}
@@ -866,18 +866,18 @@ func TestLoadActions(t *testing.T) {
&Action{
Id: "SHARED0",
ActionType: TOPUP,
BalanceType: utils.MONETARY,
ExpirationString: UNLIMITED,
Weight: 10,
Balance: &Balance{
Directions: utils.NewStringMap(utils.OUT),
DestinationIds: utils.StringMap{},
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
DestinationIds: nil,
Uuid: as2[0].Balance.Uuid,
Value: 100,
Weight: 10,
SharedGroups: utils.NewStringMap("SG1"),
TimingIDs: utils.StringMap{},
Categories: utils.StringMap{},
Value: utils.Float64Pointer(100),
Weight: utils.Float64Pointer(10),
SharedGroups: utils.StringMapPointer(utils.NewStringMap("SG1")),
TimingIDs: nil,
Categories: nil,
},
},
}
@@ -891,14 +891,14 @@ func TestLoadActions(t *testing.T) {
ActionType: CDRLOG,
ExtraParameters: `{"Category":"^ddi","MediationRunId":"^did_run"}`,
Weight: 10,
Balance: &Balance{
Balance: &BalancePointer{
Uuid: as3[0].Balance.Uuid,
Directions: utils.StringMap{},
DestinationIds: utils.StringMap{},
TimingIDs: utils.StringMap{},
Categories: utils.StringMap{},
SharedGroups: utils.StringMap{},
Blocker: false,
Directions: nil,
DestinationIds: nil,
TimingIDs: nil,
Categories: nil,
SharedGroups: nil,
Blocker: utils.BoolPointer(false),
},
},
}
@@ -1043,38 +1043,42 @@ func TestLoadActionTriggers(t *testing.T) {
}
atr := csvr.actionsTriggers["STANDARD_TRIGGER"][0]
expected := &ActionTrigger{
ID: "STANDARD_TRIGGER",
UniqueID: "st0",
BalanceType: utils.VOICE,
BalanceDirections: utils.NewStringMap(utils.OUT),
ThresholdType: utils.TRIGGER_MIN_EVENT_COUNTER,
ThresholdValue: 10,
BalanceDestinationIds: utils.NewStringMap("GERMANY_O2"),
BalanceCategories: utils.StringMap{},
BalanceTimingTags: utils.StringMap{},
BalanceSharedGroups: utils.StringMap{},
Weight: 10,
ActionsId: "SOME_1",
Executed: false,
ID: "STANDARD_TRIGGER",
UniqueID: "st0",
ThresholdType: utils.TRIGGER_MIN_EVENT_COUNTER,
ThresholdValue: 10,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
DestinationIds: utils.StringMapPointer(utils.NewStringMap("GERMANY_O2")),
Categories: nil,
TimingIDs: nil,
SharedGroups: nil,
},
Weight: 10,
ActionsId: "SOME_1",
Executed: false,
}
if !reflect.DeepEqual(atr, expected) {
t.Errorf("Error loading action trigger: %+v", atr)
}
atr = csvr.actionsTriggers["STANDARD_TRIGGER"][1]
expected = &ActionTrigger{
ID: "STANDARD_TRIGGER",
UniqueID: "st1",
BalanceType: utils.VOICE,
BalanceDirections: utils.NewStringMap(utils.OUT),
ThresholdType: utils.TRIGGER_MAX_BALANCE,
ThresholdValue: 200,
BalanceDestinationIds: utils.NewStringMap("GERMANY"),
BalanceCategories: utils.StringMap{},
BalanceTimingTags: utils.StringMap{},
BalanceSharedGroups: utils.StringMap{},
Weight: 10,
ActionsId: "SOME_2",
Executed: false,
ID: "STANDARD_TRIGGER",
UniqueID: "st1",
ThresholdType: utils.TRIGGER_MAX_BALANCE,
ThresholdValue: 200,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
DestinationIds: utils.StringMapPointer(utils.NewStringMap("GERMANY")),
Categories: nil,
TimingIDs: nil,
SharedGroups: nil,
},
Weight: 10,
ActionsId: "SOME_2",
Executed: false,
}
if !reflect.DeepEqual(atr, expected) {
t.Errorf("Error loading action trigger: %+v", atr)
@@ -1098,9 +1102,9 @@ func TestLoadAccountActions(t *testing.T) {
Value: 0,
Directions: utils.NewStringMap("*out"),
DestinationIds: utils.NewStringMap("GERMANY_O2"),
SharedGroups: utils.StringMap{},
Categories: utils.StringMap{},
TimingIDs: utils.StringMap{},
SharedGroups: nil,
Categories: nil,
TimingIDs: nil,
},
},
},
@@ -1134,7 +1138,7 @@ func TestLoadDerivedChargers(t *testing.T) {
t.Error("Failed to load derivedChargers: ", csvr.derivedChargers)
}
expCharger1 := &utils.DerivedChargers{
DestinationIDs: utils.StringMap{},
DestinationIDs: nil,
Chargers: []*utils.DerivedCharger{
&utils.DerivedCharger{RunID: "extra1", RunFilters: "^filteredHeader1/filterValue1/", RequestTypeField: "^prepaid", DirectionField: utils.META_DEFAULT,
TenantField: utils.META_DEFAULT, CategoryField: utils.META_DEFAULT, AccountField: "rif", SubjectField: "rif", DestinationField: utils.META_DEFAULT,

View File

@@ -240,26 +240,26 @@ func TestTPActionsAsExportSlice(t *testing.T) {
Identifier: "*topup_reset",
BalanceType: "*monetary",
Directions: utils.OUT,
Units: 5.0,
Units: "5.0",
ExpiryTime: "*never",
DestinationIds: "*any",
RatingSubject: "special1",
Categories: "call",
SharedGroups: "GROUP1",
BalanceWeight: 10.0,
BalanceWeight: "10.0",
ExtraParameters: "",
Weight: 10.0},
&utils.TPAction{
Identifier: "*http_post",
BalanceType: "",
Directions: "",
Units: 0.0,
Units: "0.0",
ExpiryTime: "",
DestinationIds: "",
RatingSubject: "",
Categories: "",
SharedGroups: "",
BalanceWeight: 0.0,
BalanceWeight: "0.0",
ExtraParameters: "http://localhost/&param1=value1",
Weight: 20.0},
},
@@ -561,14 +561,14 @@ func TestTPActionPlanAsExportSlice(t *testing.T) {
BalanceType: "*monetary",
BalanceDirections: "*out",
BalanceDestinationIds: "",
BalanceWeight: 0.0,
BalanceWeight: "0.0",
BalanceExpirationDate: "*never",
BalanceTimingTags: "T1",
BalanceRatingSubject: "special1",
BalanceCategories: "call",
BalanceSharedGroups: "SHARED_1",
BalanceBlocker: false,
BalanceDisabled: false,
BalanceBlocker: "false",
BalanceDisabled: "false",
MinQueuedItems: 0,
ActionsId: "LOG_WARNING",
Weight: 10},
@@ -583,14 +583,14 @@ func TestTPActionPlanAsExportSlice(t *testing.T) {
BalanceType: "*monetary",
BalanceDirections: "*out",
BalanceDestinationIds: "FS_USERS",
BalanceWeight: 0.0,
BalanceWeight: "0.0",
BalanceExpirationDate: "*never",
BalanceTimingTags: "T1",
BalanceRatingSubject: "special1",
BalanceCategories: "call",
BalanceSharedGroups: "SHARED_1",
BalanceBlocker: false,
BalanceDisabled: false,
BalanceBlocker: "false",
BalanceDisabled: "false",
MinQueuedItems: 0,
ActionsId: "LOG_WARNING",
Weight: 10},

View File

@@ -315,13 +315,15 @@ func GetUB() *Account {
Balances: BalanceChain{&Balance{Value: 1}, &Balance{Weight: 20, DestinationIds: utils.NewStringMap("NAT")}, &Balance{Weight: 10, DestinationIds: utils.NewStringMap("RET")}},
}
at := &ActionTrigger{
ID: "some_uuid",
BalanceType: utils.MONETARY,
BalanceDirections: utils.NewStringMap(utils.OUT),
ThresholdValue: 100.0,
BalanceDestinationIds: utils.NewStringMap("NAT"),
Weight: 10.0,
ActionsId: "Commando",
ID: "some_uuid",
ThresholdValue: 100.0,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
DestinationIds: utils.StringMapPointer(utils.NewStringMap("NAT")),
},
Weight: 10.0,
ActionsId: "Commando",
}
var zeroTime time.Time
zeroTime = zeroTime.UTC() // for deep equal to find location

View File

@@ -514,9 +514,9 @@ func (tpr *TpReader) LoadActions() (err error) {
}
}
acts[idx] = &Action{
Id: tag + strconv.Itoa(idx),
ActionType: tpact.Identifier,
BalanceType: tpact.BalanceType,
Id: tag + strconv.Itoa(idx),
ActionType: tpact.Identifier,
//BalanceType: tpact.BalanceType,
Weight: tpact.Weight,
ExtraParameters: tpact.ExtraParameters,
ExpirationString: tpact.ExpiryTime,
@@ -526,6 +526,9 @@ func (tpr *TpReader) LoadActions() (err error) {
if tpact.BalanceId != "" && tpact.BalanceId != utils.ANY {
acts[idx].Balance.Id = utils.StringPointer(tpact.BalanceId)
}
if tpact.BalanceType != "" && tpact.BalanceType != utils.ANY {
acts[idx].Balance.Type = utils.StringPointer(tpact.BalanceType)
}
if tpact.Units != "" && tpact.Units != utils.ANY {
u, err := strconv.ParseFloat(tpact.Units, 64)
@@ -542,6 +545,13 @@ func (tpr *TpReader) LoadActions() (err error) {
}
acts[idx].Balance.Weight = utils.Float64Pointer(u)
}
if tpact.ExpiryTime != "" && tpact.ExpiryTime != utils.ANY {
u, err := utils.ParseTimeDetectLayout(tpact.ExpiryTime, tpr.timezone)
if err != nil {
return err
}
acts[idx].Balance.ExpirationDate = utils.TimePointer(u)
}
if tpact.RatingSubject != "" && tpact.RatingSubject != utils.ANY {
acts[idx].Balance.RatingSubject = utils.StringPointer(tpact.RatingSubject)
}
@@ -666,10 +676,6 @@ func (tpr *TpReader) LoadActionTriggers() (err error) {
for key, atrsLst := range storAts {
atrs := make([]*ActionTrigger, len(atrsLst))
for idx, atr := range atrsLst {
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
@@ -686,29 +692,73 @@ func (tpr *TpReader) LoadActionTriggers() (err error) {
atr.UniqueID = utils.GenUUID()
}
atrs[idx] = &ActionTrigger{
ID: key,
UniqueID: atr.UniqueID,
ThresholdType: atr.ThresholdType,
ThresholdValue: atr.ThresholdValue,
Recurrent: atr.Recurrent,
MinSleep: minSleep,
ExpirationDate: expirationDate,
ActivationDate: activationDate,
BalanceId: atr.BalanceId,
BalanceType: atr.BalanceType,
BalanceDirections: utils.ParseStringMap(atr.BalanceDirections),
BalanceDestinationIds: utils.ParseStringMap(atr.BalanceDestinationIds),
BalanceWeight: atr.BalanceWeight,
BalanceExpirationDate: balanceExpirationDate,
BalanceTimingTags: utils.ParseStringMap(atr.BalanceTimingTags),
BalanceRatingSubject: atr.BalanceRatingSubject,
BalanceCategories: utils.ParseStringMap(atr.BalanceCategories),
BalanceSharedGroups: utils.ParseStringMap(atr.BalanceSharedGroups),
BalanceBlocker: atr.BalanceBlocker,
BalanceDisabled: atr.BalanceDisabled,
Weight: atr.Weight,
ActionsId: atr.ActionsId,
MinQueuedItems: atr.MinQueuedItems,
ID: key,
UniqueID: atr.UniqueID,
ThresholdType: atr.ThresholdType,
ThresholdValue: atr.ThresholdValue,
Recurrent: atr.Recurrent,
MinSleep: minSleep,
ExpirationDate: expirationDate,
ActivationDate: activationDate,
Balance: &BalancePointer{},
Weight: atr.Weight,
ActionsId: atr.ActionsId,
MinQueuedItems: atr.MinQueuedItems,
}
if atr.BalanceId != "" && atr.BalanceId != utils.ANY {
atrs[idx].Balance.Id = utils.StringPointer(atr.BalanceId)
}
if atr.BalanceType != "" && atr.BalanceType != utils.ANY {
atrs[idx].Balance.Type = utils.StringPointer(atr.BalanceType)
}
if atr.BalanceWeight != "" && atr.BalanceWeight != utils.ANY {
u, err := strconv.ParseFloat(atr.BalanceWeight, 64)
if err != nil {
return err
}
atrs[idx].Balance.Weight = utils.Float64Pointer(u)
}
if atr.BalanceExpirationDate != "" && atr.BalanceExpirationDate != utils.ANY {
u, err := utils.ParseTimeDetectLayout(atr.BalanceExpirationDate, tpr.timezone)
if err != nil {
return err
}
atrs[idx].Balance.ExpirationDate = utils.TimePointer(u)
}
if atr.BalanceRatingSubject != "" && atr.BalanceRatingSubject != utils.ANY {
atrs[idx].Balance.RatingSubject = utils.StringPointer(atr.BalanceRatingSubject)
}
if atr.BalanceCategories != "" && atr.BalanceCategories != utils.ANY {
atrs[idx].Balance.Categories = utils.StringMapPointer(utils.ParseStringMap(atr.BalanceCategories))
}
if atr.BalanceDirections != "" && atr.BalanceDirections != utils.ANY {
atrs[idx].Balance.Directions = utils.StringMapPointer(utils.ParseStringMap(atr.BalanceDirections))
}
if atr.BalanceDestinationIds != "" && atr.BalanceDestinationIds != utils.ANY {
atrs[idx].Balance.DestinationIds = utils.StringMapPointer(utils.ParseStringMap(atr.BalanceDestinationIds))
}
if atr.BalanceSharedGroups != "" && atr.BalanceSharedGroups != utils.ANY {
atrs[idx].Balance.SharedGroups = utils.StringMapPointer(utils.ParseStringMap(atr.BalanceSharedGroups))
}
if atr.BalanceTimingTags != "" && atr.BalanceTimingTags != utils.ANY {
atrs[idx].Balance.TimingIDs = utils.StringMapPointer(utils.ParseStringMap(atr.BalanceTimingTags))
}
if atr.BalanceBlocker != "" && atr.BalanceBlocker != utils.ANY {
u, err := strconv.ParseBool(atr.BalanceBlocker)
if err != nil {
return err
}
atrs[idx].Balance.Blocker = utils.BoolPointer(u)
}
if atr.BalanceDisabled != "" && atr.BalanceDisabled != utils.ANY {
u, err := strconv.ParseBool(atr.BalanceDisabled)
if err != nil {
return err
}
atrs[idx].Balance.Disabled = utils.BoolPointer(u)
}
}
tpr.actionsTriggers[key] = atrs
@@ -835,37 +885,80 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error
atrsMap := make(map[string][]*ActionTrigger)
for key, atrsLst := range atrs {
atrs := make([]*ActionTrigger, len(atrsLst))
for idx, apiAtr := range atrsLst {
minSleep, _ := utils.ParseDurationWithSecs(apiAtr.MinSleep)
balanceExpTime, _ := utils.ParseDate(apiAtr.BalanceExpirationDate)
expTime, _ := utils.ParseTimeDetectLayout(apiAtr.ExpirationDate, tpr.timezone)
actTime, _ := utils.ParseTimeDetectLayout(apiAtr.ActivationDate, tpr.timezone)
if apiAtr.UniqueID == "" {
apiAtr.UniqueID = utils.GenUUID()
for idx, atr := range atrsLst {
minSleep, _ := utils.ParseDurationWithSecs(atr.MinSleep)
expTime, _ := utils.ParseTimeDetectLayout(atr.ExpirationDate, tpr.timezone)
actTime, _ := utils.ParseTimeDetectLayout(atr.ActivationDate, tpr.timezone)
if atr.UniqueID == "" {
atr.UniqueID = utils.GenUUID()
}
atrs[idx] = &ActionTrigger{
ID: key,
UniqueID: apiAtr.UniqueID,
ThresholdType: apiAtr.ThresholdType,
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: balanceExpTime,
BalanceTimingTags: utils.ParseStringMap(apiAtr.BalanceTimingTags),
BalanceRatingSubject: apiAtr.BalanceRatingSubject,
BalanceCategories: utils.ParseStringMap(apiAtr.BalanceCategories),
BalanceSharedGroups: utils.ParseStringMap(apiAtr.BalanceSharedGroups),
BalanceBlocker: apiAtr.BalanceBlocker,
BalanceDisabled: apiAtr.BalanceDisabled,
Weight: apiAtr.Weight,
ActionsId: apiAtr.ActionsId,
ID: key,
UniqueID: atr.UniqueID,
ThresholdType: atr.ThresholdType,
ThresholdValue: atr.ThresholdValue,
Recurrent: atr.Recurrent,
MinSleep: minSleep,
ExpirationDate: expTime,
ActivationDate: actTime,
Balance: &BalancePointer{},
Weight: atr.Weight,
ActionsId: atr.ActionsId,
}
if atr.BalanceId != "" && atr.BalanceId != utils.ANY {
atrs[idx].Balance.Id = utils.StringPointer(atr.BalanceId)
}
if atr.BalanceType != "" && atr.BalanceType != utils.ANY {
atrs[idx].Balance.Type = utils.StringPointer(atr.BalanceType)
}
if atr.BalanceWeight != "" && atr.BalanceWeight != utils.ANY {
u, err := strconv.ParseFloat(atr.BalanceWeight, 64)
if err != nil {
return err
}
atrs[idx].Balance.Weight = utils.Float64Pointer(u)
}
if atr.BalanceExpirationDate != "" && atr.BalanceExpirationDate != utils.ANY {
u, err := utils.ParseTimeDetectLayout(atr.BalanceExpirationDate, tpr.timezone)
if err != nil {
return err
}
atrs[idx].Balance.ExpirationDate = utils.TimePointer(u)
}
if atr.BalanceRatingSubject != "" && atr.BalanceRatingSubject != utils.ANY {
atrs[idx].Balance.RatingSubject = utils.StringPointer(atr.BalanceRatingSubject)
}
if atr.BalanceCategories != "" && atr.BalanceCategories != utils.ANY {
atrs[idx].Balance.Categories = utils.StringMapPointer(utils.ParseStringMap(atr.BalanceCategories))
}
if atr.BalanceDirections != "" && atr.BalanceDirections != utils.ANY {
atrs[idx].Balance.Directions = utils.StringMapPointer(utils.ParseStringMap(atr.BalanceDirections))
}
if atr.BalanceDestinationIds != "" && atr.BalanceDestinationIds != utils.ANY {
atrs[idx].Balance.DestinationIds = utils.StringMapPointer(utils.ParseStringMap(atr.BalanceDestinationIds))
}
if atr.BalanceSharedGroups != "" && atr.BalanceSharedGroups != utils.ANY {
atrs[idx].Balance.SharedGroups = utils.StringMapPointer(utils.ParseStringMap(atr.BalanceSharedGroups))
}
if atr.BalanceTimingTags != "" && atr.BalanceTimingTags != utils.ANY {
atrs[idx].Balance.TimingIDs = utils.StringMapPointer(utils.ParseStringMap(atr.BalanceTimingTags))
}
if atr.BalanceBlocker != "" && atr.BalanceBlocker != utils.ANY {
u, err := strconv.ParseBool(atr.BalanceBlocker)
if err != nil {
return err
}
atrs[idx].Balance.Blocker = utils.BoolPointer(u)
}
if atr.BalanceDisabled != "" && atr.BalanceDisabled != utils.ANY {
u, err := strconv.ParseBool(atr.BalanceDisabled)
if err != nil {
return err
}
atrs[idx].Balance.Disabled = utils.BoolPointer(u)
}
}
atrsMap[key] = atrs
@@ -883,7 +976,7 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error
}
// actions
acts := make(map[string][]*Action)
facts := make(map[string][]*Action)
for _, actId := range actionsIds {
tpas, err := tpr.lr.GetTpActions(tpr.tpid, actId)
if err != nil {
@@ -894,7 +987,7 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error
return err
}
for tag, tpacts := range as {
enacts := make([]*Action, len(tpacts))
acts := make([]*Action, len(tpacts))
for idx, tpact := range tpacts {
// check filter field
if len(tpact.Filter) > 0 {
@@ -902,34 +995,95 @@ func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error
return fmt.Errorf("error parsing action %s filter field: %v", tag, err)
}
}
enacts[idx] = &Action{
Id: tag + strconv.Itoa(idx),
ActionType: tpact.Identifier,
BalanceType: tpact.BalanceType,
acts[idx] = &Action{
Id: tag + strconv.Itoa(idx),
ActionType: tpact.Identifier,
//BalanceType: tpact.BalanceType,
Weight: tpact.Weight,
ExtraParameters: tpact.ExtraParameters,
ExpirationString: tpact.ExpiryTime,
Filter: tpact.Filter,
Balance: &Balance{
Id: tpact.BalanceId,
Value: tpact.Units,
Weight: tpact.BalanceWeight,
RatingSubject: tpact.RatingSubject,
Categories: utils.ParseStringMap(tpact.Categories),
Directions: utils.ParseStringMap(tpact.Directions),
DestinationIds: utils.ParseStringMap(tpact.DestinationIds),
SharedGroups: utils.ParseStringMap(tpact.SharedGroups),
TimingIDs: utils.ParseStringMap(tpact.TimingTags),
Blocker: tpact.BalanceBlocker,
Disabled: tpact.BalanceDisabled,
},
Balance: &BalancePointer{},
}
if tpact.BalanceId != "" && tpact.BalanceId != utils.ANY {
acts[idx].Balance.Id = utils.StringPointer(tpact.BalanceId)
}
if tpact.BalanceType != "" && tpact.BalanceType != utils.ANY {
acts[idx].Balance.Type = utils.StringPointer(tpact.BalanceType)
}
if tpact.Units != "" && tpact.Units != utils.ANY {
u, err := strconv.ParseFloat(tpact.Units, 64)
if err != nil {
return err
}
acts[idx].Balance.Value = utils.Float64Pointer(u)
}
if tpact.BalanceWeight != "" && tpact.BalanceWeight != utils.ANY {
u, err := strconv.ParseFloat(tpact.BalanceWeight, 64)
if err != nil {
return err
}
acts[idx].Balance.Weight = utils.Float64Pointer(u)
}
if tpact.RatingSubject != "" && tpact.RatingSubject != utils.ANY {
acts[idx].Balance.RatingSubject = utils.StringPointer(tpact.RatingSubject)
}
if tpact.Categories != "" && tpact.Categories != utils.ANY {
acts[idx].Balance.Categories = utils.StringMapPointer(utils.ParseStringMap(tpact.Categories))
}
if tpact.Directions != "" && tpact.Directions != utils.ANY {
acts[idx].Balance.Directions = utils.StringMapPointer(utils.ParseStringMap(tpact.Directions))
}
if tpact.DestinationIds != "" && tpact.DestinationIds != utils.ANY {
acts[idx].Balance.DestinationIds = utils.StringMapPointer(utils.ParseStringMap(tpact.DestinationIds))
}
if tpact.SharedGroups != "" && tpact.SharedGroups != utils.ANY {
acts[idx].Balance.SharedGroups = utils.StringMapPointer(utils.ParseStringMap(tpact.SharedGroups))
}
if tpact.TimingTags != "" && tpact.TimingTags != utils.ANY {
acts[idx].Balance.TimingIDs = utils.StringMapPointer(utils.ParseStringMap(tpact.TimingTags))
}
if tpact.BalanceBlocker != "" && tpact.BalanceBlocker != utils.ANY {
u, err := strconv.ParseBool(tpact.BalanceBlocker)
if err != nil {
return err
}
acts[idx].Balance.Blocker = utils.BoolPointer(u)
}
if tpact.BalanceDisabled != "" && tpact.BalanceDisabled != utils.ANY {
u, err := strconv.ParseBool(tpact.BalanceDisabled)
if err != nil {
return err
}
acts[idx].Balance.Disabled = utils.BoolPointer(u)
}
// load action timings from tags
if tpact.TimingTags != "" {
timingIds := strings.Split(tpact.TimingTags, utils.INFIELD_SEP)
for _, timingID := range timingIds {
if timing, found := tpr.timings[timingID]; found {
acts[idx].Balance.Timings = append(acts[idx].Balance.Timings, &RITiming{
Years: timing.Years,
Months: timing.Months,
MonthDays: timing.MonthDays,
WeekDays: timing.WeekDays,
StartTime: timing.StartTime,
EndTime: timing.EndTime,
})
} else {
return fmt.Errorf("could not find timing: %v", timingID)
}
}
}
}
acts[tag] = enacts
facts[tag] = acts
}
}
// write actions
for k, as := range acts {
for k, as := range facts {
err = tpr.ratingStorage.SetActions(k, as)
if err != nil {
return err
@@ -1068,35 +1222,80 @@ func (tpr *TpReader) LoadCdrStatsFiltered(tag string, save bool) (err error) {
for _, atrsLst := range atrsM {
atrs := make([]*ActionTrigger, len(atrsLst))
for idx, apiAtr := range atrsLst {
minSleep, _ := utils.ParseDurationWithSecs(apiAtr.MinSleep)
balanceExpTime, _ := utils.ParseDate(apiAtr.BalanceExpirationDate)
expTime, _ := utils.ParseTimeDetectLayout(apiAtr.ExpirationDate, tpr.timezone)
actTime, _ := utils.ParseTimeDetectLayout(apiAtr.ActivationDate, tpr.timezone)
if apiAtr.UniqueID == "" {
apiAtr.UniqueID = utils.GenUUID()
for idx, atr := range atrsLst {
minSleep, _ := utils.ParseDurationWithSecs(atr.MinSleep)
expTime, _ := utils.ParseTimeDetectLayout(atr.ExpirationDate, tpr.timezone)
actTime, _ := utils.ParseTimeDetectLayout(atr.ActivationDate, tpr.timezone)
if atr.UniqueID == "" {
atr.UniqueID = utils.GenUUID()
}
atrs[idx] = &ActionTrigger{
ID: triggerTag,
UniqueID: apiAtr.UniqueID,
ThresholdType: apiAtr.ThresholdType,
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: balanceExpTime,
BalanceRatingSubject: apiAtr.BalanceRatingSubject,
BalanceCategories: utils.ParseStringMap(apiAtr.BalanceCategories),
BalanceSharedGroups: utils.ParseStringMap(apiAtr.BalanceSharedGroups),
BalanceTimingTags: utils.ParseStringMap(apiAtr.BalanceTimingTags),
Weight: apiAtr.Weight,
ActionsId: apiAtr.ActionsId,
ID: triggerTag,
UniqueID: atr.UniqueID,
ThresholdType: atr.ThresholdType,
ThresholdValue: atr.ThresholdValue,
Recurrent: atr.Recurrent,
MinSleep: minSleep,
ExpirationDate: expTime,
ActivationDate: actTime,
Balance: &BalancePointer{},
Weight: atr.Weight,
ActionsId: atr.ActionsId,
}
if atr.BalanceId != "" && atr.BalanceId != utils.ANY {
atrs[idx].Balance.Id = utils.StringPointer(atr.BalanceId)
}
if atr.BalanceType != "" && atr.BalanceType != utils.ANY {
atrs[idx].Balance.Type = utils.StringPointer(atr.BalanceType)
}
if atr.BalanceWeight != "" && atr.BalanceWeight != utils.ANY {
u, err := strconv.ParseFloat(atr.BalanceWeight, 64)
if err != nil {
return err
}
atrs[idx].Balance.Weight = utils.Float64Pointer(u)
}
if atr.BalanceExpirationDate != "" && atr.BalanceExpirationDate != utils.ANY {
u, err := utils.ParseTimeDetectLayout(atr.BalanceExpirationDate, tpr.timezone)
if err != nil {
return err
}
atrs[idx].Balance.ExpirationDate = utils.TimePointer(u)
}
if atr.BalanceRatingSubject != "" && atr.BalanceRatingSubject != utils.ANY {
atrs[idx].Balance.RatingSubject = utils.StringPointer(atr.BalanceRatingSubject)
}
if atr.BalanceCategories != "" && atr.BalanceCategories != utils.ANY {
atrs[idx].Balance.Categories = utils.StringMapPointer(utils.ParseStringMap(atr.BalanceCategories))
}
if atr.BalanceDirections != "" && atr.BalanceDirections != utils.ANY {
atrs[idx].Balance.Directions = utils.StringMapPointer(utils.ParseStringMap(atr.BalanceDirections))
}
if atr.BalanceDestinationIds != "" && atr.BalanceDestinationIds != utils.ANY {
atrs[idx].Balance.DestinationIds = utils.StringMapPointer(utils.ParseStringMap(atr.BalanceDestinationIds))
}
if atr.BalanceSharedGroups != "" && atr.BalanceSharedGroups != utils.ANY {
atrs[idx].Balance.SharedGroups = utils.StringMapPointer(utils.ParseStringMap(atr.BalanceSharedGroups))
}
if atr.BalanceTimingTags != "" && atr.BalanceTimingTags != utils.ANY {
atrs[idx].Balance.TimingIDs = utils.StringMapPointer(utils.ParseStringMap(atr.BalanceTimingTags))
}
if atr.BalanceBlocker != "" && atr.BalanceBlocker != utils.ANY {
u, err := strconv.ParseBool(atr.BalanceBlocker)
if err != nil {
return err
}
atrs[idx].Balance.Blocker = utils.BoolPointer(u)
}
if atr.BalanceDisabled != "" && atr.BalanceDisabled != utils.ANY {
u, err := strconv.ParseBool(atr.BalanceDisabled)
if err != nil {
return err
}
atrs[idx].Balance.Disabled = utils.BoolPointer(u)
}
}
tpr.actionsTriggers[triggerTag] = atrs
@@ -1134,7 +1333,7 @@ func (tpr *TpReader) LoadCdrStatsFiltered(tag string, save bool) (err error) {
return err
}
for tag, tpacts := range as {
enacts := make([]*Action, len(tpacts))
acts := make([]*Action, len(tpacts))
for idx, tpact := range tpacts {
// check filter field
if len(tpact.Filter) > 0 {
@@ -1142,30 +1341,74 @@ func (tpr *TpReader) LoadCdrStatsFiltered(tag string, save bool) (err error) {
return fmt.Errorf("error parsing action %s filter field: %v", tag, err)
}
}
enacts[idx] = &Action{
Id: tag + strconv.Itoa(idx),
ActionType: tpact.Identifier,
BalanceType: tpact.BalanceType,
acts[idx] = &Action{
Id: tag + strconv.Itoa(idx),
ActionType: tpact.Identifier,
//BalanceType: tpact.BalanceType,
Weight: tpact.Weight,
ExtraParameters: tpact.ExtraParameters,
ExpirationString: tpact.ExpiryTime,
Filter: tpact.Filter,
Balance: &Balance{
Id: tpact.BalanceId,
Value: tpact.Units,
Weight: tpact.BalanceWeight,
RatingSubject: tpact.RatingSubject,
Categories: utils.ParseStringMap(tpact.Categories),
Directions: utils.ParseStringMap(tpact.Directions),
DestinationIds: utils.ParseStringMap(tpact.DestinationIds),
SharedGroups: utils.ParseStringMap(tpact.SharedGroups),
TimingIDs: utils.ParseStringMap(tpact.TimingTags),
Blocker: tpact.BalanceBlocker,
Disabled: tpact.BalanceDisabled,
},
Balance: &BalancePointer{},
}
if tpact.BalanceId != "" && tpact.BalanceId != utils.ANY {
acts[idx].Balance.Id = utils.StringPointer(tpact.BalanceId)
}
if tpact.BalanceType != "" && tpact.BalanceType != utils.ANY {
acts[idx].Balance.Type = utils.StringPointer(tpact.BalanceType)
}
if tpact.Units != "" && tpact.Units != utils.ANY {
u, err := strconv.ParseFloat(tpact.Units, 64)
if err != nil {
return err
}
acts[idx].Balance.Value = utils.Float64Pointer(u)
}
if tpact.BalanceWeight != "" && tpact.BalanceWeight != utils.ANY {
u, err := strconv.ParseFloat(tpact.BalanceWeight, 64)
if err != nil {
return err
}
acts[idx].Balance.Weight = utils.Float64Pointer(u)
}
if tpact.RatingSubject != "" && tpact.RatingSubject != utils.ANY {
acts[idx].Balance.RatingSubject = utils.StringPointer(tpact.RatingSubject)
}
if tpact.Categories != "" && tpact.Categories != utils.ANY {
acts[idx].Balance.Categories = utils.StringMapPointer(utils.ParseStringMap(tpact.Categories))
}
if tpact.Directions != "" && tpact.Directions != utils.ANY {
acts[idx].Balance.Directions = utils.StringMapPointer(utils.ParseStringMap(tpact.Directions))
}
if tpact.DestinationIds != "" && tpact.DestinationIds != utils.ANY {
acts[idx].Balance.DestinationIds = utils.StringMapPointer(utils.ParseStringMap(tpact.DestinationIds))
}
if tpact.SharedGroups != "" && tpact.SharedGroups != utils.ANY {
acts[idx].Balance.SharedGroups = utils.StringMapPointer(utils.ParseStringMap(tpact.SharedGroups))
}
if tpact.TimingTags != "" && tpact.TimingTags != utils.ANY {
acts[idx].Balance.TimingIDs = utils.StringMapPointer(utils.ParseStringMap(tpact.TimingTags))
}
if tpact.BalanceBlocker != "" && tpact.BalanceBlocker != utils.ANY {
u, err := strconv.ParseBool(tpact.BalanceBlocker)
if err != nil {
return err
}
acts[idx].Balance.Blocker = utils.BoolPointer(u)
}
if tpact.BalanceDisabled != "" && tpact.BalanceDisabled != utils.ANY {
u, err := strconv.ParseBool(tpact.BalanceDisabled)
if err != nil {
return err
}
acts[idx].Balance.Disabled = utils.BoolPointer(u)
}
}
tpr.actions[tag] = enacts
tpr.actions[tag] = acts
}
}
}

View File

@@ -62,7 +62,9 @@ func (ucs UnitCounters) addUnits(amount float64, kind string, cc *CallCost, b *B
bal.AddValue(amount)
continue
}
if uc.CounterType == utils.COUNTER_BALANCE && b != nil && b.MatchFilter(bal, true) {
bp := &BalancePointer{}
bp.LoadFromBalance(bal)
if uc.CounterType == utils.COUNTER_BALANCE && b != nil && b.MatchFilter(bp, true) {
bal.AddValue(amount)
continue
}
@@ -76,7 +78,7 @@ func (ucs UnitCounters) resetCounters(a *Action) {
if uc == nil { // safeguard
continue
}
if a != nil && a.BalanceType != "" && a.BalanceType != uc.BalanceType {
if a != nil && a.Balance.Type != nil && a.Balance.GetType() != uc.BalanceType {
continue
}
for _, b := range uc.Balances {

View File

@@ -50,46 +50,58 @@ func TestUnitCountersCountAllMonetary(t *testing.T) {
a := &Account{
ActionTriggers: ActionTriggers{
&ActionTrigger{
UniqueID: "TestTR1",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
BalanceType: utils.MONETARY,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR1",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR11",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
BalanceType: utils.MONETARY,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR11",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR2",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
BalanceType: utils.VOICE,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR2",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR3",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.VOICE,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR3",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR4",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.SMS,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR4",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.SMS),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR5",
ThresholdType: utils.TRIGGER_MAX_BALANCE,
BalanceType: utils.SMS,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR5",
ThresholdType: utils.TRIGGER_MAX_BALANCE,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.SMS),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
},
}
@@ -114,46 +126,58 @@ func TestUnitCountersCountAllMonetaryId(t *testing.T) {
a := &Account{
ActionTriggers: ActionTriggers{
&ActionTrigger{
UniqueID: "TestTR1",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.MONETARY,
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceWeight: 10,
UniqueID: "TestTR1",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR11",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.MONETARY,
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceWeight: 20,
UniqueID: "TestTR11",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
Weight: utils.Float64Pointer(20),
},
},
&ActionTrigger{
UniqueID: "TestTR2",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
BalanceType: utils.VOICE,
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceWeight: 10,
UniqueID: "TestTR2",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR3",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.VOICE,
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceWeight: 10,
UniqueID: "TestTR3",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR4",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.SMS,
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceWeight: 10,
UniqueID: "TestTR4",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.SMS),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR5",
ThresholdType: utils.TRIGGER_MAX_BALANCE,
BalanceType: utils.SMS,
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceWeight: 10,
UniqueID: "TestTR5",
ThresholdType: utils.TRIGGER_MAX_BALANCE,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.SMS),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
Weight: utils.Float64Pointer(10),
},
},
},
}
@@ -178,54 +202,68 @@ func TestUnitCountersCountAllVoiceDestinationEvent(t *testing.T) {
a := &Account{
ActionTriggers: ActionTriggers{
&ActionTrigger{
UniqueID: "TestTR1",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.MONETARY,
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceWeight: 10,
UniqueID: "TestTR1",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR11",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.MONETARY,
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceWeight: 20,
UniqueID: "TestTR11",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
Weight: utils.Float64Pointer(20),
},
},
&ActionTrigger{
UniqueID: "TestTR2",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
BalanceType: utils.VOICE,
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceDestinationIds: utils.NewStringMap("NAT"),
BalanceWeight: 10,
UniqueID: "TestTR2",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
DestinationIds: utils.StringMapPointer(utils.NewStringMap("NAT")),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR22",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
BalanceType: utils.VOICE,
BalanceDestinationIds: utils.NewStringMap("RET"),
BalanceWeight: 10,
UniqueID: "TestTR22",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
DestinationIds: utils.StringMapPointer(utils.NewStringMap("RET")),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR3",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.VOICE,
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceWeight: 10,
UniqueID: "TestTR3",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR4",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.SMS,
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceWeight: 10,
UniqueID: "TestTR4",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.SMS),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR5",
ThresholdType: utils.TRIGGER_MAX_BALANCE,
BalanceType: utils.SMS,
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceWeight: 10,
UniqueID: "TestTR5",
ThresholdType: utils.TRIGGER_MAX_BALANCE,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.SMS),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
Weight: utils.Float64Pointer(10),
},
},
},
}
@@ -250,54 +288,68 @@ func TestUnitCountersKeepValuesAfterInit(t *testing.T) {
a := &Account{
ActionTriggers: ActionTriggers{
&ActionTrigger{
UniqueID: "TestTR1",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.MONETARY,
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceWeight: 10,
UniqueID: "TestTR1",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR11",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.MONETARY,
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceWeight: 20,
UniqueID: "TestTR11",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
Weight: utils.Float64Pointer(20),
},
},
&ActionTrigger{
UniqueID: "TestTR2",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
BalanceType: utils.VOICE,
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceDestinationIds: utils.NewStringMap("NAT"),
BalanceWeight: 10,
UniqueID: "TestTR2",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
DestinationIds: utils.StringMapPointer(utils.NewStringMap("NAT")),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR22",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
BalanceType: utils.VOICE,
BalanceDestinationIds: utils.NewStringMap("RET"),
BalanceWeight: 10,
UniqueID: "TestTR22",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
DestinationIds: utils.StringMapPointer(utils.NewStringMap("RET")),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR3",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.VOICE,
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceWeight: 10,
UniqueID: "TestTR3",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR4",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.SMS,
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceWeight: 10,
UniqueID: "TestTR4",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.SMS),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR5",
ThresholdType: utils.TRIGGER_MAX_BALANCE,
BalanceType: utils.SMS,
BalanceDirections: utils.NewStringMap(utils.OUT),
BalanceWeight: 10,
UniqueID: "TestTR5",
ThresholdType: utils.TRIGGER_MAX_BALANCE,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.SMS),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT)),
Weight: utils.Float64Pointer(10),
},
},
},
}
@@ -336,46 +388,58 @@ func TestUnitCountersResetCounterById(t *testing.T) {
a := &Account{
ActionTriggers: ActionTriggers{
&ActionTrigger{
UniqueID: "TestTR1",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
BalanceType: utils.MONETARY,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR1",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR11",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
BalanceType: utils.MONETARY,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR11",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR2",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
BalanceType: utils.VOICE,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR2",
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR3",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.VOICE,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR3",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.VOICE),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR4",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
BalanceType: utils.SMS,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR4",
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.SMS),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
&ActionTrigger{
UniqueID: "TestTR5",
ThresholdType: utils.TRIGGER_MAX_BALANCE,
BalanceType: utils.SMS,
BalanceDirections: utils.NewStringMap(utils.OUT, utils.IN),
BalanceWeight: 10,
UniqueID: "TestTR5",
ThresholdType: utils.TRIGGER_MAX_BALANCE,
Balance: &BalancePointer{
Type: utils.StringPointer(utils.SMS),
Directions: utils.StringMapPointer(utils.NewStringMap(utils.OUT, utils.IN)),
Weight: utils.Float64Pointer(10),
},
},
},
}
@@ -395,9 +459,9 @@ func TestUnitCountersResetCounterById(t *testing.T) {
t.Errorf("Error Initializing adding unit counters: %v", len(a.UnitCounters))
}
a.UnitCounters.resetCounters(&Action{
BalanceType: utils.MONETARY,
Balance: &Balance{
Id: "TestTR11",
Balance: &BalancePointer{
Type: utils.StringPointer(utils.MONETARY),
Id: utils.StringPointer("TestTR11"),
},
})
if len(a.UnitCounters) != 4 ||

View File

@@ -372,6 +372,10 @@ func StringMapPointer(sm StringMap) *StringMap {
return &sm
}
func TimePointer(t time.Time) *time.Time {
return &t
}
func ReflectFuncLocation(handler interface{}) (file string, line int) {
f := runtime.FuncForPC(reflect.ValueOf(handler).Pointer())
entry := f.Entry()