From fd14eb6b932b4cba1a05bf17e6f67a6931227784 Mon Sep 17 00:00:00 2001 From: DanB Date: Wed, 20 Jun 2018 14:05:06 +0200 Subject: [PATCH] Adding CGRRequest in AgentRequest struct --- agents/agentreq.go | 28 +++++++++------- agents/agentreq_test.go | 72 +++++++++++++++++++++++++++++++++++------ agents/httpagent.go | 7 ++-- utils/consts.go | 1 + 4 files changed, 84 insertions(+), 24 deletions(-) diff --git a/agents/agentreq.go b/agents/agentreq.go index 09888b25d..f86348c93 100644 --- a/agents/agentreq.go +++ b/agents/agentreq.go @@ -30,11 +30,12 @@ import ( func newAgentRequest(req engine.DataProvider, tntTpl utils.RSRFields, dfltTenant string, filterS *engine.FilterS) (ar *AgentRequest) { ar = &AgentRequest{ - Request: req, - Vars: engine.NewNavigableMap(nil), - CGRReply: engine.NewNavigableMap(nil), - Reply: engine.NewNavigableMap(nil), - filterS: filterS, + Request: req, + Vars: engine.NewNavigableMap(nil), + CGRRequest: engine.NewNavigableMap(nil), + CGRReply: engine.NewNavigableMap(nil), + Reply: engine.NewNavigableMap(nil), + filterS: filterS, } // populate tenant if tntIf, err := ar.ParseField( @@ -50,12 +51,13 @@ func newAgentRequest(req engine.DataProvider, tntTpl utils.RSRFields, // AgentRequest represents data related to one request towards agent // implements engine.DataProvider so we can pass it to filters type AgentRequest struct { - Tenant string - Request engine.DataProvider // request - Vars *engine.NavigableMap // shared data - CGRReply *engine.NavigableMap - Reply *engine.NavigableMap - filterS *engine.FilterS + Tenant string + Request engine.DataProvider // request + Vars *engine.NavigableMap // shared data + CGRRequest *engine.NavigableMap + CGRReply *engine.NavigableMap + Reply *engine.NavigableMap + filterS *engine.FilterS } // String implements engine.DataProvider @@ -72,6 +74,8 @@ func (ar *AgentRequest) FieldAsInterface(fldPath []string) (val interface{}, err return ar.Request.FieldAsInterface(fldPath[1:]) case utils.MetaVars: return ar.Vars.FieldAsInterface(fldPath[1:]) + case utils.MetaCGRRequest: + return ar.CGRRequest.FieldAsInterface(fldPath[1:]) case utils.MetaCGRReply: return ar.CGRReply.FieldAsInterface(fldPath[1:]) case utils.MetaReply: @@ -88,6 +92,8 @@ func (ar *AgentRequest) FieldAsString(fldPath []string) (val string, err error) return ar.Request.FieldAsString(fldPath[1:]) case utils.MetaVars: return ar.Vars.FieldAsString(fldPath[1:]) + case utils.MetaCGRRequest: + return ar.CGRRequest.FieldAsString(fldPath[1:]) case utils.MetaCGRReply: return ar.CGRReply.FieldAsString(fldPath[1:]) case utils.MetaReply: diff --git a/agents/agentreq_test.go b/agents/agentreq_test.go index 5c9ddd5f7..492a380a1 100644 --- a/agents/agentreq_test.go +++ b/agents/agentreq_test.go @@ -35,15 +35,69 @@ func TestAgReqAsNavigableMap(t *testing.T) { filterS := engine.NewFilterS(cfg, nil, dm) agReq := newAgentRequest(nil, nil, "cgrates.org", filterS) - agReq.CGRReply.Set([]string{utils.CGRID}, utils.Sha1("dsafdsaf", + // populate request, emulating the way will be done in HTTPAgent + agReq.CGRRequest.Set([]string{utils.CGRID}, utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), false) - agReq.CGRReply.Set([]string{utils.Account}, "1001", false) - agReq.CGRReply.Set([]string{utils.Destination}, "1002", false) - agReq.CGRReply.Set([]string{utils.AnswerTime}, + agReq.CGRRequest.Set([]string{utils.ToR}, utils.VOICE, false) + agReq.CGRRequest.Set([]string{utils.Account}, "1001", false) + agReq.CGRRequest.Set([]string{utils.Destination}, "1002", false) + agReq.CGRRequest.Set([]string{utils.AnswerTime}, time.Date(2013, 12, 30, 15, 0, 1, 0, time.UTC), false) - agReq.CGRReply.Set([]string{utils.RequestType}, utils.META_PREPAID, false) - agReq.CGRReply.Set([]string{utils.Usage}, time.Duration(2*time.Minute), false) - agReq.CGRReply.Set([]string{utils.Cost}, 1.2, false) - fmt.Printf("CGRReply: %+v\n", agReq.CGRReply.AsMapStringInterface()) - fmt.Printf("agReq: %+v\n", agReq) + agReq.CGRRequest.Set([]string{utils.RequestType}, utils.META_PREPAID, false) + agReq.CGRRequest.Set([]string{utils.Usage}, time.Duration(3*time.Minute), false) + + cgrRply := map[string]interface{}{ + utils.CapAttributes: map[string]interface{}{ + "PaypalAccount": "cgrates@paypal.com", + }, + utils.CapMaxUsage: time.Duration(120 * time.Second), + utils.Error: "", + } + agReq.CGRReply = engine.NewNavigableMap(cgrRply) + + tplFlds := []*config.CfgCdrField{ + &config.CfgCdrField{Tag: "Tenant", + FieldId: utils.Tenant, Type: utils.META_COMPOSED, + Value: utils.ParseRSRFieldsMustCompile("^cgrates.org", utils.INFIELD_SEP)}, + &config.CfgCdrField{Tag: "Account", + FieldId: utils.Account, Type: utils.META_COMPOSED, + Value: utils.ParseRSRFieldsMustCompile("*cgrRequest>Account", utils.INFIELD_SEP)}, + &config.CfgCdrField{Tag: "Destination", + FieldId: utils.Destination, Type: utils.META_COMPOSED, + Value: utils.ParseRSRFieldsMustCompile("*cgrRequest>Destination", utils.INFIELD_SEP)}, + + &config.CfgCdrField{Tag: "RequestedUsageVoice", + FieldId: "RequestedUsage", Type: utils.META_COMPOSED, + Filters: []string{"*string:*cgrRequest>ToR:*voice"}, + Value: utils.ParseRSRFieldsMustCompile( + "*cgrRequest>Usage{*duration_seconds}", utils.INFIELD_SEP)}, + &config.CfgCdrField{Tag: "RequestedUsageData", + FieldId: "RequestedUsage", Type: utils.META_COMPOSED, + Filters: []string{"*string:*cgrRequest>ToR:*data"}, + Value: utils.ParseRSRFieldsMustCompile( + "*cgrRequest>Usage{*duration_nanoseconds}", utils.INFIELD_SEP)}, + &config.CfgCdrField{Tag: "RequestedUsageSMS", + FieldId: "RequestedUsage", Type: utils.META_COMPOSED, + Filters: []string{"*string:*cgrRequest>ToR:*sms"}, + Value: utils.ParseRSRFieldsMustCompile( + "*cgrRequest>Usage{*duration_nanoseconds}", utils.INFIELD_SEP)}, + + &config.CfgCdrField{Tag: "AttrPaypalAccount", + FieldId: "PaypalAccount", Type: utils.META_COMPOSED, + Filters: []string{"*string:*cgrReply>Error:"}, + Value: utils.ParseRSRFieldsMustCompile("*cgrReply>Attributes>PaypalAccount", utils.INFIELD_SEP)}, + &config.CfgCdrField{Tag: "MaxUsage", + FieldId: "MaxUsage", Type: utils.META_COMPOSED, + Filters: []string{"*string:*cgrReply>Error:"}, + Value: utils.ParseRSRFieldsMustCompile("*cgrReply>MaxUsage", utils.INFIELD_SEP)}, + &config.CfgCdrField{Tag: "Error", + FieldId: "Error", Type: utils.META_COMPOSED, + Filters: []string{"*rsr::*cgrReply>Error(!^$)"}, + Value: utils.ParseRSRFieldsMustCompile("*cgrReply>Error", utils.INFIELD_SEP)}, + } + if mpOut, err := agReq.AsNavigableMap(tplFlds); err != nil { + t.Error(err) + } else { + fmt.Printf("mpOut: %+v\n", mpOut.AsMapStringInterface()) + } } diff --git a/agents/httpagent.go b/agents/httpagent.go index f70a64ce8..856c5639b 100644 --- a/agents/httpagent.go +++ b/agents/httpagent.go @@ -109,15 +109,14 @@ func (ha *HTTPAgent) processRequest(reqProcessor *config.HttpAgntProcCfg, reqProcessor.Filters, agReq); err != nil || !pass { return pass, err } - reqEv, err := agReq.AsNavigableMap(reqProcessor.RequestFields) - if err != nil { - return false, err + if agReq.CGRRequest, err = agReq.AsNavigableMap(reqProcessor.RequestFields); err != nil { + return } cgrEv := &utils.CGREvent{ Tenant: agReq.Tenant, ID: utils.UUIDSha1Prefix(), Time: utils.TimePointer(time.Now()), - Event: reqEv.AsMapStringInterface(), + Event: agReq.CGRRequest.AsMapStringInterface(), } var reqType string for _, typ := range []string{ diff --git a/utils/consts.go b/utils/consts.go index 8b7a8db6e..053ba325b 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -520,6 +520,7 @@ const ( MetaSessionS = "*sessions" MetaDefault = "*default" Error = "Error" + MetaCGRRequest = "*cgrRequest" MetaCGRReply = "*cgrReply" CacheS = "CacheS" CGR_ACD = "cgr_acd"