diff --git a/data/tariffplans/tutorial2/AccountActions.csv b/data/tariffplans/tutorial2/AccountActions.csv index 54ebd6e14..e2d3dfd29 100644 --- a/data/tariffplans/tutorial2/AccountActions.csv +++ b/data/tariffplans/tutorial2/AccountActions.csv @@ -1,2 +1,4 @@ #Tenant,Account,ActionPlanID,ActionTriggersID,AllowNegative,Disabled cgrates.org,1001,STANDARD_PLAN,STANDARD_TRIGGERS,, +cgrates.org,1002,STANDARD_PLAN,STANDARD_TRIGGERS,, +cgrates.org,1003,STANDARD_PLAN,STANDARD_TRIGGERS,, diff --git a/data/tariffplans/tutorial2/ActionTriggers.csv b/data/tariffplans/tutorial2/ActionTriggers.csv index 97824cc7a..1b235191f 100644 --- a/data/tariffplans/tutorial2/ActionTriggers.csv +++ b/data/tariffplans/tutorial2/ActionTriggers.csv @@ -1,3 +1,7 @@ #ID[0],UniqueID[1],ThresholdType[2],ThresholdValue[3],Recurrent[4],MinSleep[5],ExpiryTime[6],ActivationTime[7],BalanceTag[8],BalanceType[9],BalanceCategories[10],BalanceDestinationIDs[11],BalanceRatingSubject[12],BalanceSharedGroup[13],BalanceExpiryTime[14],BalanceTimingIDs[15],BalanceWeight[16],BalanceBlocker[17],BalanceDisabled[18],ActionsID[19],Weight[20] -STANDARD_TRIGGERS,,*min_balance,2,,,,,,*monetary,,,,,,,,,,LOG_WARNING,10 + +# STANDARD_TRIGGERS *min_balance will call the action when the monetary balance will go bellow 2 units +STANDARD_TRIGGERS,,*min_balance,2,,,,,,*monetary,,,,,,,,,,TOPUP_BONUS_10SMS,10 + +# STANDARD_TRIGGERS *max_balance will call action when the monetary balance will go above 100 units STANDARD_TRIGGERS,,*max_balance,100,,,,,,*monetary,,,,,,,,,,DISABLE_ACCOUNT,10 \ No newline at end of file diff --git a/data/tariffplans/tutorial2/Actions.csv b/data/tariffplans/tutorial2/Actions.csv index f62bff10c..a742ac90a 100644 --- a/data/tariffplans/tutorial2/Actions.csv +++ b/data/tariffplans/tutorial2/Actions.csv @@ -1,8 +1,28 @@ #ActionsId[0],Action[1],ExtraParameters[2],Filter[3],BalanceId[4],BalanceType[5],Categories[6],DestinationIds[7],RatingSubject[8],SharedGroup[9],ExpiryTime[10],TimingIds[11],Units[12],BalanceWeight[13],BalanceBlocker[14],BalanceDisabled[15],Weight[16] + +# TOPUP_RST_MONETARY_10 resets the <*default> <*monetary> balance to 10 units TOPUP_RST_MONETARY_10,*topup_reset,,,*default,*monetary,,,,,,,10,10,,,10 + +# TOPUP_RST_5M_VOICE resets the special *voice balance valid to destination with special rates to 10m TOPUP_RST_5M_VOICE,*topup_reset,,,PER_CALL,*voice,,DST_10,RPF_SPECIAL_BLC,,,,10m,10,,,10 + +# TOPUP_RST_10M_VOICE resets *voice balance with 0 costs rounded up to minute to 5m and priority 20 TOPUP_RST_10M_VOICE,*topup_reset,,,FREE_MINS,*voice,,,*zero1m,,,,5m,20,,,10 -TOPUP_RST_100_SMS,*topup_reset,,,FREE_SMSes,*sms,,DST_50,,,,,100,20,,,10 + +# TOPUP_RST_100_SMS resets the *sms balance to 100 units and priority 20 in balance chain +TOPUP_RST_100_SMS,*topup_reset,,,FREE_SMSes,*sms,,,,,,,100,20,,,10 + +# TOPUP_BONUS_10SMS adds 10 units to balance valid on DST_50 destination and priority 30 in balance chain +TOPUP_BONUS_10SMS,*topup,,,BONUS_SMSes,*sms,,DST_50,,,,,10,30,,,10 + +# TOPUP_RST_1024_DATA resets the *data balance to 1024 units with priority 20 in the balance chain TOPUP_RST_1024_DATA,*topup_reset,,,FREE_DATA,*data,,,,,,,1024,20,,,10 + +# LOG_WARNING will log to syslog the account attached to it LOG_WARNING,*log,,,,,,,,,,,,,,,10 -DISABLE_ACCOUNT,*disable_account,,,,,,,,,,,,,,,10 \ No newline at end of file + +# DISABLE_ACCOUNT will set the Disabled Flag on the account called +DISABLE_ACCOUNT,*disable_account,,,,,,,,,,,,,,,10 + +# WARN_HTTP_ASYNC will call url asynchronously with the account provided as JSON body +WARN_HTTP_ASYNC,*call_url_async,http://$path/$to/$warn,,,,,,,,,,,,false,false,10 \ No newline at end of file diff --git a/data/tariffplans/tutorial2/Attributes.csv b/data/tariffplans/tutorial2/Attributes.csv new file mode 100644 index 000000000..66d04458c --- /dev/null +++ b/data/tariffplans/tutorial2/Attributes.csv @@ -0,0 +1,11 @@ +# Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight + +# ATTR_CRG_SUPPLIER1 replaces Category->supplier1 and RequestType->*constant for *sessions and *cdrs events +cgrates.org,ATTR_CRG_SUPPLIER1,*sessions;*cdrs,,,,Category,*constant,supplier1,false,0 +cgrates.org,ATTR_CRG_SUPPLIER1,,,,,RequestType,*constant,*rated,, + +# ATTR_1001_AUTH returns the Password value for the account 1001 in context +cgrates.org,ATTR_1001_AUTH,auth,*string:~*req.Account:1001,,,Password,*constant,CGRateS.org,false,20 + +cgrates.org,ATTR_1002_AUTH,auth,*string:~*req.Account:1002,,,Password,*constant,CGRateS.org,false,20 +cgrates.org,ATTR_1003_AUTH,auth,*string:~*req.Account:1003,,,Password,*constant,CGRateS.org,false,20 \ No newline at end of file diff --git a/data/tariffplans/tutorial2/Chargers.csv b/data/tariffplans/tutorial2/Chargers.csv new file mode 100644 index 000000000..20ebeb42b --- /dev/null +++ b/data/tariffplans/tutorial2/Chargers.csv @@ -0,0 +1,8 @@ +# Tenant,ID,FilterIDs,ActivationInterval,RunID,AttributeIDs,Weight + +# CGR_DEFAULT is the default charger for events +cgrates.org,CGR_DEFAULT,,,*default,*none,0 + +# CGR_SUPPLIER1 creates an additional CDR for calculating supplier costs +# uses ATTR_CRG_SUPPLIER1 to replace Category and RequestType in events +cgrates.org,CRG_SUPPPLIER1,,,SUPPLIER1,ATTR_CRG_SUPPLIER1,0 diff --git a/data/tariffplans/tutorial2/DestinationRates.csv b/data/tariffplans/tutorial2/DestinationRates.csv index 61363bb15..df2733801 100644 --- a/data/tariffplans/tutorial2/DestinationRates.csv +++ b/data/tariffplans/tutorial2/DestinationRates.csv @@ -8,4 +8,5 @@ DR_1002_60C,DST_1002,RT_60C,*up,4,, DR_ANY_10C_CN,*any,RT_10C_CN,*up,4,, DR_ANY_1024_1,*any,RT_1024_1,*up,4,, DR_1002_10C1,DST_1002,RT_10C1,*up,4,, -DR_10_20C1,DST_10,RT_20C1,*up,4,, \ No newline at end of file +DR_10_20C1,DST_10,RT_20C1,*up,4,, +DR_1CNT,*any,RT_1CNT,*up,4,, \ No newline at end of file diff --git a/data/tariffplans/tutorial2/Rates.csv b/data/tariffplans/tutorial2/Rates.csv index 21ad729a4..9390417e1 100644 --- a/data/tariffplans/tutorial2/Rates.csv +++ b/data/tariffplans/tutorial2/Rates.csv @@ -1,9 +1,26 @@ #ID,ConnectFee,Rate,RateUnit,RateIncrement,GroupIntervalStart + +# RT_120C charges 0.20 units as connect fee and 1.2 in 1 minute increment in the first minute and second increments after that RT_120C,0.2,1.2,1m,1m,0 RT_120C,,1.2,1m,1s,1m + +# RT_60C charges 0.1 connect fee and 0.01 units each second RT_60C,0.1,0.01,1s,1s,0 + +# RT_0 charges 0 units rounding each call per minute RT_0,0,0,1m,1m,0 + +# RT_10C_CN charges 0.1 units as connect/call fee RT_10C_CN,0.1,0,0,1s,0 + +# RT_1024_1 will be used to charge 1 unit per every 1024 of usage in increments of 1024 RT_1024_1,0,1,1024,1024,0 + +# RT_10C1 charges 0.1 units of cost every 1 unit of usage RT_10C1,0,0.1,1,1,0 -RT_20C1,0,0.2,1,1,0 \ No newline at end of file + +# RT_20C1 charges 0.2 units of cost every 1 unit of usage +RT_20C1,0,0.2,1,1,0 + +# RT_1CNT charges 0.01 units of cost for each 1s of usage +RT_1CNT,0,0.01,1s,1s,0 diff --git a/data/tariffplans/tutorial2/RatingPlans.csv b/data/tariffplans/tutorial2/RatingPlans.csv index e327735d8..6f2954983 100644 --- a/data/tariffplans/tutorial2/RatingPlans.csv +++ b/data/tariffplans/tutorial2/RatingPlans.csv @@ -10,4 +10,5 @@ RP_1001,DR_1002_60C,*any,10 RP_SPECIAL_BLC,DR_ANY_10C_CN,*any,10 RP_DATA,DR_ANY_1024_1,*any,10 RP_SMS,DR_1002_10C1,*any,10 -RP_SMS,DR_10_20C1,*any,10 \ No newline at end of file +RP_SMS,DR_10_20C1,*any,10 +RP_1CNT,DR_1CNT,*any,0 \ No newline at end of file diff --git a/data/tariffplans/tutorial2/RatingProfiles.csv b/data/tariffplans/tutorial2/RatingProfiles.csv index 61ad4c04a..3166eafd9 100644 --- a/data/tariffplans/tutorial2/RatingProfiles.csv +++ b/data/tariffplans/tutorial2/RatingProfiles.csv @@ -4,3 +4,4 @@ cgrates.org,call,1001,2019-03-01T00:00:00Z,RP_1001,*any cgrates.org,call,RPF_SPECIAL_BLC,2019-03-01T00:00:00Z,RP_SPECIAL_BLC, cgrates.org,data,*any,2019-03-01T00:00:00Z,RP_DATA, cgrates.org,sms,*any,2019-03-01T00:00:00Z,RP_SMS, +cgrates.org,supplier1,*any,2019-03-01T00:00:00Z,RP_1CNT, diff --git a/general_tests/sessions_concur_test.go b/general_tests/sessions_concur_test.go index 96b32c5fc..b6f699f27 100644 --- a/general_tests/sessions_concur_test.go +++ b/general_tests/sessions_concur_test.go @@ -349,7 +349,7 @@ func testRunSession(t *testing.T) { t.Error(err) } else if len(cdrs) != 1 { t.Errorf("unexpected number of CDRs returned: %d", len(cdrs)) - } else if cdrs[0].Usage != "2m30s" { + } else if cdrs[0].Usage != "1m30s" { t.Errorf("unexpected usage of CDR: %+v", cdrs[0]) } } diff --git a/general_tests/tutorial2_it_test.go b/general_tests/tutorial2_it_test.go index f1d8408a8..5268eeaef 100644 --- a/general_tests/tutorial2_it_test.go +++ b/general_tests/tutorial2_it_test.go @@ -94,6 +94,12 @@ func testTutStartEngine(t *testing.T) { } } +func testTutStopEngine(t *testing.T) { + if err := engine.KillEngine(tutDelay); err != nil { + t.Error(err) + } +} + func testTutRpcConn(t *testing.T) { var err error if tutRpc, err = newRPCClient(tutCfg.ListenCfg()); err != nil { @@ -277,8 +283,30 @@ func testTutAccounts(t *testing.T) { acnt.Disabled { t.Errorf("received account: %s", utils.ToIJSON(acnt)) } + // test ActionTriggers - attrs := utils.AttrSetBalance{ + attrBlc := utils.AttrSetBalance{ + Tenant: "cgrates.org", + Account: "1001", + BalanceType: utils.MONETARY, + Value: 1, + Balance: map[string]interface{}{ + utils.ID: utils.MetaDefault, + }, + } + var rplySetBlc string + if err := tutRpc.Call(utils.ApierV1SetBalance, attrBlc, &rplySetBlc); err != nil { + t.Error("Got error on ApierV1.SetBalance: ", err.Error()) + } + if err := tutRpc.Call(utils.ApierV2GetAccount, + &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"}, + &acnt); err != nil { + t.Error(err) + } else if len(acnt.BalanceMap[utils.SMS]) != 2 || + acnt.GetBalanceWithID(utils.SMS, "BONUS_SMSes").Value != 10 { + t.Errorf("account: %s", utils.ToIJSON(acnt)) + } + attrBlc = utils.AttrSetBalance{ Tenant: "cgrates.org", Account: "1001", BalanceType: utils.MONETARY, @@ -287,8 +315,7 @@ func testTutAccounts(t *testing.T) { utils.ID: utils.MetaDefault, }, } - var reply string - if err := tutRpc.Call(utils.ApierV1SetBalance, attrs, &reply); err != nil { + if err := tutRpc.Call(utils.ApierV1SetBalance, attrBlc, &rplySetBlc); err != nil { t.Error("Got error on ApierV1.SetBalance: ", err.Error()) } if err := tutRpc.Call(utils.ApierV2GetAccount, @@ -299,6 +326,7 @@ func testTutAccounts(t *testing.T) { t.Errorf("account: %s", utils.ToIJSON(acnt)) } // enable the account again + var rplySetAcnt string if err := tutRpc.Call(utils.ApierV2SetAccount, v2.AttrSetAccount{ Tenant: "cgrates.org", @@ -306,10 +334,10 @@ func testTutAccounts(t *testing.T) { ExtraOptions: map[string]bool{ utils.Disabled: false, }, - }, &reply); err != nil { + }, &rplySetAcnt); err != nil { t.Error(err) } - acnt = &engine.Account{} + acnt = new(engine.Account) if err := tutRpc.Call(utils.ApierV2GetAccount, &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"}, &acnt); err != nil { @@ -318,9 +346,3 @@ func testTutAccounts(t *testing.T) { t.Errorf("account: %s", utils.ToJSON(acnt)) } } - -func testTutStopEngine(t *testing.T) { - if err := engine.KillEngine(tutDelay); err != nil { - t.Error(err) - } -} diff --git a/sessions/sessions.go b/sessions/sessions.go index f5c9fa7ea..ba65d90b8 100644 --- a/sessions/sessions.go +++ b/sessions/sessions.go @@ -91,7 +91,6 @@ type SessionS struct { pSIMux sync.RWMutex // protects pSessionsIdx pSessionsIdx map[string]map[string]map[string]utils.StringMap // map[fieldName]map[fieldValue][cgrID]utils.StringMap[runID]sID pSessionsRIdx map[string][]*riFieldNameVal // reverse indexes for passive sessions, used on remove - } // ListenAndServe starts the service and binds it to the listen loop