diff --git a/agents/libdiam.go b/agents/libdiam.go
index cbb69275b..522750f36 100644
--- a/agents/libdiam.go
+++ b/agents/libdiam.go
@@ -293,7 +293,7 @@ func newDADataProvider(c diam.Conn, m *diam.Message) utils.DataProvider {
}
-// diameterDP implements engine.DataProvider, serving as diam.Message data decoder
+// diameterDP implements utils.DataProvider, serving as diam.Message data decoder
// decoded data is only searched once and cached
type diameterDP struct {
c diam.Conn
@@ -301,13 +301,13 @@ type diameterDP struct {
cache *config.NavigableMap
}
-// String is part of engine.DataProvider interface
+// String is part of utils.DataProvider interface
// when called, it will display the already parsed values out of cache
func (dP *diameterDP) String() string {
return dP.m.String()
}
-// FieldAsString is part of engine.DataProvider interface
+// FieldAsString is part of utils.DataProvider interface
func (dP *diameterDP) FieldAsString(fldPath []string) (data string, err error) {
var valIface interface{}
valIface, err = dP.FieldAsInterface(fldPath)
@@ -317,12 +317,12 @@ func (dP *diameterDP) FieldAsString(fldPath []string) (data string, err error) {
return utils.IfaceAsString(valIface), nil
}
-// RemoteHost is part of engine.DataProvider interface
+// RemoteHost is part of utils.DataProvider interface
func (dP *diameterDP) RemoteHost() net.Addr {
return utils.NewNetAddr(dP.c.RemoteAddr().Network(), dP.c.RemoteAddr().String())
}
-// FieldAsInterface is part of engine.DataProvider interface
+// FieldAsInterface is part of utils.DataProvider interface
func (dP *diameterDP) FieldAsInterface(fldPath []string) (data interface{}, err error) {
if data, err = dP.cache.FieldAsInterface(fldPath); err != nil {
if err != utils.ErrNotFound { // item found in cache
diff --git a/agents/libdns.go b/agents/libdns.go
index a3e96d47b..147a914dc 100644
--- a/agents/libdns.go
+++ b/agents/libdns.go
@@ -73,13 +73,13 @@ type dnsDP struct {
cache *config.NavigableMap
}
-// String is part of engine.DataProvider interface
+// String is part of utils.DataProvider interface
// when called, it will display the already parsed values out of cache
func (dP *dnsDP) String() string {
return utils.ToJSON(dP.req)
}
-// FieldAsString is part of engine.DataProvider interface
+// FieldAsString is part of utils.DataProvider interface
func (dP *dnsDP) FieldAsString(fldPath []string) (data string, err error) {
var valIface interface{}
valIface, err = dP.FieldAsInterface(fldPath)
@@ -89,12 +89,12 @@ func (dP *dnsDP) FieldAsString(fldPath []string) (data string, err error) {
return utils.IfaceAsString(valIface), nil
}
-// RemoteHost is part of engine.DataProvider interface
+// RemoteHost is part of utils.DataProvider interface
func (dP *dnsDP) RemoteHost() net.Addr {
return utils.NewNetAddr(dP.w.RemoteAddr().Network(), dP.w.RemoteAddr().String())
}
-// FieldAsInterface is part of engine.DataProvider interface
+// FieldAsInterface is part of utils.DataProvider interface
func (dP *dnsDP) FieldAsInterface(fldPath []string) (data interface{}, err error) {
if data, err = dP.cache.FieldAsInterface(fldPath); err != nil {
if err != utils.ErrNotFound { // item found in cache
diff --git a/agents/libhttpagent.go b/agents/libhttpagent.go
index 5779ff11a..be5c44160 100644
--- a/agents/libhttpagent.go
+++ b/agents/libhttpagent.go
@@ -52,21 +52,21 @@ func newHTTPUrlDP(req *http.Request) (dP utils.DataProvider, err error) {
return
}
-// httpUrlDP implements engine.DataProvider, serving as url data decoder
+// httpUrlDP implements utils.DataProvider, serving as url data decoder
// decoded data is only searched once and cached
type httpUrlDP struct {
req *http.Request
cache *config.NavigableMap
}
-// String is part of engine.DataProvider interface
+// String is part of utils.DataProvider interface
// when called, it will display the already parsed values out of cache
func (hU *httpUrlDP) String() string {
byts, _ := httputil.DumpRequest(hU.req, true)
return string(byts)
}
-// FieldAsInterface is part of engine.DataProvider interface
+// FieldAsInterface is part of utils.DataProvider interface
func (hU *httpUrlDP) FieldAsInterface(fldPath []string) (data interface{}, err error) {
if len(fldPath) != 1 {
return nil, utils.ErrNotFound
@@ -84,7 +84,7 @@ func (hU *httpUrlDP) FieldAsInterface(fldPath []string) (data interface{}, err e
return
}
-// FieldAsString is part of engine.DataProvider interface
+// FieldAsString is part of utils.DataProvider interface
func (hU *httpUrlDP) FieldAsString(fldPath []string) (data string, err error) {
var valIface interface{}
valIface, err = hU.FieldAsInterface(fldPath)
@@ -94,7 +94,7 @@ func (hU *httpUrlDP) FieldAsString(fldPath []string) (data string, err error) {
return utils.IfaceAsString(valIface), nil
}
-// RemoteHost is part of engine.DataProvider interface
+// RemoteHost is part of utils.DataProvider interface
func (hU *httpUrlDP) RemoteHost() net.Addr {
return utils.NewNetAddr("TCP", hU.req.RemoteAddr)
}
@@ -113,7 +113,7 @@ func newHTTPXmlDP(req *http.Request) (dP utils.DataProvider, err error) {
return
}
-// httpXmlDP implements engine.DataProvider, serving as xml data decoder
+// httpXmlDP implements utils.DataProvider, serving as xml data decoder
// decoded data is only searched once and cached
type httpXmlDP struct {
cache *config.NavigableMap
@@ -121,13 +121,13 @@ type httpXmlDP struct {
addr string
}
-// String is part of engine.DataProvider interface
+// String is part of utils.DataProvider interface
// when called, it will display the already parsed values out of cache
func (hU *httpXmlDP) String() string {
return hU.xmlDoc.OutputXML(true)
}
-// FieldAsInterface is part of engine.DataProvider interface
+// FieldAsInterface is part of utils.DataProvider interface
func (hU *httpXmlDP) FieldAsInterface(fldPath []string) (data interface{}, err error) {
//if path is missing return here error because if it arrived in xmlquery library will panic
if len(fldPath) == 0 {
@@ -172,7 +172,7 @@ func (hU *httpXmlDP) FieldAsInterface(fldPath []string) (data interface{}, err e
return
}
-// FieldAsString is part of engine.DataProvider interface
+// FieldAsString is part of utils.DataProvider interface
func (hU *httpXmlDP) FieldAsString(fldPath []string) (data string, err error) {
var valIface interface{}
valIface, err = hU.FieldAsInterface(fldPath)
@@ -182,7 +182,7 @@ func (hU *httpXmlDP) FieldAsString(fldPath []string) (data string, err error) {
return utils.IfaceAsString(valIface), nil
}
-// RemoteHost is part of engine.DataProvider interface
+// RemoteHost is part of utils.DataProvider interface
func (hU *httpXmlDP) RemoteHost() net.Addr {
return utils.NewNetAddr("TCP", hU.addr)
}
diff --git a/agents/librad.go b/agents/librad.go
index c53c955fd..a3f1a8d4a 100644
--- a/agents/librad.go
+++ b/agents/librad.go
@@ -66,20 +66,20 @@ func newRADataProvider(req *radigo.Packet) (dP utils.DataProvider) {
return
}
-// radiusDP implements engine.DataProvider, serving as radigo.Packet data decoder
+// radiusDP implements utils.DataProvider, serving as radigo.Packet data decoder
// decoded data is only searched once and cached
type radiusDP struct {
req *radigo.Packet
cache *config.NavigableMap
}
-// String is part of engine.DataProvider interface
+// String is part of utils.DataProvider interface
// when called, it will display the already parsed values out of cache
func (pk *radiusDP) String() string {
return utils.ToIJSON(pk.req) // return ToJSON because Packet don't have a string method
}
-// FieldAsInterface is part of engine.DataProvider interface
+// FieldAsInterface is part of utils.DataProvider interface
func (pk *radiusDP) FieldAsInterface(fldPath []string) (data interface{}, err error) {
if len(fldPath) != 1 {
return nil, utils.ErrNotFound
@@ -99,7 +99,7 @@ func (pk *radiusDP) FieldAsInterface(fldPath []string) (data interface{}, err er
return
}
-// FieldAsString is part of engine.DataProvider interface
+// FieldAsString is part of utils.DataProvider interface
func (pk *radiusDP) FieldAsString(fldPath []string) (data string, err error) {
var valIface interface{}
valIface, err = pk.FieldAsInterface(fldPath)
@@ -109,7 +109,7 @@ func (pk *radiusDP) FieldAsString(fldPath []string) (data string, err error) {
return utils.IfaceAsString(valIface), nil
}
-// RemoteHost is part of engine.DataProvider interface
+// RemoteHost is part of utils.DataProvider interface
func (pk *radiusDP) RemoteHost() net.Addr {
return utils.NewNetAddr(pk.req.RemoteAddr().Network(), pk.req.RemoteAddr().String())
}
diff --git a/apier/v1/caches_it_test.go b/apier/v1/caches_it_test.go
index fbe720095..af6df189f 100644
--- a/apier/v1/caches_it_test.go
+++ b/apier/v1/caches_it_test.go
@@ -348,7 +348,7 @@ func testCacheSClear(t *testing.T) {
func testCacheSPrecacheStatus(t *testing.T) {
var reply map[string]string
expected := make(map[string]string)
- for k := range utils.CachePartitions.Data() {
+ for k := range utils.CachePartitions {
expected[k] = utils.MetaReady
}
if err := chcRPC.Call(utils.CacheSv1PrecacheStatus, &utils.AttrCacheIDsWithArgDispatcher{}, &reply); err != nil {
diff --git a/apier/v1/config_it_test.go b/apier/v1/config_it_test.go
index 49cb69359..4e0987bcf 100644
--- a/apier/v1/config_it_test.go
+++ b/apier/v1/config_it_test.go
@@ -154,7 +154,9 @@ func testConfigSReloadConfigFromJSONSessionS(t *testing.T) {
"StoreSCosts": false,
"AlterableFields": map[string]interface{}{},
"STIRCfg": map[string]interface{}{
- "AllowedAttest": map[string]interface{}{},
+ "AllowedAttest": map[string]interface{}{
+ utils.META_ANY: map[string]interface{}{},
+ },
"DefaultAttest": "A",
"PayloadMaxduration": -1.,
"PrivateKeyPath": "",
@@ -175,7 +177,7 @@ func testConfigSReloadConfigFromJSONSessionS(t *testing.T) {
}, &rpl); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(exp, rpl) {
- t.Errorf("Expected %+v , received: %+v ", exp, rpl)
+ t.Errorf("Expected %+v , received: %+v ", utils.ToJSON(exp), utils.ToJSON(rpl))
}
}
diff --git a/config/config_it_test.go b/config/config_it_test.go
index 031fdd865..e81567ee8 100644
--- a/config/config_it_test.go
+++ b/config/config_it_test.go
@@ -438,17 +438,20 @@ func testCGRConfigReloadERs(t *testing.T) {
flags, _ := utils.FlagsWithParamsFromSlice([]string{"*dryrun"})
flagsDefault, _ := utils.FlagsWithParamsFromSlice([]string{})
content := []*FCTemplate{
- &FCTemplate{Tag: utils.ToR, Path: utils.MetaCgreq + utils.NestingSep + utils.ToR, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.2", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
- &FCTemplate{Tag: utils.OriginID, Path: utils.MetaCgreq + utils.NestingSep + utils.OriginID, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.3", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
- &FCTemplate{Tag: utils.RequestType, Path: utils.MetaCgreq + utils.NestingSep + utils.RequestType, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.4", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
- &FCTemplate{Tag: utils.Tenant, Path: utils.MetaCgreq + utils.NestingSep + utils.Tenant, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.6", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
- &FCTemplate{Tag: utils.Category, Path: utils.MetaCgreq + utils.NestingSep + utils.Category, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.7", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
- &FCTemplate{Tag: utils.Account, Path: utils.MetaCgreq + utils.NestingSep + utils.Account, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.8", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
- &FCTemplate{Tag: utils.Subject, Path: utils.MetaCgreq + utils.NestingSep + utils.Subject, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.9", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
- &FCTemplate{Tag: utils.Destination, Path: utils.MetaCgreq + utils.NestingSep + utils.Destination, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.10", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
- &FCTemplate{Tag: utils.SetupTime, Path: utils.MetaCgreq + utils.NestingSep + utils.SetupTime, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.11", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
- &FCTemplate{Tag: utils.AnswerTime, Path: utils.MetaCgreq + utils.NestingSep + utils.AnswerTime, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.12", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
- &FCTemplate{Tag: utils.Usage, Path: utils.MetaCgreq + utils.NestingSep + utils.Usage, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.13", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
+ {Tag: utils.ToR, Path: utils.MetaCgreq + utils.NestingSep + utils.ToR, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.2", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
+ {Tag: utils.OriginID, Path: utils.MetaCgreq + utils.NestingSep + utils.OriginID, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.3", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
+ {Tag: utils.RequestType, Path: utils.MetaCgreq + utils.NestingSep + utils.RequestType, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.4", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
+ {Tag: utils.Tenant, Path: utils.MetaCgreq + utils.NestingSep + utils.Tenant, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.6", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
+ {Tag: utils.Category, Path: utils.MetaCgreq + utils.NestingSep + utils.Category, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.7", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
+ {Tag: utils.Account, Path: utils.MetaCgreq + utils.NestingSep + utils.Account, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.8", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
+ {Tag: utils.Subject, Path: utils.MetaCgreq + utils.NestingSep + utils.Subject, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.9", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
+ {Tag: utils.Destination, Path: utils.MetaCgreq + utils.NestingSep + utils.Destination, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.10", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
+ {Tag: utils.SetupTime, Path: utils.MetaCgreq + utils.NestingSep + utils.SetupTime, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.11", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
+ {Tag: utils.AnswerTime, Path: utils.MetaCgreq + utils.NestingSep + utils.AnswerTime, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.12", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
+ {Tag: utils.Usage, Path: utils.MetaCgreq + utils.NestingSep + utils.Usage, Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~*req.13", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
+ }
+ for _, v := range content {
+ v.ComputePath()
}
expAttr := &ERsCfg{
Enabled: true,
diff --git a/config/multifiles_it_test.go b/config/multifiles_it_test.go
index 4fd3fb838..f85f5a4d6 100644
--- a/config/multifiles_it_test.go
+++ b/config/multifiles_it_test.go
@@ -212,6 +212,16 @@ func TestMfHttpAgentMultipleFields(t *testing.T) {
ReplyFields: []*FCTemplate{},
}}},
}
+ for _, profile := range expected {
+ for _, rp := range profile.RequestProcessors {
+ for _, v := range rp.ReplyFields {
+ v.ComputePath()
+ }
+ for _, v := range rp.RequestFields {
+ v.ComputePath()
+ }
+ }
+ }
if !reflect.DeepEqual(mfCgrCfg.HttpAgentCfg(), expected) {
t.Errorf("Expected: %+v\n, recived: %+v", utils.ToJSON(expected), utils.ToJSON(mfCgrCfg.HttpAgentCfg()))
diff --git a/config/navigablemap_test.go b/config/navigablemap_test.go
index 19dadf7b9..38e8e8841 100644
--- a/config/navigablemap_test.go
+++ b/config/navigablemap_test.go
@@ -1182,3 +1182,333 @@ func TestNavMapGetKeys(t *testing.T) {
t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(expKeys), utils.ToJSON(keys))
}
}
+
+func TestNMAsXMLElements(t *testing.T) {
+ nM := utils.NewOrderedNavigableMap()
+ order := []utils.PathItems{
+ {{Field: "FirstLevel2"}, {Field: "SecondLevel2"}, {Field: "Field2"}},
+ {{Field: "FirstLevel"}, {Field: "SecondLevel"}, {Field: "ThirdLevel"}, {Field: "Fld1"}},
+ {{Field: "FirstLevel2"}, {Field: "Field3"}},
+ {{Field: "FirstLevel2"}, {Field: "Field5"}},
+ {{Field: "Field4"}},
+ {{Field: "FirstLevel2"}, {Field: "Field6"}},
+ }
+ if _, err := nM.Set(&utils.FullPath{Path: order[0].String(), PathItems: order[0]}, &utils.NMSlice{
+ &NMItem{Path: strings.Split(order[0].String(), utils.NestingSep),
+ Data: "attrVal1",
+ Config: &FCTemplate{Tag: "AttributeTest", AttributeID: "attribute1"}},
+ &NMItem{Path: strings.Split(order[0].String(), utils.NestingSep),
+ Data: "Value2"}}); err != nil {
+ t.Error(err)
+ }
+ if _, err := nM.Set(&utils.FullPath{Path: order[1].String(), PathItems: order[1]}, &utils.NMSlice{
+ &NMItem{Path: strings.Split(order[1].String(), utils.NestingSep),
+ Data: "Val1"}}); err != nil {
+ t.Error(err)
+ }
+ if _, err := nM.Set(&utils.FullPath{Path: order[2].String(), PathItems: order[2]}, &utils.NMSlice{
+ &NMItem{Path: strings.Split(order[2].String(), utils.NestingSep),
+ Data: "Value3"}}); err != nil {
+ t.Error(err)
+ }
+ if _, err := nM.Set(&utils.FullPath{Path: order[3].String(), PathItems: order[3]}, &utils.NMSlice{
+ &NMItem{Path: strings.Split(order[3].String(), utils.NestingSep),
+ Data: "Value5"},
+ &NMItem{Path: strings.Split(order[3].String(), utils.NestingSep),
+ Data: "attrVal5",
+ Config: &FCTemplate{Tag: "AttributeTest", AttributeID: "attribute5"}}}); err != nil {
+ t.Error(err)
+ }
+ if _, err := nM.Set(&utils.FullPath{Path: order[4].String(), PathItems: order[4]}, &utils.NMSlice{
+ &NMItem{Path: strings.Split(order[4].String(), utils.NestingSep),
+ Data: "Val4"},
+ &NMItem{Path: strings.Split(order[4].String(), utils.NestingSep),
+ Data: "attrVal2",
+ Config: &FCTemplate{Tag: "AttributeTest", AttributeID: "attribute2"}}}); err != nil {
+ t.Error(err)
+ }
+ if _, err := nM.Set(&utils.FullPath{Path: order[5].String(), PathItems: order[5]}, &utils.NMSlice{
+ &NMItem{Path: strings.Split(order[5].String(), utils.NestingSep),
+ Data: "Value6",
+ Config: &FCTemplate{Tag: "NewBranchTest", NewBranch: true}},
+ &NMItem{Path: strings.Split(order[5].String(), utils.NestingSep),
+ Data: "attrVal6",
+ Config: &FCTemplate{Tag: "AttributeTest", AttributeID: "attribute6"}}}); err != nil {
+ t.Error(err)
+ }
+ eXMLElmnts := []*XMLElement{
+ &XMLElement{
+ XMLName: xml.Name{Local: order[0][0].String()},
+ Elements: []*XMLElement{
+ &XMLElement{
+ XMLName: xml.Name{Local: order[0][1].String()},
+ Elements: []*XMLElement{
+ &XMLElement{
+ XMLName: xml.Name{Local: order[0][2].String()},
+ Attributes: []*xml.Attr{
+ &xml.Attr{
+ Name: xml.Name{Local: "attribute1"},
+ Value: "attrVal1",
+ },
+ },
+ Value: "Value2",
+ },
+ },
+ },
+ &XMLElement{
+ XMLName: xml.Name{Local: "Field3"},
+ Value: "Value3",
+ },
+ &XMLElement{
+ XMLName: xml.Name{Local: order[3][1].String()},
+ Attributes: []*xml.Attr{
+ &xml.Attr{
+ Name: xml.Name{Local: "attribute5"},
+ Value: "attrVal5",
+ },
+ },
+ Value: "Value5",
+ },
+ },
+ },
+ &XMLElement{
+ XMLName: xml.Name{Local: order[1][0].String()},
+ Elements: []*XMLElement{
+ &XMLElement{
+ XMLName: xml.Name{Local: order[1][1].String()},
+ Elements: []*XMLElement{
+ &XMLElement{
+ XMLName: xml.Name{Local: order[1][2].String()},
+ Elements: []*XMLElement{
+ &XMLElement{
+ XMLName: xml.Name{Local: "Fld1"},
+ Value: "Val1",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ &XMLElement{
+ XMLName: xml.Name{Local: order[4][0].String()},
+ Attributes: []*xml.Attr{
+ &xml.Attr{
+ Name: xml.Name{Local: "attribute2"},
+ Value: "attrVal2",
+ },
+ },
+ Value: "Val4",
+ },
+ &XMLElement{
+ XMLName: xml.Name{Local: order[5][0].String()},
+ Elements: []*XMLElement{
+ &XMLElement{
+ XMLName: xml.Name{Local: order[5][1].String()},
+ Attributes: []*xml.Attr{
+ &xml.Attr{
+ Name: xml.Name{Local: "attribute6"},
+ Value: "attrVal6",
+ },
+ },
+ Value: "Value6",
+ },
+ },
+ },
+ }
+ xmlEnts, err := NMAsXMLElements(nM)
+ if err != nil {
+ t.Error(err)
+ } else if !reflect.DeepEqual(eXMLElmnts, xmlEnts) {
+ t.Errorf("expecting: %s, received: %s", utils.ToJSON(eXMLElmnts), utils.ToJSON(xmlEnts))
+ }
+ eXML := []byte(`
+
+ Value2
+
+ Value3
+ Value5
+
+
+
+
+ Val1
+
+
+
+Val4
+
+ Value6
+`)
+ if output, err := xml.MarshalIndent(xmlEnts, "", " "); err != nil {
+ t.Error(err)
+ } else if !reflect.DeepEqual(eXML, output) {
+ t.Errorf("expecting: \n%s, received: \n%s\n", string(eXML), string(output))
+ }
+}
+
+func TestNMAsCGREvent(t *testing.T) {
+ if cgrEv := NMAsCGREvent(nil, "cgrates.org",
+ utils.NestingSep); cgrEv != nil {
+ t.Errorf("expecting: %+v, \nreceived: %+v", utils.ToJSON(nil), utils.ToJSON(cgrEv.Event))
+ }
+
+ nM := utils.NewOrderedNavigableMap()
+ if cgrEv := NMAsCGREvent(nM, "cgrates.org",
+ utils.NestingSep); cgrEv != nil {
+ t.Errorf("expecting: %+v, \nreceived: %+v", utils.ToJSON(nil), utils.ToJSON(cgrEv.Event))
+ }
+
+ path := utils.PathItems{{Field: "FirstLevel"}, {Field: "SecondLevel"}, {Field: "ThirdLevel"}, {Field: "Fld1"}}
+ if _, err := nM.Set(&utils.FullPath{Path: path.String(), PathItems: path}, &utils.NMSlice{&NMItem{
+ Path: strings.Split(path.String(), utils.NestingSep),
+ Data: "Val1",
+ }}); err != nil {
+ t.Error(err)
+ }
+
+ path = utils.PathItems{{Field: "FirstLevel2"}, {Field: "SecondLevel2"}, {Field: "Field2"}}
+ if _, err := nM.Set(&utils.FullPath{Path: path.String(), PathItems: path}, &utils.NMSlice{&NMItem{
+ Path: strings.Split(path.String(), utils.NestingSep),
+ Data: "attrVal1",
+ Config: &FCTemplate{Tag: "AttributeTest",
+ AttributeID: "attribute1"},
+ }, &NMItem{
+ Path: strings.Split(path.String(), utils.NestingSep),
+ Data: "Value2",
+ }}); err != nil {
+ t.Error(err)
+ }
+
+ path = utils.PathItems{{Field: "FirstLevel2"}, {Field: "Field3"}}
+ if _, err := nM.Set(&utils.FullPath{Path: path.String(), PathItems: path}, &utils.NMSlice{&NMItem{
+ Path: strings.Split(path.String(), utils.NestingSep),
+ Data: "Value3",
+ }}); err != nil {
+ t.Error(err)
+ }
+
+ path = utils.PathItems{{Field: "FirstLevel2"}, {Field: "Field5"}}
+ if _, err := nM.Set(&utils.FullPath{Path: path.String(), PathItems: path}, &utils.NMSlice{&NMItem{
+ Path: strings.Split(path.String(), utils.NestingSep),
+ Data: "Value5",
+ }, &NMItem{
+ Path: strings.Split(path.String(), utils.NestingSep),
+ Data: "attrVal5",
+ Config: &FCTemplate{Tag: "AttributeTest",
+ AttributeID: "attribute5"},
+ }}); err != nil {
+ t.Error(err)
+ }
+
+ path = utils.PathItems{{Field: "FirstLevel2"}, {Field: "Field6"}}
+ if _, err := nM.Set(&utils.FullPath{Path: path.String(), PathItems: path}, &utils.NMSlice{&NMItem{
+ Path: strings.Split(path.String(), utils.NestingSep),
+ Data: "Value6",
+ Config: &FCTemplate{Tag: "NewBranchTest",
+ NewBranch: true},
+ }, &NMItem{
+ Path: strings.Split(path.String(), utils.NestingSep),
+ Data: "attrVal6",
+ Config: &FCTemplate{Tag: "AttributeTest",
+ AttributeID: "attribute6"},
+ }}); err != nil {
+ t.Error(err)
+ }
+
+ path = utils.PathItems{{Field: "Field4"}}
+ if _, err := nM.Set(&utils.FullPath{Path: path.String(), PathItems: path}, &utils.NMSlice{&NMItem{
+ Path: strings.Split(path.String(), utils.NestingSep),
+ Data: "Val4",
+ }, &NMItem{
+ Path: strings.Split(path.String(), utils.NestingSep),
+ Data: "attrVal2",
+ Config: &FCTemplate{Tag: "AttributeTest",
+ AttributeID: "attribute2"},
+ }}); err != nil {
+ t.Error(err)
+ }
+ eEv := map[string]interface{}{
+ "FirstLevel2.SecondLevel2.Field2": "Value2",
+ "FirstLevel.SecondLevel.ThirdLevel.Fld1": "Val1",
+ "FirstLevel2.Field3": "Value3",
+ "FirstLevel2.Field5": "Value5",
+ "FirstLevel2.Field6": "Value6",
+ "Field4": "Val4",
+ }
+ if cgrEv := NMAsCGREvent(nM, "cgrates.org",
+ utils.NestingSep); cgrEv.Tenant != "cgrates.org" ||
+ cgrEv.Time == nil ||
+ !reflect.DeepEqual(eEv, cgrEv.Event) {
+ t.Errorf("expecting: %+v, \nreceived: %+v", utils.ToJSON(eEv), utils.ToJSON(cgrEv.Event))
+ }
+}
+
+func TestNMItemLen(t *testing.T) {
+ var nm utils.NMInterface = &NMItem{Data: "1001"}
+ if rply := nm.Len(); rply != 0 {
+ t.Errorf("Expected 0 ,received: %v", rply)
+ }
+}
+
+func TestNMItemString(t *testing.T) {
+ var nm utils.NMInterface = &NMItem{Data: "1001"}
+ expected := "{\"Path\":null,\"Data\":\"1001\",\"Config\":null}"
+ if rply := nm.String(); rply != expected {
+ t.Errorf("Expected %q ,received: %q", expected, rply)
+ }
+}
+
+func TestNMItemInterface(t *testing.T) {
+ var nm utils.NMInterface = &NMItem{Data: "1001"}
+ expected := "1001"
+ if rply := nm.Interface(); rply != expected {
+ t.Errorf("Expected %q ,received: %q", expected, rply)
+ }
+}
+
+func TestNMItemField(t *testing.T) {
+ var nm utils.NMInterface = &NMItem{Data: "1001"}
+ if _, err := nm.Field(nil); err != utils.ErrNotImplemented {
+ t.Error(err)
+ }
+}
+
+func TestNMItemRemove(t *testing.T) {
+ var nm utils.NMInterface = &NMItem{Data: "1001"}
+ if err := nm.Remove(nil); err != utils.ErrNotImplemented {
+ t.Error(err)
+ }
+}
+
+func TestNMItemEmpty(t *testing.T) {
+ var nm utils.NMInterface = &NMItem{Data: "1001"}
+ if nm.Empty() {
+ t.Error("Expected not empty type")
+ }
+ nm = &NMItem{Data: nil}
+ if !nm.Empty() {
+ t.Error("Expected empty type")
+ }
+}
+
+func TestNMItemType(t *testing.T) {
+ var nm utils.NMInterface = &NMItem{Data: "1001"}
+ if nm.Type() != utils.NMDataType {
+ t.Errorf("Expected %v ,received: %v", utils.NMDataType, nm.Type())
+ }
+}
+
+func TestNMItemSet(t *testing.T) {
+ var nm utils.NMInterface = &NMItem{Data: "1001"}
+ if _, err := nm.Set(utils.PathItems{{}}, nil); err != utils.ErrWrongPath {
+ t.Error(err)
+ }
+ if _, err := nm.Set(nil, &NMItem{Data: "1002"}); err != nil {
+ t.Error(err)
+ }
+ expected := "1002"
+ if rply := nm.Interface(); rply != expected {
+ t.Errorf("Expected %q ,received: %q", expected, rply)
+ }
+}
diff --git a/engine/action.go b/engine/action.go
index 74bed805d..0ed3b4774 100644
--- a/engine/action.go
+++ b/engine/action.go
@@ -898,20 +898,20 @@ func newCdrLogProvider(acnt *Account, action *Action) (dP utils.DataProvider) {
return
}
-// cdrLogProvider implements engine.DataProvider so we can pass it to filters
+// cdrLogProvider implements utils.DataProvider so we can pass it to filters
type cdrLogProvider struct {
acnt *Account
action *Action
cache *config.NavigableMap
}
-// String is part of engine.DataProvider interface
+// String is part of utils.DataProvider interface
// when called, it will display the already parsed values out of cache
func (cdrP *cdrLogProvider) String() string {
return utils.ToJSON(cdrP)
}
-// FieldAsInterface is part of engine.DataProvider interface
+// FieldAsInterface is part of utils.DataProvider interface
func (cdrP *cdrLogProvider) FieldAsInterface(fldPath []string) (data interface{}, err error) {
if len(fldPath) != 1 {
return nil, utils.ErrNotFound
@@ -967,7 +967,7 @@ func (cdrP *cdrLogProvider) FieldAsInterface(fldPath []string) (data interface{}
return
}
-// FieldAsString is part of engine.DataProvider interface
+// FieldAsString is part of utils.DataProvider interface
func (cdrP *cdrLogProvider) FieldAsString(fldPath []string) (data string, err error) {
var valIface interface{}
valIface, err = cdrP.FieldAsInterface(fldPath)
@@ -977,7 +977,7 @@ func (cdrP *cdrLogProvider) FieldAsString(fldPath []string) (data string, err er
return utils.IfaceAsString(valIface), nil
}
-// RemoteHost is part of engine.DataProvider interface
+// RemoteHost is part of utils.DataProvider interface
func (cdrP *cdrLogProvider) RemoteHost() net.Addr {
return utils.LocalAddr()
}
diff --git a/general_tests/cdrs_onlexp_it_test.go b/general_tests/cdrs_onlexp_it_test.go
index 97ff9f16a..4e65cad1e 100644
--- a/general_tests/cdrs_onlexp_it_test.go
+++ b/general_tests/cdrs_onlexp_it_test.go
@@ -503,8 +503,8 @@ func testCDRsOnExpFileFailover(t *testing.T) {
t.Errorf("For file <%s> and event <%s> received %s", filePath, utils.ToJSON(ev), err)
}
}
- if !reflect.DeepEqual(expectedFormats.Data(), rcvFormats.Data()) {
- t.Errorf("Missing format expecting: %s received: %s", utils.ToJSON(expectedFormats.Data()), utils.ToJSON(rcvFormats.Data()))
+ if !reflect.DeepEqual(expectedFormats, rcvFormats) {
+ t.Errorf("Missing format expecting: %s received: %s", utils.ToJSON(expectedFormats), utils.ToJSON(rcvFormats))
}
}
diff --git a/loaders/libloader.go b/loaders/libloader.go
index 57632db41..1f06cd03b 100644
--- a/loaders/libloader.go
+++ b/loaders/libloader.go
@@ -89,20 +89,20 @@ func newCsvProvider(record []string, fileName string) (dP utils.DataProvider) {
return
}
-// csvProvider implements engine.DataProvider so we can pass it to filters
+// csvProvider implements utils.DataProvider so we can pass it to filters
type csvProvider struct {
req []string
fileName string
cache *config.NavigableMap
}
-// String is part of engine.DataProvider interface
+// String is part of utils.DataProvider interface
// when called, it will display the already parsed values out of cache
func (cP *csvProvider) String() string {
return utils.ToJSON(cP)
}
-// FieldAsInterface is part of engine.DataProvider interface
+// FieldAsInterface is part of utils.DataProvider interface
func (cP *csvProvider) FieldAsInterface(fldPath []string) (data interface{}, err error) {
if data, err = cP.cache.FieldAsInterface(fldPath); err == nil ||
err != utils.ErrNotFound { // item found in cache
@@ -129,7 +129,7 @@ func (cP *csvProvider) FieldAsInterface(fldPath []string) (data interface{}, err
return
}
-// FieldAsString is part of engine.DataProvider interface
+// FieldAsString is part of utils.DataProvider interface
func (cP *csvProvider) FieldAsString(fldPath []string) (data string, err error) {
var valIface interface{}
valIface, err = cP.FieldAsInterface(fldPath)
@@ -139,7 +139,7 @@ func (cP *csvProvider) FieldAsString(fldPath []string) (data string, err error)
return utils.IfaceAsString(valIface), nil
}
-// RemoteHost is part of engine.DataProvider interface
+// RemoteHost is part of utils.DataProvider interface
func (cP *csvProvider) RemoteHost() net.Addr {
return utils.LocalAddr()
}