diff --git a/config/cfgcdrfield.go b/config/cfgcdrfield.go
index 199d73fb7..50158a6bd 100644
--- a/config/cfgcdrfield.go
+++ b/config/cfgcdrfield.go
@@ -92,6 +92,9 @@ func NewCfgCdrFieldFromCdrFieldJsonCfg(jsnCfgFld *CdrFieldJsonCfg) (*CfgCdrField
if jsnCfgFld.Break_on_success != nil {
cfgFld.BreakOnSuccess = *jsnCfgFld.Break_on_success
}
+ if jsnCfgFld.New_branch != nil {
+ cfgFld.NewBranch = *jsnCfgFld.New_branch
+ }
return cfgFld, nil
}
@@ -116,6 +119,7 @@ type CfgCdrField struct {
MaskDestID string
MaskLen int
BreakOnSuccess bool
+ NewBranch bool
}
func CfgCdrFieldsFromCdrFieldsJsonCfg(jsnCfgFldss []*CdrFieldJsonCfg) ([]*CfgCdrField, error) {
diff --git a/config/libconfig_json.go b/config/libconfig_json.go
index 3ac001ed9..61bbf42e3 100755
--- a/config/libconfig_json.go
+++ b/config/libconfig_json.go
@@ -162,6 +162,7 @@ type CdrFieldJsonCfg struct {
Mask_destinationd_id *string
Mask_length *int
Break_on_success *bool
+ New_branch *bool
}
// Cdre config section
diff --git a/engine/navigablemap.go b/engine/navigablemap.go
index 18a2d285f..408a706aa 100644
--- a/engine/navigablemap.go
+++ b/engine/navigablemap.go
@@ -203,6 +203,9 @@ func (nM *NavigableMap) AsXMLElements() (ents []*XMLElement, err error) {
return nil, fmt.Errorf("value: %+v is not []*NMItem", val)
}
for _, nmItm := range nmItms {
+ if nmItm.Config != nil && nmItm.Config.NewBranch {
+ pathIdx = make(map[string]*XMLElement) // reset cache so we can start having other elements with same path
+ }
val, canCast := utils.CastFieldIfToString(nmItm.Data)
if !canCast {
return nil,
diff --git a/engine/navigablemap_test.go b/engine/navigablemap_test.go
index 151deb904..117a3b293 100644
--- a/engine/navigablemap_test.go
+++ b/engine/navigablemap_test.go
@@ -20,7 +20,6 @@ package engine
import (
"encoding/xml"
"errors"
- "fmt"
"reflect"
"strings"
"testing"
@@ -493,59 +492,6 @@ func TestNavMapString(t *testing.T) {
}
}
-func TestNavMapMarshalXML(t *testing.T) {
- nm := &NavigableMap{
- data: map[string]interface{}{
- "FirstLevel": map[string]interface{}{
- "SecondLevel": map[string]interface{}{
- "ThirdLevel": map[string]interface{}{
- "Fld1": []*NMItem{
- &NMItem{Path: []string{"FirstLevel", "SecondLevel", "ThirdLevel", "Fld1"},
- Data: "Val1"}},
- },
- },
- },
- "FistLever2": map[string]interface{}{
- "SecondLevel2": map[string]interface{}{
- "Field2": []*NMItem{
- &NMItem{Path: []string{"FistLever2", "SecondLevel2", "Field2"},
- Data: "attrVal1",
- Config: &config.CfgCdrField{Tag: "AttributeTest", AttributeID: "attribute1"}},
- &NMItem{Path: []string{"FistLever2", "SecondLevel2", "Field2"},
- Data: "Value2"}},
- },
- "Field3": []*NMItem{
- &NMItem{Path: []string{"FistLever2", "Field3"},
- Data: "Value3"}},
- "Field5": []*NMItem{
- &NMItem{Path: []string{"FistLever2", "Field5"},
- Data: "Value5"},
- &NMItem{Path: []string{"FistLever2", "Field5"},
- Data: "attrVal5",
- Config: &config.CfgCdrField{Tag: "AttributeTest", AttributeID: "attribute5"}}},
- },
- "Field4": []*NMItem{
- &NMItem{Path: []string{"Field4"},
- Data: "Val4"},
- &NMItem{Path: []string{"Field4"},
- Data: "attrVal2",
- Config: &config.CfgCdrField{Tag: "AttributeTest", AttributeID: "attribute2"}}},
- },
- order: [][]string{
- []string{"FistLever2", "SecondLevel2", "Field2"},
- []string{"FirstLevel", "SecondLevel", "ThirdLevel", "Fld1"},
- []string{"FistLever2", "Field3"},
- []string{"FistLever2", "Field5"},
- []string{"Field4"},
- },
- }
- if output, err := xml.MarshalIndent(nm, "", " "); err != nil {
- t.Error(err)
- } else if !reflect.DeepEqual([]byte(""), output) {
- fmt.Printf("%s\n", output)
- }
-}
-
func TestNavMapAsXMLElements(t *testing.T) {
nM := &NavigableMap{
data: map[string]interface{}{
@@ -576,6 +522,14 @@ func TestNavMapAsXMLElements(t *testing.T) {
&NMItem{Path: []string{"FirstLevel2", "Field5"},
Data: "attrVal5",
Config: &config.CfgCdrField{Tag: "AttributeTest", AttributeID: "attribute5"}}},
+ "Field6": []*NMItem{
+ &NMItem{Path: []string{"FirstLevel2", "Field6"},
+ Data: "Value6",
+ Config: &config.CfgCdrField{Tag: "NewBranchTest", NewBranch: true}},
+ &NMItem{Path: []string{"FirstLevel2", "Field6"},
+ Data: "attrVal6",
+ Config: &config.CfgCdrField{Tag: "AttributeTest", AttributeID: "attribute6"}},
+ },
},
"Field4": []*NMItem{
&NMItem{Path: []string{"Field4"},
@@ -590,6 +544,7 @@ func TestNavMapAsXMLElements(t *testing.T) {
[]string{"FirstLevel2", "Field3"},
[]string{"FirstLevel2", "Field5"},
[]string{"Field4"},
+ []string{"FirstLevel2", "Field6"},
},
}
eXMLElmnts := []*XMLElement{
@@ -656,6 +611,21 @@ func TestNavMapAsXMLElements(t *testing.T) {
},
Value: "Val4",
},
+ &XMLElement{
+ XMLName: xml.Name{Local: nM.order[5][0]},
+ Elements: []*XMLElement{
+ &XMLElement{
+ XMLName: xml.Name{Local: nM.order[5][1]},
+ Attributes: []*xml.Attr{
+ &xml.Attr{
+ Name: xml.Name{Local: "attribute6"},
+ Value: "attrVal6",
+ },
+ },
+ Value: "Value6",
+ },
+ },
+ },
}
xmlEnts, err := nM.AsXMLElements()
if err != nil {
@@ -677,10 +647,13 @@ func TestNavMapAsXMLElements(t *testing.T) {
-Val4`)
+Val4
+
+ Value6
+`)
if output, err := xml.MarshalIndent(xmlEnts, "", " "); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eXML, output) {
- fmt.Printf("expecting: \n%s, received: \n%s\n", string(eXML), string(output))
+ t.Errorf("expecting: \n%s, received: \n%s\n", string(eXML), string(output))
}
}