From 6764260be49cc354ab2be2755a1f484507a65486 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 15 Jan 2020 18:06:45 +0200 Subject: [PATCH 01/14] Added *req as requirement fro attributes FieldName --- config/navigablemap.go | 36 +++++++++ engine/attributes.go | 42 +++++++---- engine/attributes_test.go | 141 +++++++++++++++++++---------------- engine/libattributes_test.go | 12 +-- engine/libtest.go | 4 +- engine/loader_csv_test.go | 4 +- engine/model_helpers_test.go | 14 ++-- engine/onstor_it_test.go | 8 +- migrator/alias.go | 2 +- migrator/derived_chargers.go | 2 +- migrator/user.go | 4 +- 11 files changed, 164 insertions(+), 105 deletions(-) diff --git a/config/navigablemap.go b/config/navigablemap.go index 30ed581c4..9d3125349 100644 --- a/config/navigablemap.go +++ b/config/navigablemap.go @@ -524,3 +524,39 @@ func (nM *NavigableMap) GetKeys() (keys []string) { } return } + +// Remove will remove the items from the given path +func (nM *NavigableMap) Remove(path []string) { + // if ordered { + // nM.order = append(nM.order, path) + // } + mp := nM.data + for i, spath := range path { + oData, has := mp[spath] + if !has { // no need to remove + return + } + if i == len(path)-1 { // last path + delete(mp, spath) + return + } + defer func(np map[string]interface{}, p string) { + o, has := np[p] + if !has { + return + } + if o == nil { + delete(np, p) + return + } + v, ok := o.(map[string]interface{}) + if !ok { + return + } + if len(v) == 0 { + delete(np, p) + } + }(mp, spath) + mp = oData.(map[string]interface{}) // so we can check further down + } +} diff --git a/engine/attributes.go b/engine/attributes.go index 6078256fd..ad6ef3630 100644 --- a/engine/attributes.go +++ b/engine/attributes.go @@ -22,6 +22,7 @@ import ( "fmt" "math" "strconv" + "strings" "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/utils" @@ -166,10 +167,9 @@ func (alS *AttributeService) processEvent(args *AttrArgsProcessEvent) ( } rply = &AttrSProcessEventReply{ MatchedProfiles: []string{attrPrf.ID}, - CGREvent: args.Clone(), + CGREvent: args.Clone(), // do not need to coppy the event blocker: attrPrf.Blocker} - evNm := config.NewNavigableMap(nil) - evNm.Set([]string{utils.MetaReq}, args.Event, false, false) + evNm := config.NewNavigableMap(map[string]interface{}{utils.MetaReq: args.Event}) for _, attribute := range attrPrf.Attributes { //in case that we have filter for attribute send them to FilterS to be processed if len(attribute.FilterIDs) != 0 { @@ -186,16 +186,16 @@ func (alS *AttributeService) processEvent(args *AttrArgsProcessEvent) ( case utils.META_CONSTANT: substitute, err = attribute.Value.ParseValue(utils.EmptyString) case utils.MetaVariable, utils.META_COMPOSED: - substitute, err = attribute.Value.ParseEvent(args.Event) + substitute, err = attribute.Value.ParseDataProvider(evNm, utils.NestingSep) case utils.META_USAGE_DIFFERENCE: if len(attribute.Value) != 2 { return nil, fmt.Errorf("invalid arguments <%s>", utils.ToJSON(attribute.Value)) } - strVal1, err := attribute.Value[0].ParseEvent(args.Event) + strVal1, err := attribute.Value[0].ParseDataProvider(evNm, utils.NestingSep) if err != nil { return nil, err } - strVal2, err := attribute.Value[1].ParseEvent(args.Event) + strVal2, err := attribute.Value[1].ParseDataProvider(evNm, utils.NestingSep) if err != nil { return nil, err } @@ -211,7 +211,7 @@ func (alS *AttributeService) processEvent(args *AttrArgsProcessEvent) ( case utils.MetaSum: iFaceVals := make([]interface{}, len(attribute.Value)) for i, val := range attribute.Value { - strVal, err := val.ParseEvent(args.Event) + strVal, err := val.ParseDataProvider(evNm, utils.NestingSep) if err != nil { return nil, err } @@ -227,7 +227,7 @@ func (alS *AttributeService) processEvent(args *AttrArgsProcessEvent) ( return nil, fmt.Errorf("invalid arguments <%s> to %s", utils.ToJSON(attribute.Value), utils.MetaValueExponent) } - strVal1, err := attribute.Value[0].ParseEvent(args.Event) // String Value + strVal1, err := attribute.Value[0].ParseDataProvider(evNm, utils.NestingSep) // String Value if err != nil { return nil, err } @@ -236,7 +236,7 @@ func (alS *AttributeService) processEvent(args *AttrArgsProcessEvent) ( return nil, fmt.Errorf("invalid value <%s> to %s", strVal1, utils.MetaValueExponent) } - strVal2, err := attribute.Value[1].ParseEvent(args.Event) // String Exponent + strVal2, err := attribute.Value[1].ParseDataProvider(evNm, utils.NestingSep) // String Exponent if err != nil { return nil, err } @@ -247,7 +247,7 @@ 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) default: // backwards compatible in case that Type is empty - substitute, err = attribute.Value.ParseEvent(args.Event) + substitute, err = attribute.Value.ParseDataProvider(evNm, utils.NestingSep) } if err != nil { @@ -258,14 +258,28 @@ func (alS *AttributeService) processEvent(args *AttrArgsProcessEvent) ( rply.AlteredFields = append(rply.AlteredFields, attribute.FieldName) } if substitute == utils.MetaRemove { - delete(rply.CGREvent.Event, attribute.FieldName) + evNm.Remove(strings.Split(attribute.FieldName, utils.NestingSep)) continue } if attribute.Type == utils.META_COMPOSED { - substitute = utils.IfaceAsString(rply.CGREvent.Event[attribute.FieldName]) + substitute + var val string + val, err = evNm.FieldAsString(strings.Split(attribute.FieldName, utils.NestingSep)) + substitute = val + substitute } - rply.CGREvent.Event[attribute.FieldName] = substitute - + evNm.Set(strings.Split(attribute.FieldName, utils.NestingSep), substitute, false, false) + } + var ev interface{} + ev, err = evNm.FieldAsInterface([]string{utils.MetaReq}) + if err != nil { + if err.Error() == utils.ErrNotFound.Error() { + rply.CGREvent.Event = make(map[string]interface{}) + return + } + return nil, err + } + var ok bool + if rply.CGREvent.Event, ok = ev.(map[string]interface{}); !ok { + return nil, fmt.Errorf("invalid event") } return } diff --git a/engine/attributes_test.go b/engine/attributes_test.go index d7d88ca43..e699cc5e4 100644 --- a/engine/attributes_test.go +++ b/engine/attributes_test.go @@ -87,7 +87,7 @@ var ( }, Attributes: []*Attribute{ { - FieldName: utils.Account, + FieldName: utils.MetaReq + utils.NestingSep + utils.Account, Value: config.NewRSRParsersMustCompile("1010", true, utils.INFIELD_SEP), }, }, @@ -104,7 +104,7 @@ var ( }, Attributes: []*Attribute{ { - FieldName: utils.Account, + FieldName: utils.MetaReq + utils.NestingSep + utils.Account, Value: config.NewRSRParsersMustCompile("1010", true, utils.INFIELD_SEP), }, }, @@ -121,7 +121,7 @@ var ( }, Attributes: []*Attribute{ { - FieldName: utils.Account, + FieldName: utils.MetaReq + utils.NestingSep + utils.Account, Value: config.NewRSRParsersMustCompile("1010", true, utils.INFIELD_SEP), }, }, @@ -138,7 +138,7 @@ var ( }, Attributes: []*Attribute{ { - FieldName: utils.Account, + FieldName: utils.MetaReq + utils.NestingSep + utils.Account, Value: config.NewRSRParsersMustCompile("1010", true, utils.INFIELD_SEP), }, }, @@ -269,7 +269,7 @@ func TestAttributeProcessEvent(t *testing.T) { attrEvs[0].CGREvent.Event["Account"] = "1010" //Field added in event after process eRply := &AttrSProcessEventReply{ MatchedProfiles: []string{"AttributeProfile1"}, - AlteredFields: []string{"Account"}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + "Account"}, CGREvent: attrEvs[0].CGREvent, } atrp, err := attrService.processEvent(attrEvs[0]) @@ -293,7 +293,7 @@ func TestAttributeProcessEventWithIDs(t *testing.T) { attrEvs[3].AttributeIDs = []string{"AttributeIDMatch"} eRply := &AttrSProcessEventReply{ MatchedProfiles: []string{"AttributeIDMatch"}, - AlteredFields: []string{"Account"}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + "Account"}, CGREvent: attrEvs[3].CGREvent, } if atrp, err := attrService.processEvent(attrEvs[3]); err != nil { @@ -406,7 +406,7 @@ func TestAttributeIndexer(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.Account, + FieldName: utils.MetaReq + utils.NestingSep + utils.Account, Value: config.NewRSRParsersMustCompile("1010", true, utils.INFIELD_SEP), }, }, @@ -474,7 +474,7 @@ func TestAttributeProcessWithMultipleRuns1(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field1", + FieldName: utils.MetaReq + utils.NestingSep + "Field1", Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, @@ -490,7 +490,7 @@ func TestAttributeProcessWithMultipleRuns1(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), }, }, @@ -506,7 +506,7 @@ func TestAttributeProcessWithMultipleRuns1(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field3", + FieldName: utils.MetaReq + utils.NestingSep + "Field3", Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), }, }, @@ -535,7 +535,11 @@ func TestAttributeProcessWithMultipleRuns1(t *testing.T) { } eRply := &AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1", "ATTR_2", "ATTR_3"}, - AlteredFields: []string{"Field1", "Field2", "Field3"}, + AlteredFields: []string{ + utils.MetaReq + utils.NestingSep + "Field1", + utils.MetaReq + utils.NestingSep + "Field2", + utils.MetaReq + utils.NestingSep + "Field3", + }, CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -552,7 +556,7 @@ func TestAttributeProcessWithMultipleRuns1(t *testing.T) { t.Errorf("Error: %+v", err) } if !reflect.DeepEqual(eRply.MatchedProfiles, reply.MatchedProfiles) { - t.Errorf("Expecting %+v, received: %+v", eRply.MatchedProfiles, reply.MatchedProfiles) + t.Fatalf("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) @@ -582,7 +586,7 @@ func TestAttributeProcessWithMultipleRuns2(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field1", + FieldName: utils.MetaReq + utils.NestingSep + "Field1", Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, @@ -598,7 +602,7 @@ func TestAttributeProcessWithMultipleRuns2(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), }, }, @@ -614,7 +618,7 @@ func TestAttributeProcessWithMultipleRuns2(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field3", + FieldName: utils.MetaReq + utils.NestingSep + "Field3", Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), }, }, @@ -643,7 +647,8 @@ func TestAttributeProcessWithMultipleRuns2(t *testing.T) { } eRply := &AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1", "ATTR_2"}, - AlteredFields: []string{"Field1", "Field2"}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + "Field1", + utils.MetaReq + utils.NestingSep + "Field2"}, CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -689,7 +694,7 @@ func TestAttributeProcessWithMultipleRuns3(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field1", + FieldName: utils.MetaReq + utils.NestingSep + "Field1", Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, @@ -705,7 +710,7 @@ func TestAttributeProcessWithMultipleRuns3(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), }, }, @@ -721,7 +726,7 @@ func TestAttributeProcessWithMultipleRuns3(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field3", + FieldName: utils.MetaReq + utils.NestingSep + "Field3", Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), }, }, @@ -750,7 +755,8 @@ func TestAttributeProcessWithMultipleRuns3(t *testing.T) { } eRply := &AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1", "ATTR_2"}, - AlteredFields: []string{"Field1", "Field2"}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + "Field1", + utils.MetaReq + utils.NestingSep + "Field2"}, CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -796,7 +802,7 @@ func TestAttributeProcessWithMultipleRuns4(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field1", + FieldName: utils.MetaReq + utils.NestingSep + "Field1", Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, @@ -812,7 +818,7 @@ func TestAttributeProcessWithMultipleRuns4(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), }, }, @@ -838,7 +844,8 @@ func TestAttributeProcessWithMultipleRuns4(t *testing.T) { } eRply := &AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1", "ATTR_2"}, - AlteredFields: []string{"Field1", "Field2"}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + "Field1", + utils.MetaReq + utils.NestingSep + "Field2"}, CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -886,7 +893,7 @@ func TestAttributeMultipleProcessWithBlocker(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field1", + FieldName: utils.MetaReq + utils.NestingSep + "Field1", Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, @@ -902,7 +909,7 @@ func TestAttributeMultipleProcessWithBlocker(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), }, }, @@ -919,7 +926,7 @@ func TestAttributeMultipleProcessWithBlocker(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field3", + FieldName: utils.MetaReq + utils.NestingSep + "Field3", Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), }, }, @@ -948,7 +955,8 @@ func TestAttributeMultipleProcessWithBlocker(t *testing.T) { } eRply := &AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1", "ATTR_2"}, - AlteredFields: []string{"Field1", "Field2"}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + "Field1", + utils.MetaReq + utils.NestingSep + "Field2"}, CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -995,7 +1003,7 @@ func TestAttributeMultipleProcessWithBlocker2(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field1", + FieldName: utils.MetaReq + utils.NestingSep + "Field1", Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, @@ -1012,7 +1020,7 @@ func TestAttributeMultipleProcessWithBlocker2(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), }, }, @@ -1028,7 +1036,7 @@ func TestAttributeMultipleProcessWithBlocker2(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field3", + FieldName: utils.MetaReq + utils.NestingSep + "Field3", Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), }, }, @@ -1057,7 +1065,7 @@ func TestAttributeMultipleProcessWithBlocker2(t *testing.T) { } eRply := &AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1"}, - AlteredFields: []string{"Field1"}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + "Field1"}, CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1103,8 +1111,8 @@ func TestAttributeProcessValue(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field2", - Value: config.NewRSRParsersMustCompile("~Field1", true, utils.INFIELD_SEP), + FieldName: utils.MetaReq + utils.NestingSep + "Field2", + Value: config.NewRSRParsersMustCompile("~*req.Field1", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -1127,7 +1135,7 @@ func TestAttributeProcessValue(t *testing.T) { } eRply := &AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1"}, - AlteredFields: []string{"Field2"}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + "Field2"}, CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1173,17 +1181,17 @@ func TestAttributeAttributeFilterIDs(t *testing.T) { Attributes: []*Attribute{ { FilterIDs: []string{"*string:~*req.PassField:Test"}, - FieldName: "PassField", + FieldName: utils.MetaReq + utils.NestingSep + "PassField", Value: config.NewRSRParsersMustCompile("Pass", true, utils.INFIELD_SEP), }, { FilterIDs: []string{"*string:~*req.PassField:RandomValue"}, - FieldName: "NotPassField", + FieldName: utils.MetaReq + utils.NestingSep + "NotPassField", Value: config.NewRSRParsersMustCompile("NotPass", true, utils.INFIELD_SEP), }, { FilterIDs: []string{"*notexists:~*req.RandomField:"}, - FieldName: "RandomField", + FieldName: utils.MetaReq + utils.NestingSep + "RandomField", Value: config.NewRSRParsersMustCompile("RandomValue", true, utils.INFIELD_SEP), }, }, @@ -1206,7 +1214,8 @@ func TestAttributeAttributeFilterIDs(t *testing.T) { } eRply := &AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1"}, - AlteredFields: []string{"PassField", "RandomField"}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + "PassField", + utils.MetaReq + utils.NestingSep + "RandomField"}, CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1252,7 +1261,7 @@ func TestAttributeProcessEventConstant(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.META_CONSTANT, Value: config.NewRSRParsersMustCompile("ConstVal", true, utils.INFIELD_SEP), }, @@ -1277,7 +1286,7 @@ func TestAttributeProcessEventConstant(t *testing.T) { } eRply := &AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1"}, - AlteredFields: []string{"Field2"}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + "Field2"}, CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1323,14 +1332,14 @@ func TestAttributeProcessEventVariable(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~Field1", true, utils.INFIELD_SEP), + Value: config.NewRSRParsersMustCompile("~*req.Field1", true, utils.INFIELD_SEP), }, { - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~TheField", true, utils.INFIELD_SEP), + Value: config.NewRSRParsersMustCompile("~*req.TheField", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -1354,7 +1363,7 @@ func TestAttributeProcessEventVariable(t *testing.T) { } eRply := &AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1"}, - AlteredFields: []string{"Field2"}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + "Field2"}, CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1401,19 +1410,19 @@ func TestAttributeProcessEventComposed(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.META_COMPOSED, - Value: config.NewRSRParsersMustCompile("~Field1", true, utils.INFIELD_SEP), + Value: config.NewRSRParsersMustCompile("~*req.Field1", true, utils.INFIELD_SEP), }, { - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.META_COMPOSED, Value: config.NewRSRParsersMustCompile("_", true, utils.INFIELD_SEP), }, { - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.META_COMPOSED, - Value: config.NewRSRParsersMustCompile("~TheField", true, utils.INFIELD_SEP), + Value: config.NewRSRParsersMustCompile("~*req.TheField", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -1437,7 +1446,7 @@ func TestAttributeProcessEventComposed(t *testing.T) { } eRply := &AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1"}, - AlteredFields: []string{"Field2"}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + "Field2"}, CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1484,9 +1493,9 @@ func TestAttributeProcessEventSum(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.MetaSum, - Value: config.NewRSRParsersMustCompile("10;~NumField;20", true, utils.INFIELD_SEP), + Value: config.NewRSRParsersMustCompile("10;~*req.NumField;20", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -1511,7 +1520,7 @@ func TestAttributeProcessEventSum(t *testing.T) { } eRply := &AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1"}, - AlteredFields: []string{"Field2"}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + "Field2"}, CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1559,9 +1568,9 @@ func TestAttributeProcessEventUsageDifference(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.META_USAGE_DIFFERENCE, - Value: config.NewRSRParsersMustCompile("~UnixTimeStamp;~UnixTimeStamp2", true, utils.INFIELD_SEP), + Value: config.NewRSRParsersMustCompile("~*req.UnixTimeStamp;~*req.UnixTimeStamp2", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -1587,7 +1596,7 @@ func TestAttributeProcessEventUsageDifference(t *testing.T) { } eRply := &AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1"}, - AlteredFields: []string{"Field2"}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + "Field2"}, CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1636,9 +1645,9 @@ func TestAttributeProcessEventValueExponent(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.MetaValueExponent, - Value: config.NewRSRParsersMustCompile("~Multiplier;~Pow", true, utils.INFIELD_SEP), + Value: config.NewRSRParsersMustCompile("~*req.Multiplier;~*req.Pow", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -1664,7 +1673,7 @@ func TestAttributeProcessEventValueExponent(t *testing.T) { } eRply := &AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1"}, - AlteredFields: []string{"Field2"}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + "Field2"}, CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1721,7 +1730,7 @@ func BenchmarkAttributeProcessEventConstant(b *testing.B) { }, Attributes: []*Attribute{ { - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.META_CONSTANT, Value: config.NewRSRParsersMustCompile("ConstVal", true, utils.INFIELD_SEP), }, @@ -1782,9 +1791,9 @@ func BenchmarkAttributeProcessEventVariable(b *testing.B) { }, Attributes: []*Attribute{ { - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~Field1", true, utils.INFIELD_SEP), + Value: config.NewRSRParsersMustCompile("~*req.Field1", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -1825,15 +1834,15 @@ func TestGetAttributeProfileFromInline(t *testing.T) { } else if test != true { t.Errorf("\nExpecting: true got :%+v", test) } - attrID := "*sum:Field2:10;~NumField;20" + attrID := "*sum:*req.Field2:10;~*req.NumField;20" expAttrPrf1 := &AttributeProfile{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: attrID, Contexts: []string{utils.META_ANY}, Attributes: []*Attribute{&Attribute{ - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.MetaSum, - Value: config.NewRSRParsersMustCompile("10;~NumField;20", true, utils.INFIELD_SEP), + Value: config.NewRSRParsersMustCompile("10;~*req.NumField;20", true, utils.INFIELD_SEP), }}, } attr, err := dm.GetAttributeProfile(config.CgrConfig().GeneralCfg().DefaultTenant, attrID, false, false, "") diff --git a/engine/libattributes_test.go b/engine/libattributes_test.go index edd3a1577..f4c0a012f 100644 --- a/engine/libattributes_test.go +++ b/engine/libattributes_test.go @@ -39,7 +39,7 @@ func TestConvertExternalToProfile(t *testing.T) { }, Attributes: []*ExternalAttribute{ &ExternalAttribute{ - FieldName: "Account", + FieldName: utils.MetaReq + utils.NestingSep + "Account", Value: "1001", }, }, @@ -57,7 +57,7 @@ func TestConvertExternalToProfile(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: "Account", + FieldName: utils.MetaReq + utils.NestingSep + "Account", Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, @@ -108,7 +108,7 @@ func TestConvertExternalToProfileMissing2(t *testing.T) { }, Attributes: []*ExternalAttribute{ &ExternalAttribute{ - FieldName: "Account", + FieldName: utils.MetaReq + utils.NestingSep + "Account", }, }, Weight: 20, @@ -122,15 +122,15 @@ func TestConvertExternalToProfileMissing2(t *testing.T) { } func TestNewAttributeFromInline(t *testing.T) { - attrID := "*sum:Field2:10;~NumField;20" + attrID := "*sum:*req.Field2:10;~*req.NumField;20" expAttrPrf1 := &AttributeProfile{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: attrID, Contexts: []string{utils.META_ANY}, Attributes: []*Attribute{&Attribute{ - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.MetaSum, - Value: config.NewRSRParsersMustCompile("10;~NumField;20", true, utils.INFIELD_SEP), + Value: config.NewRSRParsersMustCompile("10;~*req.NumField;20", true, utils.INFIELD_SEP), }}, } attr, err := NewAttributeFromInline(config.CgrConfig().GeneralCfg().DefaultTenant, attrID) diff --git a/engine/libtest.go b/engine/libtest.go index bfaa1d902..e49a0791f 100644 --- a/engine/libtest.go +++ b/engine/libtest.go @@ -263,8 +263,8 @@ cgrates.org,SPP_1,,,,,supplier1,,,,ResGroup4,Stat3,10,,, ` AttributesCSVContent = ` #Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight -cgrates.org,ALS1,con1,*string:~*req.Account:1001,2014-07-29T15:00:00Z,*string:~*req.Field1:Initial,Field1,*variable,Sub1,true,20 -cgrates.org,ALS1,con2;con3,,,,Field2,*variable,Sub2,true,20 +cgrates.org,ALS1,con1,*string:~*req.Account:1001,2014-07-29T15:00:00Z,*string:~*req.Field1:Initial,*req.Field1,*variable,Sub1,true,20 +cgrates.org,ALS1,con2;con3,,,,*req.Field2,*variable,Sub2,true,20 ` ChargersCSVContent = ` #Tenant,ID,FilterIDs,ActivationInterval,RunID,AttributeIDs,Weight diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index c5d87b6b6..ed5e887bc 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -1274,13 +1274,13 @@ func TestLoadAttributeProfiles(t *testing.T) { Attributes: []*utils.TPAttribute{ &utils.TPAttribute{ FilterIDs: []string{"*string:~*req.Field1:Initial"}, - FieldName: "Field1", + FieldName: utils.MetaReq + utils.NestingSep + "Field1", Type: utils.MetaVariable, Value: "Sub1", }, &utils.TPAttribute{ FilterIDs: []string{}, - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.MetaVariable, Value: "Sub2", }, diff --git a/engine/model_helpers_test.go b/engine/model_helpers_test.go index 9461bf020..6a5deb3f1 100644 --- a/engine/model_helpers_test.go +++ b/engine/model_helpers_test.go @@ -1211,7 +1211,7 @@ func TestAPItoAttributeProfile(t *testing.T) { }, Attributes: []*utils.TPAttribute{ &utils.TPAttribute{ - FieldName: "FL1", + FieldName: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", }, }, @@ -1227,7 +1227,7 @@ func TestAPItoAttributeProfile(t *testing.T) { }, Attributes: []*Attribute{ &Attribute{ - FieldName: "FL1", + FieldName: utils.MetaReq + utils.NestingSep + "FL1", Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, }, @@ -1253,7 +1253,7 @@ func TestAPItoModelTPAttribute(t *testing.T) { }, Attributes: []*utils.TPAttribute{ &utils.TPAttribute{ - FieldName: "FL1", + FieldName: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", }, }, @@ -1266,7 +1266,7 @@ func TestAPItoModelTPAttribute(t *testing.T) { ID: "ALS1", Contexts: "con1", FilterIDs: "FLTR_ACNT_dan;FLTR_DST_DE", - FieldName: "FL1", + FieldName: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", ActivationInterval: "2014-07-14T14:35:00Z", Weight: 20, @@ -1286,7 +1286,7 @@ func TestModelAsTPAttribute(t *testing.T) { ID: "ALS1", Contexts: "con1", FilterIDs: "FLTR_ACNT_dan;FLTR_DST_DE", - FieldName: "FL1", + FieldName: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", ActivationInterval: "2014-07-14T14:35:00Z", Weight: 20, @@ -1305,7 +1305,7 @@ func TestModelAsTPAttribute(t *testing.T) { Attributes: []*utils.TPAttribute{ &utils.TPAttribute{ FilterIDs: []string{}, - FieldName: "FL1", + FieldName: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", }, }, @@ -1324,7 +1324,7 @@ func TestModelAsTPAttribute(t *testing.T) { Attributes: []*utils.TPAttribute{ &utils.TPAttribute{ FilterIDs: []string{}, - FieldName: "FL1", + FieldName: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", }, }, diff --git a/engine/onstor_it_test.go b/engine/onstor_it_test.go index 3326463bc..b39a81292 100644 --- a/engine/onstor_it_test.go +++ b/engine/onstor_it_test.go @@ -1862,7 +1862,7 @@ func testOnStorITAttributeProfile(t *testing.T) { Contexts: []string{"con1"}, Attributes: []*Attribute{ { - FieldName: "FN1", + FieldName: utils.MetaReq + utils.NestingSep + "FN1", Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, }, @@ -1942,7 +1942,7 @@ func testOnStorITTestAttributeSubstituteIface(t *testing.T) { Contexts: []string{"con1"}, Attributes: []*Attribute{ { - FieldName: "FN1", + FieldName: utils.MetaReq + utils.NestingSep + "FN1", Value: config.NewRSRParsersMustCompile("Val1", true, utils.INFIELD_SEP), }, }, @@ -1964,7 +1964,7 @@ func testOnStorITTestAttributeSubstituteIface(t *testing.T) { } attrProfile.Attributes = []*Attribute{ { - FieldName: "FN1", + FieldName: utils.MetaReq + utils.NestingSep + "FN1", Value: config.NewRSRParsersMustCompile("123.123", true, utils.INFIELD_SEP), }, } @@ -1980,7 +1980,7 @@ func testOnStorITTestAttributeSubstituteIface(t *testing.T) { } attrProfile.Attributes = []*Attribute{ { - FieldName: "FN1", + FieldName: utils.MetaReq + utils.NestingSep + "FN1", Value: config.NewRSRParsersMustCompile("true", true, utils.INFIELD_SEP), }, } diff --git a/migrator/alias.go b/migrator/alias.go index 621a31ebe..81a11b054 100644 --- a/migrator/alias.go +++ b/migrator/alias.go @@ -109,7 +109,7 @@ func alias2AtttributeProfile(alias *v1Alias, defaultTenant string) *engine.Attri fieldName = utils.MetaTenant } attr := &engine.Attribute{ - FieldName: fieldName, + FieldName: utils.MetaReq + utils.NestingSep + fieldName, Type: utils.MetaVariable, //default type for Attribute Value: config.NewRSRParsersMustCompile(substitute, true, utils.INFIELD_SEP), } diff --git a/migrator/derived_chargers.go b/migrator/derived_chargers.go index 1ff0dfb66..0204cb054 100644 --- a/migrator/derived_chargers.go +++ b/migrator/derived_chargers.go @@ -83,7 +83,7 @@ func fieldinfo2Attribute(attr []*engine.Attribute, fieldName, fieldInfo string) return attr } return append(attr, &engine.Attribute{ - FieldName: fieldName, + FieldName: utils.MetaReq + utils.NestingSep + fieldName, Value: rp, Type: utils.MetaVariable, }) diff --git a/migrator/user.go b/migrator/user.go index 62d81ce51..51861af35 100644 --- a/migrator/user.go +++ b/migrator/user.go @@ -63,7 +63,7 @@ func userProfile2attributeProfile(user *v1UserProfile) (attr *engine.AttributePr } if user.Tenant != attr.Tenant { attr.Attributes = append(attr.Attributes, &engine.Attribute{ - FieldName: utils.MetaTenant, + FieldName: utils.MetaReq + utils.NestingSep + utils.MetaTenant, Value: config.NewRSRParsersMustCompile(user.Tenant, true, utils.INFIELD_SEP), Type: utils.META_CONSTANT, }) @@ -77,7 +77,7 @@ func userProfile2attributeProfile(user *v1UserProfile) (attr *engine.AttributePr continue } attr.Attributes = append(attr.Attributes, &engine.Attribute{ - FieldName: fieldName, + FieldName: utils.MetaReq + utils.NestingSep + fieldName, Value: config.NewRSRParsersMustCompile(substitute, true, utils.INFIELD_SEP), Type: utils.MetaVariable, }) From ae56de5cf93488300ba086500dfcc64798783370 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 17 Jan 2020 08:28:42 +0200 Subject: [PATCH 02/14] Updated tests --- agents/astagent.go | 1 + agents/diamagent_test.go | 6 +- agents/fsagent.go | 1 + agents/kamevent_test.go | 4 +- apier/v1/apier2_it_test.go | 2 +- apier/v1/attributes_it_test.go | 90 ++++++++++--------- apier/v1/cdre_it_test.go | 4 +- apier/v1/chargers_it_test.go | 4 +- apier/v1/dm_remote_it_test.go | 2 +- apier/v1/filterindexecache_it_test.go | 8 +- apier/v1/sessions_process_event_it_test.go | 16 ++-- apier/v1/sessionsv1_it_test.go | 10 +-- apier/v1/tpattributes_it_test.go | 10 +-- apier/v2/attributes_it_test.go | 24 ++--- apier/v2/cdrs_it_test.go | 2 +- data/tariffplans/cluelrn/Attributes.csv | 14 +-- data/tariffplans/dispatchers/Attributes.csv | 40 ++++----- .../dispatchers_gob/Attributes.csv | 40 ++++----- data/tariffplans/dnsagent/Attributes.csv | 2 +- data/tariffplans/oldtutorial/Attributes.csv | 4 +- data/tariffplans/precache/Attributes.csv | 4 +- data/tariffplans/testit/Attributes.csv | 6 +- data/tariffplans/testit/Chargers.csv | 2 +- data/tariffplans/testtp/Attributes.csv | 4 +- data/tariffplans/tutorial/Attributes.csv | 38 ++++---- data/tariffplans/tutorial/Chargers.csv | 2 +- data/tariffplans/tutorial2/Attributes.csv | 10 +-- dispatchers/attributes_it_test.go | 14 +-- dispatchers/chargers_it_test.go | 6 +- dispatchers/dispatchers_it_test.go | 4 +- dispatchers/sessions_it_test.go | 8 +- engine/attributes.go | 24 +++-- engine/attributes_test.go | 4 +- engine/cdr.go | 2 + engine/cdrs.go | 5 -- general_tests/cdrs_processevent_it_test.go | 2 +- general_tests/sentinel_it_test.go | 12 +-- general_tests/session3_it_test.go | 2 +- general_tests/sessions_concur_test.go | 2 +- loaders/loader_it_test.go | 4 +- loaders/loader_test.go | 12 +-- migrator/alias.go | 6 +- migrator/alias_it_test.go | 4 +- migrator/alias_test.go | 20 ++--- migrator/derived_chargers_it_test.go | 4 +- migrator/derived_chargers_test.go | 22 ++--- migrator/filters_it_test.go | 8 +- migrator/user.go | 4 +- migrator/user_it_test.go | 14 +-- migrator/user_test.go | 44 ++++----- sessions/sessions.go | 30 ++----- sessions/sessions_test.go | 2 +- 52 files changed, 304 insertions(+), 305 deletions(-) diff --git a/agents/astagent.go b/agents/astagent.go index 84663accf..f269ebf6f 100644 --- a/agents/astagent.go +++ b/agents/astagent.go @@ -179,6 +179,7 @@ func (sma *AsteriskAgent) handleStasisStart(ev *SMAsteriskEvent) { } if authReply.Attributes != nil { for _, fldName := range authReply.Attributes.AlteredFields { + fldName = strings.TrimPrefix(fldName, utils.MetaReq+utils.NestingSep) if _, has := authReply.Attributes.CGREvent.Event[fldName]; !has { continue //maybe removed } diff --git a/agents/diamagent_test.go b/agents/diamagent_test.go index 2d678e492..5e89f7d65 100644 --- a/agents/diamagent_test.go +++ b/agents/diamagent_test.go @@ -182,7 +182,7 @@ func TestProcessRequest(t *testing.T) { *prply = sessions.V1InitSessionReply{ Attributes: &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1001_SESSIONAUTH"}, - AlteredFields: []string{"Password", "PaypalAccount", "RequestType", "LCRProfile"}, + AlteredFields: []string{"*req.Password", "*req.PaypalAccount", "*req.RequestType", "*req.LCRProfile"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "e7d35bf", @@ -274,7 +274,7 @@ func TestProcessRequest(t *testing.T) { *prply = sessions.V1UpdateSessionReply{ Attributes: &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1001_SESSIONAUTH"}, - AlteredFields: []string{"Password", "PaypalAccount", "RequestType", "LCRProfile"}, + AlteredFields: []string{"*req.Password", "*req.PaypalAccount", "*req.RequestType", "*req.LCRProfile"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "e7d35bf", @@ -464,7 +464,7 @@ func TestProcessRequest(t *testing.T) { *prply = sessions.V1ProcessMessageReply{ Attributes: &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1001_SESSIONAUTH"}, - AlteredFields: []string{"Password", "PaypalAccount", "RequestType", "LCRProfile"}, + AlteredFields: []string{"*req.Password", "*req.PaypalAccount", "*req.RequestType", "*req.LCRProfile"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "e7d35bf", diff --git a/agents/fsagent.go b/agents/fsagent.go index 587cb6a77..ee55c92e2 100644 --- a/agents/fsagent.go +++ b/agents/fsagent.go @@ -155,6 +155,7 @@ func (sm *FSsessions) onChannelPark(fsev FSEvent, connIdx int) { } if authReply.Attributes != nil { for _, fldName := range authReply.Attributes.AlteredFields { + fldName = strings.TrimPrefix(fldName, utils.MetaReq+utils.NestingSep) if _, has := authReply.Attributes.CGREvent.Event[fldName]; !has { continue //maybe removed } diff --git a/agents/kamevent_test.go b/agents/kamevent_test.go index d1065d069..97c548ac1 100644 --- a/agents/kamevent_test.go +++ b/agents/kamevent_test.go @@ -243,7 +243,7 @@ func TestKamEvAsKamAuthReply(t *testing.T) { authRply = &sessions.V1AuthorizeReply{ Attributes: &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1001_ACCOUNT_PROFILE"}, - AlteredFields: []string{"Password", utils.RequestType}, + AlteredFields: []string{"*req.Password", utils.MetaReq + utils.NestingSep + utils.RequestType}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "TestKamEvAsKamAuthReply", @@ -430,7 +430,7 @@ func TestKamEvAsKamProcessEventReply(t *testing.T) { procEvhRply = &sessions.V1ProcessMessageReply{ Attributes: &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1001_ACCOUNT_PROFILE"}, - AlteredFields: []string{"Password", utils.RequestType}, + AlteredFields: []string{"*req.Password", utils.MetaReq + utils.NestingSep + utils.RequestType}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "TestKamEvAsKamAuthReply", diff --git a/apier/v1/apier2_it_test.go b/apier/v1/apier2_it_test.go index bee3adf54..8b63ff3f2 100644 --- a/apier/v1/apier2_it_test.go +++ b/apier/v1/apier2_it_test.go @@ -151,7 +151,7 @@ func testAPIerVerifyAttributesAfterLoad(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{}, - FieldName: "Password", + FieldName: utils.MetaReq + utils.NestingSep + "Password", Type: utils.META_CONSTANT, Value: config.NewRSRParsersMustCompile("CGRateS.org", true, utils.INFIELD_SEP), }, diff --git a/apier/v1/attributes_it_test.go b/apier/v1/attributes_it_test.go index d44f08cd0..190a82564 100644 --- a/apier/v1/attributes_it_test.go +++ b/apier/v1/attributes_it_test.go @@ -188,11 +188,11 @@ func testAttributeSGetAttributeForEvent(t *testing.T) { ActivationTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC)}, Attributes: []*engine.Attribute{ { - FieldName: utils.Account, + FieldName: utils.MetaReq + utils.NestingSep + utils.Account, Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, { - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, @@ -240,7 +240,7 @@ func testAttributeSGetAttributeForEventNotFound(t *testing.T) { ActivationTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC)}, Attributes: []*engine.Attribute{ { - FieldName: utils.Account, + FieldName: utils.MetaReq + utils.NestingSep + utils.Account, Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, @@ -292,7 +292,7 @@ func testAttributeSGetAttributeForEventWithMetaAnyContext(t *testing.T) { ActivationTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC)}, Attributes: []*engine.Attribute{ { - FieldName: utils.Account, + FieldName: utils.MetaReq + utils.NestingSep + utils.Account, Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, @@ -340,7 +340,8 @@ func testAttributeSProcessEvent(t *testing.T) { } eRply := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1"}, - AlteredFields: []string{utils.Subject, utils.Account}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + utils.Subject, + utils.MetaReq + utils.NestingSep + utils.Account}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "testAttributeSProcessEvent", @@ -353,7 +354,8 @@ func testAttributeSProcessEvent(t *testing.T) { } eRply2 := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1"}, - AlteredFields: []string{utils.Account, utils.Subject}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + utils.Account, + utils.MetaReq + utils.NestingSep + utils.Subject}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "testAttributeSProcessEvent", @@ -441,11 +443,11 @@ func testAttributeSProcessEventWithNoneSubstitute(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:~*req.Account:1008"}, - FieldName: utils.Account, + FieldName: utils.MetaReq + utils.NestingSep + utils.Account, Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, { - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.NewRSRParsersMustCompile(utils.MetaRemove, true, utils.INFIELD_SEP), }, }, @@ -461,7 +463,8 @@ func testAttributeSProcessEventWithNoneSubstitute(t *testing.T) { } eRply := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"AttributeWithNonSubstitute"}, - AlteredFields: []string{utils.Account, utils.Subject}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + utils.Account, + utils.MetaReq + utils.NestingSep + utils.Subject}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "testAttributeSWithNoneSubstitute", @@ -508,11 +511,11 @@ func testAttributeSProcessEventWithNoneSubstitute2(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:~*req.Account:1008"}, - FieldName: utils.Account, + FieldName: utils.MetaReq + utils.NestingSep + utils.Account, Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, { - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.NewRSRParsersMustCompile(utils.MetaRemove, true, utils.INFIELD_SEP), }, }, @@ -527,7 +530,7 @@ func testAttributeSProcessEventWithNoneSubstitute2(t *testing.T) { } eRply := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"AttributeWithNonSubstitute"}, - AlteredFields: []string{"Account", "Subject"}, + AlteredFields: []string{"*req.Account", "*req.Subject"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "testAttributeSWithNoneSubstitute", @@ -539,7 +542,8 @@ func testAttributeSProcessEventWithNoneSubstitute2(t *testing.T) { } eRply2 := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"AttributeWithNonSubstitute"}, - AlteredFields: []string{utils.Subject, utils.Account}, + AlteredFields: []string{utils.MetaReq + utils.NestingSep + utils.Subject, + utils.MetaReq + utils.NestingSep + utils.Account}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "testAttributeSWithNoneSubstitute", @@ -586,12 +590,12 @@ func testAttributeSProcessEventWithNoneSubstitute3(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:~*req.Account:1008"}, - FieldName: utils.Account, + FieldName: utils.MetaReq + utils.NestingSep + utils.Account, Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, { FilterIDs: []string{"*string:~*req.Subject:1008"}, - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.NewRSRParsersMustCompile(utils.MetaRemove, true, utils.INFIELD_SEP), }, }, @@ -606,7 +610,7 @@ func testAttributeSProcessEventWithNoneSubstitute3(t *testing.T) { } eRply := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"AttributeWithNonSubstitute"}, - AlteredFields: []string{"Account"}, + AlteredFields: []string{"*req.Account"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "testAttributeSWithNoneSubstitute", @@ -639,8 +643,8 @@ func testAttributeSProcessEventWithHeader(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: "Field2", - Value: config.NewRSRParsersMustCompile("~Field1", true, utils.INFIELD_SEP), + FieldName: utils.MetaReq + utils.NestingSep + "Field2", + Value: config.NewRSRParsersMustCompile("~*req.Field1", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -666,7 +670,7 @@ func testAttributeSProcessEventWithHeader(t *testing.T) { } eRply := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_Header"}, - AlteredFields: []string{"Field2"}, + AlteredFields: []string{"*req.Field2"}, CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "HeaderEventForAttribute", @@ -721,7 +725,7 @@ func testAttributeSSetAlsPrf(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: "FL1", + FieldName: utils.MetaReq + utils.NestingSep + "FL1", Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, }, @@ -749,11 +753,11 @@ func testAttributeSSetAlsPrf(t *testing.T) { func testAttributeSUpdateAlsPrf(t *testing.T) { alsPrf.Attributes = []*engine.Attribute{ { - FieldName: "FL1", + FieldName: utils.MetaReq + utils.NestingSep + "FL1", Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, { - FieldName: "FL2", + FieldName: utils.MetaReq + utils.NestingSep + "FL2", Value: config.NewRSRParsersMustCompile("Al2", true, utils.INFIELD_SEP), }, } @@ -814,7 +818,7 @@ func testAttributeSSetAlsPrf2(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.RSRParsers{ &config.RSRParser{ Rules: "roam", @@ -858,7 +862,7 @@ func testAttributeSSetAlsPrf3(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.RSRParsers{ &config.RSRParser{ Rules: "", @@ -889,7 +893,7 @@ func testAttributeSSetAlsPrf4(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.RSRParsers{ &config.RSRParser{}, }, @@ -926,8 +930,8 @@ func testAttributeSProcessEventWithSearchAndReplace(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: "Category", - Value: config.NewRSRParsersMustCompile("~Category:s/(.*)/${1}_suffix/", true, utils.INFIELD_SEP), + FieldName: utils.MetaReq + utils.NestingSep + "Category", + Value: config.NewRSRParsersMustCompile("~*req.Category:s/(.*)/${1}_suffix/", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -953,7 +957,7 @@ func testAttributeSProcessEventWithSearchAndReplace(t *testing.T) { } eRply := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_Search_and_replace"}, - AlteredFields: []string{"Category"}, + AlteredFields: []string{"*req.Category"}, CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "HeaderEventForAttribute", @@ -984,7 +988,7 @@ func testAttributeSProcessWithMultipleRuns(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: "Field1", + FieldName: utils.MetaReq + utils.NestingSep + "Field1", Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, @@ -1002,7 +1006,7 @@ func testAttributeSProcessWithMultipleRuns(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), }, }, @@ -1020,7 +1024,7 @@ func testAttributeSProcessWithMultipleRuns(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: "Field3", + FieldName: utils.MetaReq + utils.NestingSep + "Field3", Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), }, }, @@ -1057,7 +1061,7 @@ func testAttributeSProcessWithMultipleRuns(t *testing.T) { } eRply := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1", "ATTR_2"}, - AlteredFields: []string{"Field1", "Field2"}, + AlteredFields: []string{"*req.Field1", "*req.Field2"}, CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1094,7 +1098,7 @@ func testAttributeSProcessWithMultipleRuns2(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: "Field1", + FieldName: utils.MetaReq + utils.NestingSep + "Field1", Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, @@ -1112,7 +1116,7 @@ func testAttributeSProcessWithMultipleRuns2(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), }, }, @@ -1130,7 +1134,7 @@ func testAttributeSProcessWithMultipleRuns2(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: "Field3", + FieldName: utils.MetaReq + utils.NestingSep + "Field3", Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), }, }, @@ -1167,7 +1171,7 @@ func testAttributeSProcessWithMultipleRuns2(t *testing.T) { } eRply := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1", "ATTR_2", "ATTR_3"}, - AlteredFields: []string{"Field1", "Field2", "Field3"}, + AlteredFields: []string{"*req.Field1", "*req.Field2", "*req.Field3"}, CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1213,7 +1217,7 @@ func testAttributeSCachingMetaNone(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: "Field1", + FieldName: utils.MetaReq + utils.NestingSep + "Field1", Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, @@ -1272,7 +1276,7 @@ func testAttributeSCachingMetaLoad(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: "Field1", + FieldName: utils.MetaReq + utils.NestingSep + "Field1", Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, @@ -1364,7 +1368,7 @@ func testAttributeSCachingMetaReload1(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: "Field1", + FieldName: utils.MetaReq + utils.NestingSep + "Field1", Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, @@ -1423,7 +1427,7 @@ func testAttributeSCachingMetaReload2(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: "Field1", + FieldName: utils.MetaReq + utils.NestingSep + "Field1", Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, @@ -1463,7 +1467,7 @@ func testAttributeSCachingMetaReload2(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: "Field1", + FieldName: utils.MetaReq + utils.NestingSep + "Field1", Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, @@ -1502,7 +1506,7 @@ func testAttributeSCachingMetaRemove(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: "Field1", + FieldName: utils.MetaReq + utils.NestingSep + "Field1", Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, @@ -1552,7 +1556,7 @@ func testAttributeSCachingMetaRemove(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: "Field1", + FieldName: utils.MetaReq + utils.NestingSep + "Field1", Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, diff --git a/apier/v1/cdre_it_test.go b/apier/v1/cdre_it_test.go index 852668e80..19d822a55 100755 --- a/apier/v1/cdre_it_test.go +++ b/apier/v1/cdre_it_test.go @@ -291,11 +291,11 @@ func testCDReAddAttributes(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.NewRSRParsersMustCompile("ATTR_SUBJECT", true, utils.INFIELD_SEP), }, { - FieldName: utils.Category, + FieldName: utils.MetaReq + utils.NestingSep + utils.Category, Value: config.NewRSRParsersMustCompile("ATTR_CATEGORY", true, utils.INFIELD_SEP), }, }, diff --git a/apier/v1/chargers_it_test.go b/apier/v1/chargers_it_test.go index 8b16f77af..b47217ff7 100755 --- a/apier/v1/chargers_it_test.go +++ b/apier/v1/chargers_it_test.go @@ -166,7 +166,7 @@ func testChargerSLoadAddCharger(t *testing.T) { Contexts: []string{"simpleauth"}, Attributes: []*engine.Attribute{ { - FieldName: "Password", + FieldName: utils.MetaReq + utils.NestingSep + "Password", Value: config.RSRParsers{ &config.RSRParser{ Rules: "CGRateS.org", @@ -217,7 +217,7 @@ func testChargerSProcessEvent(t *testing.T) { { ChargerSProfile: "Charger1", AttributeSProfiles: []string{"ATTR_1001_SIMPLEAUTH"}, - AlteredFields: []string{"Password"}, + AlteredFields: []string{"*req.Password"}, CGREvent: &utils.CGREvent{ // matching Charger1 Tenant: "cgrates.org", ID: "event1", diff --git a/apier/v1/dm_remote_it_test.go b/apier/v1/dm_remote_it_test.go index 02562ebfd..80d6eef80 100644 --- a/apier/v1/dm_remote_it_test.go +++ b/apier/v1/dm_remote_it_test.go @@ -239,7 +239,7 @@ func testInternalRemoteITGetAttribute(t *testing.T) { Attributes: []*engine.Attribute{ { - FieldName: "Password", + FieldName: utils.MetaReq + utils.NestingSep + "Password", FilterIDs: []string{}, Type: utils.META_CONSTANT, Value: config.NewRSRParsersMustCompile("CGRateS.org", true, utils.INFIELD_SEP), diff --git a/apier/v1/filterindexecache_it_test.go b/apier/v1/filterindexecache_it_test.go index 0d450f575..0cef72519 100644 --- a/apier/v1/filterindexecache_it_test.go +++ b/apier/v1/filterindexecache_it_test.go @@ -922,11 +922,11 @@ func testV1FIdxCaSetAttributeProfile(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.Account, + FieldName: utils.MetaReq + utils.NestingSep + utils.Account, Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, { - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, @@ -1015,11 +1015,11 @@ func testV1FIdxCaUpdateAttributeProfile(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.Account, + FieldName: utils.MetaReq + utils.NestingSep + utils.Account, Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, { - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, diff --git a/apier/v1/sessions_process_event_it_test.go b/apier/v1/sessions_process_event_it_test.go index 1a1638243..2f461cf9c 100644 --- a/apier/v1/sessions_process_event_it_test.go +++ b/apier/v1/sessions_process_event_it_test.go @@ -43,12 +43,12 @@ var sTestSessionSv1ProcessEvent = []func(t *testing.T){ testSSv1ItRpcConn, testSSv1ItPing, testSSv1ItTPFromFolder, - testSSv1ItProcessEventAuth, + // testSSv1ItProcessEventAuth, testSSv1ItProcessEventInitiateSession, - testSSv1ItProcessEventUpdateSession, - testSSv1ItProcessEventTerminateSession, - testSSv1ItProcessCDRForSessionFromProcessEvent, - testSSv1ItGetCDRs, + // testSSv1ItProcessEventUpdateSession, + // testSSv1ItProcessEventTerminateSession, + // testSSv1ItProcessCDRForSessionFromProcessEvent, + // testSSv1ItGetCDRs, testSSv1ItStopCgrEngine, } @@ -202,7 +202,7 @@ func testSSv1ItProcessEventAuth(t *testing.T) { } eAttrs := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_ACNT_1001"}, - AlteredFields: []string{"OfficeGroup"}, + AlteredFields: []string{"*req.OfficeGroup"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "testSSv1ItProcessEventAuth", @@ -264,7 +264,7 @@ func testSSv1ItProcessEventInitiateSession(t *testing.T) { } eAttrs := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_ACNT_1001"}, - AlteredFields: []string{"OfficeGroup"}, + AlteredFields: []string{"*req.OfficeGroup"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "testSSv1ItProcessEventInitiateSession", @@ -323,7 +323,7 @@ func testSSv1ItProcessEventUpdateSession(t *testing.T) { } eAttrs := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_ACNT_1001"}, - AlteredFields: []string{"OfficeGroup"}, + AlteredFields: []string{"*req.OfficeGroup"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "testSSv1ItProcessEventUpdateSession", diff --git a/apier/v1/sessionsv1_it_test.go b/apier/v1/sessionsv1_it_test.go index 0b9fe5720..ccf482941 100644 --- a/apier/v1/sessionsv1_it_test.go +++ b/apier/v1/sessionsv1_it_test.go @@ -254,7 +254,7 @@ func testSSv1ItAuth(t *testing.T) { } eAttrs := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_ACNT_1001"}, - AlteredFields: []string{"OfficeGroup"}, + AlteredFields: []string{"*req.OfficeGroup"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "TestSSv1ItAuth", @@ -363,7 +363,7 @@ func testSSv1ItInitiateSession(t *testing.T) { } eAttrs := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_ACNT_1001"}, - AlteredFields: []string{"OfficeGroup"}, + AlteredFields: []string{"*req.OfficeGroup"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "TestSSv1ItInitiateSession", @@ -473,7 +473,7 @@ func testSSv1ItUpdateSession(t *testing.T) { } eAttrs := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_ACNT_1001"}, - AlteredFields: []string{"OfficeGroup"}, + AlteredFields: []string{"*req.OfficeGroup"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "TestSSv1ItUpdateSession", @@ -617,7 +617,7 @@ func testSSv1ItProcessEvent(t *testing.T) { } eAttrs := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_ACNT_1001"}, - AlteredFields: []string{"OfficeGroup"}, + AlteredFields: []string{"*req.OfficeGroup"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "TestSSv1ItProcessEvent", @@ -772,7 +772,7 @@ func testSSv1ItForceUpdateSession(t *testing.T) { } eAttrs := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_ACNT_1001"}, - AlteredFields: []string{"OfficeGroup"}, + AlteredFields: []string{"*req.OfficeGroup"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "TestSSv1ItUpdateSession", diff --git a/apier/v1/tpattributes_it_test.go b/apier/v1/tpattributes_it_test.go index 8c42b1740..f3499baa3 100644 --- a/apier/v1/tpattributes_it_test.go +++ b/apier/v1/tpattributes_it_test.go @@ -138,7 +138,7 @@ func testTPAlsPrfSetTPAlsPrf(t *testing.T) { Contexts: []string{"con1"}, Attributes: []*utils.TPAttribute{ &utils.TPAttribute{ - FieldName: "FL1", + FieldName: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", FilterIDs: []string{}, }, @@ -180,12 +180,12 @@ func testTPAlsPrfGetTPAlsPrfIDs(t *testing.T) { func testTPAlsPrfUpdateTPAlsPrf(t *testing.T) { tpAlsPrf.Attributes = []*utils.TPAttribute{ &utils.TPAttribute{ - FieldName: "FL1", + FieldName: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", FilterIDs: []string{}, }, &utils.TPAttribute{ - FieldName: "FL2", + FieldName: utils.MetaReq + utils.NestingSep + "FL2", Value: "Al2", FilterIDs: []string{}, }, @@ -212,12 +212,12 @@ func testTPAlsPrfGetTPAlsPrfAfterUpdate(t *testing.T) { Contexts: []string{"con1"}, Attributes: []*utils.TPAttribute{ &utils.TPAttribute{ - FieldName: "FL2", + FieldName: utils.MetaReq + utils.NestingSep + "FL2", Value: "Al2", FilterIDs: []string{}, }, &utils.TPAttribute{ - FieldName: "FL1", + FieldName: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", FilterIDs: []string{}, }, diff --git a/apier/v2/attributes_it_test.go b/apier/v2/attributes_it_test.go index f6162e1a6..90d8ef6d0 100644 --- a/apier/v2/attributes_it_test.go +++ b/apier/v2/attributes_it_test.go @@ -120,14 +120,14 @@ func testAttributeSSetAlsPrf(t *testing.T) { Tenant: "cgrates.org", ID: "ExternalAttribute", Contexts: []string{utils.MetaSessionS, utils.MetaCDRs}, - FilterIDs: []string{"*string:Account:1001"}, + FilterIDs: []string{"*string:~*req.Account:1001"}, ActivationInterval: &utils.ActivationInterval{ ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC), ExpiryTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC), }, Attributes: []*engine.ExternalAttribute{ { - FieldName: "Account", + FieldName: utils.MetaReq + utils.NestingSep + "Account", Value: "1001", }, }, @@ -146,14 +146,14 @@ func testAttributeSSetAlsPrf(t *testing.T) { Tenant: "cgrates.org", ID: "ExternalAttribute", Contexts: []string{utils.MetaSessionS, utils.MetaCDRs}, - FilterIDs: []string{"*string:Account:1001"}, + FilterIDs: []string{"*string:~*req.Account:1001"}, ActivationInterval: &utils.ActivationInterval{ ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC), ExpiryTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC), }, Attributes: []*engine.Attribute{ { - FieldName: "Account", + FieldName: utils.MetaReq + utils.NestingSep + "Account", Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, @@ -178,19 +178,19 @@ func testAttributeSUpdateAlsPrf(t *testing.T) { Tenant: "cgrates.org", ID: "ExternalAttribute", Contexts: []string{utils.MetaSessionS, utils.MetaCDRs}, - FilterIDs: []string{"*string:Account:1001"}, + FilterIDs: []string{"*string:~*req.Account:1001"}, ActivationInterval: &utils.ActivationInterval{ ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC), ExpiryTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC), }, Attributes: []*engine.ExternalAttribute{ { - FieldName: "Account", + FieldName: utils.MetaReq + utils.NestingSep + "Account", Value: "1001", }, { - FieldName: "Subject", - Value: "~Account", + FieldName: utils.MetaReq + utils.NestingSep + "Subject", + Value: "~*req.Account", }, }, Weight: 20, @@ -208,19 +208,19 @@ func testAttributeSUpdateAlsPrf(t *testing.T) { Tenant: "cgrates.org", ID: "ExternalAttribute", Contexts: []string{utils.MetaSessionS, utils.MetaCDRs}, - FilterIDs: []string{"*string:Account:1001"}, + FilterIDs: []string{"*string:~*req.Account:1001"}, ActivationInterval: &utils.ActivationInterval{ ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC), ExpiryTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC), }, Attributes: []*engine.Attribute{ { - FieldName: "Account", + FieldName: utils.MetaReq + utils.NestingSep + "Account", Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, { - FieldName: "Subject", - Value: config.NewRSRParsersMustCompile("~Account", true, utils.INFIELD_SEP), + FieldName: utils.MetaReq + utils.NestingSep + "Subject", + Value: config.NewRSRParsersMustCompile("~*req.Account", true, utils.INFIELD_SEP), }, }, Weight: 20, diff --git a/apier/v2/cdrs_it_test.go b/apier/v2/cdrs_it_test.go index 5c2dc1f13..4ed8c010b 100644 --- a/apier/v2/cdrs_it_test.go +++ b/apier/v2/cdrs_it_test.go @@ -418,7 +418,7 @@ func testV2CDRsDifferentTenants(t *testing.T) { }, }, { - FieldName: utils.Tenant, + FieldName: utils.MetaReq + utils.NestingSep + utils.Tenant, Type: utils.META_CONSTANT, Value: config.RSRParsers{ &config.RSRParser{ diff --git a/data/tariffplans/cluelrn/Attributes.csv b/data/tariffplans/cluelrn/Attributes.csv index 2917b14d4..05a033f5e 100644 --- a/data/tariffplans/cluelrn/Attributes.csv +++ b/data/tariffplans/cluelrn/Attributes.csv @@ -1,8 +1,8 @@ #Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight -cgrates.org,LRN_Dst3125650565,lrn,*string:~*req.Destination:3125650565,,,Destination,*constant,13128543000,false,10 -cgrates.org,LRN_Dst3125650565,,,,,OriginalDestination,*constant,3125650565,false,10 -cgrates.org,LRN_LATA_Dst13128543000,lrn,*string:~*req.Destination:13128543000;*rsr::~*req.OriginalDestination(!^$),,,DestinationLATA,*constant,358,false,20 -cgrates.org,LRN_LATA_Cli9174269000,lrn,*string:~*req.Account:9174269000;*rsr::~*req.DestinationLATA(!^$),,,CallerLATA,*constant,132,false,30 -cgrates.org,LRN_JURISDICTION_NY,lrn,FLTR_INTRALATA_NEWYORK,,,LRNJurisdiction,*constant,INTRA,false,50 -cgrates.org,LRN_JURISDICTION_IL,lrn,FLTR_INTRALATA_ILLINOIS,,,LRNJurisdiction,*constant,INTRA,false,50 -cgrates.org,LRN_JURISDICTION_INTER,lrn,*string:~*req.Destination:13128543000;*rsr::~*req.CallerLATA(!^$),,,LRNJurisdiction,*constant,INTER,false,40 +cgrates.org,LRN_Dst3125650565,lrn,*string:~*req.Destination:3125650565,,,*req.Destination,*constant,13128543000,false,10 +cgrates.org,LRN_Dst3125650565,,,,,*req.OriginalDestination,*constant,3125650565,false,10 +cgrates.org,LRN_LATA_Dst13128543000,lrn,*string:~*req.Destination:13128543000;*rsr::~*req.OriginalDestination(!^$),,,*req.DestinationLATA,*constant,358,false,20 +cgrates.org,LRN_LATA_Cli9174269000,lrn,*string:~*req.Account:9174269000;*rsr::~*req.DestinationLATA(!^$),,,*req.CallerLATA,*constant,132,false,30 +cgrates.org,LRN_JURISDICTION_NY,lrn,FLTR_INTRALATA_NEWYORK,,,*req.LRNJurisdiction,*constant,INTRA,false,50 +cgrates.org,LRN_JURISDICTION_IL,lrn,FLTR_INTRALATA_ILLINOIS,,,*req.LRNJurisdiction,*constant,INTRA,false,50 +cgrates.org,LRN_JURISDICTION_INTER,lrn,*string:~*req.Destination:13128543000;*rsr::~*req.CallerLATA(!^$),,,*req.LRNJurisdiction,*constant,INTER,false,40 diff --git a/data/tariffplans/dispatchers/Attributes.csv b/data/tariffplans/dispatchers/Attributes.csv index 3f4e362d4..a07ee0570 100644 --- a/data/tariffplans/dispatchers/Attributes.csv +++ b/data/tariffplans/dispatchers/Attributes.csv @@ -1,22 +1,22 @@ #Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight -cgrates.org,ATTR_1001_SIMPLEAUTH,*any,*string:~*req.Account:1001,,,Password,*constant,CGRateS.org,false,20 +cgrates.org,ATTR_1001_SIMPLEAUTH,*any,*string:~*req.Account:1001,,,*req.Password,*constant,CGRateS.org,false,20 cgrates.org,ATTR_1001_SIMPLEAUTH,*any,,,,EventName,*constant,*remove,false,20 -cgrates.org,ATTR_1003_SIMPLEAUTH,*any,*string:~*req.Account:1003,,,Password,*constant,CGRateS.com,false,20 -cgrates.org,ATTR_API_ATTR_FAKE_AUTH,*auth,*string:~*req.APIKey:12345,,,APIMethods,*constant,,false,20 -cgrates.org,ATTR_API_ATTR_AUTH,*auth,*string:~*req.APIKey:attr12345,,,APIMethods,*constant,AttributeSv1.Ping&AttributeSv1.GetAttributeForEvent&AttributeSv1.ProcessEvent,false,20 -cgrates.org,ATTR_API_CHRG_AUTH,*auth,*string:~*req.APIKey:chrg12345,,,APIMethods,*constant,ChargerSv1.Ping&ChargerSv1.GetChargersForEvent&ChargerSv1.ProcessEvent,false,20 -cgrates.org,ATTR_API_THR_AUTH,*auth,*string:~*req.APIKey:thr12345,,,APIMethods,*constant,ThresholdSv1.Ping&ThresholdSv1.GetThresholdsForEvent&ThresholdSv1.ProcessEvent&ThresholdSv1.GetThreshold&ThresholdSv1.GetThresholdIDs,false,20 -cgrates.org,ATTR_API_SUP_AUTH,*auth,*string:~*req.APIKey:sup12345,,,APIMethods,*constant,SupplierSv1.Ping&SupplierSv1.GetSuppliers&SupplierSv1.GetSupplierProfilesForEvent,false,20 -cgrates.org,ATTR_API_STAT_AUTH,*auth,*string:~*req.APIKey:stat12345,,,APIMethods,*constant,StatSv1.Ping&StatSv1.GetStatQueuesForEvent&StatSv1.GetQueueStringMetrics&StatSv1.ProcessEvent&StatSv1.GetQueueIDs&StatSv1.GetQueueFloatMetrics,false,20 -cgrates.org,ATTR_API_RES_AUTH,*auth,*string:~*req.APIKey:res12345,,,APIMethods,*constant,ResourceSv1.Ping&ResourceSv1.GetResourcesForEvent&ResourceSv1.AuthorizeResources&ResourceSv1.AllocateResources&ResourceSv1.ReleaseResources,false,20 -cgrates.org,ATTR_API_SES_AUTH,*auth,*string:~*req.APIKey:ses12345,,,APIMethods,*constant,SessionSv1.Ping&SessionSv1.AuthorizeEvent&SessionSv1.AuthorizeEventWithDigest&SessionSv1.InitiateSession&SessionSv1.InitiateSessionWithDigest&SessionSv1.UpdateSession&SessionSv1.SyncSessions&SessionSv1.TerminateSession&SessionSv1.ProcessCDR&SessionSv1.ProcessMessage&SessionSv1.GetActiveSessions&SessionSv1.GetActiveSessionsCount&SessionSv1.ForceDisconnect&SessionSv1.GetPassiveSessions&SessionSv1.GetPassiveSessionsCount&SessionSv1.ReplicateSessions&SessionSv1.SetPassiveSession&SessionSv1.ProcessEvent,false,20 -cgrates.org,ATTR_API_RSP_AUTH,*auth,*string:~*req.APIKey:rsp12345,,,APIMethods,*constant,CoreSv1.Status&CoreSv1.Ping&Responder.Shutdown&Responder.Ping,false,20 -cgrates.org,ATTR_API_CHC_AUTH,*auth,*string:~*req.APIKey:chc12345,,,APIMethods,*constant,CacheSv1.Ping&CacheSv1.GetCacheStats&CacheSv1.LoadCache&CacheSv1.PrecacheStatus&CacheSv1.GetItemIDs&CacheSv1.HasItem&CacheSv1.GetItemExpiryTime&CacheSv1.ReloadCache&CacheSv1.RemoveItem&CacheSv1.FlushCache&CacheSv1.Clear,false,20 -cgrates.org,ATTR_API_GRD_AUTH,*auth,*string:~*req.APIKey:grd12345,,,APIMethods,*constant,GuardianSv1.Ping&GuardianSv1.RemoteLock&GuardianSv1.RemoteUnlock,false,20 -cgrates.org,ATTR_API_SCHD_AUTH,*auth,*string:~*req.APIKey:sched12345,,,APIMethods,*constant,SchedulerSv1.Ping,false,20 -cgrates.org,ATTR_API_CDRS_AUTH,*auth,*string:~*req.APIKey:cdrs12345,,,APIMethods,*constant,CDRsV1.Ping&CDRsV1.ProcessEvent&CDRsV1.GetCDRs&CDRsV1.GetCDRsCount&CDRsV1.ProcessCDR&CDRsV1.ProcessExternalCDR,false,20 -cgrates.org,ATTR_API_DSP_AUTH,*auth,*string:~*req.APIKey:dsp12345,,,APIMethods,*constant,DispatcherSv1.Ping&DispatcherSv1.GetProfileForEvent,false,20 -cgrates.org,ATTR_API_PSE_AUTH,*auth,*string:~*req.APIKey:pse12345,,,APIMethods,*constant,SessionSv1.Ping&SessionSv1.AuthorizeEvent&SessionSv1.AuthorizeEventWithDigest&SessionSv1.InitiateSession&SessionSv1.InitiateSessionWithDigest&SessionSv1.UpdateSession&SessionSv1.SyncSessions&SessionSv1.TerminateSession&SessionSv1.ProcessCDR&SessionSv1.ProcessMessage&SessionSv1.GetActiveSessions&SessionSv1.GetActiveSessionsCount&SessionSv1.ForceDisconnect&SessionSv1.GetPassiveSessions&SessionSv1.GetPassiveSessionsCount&SessionSv1.ReplicateSessions&SessionSv1.SetPassiveSession&AttributeSv1.ProcessEvent&Responder.Debit&ResourceSv1.AllocateResources&ChargerSv1.ProcessEvent&Responder.MaxDebit,false,20 -cgrates.org,ATTR_API_CFG_AUTH,*auth,*string:~*req.APIKey:cfg12345,,,APIMethods,*constant,ConfigSv1.GetJSONSection&ConfigSv1.ReloadConfig,false,20 -cgrates.org,ATTR_API_APIER_AUTH,*auth,*string:~*req.APIKey:apier12345,,,APIMethods,*constant,ApierV1.GetAttributeProfile&ApierV1.SetAttributeProfile,false,20 -cgrates.org,ATTR_API_RALS_AUTH,*auth,*string:~*req.APIKey:rals12345,,,APIMethods,*constant,RALsV1.Ping&RALsV1.GetRatingPlansCost,false,20 +cgrates.org,ATTR_1003_SIMPLEAUTH,*any,*string:~*req.Account:1003,,,*req.Password,*constant,CGRateS.com,false,20 +cgrates.org,ATTR_API_ATTR_FAKE_AUTH,*auth,*string:~*req.APIKey:12345,,,*req.APIMethods,*constant,,false,20 +cgrates.org,ATTR_API_ATTR_AUTH,*auth,*string:~*req.APIKey:attr12345,,,*req.APIMethods,*constant,AttributeSv1.Ping&AttributeSv1.GetAttributeForEvent&AttributeSv1.ProcessEvent,false,20 +cgrates.org,ATTR_API_CHRG_AUTH,*auth,*string:~*req.APIKey:chrg12345,,,*req.APIMethods,*constant,ChargerSv1.Ping&ChargerSv1.GetChargersForEvent&ChargerSv1.ProcessEvent,false,20 +cgrates.org,ATTR_API_THR_AUTH,*auth,*string:~*req.APIKey:thr12345,,,*req.APIMethods,*constant,ThresholdSv1.Ping&ThresholdSv1.GetThresholdsForEvent&ThresholdSv1.ProcessEvent&ThresholdSv1.GetThreshold&ThresholdSv1.GetThresholdIDs,false,20 +cgrates.org,ATTR_API_SUP_AUTH,*auth,*string:~*req.APIKey:sup12345,,,*req.APIMethods,*constant,SupplierSv1.Ping&SupplierSv1.GetSuppliers&SupplierSv1.GetSupplierProfilesForEvent,false,20 +cgrates.org,ATTR_API_STAT_AUTH,*auth,*string:~*req.APIKey:stat12345,,,*req.APIMethods,*constant,StatSv1.Ping&StatSv1.GetStatQueuesForEvent&StatSv1.GetQueueStringMetrics&StatSv1.ProcessEvent&StatSv1.GetQueueIDs&StatSv1.GetQueueFloatMetrics,false,20 +cgrates.org,ATTR_API_RES_AUTH,*auth,*string:~*req.APIKey:res12345,,,*req.APIMethods,*constant,ResourceSv1.Ping&ResourceSv1.GetResourcesForEvent&ResourceSv1.AuthorizeResources&ResourceSv1.AllocateResources&ResourceSv1.ReleaseResources,false,20 +cgrates.org,ATTR_API_SES_AUTH,*auth,*string:~*req.APIKey:ses12345,,,*req.APIMethods,*constant,SessionSv1.Ping&SessionSv1.AuthorizeEvent&SessionSv1.AuthorizeEventWithDigest&SessionSv1.InitiateSession&SessionSv1.InitiateSessionWithDigest&SessionSv1.UpdateSession&SessionSv1.SyncSessions&SessionSv1.TerminateSession&SessionSv1.ProcessCDR&SessionSv1.ProcessMessage&SessionSv1.GetActiveSessions&SessionSv1.GetActiveSessionsCount&SessionSv1.ForceDisconnect&SessionSv1.GetPassiveSessions&SessionSv1.GetPassiveSessionsCount&SessionSv1.ReplicateSessions&SessionSv1.SetPassiveSession&SessionSv1.ProcessEvent,false,20 +cgrates.org,ATTR_API_RSP_AUTH,*auth,*string:~*req.APIKey:rsp12345,,,*req.APIMethods,*constant,CoreSv1.Status&CoreSv1.Ping&Responder.Shutdown&Responder.Ping,false,20 +cgrates.org,ATTR_API_CHC_AUTH,*auth,*string:~*req.APIKey:chc12345,,,*req.APIMethods,*constant,CacheSv1.Ping&CacheSv1.GetCacheStats&CacheSv1.LoadCache&CacheSv1.PrecacheStatus&CacheSv1.GetItemIDs&CacheSv1.HasItem&CacheSv1.GetItemExpiryTime&CacheSv1.ReloadCache&CacheSv1.RemoveItem&CacheSv1.FlushCache&CacheSv1.Clear,false,20 +cgrates.org,ATTR_API_GRD_AUTH,*auth,*string:~*req.APIKey:grd12345,,,*req.APIMethods,*constant,GuardianSv1.Ping&GuardianSv1.RemoteLock&GuardianSv1.RemoteUnlock,false,20 +cgrates.org,ATTR_API_SCHD_AUTH,*auth,*string:~*req.APIKey:sched12345,,,*req.APIMethods,*constant,SchedulerSv1.Ping,false,20 +cgrates.org,ATTR_API_CDRS_AUTH,*auth,*string:~*req.APIKey:cdrs12345,,,*req.APIMethods,*constant,CDRsV1.Ping&CDRsV1.ProcessEvent&CDRsV1.GetCDRs&CDRsV1.GetCDRsCount&CDRsV1.ProcessCDR&CDRsV1.ProcessExternalCDR,false,20 +cgrates.org,ATTR_API_DSP_AUTH,*auth,*string:~*req.APIKey:dsp12345,,,*req.APIMethods,*constant,DispatcherSv1.Ping&DispatcherSv1.GetProfileForEvent,false,20 +cgrates.org,ATTR_API_PSE_AUTH,*auth,*string:~*req.APIKey:pse12345,,,*req.APIMethods,*constant,SessionSv1.Ping&SessionSv1.AuthorizeEvent&SessionSv1.AuthorizeEventWithDigest&SessionSv1.InitiateSession&SessionSv1.InitiateSessionWithDigest&SessionSv1.UpdateSession&SessionSv1.SyncSessions&SessionSv1.TerminateSession&SessionSv1.ProcessCDR&SessionSv1.ProcessMessage&SessionSv1.GetActiveSessions&SessionSv1.GetActiveSessionsCount&SessionSv1.ForceDisconnect&SessionSv1.GetPassiveSessions&SessionSv1.GetPassiveSessionsCount&SessionSv1.ReplicateSessions&SessionSv1.SetPassiveSession&AttributeSv1.ProcessEvent&Responder.Debit&ResourceSv1.AllocateResources&ChargerSv1.ProcessEvent&Responder.MaxDebit,false,20 +cgrates.org,ATTR_API_CFG_AUTH,*auth,*string:~*req.APIKey:cfg12345,,,*req.APIMethods,*constant,ConfigSv1.GetJSONSection&ConfigSv1.ReloadConfig,false,20 +cgrates.org,ATTR_API_APIER_AUTH,*auth,*string:~*req.APIKey:apier12345,,,*req.APIMethods,*constant,ApierV1.GetAttributeProfile&ApierV1.SetAttributeProfile,false,20 +cgrates.org,ATTR_API_RALS_AUTH,*auth,*string:~*req.APIKey:rals12345,,,*req.APIMethods,*constant,RALsV1.Ping&RALsV1.GetRatingPlansCost,false,20 diff --git a/data/tariffplans/dispatchers_gob/Attributes.csv b/data/tariffplans/dispatchers_gob/Attributes.csv index 3f4e362d4..a07ee0570 100644 --- a/data/tariffplans/dispatchers_gob/Attributes.csv +++ b/data/tariffplans/dispatchers_gob/Attributes.csv @@ -1,22 +1,22 @@ #Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight -cgrates.org,ATTR_1001_SIMPLEAUTH,*any,*string:~*req.Account:1001,,,Password,*constant,CGRateS.org,false,20 +cgrates.org,ATTR_1001_SIMPLEAUTH,*any,*string:~*req.Account:1001,,,*req.Password,*constant,CGRateS.org,false,20 cgrates.org,ATTR_1001_SIMPLEAUTH,*any,,,,EventName,*constant,*remove,false,20 -cgrates.org,ATTR_1003_SIMPLEAUTH,*any,*string:~*req.Account:1003,,,Password,*constant,CGRateS.com,false,20 -cgrates.org,ATTR_API_ATTR_FAKE_AUTH,*auth,*string:~*req.APIKey:12345,,,APIMethods,*constant,,false,20 -cgrates.org,ATTR_API_ATTR_AUTH,*auth,*string:~*req.APIKey:attr12345,,,APIMethods,*constant,AttributeSv1.Ping&AttributeSv1.GetAttributeForEvent&AttributeSv1.ProcessEvent,false,20 -cgrates.org,ATTR_API_CHRG_AUTH,*auth,*string:~*req.APIKey:chrg12345,,,APIMethods,*constant,ChargerSv1.Ping&ChargerSv1.GetChargersForEvent&ChargerSv1.ProcessEvent,false,20 -cgrates.org,ATTR_API_THR_AUTH,*auth,*string:~*req.APIKey:thr12345,,,APIMethods,*constant,ThresholdSv1.Ping&ThresholdSv1.GetThresholdsForEvent&ThresholdSv1.ProcessEvent&ThresholdSv1.GetThreshold&ThresholdSv1.GetThresholdIDs,false,20 -cgrates.org,ATTR_API_SUP_AUTH,*auth,*string:~*req.APIKey:sup12345,,,APIMethods,*constant,SupplierSv1.Ping&SupplierSv1.GetSuppliers&SupplierSv1.GetSupplierProfilesForEvent,false,20 -cgrates.org,ATTR_API_STAT_AUTH,*auth,*string:~*req.APIKey:stat12345,,,APIMethods,*constant,StatSv1.Ping&StatSv1.GetStatQueuesForEvent&StatSv1.GetQueueStringMetrics&StatSv1.ProcessEvent&StatSv1.GetQueueIDs&StatSv1.GetQueueFloatMetrics,false,20 -cgrates.org,ATTR_API_RES_AUTH,*auth,*string:~*req.APIKey:res12345,,,APIMethods,*constant,ResourceSv1.Ping&ResourceSv1.GetResourcesForEvent&ResourceSv1.AuthorizeResources&ResourceSv1.AllocateResources&ResourceSv1.ReleaseResources,false,20 -cgrates.org,ATTR_API_SES_AUTH,*auth,*string:~*req.APIKey:ses12345,,,APIMethods,*constant,SessionSv1.Ping&SessionSv1.AuthorizeEvent&SessionSv1.AuthorizeEventWithDigest&SessionSv1.InitiateSession&SessionSv1.InitiateSessionWithDigest&SessionSv1.UpdateSession&SessionSv1.SyncSessions&SessionSv1.TerminateSession&SessionSv1.ProcessCDR&SessionSv1.ProcessMessage&SessionSv1.GetActiveSessions&SessionSv1.GetActiveSessionsCount&SessionSv1.ForceDisconnect&SessionSv1.GetPassiveSessions&SessionSv1.GetPassiveSessionsCount&SessionSv1.ReplicateSessions&SessionSv1.SetPassiveSession&SessionSv1.ProcessEvent,false,20 -cgrates.org,ATTR_API_RSP_AUTH,*auth,*string:~*req.APIKey:rsp12345,,,APIMethods,*constant,CoreSv1.Status&CoreSv1.Ping&Responder.Shutdown&Responder.Ping,false,20 -cgrates.org,ATTR_API_CHC_AUTH,*auth,*string:~*req.APIKey:chc12345,,,APIMethods,*constant,CacheSv1.Ping&CacheSv1.GetCacheStats&CacheSv1.LoadCache&CacheSv1.PrecacheStatus&CacheSv1.GetItemIDs&CacheSv1.HasItem&CacheSv1.GetItemExpiryTime&CacheSv1.ReloadCache&CacheSv1.RemoveItem&CacheSv1.FlushCache&CacheSv1.Clear,false,20 -cgrates.org,ATTR_API_GRD_AUTH,*auth,*string:~*req.APIKey:grd12345,,,APIMethods,*constant,GuardianSv1.Ping&GuardianSv1.RemoteLock&GuardianSv1.RemoteUnlock,false,20 -cgrates.org,ATTR_API_SCHD_AUTH,*auth,*string:~*req.APIKey:sched12345,,,APIMethods,*constant,SchedulerSv1.Ping,false,20 -cgrates.org,ATTR_API_CDRS_AUTH,*auth,*string:~*req.APIKey:cdrs12345,,,APIMethods,*constant,CDRsV1.Ping&CDRsV1.ProcessEvent&CDRsV1.GetCDRs&CDRsV1.GetCDRsCount&CDRsV1.ProcessCDR&CDRsV1.ProcessExternalCDR,false,20 -cgrates.org,ATTR_API_DSP_AUTH,*auth,*string:~*req.APIKey:dsp12345,,,APIMethods,*constant,DispatcherSv1.Ping&DispatcherSv1.GetProfileForEvent,false,20 -cgrates.org,ATTR_API_PSE_AUTH,*auth,*string:~*req.APIKey:pse12345,,,APIMethods,*constant,SessionSv1.Ping&SessionSv1.AuthorizeEvent&SessionSv1.AuthorizeEventWithDigest&SessionSv1.InitiateSession&SessionSv1.InitiateSessionWithDigest&SessionSv1.UpdateSession&SessionSv1.SyncSessions&SessionSv1.TerminateSession&SessionSv1.ProcessCDR&SessionSv1.ProcessMessage&SessionSv1.GetActiveSessions&SessionSv1.GetActiveSessionsCount&SessionSv1.ForceDisconnect&SessionSv1.GetPassiveSessions&SessionSv1.GetPassiveSessionsCount&SessionSv1.ReplicateSessions&SessionSv1.SetPassiveSession&AttributeSv1.ProcessEvent&Responder.Debit&ResourceSv1.AllocateResources&ChargerSv1.ProcessEvent&Responder.MaxDebit,false,20 -cgrates.org,ATTR_API_CFG_AUTH,*auth,*string:~*req.APIKey:cfg12345,,,APIMethods,*constant,ConfigSv1.GetJSONSection&ConfigSv1.ReloadConfig,false,20 -cgrates.org,ATTR_API_APIER_AUTH,*auth,*string:~*req.APIKey:apier12345,,,APIMethods,*constant,ApierV1.GetAttributeProfile&ApierV1.SetAttributeProfile,false,20 -cgrates.org,ATTR_API_RALS_AUTH,*auth,*string:~*req.APIKey:rals12345,,,APIMethods,*constant,RALsV1.Ping&RALsV1.GetRatingPlansCost,false,20 +cgrates.org,ATTR_1003_SIMPLEAUTH,*any,*string:~*req.Account:1003,,,*req.Password,*constant,CGRateS.com,false,20 +cgrates.org,ATTR_API_ATTR_FAKE_AUTH,*auth,*string:~*req.APIKey:12345,,,*req.APIMethods,*constant,,false,20 +cgrates.org,ATTR_API_ATTR_AUTH,*auth,*string:~*req.APIKey:attr12345,,,*req.APIMethods,*constant,AttributeSv1.Ping&AttributeSv1.GetAttributeForEvent&AttributeSv1.ProcessEvent,false,20 +cgrates.org,ATTR_API_CHRG_AUTH,*auth,*string:~*req.APIKey:chrg12345,,,*req.APIMethods,*constant,ChargerSv1.Ping&ChargerSv1.GetChargersForEvent&ChargerSv1.ProcessEvent,false,20 +cgrates.org,ATTR_API_THR_AUTH,*auth,*string:~*req.APIKey:thr12345,,,*req.APIMethods,*constant,ThresholdSv1.Ping&ThresholdSv1.GetThresholdsForEvent&ThresholdSv1.ProcessEvent&ThresholdSv1.GetThreshold&ThresholdSv1.GetThresholdIDs,false,20 +cgrates.org,ATTR_API_SUP_AUTH,*auth,*string:~*req.APIKey:sup12345,,,*req.APIMethods,*constant,SupplierSv1.Ping&SupplierSv1.GetSuppliers&SupplierSv1.GetSupplierProfilesForEvent,false,20 +cgrates.org,ATTR_API_STAT_AUTH,*auth,*string:~*req.APIKey:stat12345,,,*req.APIMethods,*constant,StatSv1.Ping&StatSv1.GetStatQueuesForEvent&StatSv1.GetQueueStringMetrics&StatSv1.ProcessEvent&StatSv1.GetQueueIDs&StatSv1.GetQueueFloatMetrics,false,20 +cgrates.org,ATTR_API_RES_AUTH,*auth,*string:~*req.APIKey:res12345,,,*req.APIMethods,*constant,ResourceSv1.Ping&ResourceSv1.GetResourcesForEvent&ResourceSv1.AuthorizeResources&ResourceSv1.AllocateResources&ResourceSv1.ReleaseResources,false,20 +cgrates.org,ATTR_API_SES_AUTH,*auth,*string:~*req.APIKey:ses12345,,,*req.APIMethods,*constant,SessionSv1.Ping&SessionSv1.AuthorizeEvent&SessionSv1.AuthorizeEventWithDigest&SessionSv1.InitiateSession&SessionSv1.InitiateSessionWithDigest&SessionSv1.UpdateSession&SessionSv1.SyncSessions&SessionSv1.TerminateSession&SessionSv1.ProcessCDR&SessionSv1.ProcessMessage&SessionSv1.GetActiveSessions&SessionSv1.GetActiveSessionsCount&SessionSv1.ForceDisconnect&SessionSv1.GetPassiveSessions&SessionSv1.GetPassiveSessionsCount&SessionSv1.ReplicateSessions&SessionSv1.SetPassiveSession&SessionSv1.ProcessEvent,false,20 +cgrates.org,ATTR_API_RSP_AUTH,*auth,*string:~*req.APIKey:rsp12345,,,*req.APIMethods,*constant,CoreSv1.Status&CoreSv1.Ping&Responder.Shutdown&Responder.Ping,false,20 +cgrates.org,ATTR_API_CHC_AUTH,*auth,*string:~*req.APIKey:chc12345,,,*req.APIMethods,*constant,CacheSv1.Ping&CacheSv1.GetCacheStats&CacheSv1.LoadCache&CacheSv1.PrecacheStatus&CacheSv1.GetItemIDs&CacheSv1.HasItem&CacheSv1.GetItemExpiryTime&CacheSv1.ReloadCache&CacheSv1.RemoveItem&CacheSv1.FlushCache&CacheSv1.Clear,false,20 +cgrates.org,ATTR_API_GRD_AUTH,*auth,*string:~*req.APIKey:grd12345,,,*req.APIMethods,*constant,GuardianSv1.Ping&GuardianSv1.RemoteLock&GuardianSv1.RemoteUnlock,false,20 +cgrates.org,ATTR_API_SCHD_AUTH,*auth,*string:~*req.APIKey:sched12345,,,*req.APIMethods,*constant,SchedulerSv1.Ping,false,20 +cgrates.org,ATTR_API_CDRS_AUTH,*auth,*string:~*req.APIKey:cdrs12345,,,*req.APIMethods,*constant,CDRsV1.Ping&CDRsV1.ProcessEvent&CDRsV1.GetCDRs&CDRsV1.GetCDRsCount&CDRsV1.ProcessCDR&CDRsV1.ProcessExternalCDR,false,20 +cgrates.org,ATTR_API_DSP_AUTH,*auth,*string:~*req.APIKey:dsp12345,,,*req.APIMethods,*constant,DispatcherSv1.Ping&DispatcherSv1.GetProfileForEvent,false,20 +cgrates.org,ATTR_API_PSE_AUTH,*auth,*string:~*req.APIKey:pse12345,,,*req.APIMethods,*constant,SessionSv1.Ping&SessionSv1.AuthorizeEvent&SessionSv1.AuthorizeEventWithDigest&SessionSv1.InitiateSession&SessionSv1.InitiateSessionWithDigest&SessionSv1.UpdateSession&SessionSv1.SyncSessions&SessionSv1.TerminateSession&SessionSv1.ProcessCDR&SessionSv1.ProcessMessage&SessionSv1.GetActiveSessions&SessionSv1.GetActiveSessionsCount&SessionSv1.ForceDisconnect&SessionSv1.GetPassiveSessions&SessionSv1.GetPassiveSessionsCount&SessionSv1.ReplicateSessions&SessionSv1.SetPassiveSession&AttributeSv1.ProcessEvent&Responder.Debit&ResourceSv1.AllocateResources&ChargerSv1.ProcessEvent&Responder.MaxDebit,false,20 +cgrates.org,ATTR_API_CFG_AUTH,*auth,*string:~*req.APIKey:cfg12345,,,*req.APIMethods,*constant,ConfigSv1.GetJSONSection&ConfigSv1.ReloadConfig,false,20 +cgrates.org,ATTR_API_APIER_AUTH,*auth,*string:~*req.APIKey:apier12345,,,*req.APIMethods,*constant,ApierV1.GetAttributeProfile&ApierV1.SetAttributeProfile,false,20 +cgrates.org,ATTR_API_RALS_AUTH,*auth,*string:~*req.APIKey:rals12345,,,*req.APIMethods,*constant,RALsV1.Ping&RALsV1.GetRatingPlansCost,false,20 diff --git a/data/tariffplans/dnsagent/Attributes.csv b/data/tariffplans/dnsagent/Attributes.csv index 651b27d1c..8ce6b217b 100644 --- a/data/tariffplans/dnsagent/Attributes.csv +++ b/data/tariffplans/dnsagent/Attributes.csv @@ -1,3 +1,3 @@ #Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight -cgrates.org,ATTR_NAPTR_ADDR,*any,*string:~*req.E164Address:4986517174964,,,NAPTRAddress,*constant,sip:\1@172.16.1.1.,false,20 +cgrates.org,ATTR_NAPTR_ADDR,*any,*string:~*req.E164Address:4986517174964,,,*req.NAPTRAddress,*constant,sip:\1@172.16.1.1.,false,20 diff --git a/data/tariffplans/oldtutorial/Attributes.csv b/data/tariffplans/oldtutorial/Attributes.csv index 41db7b3e4..21031d303 100644 --- a/data/tariffplans/oldtutorial/Attributes.csv +++ b/data/tariffplans/oldtutorial/Attributes.csv @@ -1,3 +1,3 @@ #Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight -cgrates.org,ATTR_1,*sessions;*cdrs,*string:~*req.Account:1007,2014-01-14T00:00:00Z,,Account,*constant,1001,false,10 -cgrates.org,ATTR_1,,,,,Subject,*constant,1001,, +cgrates.org,ATTR_1,*sessions;*cdrs,*string:~*req.Account:1007,2014-01-14T00:00:00Z,,*req.Account,*constant,1001,false,10 +cgrates.org,ATTR_1,,,,,*req.Subject,*constant,1001,, diff --git a/data/tariffplans/precache/Attributes.csv b/data/tariffplans/precache/Attributes.csv index 41db7b3e4..21031d303 100644 --- a/data/tariffplans/precache/Attributes.csv +++ b/data/tariffplans/precache/Attributes.csv @@ -1,3 +1,3 @@ #Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight -cgrates.org,ATTR_1,*sessions;*cdrs,*string:~*req.Account:1007,2014-01-14T00:00:00Z,,Account,*constant,1001,false,10 -cgrates.org,ATTR_1,,,,,Subject,*constant,1001,, +cgrates.org,ATTR_1,*sessions;*cdrs,*string:~*req.Account:1007,2014-01-14T00:00:00Z,,*req.Account,*constant,1001,false,10 +cgrates.org,ATTR_1,,,,,*req.Subject,*constant,1001,, diff --git a/data/tariffplans/testit/Attributes.csv b/data/tariffplans/testit/Attributes.csv index 5be22cc2f..53849032f 100644 --- a/data/tariffplans/testit/Attributes.csv +++ b/data/tariffplans/testit/Attributes.csv @@ -1,4 +1,4 @@ #Tenant,ID,Context,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight -cgrates.org,ATTR_ACNT_1001,*sessions,FLTR_ACCOUNT_1001,,,OfficeGroup,*constant,Marketing,false,10 -cgrates.org,ATTR_SUPPLIER1,*chargers,,,,Subject,*constant,SUPPLIER1,false,10 -cgrates.org,ATTR_PAYPAL,*cdrs,*string:~*req.Subject:ANY2CNT,,,PayPalAccount,*constant,paypal@cgrates.org,false,10 +cgrates.org,ATTR_ACNT_1001,*sessions,FLTR_ACCOUNT_1001,,,*req.OfficeGroup,*constant,Marketing,false,10 +cgrates.org,ATTR_SUPPLIER1,*chargers,,,,*req.Subject,*constant,SUPPLIER1,false,10 +cgrates.org,ATTR_PAYPAL,*cdrs,*string:~*req.Subject:ANY2CNT,,,*req.PayPalAccount,*constant,paypal@cgrates.org,false,10 diff --git a/data/tariffplans/testit/Chargers.csv b/data/tariffplans/testit/Chargers.csv index fc5456b60..df4000134 100644 --- a/data/tariffplans/testit/Chargers.csv +++ b/data/tariffplans/testit/Chargers.csv @@ -1,4 +1,4 @@ #Tenant,ID,FilterIDs,ActivationInterval,RunID,AttributeIDs,Weight -cgrates.org,Raw,,,*raw,*constant:RequestType:*none,20 +cgrates.org,Raw,,,*raw,*constant:*req.RequestType:*none,20 cgrates.org,CustomerCharges,,,CustomerCharges,*none,20 cgrates.org,SupplierCharges,,,SupplierCharges,ATTR_SUPPLIER1,10 \ No newline at end of file diff --git a/data/tariffplans/testtp/Attributes.csv b/data/tariffplans/testtp/Attributes.csv index 65fd8af84..fa48657eb 100644 --- a/data/tariffplans/testtp/Attributes.csv +++ b/data/tariffplans/testtp/Attributes.csv @@ -1,3 +1,3 @@ #Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight -cgrates.org,ALS1,con1,FLTR_1,2014-07-29T15:00:00Z,*string:Field1:Initial1,Field1,*constant,Sub1,false,20 -cgrates.org,ALS1,,,,*string:Field1:Initial2,Field2,*constant,Sub2,, +cgrates.org,ALS1,con1,FLTR_1,2014-07-29T15:00:00Z,*string:~*req.Field1:Initial1,*req.Field1,*constant,Sub1,false,20 +cgrates.org,ALS1,,,,*string:~*req.Field1:Initial2,*req.Field2,*constant,Sub2,, diff --git a/data/tariffplans/tutorial/Attributes.csv b/data/tariffplans/tutorial/Attributes.csv index a52b9d86a..2dabbde2d 100644 --- a/data/tariffplans/tutorial/Attributes.csv +++ b/data/tariffplans/tutorial/Attributes.csv @@ -1,24 +1,24 @@ #Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight -cgrates.org,ATTR_1001_SIMPLEAUTH,simpleauth,*string:~*req.Account:1001,,,Password,*constant,CGRateS.org,false,20 -cgrates.org,ATTR_1002_SIMPLEAUTH,simpleauth,*string:~*req.Account:1002,,,Password,*constant,CGRateS.org,false,20 -cgrates.org,ATTR_1003_SIMPLEAUTH,simpleauth,*string:~*req.Account:1003,,,Password,*constant,CGRateS.org,false,20 -cgrates.org,ATTR_1001_SESSIONAUTH,*sessions,*string:~*req.Account:1001,,,Password,*constant,CGRateS.org,false,10 -cgrates.org,ATTR_1001_SESSIONAUTH,,,,,RequestType,*constant,*prepaid,, -cgrates.org,ATTR_1001_SESSIONAUTH,,,,,PaypalAccount,*constant,cgrates@paypal.com,, -cgrates.org,ATTR_1001_SESSIONAUTH,,,,,LCRProfile,*constant,premium_cli,, -cgrates.org,ATTR_1002_SESSIONAUTH,*sessions,*string:~*req.Account:1002,,,Password,*constant,CGRateS.org,false,10 -cgrates.org,ATTR_1002_SESSIONAUTH,,,,,RequestType,*constant,*postpaid,, -cgrates.org,ATTR_1002_SESSIONAUTH,,,,,PaypalAccount,*constant,cgrates@paypal.com,, -cgrates.org,ATTR_1002_SESSIONAUTH,,,,,LCRProfile,*constant,premium_cli,, +cgrates.org,ATTR_1001_SIMPLEAUTH,simpleauth,*string:~*req.Account:1001,,,*req.Password,*constant,CGRateS.org,false,20 +cgrates.org,ATTR_1002_SIMPLEAUTH,simpleauth,*string:~*req.Account:1002,,,*req.Password,*constant,CGRateS.org,false,20 +cgrates.org,ATTR_1003_SIMPLEAUTH,simpleauth,*string:~*req.Account:1003,,,*req.Password,*constant,CGRateS.org,false,20 +cgrates.org,ATTR_1001_SESSIONAUTH,*sessions,*string:~*req.Account:1001,,,*req.Password,*constant,CGRateS.org,false,10 +cgrates.org,ATTR_1001_SESSIONAUTH,,,,,*req.RequestType,*constant,*prepaid,, +cgrates.org,ATTR_1001_SESSIONAUTH,,,,,*req.PaypalAccount,*constant,cgrates@paypal.com,, +cgrates.org,ATTR_1001_SESSIONAUTH,,,,,*req.LCRProfile,*constant,premium_cli,, +cgrates.org,ATTR_1002_SESSIONAUTH,*sessions,*string:~*req.Account:1002,,,*req.Password,*constant,CGRateS.org,false,10 +cgrates.org,ATTR_1002_SESSIONAUTH,,,,,*req.RequestType,*constant,*postpaid,, +cgrates.org,ATTR_1002_SESSIONAUTH,,,,,*req.PaypalAccount,*constant,cgrates@paypal.com,, +cgrates.org,ATTR_1002_SESSIONAUTH,,,,,*req.LCRProfile,*constant,premium_cli,, cgrates.org,ATTR_1002_SESSIONAUTH,,,,,ResourceAllocation,*constant,"ResGroup1",, -cgrates.org,ATTR_1003_SESSIONAUTH,*sessions,*string:~*req.Account:1003,,,Password,*constant,CGRateS.org,false,10 -cgrates.org,ATTR_1003_SESSIONAUTH,,,,,RequestType,*constant,*prepaid,, -cgrates.org,ATTR_1003_SESSIONAUTH,,,,,PaypalAccount,*constant,cgrates@paypal.com,, -cgrates.org,ATTR_1003_SESSIONAUTH,,,,,LCRProfile,*constant,premium_cli,, -cgrates.org,ATTR_ACC_ALIAS,*any,*string:~*req.SubscriberId:1006,,,Account,*constant,1001,false,10 -cgrates.org,ATTR_ACC_ALIAS,*any,,,,RequestType,*constant,*prepaid,, -cgrates.com,ATTR_TNT_ALIAS,*any,*string:~*req.SubscriberId:1006,,,Account,*constant,1001,false,10 -cgrates.com,ATTR_TNT_ALIAS,*any,,,,RequestType,*constant,*prepaid,, +cgrates.org,ATTR_1003_SESSIONAUTH,*sessions,*string:~*req.Account:1003,,,*req.Password,*constant,CGRateS.org,false,10 +cgrates.org,ATTR_1003_SESSIONAUTH,,,,,*req.RequestType,*constant,*prepaid,, +cgrates.org,ATTR_1003_SESSIONAUTH,,,,,*req.PaypalAccount,*constant,cgrates@paypal.com,, +cgrates.org,ATTR_1003_SESSIONAUTH,,,,,*req.LCRProfile,*constant,premium_cli,, +cgrates.org,ATTR_ACC_ALIAS,*any,*string:~*req.SubscriberId:1006,,,*req.Account,*constant,1001,false,10 +cgrates.org,ATTR_ACC_ALIAS,*any,,,,*req.RequestType,*constant,*prepaid,, +cgrates.com,ATTR_TNT_ALIAS,*any,*string:~*req.SubscriberId:1006,,,*req.Account,*constant,1001,false,10 +cgrates.com,ATTR_TNT_ALIAS,*any,,,,*req.RequestType,*constant,*prepaid,, cgrates.com,ATTR_TNT_ALIAS,*any,,,,*tenant,*constant,cgrates.org,, cgrates.com,ATTR_TNT_1001,*any,*string:~*req.Account:1001,,,*tenant,*constant,cgrates.org,, cgrates.com,ATTR_TNT_DISC,*any,*string:~*req.Account:testDiamInitWithSessionDisconnect,,,*tenant,*constant,cgrates.org,, diff --git a/data/tariffplans/tutorial/Chargers.csv b/data/tariffplans/tutorial/Chargers.csv index c58b582cb..7145717c7 100644 --- a/data/tariffplans/tutorial/Chargers.csv +++ b/data/tariffplans/tutorial/Chargers.csv @@ -1,3 +1,3 @@ #Tenant,ID,FilterIDs,ActivationInterval,RunID,AttributeIDs,Weight cgrates.org,DEFAULT,,,*default,*none,0 -cgrates.org,Raw,,,*raw,*constant:RequestType:*none,0 \ No newline at end of file +cgrates.org,Raw,,,*raw,*constant:*req.RequestType:*none,0 \ No newline at end of file diff --git a/data/tariffplans/tutorial2/Attributes.csv b/data/tariffplans/tutorial2/Attributes.csv index 66d04458c..bb9f34e9e 100644 --- a/data/tariffplans/tutorial2/Attributes.csv +++ b/data/tariffplans/tutorial2/Attributes.csv @@ -1,11 +1,11 @@ # Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight # ATTR_CRG_SUPPLIER1 replaces Category->supplier1 and RequestType->*constant for *sessions and *cdrs events -cgrates.org,ATTR_CRG_SUPPLIER1,*sessions;*cdrs,,,,Category,*constant,supplier1,false,0 -cgrates.org,ATTR_CRG_SUPPLIER1,,,,,RequestType,*constant,*rated,, +cgrates.org,ATTR_CRG_SUPPLIER1,*sessions;*cdrs,,,,*req.Category,*constant,supplier1,false,0 +cgrates.org,ATTR_CRG_SUPPLIER1,,,,,*req.RequestType,*constant,*rated,, # ATTR_1001_AUTH returns the Password value for the account 1001 in context -cgrates.org,ATTR_1001_AUTH,auth,*string:~*req.Account:1001,,,Password,*constant,CGRateS.org,false,20 +cgrates.org,ATTR_1001_AUTH,auth,*string:~*req.Account:1001,,,*req.Password,*constant,CGRateS.org,false,20 -cgrates.org,ATTR_1002_AUTH,auth,*string:~*req.Account:1002,,,Password,*constant,CGRateS.org,false,20 -cgrates.org,ATTR_1003_AUTH,auth,*string:~*req.Account:1003,,,Password,*constant,CGRateS.org,false,20 \ No newline at end of file +cgrates.org,ATTR_1002_AUTH,auth,*string:~*req.Account:1002,,,*req.Password,*constant,CGRateS.org,false,20 +cgrates.org,ATTR_1003_AUTH,auth,*string:~*req.Account:1003,,,*req.Password,*constant,CGRateS.org,false,20 \ No newline at end of file diff --git a/dispatchers/attributes_it_test.go b/dispatchers/attributes_it_test.go index 43c5e1296..75fc544e4 100755 --- a/dispatchers/attributes_it_test.go +++ b/dispatchers/attributes_it_test.go @@ -142,7 +142,7 @@ func testDspAttrGetAttrFailover(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{}, - FieldName: "Password", + FieldName: utils.MetaReq + utils.NestingSep + "Password", Type: utils.META_CONSTANT, Value: config.NewRSRParsersMustCompile("CGRateS.org", true, utils.INFIELD_SEP), }, @@ -156,7 +156,7 @@ func testDspAttrGetAttrFailover(t *testing.T) { eRply := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1002_SIMPLEAUTH"}, - AlteredFields: []string{"Password"}, + AlteredFields: []string{"*req.Password"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "testAttributeSGetAttributeForEvent", @@ -332,7 +332,7 @@ func testDspAttrTestAuthKey2(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{}, - FieldName: "Password", + FieldName: utils.MetaReq + utils.NestingSep + "Password", Type: utils.META_CONSTANT, Value: config.NewRSRParsersMustCompile("CGRateS.org", true, utils.INFIELD_SEP), }, @@ -357,7 +357,7 @@ func testDspAttrTestAuthKey2(t *testing.T) { eRply := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1001_SIMPLEAUTH"}, - AlteredFields: []string{"Password"}, + AlteredFields: []string{"*req.Password"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "testAttributeSGetAttributeForEvent", @@ -423,7 +423,7 @@ func testDspAttrGetAttrRoundRobin(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{}, - FieldName: "Password", + FieldName: utils.MetaReq + utils.NestingSep + "Password", Type: utils.META_CONSTANT, Value: config.NewRSRParsersMustCompile("CGRateS.org", true, utils.INFIELD_SEP), }, @@ -437,7 +437,7 @@ func testDspAttrGetAttrRoundRobin(t *testing.T) { eRply := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1002_SIMPLEAUTH"}, - AlteredFields: []string{"Password"}, + AlteredFields: []string{"*req.Password"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "testAttributeSGetAttributeForEvent", @@ -506,7 +506,7 @@ func testDspAttrGetAttrInternal(t *testing.T) { eRply := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1003_SIMPLEAUTH"}, - AlteredFields: []string{"Password"}, + AlteredFields: []string{"*req.Password"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "testAttributeSGetAttributeForEvent", diff --git a/dispatchers/chargers_it_test.go b/dispatchers/chargers_it_test.go index 27a9e9f26..2973afa1a 100755 --- a/dispatchers/chargers_it_test.go +++ b/dispatchers/chargers_it_test.go @@ -133,7 +133,7 @@ func testDspCppGetChtgFailover(t *testing.T) { ID: "Raw", FilterIDs: []string{}, RunID: utils.MetaRaw, - AttributeIDs: []string{"*constant:RequestType:*none"}, + AttributeIDs: []string{"*constant:*req.RequestType:*none"}, Weight: 0, }, ) @@ -222,7 +222,7 @@ func testDspCppTestAuthKey2(t *testing.T) { ID: "Raw", FilterIDs: []string{}, RunID: utils.MetaRaw, - AttributeIDs: []string{"*constant:RequestType:*none"}, + AttributeIDs: []string{"*constant:*req.RequestType:*none"}, Weight: 0, }, } @@ -285,7 +285,7 @@ func testDspCppGetChtgRoundRobin(t *testing.T) { ID: "Raw", FilterIDs: []string{}, RunID: utils.MetaRaw, - AttributeIDs: []string{"*constant:RequestType:*none"}, + AttributeIDs: []string{"*constant:*req.RequestType:*none"}, Weight: 0, }, ) diff --git a/dispatchers/dispatchers_it_test.go b/dispatchers/dispatchers_it_test.go index ad59caaa8..8a18ef393 100644 --- a/dispatchers/dispatchers_it_test.go +++ b/dispatchers/dispatchers_it_test.go @@ -61,7 +61,7 @@ func testDspApierSetAttributes(t *testing.T) { }, "Attributes": []*engine.Attribute{ { - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.RSRParsers{ &config.RSRParser{ Rules: "roam", @@ -95,7 +95,7 @@ func testDspApierGetAttributes(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.RSRParsers{ &config.RSRParser{ Rules: "roam", diff --git a/dispatchers/sessions_it_test.go b/dispatchers/sessions_it_test.go index ea4bbd9f0..6d6f560ae 100755 --- a/dispatchers/sessions_it_test.go +++ b/dispatchers/sessions_it_test.go @@ -365,7 +365,7 @@ func testDspSessionUpdate(t *testing.T) { } eAttrs := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_ACNT_1001"}, - AlteredFields: []string{"OfficeGroup"}, + AlteredFields: []string{"*req.OfficeGroup"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "TestSSv1ItUpdateSession", @@ -432,7 +432,7 @@ func testDspSessionUpdate2(t *testing.T) { } eAttrs := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1001_SESSIONAUTH"}, - AlteredFields: []string{"LCRProfile", "Password", "RequestType", "PaypalAccount"}, + AlteredFields: []string{"*req.LCRProfile", "*req.Password", "*req.RequestType", "*req.PaypalAccount"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "TestSSv1ItUpdateSession", @@ -581,7 +581,7 @@ func testDspSessionProcessEvent(t *testing.T) { } eAttrs := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_ACNT_1001"}, - AlteredFields: []string{"OfficeGroup"}, + AlteredFields: []string{"*req.OfficeGroup"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "TestSSv1ItProcessEvent", @@ -654,7 +654,7 @@ func testDspSessionProcessEvent2(t *testing.T) { } eAttrs := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1001_SIMPLEAUTH"}, - AlteredFields: []string{"Password", "EventName"}, + AlteredFields: []string{"*req.Password", "*req.EventName"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "TestSSv1ItProcessEvent", diff --git a/engine/attributes.go b/engine/attributes.go index ad6ef3630..998101680 100644 --- a/engine/attributes.go +++ b/engine/attributes.go @@ -137,6 +137,7 @@ type AttrSProcessEventReply struct { // format fldName1:fldVal1,fldName2:fldVal2 func (attrReply *AttrSProcessEventReply) Digest() (rplyDigest string) { for i, fld := range attrReply.AlteredFields { + fld = strings.TrimPrefix(fld, utils.MetaReq+utils.NestingSep) if _, has := attrReply.CGREvent.Event[fld]; !has { continue //maybe removed } @@ -167,8 +168,13 @@ func (alS *AttributeService) processEvent(args *AttrArgsProcessEvent) ( } rply = &AttrSProcessEventReply{ MatchedProfiles: []string{attrPrf.ID}, - CGREvent: args.Clone(), // do not need to coppy the event - blocker: attrPrf.Blocker} + CGREvent: &utils.CGREvent{ + Tenant: args.Tenant, + ID: args.ID, + Time: args.Time, + Event: make(map[string]interface{}), + }, + blocker: attrPrf.Blocker} evNm := config.NewNavigableMap(map[string]interface{}{utils.MetaReq: args.Event}) for _, attribute := range attrPrf.Attributes { //in case that we have filter for attribute send them to FilterS to be processed @@ -257,6 +263,14 @@ func (alS *AttributeService) processEvent(args *AttrArgsProcessEvent) ( if !utils.IsSliceMember(rply.AlteredFields, attribute.FieldName) { rply.AlteredFields = append(rply.AlteredFields, attribute.FieldName) } + if attribute.FieldName == utils.MetaTenant { + if attribute.Type == utils.META_COMPOSED { + args.CGREvent.Tenant += substitute + } else { + args.CGREvent.Tenant = substitute + } + continue + } if substitute == utils.MetaRemove { evNm.Remove(strings.Split(attribute.FieldName, utils.NestingSep)) continue @@ -272,7 +286,6 @@ func (alS *AttributeService) processEvent(args *AttrArgsProcessEvent) ( ev, err = evNm.FieldAsInterface([]string{utils.MetaReq}) if err != nil { if err.Error() == utils.ErrNotFound.Error() { - rply.CGREvent.Event = make(map[string]interface{}) return } return nil, err @@ -342,10 +355,9 @@ func (alS *AttributeService) V1ProcessEvent(args *AttrArgsProcessEvent, apiRply.MatchedProfiles = append(apiRply.MatchedProfiles, evRply.MatchedProfiles[0]) apiRply.CGREvent = evRply.CGREvent for _, fldName := range evRply.AlteredFields { - if utils.IsSliceMember(apiRply.AlteredFields, fldName) { - continue // only add processed fieldName once + if !utils.IsSliceMember(apiRply.AlteredFields, fldName) { + apiRply.AlteredFields = append(apiRply.AlteredFields, fldName) // only add processed fieldName once } - apiRply.AlteredFields = append(apiRply.AlteredFields, fldName) } if evRply.blocker { break diff --git a/engine/attributes_test.go b/engine/attributes_test.go index e699cc5e4..a5b8709ba 100644 --- a/engine/attributes_test.go +++ b/engine/attributes_test.go @@ -347,7 +347,7 @@ func TestAttributeEventReplyDigest2(t *testing.T) { func TestAttributeEventReplyDigest3(t *testing.T) { eRpl := &AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1"}, - AlteredFields: []string{"Subject"}, + AlteredFields: []string{"*req.Subject"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "testAttributeSProcessEvent", @@ -368,7 +368,7 @@ func TestAttributeEventReplyDigest3(t *testing.T) { func TestAttributeEventReplyDigest4(t *testing.T) { eRpl := &AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_1"}, - AlteredFields: []string{"Subject"}, + AlteredFields: []string{"*req.Subject"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "testAttributeSProcessEvent", diff --git a/engine/cdr.go b/engine/cdr.go index 9f09fe104..dc027bfc7 100644 --- a/engine/cdr.go +++ b/engine/cdr.go @@ -23,6 +23,7 @@ import ( "fmt" "math" "strconv" + "strings" "time" "github.com/cgrates/cgrates/config" @@ -537,6 +538,7 @@ func (cdr *CDR) AsCGREvent() *utils.CGREvent { // UpdateFromCGREvent will update CDR with event fields from CGREvent func (cdr *CDR) UpdateFromCGREvent(cgrEv *utils.CGREvent, fields []string) (err error) { for _, fldName := range fields { + fldName = strings.TrimPrefix(fldName, utils.MetaReq+utils.NestingSep) if _, has := cgrEv.Event[fldName]; !has { continue //maybe removed } diff --git a/engine/cdrs.go b/engine/cdrs.go index 0d263bac3..dcbd111b0 100644 --- a/engine/cdrs.go +++ b/engine/cdrs.go @@ -344,11 +344,6 @@ func (cdrS *CDRServer) attrSProcessEvent(cgrEv *utils.CGREventWithArgDispatcher) utils.AttributeSv1ProcessEvent, attrArgs, &rplyEv); err == nil && len(rplyEv.AlteredFields) != 0 { cgrEv.CGREvent = rplyEv.CGREvent - if tntIface, has := cgrEv.CGREvent.Event[utils.MetaTenant]; has { - // special case when we want to overwrite the tenant - cgrEv.CGREvent.Tenant = tntIface.(string) - delete(cgrEv.CGREvent.Event, utils.MetaTenant) - } } else if err.Error() == utils.ErrNotFound.Error() { err = nil // cancel ErrNotFound } diff --git a/general_tests/cdrs_processevent_it_test.go b/general_tests/cdrs_processevent_it_test.go index 9452a8b72..e881ee4cb 100644 --- a/general_tests/cdrs_processevent_it_test.go +++ b/general_tests/cdrs_processevent_it_test.go @@ -178,7 +178,7 @@ func testV1CDRsProcessEventAttrS(t *testing.T) { FilterIDs: []string{"*string:~*req.Account:1001"}, Attributes: []*engine.Attribute{ { - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.NewRSRParsersMustCompile("1011", true, utils.INFIELD_SEP), }, }, diff --git a/general_tests/sentinel_it_test.go b/general_tests/sentinel_it_test.go index cb8286b83..1933575e5 100755 --- a/general_tests/sentinel_it_test.go +++ b/general_tests/sentinel_it_test.go @@ -126,10 +126,10 @@ func testRedisSentinelSetGetAttribute(t *testing.T) { Tenant: "cgrates.org", ID: "ApierTest", Contexts: []string{utils.MetaSessionS, utils.MetaCDRs}, - FilterIDs: []string{"*string:Account:1001"}, + FilterIDs: []string{"*string:~*req.Account:1001"}, Attributes: []*engine.Attribute{ { - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, @@ -160,10 +160,10 @@ func testRedisSentinelInsertion(t *testing.T) { Tenant: "cgrates.org", ID: "ApierTest", Contexts: []string{utils.MetaSessionS, utils.MetaCDRs}, - FilterIDs: []string{"*string:Account:1001"}, + FilterIDs: []string{"*string:~*reqAccount:1001"}, Attributes: []*engine.Attribute{ { - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, @@ -244,10 +244,10 @@ func testRedisSentinelGetAttrAfterFailover(t *testing.T) { Tenant: "cgrates.org", ID: "ApierTest", Contexts: []string{utils.MetaSessionS, utils.MetaCDRs}, - FilterIDs: []string{"*string:Account:1001"}, + FilterIDs: []string{"*string:~*req.Account:1001"}, Attributes: []*engine.Attribute{ { - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, diff --git a/general_tests/session3_it_test.go b/general_tests/session3_it_test.go index 477458baf..f28a229e4 100644 --- a/general_tests/session3_it_test.go +++ b/general_tests/session3_it_test.go @@ -165,7 +165,7 @@ func testSes3ItProcessEvent(t *testing.T) { } eAttrs := &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_ACNT_1001"}, - AlteredFields: []string{"OfficeGroup"}, + AlteredFields: []string{"*req.OfficeGroup"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "TestSSv1ItProcessEvent", diff --git a/general_tests/sessions_concur_test.go b/general_tests/sessions_concur_test.go index 736fd3785..51b7c7f9b 100644 --- a/general_tests/sessions_concur_test.go +++ b/general_tests/sessions_concur_test.go @@ -132,7 +132,7 @@ func testSCncrLoadTP(t *testing.T) { Contexts: []string{utils.ANY}, Attributes: []*engine.ExternalAttribute{ { - FieldName: "TestType", + FieldName: utils.MetaReq + utils.NestingSep + "TestType", Value: "ConcurrentSessions", }, }, diff --git a/loaders/loader_it_test.go b/loaders/loader_it_test.go index 22c159269..7eaecfe73 100644 --- a/loaders/loader_it_test.go +++ b/loaders/loader_it_test.go @@ -173,13 +173,13 @@ func testLoaderCheckAttributes(t *testing.T) { Attributes: []*engine.Attribute{ &engine.Attribute{ FilterIDs: []string{"*string:~*req.Field1:Initial"}, - FieldName: "Field1", + FieldName: utils.MetaReq + utils.NestingSep + "Field1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Sub1", true, utils.INFIELD_SEP), }, &engine.Attribute{ FilterIDs: []string{}, - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Sub2", true, utils.INFIELD_SEP), }}, diff --git a/loaders/loader_test.go b/loaders/loader_test.go index 0dc8da752..cb171f2ad 100644 --- a/loaders/loader_test.go +++ b/loaders/loader_test.go @@ -111,13 +111,13 @@ func TestLoaderProcessContentSingleFile(t *testing.T) { Attributes: []*engine.Attribute{ &engine.Attribute{ FilterIDs: []string{"*string:~*req.Field1:Initial"}, - FieldName: "Field1", + FieldName: utils.MetaReq + utils.NestingSep + "Field1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Sub1", true, utils.INFIELD_SEP), }, &engine.Attribute{ FilterIDs: []string{}, - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Sub2", true, utils.INFIELD_SEP), }}, @@ -137,7 +137,7 @@ func TestLoaderProcessContentSingleFile(t *testing.T) { } func TestLoaderProcessContentMultiFiles(t *testing.T) { - file1CSV := `ignored,ignored,ignored,ignored,ignored,,Subject,1001,ignored,ignored` + file1CSV := `ignored,ignored,ignored,ignored,ignored,,*req.Subject,1001,ignored,ignored` file2CSV := `ignored,TestLoader2` data := engine.NewInternalDB(nil, nil, true, config.CgrConfig().DataDbCfg().Items) ldr := &Loader{ @@ -198,7 +198,7 @@ func TestLoaderProcessContentMultiFiles(t *testing.T) { Contexts: []string{utils.ANY}, Attributes: []*engine.Attribute{ &engine.Attribute{ - FieldName: "Subject", + FieldName: utils.MetaReq + utils.NestingSep + "Subject", FilterIDs: []string{}, Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }}, @@ -1151,13 +1151,13 @@ func TestLoaderRemoveContentSingleFile(t *testing.T) { Attributes: []*engine.Attribute{ &engine.Attribute{ FilterIDs: []string{"*string:~*req.Field1:Initial"}, - FieldName: "Field1", + FieldName: utils.MetaReq + utils.NestingSep + "Field1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Sub1", true, utils.INFIELD_SEP), }, &engine.Attribute{ FilterIDs: []string{}, - FieldName: "Field2", + FieldName: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Sub2", true, utils.INFIELD_SEP), }}, diff --git a/migrator/alias.go b/migrator/alias.go index 81a11b054..256355723 100644 --- a/migrator/alias.go +++ b/migrator/alias.go @@ -105,11 +105,15 @@ func alias2AtttributeProfile(alias *v1Alias, defaultTenant string) *engine.Attri } for fieldName, vals := range av.Pairs { for initial, substitute := range vals { + var fld string if fieldName == utils.Tenant { fieldName = utils.MetaTenant + fld = utils.MetaTenant + } else { + fld = utils.MetaReq + utils.NestingSep + fieldName } attr := &engine.Attribute{ - FieldName: utils.MetaReq + utils.NestingSep + fieldName, + FieldName: fld, Type: utils.MetaVariable, //default type for Attribute Value: config.NewRSRParsersMustCompile(substitute, true, utils.INFIELD_SEP), } diff --git a/migrator/alias_it_test.go b/migrator/alias_it_test.go index 4074ee493..ab483952c 100644 --- a/migrator/alias_it_test.go +++ b/migrator/alias_it_test.go @@ -144,13 +144,13 @@ func testAlsITMigrateAndMove(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ { - FieldName: "Account", + FieldName: utils.MetaReq + utils.NestingSep + "Account", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, { FilterIDs: []string{"*string:~*req.Category:call_1001"}, - FieldName: "Category", + FieldName: utils.MetaReq + utils.NestingSep + "Category", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("call_1002", true, utils.INFIELD_SEP), }, diff --git a/migrator/alias_test.go b/migrator/alias_test.go index 2c9cbb80b..9e33e247d 100644 --- a/migrator/alias_test.go +++ b/migrator/alias_test.go @@ -181,7 +181,7 @@ func TestAlias2AtttributeProfile(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:~*req.Account:1001"}, - FieldName: "Account", + FieldName: utils.MetaReq + utils.NestingSep + "Account", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, @@ -198,13 +198,13 @@ func TestAlias2AtttributeProfile(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:~*req.Account:1001"}, - FieldName: "Account", + FieldName: utils.MetaReq + utils.NestingSep + "Account", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, { FilterIDs: []string{"*string:~*req.Account:1003"}, - FieldName: "Account", + FieldName: utils.MetaReq + utils.NestingSep + "Account", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1004", true, utils.INFIELD_SEP), }, @@ -221,13 +221,13 @@ func TestAlias2AtttributeProfile(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:~*req.Account:1001"}, - FieldName: "Account", + FieldName: utils.MetaReq + utils.NestingSep + "Account", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, { FilterIDs: []string{"*string:~*req.Account:1003"}, - FieldName: "Account", + FieldName: utils.MetaReq + utils.NestingSep + "Account", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1004", true, utils.INFIELD_SEP), }, @@ -247,12 +247,12 @@ func TestAlias2AtttributeProfile(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ { - FieldName: "Account", + FieldName: utils.MetaReq + utils.NestingSep + "Account", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, { - FieldName: "Subject", + FieldName: utils.MetaReq + utils.NestingSep + "Subject", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("call_1001", true, utils.INFIELD_SEP), }, @@ -272,12 +272,12 @@ func TestAlias2AtttributeProfile(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ { - FieldName: "Account", + FieldName: utils.MetaReq + utils.NestingSep + "Account", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, { - FieldName: "Category", + FieldName: utils.MetaReq + utils.NestingSep + "Category", Type: utils.MetaVariable, FilterIDs: []string{"*string:~*req.Category:call_1001"}, Value: config.NewRSRParsersMustCompile("call_1002", true, utils.INFIELD_SEP), @@ -295,7 +295,7 @@ func TestAlias2AtttributeProfile(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.Category, + FieldName: utils.MetaReq + utils.NestingSep + utils.Category, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("somecateg_roam_fromz4", true, utils.INFIELD_SEP), }, diff --git a/migrator/derived_chargers_it_test.go b/migrator/derived_chargers_it_test.go index cd1f68120..7683e9a49 100644 --- a/migrator/derived_chargers_it_test.go +++ b/migrator/derived_chargers_it_test.go @@ -149,12 +149,12 @@ func testDCITMigrateAndMove(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ { - FieldName: utils.Account, + FieldName: utils.MetaReq + utils.NestingSep + utils.Account, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1004", true, utils.INFIELD_SEP), }, { - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("call_1003", true, utils.INFIELD_SEP), }, diff --git a/migrator/derived_chargers_test.go b/migrator/derived_chargers_test.go index 2c3b6d798..ec5ed4e09 100644 --- a/migrator/derived_chargers_test.go +++ b/migrator/derived_chargers_test.go @@ -53,7 +53,7 @@ func TestFieldinfo2Attribute(t *testing.T) { Initial: make([]*engine.Attribute, 0), Expected: []*engine.Attribute{ &engine.Attribute{ - FieldName: utils.Account, + FieldName: utils.MetaReq + utils.NestingSep + utils.Account, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP), }, @@ -65,7 +65,7 @@ func TestFieldinfo2Attribute(t *testing.T) { Initial: make([]*engine.Attribute, 0), Expected: []*engine.Attribute{ &engine.Attribute{ - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile(`~effective_caller_id_number:s/(\d+)/+$1/`, true, utils.INFIELD_SEP), }, @@ -76,19 +76,19 @@ func TestFieldinfo2Attribute(t *testing.T) { FieldInfo: "^call_1003", Initial: []*engine.Attribute{ &engine.Attribute{ - FieldName: utils.Account, + FieldName: utils.MetaReq + utils.NestingSep + utils.Account, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP), }, }, Expected: []*engine.Attribute{ &engine.Attribute{ - FieldName: utils.Account, + FieldName: utils.MetaReq + utils.NestingSep + utils.Account, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP), }, &engine.Attribute{ - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("call_1003", true, utils.INFIELD_SEP), }, @@ -128,12 +128,12 @@ func TestDerivedChargers2AttributeProfile(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ &engine.Attribute{ - FieldName: utils.Category, + FieldName: utils.MetaReq + utils.NestingSep + utils.Category, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("*voice", true, utils.INFIELD_SEP), }, &engine.Attribute{ - FieldName: utils.Account, + FieldName: utils.MetaReq + utils.NestingSep + utils.Account, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP), }, @@ -161,22 +161,22 @@ func TestDerivedChargers2AttributeProfile(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ &engine.Attribute{ - FieldName: utils.Category, + FieldName: utils.MetaReq + utils.NestingSep + utils.Category, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("*voice", true, utils.INFIELD_SEP), }, &engine.Attribute{ - FieldName: utils.Account, + FieldName: utils.MetaReq + utils.NestingSep + utils.Account, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP), }, &engine.Attribute{ - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("call_1003_to_1004", true, utils.INFIELD_SEP), }, &engine.Attribute{ - FieldName: utils.Destination, + FieldName: utils.MetaReq + utils.NestingSep + utils.Destination, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1004", true, utils.INFIELD_SEP), }, diff --git a/migrator/filters_it_test.go b/migrator/filters_it_test.go index 33e46b2a1..a90d0fbe8 100644 --- a/migrator/filters_it_test.go +++ b/migrator/filters_it_test.go @@ -162,7 +162,7 @@ func testFltrITMigrateAndMove(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:Account:1001"}, - FieldName: "Account", + FieldName: utils.MetaReq + utils.NestingSep + "Account", Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, }, @@ -177,7 +177,7 @@ func testFltrITMigrateAndMove(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:~*req.Account:1001"}, - FieldName: "Account", + FieldName: utils.MetaReq + utils.NestingSep + "Account", Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, }, @@ -329,7 +329,7 @@ func testFltrITMigratev2(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:~Account:1001"}, - FieldName: "Account", + FieldName: utils.MetaReq + utils.NestingSep + "Account", Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, }, @@ -344,7 +344,7 @@ func testFltrITMigratev2(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:~*req.Account:1001"}, - FieldName: "Account", + FieldName: utils.MetaReq + utils.NestingSep + "Account", Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, }, diff --git a/migrator/user.go b/migrator/user.go index 51861af35..5a35e965a 100644 --- a/migrator/user.go +++ b/migrator/user.go @@ -63,7 +63,7 @@ func userProfile2attributeProfile(user *v1UserProfile) (attr *engine.AttributePr } if user.Tenant != attr.Tenant { attr.Attributes = append(attr.Attributes, &engine.Attribute{ - FieldName: utils.MetaReq + utils.NestingSep + utils.MetaTenant, + FieldName: utils.MetaTenant, Value: config.NewRSRParsersMustCompile(user.Tenant, true, utils.INFIELD_SEP), Type: utils.META_CONSTANT, }) @@ -107,7 +107,7 @@ func (m *Migrator) migrateV1User2AttributeProfile() (err error) { if err := m.dmOut.DataManager().SetAttributeProfile(attr, true); err != nil { return err } - m.stats[utils.User] += 1 + m.stats[utils.User]++ } if m.dryRun { return diff --git a/migrator/user_it_test.go b/migrator/user_it_test.go index f5164e3be..25bd50fdc 100644 --- a/migrator/user_it_test.go +++ b/migrator/user_it_test.go @@ -130,20 +130,20 @@ func testUsrITMigrateAndMove(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaTenant, - Type: utils.META_CONSTANT, - Value: config.NewRSRParsersMustCompile("cgrates.com", true, utils.INFIELD_SEP), - }, - { - FieldName: utils.RequestType, + FieldName: utils.MetaReq + utils.NestingSep + utils.RequestType, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("*prepaid", true, utils.INFIELD_SEP), }, { - FieldName: "msisdn", + FieldName: utils.MetaReq + utils.NestingSep + "msisdn", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("123423534646752", true, utils.INFIELD_SEP), }, + { + FieldName: utils.MetaTenant, + Type: utils.META_CONSTANT, + Value: config.NewRSRParsersMustCompile("cgrates.com", true, utils.INFIELD_SEP), + }, }, Blocker: false, Weight: 10, diff --git a/migrator/user_test.go b/migrator/user_test.go index 0f009b559..3ef631086 100644 --- a/migrator/user_test.go +++ b/migrator/user_test.go @@ -103,16 +103,16 @@ func TestUserProfile2attributeProfile(t *testing.T) { FilterIDs: []string{"*string:~Account:1002"}, ActivationInterval: nil, Attributes: []*engine.Attribute{ + { + FieldName: utils.MetaReq + utils.NestingSep + "Subject", + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("call_1001", true, utils.INFIELD_SEP), + }, { FieldName: utils.MetaTenant, Type: utils.META_CONSTANT, Value: config.NewRSRParsersMustCompile(usrTenant, true, utils.INFIELD_SEP), }, - { - FieldName: "Subject", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("call_1001", true, utils.INFIELD_SEP), - }, }, Blocker: false, Weight: 10, @@ -127,12 +127,12 @@ func TestUserProfile2attributeProfile(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ { - FieldName: utils.RequestType, + FieldName: utils.MetaReq + utils.NestingSep + utils.RequestType, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("*prepaid", true, utils.INFIELD_SEP), }, { - FieldName: "msisdn", + FieldName: utils.MetaReq + utils.NestingSep + "msisdn", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("123423534646752", true, utils.INFIELD_SEP), }, @@ -147,16 +147,16 @@ func TestUserProfile2attributeProfile(t *testing.T) { FilterIDs: []string{"*string:~Account:1002"}, ActivationInterval: nil, Attributes: []*engine.Attribute{ + { + FieldName: utils.MetaReq + utils.NestingSep + utils.RequestType, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("*prepaid", true, utils.INFIELD_SEP), + }, { FieldName: utils.MetaTenant, Type: utils.META_CONSTANT, Value: config.NewRSRParsersMustCompile(usrTenant, true, utils.INFIELD_SEP), }, - { - FieldName: utils.RequestType, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("*prepaid", true, utils.INFIELD_SEP), - }, }, Blocker: false, Weight: 10, @@ -171,30 +171,30 @@ func TestUserProfile2attributeProfile(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaTenant, - Type: utils.META_CONSTANT, - Value: config.NewRSRParsersMustCompile(usrTenant, true, utils.INFIELD_SEP), - }, - { - FieldName: utils.RequestType, + FieldName: utils.MetaReq + utils.NestingSep + utils.RequestType, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("*prepaid", true, utils.INFIELD_SEP), }, { - FieldName: utils.Subject, + FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("acnt63", true, utils.INFIELD_SEP), }, { - FieldName: "imsi", + FieldName: utils.MetaReq + utils.NestingSep + "imsi", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("12345", true, utils.INFIELD_SEP), }, { - FieldName: "msisdn", + FieldName: utils.MetaReq + utils.NestingSep + "msisdn", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("12345", true, utils.INFIELD_SEP), }, + { + FieldName: utils.MetaTenant, + Type: utils.META_CONSTANT, + Value: config.NewRSRParsersMustCompile(usrTenant, true, utils.INFIELD_SEP), + }, }, Blocker: false, Weight: 10, @@ -209,7 +209,7 @@ func TestUserProfile2attributeProfile(t *testing.T) { return rply.Attributes[i].FieldName < rply.Attributes[j].FieldName }) // only for test; map returns random keys if !reflect.DeepEqual(expected[i], rply) { - t.Errorf("For %v expected: %s ,\nreceived: %s ", i, utils.ToIJSON(expected[i]), utils.ToIJSON(rply)) + t.Errorf("For %v expected: %s ,\nreceived: %s ", i, utils.ToJSON(expected[i]), utils.ToJSON(rply)) } } } diff --git a/sessions/sessions.go b/sessions/sessions.go index 86fb262b0..597302937 100644 --- a/sessions/sessions.go +++ b/sessions/sessions.go @@ -1755,6 +1755,7 @@ func (v1AuthReply *V1AuthorizeReply) AsNavigableMap( if v1AuthReply.Attributes != nil { attrs := make(map[string]interface{}) for _, fldName := range v1AuthReply.Attributes.AlteredFields { + fldName = strings.TrimPrefix(fldName, utils.MetaReq+utils.NestingSep) if v1AuthReply.Attributes.CGREvent.HasField(fldName) { attrs[fldName] = v1AuthReply.Attributes.CGREvent.Event[fldName] } @@ -1819,11 +1820,6 @@ func (sS *SessionS) BiRPCv1AuthorizeEvent(clnt rpcclient.ClientConnector, args.AttributeIDs) if err == nil { args.CGREvent = rplyAttr.CGREvent - if tntIface, has := args.CGREvent.Event[utils.MetaTenant]; has { - // special case when we want to overwrite the tenant - args.CGREvent.Tenant = tntIface.(string) - delete(args.CGREvent.Event, utils.MetaTenant) - } authReply.Attributes = &rplyAttr } else if err.Error() != utils.ErrNotFound.Error() { return utils.NewErrAttributeS(err) @@ -2028,6 +2024,7 @@ func (v1Rply *V1InitSessionReply) AsNavigableMap( if v1Rply.Attributes != nil { attrs := make(map[string]interface{}) for _, fldName := range v1Rply.Attributes.AlteredFields { + fldName = strings.TrimPrefix(fldName, utils.MetaReq+utils.NestingSep) if v1Rply.Attributes.CGREvent.HasField(fldName) { attrs[fldName] = v1Rply.Attributes.CGREvent.Event[fldName] } @@ -2090,11 +2087,6 @@ func (sS *SessionS) BiRPCv1InitiateSession(clnt rpcclient.ClientConnector, args.AttributeIDs) if err == nil { args.CGREvent = rplyAttr.CGREvent.Clone() // avoid concurrency with rply.Attributes - if tntIface, has := args.CGREvent.Event[utils.MetaTenant]; has { - // special case when we want to overwrite the tenant - args.CGREvent.Tenant = tntIface.(string) - delete(args.CGREvent.Event, utils.MetaTenant) - } rply.Attributes = &rplyAttr } else if err.Error() != utils.ErrNotFound.Error() { return utils.NewErrAttributeS(err) @@ -2262,6 +2254,7 @@ func (v1Rply *V1UpdateSessionReply) AsNavigableMap( if v1Rply.Attributes != nil { attrs := make(map[string]interface{}) for _, fldName := range v1Rply.Attributes.AlteredFields { + fldName = strings.TrimPrefix(fldName, utils.MetaReq+utils.NestingSep) if v1Rply.Attributes.CGREvent.HasField(fldName) { attrs[fldName] = v1Rply.Attributes.CGREvent.Event[fldName] } @@ -2313,11 +2306,6 @@ func (sS *SessionS) BiRPCv1UpdateSession(clnt rpcclient.ClientConnector, args.AttributeIDs) if err == nil { args.CGREvent = rplyAttr.CGREvent.Clone() - if tntIface, has := args.CGREvent.Event[utils.MetaTenant]; has { - // special case when we want to overwrite the tenant - args.CGREvent.Tenant = tntIface.(string) - delete(args.CGREvent.Event, utils.MetaTenant) - } rply.Attributes = &rplyAttr } else if err.Error() != utils.ErrNotFound.Error() { return utils.NewErrAttributeS(err) @@ -2738,6 +2726,7 @@ func (v1Rply *V1ProcessMessageReply) AsNavigableMap( if v1Rply.Attributes != nil { attrs := make(map[string]interface{}) for _, fldName := range v1Rply.Attributes.AlteredFields { + fldName = strings.TrimPrefix(fldName, utils.MetaReq+utils.NestingSep) if v1Rply.Attributes.CGREvent.HasField(fldName) { attrs[fldName] = v1Rply.Attributes.CGREvent.Event[fldName] } @@ -2796,11 +2785,6 @@ func (sS *SessionS) BiRPCv1ProcessMessage(clnt rpcclient.ClientConnector, args.AttributeIDs) if err == nil { args.CGREvent = rplyAttr.CGREvent - if tntIface, has := args.CGREvent.Event[utils.MetaTenant]; has { - // special case when we want to overwrite the tenant - args.CGREvent.Tenant = tntIface.(string) - delete(args.CGREvent.Event, utils.MetaTenant) - } rply.Attributes = &rplyAttr } else if err.Error() != utils.ErrNotFound.Error() { return utils.NewErrAttributeS(err) @@ -2915,6 +2899,7 @@ func (v1Rply *V1ProcessEventReply) AsNavigableMap( if v1Rply.Attributes != nil { attrs := make(map[string]interface{}) for _, fldName := range v1Rply.Attributes.AlteredFields { + fldName = strings.TrimPrefix(fldName, utils.MetaReq+utils.NestingSep) if v1Rply.Attributes.CGREvent.HasField(fldName) { attrs[fldName] = v1Rply.Attributes.CGREvent.Event[fldName] } @@ -2980,11 +2965,6 @@ func (sS *SessionS) BiRPCv1ProcessEvent(clnt rpcclient.ClientConnector, argsFlagsWithParams.ParamsSlice(utils.MetaAttributes)) if err == nil { args.CGREvent = rplyAttr.CGREvent.Clone() - if tntIface, has := args.CGREvent.Event[utils.MetaTenant]; has { - // special case when we want to overwrite the tenant - args.CGREvent.Tenant = tntIface.(string) - delete(args.CGREvent.Event, utils.MetaTenant) - } rply.Attributes = &rplyAttr } else if err.Error() != utils.ErrNotFound.Error() { return utils.NewErrAttributeS(err) diff --git a/sessions/sessions_test.go b/sessions/sessions_test.go index 2f3547815..ea77b8399 100644 --- a/sessions/sessions_test.go +++ b/sessions/sessions_test.go @@ -34,7 +34,7 @@ import ( var attrs = &engine.AttrSProcessEventReply{ MatchedProfiles: []string{"ATTR_ACNT_1001"}, - AlteredFields: []string{"OfficeGroup"}, + AlteredFields: []string{"*req.OfficeGroup"}, CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "TestSSv1ItAuth", From c17dc6cd468e83f6d8681ee85548b4ce6c805cab Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 17 Jan 2020 13:15:48 +0200 Subject: [PATCH 03/14] Updated integration tests --- apier/v1/sessions_process_event_it_test.go | 10 +++--- .../dispatchers_internal/cgrates.json | 14 +++------ .../dispatchers_mongo/cgrates.json | 15 +++------ .../dispatchers_mysql/cgrates.json | 15 +++------ data/tariffplans/dispatchers/Attributes.csv | 2 +- engine/attributes.go | 31 ++++--------------- 6 files changed, 24 insertions(+), 63 deletions(-) diff --git a/apier/v1/sessions_process_event_it_test.go b/apier/v1/sessions_process_event_it_test.go index 2f461cf9c..aa73ff037 100644 --- a/apier/v1/sessions_process_event_it_test.go +++ b/apier/v1/sessions_process_event_it_test.go @@ -43,12 +43,12 @@ var sTestSessionSv1ProcessEvent = []func(t *testing.T){ testSSv1ItRpcConn, testSSv1ItPing, testSSv1ItTPFromFolder, - // testSSv1ItProcessEventAuth, + testSSv1ItProcessEventAuth, testSSv1ItProcessEventInitiateSession, - // testSSv1ItProcessEventUpdateSession, - // testSSv1ItProcessEventTerminateSession, - // testSSv1ItProcessCDRForSessionFromProcessEvent, - // testSSv1ItGetCDRs, + testSSv1ItProcessEventUpdateSession, + testSSv1ItProcessEventTerminateSession, + testSSv1ItProcessCDRForSessionFromProcessEvent, + testSSv1ItGetCDRs, testSSv1ItStopCgrEngine, } diff --git a/data/conf/samples/dispatchers/dispatchers_internal/cgrates.json b/data/conf/samples/dispatchers/dispatchers_internal/cgrates.json index c31e657ac..7c4efb2f7 100644 --- a/data/conf/samples/dispatchers/dispatchers_internal/cgrates.json +++ b/data/conf/samples/dispatchers/dispatchers_internal/cgrates.json @@ -50,19 +50,13 @@ "enabled": true, }, - "rpc_conns": { - "conn1": { - "strategy": "*first", - "conns": [{"address": "127.0.0.1:2012", "transport":"*json"}], - }, - }, "sessions": { "enabled": true, - "attributes_conns": ["conn1"], - "rals_conns": ["conn1"], - "resources_conns": ["conn1"], - "chargers_conns": ["conn1"], + "attributes_conns": ["*localhost"], + "rals_conns": ["*localhost"], + "resources_conns": ["*localhost"], + "chargers_conns": ["*localhost"], "listen_bijson": ":3014", }, diff --git a/data/conf/samples/dispatchers/dispatchers_mongo/cgrates.json b/data/conf/samples/dispatchers/dispatchers_mongo/cgrates.json index a991c2a98..a61e81682 100644 --- a/data/conf/samples/dispatchers/dispatchers_mongo/cgrates.json +++ b/data/conf/samples/dispatchers/dispatchers_mongo/cgrates.json @@ -53,19 +53,12 @@ "enabled": true, }, -"rpc_conns": { - "conn1": { - "strategy": "*first", - "conns": [{"address": "127.0.0.1:2012", "transport":"*json"}], - }, -}, - "sessions": { "enabled": true, - "attributes_conns": ["conn1"], - "rals_conns": ["conn1"], - "resources_conns": ["conn1"], - "chargers_conns": ["conn1"], + "attributes_conns": ["*localhost"], + "rals_conns": ["*localhost"], + "resources_conns": ["*localhost"], + "chargers_conns": ["*localhost"], "listen_bijson": ":3014", }, diff --git a/data/conf/samples/dispatchers/dispatchers_mysql/cgrates.json b/data/conf/samples/dispatchers/dispatchers_mysql/cgrates.json index 386e45435..1fd1c9de9 100755 --- a/data/conf/samples/dispatchers/dispatchers_mysql/cgrates.json +++ b/data/conf/samples/dispatchers/dispatchers_mysql/cgrates.json @@ -44,19 +44,12 @@ "enabled": true, }, -"rpc_conns": { - "conn1": { - "strategy": "*first", - "conns": [{"address": "127.0.0.1:2012", "transport":"*json"}], - }, -}, - "sessions": { "enabled": true, - "attributes_conns": ["conn1"], - "rals_conns": ["conn1"], - "resources_conns": ["conn1"], - "chargers_conns": ["conn1"], + "attributes_conns": ["*localhost"], + "rals_conns": ["*localhost"], + "resources_conns": ["*localhost"], + "chargers_conns": ["*localhost"], "listen_bijson": ":3014", }, diff --git a/data/tariffplans/dispatchers/Attributes.csv b/data/tariffplans/dispatchers/Attributes.csv index a07ee0570..5f004a8e6 100644 --- a/data/tariffplans/dispatchers/Attributes.csv +++ b/data/tariffplans/dispatchers/Attributes.csv @@ -1,6 +1,6 @@ #Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight cgrates.org,ATTR_1001_SIMPLEAUTH,*any,*string:~*req.Account:1001,,,*req.Password,*constant,CGRateS.org,false,20 -cgrates.org,ATTR_1001_SIMPLEAUTH,*any,,,,EventName,*constant,*remove,false,20 +cgrates.org,ATTR_1001_SIMPLEAUTH,*any,,,,*req.EventName,*constant,*remove,false,20 cgrates.org,ATTR_1003_SIMPLEAUTH,*any,*string:~*req.Account:1003,,,*req.Password,*constant,CGRateS.com,false,20 cgrates.org,ATTR_API_ATTR_FAKE_AUTH,*auth,*string:~*req.APIKey:12345,,,*req.APIMethods,*constant,,false,20 cgrates.org,ATTR_API_ATTR_AUTH,*auth,*string:~*req.APIKey:attr12345,,,*req.APIMethods,*constant,AttributeSv1.Ping&AttributeSv1.GetAttributeForEvent&AttributeSv1.ProcessEvent,false,20 diff --git a/engine/attributes.go b/engine/attributes.go index 998101680..0a4c5cc84 100644 --- a/engine/attributes.go +++ b/engine/attributes.go @@ -168,14 +168,9 @@ func (alS *AttributeService) processEvent(args *AttrArgsProcessEvent) ( } rply = &AttrSProcessEventReply{ MatchedProfiles: []string{attrPrf.ID}, - CGREvent: &utils.CGREvent{ - Tenant: args.Tenant, - ID: args.ID, - Time: args.Time, - Event: make(map[string]interface{}), - }, - blocker: attrPrf.Blocker} - evNm := config.NewNavigableMap(map[string]interface{}{utils.MetaReq: args.Event}) + CGREvent: args.CGREvent, + blocker: attrPrf.Blocker} + evNm := config.NewNavigableMap(map[string]interface{}{utils.MetaReq: rply.CGREvent.Event}) for _, attribute := range attrPrf.Attributes { //in case that we have filter for attribute send them to FilterS to be processed if len(attribute.FilterIDs) != 0 { @@ -265,9 +260,9 @@ func (alS *AttributeService) processEvent(args *AttrArgsProcessEvent) ( } if attribute.FieldName == utils.MetaTenant { if attribute.Type == utils.META_COMPOSED { - args.CGREvent.Tenant += substitute + rply.CGREvent.Tenant += substitute } else { - args.CGREvent.Tenant = substitute + rply.CGREvent.Tenant = substitute } continue } @@ -282,18 +277,6 @@ func (alS *AttributeService) processEvent(args *AttrArgsProcessEvent) ( } evNm.Set(strings.Split(attribute.FieldName, utils.NestingSep), substitute, false, false) } - var ev interface{} - ev, err = evNm.FieldAsInterface([]string{utils.MetaReq}) - if err != nil { - if err.Error() == utils.ErrNotFound.Error() { - return - } - return nil, err - } - var ok bool - if rply.CGREvent.Event, ok = ev.(map[string]interface{}); !ok { - return nil, fmt.Errorf("invalid event") - } return } @@ -327,6 +310,7 @@ func (alS *AttributeService) V1ProcessEvent(args *AttrArgsProcessEvent, args.ProcessRuns = utils.IntPointer(alS.cgrcfg.AttributeSCfg().ProcessRuns) } var apiRply *AttrSProcessEventReply // aggregate response here + args.CGREvent = args.CGREvent.Clone() for i := 0; i < *args.ProcessRuns; i++ { var evRply *AttrSProcessEventReply evRply, err = alS.processEvent(args) @@ -338,9 +322,6 @@ func (alS *AttributeService) V1ProcessEvent(args *AttrArgsProcessEvent, } break } - if len(evRply.AlteredFields) != 0 { - args.CGREvent = evRply.CGREvent // for next loop - } if apiRply == nil { // first reply apiRply = evRply if apiRply.blocker { From 5465d8c56511e1d95e176b57a458d010d8cf5782 Mon Sep 17 00:00:00 2001 From: adragusin Date: Fri, 17 Jan 2020 17:55:00 +0200 Subject: [PATCH 04/14] Updated IT tests --- agents/diam_it_test.go | 16 -- agents/dnsagent_it_test.go | 49 +++-- agents/httpagent_it_test.go | 107 ++++++----- agents/lib_test.go | 47 +++++ cmd/cgr-engine/cgr-engine.go | 2 +- .../attributes.json | 0 .../samples/dnsagent_internal/cgrates.json | 76 ++++++++ .../dryrun.json | 0 .../suppliers.json | 0 .../samples/dnsagent_mongo/attributes.json | 31 ++++ data/conf/samples/dnsagent_mongo/cgrates.json | 81 +++++++++ data/conf/samples/dnsagent_mongo/dryrun.json | 24 +++ .../samples/dnsagent_mongo/suppliers.json | 66 +++++++ .../samples/dnsagent_mysql/attributes.json | 31 ++++ .../{dnsagent => dnsagent_mysql}/cgrates.json | 0 data/conf/samples/dnsagent_mysql/dryrun.json | 24 +++ .../samples/dnsagent_mysql/suppliers.json | 66 +++++++ .../samples/httpagent_internal/cgrates.json | 64 +++++++ .../httpagent.json | 0 .../httpagent_internal_gob/cgrates.json | 71 ++++++++ .../httpagent.json | 0 .../conf/samples/httpagent_mongo/cgrates.json | 67 +++++++ .../samples/httpagent_mongo/httpagent.json | 168 +++++++++++++++++ .../samples/httpagent_mongo_gob/cgrates.json | 73 ++++++++ .../httpagent_mongo_gob/httpagent.json | 168 +++++++++++++++++ .../cgrates.json | 0 .../samples/httpagent_mysql/httpagent.json | 168 +++++++++++++++++ .../cgrates.json | 0 .../httpagent_mysql_gob/httpagent.json | 168 +++++++++++++++++ .../httpagenttls_internal/cgrates.json | 75 ++++++++ .../httpagent.json | 0 .../httpagenttls_internal_gob/cgrates.json | 84 +++++++++ .../httpagent.json | 0 .../samples/httpagenttls_mongo/cgrates.json | 77 ++++++++ .../samples/httpagenttls_mongo/httpagent.json | 169 ++++++++++++++++++ .../httpagenttls_mongo_gob/cgrates.json | 85 +++++++++ .../httpagenttls_mongo_gob/httpagent.json | 169 ++++++++++++++++++ .../cgrates.json | 0 .../samples/httpagenttls_mysql/httpagent.json | 169 ++++++++++++++++++ .../cgrates.json | 0 .../httpagenttls_mysql_gob/httpagent.json | 169 ++++++++++++++++++ integration_test.sh | 17 +- loaders/lib_test.go | 47 +++++ loaders/loader_it_test.go | 70 ++++---- 44 files changed, 2577 insertions(+), 121 deletions(-) create mode 100644 agents/lib_test.go rename data/conf/samples/{dnsagent => dnsagent_internal}/attributes.json (100%) create mode 100644 data/conf/samples/dnsagent_internal/cgrates.json rename data/conf/samples/{dnsagent => dnsagent_internal}/dryrun.json (100%) rename data/conf/samples/{dnsagent => dnsagent_internal}/suppliers.json (100%) create mode 100644 data/conf/samples/dnsagent_mongo/attributes.json create mode 100644 data/conf/samples/dnsagent_mongo/cgrates.json create mode 100644 data/conf/samples/dnsagent_mongo/dryrun.json create mode 100644 data/conf/samples/dnsagent_mongo/suppliers.json create mode 100644 data/conf/samples/dnsagent_mysql/attributes.json rename data/conf/samples/{dnsagent => dnsagent_mysql}/cgrates.json (100%) create mode 100644 data/conf/samples/dnsagent_mysql/dryrun.json create mode 100644 data/conf/samples/dnsagent_mysql/suppliers.json create mode 100644 data/conf/samples/httpagent_internal/cgrates.json rename data/conf/samples/{httpagent => httpagent_internal}/httpagent.json (100%) create mode 100644 data/conf/samples/httpagent_internal_gob/cgrates.json rename data/conf/samples/{httpagent_gob => httpagent_internal_gob}/httpagent.json (100%) create mode 100644 data/conf/samples/httpagent_mongo/cgrates.json create mode 100644 data/conf/samples/httpagent_mongo/httpagent.json create mode 100644 data/conf/samples/httpagent_mongo_gob/cgrates.json create mode 100644 data/conf/samples/httpagent_mongo_gob/httpagent.json rename data/conf/samples/{httpagent => httpagent_mysql}/cgrates.json (100%) create mode 100644 data/conf/samples/httpagent_mysql/httpagent.json rename data/conf/samples/{httpagent_gob => httpagent_mysql_gob}/cgrates.json (100%) create mode 100644 data/conf/samples/httpagent_mysql_gob/httpagent.json create mode 100755 data/conf/samples/httpagenttls_internal/cgrates.json rename data/conf/samples/{httpagenttls => httpagenttls_internal}/httpagent.json (100%) create mode 100755 data/conf/samples/httpagenttls_internal_gob/cgrates.json rename data/conf/samples/{httpagenttls_gob => httpagenttls_internal_gob}/httpagent.json (100%) create mode 100755 data/conf/samples/httpagenttls_mongo/cgrates.json create mode 100755 data/conf/samples/httpagenttls_mongo/httpagent.json create mode 100755 data/conf/samples/httpagenttls_mongo_gob/cgrates.json create mode 100755 data/conf/samples/httpagenttls_mongo_gob/httpagent.json rename data/conf/samples/{httpagenttls => httpagenttls_mysql}/cgrates.json (100%) create mode 100755 data/conf/samples/httpagenttls_mysql/httpagent.json rename data/conf/samples/{httpagenttls_gob => httpagenttls_mysql_gob}/cgrates.json (100%) create mode 100755 data/conf/samples/httpagenttls_mysql_gob/httpagent.json create mode 100644 loaders/lib_test.go diff --git a/agents/diam_it_test.go b/agents/diam_it_test.go index a0afedadf..3eff867f3 100644 --- a/agents/diam_it_test.go +++ b/agents/diam_it_test.go @@ -18,10 +18,8 @@ along with this program. If not, see package agents import ( - "errors" "flag" "net/rpc" - "net/rpc/jsonrpc" "os/exec" "path" "strings" @@ -38,11 +36,8 @@ import ( ) var ( - waitRater = flag.Int("wait_rater", 100, "Number of miliseconds to wait for rater to start and cache") - dataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here") interations = flag.Int("iterations", 1, "Number of iterations to do for dry run simulation") replyTimeout = flag.String("reply_timeout", "1s", "Maximum duration to wait for a reply") - encoding = flag.String("rpc", utils.MetaJSON, "what encoding whould be used for rpc comunication") daCfgPath, diamConfigDIR string daCfg *config.CGRConfig @@ -70,17 +65,6 @@ var ( } ) -func newRPCClient(cfg *config.ListenCfg) (c *rpc.Client, err error) { - switch *encoding { - case utils.MetaJSON: - return jsonrpc.Dial(utils.TCP, cfg.RPCJSONListen) - case utils.MetaGOB: - return rpc.Dial(utils.TCP, cfg.RPCGOBListen) - default: - return nil, errors.New("UNSUPPORTED_RPC") - } -} - // Test start here func TestDiamItTcp(t *testing.T) { engine.KillEngine(0) diff --git a/agents/dnsagent_it_test.go b/agents/dnsagent_it_test.go index ce0b40e6e..e8e3e39d7 100644 --- a/agents/dnsagent_it_test.go +++ b/agents/dnsagent_it_test.go @@ -34,36 +34,53 @@ import ( var ( dnsCfgPath string + dnsCfgDIR string dnsCfg *config.CGRConfig dnsRPC *rpc.Client dnsClnt *dns.Conn // so we can cache the connection + + sTestsDNS = []func(t *testing.T){ + testDNSitInitCfg, + testDNSitResetDB, + testDNSitStartEngine, + testDNSitApierRpcConn, + testDNSitTPFromFolder, + testDNSitClntConn, + testDNSitClntNAPTRDryRun, + testDNSitClntNAPTRAttributes, + testDNSitClntNAPTRSuppliers, + testDNSitStopEngine, + } ) -var sTestsDNS = []func(t *testing.T){ - testDNSitResetDB, - testDNSitStartEngine, - testDNSitApierRpcConn, - testDNSitTPFromFolder, - testDNSitClntConn, - testDNSitClntNAPTRDryRun, - testDNSitClntNAPTRAttributes, - testDNSitClntNAPTRSuppliers, - testDNSitStopEngine, +func TestDNSitSimple(t *testing.T) { + switch *dbType { + case utils.MetaInternal: + dnsCfgDIR = "dnsagent_internal" + case utils.MetaSQL: + dnsCfgDIR = "dnsagent_mysql" + case utils.MetaMongo: + dnsCfgDIR = "dnsagent_mongo" + case utils.MetaPostgres: + t.SkipNow() + default: + t.Fatal("Unknown Database type") + } + for _, stest := range sTestsDNS { + t.Run(dnsCfgDIR, stest) + } } -func TestDNSitSimple(t *testing.T) { - dnsCfgPath = path.Join(*dataDir, "conf", "samples", "dnsagent") - // Init config first +// Init config +func testDNSitInitCfg(t *testing.T) { var err error + dnsCfgPath = path.Join(*dataDir, "conf", "samples", dnsCfgDIR) dnsCfg, err = config.NewCGRConfigFromPath(dnsCfgPath) if err != nil { t.Error(err) } dnsCfg.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() config.SetCgrConfig(dnsCfg) - for _, stest := range sTestsDNS { - t.Run("dnsAgent", stest) - } } // Remove data in both rating and accounting db diff --git a/agents/httpagent_it_test.go b/agents/httpagent_it_test.go index 02b7c1570..2d037696f 100644 --- a/agents/httpagent_it_test.go +++ b/agents/httpagent_it_test.go @@ -40,6 +40,7 @@ import ( var ( haCfgPath string + haCfgDIR string haCfg *config.CGRConfig haRPC *rpc.Client httpC *http.Client // so we can cache the connection @@ -48,6 +49,8 @@ var ( ) var sTestsHA = []func(t *testing.T){ + testHAitInitCfg, + testHAitHttp, testHAitResetDB, testHAitStartEngine, testHAitApierRpcConn, @@ -60,64 +63,82 @@ var sTestsHA = []func(t *testing.T){ testHAitStopEngine, } -func TestHAitSimple(t *testing.T) { - haCfgPath = path.Join(*dataDir, "conf", "samples", "httpagent") +func TestHAit(t *testing.T) { + var configDir, configDirTls string + switch *dbType { + case utils.MetaInternal: + configDir = "httpagent_internal" + configDirTls = "httpagenttls_internal" + case utils.MetaSQL: + configDir = "httpagent_mysql" + configDirTls = "httpagenttls_mysql" + case utils.MetaMongo: + configDir = "httpagent_mongo" + configDirTls = "httpagenttls_mongo" + case utils.MetaPostgres: + t.SkipNow() + default: + t.Fatal("Unknown Database type") + } if *encoding == utils.MetaGOB { - haCfgPath = path.Join(*dataDir, "conf", "samples", "httpagent_gob") + configDir += "_gob" + configDirTls += "_gob" } - // Init config first - var err error - haCfg, err = config.NewCGRConfigFromPath(haCfgPath) - if err != nil { - t.Error(err) - } - haCfg.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() - config.SetCgrConfig(haCfg) - httpC = new(http.Client) + + //Run the tests without Tls + isTls = false + haCfgDIR = configDir for _, stest := range sTestsHA { - t.Run("httpagent", stest) + t.Run(haCfgDIR, stest) + } + //Run the tests with Tls + isTls = true + haCfgDIR = configDirTls + for _, stest := range sTestsHA { + t.Run(haCfgDIR, stest) } } -func TestHA2itWithTls(t *testing.T) { - haCfgPath = path.Join(*dataDir, "conf", "samples", "httpagenttls") - if *encoding == utils.MetaGOB { - haCfgPath = path.Join(*dataDir, "conf", "samples", "httpagenttls_gob") - } - // Init config first +// Init config first +func testHAitInitCfg(t *testing.T) { var err error + haCfgPath = path.Join(*dataDir, "conf", "samples", haCfgDIR) haCfg, err = config.NewCGRConfigFromPath(haCfgPath) if err != nil { t.Error(err) } haCfg.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() config.SetCgrConfig(haCfg) - //make http client with tls - cert, err := tls.LoadX509KeyPair(haCfg.TlsCfg().ClientCerificate, haCfg.TlsCfg().ClientKey) - if err != nil { - t.Error(err) - } +} - // Load CA cert - caCert, err := ioutil.ReadFile(haCfg.TlsCfg().CaCertificate) - if err != nil { - t.Error(err) - } - rootCAs, _ := x509.SystemCertPool() - if ok := rootCAs.AppendCertsFromPEM(caCert); !ok { - t.Error("Cannot append CA") - } +func testHAitHttp(t *testing.T) { + if isTls { + // With Tls + //make http client with tls + cert, err := tls.LoadX509KeyPair(haCfg.TlsCfg().ClientCerificate, haCfg.TlsCfg().ClientKey) + if err != nil { + t.Error(err) + } + // Load CA cert + caCert, err := ioutil.ReadFile(haCfg.TlsCfg().CaCertificate) + if err != nil { + t.Error(err) + } + rootCAs, _ := x509.SystemCertPool() + if ok := rootCAs.AppendCertsFromPEM(caCert); !ok { + t.Error("Cannot append CA") + } - // Setup HTTPS client - tlsConfig := &tls.Config{ - Certificates: []tls.Certificate{cert}, - RootCAs: rootCAs, - } - transport := &http.Transport{TLSClientConfig: tlsConfig} - httpC = &http.Client{Transport: transport} - isTls = true - for _, stest := range sTestsHA { - t.Run("httpagenttls", stest) + // Setup HTTPS client + tlsConfig := &tls.Config{ + Certificates: []tls.Certificate{cert}, + RootCAs: rootCAs, + } + transport := &http.Transport{TLSClientConfig: tlsConfig} + httpC = &http.Client{Transport: transport} + } else { + // Without Tls + httpC = new(http.Client) } } diff --git a/agents/lib_test.go b/agents/lib_test.go new file mode 100644 index 000000000..0f42e0ec2 --- /dev/null +++ b/agents/lib_test.go @@ -0,0 +1,47 @@ +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package agents + +import ( + "errors" + "flag" + "net/rpc" + "net/rpc/jsonrpc" + + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/utils" +) + +var ( + waitRater = flag.Int("wait_rater", 100, "Number of miliseconds to wait for rater to start and cache") + dataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here") + encoding = flag.String("rpc", utils.MetaJSON, "what encoding whould be used for rpc comunication") + dbType = flag.String("dbtype", utils.MetaInternal, "The type of DataBase (Internal/Mongo/mySql)") +) + +func newRPCClient(cfg *config.ListenCfg) (c *rpc.Client, err error) { + switch *encoding { + case utils.MetaJSON: + return jsonrpc.Dial(utils.TCP, cfg.RPCJSONListen) + case utils.MetaGOB: + return rpc.Dial(utils.TCP, cfg.RPCGOBListen) + default: + return nil, errors.New("UNSUPPORTED_RPC") + } +} diff --git a/cmd/cgr-engine/cgr-engine.go b/cmd/cgr-engine/cgr-engine.go index 7b8468797..9f86338ff 100644 --- a/cmd/cgr-engine/cgr-engine.go +++ b/cmd/cgr-engine/cgr-engine.go @@ -55,7 +55,7 @@ var ( singlecpu = cgrEngineFlags.Bool("singlecpu", false, "Run on single CPU core") syslogger = cgrEngineFlags.String("logger", "", "logger <*syslog|*stdout>") nodeID = cgrEngineFlags.String("node_id", "", "The node ID of the engine") - logLevel = cgrEngineFlags.Int("log_level", 6, "Log level (0-emergency to 7-debug)") + logLevel = cgrEngineFlags.Int("log_level", -1, "Log level (0-emergency to 7-debug)") cfg *config.CGRConfig ) diff --git a/data/conf/samples/dnsagent/attributes.json b/data/conf/samples/dnsagent_internal/attributes.json similarity index 100% rename from data/conf/samples/dnsagent/attributes.json rename to data/conf/samples/dnsagent_internal/attributes.json diff --git a/data/conf/samples/dnsagent_internal/cgrates.json b/data/conf/samples/dnsagent_internal/cgrates.json new file mode 100644 index 000000000..51fe78347 --- /dev/null +++ b/data/conf/samples/dnsagent_internal/cgrates.json @@ -0,0 +1,76 @@ +{ + +// Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +// Copyright (C) ITsysCOM GmbH +// +// This file contains the default configuration hardcoded into CGRateS. +// This is what you get when you load CGRateS with an empty configuration file. + + +"general": { + "log_level": 7, // control the level of messages logged (0-emerg to 7-debug) +}, + +"data_db": { + "db_type": "*internal", +}, + + +"stor_db": { + "db_type": "*internal", +}, + + +"schedulers": { + "enabled": true, + "cdrs_conns": ["*internal"], +}, + + +"sessions": { + "enabled": true, + "attributes_conns": ["*localhost"], + "rals_conns": ["*internal"], + "cdrs_conns": ["*internal"], + "chargers_conns": ["*internal"], + "suppliers_conns": ["*localhost"], +}, + + +"rals": { + "enabled": true, +}, + + +"cdrs": { + "enabled": true, + "rals_conns": ["*internal"], +}, + + +"chargers": { + "enabled": true, +}, + + +"attributes": { + "enabled": true, +}, + + +"suppliers": { + "enabled": true, +}, + + +"dns_agent": { + "enabled": true, + "listen": ":2053", + "sessions_conns": ["*localhost"], +}, + + +"apier": { + "scheduler_conns": ["*internal"], +}, +} \ No newline at end of file diff --git a/data/conf/samples/dnsagent/dryrun.json b/data/conf/samples/dnsagent_internal/dryrun.json similarity index 100% rename from data/conf/samples/dnsagent/dryrun.json rename to data/conf/samples/dnsagent_internal/dryrun.json diff --git a/data/conf/samples/dnsagent/suppliers.json b/data/conf/samples/dnsagent_internal/suppliers.json similarity index 100% rename from data/conf/samples/dnsagent/suppliers.json rename to data/conf/samples/dnsagent_internal/suppliers.json diff --git a/data/conf/samples/dnsagent_mongo/attributes.json b/data/conf/samples/dnsagent_mongo/attributes.json new file mode 100644 index 000000000..78f9449e1 --- /dev/null +++ b/data/conf/samples/dnsagent_mongo/attributes.json @@ -0,0 +1,31 @@ +{ + +"dns_agent": { + "request_processors": [ + { + "id": "NAPTRAttributes", + "filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.E164Address:4986517174964"], + "flags": ["*auth", "*attributes"], + "request_fields":[ + {"tag": "E164Address", "field_id": "E164Address", + "type": "*constant", "value": "4986517174964"}, + {"tag": "NAPTRAddress", "field_id": "NAPTRAddress", + "type": "*constant", "value": "*attributes"} + ], + "reply_fields":[ + {"tag": "NAPTROrder", "field_id": "Order", + "type": "*constant", "value": "100"}, + {"tag": "NAPTRPreference", "field_id": "Preference", + "type": "*constant", "value": "10"}, + {"tag": "NAPTRFlags", "field_id": "Flags", + "type": "*constant", "value": "U"}, + {"tag": "NAPTRService", "field_id": "Service", + "type": "*constant", "value": "E2U+SIP"}, + {"tag": "NAPTRRegex", "field_id": "Regexp", + "type": "*variable", "value": "~*cgrep.Attributes.NAPTRAddress"}, + ], + }, + ], +}, + +} \ No newline at end of file diff --git a/data/conf/samples/dnsagent_mongo/cgrates.json b/data/conf/samples/dnsagent_mongo/cgrates.json new file mode 100644 index 000000000..b531ed6c7 --- /dev/null +++ b/data/conf/samples/dnsagent_mongo/cgrates.json @@ -0,0 +1,81 @@ +{ + +// Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +// Copyright (C) ITsysCOM GmbH +// +// This file contains the default configuration hardcoded into CGRateS. +// This is what you get when you load CGRateS with an empty configuration file. + + +"general": { + "log_level": 7, // control the level of messages logged (0-emerg to 7-debug) +}, + +"data_db": { + "db_type": "mongo", + "db_name": "10", + "db_port": 27017, +}, + + +"stor_db": { + "db_type": "mongo", + "db_name": "cgrates", + "db_port": 27017, +}, + + + +"schedulers": { + "enabled": true, + "cdrs_conns": ["*internal"], +}, + + +"sessions": { + "enabled": true, + "attributes_conns": ["*localhost"], + "rals_conns": ["*internal"], + "cdrs_conns": ["*internal"], + "chargers_conns": ["*internal"], + "suppliers_conns": ["*localhost"], +}, + + +"rals": { + "enabled": true, +}, + + +"cdrs": { + "enabled": true, + "rals_conns": ["*internal"], +}, + + +"chargers": { + "enabled": true, +}, + + +"attributes": { + "enabled": true, +}, + + +"suppliers": { + "enabled": true, +}, + + +"dns_agent": { + "enabled": true, + "listen": ":2053", + "sessions_conns": ["*localhost"], +}, + + +"apier": { + "scheduler_conns": ["*internal"], +}, +} \ No newline at end of file diff --git a/data/conf/samples/dnsagent_mongo/dryrun.json b/data/conf/samples/dnsagent_mongo/dryrun.json new file mode 100644 index 000000000..e485a7997 --- /dev/null +++ b/data/conf/samples/dnsagent_mongo/dryrun.json @@ -0,0 +1,24 @@ +{ + +"dns_agent": { + "request_processors": [ + { + "id": "DryRunNAPTR", + "filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.E164Address:4986517174963"], + "flags": ["*dryrun"], + "request_fields":[ + {"tag": "TOR", "field_id": "ToR", "type": "*constant", "value": "*sms"}, + ], + "reply_fields":[ + {"tag": "NAPTROrder", "field_id": "Order", "type": "*constant", "value": "100"}, + {"tag": "NAPTRPreference", "field_id": "Preference", "type": "*constant", "value": "10"}, + {"tag": "NAPTRFlags", "field_id": "Flags", "type": "*constant", "value": "U"}, + {"tag": "NAPTRService", "field_id": "Service", "type": "*constant", "value": "E2U+SIP"}, + {"tag": "NAPTRRegexp", "field_id": "Regexp", "type": "*constant", "value": "!^(.*)$!sip:\\1@172.16.1.10.!"}, + {"tag": "NAPTRReplacement", "field_id": "Replacement", "type": "*constant", "value": "."}, + ], + }, + ], +}, + +} \ No newline at end of file diff --git a/data/conf/samples/dnsagent_mongo/suppliers.json b/data/conf/samples/dnsagent_mongo/suppliers.json new file mode 100644 index 000000000..b531e99f1 --- /dev/null +++ b/data/conf/samples/dnsagent_mongo/suppliers.json @@ -0,0 +1,66 @@ +{ + +"dns_agent": { + "request_processors": [ + { + "id": "NAPTRSuppliersQuery", + "filters": ["*string:~*vars.QueryType:NAPTR", + "*string:~*vars.E164Address:4986517174965"], + "flags": ["*message", "*suppliers"], + "request_fields":[ + {"tag": "TOR", "field_id": "Account", "type": "*constant", "value": "1001"}, // so we can match the supplier profile + ], + "reply_fields":[ + {"tag": "DispatchReply", "type": "*none", + "blocker": true}, // enforces continue_on_success so we can check answer with filters + ], + "continue": true, + }, + { + "id": "NAPTRSuppliersOneSupplier", + "filters": ["*string:~*vars.QueryType:NAPTR", + "*string:~*vars.E164Address:4986517174965", + "*gte:~*cgrep.Suppliers.Count:1"], + "flags": ["*none"], // do not send request to CGRateS + "reply_fields":[ + {"tag": "NAPTROrder", "field_id": "Order", + "type": "*constant", "value": "100"}, + {"tag": "NAPTRPreference", "field_id": "Preference", + "type": "*constant", "value": "10"}, + {"tag": "NAPTRFlags", "field_id": "Flags", + "type": "*constant", "value": "U"}, + {"tag": "NAPTRService", "field_id": "Service", + "type": "*constant", "value": "E2U+SIP"}, + {"tag": "NAPTRRegexp", "field_id": "Regexp", "type": "*variable", + "value": "~*cgrep.Suppliers.SortedSuppliers[0].SupplierParameters"}, + {"tag": "NAPTRReplacement", "field_id": "Replacement", + "type": "*constant", "value": "."}, + ], + "continue": true, + }, + { + "id": "NAPTRSuppliersTwoSuppliers", + "filters": ["*string:~*vars.QueryType:NAPTR", + "*string:~*vars.E164Address:4986517174965", + "*gte:~*cgrep.Suppliers.Count:2"], + "flags": ["*none"], + "reply_fields":[ + {"tag": "NAPTROrder", "type": "*constant", "new_branch": true, + "field_id": "Order", "value": "100"}, + {"tag": "NAPTRPreference", "field_id": "Preference", + "type": "*constant", "value": "10"}, + {"tag": "NAPTRFlags", "field_id": "Flags", + "type": "*constant", "value": "U"}, + {"tag": "NAPTRService", "field_id": "Service", + "type": "*constant", "value": "E2U+SIP"}, + {"tag": "NAPTRRegexp", "field_id": "Regexp", "type": "*variable", + "value": "~*cgrep.Suppliers.SortedSuppliers[1].SupplierParameters"}, + {"tag": "NAPTRReplacement", "field_id": "Replacement", + "type": "*constant", "value": "."}, + ], + "continue": true, + }, + ], +}, + +} diff --git a/data/conf/samples/dnsagent_mysql/attributes.json b/data/conf/samples/dnsagent_mysql/attributes.json new file mode 100644 index 000000000..78f9449e1 --- /dev/null +++ b/data/conf/samples/dnsagent_mysql/attributes.json @@ -0,0 +1,31 @@ +{ + +"dns_agent": { + "request_processors": [ + { + "id": "NAPTRAttributes", + "filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.E164Address:4986517174964"], + "flags": ["*auth", "*attributes"], + "request_fields":[ + {"tag": "E164Address", "field_id": "E164Address", + "type": "*constant", "value": "4986517174964"}, + {"tag": "NAPTRAddress", "field_id": "NAPTRAddress", + "type": "*constant", "value": "*attributes"} + ], + "reply_fields":[ + {"tag": "NAPTROrder", "field_id": "Order", + "type": "*constant", "value": "100"}, + {"tag": "NAPTRPreference", "field_id": "Preference", + "type": "*constant", "value": "10"}, + {"tag": "NAPTRFlags", "field_id": "Flags", + "type": "*constant", "value": "U"}, + {"tag": "NAPTRService", "field_id": "Service", + "type": "*constant", "value": "E2U+SIP"}, + {"tag": "NAPTRRegex", "field_id": "Regexp", + "type": "*variable", "value": "~*cgrep.Attributes.NAPTRAddress"}, + ], + }, + ], +}, + +} \ No newline at end of file diff --git a/data/conf/samples/dnsagent/cgrates.json b/data/conf/samples/dnsagent_mysql/cgrates.json similarity index 100% rename from data/conf/samples/dnsagent/cgrates.json rename to data/conf/samples/dnsagent_mysql/cgrates.json diff --git a/data/conf/samples/dnsagent_mysql/dryrun.json b/data/conf/samples/dnsagent_mysql/dryrun.json new file mode 100644 index 000000000..e485a7997 --- /dev/null +++ b/data/conf/samples/dnsagent_mysql/dryrun.json @@ -0,0 +1,24 @@ +{ + +"dns_agent": { + "request_processors": [ + { + "id": "DryRunNAPTR", + "filters": ["*string:~*vars.QueryType:NAPTR", "*string:~*vars.E164Address:4986517174963"], + "flags": ["*dryrun"], + "request_fields":[ + {"tag": "TOR", "field_id": "ToR", "type": "*constant", "value": "*sms"}, + ], + "reply_fields":[ + {"tag": "NAPTROrder", "field_id": "Order", "type": "*constant", "value": "100"}, + {"tag": "NAPTRPreference", "field_id": "Preference", "type": "*constant", "value": "10"}, + {"tag": "NAPTRFlags", "field_id": "Flags", "type": "*constant", "value": "U"}, + {"tag": "NAPTRService", "field_id": "Service", "type": "*constant", "value": "E2U+SIP"}, + {"tag": "NAPTRRegexp", "field_id": "Regexp", "type": "*constant", "value": "!^(.*)$!sip:\\1@172.16.1.10.!"}, + {"tag": "NAPTRReplacement", "field_id": "Replacement", "type": "*constant", "value": "."}, + ], + }, + ], +}, + +} \ No newline at end of file diff --git a/data/conf/samples/dnsagent_mysql/suppliers.json b/data/conf/samples/dnsagent_mysql/suppliers.json new file mode 100644 index 000000000..b531e99f1 --- /dev/null +++ b/data/conf/samples/dnsagent_mysql/suppliers.json @@ -0,0 +1,66 @@ +{ + +"dns_agent": { + "request_processors": [ + { + "id": "NAPTRSuppliersQuery", + "filters": ["*string:~*vars.QueryType:NAPTR", + "*string:~*vars.E164Address:4986517174965"], + "flags": ["*message", "*suppliers"], + "request_fields":[ + {"tag": "TOR", "field_id": "Account", "type": "*constant", "value": "1001"}, // so we can match the supplier profile + ], + "reply_fields":[ + {"tag": "DispatchReply", "type": "*none", + "blocker": true}, // enforces continue_on_success so we can check answer with filters + ], + "continue": true, + }, + { + "id": "NAPTRSuppliersOneSupplier", + "filters": ["*string:~*vars.QueryType:NAPTR", + "*string:~*vars.E164Address:4986517174965", + "*gte:~*cgrep.Suppliers.Count:1"], + "flags": ["*none"], // do not send request to CGRateS + "reply_fields":[ + {"tag": "NAPTROrder", "field_id": "Order", + "type": "*constant", "value": "100"}, + {"tag": "NAPTRPreference", "field_id": "Preference", + "type": "*constant", "value": "10"}, + {"tag": "NAPTRFlags", "field_id": "Flags", + "type": "*constant", "value": "U"}, + {"tag": "NAPTRService", "field_id": "Service", + "type": "*constant", "value": "E2U+SIP"}, + {"tag": "NAPTRRegexp", "field_id": "Regexp", "type": "*variable", + "value": "~*cgrep.Suppliers.SortedSuppliers[0].SupplierParameters"}, + {"tag": "NAPTRReplacement", "field_id": "Replacement", + "type": "*constant", "value": "."}, + ], + "continue": true, + }, + { + "id": "NAPTRSuppliersTwoSuppliers", + "filters": ["*string:~*vars.QueryType:NAPTR", + "*string:~*vars.E164Address:4986517174965", + "*gte:~*cgrep.Suppliers.Count:2"], + "flags": ["*none"], + "reply_fields":[ + {"tag": "NAPTROrder", "type": "*constant", "new_branch": true, + "field_id": "Order", "value": "100"}, + {"tag": "NAPTRPreference", "field_id": "Preference", + "type": "*constant", "value": "10"}, + {"tag": "NAPTRFlags", "field_id": "Flags", + "type": "*constant", "value": "U"}, + {"tag": "NAPTRService", "field_id": "Service", + "type": "*constant", "value": "E2U+SIP"}, + {"tag": "NAPTRRegexp", "field_id": "Regexp", "type": "*variable", + "value": "~*cgrep.Suppliers.SortedSuppliers[1].SupplierParameters"}, + {"tag": "NAPTRReplacement", "field_id": "Replacement", + "type": "*constant", "value": "."}, + ], + "continue": true, + }, + ], +}, + +} diff --git a/data/conf/samples/httpagent_internal/cgrates.json b/data/conf/samples/httpagent_internal/cgrates.json new file mode 100644 index 000000000..9ec91f4cd --- /dev/null +++ b/data/conf/samples/httpagent_internal/cgrates.json @@ -0,0 +1,64 @@ +{ +// CGRateS Configuration file +// + + +"general": { + "log_level": 7, +}, + + +"listen": { + "rpc_json": ":2012", + "rpc_gob": ":2013", + "http": ":2080", +}, + +"stor_db": { + "db_type": "*internal", +}, + + +"rals": { + "enabled": true, + "max_increments":3000000, +}, + + +"schedulers": { + "enabled": true, +}, + + +"cdrs": { + "enabled": true, + "chargers_conns": ["*internal"], + "rals_conns": ["*internal"], +}, + + +"attributes": { + "enabled": true, +}, + +"chargers": { + "enabled": true, + "attributes_conns": ["*internal"], +}, + + +"sessions": { + "enabled": true, + "attributes_conns": ["*localhost"], + "cdrs_conns": ["*localhost"], + "rals_conns": ["*localhost"], + "chargers_conns": ["*internal"], +}, + + +"apier": { + "scheduler_conns": ["*internal"], +}, + + +} diff --git a/data/conf/samples/httpagent/httpagent.json b/data/conf/samples/httpagent_internal/httpagent.json similarity index 100% rename from data/conf/samples/httpagent/httpagent.json rename to data/conf/samples/httpagent_internal/httpagent.json diff --git a/data/conf/samples/httpagent_internal_gob/cgrates.json b/data/conf/samples/httpagent_internal_gob/cgrates.json new file mode 100644 index 000000000..1d6e1ec7b --- /dev/null +++ b/data/conf/samples/httpagent_internal_gob/cgrates.json @@ -0,0 +1,71 @@ +{ +// CGRateS Configuration file +// + + +"general": { + "log_level": 7, +}, + + +"listen": { + "rpc_json": ":2012", + "rpc_gob": ":2013", + "http": ":2080", +}, + +"rpc_conns": { + "conn1": { + "strategy": "*first", + "conns": [{"address": "127.0.0.1:2013", "transport":"*gob"}], + }, +}, + +"stor_db": { + "db_type": "*internal", +}, + + +"rals": { + "enabled": true, + "max_increments":3000000, +}, + + +"schedulers": { + "enabled": true, +}, + + +"cdrs": { + "enabled": true, + "chargers_conns": ["*internal"], + "rals_conns": ["*internal"], +}, + + +"attributes": { + "enabled": true, +}, + +"chargers": { + "enabled": true, + "attributes_conns": ["*internal"], +}, + + +"sessions": { + "enabled": true, + "attributes_conns": ["conn1"], + "cdrs_conns": ["conn1"], + "rals_conns": ["conn1"], + "chargers_conns": ["*internal"], +}, + + +"apier": { + "scheduler_conns": ["*internal"], +}, + + +} diff --git a/data/conf/samples/httpagent_gob/httpagent.json b/data/conf/samples/httpagent_internal_gob/httpagent.json similarity index 100% rename from data/conf/samples/httpagent_gob/httpagent.json rename to data/conf/samples/httpagent_internal_gob/httpagent.json diff --git a/data/conf/samples/httpagent_mongo/cgrates.json b/data/conf/samples/httpagent_mongo/cgrates.json new file mode 100644 index 000000000..bce58861d --- /dev/null +++ b/data/conf/samples/httpagent_mongo/cgrates.json @@ -0,0 +1,67 @@ +{ +// CGRateS Configuration file +// + + +"general": { + "log_level": 7, +}, + + +"listen": { + "rpc_json": ":2012", + "rpc_gob": ":2013", + "http": ":2080", +}, + + +"stor_db": { + "db_type": "mongo", + "db_name": "cgrates", + "db_port": 27017, +}, + + +"rals": { + "enabled": true, + "max_increments":3000000, +}, + + +"schedulers": { + "enabled": true, +}, + + +"cdrs": { + "enabled": true, + "chargers_conns": ["*internal"], + "rals_conns": ["*internal"], +}, + + +"attributes": { + "enabled": true, +}, + +"chargers": { + "enabled": true, + "attributes_conns": ["*internal"], +}, + + +"sessions": { + "enabled": true, + "attributes_conns": ["*localhost"], + "cdrs_conns": ["*localhost"], + "rals_conns": ["*localhost"], + "chargers_conns": ["*internal"], +}, + + +"apier": { + "scheduler_conns": ["*internal"], +}, + + +} diff --git a/data/conf/samples/httpagent_mongo/httpagent.json b/data/conf/samples/httpagent_mongo/httpagent.json new file mode 100644 index 000000000..48c2d4f3f --- /dev/null +++ b/data/conf/samples/httpagent_mongo/httpagent.json @@ -0,0 +1,168 @@ +{ + + +"http_agent": [ + { + "id": "conecto1", + "url": "/conecto", + "sessions_conns": ["*localhost"], + "request_payload": "*url", + "reply_payload": "*xml", + "request_processors": [ + { + "id": "OutboundAUTHDryRun", + "filters": ["*string:~*req.request_type:OutboundAUTH","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Allow", "field_id": "response.Allow", "type": "*constant", + "value": "1", "mandatory": true}, + {"tag": "Concatenated1", "field_id": "response.Concatenated", "type": "*composed", + "value": "~*req.MCC;/", "mandatory": true}, + {"tag": "Concatenated2", "field_id": "response.Concatenated", "type": "*composed", + "value": "Val1"}, + {"tag": "MaxDuration", "field_id": "response.MaxDuration", "type": "*constant", + "value": "1200", "blocker": true}, + {"tag": "Unused", "field_id": "response.Unused", "type": "*constant", + "value": "0"}, + ], + }, + { + "id": "OutboundAUTH", + "filters": ["*string:~*req.request_type:OutboundAUTH"], + "tenant": "cgrates.org", + "flags": [ "*auth", "*accounts", "*attributes"], + "request_fields":[ + {"tag": "Category", "field_id": "Category", "type": "*constant", "value": "call"}, + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.CallID", "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.Msisdn", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.Destination", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*constant", + "value": "*now", "mandatory": true}, + ], + "reply_fields":[ + {"tag": "Allow", "field_id": "response.Allow", "type": "*constant", + "value": "1", "mandatory": true}, + {"tag": "MaxDuration", "field_id": "response.MaxDuration", "type": "*composed", + "value": "~*cgrep.MaxUsage{*duration_seconds}", "mandatory": true}, + ], + }, + { + "id": "mtcall_cdr", + "filters": ["*string:~*req.request_type:MTCALL_CDR"], + "tenant": "cgrates.org", + "flags": ["*cdrs"], + "request_fields":[ + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.CDR_ID", "mandatory": true}, + {"tag": "OriginHost", "field_id": "OriginHost", "type": "*remote_host", + "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.msisdn", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.destination", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*variable", + "value": "~*req.timestamp", "mandatory": true}, + {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*variable", + "value": "~*req.timestamp", "mandatory": true}, + {"tag": "Usage", "field_id": "Usage", "type": "*composed", + "value": "~*req.leg_duration;s", "mandatory": true}, + ], + "reply_fields":[ + {"tag": "ResultCode", "filters": ["*rsr::~*cgrep.Error(!^$)"], + "field_id": "CDR_RESPONSE.RESULT_CODE", "type": "*composed", "value": "~*cgrep.Error", "blocker": true}, + {"tag": "CDR_ID", "field_id": "CDR_RESPONSE.CDR_ID", "type": "*composed", + "value": "~*req.CDR_ID", "mandatory": true}, + {"tag": "CDR_STATUS", "field_id": "CDR_RESPONSE.CDR_STATUS", "type": "*constant", + "value": "1", "mandatory": true}, + ], + } + ], + }, + { + "id": "conecto_xml", + "url": "/conecto_xml", + "sessions_conns": ["*localhost"], + "request_payload": "*xml", + "reply_payload": "*xml", + "request_processors": [ + { + "id": "cdr_from_xml", + "tenant": "cgrates.org", + "flags": ["*cdrs"], + "request_fields":[ + {"tag": "TOR", "field_id": "ToR", "type": "*constant", + "value": "*data", "mandatory": true}, + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.complete-datasession-notification.customerid", "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.complete-datasession-notification.username", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.complete-datasession-notification.userid", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed", + "value": "~*req.complete-datasession-notification.createtime", "mandatory": true}, + {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed", + "value": "~*req.complete-datasession-notification.createtime", "mandatory": true}, + {"tag": "Usage", "field_id": "Usage", "type": "*composed", + "value": "~*req.complete-datasession-notification.callleg.bytes", "mandatory": true}, + ], + "reply_fields":[], + } + ], + }, + { + "id": "textplain", + "url": "/textplain", + "sessions_conns": ["*localhost"], + "request_payload": "*url", + "reply_payload": "*text_plain", + "request_processors": [ + { + "id": "TextPlainDryRun", + "filters": ["*string:~*req.request_type:TextPlainDryRun","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Field1", "field_id": "Variable1", "type": "*variable", + "value": "Hola1", "mandatory": true}, + {"tag": "Field2", "field_id": "Variable2", "type": "*variable", + "value": "Hola2", "mandatory": true}, + {"tag": "Field3", "field_id": "ComposedVar", "type": "*composed", + "value": "Test", "mandatory": true}, + {"tag": "Field4", "field_id": "ComposedVar", "type": "*composed", + "value": "Composed", "mandatory": true}, + {"tag": "Field5", "field_id": "Item1.1", "type": "*variable", + "value": "Val1", "mandatory": true}, + ], + "continue": true, + }, + { + "id": "TextPlainDryRun2", + "filters": ["*string:~*req.request_type:TextPlainDryRun","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[], + "reply_fields":[ + {"tag": "Field1", "field_id": "Item1.1", "type": "*variable", + "value": "Val2", "mandatory": true}, + ], + }, + ], + }, +], + + +} \ No newline at end of file diff --git a/data/conf/samples/httpagent_mongo_gob/cgrates.json b/data/conf/samples/httpagent_mongo_gob/cgrates.json new file mode 100644 index 000000000..b13361087 --- /dev/null +++ b/data/conf/samples/httpagent_mongo_gob/cgrates.json @@ -0,0 +1,73 @@ +{ +// CGRateS Configuration file +// + + +"general": { + "log_level": 7, +}, + + +"listen": { + "rpc_json": ":2012", + "rpc_gob": ":2013", + "http": ":2080", +}, + +"rpc_conns": { + "conn1": { + "strategy": "*first", + "conns": [{"address": "127.0.0.1:2013", "transport":"*gob"}], + }, +}, + +"stor_db": { + "db_type": "mongo", + "db_name": "cgrates", + "db_port": 27017, +}, + + +"rals": { + "enabled": true, + "max_increments":3000000, +}, + + +"schedulers": { + "enabled": true, +}, + + +"cdrs": { + "enabled": true, + "chargers_conns": ["*internal"], + "rals_conns": ["*internal"], +}, + + +"attributes": { + "enabled": true, +}, + +"chargers": { + "enabled": true, + "attributes_conns": ["*internal"], +}, + + +"sessions": { + "enabled": true, + "attributes_conns": ["conn1"], + "cdrs_conns": ["conn1"], + "rals_conns": ["conn1"], + "chargers_conns": ["*internal"], +}, + + +"apier": { + "scheduler_conns": ["*internal"], +}, + + +} diff --git a/data/conf/samples/httpagent_mongo_gob/httpagent.json b/data/conf/samples/httpagent_mongo_gob/httpagent.json new file mode 100644 index 000000000..708fa58d4 --- /dev/null +++ b/data/conf/samples/httpagent_mongo_gob/httpagent.json @@ -0,0 +1,168 @@ +{ + + +"http_agent": [ + { + "id": "conecto1", + "url": "/conecto", + "sessions_conns": ["conn1"], + "request_payload": "*url", + "reply_payload": "*xml", + "request_processors": [ + { + "id": "OutboundAUTHDryRun", + "filters": ["*string:~*req.request_type:OutboundAUTH","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Allow", "field_id": "response.Allow", "type": "*constant", + "value": "1", "mandatory": true}, + {"tag": "Concatenated1", "field_id": "response.Concatenated", "type": "*composed", + "value": "~*req.MCC;/", "mandatory": true}, + {"tag": "Concatenated2", "field_id": "response.Concatenated", "type": "*composed", + "value": "Val1"}, + {"tag": "MaxDuration", "field_id": "response.MaxDuration", "type": "*constant", + "value": "1200", "blocker": true}, + {"tag": "Unused", "field_id": "response.Unused", "type": "*constant", + "value": "0"}, + ], + }, + { + "id": "OutboundAUTH", + "filters": ["*string:~*req.request_type:OutboundAUTH"], + "tenant": "cgrates.org", + "flags": [ "*auth", "*accounts", "*attributes"], + "request_fields":[ + {"tag": "Category", "field_id": "Category", "type": "*constant", "value": "call"}, + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.CallID", "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.Msisdn", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.Destination", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*constant", + "value": "*now", "mandatory": true}, + ], + "reply_fields":[ + {"tag": "Allow", "field_id": "response.Allow", "type": "*constant", + "value": "1", "mandatory": true}, + {"tag": "MaxDuration", "field_id": "response.MaxDuration", "type": "*composed", + "value": "~*cgrep.MaxUsage{*duration_seconds}", "mandatory": true}, + ], + }, + { + "id": "mtcall_cdr", + "filters": ["*string:~*req.request_type:MTCALL_CDR"], + "tenant": "cgrates.org", + "flags": ["*cdrs"], + "request_fields":[ + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.CDR_ID", "mandatory": true}, + {"tag": "OriginHost", "field_id": "OriginHost", "type": "*remote_host", + "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.msisdn", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.destination", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*variable", + "value": "~*req.timestamp", "mandatory": true}, + {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*variable", + "value": "~*req.timestamp", "mandatory": true}, + {"tag": "Usage", "field_id": "Usage", "type": "*composed", + "value": "~*req.leg_duration;s", "mandatory": true}, + ], + "reply_fields":[ + {"tag": "ResultCode", "filters": ["*rsr::~*cgrep.Error(!^$)"], + "field_id": "CDR_RESPONSE.RESULT_CODE", "type": "*composed", "value": "~*cgrep.Error", "blocker": true}, + {"tag": "CDR_ID", "field_id": "CDR_RESPONSE.CDR_ID", "type": "*composed", + "value": "~*req.CDR_ID", "mandatory": true}, + {"tag": "CDR_STATUS", "field_id": "CDR_RESPONSE.CDR_STATUS", "type": "*constant", + "value": "1", "mandatory": true}, + ], + } + ], + }, + { + "id": "conecto_xml", + "url": "/conecto_xml", + "sessions_conns": ["conn1"], + "request_payload": "*xml", + "reply_payload": "*xml", + "request_processors": [ + { + "id": "cdr_from_xml", + "tenant": "cgrates.org", + "flags": ["*cdrs"], + "request_fields":[ + {"tag": "TOR", "field_id": "ToR", "type": "*constant", + "value": "*data", "mandatory": true}, + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.complete-datasession-notification.customerid", "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.complete-datasession-notification.username", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.complete-datasession-notification.userid", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed", + "value": "~*req.complete-datasession-notification.createtime", "mandatory": true}, + {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed", + "value": "~*req.complete-datasession-notification.createtime", "mandatory": true}, + {"tag": "Usage", "field_id": "Usage", "type": "*composed", + "value": "~*req.complete-datasession-notification.callleg.bytes", "mandatory": true}, + ], + "reply_fields":[], + } + ], + }, + { + "id": "textplain", + "url": "/textplain", + "sessions_conns": ["conn1"], + "request_payload": "*url", + "reply_payload": "*text_plain", + "request_processors": [ + { + "id": "TextPlainDryRun", + "filters": ["*string:~*req.request_type:TextPlainDryRun","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Field1", "field_id": "Variable1", "type": "*variable", + "value": "Hola1", "mandatory": true}, + {"tag": "Field2", "field_id": "Variable2", "type": "*variable", + "value": "Hola2", "mandatory": true}, + {"tag": "Field3", "field_id": "ComposedVar", "type": "*composed", + "value": "Test", "mandatory": true}, + {"tag": "Field4", "field_id": "ComposedVar", "type": "*composed", + "value": "Composed", "mandatory": true}, + {"tag": "Field5", "field_id": "Item1.1", "type": "*variable", + "value": "Val1", "mandatory": true}, + ], + "continue": true, + }, + { + "id": "TextPlainDryRun2", + "filters": ["*string:~*req.request_type:TextPlainDryRun","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[], + "reply_fields":[ + {"tag": "Field1", "field_id": "Item1.1", "type": "*variable", + "value": "Val2", "mandatory": true}, + ], + }, + ], + }, +], + + +} \ No newline at end of file diff --git a/data/conf/samples/httpagent/cgrates.json b/data/conf/samples/httpagent_mysql/cgrates.json similarity index 100% rename from data/conf/samples/httpagent/cgrates.json rename to data/conf/samples/httpagent_mysql/cgrates.json diff --git a/data/conf/samples/httpagent_mysql/httpagent.json b/data/conf/samples/httpagent_mysql/httpagent.json new file mode 100644 index 000000000..48c2d4f3f --- /dev/null +++ b/data/conf/samples/httpagent_mysql/httpagent.json @@ -0,0 +1,168 @@ +{ + + +"http_agent": [ + { + "id": "conecto1", + "url": "/conecto", + "sessions_conns": ["*localhost"], + "request_payload": "*url", + "reply_payload": "*xml", + "request_processors": [ + { + "id": "OutboundAUTHDryRun", + "filters": ["*string:~*req.request_type:OutboundAUTH","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Allow", "field_id": "response.Allow", "type": "*constant", + "value": "1", "mandatory": true}, + {"tag": "Concatenated1", "field_id": "response.Concatenated", "type": "*composed", + "value": "~*req.MCC;/", "mandatory": true}, + {"tag": "Concatenated2", "field_id": "response.Concatenated", "type": "*composed", + "value": "Val1"}, + {"tag": "MaxDuration", "field_id": "response.MaxDuration", "type": "*constant", + "value": "1200", "blocker": true}, + {"tag": "Unused", "field_id": "response.Unused", "type": "*constant", + "value": "0"}, + ], + }, + { + "id": "OutboundAUTH", + "filters": ["*string:~*req.request_type:OutboundAUTH"], + "tenant": "cgrates.org", + "flags": [ "*auth", "*accounts", "*attributes"], + "request_fields":[ + {"tag": "Category", "field_id": "Category", "type": "*constant", "value": "call"}, + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.CallID", "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.Msisdn", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.Destination", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*constant", + "value": "*now", "mandatory": true}, + ], + "reply_fields":[ + {"tag": "Allow", "field_id": "response.Allow", "type": "*constant", + "value": "1", "mandatory": true}, + {"tag": "MaxDuration", "field_id": "response.MaxDuration", "type": "*composed", + "value": "~*cgrep.MaxUsage{*duration_seconds}", "mandatory": true}, + ], + }, + { + "id": "mtcall_cdr", + "filters": ["*string:~*req.request_type:MTCALL_CDR"], + "tenant": "cgrates.org", + "flags": ["*cdrs"], + "request_fields":[ + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.CDR_ID", "mandatory": true}, + {"tag": "OriginHost", "field_id": "OriginHost", "type": "*remote_host", + "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.msisdn", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.destination", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*variable", + "value": "~*req.timestamp", "mandatory": true}, + {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*variable", + "value": "~*req.timestamp", "mandatory": true}, + {"tag": "Usage", "field_id": "Usage", "type": "*composed", + "value": "~*req.leg_duration;s", "mandatory": true}, + ], + "reply_fields":[ + {"tag": "ResultCode", "filters": ["*rsr::~*cgrep.Error(!^$)"], + "field_id": "CDR_RESPONSE.RESULT_CODE", "type": "*composed", "value": "~*cgrep.Error", "blocker": true}, + {"tag": "CDR_ID", "field_id": "CDR_RESPONSE.CDR_ID", "type": "*composed", + "value": "~*req.CDR_ID", "mandatory": true}, + {"tag": "CDR_STATUS", "field_id": "CDR_RESPONSE.CDR_STATUS", "type": "*constant", + "value": "1", "mandatory": true}, + ], + } + ], + }, + { + "id": "conecto_xml", + "url": "/conecto_xml", + "sessions_conns": ["*localhost"], + "request_payload": "*xml", + "reply_payload": "*xml", + "request_processors": [ + { + "id": "cdr_from_xml", + "tenant": "cgrates.org", + "flags": ["*cdrs"], + "request_fields":[ + {"tag": "TOR", "field_id": "ToR", "type": "*constant", + "value": "*data", "mandatory": true}, + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.complete-datasession-notification.customerid", "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.complete-datasession-notification.username", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.complete-datasession-notification.userid", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed", + "value": "~*req.complete-datasession-notification.createtime", "mandatory": true}, + {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed", + "value": "~*req.complete-datasession-notification.createtime", "mandatory": true}, + {"tag": "Usage", "field_id": "Usage", "type": "*composed", + "value": "~*req.complete-datasession-notification.callleg.bytes", "mandatory": true}, + ], + "reply_fields":[], + } + ], + }, + { + "id": "textplain", + "url": "/textplain", + "sessions_conns": ["*localhost"], + "request_payload": "*url", + "reply_payload": "*text_plain", + "request_processors": [ + { + "id": "TextPlainDryRun", + "filters": ["*string:~*req.request_type:TextPlainDryRun","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Field1", "field_id": "Variable1", "type": "*variable", + "value": "Hola1", "mandatory": true}, + {"tag": "Field2", "field_id": "Variable2", "type": "*variable", + "value": "Hola2", "mandatory": true}, + {"tag": "Field3", "field_id": "ComposedVar", "type": "*composed", + "value": "Test", "mandatory": true}, + {"tag": "Field4", "field_id": "ComposedVar", "type": "*composed", + "value": "Composed", "mandatory": true}, + {"tag": "Field5", "field_id": "Item1.1", "type": "*variable", + "value": "Val1", "mandatory": true}, + ], + "continue": true, + }, + { + "id": "TextPlainDryRun2", + "filters": ["*string:~*req.request_type:TextPlainDryRun","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[], + "reply_fields":[ + {"tag": "Field1", "field_id": "Item1.1", "type": "*variable", + "value": "Val2", "mandatory": true}, + ], + }, + ], + }, +], + + +} \ No newline at end of file diff --git a/data/conf/samples/httpagent_gob/cgrates.json b/data/conf/samples/httpagent_mysql_gob/cgrates.json similarity index 100% rename from data/conf/samples/httpagent_gob/cgrates.json rename to data/conf/samples/httpagent_mysql_gob/cgrates.json diff --git a/data/conf/samples/httpagent_mysql_gob/httpagent.json b/data/conf/samples/httpagent_mysql_gob/httpagent.json new file mode 100644 index 000000000..708fa58d4 --- /dev/null +++ b/data/conf/samples/httpagent_mysql_gob/httpagent.json @@ -0,0 +1,168 @@ +{ + + +"http_agent": [ + { + "id": "conecto1", + "url": "/conecto", + "sessions_conns": ["conn1"], + "request_payload": "*url", + "reply_payload": "*xml", + "request_processors": [ + { + "id": "OutboundAUTHDryRun", + "filters": ["*string:~*req.request_type:OutboundAUTH","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Allow", "field_id": "response.Allow", "type": "*constant", + "value": "1", "mandatory": true}, + {"tag": "Concatenated1", "field_id": "response.Concatenated", "type": "*composed", + "value": "~*req.MCC;/", "mandatory": true}, + {"tag": "Concatenated2", "field_id": "response.Concatenated", "type": "*composed", + "value": "Val1"}, + {"tag": "MaxDuration", "field_id": "response.MaxDuration", "type": "*constant", + "value": "1200", "blocker": true}, + {"tag": "Unused", "field_id": "response.Unused", "type": "*constant", + "value": "0"}, + ], + }, + { + "id": "OutboundAUTH", + "filters": ["*string:~*req.request_type:OutboundAUTH"], + "tenant": "cgrates.org", + "flags": [ "*auth", "*accounts", "*attributes"], + "request_fields":[ + {"tag": "Category", "field_id": "Category", "type": "*constant", "value": "call"}, + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.CallID", "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.Msisdn", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.Destination", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*constant", + "value": "*now", "mandatory": true}, + ], + "reply_fields":[ + {"tag": "Allow", "field_id": "response.Allow", "type": "*constant", + "value": "1", "mandatory": true}, + {"tag": "MaxDuration", "field_id": "response.MaxDuration", "type": "*composed", + "value": "~*cgrep.MaxUsage{*duration_seconds}", "mandatory": true}, + ], + }, + { + "id": "mtcall_cdr", + "filters": ["*string:~*req.request_type:MTCALL_CDR"], + "tenant": "cgrates.org", + "flags": ["*cdrs"], + "request_fields":[ + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.CDR_ID", "mandatory": true}, + {"tag": "OriginHost", "field_id": "OriginHost", "type": "*remote_host", + "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.msisdn", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.destination", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*variable", + "value": "~*req.timestamp", "mandatory": true}, + {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*variable", + "value": "~*req.timestamp", "mandatory": true}, + {"tag": "Usage", "field_id": "Usage", "type": "*composed", + "value": "~*req.leg_duration;s", "mandatory": true}, + ], + "reply_fields":[ + {"tag": "ResultCode", "filters": ["*rsr::~*cgrep.Error(!^$)"], + "field_id": "CDR_RESPONSE.RESULT_CODE", "type": "*composed", "value": "~*cgrep.Error", "blocker": true}, + {"tag": "CDR_ID", "field_id": "CDR_RESPONSE.CDR_ID", "type": "*composed", + "value": "~*req.CDR_ID", "mandatory": true}, + {"tag": "CDR_STATUS", "field_id": "CDR_RESPONSE.CDR_STATUS", "type": "*constant", + "value": "1", "mandatory": true}, + ], + } + ], + }, + { + "id": "conecto_xml", + "url": "/conecto_xml", + "sessions_conns": ["conn1"], + "request_payload": "*xml", + "reply_payload": "*xml", + "request_processors": [ + { + "id": "cdr_from_xml", + "tenant": "cgrates.org", + "flags": ["*cdrs"], + "request_fields":[ + {"tag": "TOR", "field_id": "ToR", "type": "*constant", + "value": "*data", "mandatory": true}, + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.complete-datasession-notification.customerid", "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.complete-datasession-notification.username", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.complete-datasession-notification.userid", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed", + "value": "~*req.complete-datasession-notification.createtime", "mandatory": true}, + {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed", + "value": "~*req.complete-datasession-notification.createtime", "mandatory": true}, + {"tag": "Usage", "field_id": "Usage", "type": "*composed", + "value": "~*req.complete-datasession-notification.callleg.bytes", "mandatory": true}, + ], + "reply_fields":[], + } + ], + }, + { + "id": "textplain", + "url": "/textplain", + "sessions_conns": ["conn1"], + "request_payload": "*url", + "reply_payload": "*text_plain", + "request_processors": [ + { + "id": "TextPlainDryRun", + "filters": ["*string:~*req.request_type:TextPlainDryRun","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Field1", "field_id": "Variable1", "type": "*variable", + "value": "Hola1", "mandatory": true}, + {"tag": "Field2", "field_id": "Variable2", "type": "*variable", + "value": "Hola2", "mandatory": true}, + {"tag": "Field3", "field_id": "ComposedVar", "type": "*composed", + "value": "Test", "mandatory": true}, + {"tag": "Field4", "field_id": "ComposedVar", "type": "*composed", + "value": "Composed", "mandatory": true}, + {"tag": "Field5", "field_id": "Item1.1", "type": "*variable", + "value": "Val1", "mandatory": true}, + ], + "continue": true, + }, + { + "id": "TextPlainDryRun2", + "filters": ["*string:~*req.request_type:TextPlainDryRun","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[], + "reply_fields":[ + {"tag": "Field1", "field_id": "Item1.1", "type": "*variable", + "value": "Val2", "mandatory": true}, + ], + }, + ], + }, +], + + +} \ No newline at end of file diff --git a/data/conf/samples/httpagenttls_internal/cgrates.json b/data/conf/samples/httpagenttls_internal/cgrates.json new file mode 100755 index 000000000..466679457 --- /dev/null +++ b/data/conf/samples/httpagenttls_internal/cgrates.json @@ -0,0 +1,75 @@ +{ +// CGRateS Configuration file +// + + +"general": { + "log_level": 7, +}, + + +"listen": { + "rpc_json": ":2012", + "rpc_gob": ":2013", + "http": ":2080", + "rpc_json_tls":":2022", + "rpc_gob_tls":":2023", + "http_tls": "localhost:2280", +}, + +"tls": { + "server_certificate" : "/usr/share/cgrates/tls/server.crt", // path to server certificate(must conatin server.crt + ca.crt) + "server_key":"/usr/share/cgrates/tls/server.key", // path to server key + "client_certificate" : "/usr/share/cgrates/tls/client.crt", // path to client certificate(must conatin client.crt + ca.crt) + "client_key":"/usr/share/cgrates/tls/client.key", // path to client key + "ca_certificate":"/usr/share/cgrates/tls/ca.crt", +}, + + +"stor_db": { + "db_type": "*internal", +}, + + +"rals": { + "enabled": true, + "max_increments":3000000, +}, + + +"schedulers": { + "enabled": true, +}, + + +"cdrs": { + "enabled": true, + "chargers_conns": ["*internal"], + "rals_conns": ["*internal"], +}, + + +"attributes": { + "enabled": true, +}, + +"chargers": { + "enabled": true, + "attributes_conns": ["*internal"], +}, + +"sessions": { + "enabled": true, + "attributes_conns": ["*localhost"], + "cdrs_conns": ["*localhost"], + "rals_conns": ["*localhost"], + "chargers_conns": ["*internal"], +}, + + +"apier": { + "scheduler_conns": ["*internal"], +}, + + +} diff --git a/data/conf/samples/httpagenttls/httpagent.json b/data/conf/samples/httpagenttls_internal/httpagent.json similarity index 100% rename from data/conf/samples/httpagenttls/httpagent.json rename to data/conf/samples/httpagenttls_internal/httpagent.json diff --git a/data/conf/samples/httpagenttls_internal_gob/cgrates.json b/data/conf/samples/httpagenttls_internal_gob/cgrates.json new file mode 100755 index 000000000..acafbe97b --- /dev/null +++ b/data/conf/samples/httpagenttls_internal_gob/cgrates.json @@ -0,0 +1,84 @@ +{ +// CGRateS Configuration file +// + + +"general": { + "log_level": 7, +}, + + +"listen": { + "rpc_json": ":2012", + "rpc_gob": ":2013", + "http": ":2080", + "rpc_json_tls":":2022", + "rpc_gob_tls":":2023", + "http_tls": "localhost:2280", +}, + + +"rpc_conns": { + "conn1": { + "strategy": "*first", + "conns": [{"address": "127.0.0.1:2013", "transport":"*gob"}], + }, +}, + + +"tls": { + "server_certificate" : "/usr/share/cgrates/tls/server.crt", // path to server certificate(must conatin server.crt + ca.crt) + "server_key":"/usr/share/cgrates/tls/server.key", // path to server key + "client_certificate" : "/usr/share/cgrates/tls/client.crt", // path to client certificate(must conatin client.crt + ca.crt) + "client_key":"/usr/share/cgrates/tls/client.key", // path to client key + "ca_certificate":"/usr/share/cgrates/tls/ca.crt", +}, + + +"stor_db": { + "db_type": "*internal", +}, + + +"rals": { + "enabled": true, + "max_increments":3000000, +}, + + +"schedulers": { + "enabled": true, +}, + + +"cdrs": { + "enabled": true, + "chargers_conns": ["*internal"], + "rals_conns": ["*internal"], +}, + + +"attributes": { + "enabled": true, +}, + +"chargers": { + "enabled": true, + "attributes_conns": ["*internal"], +}, + +"sessions": { + "enabled": true, + "attributes_conns": ["conn1"], + "cdrs_conns": ["conn1"], + "rals_conns": ["conn1"], + "chargers_conns": ["*internal"], +}, + + +"apier": { + "scheduler_conns": ["*internal"], +}, + + +} diff --git a/data/conf/samples/httpagenttls_gob/httpagent.json b/data/conf/samples/httpagenttls_internal_gob/httpagent.json similarity index 100% rename from data/conf/samples/httpagenttls_gob/httpagent.json rename to data/conf/samples/httpagenttls_internal_gob/httpagent.json diff --git a/data/conf/samples/httpagenttls_mongo/cgrates.json b/data/conf/samples/httpagenttls_mongo/cgrates.json new file mode 100755 index 000000000..ee460ecfb --- /dev/null +++ b/data/conf/samples/httpagenttls_mongo/cgrates.json @@ -0,0 +1,77 @@ +{ +// CGRateS Configuration file +// + + +"general": { + "log_level": 7, +}, + + +"listen": { + "rpc_json": ":2012", + "rpc_gob": ":2013", + "http": ":2080", + "rpc_json_tls":":2022", + "rpc_gob_tls":":2023", + "http_tls": "localhost:2280", +}, + +"tls": { + "server_certificate" : "/usr/share/cgrates/tls/server.crt", // path to server certificate(must conatin server.crt + ca.crt) + "server_key":"/usr/share/cgrates/tls/server.key", // path to server key + "client_certificate" : "/usr/share/cgrates/tls/client.crt", // path to client certificate(must conatin client.crt + ca.crt) + "client_key":"/usr/share/cgrates/tls/client.key", // path to client key + "ca_certificate":"/usr/share/cgrates/tls/ca.crt", +}, + + +"stor_db": { + "db_type": "mongo", + "db_name": "cgrates", + "db_port": 27017, +}, + + +"rals": { + "enabled": true, + "max_increments":3000000, +}, + + +"schedulers": { + "enabled": true, +}, + + +"cdrs": { + "enabled": true, + "chargers_conns": ["*internal"], + "rals_conns": ["*internal"], +}, + + +"attributes": { + "enabled": true, +}, + +"chargers": { + "enabled": true, + "attributes_conns": ["*internal"], +}, + +"sessions": { + "enabled": true, + "attributes_conns": ["*localhost"], + "cdrs_conns": ["*localhost"], + "rals_conns": ["*localhost"], + "chargers_conns": ["*internal"], +}, + + +"apier": { + "scheduler_conns": ["*internal"], +}, + + +} diff --git a/data/conf/samples/httpagenttls_mongo/httpagent.json b/data/conf/samples/httpagenttls_mongo/httpagent.json new file mode 100755 index 000000000..7df9f5e06 --- /dev/null +++ b/data/conf/samples/httpagenttls_mongo/httpagent.json @@ -0,0 +1,169 @@ +{ + + +"http_agent": [ + { + "id": "conecto1", + "url": "/conecto", + "sessions_conns": ["*localhost"], + "request_payload": "*url", + "reply_payload": "*xml", + "request_processors": [ + { + "id": "OutboundAUTHDryRun", + "filters": ["*string:~*req.request_type:OutboundAUTH","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Allow", "field_id": "response.Allow", "type": "*constant", + "value": "1", "mandatory": true}, + {"tag": "Concatenated1", "field_id": "response.Concatenated", "type": "*composed", + "value": "~*req.MCC;/", "mandatory": true}, + {"tag": "Concatenated2", "field_id": "response.Concatenated", "type": "*composed", + "value": "Val1"}, + {"tag": "MaxDuration", "field_id": "response.MaxDuration", "type": "*constant", + "value": "1200", "blocker": true}, + {"tag": "Unused", "field_id": "response.Unused", "type": "*constant", + "value": "0"}, + ], + }, + { + "id": "OutboundAUTH", + "filters": ["*string:~*req.request_type:OutboundAUTH"], + "tenant": "cgrates.org", + "flags": [ "*auth", "*accounts", "*attributes"], + "request_fields":[ + {"tag": "Category", "field_id": "Category", "type": "*constant", "value": "call"}, + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.CallID", "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.Msisdn", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.Destination", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*constant", + "value": "*now", "mandatory": true}, + ], + "reply_fields":[ + {"tag": "Allow", "field_id": "response.Allow", "type": "*constant", + "value": "1", "mandatory": true}, + {"tag": "MaxDuration", "field_id": "response.MaxDuration", "type": "*composed", + "value": "~*cgrep.MaxUsage{*duration_seconds}", "mandatory": true}, + ], + }, + { + "id": "mtcall_cdr", + "filters": ["*string:~*req.request_type:MTCALL_CDR"], + "tenant": "cgrates.org", + "flags": ["*cdrs"], + "request_fields":[ + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.CDR_ID", "mandatory": true}, + {"tag": "OriginHost", "field_id": "OriginHost", "type": "*remote_host", + "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.msisdn", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.destination", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed", + "value": "~*req.timestamp", "mandatory": true}, + {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed", + "value": "~*req.timestamp", "mandatory": true}, + {"tag": "Usage", "field_id": "Usage", "type": "*composed", + "value": "~*req.leg_duration;s", "mandatory": true}, + ], + "reply_fields":[ + {"tag": "ResultCode", "filters": ["*rsr::~*cgrep.Error(!^$)"], + "field_id": "CDR_RESPONSE.RESULT_CODE", "type": "*composed", "value": "~*cgrep.Error", "blocker": true}, + {"tag": "CDR_ID", "field_id": "CDR_RESPONSE.CDR_ID", "type": "*composed", + "value": "~*req.CDR_ID", "mandatory": true}, + {"tag": "CDR_STATUS", "field_id": "CDR_RESPONSE.CDR_STATUS", "type": "*constant", + "value": "1", "mandatory": true}, + ], + } + ], + }, + { + "id": "conecto_xml", + "url": "/conecto_xml", + "sessions_conns": ["*localhost"], + "request_payload": "*xml", + "reply_payload": "*xml", + "request_processors": [ + { + "id": "cdr_from_xml", + "tenant": "cgrates.org", + "flags": ["*cdrs"], + "request_fields":[ + {"tag": "TOR", "field_id": "ToR", "type": "*constant", + "value": "*data", "mandatory": true}, + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.complete-datasession-notification.customerid", "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.complete-datasession-notification.username", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.complete-datasession-notification.userid", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed", + "value": "~*req.complete-datasession-notification.createtime", "mandatory": true}, + {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed", + "value": "~*req.complete-datasession-notification.createtime", "mandatory": true}, + {"tag": "Usage", "field_id": "Usage", "type": "*composed", + "value": "~*req.complete-datasession-notification.callleg.bytes", "mandatory": true}, + ], + "reply_fields":[], + } + ], + }, + { + "id": "textplain", + "url": "/textplain", + "sessions_conns": ["*localhost"], + "request_payload": "*url", + "reply_payload": "*text_plain", + "request_processors": [ + { + "id": "TextPlainDryRun", + "filters": ["*string:~*req.request_type:TextPlainDryRun","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Field1", "field_id": "Variable1", "type": "*variable", + "value": "Hola1", "mandatory": true}, + {"tag": "Field2", "field_id": "Variable2", "type": "*variable", + "value": "Hola2", "mandatory": true}, + {"tag": "Field3", "field_id": "ComposedVar", "type": "*composed", + "value": "Test", "mandatory": true}, + {"tag": "Field4", "field_id": "ComposedVar", "type": "*composed", + "value": "Composed", "mandatory": true}, + {"tag": "Field5", "field_id": "Item1.1", "type": "*variable", + "value": "Val1", "mandatory": true}, + ], + "continue": true, + }, + { + "id": "TextPlainDryRun2", + "filters": ["*string:~*req.request_type:TextPlainDryRun","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Field1", "field_id": "Item1.1", "type": "*variable", + "value": "Val2", "mandatory": true}, + ], + }, + ], + }, +], + + +} \ No newline at end of file diff --git a/data/conf/samples/httpagenttls_mongo_gob/cgrates.json b/data/conf/samples/httpagenttls_mongo_gob/cgrates.json new file mode 100755 index 000000000..96b87ddbc --- /dev/null +++ b/data/conf/samples/httpagenttls_mongo_gob/cgrates.json @@ -0,0 +1,85 @@ +{ +// CGRateS Configuration file +// + + +"general": { + "log_level": 7, +}, + + +"listen": { + "rpc_json": ":2012", + "rpc_gob": ":2013", + "http": ":2080", + "rpc_json_tls":":2022", + "rpc_gob_tls":":2023", + "http_tls": "localhost:2280", +}, + + +"rpc_conns": { + "conn1": { + "strategy": "*first", + "conns": [{"address": "127.0.0.1:2013", "transport":"*gob"}], + }, +}, + + +"tls": { + "server_certificate" : "/usr/share/cgrates/tls/server.crt", // path to server certificate(must conatin server.crt + ca.crt) + "server_key":"/usr/share/cgrates/tls/server.key", // path to server key + "client_certificate" : "/usr/share/cgrates/tls/client.crt", // path to client certificate(must conatin client.crt + ca.crt) + "client_key":"/usr/share/cgrates/tls/client.key", // path to client key + "ca_certificate":"/usr/share/cgrates/tls/ca.crt", +}, + +"stor_db": { + "db_type": "mongo", + "db_name": "cgrates", + "db_port": 27017, +}, + + +"rals": { + "enabled": true, + "max_increments":3000000, +}, + + +"schedulers": { + "enabled": true, +}, + + +"cdrs": { + "enabled": true, + "chargers_conns": ["*internal"], + "rals_conns": ["*internal"], +}, + + +"attributes": { + "enabled": true, +}, + +"chargers": { + "enabled": true, + "attributes_conns": ["*internal"], +}, + +"sessions": { + "enabled": true, + "attributes_conns": ["conn1"], + "cdrs_conns": ["conn1"], + "rals_conns": ["conn1"], + "chargers_conns": ["*internal"], +}, + + +"apier": { + "scheduler_conns": ["*internal"], +}, + + +} diff --git a/data/conf/samples/httpagenttls_mongo_gob/httpagent.json b/data/conf/samples/httpagenttls_mongo_gob/httpagent.json new file mode 100755 index 000000000..e2e9ea92f --- /dev/null +++ b/data/conf/samples/httpagenttls_mongo_gob/httpagent.json @@ -0,0 +1,169 @@ +{ + + +"http_agent": [ + { + "id": "conecto1", + "url": "/conecto", + "sessions_conns": ["conn1"], + "request_payload": "*url", + "reply_payload": "*xml", + "request_processors": [ + { + "id": "OutboundAUTHDryRun", + "filters": ["*string:~*req.request_type:OutboundAUTH","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Allow", "field_id": "response.Allow", "type": "*constant", + "value": "1", "mandatory": true}, + {"tag": "Concatenated1", "field_id": "response.Concatenated", "type": "*composed", + "value": "~*req.MCC;/", "mandatory": true}, + {"tag": "Concatenated2", "field_id": "response.Concatenated", "type": "*composed", + "value": "Val1"}, + {"tag": "MaxDuration", "field_id": "response.MaxDuration", "type": "*constant", + "value": "1200", "blocker": true}, + {"tag": "Unused", "field_id": "response.Unused", "type": "*constant", + "value": "0"}, + ], + }, + { + "id": "OutboundAUTH", + "filters": ["*string:~*req.request_type:OutboundAUTH"], + "tenant": "cgrates.org", + "flags": [ "*auth", "*accounts", "*attributes"], + "request_fields":[ + {"tag": "Category", "field_id": "Category", "type": "*constant", "value": "call"}, + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.CallID", "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.Msisdn", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.Destination", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*constant", + "value": "*now", "mandatory": true}, + ], + "reply_fields":[ + {"tag": "Allow", "field_id": "response.Allow", "type": "*constant", + "value": "1", "mandatory": true}, + {"tag": "MaxDuration", "field_id": "response.MaxDuration", "type": "*composed", + "value": "~*cgrep.MaxUsage{*duration_seconds}", "mandatory": true}, + ], + }, + { + "id": "mtcall_cdr", + "filters": ["*string:~*req.request_type:MTCALL_CDR"], + "tenant": "cgrates.org", + "flags": ["*cdrs"], + "request_fields":[ + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.CDR_ID", "mandatory": true}, + {"tag": "OriginHost", "field_id": "OriginHost", "type": "*remote_host", + "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.msisdn", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.destination", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed", + "value": "~*req.timestamp", "mandatory": true}, + {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed", + "value": "~*req.timestamp", "mandatory": true}, + {"tag": "Usage", "field_id": "Usage", "type": "*composed", + "value": "~*req.leg_duration;s", "mandatory": true}, + ], + "reply_fields":[ + {"tag": "ResultCode", "filters": ["*rsr::~*cgrep.Error(!^$)"], + "field_id": "CDR_RESPONSE.RESULT_CODE", "type": "*composed", "value": "~*cgrep.Error", "blocker": true}, + {"tag": "CDR_ID", "field_id": "CDR_RESPONSE.CDR_ID", "type": "*composed", + "value": "~*req.CDR_ID", "mandatory": true}, + {"tag": "CDR_STATUS", "field_id": "CDR_RESPONSE.CDR_STATUS", "type": "*constant", + "value": "1", "mandatory": true}, + ], + } + ], + }, + { + "id": "conecto_xml", + "url": "/conecto_xml", + "sessions_conns": ["conn1"], + "request_payload": "*xml", + "reply_payload": "*xml", + "request_processors": [ + { + "id": "cdr_from_xml", + "tenant": "cgrates.org", + "flags": ["*cdrs"], + "request_fields":[ + {"tag": "TOR", "field_id": "ToR", "type": "*constant", + "value": "*data", "mandatory": true}, + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.complete-datasession-notification.customerid", "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.complete-datasession-notification.username", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.complete-datasession-notification.userid", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed", + "value": "~*req.complete-datasession-notification.createtime", "mandatory": true}, + {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed", + "value": "~*req.complete-datasession-notification.createtime", "mandatory": true}, + {"tag": "Usage", "field_id": "Usage", "type": "*composed", + "value": "~*req.complete-datasession-notification.callleg.bytes", "mandatory": true}, + ], + "reply_fields":[], + } + ], + }, + { + "id": "textplain", + "url": "/textplain", + "sessions_conns": ["conn1"], + "request_payload": "*url", + "reply_payload": "*text_plain", + "request_processors": [ + { + "id": "TextPlainDryRun", + "filters": ["*string:~*req.request_type:TextPlainDryRun","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Field1", "field_id": "Variable1", "type": "*variable", + "value": "Hola1", "mandatory": true}, + {"tag": "Field2", "field_id": "Variable2", "type": "*variable", + "value": "Hola2", "mandatory": true}, + {"tag": "Field3", "field_id": "ComposedVar", "type": "*composed", + "value": "Test", "mandatory": true}, + {"tag": "Field4", "field_id": "ComposedVar", "type": "*composed", + "value": "Composed", "mandatory": true}, + {"tag": "Field5", "field_id": "Item1.1", "type": "*variable", + "value": "Val1", "mandatory": true}, + ], + "continue": true, + }, + { + "id": "TextPlainDryRun2", + "filters": ["*string:~*req.request_type:TextPlainDryRun","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Field1", "field_id": "Item1.1", "type": "*variable", + "value": "Val2", "mandatory": true}, + ], + }, + ], + }, +], + + +} \ No newline at end of file diff --git a/data/conf/samples/httpagenttls/cgrates.json b/data/conf/samples/httpagenttls_mysql/cgrates.json similarity index 100% rename from data/conf/samples/httpagenttls/cgrates.json rename to data/conf/samples/httpagenttls_mysql/cgrates.json diff --git a/data/conf/samples/httpagenttls_mysql/httpagent.json b/data/conf/samples/httpagenttls_mysql/httpagent.json new file mode 100755 index 000000000..7df9f5e06 --- /dev/null +++ b/data/conf/samples/httpagenttls_mysql/httpagent.json @@ -0,0 +1,169 @@ +{ + + +"http_agent": [ + { + "id": "conecto1", + "url": "/conecto", + "sessions_conns": ["*localhost"], + "request_payload": "*url", + "reply_payload": "*xml", + "request_processors": [ + { + "id": "OutboundAUTHDryRun", + "filters": ["*string:~*req.request_type:OutboundAUTH","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Allow", "field_id": "response.Allow", "type": "*constant", + "value": "1", "mandatory": true}, + {"tag": "Concatenated1", "field_id": "response.Concatenated", "type": "*composed", + "value": "~*req.MCC;/", "mandatory": true}, + {"tag": "Concatenated2", "field_id": "response.Concatenated", "type": "*composed", + "value": "Val1"}, + {"tag": "MaxDuration", "field_id": "response.MaxDuration", "type": "*constant", + "value": "1200", "blocker": true}, + {"tag": "Unused", "field_id": "response.Unused", "type": "*constant", + "value": "0"}, + ], + }, + { + "id": "OutboundAUTH", + "filters": ["*string:~*req.request_type:OutboundAUTH"], + "tenant": "cgrates.org", + "flags": [ "*auth", "*accounts", "*attributes"], + "request_fields":[ + {"tag": "Category", "field_id": "Category", "type": "*constant", "value": "call"}, + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.CallID", "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.Msisdn", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.Destination", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*constant", + "value": "*now", "mandatory": true}, + ], + "reply_fields":[ + {"tag": "Allow", "field_id": "response.Allow", "type": "*constant", + "value": "1", "mandatory": true}, + {"tag": "MaxDuration", "field_id": "response.MaxDuration", "type": "*composed", + "value": "~*cgrep.MaxUsage{*duration_seconds}", "mandatory": true}, + ], + }, + { + "id": "mtcall_cdr", + "filters": ["*string:~*req.request_type:MTCALL_CDR"], + "tenant": "cgrates.org", + "flags": ["*cdrs"], + "request_fields":[ + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.CDR_ID", "mandatory": true}, + {"tag": "OriginHost", "field_id": "OriginHost", "type": "*remote_host", + "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.msisdn", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.destination", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed", + "value": "~*req.timestamp", "mandatory": true}, + {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed", + "value": "~*req.timestamp", "mandatory": true}, + {"tag": "Usage", "field_id": "Usage", "type": "*composed", + "value": "~*req.leg_duration;s", "mandatory": true}, + ], + "reply_fields":[ + {"tag": "ResultCode", "filters": ["*rsr::~*cgrep.Error(!^$)"], + "field_id": "CDR_RESPONSE.RESULT_CODE", "type": "*composed", "value": "~*cgrep.Error", "blocker": true}, + {"tag": "CDR_ID", "field_id": "CDR_RESPONSE.CDR_ID", "type": "*composed", + "value": "~*req.CDR_ID", "mandatory": true}, + {"tag": "CDR_STATUS", "field_id": "CDR_RESPONSE.CDR_STATUS", "type": "*constant", + "value": "1", "mandatory": true}, + ], + } + ], + }, + { + "id": "conecto_xml", + "url": "/conecto_xml", + "sessions_conns": ["*localhost"], + "request_payload": "*xml", + "reply_payload": "*xml", + "request_processors": [ + { + "id": "cdr_from_xml", + "tenant": "cgrates.org", + "flags": ["*cdrs"], + "request_fields":[ + {"tag": "TOR", "field_id": "ToR", "type": "*constant", + "value": "*data", "mandatory": true}, + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.complete-datasession-notification.customerid", "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.complete-datasession-notification.username", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.complete-datasession-notification.userid", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed", + "value": "~*req.complete-datasession-notification.createtime", "mandatory": true}, + {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed", + "value": "~*req.complete-datasession-notification.createtime", "mandatory": true}, + {"tag": "Usage", "field_id": "Usage", "type": "*composed", + "value": "~*req.complete-datasession-notification.callleg.bytes", "mandatory": true}, + ], + "reply_fields":[], + } + ], + }, + { + "id": "textplain", + "url": "/textplain", + "sessions_conns": ["*localhost"], + "request_payload": "*url", + "reply_payload": "*text_plain", + "request_processors": [ + { + "id": "TextPlainDryRun", + "filters": ["*string:~*req.request_type:TextPlainDryRun","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Field1", "field_id": "Variable1", "type": "*variable", + "value": "Hola1", "mandatory": true}, + {"tag": "Field2", "field_id": "Variable2", "type": "*variable", + "value": "Hola2", "mandatory": true}, + {"tag": "Field3", "field_id": "ComposedVar", "type": "*composed", + "value": "Test", "mandatory": true}, + {"tag": "Field4", "field_id": "ComposedVar", "type": "*composed", + "value": "Composed", "mandatory": true}, + {"tag": "Field5", "field_id": "Item1.1", "type": "*variable", + "value": "Val1", "mandatory": true}, + ], + "continue": true, + }, + { + "id": "TextPlainDryRun2", + "filters": ["*string:~*req.request_type:TextPlainDryRun","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Field1", "field_id": "Item1.1", "type": "*variable", + "value": "Val2", "mandatory": true}, + ], + }, + ], + }, +], + + +} \ No newline at end of file diff --git a/data/conf/samples/httpagenttls_gob/cgrates.json b/data/conf/samples/httpagenttls_mysql_gob/cgrates.json similarity index 100% rename from data/conf/samples/httpagenttls_gob/cgrates.json rename to data/conf/samples/httpagenttls_mysql_gob/cgrates.json diff --git a/data/conf/samples/httpagenttls_mysql_gob/httpagent.json b/data/conf/samples/httpagenttls_mysql_gob/httpagent.json new file mode 100755 index 000000000..e2e9ea92f --- /dev/null +++ b/data/conf/samples/httpagenttls_mysql_gob/httpagent.json @@ -0,0 +1,169 @@ +{ + + +"http_agent": [ + { + "id": "conecto1", + "url": "/conecto", + "sessions_conns": ["conn1"], + "request_payload": "*url", + "reply_payload": "*xml", + "request_processors": [ + { + "id": "OutboundAUTHDryRun", + "filters": ["*string:~*req.request_type:OutboundAUTH","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Allow", "field_id": "response.Allow", "type": "*constant", + "value": "1", "mandatory": true}, + {"tag": "Concatenated1", "field_id": "response.Concatenated", "type": "*composed", + "value": "~*req.MCC;/", "mandatory": true}, + {"tag": "Concatenated2", "field_id": "response.Concatenated", "type": "*composed", + "value": "Val1"}, + {"tag": "MaxDuration", "field_id": "response.MaxDuration", "type": "*constant", + "value": "1200", "blocker": true}, + {"tag": "Unused", "field_id": "response.Unused", "type": "*constant", + "value": "0"}, + ], + }, + { + "id": "OutboundAUTH", + "filters": ["*string:~*req.request_type:OutboundAUTH"], + "tenant": "cgrates.org", + "flags": [ "*auth", "*accounts", "*attributes"], + "request_fields":[ + {"tag": "Category", "field_id": "Category", "type": "*constant", "value": "call"}, + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.CallID", "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.Msisdn", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.Destination", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*constant", + "value": "*now", "mandatory": true}, + ], + "reply_fields":[ + {"tag": "Allow", "field_id": "response.Allow", "type": "*constant", + "value": "1", "mandatory": true}, + {"tag": "MaxDuration", "field_id": "response.MaxDuration", "type": "*composed", + "value": "~*cgrep.MaxUsage{*duration_seconds}", "mandatory": true}, + ], + }, + { + "id": "mtcall_cdr", + "filters": ["*string:~*req.request_type:MTCALL_CDR"], + "tenant": "cgrates.org", + "flags": ["*cdrs"], + "request_fields":[ + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.CDR_ID", "mandatory": true}, + {"tag": "OriginHost", "field_id": "OriginHost", "type": "*remote_host", + "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.msisdn", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.destination", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed", + "value": "~*req.timestamp", "mandatory": true}, + {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed", + "value": "~*req.timestamp", "mandatory": true}, + {"tag": "Usage", "field_id": "Usage", "type": "*composed", + "value": "~*req.leg_duration;s", "mandatory": true}, + ], + "reply_fields":[ + {"tag": "ResultCode", "filters": ["*rsr::~*cgrep.Error(!^$)"], + "field_id": "CDR_RESPONSE.RESULT_CODE", "type": "*composed", "value": "~*cgrep.Error", "blocker": true}, + {"tag": "CDR_ID", "field_id": "CDR_RESPONSE.CDR_ID", "type": "*composed", + "value": "~*req.CDR_ID", "mandatory": true}, + {"tag": "CDR_STATUS", "field_id": "CDR_RESPONSE.CDR_STATUS", "type": "*constant", + "value": "1", "mandatory": true}, + ], + } + ], + }, + { + "id": "conecto_xml", + "url": "/conecto_xml", + "sessions_conns": ["conn1"], + "request_payload": "*xml", + "reply_payload": "*xml", + "request_processors": [ + { + "id": "cdr_from_xml", + "tenant": "cgrates.org", + "flags": ["*cdrs"], + "request_fields":[ + {"tag": "TOR", "field_id": "ToR", "type": "*constant", + "value": "*data", "mandatory": true}, + {"tag": "RequestType", "field_id": "RequestType", "type": "*constant", + "value": "*pseudoprepaid", "mandatory": true}, + {"tag": "OriginID", "field_id": "OriginID", "type": "*composed", + "value": "~*req.complete-datasession-notification.customerid", "mandatory": true}, + {"tag": "Account", "field_id": "Account", "type": "*composed", + "value": "~*req.complete-datasession-notification.username", "mandatory": true}, + {"tag": "Destination", "field_id": "Destination", "type": "*composed", + "value": "~*req.complete-datasession-notification.userid", "mandatory": true}, + {"tag": "SetupTime", "field_id": "SetupTime", "type": "*composed", + "value": "~*req.complete-datasession-notification.createtime", "mandatory": true}, + {"tag": "AnswerTime", "field_id": "AnswerTime", "type": "*composed", + "value": "~*req.complete-datasession-notification.createtime", "mandatory": true}, + {"tag": "Usage", "field_id": "Usage", "type": "*composed", + "value": "~*req.complete-datasession-notification.callleg.bytes", "mandatory": true}, + ], + "reply_fields":[], + } + ], + }, + { + "id": "textplain", + "url": "/textplain", + "sessions_conns": ["conn1"], + "request_payload": "*url", + "reply_payload": "*text_plain", + "request_processors": [ + { + "id": "TextPlainDryRun", + "filters": ["*string:~*req.request_type:TextPlainDryRun","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Field1", "field_id": "Variable1", "type": "*variable", + "value": "Hola1", "mandatory": true}, + {"tag": "Field2", "field_id": "Variable2", "type": "*variable", + "value": "Hola2", "mandatory": true}, + {"tag": "Field3", "field_id": "ComposedVar", "type": "*composed", + "value": "Test", "mandatory": true}, + {"tag": "Field4", "field_id": "ComposedVar", "type": "*composed", + "value": "Composed", "mandatory": true}, + {"tag": "Field5", "field_id": "Item1.1", "type": "*variable", + "value": "Val1", "mandatory": true}, + ], + "continue": true, + }, + { + "id": "TextPlainDryRun2", + "filters": ["*string:~*req.request_type:TextPlainDryRun","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Field1", "field_id": "Item1.1", "type": "*variable", + "value": "Val2", "mandatory": true}, + ], + }, + ], + }, +], + + +} \ No newline at end of file diff --git a/integration_test.sh b/integration_test.sh index 682abb150..68488378b 100755 --- a/integration_test.sh +++ b/integration_test.sh @@ -17,6 +17,9 @@ echo 'go test github.com/cgrates/cgrates/ers -tags=integration -dbtype=*internal go test github.com/cgrates/cgrates/ers -tags=integration -dbtype=*internal ers_internal=$? +echo 'go test github.com/cgrates/cgrates/loaders -tags=integration -dbtype=*internal' +go test github.com/cgrates/cgrates/loaders -tags=integration -dbtype=*internal +lds_internal=$? # SQL echo 'go test github.com/cgrates/cgrates/apier/v1 -tags=integration -dbtype=*sql' go test github.com/cgrates/cgrates/apier/v1 -tags=integration -dbtype=*sql @@ -30,7 +33,9 @@ en_sql=$? echo 'go test github.com/cgrates/cgrates/ers -tags=integration -dbtype=*sql' go test github.com/cgrates/cgrates/ers -tags=integration -dbtype=*sql ers_sql=$? - +echo 'go test github.com/cgrates/cgrates/loaders -tags=integration -dbtype=*sql' +go test github.com/cgrates/cgrates/loaders -tags=integration -dbtype=*sql +lds_sql=$? # Mongo echo 'go test github.com/cgrates/cgrates/apier/v1 -tags=integration -dbtype=*mongo' go test github.com/cgrates/cgrates/apier/v1 -tags=integration -dbtype=*mongo @@ -44,7 +49,9 @@ en_mongo=$? echo 'go test github.com/cgrates/cgrates/ers -tags=integration -dbtype=*mongo' go test github.com/cgrates/cgrates/ers -tags=integration -dbtype=*mongo ers_mongo=$? - +echo 'go test github.com/cgrates/cgrates/loaders -tags=integration -dbtype=*mongo' +go test github.com/cgrates/cgrates/loaders -tags=integration -dbtype=*mongo +lds_mongo=$? # Postgres echo 'go test github.com/cgrates/cgrates/apier/v1 -tags=integration -dbtype=*postgres' go test github.com/cgrates/cgrates/apier/v1 -tags=integration -dbtype=*postgres @@ -58,6 +65,9 @@ en_postgres=$? echo 'go test github.com/cgrates/cgrates/ers -tags=integration -dbtype=*postgres' go test github.com/cgrates/cgrates/ers -tags=integration -dbtype=*postgres ers_postgres=$? +echo 'go test github.com/cgrates/cgrates/loaders -tags=integration -dbtype=*postgres' +go test github.com/cgrates/cgrates/loaders -tags=integration -dbtype=*postgres +lds_postgres=$? echo 'go test github.com/cgrates/cgrates/cdrc -tags=integration' go test github.com/cgrates/cgrates/cdrc -tags=integration @@ -82,9 +92,6 @@ mgr=$? echo 'go test github.com/cgrates/cgrates/dispatchers -tags=integration' go test github.com/cgrates/cgrates/dispatchers -tags=integration dis=$? -echo 'go test github.com/cgrates/cgrates/loaders -tags=integration' -go test github.com/cgrates/cgrates/loaders -tags=integration -lds=$? echo 'go test github.com/cgrates/cgrates/services -tags=integration' go test github.com/cgrates/cgrates/services -tags=integration srv=$? diff --git a/loaders/lib_test.go b/loaders/lib_test.go new file mode 100644 index 000000000..89229649b --- /dev/null +++ b/loaders/lib_test.go @@ -0,0 +1,47 @@ +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package loaders + +import ( + "errors" + "flag" + "net/rpc" + "net/rpc/jsonrpc" + + "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/utils" +) + +var ( + waitRater = flag.Int("wait_rater", 100, "Number of miliseconds to wait for rater to start and cache") + dataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here") + encoding = flag.String("rpc", utils.MetaJSON, "what encoding whould be used for rpc comunication") + dbType = flag.String("dbtype", utils.MetaInternal, "The type of DataBase (Internal/Mongo/mySql)") +) + +func newRPCClient(cfg *config.ListenCfg) (c *rpc.Client, err error) { + switch *encoding { + case utils.MetaJSON: + return jsonrpc.Dial(utils.TCP, cfg.RPCJSONListen) + case utils.MetaGOB: + return rpc.Dial(utils.TCP, cfg.RPCGOBListen) + default: + return nil, errors.New("UNSUPPORTED_RPC") + } +} diff --git a/loaders/loader_it_test.go b/loaders/loader_it_test.go index 7eaecfe73..d998ed85c 100644 --- a/loaders/loader_it_test.go +++ b/loaders/loader_it_test.go @@ -20,11 +20,8 @@ along with this program. If not, see package loaders import ( - "errors" - "flag" "io/ioutil" "net/rpc" - "net/rpc/jsonrpc" "os" "path" "reflect" @@ -39,61 +36,54 @@ import ( var ( loaderCfgPath string + loaderCfgDIR string //run tests for specific configuration loaderCfg *config.CGRConfig loaderRPC *rpc.Client - loaderDataDir = "/usr/share/cgrates" - loaderConfigDIR string //run tests for specific configuration loaderPathIn, loaderPathOut string - encoding = flag.String("rpc", utils.MetaJSON, "what encoding whould be uused for rpc comunication") + + sTestsLoader = []func(t *testing.T){ + testLoaderMakeFolders, + testLoaderInitCfg, + testLoaderResetDataDB, + testLoaderStartEngine, + testLoaderRPCConn, + testLoaderPopulateData, + testLoaderLoadAttributes, + testLoaderVerifyOutDir, + testLoaderCheckAttributes, + testLoaderKillEngine, + } ) -func newRPCClient(cfg *config.ListenCfg) (c *rpc.Client, err error) { - switch *encoding { - case utils.MetaJSON: - return jsonrpc.Dial(utils.TCP, cfg.RPCJSONListen) - case utils.MetaGOB: - return rpc.Dial(utils.TCP, cfg.RPCGOBListen) - default: - return nil, errors.New("UNSUPPORTED_RPC") - } -} - -var sTestsLoader = []func(t *testing.T){ - testLoaderMakeFolders, - testLoaderInitCfg, - testLoaderResetDataDB, - testLoaderStartEngine, - testLoaderRPCConn, - testLoaderPopulateData, - testLoaderLoadAttributes, - testLoaderVerifyOutDir, - testLoaderCheckAttributes, - testLoaderKillEngine, -} - //Test start here -func TestLoaderITMySql(t *testing.T) { - loaderConfigDIR = "tutmysql" - for _, stest := range sTestsLoader { - t.Run(loaderConfigDIR, stest) +func TestLoaderIT(t *testing.T) { + switch *dbType { + case utils.MetaInternal: + loaderCfgDIR = "tutinternal" + case utils.MetaSQL: + loaderCfgDIR = "tutmysql" + case utils.MetaMongo: + loaderCfgDIR = "tutmongo" + case utils.MetaPostgres: + t.SkipNow() + default: + t.Fatal("Unknown Database type") } -} -func TestLoaderITMongo(t *testing.T) { - loaderConfigDIR = "tutmongo" + loaderCfgDIR = "tutmysql" for _, stest := range sTestsLoader { - t.Run(loaderConfigDIR, stest) + t.Run(loaderCfgDIR, stest) } } func testLoaderInitCfg(t *testing.T) { var err error - loaderCfgPath = path.Join(loaderDataDir, "conf", "samples", "loaders", loaderConfigDIR) + loaderCfgPath = path.Join(*dataDir, "conf", "samples", "loaders", loaderCfgDIR) loaderCfg, err = config.NewCGRConfigFromPath(loaderCfgPath) if err != nil { t.Fatal(err) } - loaderCfg.DataFolderPath = loaderDataDir // Share DataFolderPath through config towards StoreDb for Flush() + loaderCfg.DataFolderPath = *dataDir // Share DataFolderPath through config towards StoreDb for Flush() config.SetCgrConfig(loaderCfg) } From a0978f81a74f526cba1d2942e4e057b88a19a2ac Mon Sep 17 00:00:00 2001 From: DanB Date: Sat, 18 Jan 2020 20:00:17 +0100 Subject: [PATCH 05/14] Adding configuration sample to Diameter doc --- docs/cgrates_json.rst | 11 ++- docs/diamagent.rst | 174 +++++++++++++++++++++++++++++++++++++++++- docs/index.rst | 2 +- 3 files changed, 182 insertions(+), 5 deletions(-) diff --git a/docs/cgrates_json.rst b/docs/cgrates_json.rst index b62b3b8c4..cf75db2e8 100644 --- a/docs/cgrates_json.rst +++ b/docs/cgrates_json.rst @@ -4,9 +4,16 @@ 4.1. cgr-engine configuration file ================================== -Organized into configuration sections. All configuration options come with defaults and we have tried our best to choose the best ones for a minimum of efforts necessary when running. +Has a *JSON* format with commented lines starting with *//*. +Organized into configuration sections which offers the advantage of being easily splitable. +All configuration options come with defaults and we have tried our best to choose the best ones for a minimum of efforts necessary when running. +Can be loaded from local folders or remotely using http transport. -Below is the default configuration file which comes hardcoded into `cgr-engine`_. +.. hint:: You can split the configuration into any number of *.json* files/directories since the :ref:cgr-engine loads recursively the complete configuration folder, alphabetically ordered + + + +Below is the default configuration file which comes hardcoded into :ref:cgr-engine: .. literalinclude:: ../data/conf/cgrates/cgrates.json :language: javascript diff --git a/docs/diamagent.rst b/docs/diamagent.rst index e3f9f07da..8fffaa05a 100644 --- a/docs/diamagent.rst +++ b/docs/diamagent.rst @@ -1,5 +1,175 @@ +.. _Diameter: https://tools.ietf.org/html/rfc6733 + +.. _DiameterAgent: + DiameterAgent ============= -Implements Diameter_ protocol interface in a standard agnostic manner, having the ability to implement them by defining simple *processor templates* within the :ref:`configuration ` files. -Used mostly in modern mobile networks (xG). \ No newline at end of file +**DiameterAgent** translates between Diameter_ and **CGRateS**, sending *RPC* requests towards **SessionS** component and returning replies from it to the *DiameterClient*. +Implements Diameter_ protocol in a standard agnostic manner, giving users the ability to implement own interfaces by defining simple *processor templates* within the :ref:`configuration ` files. +Used mostly in modern mobile networks (LTE/xG). + + +Configuration +------------- + +The **DiameterAgent** is configured via *diameter_agent* section within :ref:`configuration `. + + +Sample config (explanation in the comments): + +:: + + "diameter_agent": { + "enabled": false, // enables the diameter agent: + "listen": "127.0.0.1:3868", // address where to listen for diameter requests + "listen_net": "tcp", // transport type for diameter + "dictionaries_path": "/usr/share/cgrates/diameter/dict/", // path towards directory holding additional dictionaries to load + "sessions_conns": ["*internal"], + "origin_host": "CGR-DA", // diameter Origin-Host AVP used in replies + "origin_realm": "cgrates.org", // diameter Origin-Realm AVP used in replies + "vendor_id": 0, // diameter Vendor-Id AVP used in replies + "product_name": "CGRateS", // diameter Product-Name AVP used in replies + "concurrent_requests": -1, // limit the number of active requests processed by the server <-1|0-n> + "synced_conn_requests": false, // process one request at the time per connection + "asr_template": "*asr", // enable AbortSession message being sent to client + // forcing session disconnection from CGRateS side + + "templates":{ // message templates which can be injected within request/replies + "*err": [ + {"tag": "SessionId", "field_id": "Session-Id", "type": "*composed", + "value": "~*req.Session-Id", "mandatory": true}, + {"tag": "OriginHost", "field_id": "Origin-Host", "type": "*composed", + "value": "~*vars.OriginHost", "mandatory": true}, + {"tag": "OriginRealm", "field_id": "Origin-Realm", "type": "*composed", + "value": "~*vars.OriginRealm", "mandatory": true}, + ], + "*cca": [ + {"tag": "SessionId", "field_id": "Session-Id", "type": "*composed", + "value": "~*req.Session-Id", "mandatory": true}, + {"tag": "ResultCode", "field_id": "Result-Code", "type": "*constant", + "value": "2001"}, + {"tag": "OriginHost", "field_id": "Origin-Host", "type": "*composed", + "value": "~*vars.OriginHost", "mandatory": true}, + {"tag": "OriginRealm", "field_id": "Origin-Realm", "type": "*composed", + "value": "~*vars.OriginRealm", "mandatory": true}, + {"tag": "AuthApplicationId", "field_id": "Auth-Application-Id", "type": "*composed", + "value": "~*vars.*appid", "mandatory": true}, + {"tag": "CCRequestType", "field_id": "CC-Request-Type", "type": "*composed", + "value": "~*req.CC-Request-Type", "mandatory": true}, + {"tag": "CCRequestNumber", "field_id": "CC-Request-Number", "type": "*composed", + "value": "~*req.CC-Request-Number", "mandatory": true}, + ], + "*asr": [ + {"tag": "SessionId", "field_id": "Session-Id", "type": "*variable", + "value": "~*req.Session-Id", "mandatory": true}, + {"tag": "OriginHost", "field_id": "Origin-Host", "type": "*variable", + "value": "~*req.Destination-Host", "mandatory": true}, + {"tag": "OriginRealm", "field_id": "Origin-Realm", "type": "*variable", + "value": "~*req.Destination-Realm", "mandatory": true}, + {"tag": "DestinationRealm", "field_id": "Destination-Realm", "type": "*variable", + "value": "~*req.Origin-Realm", "mandatory": true}, + {"tag": "DestinationHost", "field_id": "Destination-Host", "type": "*variable", + "value": "~*req.Origin-Host", "mandatory": true}, + {"tag": "AuthApplicationId", "field_id": "Auth-Application-Id", "type": "*variable", + "value": "~*vars.*appid", "mandatory": true}, + {"tag": "UserName", "field_id": "User-Name", "type": "*variable", + "value": "~*req.User-Name", "mandatory": true}, + {"tag": "OriginStateID", "field_id": "Origin-State-Id", "type": "*constant", + "value": "1"}, + ] + }, + "request_processors": [ // decision logic for message processing + { + "id": "SMSes", // id is used for debug in logs (ie: using *log flag) + "filters": [ // list of filters to be applied on message for this processor to run + "*string:~*vars.*cmd:CCR", + "*string:~*req.CC-Request-Type:4", + "*string:~*req.Service-Context-Id:LPP" + ], + "flags": ["*event", "*accounts", "*cdrs"], // influence processing logic within CGRateS workflow + "request_fields":[ // data exchanged between Diameter and CGRateS + { + "tag": "TOR", "field_id": "ToR", // tag is used in debug, field_id is the field on CGRateS side + "type": "*constant", "value": "*sms"} // type defines the method to provide the value + { + "tag": "OriginID", "field_id": "OriginID", // OriginID will identify uniquely the session on CGRateS side + "type": "*variable", "mandatory": true, // it's value will be taken from Diameter AVP: + "value": "~*req.Multiple-Services-Credit-Control.Service-Identifier"// Multiple-Services-Credit-Control.Service-Identifier + }, + { + "tag": "OriginHost", "field_id": "OriginHost", // OriginHost combined with OriginID is used by CGRateS to build the CGRID + "mandatory": true, "type": "*constant", "value": "0.0.0.0" + }, + { + "tag": "RequestType", "field_id": "RequestType",// RequestType tells SessionS which charging type to apply for the event + "type": "*constant", "value": "*prepaid" + }, + { + "tag": "Category", "field_id": "Category", // Category serves for ataching Account and RatingProfile to the request + "type": "*constant", "value": "sms" + }, + { + "tag": "Account", "field_id": "Account", // Account serves for ataching Account and RatingProfile to the request + "type": "*variable", "mandatory": true, // value is taken from a groupped AVP ( + "value": "~*req.Subscription-Id.Subscription-Id-Data[~Subscription-Id-Type(0)]" // where Subscription-Id-Type is 0) + }, + { + "tag": "Destination", "field_id": "Destination", // Destination is used for charging + "type": "*variable", "mandatory": true, // value from Diameter will be mediated before sent to CGRateS + "value": "~*req.Service-Information.SMS-Information.Recipient-Info.Recipient-Address.Address-Data:s/^\\+49(\\d+)/int${1}/:s/^0049(\\d+)/int${1}/:s/^49(\\d+)/int${1}/:s/^00(\\d+)/+${1}/:s/^[\\+]?(\\d+)/int${1}/:s/int(\\d+)/+49${1}/" + }, + { + "tag": "Destination", "field_id": "Destination", // Second Destination will overwrite the first in specific cases + "filters":[ // Only overwrite when filters are matching + "*notprefix:~*req.Service-Information.SMS-Information.Recipient-Info.Recipient-Address.Address-Data:49", + "*notprefix:~*req.Service-Information.SMS-Information.Recipient-Info.Recipient-Address.Address-Data:3958" + ], + "type": "*variable", "mandatory": true, + "value": "~*req.Service-Information.SMS-Information.Recipient-Info.Recipient-Address.Address-Data:s/^[\\+]?(\\d+)/int${1}/:s/int(\\d+)/+00${1}/"}, + { + "tag": "SetupTime", "field_id": "SetupTime", // SetupTime is used by charging + "type": "*variable", + "value": "~*req.Event-Timestamp", "mandatory": true + }, + { + "tag": "AnswerTime", "field_id": "AnswerTime", // AnswerTime is used by charging + "type": "*variable", , "mandatory": true, "value": "~*req.Event-Timestamp" + }, + { + "tag": "Usage", "field_id": "Usage", // Usage is used by charging + "type": "*variable", "mandatory": true, + "value": "~*req.Multiple-Services-Credit-Control.Requested-Service-Unit.CC-Service-Specific-Units" + }, + { + "tag": "Originator-SCCP-Address", // Originator-SCCP-Address is an extra field which we want in CDR + "field_id": "Originator-SCCP-Address", // not used by CGRateS + "type": "*variable", "mandatory": true, + "value": "~*req.Service-Information.SMS-Information.Originator-SCCP-Address" + }, + ], + "reply_fields":[ // fields which are sent back to DiameterClient + { + "tag": "CCATemplate", // inject complete Template defined as *cca above + "type": "*template", "value": "*cca" + }, + { + "tag": "ResultCode", // Change the ResultCode if the reply received from CGRateS contains a 0 MaxUsage + "filters": ["*eq:~*cgrep.MaxUsage:0"], + "field_id": "Result-Code", "blocker": true, // do not consider further fields if this one is processed + "type": "*constant", "value": "4012"}, + {"tag": "ResultCode", // Change the ResultCode AVP if there was an error received from CGRateS + "filters": ["*notempty:~*cgrep.Error:"], + "field_id": "Result-Code", "blocker": true, + "type": "*constant", "value": "5030"} + ] + } + + ] + }, + + ], + }, + + + diff --git a/docs/index.rst b/docs/index.rst index f207e81f2..591bca279 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -10,7 +10,7 @@ Full contents: ============= .. toctree:: - :maxdepth: 2 + :maxdepth: 5 introduction architecture From d365b67dfd229d3ef243c5da69c60ad032a987f4 Mon Sep 17 00:00:00 2001 From: DanB Date: Sun, 19 Jan 2020 11:19:47 +0100 Subject: [PATCH 06/14] Reorganizing docs/index --- docs/diamagent.rst | 2 + docs/index.rst | 208 ++++++++++++++++++++++++++++++++++++++++-- docs/introduction.rst | 2 +- 3 files changed, 203 insertions(+), 9 deletions(-) diff --git a/docs/diamagent.rst b/docs/diamagent.rst index 8fffaa05a..f83f74843 100644 --- a/docs/diamagent.rst +++ b/docs/diamagent.rst @@ -6,7 +6,9 @@ DiameterAgent ============= **DiameterAgent** translates between Diameter_ and **CGRateS**, sending *RPC* requests towards **SessionS** component and returning replies from it to the *DiameterClient*. + Implements Diameter_ protocol in a standard agnostic manner, giving users the ability to implement own interfaces by defining simple *processor templates* within the :ref:`configuration ` files. + Used mostly in modern mobile networks (LTE/xG). diff --git a/docs/index.rst b/docs/index.rst index 591bca279..23b3b00f3 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,18 +1,192 @@ -.. CGRateS documentation master file, created by - sphinx-quickstart on Mon Mar 5 10:59:27 2012. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - Welcome to CGRateS's documentation! =================================== -Full contents: -============= + +`CGRateS`_ is a *very fast* (**50k+ CPS**) and *easily scalable* (**load-balancer** + **replication** included) **Real-time Enterprise Billing Suite** targeted especially for ISPs and Telecom Operators (but not only). + +Starting as a pure **billing engine**, CGRateS has evolved over the years into a reliable **real-time charging framework**, able to accommodate various business cases in a *generic way*. + +Being an *"engine style"* the project focuses on providing best ratio between **functionality** (over 15 daemons/services implemented with a rich number of `features `_ and a development team agile in developing new ones) and **performance** (dedicated benchmark tool, asynchronous request processing, own transactional cache component), however not losing focus of **quality** (test driven development policy). + +It is written in `Go`_ programming language and accessible from any programming language via JSON RPC. +The code is well documented (**go doc** compliant `API docs`_) and heavily tested (**5k+** tests are part of the unit test suite). + +Meant to be pluggable into existing billing infrastructure and as non-intrusive as possible, +CGRateS passes the decisions about logic flow to system administrators and incorporates as less as possible business logic. + +Modular and flexible, CGRateS provides APIs over a variety of simultaneously accessible communication interfaces: + - **In-process** : optimal when there is no need to split services over different processes + - **JSON over TCP** : most preferred due to its simplicity and readability + - **JSON over HTTP** : popular due to fast interoperability development + - **JSON over Websockets** : useful where 2 ways interaction over same TCP socket is required + - **GOB over TCP** : slightly faster than JSON one but only accessible for the moment out of Go (``_). + +CGRateS is capable of four charging modes: + +- \*prepaid + - Session events monitored in real-time + - Session authorization via events with security call timer + - Real-time balance updates with configurable debit interval + - Support for simultaneous sessions out of the same account + - Real-time fraud detection with automatic mitigation + - *Advantage*: real-time overview of the costs and fast detection in case of fraud, concurrent account sessions supported + - *Disadvantage*: more CPU intensive. + +- \*pseudoprepaid + - Session authorization via events + - Charging done at the end of the session out of CDR received + - *Advantage*: less CPU intensive due to less events processed + - *Disadvantage*: as balance updates happen only at the end of the session there can be costs discrepancy in case of multiple sessions out of same account (including going on negative balance). + +- \*postpaid + - Charging done at the end of the session out of CDR received without session authorization + - Useful when no authorization is necessary (trusted accounts) and no real-time event interaction is present (balance is updated only when CDR is present). + +- \*rated + - Special charging mode where there is no accounting interaction (no balances are used) but the primary interest is attaching costs to CDRs. + - Specific mode for Wholesale business processing high-throughput CDRs + - Least CPU usage out of the four modes (fastest charging). + + +.. _cgrates_features: + +Features +-------- + +- Performance oriented. To get an idea about speed, we have benchmarked 50000+ req/sec on comodity hardware without any tweaks in the kernel + - Using most modern programming concepts like multiprocessor support, asynchronous code execution within microthreads, channel based locking + - Built-in data caching system with LRU and TTL support + - Linear performance increase via simple hardware addition + - On demand performance increase via in-process / over network communication between engine services. + +- Modular architecture + - Plugable into existing infrastructure + - Non-intrusive into existing setups + - Easy to enhance functionality by writing custom components + - Flexible API accessible via both **GOB** (`Go`_ specific, increased performance) or **JSON** (platform independent, universally accessible) + - Easy distribution (one binary concept, can run via NFS on all Linux servers without install). + +- Easy administration + - One binary can run on all Linux servers without additional installation (simple copy) + - Can run diskless via NFS + - Virtualization/containerization friendly(runs on Docker_). + +- GOCS (Global Online Charging System) + - Support for global networks with one master + multi-cache nodes around the globe for low query latency + - Mutiple Balance types per Account (\*monetary, \*voice, \*sms, \*data, \*generic) + - Unlimited number of Account Balances with weight based prioritization + - Various Balance filters (ie: per-destination, roaming-only, weekend-only) + - Support for Volume based discounts and automatic bonuses (ie: 5 SMS free for every 10 minutes in one hour to specific destination) + - Session based charging with support for concurrent sessions per account and per session dynamic debit interval + - Session emulation combined with Derived Charging (separate charging for distributors chaining, customer/supplier parallel calculations) + - Balance reservation and refunds + - Event based charging (ie: SMS, MESSAGE) + - Built-in Task-Scheduler supporting both one-time as well as recurrent actions (automatic subscriptions management, recurrent \*debit/\*topup, DID charging) + - Real-time balance monitors with automatic actions triggered (bonuses or fraud detection). + +- Highly configurable Rating + - Connect Fees + - Priced Units definition + - Rate increments + - Rate groups (ie. charge first minute in a call as a whole and next ones per second) + - Verbose durations(up to nanoseconds billing) + - Configurable decimals per destination + - Rating subject categorization (ie. premium/local charges, roaming) + - Recurrent rates definition (per year, month, day, dayOfWeek, time) + - Rating Profiles activation times (eg: rates becoming active at specific time in the future) + - Rating Profiles fallback (per subject destinations with fallback to server wide pricing) + - Verbose charging logs to comply strict rules imposed by some country laws. + +- Multi-Tenant from day one + - Default Tenant configurable for one-tenant systems + - Security enforced for RPC-API on Tenant level. + +- Online configuration reloads without restart + - Engine configuration from .json folder or remote http server + - Tariff Plans from .csv folder or database storage. + +- CDR server + - Optional offline database storage + - Online (rating queues) or offline (via RPC-API) exports with customizable content via .json templates + - Multiple export interfaces: files, HTTP, AMQP_, SQS_, Kafka_. + +- Generic Event Reader + - Process various sources of events and convert them into internal ones which are sent to CDR server for rating + - Conversion rules defined in .json templates + - Supported interfaces: .csv, .xml, fixed width files, Kafka_. + +- Events mediation + - Ability to add/change/remove information within *Events* to achieve additional services or correction + - Performance oriented. + +- Routing server for VoIP + - Implements strategies like *Least Cost Routing*, *Load Balacer*, *High Availability* + - Implements *Number Portability* service. + +- Resource allocation controller + - Generic filters for advanced logic + - In-memory operations for increased performance + - Backup in offline storage. + +- Stats service + - Generic stats (\*sum, \*difference, \*multiply, \*divide) + - In-memory operations for increased performance + - Backup in offline storage. + +- Thresholds monitor + - Particular implementation of *Fraud Detection with automatic mitigation* + - Execute independent actions which can serve various purposes (notifications, accounts disables, bonuses to accounts). + +- Multiple RPC interfaces + - Support for *JSON-RPC*, *GOB-PC* over TCP, HTTP, websockets + - Support for HTTP-REST interface. + +- Various agents to outside world: + - Asterisk_ + - FreeSWITCH_ + - Kamailio_ + - OpenSIPS_ + - Diameter + - Radius + - Generic HTTP + - DNS/ENUM. + +- Built in High-Availability mechanisms: + - Dispatcher with static or dynamic routing + - Server data replication + - Client remote data querying. + + +- Good documentation ( that's me :). + +- **"Free as in Beer"** with commercial support available on-demand. + + +Links +----- + +- CGRateS home page ``_ +- Documentation ``_ +- API docs ``_ +- Source code ``_ +- Travis CI ``_ +- Google group ``_ +- IRC `irc.freenode.net #cgrates `_ + + +License +------- + +`CGRateS`_ is released under the terms of the `[GNU GENERAL PUBLIC LICENSE Version 3] `_. See **LICENSE.txt** file for details. + + + +Table of Contents +----------------- .. toctree:: :maxdepth: 5 - introduction architecture installation configuration @@ -22,3 +196,21 @@ Full contents: miscellaneous + +.. _CGRateS: http://cgrates.org +.. _Go: http://golang.org +.. _Docker: https://www.docker.com/ +.. _Kafka: https://kafka.apache.org/ +.. _redis: http://redis.io +.. _mongodb: http://www.mongodb.org +.. _api docs: https://godoc.org/github.com/cgrates/cgrates/apier +.. _SQS: https://aws.amazon.com/de/sqs/ +.. _AMQP: https://www.amqp.org/ +.. _Asterisk: https://www.asterisk.org/ +.. _FreeSWITCH: https://freeswitch.com/ +.. _Kamailio: https://www.kamailio.org/w/ +.. _OpenSIPS: https://opensips.org/ + + + + diff --git a/docs/introduction.rst b/docs/introduction.rst index 95e184867..f7d99d259 100644 --- a/docs/introduction.rst +++ b/docs/introduction.rst @@ -2,7 +2,7 @@ Introduction ************ -`CGRateS`_ is a *very fast* (**50k+ CPS**) and *easily scalable* (**load-balancer** + **replication** included) **Real-time Enterprise Billing Suite** *ENGINE* targeted especially for ISPs and Telecom Operators (but not only). +`CGRateS`_ is a *very fast* (**50k+ CPS**) and *easily scalable* (**load-balancer** + **replication** included) **Real-time Enterprise Billing Suite** targeted especially for ISPs and Telecom Operators (but not only). Starting as a pure **billing engine**, CGRateS has evolved over the years into a reliable **real-time charging framework**, able to accommodate various business cases in a *generic way*. From 4b7601eacea9f85a7ce11f2ed4e1ae539d240dc1 Mon Sep 17 00:00:00 2001 From: DanB Date: Sun, 19 Jan 2020 11:47:44 +0100 Subject: [PATCH 07/14] Docs - index formatting --- docs/index.rst | 166 +++-------------------- docs/introduction.rst | 197 --------------------------- docs/overview.rst | 305 +++++++++++++++++------------------------- 3 files changed, 142 insertions(+), 526 deletions(-) delete mode 100644 docs/introduction.rst diff --git a/docs/index.rst b/docs/index.rst index 23b3b00f3..9ce990fba 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,5 +1,20 @@ -Welcome to CGRateS's documentation! -=================================== +.. _CGRateS: http://cgrates.org +.. _Go: http://golang.org +.. _Docker: https://www.docker.com/ +.. _Kafka: https://kafka.apache.org/ +.. _redis: http://redis.io +.. _mongodb: http://www.mongodb.org +.. _api docs: https://godoc.org/github.com/cgrates/cgrates/apier +.. _SQS: https://aws.amazon.com/de/sqs/ +.. _AMQP: https://www.amqp.org/ +.. _Asterisk: https://www.asterisk.org/ +.. _FreeSWITCH: https://freeswitch.com/ +.. _Kamailio: https://www.kamailio.org/w/ +.. _OpenSIPS: https://opensips.org/ + + +Introduction +============ `CGRateS`_ is a *very fast* (**50k+ CPS**) and *easily scalable* (**load-balancer** + **replication** included) **Real-time Enterprise Billing Suite** targeted especially for ISPs and Telecom Operators (but not only). @@ -48,137 +63,12 @@ CGRateS is capable of four charging modes: - Least CPU usage out of the four modes (fastest charging). -.. _cgrates_features: +More overview content: -Features --------- - -- Performance oriented. To get an idea about speed, we have benchmarked 50000+ req/sec on comodity hardware without any tweaks in the kernel - - Using most modern programming concepts like multiprocessor support, asynchronous code execution within microthreads, channel based locking - - Built-in data caching system with LRU and TTL support - - Linear performance increase via simple hardware addition - - On demand performance increase via in-process / over network communication between engine services. - -- Modular architecture - - Plugable into existing infrastructure - - Non-intrusive into existing setups - - Easy to enhance functionality by writing custom components - - Flexible API accessible via both **GOB** (`Go`_ specific, increased performance) or **JSON** (platform independent, universally accessible) - - Easy distribution (one binary concept, can run via NFS on all Linux servers without install). - -- Easy administration - - One binary can run on all Linux servers without additional installation (simple copy) - - Can run diskless via NFS - - Virtualization/containerization friendly(runs on Docker_). - -- GOCS (Global Online Charging System) - - Support for global networks with one master + multi-cache nodes around the globe for low query latency - - Mutiple Balance types per Account (\*monetary, \*voice, \*sms, \*data, \*generic) - - Unlimited number of Account Balances with weight based prioritization - - Various Balance filters (ie: per-destination, roaming-only, weekend-only) - - Support for Volume based discounts and automatic bonuses (ie: 5 SMS free for every 10 minutes in one hour to specific destination) - - Session based charging with support for concurrent sessions per account and per session dynamic debit interval - - Session emulation combined with Derived Charging (separate charging for distributors chaining, customer/supplier parallel calculations) - - Balance reservation and refunds - - Event based charging (ie: SMS, MESSAGE) - - Built-in Task-Scheduler supporting both one-time as well as recurrent actions (automatic subscriptions management, recurrent \*debit/\*topup, DID charging) - - Real-time balance monitors with automatic actions triggered (bonuses or fraud detection). - -- Highly configurable Rating - - Connect Fees - - Priced Units definition - - Rate increments - - Rate groups (ie. charge first minute in a call as a whole and next ones per second) - - Verbose durations(up to nanoseconds billing) - - Configurable decimals per destination - - Rating subject categorization (ie. premium/local charges, roaming) - - Recurrent rates definition (per year, month, day, dayOfWeek, time) - - Rating Profiles activation times (eg: rates becoming active at specific time in the future) - - Rating Profiles fallback (per subject destinations with fallback to server wide pricing) - - Verbose charging logs to comply strict rules imposed by some country laws. - -- Multi-Tenant from day one - - Default Tenant configurable for one-tenant systems - - Security enforced for RPC-API on Tenant level. - -- Online configuration reloads without restart - - Engine configuration from .json folder or remote http server - - Tariff Plans from .csv folder or database storage. - -- CDR server - - Optional offline database storage - - Online (rating queues) or offline (via RPC-API) exports with customizable content via .json templates - - Multiple export interfaces: files, HTTP, AMQP_, SQS_, Kafka_. - -- Generic Event Reader - - Process various sources of events and convert them into internal ones which are sent to CDR server for rating - - Conversion rules defined in .json templates - - Supported interfaces: .csv, .xml, fixed width files, Kafka_. - -- Events mediation - - Ability to add/change/remove information within *Events* to achieve additional services or correction - - Performance oriented. - -- Routing server for VoIP - - Implements strategies like *Least Cost Routing*, *Load Balacer*, *High Availability* - - Implements *Number Portability* service. - -- Resource allocation controller - - Generic filters for advanced logic - - In-memory operations for increased performance - - Backup in offline storage. - -- Stats service - - Generic stats (\*sum, \*difference, \*multiply, \*divide) - - In-memory operations for increased performance - - Backup in offline storage. - -- Thresholds monitor - - Particular implementation of *Fraud Detection with automatic mitigation* - - Execute independent actions which can serve various purposes (notifications, accounts disables, bonuses to accounts). - -- Multiple RPC interfaces - - Support for *JSON-RPC*, *GOB-PC* over TCP, HTTP, websockets - - Support for HTTP-REST interface. - -- Various agents to outside world: - - Asterisk_ - - FreeSWITCH_ - - Kamailio_ - - OpenSIPS_ - - Diameter - - Radius - - Generic HTTP - - DNS/ENUM. - -- Built in High-Availability mechanisms: - - Dispatcher with static or dynamic routing - - Server data replication - - Client remote data querying. - - -- Good documentation ( that's me :). - -- **"Free as in Beer"** with commercial support available on-demand. - - -Links ------ - -- CGRateS home page ``_ -- Documentation ``_ -- API docs ``_ -- Source code ``_ -- Travis CI ``_ -- Google group ``_ -- IRC `irc.freenode.net #cgrates `_ - - -License -------- - -`CGRateS`_ is released under the terms of the `[GNU GENERAL PUBLIC LICENSE Version 3] `_. See **LICENSE.txt** file for details. +.. toctree:: + :maxdepth: 1 + overview.rst Table of Contents @@ -197,19 +87,7 @@ Table of Contents -.. _CGRateS: http://cgrates.org -.. _Go: http://golang.org -.. _Docker: https://www.docker.com/ -.. _Kafka: https://kafka.apache.org/ -.. _redis: http://redis.io -.. _mongodb: http://www.mongodb.org -.. _api docs: https://godoc.org/github.com/cgrates/cgrates/apier -.. _SQS: https://aws.amazon.com/de/sqs/ -.. _AMQP: https://www.amqp.org/ -.. _Asterisk: https://www.asterisk.org/ -.. _FreeSWITCH: https://freeswitch.com/ -.. _Kamailio: https://www.kamailio.org/w/ -.. _OpenSIPS: https://opensips.org/ + diff --git a/docs/introduction.rst b/docs/introduction.rst deleted file mode 100644 index f7d99d259..000000000 --- a/docs/introduction.rst +++ /dev/null @@ -1,197 +0,0 @@ -************ -Introduction -************ - -`CGRateS`_ is a *very fast* (**50k+ CPS**) and *easily scalable* (**load-balancer** + **replication** included) **Real-time Enterprise Billing Suite** targeted especially for ISPs and Telecom Operators (but not only). - -Starting as a pure **billing engine**, CGRateS has evolved over the years into a reliable **real-time charging framework**, able to accommodate various business cases in a *generic way*. - -Being an *"engine style"* the project focuses on providing best ratio between **functionality** (over 15 daemons/services implemented with a rich number of `features `_ and a development team agile in developing new ones) and **performance** (dedicated benchmark tool, asynchronous request processing, own transactional cache component), however not losing focus of **quality** (test driven development policy). - -It is written in `Go`_ programming language and accessible from any programming language via JSON RPC. -The code is well documented (**go doc** compliant `API docs`_) and heavily tested (**5k+** tests are part of the unit test suite). - -Meant to be pluggable into existing billing infrastructure and as non-intrusive as possible, -CGRateS passes the decisions about logic flow to system administrators and incorporates as less as possible business logic. - -Modular and flexible, CGRateS provides APIs over a variety of simultaneously accessible communication interfaces: - - **In-process** : optimal when there is no need to split services over different processes - - **JSON over TCP** : most preferred due to its simplicity and readability - - **JSON over HTTP** : popular due to fast interoperability development - - **JSON over Websockets** : useful where 2 ways interaction over same TCP socket is required - - **GOB over TCP** : slightly faster than JSON one but only accessible for the moment out of Go (``_). - -CGRateS is capable of four charging modes: - -- \*prepaid - - Session events monitored in real-time - - Session authorization via events with security call timer - - Real-time balance updates with configurable debit interval - - Support for simultaneous sessions out of the same account - - Real-time fraud detection with automatic mitigation - - *Advantage*: real-time overview of the costs and fast detection in case of fraud, concurrent account sessions supported - - *Disadvantage*: more CPU intensive. - -- \*pseudoprepaid - - Session authorization via events - - Charging done at the end of the session out of CDR received - - *Advantage*: less CPU intensive due to less events processed - - *Disadvantage*: as balance updates happen only at the end of the session there can be costs discrepancy in case of multiple sessions out of same account (including going on negative balance). - -- \*postpaid - - Charging done at the end of the session out of CDR received without session authorization - - Useful when no authorization is necessary (trusted accounts) and no real-time event interaction is present (balance is updated only when CDR is present). - -- \*rated - - Special charging mode where there is no accounting interaction (no balances are used) but the primary interest is attaching costs to CDRs. - - Specific mode for Wholesale business processing high-throughput CDRs - - Least CPU usage out of the four modes (fastest charging). - - -.. _cgrates_features: - -Features -======== - -- Performance oriented. To get an idea about speed, we have benchmarked 50000+ req/sec on comodity hardware without any tweaks in the kernel - - Using most modern programming concepts like multiprocessor support, asynchronous code execution within microthreads, channel based locking - - Built-in data caching system with LRU and TTL support - - Linear performance increase via simple hardware addition - - On demand performance increase via in-process / over network communication between engine services. - -- Modular architecture - - Plugable into existing infrastructure - - Non-intrusive into existing setups - - Easy to enhance functionality by writing custom components - - Flexible API accessible via both **GOB** (`Go`_ specific, increased performance) or **JSON** (platform independent, universally accessible) - - Easy distribution (one binary concept, can run via NFS on all Linux servers without install). - -- Easy administration - - One binary can run on all Linux servers without additional installation (simple copy) - - Can run diskless via NFS - - Virtualization/containerization friendly(runs on Docker_). - -- GOCS (Global Online Charging System) - - Support for global networks with one master + multi-cache nodes around the globe for low query latency - - Mutiple Balance types per Account (\*monetary, \*voice, \*sms, \*data, \*generic) - - Unlimited number of Account Balances with weight based prioritization - - Various Balance filters (ie: per-destination, roaming-only, weekend-only) - - Support for Volume based discounts and automatic bonuses (ie: 5 SMS free for every 10 minutes in one hour to specific destination) - - Session based charging with support for concurrent sessions per account and per session dynamic debit interval - - Session emulation combined with Derived Charging (separate charging for distributors chaining, customer/supplier parallel calculations) - - Balance reservation and refunds - - Event based charging (ie: SMS, MESSAGE) - - Built-in Task-Scheduler supporting both one-time as well as recurrent actions (automatic subscriptions management, recurrent \*debit/\*topup, DID charging) - - Real-time balance monitors with automatic actions triggered (bonuses or fraud detection). - -- Highly configurable Rating - - Connect Fees - - Priced Units definition - - Rate increments - - Rate groups (ie. charge first minute in a call as a whole and next ones per second) - - Verbose durations(up to nanoseconds billing) - - Configurable decimals per destination - - Rating subject categorization (ie. premium/local charges, roaming) - - Recurrent rates definition (per year, month, day, dayOfWeek, time) - - Rating Profiles activation times (eg: rates becoming active at specific time in the future) - - Rating Profiles fallback (per subject destinations with fallback to server wide pricing) - - Verbose charging logs to comply strict rules imposed by some country laws. - -- Multi-Tenant from day one - - Default Tenant configurable for one-tenant systems - - Security enforced for RPC-API on Tenant level. - -- Online configuration reloads without restart - - Engine configuration from .json folder or remote http server - - Tariff Plans from .csv folder or database storage. - -- CDR server - - Optional offline database storage - - Online (rating queues) or offline (via RPC-API) exports with customizable content via .json templates - - Multiple export interfaces: files, HTTP, AMQP_, SQS_, Kafka_. - -- Generic Event Reader - - Process various sources of events and convert them into internal ones which are sent to CDR server for rating - - Conversion rules defined in .json templates - - Supported interfaces: .csv, .xml, fixed width files, Kafka_. - -- Events mediation - - Ability to add/change/remove information within *Events* to achieve additional services or correction - - Performance oriented. - -- Routing server for VoIP - - Implements strategies like *Least Cost Routing*, *Load Balacer*, *High Availability* - - Implements *Number Portability* service. - -- Resource allocation controller - - Generic filters for advanced logic - - In-memory operations for increased performance - - Backup in offline storage. - -- Stats service - - Generic stats (\*sum, \*difference, \*multiply, \*divide) - - In-memory operations for increased performance - - Backup in offline storage. - -- Thresholds monitor - - Particular implementation of *Fraud Detection with automatic mitigation* - - Execute independent actions which can serve various purposes (notifications, accounts disables, bonuses to accounts). - -- Multiple RPC interfaces - - Support for *JSON-RPC*, *GOB-PC* over TCP, HTTP, websockets - - Support for HTTP-REST interface. - -- Various agents to outside world: - - Asterisk_ - - FreeSWITCH_ - - Kamailio_ - - OpenSIPS_ - - Diameter - - Radius - - Generic HTTP - - DNS/ENUM. - -- Built in High-Availability mechanisms: - - Dispatcher with static or dynamic routing - - Server data replication - - Client remote data querying. - - -- Good documentation ( that's me :). - -- **"Free as in Beer"** with commercial support available on-demand. - - -Links -===== - -- CGRateS home page ``_ -- Documentation ``_ -- API docs ``_ -- Source code ``_ -- Travis CI ``_ -- Google group ``_ -- IRC `irc.freenode.net #cgrates `_ - - -License -======= - -`CGRateS`_ is released under the terms of the `[GNU GENERAL PUBLIC LICENSE Version 3] `_. See **LICENSE.txt** file for details. - - -.. _CGRateS: http://cgrates.org -.. _Go: http://golang.org -.. _Docker: https://www.docker.com/ -.. _Kafka: https://kafka.apache.org/ -.. _redis: http://redis.io -.. _mongodb: http://www.mongodb.org -.. _api docs: https://godoc.org/github.com/cgrates/cgrates/apier -.. _SQS: https://aws.amazon.com/de/sqs/ -.. _AMQP: https://www.amqp.org/ -.. _Asterisk: https://www.asterisk.org/ -.. _FreeSWITCH: https://freeswitch.com/ -.. _Kamailio: https://www.kamailio.org/w/ -.. _OpenSIPS: https://opensips.org/ - - diff --git a/docs/overview.rst b/docs/overview.rst index 8aec3b1e5..2570e6f3d 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -1,195 +1,130 @@ +.. _cgrates_features: -2. CGRateS Subsystems -===================== +Features +======== + +- Performance oriented. To get an idea about speed, we have benchmarked 50000+ req/sec on comodity hardware without any tweaks in the kernel + - Using most modern programming concepts like multiprocessor support, asynchronous code execution within microthreads, channel based locking + - Built-in data caching system with LRU and TTL support + - Linear performance increase via simple hardware addition + - On demand performance increase via in-process / over network communication between engine services. + +- Modular architecture + - Plugable into existing infrastructure + - Non-intrusive into existing setups + - Easy to enhance functionality by writing custom components + - Flexible API accessible via both **GOB** (`Go`_ specific, increased performance) or **JSON** (platform independent, universally accessible) + - Easy distribution (one binary concept, can run via NFS on all Linux servers without install). + +- Easy administration + - One binary can run on all Linux servers without additional installation (simple copy) + - Can run diskless via NFS + - Virtualization/containerization friendly(runs on Docker_). + +- GOCS (Global Online Charging System) + - Support for global networks with one master + multi-cache nodes around the globe for low query latency + - Mutiple Balance types per Account (\*monetary, \*voice, \*sms, \*data, \*generic) + - Unlimited number of Account Balances with weight based prioritization + - Various Balance filters (ie: per-destination, roaming-only, weekend-only) + - Support for Volume based discounts and automatic bonuses (ie: 5 SMS free for every 10 minutes in one hour to specific destination) + - Session based charging with support for concurrent sessions per account and per session dynamic debit interval + - Session emulation combined with Derived Charging (separate charging for distributors chaining, customer/supplier parallel calculations) + - Balance reservation and refunds + - Event based charging (ie: SMS, MESSAGE) + - Built-in Task-Scheduler supporting both one-time as well as recurrent actions (automatic subscriptions management, recurrent \*debit/\*topup, DID charging) + - Real-time balance monitors with automatic actions triggered (bonuses or fraud detection). + +- Highly configurable Rating + - Connect Fees + - Priced Units definition + - Rate increments + - Rate groups (ie. charge first minute in a call as a whole and next ones per second) + - Verbose durations(up to nanoseconds billing) + - Configurable decimals per destination + - Rating subject categorization (ie. premium/local charges, roaming) + - Recurrent rates definition (per year, month, day, dayOfWeek, time) + - Rating Profiles activation times (eg: rates becoming active at specific time in the future) + - Rating Profiles fallback (per subject destinations with fallback to server wide pricing) + - Verbose charging logs to comply strict rules imposed by some country laws. + +- Multi-Tenant from day one + - Default Tenant configurable for one-tenant systems + - Security enforced for RPC-API on Tenant level. + +- Online configuration reloads without restart + - Engine configuration from .json folder or remote http server + - Tariff Plans from .csv folder or database storage. + +- CDR server + - Optional offline database storage + - Online (rating queues) or offline (via RPC-API) exports with customizable content via .json templates + - Multiple export interfaces: files, HTTP, AMQP_, SQS_, Kafka_. + +- Generic Event Reader + - Process various sources of events and convert them into internal ones which are sent to CDR server for rating + - Conversion rules defined in .json templates + - Supported interfaces: .csv, .xml, fixed width files, Kafka_. + +- Events mediation + - Ability to add/change/remove information within *Events* to achieve additional services or correction + - Performance oriented. + +- Routing server for VoIP + - Implements strategies like *Least Cost Routing*, *Load Balacer*, *High Availability* + - Implements *Number Portability* service. + +- Resource allocation controller + - Generic filters for advanced logic + - In-memory operations for increased performance + - Backup in offline storage. + +- Stats service + - Generic stats (\*sum, \*difference, \*multiply, \*divide) + - In-memory operations for increased performance + - Backup in offline storage. + +- Thresholds monitor + - Particular implementation of *Fraud Detection with automatic mitigation* + - Execute independent actions which can serve various purposes (notifications, accounts disables, bonuses to accounts). + +- Multiple RPC interfaces + - Support for *JSON-RPC*, *GOB-PC* over TCP, HTTP, websockets + - Support for HTTP-REST interface. + +- Various agents to outside world: + - Asterisk_ + - FreeSWITCH_ + - Kamailio_ + - OpenSIPS_ + - Diameter + - Radius + - Generic HTTP + - DNS/ENUM. + +- Built in High-Availability mechanisms: + - Dispatcher with static or dynamic routing + - Server data replication + - Client remote data querying. -2.1. RALs (RatingAccountingLCRservice) --------------------------------------- -- Primary component, offering the most functionality out of the subsystems. -- Computes replies based on static list of "rules" defined in TariffPlan. +- Good documentation ( that's me :). -2.1.1. Rater -~~~~~~~~~~~~ -- Defines the performance of the system as a whole being the "heart" component -- Support for multiple TypeOfRecord (**\*voice**, **\*data**, **\*sms**, **\*generic**) -- Time based calculations (activation time in the future/rate-destination timely coupled) with granular time definitions (year, month, month day, weekday, time in seconds) -- Compressed destination prefixes, helping on faster destination match as well as memory consumption -- Advanced Rating capabilities: - ConnectFee (charged at beginning of the session); - RateUnit (automatic divider for the cost); - RateIncrement (increase verbosity of the charging interval); - Grouped interval rating inside the call duration (charging each second within a session independently) -- Per destination rounding: control number of decimals displayed in costs, decide rounding methods (**\*up**, **\*down**, **\*middle**) -- Control of the MaxSessionCost with decision on action taken on threshold hit (**\*free**, **\*disconnect**) -- Unlimited chaining of rating profiles (escalation price lists) - -2.1.2. Accounting -~~~~~~~~~~~~~~~~~ -- Maintains accounts with bundles and usage counters -- Support for multiple TypeOfRecord (**\*voice**, **\*data**, **\*sms**, **\*generic**) -- Unlimited number of balances per account -- Balance prioritization via balance weights -- Advanced balance selection (Direction, Destinations, RatingSubject - volume discounts in real-time, Categories) -- Accurate balance lifespan definition (ExpirationDate, Activation intervals) -- Safe account operations via in-/inter-process locks and on-disk storage -- Shared balances between multiple accounts (family/company bundles) with per-consumer configurable debit strategy and rates selected. -- Concurrent sessions per account doing balance reservation in chunks of debit interval and support for refunds and debit sleep when needed -- Scheduled account operations via predefined actions (eg: **\*topup**, **\*debit**) or notifications (**\*http_post**, **\*mail**) -- Fraud detection with automatic mitigation via action triggers/thresholds monitoring both balance status as well as combined usage - -2.1.3. LCR -~~~~~~~~~~ -- Accessible via RPC for queries or coupled with external communication systems sharing supplier information via specific channel variables. -- Integrates traffic patterns (LCR for specific session duration) -- Advanced profile selection mechanism (Direction, Tenant, Category, Account, Subject, Destination). -- Weight based prioritisation. -- Profile activation in the future possible through ActivationTime parameter. -- Tightly coupled with Accounting subsystem providing LCR over bundles (eg: consider minutes with special price only during weekend) -- Extended functionality through the use of strategies and individual parameters per strategy - - **\*static**: list of suppliers is always statically returned, independent on cost - - **\*least_cost**: classic LCR where suppliers are ordered based on cheapest cost - - **\*highest_cost**: suppliers are ordered based on highest cost - - **\*qos_thresholds**: suppliers are ordered based on cheapest cost and considered only if their quality stats (ASR, ACD, TCD, ACC, TCC, PDD, DDC) are within the defined intervals - - **\*qos**: suppliers are ordered by their quality stats (ASR, ACD, TCD, ACC, TCC, PDD, DDC) - - **\*load_distribution**: suppliers are ordered based on preconfigured load distribution scheme, independent on their costs. - -2.2. CDRs ---------- -- Real-time, centralized CDR server designed to receive CDRs via RPC interfaces -- Attaches Costs received from RALs to CDR events -- Offline CDR storage -- Real-time CDR replication to multiple upstream servers (CDR Rating queues) for high performance (optional disk-less) CDR processing -- Flexible export interfaces (JSON templates) with output mediation -- SureTax integration for US specific tax calculations - -2.3. CDRStatS -------------- -- Compute real-time stats based on CDR events received -- In-memory / performance oriented -- Unlimited StatQueues computing the same CDR event -- Flexible queue configuration (QueueLength, TimeWindow, Metrics, CDR field filters) -- Fraud detection with automatic mitigation through action triggers - -2.4. AliaseS ------------- -- Context based data aliasing (**\*rating** - converts data on input before calculations) -- Multiple layers for filtering (Direction, Tenant, Category, Account, Subject, DestinationID, Context) -- Multiple fields replaced simultaneously based on Target parameter - -2.5. UserS ----------- -- Populate requests with user profile fields (replace **\*users** marked fields with data from matched profile) -- Best match inside user properties -- Attribute-value store (similar to LDAP/Diameter) - -2.6. RLs (ResourceLimiterService) ---------------------------------- -- Limits resources during authorization (eg: maximum calls per destination for an account) -- Time aware (resources available during predefined time interval) - -2.7. PubsubS ------------- -- Expose internal events to subscribed external entities (eg: real-time balance updates being sent to an external http server) -- Advanced regexp filters for subscriptions -- Configurable subscription lifespan - -2.8. HistoryS -------------- -- Archive rate changes in git powered environment -- In-memory diffs with regular dumps to filesystem - -2.9. DA (DiameterAgent) ------------------------ -- Diameter **server** implementation -- Flexible processing logic configured inside JSON templates (standard agnostic) -- Mediation for incoming fields (regexp support with in-memory compiled rules). - -2.10. SM (SessionManager) -------------------------- -- Maintain/disconnect sessions -- Balance reservation and refunds - -2.10.1. SMG (SessionManagerGeneric) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Switch agnostic session management via RPC interface -- Bi-JSONRPC support - -2.10.2. SMG-Asterisk -~~~~~~~~~~~~~~~~~~~~ -- Asterisk specific communication over ARI and AMI interfaces -- Bidirectional (subscribing for events as well as sending commands) - -2.10.3. FreeSWITCHAgent -~~~~~~~~~~~~~~~~~~~~~ -- FreeSWITCH specific communication interface via ESL -- Bidirectional (subscribing for events as well as sending commands) -- Zero configuration in FreeSWITCH for CDR generation (useful for billing assurance/parallel billing) -- Ability to manage multiple FreeSWITCH servers from the same CGR-SM component - -2.10.4. SM-Kamailio -~~~~~~~~~~~~~~~~~~~ -- Bidirectional Kamailio communication via evapi -- Ability to manage multiple Kamailio instances from the same CGR-SM component - -2.10.5. SM-OpenSIPS -~~~~~~~~~~~~~~~~~~~ -- Bidirectional OpenSIPS communication via event_diagram/mi_datagram -- Deadlink detection via subscription mechanism - -2.11. CDRC (CDR Client) ------------------------ -- Offline CDR processing for **.csv**, **.xml** and **.fwv** file sources -- Mediation via in-memory regexp rules inside JSON templates -- Linux inotify support for instant file processing or delayed folder monitoring +- **"Free as in Beer"** with commercial support available on-demand. -3. CGRateS Peripherals -====================== -Packaged together due to common usage +Links +===== -3.1. cgr-engine ---------------- -- Configured via .json files, encorporating CGRateS subsystems mentioned above -- Can start as many / less services as needed communicating over internal or external sockets -- Multiple cgr-engine processes can be started on the same host -- Asynchronous service runs (services synchronize later inside process via specific communication channels, however they all run independent of each other). -- RPC Server with multiple interfaces started automatically based on needs. -- TCP sockets shared between services +- CGRateS home page ``_ +- Documentation ``_ +- API docs ``_ +- Source code ``_ +- Travis CI ``_ +- Google group ``_ +- IRC `irc.freenode.net #cgrates `_ -3.2. cgr-console ----------------- -- Application interfacing with cgr-engine via TCP sockets (JSON serialization) -- History and help command support -3.3. cgr-loader ---------------- -- Loads TariffPlan data out of .csv files into CGRateS live database or imports it into offline one for offline management -- Automatic cache reloads with optimizations for data loaded +License +======= -3.4. cgr-tester ---------------- -- Benchmarking tool to test based on particular TariffPlans of users. - -3.5. cgr-admin (``_) ----------------------------------------------------- -- PoC web interface demonstrating recommended way to interact with CGRateS from an external GUI. - -4. Fraud detection within CGRateS -================================= -- Due to its importance in billing, CGRateS has invested considerable efforts into fraud detection and automatic mitigation. -- For redundancy and reliability purposes, there are two mechanisms available within CGRateS to detect fraud. - -4.1. Fraud detection within Accounting: ---------------------------------------- -- Events are happening in real-time, being available during updates (eg: every n seconds of a session). -- Thresholds set by the administrator are reacting by calling a set of predefined actions **synchronously** - (with the advantage of having account in locked state, eg. no other events are possible until decision is made) or **asynchronously** (unlocking the accounts faster) -- Two types of thresholds can be set - - **min-/max-balance** monitoring balance values - - **min-/max-usage** counters (eg: amount of minutes to specific destination). -- Middle session control (sessions can be disconnected as fraud is detected - -4.2. Fraud detection within CDRStatS: -------------------------------------- -- Thresholds are monitoring CDRStatS queues and reacting by calling synchronously or asynchronously a set of predefined actions. -- Various stats metrics can be monitored (min-/max- ASR, ACD, TCD, ACC, TCC, PDD, DDC) +`CGRateS`_ is released under the terms of the `[GNU GENERAL PUBLIC LICENSE Version 3] `_. See **LICENSE.txt** file for details. From d1a5827e9fcbd1201091f3d9e1ba4afb5f84cd58 Mon Sep 17 00:00:00 2001 From: DanB Date: Sun, 19 Jan 2020 13:30:35 +0100 Subject: [PATCH 08/14] Docs - another index reformat --- docs/index.rst | 59 ++++------------------------------------------- docs/overview.rst | 54 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 57 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 9ce990fba..f51ccf01a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -13,70 +13,21 @@ .. _OpenSIPS: https://opensips.org/ -Introduction -============ +Preface +======= +Welcome to `CGRateS`_'s documentation! `CGRateS`_ is a *very fast* (**50k+ CPS**) and *easily scalable* (**load-balancer** + **replication** included) **Real-time Enterprise Billing Suite** targeted especially for ISPs and Telecom Operators (but not only). -Starting as a pure **billing engine**, CGRateS has evolved over the years into a reliable **real-time charging framework**, able to accommodate various business cases in a *generic way*. - -Being an *"engine style"* the project focuses on providing best ratio between **functionality** (over 15 daemons/services implemented with a rich number of `features `_ and a development team agile in developing new ones) and **performance** (dedicated benchmark tool, asynchronous request processing, own transactional cache component), however not losing focus of **quality** (test driven development policy). - -It is written in `Go`_ programming language and accessible from any programming language via JSON RPC. -The code is well documented (**go doc** compliant `API docs`_) and heavily tested (**5k+** tests are part of the unit test suite). - -Meant to be pluggable into existing billing infrastructure and as non-intrusive as possible, -CGRateS passes the decisions about logic flow to system administrators and incorporates as less as possible business logic. - -Modular and flexible, CGRateS provides APIs over a variety of simultaneously accessible communication interfaces: - - **In-process** : optimal when there is no need to split services over different processes - - **JSON over TCP** : most preferred due to its simplicity and readability - - **JSON over HTTP** : popular due to fast interoperability development - - **JSON over Websockets** : useful where 2 ways interaction over same TCP socket is required - - **GOB over TCP** : slightly faster than JSON one but only accessible for the moment out of Go (``_). - -CGRateS is capable of four charging modes: - -- \*prepaid - - Session events monitored in real-time - - Session authorization via events with security call timer - - Real-time balance updates with configurable debit interval - - Support for simultaneous sessions out of the same account - - Real-time fraud detection with automatic mitigation - - *Advantage*: real-time overview of the costs and fast detection in case of fraud, concurrent account sessions supported - - *Disadvantage*: more CPU intensive. - -- \*pseudoprepaid - - Session authorization via events - - Charging done at the end of the session out of CDR received - - *Advantage*: less CPU intensive due to less events processed - - *Disadvantage*: as balance updates happen only at the end of the session there can be costs discrepancy in case of multiple sessions out of same account (including going on negative balance). - -- \*postpaid - - Charging done at the end of the session out of CDR received without session authorization - - Useful when no authorization is necessary (trusted accounts) and no real-time event interaction is present (balance is updated only when CDR is present). - -- \*rated - - Special charging mode where there is no accounting interaction (no balances are used) but the primary interest is attaching costs to CDRs. - - Specific mode for Wholesale business processing high-throughput CDRs - - Least CPU usage out of the four modes (fastest charging). -More overview content: - -.. toctree:: - :maxdepth: 1 - - overview.rst - - -Table of Contents ------------------ +Table of contents: .. toctree:: :maxdepth: 5 + overview architecture installation configuration diff --git a/docs/overview.rst b/docs/overview.rst index 2570e6f3d..f7d5f6463 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -1,8 +1,56 @@ .. _cgrates_features: -Features + +Overview ======== +Starting as a pure **billing engine**, CGRateS has evolved over the years into a reliable **real-time charging framework**, able to accommodate various business cases in a *generic way*. + +Being an *"engine style"* the project focuses on providing best ratio between **functionality** (over 15 daemons/services implemented with a rich number of `features `_ and a development team agile in developing new ones) and **performance** (dedicated benchmark tool, asynchronous request processing, own transactional cache component), however not losing focus of **quality** (test driven development policy). + +It is written in `Go`_ programming language and accessible from any programming language via JSON RPC. +The code is well documented (**go doc** compliant `API docs`_) and heavily tested (**5k+** tests are part of the unit test suite). + +Meant to be pluggable into existing billing infrastructure and as non-intrusive as possible, +CGRateS passes the decisions about logic flow to system administrators and incorporates as less as possible business logic. + +Modular and flexible, CGRateS provides APIs over a variety of simultaneously accessible communication interfaces: + - **In-process** : optimal when there is no need to split services over different processes + - **JSON over TCP** : most preferred due to its simplicity and readability + - **JSON over HTTP** : popular due to fast interoperability development + - **JSON over Websockets** : useful where 2 ways interaction over same TCP socket is required + - **GOB over TCP** : slightly faster than JSON one but only accessible for the moment out of Go (``_). + + +CGRateS is capable of four charging modes: + +- \*prepaid + - Session events monitored in real-time + - Session authorization via events with security call timer + - Real-time balance updates with configurable debit interval + - Support for simultaneous sessions out of the same account + - Real-time fraud detection with automatic mitigation + - *Advantage*: real-time overview of the costs and fast detection in case of fraud, concurrent account sessions supported + - *Disadvantage*: more CPU intensive. + +- \*pseudoprepaid + - Session authorization via events + - Charging done at the end of the session out of CDR received + - *Advantage*: less CPU intensive due to less events processed + - *Disadvantage*: as balance updates happen only at the end of the session there can be costs discrepancy in case of multiple sessions out of same account (including going on negative balance). + +- \*postpaid + - Charging done at the end of the session out of CDR received without session authorization + - Useful when no authorization is necessary (trusted accounts) and no real-time event interaction is present (balance is updated only when CDR is present). + +- \*rated + - Special charging mode where there is no accounting interaction (no balances are used) but the primary interest is attaching costs to CDRs. + - Specific mode for Wholesale business processing high-throughput CDRs + - Least CPU usage out of the four modes (fastest charging). + +Features +-------- + - Performance oriented. To get an idea about speed, we have benchmarked 50000+ req/sec on comodity hardware without any tweaks in the kernel - Using most modern programming concepts like multiprocessor support, asynchronous code execution within microthreads, channel based locking - Built-in data caching system with LRU and TTL support @@ -113,7 +161,7 @@ Features Links -===== +----- - CGRateS home page ``_ - Documentation ``_ @@ -125,6 +173,6 @@ Links License -======= +------- `CGRateS`_ is released under the terms of the `[GNU GENERAL PUBLIC LICENSE Version 3] `_. See **LICENSE.txt** file for details. From ad8c36181840e0074642aacea5159d666e2cdc49 Mon Sep 17 00:00:00 2001 From: DanB Date: Sun, 19 Jan 2020 13:36:22 +0100 Subject: [PATCH 09/14] Doc index structure in place --- docs/index.rst | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index f51ccf01a..ee9c1f78c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -13,17 +13,11 @@ .. _OpenSIPS: https://opensips.org/ -Preface -======= - Welcome to `CGRateS`_'s documentation! `CGRateS`_ is a *very fast* (**50k+ CPS**) and *easily scalable* (**load-balancer** + **replication** included) **Real-time Enterprise Billing Suite** targeted especially for ISPs and Telecom Operators (but not only). - -Table of contents: - .. toctree:: :maxdepth: 5 From 1d3fdcdc243ae545dc588ec984d3694e99e83a8e Mon Sep 17 00:00:00 2001 From: DanB Date: Sun, 19 Jan 2020 13:50:54 +0100 Subject: [PATCH 10/14] Docs - adding missing refs in overview --- docs/index.rst | 14 ++------------ docs/overview.rst | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index ee9c1f78c..6fe8372b1 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,17 +1,7 @@ .. _CGRateS: http://cgrates.org -.. _Go: http://golang.org -.. _Docker: https://www.docker.com/ -.. _Kafka: https://kafka.apache.org/ -.. _redis: http://redis.io -.. _mongodb: http://www.mongodb.org -.. _api docs: https://godoc.org/github.com/cgrates/cgrates/apier -.. _SQS: https://aws.amazon.com/de/sqs/ -.. _AMQP: https://www.amqp.org/ -.. _Asterisk: https://www.asterisk.org/ -.. _FreeSWITCH: https://freeswitch.com/ -.. _Kamailio: https://www.kamailio.org/w/ -.. _OpenSIPS: https://opensips.org/ +Preface +======= Welcome to `CGRateS`_'s documentation! diff --git a/docs/overview.rst b/docs/overview.rst index f7d5f6463..44b7a0fdb 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -1,4 +1,17 @@ -.. _cgrates_features: +.. _CGRateS: http://cgrates.org +.. _Go: http://golang.org +.. _Docker: https://www.docker.com/ +.. _Kafka: https://kafka.apache.org/ +.. _redis: http://redis.io +.. _mongodb: http://www.mongodb.org +.. _api docs: https://godoc.org/github.com/cgrates/cgrates/apier +.. _SQS: https://aws.amazon.com/de/sqs/ +.. _AMQP: https://www.amqp.org/ +.. _Asterisk: https://www.asterisk.org/ +.. _FreeSWITCH: https://freeswitch.com/ +.. _Kamailio: https://www.kamailio.org/w/ +.. _OpenSIPS: https://opensips.org/ + Overview @@ -48,6 +61,9 @@ CGRateS is capable of four charging modes: - Specific mode for Wholesale business processing high-throughput CDRs - Least CPU usage out of the four modes (fastest charging). + +.. _cgrates_features: + Features -------- From 27e9431e363abd2c443f592d4512e631c62fa724 Mon Sep 17 00:00:00 2001 From: DanB Date: Sun, 19 Jan 2020 20:19:01 +0100 Subject: [PATCH 11/14] Docs config params started on diameter agent --- docs/cgr-engine.rst | 5 +++-- docs/diamagent.rst | 19 ++++++++++++++++--- docs/index.rst | 6 +++--- docs/overview.rst | 11 ++++++++--- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/docs/cgr-engine.rst b/docs/cgr-engine.rst index 01436caf5..28189f802 100644 --- a/docs/cgr-engine.rst +++ b/docs/cgr-engine.rst @@ -3,9 +3,10 @@ cgr-engine ========== -Groups various services and components. +Groups most of functionality from services and components. Customisable through the use of *json* :ref:`configuration ` or command line arguments (higher prio). + Able to read the configuration from either a local directory of *.json* files with an unlimited number of subfolders (ordered alphabetically) or a list of http paths (separated by ";"). :: @@ -62,7 +63,7 @@ All of the **Agents** implemented within CGRateS are flexible to be configured w Following *Agents* are implemented within CGRateS: .. toctree:: - :maxdepth: 2 + :maxdepth: 1 diamagent radagent diff --git a/docs/diamagent.rst b/docs/diamagent.rst index f83f74843..03c303a9d 100644 --- a/docs/diamagent.rst +++ b/docs/diamagent.rst @@ -5,20 +5,23 @@ DiameterAgent ============= -**DiameterAgent** translates between Diameter_ and **CGRateS**, sending *RPC* requests towards **SessionS** component and returning replies from it to the *DiameterClient*. +**DiameterAgent** translates between Diameter_ and **CGRateS**, sending *RPC* requests towards **CGRateS/SessionS** component and returning replies from it to the *DiameterClient*. Implements Diameter_ protocol in a standard agnostic manner, giving users the ability to implement own interfaces by defining simple *processor templates* within the :ref:`configuration ` files. Used mostly in modern mobile networks (LTE/xG). +The **DiameterAgent** is configured via *diameter_agent* section within :ref:`configuration `. + Configuration ------------- -The **DiameterAgent** is configured via *diameter_agent* section within :ref:`configuration `. +Sample config +^^^^^^^^^^^^^ -Sample config (explanation in the comments): +With explanations in the comments: :: @@ -174,4 +177,14 @@ Sample config (explanation in the comments): }, +Config params +^^^^^^^^^^^^^ + +listen_net + The network the *DiameterAgent* will bind to. CGRateS supports both **tcp** and **sctp** specified in Diameter_ standard. + +asr_template + The template (out of templates config section) used to build the AbortSession message. If not specified the ASR message is never sent out. + + diff --git a/docs/index.rst b/docs/index.rst index 6fe8372b1..dae6cdb2d 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,7 +1,7 @@ .. _CGRateS: http://cgrates.org -Preface -======= +CGRateS Documentation +===================== Welcome to `CGRateS`_'s documentation! @@ -9,7 +9,7 @@ Welcome to `CGRateS`_'s documentation! .. toctree:: - :maxdepth: 5 + :maxdepth: 4 overview architecture diff --git a/docs/overview.rst b/docs/overview.rst index 44b7a0fdb..1c38557ed 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -11,6 +11,11 @@ .. _FreeSWITCH: https://freeswitch.com/ .. _Kamailio: https://www.kamailio.org/w/ .. _OpenSIPS: https://opensips.org/ +.. _Diameter: https://tools.ietf.org/html/rfc6733 +.. _Radius: https://tools.ietf.org/html/rfc2865 +.. _DNS: https://tools.ietf.org/html/rfc1034 +.. _ENUM: https://tools.ietf.org/html/rfc6116 + @@ -160,10 +165,10 @@ Features - FreeSWITCH_ - Kamailio_ - OpenSIPS_ - - Diameter - - Radius + - Diameter_ + - Radius_ - Generic HTTP - - DNS/ENUM. + - DNS_/ENUM_. - Built in High-Availability mechanisms: - Dispatcher with static or dynamic routing From 999aabdf9fe52eca66a5e8228be05dec7f7357a3 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 20 Jan 2020 14:44:36 +0200 Subject: [PATCH 12/14] Updated FieldName for attributes --- apier/v1/apier2_it_test.go | 2 +- apier/v1/attributes_it_test.go | 110 +++++----- apier/v1/cdre_it_test.go | 8 +- apier/v1/chargers_it_test.go | 2 +- apier/v1/dm_remote_it_test.go | 8 +- apier/v1/filter_indexes.go | 42 ++-- apier/v1/filter_indexes_it_test.go | 64 +++--- apier/v1/filterindexecache_it_test.go | 178 +++++++-------- apier/v1/filters_it_test.go | 18 +- apier/v1/stats_it_test.go | 12 +- apier/v1/tpattributes_it_test.go | 14 +- apier/v1/tpfilters_it_test.go | 22 +- apier/v2/attributes_it_test.go | 24 +- apier/v2/cdrs_it_test.go | 8 +- cdrc/csv_it_test.go | 12 +- cdrc/fwv_it_test.go | 6 +- cdrc/xml_it_test.go | 12 +- config/config_defaults.go | 8 +- config/config_json_test.go | 16 +- config/config_test.go | 16 +- data/conf/cgrates/cgrates.json | 8 +- .../samples/loaders/tutmongo/cgrates.json | 2 +- .../samples/loaders/tutmysql/cgrates.json | 2 +- .../samples/tutmysql_internal/cgrates.json | 6 +- .../mysql/create_tariffplan_tables.sql | 12 +- .../postgres/create_tariffplan_tables.sql | 12 +- data/tariffplans/cluelrn/Attributes.csv | 2 +- data/tariffplans/cluelrn/Filters.csv | 2 +- data/tariffplans/dispatchers/Attributes.csv | 2 +- .../dispatchers_gob/Attributes.csv | 2 +- data/tariffplans/dnsagent/Attributes.csv | 2 +- data/tariffplans/oldtutorial/Attributes.csv | 2 +- data/tariffplans/oldtutorial/Filters.csv | 2 +- data/tariffplans/precache/Attributes.csv | 2 +- data/tariffplans/precache/Filters.csv | 2 +- data/tariffplans/testit/Attributes.csv | 2 +- data/tariffplans/testit/Filters.csv | 2 +- data/tariffplans/testtp/Attributes.csv | 2 +- data/tariffplans/testtp/Filters.csv | 2 +- data/tariffplans/tutorial/Attributes.csv | 2 +- data/tariffplans/tutorial/Filters.csv | 2 +- data/tariffplans/tutorial2/Attributes.csv | 2 +- dispatchers/attributes_it_test.go | 6 +- dispatchers/dispatchers_it_test.go | 4 +- docs/filters.rst | 18 +- docs/tariff_plans.rst | 6 +- engine/action.go | 2 +- engine/attributes.go | 14 +- engine/attributes_test.go | 206 +++++++++--------- engine/chargers_test.go | 30 +-- engine/filterindexer.go | 20 +- engine/filterindexer_it_test.go | 34 +-- engine/filters.go | 56 ++--- engine/filters_test.go | 74 +++---- engine/libattributes.go | 22 +- engine/libattributes_test.go | 16 +- engine/libtest.go | 4 +- engine/loader_csv_test.go | 40 ++-- engine/model_helpers.go | 32 +-- engine/model_helpers_test.go | 96 ++++---- engine/models.go | 8 +- engine/onstor_it_test.go | 40 ++-- engine/resources_test.go | 54 ++--- engine/stats_test.go | 54 ++--- engine/suppliers_test.go | 42 ++-- engine/thresholds_test.go | 30 +-- general_tests/cdrs_processevent_it_test.go | 4 +- general_tests/filters_it_test.go | 36 +-- general_tests/sentinel_it_test.go | 12 +- general_tests/sessions_concur_test.go | 4 +- loaders/libloader_test.go | 22 +- loaders/loader_it_test.go | 4 +- loaders/loader_test.go | 54 ++--- migrator/alias.go | 6 +- migrator/alias_it_test.go | 12 +- migrator/alias_test.go | 40 ++-- migrator/attributes.go | 6 +- migrator/attributes_it_test.go | 6 +- migrator/attributes_test.go | 8 +- migrator/derived_chargers.go | 6 +- migrator/derived_chargers_it_test.go | 14 +- migrator/derived_chargers_test.go | 80 +++---- migrator/filters.go | 30 +-- migrator/filters_it_test.go | 56 ++--- migrator/filters_test.go | 84 +++---- migrator/tp_filters_it_test.go | 6 +- migrator/user.go | 12 +- migrator/user_it_test.go | 20 +- migrator/user_test.go | 70 +++--- sessions/sessions.go | 2 +- sessions/sessions_test.go | 6 +- utils/apitpdata.go | 10 +- utils/apitpdata_test.go | 12 +- utils/consts.go | 1 + 94 files changed, 1099 insertions(+), 1088 deletions(-) diff --git a/apier/v1/apier2_it_test.go b/apier/v1/apier2_it_test.go index 8b63ff3f2..9a6087840 100644 --- a/apier/v1/apier2_it_test.go +++ b/apier/v1/apier2_it_test.go @@ -151,7 +151,7 @@ func testAPIerVerifyAttributesAfterLoad(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{}, - FieldName: utils.MetaReq + utils.NestingSep + "Password", + Path: utils.MetaReq + utils.NestingSep + "Password", Type: utils.META_CONSTANT, Value: config.NewRSRParsersMustCompile("CGRateS.org", true, utils.INFIELD_SEP), }, diff --git a/apier/v1/attributes_it_test.go b/apier/v1/attributes_it_test.go index 190a82564..eb601e74b 100644 --- a/apier/v1/attributes_it_test.go +++ b/apier/v1/attributes_it_test.go @@ -188,12 +188,12 @@ func testAttributeSGetAttributeForEvent(t *testing.T) { ActivationTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC)}, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Account, - Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Account, + Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, - Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Subject, + Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, Weight: 10.0, @@ -240,8 +240,8 @@ func testAttributeSGetAttributeForEventNotFound(t *testing.T) { ActivationTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC)}, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Account, - Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Account, + Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, Weight: 10.0, @@ -292,8 +292,8 @@ func testAttributeSGetAttributeForEventWithMetaAnyContext(t *testing.T) { ActivationTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC)}, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Account, - Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Account, + Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, Weight: 10.0, @@ -443,12 +443,12 @@ func testAttributeSProcessEventWithNoneSubstitute(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:~*req.Account:1008"}, - FieldName: utils.MetaReq + utils.NestingSep + utils.Account, + Path: utils.MetaReq + utils.NestingSep + utils.Account, Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, - Value: config.NewRSRParsersMustCompile(utils.MetaRemove, true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Subject, + Value: config.NewRSRParsersMustCompile(utils.MetaRemove, true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -511,12 +511,12 @@ func testAttributeSProcessEventWithNoneSubstitute2(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:~*req.Account:1008"}, - FieldName: utils.MetaReq + utils.NestingSep + utils.Account, + Path: utils.MetaReq + utils.NestingSep + utils.Account, Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, - Value: config.NewRSRParsersMustCompile(utils.MetaRemove, true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Subject, + Value: config.NewRSRParsersMustCompile(utils.MetaRemove, true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -590,12 +590,12 @@ func testAttributeSProcessEventWithNoneSubstitute3(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:~*req.Account:1008"}, - FieldName: utils.MetaReq + utils.NestingSep + utils.Account, + Path: utils.MetaReq + utils.NestingSep + utils.Account, Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, { FilterIDs: []string{"*string:~*req.Subject:1008"}, - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, + Path: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.NewRSRParsersMustCompile(utils.MetaRemove, true, utils.INFIELD_SEP), }, }, @@ -643,8 +643,8 @@ func testAttributeSProcessEventWithHeader(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Value: config.NewRSRParsersMustCompile("~*req.Field1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Value: config.NewRSRParsersMustCompile("~*req.Field1", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -725,8 +725,8 @@ func testAttributeSSetAlsPrf(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "FL1", - Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "FL1", + Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -753,12 +753,12 @@ func testAttributeSSetAlsPrf(t *testing.T) { func testAttributeSUpdateAlsPrf(t *testing.T) { alsPrf.Attributes = []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "FL1", - Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "FL1", + Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaReq + utils.NestingSep + "FL2", - Value: config.NewRSRParsersMustCompile("Al2", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "FL2", + Value: config.NewRSRParsersMustCompile("Al2", true, utils.INFIELD_SEP), }, } alsPrf.Compile() @@ -818,7 +818,7 @@ func testAttributeSSetAlsPrf2(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, + Path: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.RSRParsers{ &config.RSRParser{ Rules: "roam", @@ -862,7 +862,7 @@ func testAttributeSSetAlsPrf3(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, + Path: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.RSRParsers{ &config.RSRParser{ Rules: "", @@ -893,7 +893,7 @@ func testAttributeSSetAlsPrf4(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, + Path: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.RSRParsers{ &config.RSRParser{}, }, @@ -930,8 +930,8 @@ func testAttributeSProcessEventWithSearchAndReplace(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Category", - Value: config.NewRSRParsersMustCompile("~*req.Category:s/(.*)/${1}_suffix/", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Category", + Value: config.NewRSRParsersMustCompile("~*req.Category:s/(.*)/${1}_suffix/", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -988,8 +988,8 @@ func testAttributeSProcessWithMultipleRuns(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field1", - Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field1", + Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, Weight: 10, @@ -1006,8 +1006,8 @@ func testAttributeSProcessWithMultipleRuns(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -1024,8 +1024,8 @@ func testAttributeSProcessWithMultipleRuns(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field3", - Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field3", + Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), }, }, Weight: 30, @@ -1098,8 +1098,8 @@ func testAttributeSProcessWithMultipleRuns2(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field1", - Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field1", + Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, Weight: 10, @@ -1116,8 +1116,8 @@ func testAttributeSProcessWithMultipleRuns2(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -1134,8 +1134,8 @@ func testAttributeSProcessWithMultipleRuns2(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field3", - Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field3", + Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), }, }, Weight: 30, @@ -1217,8 +1217,8 @@ func testAttributeSCachingMetaNone(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field1", - Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field1", + Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, Weight: 10, @@ -1276,8 +1276,8 @@ func testAttributeSCachingMetaLoad(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field1", - Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field1", + Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, Weight: 10, @@ -1368,8 +1368,8 @@ func testAttributeSCachingMetaReload1(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field1", - Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field1", + Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, Weight: 10, @@ -1427,8 +1427,8 @@ func testAttributeSCachingMetaReload2(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field1", - Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field1", + Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, Weight: 10, @@ -1467,8 +1467,8 @@ func testAttributeSCachingMetaReload2(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field1", - Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field1", + Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, Weight: 10, @@ -1506,8 +1506,8 @@ func testAttributeSCachingMetaRemove(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field1", - Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field1", + Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, Weight: 10, @@ -1556,8 +1556,8 @@ func testAttributeSCachingMetaRemove(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field1", - Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field1", + Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, Weight: 10, diff --git a/apier/v1/cdre_it_test.go b/apier/v1/cdre_it_test.go index 19d822a55..0049e36eb 100755 --- a/apier/v1/cdre_it_test.go +++ b/apier/v1/cdre_it_test.go @@ -291,12 +291,12 @@ func testCDReAddAttributes(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, - Value: config.NewRSRParsersMustCompile("ATTR_SUBJECT", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Subject, + Value: config.NewRSRParsersMustCompile("ATTR_SUBJECT", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaReq + utils.NestingSep + utils.Category, - Value: config.NewRSRParsersMustCompile("ATTR_CATEGORY", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Category, + Value: config.NewRSRParsersMustCompile("ATTR_CATEGORY", true, utils.INFIELD_SEP), }, }, Weight: 20, diff --git a/apier/v1/chargers_it_test.go b/apier/v1/chargers_it_test.go index b47217ff7..0d9cd8194 100755 --- a/apier/v1/chargers_it_test.go +++ b/apier/v1/chargers_it_test.go @@ -166,7 +166,7 @@ func testChargerSLoadAddCharger(t *testing.T) { Contexts: []string{"simpleauth"}, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Password", + Path: utils.MetaReq + utils.NestingSep + "Password", Value: config.RSRParsers{ &config.RSRParser{ Rules: "CGRateS.org", diff --git a/apier/v1/dm_remote_it_test.go b/apier/v1/dm_remote_it_test.go index 80d6eef80..aa6a9ee38 100644 --- a/apier/v1/dm_remote_it_test.go +++ b/apier/v1/dm_remote_it_test.go @@ -239,7 +239,7 @@ func testInternalRemoteITGetAttribute(t *testing.T) { Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Password", + Path: utils.MetaReq + utils.NestingSep + "Password", FilterIDs: []string{}, Type: utils.META_CONSTANT, Value: config.NewRSRParsersMustCompile("CGRateS.org", true, utils.INFIELD_SEP), @@ -463,9 +463,9 @@ func testInternalRemoteITGetFilter(t *testing.T) { ID: "FLTR_ACNT_1001", Rules: []*engine.FilterRule{ { - Type: "*string", - FieldName: "~*req.Account", - Values: []string{"1001"}, + Type: utils.MetaString, + Element: "~*req.Account", + Values: []string{"1001"}, }, }, ActivationInterval: &utils.ActivationInterval{ diff --git a/apier/v1/filter_indexes.go b/apier/v1/filter_indexes.go index 86ba9e370..06083d158 100644 --- a/apier/v1/filter_indexes.go +++ b/apier/v1/filter_indexes.go @@ -492,9 +492,9 @@ func (api *ApierV1) computeThresholdIndexes(tenant string, thIDs *[]string, ID: th.ID, Rules: []*engine.FilterRule{ { - Type: utils.META_NONE, - FieldName: utils.META_ANY, - Values: []string{utils.META_ANY}, + Type: utils.META_NONE, + Element: utils.META_ANY, + Values: []string{utils.META_ANY}, }, }, } @@ -562,9 +562,9 @@ func (api *ApierV1) computeAttributeIndexes(tenant, context string, attrIDs *[]s ID: ap.ID, Rules: []*engine.FilterRule{ { - Type: utils.META_NONE, - FieldName: utils.META_ANY, - Values: []string{utils.META_ANY}, + Type: utils.META_NONE, + Element: utils.META_ANY, + Values: []string{utils.META_ANY}, }, }, } @@ -628,9 +628,9 @@ func (api *ApierV1) computeResourceIndexes(tenant string, rsIDs *[]string, ID: rp.ID, Rules: []*engine.FilterRule{ { - Type: utils.META_NONE, - FieldName: utils.META_ANY, - Values: []string{utils.META_ANY}, + Type: utils.META_NONE, + Element: utils.META_ANY, + Values: []string{utils.META_ANY}, }, }, } @@ -694,9 +694,9 @@ func (api *ApierV1) computeStatIndexes(tenant string, stIDs *[]string, ID: sqp.ID, Rules: []*engine.FilterRule{ { - Type: utils.META_NONE, - FieldName: utils.META_ANY, - Values: []string{utils.META_ANY}, + Type: utils.META_NONE, + Element: utils.META_ANY, + Values: []string{utils.META_ANY}, }, }, } @@ -760,9 +760,9 @@ func (api *ApierV1) computeSupplierIndexes(tenant string, sppIDs *[]string, ID: spp.ID, Rules: []*engine.FilterRule{ { - Type: utils.META_NONE, - FieldName: utils.META_ANY, - Values: []string{utils.META_ANY}, + Type: utils.META_NONE, + Element: utils.META_ANY, + Values: []string{utils.META_ANY}, }, }, } @@ -826,9 +826,9 @@ func (api *ApierV1) computeChargerIndexes(tenant string, cppIDs *[]string, ID: cpp.ID, Rules: []*engine.FilterRule{ { - Type: utils.META_NONE, - FieldName: utils.META_ANY, - Values: []string{utils.META_ANY}, + Type: utils.META_NONE, + Element: utils.META_ANY, + Values: []string{utils.META_ANY}, }, }, } @@ -896,9 +896,9 @@ func (api *ApierV1) computeDispatcherIndexes(tenant, context string, dspIDs *[]s ID: dsp.ID, Rules: []*engine.FilterRule{ { - Type: utils.META_NONE, - FieldName: utils.META_ANY, - Values: []string{utils.META_ANY}, + Type: utils.META_NONE, + Element: utils.META_ANY, + Values: []string{utils.META_ANY}, }, }, } diff --git a/apier/v1/filter_indexes_it_test.go b/apier/v1/filter_indexes_it_test.go index 4067bd642..8eb9853d4 100644 --- a/apier/v1/filter_indexes_it_test.go +++ b/apier/v1/filter_indexes_it_test.go @@ -158,9 +158,9 @@ func testV1FIdxSetThresholdProfile(t *testing.T) { Tenant: tenant, ID: "TestFilter", Rules: []*engine.FilterRule{{ - FieldName: "~*req.Account", - Type: utils.MetaString, - Values: []string{"1001"}, + Element: "~*req.Account", + Type: utils.MetaString, + Values: []string{"1001"}, }}, ActivationInterval: &utils.ActivationInterval{ ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), @@ -252,9 +252,9 @@ func testV1FIdxSetSecondThresholdProfile(t *testing.T) { Tenant: tenant, ID: "TestFilter2", Rules: []*engine.FilterRule{{ - FieldName: "~*req.Account", - Type: utils.MetaString, - Values: []string{"1002"}, + Element: "~*req.Account", + Type: utils.MetaString, + Values: []string{"1002"}, }}, ActivationInterval: &utils.ActivationInterval{ ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), @@ -417,9 +417,9 @@ func testV1FIdxSetStatQueueProfileIndexes(t *testing.T) { Tenant: tenant, ID: "FLTR_1", Rules: []*engine.FilterRule{{ - FieldName: "~*req.Account", - Type: utils.MetaString, - Values: []string{"1001"}, + Element: "~*req.Account", + Type: utils.MetaString, + Values: []string{"1001"}, }}, ActivationInterval: &utils.ActivationInterval{ ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), @@ -520,9 +520,9 @@ func testV1FIdxSetSecondStatQueueProfileIndexes(t *testing.T) { Tenant: tenant, ID: "FLTR_2", Rules: []*engine.FilterRule{{ - FieldName: "~*req.Account", - Type: utils.MetaString, - Values: []string{"1001"}, + Element: "~*req.Account", + Type: utils.MetaString, + Values: []string{"1001"}, }}, ActivationInterval: &utils.ActivationInterval{ ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), @@ -666,9 +666,9 @@ func testV1FIdxSetResourceProfileIndexes(t *testing.T) { Tenant: tenant, ID: "FLTR_RES_RCFG1", Rules: []*engine.FilterRule{{ - FieldName: "~*req.Account", - Type: utils.MetaString, - Values: []string{"1001"}, + Element: "~*req.Account", + Type: utils.MetaString, + Values: []string{"1001"}, }}, ActivationInterval: &utils.ActivationInterval{ ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), @@ -759,9 +759,9 @@ func testV1FIdxSetSecondResourceProfileIndexes(t *testing.T) { Tenant: tenant, ID: "FLTR_2", Rules: []*engine.FilterRule{{ - FieldName: "~*req.Account", - Type: utils.MetaString, - Values: []string{"1001"}, + Element: "~*req.Account", + Type: utils.MetaString, + Values: []string{"1001"}, }}, ActivationInterval: &utils.ActivationInterval{ ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), @@ -895,9 +895,9 @@ func testV1FIdxSetSupplierProfileIndexes(t *testing.T) { ID: "FLTR_1", Rules: []*engine.FilterRule{ { - FieldName: "~*req.Account", - Type: utils.MetaString, - Values: []string{"1001"}, + Element: "~*req.Account", + Type: utils.MetaString, + Values: []string{"1001"}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -994,9 +994,9 @@ func testV1FIdxSetSecondSupplierProfileIndexes(t *testing.T) { Tenant: tenant, ID: "FLTR_2", Rules: []*engine.FilterRule{{ - FieldName: "~*req.Account", - Type: utils.MetaString, - Values: []string{"1001"}, + Element: "~*req.Account", + Type: utils.MetaString, + Values: []string{"1001"}, }}, ActivationInterval: &utils.ActivationInterval{ ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), @@ -1137,9 +1137,9 @@ func testV1FIdxSetAttributeProfileIndexes(t *testing.T) { Tenant: tenant, ID: "FLTR_1", Rules: []*engine.FilterRule{{ - FieldName: "~*req.Account", - Type: utils.MetaString, - Values: []string{"1001"}, + Element: "~*req.Account", + Type: utils.MetaString, + Values: []string{"1001"}, }}, ActivationInterval: &utils.ActivationInterval{ ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), @@ -1171,7 +1171,7 @@ func testV1FIdxSetAttributeProfileIndexes(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:~*req.FL1:In1"}, - FieldName: "FL1", + Path: "FL1", Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, }, @@ -1245,9 +1245,9 @@ func testV1FIdxSetSecondAttributeProfileIndexes(t *testing.T) { Tenant: tenant, ID: "FLTR_2", Rules: []*engine.FilterRule{{ - FieldName: "~*req.Account", - Type: utils.MetaString, - Values: []string{"1001"}, + Element: "~*req.Account", + Type: utils.MetaString, + Values: []string{"1001"}, }}, ActivationInterval: &utils.ActivationInterval{ ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), @@ -1279,7 +1279,7 @@ func testV1FIdxSetSecondAttributeProfileIndexes(t *testing.T) { }, Attributes: []*engine.Attribute{{ FilterIDs: []string{"*string:~*req.FL1:In1"}, - FieldName: "FL1", + Path: "FL1", Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }}, Weight: 20, diff --git a/apier/v1/filterindexecache_it_test.go b/apier/v1/filterindexecache_it_test.go index 0cef72519..c0b01503c 100644 --- a/apier/v1/filterindexecache_it_test.go +++ b/apier/v1/filterindexecache_it_test.go @@ -163,14 +163,14 @@ func testV1FIdxCaSetThresholdProfile(t *testing.T) { ID: "TestFilter", Rules: []*engine.FilterRule{ { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, - Type: "*string", - Values: []string{"1001"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, + Type: utils.MetaString, + Values: []string{"1001"}, }, { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.EventType, - Type: "*string", - Values: []string{utils.BalanceUpdate}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.EventType, + Type: utils.MetaString, + Values: []string{utils.BalanceUpdate}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -257,14 +257,14 @@ func testV1FIdxCaUpdateThresholdProfile(t *testing.T) { ID: "TestFilter2", Rules: []*engine.FilterRule{ { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, - Type: "*string", - Values: []string{"1002"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, + Type: utils.MetaString, + Values: []string{"1002"}, }, { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.EventType, - Type: "*string", - Values: []string{utils.AccountUpdate}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.EventType, + Type: utils.MetaString, + Values: []string{utils.AccountUpdate}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -337,14 +337,14 @@ func testV1FIdxCaUpdateThresholdProfileFromTP(t *testing.T) { ID: "TestFilter3", Rules: []*engine.FilterRule{ { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, - Type: "*string", - Values: []string{"1003"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, + Type: utils.MetaString, + Values: []string{"1003"}, }, { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.EventType, - Type: "*string", - Values: []string{utils.BalanceUpdate}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.EventType, + Type: utils.MetaString, + Values: []string{utils.BalanceUpdate}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -500,14 +500,14 @@ func testV1FIdxCaSetStatQueueProfile(t *testing.T) { ID: "FLTR_1", Rules: []*engine.FilterRule{ { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, - Type: "*string", - Values: []string{"1001"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, + Type: utils.MetaString, + Values: []string{"1001"}, }, { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.EventType, - Type: "*string", - Values: []string{utils.AccountUpdate}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.EventType, + Type: utils.MetaString, + Values: []string{utils.AccountUpdate}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -654,14 +654,14 @@ func testV1FIdxCaUpdateStatQueueProfile(t *testing.T) { ID: "FLTR_2", Rules: []*engine.FilterRule{ { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, - Type: "*string", - Values: []string{"1003"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, + Type: utils.MetaString, + Values: []string{"1003"}, }, { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.EventType, - Type: "*string", - Values: []string{utils.BalanceUpdate}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.EventType, + Type: utils.MetaString, + Values: []string{utils.BalanceUpdate}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -729,14 +729,14 @@ func testV1FIdxCaUpdateStatQueueProfileFromTP(t *testing.T) { ID: "FLTR_3", Rules: []*engine.FilterRule{ { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, - Type: "*string", - Values: []string{"1003"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, + Type: utils.MetaString, + Values: []string{"1003"}, }, { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.EventType, - Type: "*string", - Values: []string{utils.AccountUpdate}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.EventType, + Type: utils.MetaString, + Values: []string{utils.AccountUpdate}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -890,14 +890,14 @@ func testV1FIdxCaSetAttributeProfile(t *testing.T) { ID: "TestFilter", Rules: []*engine.FilterRule{ { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, - Type: "*string", - Values: []string{"1009"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, + Type: utils.MetaString, + Values: []string{"1009"}, }, { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Destination, - Type: "*string", - Values: []string{"+491511231234"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Destination, + Type: utils.MetaString, + Values: []string{"+491511231234"}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -922,12 +922,12 @@ func testV1FIdxCaSetAttributeProfile(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Account, - Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Account, + Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, - Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Subject, + Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -983,14 +983,14 @@ func testV1FIdxCaUpdateAttributeProfile(t *testing.T) { ID: "TestFilter2", Rules: []*engine.FilterRule{ { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, - Type: "*string", - Values: []string{"2009"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, + Type: utils.MetaString, + Values: []string{"2009"}, }, { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Destination, - Type: "*string", - Values: []string{"+492511231234"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Destination, + Type: utils.MetaString, + Values: []string{"+492511231234"}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -1015,12 +1015,12 @@ func testV1FIdxCaUpdateAttributeProfile(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Account, - Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Account, + Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, - Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Subject, + Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -1056,14 +1056,14 @@ func testV1FIdxCaUpdateAttributeProfileFromTP(t *testing.T) { ID: "TestFilter3", Rules: []*engine.FilterRule{ { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, - Type: "*string", - Values: []string{"3009"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, + Type: utils.MetaString, + Values: []string{"3009"}, }, { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Destination, - Type: "*string", - Values: []string{"+492511231234"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Destination, + Type: utils.MetaString, + Values: []string{"+492511231234"}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -1209,19 +1209,19 @@ func testV1FIdxCaSetResourceProfile(t *testing.T) { ID: "FLTR_RES_RCFG1", Rules: []*engine.FilterRule{ { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, - Type: "*string", - Values: []string{"1001"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, + Type: utils.MetaString, + Values: []string{"1001"}, }, { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Subject, - Type: "*string", - Values: []string{"1002"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Subject, + Type: utils.MetaString, + Values: []string{"1002"}, }, { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Destination, - Type: "*string", - Values: []string{"1001"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Destination, + Type: utils.MetaString, + Values: []string{"1001"}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -1338,19 +1338,19 @@ func testV1FIdxCaUpdateResourceProfile(t *testing.T) { ID: "FLTR_RES_RCFG2", Rules: []*engine.FilterRule{ { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, - Type: "*string", - Values: []string{"2002"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, + Type: utils.MetaString, + Values: []string{"2002"}, }, { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Subject, - Type: "*string", - Values: []string{"2001"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Subject, + Type: utils.MetaString, + Values: []string{"2001"}, }, { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Destination, - Type: "*string", - Values: []string{"2002"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Destination, + Type: utils.MetaString, + Values: []string{"2002"}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -1414,19 +1414,19 @@ func testV1FIdxCaUpdateResourceProfileFromTP(t *testing.T) { ID: "FLTR_RES_RCFG3", Rules: []*engine.FilterRule{ { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, - Type: "*string", - Values: []string{"1002"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, + Type: utils.MetaString, + Values: []string{"1002"}, }, { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Subject, - Type: "*string", - Values: []string{"1001"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Subject, + Type: utils.MetaString, + Values: []string{"1001"}, }, { - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Destination, - Type: "*string", - Values: []string{"1002"}, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Destination, + Type: utils.MetaString, + Values: []string{"1002"}, }, }, ActivationInterval: &utils.ActivationInterval{ diff --git a/apier/v1/filters_it_test.go b/apier/v1/filters_it_test.go index 2937499db..c765c4f40 100644 --- a/apier/v1/filters_it_test.go +++ b/apier/v1/filters_it_test.go @@ -125,9 +125,9 @@ func testFilterSetFilter(t *testing.T) { ID: "Filter1", Rules: []*engine.FilterRule{ { - FieldName: "*string", - Type: "~Account", - Values: []string{"1001", "1002"}, + Element: utils.MetaString, + Type: "~Account", + Values: []string{"1001", "1002"}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -167,14 +167,14 @@ func testFilterGetFilterAfterSet(t *testing.T) { func testFilterUpdateFilter(t *testing.T) { filter.Rules = []*engine.FilterRule{ { - FieldName: utils.MetaString, - Type: "~Account", - Values: []string{"1001", "1002"}, + Element: utils.MetaString, + Type: "~Account", + Values: []string{"1001", "1002"}, }, { - FieldName: utils.MetaPrefix, - Type: "~Destination", - Values: []string{"10", "20"}, + Element: utils.MetaPrefix, + Type: "~Destination", + Values: []string{"10", "20"}, }, } var result string diff --git a/apier/v1/stats_it_test.go b/apier/v1/stats_it_test.go index 97d410af3..1599df60b 100644 --- a/apier/v1/stats_it_test.go +++ b/apier/v1/stats_it_test.go @@ -340,9 +340,9 @@ func testV1STSSetStatQueueProfile(t *testing.T) { ID: "FLTR_1", Rules: []*engine.FilterRule{ { - FieldName: "~*req.Account", - Type: "*string", - Values: []string{"1001"}, + Element: "~*req.Account", + Type: utils.MetaString, + Values: []string{"1001"}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -420,9 +420,9 @@ func testV1STSUpdateStatQueueProfile(t *testing.T) { ID: "FLTR_2", Rules: []*engine.FilterRule{ { - FieldName: "~*req.Account", - Type: "*string", - Values: []string{"1001"}, + Element: "~*req.Account", + Type: utils.MetaString, + Values: []string{"1001"}, }, }, ActivationInterval: &utils.ActivationInterval{ diff --git a/apier/v1/tpattributes_it_test.go b/apier/v1/tpattributes_it_test.go index f3499baa3..1155cd844 100644 --- a/apier/v1/tpattributes_it_test.go +++ b/apier/v1/tpattributes_it_test.go @@ -138,7 +138,7 @@ func testTPAlsPrfSetTPAlsPrf(t *testing.T) { Contexts: []string{"con1"}, Attributes: []*utils.TPAttribute{ &utils.TPAttribute{ - FieldName: utils.MetaReq + utils.NestingSep + "FL1", + Path: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", FilterIDs: []string{}, }, @@ -180,12 +180,12 @@ func testTPAlsPrfGetTPAlsPrfIDs(t *testing.T) { func testTPAlsPrfUpdateTPAlsPrf(t *testing.T) { tpAlsPrf.Attributes = []*utils.TPAttribute{ &utils.TPAttribute{ - FieldName: utils.MetaReq + utils.NestingSep + "FL1", + Path: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", FilterIDs: []string{}, }, &utils.TPAttribute{ - FieldName: utils.MetaReq + utils.NestingSep + "FL2", + Path: utils.MetaReq + utils.NestingSep + "FL2", Value: "Al2", FilterIDs: []string{}, }, @@ -212,12 +212,12 @@ func testTPAlsPrfGetTPAlsPrfAfterUpdate(t *testing.T) { Contexts: []string{"con1"}, Attributes: []*utils.TPAttribute{ &utils.TPAttribute{ - FieldName: utils.MetaReq + utils.NestingSep + "FL2", + Path: utils.MetaReq + utils.NestingSep + "FL2", Value: "Al2", FilterIDs: []string{}, }, &utils.TPAttribute{ - FieldName: utils.MetaReq + utils.NestingSep + "FL1", + Path: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", FilterIDs: []string{}, }, @@ -226,7 +226,7 @@ func testTPAlsPrfGetTPAlsPrfAfterUpdate(t *testing.T) { } sort.Strings(revTPAlsPrf.FilterIDs) sort.Slice(revTPAlsPrf.Attributes, func(i, j int) bool { - return strings.Compare(revTPAlsPrf.Attributes[i].FieldName, revTPAlsPrf.Attributes[j].FieldName) == -1 + return strings.Compare(revTPAlsPrf.Attributes[i].Path, revTPAlsPrf.Attributes[j].Path) == -1 }) if err := tpAlsPrfRPC.Call(utils.ApierV1GetTPAttributeProfile, &utils.TPTntID{TPid: "TP1", Tenant: "cgrates.org", ID: "Attr1"}, &reply); err != nil { @@ -234,7 +234,7 @@ func testTPAlsPrfGetTPAlsPrfAfterUpdate(t *testing.T) { } sort.Strings(reply.FilterIDs) sort.Slice(reply.Attributes, func(i, j int) bool { - return strings.Compare(reply.Attributes[i].FieldName, reply.Attributes[j].FieldName) == -1 + return strings.Compare(reply.Attributes[i].Path, reply.Attributes[j].Path) == -1 }) if !reflect.DeepEqual(tpAlsPrf, reply) && !reflect.DeepEqual(revTPAlsPrf, reply) { t.Errorf("Expecting : %+v, \n received: %+v", utils.ToJSON(tpAlsPrf), utils.ToJSON(reply)) diff --git a/apier/v1/tpfilters_it_test.go b/apier/v1/tpfilters_it_test.go index 2bea05161..69d696913 100644 --- a/apier/v1/tpfilters_it_test.go +++ b/apier/v1/tpfilters_it_test.go @@ -141,9 +141,9 @@ func testTPFilterSetTPFilter(t *testing.T) { ID: "Filter", Filters: []*utils.TPFilter{ &utils.TPFilter{ - Type: utils.MetaString, - FieldName: "Account", - Values: []string{"1001", "1002"}, + Type: utils.MetaString, + Element: "Account", + Values: []string{"1001", "1002"}, }, }, ActivationInterval: &utils.TPActivationInterval{ @@ -187,20 +187,20 @@ func testTPFilterGetFilterIds(t *testing.T) { func testTPFilterUpdateTPFilter(t *testing.T) { tpFilter.Filters = []*utils.TPFilter{ &utils.TPFilter{ - Type: utils.MetaString, - FieldName: "Account", - Values: []string{"1001", "1002"}, + Type: utils.MetaString, + Element: "Account", + Values: []string{"1001", "1002"}, }, &utils.TPFilter{ - Type: utils.MetaPrefix, - FieldName: "Destination", - Values: []string{"10", "20"}, + Type: utils.MetaPrefix, + Element: "Destination", + Values: []string{"10", "20"}, }, } sort.Slice(tpFilter.Filters, func(i, j int) bool { sort.Strings(tpFilter.Filters[i].Values) sort.Strings(tpFilter.Filters[j].Values) - return strings.Compare(tpFilter.Filters[i].FieldName, tpFilter.Filters[j].FieldName) == -1 + return strings.Compare(tpFilter.Filters[i].Element, tpFilter.Filters[j].Element) == -1 }) var result string if err := tpFilterRPC.Call(utils.ApierV1SetTPFilterProfile, tpFilter, &result); err != nil { @@ -219,7 +219,7 @@ func testTPFilterGetTPFilterAfterUpdate(t *testing.T) { sort.Slice(reply.Filters, func(i, j int) bool { sort.Strings(reply.Filters[i].Values) sort.Strings(reply.Filters[j].Values) - return strings.Compare(reply.Filters[i].FieldName, reply.Filters[j].FieldName) == -1 + return strings.Compare(reply.Filters[i].Element, reply.Filters[j].Element) == -1 }) if !reflect.DeepEqual(tpFilter, reply) { t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(tpFilter), utils.ToJSON(reply)) diff --git a/apier/v2/attributes_it_test.go b/apier/v2/attributes_it_test.go index 90d8ef6d0..e050e1b66 100644 --- a/apier/v2/attributes_it_test.go +++ b/apier/v2/attributes_it_test.go @@ -127,8 +127,8 @@ func testAttributeSSetAlsPrf(t *testing.T) { }, Attributes: []*engine.ExternalAttribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Account", - Value: "1001", + Path: utils.MetaReq + utils.NestingSep + "Account", + Value: "1001", }, }, Weight: 20, @@ -153,8 +153,8 @@ func testAttributeSSetAlsPrf(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Account", - Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Account", + Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -185,12 +185,12 @@ func testAttributeSUpdateAlsPrf(t *testing.T) { }, Attributes: []*engine.ExternalAttribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Account", - Value: "1001", + Path: utils.MetaReq + utils.NestingSep + "Account", + Value: "1001", }, { - FieldName: utils.MetaReq + utils.NestingSep + "Subject", - Value: "~*req.Account", + Path: utils.MetaReq + utils.NestingSep + "Subject", + Value: "~*req.Account", }, }, Weight: 20, @@ -215,12 +215,12 @@ func testAttributeSUpdateAlsPrf(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Account", - Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Account", + Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaReq + utils.NestingSep + "Subject", - Value: config.NewRSRParsersMustCompile("~*req.Account", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Subject", + Value: config.NewRSRParsersMustCompile("~*req.Account", true, utils.INFIELD_SEP), }, }, Weight: 20, diff --git a/apier/v2/cdrs_it_test.go b/apier/v2/cdrs_it_test.go index 4ed8c010b..f8c015af4 100644 --- a/apier/v2/cdrs_it_test.go +++ b/apier/v2/cdrs_it_test.go @@ -408,8 +408,8 @@ func testV2CDRsDifferentTenants(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaTenant, - Type: utils.META_CONSTANT, + Path: utils.MetaTenant, + Type: utils.META_CONSTANT, Value: config.RSRParsers{ &config.RSRParser{ Rules: "CustomTenant", @@ -418,8 +418,8 @@ func testV2CDRsDifferentTenants(t *testing.T) { }, }, { - FieldName: utils.MetaReq + utils.NestingSep + utils.Tenant, - Type: utils.META_CONSTANT, + Path: utils.MetaReq + utils.NestingSep + utils.Tenant, + Type: utils.META_CONSTANT, Value: config.RSRParsers{ &config.RSRParser{ Rules: "CustomTenant", diff --git a/cdrc/csv_it_test.go b/cdrc/csv_it_test.go index 2e040aa41..fc5ff534e 100644 --- a/cdrc/csv_it_test.go +++ b/cdrc/csv_it_test.go @@ -517,9 +517,9 @@ func TestCsvIT5AddFilters(t *testing.T) { ID: "FLTR_CDRC_ACC", Rules: []*engine.FilterRule{ { - Type: "*string", - FieldName: "~*req.3", - Values: []string{"1002"}, + Type: utils.MetaString, + Element: "~*req.3", + Values: []string{"1002"}, }, }, }, @@ -536,9 +536,9 @@ func TestCsvIT5AddFilters(t *testing.T) { ID: "FLTR_CDRC_ACC", Rules: []*engine.FilterRule{ { - Type: "*string", - FieldName: "~*req.3", - Values: []string{"1001"}, + Type: utils.MetaString, + Element: "~*req.3", + Values: []string{"1001"}, }, }, }, diff --git a/cdrc/fwv_it_test.go b/cdrc/fwv_it_test.go index 658278e0f..225c4864d 100644 --- a/cdrc/fwv_it_test.go +++ b/cdrc/fwv_it_test.go @@ -331,9 +331,9 @@ func TestFwvit3AddFilters(t *testing.T) { ID: "FLTR_FWV", Rules: []*engine.FilterRule{ { - Type: "*string", - FieldName: "0-10", - Values: []string{"CDR0000010"}, + Type: utils.MetaString, + Element: "0-10", + Values: []string{"CDR0000010"}, }, }, }, diff --git a/cdrc/xml_it_test.go b/cdrc/xml_it_test.go index 3faa4429f..d2be26e5f 100644 --- a/cdrc/xml_it_test.go +++ b/cdrc/xml_it_test.go @@ -467,14 +467,14 @@ func TestXmlIT5AddFilters(t *testing.T) { ID: "FLTR_XML", Rules: []*engine.FilterRule{ { - Type: "*string", - FieldName: "~*req.broadWorksCDR.cdrData.basicModule.userNumber", - Values: []string{"1002"}, + Type: utils.MetaString, + Element: "~*req.broadWorksCDR.cdrData.basicModule.userNumber", + Values: []string{"1002"}, }, { - Type: "*string", - FieldName: "~*req.broadWorksCDR.cdrData.headerModule.type", - Values: []string{"Normal"}, + Type: utils.MetaString, + Element: "~*req.broadWorksCDR.cdrData.headerModule.type", + Values: []string{"Normal"}, }, }, }, diff --git a/config/config_defaults.go b/config/config_defaults.go index 956ae1073..29aeae6b2 100755 --- a/config/config_defaults.go +++ b/config/config_defaults.go @@ -643,7 +643,7 @@ const CGRATES_CFG_JSON = ` {"tag": "FilterIDs", "field_id": "FilterIDs", "type": "*variable", "value": "~3"}, {"tag": "ActivationInterval", "field_id": "ActivationInterval", "type": "*variable", "value": "~4"}, {"tag": "AttributeFilterIDs", "field_id": "AttributeFilterIDs", "type": "*variable", "value": "~5"}, - {"tag": "FieldName", "field_id": "FieldName", "type": "*variable", "value": "~6"}, + {"tag": "Path", "field_id": "Path", "type": "*variable", "value": "~6"}, {"tag": "Type", "field_id": "Type", "type": "*variable", "value": "~7"}, {"tag": "Value", "field_id": "Value", "type": "*variable", "value": "~8"}, {"tag": "Blocker", "field_id": "Blocker", "type": "*variable", "value": "~9"}, @@ -656,9 +656,9 @@ const CGRATES_CFG_JSON = ` "fields": [ {"tag": "Tenant", "field_id": "Tenant", "type": "*variable", "value": "~0", "mandatory": true}, {"tag": "ID", "field_id": "ID", "type": "*variable", "value": "~1", "mandatory": true}, - {"tag": "FilterType", "field_id": "FilterType", "type": "*variable", "value": "~2"}, - {"tag": "FilterFieldName", "field_id": "FilterFieldName", "type": "*variable", "value": "~3"}, - {"tag": "FilterFieldValues", "field_id": "FilterFieldValues", "type": "*variable", "value": "~4"}, + {"tag": "Type", "field_id": "Type", "type": "*variable", "value": "~2"}, + {"tag": "Element", "field_id": "Element", "type": "*variable", "value": "~3"}, + {"tag": "Values", "field_id": "Values", "type": "*variable", "value": "~4"}, {"tag": "ActivationInterval", "field_id": "ActivationInterval", "type": "*variable", "value": "~5"}, ], }, diff --git a/config/config_json_test.go b/config/config_json_test.go index 46bdfc90d..155b4d3aa 100755 --- a/config/config_json_test.go +++ b/config/config_json_test.go @@ -1049,8 +1049,8 @@ func TestDfLoaderJsonCfg(t *testing.T) { Field_id: utils.StringPointer("AttributeFilterIDs"), Type: utils.StringPointer(utils.MetaVariable), Value: utils.StringPointer("~5")}, - {Tag: utils.StringPointer("FieldName"), - Field_id: utils.StringPointer(utils.FieldName), + {Tag: utils.StringPointer("Path"), + Field_id: utils.StringPointer(utils.Path), Type: utils.StringPointer(utils.MetaVariable), Value: utils.StringPointer("~6")}, {Tag: utils.StringPointer("Type"), @@ -1085,16 +1085,16 @@ func TestDfLoaderJsonCfg(t *testing.T) { Type: utils.StringPointer(utils.MetaVariable), Value: utils.StringPointer("~1"), Mandatory: utils.BoolPointer(true)}, - {Tag: utils.StringPointer("FilterType"), - Field_id: utils.StringPointer("FilterType"), + {Tag: utils.StringPointer("Type"), + Field_id: utils.StringPointer("Type"), Type: utils.StringPointer(utils.MetaVariable), Value: utils.StringPointer("~2")}, - {Tag: utils.StringPointer("FilterFieldName"), - Field_id: utils.StringPointer("FilterFieldName"), + {Tag: utils.StringPointer("Element"), + Field_id: utils.StringPointer("Element"), Type: utils.StringPointer(utils.MetaVariable), Value: utils.StringPointer("~3")}, - {Tag: utils.StringPointer("FilterFieldValues"), - Field_id: utils.StringPointer("FilterFieldValues"), + {Tag: utils.StringPointer("Values"), + Field_id: utils.StringPointer("Values"), Type: utils.StringPointer(utils.MetaVariable), Value: utils.StringPointer("~4")}, {Tag: utils.StringPointer("ActivationInterval"), diff --git a/config/config_test.go b/config/config_test.go index 64ecf6832..0eebd2f0e 100755 --- a/config/config_test.go +++ b/config/config_test.go @@ -1082,8 +1082,8 @@ func TestCgrLoaderCfgITDefaults(t *testing.T) { FieldId: "AttributeFilterIDs", Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~5", true, utils.INFIELD_SEP)}, - {Tag: "FieldName", - FieldId: "FieldName", + {Tag: "Path", + FieldId: "Path", Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~6", true, utils.INFIELD_SEP)}, {Tag: "Type", @@ -1118,16 +1118,16 @@ func TestCgrLoaderCfgITDefaults(t *testing.T) { Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~1", true, utils.INFIELD_SEP), Mandatory: true}, - {Tag: "FilterType", - FieldId: "FilterType", + {Tag: "Type", + FieldId: "Type", Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~2", true, utils.INFIELD_SEP)}, - {Tag: "FilterFieldName", - FieldId: "FilterFieldName", + {Tag: "Element", + FieldId: "Element", Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~3", true, utils.INFIELD_SEP)}, - {Tag: "FilterFieldValues", - FieldId: "FilterFieldValues", + {Tag: "Values", + FieldId: "Values", Type: utils.MetaVariable, Value: NewRSRParsersMustCompile("~4", true, utils.INFIELD_SEP)}, {Tag: "ActivationInterval", diff --git a/data/conf/cgrates/cgrates.json b/data/conf/cgrates/cgrates.json index cd07354e7..d6d88690f 100755 --- a/data/conf/cgrates/cgrates.json +++ b/data/conf/cgrates/cgrates.json @@ -597,7 +597,7 @@ // {"tag": "FilterIDs", "field_id": "FilterIDs", "type": "*variable", "value": "~3"}, // {"tag": "ActivationInterval", "field_id": "ActivationInterval", "type": "*variable", "value": "~4"}, // {"tag": "AttributeFilterIDs", "field_id": "AttributeFilterIDs", "type": "*variable", "value": "~5"}, -// {"tag": "FieldName", "field_id": "FieldName", "type": "*variable", "value": "~6"}, +// {"tag": "Path", "field_id": "Path", "type": "*variable", "value": "~6"}, // {"tag": "Type", "field_id": "Type", "type": "*variable", "value": "~7"}, // {"tag": "Value", "field_id": "Value", "type": "*variable", "value": "~8"}, // {"tag": "Blocker", "field_id": "Blocker", "type": "*variable", "value": "~9"}, @@ -610,9 +610,9 @@ // "fields": [ // {"tag": "Tenant", "field_id": "Tenant", "type": "*variable", "value": "~0", "mandatory": true}, // {"tag": "ID", "field_id": "ID", "type": "*variable", "value": "~1", "mandatory": true}, -// {"tag": "FilterType", "field_id": "FilterType", "type": "*variable", "value": "~2"}, -// {"tag": "FilterFieldName", "field_id": "FilterFieldName", "type": "*variable", "value": "~3"}, -// {"tag": "FilterFieldValues", "field_id": "FilterFieldValues", "type": "*variable", "value": "~4"}, +// {"tag": "Type", "field_id": "Type", "type": "*variable", "value": "~2"}, +// {"tag": "Element", "field_id": "Element", "type": "*variable", "value": "~3"}, +// {"tag": "Values", "field_id": "Values", "type": "*variable", "value": "~4"}, // {"tag": "ActivationInterval", "field_id": "ActivationInterval", "type": "*variable", "value": "~5"}, // ], // }, diff --git a/data/conf/samples/loaders/tutmongo/cgrates.json b/data/conf/samples/loaders/tutmongo/cgrates.json index 039737224..107343c63 100644 --- a/data/conf/samples/loaders/tutmongo/cgrates.json +++ b/data/conf/samples/loaders/tutmongo/cgrates.json @@ -126,7 +126,7 @@ {"tag": "FilterIDs", "field_id": "FilterIDs", "type": "*variable", "value": "~3"}, {"tag": "ActivationInterval", "field_id": "ActivationInterval", "type": "*variable", "value": "~4"}, {"tag": "AttributeFilterIDs", "field_id": "AttributeFilterIDs", "type": "*variable", "value": "~5"}, - {"tag": "FieldName", "field_id": "FieldName", "type": "*variable", "value": "~6"}, + {"tag": "Path", "field_id": "Path", "type": "*variable", "value": "~6"}, {"tag": "Type", "field_id": "Type", "type": "*variable", "value": "~7"}, {"tag": "Value", "field_id": "Value", "type": "*variable", "value": "~8"}, {"tag": "Blocker", "field_id": "Blocker", "type": "*variable", "value": "~9"}, diff --git a/data/conf/samples/loaders/tutmysql/cgrates.json b/data/conf/samples/loaders/tutmysql/cgrates.json index 9e450d7ff..a30852813 100644 --- a/data/conf/samples/loaders/tutmysql/cgrates.json +++ b/data/conf/samples/loaders/tutmysql/cgrates.json @@ -86,7 +86,7 @@ {"tag": "FilterIDs", "field_id": "FilterIDs", "type": "*variable", "value": "~3"}, {"tag": "ActivationInterval", "field_id": "ActivationInterval", "type": "*variable", "value": "~4"}, {"tag": "AttributeFilterIDs", "field_id": "AttributeFilterIDs", "type": "*variable", "value": "~5"}, - {"tag": "FieldName", "field_id": "FieldName", "type": "*variable", "value": "~6"}, + {"tag": "Path", "field_id": "Path", "type": "*variable", "value": "~6"}, {"tag": "Type", "field_id": "Type", "type": "*variable", "value": "~7"}, {"tag": "Value", "field_id": "Value", "type": "*variable", "value": "~8"}, {"tag": "Blocker", "field_id": "Blocker", "type": "*variable", "value": "~9"}, diff --git a/data/conf/samples/tutmysql_internal/cgrates.json b/data/conf/samples/tutmysql_internal/cgrates.json index fb4e6fa8a..afc4fbe6e 100644 --- a/data/conf/samples/tutmysql_internal/cgrates.json +++ b/data/conf/samples/tutmysql_internal/cgrates.json @@ -168,9 +168,9 @@ "fields": [ {"tag": "Tenant", "field_id": "Tenant", "type": "*variable", "value": "~0", "mandatory": true}, {"tag": "ID", "field_id": "ID", "type": "*variable", "value": "~1", "mandatory": true}, - {"tag": "FilterType", "field_id": "FilterType", "type": "*variable", "value": "~2"}, - {"tag": "FilterFieldName", "field_id": "FilterFieldName", "type": "*variable", "value": "~3"}, - {"tag": "FilterFieldValues", "field_id": "FilterFieldValues", "type": "*variable", "value": "~4"}, + {"tag": "Type", "field_id": "Type", "type": "*variable", "value": "~2"}, + {"tag": "Element", "field_id": "Element", "type": "*variable", "value": "~3"}, + {"tag": "Values", "field_id": "Values", "type": "*variable", "value": "~4"}, {"tag": "ActivationInterval", "field_id": "ActivationInterval", "type": "*variable", "value": "~5"}, ], }, diff --git a/data/storage/mysql/create_tariffplan_tables.sql b/data/storage/mysql/create_tariffplan_tables.sql index 455c58e47..a203d7090 100644 --- a/data/storage/mysql/create_tariffplan_tables.sql +++ b/data/storage/mysql/create_tariffplan_tables.sql @@ -329,14 +329,14 @@ CREATE TABLE tp_filters ( `tpid` varchar(64) NOT NULL, `tenant` varchar(64) NOT NULL, `id` varchar(64) NOT NULL, - `filter_type` varchar(16) NOT NULL, - `filter_field_name` varchar(64) NOT NULL, - `filter_field_values` varchar(256) NOT NULL, + `type` varchar(16) NOT NULL, + `element` varchar(64) NOT NULL, + `values` varchar(256) NOT NULL, `activation_interval` varchar(64) NOT NULL, `created_at` TIMESTAMP, PRIMARY KEY (`pk`), KEY `tpid` (`tpid`), - UNIQUE KEY `unique_tp_filters` (`tpid`,`tenant`, `id`, `filter_type`, `filter_field_name`) + UNIQUE KEY `unique_tp_filters` (`tpid`,`tenant`, `id`, `type`, `element`) ); -- @@ -386,7 +386,7 @@ CREATE TABLE tp_attributes ( `filter_ids` varchar(64) NOT NULL, `activation_interval` varchar(64) NOT NULL, `attribute_filter_ids` varchar(64) NOT NULL, - `field_name` varchar(64) NOT NULL, + `path` varchar(64) NOT NULL, `type` varchar(64) NOT NULL, `value` varchar(64) NOT NULL, `blocker` BOOLEAN NOT NULL, @@ -395,7 +395,7 @@ CREATE TABLE tp_attributes ( PRIMARY KEY (`pk`), KEY `tpid` (`tpid`), UNIQUE KEY `unique_tp_attributes` (`tpid`,`tenant`, - `id`,`filter_ids`,`field_name`,`value` ) + `id`,`filter_ids`,`path`,`value` ) ); -- diff --git a/data/storage/postgres/create_tariffplan_tables.sql b/data/storage/postgres/create_tariffplan_tables.sql index c6d7d60ad..29a9502df 100644 --- a/data/storage/postgres/create_tariffplan_tables.sql +++ b/data/storage/postgres/create_tariffplan_tables.sql @@ -323,14 +323,14 @@ CREATE TABLE tp_filters ( "tpid" varchar(64) NOT NULL, "tenant" varchar(64) NOT NULL, "id" varchar(64) NOT NULL, - "filter_type" varchar(16) NOT NULL, - "filter_field_name" varchar(64) NOT NULL, - "filter_field_values" varchar(256) NOT NULL, + "type" varchar(16) NOT NULL, + "element" varchar(64) NOT NULL, + "values" varchar(256) NOT NULL, "activation_interval" varchar(64) NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE ); CREATE INDEX tp_filters_idx ON tp_filters (tpid); - CREATE INDEX tp_filters_unique ON tp_filters ("tpid","tenant", "id", "filter_type", "filter_field_name"); + CREATE INDEX tp_filters_unique ON tp_filters ("tpid","tenant", "id", "type", "element"); -- -- Table structure for table `tp_suppliers` @@ -377,7 +377,7 @@ CREATE INDEX tp_suppliers_unique ON tp_suppliers ("tpid", "tenant", "id", "filter_ids" varchar(64) NOT NULL, "activation_interval" varchar(64) NOT NULL, "attribute_filter_ids" varchar(64) NOT NULL, - "field_name" varchar(64) NOT NULL, + "path" varchar(64) NOT NULL, "type" varchar(64) NOT NULL, "value" varchar(64) NOT NULL, "blocker" BOOLEAN NOT NULL, @@ -386,7 +386,7 @@ CREATE INDEX tp_suppliers_unique ON tp_suppliers ("tpid", "tenant", "id", ); CREATE INDEX tp_attributes_ids ON tp_attributes (tpid); CREATE INDEX tp_attributes_unique ON tp_attributes ("tpid", "tenant", "id", - "filter_ids","field_name","value"); + "filter_ids","path","value"); -- -- Table structure for table `tp_chargers` diff --git a/data/tariffplans/cluelrn/Attributes.csv b/data/tariffplans/cluelrn/Attributes.csv index 05a033f5e..cc128ac6e 100644 --- a/data/tariffplans/cluelrn/Attributes.csv +++ b/data/tariffplans/cluelrn/Attributes.csv @@ -1,4 +1,4 @@ -#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight +#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,Path,Type,Value,Blocker,Weight cgrates.org,LRN_Dst3125650565,lrn,*string:~*req.Destination:3125650565,,,*req.Destination,*constant,13128543000,false,10 cgrates.org,LRN_Dst3125650565,,,,,*req.OriginalDestination,*constant,3125650565,false,10 cgrates.org,LRN_LATA_Dst13128543000,lrn,*string:~*req.Destination:13128543000;*rsr::~*req.OriginalDestination(!^$),,,*req.DestinationLATA,*constant,358,false,20 diff --git a/data/tariffplans/cluelrn/Filters.csv b/data/tariffplans/cluelrn/Filters.csv index 916436222..e85258894 100644 --- a/data/tariffplans/cluelrn/Filters.csv +++ b/data/tariffplans/cluelrn/Filters.csv @@ -1,4 +1,4 @@ -#Tenant[0],ID[1],FilterType[2],FilterFieldName[3],FilterFieldValues[4],ActivationInterval[5] +#Tenant[0],ID[1],Type[2],Path[3],Values[4],ActivationInterval[5] cgrates.org,FLTR_INTRALATA_NEWYORK,*string,~*req.CallerLATA,224;222;220;132, cgrates.org,FLTR_INTRALATA_NEWYORK,*string,~*req.DestinationLATA,224;222;220;132, cgrates.org,FLTR_INTRALATA_ILLINOIS,*string,~*req.CallerLATA,358;359, diff --git a/data/tariffplans/dispatchers/Attributes.csv b/data/tariffplans/dispatchers/Attributes.csv index 5f004a8e6..defe079eb 100644 --- a/data/tariffplans/dispatchers/Attributes.csv +++ b/data/tariffplans/dispatchers/Attributes.csv @@ -1,4 +1,4 @@ -#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight +#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,Path,Type,Value,Blocker,Weight cgrates.org,ATTR_1001_SIMPLEAUTH,*any,*string:~*req.Account:1001,,,*req.Password,*constant,CGRateS.org,false,20 cgrates.org,ATTR_1001_SIMPLEAUTH,*any,,,,*req.EventName,*constant,*remove,false,20 cgrates.org,ATTR_1003_SIMPLEAUTH,*any,*string:~*req.Account:1003,,,*req.Password,*constant,CGRateS.com,false,20 diff --git a/data/tariffplans/dispatchers_gob/Attributes.csv b/data/tariffplans/dispatchers_gob/Attributes.csv index a07ee0570..610f17c9d 100644 --- a/data/tariffplans/dispatchers_gob/Attributes.csv +++ b/data/tariffplans/dispatchers_gob/Attributes.csv @@ -1,4 +1,4 @@ -#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight +#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,Path,Type,Value,Blocker,Weight cgrates.org,ATTR_1001_SIMPLEAUTH,*any,*string:~*req.Account:1001,,,*req.Password,*constant,CGRateS.org,false,20 cgrates.org,ATTR_1001_SIMPLEAUTH,*any,,,,EventName,*constant,*remove,false,20 cgrates.org,ATTR_1003_SIMPLEAUTH,*any,*string:~*req.Account:1003,,,*req.Password,*constant,CGRateS.com,false,20 diff --git a/data/tariffplans/dnsagent/Attributes.csv b/data/tariffplans/dnsagent/Attributes.csv index 8ce6b217b..12f1c7d1e 100644 --- a/data/tariffplans/dnsagent/Attributes.csv +++ b/data/tariffplans/dnsagent/Attributes.csv @@ -1,3 +1,3 @@ -#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight +#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,Path,Type,Value,Blocker,Weight cgrates.org,ATTR_NAPTR_ADDR,*any,*string:~*req.E164Address:4986517174964,,,*req.NAPTRAddress,*constant,sip:\1@172.16.1.1.,false,20 diff --git a/data/tariffplans/oldtutorial/Attributes.csv b/data/tariffplans/oldtutorial/Attributes.csv index 21031d303..b96c5799a 100644 --- a/data/tariffplans/oldtutorial/Attributes.csv +++ b/data/tariffplans/oldtutorial/Attributes.csv @@ -1,3 +1,3 @@ -#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight +#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,Path,Type,Value,Blocker,Weight cgrates.org,ATTR_1,*sessions;*cdrs,*string:~*req.Account:1007,2014-01-14T00:00:00Z,,*req.Account,*constant,1001,false,10 cgrates.org,ATTR_1,,,,,*req.Subject,*constant,1001,, diff --git a/data/tariffplans/oldtutorial/Filters.csv b/data/tariffplans/oldtutorial/Filters.csv index 78c286f68..8cb901d2e 100644 --- a/data/tariffplans/oldtutorial/Filters.csv +++ b/data/tariffplans/oldtutorial/Filters.csv @@ -1,4 +1,4 @@ -#Tenant[0],ID[1],FilterType[2],FilterFieldName[3],FilterFieldValues[4],ActivationInterval[5] +#Tenant[0],ID[1],Type[2],Path[3],Values[4],ActivationInterval[5] cgrates.org,FLTR_1,*string,~*req.Account,1001;1002,2014-07-29T15:00:00Z cgrates.org,FLTR_1,*prefix,~*req.Destination,10;20, cgrates.org,FLTR_1,*rsr,,~*req.Subject(~^1.*1$);~*req.Destination(1002), diff --git a/data/tariffplans/precache/Attributes.csv b/data/tariffplans/precache/Attributes.csv index 21031d303..b96c5799a 100644 --- a/data/tariffplans/precache/Attributes.csv +++ b/data/tariffplans/precache/Attributes.csv @@ -1,3 +1,3 @@ -#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight +#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,Path,Type,Value,Blocker,Weight cgrates.org,ATTR_1,*sessions;*cdrs,*string:~*req.Account:1007,2014-01-14T00:00:00Z,,*req.Account,*constant,1001,false,10 cgrates.org,ATTR_1,,,,,*req.Subject,*constant,1001,, diff --git a/data/tariffplans/precache/Filters.csv b/data/tariffplans/precache/Filters.csv index 71490d627..2782f4fe2 100644 --- a/data/tariffplans/precache/Filters.csv +++ b/data/tariffplans/precache/Filters.csv @@ -1,4 +1,4 @@ -#Tenant[0],ID[1],FilterType[2],FilterFieldName[3],FilterFieldValues[4],ActivationInterval[5] +#Tenant[0],ID[1],Type[2],Path[3],Values[4],ActivationInterval[5] cgrates.org,FLTR_1,*string,~*req.Account,1001;1002,2014-07-29T15:00:00Z cgrates.org,FLTR_1,*prefix,~*req.Destination,10;20, cgrates.org,FLTR_1,*rsr,,~*req.Subject(~^1.*1$);~Destination(1002), diff --git a/data/tariffplans/testit/Attributes.csv b/data/tariffplans/testit/Attributes.csv index 53849032f..b93e70ff2 100644 --- a/data/tariffplans/testit/Attributes.csv +++ b/data/tariffplans/testit/Attributes.csv @@ -1,4 +1,4 @@ -#Tenant,ID,Context,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight +#Tenant,ID,Context,FilterIDs,ActivationInterval,AttributeFilterIDs,Path,Type,Value,Blocker,Weight cgrates.org,ATTR_ACNT_1001,*sessions,FLTR_ACCOUNT_1001,,,*req.OfficeGroup,*constant,Marketing,false,10 cgrates.org,ATTR_SUPPLIER1,*chargers,,,,*req.Subject,*constant,SUPPLIER1,false,10 cgrates.org,ATTR_PAYPAL,*cdrs,*string:~*req.Subject:ANY2CNT,,,*req.PayPalAccount,*constant,paypal@cgrates.org,false,10 diff --git a/data/tariffplans/testit/Filters.csv b/data/tariffplans/testit/Filters.csv index 8b6c7652d..80ed6745e 100644 --- a/data/tariffplans/testit/Filters.csv +++ b/data/tariffplans/testit/Filters.csv @@ -1,4 +1,4 @@ -#Tenant[0],ID[1],FilterType[2],FilterFieldName[3],FilterFieldValues[4],ActivationInterval[5] +#Tenant[0],ID[1],Type[2],Path[3],Values[4],ActivationInterval[5] cgrates.org,FLTR_ACCOUNT_1001,*string,~*req.Account,1001,2014-07-29T15:00:00Z cgrates.org,FLTR_DST_DE,*destinations,~*req.Destination,DST_DE_MOBILE,2014-07-29T15:00:00Z cgrates.org,FLTR_1,*string,~*req.Account,1003;1002,2014-07-29T15:00:00Z diff --git a/data/tariffplans/testtp/Attributes.csv b/data/tariffplans/testtp/Attributes.csv index fa48657eb..c6abdd8c3 100644 --- a/data/tariffplans/testtp/Attributes.csv +++ b/data/tariffplans/testtp/Attributes.csv @@ -1,3 +1,3 @@ -#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight +#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,Path,Type,Value,Blocker,Weight cgrates.org,ALS1,con1,FLTR_1,2014-07-29T15:00:00Z,*string:~*req.Field1:Initial1,*req.Field1,*constant,Sub1,false,20 cgrates.org,ALS1,,,,*string:~*req.Field1:Initial2,*req.Field2,*constant,Sub2,, diff --git a/data/tariffplans/testtp/Filters.csv b/data/tariffplans/testtp/Filters.csv index 74926470d..3442e65b4 100644 --- a/data/tariffplans/testtp/Filters.csv +++ b/data/tariffplans/testtp/Filters.csv @@ -1,4 +1,4 @@ -#Tenant[0],ID[1],FilterType[2],FilterFieldName[3],FilterFieldValues[4],ActivationInterval[5] +#Tenant[0],ID[1],Type[2],Path[3],Values[4],ActivationInterval[5] cgrates.org,FLTR_1,*string,~*req.Account,1001;1002,2014-07-29T15:00:00Z cgrates.org,FLTR_1,*prefix,~*req.Destination,10;20, cgrates.org,FLTR_1,*rsr,,~*req.Subject(~^1.*1$);~Destination(1002), diff --git a/data/tariffplans/tutorial/Attributes.csv b/data/tariffplans/tutorial/Attributes.csv index 2dabbde2d..2a7a41590 100644 --- a/data/tariffplans/tutorial/Attributes.csv +++ b/data/tariffplans/tutorial/Attributes.csv @@ -1,4 +1,4 @@ -#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight +#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,Path,Type,Value,Blocker,Weight cgrates.org,ATTR_1001_SIMPLEAUTH,simpleauth,*string:~*req.Account:1001,,,*req.Password,*constant,CGRateS.org,false,20 cgrates.org,ATTR_1002_SIMPLEAUTH,simpleauth,*string:~*req.Account:1002,,,*req.Password,*constant,CGRateS.org,false,20 cgrates.org,ATTR_1003_SIMPLEAUTH,simpleauth,*string:~*req.Account:1003,,,*req.Password,*constant,CGRateS.org,false,20 diff --git a/data/tariffplans/tutorial/Filters.csv b/data/tariffplans/tutorial/Filters.csv index d889e87f1..b5f8c0a21 100644 --- a/data/tariffplans/tutorial/Filters.csv +++ b/data/tariffplans/tutorial/Filters.csv @@ -1,4 +1,4 @@ -#Tenant[0],ID[1],FilterType[2],FilterFieldName[3],FilterFieldValues[4],ActivationInterval[5] +#Tenant[0],ID[1],Type[2],Element[3],Values[4],ActivationInterval[5] cgrates.org,FLTR_RES,*string,~*req.Account,1001;1002;1003,2014-07-29T15:00:00Z cgrates.org,FLTR_DST_FS,*string,~*req.Account,1001,2014-07-29T15:00:00Z cgrates.org,FLTR_DST_FS,*destinations,~*req.Destination,DST_FS, diff --git a/data/tariffplans/tutorial2/Attributes.csv b/data/tariffplans/tutorial2/Attributes.csv index bb9f34e9e..bb841477c 100644 --- a/data/tariffplans/tutorial2/Attributes.csv +++ b/data/tariffplans/tutorial2/Attributes.csv @@ -1,4 +1,4 @@ -# Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight +# Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,Path,Type,Value,Blocker,Weight # ATTR_CRG_SUPPLIER1 replaces Category->supplier1 and RequestType->*constant for *sessions and *cdrs events cgrates.org,ATTR_CRG_SUPPLIER1,*sessions;*cdrs,,,,*req.Category,*constant,supplier1,false,0 diff --git a/dispatchers/attributes_it_test.go b/dispatchers/attributes_it_test.go index 75fc544e4..77aa96f05 100755 --- a/dispatchers/attributes_it_test.go +++ b/dispatchers/attributes_it_test.go @@ -142,7 +142,7 @@ func testDspAttrGetAttrFailover(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{}, - FieldName: utils.MetaReq + utils.NestingSep + "Password", + Path: utils.MetaReq + utils.NestingSep + "Password", Type: utils.META_CONSTANT, Value: config.NewRSRParsersMustCompile("CGRateS.org", true, utils.INFIELD_SEP), }, @@ -332,7 +332,7 @@ func testDspAttrTestAuthKey2(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{}, - FieldName: utils.MetaReq + utils.NestingSep + "Password", + Path: utils.MetaReq + utils.NestingSep + "Password", Type: utils.META_CONSTANT, Value: config.NewRSRParsersMustCompile("CGRateS.org", true, utils.INFIELD_SEP), }, @@ -423,7 +423,7 @@ func testDspAttrGetAttrRoundRobin(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{}, - FieldName: utils.MetaReq + utils.NestingSep + "Password", + Path: utils.MetaReq + utils.NestingSep + "Password", Type: utils.META_CONSTANT, Value: config.NewRSRParsersMustCompile("CGRateS.org", true, utils.INFIELD_SEP), }, diff --git a/dispatchers/dispatchers_it_test.go b/dispatchers/dispatchers_it_test.go index 8a18ef393..a5c3327ec 100644 --- a/dispatchers/dispatchers_it_test.go +++ b/dispatchers/dispatchers_it_test.go @@ -61,7 +61,7 @@ func testDspApierSetAttributes(t *testing.T) { }, "Attributes": []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, + Path: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.RSRParsers{ &config.RSRParser{ Rules: "roam", @@ -95,7 +95,7 @@ func testDspApierGetAttributes(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, + Path: utils.MetaReq + utils.NestingSep + utils.Subject, Value: config.RSRParsers{ &config.RSRParser{ Rules: "roam", diff --git a/docs/filters.rst b/docs/filters.rst index 9f6d4d6f4..5d0dc4ffc 100644 --- a/docs/filters.rst +++ b/docs/filters.rst @@ -35,7 +35,7 @@ Definition:: type FilterRule struct { Type string // Filter type - FieldName string // Name of the field providing us the Values to check (used in case of some ) + Element string // Name of the field providing us the Values to check (used in case of some ) Values []string // Filter definition } @@ -44,31 +44,31 @@ The matching logic of each FilterRule is given by it's type. The following types are implemented: -- *\*string* will match in full the *FieldName* with at least one value defined inside *Values*. Any of the values matching will have the FilterRule as *matched*. +- *\*string* will match in full the *Element* with at least one value defined inside *Values*. Any of the values matching will have the FilterRule as *matched*. - *\*notstring* is the negation of *\*string*. -- *\*prefix* will match at beginning of *FieldName* one of the values defined inside *Values*. +- *\*prefix* will match at beginning of *Element* one of the values defined inside *Values*. - *\*notprefix* is the negation of *\*prefix*. -- *\*suffix* will match at end of *FieldName* one of the values defined inside *Values*. +- *\*suffix* will match at end of *Element* one of the values defined inside *Values*. - *\*notsuffix* is the negation of *\*suffix*. -- *\*empty* will make sure that *FieldName* is empty or it does not exist in the event. +- *\*empty* will make sure that *Element* is empty or it does not exist in the event. - *\*notempty* is the negation of *\*empty*. -- *\*exists* will make sure that *FieldName* exists in the event. +- *\*exists* will make sure that *Element* exists in the event. - *\*notexists* is the negation of *\*exists*. -- *\*timings* will compare the time contained in *FieldName* with one of the TimingIDs defined in Values. +- *\*timings* will compare the time contained in *Element* with one of the TimingIDs defined in Values. - *\*nottimings* is the negation of *\*timings*. -- *\*destinations* will make sure that the *FieldName* is a prefix contained inside one of the destination IDs as *Values*. +- *\*destinations* will make sure that the *Element* is a prefix contained inside one of the destination IDs as *Values*. - *\*notdestinations* is the negation of *\*destinations*. @@ -76,7 +76,7 @@ The following types are implemented: - *\*notrsr* is the negation of *\*rsr*. -- *\*lt* (less than), *\*lte* (less than or equal), *\*gt* (greather than), *\*gte* (greather than or equal) are comparison operators and they pass if at least one of the values defined in *Values* are passing for the *FieldName* of event. The operators are able to compare string, float, int, time.Time, time.Duration, however both types need to be the same, otherwise the filter will raise *incomparable* as error. +- *\*lt* (less than), *\*lte* (less than or equal), *\*gt* (greather than), *\*gte* (greather than or equal) are comparison operators and they pass if at least one of the values defined in *Values* are passing for the *Element* of event. The operators are able to compare string, float, int, time.Time, time.Duration, however both types need to be the same, otherwise the filter will raise *incomparable* as error. Inline Filter diff --git a/docs/tariff_plans.rst b/docs/tariff_plans.rst index 9212af832..a4be2f063 100644 --- a/docs/tariff_plans.rst +++ b/docs/tariff_plans.rst @@ -860,13 +860,13 @@ TBD [0] - Tag TBD -[1] - FilterType +[1] - Type TBD -[2] - FilterFieldName +[2] - Element TBD -[3] - FilterFieldValues +[3] - Values TBD [4] - ActivationTime diff --git a/engine/action.go b/engine/action.go index d50b6352d..b509b4501 100644 --- a/engine/action.go +++ b/engine/action.go @@ -1000,7 +1000,7 @@ func removeSessionCosts(_ *Account, action *Action, _ Actions, _ interface{}) er continue } for _, rule := range fltr.Rules { - smcFilter, err = utils.AppendToSMCostFilter(smcFilter, rule.Type, rule.FieldName, rule.Values, config.CgrConfig().GeneralCfg().DefaultTimezone) + smcFilter, err = utils.AppendToSMCostFilter(smcFilter, rule.Type, rule.Element, rule.Values, config.CgrConfig().GeneralCfg().DefaultTimezone) if err != nil { utils.Logger.Warning(fmt.Sprintf("<%s> %s in action: <%s>", utils.Actions, err.Error(), utils.MetaRemoveSessionCosts)) } diff --git a/engine/attributes.go b/engine/attributes.go index 0a4c5cc84..393deb7ed 100644 --- a/engine/attributes.go +++ b/engine/attributes.go @@ -254,11 +254,11 @@ func (alS *AttributeService) processEvent(args *AttrArgsProcessEvent) ( if err != nil { return nil, err } - //add only once the FieldName in AlteredFields - if !utils.IsSliceMember(rply.AlteredFields, attribute.FieldName) { - rply.AlteredFields = append(rply.AlteredFields, attribute.FieldName) + //add only once the Path in AlteredFields + if !utils.IsSliceMember(rply.AlteredFields, attribute.Path) { + rply.AlteredFields = append(rply.AlteredFields, attribute.Path) } - if attribute.FieldName == utils.MetaTenant { + if attribute.Path == utils.MetaTenant { if attribute.Type == utils.META_COMPOSED { rply.CGREvent.Tenant += substitute } else { @@ -267,15 +267,15 @@ func (alS *AttributeService) processEvent(args *AttrArgsProcessEvent) ( continue } if substitute == utils.MetaRemove { - evNm.Remove(strings.Split(attribute.FieldName, utils.NestingSep)) + evNm.Remove(strings.Split(attribute.Path, utils.NestingSep)) continue } if attribute.Type == utils.META_COMPOSED { var val string - val, err = evNm.FieldAsString(strings.Split(attribute.FieldName, utils.NestingSep)) + val, err = evNm.FieldAsString(strings.Split(attribute.Path, utils.NestingSep)) substitute = val + substitute } - evNm.Set(strings.Split(attribute.FieldName, utils.NestingSep), substitute, false, false) + evNm.Set(strings.Split(attribute.Path, utils.NestingSep), substitute, false, false) } return } diff --git a/engine/attributes_test.go b/engine/attributes_test.go index a5b8709ba..ecca46bd2 100644 --- a/engine/attributes_test.go +++ b/engine/attributes_test.go @@ -87,8 +87,8 @@ var ( }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Account, - Value: config.NewRSRParsersMustCompile("1010", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Account, + Value: config.NewRSRParsersMustCompile("1010", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -104,8 +104,8 @@ var ( }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Account, - Value: config.NewRSRParsersMustCompile("1010", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Account, + Value: config.NewRSRParsersMustCompile("1010", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -121,8 +121,8 @@ var ( }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Account, - Value: config.NewRSRParsersMustCompile("1010", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Account, + Value: config.NewRSRParsersMustCompile("1010", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -138,8 +138,8 @@ var ( }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Account, - Value: config.NewRSRParsersMustCompile("1010", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Account, + Value: config.NewRSRParsersMustCompile("1010", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -167,19 +167,19 @@ func TestAttributeAddFilters(t *testing.T) { ID: "FLTR_ATTR_1", Rules: []*FilterRule{ { - Type: utils.MetaString, - FieldName: "~*req.Attribute", - Values: []string{"AttributeProfile1"}, + Type: utils.MetaString, + Element: "~*req.Attribute", + Values: []string{"AttributeProfile1"}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: "~*req.UsageInterval", - Values: []string{(1 * time.Second).String()}, + Type: utils.MetaGreaterOrEqual, + Element: "~*req.UsageInterval", + Values: []string{(1 * time.Second).String()}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: "~*req." + utils.Weight, - Values: []string{"9.0"}, + Type: utils.MetaGreaterOrEqual, + Element: "~*req." + utils.Weight, + Values: []string{"9.0"}, }, }, } @@ -189,9 +189,9 @@ func TestAttributeAddFilters(t *testing.T) { ID: "FLTR_ATTR_2", Rules: []*FilterRule{ { - Type: utils.MetaString, - FieldName: "~*req.Attribute", - Values: []string{"AttributeProfile2"}, + Type: utils.MetaString, + Element: "~*req.Attribute", + Values: []string{"AttributeProfile2"}, }, }, } @@ -201,9 +201,9 @@ func TestAttributeAddFilters(t *testing.T) { ID: "FLTR_ATTR_3", Rules: []*FilterRule{ { - Type: utils.MetaPrefix, - FieldName: "~*req.Attribute", - Values: []string{"AttributeProfilePrefix"}, + Type: utils.MetaPrefix, + Element: "~*req.Attribute", + Values: []string{"AttributeProfilePrefix"}, }, }, } @@ -213,9 +213,9 @@ func TestAttributeAddFilters(t *testing.T) { ID: "FLTR_ATTR_4", Rules: []*FilterRule{ { - Type: utils.MetaGreaterOrEqual, - FieldName: "~*req." + utils.Weight, - Values: []string{"200.00"}, + Type: utils.MetaGreaterOrEqual, + Element: "~*req." + utils.Weight, + Values: []string{"200.00"}, }, }, } @@ -406,8 +406,8 @@ func TestAttributeIndexer(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Account, - Value: config.NewRSRParsersMustCompile("1010", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Account, + Value: config.NewRSRParsersMustCompile("1010", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -474,8 +474,8 @@ func TestAttributeProcessWithMultipleRuns1(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field1", - Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field1", + Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, Weight: 10, @@ -490,8 +490,8 @@ func TestAttributeProcessWithMultipleRuns1(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -506,8 +506,8 @@ func TestAttributeProcessWithMultipleRuns1(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field3", - Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field3", + Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), }, }, Weight: 30, @@ -586,8 +586,8 @@ func TestAttributeProcessWithMultipleRuns2(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field1", - Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field1", + Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, Weight: 10, @@ -602,8 +602,8 @@ func TestAttributeProcessWithMultipleRuns2(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -618,8 +618,8 @@ func TestAttributeProcessWithMultipleRuns2(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field3", - Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field3", + Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), }, }, Weight: 30, @@ -694,8 +694,8 @@ func TestAttributeProcessWithMultipleRuns3(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field1", - Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field1", + Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, Weight: 10, @@ -710,8 +710,8 @@ func TestAttributeProcessWithMultipleRuns3(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -726,8 +726,8 @@ func TestAttributeProcessWithMultipleRuns3(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field3", - Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field3", + Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), }, }, Weight: 30, @@ -802,8 +802,8 @@ func TestAttributeProcessWithMultipleRuns4(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field1", - Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field1", + Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, Weight: 10, @@ -818,8 +818,8 @@ func TestAttributeProcessWithMultipleRuns4(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -893,8 +893,8 @@ func TestAttributeMultipleProcessWithBlocker(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field1", - Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field1", + Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, Weight: 10, @@ -909,8 +909,8 @@ func TestAttributeMultipleProcessWithBlocker(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -926,8 +926,8 @@ func TestAttributeMultipleProcessWithBlocker(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field3", - Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field3", + Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), }, }, Weight: 30, @@ -1003,8 +1003,8 @@ func TestAttributeMultipleProcessWithBlocker2(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field1", - Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field1", + Value: config.NewRSRParsersMustCompile("Value1", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -1020,8 +1020,8 @@ func TestAttributeMultipleProcessWithBlocker2(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Value: config.NewRSRParsersMustCompile("Value2", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -1036,8 +1036,8 @@ func TestAttributeMultipleProcessWithBlocker2(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field3", - Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field3", + Value: config.NewRSRParsersMustCompile("Value3", true, utils.INFIELD_SEP), }, }, Weight: 30, @@ -1111,8 +1111,8 @@ func TestAttributeProcessValue(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Value: config.NewRSRParsersMustCompile("~*req.Field1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Value: config.NewRSRParsersMustCompile("~*req.Field1", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -1181,17 +1181,17 @@ func TestAttributeAttributeFilterIDs(t *testing.T) { Attributes: []*Attribute{ { FilterIDs: []string{"*string:~*req.PassField:Test"}, - FieldName: utils.MetaReq + utils.NestingSep + "PassField", + Path: utils.MetaReq + utils.NestingSep + "PassField", Value: config.NewRSRParsersMustCompile("Pass", true, utils.INFIELD_SEP), }, { FilterIDs: []string{"*string:~*req.PassField:RandomValue"}, - FieldName: utils.MetaReq + utils.NestingSep + "NotPassField", + Path: utils.MetaReq + utils.NestingSep + "NotPassField", Value: config.NewRSRParsersMustCompile("NotPass", true, utils.INFIELD_SEP), }, { FilterIDs: []string{"*notexists:~*req.RandomField:"}, - FieldName: utils.MetaReq + utils.NestingSep + "RandomField", + Path: utils.MetaReq + utils.NestingSep + "RandomField", Value: config.NewRSRParsersMustCompile("RandomValue", true, utils.INFIELD_SEP), }, }, @@ -1261,9 +1261,9 @@ func TestAttributeProcessEventConstant(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Type: utils.META_CONSTANT, - Value: config.NewRSRParsersMustCompile("ConstVal", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Type: utils.META_CONSTANT, + Value: config.NewRSRParsersMustCompile("ConstVal", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -1332,14 +1332,14 @@ func TestAttributeProcessEventVariable(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.Field1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("~*req.Field1", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.TheField", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("~*req.TheField", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -1410,19 +1410,19 @@ func TestAttributeProcessEventComposed(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Type: utils.META_COMPOSED, - Value: config.NewRSRParsersMustCompile("~*req.Field1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Type: utils.META_COMPOSED, + Value: config.NewRSRParsersMustCompile("~*req.Field1", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Type: utils.META_COMPOSED, - Value: config.NewRSRParsersMustCompile("_", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Type: utils.META_COMPOSED, + Value: config.NewRSRParsersMustCompile("_", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Type: utils.META_COMPOSED, - Value: config.NewRSRParsersMustCompile("~*req.TheField", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Type: utils.META_COMPOSED, + Value: config.NewRSRParsersMustCompile("~*req.TheField", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -1493,9 +1493,9 @@ func TestAttributeProcessEventSum(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Type: utils.MetaSum, - Value: config.NewRSRParsersMustCompile("10;~*req.NumField;20", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Type: utils.MetaSum, + Value: config.NewRSRParsersMustCompile("10;~*req.NumField;20", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -1568,9 +1568,9 @@ func TestAttributeProcessEventUsageDifference(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Type: utils.META_USAGE_DIFFERENCE, - Value: config.NewRSRParsersMustCompile("~*req.UnixTimeStamp;~*req.UnixTimeStamp2", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Type: utils.META_USAGE_DIFFERENCE, + Value: config.NewRSRParsersMustCompile("~*req.UnixTimeStamp;~*req.UnixTimeStamp2", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -1645,9 +1645,9 @@ func TestAttributeProcessEventValueExponent(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Type: utils.MetaValueExponent, - Value: config.NewRSRParsersMustCompile("~*req.Multiplier;~*req.Pow", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Type: utils.MetaValueExponent, + Value: config.NewRSRParsersMustCompile("~*req.Multiplier;~*req.Pow", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -1730,9 +1730,9 @@ func BenchmarkAttributeProcessEventConstant(b *testing.B) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Type: utils.META_CONSTANT, - Value: config.NewRSRParsersMustCompile("ConstVal", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Type: utils.META_CONSTANT, + Value: config.NewRSRParsersMustCompile("ConstVal", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -1791,9 +1791,9 @@ func BenchmarkAttributeProcessEventVariable(b *testing.B) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("~*req.Field1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("~*req.Field1", true, utils.INFIELD_SEP), }, }, Blocker: true, @@ -1840,9 +1840,9 @@ func TestGetAttributeProfileFromInline(t *testing.T) { ID: attrID, Contexts: []string{utils.META_ANY}, Attributes: []*Attribute{&Attribute{ - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Type: utils.MetaSum, - Value: config.NewRSRParsersMustCompile("10;~*req.NumField;20", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Type: utils.MetaSum, + Value: config.NewRSRParsersMustCompile("10;~*req.NumField;20", true, utils.INFIELD_SEP), }}, } attr, err := dm.GetAttributeProfile(config.CgrConfig().GeneralCfg().DefaultTenant, attrID, false, false, "") diff --git a/engine/chargers_test.go b/engine/chargers_test.go index 2056a327b..9a612cd11 100755 --- a/engine/chargers_test.go +++ b/engine/chargers_test.go @@ -117,14 +117,14 @@ func TestChargerAddFilter(t *testing.T) { ID: "FLTR_CP_1", Rules: []*FilterRule{ { - Type: utils.MetaString, - FieldName: "~*req.Charger", - Values: []string{"ChargerProfile1"}, + Type: utils.MetaString, + Element: "~*req.Charger", + Values: []string{"ChargerProfile1"}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: "~*req.UsageInterval", - Values: []string{(1 * time.Second).String()}, + Type: utils.MetaGreaterOrEqual, + Element: "~*req.UsageInterval", + Values: []string{(1 * time.Second).String()}, }, }, } @@ -134,9 +134,9 @@ func TestChargerAddFilter(t *testing.T) { ID: "FLTR_CP_2", Rules: []*FilterRule{ { - Type: utils.MetaString, - FieldName: "~*req.Charger", - Values: []string{"ChargerProfile2"}, + Type: utils.MetaString, + Element: "~*req.Charger", + Values: []string{"ChargerProfile2"}, }, }, } @@ -146,9 +146,9 @@ func TestChargerAddFilter(t *testing.T) { ID: "FLTR_CP_3", Rules: []*FilterRule{ { - Type: utils.MetaPrefix, - FieldName: "~*req.harger", - Values: []string{"Charger"}, + Type: utils.MetaPrefix, + Element: "~*req.harger", + Values: []string{"Charger"}, }, }, } @@ -158,9 +158,9 @@ func TestChargerAddFilter(t *testing.T) { ID: "FLTR_CP_4", Rules: []*FilterRule{ { - Type: utils.MetaGreaterOrEqual, - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, - Values: []string{"200.00"}, + Type: utils.MetaGreaterOrEqual, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, + Values: []string{"200.00"}, }, }, } diff --git a/engine/filterindexer.go b/engine/filterindexer.go index 963e4c3c2..c5d7a960f 100644 --- a/engine/filterindexer.go +++ b/engine/filterindexer.go @@ -49,7 +49,7 @@ func (rfi *FilterIndexer) IndexTPFilter(tpFltr *utils.TPFilterProfile, itemID st switch fltr.Type { case utils.MetaString: for _, fldVal := range fltr.Values { - concatKey := utils.ConcatenatedKey(fltr.Type, fltr.FieldName, fldVal) + concatKey := utils.ConcatenatedKey(fltr.Type, fltr.Element, fldVal) if _, hasIt := rfi.indexes[concatKey]; !hasIt { rfi.indexes[concatKey] = make(utils.StringMap) } @@ -58,7 +58,7 @@ func (rfi *FilterIndexer) IndexTPFilter(tpFltr *utils.TPFilterProfile, itemID st } case utils.MetaPrefix: for _, fldVal := range fltr.Values { - concatKey := utils.ConcatenatedKey(fltr.Type, fltr.FieldName, fldVal) + concatKey := utils.ConcatenatedKey(fltr.Type, fltr.Element, fldVal) if _, hasIt := rfi.indexes[concatKey]; !hasIt { rfi.indexes[concatKey] = make(utils.StringMap) } @@ -232,9 +232,9 @@ func (rfi *FilterIndexer) RemoveItemFromIndex(tenant, itemID string, oldFilters ID: itemID, Rules: []*FilterRule{ { - Type: utils.META_NONE, - FieldName: utils.META_ANY, - Values: []string{utils.META_ANY}, + Type: utils.META_NONE, + Element: utils.META_ANY, + Values: []string{utils.META_ANY}, }, }, } @@ -250,7 +250,7 @@ func (rfi *FilterIndexer) RemoveItemFromIndex(tenant, itemID string, oldFilters var fldType, fldName string var fldVals []string if utils.SliceHasMember([]string{utils.META_NONE, utils.MetaPrefix, utils.MetaString}, flt.Type) { - fldType, fldName = flt.Type, flt.FieldName + fldType, fldName = flt.Type, flt.Element fldVals = flt.Values } for _, fldVal := range fldVals { @@ -293,9 +293,9 @@ func createAndIndex(itemPrefix, tenant, context, itemID string, filterIDs []stri ID: itemID, Rules: []*FilterRule{ { - Type: utils.META_NONE, - FieldName: utils.META_ANY, - Values: []string{utils.META_ANY}, + Type: utils.META_NONE, + Element: utils.META_ANY, + Values: []string{utils.META_ANY}, }, }, } @@ -311,7 +311,7 @@ func createAndIndex(itemPrefix, tenant, context, itemID string, filterIDs []stri var fldType, fldName string var fldVals []string if utils.SliceHasMember([]string{utils.META_NONE, utils.MetaPrefix, utils.MetaString}, flt.Type) { - fldType, fldName = flt.Type, flt.FieldName + fldType, fldName = flt.Type, flt.Element fldVals = flt.Values } for _, fldVal := range fldVals { diff --git a/engine/filterindexer_it_test.go b/engine/filterindexer_it_test.go index b732807e6..21ded98f6 100644 --- a/engine/filterindexer_it_test.go +++ b/engine/filterindexer_it_test.go @@ -225,9 +225,9 @@ func testITTestThresholdFilterIndexes(t *testing.T) { ID: "Filter1", Rules: []*FilterRule{ { - FieldName: "EventType", - Type: "*string", - Values: []string{"Event1", "Event2"}, + Element: "EventType", + Type: utils.MetaString, + Values: []string{"Event1", "Event2"}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -292,9 +292,9 @@ func testITTestThresholdFilterIndexes(t *testing.T) { ID: "Filter2", Rules: []*FilterRule{ { - FieldName: "Account", - Type: "*string", - Values: []string{"1001", "1002"}, + Element: "Account", + Type: utils.MetaString, + Values: []string{"1001", "1002"}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -339,9 +339,9 @@ func testITTestThresholdFilterIndexes(t *testing.T) { ID: "Filter3", Rules: []*FilterRule{ { - FieldName: "Destination", - Type: "*string", - Values: []string{"10", "20"}, + Element: "Destination", + Type: utils.MetaString, + Values: []string{"10", "20"}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -405,9 +405,9 @@ func testITTestAttributeProfileFilterIndexes(t *testing.T) { ID: "AttrFilter", Rules: []*FilterRule{ { - FieldName: "EventType", - Type: "*string", - Values: []string{"Event1", "Event2"}, + Element: "EventType", + Type: utils.MetaString, + Values: []string{"Event1", "Event2"}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -428,8 +428,8 @@ func testITTestAttributeProfileFilterIndexes(t *testing.T) { Contexts: []string{"con1", "con2"}, Attributes: []*Attribute{ { - FieldName: "FN1", - Value: config.NewRSRParsersMustCompile("Val1", true, utils.INFIELD_SEP), + Path: "FN1", + Value: config.NewRSRParsersMustCompile("Val1", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -505,9 +505,9 @@ func testITTestThresholdInlineFilterIndexing(t *testing.T) { ID: "Filter1", Rules: []*FilterRule{ { - FieldName: "EventType", - Type: "*string", - Values: []string{"Event1", "Event2"}, + Element: "EventType", + Type: utils.MetaString, + Values: []string{"Event1", "Event2"}, }, }, ActivationInterval: &utils.ActivationInterval{ diff --git a/engine/filters.go b/engine/filters.go index 784fba526..ff2fd760b 100644 --- a/engine/filters.go +++ b/engine/filters.go @@ -25,6 +25,7 @@ import ( "github.com/cgrates/cgrates/utils" ) +// NewFilterS initializtes the filter service func NewFilterS(cfg *config.CGRConfig, connMgr *ConnManager, dm *DataManager) (fS *FilterS) { fS = &FilterS{ dm: dm, @@ -67,7 +68,7 @@ func (fS *FilterS) Pass(tenant string, filterIDs []string, continue } for _, fltr := range f.Rules { - fieldNameDP, err = fS.getFieldNameDataProvider(ev, fltr.FieldName, tenant) + fieldNameDP, err = fS.getFieldNameDataProvider(ev, fltr.Element, tenant) if err != nil { return pass, err } @@ -94,9 +95,9 @@ func NewFilterFromInline(tenant, inlnRule string) (f *Filter, err error) { Tenant: tenant, ID: inlnRule, Rules: []*FilterRule{{ - Type: ruleSplt[0], - FieldName: ruleSplt[1], - Values: strings.Split(strings.Join(ruleSplt[2:], utils.InInFieldSep), utils.INFIELD_SEP), + Type: ruleSplt[0], + Element: ruleSplt[1], + Values: strings.Split(strings.Join(ruleSplt[2:], utils.InInFieldSep), utils.INFIELD_SEP), }}, } if err = f.Compile(); err != nil { @@ -105,6 +106,7 @@ func NewFilterFromInline(tenant, inlnRule string) (f *Filter, err error) { return } +// Filter structure to define a basic filter type Filter struct { Tenant string ID string @@ -112,13 +114,14 @@ type Filter struct { ActivationInterval *utils.ActivationInterval } -func (flt *Filter) TenantID() string { - return utils.ConcatenatedKey(flt.Tenant, flt.ID) +// TenantID returns the tenant wit the ID +func (fltr *Filter) TenantID() string { + return utils.ConcatenatedKey(fltr.Tenant, fltr.ID) } // Compile will compile the underlaying request filters where necessary (ie. regexp rules) -func (f *Filter) Compile() (err error) { - for _, rf := range f.Rules { +func (fltr *Filter) Compile() (err error) { + for _, rf := range fltr.Rules { if err = rf.CompileValues(); err != nil { return } @@ -140,6 +143,7 @@ var needsValues *utils.StringSet = utils.NewStringSet([]string{utils.MetaString, utils.MetaLessThan, utils.MetaLessOrEqual, utils.MetaGreaterThan, utils.MetaGreaterOrEqual, utils.MetaEqual, utils.MetaNotEqual}) +// NewFilterRule returns a new filter func NewFilterRule(rfType, fieldName string, vals []string) (*FilterRule, error) { var negative bool rType := rfType @@ -151,16 +155,16 @@ func NewFilterRule(rfType, fieldName string, vals []string) (*FilterRule, error) return nil, fmt.Errorf("Unsupported filter Type: %s", rfType) } if fieldName == "" && needsFieldName.Has(rType) { - return nil, fmt.Errorf("FieldName is mandatory for Type: %s", rfType) + return nil, fmt.Errorf("Element is mandatory for Type: %s", rfType) } if len(vals) == 0 && needsValues.Has(rType) { return nil, fmt.Errorf("Values is mandatory for Type: %s", rfType) } rf := &FilterRule{ - Type: rfType, - FieldName: fieldName, - Values: vals, - negative: utils.BoolPointer(negative), + Type: rfType, + Element: fieldName, + Values: vals, + negative: utils.BoolPointer(negative), } if err := rf.CompileValues(); err != nil { return nil, err @@ -172,17 +176,17 @@ func NewFilterRule(rfType, fieldName string, vals []string) (*FilterRule, error) // Pass rule: default negative, one mathing rule should pass the filter type FilterRule struct { Type string // Filter type (*string, *timing, *rsr_filters, *stats, *lt, *lte, *gt, *gte) - FieldName string // Name of the field providing us the Values to check (used in case of some ) + Element string // Name of the field providing us the Values to check (used in case of some ) Values []string // Filter definition rsrFields config.RSRParsers // Cache here the RSRFilter Values negative *bool } -// Separate method to compile RSR fields -func (rf *FilterRule) CompileValues() (err error) { - switch rf.Type { +// CompileValues compiles RSR fields +func (fltr *FilterRule) CompileValues() (err error) { + switch fltr.Type { case utils.MetaRSR, utils.MetaNotRSR: - if rf.rsrFields, err = config.NewRSRParsersFromSlice(rf.Values, true); err != nil { + if fltr.rsrFields, err = config.NewRSRParsersFromSlice(fltr.Values, true); err != nil { return } } @@ -227,7 +231,7 @@ func (fltr *FilterRule) Pass(fieldNameDP config.DataProvider, } func (fltr *FilterRule) passString(fielNameDP config.DataProvider, fieldValuesDP []config.DataProvider) (bool, error) { - strVal, err := config.DPDynamicString(fltr.FieldName, fielNameDP) + strVal, err := config.DPDynamicString(fltr.Element, fielNameDP) if err != nil { if err == utils.ErrNotFound { return false, nil @@ -247,7 +251,7 @@ func (fltr *FilterRule) passString(fielNameDP config.DataProvider, fieldValuesDP } func (fltr *FilterRule) passExists(fielNameDP config.DataProvider) (bool, error) { - _, err := config.DPDynamicInterface(fltr.FieldName, fielNameDP) + _, err := config.DPDynamicInterface(fltr.Element, fielNameDP) if err != nil { if err == utils.ErrNotFound { return false, nil @@ -258,7 +262,7 @@ func (fltr *FilterRule) passExists(fielNameDP config.DataProvider) (bool, error) } func (fltr *FilterRule) passEmpty(fielNameDP config.DataProvider) (bool, error) { - val, err := config.DPDynamicInterface(fltr.FieldName, fielNameDP) + val, err := config.DPDynamicInterface(fltr.Element, fielNameDP) if err != nil { if err == utils.ErrNotFound { return true, nil @@ -288,7 +292,7 @@ func (fltr *FilterRule) passEmpty(fielNameDP config.DataProvider) (bool, error) } func (fltr *FilterRule) passStringPrefix(fielNameDP config.DataProvider, fieldValuesDP []config.DataProvider) (bool, error) { - strVal, err := config.DPDynamicString(fltr.FieldName, fielNameDP) + strVal, err := config.DPDynamicString(fltr.Element, fielNameDP) if err != nil { if err == utils.ErrNotFound { return false, nil @@ -308,7 +312,7 @@ func (fltr *FilterRule) passStringPrefix(fielNameDP config.DataProvider, fieldVa } func (fltr *FilterRule) passStringSuffix(fielNameDP config.DataProvider, fieldValuesDP []config.DataProvider) (bool, error) { - strVal, err := config.DPDynamicString(fltr.FieldName, fielNameDP) + strVal, err := config.DPDynamicString(fltr.Element, fielNameDP) if err != nil { if err == utils.ErrNotFound { return false, nil @@ -333,7 +337,7 @@ func (fltr *FilterRule) passTimings(fielNameDP config.DataProvider, fieldValuesD } func (fltr *FilterRule) passDestinations(fielNameDP config.DataProvider, fieldValuesDP []config.DataProvider) (bool, error) { - dst, err := config.DPDynamicString(fltr.FieldName, fielNameDP) + dst, err := config.DPDynamicString(fltr.Element, fielNameDP) if err != nil { if err == utils.ErrNotFound { return false, nil @@ -370,7 +374,7 @@ func (fltr *FilterRule) passRSR(fieldValuesDP []config.DataProvider) (bool, erro } func (fltr *FilterRule) passGreaterThan(fielNameDP config.DataProvider, fieldValuesDP []config.DataProvider) (bool, error) { - fldIf, err := config.DPDynamicInterface(fltr.FieldName, fielNameDP) + fldIf, err := config.DPDynamicInterface(fltr.Element, fielNameDP) if err != nil { if err == utils.ErrNotFound { return false, nil @@ -402,7 +406,7 @@ func (fltr *FilterRule) passGreaterThan(fielNameDP config.DataProvider, fieldVal } func (fltr *FilterRule) passEqualTo(fielNameDP config.DataProvider, fieldValuesDP []config.DataProvider) (bool, error) { - fldIf, err := config.DPDynamicInterface(fltr.FieldName, fielNameDP) + fldIf, err := config.DPDynamicInterface(fltr.Element, fielNameDP) if err != nil { if err == utils.ErrNotFound { return false, nil diff --git a/engine/filters_test.go b/engine/filters_test.go index f8f1c0975..806a30393 100644 --- a/engine/filters_test.go +++ b/engine/filters_test.go @@ -35,14 +35,14 @@ func TestFilterPassString(t *testing.T) { ExtraFields: map[string]string{"navigation": "off"}, } rf := &FilterRule{Type: utils.MetaString, - FieldName: "~Category", Values: []string{"call"}} + Element: "~Category", Values: []string{"call"}} if passes, err := rf.passString(cd, []config.DataProvider{cd}); err != nil { t.Error(err) } else if !passes { t.Error("Not passes filter") } rf = &FilterRule{Type: utils.MetaString, - FieldName: "~Category", Values: []string{"cal"}} + Element: "~Category", Values: []string{"cal"}} if passes, err := rf.passString(cd, []config.DataProvider{cd}); err != nil { t.Error(err) } else if passes { @@ -50,14 +50,14 @@ func TestFilterPassString(t *testing.T) { } //not rf = &FilterRule{Type: utils.MetaNotString, - FieldName: "~Category", Values: []string{"call"}} + Element: "~Category", Values: []string{"call"}} if passes, err := rf.Pass(cd, []config.DataProvider{cd}); err != nil { t.Error(err) } else if passes { t.Error("Filter passes") } rf = &FilterRule{Type: utils.MetaNotString, - FieldName: "~Category", Values: []string{"cal"}} + Element: "~Category", Values: []string{"cal"}} if passes, err := rf.Pass(cd, []config.DataProvider{cd}); err != nil { t.Error(err) } else if !passes { @@ -76,27 +76,27 @@ func TestFilterPassEmpty(t *testing.T) { DurationIndex: 132 * time.Second, ExtraFields: map[string]string{"navigation": "off"}, } - rf := &FilterRule{Type: utils.MetaEmpty, FieldName: "~Category", Values: []string{}} + rf := &FilterRule{Type: utils.MetaEmpty, Element: "~Category", Values: []string{}} if passes, err := rf.passEmpty(cd); err != nil { t.Error(err) } else if !passes { t.Error("Not passes filter") } - rf = &FilterRule{Type: utils.MetaEmpty, FieldName: "~ExtraFields", Values: []string{}} + rf = &FilterRule{Type: utils.MetaEmpty, Element: "~ExtraFields", Values: []string{}} if passes, err := rf.passEmpty(cd); err != nil { t.Error(err) } else if passes { t.Error("Filter passes") } cd.ExtraFields = map[string]string{} - rf = &FilterRule{Type: utils.MetaEmpty, FieldName: "~ExtraFields", Values: []string{}} + rf = &FilterRule{Type: utils.MetaEmpty, Element: "~ExtraFields", Values: []string{}} if passes, err := rf.passEmpty(cd); err != nil { t.Error(err) } else if !passes { t.Error("Not passes filter") } //not - rf = &FilterRule{Type: utils.MetaNotEmpty, FieldName: "~Category", Values: []string{}} + rf = &FilterRule{Type: utils.MetaNotEmpty, Element: "~Category", Values: []string{}} if passes, err := rf.Pass(cd, []config.DataProvider{}); err != nil { t.Error(err) } else if passes { @@ -115,27 +115,27 @@ func TestFilterPassExists(t *testing.T) { DurationIndex: 132 * time.Second, ExtraFields: map[string]string{"navigation": "off"}, } - rf := &FilterRule{Type: utils.MetaExists, FieldName: "~Category", Values: []string{}} + rf := &FilterRule{Type: utils.MetaExists, Element: "~Category", Values: []string{}} if passes, err := rf.passExists(cd); err != nil { t.Error(err) } else if !passes { t.Error("Not passes filter") } - rf = &FilterRule{Type: utils.MetaExists, FieldName: "~ExtraFields1", Values: []string{}} + rf = &FilterRule{Type: utils.MetaExists, Element: "~ExtraFields1", Values: []string{}} if passes, err := rf.passExists(cd); err != nil { t.Error(err) } else if passes { t.Error("Filter passes") } cd.ExtraFields = map[string]string{} - rf = &FilterRule{Type: utils.MetaExists, FieldName: "~ExtraFields", Values: []string{}} + rf = &FilterRule{Type: utils.MetaExists, Element: "~ExtraFields", Values: []string{}} if passes, err := rf.passExists(cd); err != nil { t.Error(err) } else if !passes { t.Error("Not passes filter") } //not - rf = &FilterRule{Type: utils.MetaNotExists, FieldName: "~Category1", Values: []string{}} + rf = &FilterRule{Type: utils.MetaNotExists, Element: "~Category1", Values: []string{}} if passes, err := rf.Pass(cd, []config.DataProvider{}); err != nil { t.Error(err) } else if !passes { @@ -154,44 +154,44 @@ func TestFilterPassStringPrefix(t *testing.T) { DurationIndex: 132 * time.Second, ExtraFields: map[string]string{"navigation": "off"}, } - rf := &FilterRule{Type: utils.MetaPrefix, FieldName: "~Category", Values: []string{"call"}} + rf := &FilterRule{Type: utils.MetaPrefix, Element: "~Category", Values: []string{"call"}} if passes, err := rf.passStringPrefix(cd, []config.DataProvider{cd}); err != nil { t.Error(err) } else if !passes { t.Error("Not passes filter") } - rf = &FilterRule{Type: utils.MetaPrefix, FieldName: "~Category", Values: []string{"premium"}} + rf = &FilterRule{Type: utils.MetaPrefix, Element: "~Category", Values: []string{"premium"}} if passes, err := rf.passStringPrefix(cd, []config.DataProvider{cd}); err != nil { t.Error(err) } else if passes { t.Error("Passes filter") } - rf = &FilterRule{Type: utils.MetaPrefix, FieldName: "~Destination", Values: []string{"+49"}} + rf = &FilterRule{Type: utils.MetaPrefix, Element: "~Destination", Values: []string{"+49"}} if passes, err := rf.passStringPrefix(cd, []config.DataProvider{cd}); err != nil { t.Error(err) } else if !passes { t.Error("Not passes filter") } - rf = &FilterRule{Type: utils.MetaPrefix, FieldName: "~Destination", Values: []string{"+499"}} + rf = &FilterRule{Type: utils.MetaPrefix, Element: "~Destination", Values: []string{"+499"}} if passes, err := rf.passStringPrefix(cd, []config.DataProvider{cd}); err != nil { t.Error(err) } else if passes { t.Error("Passes filter") } - rf = &FilterRule{Type: utils.MetaPrefix, FieldName: "~navigation", Values: []string{"off"}} + rf = &FilterRule{Type: utils.MetaPrefix, Element: "~navigation", Values: []string{"off"}} if passes, err := rf.passStringPrefix(cd, []config.DataProvider{cd}); err != nil { t.Error(err) } else if !passes { t.Error("Not passes filter") } - rf = &FilterRule{Type: utils.MetaPrefix, FieldName: "~nonexisting", Values: []string{"off"}} + rf = &FilterRule{Type: utils.MetaPrefix, Element: "~nonexisting", Values: []string{"off"}} if passing, err := rf.passStringPrefix(cd, []config.DataProvider{cd}); err != nil { t.Error(err) } else if passing { t.Error("Passes filter") } //not - rf = &FilterRule{Type: utils.MetaNotPrefix, FieldName: "~Category", Values: []string{"premium"}} + rf = &FilterRule{Type: utils.MetaNotPrefix, Element: "~Category", Values: []string{"premium"}} if passes, err := rf.Pass(cd, []config.DataProvider{cd}); err != nil { t.Error(err) } else if !passes { @@ -210,44 +210,44 @@ func TestFilterPassStringSuffix(t *testing.T) { DurationIndex: 132 * time.Second, ExtraFields: map[string]string{"navigation": "off"}, } - rf := &FilterRule{Type: utils.MetaSuffix, FieldName: "~Category", Values: []string{"call"}} + rf := &FilterRule{Type: utils.MetaSuffix, Element: "~Category", Values: []string{"call"}} if passes, err := rf.passStringSuffix(cd, []config.DataProvider{cd}); err != nil { t.Error(err) } else if !passes { t.Error("Not passes filter") } - rf = &FilterRule{Type: utils.MetaSuffix, FieldName: "~Category", Values: []string{"premium"}} + rf = &FilterRule{Type: utils.MetaSuffix, Element: "~Category", Values: []string{"premium"}} if passes, err := rf.passStringSuffix(cd, []config.DataProvider{cd}); err != nil { t.Error(err) } else if passes { t.Error("Passes filter") } - rf = &FilterRule{Type: utils.MetaSuffix, FieldName: "~Destination", Values: []string{"963"}} + rf = &FilterRule{Type: utils.MetaSuffix, Element: "~Destination", Values: []string{"963"}} if passes, err := rf.passStringSuffix(cd, []config.DataProvider{cd}); err != nil { t.Error(err) } else if !passes { t.Error("Not passes filter") } - rf = &FilterRule{Type: utils.MetaSuffix, FieldName: "~Destination", Values: []string{"4966"}} + rf = &FilterRule{Type: utils.MetaSuffix, Element: "~Destination", Values: []string{"4966"}} if passes, err := rf.passStringSuffix(cd, []config.DataProvider{cd}); err != nil { t.Error(err) } else if passes { t.Error("Passes filter") } - rf = &FilterRule{Type: utils.MetaSuffix, FieldName: "~navigation", Values: []string{"off"}} + rf = &FilterRule{Type: utils.MetaSuffix, Element: "~navigation", Values: []string{"off"}} if passes, err := rf.passStringSuffix(cd, []config.DataProvider{cd}); err != nil { t.Error(err) } else if !passes { t.Error("Not passes filter") } - rf = &FilterRule{Type: utils.MetaSuffix, FieldName: "~nonexisting", Values: []string{"off"}} + rf = &FilterRule{Type: utils.MetaSuffix, Element: "~nonexisting", Values: []string{"off"}} if passing, err := rf.passStringSuffix(cd, []config.DataProvider{cd}); err != nil { t.Error(err) } else if passing { t.Error("Passes filter") } //not - rf = &FilterRule{Type: utils.MetaNotSuffix, FieldName: "~Destination", Values: []string{"963"}} + rf = &FilterRule{Type: utils.MetaNotSuffix, Element: "~Destination", Values: []string{"963"}} if passes, err := rf.Pass(cd, []config.DataProvider{cd}); err != nil { t.Error(err) } else if passes { @@ -517,7 +517,7 @@ func TestFilterNewRequestFilter(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } - erf := &FilterRule{Type: utils.MetaString, FieldName: "~MetaString", Values: []string{"String"}, negative: utils.BoolPointer(false)} + erf := &FilterRule{Type: utils.MetaString, Element: "~MetaString", Values: []string{"String"}, negative: utils.BoolPointer(false)} if !reflect.DeepEqual(erf, rf) { t.Errorf("Expecting: %+v, received: %+v", erf, rf) } @@ -525,7 +525,7 @@ func TestFilterNewRequestFilter(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } - erf = &FilterRule{Type: utils.MetaEmpty, FieldName: "~MetaEmpty", Values: []string{}, negative: utils.BoolPointer(false)} + erf = &FilterRule{Type: utils.MetaEmpty, Element: "~MetaEmpty", Values: []string{}, negative: utils.BoolPointer(false)} if !reflect.DeepEqual(erf, rf) { t.Errorf("Expecting: %+v, received: %+v", erf, rf) } @@ -533,7 +533,7 @@ func TestFilterNewRequestFilter(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } - erf = &FilterRule{Type: utils.MetaExists, FieldName: "~MetaExists", Values: []string{}, negative: utils.BoolPointer(false)} + erf = &FilterRule{Type: utils.MetaExists, Element: "~MetaExists", Values: []string{}, negative: utils.BoolPointer(false)} if !reflect.DeepEqual(erf, rf) { t.Errorf("Expecting: %+v, received: %+v", erf, rf) } @@ -541,7 +541,7 @@ func TestFilterNewRequestFilter(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } - erf = &FilterRule{Type: utils.MetaPrefix, FieldName: "~MetaPrefix", Values: []string{"stringPrefix"}, negative: utils.BoolPointer(false)} + erf = &FilterRule{Type: utils.MetaPrefix, Element: "~MetaPrefix", Values: []string{"stringPrefix"}, negative: utils.BoolPointer(false)} if !reflect.DeepEqual(erf, rf) { t.Errorf("Expecting: %+v, received: %+v", erf, rf) } @@ -549,7 +549,7 @@ func TestFilterNewRequestFilter(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } - erf = &FilterRule{Type: utils.MetaSuffix, FieldName: "~MetaSuffix", Values: []string{"stringSuffix"}, negative: utils.BoolPointer(false)} + erf = &FilterRule{Type: utils.MetaSuffix, Element: "~MetaSuffix", Values: []string{"stringSuffix"}, negative: utils.BoolPointer(false)} if !reflect.DeepEqual(erf, rf) { t.Errorf("Expecting: %+v, received: %+v", erf, rf) } @@ -557,7 +557,7 @@ func TestFilterNewRequestFilter(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } - erf = &FilterRule{Type: utils.MetaTimings, FieldName: "~MetaTimings", Values: []string{""}, negative: utils.BoolPointer(false)} + erf = &FilterRule{Type: utils.MetaTimings, Element: "~MetaTimings", Values: []string{""}, negative: utils.BoolPointer(false)} if !reflect.DeepEqual(erf, rf) { t.Errorf("Expecting: %+v, received: %+v", erf, rf) } @@ -565,7 +565,7 @@ func TestFilterNewRequestFilter(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } - erf = &FilterRule{Type: utils.MetaDestinations, FieldName: "~MetaDestinations", Values: []string{""}, negative: utils.BoolPointer(false)} + erf = &FilterRule{Type: utils.MetaDestinations, Element: "~MetaDestinations", Values: []string{""}, negative: utils.BoolPointer(false)} if !reflect.DeepEqual(erf, rf) { t.Errorf("Expecting: %+v, received: %+v", erf, rf) } @@ -573,7 +573,7 @@ func TestFilterNewRequestFilter(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } - erf = &FilterRule{Type: utils.MetaLessThan, FieldName: "~MetaLessThan", Values: []string{"20"}, negative: utils.BoolPointer(false)} + erf = &FilterRule{Type: utils.MetaLessThan, Element: "~MetaLessThan", Values: []string{"20"}, negative: utils.BoolPointer(false)} if !reflect.DeepEqual(erf, rf) { t.Errorf("Expecting: %+v, received: %+v", erf, rf) } @@ -581,7 +581,7 @@ func TestFilterNewRequestFilter(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } - erf = &FilterRule{Type: utils.MetaLessOrEqual, FieldName: "~MetaLessOrEqual", Values: []string{"20"}, negative: utils.BoolPointer(false)} + erf = &FilterRule{Type: utils.MetaLessOrEqual, Element: "~MetaLessOrEqual", Values: []string{"20"}, negative: utils.BoolPointer(false)} if !reflect.DeepEqual(erf, rf) { t.Errorf("Expecting: %+v, received: %+v", erf, rf) } @@ -589,7 +589,7 @@ func TestFilterNewRequestFilter(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } - erf = &FilterRule{Type: utils.MetaGreaterThan, FieldName: "~MetaGreaterThan", Values: []string{"20"}, negative: utils.BoolPointer(false)} + erf = &FilterRule{Type: utils.MetaGreaterThan, Element: "~MetaGreaterThan", Values: []string{"20"}, negative: utils.BoolPointer(false)} if !reflect.DeepEqual(erf, rf) { t.Errorf("Expecting: %+v, received: %+v", erf, rf) } @@ -597,7 +597,7 @@ func TestFilterNewRequestFilter(t *testing.T) { if err != nil { t.Errorf("Error: %+v", err) } - erf = &FilterRule{Type: utils.MetaGreaterOrEqual, FieldName: "~MetaGreaterOrEqual", Values: []string{"20"}, negative: utils.BoolPointer(false)} + erf = &FilterRule{Type: utils.MetaGreaterOrEqual, Element: "~MetaGreaterOrEqual", Values: []string{"20"}, negative: utils.BoolPointer(false)} if !reflect.DeepEqual(erf, rf) { t.Errorf("Expecting: %+v, received: %+v", erf, rf) } diff --git a/engine/libattributes.go b/engine/libattributes.go index 3d2a9409c..3587494ac 100644 --- a/engine/libattributes.go +++ b/engine/libattributes.go @@ -27,13 +27,15 @@ import ( "github.com/cgrates/cgrates/utils" ) +// Attribute used by AttributeProfile to describe a single attribute type Attribute struct { FilterIDs []string - FieldName string + Path string Type string Value config.RSRParsers } +// AttributeProfile the profile definition for the attributes type AttributeProfile struct { Tenant string ID string @@ -59,8 +61,9 @@ func (ap *AttributeProfile) Compile() error { return ap.compileSubstitutes() } -func (als *AttributeProfile) TenantID() string { - return utils.ConcatenatedKey(als.Tenant, als.ID) +// TenantID returns the tenant wit the ID +func (ap *AttributeProfile) TenantID() string { + return utils.ConcatenatedKey(ap.Tenant, ap.ID) } // AttributeProfiles is a sortable list of Attribute profiles @@ -71,13 +74,15 @@ func (aps AttributeProfiles) Sort() { sort.Slice(aps, func(i, j int) bool { return aps[i].Weight > aps[j].Weight }) } +// ExternalAttribute the attribute for external profile type ExternalAttribute struct { FilterIDs []string - FieldName string + Path string Type string Value string } +// ExternalAttributeProfile used by APIs type ExternalAttributeProfile struct { Tenant string ID string @@ -89,6 +94,7 @@ type ExternalAttributeProfile struct { Weight float64 } +// AsAttributeProfile converts the external attribute format to the actual AttributeProfile func (ext *ExternalAttributeProfile) AsAttributeProfile() (attr *AttributeProfile, err error) { attr = new(AttributeProfile) if len(ext.Attributes) == 0 { @@ -105,7 +111,7 @@ func (ext *ExternalAttributeProfile) AsAttributeProfile() (attr *AttributeProfil } attr.Attributes[i].Type = extAttr.Type attr.Attributes[i].FilterIDs = extAttr.FilterIDs - attr.Attributes[i].FieldName = extAttr.FieldName + attr.Attributes[i].Path = extAttr.Path } attr.Tenant = ext.Tenant attr.ID = ext.ID @@ -132,9 +138,9 @@ func NewAttributeFromInline(tenant, inlnRule string) (attr *AttributeProfile, er ID: inlnRule, Contexts: []string{utils.META_ANY}, Attributes: []*Attribute{&Attribute{ - FieldName: ruleSplt[1], - Type: ruleSplt[0], - Value: vals, + Path: ruleSplt[1], + Type: ruleSplt[0], + Value: vals, }}, } if err = attr.Compile(); err != nil { diff --git a/engine/libattributes_test.go b/engine/libattributes_test.go index f4c0a012f..a50befebf 100644 --- a/engine/libattributes_test.go +++ b/engine/libattributes_test.go @@ -39,8 +39,8 @@ func TestConvertExternalToProfile(t *testing.T) { }, Attributes: []*ExternalAttribute{ &ExternalAttribute{ - FieldName: utils.MetaReq + utils.NestingSep + "Account", - Value: "1001", + Path: utils.MetaReq + utils.NestingSep + "Account", + Value: "1001", }, }, Weight: 20, @@ -57,8 +57,8 @@ func TestConvertExternalToProfile(t *testing.T) { }, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Account", - Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Account", + Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -108,7 +108,7 @@ func TestConvertExternalToProfileMissing2(t *testing.T) { }, Attributes: []*ExternalAttribute{ &ExternalAttribute{ - FieldName: utils.MetaReq + utils.NestingSep + "Account", + Path: utils.MetaReq + utils.NestingSep + "Account", }, }, Weight: 20, @@ -128,9 +128,9 @@ func TestNewAttributeFromInline(t *testing.T) { ID: attrID, Contexts: []string{utils.META_ANY}, Attributes: []*Attribute{&Attribute{ - FieldName: utils.MetaReq + utils.NestingSep + "Field2", - Type: utils.MetaSum, - Value: config.NewRSRParsersMustCompile("10;~*req.NumField;20", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Field2", + Type: utils.MetaSum, + Value: config.NewRSRParsersMustCompile("10;~*req.NumField;20", true, utils.INFIELD_SEP), }}, } attr, err := NewAttributeFromInline(config.CgrConfig().GeneralCfg().DefaultTenant, attrID) diff --git a/engine/libtest.go b/engine/libtest.go index e49a0791f..de35b29ee 100644 --- a/engine/libtest.go +++ b/engine/libtest.go @@ -246,7 +246,7 @@ cgrates.org,Threshold1,*string:~*req.Account:1001;*string:~*req.RunID:*default,2 ` FiltersCSVContent = ` -#Tenant[0],ID[1],FilterType[2],FilterFieldName[3],FilterFieldValues[4],ActivationInterval[5] +#Tenant[0],ID[1],Type[2],Element[3],Values[4],ActivationInterval[5] cgrates.org,FLTR_1,*string,~*req.Account,1001;1002,2014-07-29T15:00:00Z cgrates.org,FLTR_1,*prefix,~*req.Destination,10;20,2014-07-29T15:00:00Z cgrates.org,FLTR_1,*rsr,,~*req.Subject(~^1.*1$);~*req.Destination(1002), @@ -262,7 +262,7 @@ cgrates.org,SPP_1,,,,,supplier1,FLTR_DST_DE,Account2,RPL_3,ResGroup3,Stat2,10,,, cgrates.org,SPP_1,,,,,supplier1,,,,ResGroup4,Stat3,10,,, ` AttributesCSVContent = ` -#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,FieldName,Type,Value,Blocker,Weight +#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,Path,Type,Value,Blocker,Weight cgrates.org,ALS1,con1,*string:~*req.Account:1001,2014-07-29T15:00:00Z,*string:~*req.Field1:Initial,*req.Field1,*variable,Sub1,true,20 cgrates.org,ALS1,con2;con3,,,,*req.Field2,*variable,Sub2,true,20 ` diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index ed5e887bc..221fd5ebf 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -1151,19 +1151,19 @@ func TestLoadFilters(t *testing.T) { ID: "FLTR_1", Filters: []*utils.TPFilter{ &utils.TPFilter{ - FieldName: "~*req.Account", - Type: utils.MetaString, - Values: []string{"1001", "1002"}, + Element: "~*req.Account", + Type: utils.MetaString, + Values: []string{"1001", "1002"}, }, &utils.TPFilter{ - FieldName: "~*req.Destination", - Type: utils.MetaPrefix, - Values: []string{"10", "20"}, + Element: "~*req.Destination", + Type: utils.MetaPrefix, + Values: []string{"10", "20"}, }, &utils.TPFilter{ - FieldName: "", - Type: utils.MetaRSR, - Values: []string{"~*req.Subject(~^1.*1$)", "~*req.Destination(1002)"}, + Element: "", + Type: utils.MetaRSR, + Values: []string{"~*req.Subject(~^1.*1$)", "~*req.Destination(1002)"}, }, }, ActivationInterval: &utils.TPActivationInterval{ @@ -1176,9 +1176,9 @@ func TestLoadFilters(t *testing.T) { ID: "FLTR_ACNT_dan", Filters: []*utils.TPFilter{ &utils.TPFilter{ - FieldName: "~*req.Account", - Type: utils.MetaString, - Values: []string{"dan"}, + Element: "~*req.Account", + Type: utils.MetaString, + Values: []string{"dan"}, }, }, ActivationInterval: &utils.TPActivationInterval{ @@ -1191,9 +1191,9 @@ func TestLoadFilters(t *testing.T) { ID: "FLTR_DST_DE", Filters: []*utils.TPFilter{ &utils.TPFilter{ - FieldName: "~*req.Destination", - Type: utils.MetaDestinations, - Values: []string{"DST_DE"}, + Element: "~*req.Destination", + Type: utils.MetaDestinations, + Values: []string{"DST_DE"}, }, }, ActivationInterval: &utils.TPActivationInterval{ @@ -1206,9 +1206,9 @@ func TestLoadFilters(t *testing.T) { ID: "FLTR_DST_NL", Filters: []*utils.TPFilter{ &utils.TPFilter{ - FieldName: "~*req.Destination", - Type: utils.MetaDestinations, - Values: []string{"DST_NL"}, + Element: "~*req.Destination", + Type: utils.MetaDestinations, + Values: []string{"DST_NL"}, }, }, ActivationInterval: &utils.TPActivationInterval{ @@ -1274,13 +1274,13 @@ func TestLoadAttributeProfiles(t *testing.T) { Attributes: []*utils.TPAttribute{ &utils.TPAttribute{ FilterIDs: []string{"*string:~*req.Field1:Initial"}, - FieldName: utils.MetaReq + utils.NestingSep + "Field1", + Path: utils.MetaReq + utils.NestingSep + "Field1", Type: utils.MetaVariable, Value: "Sub1", }, &utils.TPAttribute{ FilterIDs: []string{}, - FieldName: utils.MetaReq + utils.NestingSep + "Field2", + Path: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.MetaVariable, Value: "Sub2", }, diff --git a/engine/model_helpers.go b/engine/model_helpers.go index c7e428e27..6bd3d3f50 100644 --- a/engine/model_helpers.go +++ b/engine/model_helpers.go @@ -1692,11 +1692,11 @@ func (tps TpFilterS) AsTPFilter() (result []*utils.TPFilterProfile) { th.ActivationInterval.ActivationTime = aiSplt[0] } } - if tp.FilterType != "" { + if tp.Type != "" { th.Filters = append(th.Filters, &utils.TPFilter{ - Type: tp.FilterType, - FieldName: tp.FilterFieldName, - Values: strings.Split(tp.FilterFieldValues, utils.INFIELD_SEP)}) + Type: tp.Type, + Element: tp.Element, + Values: strings.Split(tp.Values, utils.INFIELD_SEP)}) } mst[(&utils.TenantID{Tenant: tp.Tenant, ID: tp.ID}).TenantID()] = th } @@ -1719,8 +1719,8 @@ func APItoModelTPFilter(th *utils.TPFilterProfile) (mdls TpFilterS) { Tenant: th.Tenant, ID: th.ID, } - mdl.FilterType = fltr.Type - mdl.FilterFieldName = fltr.FieldName + mdl.Type = fltr.Type + mdl.Element = fltr.Element if th.ActivationInterval != nil { if th.ActivationInterval.ActivationTime != "" { mdl.ActivationInterval = th.ActivationInterval.ActivationTime @@ -1731,9 +1731,9 @@ func APItoModelTPFilter(th *utils.TPFilterProfile) (mdls TpFilterS) { } for i, val := range fltr.Values { if i != 0 { - mdl.FilterFieldValues += utils.INFIELD_SEP + mdl.Values += utils.INFIELD_SEP } - mdl.FilterFieldValues += val + mdl.Values += val } mdls = append(mdls, mdl) } @@ -1747,7 +1747,7 @@ func APItoFilter(tpTH *utils.TPFilterProfile, timezone string) (th *Filter, err Rules: make([]*FilterRule, len(tpTH.Filters)), } for i, f := range tpTH.Filters { - rf := &FilterRule{Type: f.Type, FieldName: f.FieldName, Values: f.Values} + rf := &FilterRule{Type: f.Type, Element: f.Element, Values: f.Values} if err := rf.CompileValues(); err != nil { return nil, err } @@ -1769,9 +1769,9 @@ func FilterToTPFilter(f *Filter) (tpFltr *utils.TPFilterProfile) { } for i, reqFltr := range f.Rules { tpFltr.Filters[i] = &utils.TPFilter{ - Type: reqFltr.Type, - FieldName: reqFltr.FieldName, - Values: make([]string, len(reqFltr.Values)), + Type: reqFltr.Type, + Element: reqFltr.Element, + Values: make([]string, len(reqFltr.Values)), } for j, val := range reqFltr.Values { tpFltr.Filters[i].Values[j] = val @@ -2051,7 +2051,7 @@ func (tps TPAttributes) AsTPAttributes() (result []*utils.TPAttributeProfile) { contextMap[key.TenantID()][context] = true } } - if tp.FieldName != "" { + if tp.Path != "" { filterIDs := make([]string, 0) if tp.AttributeFilterIDs != "" { filterAttrSplit := strings.Split(tp.AttributeFilterIDs, utils.INFIELD_SEP) @@ -2062,7 +2062,7 @@ func (tps TPAttributes) AsTPAttributes() (result []*utils.TPAttributeProfile) { th.Attributes = append(th.Attributes, &utils.TPAttribute{ FilterIDs: filterIDs, Type: tp.Type, - FieldName: tp.FieldName, + Path: tp.Path, Value: tp.Value, }) } @@ -2125,7 +2125,7 @@ func APItoModelTPAttribute(th *utils.TPAttributeProfile) (mdls TPAttributes) { mdl.AttributeFilterIDs += val } } - mdl.FieldName = reqAttribute.FieldName + mdl.Path = reqAttribute.Path mdl.Value = reqAttribute.Value mdl.Type = reqAttribute.Type mdls = append(mdls, mdl) @@ -2156,7 +2156,7 @@ func APItoAttributeProfile(tpAttr *utils.TPAttributeProfile, timezone string) (a } attrPrf.Attributes[i] = &Attribute{ FilterIDs: reqAttr.FilterIDs, - FieldName: reqAttr.FieldName, + Path: reqAttr.Path, Type: reqAttr.Type, Value: sbstPrsr, } diff --git a/engine/model_helpers_test.go b/engine/model_helpers_test.go index 6a5deb3f1..9cc573868 100644 --- a/engine/model_helpers_test.go +++ b/engine/model_helpers_test.go @@ -1050,11 +1050,11 @@ func TestAPItoTPThreshold(t *testing.T) { func TestTPFilterAsTPFilter(t *testing.T) { tps := []*TpFilter{ &TpFilter{ - Tpid: "TEST_TPID", - ID: "Filter1", - FilterType: utils.MetaPrefix, - FilterFieldName: "Account", - FilterFieldValues: "1001;1002", + Tpid: "TEST_TPID", + ID: "Filter1", + Type: utils.MetaPrefix, + Element: "Account", + Values: "1001;1002", }, } eTPs := []*utils.TPFilterProfile{ @@ -1063,9 +1063,9 @@ func TestTPFilterAsTPFilter(t *testing.T) { ID: tps[0].ID, Filters: []*utils.TPFilter{ &utils.TPFilter{ - Type: utils.MetaPrefix, - FieldName: "Account", - Values: []string{"1001", "1002"}, + Type: utils.MetaPrefix, + Element: "Account", + Values: []string{"1001", "1002"}, }, }, }, @@ -1080,20 +1080,20 @@ func TestTPFilterAsTPFilter(t *testing.T) { func TestTPFilterAsTPFilter2(t *testing.T) { tps := []*TpFilter{ &TpFilter{ - Tpid: "TEST_TPID", - Tenant: "cgrates.org", - ID: "Filter1", - FilterType: utils.MetaPrefix, - FilterFieldName: "Account", - FilterFieldValues: "1001;1002", + Tpid: "TEST_TPID", + Tenant: "cgrates.org", + ID: "Filter1", + Type: utils.MetaPrefix, + Element: "Account", + Values: "1001;1002", }, &TpFilter{ - Tpid: "TEST_TPID", - Tenant: "anotherTenant", - ID: "Filter1", - FilterType: utils.MetaPrefix, - FilterFieldName: "Account", - FilterFieldValues: "1010", + Tpid: "TEST_TPID", + Tenant: "anotherTenant", + ID: "Filter1", + Type: utils.MetaPrefix, + Element: "Account", + Values: "1010", }, } eTPs := []*utils.TPFilterProfile{ @@ -1103,9 +1103,9 @@ func TestTPFilterAsTPFilter2(t *testing.T) { ID: tps[0].ID, Filters: []*utils.TPFilter{ &utils.TPFilter{ - Type: utils.MetaPrefix, - FieldName: "Account", - Values: []string{"1001", "1002"}, + Type: utils.MetaPrefix, + Element: "Account", + Values: []string{"1001", "1002"}, }, }, }, @@ -1115,9 +1115,9 @@ func TestTPFilterAsTPFilter2(t *testing.T) { ID: tps[1].ID, Filters: []*utils.TPFilter{ &utils.TPFilter{ - Type: utils.MetaPrefix, - FieldName: "Account", - Values: []string{"1010"}, + Type: utils.MetaPrefix, + Element: "Account", + Values: []string{"1010"}, }, }, }, @@ -1136,9 +1136,9 @@ func TestAPItoTPFilter(t *testing.T) { ID: "Filter1", Filters: []*utils.TPFilter{ &utils.TPFilter{ - FieldName: "Account", - Type: utils.MetaString, - Values: []string{"1001", "1002"}, + Element: "Account", + Type: utils.MetaString, + Values: []string{"1001", "1002"}, }, }, } @@ -1148,9 +1148,9 @@ func TestAPItoTPFilter(t *testing.T) { ID: tps.ID, Rules: []*FilterRule{ &FilterRule{ - FieldName: "Account", - Type: utils.MetaString, - Values: []string{"1001", "1002"}, + Element: "Account", + Type: utils.MetaString, + Values: []string{"1001", "1002"}, }, }, } @@ -1171,9 +1171,9 @@ func TestFilterToTPFilter(t *testing.T) { }, Rules: []*FilterRule{ &FilterRule{ - FieldName: "Account", - Type: utils.MetaString, - Values: []string{"1001", "1002"}, + Element: "Account", + Type: utils.MetaString, + Values: []string{"1001", "1002"}, }, }, } @@ -1186,9 +1186,9 @@ func TestFilterToTPFilter(t *testing.T) { }, Filters: []*utils.TPFilter{ &utils.TPFilter{ - FieldName: "Account", - Type: utils.MetaString, - Values: []string{"1001", "1002"}, + Element: "Account", + Type: utils.MetaString, + Values: []string{"1001", "1002"}, }, }, } @@ -1211,8 +1211,8 @@ func TestAPItoAttributeProfile(t *testing.T) { }, Attributes: []*utils.TPAttribute{ &utils.TPAttribute{ - FieldName: utils.MetaReq + utils.NestingSep + "FL1", - Value: "Al1", + Path: utils.MetaReq + utils.NestingSep + "FL1", + Value: "Al1", }, }, Weight: 20, @@ -1227,8 +1227,8 @@ func TestAPItoAttributeProfile(t *testing.T) { }, Attributes: []*Attribute{ &Attribute{ - FieldName: utils.MetaReq + utils.NestingSep + "FL1", - Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "FL1", + Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -1253,8 +1253,8 @@ func TestAPItoModelTPAttribute(t *testing.T) { }, Attributes: []*utils.TPAttribute{ &utils.TPAttribute{ - FieldName: utils.MetaReq + utils.NestingSep + "FL1", - Value: "Al1", + Path: utils.MetaReq + utils.NestingSep + "FL1", + Value: "Al1", }, }, Weight: 20, @@ -1266,7 +1266,7 @@ func TestAPItoModelTPAttribute(t *testing.T) { ID: "ALS1", Contexts: "con1", FilterIDs: "FLTR_ACNT_dan;FLTR_DST_DE", - FieldName: utils.MetaReq + utils.NestingSep + "FL1", + Path: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", ActivationInterval: "2014-07-14T14:35:00Z", Weight: 20, @@ -1286,7 +1286,7 @@ func TestModelAsTPAttribute(t *testing.T) { ID: "ALS1", Contexts: "con1", FilterIDs: "FLTR_ACNT_dan;FLTR_DST_DE", - FieldName: utils.MetaReq + utils.NestingSep + "FL1", + Path: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", ActivationInterval: "2014-07-14T14:35:00Z", Weight: 20, @@ -1305,7 +1305,7 @@ func TestModelAsTPAttribute(t *testing.T) { Attributes: []*utils.TPAttribute{ &utils.TPAttribute{ FilterIDs: []string{}, - FieldName: utils.MetaReq + utils.NestingSep + "FL1", + Path: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", }, }, @@ -1324,7 +1324,7 @@ func TestModelAsTPAttribute(t *testing.T) { Attributes: []*utils.TPAttribute{ &utils.TPAttribute{ FilterIDs: []string{}, - FieldName: utils.MetaReq + utils.NestingSep + "FL1", + Path: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", }, }, diff --git a/engine/models.go b/engine/models.go index 3cf37f3a5..49befba33 100644 --- a/engine/models.go +++ b/engine/models.go @@ -270,9 +270,9 @@ type TpFilter struct { Tpid string Tenant string `index:"0" re:""` ID string `index:"1" re:""` - FilterType string `index:"2" re:"^\*[A-Za-z].*"` - FilterFieldName string `index:"3" re:""` - FilterFieldValues string `index:"4" re:""` + Type string `index:"2" re:"^\*[A-Za-z].*"` + Element string `index:"3" re:""` + Values string `index:"4" re:""` ActivationInterval string `index:"5" re:""` CreatedAt time.Time } @@ -396,7 +396,7 @@ type TPAttribute struct { FilterIDs string `index:"3" re:""` ActivationInterval string `index:"4" re:""` AttributeFilterIDs string `index:"5" re:""` - FieldName string `index:"6" re:""` + Path string `index:"6" re:""` Type string `index:"7" re:""` Value string `index:"8" re:""` Blocker bool `index:"9" re:""` diff --git a/engine/onstor_it_test.go b/engine/onstor_it_test.go index b39a81292..1b1424afe 100644 --- a/engine/onstor_it_test.go +++ b/engine/onstor_it_test.go @@ -1536,9 +1536,9 @@ func testOnStorITThresholdProfile(t *testing.T) { ID: "TestFilter2", Rules: []*FilterRule{ { - FieldName: "Account", - Type: "*string", - Values: []string{"1001", "1002"}, + Element: "Account", + Type: utils.MetaString, + Values: []string{"1001", "1002"}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -1660,9 +1660,9 @@ func testOnStorITFilter(t *testing.T) { ID: "Filter1", Rules: []*FilterRule{ { - FieldName: "Account", - Type: "*string", - Values: []string{"1001", "1002"}, + Element: "Account", + Type: utils.MetaString, + Values: []string{"1001", "1002"}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -1700,14 +1700,14 @@ func testOnStorITFilter(t *testing.T) { //update fp.Rules = []*FilterRule{ { - FieldName: "Account", - Type: "*string", - Values: []string{"1001", "1002"}, + Element: "Account", + Type: utils.MetaString, + Values: []string{"1001", "1002"}, }, { - FieldName: "Destination", - Type: "*string", - Values: []string{"10", "20"}, + Element: "Destination", + Type: utils.MetaString, + Values: []string{"10", "20"}, }, } if err := onStor.SetFilter(fp); err != nil { @@ -1862,8 +1862,8 @@ func testOnStorITAttributeProfile(t *testing.T) { Contexts: []string{"con1"}, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "FN1", - Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "FN1", + Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -1942,8 +1942,8 @@ func testOnStorITTestAttributeSubstituteIface(t *testing.T) { Contexts: []string{"con1"}, Attributes: []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "FN1", - Value: config.NewRSRParsersMustCompile("Val1", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "FN1", + Value: config.NewRSRParsersMustCompile("Val1", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -1964,8 +1964,8 @@ func testOnStorITTestAttributeSubstituteIface(t *testing.T) { } attrProfile.Attributes = []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "FN1", - Value: config.NewRSRParsersMustCompile("123.123", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "FN1", + Value: config.NewRSRParsersMustCompile("123.123", true, utils.INFIELD_SEP), }, } if err := onStor.SetAttributeProfile(attrProfile, false); err != nil { @@ -1980,8 +1980,8 @@ func testOnStorITTestAttributeSubstituteIface(t *testing.T) { } attrProfile.Attributes = []*Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "FN1", - Value: config.NewRSRParsersMustCompile("true", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "FN1", + Value: config.NewRSRParsersMustCompile("true", true, utils.INFIELD_SEP), }, } if err := onStor.SetAttributeProfile(attrProfile, false); err != nil { diff --git a/engine/resources_test.go b/engine/resources_test.go index f827f3485..a3fc0dd1d 100644 --- a/engine/resources_test.go +++ b/engine/resources_test.go @@ -408,24 +408,24 @@ func TestResourceAddFilters(t *testing.T) { ID: "FLTR_RES_1", Rules: []*FilterRule{ { - Type: utils.MetaString, - FieldName: "~*req.Resources", - Values: []string{"ResourceProfile1"}, + Type: utils.MetaString, + Element: "~*req.Resources", + Values: []string{"ResourceProfile1"}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: "~*req.UsageInterval", - Values: []string{(1 * time.Second).String()}, + Type: utils.MetaGreaterOrEqual, + Element: "~*req.UsageInterval", + Values: []string{(1 * time.Second).String()}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Usage, - Values: []string{(1 * time.Second).String()}, + Type: utils.MetaGreaterOrEqual, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Usage, + Values: []string{(1 * time.Second).String()}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, - Values: []string{"9.0"}, + Type: utils.MetaGreaterOrEqual, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, + Values: []string{"9.0"}, }, }, } @@ -435,24 +435,24 @@ func TestResourceAddFilters(t *testing.T) { ID: "FLTR_RES_2", Rules: []*FilterRule{ { - Type: utils.MetaString, - FieldName: "~*req.Resources", - Values: []string{"ResourceProfile2"}, + Type: utils.MetaString, + Element: "~*req.Resources", + Values: []string{"ResourceProfile2"}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: "~*req.PddInterval", - Values: []string{(1 * time.Second).String()}, + Type: utils.MetaGreaterOrEqual, + Element: "~*req.PddInterval", + Values: []string{(1 * time.Second).String()}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Usage, - Values: []string{(1 * time.Second).String()}, + Type: utils.MetaGreaterOrEqual, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Usage, + Values: []string{(1 * time.Second).String()}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, - Values: []string{"15.0"}, + Type: utils.MetaGreaterOrEqual, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, + Values: []string{"15.0"}, }, }, } @@ -462,9 +462,9 @@ func TestResourceAddFilters(t *testing.T) { ID: "FLTR_RES_3", Rules: []*FilterRule{ { - Type: utils.MetaPrefix, - FieldName: "~*req.Resources", - Values: []string{"ResourceProfilePrefix"}, + Type: utils.MetaPrefix, + Element: "~*req.Resources", + Values: []string{"ResourceProfilePrefix"}, }, }, } diff --git a/engine/stats_test.go b/engine/stats_test.go index d8973be42..7730f7143 100644 --- a/engine/stats_test.go +++ b/engine/stats_test.go @@ -162,24 +162,24 @@ func TestStatQueuesAddFilters(t *testing.T) { ID: "FLTR_STATS_1", Rules: []*FilterRule{ { - Type: utils.MetaString, - FieldName: "~*req.Stats", - Values: []string{"StatQueueProfile1"}, + Type: utils.MetaString, + Element: "~*req.Stats", + Values: []string{"StatQueueProfile1"}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: "~*req.UsageInterval", - Values: []string{(1 * time.Second).String()}, + Type: utils.MetaGreaterOrEqual, + Element: "~*req.UsageInterval", + Values: []string{(1 * time.Second).String()}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Usage, - Values: []string{(1 * time.Second).String()}, + Type: utils.MetaGreaterOrEqual, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Usage, + Values: []string{(1 * time.Second).String()}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, - Values: []string{"9.0"}, + Type: utils.MetaGreaterOrEqual, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, + Values: []string{"9.0"}, }, }, } @@ -189,24 +189,24 @@ func TestStatQueuesAddFilters(t *testing.T) { ID: "FLTR_STATS_2", Rules: []*FilterRule{ { - Type: utils.MetaString, - FieldName: "~*req.Stats", - Values: []string{"StatQueueProfile2"}, + Type: utils.MetaString, + Element: "~*req.Stats", + Values: []string{"StatQueueProfile2"}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: "~*req.PddInterval", - Values: []string{(1 * time.Second).String()}, + Type: utils.MetaGreaterOrEqual, + Element: "~*req.PddInterval", + Values: []string{(1 * time.Second).String()}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Usage, - Values: []string{(1 * time.Second).String()}, + Type: utils.MetaGreaterOrEqual, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Usage, + Values: []string{(1 * time.Second).String()}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, - Values: []string{"15.0"}, + Type: utils.MetaGreaterOrEqual, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, + Values: []string{"15.0"}, }, }, } @@ -216,9 +216,9 @@ func TestStatQueuesAddFilters(t *testing.T) { ID: "FLTR_STATS_3", Rules: []*FilterRule{ { - Type: utils.MetaPrefix, - FieldName: "~*req.Stats", - Values: []string{"StatQueueProfilePrefix"}, + Type: utils.MetaPrefix, + Element: "~*req.Stats", + Values: []string{"StatQueueProfilePrefix"}, }, }, } diff --git a/engine/suppliers_test.go b/engine/suppliers_test.go index 4f2bcac96..b6c27a6ab 100644 --- a/engine/suppliers_test.go +++ b/engine/suppliers_test.go @@ -306,19 +306,19 @@ func TestSuppliersAddFilters(t *testing.T) { ID: "FLTR_SUPP_1", Rules: []*FilterRule{ { - Type: utils.MetaString, - FieldName: "~*req.Supplier", - Values: []string{"SupplierProfile1"}, + Type: utils.MetaString, + Element: "~*req.Supplier", + Values: []string{"SupplierProfile1"}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: "~*req.UsageInterval", - Values: []string{(1 * time.Second).String()}, + Type: utils.MetaGreaterOrEqual, + Element: "~*req.UsageInterval", + Values: []string{(1 * time.Second).String()}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, - Values: []string{"9.0"}, + Type: utils.MetaGreaterOrEqual, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, + Values: []string{"9.0"}, }, }, } @@ -328,19 +328,19 @@ func TestSuppliersAddFilters(t *testing.T) { ID: "FLTR_SUPP_2", Rules: []*FilterRule{ { - Type: utils.MetaString, - FieldName: "~*req.Supplier", - Values: []string{"SupplierProfile2"}, + Type: utils.MetaString, + Element: "~*req.Supplier", + Values: []string{"SupplierProfile2"}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: "~*req.PddInterval", - Values: []string{(1 * time.Second).String()}, + Type: utils.MetaGreaterOrEqual, + Element: "~*req.PddInterval", + Values: []string{(1 * time.Second).String()}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, - Values: []string{"15.0"}, + Type: utils.MetaGreaterOrEqual, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, + Values: []string{"15.0"}, }, }, } @@ -350,9 +350,9 @@ func TestSuppliersAddFilters(t *testing.T) { ID: "FLTR_SUPP_3", Rules: []*FilterRule{ { - Type: utils.MetaPrefix, - FieldName: "~*req.Supplier", - Values: []string{"SupplierProfilePrefix"}, + Type: utils.MetaPrefix, + Element: "~*req.Supplier", + Values: []string{"SupplierProfilePrefix"}, }, }, } diff --git a/engine/thresholds_test.go b/engine/thresholds_test.go index 0bae470b0..b92cd8a80 100644 --- a/engine/thresholds_test.go +++ b/engine/thresholds_test.go @@ -160,14 +160,14 @@ func TestThresholdsAddFilters(t *testing.T) { ID: "FLTR_TH_1", Rules: []*FilterRule{ { - Type: utils.MetaString, - FieldName: "~*req.Threshold", - Values: []string{"TH_1"}, + Type: utils.MetaString, + Element: "~*req.Threshold", + Values: []string{"TH_1"}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, - Values: []string{"9.0"}, + Type: utils.MetaGreaterOrEqual, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, + Values: []string{"9.0"}, }, }, } @@ -177,14 +177,14 @@ func TestThresholdsAddFilters(t *testing.T) { ID: "FLTR_TH_2", Rules: []*FilterRule{ { - Type: utils.MetaString, - FieldName: "~*req.Threshold", - Values: []string{"TH_2"}, + Type: utils.MetaString, + Element: "~*req.Threshold", + Values: []string{"TH_2"}, }, { - Type: utils.MetaGreaterOrEqual, - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, - Values: []string{"15.0"}, + Type: utils.MetaGreaterOrEqual, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Weight, + Values: []string{"15.0"}, }, }, } @@ -194,9 +194,9 @@ func TestThresholdsAddFilters(t *testing.T) { ID: "FLTR_TH_3", Rules: []*FilterRule{ { - Type: utils.MetaPrefix, - FieldName: "~*req.Threshold", - Values: []string{"ThresholdPrefix"}, + Type: utils.MetaPrefix, + Element: "~*req.Threshold", + Values: []string{"ThresholdPrefix"}, }, }, } diff --git a/general_tests/cdrs_processevent_it_test.go b/general_tests/cdrs_processevent_it_test.go index e881ee4cb..b97d3c6f6 100644 --- a/general_tests/cdrs_processevent_it_test.go +++ b/general_tests/cdrs_processevent_it_test.go @@ -178,8 +178,8 @@ func testV1CDRsProcessEventAttrS(t *testing.T) { FilterIDs: []string{"*string:~*req.Account:1001"}, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, - Value: config.NewRSRParsersMustCompile("1011", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Subject, + Value: config.NewRSRParsersMustCompile("1011", true, utils.INFIELD_SEP), }, }, Weight: 20, diff --git a/general_tests/filters_it_test.go b/general_tests/filters_it_test.go index 45b0bf3b2..fdb2875e8 100644 --- a/general_tests/filters_it_test.go +++ b/general_tests/filters_it_test.go @@ -261,9 +261,9 @@ func testV1FltrPupulateThreshold(t *testing.T) { ID: "FLTR_TH_Stats1", Rules: []*engine.FilterRule{ { - Type: "*gt", - FieldName: "~*stats.Stat_1.*acd", - Values: []string{"10.0"}, + Type: "*gt", + Element: "~*stats.Stat_1.*acd", + Values: []string{"10.0"}, }, }, }, @@ -346,9 +346,9 @@ func testV1FltrGetThresholdForEvent2(t *testing.T) { ID: "FLTR_TH_Stats1", Rules: []*engine.FilterRule{ { - Type: "*lt", - FieldName: "~*stats.Stat_1.*acd", - Values: []string{"10.0"}, + Type: "*lt", + Element: "~*stats.Stat_1.*acd", + Values: []string{"10.0"}, }, }, }, @@ -451,9 +451,9 @@ func testV1FltrPopulateResources(t *testing.T) { ID: "FLTR_TH_Resource", Rules: []*engine.FilterRule{ { - Type: "*gt", - FieldName: "~*resources.ResTest.TotalUsage", - Values: []string{"2.0"}, + Type: "*gt", + Element: "~*resources.ResTest.TotalUsage", + Values: []string{"2.0"}, }, }, }, @@ -515,9 +515,9 @@ func testV1FltrPopulateResources(t *testing.T) { ID: "FLTR_TH_Resource", Rules: []*engine.FilterRule{ { - Type: "*lt", - FieldName: "~*resources.ResTest.TotalUsage", - Values: []string{"2.0"}, + Type: "*lt", + Element: "~*resources.ResTest.TotalUsage", + Values: []string{"2.0"}, }, }, } @@ -559,9 +559,9 @@ func testV1FltrAccounts(t *testing.T) { ID: "FLTR_TH_Accounts", Rules: []*engine.FilterRule{ { - Type: "*gt", - FieldName: "~*accounts.1001.BalanceMap.*monetary[0].Value", - Values: []string{"9"}, + Type: "*gt", + Element: "~*accounts.1001.BalanceMap.*monetary[0].Value", + Values: []string{"9"}, }, }, }, @@ -633,9 +633,9 @@ func testV1FltrAccounts(t *testing.T) { ID: "FLTR_TH_Accounts", Rules: []*engine.FilterRule{ { - Type: "*gt", - FieldName: "~*accounts.1001.BalanceMap.*monetary[0].Value", - Values: []string{"11"}, + Type: "*gt", + Element: "~*accounts.1001.BalanceMap.*monetary[0].Value", + Values: []string{"11"}, }, }, } diff --git a/general_tests/sentinel_it_test.go b/general_tests/sentinel_it_test.go index 1933575e5..e414ce7b1 100755 --- a/general_tests/sentinel_it_test.go +++ b/general_tests/sentinel_it_test.go @@ -129,8 +129,8 @@ func testRedisSentinelSetGetAttribute(t *testing.T) { FilterIDs: []string{"*string:~*req.Account:1001"}, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, - Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Subject, + Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -163,8 +163,8 @@ func testRedisSentinelInsertion(t *testing.T) { FilterIDs: []string{"*string:~*reqAccount:1001"}, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, - Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Subject, + Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -247,8 +247,8 @@ func testRedisSentinelGetAttrAfterFailover(t *testing.T) { FilterIDs: []string{"*string:~*req.Account:1001"}, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, - Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Subject, + Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }, }, Weight: 20, diff --git a/general_tests/sessions_concur_test.go b/general_tests/sessions_concur_test.go index 51b7c7f9b..5462cf55b 100644 --- a/general_tests/sessions_concur_test.go +++ b/general_tests/sessions_concur_test.go @@ -132,8 +132,8 @@ func testSCncrLoadTP(t *testing.T) { Contexts: []string{utils.ANY}, Attributes: []*engine.ExternalAttribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "TestType", - Value: "ConcurrentSessions", + Path: utils.MetaReq + utils.NestingSep + "TestType", + Value: "ConcurrentSessions", }, }, Weight: 20, diff --git a/loaders/libloader_test.go b/loaders/libloader_test.go index 168aabf0f..f0ec4c68e 100644 --- a/loaders/libloader_test.go +++ b/loaders/libloader_test.go @@ -50,8 +50,8 @@ func TestDataUpdateFromCSVOneFile(t *testing.T) { FieldId: "ActivationInterval", Type: utils.META_COMPOSED, Value: config.NewRSRParsersMustCompile("~4", true, utils.INFIELD_SEP)}, - &config.FCTemplate{Tag: "FieldName", - FieldId: "FieldName", + &config.FCTemplate{Tag: "Path", + FieldId: "Path", Type: utils.META_COMPOSED, Value: config.NewRSRParsersMustCompile("~5", true, utils.INFIELD_SEP)}, &config.FCTemplate{Tag: "Initial", @@ -86,7 +86,7 @@ func TestDataUpdateFromCSVOneFile(t *testing.T) { "Contexts": "*sessions;*cdrs", "FilterIDs": "*string:Account:1007", "ActivationInterval": "2014-01-14T00:00:00Z", - "FieldName": "Account", + "Path": "Account", "Initial": "*any", "Substitute": "1001", "Append": "false", @@ -105,7 +105,7 @@ func TestDataUpdateFromCSVOneFile(t *testing.T) { "Contexts": "", "FilterIDs": "", "ActivationInterval": "", - "FieldName": "Subject", + "Path": "Subject", "Initial": "*any", "Substitute": "1001", "Append": "true", @@ -140,8 +140,8 @@ func TestDataUpdateFromCSVOneFile2(t *testing.T) { FieldId: "ActivationInterval", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("~4", true, utils.INFIELD_SEP)}, - &config.FCTemplate{Tag: "FieldName", - FieldId: "FieldName", + &config.FCTemplate{Tag: "Path", + FieldId: "Path", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("~5", true, utils.INFIELD_SEP)}, &config.FCTemplate{Tag: "Initial", @@ -176,7 +176,7 @@ func TestDataUpdateFromCSVOneFile2(t *testing.T) { "Contexts": "*sessions;*cdrs", "FilterIDs": "*string:Account:1007", "ActivationInterval": "2014-01-14T00:00:00Z", - "FieldName": "Account", + "Path": "Account", "Initial": "*any", "Substitute": "1001", "Append": "false", @@ -195,7 +195,7 @@ func TestDataUpdateFromCSVOneFile2(t *testing.T) { "Contexts": "", "FilterIDs": "", "ActivationInterval": "", - "FieldName": "Subject", + "Path": "Subject", "Initial": "*any", "Substitute": "1001", "Append": "true", @@ -222,8 +222,8 @@ func TestDataUpdateFromCSVMultiFiles(t *testing.T) { FieldId: "Contexts", Type: utils.MetaString, Value: config.NewRSRParsersMustCompile("*any", true, utils.INFIELD_SEP)}, - &config.FCTemplate{Tag: "FieldName", - FieldId: "FieldName", + &config.FCTemplate{Tag: "Path", + FieldId: "Path", Type: utils.META_COMPOSED, Value: config.NewRSRParsersMustCompile("~File1.csv:5", true, utils.INFIELD_SEP)}, &config.FCTemplate{Tag: "Initial", @@ -259,7 +259,7 @@ func TestDataUpdateFromCSVMultiFiles(t *testing.T) { eLData := LoaderData{"Tenant": "cgrates.org", "ID": "ATTR_1", "Contexts": "*any", - "FieldName": "Subject", + "Path": "Subject", "Initial": "*any", "Substitute": "1001", "Append": "true", diff --git a/loaders/loader_it_test.go b/loaders/loader_it_test.go index d998ed85c..31f61087e 100644 --- a/loaders/loader_it_test.go +++ b/loaders/loader_it_test.go @@ -163,13 +163,13 @@ func testLoaderCheckAttributes(t *testing.T) { Attributes: []*engine.Attribute{ &engine.Attribute{ FilterIDs: []string{"*string:~*req.Field1:Initial"}, - FieldName: utils.MetaReq + utils.NestingSep + "Field1", + Path: utils.MetaReq + utils.NestingSep + "Field1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Sub1", true, utils.INFIELD_SEP), }, &engine.Attribute{ FilterIDs: []string{}, - FieldName: utils.MetaReq + utils.NestingSep + "Field2", + Path: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Sub2", true, utils.INFIELD_SEP), }}, diff --git a/loaders/loader_test.go b/loaders/loader_test.go index cb171f2ad..8496c6e12 100644 --- a/loaders/loader_test.go +++ b/loaders/loader_test.go @@ -68,8 +68,8 @@ func TestLoaderProcessContentSingleFile(t *testing.T) { FieldId: "AttributeFilterIDs", Type: utils.META_COMPOSED, Value: config.NewRSRParsersMustCompile("~5", true, utils.INFIELD_SEP)}, - &config.FCTemplate{Tag: "FieldName", - FieldId: "FieldName", + &config.FCTemplate{Tag: "Path", + FieldId: "Path", Type: utils.META_COMPOSED, Value: config.NewRSRParsersMustCompile("~6", true, utils.INFIELD_SEP)}, &config.FCTemplate{Tag: "Type", @@ -111,13 +111,13 @@ func TestLoaderProcessContentSingleFile(t *testing.T) { Attributes: []*engine.Attribute{ &engine.Attribute{ FilterIDs: []string{"*string:~*req.Field1:Initial"}, - FieldName: utils.MetaReq + utils.NestingSep + "Field1", + Path: utils.MetaReq + utils.NestingSep + "Field1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Sub1", true, utils.INFIELD_SEP), }, &engine.Attribute{ FilterIDs: []string{}, - FieldName: utils.MetaReq + utils.NestingSep + "Field2", + Path: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Sub2", true, utils.INFIELD_SEP), }}, @@ -162,8 +162,8 @@ func TestLoaderProcessContentMultiFiles(t *testing.T) { FieldId: "Contexts", Type: utils.MetaString, Value: config.NewRSRParsersMustCompile("*any", true, utils.INFIELD_SEP)}, - &config.FCTemplate{Tag: "FieldName", - FieldId: "FieldName", + &config.FCTemplate{Tag: "Path", + FieldId: "Path", Type: utils.META_COMPOSED, Value: config.NewRSRParsersMustCompile("~File1.csv:6", true, utils.INFIELD_SEP)}, &config.FCTemplate{Tag: "Value", @@ -198,7 +198,7 @@ func TestLoaderProcessContentMultiFiles(t *testing.T) { Contexts: []string{utils.ANY}, Attributes: []*engine.Attribute{ &engine.Attribute{ - FieldName: utils.MetaReq + utils.NestingSep + "Subject", + Path: utils.MetaReq + utils.NestingSep + "Subject", FilterIDs: []string{}, Value: config.NewRSRParsersMustCompile("1001", true, utils.INFIELD_SEP), }}, @@ -354,16 +354,16 @@ func TestLoaderProcessFilters(t *testing.T) { Type: utils.META_COMPOSED, Value: config.NewRSRParsersMustCompile("~1", true, utils.INFIELD_SEP), Mandatory: true}, - &config.FCTemplate{Tag: "FilterType", - FieldId: "FilterType", + &config.FCTemplate{Tag: "Type", + FieldId: "Type", Type: utils.META_COMPOSED, Value: config.NewRSRParsersMustCompile("~2", true, utils.INFIELD_SEP)}, - &config.FCTemplate{Tag: "FilterFieldName", - FieldId: "FilterFieldName", + &config.FCTemplate{Tag: "Element", + FieldId: "Element", Type: utils.META_COMPOSED, Value: config.NewRSRParsersMustCompile("~3", true, utils.INFIELD_SEP)}, - &config.FCTemplate{Tag: "FilterFieldValues", - FieldId: "FilterFieldValues", + &config.FCTemplate{Tag: "Values", + FieldId: "Values", Type: utils.META_COMPOSED, Value: config.NewRSRParsersMustCompile("~4", true, utils.INFIELD_SEP)}, &config.FCTemplate{Tag: "ActivationInterval", @@ -388,19 +388,19 @@ func TestLoaderProcessFilters(t *testing.T) { ID: "FLTR_1", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaString, - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, - Values: []string{"1001", "1002"}, + Type: utils.MetaString, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Account, + Values: []string{"1001", "1002"}, }, &engine.FilterRule{ - Type: "*prefix", - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Destination, - Values: []string{"10", "20"}, + Type: "*prefix", + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Destination, + Values: []string{"10", "20"}, }, &engine.FilterRule{ - Type: "*rsr", - FieldName: "", - Values: []string{"~*req.Subject(~^1.*1$)", "~*req.Destination(1002)"}, + Type: "*rsr", + Element: "", + Values: []string{"~*req.Subject(~^1.*1$)", "~*req.Destination(1002)"}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -416,9 +416,9 @@ func TestLoaderProcessFilters(t *testing.T) { ID: "FLTR_DST_DE", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: "*destinations", - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Destination, - Values: []string{"DST_DE"}, + Type: "*destinations", + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.Destination, + Values: []string{"DST_DE"}, }, }, ActivationInterval: &utils.ActivationInterval{ @@ -1151,13 +1151,13 @@ func TestLoaderRemoveContentSingleFile(t *testing.T) { Attributes: []*engine.Attribute{ &engine.Attribute{ FilterIDs: []string{"*string:~*req.Field1:Initial"}, - FieldName: utils.MetaReq + utils.NestingSep + "Field1", + Path: utils.MetaReq + utils.NestingSep + "Field1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Sub1", true, utils.INFIELD_SEP), }, &engine.Attribute{ FilterIDs: []string{}, - FieldName: utils.MetaReq + utils.NestingSep + "Field2", + Path: utils.MetaReq + utils.NestingSep + "Field2", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Sub2", true, utils.INFIELD_SEP), }}, diff --git a/migrator/alias.go b/migrator/alias.go index 256355723..3393e101e 100644 --- a/migrator/alias.go +++ b/migrator/alias.go @@ -113,9 +113,9 @@ func alias2AtttributeProfile(alias *v1Alias, defaultTenant string) *engine.Attri fld = utils.MetaReq + utils.NestingSep + fieldName } attr := &engine.Attribute{ - FieldName: fld, - Type: utils.MetaVariable, //default type for Attribute - Value: config.NewRSRParsersMustCompile(substitute, true, utils.INFIELD_SEP), + Path: fld, + Type: utils.MetaVariable, //default type for Attribute + Value: config.NewRSRParsersMustCompile(substitute, true, utils.INFIELD_SEP), } out.Attributes = append(out.Attributes, attr) // Add attribute filters if needed diff --git a/migrator/alias_it_test.go b/migrator/alias_it_test.go index ab483952c..e9fd07795 100644 --- a/migrator/alias_it_test.go +++ b/migrator/alias_it_test.go @@ -144,13 +144,13 @@ func testAlsITMigrateAndMove(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Account", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Account", + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, { FilterIDs: []string{"*string:~*req.Category:call_1001"}, - FieldName: utils.MetaReq + utils.NestingSep + "Category", + Path: utils.MetaReq + utils.NestingSep + "Category", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("call_1002", true, utils.INFIELD_SEP), }, @@ -193,10 +193,10 @@ func testAlsITMigrateAndMove(t *testing.T) { } result.Compile() sort.Slice(result.Attributes, func(i, j int) bool { - if result.Attributes[i].FieldName == result.Attributes[j].FieldName { + if result.Attributes[i].Path == result.Attributes[j].Path { return result.Attributes[i].FilterIDs[0] < result.Attributes[j].FilterIDs[0] } - return result.Attributes[i].FieldName < result.Attributes[j].FieldName + return result.Attributes[i].Path < result.Attributes[j].Path }) // only for test; map returns random keys if !reflect.DeepEqual(*attrProf, *result) { t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(attrProf), utils.ToJSON(result)) diff --git a/migrator/alias_test.go b/migrator/alias_test.go index 9e33e247d..885399bd6 100644 --- a/migrator/alias_test.go +++ b/migrator/alias_test.go @@ -181,7 +181,7 @@ func TestAlias2AtttributeProfile(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:~*req.Account:1001"}, - FieldName: utils.MetaReq + utils.NestingSep + "Account", + Path: utils.MetaReq + utils.NestingSep + "Account", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, @@ -198,13 +198,13 @@ func TestAlias2AtttributeProfile(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:~*req.Account:1001"}, - FieldName: utils.MetaReq + utils.NestingSep + "Account", + Path: utils.MetaReq + utils.NestingSep + "Account", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, { FilterIDs: []string{"*string:~*req.Account:1003"}, - FieldName: utils.MetaReq + utils.NestingSep + "Account", + Path: utils.MetaReq + utils.NestingSep + "Account", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1004", true, utils.INFIELD_SEP), }, @@ -221,13 +221,13 @@ func TestAlias2AtttributeProfile(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:~*req.Account:1001"}, - FieldName: utils.MetaReq + utils.NestingSep + "Account", + Path: utils.MetaReq + utils.NestingSep + "Account", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, { FilterIDs: []string{"*string:~*req.Account:1003"}, - FieldName: utils.MetaReq + utils.NestingSep + "Account", + Path: utils.MetaReq + utils.NestingSep + "Account", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("1004", true, utils.INFIELD_SEP), }, @@ -247,14 +247,14 @@ func TestAlias2AtttributeProfile(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Account", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Account", + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaReq + utils.NestingSep + "Subject", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("call_1001", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Subject", + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("call_1001", true, utils.INFIELD_SEP), }, }, Blocker: false, @@ -272,12 +272,12 @@ func TestAlias2AtttributeProfile(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Account", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Account", + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaReq + utils.NestingSep + "Category", + Path: utils.MetaReq + utils.NestingSep + "Category", Type: utils.MetaVariable, FilterIDs: []string{"*string:~*req.Category:call_1001"}, Value: config.NewRSRParsersMustCompile("call_1002", true, utils.INFIELD_SEP), @@ -295,9 +295,9 @@ func TestAlias2AtttributeProfile(t *testing.T) { }, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Category, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("somecateg_roam_fromz4", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Category, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("somecateg_roam_fromz4", true, utils.INFIELD_SEP), }, }, Weight: 20, @@ -306,10 +306,10 @@ func TestAlias2AtttributeProfile(t *testing.T) { for i := range expected { rply := alias2AtttributeProfile(aliases[i], defaultTenant) sort.Slice(rply.Attributes, func(i, j int) bool { - if rply.Attributes[i].FieldName == rply.Attributes[j].FieldName { + if rply.Attributes[i].Path == rply.Attributes[j].Path { return rply.Attributes[i].FilterIDs[0] < rply.Attributes[j].FilterIDs[0] } - return rply.Attributes[i].FieldName < rply.Attributes[j].FieldName + return rply.Attributes[i].Path < rply.Attributes[j].Path }) // only for test; map returns random keys if !reflect.DeepEqual(expected[i], rply) { t.Errorf("For %v expected: %s ,recived: %s ", i, utils.ToJSON(expected[i]), utils.ToJSON(rply)) diff --git a/migrator/attributes.go b/migrator/attributes.go index d0a32be4e..01908de90 100644 --- a/migrator/attributes.go +++ b/migrator/attributes.go @@ -257,7 +257,7 @@ func (v1AttrPrf v1AttributeProfile) AsAttributeProfile() (attrPrf *engine.Attrib } attrPrf.Attributes = append(attrPrf.Attributes, &engine.Attribute{ FilterIDs: filterIDs, - FieldName: attr.FieldName, + Path: attr.FieldName, Value: sbstPrsr, Type: utils.MetaVariable, }) @@ -308,7 +308,7 @@ func (v2AttrPrf v2AttributeProfile) AsAttributeProfile() (attrPrf *engine.Attrib } attrPrf.Attributes = append(attrPrf.Attributes, &engine.Attribute{ FilterIDs: filterIDs, - FieldName: attr.FieldName, + Path: attr.FieldName, Value: attr.Substitute, Type: utils.MetaVariable, }) @@ -344,7 +344,7 @@ func (v3AttrPrf v3AttributeProfile) AsAttributeProfile() (attrPrf *engine.Attrib for _, attr := range v3AttrPrf.Attributes { attrPrf.Attributes = append(attrPrf.Attributes, &engine.Attribute{ FilterIDs: attr.FilterIDs, - FieldName: attr.FieldName, + Path: attr.FieldName, Value: attr.Substitute, Type: utils.MetaVariable, //default value for type }) diff --git a/migrator/attributes_it_test.go b/migrator/attributes_it_test.go index 8f812ab9f..961a360d2 100755 --- a/migrator/attributes_it_test.go +++ b/migrator/attributes_it_test.go @@ -292,7 +292,7 @@ func testAttrITMigrateAndMove(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:FL1:In1"}, - FieldName: "FL1", + Path: "FL1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, @@ -412,7 +412,7 @@ func testAttrITMigrateV2(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:FL1:In1"}, - FieldName: "FL1", + Path: "FL1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, @@ -494,7 +494,7 @@ func testAttrITMigrateV3(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:FL1:In1"}, - FieldName: "FL1", + Path: "FL1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, diff --git a/migrator/attributes_test.go b/migrator/attributes_test.go index 0417ee26d..70a560e97 100644 --- a/migrator/attributes_test.go +++ b/migrator/attributes_test.go @@ -61,7 +61,7 @@ func TestV1AttributeProfileAsAttributeProfile(t *testing.T) { Attributes: []*engine.Attribute{ &engine.Attribute{ FilterIDs: []string{"*string:FL1:In1"}, - FieldName: "FL1", + Path: "FL1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, @@ -108,7 +108,7 @@ func TestV2AttributeProfileAsAttributeProfile(t *testing.T) { Attributes: []*engine.Attribute{ &engine.Attribute{ FilterIDs: []string{"*string:FL1:In1"}, - FieldName: "FL1", + Path: "FL1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, @@ -155,7 +155,7 @@ func TestV2AttributeProfileAsAttributeProfile2(t *testing.T) { Attributes: []*engine.Attribute{ &engine.Attribute{ FilterIDs: []string{}, - FieldName: "FL1", + Path: "FL1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, @@ -201,7 +201,7 @@ func TestV3AttributeProfileAsAttributeProfile(t *testing.T) { Attributes: []*engine.Attribute{ &engine.Attribute{ FilterIDs: []string{"*string:FL1:In1"}, - FieldName: "FL1", + Path: "FL1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, diff --git a/migrator/derived_chargers.go b/migrator/derived_chargers.go index 0204cb054..29399148d 100644 --- a/migrator/derived_chargers.go +++ b/migrator/derived_chargers.go @@ -83,9 +83,9 @@ func fieldinfo2Attribute(attr []*engine.Attribute, fieldName, fieldInfo string) return attr } return append(attr, &engine.Attribute{ - FieldName: utils.MetaReq + utils.NestingSep + fieldName, - Value: rp, - Type: utils.MetaVariable, + Path: utils.MetaReq + utils.NestingSep + fieldName, + Value: rp, + Type: utils.MetaVariable, }) } diff --git a/migrator/derived_chargers_it_test.go b/migrator/derived_chargers_it_test.go index 7683e9a49..631ceaae2 100644 --- a/migrator/derived_chargers_it_test.go +++ b/migrator/derived_chargers_it_test.go @@ -149,14 +149,14 @@ func testDCITMigrateAndMove(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.Account, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("1004", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Account, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("1004", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("call_1003", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Subject, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("call_1003", true, utils.INFIELD_SEP), }, }, Blocker: false, @@ -210,7 +210,7 @@ func testDCITMigrateAndMove(t *testing.T) { } result.Compile() sort.Slice(result.Attributes, func(i, j int) bool { - return result.Attributes[i].FieldName < result.Attributes[j].FieldName + return result.Attributes[i].Path < result.Attributes[j].Path }) // only for test; map returns random keys if !reflect.DeepEqual(*attrProf, *result) { t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(attrProf), utils.ToJSON(result)) diff --git a/migrator/derived_chargers_test.go b/migrator/derived_chargers_test.go index ec5ed4e09..ff3854039 100644 --- a/migrator/derived_chargers_test.go +++ b/migrator/derived_chargers_test.go @@ -29,74 +29,74 @@ import ( func TestFieldinfo2Attribute(t *testing.T) { type testA struct { - FieldName string + Path string FieldInfo string Initial []*engine.Attribute Expected []*engine.Attribute } tests := []testA{ testA{ - FieldName: utils.Account, + Path: utils.Account, FieldInfo: utils.MetaDefault, Initial: make([]*engine.Attribute, 0), Expected: make([]*engine.Attribute, 0), }, testA{ - FieldName: utils.Account, + Path: utils.Account, FieldInfo: "", Initial: make([]*engine.Attribute, 0), Expected: make([]*engine.Attribute, 0), }, testA{ - FieldName: utils.Account, + Path: utils.Account, FieldInfo: "^1003", Initial: make([]*engine.Attribute, 0), Expected: []*engine.Attribute{ &engine.Attribute{ - FieldName: utils.MetaReq + utils.NestingSep + utils.Account, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Account, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP), }, }, }, testA{ - FieldName: utils.Subject, + Path: utils.Subject, FieldInfo: `~effective_caller_id_number:s/(\d+)/+$1/`, Initial: make([]*engine.Attribute, 0), Expected: []*engine.Attribute{ &engine.Attribute{ - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile(`~effective_caller_id_number:s/(\d+)/+$1/`, true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Subject, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile(`~effective_caller_id_number:s/(\d+)/+$1/`, true, utils.INFIELD_SEP), }, }, }, testA{ - FieldName: utils.Subject, + Path: utils.Subject, FieldInfo: "^call_1003", Initial: []*engine.Attribute{ &engine.Attribute{ - FieldName: utils.MetaReq + utils.NestingSep + utils.Account, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Account, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP), }, }, Expected: []*engine.Attribute{ &engine.Attribute{ - FieldName: utils.MetaReq + utils.NestingSep + utils.Account, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Account, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP), }, &engine.Attribute{ - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("call_1003", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Subject, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("call_1003", true, utils.INFIELD_SEP), }, }, }, } for i, v := range tests { - if rply := fieldinfo2Attribute(v.Initial, v.FieldName, v.FieldInfo); !reflect.DeepEqual(v.Expected, rply) { + if rply := fieldinfo2Attribute(v.Initial, v.Path, v.FieldInfo); !reflect.DeepEqual(v.Expected, rply) { t.Errorf("For %v expected: %s ,recieved: %s", i, utils.ToJSON(v.Expected), utils.ToJSON(rply)) } } @@ -128,14 +128,14 @@ func TestDerivedChargers2AttributeProfile(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ &engine.Attribute{ - FieldName: utils.MetaReq + utils.NestingSep + utils.Category, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("*voice", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Category, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("*voice", true, utils.INFIELD_SEP), }, &engine.Attribute{ - FieldName: utils.MetaReq + utils.NestingSep + utils.Account, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Account, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP), }, }, Blocker: false, @@ -161,24 +161,24 @@ func TestDerivedChargers2AttributeProfile(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ &engine.Attribute{ - FieldName: utils.MetaReq + utils.NestingSep + utils.Category, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("*voice", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Category, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("*voice", true, utils.INFIELD_SEP), }, &engine.Attribute{ - FieldName: utils.MetaReq + utils.NestingSep + utils.Account, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Account, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("1003", true, utils.INFIELD_SEP), }, &engine.Attribute{ - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("call_1003_to_1004", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Subject, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("call_1003_to_1004", true, utils.INFIELD_SEP), }, &engine.Attribute{ - FieldName: utils.MetaReq + utils.NestingSep + utils.Destination, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("1004", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Destination, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("1004", true, utils.INFIELD_SEP), }, }, Blocker: false, diff --git a/migrator/filters.go b/migrator/filters.go index 5ea4505bc..9466152e2 100644 --- a/migrator/filters.go +++ b/migrator/filters.go @@ -49,7 +49,7 @@ func (m *Migrator) migrateCurrentRequestFilter() (err error) { if err := m.dmOut.DataManager().SetFilter(fl); err != nil { return err } - m.stats[utils.RQF] += 1 + m.stats[utils.RQF]++ } return } @@ -59,34 +59,34 @@ var filterTypes = utils.NewStringSet([]string{utils.MetaRSR, utils.MetaStatS, ut func migrateFilterV1(fl *engine.Filter) *engine.Filter { for i, rule := range fl.Rules { - if rule.FieldName == "" || - strings.HasPrefix(rule.FieldName, utils.DynamicDataPrefix) || + if rule.Element == "" || + strings.HasPrefix(rule.Element, utils.DynamicDataPrefix) || filterTypes.Has(rule.Type) { continue } - fl.Rules[i].FieldName = utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + rule.FieldName + fl.Rules[i].Element = utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + rule.Element } return fl } func migrateFilterV2(fl *engine.Filter) *engine.Filter { for i, rule := range fl.Rules { - if (rule.FieldName == "" && rule.Type != utils.MetaRSR) || - strings.HasPrefix(rule.FieldName, utils.DynamicDataPrefix+utils.MetaReq) || - strings.HasPrefix(rule.FieldName, utils.DynamicDataPrefix+utils.MetaVars) || - strings.HasPrefix(rule.FieldName, utils.DynamicDataPrefix+utils.MetaCgreq) || - strings.HasPrefix(rule.FieldName, utils.DynamicDataPrefix+utils.MetaCgrep) || - strings.HasPrefix(rule.FieldName, utils.DynamicDataPrefix+utils.MetaRep) || - strings.HasPrefix(rule.FieldName, utils.DynamicDataPrefix+utils.MetaCGRAReq) || - strings.HasPrefix(rule.FieldName, utils.DynamicDataPrefix+utils.MetaAct) { + if (rule.Element == "" && rule.Type != utils.MetaRSR) || + strings.HasPrefix(rule.Element, utils.DynamicDataPrefix+utils.MetaReq) || + strings.HasPrefix(rule.Element, utils.DynamicDataPrefix+utils.MetaVars) || + strings.HasPrefix(rule.Element, utils.DynamicDataPrefix+utils.MetaCgreq) || + strings.HasPrefix(rule.Element, utils.DynamicDataPrefix+utils.MetaCgrep) || + strings.HasPrefix(rule.Element, utils.DynamicDataPrefix+utils.MetaRep) || + strings.HasPrefix(rule.Element, utils.DynamicDataPrefix+utils.MetaCGRAReq) || + strings.HasPrefix(rule.Element, utils.DynamicDataPrefix+utils.MetaAct) { continue } if rule.Type != utils.MetaRSR { // in case we found dynamic data prefix we remove it - if strings.HasPrefix(rule.FieldName, utils.DynamicDataPrefix) { - fl.Rules[i].FieldName = fl.Rules[i].FieldName[1:] + if strings.HasPrefix(rule.Element, utils.DynamicDataPrefix) { + fl.Rules[i].Element = fl.Rules[i].Element[1:] } - fl.Rules[i].FieldName = utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + rule.FieldName + fl.Rules[i].Element = utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + rule.Element } else { for idx, val := range rule.Values { if strings.HasPrefix(val, utils.DynamicDataPrefix) { diff --git a/migrator/filters_it_test.go b/migrator/filters_it_test.go index a90d0fbe8..0ebc7eb78 100644 --- a/migrator/filters_it_test.go +++ b/migrator/filters_it_test.go @@ -135,9 +135,9 @@ func testFltrITMigrateAndMove(t *testing.T) { ID: "FLTR_2", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaPrefix, - FieldName: "Account", - Values: []string{"1001"}, + Type: utils.MetaPrefix, + Element: "Account", + Values: []string{"1001"}, }, }, } @@ -146,9 +146,9 @@ func testFltrITMigrateAndMove(t *testing.T) { ID: "FLTR_2", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaPrefix, - FieldName: "~*req.Account", - Values: []string{"1001"}, + Type: utils.MetaPrefix, + Element: "~*req.Account", + Values: []string{"1001"}, }, }, } @@ -162,7 +162,7 @@ func testFltrITMigrateAndMove(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:Account:1001"}, - FieldName: utils.MetaReq + utils.NestingSep + "Account", + Path: utils.MetaReq + utils.NestingSep + "Account", Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, }, @@ -177,7 +177,7 @@ func testFltrITMigrateAndMove(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:~*req.Account:1001"}, - FieldName: utils.MetaReq + utils.NestingSep + "Account", + Path: utils.MetaReq + utils.NestingSep + "Account", Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, }, @@ -282,19 +282,19 @@ func testFltrITMigratev2(t *testing.T) { ID: "FLTR_2", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaString, - FieldName: "~Account", - Values: []string{"1001"}, + Type: utils.MetaString, + Element: "~Account", + Values: []string{"1001"}, }, &engine.FilterRule{ - Type: utils.MetaString, - FieldName: "~*req.Subject", - Values: []string{"1001"}, + Type: utils.MetaString, + Element: "~*req.Subject", + Values: []string{"1001"}, }, &engine.FilterRule{ - Type: utils.MetaRSR, - FieldName: utils.EmptyString, - Values: []string{"~Tenant(~^cgr.*\\.org$)"}, + Type: utils.MetaRSR, + Element: utils.EmptyString, + Values: []string{"~Tenant(~^cgr.*\\.org$)"}, }, }, } @@ -303,19 +303,19 @@ func testFltrITMigratev2(t *testing.T) { ID: "FLTR_2", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaString, - FieldName: "~*req.Account", - Values: []string{"1001"}, + Type: utils.MetaString, + Element: "~*req.Account", + Values: []string{"1001"}, }, &engine.FilterRule{ - Type: utils.MetaString, - FieldName: "~*req.Subject", - Values: []string{"1001"}, + Type: utils.MetaString, + Element: "~*req.Subject", + Values: []string{"1001"}, }, &engine.FilterRule{ - Type: utils.MetaRSR, - FieldName: utils.EmptyString, - Values: []string{"~*req.Tenant(~^cgr.*\\.org$)"}, + Type: utils.MetaRSR, + Element: utils.EmptyString, + Values: []string{"~*req.Tenant(~^cgr.*\\.org$)"}, }, }, } @@ -329,7 +329,7 @@ func testFltrITMigratev2(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:~Account:1001"}, - FieldName: utils.MetaReq + utils.NestingSep + "Account", + Path: utils.MetaReq + utils.NestingSep + "Account", Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, }, @@ -344,7 +344,7 @@ func testFltrITMigratev2(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:~*req.Account:1001"}, - FieldName: utils.MetaReq + utils.NestingSep + "Account", + Path: utils.MetaReq + utils.NestingSep + "Account", Value: config.NewRSRParsersMustCompile("1002", true, utils.INFIELD_SEP), }, }, diff --git a/migrator/filters_test.go b/migrator/filters_test.go index 4807987cc..1ec92613a 100644 --- a/migrator/filters_test.go +++ b/migrator/filters_test.go @@ -65,9 +65,9 @@ func TestFiltersMigrate(t *testing.T) { ID: "FLTR_1", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaString, - FieldName: "Account", - Values: []string{}, + Type: utils.MetaString, + Element: "Account", + Values: []string{}, }, }, }, @@ -76,9 +76,9 @@ func TestFiltersMigrate(t *testing.T) { ID: "FLTR_1", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaString, - FieldName: "~*req.Account", - Values: []string{}, + Type: utils.MetaString, + Element: "~*req.Account", + Values: []string{}, }, }, }, @@ -89,9 +89,9 @@ func TestFiltersMigrate(t *testing.T) { ID: "FLTR_2", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaPrefix, - FieldName: "~Account", - Values: []string{}, + Type: utils.MetaPrefix, + Element: "~Account", + Values: []string{}, }, }, }, @@ -100,9 +100,9 @@ func TestFiltersMigrate(t *testing.T) { ID: "FLTR_2", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaPrefix, - FieldName: "~Account", - Values: []string{}, + Type: utils.MetaPrefix, + Element: "~Account", + Values: []string{}, }, }, }, @@ -123,9 +123,9 @@ func TestFiltersMigrateV2(t *testing.T) { ID: "FLTR_1", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaString, - FieldName: "~Account", - Values: []string{}, + Type: utils.MetaString, + Element: "~Account", + Values: []string{}, }, }, }, @@ -134,9 +134,9 @@ func TestFiltersMigrateV2(t *testing.T) { ID: "FLTR_1", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaString, - FieldName: "~*req.Account", - Values: []string{}, + Type: utils.MetaString, + Element: "~*req.Account", + Values: []string{}, }, }, }, @@ -147,9 +147,9 @@ func TestFiltersMigrateV2(t *testing.T) { ID: "FLTR_2", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaPrefix, - FieldName: "~*req.Account", - Values: []string{}, + Type: utils.MetaPrefix, + Element: "~*req.Account", + Values: []string{}, }, }, }, @@ -158,9 +158,9 @@ func TestFiltersMigrateV2(t *testing.T) { ID: "FLTR_2", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaPrefix, - FieldName: "~*req.Account", - Values: []string{}, + Type: utils.MetaPrefix, + Element: "~*req.Account", + Values: []string{}, }, }, }, @@ -171,9 +171,9 @@ func TestFiltersMigrateV2(t *testing.T) { ID: "FLTR_3", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaPrefix, - FieldName: "~*act.Account", - Values: []string{}, + Type: utils.MetaPrefix, + Element: "~*act.Account", + Values: []string{}, }, }, }, @@ -182,9 +182,9 @@ func TestFiltersMigrateV2(t *testing.T) { ID: "FLTR_3", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaPrefix, - FieldName: "~*act.Account", - Values: []string{}, + Type: utils.MetaPrefix, + Element: "~*act.Account", + Values: []string{}, }, }, }, @@ -195,9 +195,9 @@ func TestFiltersMigrateV2(t *testing.T) { ID: "FLTR_4", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaPrefix, - FieldName: "~*act.Account", - Values: []string{}, + Type: utils.MetaPrefix, + Element: "~*act.Account", + Values: []string{}, }, }, }, @@ -206,9 +206,9 @@ func TestFiltersMigrateV2(t *testing.T) { ID: "FLTR_4", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaPrefix, - FieldName: "~*act.Account", - Values: []string{}, + Type: utils.MetaPrefix, + Element: "~*act.Account", + Values: []string{}, }, }, }, @@ -219,9 +219,9 @@ func TestFiltersMigrateV2(t *testing.T) { ID: "FLTR_5", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaPrefix, - FieldName: "~*vars.Account", - Values: []string{}, + Type: utils.MetaPrefix, + Element: "~*vars.Account", + Values: []string{}, }, }, }, @@ -230,9 +230,9 @@ func TestFiltersMigrateV2(t *testing.T) { ID: "FLTR_5", Rules: []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaPrefix, - FieldName: "~*vars.Account", - Values: []string{}, + Type: utils.MetaPrefix, + Element: "~*vars.Account", + Values: []string{}, }, }, }, diff --git a/migrator/tp_filters_it_test.go b/migrator/tp_filters_it_test.go index cea1259a2..d7b2d0b0a 100755 --- a/migrator/tp_filters_it_test.go +++ b/migrator/tp_filters_it_test.go @@ -113,9 +113,9 @@ func testTpFltrITPopulate(t *testing.T) { ID: "Filter", Filters: []*utils.TPFilter{ { - Type: "*string", - FieldName: "Account", - Values: []string{"1001", "1002"}, + Type: utils.MetaString, + Element: "Account", + Values: []string{"1001", "1002"}, }, }, ActivationInterval: &utils.TPActivationInterval{ diff --git a/migrator/user.go b/migrator/user.go index 5a35e965a..96b584582 100644 --- a/migrator/user.go +++ b/migrator/user.go @@ -63,9 +63,9 @@ func userProfile2attributeProfile(user *v1UserProfile) (attr *engine.AttributePr } if user.Tenant != attr.Tenant { attr.Attributes = append(attr.Attributes, &engine.Attribute{ - FieldName: utils.MetaTenant, - Value: config.NewRSRParsersMustCompile(user.Tenant, true, utils.INFIELD_SEP), - Type: utils.META_CONSTANT, + Path: utils.MetaTenant, + Value: config.NewRSRParsersMustCompile(user.Tenant, true, utils.INFIELD_SEP), + Type: utils.META_CONSTANT, }) } for fieldName, substitute := range user.Profile { @@ -77,9 +77,9 @@ func userProfile2attributeProfile(user *v1UserProfile) (attr *engine.AttributePr continue } attr.Attributes = append(attr.Attributes, &engine.Attribute{ - FieldName: utils.MetaReq + utils.NestingSep + fieldName, - Value: config.NewRSRParsersMustCompile(substitute, true, utils.INFIELD_SEP), - Type: utils.MetaVariable, + Path: utils.MetaReq + utils.NestingSep + fieldName, + Value: config.NewRSRParsersMustCompile(substitute, true, utils.INFIELD_SEP), + Type: utils.MetaVariable, }) } return diff --git a/migrator/user_it_test.go b/migrator/user_it_test.go index 25bd50fdc..beacb6703 100644 --- a/migrator/user_it_test.go +++ b/migrator/user_it_test.go @@ -130,19 +130,19 @@ func testUsrITMigrateAndMove(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.RequestType, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("*prepaid", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.RequestType, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("*prepaid", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaReq + utils.NestingSep + "msisdn", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("123423534646752", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "msisdn", + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("123423534646752", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaTenant, - Type: utils.META_CONSTANT, - Value: config.NewRSRParsersMustCompile("cgrates.com", true, utils.INFIELD_SEP), + Path: utils.MetaTenant, + Type: utils.META_CONSTANT, + Value: config.NewRSRParsersMustCompile("cgrates.com", true, utils.INFIELD_SEP), }, }, Blocker: false, @@ -183,7 +183,7 @@ func testUsrITMigrateAndMove(t *testing.T) { } result.Compile() sort.Slice(result.Attributes, func(i, j int) bool { - return result.Attributes[i].FieldName < result.Attributes[j].FieldName + return result.Attributes[i].Path < result.Attributes[j].Path }) // only for test; map returns random keys if !reflect.DeepEqual(*attrProf, *result) { t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(attrProf), utils.ToJSON(result)) diff --git a/migrator/user_test.go b/migrator/user_test.go index 3ef631086..6d2f58e27 100644 --- a/migrator/user_test.go +++ b/migrator/user_test.go @@ -104,14 +104,14 @@ func TestUserProfile2attributeProfile(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + "Subject", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("call_1001", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "Subject", + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("call_1001", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaTenant, - Type: utils.META_CONSTANT, - Value: config.NewRSRParsersMustCompile(usrTenant, true, utils.INFIELD_SEP), + Path: utils.MetaTenant, + Type: utils.META_CONSTANT, + Value: config.NewRSRParsersMustCompile(usrTenant, true, utils.INFIELD_SEP), }, }, Blocker: false, @@ -127,14 +127,14 @@ func TestUserProfile2attributeProfile(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.RequestType, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("*prepaid", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.RequestType, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("*prepaid", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaReq + utils.NestingSep + "msisdn", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("123423534646752", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "msisdn", + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("123423534646752", true, utils.INFIELD_SEP), }, }, Blocker: false, @@ -148,14 +148,14 @@ func TestUserProfile2attributeProfile(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.RequestType, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("*prepaid", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.RequestType, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("*prepaid", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaTenant, - Type: utils.META_CONSTANT, - Value: config.NewRSRParsersMustCompile(usrTenant, true, utils.INFIELD_SEP), + Path: utils.MetaTenant, + Type: utils.META_CONSTANT, + Value: config.NewRSRParsersMustCompile(usrTenant, true, utils.INFIELD_SEP), }, }, Blocker: false, @@ -171,29 +171,29 @@ func TestUserProfile2attributeProfile(t *testing.T) { ActivationInterval: nil, Attributes: []*engine.Attribute{ { - FieldName: utils.MetaReq + utils.NestingSep + utils.RequestType, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("*prepaid", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.RequestType, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("*prepaid", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaReq + utils.NestingSep + utils.Subject, - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("acnt63", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + utils.Subject, + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("acnt63", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaReq + utils.NestingSep + "imsi", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("12345", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "imsi", + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("12345", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaReq + utils.NestingSep + "msisdn", - Type: utils.MetaVariable, - Value: config.NewRSRParsersMustCompile("12345", true, utils.INFIELD_SEP), + Path: utils.MetaReq + utils.NestingSep + "msisdn", + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("12345", true, utils.INFIELD_SEP), }, { - FieldName: utils.MetaTenant, - Type: utils.META_CONSTANT, - Value: config.NewRSRParsersMustCompile(usrTenant, true, utils.INFIELD_SEP), + Path: utils.MetaTenant, + Type: utils.META_CONSTANT, + Value: config.NewRSRParsersMustCompile(usrTenant, true, utils.INFIELD_SEP), }, }, Blocker: false, @@ -203,10 +203,10 @@ func TestUserProfile2attributeProfile(t *testing.T) { for i := range expected { rply := userProfile2attributeProfile(users[i]) sort.Slice(rply.Attributes, func(i, j int) bool { - if rply.Attributes[i].FieldName == rply.Attributes[j].FieldName { + if rply.Attributes[i].Path == rply.Attributes[j].Path { return rply.Attributes[i].FilterIDs[0] < rply.Attributes[j].FilterIDs[0] } - return rply.Attributes[i].FieldName < rply.Attributes[j].FieldName + return rply.Attributes[i].Path < rply.Attributes[j].Path }) // only for test; map returns random keys if !reflect.DeepEqual(expected[i], rply) { t.Errorf("For %v expected: %s ,\nreceived: %s ", i, utils.ToJSON(expected[i]), utils.ToJSON(rply)) diff --git a/sessions/sessions.go b/sessions/sessions.go index 597302937..8fc3c4bb3 100644 --- a/sessions/sessions.go +++ b/sessions/sessions.go @@ -811,7 +811,7 @@ func (sS *SessionS) getIndexedFilters(tenant string, fltrs []string) ( continue } for _, fltr := range f.Rules { - fldName := strings.TrimPrefix(fltr.FieldName, utils.DynamicDataPrefix+utils.MetaReq+utils.NestingSep) // remove ~req. prefix + fldName := strings.TrimPrefix(fltr.Element, utils.DynamicDataPrefix+utils.MetaReq+utils.NestingSep) // remove ~req. prefix if fltr.Type != utils.MetaString || !sS.cgrCfg.SessionSCfg().SessionIndexes.HasKey(fldName) { unindexedFltr = append(unindexedFltr, fltr) diff --git a/sessions/sessions_test.go b/sessions/sessions_test.go index ea77b8399..0f9201710 100644 --- a/sessions/sessions_test.go +++ b/sessions/sessions_test.go @@ -1574,9 +1574,9 @@ func TestSessionSGetIndexedFilters(t *testing.T) { expIndx := map[string][]string{} expUindx := []*engine.FilterRule{ &engine.FilterRule{ - Type: utils.MetaString, - FieldName: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.ToR, - Values: []string{utils.VOICE}, + Type: utils.MetaString, + Element: utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + utils.ToR, + Values: []string{utils.VOICE}, }, } fltrs := []string{"*string:~*req.ToR:*voice"} diff --git a/utils/apitpdata.go b/utils/apitpdata.go index b9e681fae..4d0b1e1ee 100755 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -1077,11 +1077,11 @@ type TPFilterProfile struct { ActivationInterval *TPActivationInterval // Time when this limit becomes active and expires } -// TPFilterProfile is used in TPFilterProfile +// TPFilter is used in TPFilterProfile type TPFilter struct { - Type string // Filter type (*string, *timing, *rsr_filters, *cdr_stats) - FieldName string // Name of the field providing us the Values to check (used in case of some ) - Values []string // Filter definition + Type string // Filter type (*string, *timing, *rsr_filters, *cdr_stats) + Element string // Name of the field providing us the Values to check (used in case of some ) + Values []string // Filter definition } // TPSupplier is used in TPSupplierProfile @@ -1113,7 +1113,7 @@ type TPSupplierProfile struct { // TPAttribute is used in TPAttributeProfile type TPAttribute struct { FilterIDs []string - FieldName string + Path string Type string Value string } diff --git a/utils/apitpdata_test.go b/utils/apitpdata_test.go index 28621d0a0..a80b6fd6b 100644 --- a/utils/apitpdata_test.go +++ b/utils/apitpdata_test.go @@ -797,7 +797,7 @@ func TestAppendToSMCostFilter(t *testing.T) { expected := &SMCostFilter{ CGRIDs: []string{"CGRID1", "CGRID2"}, } - if smfltr, err = AppendToSMCostFilter(smfltr, "*string", DynamicDataPrefix+CGRID, []string{"CGRID1", "CGRID2"}, ""); err != nil { + if smfltr, err = AppendToSMCostFilter(smfltr, MetaString, DynamicDataPrefix+CGRID, []string{"CGRID1", "CGRID2"}, ""); err != nil { t.Error(err) } else if !reflect.DeepEqual(smfltr, expected) { t.Errorf("Expected: %s ,received: %s ", ToJSON(expected), ToJSON(smfltr)) @@ -810,7 +810,7 @@ func TestAppendToSMCostFilter(t *testing.T) { } expected.RunIDs = []string{"RunID1", "RunID2"} - if smfltr, err = AppendToSMCostFilter(smfltr, "*string", DynamicDataPrefix+RunID, []string{"RunID1", "RunID2"}, ""); err != nil { + if smfltr, err = AppendToSMCostFilter(smfltr, MetaString, DynamicDataPrefix+RunID, []string{"RunID1", "RunID2"}, ""); err != nil { t.Error(err) } else if !reflect.DeepEqual(smfltr, expected) { t.Errorf("Expected: %s ,received: %s ", ToJSON(expected), ToJSON(smfltr)) @@ -823,7 +823,7 @@ func TestAppendToSMCostFilter(t *testing.T) { } expected.OriginHosts = []string{"OriginHost1", "OriginHost2"} - if smfltr, err = AppendToSMCostFilter(smfltr, "*string", DynamicDataPrefix+OriginHost, []string{"OriginHost1", "OriginHost2"}, ""); err != nil { + if smfltr, err = AppendToSMCostFilter(smfltr, MetaString, DynamicDataPrefix+OriginHost, []string{"OriginHost1", "OriginHost2"}, ""); err != nil { t.Error(err) } else if !reflect.DeepEqual(smfltr, expected) { t.Errorf("Expected: %s ,received: %s ", ToJSON(expected), ToJSON(smfltr)) @@ -836,7 +836,7 @@ func TestAppendToSMCostFilter(t *testing.T) { } expected.OriginIDs = []string{"OriginID1", "OriginID2"} - if smfltr, err = AppendToSMCostFilter(smfltr, "*string", DynamicDataPrefix+OriginID, []string{"OriginID1", "OriginID2"}, ""); err != nil { + if smfltr, err = AppendToSMCostFilter(smfltr, MetaString, DynamicDataPrefix+OriginID, []string{"OriginID1", "OriginID2"}, ""); err != nil { t.Error(err) } else if !reflect.DeepEqual(smfltr, expected) { t.Errorf("Expected: %s ,received: %s ", ToJSON(expected), ToJSON(smfltr)) @@ -849,7 +849,7 @@ func TestAppendToSMCostFilter(t *testing.T) { } expected.CostSources = []string{"CostSource1", "CostSource2"} - if smfltr, err = AppendToSMCostFilter(smfltr, "*string", DynamicDataPrefix+CostSource, []string{"CostSource1", "CostSource2"}, ""); err != nil { + if smfltr, err = AppendToSMCostFilter(smfltr, MetaString, DynamicDataPrefix+CostSource, []string{"CostSource1", "CostSource2"}, ""); err != nil { t.Error(err) } else if !reflect.DeepEqual(smfltr, expected) { t.Errorf("Expected: %s ,received: %s ", ToJSON(expected), ToJSON(smfltr)) @@ -891,7 +891,7 @@ func TestAppendToSMCostFilter(t *testing.T) { if !reflect.DeepEqual(smfltr, expected) { t.Errorf("Expected: %s ,received: %s ", ToJSON(expected), ToJSON(smfltr)) } - if smfltr, err = AppendToSMCostFilter(smfltr, "*string", CGRID, []string{"CGRID1", "CGRID2"}, ""); err == nil || err.Error() != "FieldName: \"CGRID\" not supported" { + if smfltr, err = AppendToSMCostFilter(smfltr, MetaString, CGRID, []string{"CGRID1", "CGRID2"}, ""); err == nil || err.Error() != "FieldName: \"CGRID\" not supported" { t.Errorf("Expected error: FieldName: \"CGRID\" not supported ,received %v", err) } if !reflect.DeepEqual(smfltr, expected) { diff --git a/utils/consts.go b/utils/consts.go index f6523d2a3..28897e51e 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -499,6 +499,7 @@ const ( CGR_ACD = "cgr_acd" FilterIDs = "FilterIDs" FieldName = "FieldName" + Path = "Path" MetaRound = "*round" Pong = "Pong" MetaEventCost = "*event_cost" From 233bb94096c0af0b9b59adffe2c29fc32d957604 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 20 Jan 2020 16:10:55 +0200 Subject: [PATCH 13/14] Added Attribute migration from v4 to v5 --- engine/version.go | 2 +- migrator/attributes.go | 95 +++++++++++++++++++++++++++--- migrator/attributes_it_test.go | 99 +++++++++++++++++++++++++++++--- migrator/attributes_test.go | 8 +-- migrator/migrator_datadb.go | 4 ++ migrator/storage_map_datadb.go | 16 ++++++ migrator/storage_mongo_datadb.go | 33 +++++++++++ migrator/storage_redis.go | 48 ++++++++++++++++ 8 files changed, 286 insertions(+), 19 deletions(-) diff --git a/engine/version.go b/engine/version.go index 9b4378450..df4459c36 100644 --- a/engine/version.go +++ b/engine/version.go @@ -151,7 +151,7 @@ func CurrentDataDBVersions() Versions { utils.SharedGroups: 2, utils.Thresholds: 3, utils.Suppliers: 1, - utils.Attributes: 4, + utils.Attributes: 5, utils.Timing: 1, utils.RQF: 3, utils.Resource: 1, diff --git a/migrator/attributes.go b/migrator/attributes.go index 01908de90..1b0170f19 100644 --- a/migrator/attributes.go +++ b/migrator/attributes.go @@ -67,7 +67,7 @@ func (m *Migrator) migrateCurrentAttributeProfile() (err error) { idg, utils.NonTransactional, false); err != nil { return err } - m.stats[utils.Attributes] += 1 + m.stats[utils.Attributes]++ } return } @@ -98,7 +98,7 @@ func (m *Migrator) migrateV1Attributes() (err error) { if err := m.dmOut.DataManager().SetAttributeProfile(attrPrf, true); err != nil { return err } - m.stats[utils.Attributes] += 1 + m.stats[utils.Attributes]++ } if m.dryRun { return @@ -137,7 +137,7 @@ func (m *Migrator) migrateV2Attributes() (err error) { if err := m.dmOut.DataManager().SetAttributeProfile(attrPrf, true); err != nil { return err } - m.stats[utils.Attributes] += 1 + m.stats[utils.Attributes]++ } if m.dryRun { return @@ -176,7 +176,46 @@ func (m *Migrator) migrateV3Attributes() (err error) { if err := m.dmOut.DataManager().SetAttributeProfile(attrPrf, true); err != nil { return err } - m.stats[utils.Attributes] += 1 + m.stats[utils.Attributes]++ + } + if m.dryRun { + return + } + // All done, update version wtih current one + vrs := engine.Versions{utils.Attributes: engine.CurrentDataDBVersions()[utils.Attributes]} + if err = m.dmOut.DataManager().DataDB().SetVersions(vrs, false); err != nil { + return utils.NewCGRError(utils.Migrator, + utils.ServerErrorCaps, + err.Error(), + fmt.Sprintf("error: <%s> when updating Thresholds version into dataDB", err.Error())) + } + return +} + +func (m *Migrator) migrateV4Attributes() (err error) { + var v4Attr *v4AttributeProfile + for { + v4Attr, err = m.dmIN.getV4AttributeProfile() + if err != nil && err != utils.ErrNoMoreData { + return err + } + if err == utils.ErrNoMoreData { + break + } + if v4Attr == nil { + continue + } + attrPrf, err := v4Attr.AsAttributeProfile() + if err != nil { + return err + } + if m.dryRun { + continue + } + if err := m.dmOut.DataManager().SetAttributeProfile(attrPrf, true); err != nil { + return err + } + m.stats[utils.Attributes]++ } if m.dryRun { return @@ -227,6 +266,10 @@ func (m *Migrator) migrateAttributeProfile() (err error) { if err = m.migrateV3Attributes(); err != nil { return err } + case 4: + if err = m.migrateV4Attributes(); err != nil { + return err + } } return m.ensureIndexesDataDB(engine.ColAttr) } @@ -257,7 +300,7 @@ func (v1AttrPrf v1AttributeProfile) AsAttributeProfile() (attrPrf *engine.Attrib } attrPrf.Attributes = append(attrPrf.Attributes, &engine.Attribute{ FilterIDs: filterIDs, - Path: attr.FieldName, + Path: utils.MetaReq + utils.NestingSep + attr.FieldName, Value: sbstPrsr, Type: utils.MetaVariable, }) @@ -308,7 +351,7 @@ func (v2AttrPrf v2AttributeProfile) AsAttributeProfile() (attrPrf *engine.Attrib } attrPrf.Attributes = append(attrPrf.Attributes, &engine.Attribute{ FilterIDs: filterIDs, - Path: attr.FieldName, + Path: utils.MetaReq + utils.NestingSep + attr.FieldName, Value: attr.Substitute, Type: utils.MetaVariable, }) @@ -344,10 +387,48 @@ func (v3AttrPrf v3AttributeProfile) AsAttributeProfile() (attrPrf *engine.Attrib for _, attr := range v3AttrPrf.Attributes { attrPrf.Attributes = append(attrPrf.Attributes, &engine.Attribute{ FilterIDs: attr.FilterIDs, - Path: attr.FieldName, + Path: utils.MetaReq + utils.NestingSep + attr.FieldName, Value: attr.Substitute, Type: utils.MetaVariable, //default value for type }) } return } + +type v4Attribute struct { + FilterIDs []string + FieldName string + Type string + Value config.RSRParsers +} + +type v4AttributeProfile struct { + Tenant string + ID string + Contexts []string // bind this AttributeProfile to multiple contexts + FilterIDs []string + ActivationInterval *utils.ActivationInterval // Activation interval + Attributes []*v4Attribute + Blocker bool // blocker flag to stop processing on multiple runs + Weight float64 +} + +func (v4AttrPrf v4AttributeProfile) AsAttributeProfile() (attrPrf *engine.AttributeProfile, err error) { + attrPrf = &engine.AttributeProfile{ + Tenant: v4AttrPrf.Tenant, + ID: v4AttrPrf.ID, + Contexts: v4AttrPrf.Contexts, + FilterIDs: v4AttrPrf.FilterIDs, + Weight: v4AttrPrf.Weight, + ActivationInterval: v4AttrPrf.ActivationInterval, + } + for _, attr := range v4AttrPrf.Attributes { + attrPrf.Attributes = append(attrPrf.Attributes, &engine.Attribute{ + FilterIDs: attr.FilterIDs, + Path: utils.MetaReq + utils.NestingSep + attr.FieldName, + Value: attr.Value, + Type: attr.Type, + }) + } + return +} diff --git a/migrator/attributes_it_test.go b/migrator/attributes_it_test.go index 961a360d2..bd0c160b0 100755 --- a/migrator/attributes_it_test.go +++ b/migrator/attributes_it_test.go @@ -51,6 +51,8 @@ var sTestsAttrIT = []func(t *testing.T){ testAttrITMigrateV2, testAttrITFlush, testAttrITMigrateV3, + testAttrITFlush, + testAttrITMigrateV4, } func TestAttributeITRedis(t *testing.T) { @@ -254,7 +256,7 @@ func testAttrITMigrateOnlyVersion(t *testing.T) { if vrs, err := attrMigrator.dmOut.DataManager().DataDB().GetVersions(""); err != nil { t.Error(err) - } else if vrs[utils.Attributes] != 4 { + } else if vrs[utils.Attributes] != 5 { t.Errorf("Unexpected version returned: %d", vrs[utils.Attributes]) } } @@ -292,7 +294,7 @@ func testAttrITMigrateAndMove(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:FL1:In1"}, - Path: "FL1", + Path: utils.MetaReq + utils.NestingSep + "FL1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, @@ -324,7 +326,7 @@ func testAttrITMigrateAndMove(t *testing.T) { if vrs, err := attrMigrator.dmOut.DataManager().DataDB().GetVersions(""); err != nil { t.Error(err) - } else if vrs[utils.Attributes] != 4 { + } else if vrs[utils.Attributes] != 5 { t.Errorf("Unexpected version returned: %d", vrs[utils.Attributes]) } result, err := attrMigrator.dmOut.DataManager().GetAttributeProfile("cgrates.org", @@ -412,7 +414,7 @@ func testAttrITMigrateV2(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:FL1:In1"}, - Path: "FL1", + Path: utils.MetaReq + utils.NestingSep + "FL1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, @@ -443,7 +445,7 @@ func testAttrITMigrateV2(t *testing.T) { if vrs, err := attrMigrator.dmOut.DataManager().DataDB().GetVersions(""); err != nil { t.Error(err) - } else if vrs[utils.Attributes] != 4 { + } else if vrs[utils.Attributes] != 5 { t.Errorf("Unexpected version returned: %d", vrs[utils.Attributes]) } result, err := attrMigrator.dmOut.DataManager().GetAttributeProfile("cgrates.org", @@ -494,7 +496,7 @@ func testAttrITMigrateV3(t *testing.T) { Attributes: []*engine.Attribute{ { FilterIDs: []string{"*string:FL1:In1"}, - Path: "FL1", + Path: utils.MetaReq + utils.NestingSep + "FL1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, @@ -525,7 +527,90 @@ func testAttrITMigrateV3(t *testing.T) { if vrs, err := attrMigrator.dmOut.DataManager().DataDB().GetVersions(""); err != nil { t.Error(err) - } else if vrs[utils.Attributes] != 4 { + } else if vrs[utils.Attributes] != 5 { + t.Errorf("Unexpected version returned: %d", vrs[utils.Attributes]) + } + result, err := attrMigrator.dmOut.DataManager().GetAttributeProfile("cgrates.org", + "ATTR_1", false, false, utils.NonTransactional) + if err != nil { + t.Fatal("Error when getting Attribute ", err.Error()) + } + result.Compile() + attrPrf.Compile() + if !reflect.DeepEqual(result, attrPrf) { + t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(attrPrf), utils.ToJSON(result)) + } +} + +func testAttrITMigrateV4(t *testing.T) { + if attrAction != utils.Migrate { + return + } + + v4attr := &v4AttributeProfile{ + Tenant: "cgrates.org", + ID: "ATTR_1", + Contexts: []string{utils.MetaSessionS}, + FilterIDs: []string{"*string:Accont:1001"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + ExpiryTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + }, + Attributes: []*v4Attribute{ + &v4Attribute{ + FilterIDs: []string{"*string:FL1:In1"}, + FieldName: "FL1", + Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), + Type: utils.MetaVariable, + }, + }, + Weight: 20, + } + + attrPrf := &engine.AttributeProfile{ + Tenant: "cgrates.org", + ID: "ATTR_1", + Contexts: []string{utils.MetaSessionS}, + FilterIDs: []string{"*string:Accont:1001"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + ExpiryTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + }, + Attributes: []*engine.Attribute{ + { + FilterIDs: []string{"*string:FL1:In1"}, + Path: utils.MetaReq + utils.NestingSep + "FL1", + Type: utils.MetaVariable, + Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), + }, + }, + Weight: 20, + } + + err := attrMigrator.dmIN.setV4AttributeProfile(v4attr) + if err != nil { + t.Error("Error when setting v3 AttributeProfile ", err.Error()) + } + currentVersion := engine.Versions{utils.Attributes: 4} + err = attrMigrator.dmIN.DataManager().DataDB().SetVersions(currentVersion, false) + if err != nil { + t.Error("Error when setting version for Attributes ", err.Error()) + } + + if vrs, err := attrMigrator.dmIN.DataManager().DataDB().GetVersions(""); err != nil { + t.Error(err) + } else if vrs[utils.Attributes] != 4 { + t.Errorf("Unexpected version returned: %d", vrs[utils.Attributes]) + } + + err, _ = attrMigrator.Migrate([]string{utils.MetaAttributes}) + if err != nil { + t.Error("Error when migrating Attributes ", err.Error()) + } + + if vrs, err := attrMigrator.dmOut.DataManager().DataDB().GetVersions(""); err != nil { + t.Error(err) + } else if vrs[utils.Attributes] != 5 { t.Errorf("Unexpected version returned: %d", vrs[utils.Attributes]) } result, err := attrMigrator.dmOut.DataManager().GetAttributeProfile("cgrates.org", diff --git a/migrator/attributes_test.go b/migrator/attributes_test.go index 70a560e97..f67d59fa9 100644 --- a/migrator/attributes_test.go +++ b/migrator/attributes_test.go @@ -61,7 +61,7 @@ func TestV1AttributeProfileAsAttributeProfile(t *testing.T) { Attributes: []*engine.Attribute{ &engine.Attribute{ FilterIDs: []string{"*string:FL1:In1"}, - Path: "FL1", + Path: utils.MetaReq + utils.NestingSep + "FL1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, @@ -108,7 +108,7 @@ func TestV2AttributeProfileAsAttributeProfile(t *testing.T) { Attributes: []*engine.Attribute{ &engine.Attribute{ FilterIDs: []string{"*string:FL1:In1"}, - Path: "FL1", + Path: utils.MetaReq + utils.NestingSep + "FL1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, @@ -155,7 +155,7 @@ func TestV2AttributeProfileAsAttributeProfile2(t *testing.T) { Attributes: []*engine.Attribute{ &engine.Attribute{ FilterIDs: []string{}, - Path: "FL1", + Path: utils.MetaReq + utils.NestingSep + "FL1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, @@ -201,7 +201,7 @@ func TestV3AttributeProfileAsAttributeProfile(t *testing.T) { Attributes: []*engine.Attribute{ &engine.Attribute{ FilterIDs: []string{"*string:FL1:In1"}, - Path: "FL1", + Path: utils.MetaReq + utils.NestingSep + "FL1", Type: utils.MetaVariable, Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, diff --git a/migrator/migrator_datadb.go b/migrator/migrator_datadb.go index 4b03daf65..9f8372439 100644 --- a/migrator/migrator_datadb.go +++ b/migrator/migrator_datadb.go @@ -62,6 +62,10 @@ type MigratorDataDB interface { setV3AttributeProfile(x *v3AttributeProfile) (err error) remV3AttributeProfile(tenant, id string) (err error) + getV4AttributeProfile() (v4attrPrf *v4AttributeProfile, err error) + setV4AttributeProfile(x *v4AttributeProfile) (err error) + remV4AttributeProfile(tenant, id string) (err error) + DataManager() *engine.DataManager close() } diff --git a/migrator/storage_map_datadb.go b/migrator/storage_map_datadb.go index cd6a5103e..43ee0cb52 100755 --- a/migrator/storage_map_datadb.go +++ b/migrator/storage_map_datadb.go @@ -247,4 +247,20 @@ func (iDBMig *internalMigrator) remV3AttributeProfile(tenant, id string) (err er return utils.ErrNotImplemented } +//AttributeProfile methods +//get +func (iDBMig *internalMigrator) getV4AttributeProfile() (v4attrPrf *v4AttributeProfile, err error) { + return nil, utils.ErrNotImplemented +} + +//set +func (iDBMig *internalMigrator) setV4AttributeProfile(x *v4AttributeProfile) (err error) { + return utils.ErrNotImplemented +} + +//rem +func (iDBMig *internalMigrator) remV4AttributeProfile(tenant, id string) (err error) { + return utils.ErrNotImplemented +} + func (iDBMig *internalMigrator) close() {} diff --git a/migrator/storage_mongo_datadb.go b/migrator/storage_mongo_datadb.go index 0e92dc220..f3d6fcea9 100644 --- a/migrator/storage_mongo_datadb.go +++ b/migrator/storage_mongo_datadb.go @@ -588,3 +588,36 @@ func (v1ms *mongoMigrator) remV3AttributeProfile(tenant, id string) (err error) _, err = v1ms.mgoDB.DB().Collection(v1AttributeProfilesCol).DeleteOne(v1ms.mgoDB.GetContext(), bson.M{"tenant": tenant, "id": id}) return } + +//AttributeProfile methods +//get +func (v1ms *mongoMigrator) getV4AttributeProfile() (v4attrPrf *v4AttributeProfile, err error) { + if v1ms.cursor == nil { + v1ms.cursor, err = v1ms.mgoDB.DB().Collection(v1AttributeProfilesCol).Find(v1ms.mgoDB.GetContext(), bson.D{}) + if err != nil { + return nil, err + } + } + if !(*v1ms.cursor).Next(v1ms.mgoDB.GetContext()) { + (*v1ms.cursor).Close(v1ms.mgoDB.GetContext()) + v1ms.cursor = nil + return nil, utils.ErrNoMoreData + } + v4attrPrf = new(v4AttributeProfile) + if err := (*v1ms.cursor).Decode(v4attrPrf); err != nil { + return nil, err + } + return v4attrPrf, nil +} + +//set +func (v1ms *mongoMigrator) setV4AttributeProfile(x *v4AttributeProfile) (err error) { + _, err = v1ms.mgoDB.DB().Collection(v1AttributeProfilesCol).InsertOne(v1ms.mgoDB.GetContext(), x) + return +} + +//rem +func (v1ms *mongoMigrator) remV4AttributeProfile(tenant, id string) (err error) { + _, err = v1ms.mgoDB.DB().Collection(v1AttributeProfilesCol).DeleteOne(v1ms.mgoDB.GetContext(), bson.M{"tenant": tenant, "id": id}) + return +} diff --git a/migrator/storage_redis.go b/migrator/storage_redis.go index c1dfdca56..5931e3067 100644 --- a/migrator/storage_redis.go +++ b/migrator/storage_redis.go @@ -754,3 +754,51 @@ func (v1rs *redisMigrator) remV3AttributeProfile(tenant, id string) (err error) key := utils.AttributeProfilePrefix + utils.ConcatenatedKey(tenant, id) return v1rs.rds.Cmd("DEL", key).Err } + +//AttributeProfile methods +//get +func (v1rs *redisMigrator) getV4AttributeProfile() (v3attrPrf *v4AttributeProfile, err error) { + var v4attr *v4AttributeProfile + if v1rs.qryIdx == nil { + v1rs.dataKeys, err = v1rs.rds.GetKeysForPrefix(utils.AttributeProfilePrefix) + if err != nil { + return + } else if len(v1rs.dataKeys) == 0 { + return nil, utils.ErrNoMoreData + } + v1rs.qryIdx = utils.IntPointer(0) + } + if *v1rs.qryIdx <= len(v1rs.dataKeys)-1 { + strVal, err := v1rs.rds.Cmd("GET", v1rs.dataKeys[*v1rs.qryIdx]).Bytes() + if err != nil { + return nil, err + } + if err := v1rs.rds.Marshaler().Unmarshal(strVal, &v4attr); err != nil { + return nil, err + } + *v1rs.qryIdx = *v1rs.qryIdx + 1 + } else { + v1rs.qryIdx = nil + return nil, utils.ErrNoMoreData + } + return v4attr, nil +} + +//set +func (v1rs *redisMigrator) setV4AttributeProfile(x *v4AttributeProfile) (err error) { + key := utils.AttributeProfilePrefix + utils.ConcatenatedKey(x.Tenant, x.ID) + bit, err := v1rs.rds.Marshaler().Marshal(x) + if err != nil { + return err + } + if err = v1rs.rds.Cmd("SET", key, bit).Err; err != nil { + return err + } + return +} + +//rem +func (v1rs *redisMigrator) remV4AttributeProfile(tenant, id string) (err error) { + key := utils.AttributeProfilePrefix + utils.ConcatenatedKey(tenant, id) + return v1rs.rds.Cmd("DEL", key).Err +} From b34821c4ccf479a283cc18598e5d615fa5c34d0f Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 20 Jan 2020 18:08:10 +0200 Subject: [PATCH 14/14] Added Filters migration from v3 to v4 --- engine/version.go | 2 +- migrator/filters.go | 207 +++++++++++++++++++++---------- migrator/filters_it_test.go | 146 +++++++++++++++++----- migrator/filters_test.go | 94 +++++++------- migrator/migrator_datadb.go | 4 + migrator/storage_map_datadb.go | 16 +++ migrator/storage_mongo_datadb.go | 41 +++++- migrator/storage_redis.go | 56 ++++++++- 8 files changed, 415 insertions(+), 151 deletions(-) diff --git a/engine/version.go b/engine/version.go index df4459c36..93afbbae3 100644 --- a/engine/version.go +++ b/engine/version.go @@ -153,7 +153,7 @@ func CurrentDataDBVersions() Versions { utils.Suppliers: 1, utils.Attributes: 5, utils.Timing: 1, - utils.RQF: 3, + utils.RQF: 4, utils.Resource: 1, utils.Subscribers: 1, utils.Destinations: 1, diff --git a/migrator/filters.go b/migrator/filters.go index 9466152e2..816db9381 100644 --- a/migrator/filters.go +++ b/migrator/filters.go @@ -57,47 +57,86 @@ func (m *Migrator) migrateCurrentRequestFilter() (err error) { var filterTypes = utils.NewStringSet([]string{utils.MetaRSR, utils.MetaStatS, utils.MetaResources, utils.MetaNotRSR, utils.MetaNotStatS, utils.MetaNotResources}) -func migrateFilterV1(fl *engine.Filter) *engine.Filter { +func migrateFilterV1(fl *v1Filter) (fltr *engine.Filter) { + fltr = &engine.Filter{ + Tenant: fl.Tenant, + ID: fl.ID, + Rules: make([]*engine.FilterRule, len(fl.Rules)), + ActivationInterval: fl.ActivationInterval, + } for i, rule := range fl.Rules { - if rule.Element == "" || - strings.HasPrefix(rule.Element, utils.DynamicDataPrefix) || + fltr.Rules[i] = &engine.FilterRule{ + Type: rule.Type, + Element: rule.FieldName, + Values: rule.Values, + } + if rule.FieldName == "" || + strings.HasPrefix(rule.FieldName, utils.DynamicDataPrefix) || filterTypes.Has(rule.Type) { continue } - fl.Rules[i].Element = utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + rule.Element + fltr.Rules[i].Element = utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + rule.FieldName } - return fl + return } -func migrateFilterV2(fl *engine.Filter) *engine.Filter { +func migrateFilterV2(fl *v1Filter) (fltr *engine.Filter) { + fltr = &engine.Filter{ + Tenant: fl.Tenant, + ID: fl.ID, + Rules: make([]*engine.FilterRule, len(fl.Rules)), + ActivationInterval: fl.ActivationInterval, + } for i, rule := range fl.Rules { - if (rule.Element == "" && rule.Type != utils.MetaRSR) || - strings.HasPrefix(rule.Element, utils.DynamicDataPrefix+utils.MetaReq) || - strings.HasPrefix(rule.Element, utils.DynamicDataPrefix+utils.MetaVars) || - strings.HasPrefix(rule.Element, utils.DynamicDataPrefix+utils.MetaCgreq) || - strings.HasPrefix(rule.Element, utils.DynamicDataPrefix+utils.MetaCgrep) || - strings.HasPrefix(rule.Element, utils.DynamicDataPrefix+utils.MetaRep) || - strings.HasPrefix(rule.Element, utils.DynamicDataPrefix+utils.MetaCGRAReq) || - strings.HasPrefix(rule.Element, utils.DynamicDataPrefix+utils.MetaAct) { + fltr.Rules[i] = &engine.FilterRule{ + Type: rule.Type, + Element: rule.FieldName, + Values: rule.Values, + } + if (rule.FieldName == "" && rule.Type != utils.MetaRSR) || + strings.HasPrefix(rule.FieldName, utils.DynamicDataPrefix+utils.MetaReq) || + strings.HasPrefix(rule.FieldName, utils.DynamicDataPrefix+utils.MetaVars) || + strings.HasPrefix(rule.FieldName, utils.DynamicDataPrefix+utils.MetaCgreq) || + strings.HasPrefix(rule.FieldName, utils.DynamicDataPrefix+utils.MetaCgrep) || + strings.HasPrefix(rule.FieldName, utils.DynamicDataPrefix+utils.MetaRep) || + strings.HasPrefix(rule.FieldName, utils.DynamicDataPrefix+utils.MetaCGRAReq) || + strings.HasPrefix(rule.FieldName, utils.DynamicDataPrefix+utils.MetaAct) { continue } if rule.Type != utils.MetaRSR { // in case we found dynamic data prefix we remove it - if strings.HasPrefix(rule.Element, utils.DynamicDataPrefix) { - fl.Rules[i].Element = fl.Rules[i].Element[1:] + if strings.HasPrefix(rule.FieldName, utils.DynamicDataPrefix) { + fl.Rules[i].FieldName = fl.Rules[i].FieldName[1:] } - fl.Rules[i].Element = utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + rule.Element + fltr.Rules[i].Element = utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + rule.FieldName } else { for idx, val := range rule.Values { if strings.HasPrefix(val, utils.DynamicDataPrefix) { // remove dynamic data prefix from fieldName val = val[1:] } - fl.Rules[i].Values[idx] = utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + val + fltr.Rules[i].Values[idx] = utils.DynamicDataPrefix + utils.MetaReq + utils.NestingSep + val } } } - return fl + return +} + +func migrateFilterV3(fl *v1Filter) (fltr *engine.Filter) { + fltr = &engine.Filter{ + Tenant: fl.Tenant, + ID: fl.ID, + Rules: make([]*engine.FilterRule, len(fl.Rules)), + ActivationInterval: fl.ActivationInterval, + } + for i, rule := range fl.Rules { + fltr.Rules[i] = &engine.FilterRule{ + Type: rule.Type, + Element: rule.FieldName, + Values: rule.Values, + } + } + return } func migrateInlineFilter(fl string) string { @@ -141,36 +180,30 @@ func migrateInlineFilterV2(fl string) string { ruleSplt[1] = ruleSplt[1][1:] } return fmt.Sprintf("%s:~%s:%s", ruleSplt[0], utils.MetaReq+utils.NestingSep+ruleSplt[1], strings.Join(ruleSplt[2:], utils.InInFieldSep)) - } else { // in case of *rsr filter we need to add the prefix at fieldValue - if strings.HasPrefix(ruleSplt[2], utils.DynamicDataPrefix) { - // remove dynamic data prefix from fieldName - ruleSplt[2] = ruleSplt[2][1:] - } - return fmt.Sprintf("%s::~%s", ruleSplt[0], utils.MetaReq+utils.NestingSep+strings.Join(ruleSplt[2:], utils.InInFieldSep)) + } // in case of *rsr filter we need to add the prefix at fieldValue + if strings.HasPrefix(ruleSplt[2], utils.DynamicDataPrefix) { + // remove dynamic data prefix from fieldName + ruleSplt[2] = ruleSplt[2][1:] } - + return fmt.Sprintf("%s::~%s", ruleSplt[0], utils.MetaReq+utils.NestingSep+strings.Join(ruleSplt[2:], utils.InInFieldSep)) } func (m *Migrator) migrateRequestFilterV1() (err error) { - var ids []string - tenant := config.CgrConfig().GeneralCfg().DefaultTenant - ids, err = m.dmIN.DataManager().DataDB().GetKeysForPrefix(utils.FilterPrefix) - if err != nil { - return err - } - for _, id := range ids { - idg := strings.TrimPrefix(id, utils.FilterPrefix+tenant+":") - fl, err := engine.GetFilter(m.dmIN.DataManager(), tenant, idg, false, false, utils.NonTransactional) - if err != nil { + for { + fl, err := m.dmIN.getV1Filter() + if err != nil && err != utils.ErrNoMoreData { return err } + if err == utils.ErrNoMoreData { + break + } if m.dryRun || fl == nil { continue } if err := m.dmOut.DataManager().SetFilter(migrateFilterV1(fl)); err != nil { return err } - m.stats[utils.RQF] += 1 + m.stats[utils.RQF]++ } if err = m.migrateResourceProfileFiltersV1(); err != nil { return err @@ -193,7 +226,7 @@ func (m *Migrator) migrateRequestFilterV1() (err error) { if err = m.migrateDispatcherProfileFiltersV1(); err != nil { return err } - vrs := engine.Versions{utils.RQF: 2} + vrs := engine.Versions{utils.RQF: engine.CurrentDataDBVersions()[utils.RQF]} if err = m.dmOut.DataManager().DataDB().SetVersions(vrs, false); err != nil { return utils.NewCGRError(utils.Migrator, utils.ServerErrorCaps, @@ -204,27 +237,22 @@ func (m *Migrator) migrateRequestFilterV1() (err error) { } func (m *Migrator) migrateRequestFilterV2() (err error) { - var ids []string - tenant := config.CgrConfig().GeneralCfg().DefaultTenant - ids, err = m.dmIN.DataManager().DataDB().GetKeysForPrefix(utils.FilterPrefix) - if err != nil { - return fmt.Errorf("Error: <%s> when getting filter IDs for migration", err.Error()) - } - for _, id := range ids { - idg := strings.TrimPrefix(id, utils.FilterPrefix+tenant+":") - fl, err := engine.GetFilter(m.dmIN.DataManager(), tenant, idg, false, false, utils.NonTransactional) - if err != nil { - return fmt.Errorf("Error: <%s> when getting filter with tenant: <%s> and id: <%s> for migration", - err.Error(), tenant, idg) + for { + fl, err := m.dmIN.getV1Filter() + if err != nil && err != utils.ErrNoMoreData { + return err + } + if err == utils.ErrNoMoreData { + break } if m.dryRun || fl == nil { continue } if err := m.dmOut.DataManager().SetFilter(migrateFilterV2(fl)); err != nil { return fmt.Errorf("Error: <%s> when setting filter with tenant: <%s> and id: <%s> after migration", - err.Error(), tenant, idg) + err.Error(), fl.Tenant, fl.ID) } - m.stats[utils.RQF] += 1 + m.stats[utils.RQF]++ } if err = m.migrateResourceProfileFiltersV2(); err != nil { return fmt.Errorf("Error: <%s> when trying to migrate filter for ResourceProfiles", @@ -264,6 +292,34 @@ func (m *Migrator) migrateRequestFilterV2() (err error) { return } +func (m *Migrator) migrateRequestFilterV3() (err error) { + for { + fl, err := m.dmIN.getV1Filter() + if err != nil && err != utils.ErrNoMoreData { + return err + } + if err == utils.ErrNoMoreData { + break + } + if m.dryRun || fl == nil { + continue + } + if err := m.dmOut.DataManager().SetFilter(migrateFilterV3(fl)); err != nil { + return fmt.Errorf("Error: <%s> when setting filter with tenant: <%s> and id: <%s> after migration", + err.Error(), fl.Tenant, fl.ID) + } + m.stats[utils.RQF]++ + } + vrs := engine.Versions{utils.RQF: engine.CurrentDataDBVersions()[utils.RQF]} + if err = m.dmOut.DataManager().DataDB().SetVersions(vrs, false); err != nil { + return utils.NewCGRError(utils.Migrator, + utils.ServerErrorCaps, + err.Error(), + fmt.Sprintf("error: <%s> when updating Filters version into dataDB", err.Error())) + } + return +} + func (m *Migrator) migrateFilters() (err error) { var vrs engine.Versions current := engine.CurrentDataDBVersions() @@ -280,6 +336,10 @@ func (m *Migrator) migrateFilters() (err error) { "version number is not defined for ActionTriggers model") } switch vrs[utils.RQF] { + case 3: + if err = m.migrateRequestFilterV3(); err != nil { + return err + } case 2: if err = m.migrateRequestFilterV2(); err != nil { return err @@ -321,7 +381,7 @@ func (m *Migrator) migrateResourceProfileFiltersV1() (err error) { if err := m.dmOut.DataManager().SetResourceProfile(res, true); err != nil { return err } - m.stats[utils.RQF] += 1 + m.stats[utils.RQF]++ } return } @@ -348,7 +408,7 @@ func (m *Migrator) migrateStatQueueProfileFiltersV1() (err error) { if err = m.dmOut.DataManager().SetStatQueueProfile(sgs, true); err != nil { return err } - m.stats[utils.RQF] += 1 + m.stats[utils.RQF]++ } return } @@ -375,7 +435,7 @@ func (m *Migrator) migrateThresholdsProfileFiltersV1() (err error) { if err := m.dmOut.DataManager().SetThresholdProfile(ths, true); err != nil { return err } - m.stats[utils.RQF] += 1 + m.stats[utils.RQF]++ } return } @@ -402,7 +462,7 @@ func (m *Migrator) migrateSupplierProfileFiltersV1() (err error) { if err := m.dmOut.DataManager().SetSupplierProfile(splp, true); err != nil { return err } - m.stats[utils.RQF] += 1 + m.stats[utils.RQF]++ } return } @@ -434,7 +494,7 @@ func (m *Migrator) migrateAttributeProfileFiltersV1() (err error) { if err := m.dmOut.DataManager().SetAttributeProfile(attrPrf, true); err != nil { return err } - m.stats[utils.RQF] += 1 + m.stats[utils.RQF]++ } return } @@ -461,7 +521,7 @@ func (m *Migrator) migrateChargerProfileFiltersV1() (err error) { if err := m.dmOut.DataManager().SetChargerProfile(cpp, true); err != nil { return err } - m.stats[utils.RQF] += 1 + m.stats[utils.RQF]++ } return } @@ -488,7 +548,7 @@ func (m *Migrator) migrateDispatcherProfileFiltersV1() (err error) { if err := m.dmOut.DataManager().SetDispatcherProfile(dpp, true); err != nil { return err } - m.stats[utils.RQF] += 1 + m.stats[utils.RQF]++ } return } @@ -518,7 +578,7 @@ func (m *Migrator) migrateResourceProfileFiltersV2() (err error) { return fmt.Errorf("error: <%s> when setting resource profile with tenant: <%s> and id: <%s>", err.Error(), tenant, idg) } - m.stats[utils.RQF] += 1 + m.stats[utils.RQF]++ } return } @@ -547,7 +607,7 @@ func (m *Migrator) migrateStatQueueProfileFiltersV2() (err error) { return fmt.Errorf("error: <%s> when setting statQueue profile with tenant: <%s> and id: <%s>", err.Error(), tenant, idg) } - m.stats[utils.RQF] += 1 + m.stats[utils.RQF]++ } return } @@ -576,7 +636,7 @@ func (m *Migrator) migrateThresholdsProfileFiltersV2() (err error) { return fmt.Errorf("error: <%s> when setting threshold profile with tenant: <%s> and id: <%s>", err.Error(), tenant, idg) } - m.stats[utils.RQF] += 1 + m.stats[utils.RQF]++ } return } @@ -605,7 +665,7 @@ func (m *Migrator) migrateSupplierProfileFiltersV2() (err error) { return fmt.Errorf("error: <%s> when setting supplier profile with tenant: <%s> and id: <%s>", err.Error(), tenant, idg) } - m.stats[utils.RQF] += 1 + m.stats[utils.RQF]++ } return } @@ -639,7 +699,7 @@ func (m *Migrator) migrateAttributeProfileFiltersV2() (err error) { return fmt.Errorf("error: <%s> when setting attribute profile with tenant: <%s> and id: <%s>", err.Error(), tenant, idg) } - m.stats[utils.RQF] += 1 + m.stats[utils.RQF]++ } return } @@ -668,7 +728,7 @@ func (m *Migrator) migrateChargerProfileFiltersV2() (err error) { return fmt.Errorf("error: <%s> when setting charger profile with tenant: <%s> and id: <%s>", err.Error(), tenant, idg) } - m.stats[utils.RQF] += 1 + m.stats[utils.RQF]++ } return } @@ -697,7 +757,22 @@ func (m *Migrator) migrateDispatcherProfileFiltersV2() (err error) { return fmt.Errorf("error: <%s> when setting dispatcher profile with tenant: <%s> and id: <%s>", err.Error(), tenant, idg) } - m.stats[utils.RQF] += 1 + m.stats[utils.RQF]++ } return } + +type v1Filter struct { + Tenant string + ID string + Rules []*v1FilterRule + ActivationInterval *utils.ActivationInterval +} + +type v1FilterRule struct { + Type string // Filter type (*string, *timing, *rsr_filters, *stats, *lt, *lte, *gt, *gte) + FieldName string // Name of the field providing us the Values to check (used in case of some ) + Values []string // Filter definition + rsrFields config.RSRParsers // Cache here the RSRFilter Values + negative *bool +} diff --git a/migrator/filters_it_test.go b/migrator/filters_it_test.go index 0ebc7eb78..7cb1140f2 100644 --- a/migrator/filters_it_test.go +++ b/migrator/filters_it_test.go @@ -42,7 +42,10 @@ var sTestsFltrIT = []func(t *testing.T){ testFltrITConnect, testFltrITFlush, testFltrITMigrateAndMove, + testFltrITFlush, testFltrITMigratev2, + testFltrITFlush, + testFltrITMigratev3, } func TestFiltersMigrateITRedis(t *testing.T) { @@ -130,14 +133,14 @@ func testFltrITFlush(t *testing.T) { } func testFltrITMigrateAndMove(t *testing.T) { - Filters := &engine.Filter{ + Filters := &v1Filter{ Tenant: "cgrates.org", ID: "FLTR_2", - Rules: []*engine.FilterRule{ - &engine.FilterRule{ - Type: utils.MetaPrefix, - Element: "Account", - Values: []string{"1001"}, + Rules: []*v1FilterRule{ + &v1FilterRule{ + Type: utils.MetaPrefix, + FieldName: "Account", + Values: []string{"1001"}, }, }, } @@ -187,7 +190,7 @@ func testFltrITMigrateAndMove(t *testing.T) { attrProf.Compile() switch fltrAction { case utils.Migrate: - if err := fltrMigrator.dmIN.DataManager().SetFilter(Filters); err != nil { + if err := fltrMigrator.dmIN.setV1Filter(Filters); err != nil { t.Error("Error when setting v1 Filters ", err.Error()) } if err := fltrMigrator.dmIN.DataManager().SetAttributeProfile(attrProf, false); err != nil { @@ -212,7 +215,7 @@ func testFltrITMigrateAndMove(t *testing.T) { //check if version was updated if vrs, err := fltrMigrator.dmOut.DataManager().DataDB().GetVersions(""); err != nil { t.Error(err) - } else if vrs[utils.RQF] != 2 { + } else if vrs[utils.RQF] != 4 { t.Errorf("Unexpected version returned: %d", vrs[utils.RQF]) } //check if Filters was migrate correctly @@ -243,7 +246,7 @@ func testFltrITMigrateAndMove(t *testing.T) { t.Errorf("Expected %v, recived: %v", utils.ToJSON(expFltrIdx), utils.ToJSON(fltridx)) } case utils.Move: - if err := fltrMigrator.dmIN.DataManager().SetFilter(Filters); err != nil { + if err := fltrMigrator.dmIN.DataManager().SetFilter(expFilters); err != nil { t.Error(err) } currentVersion := engine.CurrentDataDBVersions() @@ -257,16 +260,16 @@ func testFltrITMigrateAndMove(t *testing.T) { t.Error("Error when fltrMigratorrating Filters ", err.Error()) } //check if account was migrate correctly - result, err := engine.GetFilter(fltrMigrator.dmOut.DataManager(), Filters.Tenant, Filters.ID, false, false, utils.NonTransactional) + result, err := engine.GetFilter(fltrMigrator.dmOut.DataManager(), expFilters.Tenant, expFilters.ID, false, false, utils.NonTransactional) if err != nil { t.Error(err) } result.Compile() - if !reflect.DeepEqual(Filters, result) { - t.Errorf("Expecting: %+v, received: %+v", Filters, result) + if !reflect.DeepEqual(expFilters, result) { + t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(expFilters), utils.ToJSON(result)) } // check if old account was deleted - result, err = engine.GetFilter(fltrMigrator.dmIN.DataManager(), Filters.Tenant, Filters.ID, false, false, utils.NonTransactional) + result, err = engine.GetFilter(fltrMigrator.dmIN.DataManager(), expFilters.Tenant, expFilters.ID, false, false, utils.NonTransactional) if err != utils.ErrNotFound { t.Error(err) } @@ -277,24 +280,24 @@ func testFltrITMigratev2(t *testing.T) { if fltrAction != utils.Migrate { t.SkipNow() } - filters := &engine.Filter{ + filters := &v1Filter{ Tenant: "cgrates.org", ID: "FLTR_2", - Rules: []*engine.FilterRule{ - &engine.FilterRule{ - Type: utils.MetaString, - Element: "~Account", - Values: []string{"1001"}, + Rules: []*v1FilterRule{ + &v1FilterRule{ + Type: utils.MetaString, + FieldName: "~Account", + Values: []string{"1001"}, }, - &engine.FilterRule{ - Type: utils.MetaString, - Element: "~*req.Subject", - Values: []string{"1001"}, + &v1FilterRule{ + Type: utils.MetaString, + FieldName: "~*req.Subject", + Values: []string{"1001"}, }, - &engine.FilterRule{ - Type: utils.MetaRSR, - Element: utils.EmptyString, - Values: []string{"~Tenant(~^cgr.*\\.org$)"}, + &v1FilterRule{ + Type: utils.MetaRSR, + FieldName: utils.EmptyString, + Values: []string{"~Tenant(~^cgr.*\\.org$)"}, }, }, } @@ -353,7 +356,7 @@ func testFltrITMigratev2(t *testing.T) { expAttrProf.Compile() attrProf.Compile() - if err := fltrMigrator.dmIN.DataManager().SetFilter(filters); err != nil { + if err := fltrMigrator.dmIN.setV1Filter(filters); err != nil { t.Error("Error when setting v1 Filters ", err.Error()) } if err := fltrMigrator.dmIN.DataManager().SetAttributeProfile(attrProf, false); err != nil { @@ -378,7 +381,7 @@ func testFltrITMigratev2(t *testing.T) { //check if version was updated if vrs, err := fltrMigrator.dmOut.DataManager().DataDB().GetVersions(""); err != nil { t.Error(err) - } else if vrs[utils.RQF] != 3 { + } else if vrs[utils.RQF] != 4 { t.Errorf("Unexpected version returned: %d", vrs[utils.RQF]) } //check if Filters was migrate correctly @@ -400,7 +403,6 @@ func testFltrITMigratev2(t *testing.T) { t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(expAttrProf), utils.ToJSON(resultAttr)) } expFltrIdx := map[string]utils.StringMap{ - "*prefix:~*req.Account:1001": utils.StringMap{"ATTR_1": true}, "*string:~*req.Account:1001": utils.StringMap{"ATTR_1": true}, "*string:~*req.Subject:1001": utils.StringMap{"ATTR_1": true}, } @@ -411,3 +413,87 @@ func testFltrITMigratev2(t *testing.T) { t.Errorf("Expected %v, recived: %v", utils.ToJSON(expFltrIdx), utils.ToJSON(fltridx)) } } + +func testFltrITMigratev3(t *testing.T) { + if fltrAction != utils.Migrate { + t.SkipNow() + } + filters := &v1Filter{ + Tenant: "cgrates.org", + ID: "FLTR_2", + Rules: []*v1FilterRule{ + &v1FilterRule{ + Type: utils.MetaString, + FieldName: "~*req.Account", + Values: []string{"1001"}, + }, + &v1FilterRule{ + Type: utils.MetaString, + FieldName: "~*req.Subject", + Values: []string{"1001"}, + }, + &v1FilterRule{ + Type: utils.MetaRSR, + FieldName: utils.EmptyString, + Values: []string{"~*req.Tenant(~^cgr.*\\.org$)"}, + }, + }, + } + expFilters := &engine.Filter{ + Tenant: "cgrates.org", + ID: "FLTR_2", + Rules: []*engine.FilterRule{ + &engine.FilterRule{ + Type: utils.MetaString, + Element: "~*req.Account", + Values: []string{"1001"}, + }, + &engine.FilterRule{ + Type: utils.MetaString, + Element: "~*req.Subject", + Values: []string{"1001"}, + }, + &engine.FilterRule{ + Type: utils.MetaRSR, + Element: utils.EmptyString, + Values: []string{"~*req.Tenant(~^cgr.*\\.org$)"}, + }, + }, + } + expFilters.Compile() + + if err := fltrMigrator.dmIN.setV1Filter(filters); err != nil { + t.Error("Error when setting v1 Filters ", err.Error()) + } + currentVersion := engine.Versions{utils.RQF: 3} + err := fltrMigrator.dmIN.DataManager().DataDB().SetVersions(currentVersion, false) + if err != nil { + t.Error("Error when setting version for Filters ", err.Error()) + } + //check if version was set correctly + if vrs, err := fltrMigrator.dmIN.DataManager().DataDB().GetVersions(""); err != nil { + t.Error(err) + } else if vrs[utils.RQF] != 3 { + t.Errorf("Unexpected version returned: %d", vrs[utils.RQF]) + } + //migrate Filters + err, _ = fltrMigrator.Migrate([]string{utils.MetaFilters}) + if err != nil { + t.Error("Error when migrating Filters ", err.Error()) + } + //check if version was updated + if vrs, err := fltrMigrator.dmOut.DataManager().DataDB().GetVersions(""); err != nil { + t.Error(err) + } else if vrs[utils.RQF] != 4 { + t.Errorf("Unexpected version returned: %d", vrs[utils.RQF]) + } + //check if Filters was migrate correctly + result, err := engine.GetFilter(fltrMigrator.dmOut.DataManager(), filters.Tenant, filters.ID, false, false, utils.NonTransactional) + if err != nil { + t.Fatalf("Error when getting filters %v", err.Error()) + } + result.Compile() + if !reflect.DeepEqual(*expFilters, *result) { + t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(expFilters), utils.ToJSON(result)) + } +} diff --git a/migrator/filters_test.go b/migrator/filters_test.go index 1ec92613a..b72a2869b 100644 --- a/migrator/filters_test.go +++ b/migrator/filters_test.go @@ -58,16 +58,19 @@ func TestFiltersInlineMigrate(t *testing.T) { } func TestFiltersMigrate(t *testing.T) { - data := []struct{ in, exp *engine.Filter }{ + data := []struct { + in *v1Filter + exp *engine.Filter + }{ { - in: &engine.Filter{ + in: &v1Filter{ Tenant: "cgrates.org", ID: "FLTR_1", - Rules: []*engine.FilterRule{ - &engine.FilterRule{ - Type: utils.MetaString, - Element: "Account", - Values: []string{}, + Rules: []*v1FilterRule{ + &v1FilterRule{ + Type: utils.MetaString, + FieldName: "Account", + Values: []string{}, }, }, }, @@ -84,14 +87,14 @@ func TestFiltersMigrate(t *testing.T) { }, }, { - in: &engine.Filter{ + in: &v1Filter{ Tenant: "cgrates.org", ID: "FLTR_2", - Rules: []*engine.FilterRule{ - &engine.FilterRule{ - Type: utils.MetaPrefix, - Element: "~Account", - Values: []string{}, + Rules: []*v1FilterRule{ + &v1FilterRule{ + Type: utils.MetaPrefix, + FieldName: "~Account", + Values: []string{}, }, }, }, @@ -116,16 +119,19 @@ func TestFiltersMigrate(t *testing.T) { } func TestFiltersMigrateV2(t *testing.T) { - data := []struct{ in, exp *engine.Filter }{ + data := []struct { + in *v1Filter + exp *engine.Filter + }{ { - in: &engine.Filter{ + in: &v1Filter{ Tenant: "cgrates.org", ID: "FLTR_1", - Rules: []*engine.FilterRule{ - &engine.FilterRule{ - Type: utils.MetaString, - Element: "~Account", - Values: []string{}, + Rules: []*v1FilterRule{ + &v1FilterRule{ + Type: utils.MetaString, + FieldName: "~Account", + Values: []string{}, }, }, }, @@ -142,14 +148,14 @@ func TestFiltersMigrateV2(t *testing.T) { }, }, { - in: &engine.Filter{ + in: &v1Filter{ Tenant: "cgrates.org", ID: "FLTR_2", - Rules: []*engine.FilterRule{ - &engine.FilterRule{ - Type: utils.MetaPrefix, - Element: "~*req.Account", - Values: []string{}, + Rules: []*v1FilterRule{ + &v1FilterRule{ + Type: utils.MetaPrefix, + FieldName: "~*req.Account", + Values: []string{}, }, }, }, @@ -166,14 +172,14 @@ func TestFiltersMigrateV2(t *testing.T) { }, }, { - in: &engine.Filter{ + in: &v1Filter{ Tenant: "cgrates.org", ID: "FLTR_3", - Rules: []*engine.FilterRule{ - &engine.FilterRule{ - Type: utils.MetaPrefix, - Element: "~*act.Account", - Values: []string{}, + Rules: []*v1FilterRule{ + &v1FilterRule{ + Type: utils.MetaPrefix, + FieldName: "~*act.Account", + Values: []string{}, }, }, }, @@ -190,14 +196,14 @@ func TestFiltersMigrateV2(t *testing.T) { }, }, { - in: &engine.Filter{ + in: &v1Filter{ Tenant: "cgrates.org", ID: "FLTR_4", - Rules: []*engine.FilterRule{ - &engine.FilterRule{ - Type: utils.MetaPrefix, - Element: "~*act.Account", - Values: []string{}, + Rules: []*v1FilterRule{ + &v1FilterRule{ + Type: utils.MetaPrefix, + FieldName: "~*act.Account", + Values: []string{}, }, }, }, @@ -214,14 +220,14 @@ func TestFiltersMigrateV2(t *testing.T) { }, }, { - in: &engine.Filter{ + in: &v1Filter{ Tenant: "cgrates.org", ID: "FLTR_5", - Rules: []*engine.FilterRule{ - &engine.FilterRule{ - Type: utils.MetaPrefix, - Element: "~*vars.Account", - Values: []string{}, + Rules: []*v1FilterRule{ + &v1FilterRule{ + Type: utils.MetaPrefix, + FieldName: "~*vars.Account", + Values: []string{}, }, }, }, diff --git a/migrator/migrator_datadb.go b/migrator/migrator_datadb.go index 9f8372439..82fad78ff 100644 --- a/migrator/migrator_datadb.go +++ b/migrator/migrator_datadb.go @@ -66,6 +66,10 @@ type MigratorDataDB interface { setV4AttributeProfile(x *v4AttributeProfile) (err error) remV4AttributeProfile(tenant, id string) (err error) + getV1Filter() (v1Fltr *v1Filter, err error) + setV1Filter(x *v1Filter) (err error) + remV1Filter(tenant, id string) (err error) + DataManager() *engine.DataManager close() } diff --git a/migrator/storage_map_datadb.go b/migrator/storage_map_datadb.go index 43ee0cb52..079aac1cd 100755 --- a/migrator/storage_map_datadb.go +++ b/migrator/storage_map_datadb.go @@ -263,4 +263,20 @@ func (iDBMig *internalMigrator) remV4AttributeProfile(tenant, id string) (err er return utils.ErrNotImplemented } +// Filter Methods +//get +func (iDBMig *internalMigrator) getV1Filter() (v1Fltr *v1Filter, err error) { + return nil, utils.ErrNotImplemented +} + +//set +func (iDBMig *internalMigrator) setV1Filter(x *v1Filter) (err error) { + return utils.ErrNotImplemented +} + +//rem +func (iDBMig *internalMigrator) remV1Filter(tenant, id string) (err error) { + return utils.ErrNotImplemented +} + func (iDBMig *internalMigrator) close() {} diff --git a/migrator/storage_mongo_datadb.go b/migrator/storage_mongo_datadb.go index f3d6fcea9..f4bbe86bc 100644 --- a/migrator/storage_mongo_datadb.go +++ b/migrator/storage_mongo_datadb.go @@ -59,12 +59,12 @@ func newMongoMigrator(dm *engine.DataManager) (mgoMig *mongoMigrator) { } } -func (mgoMig *mongoMigrator) close() { - mgoMig.mgoDB.Close() +func (v1ms *mongoMigrator) close() { + v1ms.mgoDB.Close() } -func (mgoMig *mongoMigrator) DataManager() *engine.DataManager { - return mgoMig.dm +func (v1ms *mongoMigrator) DataManager() *engine.DataManager { + return v1ms.dm } //Account methods @@ -621,3 +621,36 @@ func (v1ms *mongoMigrator) remV4AttributeProfile(tenant, id string) (err error) _, err = v1ms.mgoDB.DB().Collection(v1AttributeProfilesCol).DeleteOne(v1ms.mgoDB.GetContext(), bson.M{"tenant": tenant, "id": id}) return } + +// Filter Methods +//get +func (v1ms *mongoMigrator) getV1Filter() (v1Fltr *v1Filter, err error) { + if v1ms.cursor == nil { + v1ms.cursor, err = v1ms.mgoDB.DB().Collection(engine.ColFlt).Find(v1ms.mgoDB.GetContext(), bson.D{}) + if err != nil { + return nil, err + } + } + if !(*v1ms.cursor).Next(v1ms.mgoDB.GetContext()) { + (*v1ms.cursor).Close(v1ms.mgoDB.GetContext()) + v1ms.cursor = nil + return nil, utils.ErrNoMoreData + } + v1Fltr = new(v1Filter) + if err := (*v1ms.cursor).Decode(v1Fltr); err != nil { + return nil, err + } + return +} + +//set +func (v1ms *mongoMigrator) setV1Filter(x *v1Filter) (err error) { + _, err = v1ms.mgoDB.DB().Collection(engine.ColFlt).InsertOne(v1ms.mgoDB.GetContext(), x) + return +} + +//rem +func (v1ms *mongoMigrator) remV1Filter(tenant, id string) (err error) { + _, err = v1ms.mgoDB.DB().Collection(engine.ColFlt).DeleteOne(v1ms.mgoDB.GetContext(), bson.M{"tenant": tenant, "id": id}) + return +} diff --git a/migrator/storage_redis.go b/migrator/storage_redis.go index 5931e3067..345af4cd1 100644 --- a/migrator/storage_redis.go +++ b/migrator/storage_redis.go @@ -34,7 +34,7 @@ type redisMigrator struct { } var ( - REVERSE_ALIASES_PREFIX = "rls_" + reverseAliasesPrefix = "rls_" ) func newRedisMigrator(dm *engine.DataManager) (rM *redisMigrator) { @@ -44,12 +44,12 @@ func newRedisMigrator(dm *engine.DataManager) (rM *redisMigrator) { } } -func (rdsMig *redisMigrator) close() { - rdsMig.rds.Close() +func (v1rs *redisMigrator) close() { + v1rs.rds.Close() } -func (rdsMig *redisMigrator) DataManager() *engine.DataManager { - return rdsMig.dm +func (v1rs *redisMigrator) DataManager() *engine.DataManager { + return v1rs.dm } //Account methods @@ -558,7 +558,7 @@ func (v1rs *redisMigrator) remV1Alias(key string) (err error) { for target, pairs := range value.Pairs { for _, alias := range pairs { revID := alias + target + al.Context - err = v1rs.rds.Cmd("SREM", REVERSE_ALIASES_PREFIX+revID, tmpKey).Err + err = v1rs.rds.Cmd("SREM", reverseAliasesPrefix+revID, tmpKey).Err if err != nil { return err } @@ -802,3 +802,47 @@ func (v1rs *redisMigrator) remV4AttributeProfile(tenant, id string) (err error) key := utils.AttributeProfilePrefix + utils.ConcatenatedKey(tenant, id) return v1rs.rds.Cmd("DEL", key).Err } + +// Filter Methods +//get +func (v1rs *redisMigrator) getV1Filter() (v1Fltr *v1Filter, err error) { + if v1rs.qryIdx == nil { + v1rs.dataKeys, err = v1rs.rds.GetKeysForPrefix(utils.FilterPrefix) + if err != nil { + return + } else if len(v1rs.dataKeys) == 0 { + return nil, utils.ErrNoMoreData + } + v1rs.qryIdx = utils.IntPointer(0) + } + if *v1rs.qryIdx <= len(v1rs.dataKeys)-1 { + strVal, err := v1rs.rds.Cmd("GET", v1rs.dataKeys[*v1rs.qryIdx]).Bytes() + if err != nil { + return nil, err + } + if err := v1rs.rds.Marshaler().Unmarshal(strVal, &v1Fltr); err != nil { + return nil, err + } + *v1rs.qryIdx = *v1rs.qryIdx + 1 + } else { + v1rs.qryIdx = nil + return nil, utils.ErrNoMoreData + } + return +} + +//set +func (v1rs *redisMigrator) setV1Filter(x *v1Filter) (err error) { + key := utils.FilterPrefix + utils.ConcatenatedKey(x.Tenant, x.ID) + bit, err := v1rs.rds.Marshaler().Marshal(x) + if err != nil { + return err + } + return v1rs.rds.Cmd("SET", key, bit).Err +} + +//rem +func (v1rs *redisMigrator) remV1Filter(tenant, id string) (err error) { + key := utils.FilterPrefix + utils.ConcatenatedKey(tenant, id) + return v1rs.rds.Cmd("DEL", key).Err +}