Config InflateTemplates function as standalone, added *appid to request *vars

This commit is contained in:
DanB
2018-10-02 19:42:09 +02:00
parent 1c079a935b
commit 70a07a1636
12 changed files with 72 additions and 65 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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":[

View File

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

View File

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

View File

@@ -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":[

View File

@@ -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":[

View File

@@ -521,6 +521,7 @@ const (
ANDSep = "&"
PipeSep = "|"
MetaApp = "*app"
MetaAppID = "*appid"
MetaCmd = "*cmd"
MetaTemplate = "*template"
MetaCCA = "*cca"