From cd7119c1effad1fd9cf911d5795db1cc9644aece Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 1 Jul 2021 12:31:45 +0300 Subject: [PATCH] Added *sipcid field type --- agents/agentreq.go | 11 +++++ agents/agentreq_test.go | 42 +++++++++++++++++ engine/attributes.go | 10 +++++ engine/attributes_test.go | 95 +++++++++++++++++++++++++++++++++++++++ utils/consts.go | 1 + 5 files changed, 159 insertions(+) diff --git a/agents/agentreq.go b/agents/agentreq.go index 8f5268be7..440d7deb8 100644 --- a/agents/agentreq.go +++ b/agents/agentreq.go @@ -22,6 +22,7 @@ import ( "fmt" "math" "net" + "sort" "strconv" "strings" "time" @@ -429,6 +430,16 @@ func (ar *AgentRequest) ParseField( return nil, err } out = strconv.Itoa(int(t.Unix())) + case utils.MetaSIPCID: + isString = true + values := make([]string, len(cfgFld.Value)) + for i, val := range cfgFld.Value { + if values[i], err = val.ParseDataProvider(ar, utils.NestingSep); err != nil { + return nil, err + } + } + sort.Strings(values[1:]) + out = strings.Join(values, utils.INFIELD_SEP) } if err != nil && diff --git a/agents/agentreq_test.go b/agents/agentreq_test.go index 3e494bf1d..014dd7b17 100644 --- a/agents/agentreq_test.go +++ b/agents/agentreq_test.go @@ -1734,3 +1734,45 @@ func BenchmarkAgReqSetField(b *testing.B) { } } } + +func TestAgReqSetFieldsSIPCID(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: "cid", PathItems: utils.PathItems{{Field: "cid"}}}, utils.NewNMData("12345")) + agReq.CGRRequest.Set(&utils.FullPath{Path: "to", PathItems: utils.PathItems{{Field: "to"}}}, utils.NewNMData("1001")) + agReq.CGRRequest.Set(&utils.FullPath{Path: "from", PathItems: utils.PathItems{{Field: "from"}}}, utils.NewNMData("1002")) + + tplFlds := []*config.FCTemplate{ + {Tag: "OriginID", + Path: utils.MetaVars + utils.NestingSep + "OriginID", Type: utils.MetaSIPCID, + Value: config.NewRSRParsersMustCompile("~*cgreq.cid;~*cgreq.to;~*cgreq.from", 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: "OriginID"}}, &utils.NMSlice{ + &config.NMItem{Data: "12345;1001;1002", Path: []string{"OriginID"}, + 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) + } + + agReq = NewAgentRequest(nil, nil, nil, nil, nil, "cgrates.org", "", filterS, nil, nil) + agReq.CGRRequest.Set(&utils.FullPath{Path: "cid", PathItems: utils.PathItems{{Field: "cid"}}}, utils.NewNMData("12345")) + agReq.CGRRequest.Set(&utils.FullPath{Path: "to", PathItems: utils.PathItems{{Field: "to"}}}, utils.NewNMData("1002")) + agReq.CGRRequest.Set(&utils.FullPath{Path: "from", PathItems: utils.PathItems{{Field: "from"}}}, utils.NewNMData("1001")) + + 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) + } +} diff --git a/engine/attributes.go b/engine/attributes.go index 600a4a154..0cabe01f2 100644 --- a/engine/attributes.go +++ b/engine/attributes.go @@ -21,6 +21,7 @@ package engine import ( "fmt" "math" + "sort" "strconv" "strings" @@ -246,6 +247,15 @@ func (alS *AttributeService) processEvent(args *AttrArgsProcessEvent) ( } substitute = strconv.FormatFloat(utils.Round(val*math.Pow10(exp), config.CgrConfig().GeneralCfg().RoundingDecimals, utils.ROUNDING_MIDDLE), 'f', -1, 64) + case utils.MetaSIPCID: + values := make([]string, len(attribute.Value)) + for i, val := range attribute.Value { + if values[i], err = val.ParseDataProvider(evNm, utils.NestingSep); err != nil { + return nil, err + } + } + sort.Strings(values[1:]) + substitute = strings.Join(values, utils.INFIELD_SEP) default: // backwards compatible in case that Type is empty substitute, err = attribute.Value.ParseDataProvider(evNm, utils.NestingSep) } diff --git a/engine/attributes_test.go b/engine/attributes_test.go index ecca46bd2..01cf67d81 100644 --- a/engine/attributes_test.go +++ b/engine/attributes_test.go @@ -1852,3 +1852,98 @@ func TestGetAttributeProfileFromInline(t *testing.T) { t.Errorf("Expecting %+v, received: %+v", utils.ToJSON(expAttrPrf1), utils.ToJSON(attr)) } } + +func TestAttributesProcessEventSIPCID(t *testing.T) { + //refresh the DM + if err := dmAtr.DataDB().Flush(""); err != nil { + t.Error(err) + } + Cache.Clear(nil) + if test, err := dmAtr.DataDB().IsDBEmpty(); err != nil { + t.Error(err) + } else if test != true { + t.Errorf("\nExpecting: true got :%+v", test) + } + attrPrf1 := &AttributeProfile{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: "ATTR_1", + Contexts: []string{utils.MetaSessionS}, + Attributes: []*Attribute{ + { + Path: utils.MetaReq + utils.NestingSep + "OriginID", + Type: utils.MetaSIPCID, + Value: config.NewRSRParsersMustCompile("~*req.cid;~*req.to;~*req.from", true, utils.INFIELD_SEP), + }, + }, + Blocker: true, + Weight: 10, + } + // Add attribute in DM + if err := dmAtr.SetAttributeProfile(attrPrf1, true); err != nil { + t.Error(err) + } + attrArgs := &AttrArgsProcessEvent{ + Context: utils.StringPointer(utils.MetaSessionS), + ProcessRuns: utils.IntPointer(1), + CGREvent: &utils.CGREvent{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: utils.GenUUID(), + Event: map[string]interface{}{ + "cid": "12345", + "to": "1001", + "from": "1002", + }, + }, + } + eRply := &AttrSProcessEventReply{ + MatchedProfiles: []string{"ATTR_1"}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + "OriginID"}, + CGREvent: &utils.CGREvent{ + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, + ID: utils.GenUUID(), + Event: map[string]interface{}{ + "cid": "12345", + "to": "1001", + "from": "1002", + "OriginID": "12345;1001;1002", + }, + }, + } + var reply AttrSProcessEventReply + if err := attrService.V1ProcessEvent(attrArgs, &reply); err != nil { + t.Errorf("Error: %+v", err) + } + if !reflect.DeepEqual(eRply.MatchedProfiles, reply.MatchedProfiles) { + t.Errorf("Expecting %+v, received: %+v", eRply.MatchedProfiles, reply.MatchedProfiles) + } + if !reflect.DeepEqual(eRply.AlteredFields, reply.AlteredFields) { + t.Errorf("Expecting %+v, received: %+v", eRply.AlteredFields, reply.AlteredFields) + } + if !reflect.DeepEqual(eRply.CGREvent.Event, reply.CGREvent.Event) { + t.Errorf("Expecting %+v, received: %+v", eRply.CGREvent.Event, reply.CGREvent.Event) + } + + attrArgs.CGREvent.Event = map[string]interface{}{ + "cid": "12345", + "to": "1002", + "from": "1001", + } + eRply.CGREvent.Event = map[string]interface{}{ + "cid": "12345", + "to": "1002", + "from": "1001", + "OriginID": "12345;1001;1002", + } + if err := attrService.V1ProcessEvent(attrArgs, &reply); err != nil { + t.Errorf("Error: %+v", err) + } + if !reflect.DeepEqual(eRply.MatchedProfiles, reply.MatchedProfiles) { + t.Errorf("Expecting %+v, received: %+v", eRply.MatchedProfiles, reply.MatchedProfiles) + } + if !reflect.DeepEqual(eRply.AlteredFields, reply.AlteredFields) { + t.Errorf("Expecting %+v, received: %+v", eRply.AlteredFields, reply.AlteredFields) + } + if !reflect.DeepEqual(eRply.CGREvent.Event, reply.CGREvent.Event) { + t.Errorf("Expecting %+v, received: %+v", eRply.CGREvent.Event, reply.CGREvent.Event) + } +} diff --git a/utils/consts.go b/utils/consts.go index 2c3ef9690..7adf5f5ec 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -309,6 +309,7 @@ const ( HIERARCHY_SEP = ">" META_COMPOSED = "*composed" META_USAGE_DIFFERENCE = "*usage_difference" + MetaSIPCID = "*sipcid" MetaDifference = "*difference" MetaVariable = "*variable" MetaCCUsage = "*cc_usage"