diff --git a/agents/kamagent.go b/agents/kamagent.go index 5d6f8df13..b0a0b9557 100644 --- a/agents/kamagent.go +++ b/agents/kamagent.go @@ -128,6 +128,7 @@ func (ka *KamailioAgent) onCallStart(evData []byte, connID string) { ka.disconnectSession(connID, NewKamSessionDisconnect(kev[KamHashEntry], kev[KamHashID], utils.ErrMandatoryIeMissing.Error())) + return } initSessionArgs := kev.V1InitSessionArgs() initSessionArgs.CGREvent.Event[EvapiConnID] = connID // Attach the connection ID so we can properly disconnect later diff --git a/agents/kamevent.go b/agents/kamevent.go index 66c28ffa2..2f2bceb7c 100644 --- a/agents/kamevent.go +++ b/agents/kamevent.go @@ -99,8 +99,6 @@ func (kev KamEvent) MissingParameter() bool { }, "") case CGR_CALL_END: return utils.IsSliceMember([]string{ - kev[KamHashEntry], - kev[KamHashID], kev[utils.OriginID], kev[utils.AnswerTime], kev[utils.Account], diff --git a/data/tutorials/kamevapi/cgrates/etc/cgrates/cgrates.json b/data/tutorials/kamevapi/cgrates/etc/cgrates/cgrates.json index a6d86e587..4e0a042e6 100644 --- a/data/tutorials/kamevapi/cgrates/etc/cgrates/cgrates.json +++ b/data/tutorials/kamevapi/cgrates/etc/cgrates/cgrates.json @@ -10,24 +10,15 @@ "log_level": 7, }, -"stor_db": { // database used to store offline tariff plans and CDRs - "db_password": "CGRateS.org", // password to use when connecting to stordb +"listen": { + "rpc_json": ":2012", + "rpc_gob": ":2013", + "http": ":2080", }, -"rals": { - "enabled": true, - "cdrstats_conns": [ - {"address": "*internal"} - ], - "pubsubs_conns": [ - {"address": "*internal"} - ], - "users_conns": [ - {"address": "*internal"} - ], - "aliases_conns": [ - {"address": "*internal"} - ], + +"stor_db": { + "db_password": "CGRateS.org", }, @@ -36,85 +27,54 @@ }, -"cdrs": { +"rals": { "enabled": true, - "cdrstats_conns": [ + "thresholds_conns": [ + {"address": "*internal"} + ], + "stats_conns": [ + {"address": "*internal"} + ], + "pubsubs_conns": [ + {"address": "*internal"} + ], + "attributes_conns": [ {"address": "*internal"} ], }, -"cdrstats": { +"cdrs": { "enabled": true, }, -"cdre": { - "*default": { - "cdr_format": "csv", - "field_separator": ",", - "data_usage_multiply_factor": 1, - "sms_usage_multiply_factor": 1, - "generic_usage_multiply_factor": 1, - "cost_multiply_factor": 1, - "cost_rounding_decimals": -1, - "cost_shift_digits": 0, - "mask_destination_id": "MASKED_DESTINATIONS", - "mask_length": 0, - "export_dir": "/tmp/cgr_kamevapi/cgrates/cdre", - "header_fields": [], - "content_fields": [ - {"tag": "CgrId", "type": "*composed", "value": "CGRID"}, - {"tag":"RunId", "type": "*composed", "value": "RunID"}, - {"tag":"Tor", "type": "*composed", "value": "ToR"}, - {"tag":"AccId", "type": "*composed", "value": "OriginID"}, - {"tag":"ReqType", "type": "*composed", "value": "RequestType"}, - {"tag":"Direction", "type": "*composed", "value": "Direction"}, - {"tag":"Tenant", "type": "*composed", "value": "Tenant"}, - {"tag":"Category", "type": "*composed", "value": "Category"}, - {"tag":"Account", "type": "*composed", "value": "Account"}, - {"tag":"Subject", "type": "*composed", "value": "Subject"}, - {"tag":"Destination", "type": "*composed", "value": "Destination"}, - {"tag":"SetupTime", "type": "*datetime", "value": "SetupTime", "layout": "2006-01-02T15:04:05Z07:00"}, - {"tag":"AnswerTime", "type": "*datetime", "value": "AnswerTime", "layout": "2006-01-02T15:04:05Z07:00"}, - {"tag":"Usage", "type": "*composed", "value": "usage"}, - {"tag":"Cost", "type": "*composed", "value": "cost"}, - ], - "trailer_fields": [], - }, - "customer_tpl": { - "cdr_format": "csv", - "field_separator": ";", - "data_usage_multiply_factor": 1, - "sms_usage_multiply_factor": 1, - "generic_usage_multiply_factor": 1, - "cost_multiply_factor": 1, - "cost_rounding_decimals": -1, - "cost_shift_digits": 0, - "mask_destination_id": "MASKED_DESTINATIONS", - "mask_length": 0, - "export_dir": "/tmp/cgr_kamevapi/cgrates/cdre", - "header_fields": [], - "content_fields": [ - {"tag": "CgrId", "type": "*composed", "value": "CGRID"}, - {"tag":"AccId", "type": "*composed", "value": "OriginID"}, - {"tag":"ReqType", "type": "*composed", "value": "RequestType"}, - {"tag":"Tenant", "type": "*composed", "value": "Tenant"}, - {"tag":"Category", "type": "*composed", "value": "Category"}, - {"tag":"Subject", "type": "*composed", "value": "Account"}, - {"tag":"Destination", "type": "*composed", "value": "~Destination:s/^1(\\d+)/+$1/:s/^\\+(\\d+)/00$1/"}, - {"tag":"AnswerTime", "type": "*datetime", "value": "AnswerTime", "layout": "2006-01-02T15:04:05Z07:00"}, - {"tag":"Usage", "type": "*composed", "value": "Usage"}, - {"tag":"Cost", "type": "*composed", "value": "Cost"}, - ], - "trailer_fields": [], - } +"sessions": { + "enabled": true, + "rals_conns": [ + {"address": "127.0.0.1:2012", "transport": "*json"} + ], + "cdrs_conns": [ + {"address": "127.0.0.1:2012", "transport": "*json"} + ], + "resources_conns": [ + {"address": "127.0.0.1:2012", "transport": "*json"} + ], + "suppliers_conns": [ + {"address": "127.0.0.1:2012", "transport": "*json"} + ], + "attributes_conns": [ + {"address": "127.0.0.1:2012", "transport": "*json"} + ], + "debit_interval": "10s", }, -"sm_kamailio": { +"kamailio_agent": { "enabled": true, - "create_cdr": true, + "evapi_conns":[ // instantiate connections to multiple Kamailio servers + {"address": "127.0.0.1:8448", "reconnects": 5} + ], }, @@ -123,14 +83,43 @@ }, -"aliases": { +"attributes": { "enabled": true, }, -"users": { +"resources": { "enabled": true, - "indexes": ["Uuid"], + "thresholds_conns": [ + {"address": "*internal"} + ], +}, + + +"stats": { + "enabled": true, + "thresholds_conns": [ + {"address": "*internal"} + ], +}, + + +"thresholds": { + "enabled": true, +}, + + +"suppliers": { + "enabled": true, + "rals_conns": [ + {"address": "*internal"} + ], + "resources_conns": [ + {"address": "*internal"} + ], + "stats_conns": [ + {"address": "*internal"} + ], }, diff --git a/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio-cgrates.cfg b/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio-cgrates.cfg index 63ef6a2be..c201b182b 100644 --- a/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio-cgrates.cfg +++ b/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio-cgrates.cfg @@ -34,6 +34,15 @@ event_route[tm:local-request] { route(CGR_CALL_END); } +# CGRateS request for session disconnect +route[CGR_SESSION_DISCONNECT] { + json_get_field("$evapi(msg)", "HashEntry", "$var(HashEntry)"); + json_get_field("$evapi(msg)", "HashId", "$var(HashId)"); + json_get_field("$evapi(msg)", "Reason", "$var(Reason)"); + jsonrpc_exec('{"jsonrpc":"2.0","id":1, "method":"dlg.end_dlg","params":[$(var(HashEntry){s.rm,"}),$(var(HashId){s.rm,"})]}'); + #$jsonrpl($var(reply)); +} + # Send AUTH_REQUEST to CGRateS route[CGRATES_AUTH_REQUEST] { @@ -45,117 +54,63 @@ route[CGRATES_AUTH_REQUEST] { evapi_async_relay("{\"event\":\"CGR_AUTH_REQUEST\", \"tr_index\":\"$T(id_index)\", \"tr_label\":\"$T(id_label)\", - \"cgr_reqtype\":\"$dlg_var(cgrReqType)\", - \"cgr_tenant\":\"$dlg_var(cgrTenant)\", - \"cgr_account\":\"$dlg_var(cgrAccount)\", - \"cgr_destination\":\"$dlg_var(cgrDestination)\", - \"cgr_setuptime\":\"$TS\", - \"cgr_computelcr\":\"true\"}"); + \"cgr_subsystems\":\"*attributes;*resources;*accounts;*suppliers\", + \"RequestType\":\"$dlg_var(cgrReqType)\", + \"Tenant\":\"$dlg_var(cgrTenant)\", + \"Account\":\"$dlg_var(cgrAccount)\", + \"Destination\":\"$dlg_var(cgrDestination)\", + \"SetupTime\":\"$TS\"}"); } # Process AUTH_REPLY from CGRateS route[CGR_AUTH_REPLY] { json_get_field("$evapi(msg)", "TransactionIndex", "$var(TransactionIndex)"); + $var(TransactionIndex) = $(var(TransactionIndex){s.rm,"}); + $var(id_index) = $(var(TransactionIndex){s.int}); + json_get_field("$evapi(msg)", "TransactionLabel", "$var(TransactionLabel)"); - json_get_field("$evapi(msg)", "MaxSessionTime", "$var(MaxSessionTime)"); - json_get_field("$evapi(msg)", "Suppliers", "$var(Suppliers)"); - json_get_field("$evapi(msg)", "ResourceAllowed", "$var(CGRResourceAllowed)"); - json_get_field("$evapi(msg)", "Error", "$var(CgrError)"); - $var(id_index) = $(var(TransactionIndex){s.int}); + $var(TransactionLabel) = $(var(TransactionLabel){s.rm,"}); $var(id_label) = $(var(TransactionLabel){s.int}); - $var(CgrMaxSessionTime) = $(var(MaxSessionTime){s.int}); - $var(CgrSuppliers) = $(var(Suppliers){s.rm,"}); - $var(CGRResourceAllowed) = $(var(CGRResourceAllowed){s.rm,"}); - $var(CgrError) = $(var(CgrError){s.rm,"}); + + json_get_field("$evapi(msg)", "Attributes", "$var(cgrAttributes)"); + $var(cgrAttributes) = $(var(cgrAttributes){s.rm,"}); + + json_get_field("$evapi(msg)", "ResourceAllocation", "$var(cgrResourceAllocation)"); + $var($var(cgrResourceAllocation)) = $(var(cgrResourceAllocation){s.rm,"}); + + json_get_field("$evapi(msg)", "MaxUsage", "$var(MaxUsage)"); + $var(cgrMaxUsage) = $(var(MaxUsage){s.int}); + + json_get_field("$evapi(msg)", "Suppliers", "$var(cgrSuppliers)"); + $var($var(cgrSuppliers)) = $(var(cgrSuppliers){s.rm,"}); + + json_get_field("$evapi(msg)", "Error", "$var(cgrError)"); + $var(cgrError) = $(var(cgrError){s.rm,"}); + t_continue("$var(id_index)", "$var(id_label)", "CGRATES_AUTH_REPLY"); # Unpark the transaction } -# Send LCR_REQUEST to CGRateS -route[CGRATES_LCR_REQUEST] { - # Auth INVITEs with CGRateS - if $sht(cgrconn=>cgr) == $null { - sl_send_reply("503","Charging controller unreachable"); - exit; - } - evapi_async_relay("{\"event\":\"CGR_LCR_REQUEST\", - \"tr_index\":\"$T(id_index)\", - \"tr_label\":\"$T(id_label)\", - \"cgr_tenant\":\"$dlg_var(cgrTenant)\", - \"cgr_account\":\"$dlg_var(cgrAccount)\", - \"cgr_destination\":\"$dlg_var(cgrDestination)\", - \"cgr_setuptime\":\"$TS\"}"); -} - -# Process LCR_REPLY from CGRateS -route[CGR_LCR_REPLY] { - json_get_field("$evapi(msg)", "TransactionIndex", "$var(TransactionIndex)"); - json_get_field("$evapi(msg)", "TransactionLabel", "$var(TransactionLabel)"); - json_get_field("$evapi(msg)", "MaxSessionTime", "$var(MaxSessionTime)"); - json_get_field("$evapi(msg)", "Suppliers", "$var(Suppliers)"); - json_get_field("$evapi(msg)", "Error", "$var(Error)"); - $var(id_index) = $(var(TransactionIndex){s.int}); - $var(id_label) = $(var(TransactionLabel){s.int}); - $var(CgrMaxSessionTime) = $(var(MaxSessionTime){s.int}); - $var(CgrSuppliers) = $(var(Suppliers){s.rm,"}); - $var(CgrError) = $(var(Error){s.rm,"}); - t_continue("$var(id_index)", "$var(id_label)", "CGRATES_AUTH_REPLY"); # Unpark the transaction -} - - -# Send ResourceAllocation request to CGRateS -route[CGRATES_RL_REQUEST] { - if $sht(cgrconn=>cgr) == $null { - sl_send_reply("503","Charging controller unreachable"); - exit; - } - evapi_async_relay("{\"event\":\"CGR_RL_REQUEST\", - \"tr_index\":\"$T(id_index)\", - \"tr_label\":\"$T(id_label)\", - \"cgr_tenant\":\"$dlg_var(cgrTenant)\", - \"cgr_account\":\"$dlg_var(cgrAccount)\", - \"cgr_destination\":\"$dlg_var(cgrDestination)\", - \"cgr_setuptime\":\"$TS\"}"); -} - -# Process RL_REPLY from CGRateS -route[CGR_RL_REPLY] { - json_get_field("$evapi(msg)", "ResourceAllocated", "$var(CGRResourceAllocated)"); - json_get_field("$evapi(msg)", "Error", "$var(CgrError)"); - $var(id_index) = $(var(TransactionIndex){s.int}); - $var(id_label) = $(var(TransactionLabel){s.int}); - $var(CGRResourceAllocated) = $(var(CGRResourceAllocated){s.rm,"}); - $var(CgrError) = $(var(CgrError){s.rm,"}); - t_continue("$var(id_index)", "$var(id_label)", "CGRATES_RL_REPLY"); # Unpark the transaction -} - -# CGRateS request for session disconnect -route[CGR_SESSION_DISCONNECT] { - json_get_field("$evapi(msg)", "HashEntry", "$var(HashEntry)"); - json_get_field("$evapi(msg)", "HashId", "$var(HashId)"); - json_get_field("$evapi(msg)", "Reason", "$var(Reason)"); - jsonrpc_exec('{"jsonrpc":"2.0","id":1, "method":"dlg.end_dlg","params":[$(var(HashEntry){s.rm,"}),$(var(HashId){s.rm,"})]}'); - #$jsonrpl($var(reply)); -} - # Inform CGRateS about CALL_START (start prepaid sessions loops) route[CGR_CALL_START] { if $sht(cgrconn=>cgr) == $null { xlog("Charging controller unreachable"); exit; } + $var(cgrOriginID) = $dlg(callid)+";"+$dlg(from_tag); evapi_relay("{\"event\":\"CGR_CALL_START\", - \"callid\":\"$dlg(callid)\", - \"from_tag\":\"$dlg(from_tag)\", \"h_entry\":\"$dlg(h_entry)\", \"h_id\":\"$dlg(h_id)\", - \"cgr_reqtype\":\"$dlg_var(cgrReqType)\", - \"cgr_tenant\":\"$dlg_var(cgrTenant)\", - \"cgr_account\":\"$dlg_var(cgrAccount)\", - \"cgr_destination\":\"$dlg_var(cgrDestination)\", - \"cgr_answertime\":\"$TS\", - \"cgr_supplier\":\"$dlg_var(cgrSupplier)\"}"); + \"cgr_subsystems\":\"*resources;*accounts\", + \"OriginID\":\"$dlg_var(cgrOriginID)\", + \"RequestType\":\"$dlg_var(cgrReqType)\", + \"Tenant\":\"$dlg_var(cgrTenant)\", + \"Account\":\"$dlg_var(cgrAccount)\", + \"Destination\":\"$dlg_var(cgrDestination)\", + \"AnswerTime\":\"$TS\"}"); } + + # Inform CGRateS about CALL_END (stop debit loops, perform accounting if desired in this way) route[CGR_CALL_END] { if $sht(cgrconn=>cgr) == $null { @@ -164,15 +119,12 @@ route[CGR_CALL_END] { } $var(callDur) = $TS - $dlg(start_ts); evapi_relay("{\"event\":\"CGR_CALL_END\", - \"callid\":\"$dlg(callid)\", - \"from_tag\":\"$dlg(from_tag)\", - \"cgr_reqtype\":\"$dlg_var(cgrReqType)\", - \"cgr_tenant\":\"$dlg_var(cgrTenant)\", - \"cgr_account\":\"$dlg_var(cgrAccount)\", - \"cgr_destination\":\"$dlg_var(cgrDestination)\", - \"cgr_answertime\":\"$dlg(start_ts)\", - \"cgr_duration\":\"$var(callDur)\", - \"cgr_supplier\":\"$dlg_var(cgrSupplier)\", - \"cgr_disconnectcause\":\"$T_reply_code\"}"); -} - + \"cgr_subsystems\":\"*resources;*accounts\", + \"OriginID\":\"$dlg_var(cgrOriginID)\", + \"RequestType\":\"$dlg_var(cgrReqType)\", + \"Tenant\":\"$dlg_var(cgrTenant)\", + \"Account\":\"$dlg_var(cgrAccount)\", + \"Destination\":\"$dlg_var(cgrDestination)\", + \"AnswerTime\":\"$dlg(start_ts)\", + \"Usage\":\"$var(callDur)\"}"); +} \ No newline at end of file diff --git a/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio.cfg b/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio.cfg index 4e7549db8..8dee82b80 100644 --- a/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio.cfg +++ b/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio.cfg @@ -1,5 +1,8 @@ #!KAMAILIO +# Sample demo config for Kamailio-CGRateS communication +# tested against Kamailio 5.0 + ####### Defined Values ######### #!define FLT_DIALOG 4 @@ -27,7 +30,7 @@ dns_use_search_list=no ####### Modules Section ######## -mpath="/usr/lib64/kamailio/modules/" +mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules/" loadmodule "kex.so" loadmodule "corex.so" @@ -50,12 +53,13 @@ loadmodule "evapi.so" loadmodule "json.so" loadmodule "dialog.so" loadmodule "xhttp.so" -loadmodule "jsonrpc-s.so" +loadmodule "jsonrpcs.so" # ----------------- setting module-specific parameters --------------- +modparam("evapi", "bind_addr", "10.10.10.205:8448") # ----- tm params ----- modparam("tm", "failure_reply_mode", 3) @@ -180,49 +184,33 @@ request_route { default: $dlg_var(cgrReqType) = "*rated"; } + $dlg_var(cgrOriginID) = $dlg(callid) + ";" + $dlg(from_tag); $dlg_var(cgrTenant) = "cgrates.org"; $dlg_var(cgrAccount) = $fU; $dlg_var(cgrDestination) = $rU; route(CGRATES_AUTH_REQUEST); # Will be answered in CGRATES_AUTH_REPLY - #route(CGRATES_LCR_REQUEST); + #route(RELAY); exit; } # Here will land requests after processing them with CGRateS. Call RELAY or other routes following this route route[CGRATES_AUTH_REPLY] { - if $var(CgrError) != "" { - xlog("CGR_AUTH_ERROR: $var(CgrError)"); + if $var(cgrError) != "" { + xlog("CGR_AUTH_ERROR: $var(cgrError)"); sl_send_reply("503","CGR_ERROR"); exit; } - if $var(CgrMaxSessionTime) != -1 { - if $var(CgrMaxSessionTime) == 0 { // Not enough balance, do not allow the call to go through + if $var(cgrMaxUsage) != -1 { + if $var(cgrMaxUsage) == 0 { // Not enough balance, do not allow the call to go through sl_send_reply("403","Insufficient credit"); exit; - } else if !dlg_set_timeout("$var(CgrMaxSessionTime)") { - sl_send_reply("503","CGR_MAX_SESSION_TIME_ERROR"); + } else if !dlg_set_timeout("$var(cgrMaxUsage)") { + sl_send_reply("503","CGR_MAX_USAGE_ERROR"); exit; } } - if $var(CgrSuppliers) != "" { # Enforce the supplier variable to the first one received from CGRateS, more for testing purposes - $dlg_var(cgrSupplier) = $(var(CgrSuppliers){s.select,0,,}); - } - if $var(CGRResourceAllowed) == "false" { - sl_send_reply("403","Resource not allowed"); - exit; - } - route(RELAY); -} - -route[CGRATES_RL_REPLY] { - if $var(CgrError) != "" { - xlog("CGR_RL_ERROR: $var(CgrError)"); - sl_send_reply("503","CGR_ERROR"); - exit; - } - if $var(CGRResourceAllocated) == "false" { - sl_send_reply("403","Resource not allowed"); - exit; + if $var(cgrSuppliers) != "" { # Enforce the supplier variable to the first one received from CGRateS, here more for demo purposes + $dlg_var(cgrSupplier) = $(var(cgrSuppliers){s.select,0,,}); } route(RELAY); } diff --git a/engine/balances.go b/engine/balances.go index 2d5136f84..bc55da63f 100644 --- a/engine/balances.go +++ b/engine/balances.go @@ -793,7 +793,8 @@ func (bc Balances) SaveDirtyBalances(acc *Account) { thEv.Event[utils.ExpiryTime] = b.ExpirationDate.Format(time.RFC3339) } var hits int - if err := thresholdS.Call(utils.ThresholdSv1ProcessEvent, thEv, &hits); err != nil { + if err := thresholdS.Call(utils.ThresholdSv1ProcessEvent, thEv, &hits); err != nil && + err.Error() != utils.ErrNotFound.Error() { utils.Logger.Warning( fmt.Sprintf(" error: %s processing balance event %+v with ThresholdS.", err.Error(), thEv)) } @@ -839,7 +840,8 @@ func (bc Balances) SaveDirtyBalances(acc *Account) { utils.AllowNegative: acnt.AllowNegative, utils.Disabled: acnt.Disabled}}} var hits int - if err := thresholdS.Call(utils.ThresholdSv1ProcessEvent, thEv, &hits); err != nil { + if err := thresholdS.Call(utils.ThresholdSv1ProcessEvent, thEv, &hits); err != nil && + err.Error() != utils.ErrNotFound.Error() { utils.Logger.Warning( fmt.Sprintf(" error: %s processing account event %+v with ThresholdS.", err.Error(), thEv)) } diff --git a/engine/cdrs.go b/engine/cdrs.go index a6cc81e8c..9170c7db5 100644 --- a/engine/cdrs.go +++ b/engine/cdrs.go @@ -202,7 +202,8 @@ func (self *CdrServer) processCdr(cdr *CDR) (err error) { var hits int thEv := &ArgsProcessEvent{ CGREvent: *cdr.AsCGREvent()} - if err := self.thdS.Call(utils.ThresholdSv1ProcessEvent, thEv, &hits); err != nil { + if err := self.thdS.Call(utils.ThresholdSv1ProcessEvent, thEv, &hits); err != nil && + err.Error() != utils.ErrNotFound.Error() { utils.Logger.Warning( fmt.Sprintf(" error: %s processing CDR event %+v with thdS.", err.Error(), thEv)) } diff --git a/engine/cgrcdr_test.go b/engine/cgrcdr_test.go index 56a4bfcca..5cd368a74 100644 --- a/engine/cgrcdr_test.go +++ b/engine/cgrcdr_test.go @@ -59,8 +59,9 @@ func TestCgrCdrAsCDR(t *testing.T) { // Make sure the replicated CDR matches the expected CDR func TestReplicatedCgrCdrAsCDR(t *testing.T) { - cgrCdr := CgrCdr{utils.CGRID: "164b0422fdc6a5117031b427439482c6a4f90e41", - utils.TOR: utils.VOICE, utils.OriginID: "dsafdsaf", + cgrCdr := CgrCdr{ + utils.CGRID: "164b0422fdc6a5117031b427439482c6a4f90e41", + utils.TOR: utils.VOICE, utils.OriginID: "dsafdsaf", utils.OriginHost: "192.168.1.1", utils.Source: "internal_test", utils.RequestType: utils.META_RATED, @@ -72,7 +73,8 @@ func TestReplicatedCgrCdrAsCDR(t *testing.T) { utils.Usage: "10s", utils.COST: "0.12", utils.RATED: "true", "field_extr1": "val_extr1", "fieldextr2": "valextr2"} - expctRtCdr := &CDR{CGRID: cgrCdr[utils.CGRID], + expctRtCdr := &CDR{ + CGRID: cgrCdr[utils.CGRID], ToR: cgrCdr[utils.TOR], OriginID: cgrCdr[utils.OriginID], OriginHost: cgrCdr[utils.OriginHost], diff --git a/engine/resources.go b/engine/resources.go index fb6de0808..597f8f73c 100755 --- a/engine/resources.go +++ b/engine/resources.go @@ -511,7 +511,8 @@ func (rS *ResourceService) processThresholds(r *Resource) (err error) { utils.ResourceID: r.ID, utils.Usage: r.totalUsage()}}} var hits int - if err = thresholdS.Call(utils.ThresholdSv1ProcessEvent, thEv, &hits); err != nil { + if err = thresholdS.Call(utils.ThresholdSv1ProcessEvent, thEv, &hits); err != nil && + err.Error() != utils.ErrNotFound.Error() { utils.Logger.Warning( fmt.Sprintf(" error: %s processing event %+v with ThresholdS.", err.Error(), thEv)) } diff --git a/engine/stats.go b/engine/stats.go index 6a308277c..8aaa0ebef 100644 --- a/engine/stats.go +++ b/engine/stats.go @@ -250,7 +250,8 @@ func (sS *StatService) processEvent(ev *utils.CGREvent) (err error) { thEv.Event[metricID] = metric.GetValue() } var hits int - if err := thresholdS.Call(utils.ThresholdSv1ProcessEvent, thEv, &hits); err != nil { + if err := thresholdS.Call(utils.ThresholdSv1ProcessEvent, thEv, &hits); err != nil && + err.Error() != utils.ErrNotFound.Error() { utils.Logger.Warning( fmt.Sprintf(" error: %s processing event %+v with ThresholdS.", err.Error(), thEv)) withErrors = true diff --git a/sessionmanager/smgeneric.go b/sessionmanager/smgeneric.go index 4d29b14db..0ab2ba5a4 100644 --- a/sessionmanager/smgeneric.go +++ b/sessionmanager/smgeneric.go @@ -1305,6 +1305,10 @@ type V1AuthorizeReply struct { // BiRPCV1Authorize performs authorization for CGREvent based on specific components func (smg *SMGeneric) BiRPCv1AuthorizeEvent(clnt rpcclient.RpcClientConnection, args *V1AuthorizeArgs, authReply *V1AuthorizeReply) (err error) { + if !args.GetAttributes && !args.AuthorizeResources && + !args.GetMaxUsage && !args.GetSuppliers { + return utils.NewErrMandatoryIeMissing("subsystems") + } if args.GetAttributes { if smg.attrS == nil { return utils.NewErrNotConnected(utils.AttributeS) @@ -1335,9 +1339,9 @@ func (smg *SMGeneric) BiRPCv1AuthorizeEvent(clnt rpcclient.RpcClientConnection, if smg.resS == nil { return utils.NewErrNotConnected(utils.ResourceS) } - originID, err := args.CGREvent.FieldAsString(utils.OriginID) - if err != nil { - return utils.NewErrMandatoryIeMissing(utils.OriginID) + originID, _ := args.CGREvent.FieldAsString(utils.OriginID) + if originID == "" { + originID = utils.UUIDSha1Prefix() } var allocMsg string attrRU := utils.ArgRSv1ResourceUsage{ @@ -1382,6 +1386,10 @@ type V1AuthorizeReplyWithDigest struct { // returning one level fields instead of multiple ones returned by BiRPCv1AuthorizeEvent func (smg *SMGeneric) BiRPCv1AuthorizeEventWithDigest(clnt rpcclient.RpcClientConnection, args *V1AuthorizeArgs, authReply *V1AuthorizeReplyWithDigest) (err error) { + if !args.GetAttributes && !args.AuthorizeResources && + !args.GetMaxUsage && !args.GetSuppliers { + return utils.NewErrMandatoryIeMissing("subsystems") + } var initAuthRply V1AuthorizeReply if err = smg.BiRPCv1AuthorizeEvent(clnt, args, &initAuthRply); err != nil { return @@ -1417,6 +1425,9 @@ type V1InitSessionReply struct { // BiRPCV2InitiateSession initiates a new session, returns the maximum duration the session can last func (smg *SMGeneric) BiRPCv1InitiateSession(clnt rpcclient.RpcClientConnection, args *V1InitSessionArgs, rply *V1InitSessionReply) (err error) { + if !args.GetAttributes && !args.AllocateResources && !args.InitSession { + return utils.NewErrMandatoryIeMissing("subsystems") + } if args.GetAttributes { if smg.attrS == nil { return utils.NewErrNotConnected(utils.AttributeS) @@ -1481,6 +1492,9 @@ type V1UpdateSessionReply struct { // BiRPCV1UpdateSession updates an existing session, returning the duration which the session can still last func (smg *SMGeneric) BiRPCv1UpdateSession(clnt rpcclient.RpcClientConnection, args *V1UpdateSessionArgs, rply *V1UpdateSessionReply) (err error) { + if !args.GetAttributes && !args.UpdateSession { + return utils.NewErrMandatoryIeMissing("subsystems") + } if args.GetAttributes { if smg.attrS == nil { return utils.NewErrNotConnected(utils.AttributeS) @@ -1541,6 +1555,9 @@ type V1TerminateSessionArgs struct { // BiRPCV1TerminateSession will stop debit loops as well as release any used resources func (smg *SMGeneric) BiRPCv1TerminateSession(clnt rpcclient.RpcClientConnection, args *V1TerminateSessionArgs, rply *string) (err error) { + if !args.TerminateSession && !args.ReleaseResources { + return utils.NewErrMandatoryIeMissing("subsystems") + } if args.TerminateSession { if smg.rals == nil { return utils.NewErrNotConnected(utils.RALService)