diff --git a/engine/action.go b/engine/action.go index 6510bfb52..1d942d425 100644 --- a/engine/action.go +++ b/engine/action.go @@ -23,7 +23,9 @@ import ( "errors" "fmt" "net/smtp" + "reflect" "sort" + "strconv" "strings" "time" @@ -65,14 +67,17 @@ const ( CALL_URL_ASYNC = "*call_url_async" MAIL_ASYNC = "*mail_async" UNLIMITED = "*unlimited" + CDRLOG = "*cdrlog" ) -type actionTypeFunc func(*Account, *StatsQueueTriggered, *Action) error +type actionTypeFunc func(*Account, *StatsQueueTriggered, *Action, Actions) error func getActionFunc(typ string) (actionTypeFunc, bool) { switch typ { case LOG: return logAction, true + case CDRLOG: + return cdrLogAction, true case RESET_TRIGGERS: return resetTriggersAction, true case SET_RECURRENT: @@ -111,7 +116,7 @@ func getActionFunc(typ string) (actionTypeFunc, bool) { return nil, false } -func logAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err error) { +func logAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) (err error) { if ub != nil { body, _ := json.Marshal(ub) Logger.Info(fmt.Sprintf("Threshold hit, Balance: %s", body)) @@ -123,7 +128,61 @@ func logAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err error) { return } -func resetTriggersAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err error) { +func cdrLogAction(acc *Account, sq *StatsQueueTriggered, a *Action, acs Actions) (err error) { + tor, _ := utils.NewRSRField("^tor_test") + cdrhost, _ := utils.NewRSRField("^127.0.0.1") + defaultTemplate := map[string]*utils.RSRField{ + "TOR": tor, + "CdrHost": cdrhost, + } + template := make(map[string]string) + + // overwrite default template + if a.ExtraParameters != "" { + if err = json.Unmarshal([]byte(a.ExtraParameters), &template); err != nil { + return + } + for field, rsr := range template { + if rsrField, err := utils.NewRSRField(rsr); err == nil { + defaultTemplate[field] = rsrField + } else { + return err + } + } + } + + // set sored cdr values + var cdrs []*StoredCdr + for _, action := range acs { + if action.ActionType == DEBIT || action.ActionType == DEBIT_RESET { + cdr := &StoredCdr{CdrSource: CDRLOG, SetupTime: time.Now(), AnswerTime: time.Now(), AccId: utils.GenUUID()} + cdr.CgrId = utils.Sha1(cdr.AccId, cdr.SetupTime.String()) + elem := reflect.ValueOf(cdr).Elem() + for key, rsr := range defaultTemplate { + field := elem.FieldByName(key) + if field.IsValid() && field.CanSet() { + switch field.Kind() { + case reflect.Float64: + value, err := strconv.ParseFloat(rsr.ParseValue(""), 64) + if err != nil { + continue + } + field.SetFloat(value) + case reflect.String: + field.SetString(rsr.ParseValue("")) + } + } + } + cdrs = append(cdrs, cdr) + } + } + + b, _ := json.Marshal(cdrs) + a.ExpirationString = string(b) // testing purpose only + return +} + +func resetTriggersAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) (err error) { if ub == nil { return errors.New("Nil user balance") } @@ -131,7 +190,7 @@ func resetTriggersAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err e return } -func setRecurrentAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err error) { +func setRecurrentAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) (err error) { if ub == nil { return errors.New("Nil user balance") } @@ -139,7 +198,7 @@ func setRecurrentAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err er return } -func unsetRecurrentAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err error) { +func unsetRecurrentAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) (err error) { if ub == nil { return errors.New("Nil user balance") } @@ -147,7 +206,7 @@ func unsetRecurrentAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err return } -func allowNegativeAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err error) { +func allowNegativeAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) (err error) { if ub == nil { return errors.New("Nil user balance") } @@ -155,7 +214,7 @@ func allowNegativeAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err e return } -func denyNegativeAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err error) { +func denyNegativeAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) (err error) { if ub == nil { return errors.New("Nil user balance") } @@ -163,14 +222,14 @@ func denyNegativeAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err er return } -func resetAccountAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err error) { +func resetAccountAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) (err error) { if ub == nil { return errors.New("Nil user balance") } return genericReset(ub) } -func topupResetAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err error) { +func topupResetAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) (err error) { if ub == nil { return errors.New("Nil user balance") } @@ -181,7 +240,7 @@ func topupResetAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err erro return genericDebit(ub, a, true) } -func topupAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err error) { +func topupAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) (err error) { if ub == nil { return errors.New("Nil user balance") } @@ -189,7 +248,7 @@ func topupAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err error) { return genericDebit(ub, a, false) } -func debitResetAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err error) { +func debitResetAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) (err error) { if ub == nil { return errors.New("Nil user balance") } @@ -199,14 +258,14 @@ func debitResetAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err erro return genericDebit(ub, a, true) } -func debitAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err error) { +func debitAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) (err error) { if ub == nil { return errors.New("Nil user balance") } return genericDebit(ub, a, false) } -func resetCounterAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err error) { +func resetCounterAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) (err error) { if ub == nil { return errors.New("Nil user balance") } @@ -219,7 +278,7 @@ func resetCounterAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err er return } -func resetCountersAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err error) { +func resetCountersAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) (err error) { if ub == nil { return errors.New("Nil user balance") } @@ -245,7 +304,7 @@ func genericDebit(ub *Account, a *Action, reset bool) (err error) { return } -func enableUserAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err error) { +func enableUserAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) (err error) { if ub == nil { return errors.New("Nil user balance") } @@ -253,7 +312,7 @@ func enableUserAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err erro return } -func disableUserAction(ub *Account, sq *StatsQueueTriggered, a *Action) (err error) { +func disableUserAction(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) (err error) { if ub == nil { return errors.New("Nil user balance") } @@ -270,7 +329,7 @@ func genericReset(ub *Account) error { return nil } -func callUrl(ub *Account, sq *StatsQueueTriggered, a *Action) (err error) { +func callUrl(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) (err error) { var o interface{} if ub != nil { o = ub @@ -288,7 +347,7 @@ func callUrl(ub *Account, sq *StatsQueueTriggered, a *Action) (err error) { } // Does not block for posts, no error reports -func callUrlAsync(ub *Account, sq *StatsQueueTriggered, a *Action) error { +func callUrlAsync(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) error { var o interface{} if ub != nil { o = ub @@ -317,7 +376,7 @@ func callUrlAsync(ub *Account, sq *StatsQueueTriggered, a *Action) error { } // Mails the balance hitting the threshold towards predefined list of addresses -func mailAsync(ub *Account, sq *StatsQueueTriggered, a *Action) error { +func mailAsync(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) error { cgrCfg := config.CgrConfig() params := strings.Split(a.ExtraParameters, string(utils.CSV_SEP)) if len(params) == 0 { diff --git a/engine/action_timing.go b/engine/action_timing.go index ea9970798..bc11ef486 100644 --- a/engine/action_timing.go +++ b/engine/action_timing.go @@ -266,7 +266,7 @@ func (at *ActionTiming) Execute() (err error) { return 0, fmt.Errorf("Account %s is disabled", ubId) } //Logger.Info(fmt.Sprintf("Executing %v on %+v", a.ActionType, ub)) - err = actionFunction(ub, nil, a) + err = actionFunction(ub, nil, a, aac) //Logger.Info(fmt.Sprintf("After execute, account: %+v", ub)) accountingStorage.SetAccount(ub) return 0, nil diff --git a/engine/action_trigger.go b/engine/action_trigger.go index 4064c9765..2c3045c7c 100644 --- a/engine/action_trigger.go +++ b/engine/action_trigger.go @@ -82,7 +82,7 @@ func (at *ActionTrigger) Execute(ub *Account, sq *StatsQueueTriggered) (err erro return } //go Logger.Info(fmt.Sprintf("Executing %v, %v: %v", ub, sq, a)) - err = actionFunction(ub, sq, a) + err = actionFunction(ub, sq, a, aac) if err == nil { atLeastOneActionExecuted = true } diff --git a/engine/actions_test.go b/engine/actions_test.go index ae01500f8..7a4374174 100644 --- a/engine/actions_test.go +++ b/engine/actions_test.go @@ -23,6 +23,7 @@ import ( "github.com/cgrates/cgrates/utils" + "encoding/json" "testing" "time" ) @@ -651,7 +652,7 @@ func TestActionResetTriggres(t *testing.T) { UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1}}}}, ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } - resetTriggersAction(ub, nil, nil) + resetTriggersAction(ub, nil, nil, nil) if ub.ActionTriggers[0].Executed == true || ub.ActionTriggers[1].Executed == true { t.Error("Reset triggers action failed!") } @@ -664,7 +665,7 @@ func TestActionResetTriggresExecutesThem(t *testing.T) { UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1}}}}, ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } - resetTriggersAction(ub, nil, nil) + resetTriggersAction(ub, nil, nil, nil) if ub.ActionTriggers[0].Executed == true || ub.BalanceMap[utils.MONETARY][0].Value == 12 { t.Error("Reset triggers action failed!") } @@ -677,7 +678,7 @@ func TestActionResetTriggresActionFilter(t *testing.T) { UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1}}}}, ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } - resetTriggersAction(ub, nil, &Action{BalanceType: utils.SMS}) + resetTriggersAction(ub, nil, &Action{BalanceType: utils.SMS}, nil) if ub.ActionTriggers[0].Executed == false || ub.ActionTriggers[1].Executed == false { t.Error("Reset triggers action failed!") } @@ -690,7 +691,7 @@ func TestActionSetPostpaid(t *testing.T) { UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1}}}}, ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } - allowNegativeAction(ub, nil, nil) + allowNegativeAction(ub, nil, nil, nil) if !ub.AllowNegative { t.Error("Set postpaid action failed!") } @@ -704,7 +705,7 @@ func TestActionSetPrepaid(t *testing.T) { UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1}}}}, ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } - denyNegativeAction(ub, nil, nil) + denyNegativeAction(ub, nil, nil, nil) if ub.AllowNegative { t.Error("Set prepaid action failed!") } @@ -718,7 +719,7 @@ func TestActionResetPrepaid(t *testing.T) { UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1}}}}, ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: utils.SMS, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.SMS, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } - resetAccountAction(ub, nil, nil) + resetAccountAction(ub, nil, nil, nil) if !ub.AllowNegative || ub.BalanceMap[utils.MONETARY].GetTotalValue() != 0 || len(ub.UnitCounters) != 0 || @@ -736,7 +737,7 @@ func TestActionResetPostpaid(t *testing.T) { UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1}}}}, ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: utils.SMS, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.SMS, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } - resetAccountAction(ub, nil, nil) + resetAccountAction(ub, nil, nil, nil) if ub.BalanceMap[utils.MONETARY].GetTotalValue() != 0 || len(ub.UnitCounters) != 0 || ub.BalanceMap[utils.VOICE+OUTBOUND][0].Value != 0 || @@ -753,7 +754,7 @@ func TestActionTopupResetCredit(t *testing.T) { ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: utils.MONETARY, BalanceDirection: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, BalanceDirection: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } a := &Action{BalanceType: utils.MONETARY, Direction: OUTBOUND, Balance: &Balance{Value: 10}} - topupResetAction(ub, nil, a) + topupResetAction(ub, nil, a, nil) if ub.AllowNegative || ub.BalanceMap[utils.MONETARY+OUTBOUND].GetTotalValue() != 10 || len(ub.UnitCounters) != 1 || @@ -774,7 +775,7 @@ func TestActionTopupResetCreditId(t *testing.T) { }, } a := &Action{BalanceType: utils.MONETARY, Direction: OUTBOUND, Balance: &Balance{Id: "TEST_B", Value: 10}} - topupResetAction(ub, nil, a) + topupResetAction(ub, nil, a, nil) if ub.AllowNegative || ub.BalanceMap[utils.MONETARY+OUTBOUND].GetTotalValue() != 110 || len(ub.BalanceMap[utils.MONETARY+OUTBOUND]) != 2 { @@ -793,7 +794,7 @@ func TestActionTopupResetCreditNoId(t *testing.T) { }, } a := &Action{BalanceType: utils.MONETARY, Direction: OUTBOUND, Balance: &Balance{Value: 10}} - topupResetAction(ub, nil, a) + topupResetAction(ub, nil, a, nil) if ub.AllowNegative || ub.BalanceMap[utils.MONETARY+OUTBOUND].GetTotalValue() != 20 || len(ub.BalanceMap[utils.MONETARY+OUTBOUND]) != 2 { @@ -811,7 +812,7 @@ func TestActionTopupResetMinutes(t *testing.T) { ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: utils.MONETARY, BalanceDirection: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, BalanceDirection: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } a := &Action{BalanceType: utils.VOICE, Direction: OUTBOUND, Balance: &Balance{Value: 5, Weight: 20, DestinationId: "NAT"}} - topupResetAction(ub, nil, a) + topupResetAction(ub, nil, a, nil) if ub.AllowNegative || ub.BalanceMap[utils.VOICE+OUTBOUND].GetTotalValue() != 5 || ub.BalanceMap[utils.MONETARY+OUTBOUND].GetTotalValue() != 100 || @@ -830,7 +831,7 @@ func TestActionTopupCredit(t *testing.T) { ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: utils.MONETARY, BalanceDirection: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, BalanceDirection: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } a := &Action{BalanceType: utils.MONETARY, Direction: OUTBOUND, Balance: &Balance{Value: 10}} - topupAction(ub, nil, a) + topupAction(ub, nil, a, nil) if ub.AllowNegative || ub.BalanceMap[utils.MONETARY+OUTBOUND].GetTotalValue() != 110 || len(ub.UnitCounters) != 1 || @@ -848,7 +849,7 @@ func TestActionTopupMinutes(t *testing.T) { ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } a := &Action{BalanceType: utils.VOICE, Direction: OUTBOUND, Balance: &Balance{Value: 5, Weight: 20, DestinationId: "NAT"}} - topupAction(ub, nil, a) + topupAction(ub, nil, a, nil) if ub.AllowNegative || ub.BalanceMap[utils.VOICE+OUTBOUND].GetTotalValue() != 15 || ub.BalanceMap[utils.MONETARY].GetTotalValue() != 100 || @@ -867,7 +868,7 @@ func TestActionDebitCredit(t *testing.T) { ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: utils.MONETARY, BalanceDirection: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, BalanceDirection: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } a := &Action{BalanceType: utils.MONETARY, Direction: OUTBOUND, Balance: &Balance{Value: 10}} - debitAction(ub, nil, a) + debitAction(ub, nil, a, nil) if ub.AllowNegative || ub.BalanceMap[utils.MONETARY+OUTBOUND].GetTotalValue() != 90 || len(ub.UnitCounters) != 1 || @@ -885,7 +886,7 @@ func TestActionDebitMinutes(t *testing.T) { ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}, &ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } a := &Action{BalanceType: utils.VOICE, Direction: OUTBOUND, Balance: &Balance{Value: 5, Weight: 20, DestinationId: "NAT"}} - debitAction(ub, nil, a) + debitAction(ub, nil, a, nil) if ub.AllowNegative || ub.BalanceMap[utils.VOICE+OUTBOUND][0].Value != 5 || ub.BalanceMap[utils.MONETARY].GetTotalValue() != 100 || @@ -908,7 +909,7 @@ func TestActionResetAllCounters(t *testing.T) { UnitCounters: []*UnitsCounter{&UnitsCounter{BalanceType: utils.MONETARY, Balances: BalanceChain{&Balance{Value: 1}}}}, ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: utils.MONETARY, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } - resetCountersAction(ub, nil, nil) + resetCountersAction(ub, nil, nil, nil) if !ub.AllowNegative || ub.BalanceMap[utils.MONETARY].GetTotalValue() != 100 || len(ub.UnitCounters) != 1 || @@ -937,7 +938,7 @@ func TestActionResetCounterMinutes(t *testing.T) { ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: utils.MONETARY, ThresholdType: "*max_counter", ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } a := &Action{BalanceType: utils.VOICE} - resetCounterAction(ub, nil, a) + resetCounterAction(ub, nil, a, nil) if !ub.AllowNegative || ub.BalanceMap[utils.MONETARY].GetTotalValue() != 100 || len(ub.UnitCounters) != 2 || @@ -967,7 +968,7 @@ func TestActionResetCounterCredit(t *testing.T) { ActionTriggers: ActionTriggerPriotityList{&ActionTrigger{BalanceType: utils.MONETARY, BalanceDirection: OUTBOUND, ThresholdValue: 2, ActionsId: "TEST_ACTIONS", Executed: true}}, } a := &Action{BalanceType: utils.MONETARY, Direction: OUTBOUND} - resetCounterAction(ub, nil, a) + resetCounterAction(ub, nil, a, nil) if !ub.AllowNegative || ub.BalanceMap[utils.MONETARY].GetTotalValue() != 100 || len(ub.UnitCounters) != 2 || @@ -1111,6 +1112,50 @@ func TestTopupActionLoaded(t *testing.T) { } } +func TestActionCdrlogEmpty(t *testing.T) { + cdrlog := &Action{ + ActionType: CDRLOG, + } + err := cdrLogAction(nil, nil, cdrlog, Actions{ + &Action{ + ActionType: DEBIT, + }, + }) + if err != nil { + t.Error("Error performing cdrlog action: ", err) + } + cdrs := make([]*StoredCdr, 0) + json.Unmarshal([]byte(cdrlog.ExpirationString), &cdrs) + if len(cdrs) != 1 || cdrs[0].TOR != "tor_test" { + t.Errorf("Wrong cdrlogs: %+v", cdrs[0]) + } +} + +func TestActionCdrlogWithParams(t *testing.T) { + cdrlog := &Action{ + ActionType: CDRLOG, + ExtraParameters: `{"Account":"^dan","Subject": "^rif","Destination":"^1234","Tor":"~action_tag:s/^at(.)$/0$1/"}`, + } + err := cdrLogAction(nil, nil, cdrlog, Actions{ + &Action{ + ActionType: DEBIT, + }, + &Action{ + ActionType: DEBIT_RESET, + }, + }) + if err != nil { + t.Error("Error performing cdrlog action: ", err) + } + cdrs := make([]*StoredCdr, 0) + json.Unmarshal([]byte(cdrlog.ExpirationString), &cdrs) + if len(cdrs) != 2 || + cdrs[0].TOR != "tor_test" || + cdrs[0].Subject != "rif" { + t.Errorf("Wrong cdrlogs: %+v", cdrs[0]) + } +} + /********************************** Benchmarks ********************************/ func BenchmarkUUID(b *testing.B) {