From 5f032bfb5f46e8f8b889ed9c1a829d189947d2dd Mon Sep 17 00:00:00 2001 From: DanB Date: Tue, 16 Oct 2018 18:15:13 +0200 Subject: [PATCH] Optimized AsteriskAgent hangupChannel function --- agents/asterisk_event.go | 2 +- agents/asteriskagent.go | 75 ++++++---------- .../cgrates/etc/cgrates/cgrates.json | 86 +------------------ 3 files changed, 29 insertions(+), 134 deletions(-) diff --git a/agents/asterisk_event.go b/agents/asterisk_event.go index 185cf14f8..3c290d6a9 100644 --- a/agents/asterisk_event.go +++ b/agents/asterisk_event.go @@ -243,7 +243,7 @@ func (smaEv *SMAsteriskEvent) AsMapStringInterface() (mp map[string]interface{}) return } -// AsCDR converts KamEvent into CGREvent +// AsCDR converts AsteriskEvent into CGREvent func (smaEv *SMAsteriskEvent) AsCGREvent(timezone string) (cgrEv *utils.CGREvent, err error) { setupTime, err := utils.ParseTimeDetectLayout( smaEv.Timestamp(), timezone) diff --git a/agents/asteriskagent.go b/agents/asteriskagent.go index fa975eb2d..e1b2ae2c3 100644 --- a/agents/asteriskagent.go +++ b/agents/asteriskagent.go @@ -108,10 +108,17 @@ func (sma *AsteriskAgent) ListenAndServe() (err error) { } // hangupChannel will disconnect from CGRateS side with congestion reason -func (sma *AsteriskAgent) hangupChannel(channelID string) (err error) { - _, err = sma.astConn.Call(aringo.HTTP_DELETE, fmt.Sprintf("http://%s/ari/channels/%s", +func (sma *AsteriskAgent) hangupChannel(channelID, warnMsg string) { + if warnMsg != "" { + utils.Logger.Warning(warnMsg) + } + if _, err := sma.astConn.Call(aringo.HTTP_DELETE, fmt.Sprintf("http://%s/ari/channels/%s", sma.cgrCfg.AsteriskAgentCfg().AsteriskConns[sma.astConnIdx].Address, channelID), - url.Values{"reason": {"congestion"}}) + url.Values{"reason": {"congestion"}}); err != nil { + utils.Logger.Warning( + fmt.Sprintf("<%s> failed disconnecting channel <%s>, err: %s", + utils.AsteriskAgent, channelID, err.Error())) + } return } @@ -121,14 +128,12 @@ func (sma *AsteriskAgent) handleStasisStart(ev *SMAsteriskEvent) { fmt.Sprintf("http://%s/ari/applications/%s/subscription?eventSource=channel:%s", sma.cgrCfg.AsteriskAgentCfg().AsteriskConns[sma.astConnIdx].Address, CGRAuthAPP, ev.ChannelID()), nil); err != nil { - utils.Logger.Err(fmt.Sprintf("<%s> Error: %s when subscribingto events for channelID: %s", - utils.AsteriskAgent, err.Error(), ev.ChannelID())) // Since we got error, disconnect channel - if err := sma.hangupChannel(ev.ChannelID()); err != nil { - utils.Logger.Err(fmt.Sprintf("<%s> Error: %s when attempting to disconnect channelID: %s", + sma.hangupChannel(ev.ChannelID(), + fmt.Sprintf("<%s> error: %s subscribing for channelID: %s", utils.AsteriskAgent, err.Error(), ev.ChannelID())) - } return + } //authorize Session authArgs := ev.V1AuthorizeArgs() @@ -139,19 +144,13 @@ func (sma *AsteriskAgent) handleStasisStart(ev *SMAsteriskEvent) { } var authReply sessions.V1AuthorizeReply if err := sma.smg.Call(utils.SessionSv1AuthorizeEvent, authArgs, &authReply); err != nil { - utils.Logger.Err(fmt.Sprintf("<%s> Error: %s when attempting to authorize session for channelID: %s", - utils.AsteriskAgent, err.Error(), ev.ChannelID())) - if err := sma.hangupChannel(ev.ChannelID()); err != nil { - utils.Logger.Err(fmt.Sprintf("<%s> Error: %s when attempting to disconnect channelID: %s", + sma.hangupChannel(ev.ChannelID(), + fmt.Sprintf("<%s> Error: %s when attempting to authorize session for channelID: %s", utils.AsteriskAgent, err.Error(), ev.ChannelID())) - } return } if authReply.MaxUsage != nil && *authReply.MaxUsage == time.Duration(0) { - if err := sma.hangupChannel(ev.ChannelID()); err != nil { - utils.Logger.Err(fmt.Sprintf("<%s> Error: %s when attempting to disconnect channelID: %s", - utils.AsteriskAgent, err.Error(), ev.ChannelID())) - } + sma.hangupChannel(ev.ChannelID(), "") return } else if *authReply.MaxUsage != time.Duration(-1) { // Set absolute timeout for non-postpaid calls @@ -164,10 +163,7 @@ func (sma *AsteriskAgent) handleStasisStart(ev *SMAsteriskEvent) { utils.Logger.Err(fmt.Sprintf("<%s> Error: %s when setting %s for channelID: %s", utils.AsteriskAgent, err.Error(), CGRMaxSessionTime, ev.ChannelID())) // Since we got error, disconnect channel - if err := sma.hangupChannel(ev.ChannelID()); err != nil { - utils.Logger.Err(fmt.Sprintf("<%s> Error: %s when attempting to disconnect channelID: %s", - utils.AsteriskAgent, err.Error(), ev.ChannelID())) - } + sma.hangupChannel(ev.ChannelID(), "") return } } @@ -198,14 +194,9 @@ func (sma *AsteriskAgent) handleChannelStateChange(ev *SMAsteriskEvent) { err := ev.UpdateCGREvent(cgrEv) // Updates the event directly in the cache sma.evCacheMux.Unlock() if err != nil { - utils.Logger.Err( - fmt.Sprintf("<%s> Error: %s when attempting to initiate session for channelID: %s", + sma.hangupChannel(ev.ChannelID(), + fmt.Sprintf("<%s> error: %s when attempting to initiate session for channelID: %s", utils.AsteriskAgent, err.Error(), ev.ChannelID())) - if err := sma.hangupChannel(ev.ChannelID()); err != nil { - utils.Logger.Err( - fmt.Sprintf("<%s> Error: %s when attempting to disconnect channelID: %s", - utils.AsteriskAgent, err.Error(), ev.ChannelID())) - } return } // populate init session args @@ -220,21 +211,12 @@ func (sma *AsteriskAgent) handleChannelStateChange(ev *SMAsteriskEvent) { var initReply sessions.V1InitSessionReply if err := sma.smg.Call(utils.SessionSv1InitiateSession, initSessionArgs, &initReply); err != nil { - utils.Logger.Err( - fmt.Sprintf("<%s> Error: %s when attempting to initiate session for channelID: %s", + sma.hangupChannel(ev.ChannelID(), + fmt.Sprintf("<%s> error: %s when attempting to initiate session for channelID: %s", utils.AsteriskAgent, err.Error(), ev.ChannelID())) - if err := sma.hangupChannel(ev.ChannelID()); err != nil { - utils.Logger.Err( - fmt.Sprintf("<%s> Error: %s when attempting to disconnect channelID: %s", - utils.AsteriskAgent, err.Error(), ev.ChannelID())) - } return } else if initReply.MaxUsage != nil && *initReply.MaxUsage == time.Duration(0) { - if err := sma.hangupChannel(ev.ChannelID()); err != nil { - utils.Logger.Err( - fmt.Sprintf("<%s> Error: %s when attempting to disconnect channelID: %s", - utils.AsteriskAgent, err.Error(), ev.ChannelID())) - } + sma.hangupChannel(ev.ChannelID(), "") return } @@ -252,12 +234,9 @@ func (sma *AsteriskAgent) handleChannelDestroyed(ev *SMAsteriskEvent) { err := ev.UpdateCGREvent(cgrEv) // Updates the event directly in the cache sma.evCacheMux.Unlock() if err != nil { - utils.Logger.Err(fmt.Sprintf("<%s> Error: %s when attempting to initiate session for channelID: %s", - utils.AsteriskAgent, err.Error(), ev.ChannelID())) - if err := sma.hangupChannel(ev.ChannelID()); err != nil { - utils.Logger.Err(fmt.Sprintf("<%s> Error: %s when attempting to disconnect channelID: %s", + utils.Logger.Warning( + fmt.Sprintf("<%s> error: %s when attempting to destroy session for channelID: %s", utils.AsteriskAgent, err.Error(), ev.ChannelID())) - } return } // populate terminate session args @@ -291,11 +270,7 @@ func (sma *AsteriskAgent) ServiceShutdown() error { // Internal method to disconnect session in asterisk func (sma *AsteriskAgent) V1DisconnectSession(args utils.AttrDisconnectSession, reply *string) error { channelID := engine.NewMapEvent(args.EventStart).GetStringIgnoreErrors(utils.OriginID) - if err := sma.hangupChannel(channelID); err != nil { - utils.Logger.Err( - fmt.Sprintf("<%s> Error: %s when attempting to disconnect channelID: %s", - utils.AsteriskAgent, err.Error(), channelID)) - } + sma.hangupChannel(channelID, "") *reply = utils.OK return nil } diff --git a/data/tutorials/asterisk_ari/cgrates/etc/cgrates/cgrates.json b/data/tutorials/asterisk_ari/cgrates/etc/cgrates/cgrates.json index 1d16f47cd..a7c6a4860 100644 --- a/data/tutorials/asterisk_ari/cgrates/etc/cgrates/cgrates.json +++ b/data/tutorials/asterisk_ari/cgrates/etc/cgrates/cgrates.json @@ -33,9 +33,6 @@ "stats_conns": [ {"address": "127.0.0.1:2012", "transport": "*json"} ], - "pubsubs_conns": [ - {"address": "*internal"} - ], "attributes_conns": [ {"address": "127.0.0.1:2012", "transport": "*json"} ], @@ -44,9 +41,6 @@ "cdrs": { "enabled": true, - "sessions_conns": [ - {"address": "127.0.0.1:2012", "transport": "*json"} - ], "stats_conns": [ {"address": "127.0.0.1:2012", "transport": "*json"} ], @@ -81,69 +75,6 @@ }, -"cdre": { - "*default": { - "cdr_format": "csv", // exported CDRs format - "field_separator": ",", - "data_usage_multiply_factor": 1, // multiply data usage before export (eg: convert from KBytes to Bytes) - "sms_usage_multiply_factor": 1, // multiply data usage before export (eg: convert from SMS unit to call duration in some billing systems) - "generic_usage_multiply_factor": 1, // multiply data usage before export (eg: convert from GENERIC unit to call duration in some billing systems) - "cost_multiply_factor": 1, // multiply cost before export, eg: add VAT - "cost_rounding_decimals": -1, // rounding decimals for Cost values. -1 to disable rounding - "cost_shift_digits": 0, // shift digits in the cost on export (eg: convert from EUR to cents) - "mask_destination_id": "MASKED_DESTINATIONS", // destination id containing called addresses to be masked on export - "mask_length": 0, // length of the destination suffix to be masked - "export_dir": "/tmp/cgr_osipsasync/cgrates/cdre", // path where the exported CDRs will be placed - "header_fields": [], // template of the exported header fields - "content_fields": [ // template of the exported 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": [], // template of the exported trailer fields - }, - "customer_tpl": { - "cdr_format": "csv", // exported CDRs format - "field_separator": ";", - "data_usage_multiply_factor": 1, // multiply data usage before export (eg: convert from KBytes to Bytes) - "sms_usage_multiply_factor": 1, // multiply data usage before export (eg: convert from SMS unit to call duration in some billing systems) - "generic_usage_multiply_factor": 1, // multiply data usage before export (eg: convert from GENERIC unit to call duration in some billing systems) - "cost_multiply_factor": 1, // multiply cost before export, eg: add VAT - "cost_rounding_decimals": -1, // rounding decimals for Cost values. -1 to disable rounding - "cost_shift_digits": 0, // shift digits in the cost on export (eg: convert from EUR to cents) - "mask_destination_id": "MASKED_DESTINATIONS", // destination id containing called addresses to be masked on export - "mask_length": 0, // length of the destination suffix to be masked - "export_directory": "/tmp/cgr_osipsasync/cgrates/cdre", // path where the exported CDRs will be placed - "header_fields": [], // template of the exported header fields - "content_fields": [ // template of the exported 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": "*datetime", "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": [], - }, -}, - - "asterisk_agent": { "enabled": true, "sessions_conns": [ @@ -151,19 +82,14 @@ ], "create_cdr": true, "asterisk_conns":[ - {"address": "127.0.0.1:8088", "user": "cgrates", "password": "CGRateS.org", "connect_attempts": 3,"reconnects": 10} + {"address": "192.168.56.103:8088", "user": "cgrates", + "password": "CGRateS.org", "connect_attempts": 3,"reconnects": 10} ], }, -"pubsubs": { - "enabled": true, -}, - - "attributes": { - "enabled": true, - "string_indexed_fields": ["Account"], + "enabled": true, }, @@ -172,8 +98,6 @@ "thresholds_conns": [ {"address": "*internal"} ], - "string_indexed_fields": ["Account"], - "prefix_indexed_fields": ["Destination"], }, @@ -182,13 +106,11 @@ "thresholds_conns": [ {"address": "*internal"} ], - "string_indexed_fields": ["Account"], }, "thresholds": { "enabled": true, - "string_indexed_fields": ["Account"], }, @@ -203,8 +125,6 @@ "stats_conns": [ {"address": "*internal"} ], - "string_indexed_fields": ["Account"], - "prefix_indexed_fields": ["Destination"], },