From eabacead261bbb871070e919ee061e1787ab4650 Mon Sep 17 00:00:00 2001 From: DanB Date: Tue, 17 Apr 2018 19:28:16 +0200 Subject: [PATCH] CGRReply with data converters within radius agent --- agents/librad.go | 28 +++++++++++++++++++++++----- agents/librad_test.go | 22 ++++++++++++++-------- sessions/sessions.go | 22 +++++++++++----------- utils/consts.go | 7 ++++++- utils/dataconverter.go | 2 +- utils/dataconverter_test.go | 2 +- 6 files changed, 56 insertions(+), 27 deletions(-) diff --git a/agents/librad.go b/agents/librad.go index f56b0956a..436afbf10 100644 --- a/agents/librad.go +++ b/agents/librad.go @@ -79,7 +79,7 @@ func (pv processorVars) valAsString(fldPath string) (val string, err error) { return "", errors.New("not found") } if fldName == utils.MetaCGRReply { - cgrRply := pv[utils.MetaCGRReply].(utils.CGRReply) + cgrRply := pv[utils.MetaCGRReply].(*utils.CGRReply) return cgrRply.GetFieldAsString(fldPath, utils.HIERARCHY_SEP) } if valIface, hasIt := pv[fldName]; hasIt { @@ -137,7 +137,13 @@ func radComposedFieldValue(pkt *radigo.Packet, procVars processorVars, outTpl utils.RSRFields) (outVal string) { for _, rsrTpl := range outTpl { if rsrTpl.IsStatic() { - outVal += rsrTpl.ParseValue("") + if parsed, err := rsrTpl.Parse(""); err != nil { + utils.Logger.Warning( + fmt.Sprintf("<%s> %s", + utils.RadiusAgent, err.Error())) + } else { + outVal += parsed + } continue } if val, err := procVars.valAsString(rsrTpl.Id); err != nil { @@ -148,12 +154,24 @@ func radComposedFieldValue(pkt *radigo.Packet, continue } } else { - outVal += rsrTpl.ParseValue(val) + if parsed, err := rsrTpl.Parse(val); err != nil { + utils.Logger.Warning( + fmt.Sprintf("<%s> %s", + utils.RadiusAgent, err.Error())) + } else { + outVal += parsed + } continue } for _, avp := range pkt.AttributesWithName( attrVendorFromPath(rsrTpl.Id)) { - outVal += rsrTpl.ParseValue(avp.GetStringValue()) + if parsed, err := rsrTpl.Parse(avp.GetStringValue()); err != nil { + utils.Logger.Warning( + fmt.Sprintf("<%s> %s", + utils.RadiusAgent, err.Error())) + } else { + outVal += parsed + } } } return outVal @@ -178,7 +196,7 @@ func radMetaHandler(pkt *radigo.Packet, procVars processorVars, return "", err } return tEnd.Sub(tStart).String(), nil - case utils.MetaUsageSeconds: + case utils.MetaDurationSeconds: if len(handlerArgs) != 1 { return "", errors.New("unexpected number of arguments") } diff --git a/agents/librad_test.go b/agents/librad_test.go index 6fbc5eb7c..2c5096205 100644 --- a/agents/librad_test.go +++ b/agents/librad_test.go @@ -388,16 +388,23 @@ func TestRadV1TerminateSessionArgs(t *testing.T) { } } -/* func TestRadReplyAppendAttributes(t *testing.T) { rply := radigo.NewPacket(radigo.AccessRequest, 2, dictRad, coder, "CGRateS.org").Reply() rplyFlds := []*config.CfgCdrField{ - &config.CfgCdrField{Tag: "ReplyCode", FieldId: MetaRadReplyCode, Type: utils.META_CONSTANT, - Value: utils.ParseRSRFieldsMustCompile("AccessAccept", utils.INFIELD_SEP)}, + &config.CfgCdrField{Tag: "ReplyCode", FieldId: MetaRadReplyCode, Type: utils.META_COMPOSED, + Value: utils.ParseRSRFieldsMustCompile("*cgrReply>Attributes>RadReply", utils.INFIELD_SEP)}, &config.CfgCdrField{Tag: "Acct-Session-Time", FieldId: "Acct-Session-Time", Type: utils.META_COMPOSED, - Value: utils.ParseRSRFieldsMustCompile("~*cgrMaxUsage:s/(\\d*)\\d{9}$/$1/", utils.INFIELD_SEP)}, + Value: utils.ParseRSRFieldsMustCompile("*cgrReply>MaxUsage{*duration_seconds}", utils.INFIELD_SEP)}, } - if err := radReplyAppendAttributes(rply, processorVars{MetaCGRMaxUsage: "30000000000"}, rplyFlds); err != nil { + procVars := make(processorVars) + procVars[utils.MetaCGRReply] = &utils.CGRReply{ + utils.CapAttributes: map[string]interface{}{ + "RadReply": "AccessAccept", + utils.Account: "1001", + }, + utils.CapMaxUsage: time.Duration(time.Hour), + } + if err := radReplyAppendAttributes(rply, procVars, rplyFlds); err != nil { t.Error(err) } if rply.Code != radigo.AccessAccept { @@ -405,8 +412,7 @@ func TestRadReplyAppendAttributes(t *testing.T) { } if avps := rply.AttributesWithName("Acct-Session-Time", ""); len(avps) == 0 { t.Error("Cannot find Acct-Session-Time in reply") - } else if avps[0].GetStringValue() != "30" { - t.Errorf("Expecting: 30, received: %s", avps[0].GetStringValue()) + } else if avps[0].GetStringValue() != "3600" { + t.Errorf("Expecting: 3600, received: %s", avps[0].GetStringValue()) } } -*/ diff --git a/sessions/sessions.go b/sessions/sessions.go index ea3d52303..021a3144a 100644 --- a/sessions/sessions.go +++ b/sessions/sessions.go @@ -1334,19 +1334,19 @@ func (v1AuthReply *V1AuthorizeReply) AsCGRReply() (cgrReply utils.CGRReply, err attrs[fldName] = v1AuthReply.Attributes.CGREvent.Event[fldName] } } - cgrReply["Attributes"] = attrs + cgrReply[utils.CapAttributes] = attrs } if v1AuthReply.ResourceAllocation != nil { - cgrReply["ResourceAllocation"] = *v1AuthReply.ResourceAllocation + cgrReply[utils.CapResourceAllocation] = *v1AuthReply.ResourceAllocation } if v1AuthReply.MaxUsage != nil { - cgrReply["MaxUsage"] = *v1AuthReply.MaxUsage + cgrReply[utils.CapMaxUsage] = *v1AuthReply.MaxUsage } if v1AuthReply.Suppliers != nil { - cgrReply["Suppliers"] = v1AuthReply.Suppliers.Digest() + cgrReply[utils.CapSuppliers] = v1AuthReply.Suppliers.Digest() } if v1AuthReply.ThresholdHits != nil { - cgrReply["ThresholdHits"] = *v1AuthReply.ThresholdHits + cgrReply[utils.CapThresholdHits] = *v1AuthReply.ThresholdHits } return } @@ -1524,16 +1524,16 @@ func (v1Rply *V1InitSessionReply) AsCGRReply() (cgrReply utils.CGRReply, err err attrs[fldName] = v1Rply.Attributes.CGREvent.Event[fldName] } } - cgrReply["Attributes"] = attrs + cgrReply[utils.CapAttributes] = attrs } if v1Rply.ResourceAllocation != nil { - cgrReply["ResourceAllocation"] = *v1Rply.ResourceAllocation + cgrReply[utils.CapResourceAllocation] = *v1Rply.ResourceAllocation } if v1Rply.MaxUsage != nil { - cgrReply["MaxUsage"] = *v1Rply.MaxUsage + cgrReply[utils.CapMaxUsage] = *v1Rply.MaxUsage } if v1Rply.ThresholdHits != nil { - cgrReply["ThresholdHits"] = *v1Rply.ThresholdHits + cgrReply[utils.CapThresholdHits] = *v1Rply.ThresholdHits } return } @@ -1648,10 +1648,10 @@ func (v1Rply *V1UpdateSessionReply) AsCGRReply() (cgrReply utils.CGRReply, err e attrs[fldName] = v1Rply.Attributes.CGREvent.Event[fldName] } } - cgrReply["Attributes"] = attrs + cgrReply[utils.CapAttributes] = attrs } if v1Rply.MaxUsage != nil { - cgrReply["MaxUsage"] = *v1Rply.MaxUsage + cgrReply[utils.CapMaxUsage] = *v1Rply.MaxUsage } return } diff --git a/utils/consts.go b/utils/consts.go index 42027ae3a..014a425bd 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -590,7 +590,12 @@ const ( MetaTpDestinations = "*tp_destinations" MetaTpRatingPlan = "*tp_rating_plan" MetaTpRatingProfile = "*tp_rating_profile" - MetaUsageSeconds = "*duration_seconds" + MetaDurationSeconds = "*duration_seconds" + CapAttributes = "Attributes" + CapResourceAllocation = "ResourceAllocation" + CapMaxUsage = "MaxUsage" + CapSuppliers = "Suppliers" + CapThresholdHits = "ThresholdHits" ) // MetaFilterIndexesAPIs diff --git a/utils/dataconverter.go b/utils/dataconverter.go index aea51b875..ffb662fec 100644 --- a/utils/dataconverter.go +++ b/utils/dataconverter.go @@ -54,7 +54,7 @@ type DataConverter interface { func NewDataConverter(params string) ( conv DataConverter, err error) { switch { - case params == MetaUsageSeconds: + case params == MetaDurationSeconds: return NewDurationSecondsConverter("") case strings.HasPrefix(params, MetaRound): if len(params) == len(MetaRound) { // no extra params, defaults implied diff --git a/utils/dataconverter_test.go b/utils/dataconverter_test.go index 3f8d14b01..c2742ff14 100644 --- a/utils/dataconverter_test.go +++ b/utils/dataconverter_test.go @@ -24,7 +24,7 @@ import ( ) func TestNewDataConverter(t *testing.T) { - a, err := NewDataConverter(MetaUsageSeconds) + a, err := NewDataConverter(MetaDurationSeconds) if err != nil { t.Error(err.Error()) }