CGRReply with data converters within radius agent

This commit is contained in:
DanB
2018-04-17 19:28:16 +02:00
parent 02c93a248c
commit eabacead26
6 changed files with 56 additions and 27 deletions

View File

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

View File

@@ -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())
}
}
*/

View File

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

View File

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

View File

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

View File

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