diff --git a/agents/librad.go b/agents/librad.go index 353a460ef..5300e7cbd 100644 --- a/agents/librad.go +++ b/agents/librad.go @@ -50,6 +50,29 @@ func (pv processorVars) hasVar(k string) (has bool) { return } +// valAsString returns the string value for fldName +// returns empty if fldName not found +func (pv processorVars) valAsString(fldPath string) (val string, err error) { + fldName := fldPath + if strings.HasPrefix(fldPath, utils.MetaCGRReply) { + fldName = utils.MetaCGRReply + } + if !pv.hasVar(fldName) { + return "", errors.New("not found") + } + if fldName == utils.MetaCGRReply { + cgrRply := pv[utils.MetaCGRReply].(*utils.CGRReply) + return cgrRply.GetFieldAsString(fldPath, utils.HIERARCHY_SEP) + } + if valIface, hasIt := pv[fldName]; hasIt { // ProcessorVars have priority + var canCast bool + if val, canCast = utils.CastFieldIfToString(valIface); !canCast { + return "", fmt.Errorf("cannot cast field <%s> to string", fldPath) + } + } + return +} + // radAttrVendorFromPath returns AttributenName and VendorName from path // path should be the form attributeName or vendorName/attributeName func attrVendorFromPath(path string) (attrName, vendorName string) { @@ -98,15 +121,15 @@ func radComposedFieldValue(pkt *radigo.Packet, outVal += rsrTpl.ParseValue("") continue } - if valIface, hasIt := processorVars[rsrTpl.Id]; hasIt { // ProcessorVars have priority - if val, canCast := utils.CastFieldIfToString(valIface); !canCast { + if val, err := processorVars.valAsString(rsrTpl.Id); err != nil { + if err.Error() != "not found" { utils.Logger.Warning( - fmt.Sprintf("<%s> cannot cast field <%s> to string", - utils.RadiusAgent, rsrTpl.Id)) - } else { - outVal += rsrTpl.ParseValue(val) + fmt.Sprintf("<%s> %s", + utils.RadiusAgent, err.Error())) + continue } - continue + } else { + outVal += rsrTpl.ParseValue(val) } for _, avp := range pkt.AttributesWithName( attrVendorFromPath(rsrTpl.Id)) { diff --git a/agents/librad_test.go b/agents/librad_test.go index cdd3f58c3..1236d53df 100644 --- a/agents/librad_test.go +++ b/agents/librad_test.go @@ -137,7 +137,8 @@ func TestRadComposedFieldValue(t *testing.T) { } eOut := fmt.Sprintf("%s|flopsy|CGR1", MetaRadAcctStart) if out := radComposedFieldValue(pkt, processorVars{MetaRadReqType: MetaRadAcctStart}, - utils.ParseRSRFieldsMustCompile(fmt.Sprintf("%s;^|;User-Name;^|;Cisco/Cisco-NAS-Port", MetaRadReqType), utils.INFIELD_SEP)); out != eOut { + utils.ParseRSRFieldsMustCompile(fmt.Sprintf("%s;^|;User-Name;^|;Cisco/Cisco-NAS-Port", + MetaRadReqType), utils.INFIELD_SEP)); out != eOut { t.Errorf("Expecting: <%s>, received: <%s>", eOut, out) } } diff --git a/data/conf/samples/radagent/cgrates.json b/data/conf/samples/radagent/cgrates.json index e1f43b229..da1def9c9 100644 --- a/data/conf/samples/radagent/cgrates.json +++ b/data/conf/samples/radagent/cgrates.json @@ -116,7 +116,7 @@ ], "reply_fields":[ {"tag": "MaxUsage", "field_id": "SIP-AVP", "type": "*composed", - "value": "^session_max_time#;~*cgrMaxUsage:s/(\\d*)\\d{9}$/$1/", "mandatory": true}, + "value": "^session_max_time#;~*cgrReply>MaxUsage:s/(\\d*)\\d{9}$/$1/", "mandatory": true}, ], }, {