mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
KamailioAgent in beta, kamailio evapi tutorial operational
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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"}
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
|
||||
@@ -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)\"}");
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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("<AccountS> 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("<AccountS> error: %s processing account event %+v with ThresholdS.", err.Error(), thEv))
|
||||
}
|
||||
|
||||
@@ -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("<CDRS> error: %s processing CDR event %+v with thdS.", err.Error(), thEv))
|
||||
}
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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("<ResourceS> error: %s processing event %+v with ThresholdS.", err.Error(), thEv))
|
||||
}
|
||||
|
||||
@@ -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("<StatS> error: %s processing event %+v with ThresholdS.", err.Error(), thEv))
|
||||
withErrors = true
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user