diff --git a/agents/agentreq.go b/agents/agentreq.go
index d859e2732..708819ef2 100644
--- a/agents/agentreq.go
+++ b/agents/agentreq.go
@@ -243,11 +243,9 @@ func (aReq *AgentRequest) ParseField(
out, err = utils.Sum(iFaceVals...)
}
if err != nil &&
- (!strings.HasPrefix(err.Error(), "Could not find") ||
- cfgFld.Mandatory) {
+ !strings.HasPrefix(err.Error(), "Could not find") {
return
}
- err = nil
if isString { // format the string additionally with fmtFieldWidth
out, err = utils.FmtFieldWidth(cfgFld.Tag, out.(string), cfgFld.Width,
cfgFld.Strip, cfgFld.Padding, cfgFld.Mandatory)
diff --git a/agents/agentreq_test.go b/agents/agentreq_test.go
index 410f529bd..1b0d956e2 100644
--- a/agents/agentreq_test.go
+++ b/agents/agentreq_test.go
@@ -19,13 +19,21 @@ along with this program. If not, see
package agents
import (
+ "bufio"
+ "bytes"
+ "net/http"
"reflect"
+ "strings"
"testing"
"time"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
+ "github.com/cgrates/radigo"
+ "github.com/fiorix/go-diameter/diam"
+ "github.com/fiorix/go-diameter/diam/avp"
+ "github.com/fiorix/go-diameter/diam/datatype"
)
func TestAgReqAsNavigableMap(t *testing.T) {
@@ -155,3 +163,195 @@ func TestAgReqMaxCost(t *testing.T) {
t.Errorf("expecting: %+v, received: %+v", eMp, mpOut)
}
}
+
+func TestAgReqParseFieldDiameter(t *testing.T) {
+ //creater diameter message
+ m := diam.NewRequest(diam.CreditControl, 4, nil)
+ m.NewAVP("Session-Id", avp.Mbit, 0, datatype.UTF8String("simuhuawei;1449573472;00002"))
+ m.NewAVP("Subscription-Id", avp.Mbit, 0, &diam.GroupedAVP{
+ AVP: []*diam.AVP{
+ diam.NewAVP(450, avp.Mbit, 0, datatype.Enumerated(2)), // Subscription-Id-Type
+ diam.NewAVP(444, avp.Mbit, 0, datatype.UTF8String("208708000004")), // Subscription-Id-Data
+ diam.NewAVP(avp.ValueDigits, avp.Mbit, 0, datatype.Integer64(20000)),
+ }})
+ //create diameterDataProvider
+ dP := newDADataProvider(m)
+ data, _ := engine.NewMapStorage()
+ dm := engine.NewDataManager(data)
+ cfg, _ := config.NewDefaultCGRConfig()
+ filterS := engine.NewFilterS(cfg, nil, dm)
+ //pass the data provider to agent request
+ agReq := newAgentRequest(dP, nil, nil, nil, "cgrates.org", "", filterS)
+
+ tplFlds := []*config.FCTemplate{
+ &config.FCTemplate{Tag: "MandatoryFalse",
+ FieldId: "MandatoryFalse", Type: utils.META_COMPOSED,
+ Value: config.NewRSRParsersMustCompile("~*req.MandatoryFalse", true),
+ Mandatory: false},
+ &config.FCTemplate{Tag: "MandatoryTrue",
+ FieldId: "MandatoryTrue", Type: utils.META_COMPOSED,
+ Value: config.NewRSRParsersMustCompile("~*req.MandatoryTrue", true),
+ Mandatory: true},
+ }
+ expected := ""
+ if out, err := agReq.ParseField(tplFlds[0]); err != nil {
+ t.Error(err)
+ } else if !reflect.DeepEqual(out, expected) {
+ t.Errorf("expecting: <%+v>, received: <%+v>", expected, out)
+ }
+ if _, err := agReq.ParseField(tplFlds[1]); err == nil ||
+ err.Error() != "Empty source value for fieldID: " {
+ t.Error(err)
+ }
+}
+
+func TestAgReqParseFieldRadius(t *testing.T) {
+ //creater radius message
+ pkt := radigo.NewPacket(radigo.AccountingRequest, 1, dictRad, coder, "CGRateS.org")
+ if err := pkt.AddAVPWithName("User-Name", "flopsy", ""); err != nil {
+ t.Error(err)
+ }
+ if err := pkt.AddAVPWithName("Cisco-NAS-Port", "CGR1", "Cisco"); err != nil {
+ t.Error(err)
+ }
+ //create radiusDataProvider
+ dP, _ := newRADataProvider(pkt)
+ data, _ := engine.NewMapStorage()
+ dm := engine.NewDataManager(data)
+ cfg, _ := config.NewDefaultCGRConfig()
+ filterS := engine.NewFilterS(cfg, nil, dm)
+ //pass the data provider to agent request
+ agReq := newAgentRequest(dP, nil, nil, nil, "cgrates.org", "", filterS)
+ tplFlds := []*config.FCTemplate{
+ &config.FCTemplate{Tag: "MandatoryFalse",
+ FieldId: "MandatoryFalse", Type: utils.META_COMPOSED,
+ Value: config.NewRSRParsersMustCompile("~*req.MandatoryFalse", true),
+ Mandatory: false},
+ &config.FCTemplate{Tag: "MandatoryTrue",
+ FieldId: "MandatoryTrue", Type: utils.META_COMPOSED,
+ Value: config.NewRSRParsersMustCompile("~*req.MandatoryTrue", true),
+ Mandatory: true},
+ }
+ expected := ""
+ if out, err := agReq.ParseField(tplFlds[0]); err != nil {
+ t.Error(err)
+ } else if !reflect.DeepEqual(out, expected) {
+ t.Errorf("expecting: <%+v>, received: <%+v>", expected, out)
+ }
+ if _, err := agReq.ParseField(tplFlds[1]); err == nil ||
+ err.Error() != "Empty source value for fieldID: " {
+ t.Error(err)
+ }
+}
+
+func TestAgReqParseFieldHttpUrl(t *testing.T) {
+ //creater radius message
+ br := bufio.NewReader(strings.NewReader(`GET /cdr?request_type=MOSMS_CDR×tamp=2008-08-15%2017:49:21&message_date=2008-08-15%2017:49:21&transactionid=100744&CDR_ID=123456&carrierid=1&mcc=222&mnc=10&imsi=235180000000000&msisdn=%2B4977000000000&destination=%2B497700000001&message_status=0&IOT=0&service_id=1 HTTP/1.1
+Host: api.cgrates.org
+
+`))
+ req, err := http.ReadRequest(br)
+ if err != nil {
+ t.Error(err)
+ }
+ //create radiusDataProvider
+ dP, _ := newHTTPUrlDP(req)
+ data, _ := engine.NewMapStorage()
+ dm := engine.NewDataManager(data)
+ cfg, _ := config.NewDefaultCGRConfig()
+ filterS := engine.NewFilterS(cfg, nil, dm)
+ //pass the data provider to agent request
+ agReq := newAgentRequest(dP, nil, nil, nil, "cgrates.org", "", filterS)
+ tplFlds := []*config.FCTemplate{
+ &config.FCTemplate{Tag: "MandatoryFalse",
+ FieldId: "MandatoryFalse", Type: utils.META_COMPOSED,
+ Value: config.NewRSRParsersMustCompile("~*req.MandatoryFalse", true),
+ Mandatory: false},
+ &config.FCTemplate{Tag: "MandatoryTrue",
+ FieldId: "MandatoryTrue", Type: utils.META_COMPOSED,
+ Value: config.NewRSRParsersMustCompile("~*req.MandatoryTrue", true),
+ Mandatory: true},
+ }
+ expected := ""
+ if out, err := agReq.ParseField(tplFlds[0]); err != nil {
+ t.Error(err)
+ } else if !reflect.DeepEqual(out, expected) {
+ t.Errorf("expecting: <%+v>, received: <%+v>", expected, out)
+ }
+
+ if _, err := agReq.ParseField(tplFlds[1]); err == nil ||
+ err.Error() != "Empty source value for fieldID: " {
+ t.Error(err)
+ }
+}
+
+func TestAgReqParseFieldHttpXml(t *testing.T) {
+ //creater radius message
+ body := `
+ 2005-08-26T14:16:42
+ 2005-08-26T14:16:56
+ 2005-08-26T14:17:34
+ My Call Reference
+ 386
+ sampleusername
+ 1
+ Conecto LLC
+ US$0.21
+ yes
+ no
+ US$0.13
+ 44
+
+ +441624828505
+ Isle of Man
+ 38
+ US$0.0200
+ US$0.0140
+ US$0.0130
+ US$0.0082
+
+
+ +44 7624 494075
+ Isle of Man
+ 37
+ US$0.2700
+ US$0.1890
+ US$0.1880
+ US$0.1159
+
+
+`
+ req, err := http.NewRequest("POST", "http://localhost:8080/", bytes.NewBuffer([]byte(body)))
+ if err != nil {
+ t.Error(err)
+ }
+ //create radiusDataProvider
+ dP, _ := newHTTPXmlDP(req)
+ data, _ := engine.NewMapStorage()
+ dm := engine.NewDataManager(data)
+ cfg, _ := config.NewDefaultCGRConfig()
+ filterS := engine.NewFilterS(cfg, nil, dm)
+ //pass the data provider to agent request
+ agReq := newAgentRequest(dP, nil, nil, nil, "cgrates.org", "", filterS)
+ tplFlds := []*config.FCTemplate{
+ &config.FCTemplate{Tag: "MandatoryFalse",
+ FieldId: "MandatoryFalse", Type: utils.META_COMPOSED,
+ Value: config.NewRSRParsersMustCompile("~*req.MandatoryFalse", true),
+ Mandatory: false},
+ &config.FCTemplate{Tag: "MandatoryTrue",
+ FieldId: "MandatoryTrue", Type: utils.META_COMPOSED,
+ Value: config.NewRSRParsersMustCompile("~*req.MandatoryTrue", true),
+ Mandatory: true},
+ }
+ expected := ""
+ if out, err := agReq.ParseField(tplFlds[0]); err != nil {
+ t.Error(err)
+ } else if !reflect.DeepEqual(out, expected) {
+ t.Errorf("expecting: <%+v>, received: <%+v>", expected, out)
+ }
+ if _, err := agReq.ParseField(tplFlds[1]); err == nil ||
+ err.Error() != "Empty source value for fieldID: " {
+ t.Error(err)
+ }
+
+}
diff --git a/data/conf/samples/diamagent/dryrun.json b/data/conf/samples/diamagent/dryrun.json
index c9302ccc3..927f58ad5 100644
--- a/data/conf/samples/diamagent/dryrun.json
+++ b/data/conf/samples/diamagent/dryrun.json
@@ -13,7 +13,7 @@
{"tag": "Val2", "field_id": "Val2", "type": "*constant", "value": "2"},
{"tag": "Val3", "field_id": "Val3", "type": "*constant", "value": "3"},
{"tag": "OptionalField", "field_id":"OptionalField", "type":"*composed",
- "value":"~*req.Inexistent", "manadatory":false},
+ "value":"~*req.Inexistent", "mandatory":false},
{"tag": "OriginID", "field_id": "OriginID", "type": "*composed",
"value": "~*req.Session-Id", "mandatory": true},
{"tag": "RequestType", "field_id": "RequestType",
diff --git a/data/conf/samples/diamsctpagent/dryrun.json b/data/conf/samples/diamsctpagent/dryrun.json
index 1cbc8d995..927f58ad5 100755
--- a/data/conf/samples/diamsctpagent/dryrun.json
+++ b/data/conf/samples/diamsctpagent/dryrun.json
@@ -13,21 +13,32 @@
{"tag": "Val2", "field_id": "Val2", "type": "*constant", "value": "2"},
{"tag": "Val3", "field_id": "Val3", "type": "*constant", "value": "3"},
{"tag": "OptionalField", "field_id":"OptionalField", "type":"*composed",
- "value":"~*req.Inexistent", "manadatory":false},
+ "value":"~*req.Inexistent", "mandatory":false},
{"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},
+ {"tag": "RequestType", "field_id": "RequestType",
+ "type": "*constant", "value": "*prepaid"},
+ {"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed",
+ "value": "~*req.Event-Timestamp", "mandatory": true},
+ {"tag": "UsedUnits1", "field_id": "UsedUnits1", "type": "*composed", "mandatory": true,
+ "value": "~*req.Multiple-Services-Credit-Control.Used-Service-Unit.CC-Total-Octets[~Rating-Group(1)]"},
+ {"tag": "UsedUnits2", "field_id": "UsedUnits2", "type": "*composed", "mandatory": true,
+ "value": "~*req.Multiple-Services-Credit-Control.Used-Service-Unit.CC-Total-Octets[~Rating-Group(2)]"},
+
],
"reply_fields":[
{"tag": "CCATemplate", "type": "*template", "value": "*cca"},
{"tag": "ResultCode", "field_id": "Result-Code", "type": "*constant", "value": "2002"},
{"tag": "RatingGroup", "field_id": "Multiple-Services-Credit-Control.Rating-Group",
- "type": "*constant", "value": "65000","new_branch": true},
- {"tag": "RatingGroup", "field_id": "Multiple-Services-Credit-Control.Rating-Group",
- "type": "*constant", "value": "100","new_branch": true},
- {"tag": "GrantedUsage", "field_id": "Granted-Service-Unit.CC-Time", "type": "*sum",
- "value": "~*cgreq.Val1;~*cgreq.Val2;~*cgreq.Val3"},
+ "type": "*constant", "value": "1"},
+ {"tag": "CCTotalOctets1", "field_id": "Multiple-Services-Credit-Control.Used-Service-Unit.CC-Total-Octets",
+ "type": "*variable", "value": "~*cgreq.UsedUnits1"},
+ {"tag": "RatingGroup", "field_id": "Multiple-Services-Credit-Control.Rating-Group",
+ "type": "*constant", "value": "2","new_branch": true},
+ {"tag": "CCTotalOctets2", "field_id": "Multiple-Services-Credit-Control.Used-Service-Unit.CC-Total-Octets",
+ "type": "*variable", "value": "~*cgreq.UsedUnits2"},
+ {"tag": "GrantedUsage", "field_id": "Granted-Service-Unit.CC-Time", "type": "*sum",
+ "value": "~*cgreq.Val1;~*cgreq.Val2;~*cgreq.Val3"},
],
},
],