From 70a07a16363f13310fd7e2748405b765d27c0022 Mon Sep 17 00:00:00 2001 From: DanB Date: Tue, 2 Oct 2018 19:42:09 +0200 Subject: [PATCH] Config InflateTemplates function as standalone, added *appid to request *vars --- agents/agentreq.go | 17 +++------ agents/diamagent.go | 9 +++-- config/config_defaults.go | 2 +- config/config_json_test.go | 2 +- config/daconfig.go | 8 ++--- config/fctemplate.go | 35 ++++++++++--------- data/conf/samples/diamagent/data.json | 8 ++--- data/conf/samples/diamagent/dryrun.json | 25 +++++++++++++ ...{diameter_processors.json => message.json} | 22 ++---------- data/conf/samples/diamagent/simpa.json | 2 +- data/conf/samples/diamagent/voice.json | 6 ++-- utils/consts.go | 1 + 12 files changed, 72 insertions(+), 65 deletions(-) create mode 100644 data/conf/samples/diamagent/dryrun.json rename data/conf/samples/diamagent/{diameter_processors.json => message.json} (68%) diff --git a/agents/agentreq.go b/agents/agentreq.go index 0c6224d07..68581ead8 100644 --- a/agents/agentreq.go +++ b/agents/agentreq.go @@ -91,20 +91,11 @@ func (ar *AgentRequest) FieldAsInterface(fldPath []string) (val interface{}, err // FieldAsString implements engine.DataProvider func (ar *AgentRequest) FieldAsString(fldPath []string) (val string, err error) { - switch fldPath[0] { - default: - return "", fmt.Errorf("unsupported field prefix: <%s>", fldPath[0]) - case utils.MetaReq: - return ar.Request.FieldAsString(fldPath[1:]) - case utils.MetaVars: - return ar.Vars.FieldAsString(fldPath[1:]) - case utils.MetaCgreq: - return ar.CGRRequest.FieldAsString(fldPath[1:]) - case utils.MetaCgrep: - return ar.CGRReply.FieldAsString(fldPath[1:]) - case utils.MetaRep: - return ar.Reply.FieldAsString(fldPath[1:]) + var iface interface{} + if iface, err = ar.FieldAsInterface(fldPath); err != nil { + return } + return utils.IfaceAsString(iface) } // AsNavigableMap implements engine.DataProvider diff --git a/agents/diamagent.go b/agents/diamagent.go index ad5648d39..df875bace 100644 --- a/agents/diamagent.go +++ b/agents/diamagent.go @@ -47,11 +47,15 @@ func NewDiameterAgent(cgrCfg *config.CGRConfig, filterS *engine.FilterS, msgTemplates := da.cgrCfg.DiameterAgentCfg().Templates // Inflate *template field types for _, procsr := range da.cgrCfg.DiameterAgentCfg().RequestProcessors { - if err := procsr.RequestFields.InflateTemplates(msgTemplates); err != nil { + if tpls, err := config.InflateTemplates(procsr.RequestFields, msgTemplates); err != nil { return nil, err + } else if tpls != nil { + procsr.RequestFields = tpls } - if err := procsr.ReplyFields.InflateTemplates(msgTemplates); err != nil { + if tpls, err := config.InflateTemplates(procsr.ReplyFields, msgTemplates); err != nil { return nil, err + } else if tpls != nil { + procsr.ReplyFields = tpls } } return da, nil @@ -110,6 +114,7 @@ func (da *DiameterAgent) handleMessage(c diam.Conn, m *diam.Message) { utils.OriginRealm: da.cgrCfg.DiameterAgentCfg().OriginRealm, utils.ProductName: da.cgrCfg.DiameterAgentCfg().ProductName, utils.MetaApp: dApp.Name, + utils.MetaAppID: dApp.ID, utils.MetaCmd: dCmd.Short + "R", } rply := config.NewNavigableMap(nil) // share it among different processors diff --git a/config/config_defaults.go b/config/config_defaults.go index 71b54847f..7626b0b07 100755 --- a/config/config_defaults.go +++ b/config/config_defaults.go @@ -384,7 +384,7 @@ const CGRATES_CFG_JSON = ` {"tag": "OriginRealm", "field_id": "Origin-Realm", "type": "*composed", "value": "~*vars.OriginRealm", "mandatory": true}, {"tag": "AuthApplicationId", "field_id": "Auth-Application-Id", "type": "*composed", - "value": "~*vars.ProductName", "mandatory": true}, + "value": "~*vars.*appid", "mandatory": true}, {"tag": "CCRequestType", "field_id": "CC-Request-Type", "type": "*composed", "value": "~*req.CC-Request-Type", "mandatory": true}, {"tag": "CCRequestNumber", "field_id": "CC-Request-Number", "type": "*composed", diff --git a/config/config_json_test.go b/config/config_json_test.go index bf566cad6..1f3cddbca 100755 --- a/config/config_json_test.go +++ b/config/config_json_test.go @@ -631,7 +631,7 @@ func TestDiameterAgentJsonCfg(t *testing.T) { {Tag: utils.StringPointer("AuthApplicationId"), Field_id: utils.StringPointer("Auth-Application-Id"), Type: utils.StringPointer(utils.META_COMPOSED), - Value: utils.StringPointer("~*vars.ProductName"), + Value: utils.StringPointer("~*vars.*appid"), Mandatory: utils.BoolPointer(true)}, {Tag: utils.StringPointer("CCRequestType"), Field_id: utils.StringPointer("CC-Request-Type"), diff --git a/config/daconfig.go b/config/daconfig.go index 7eaf46264..011ff7639 100644 --- a/config/daconfig.go +++ b/config/daconfig.go @@ -31,7 +31,7 @@ type DiameterAgentCfg struct { OriginRealm string VendorId int ProductName string - Templates map[string]FCTemplates + Templates map[string][]*FCTemplate RequestProcessors []*DARequestProcessor } @@ -69,7 +69,7 @@ func (da *DiameterAgentCfg) loadFromJsonCfg(jsnCfg *DiameterAgentJsonCfg) (err e } if jsnCfg.Templates != nil { if da.Templates == nil { - da.Templates = make(map[string]FCTemplates) + da.Templates = make(map[string][]*FCTemplate) } for k, jsnTpls := range jsnCfg.Templates { if da.Templates[k], err = FCTemplatesFromFCTemplatesJsonCfg(jsnTpls); err != nil { @@ -107,8 +107,8 @@ type DARequestProcessor struct { Flags utils.StringMap Timezone string // timezone for timestamps where not specified <""|UTC|Local|$IANA_TZ_DB> ContinueOnSuccess bool - RequestFields FCTemplates - ReplyFields FCTemplates + RequestFields []*FCTemplate + ReplyFields []*FCTemplate } func (dap *DARequestProcessor) loadFromJsonCfg(jsnCfg *DARequestProcessorJsnCfg) (err error) { diff --git a/config/fctemplate.go b/config/fctemplate.go index 7f57270db..38d9da4fa 100755 --- a/config/fctemplate.go +++ b/config/fctemplate.go @@ -129,31 +129,34 @@ func FCTemplatesFromFCTemplatesJsonCfg(jsnCfgFlds []*FcTemplateJsonCfg) ([]*FCTe return retFields, nil } -type FCTemplates []*FCTemplate - -// PopulateFromTemplates will replace fields of type "*template" with values out of map -func (tpls FCTemplates) InflateTemplates(msgTemplates map[string]FCTemplates) (err error) { - for i := 0; i < len(tpls); { - if tpls[i].Type == utils.MetaTemplate { - var tplID string - if tplID, err = tpls[i].Value.ParseValue(nil); err != nil { - return +// InflateTemplates will replace the *template fields with template content out msgTpls +func InflateTemplates(fcts []*FCTemplate, msgTpls map[string][]*FCTemplate) ([]*FCTemplate, error) { + var hasTpl bool + for i := 0; i < len(fcts); { + if fcts[i].Type == utils.MetaTemplate { + hasTpl = true + tplID, err := fcts[i].Value.ParseValue(nil) + if err != nil { + return nil, err } - refTpl, has := msgTemplates[tplID] + refTpl, has := msgTpls[tplID] if !has { - return fmt.Errorf("no template with id: <%s>", tplID) + return nil, fmt.Errorf("no template with id: <%s>", tplID) } else if len(refTpl) == 0 { continue } - wrkSlice := make([]*FCTemplate, len(refTpl)+len(tpls[i:])-1) // so we can cover tpls[i+1:] + wrkSlice := make([]*FCTemplate, len(refTpl)+len(fcts[i:])-1) // so we can cover tpls[i+1:] copy(wrkSlice[:len(refTpl)], refTpl) // copy fields out of referenced template - if len(tpls[i:]) > 1 { // copy the rest of the fields after MetaTemplate - copy(wrkSlice[len(refTpl):], tpls[i+1:]) + if len(fcts[i:]) > 1 { // copy the rest of the fields after MetaTemplate + copy(wrkSlice[len(refTpl):], fcts[i+1:]) } - tpls = append(tpls[:i], wrkSlice...) // append the work + fcts = append(fcts[:i], wrkSlice...) // append the work continue // don't increase index so we can recheck } i++ } - return + if !hasTpl { + return nil, nil + } + return fcts, nil } diff --git a/data/conf/samples/diamagent/data.json b/data/conf/samples/diamagent/data.json index 6e7da7f2e..bc9d340cc 100644 --- a/data/conf/samples/diamagent/data.json +++ b/data/conf/samples/diamagent/data.json @@ -6,7 +6,7 @@ { "id": "data_init", - "filters": ["*string:*vars.cmd:*ccr", "*string:*req.CC-Request-Type:1", "*prefix:*req.Service-Context-Id:gprs"], + "filters": ["*string:*vars.*cmd:CCR", "*string:*req.CC-Request-Type:1", "*prefix:*req.Service-Context-Id:gprs"], "flags": ["*initiate", "*accounts"], "request_fields":[ {"tag": "TOR", "field_id": "ToR", "type": "*constant", "value": "*data"}, @@ -32,7 +32,7 @@ { "id": "data_update_grp1", - "filters": ["*string:*vars.cmd:*ccr", "*string:*req.CC-Request-Type:2", + "filters": ["*string:*vars.*cmd:CCR", "*string:*req.CC-Request-Type:2", "*string:*req.Multiple-Services-Credit-Control.Rating-Group:1", "*prefix:*req.Service-Context-Id:gprs"], "flags": ["*update", "*accounts"], "continue_on_success": true, @@ -65,7 +65,7 @@ { "id": "data_update_grp2", - "filters": ["*string:*vars.cmd:*ccr", "*string:*req.CC-Request-Type:2", + "filters": ["*string:*vars.*cmd:CCR", "*string:*req.CC-Request-Type:2", "*string:*req.Multiple-Services-Credit-Control.Rating-Group[1]:2", "*prefix:*req.Service-Context-Id:gprs"], "flags": ["*update", "*accounts"], "request_fields":[ @@ -97,7 +97,7 @@ { "id": "data_terminate", - "filters": ["*string:*vars.cmd:*ccr", "*string:*req.CC-Request-Type:3", + "filters": ["*string:*vars.*cmd:CCR", "*string:*req.CC-Request-Type:3", "*prefix:*req.Service-Context-Id:gprs"], "flags": ["*terminate", "*accounts"], "request_fields":[ diff --git a/data/conf/samples/diamagent/dryrun.json b/data/conf/samples/diamagent/dryrun.json new file mode 100644 index 000000000..28b03dba2 --- /dev/null +++ b/data/conf/samples/diamagent/dryrun.json @@ -0,0 +1,25 @@ +{ + +"diameter_agent": { + "request_processors": [ + + { + "id": "dryrun1", + "filters": ["*string:*vars.*cmd:CCR", "*string:*req.Service-Context-Id:TestDiamITDryRun"], + "flags": ["*dryrun"], + "request_fields":[ + {"tag": "TOR", "field_id": "ToR", "type": "*constant", "value": "*sms"}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.Session-Id", "mandatory": true}, + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", "value": "*prepaid"}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed", "value": "~*req.Event-Timestamp", "mandatory": true}, + ], + "reply_fields":[ + {"tag": "CCATemplate", "type": "*template", "value": "*cca"}, + {"tag": "ResultCode", "field_id": "Result-Code", "type": "*constant", "value": "300"}, + ], + }, + ], +}, + +} \ No newline at end of file diff --git a/data/conf/samples/diamagent/diameter_processors.json b/data/conf/samples/diamagent/message.json similarity index 68% rename from data/conf/samples/diamagent/diameter_processors.json rename to data/conf/samples/diamagent/message.json index 43ec85e64..86bd7e1ce 100644 --- a/data/conf/samples/diamagent/diameter_processors.json +++ b/data/conf/samples/diamagent/message.json @@ -3,26 +3,9 @@ "diameter_agent": { "request_processors": [ - { - "id": "dryrun1", - "filters": ["*string:*vars.cmd:*ccr", "*string:*req.Service-Context-Id:gprs"], - "flags": ["*dryrun"], - "request_fields":[ - {"tag": "TOR", "field_id": "ToR", "type": "*constant", "value": "*sms"}, - {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", - "value": "~*req.Session-Id", "mandatory": true}, - {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", "value": "*prepaid"}, - {"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed", "value": "~*req.Event-Timestamp", "mandatory": true}, - ], - "reply_fields":[ - {"tag": "CCATemplate", "type": "*template", "value": "*cca"}, - {"tag": "ResultCode", "field_id": "Result-Code", "type": "*constant", "value": "300"}, - ], - }, - { "id": "message", - "filters": ["*string:*vars.cmd:*ccr", "*prefix:*req.Service-Context-Id:message", + "filters": ["*string:*vars.*cmd:CCR", "*prefix:*req.Service-Context-Id:message", "*string:*req.CC-Request-Type:4"], "flags": ["*event", "*accounts"], "request_fields":[ @@ -54,5 +37,4 @@ ], }, -} - +} \ No newline at end of file diff --git a/data/conf/samples/diamagent/simpa.json b/data/conf/samples/diamagent/simpa.json index 21708bfdd..d58867b16 100644 --- a/data/conf/samples/diamagent/simpa.json +++ b/data/conf/samples/diamagent/simpa.json @@ -5,7 +5,7 @@ "request_processors": [ { "id": "simpa_event", - "filters": ["*string:*vars.cmd:*ccr", "*string:*req.CC-Request-Type:4", + "filters": ["*string:*vars.*cmd:CCR", "*string:*req.CC-Request-Type:4", "*prefix:*req.Service-Context-Id:simpa"], "flags": ["*event", "*accounts"], "request_fields":[ diff --git a/data/conf/samples/diamagent/voice.json b/data/conf/samples/diamagent/voice.json index e79c9ba85..1ff077007 100644 --- a/data/conf/samples/diamagent/voice.json +++ b/data/conf/samples/diamagent/voice.json @@ -5,7 +5,7 @@ "request_processors": [ { "id": "VoiceInit", - "filters": ["*string:*vars.cmd:*ccr", "*string:*req.CC-Request-Type:1", + "filters": ["*string:*vars.*cmd:CCR", "*string:*req.CC-Request-Type:1", "*prefix:*req.Service-Context-Id:voice"], "flags": ["*initiate", "*accounts", "*attributes"], "request_fields":[ @@ -33,7 +33,7 @@ }, { "id": "VoiceUpdate", - "filters": ["*string:*vars.cmd:*ccr", "*string:*req.CC-Request-Type:2", + "filters": ["*string:*vars.*cmd:CCR", "*string:*req.CC-Request-Type:2", "*prefix:*req.Service-Context-Id:voice"], "flags": ["*update", "*accounts", "*attributes"], "request_fields":[ @@ -59,7 +59,7 @@ }, { "id": "VoiceTerminate", - "filters": ["*string:*vars.cmd:*ccr", "*string:*req.CC-Request-Type:3", + "filters": ["*string:*vars.*cmd:CCR", "*string:*req.CC-Request-Type:3", "*prefix:*req.Service-Context-Id:voice"], "flags": ["*terminate", "*accounts", "*attributes"], "request_fields":[ diff --git a/utils/consts.go b/utils/consts.go index 3a1692bdf..0d5220269 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -521,6 +521,7 @@ const ( ANDSep = "&" PipeSep = "|" MetaApp = "*app" + MetaAppID = "*appid" MetaCmd = "*cmd" MetaTemplate = "*template" MetaCCA = "*cca"