KamailioAgent in beta, kamailio evapi tutorial operational

This commit is contained in:
DanB
2018-01-27 13:42:03 +01:00
parent 05be53bc0a
commit 1ef7f2c3a1
11 changed files with 179 additions and 227 deletions

View File

@@ -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

View File

@@ -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],

View File

@@ -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"}
],
},

View File

@@ -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)\"}");
}

View File

@@ -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);
}

View File

@@ -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))
}

View File

@@ -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))
}

View File

@@ -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],

View File

@@ -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))
}

View File

@@ -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

View File

@@ -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)