mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-17 14:19:54 +05:00
keep counter value on re-init
This commit is contained in:
@@ -569,9 +569,9 @@ func (ub *Account) refundIncrement(increment *Increment, cd *CallDescriptor, cou
|
||||
}
|
||||
|
||||
// Scans the action trigers and execute the actions for which trigger is met
|
||||
func (ub *Account) ExecuteActionTriggers(a *Action) {
|
||||
ub.ActionTriggers.Sort()
|
||||
for _, at := range ub.ActionTriggers {
|
||||
func (acc *Account) ExecuteActionTriggers(a *Action) {
|
||||
acc.ActionTriggers.Sort()
|
||||
for _, at := range acc.ActionTriggers {
|
||||
// sanity check
|
||||
if !strings.Contains(at.ThresholdType, "counter") && !strings.Contains(at.ThresholdType, "balance") {
|
||||
continue
|
||||
@@ -585,45 +585,45 @@ func (ub *Account) ExecuteActionTriggers(a *Action) {
|
||||
continue
|
||||
}
|
||||
if strings.Contains(at.ThresholdType, "counter") {
|
||||
for _, uc := range ub.UnitCounters {
|
||||
for _, uc := range acc.UnitCounters {
|
||||
if uc.BalanceType == at.BalanceType &&
|
||||
strings.Contains(at.ThresholdType, uc.CounterType[1:]) {
|
||||
for _, mb := range uc.Balances {
|
||||
for _, b := range uc.Balances {
|
||||
if strings.HasPrefix(at.ThresholdType, "*max") {
|
||||
if mb.MatchActionTrigger(at) && mb.GetValue() >= at.ThresholdValue {
|
||||
at.Execute(ub, nil)
|
||||
if b.MatchActionTrigger(at) && b.GetValue() >= at.ThresholdValue {
|
||||
at.Execute(acc, nil)
|
||||
}
|
||||
} else { //MIN
|
||||
if mb.MatchActionTrigger(at) && mb.GetValue() <= at.ThresholdValue {
|
||||
at.Execute(ub, nil)
|
||||
if b.MatchActionTrigger(at) && b.GetValue() <= at.ThresholdValue {
|
||||
at.Execute(acc, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // BALANCE
|
||||
for _, b := range ub.BalanceMap[at.BalanceType] {
|
||||
for _, b := range acc.BalanceMap[at.BalanceType] {
|
||||
if !b.dirty && at.ThresholdType != utils.TRIGGER_BALANCE_EXPIRED { // do not check clean balances
|
||||
continue
|
||||
}
|
||||
switch at.ThresholdType {
|
||||
case utils.TRIGGER_MAX_BALANCE:
|
||||
if b.MatchActionTrigger(at) && b.GetValue() >= at.ThresholdValue {
|
||||
at.Execute(ub, nil)
|
||||
at.Execute(acc, nil)
|
||||
}
|
||||
case utils.TRIGGER_MIN_BALANCE:
|
||||
if b.MatchActionTrigger(at) && b.GetValue() <= at.ThresholdValue {
|
||||
at.Execute(ub, nil)
|
||||
at.Execute(acc, nil)
|
||||
}
|
||||
case utils.TRIGGER_BALANCE_EXPIRED:
|
||||
if b.MatchActionTrigger(at) && b.IsExpired() {
|
||||
at.Execute(ub, nil)
|
||||
at.Execute(acc, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ub.CleanExpiredBalances()
|
||||
acc.CleanExpiredBalances()
|
||||
}
|
||||
|
||||
// Mark all action trigers as ready for execution
|
||||
@@ -656,6 +656,7 @@ func (acc *Account) countUnits(amount float64, kind string, cc *CallCost, b *Bal
|
||||
|
||||
// Create counters for all triggered actions
|
||||
func (acc *Account) InitCounters() {
|
||||
oldUcs := acc.UnitCounters
|
||||
acc.UnitCounters = nil
|
||||
ucTempMap := make(map[string]*UnitCounter)
|
||||
for _, at := range acc.ActionTriggers {
|
||||
@@ -682,6 +683,14 @@ func (acc *Account) InitCounters() {
|
||||
uc.Balances = append(uc.Balances, b)
|
||||
}
|
||||
}
|
||||
// copy old counter values
|
||||
for _, uc := range acc.UnitCounters {
|
||||
for _, oldUc := range oldUcs {
|
||||
if uc.CopyCounterValues(oldUc) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (acc *Account) CleanExpiredBalances() {
|
||||
|
||||
@@ -553,14 +553,14 @@ func removeAccountAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Ac
|
||||
utils.Logger.Err(fmt.Sprintf("Could not remove account Id: %s: %v", accID, err))
|
||||
return err
|
||||
}
|
||||
// clean the account id from all action plans
|
||||
allAPs, err := ratingStorage.GetAllActionPlans()
|
||||
if err != nil && err != utils.ErrNotFound {
|
||||
utils.Logger.Err(fmt.Sprintf("Could not get action plans: %s: %v", accID, err))
|
||||
return err
|
||||
}
|
||||
var dirtyAps []string
|
||||
_, err = Guardian.Guard(func() (interface{}, error) {
|
||||
_, err := Guardian.Guard(func() (interface{}, error) {
|
||||
// clean the account id from all action plans
|
||||
allAPs, err := ratingStorage.GetAllActionPlans()
|
||||
if err != nil && err != utils.ErrNotFound {
|
||||
utils.Logger.Err(fmt.Sprintf("Could not get action plans: %s: %v", accID, err))
|
||||
return 0, err
|
||||
}
|
||||
var dirtyAps []string
|
||||
for key, ap := range allAPs {
|
||||
if _, exists := ap.AccountIDs[accID]; !exists {
|
||||
// save action plan
|
||||
@@ -580,7 +580,6 @@ func removeAccountAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Ac
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO: no scheduler reload?
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,23 @@ type UnitCounter struct {
|
||||
Balances BalanceChain // first balance is the general one (no destination)
|
||||
}
|
||||
|
||||
// Returns true if the counters were of the same type
|
||||
// Copies the value from old balances
|
||||
func (uc *UnitCounter) CopyCounterValues(oldUc *UnitCounter) bool {
|
||||
if uc.BalanceType+uc.CounterType != oldUc.BalanceType+oldUc.CounterType { // type check
|
||||
return false
|
||||
}
|
||||
for _, b := range uc.Balances {
|
||||
for _, oldB := range oldUc.Balances {
|
||||
if b.Equal(oldB) {
|
||||
b.Value = oldB.Value
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
type UnitCounters []*UnitCounter
|
||||
|
||||
func (ucs UnitCounters) addUnits(amount float64, kind string, cc *CallCost, b *Balance) {
|
||||
|
||||
@@ -246,6 +246,92 @@ func TestUnitCountersCountAllVoiceDestinationEvent(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
},
|
||||
&ActionTrigger{
|
||||
UniqueID: "TestTR11",
|
||||
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
|
||||
BalanceType: utils.MONETARY,
|
||||
BalanceDirections: utils.NewStringMap(utils.OUT),
|
||||
BalanceWeight: 20,
|
||||
},
|
||||
&ActionTrigger{
|
||||
UniqueID: "TestTR2",
|
||||
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
|
||||
BalanceType: utils.VOICE,
|
||||
BalanceDirections: utils.NewStringMap(utils.OUT),
|
||||
BalanceDestinationIds: utils.NewStringMap("NAT"),
|
||||
BalanceWeight: 10,
|
||||
},
|
||||
&ActionTrigger{
|
||||
UniqueID: "TestTR22",
|
||||
ThresholdType: utils.TRIGGER_MAX_EVENT_COUNTER,
|
||||
BalanceType: utils.VOICE,
|
||||
BalanceDestinationIds: utils.NewStringMap("RET"),
|
||||
BalanceWeight: 10,
|
||||
},
|
||||
&ActionTrigger{
|
||||
UniqueID: "TestTR3",
|
||||
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
|
||||
BalanceType: utils.VOICE,
|
||||
BalanceDirections: utils.NewStringMap(utils.OUT),
|
||||
BalanceWeight: 10,
|
||||
},
|
||||
&ActionTrigger{
|
||||
UniqueID: "TestTR4",
|
||||
ThresholdType: utils.TRIGGER_MAX_BALANCE_COUNTER,
|
||||
BalanceType: utils.SMS,
|
||||
BalanceDirections: utils.NewStringMap(utils.OUT),
|
||||
BalanceWeight: 10,
|
||||
},
|
||||
&ActionTrigger{
|
||||
UniqueID: "TestTR5",
|
||||
ThresholdType: utils.TRIGGER_MAX_BALANCE,
|
||||
BalanceType: utils.SMS,
|
||||
BalanceDirections: utils.NewStringMap(utils.OUT),
|
||||
BalanceWeight: 10,
|
||||
},
|
||||
},
|
||||
}
|
||||
a.InitCounters()
|
||||
a.UnitCounters.addUnits(10, utils.VOICE, &CallCost{Destination: "0723045326"}, nil)
|
||||
|
||||
if len(a.UnitCounters) != 4 ||
|
||||
len(a.UnitCounters[1].Balances) != 2 ||
|
||||
a.UnitCounters[1].Balances[0].Value != 10 ||
|
||||
a.UnitCounters[1].Balances[1].Value != 10 {
|
||||
for _, uc := range a.UnitCounters {
|
||||
t.Logf("UC: %+v", uc)
|
||||
for _, b := range uc.Balances {
|
||||
t.Logf("B: %+v", b)
|
||||
}
|
||||
}
|
||||
t.Errorf("Error adding unit counters: %v", len(a.UnitCounters))
|
||||
}
|
||||
a.InitCounters()
|
||||
|
||||
if len(a.UnitCounters) != 4 ||
|
||||
len(a.UnitCounters[1].Balances) != 2 ||
|
||||
a.UnitCounters[1].Balances[0].Value != 10 ||
|
||||
a.UnitCounters[1].Balances[1].Value != 10 {
|
||||
for _, uc := range a.UnitCounters {
|
||||
t.Logf("UC: %+v", uc)
|
||||
for _, b := range uc.Balances {
|
||||
t.Logf("B: %+v", b)
|
||||
}
|
||||
}
|
||||
t.Errorf("Error keeping counter values after init: %v", len(a.UnitCounters))
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnitCountersResetCounterById(t *testing.T) {
|
||||
a := &Account{
|
||||
ActionTriggers: ActionTriggers{
|
||||
|
||||
Reference in New Issue
Block a user