From 1582620ccd28600c62c330fb3a9cea2a352d8d6a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 20 Jul 2020 13:36:20 +0300 Subject: [PATCH] Added new dataconverter *string2hex --- agents/agentreq_test.go | 58 ++++++++++++++++++++++++++++++++ packages/debian/changelog | 5 +-- utils/consts.go | 1 + utils/dataconverter.go | 22 ++++++++++-- utils/dataconverter_test.go | 67 ++++++++++++++++++++++++++++++++++++- 5 files changed, 147 insertions(+), 6 deletions(-) diff --git a/agents/agentreq_test.go b/agents/agentreq_test.go index 9fe9aca34..3e494bf1d 100644 --- a/agents/agentreq_test.go +++ b/agents/agentreq_test.go @@ -1541,6 +1541,64 @@ func TestAgReqGroupType(t *testing.T) { } } +func TestAgReqSetFieldsIp2Hex(t *testing.T) { + cfg, _ := config.NewDefaultCGRConfig() + data := engine.NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil) + filterS := engine.NewFilterS(cfg, nil, dm) + agReq := NewAgentRequest(nil, nil, nil, nil, nil, "cgrates.org", "", filterS, nil, nil) + agReq.CGRRequest.Set(&utils.FullPath{Path: "IP", PathItems: utils.PathItems{{Field: "IP"}}}, utils.NewNMData("62.87.114.244")) + + tplFlds := []*config.FCTemplate{ + {Tag: "IP", + Path: utils.MetaVars + utils.NestingSep + "IP", Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("~*cgreq.IP{*ip2hex}", true, utils.INFIELD_SEP)}, + } + for _, v := range tplFlds { + v.ComputePath() + } + eMp := utils.NavigableMap2{} + eMp.Set(utils.PathItems{{Field: utils.NodeID}}, utils.NewNMData(config.CgrConfig().GeneralCfg().NodeID)) + eMp.Set(utils.PathItems{{Field: "IP"}}, &utils.NMSlice{ + &config.NMItem{Data: "0x3e5772f4", Path: []string{"IP"}, + Config: tplFlds[0]}}) + + if err := agReq.SetFields(tplFlds); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(agReq.Vars, eMp) { + t.Errorf("expecting: %+v,\n received: %+v", eMp, agReq.Vars) + } +} + +func TestAgReqSetFieldsString2Hex(t *testing.T) { + cfg, _ := config.NewDefaultCGRConfig() + data := engine.NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items) + dm := engine.NewDataManager(data, config.CgrConfig().CacheCfg(), nil) + filterS := engine.NewFilterS(cfg, nil, dm) + agReq := NewAgentRequest(nil, nil, nil, nil, nil, "cgrates.org", "", filterS, nil, nil) + agReq.CGRRequest.Set(&utils.FullPath{Path: "CustomField", PathItems: utils.PathItems{{Field: "CustomField"}}}, utils.NewNMData(string([]byte{0x94, 0x71, 0x02, 0x31, 0x01, 0x59}))) + + tplFlds := []*config.FCTemplate{ + {Tag: "CustomField", + Path: utils.MetaVars + utils.NestingSep + "CustomField", Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("~*cgreq.CustomField{*string2hex}", true, utils.INFIELD_SEP)}, + } + for _, v := range tplFlds { + v.ComputePath() + } + eMp := utils.NavigableMap2{} + eMp.Set(utils.PathItems{{Field: utils.NodeID}}, utils.NewNMData(config.CgrConfig().GeneralCfg().NodeID)) + eMp.Set(utils.PathItems{{Field: "CustomField"}}, &utils.NMSlice{ + &config.NMItem{Data: "0x947102310159", Path: []string{"CustomField"}, + Config: tplFlds[0]}}) + + if err := agReq.SetFields(tplFlds); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(agReq.Vars, eMp) { + t.Errorf("expecting: %+v,\n received: %+v", eMp, agReq.Vars) + } +} + func TestAgReqFiltersInsideField(t *testing.T) { //simulate the diameter request m := diam.NewRequest(diam.CreditControl, 4, nil) diff --git a/packages/debian/changelog b/packages/debian/changelog index 8cfcd688f..e84a95d03 100644 --- a/packages/debian/changelog +++ b/packages/debian/changelog @@ -23,8 +23,8 @@ cgrates (0.10.1) UNRELEASED; urgency=medium * [DiameterAgent] Using String function from diam.Message instead of ToJSON for request String method * [DiameterAgent] Updated 3gp_vendor dictionary - * [Templates] Added new dataconvertor: *ip2hex - * [AgentRequest] Added support for *group type and correctly overwrite + * [Templates] Added new dataconverter: *ip2hex + * [AgentS] Added support for *group type and correctly overwrite the values in case of *variable * [ERs] Correctly populate ConcurrentRequest from config in EventReader @@ -45,6 +45,7 @@ cgrates (0.10.1) UNRELEASED; urgency=medium * [CacheS] Avoid long recaching * [SessionS] Use correctly SessionTTLUsage when calculate end usage in case of terminate session from ttl mechanism * [SessionS] Add SessionTLLLastUsage as option for an extra debit in case of ttl mechanism + * [Templates] Added new dataconverter: *string2hex -- DanB Wed, 5 May 2020 15:22:59 +0200 diff --git a/utils/consts.go b/utils/consts.go index 3972ba9f3..587581d45 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -589,6 +589,7 @@ const ( MetaDuration = "*duration" MetaLibPhoneNumber = "*libphonenumber" MetaIP2Hex = "*ip2hex" + MetaString2Hex = "*string2hex" MetaReload = "*reload" MetaLoad = "*load" MetaRemove = "*remove" diff --git a/utils/dataconverter.go b/utils/dataconverter.go index 5543d181b..0b7322762 100644 --- a/utils/dataconverter.go +++ b/utils/dataconverter.go @@ -74,7 +74,9 @@ func NewDataConverter(params string) (conv DataConverter, err error) { case params == MetaDuration: return NewDurationConverter("") case params == MetaIP2Hex: - return &IP2HexConvertor{}, nil + return new(IP2HexConverter), nil + case params == MetaString2Hex: + return new(String2HexConverter), nil case strings.HasPrefix(params, MetaLibPhoneNumber): if len(params) == len(MetaLibPhoneNumber) { return NewPhoneNumberConverter("") @@ -279,9 +281,9 @@ func (lc *PhoneNumberConverter) Convert(in interface{}) (out interface{}, err er } // HexConvertor will round floats -type IP2HexConvertor struct{} +type IP2HexConverter struct{} -func (_ *IP2HexConvertor) Convert(in interface{}) (out interface{}, err error) { +func (_ *IP2HexConverter) Convert(in interface{}) (out interface{}, err error) { var ip net.IP switch val := in.(type) { case string: @@ -299,3 +301,17 @@ func (_ *IP2HexConvertor) Convert(in interface{}) (out interface{}, err error) { } return "0x" + string([]byte(hx)[len(hx)-8:]), nil } + +// String2HexConverter will transform the string to hex +type String2HexConverter struct{} + +// Convert implements DataConverter interface +func (*String2HexConverter) Convert(in interface{}) (o interface{}, err error) { + var out string + if out = hex.EncodeToString([]byte(IfaceAsString(in))); len(out) == 0 { + o = out + return + } + o = "0x" + out + return +} diff --git a/utils/dataconverter_test.go b/utils/dataconverter_test.go index 3ae1542e9..10d2ffa5e 100644 --- a/utils/dataconverter_test.go +++ b/utils/dataconverter_test.go @@ -142,6 +142,14 @@ func TestNewDataConverter(t *testing.T) { if _, err := NewDataConverter("unsupported"); err == nil || err.Error() != "unsupported converter definition: " { } + hex, err := NewDataConverter(MetaString2Hex) + if err != nil { + t.Error(err) + } + exp := new(String2HexConverter) + if !reflect.DeepEqual(hex, exp) { + t.Errorf("Expected %+v received: %+v", exp, hex) + } } func TestNewDataConverterMustCompile(t *testing.T) { @@ -614,7 +622,7 @@ func TestPhoneNumberConverter(t *testing.T) { } func TestHexConvertor(t *testing.T) { - hx := IP2HexConvertor{} + hx := IP2HexConverter{} val := "127.0.0.1" expected := "0x7f000001" if rpl, err := hx.Convert(val); err != nil { @@ -628,4 +636,61 @@ func TestHexConvertor(t *testing.T) { } else if !reflect.DeepEqual(expected, rpl) { t.Errorf("expecting: %+v, received: %+v", expected, rpl) } + + val3 := []byte("127.0.0.1") + if rpl, err := hx.Convert(val3); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expected, rpl) { + t.Errorf("expecting: %+v, received: %+v", expected, rpl) + } + + val = "" + expected = "" + if rpl, err := hx.Convert(val); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expected, rpl) { + t.Errorf("expecting: %+v, received: %+v", expected, rpl) + } + + val = "62.87.114.244" + expected = "0x3e5772f4" + if rpl, err := hx.Convert(val); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expected, rpl) { + t.Errorf("expecting: %+v, received: %+v", expected, rpl) + } +} + +func TestStringHexConvertor(t *testing.T) { + hx := new(String2HexConverter) + val := "127.0.0.1" + expected := "0x3132372e302e302e31" + if rpl, err := hx.Convert(val); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expected, rpl) { + t.Errorf("expecting: %+v, received: %+v", expected, rpl) + } + + val3 := []byte("127.0.0.1") + if rpl, err := hx.Convert(val3); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expected, rpl) { + t.Errorf("expecting: %+v, received: %+v", expected, rpl) + } + + val = "" + expected = "" + if rpl, err := hx.Convert(val); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expected, rpl) { + t.Errorf("expecting: %+v, received: %+v", expected, rpl) + } + + val3 = []byte{0x94, 0x71, 0x02, 0x31, 0x01, 0x59} + expected = "0x947102310159" + if rpl, err := hx.Convert(val3); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expected, rpl) { + t.Errorf("expecting: %+v, received: %+v", expected, rpl) + } }