From 1fd9ac009efdc4ddbed41251d9b987b613baacb2 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 20 May 2020 10:39:05 +0300 Subject: [PATCH] Added DynamicDataProvider to AgentRequest --- agents/agentreq.go | 54 ++++--- engine/model_helpers_test.go | 258 +++++++++++++++--------------- packages/debian/changelog | 1 + utils/dataprovider.go | 7 +- utils/mapstorage_test.go | 15 +- utils/navigablemap.go | 4 +- utils/navigablemap_test.go | 46 +++--- utils/nmslice.go | 21 ++- utils/nmslice_test.go | 30 ++-- utils/orderednavigablemap.go | 3 +- utils/orderednavigablemap_test.go | 146 ++++++++--------- utils/pathitem.go | 11 +- utils/pathitem_test.go | 14 +- 13 files changed, 316 insertions(+), 294 deletions(-) diff --git a/agents/agentreq.go b/agents/agentreq.go index 4c77d1f254..fd649bf7b3 100644 --- a/agents/agentreq.go +++ b/agents/agentreq.go @@ -65,6 +65,7 @@ func NewAgentRequest(req utils.DataProvider, Trailer: trailer, Opts: opts, } + ar.dynamicProvider = utils.NewDynamicDataProvider(ar) // populate tenant if tntIf, err := ar.ParseField( &config.FCTemplate{Type: utils.META_COMPOSED, @@ -80,19 +81,20 @@ func NewAgentRequest(req utils.DataProvider, // AgentRequest represents data related to one request towards agent // implements utils.DataProvider so we can pass it to filters type AgentRequest struct { - Request utils.DataProvider // request - Vars utils.NavigableMap2 // shared data - CGRRequest *utils.OrderedNavigableMap // Used in reply to access the request that was send - CGRReply *utils.NavigableMap2 - Reply *utils.OrderedNavigableMap - Tenant string - Timezone string - filterS *engine.FilterS - Header utils.DataProvider - Trailer utils.DataProvider - diamreq *utils.OrderedNavigableMap // used in case of building requests (ie. DisconnectSession) - tmp utils.NavigableMap2 // used in case you want to store temporary items and access them later - Opts *utils.OrderedNavigableMap + Request utils.DataProvider // request + Vars utils.NavigableMap2 // shared data + CGRRequest *utils.OrderedNavigableMap // Used in reply to access the request that was send + CGRReply *utils.NavigableMap2 + Reply *utils.OrderedNavigableMap + Tenant string + Timezone string + filterS *engine.FilterS + Header utils.DataProvider + Trailer utils.DataProvider + diamreq *utils.OrderedNavigableMap // used in case of building requests (ie. DisconnectSession) + tmp utils.NavigableMap2 // used in case you want to store temporary items and access them later + Opts *utils.OrderedNavigableMap + dynamicProvider *utils.DynamicDataProvider } // String implements utils.DataProvider @@ -357,18 +359,18 @@ func (ar *AgentRequest) ParseField( out = ar.RemoteHost().String() isString = true case utils.MetaVariable, utils.META_COMPOSED, utils.MetaGroup: - out, err = cfgFld.Value.ParseDataProvider(ar, utils.NestingSep) + out, err = cfgFld.Value.ParseDataProvider(ar.dynamicProvider, utils.NestingSep) isString = true case utils.META_USAGE_DIFFERENCE: if len(cfgFld.Value) != 2 { return nil, fmt.Errorf("invalid arguments <%s> to %s", utils.ToJSON(cfgFld.Value), utils.META_USAGE_DIFFERENCE) } - strVal1, err := cfgFld.Value[0].ParseDataProvider(ar, utils.NestingSep) + strVal1, err := cfgFld.Value[0].ParseDataProvider(ar.dynamicProvider, utils.NestingSep) if err != nil { return "", err } - strVal2, err := cfgFld.Value[1].ParseDataProvider(ar, utils.NestingSep) + strVal2, err := cfgFld.Value[1].ParseDataProvider(ar.dynamicProvider, utils.NestingSep) if err != nil { return "", err } @@ -387,7 +389,7 @@ func (ar *AgentRequest) ParseField( return nil, fmt.Errorf("invalid arguments <%s> to %s", utils.ToJSON(cfgFld.Value), utils.MetaCCUsage) } - strVal1, err := cfgFld.Value[0].ParseDataProvider(ar, utils.NestingSep) // ReqNr + strVal1, err := cfgFld.Value[0].ParseDataProvider(ar.dynamicProvider, utils.NestingSep) // ReqNr if err != nil { return "", err } @@ -396,7 +398,7 @@ func (ar *AgentRequest) ParseField( return "", fmt.Errorf("invalid requestNumber <%s> to %s", strVal1, utils.MetaCCUsage) } - strVal2, err := cfgFld.Value[1].ParseDataProvider(ar, utils.NestingSep) // TotalUsage + strVal2, err := cfgFld.Value[1].ParseDataProvider(ar.dynamicProvider, utils.NestingSep) // TotalUsage if err != nil { return "", err } @@ -405,7 +407,7 @@ func (ar *AgentRequest) ParseField( return "", fmt.Errorf("invalid usedCCTime <%s> to %s", strVal2, utils.MetaCCUsage) } - strVal3, err := cfgFld.Value[2].ParseDataProvider(ar, utils.NestingSep) // DebitInterval + strVal3, err := cfgFld.Value[2].ParseDataProvider(ar.dynamicProvider, utils.NestingSep) // DebitInterval if err != nil { return "", err } @@ -422,7 +424,7 @@ func (ar *AgentRequest) ParseField( case utils.MetaSum: iFaceVals := make([]interface{}, len(cfgFld.Value)) for i, val := range cfgFld.Value { - strVal, err := val.ParseDataProvider(ar, utils.NestingSep) + strVal, err := val.ParseDataProvider(ar.dynamicProvider, utils.NestingSep) if err != nil { return "", err } @@ -432,7 +434,7 @@ func (ar *AgentRequest) ParseField( case utils.MetaDifference: iFaceVals := make([]interface{}, len(cfgFld.Value)) for i, val := range cfgFld.Value { - strVal, err := val.ParseDataProvider(ar, utils.NestingSep) + strVal, err := val.ParseDataProvider(ar.dynamicProvider, utils.NestingSep) if err != nil { return "", err } @@ -442,7 +444,7 @@ func (ar *AgentRequest) ParseField( case utils.MetaMultiply: iFaceVals := make([]interface{}, len(cfgFld.Value)) for i, val := range cfgFld.Value { - strVal, err := val.ParseDataProvider(ar, utils.NestingSep) + strVal, err := val.ParseDataProvider(ar.dynamicProvider, utils.NestingSep) if err != nil { return "", err } @@ -452,7 +454,7 @@ func (ar *AgentRequest) ParseField( case utils.MetaDivide: iFaceVals := make([]interface{}, len(cfgFld.Value)) for i, val := range cfgFld.Value { - strVal, err := val.ParseDataProvider(ar, utils.NestingSep) + strVal, err := val.ParseDataProvider(ar.dynamicProvider, utils.NestingSep) if err != nil { return "", err } @@ -464,7 +466,7 @@ func (ar *AgentRequest) ParseField( return nil, fmt.Errorf("invalid arguments <%s> to %s", utils.ToJSON(cfgFld.Value), utils.MetaValueExponent) } - strVal1, err := cfgFld.Value[0].ParseDataProvider(ar, utils.NestingSep) // String Value + strVal1, err := cfgFld.Value[0].ParseDataProvider(ar.dynamicProvider, utils.NestingSep) // String Value if err != nil { return "", err } @@ -473,7 +475,7 @@ func (ar *AgentRequest) ParseField( return "", fmt.Errorf("invalid value <%s> to %s", strVal1, utils.MetaValueExponent) } - strVal2, err := cfgFld.Value[1].ParseDataProvider(ar, utils.NestingSep) // String Exponent + strVal2, err := cfgFld.Value[1].ParseDataProvider(ar.dynamicProvider, utils.NestingSep) // String Exponent if err != nil { return "", err } @@ -484,7 +486,7 @@ func (ar *AgentRequest) ParseField( out = strconv.FormatFloat(utils.Round(val*math.Pow10(exp), config.CgrConfig().GeneralCfg().RoundingDecimals, utils.ROUNDING_MIDDLE), 'f', -1, 64) case utils.MetaUnixTimestamp: - val, err := cfgFld.Value.ParseDataProvider(ar, utils.NestingSep) + val, err := cfgFld.Value.ParseDataProvider(ar.dynamicProvider, utils.NestingSep) if err != nil { return nil, err } diff --git a/engine/model_helpers_test.go b/engine/model_helpers_test.go index c16b371d94..634e9d92f3 100644 --- a/engine/model_helpers_test.go +++ b/engine/model_helpers_test.go @@ -54,9 +54,9 @@ func TestTPDestinationAsExportSlice(t *testing.T) { Prefixes: []string{"49", "49176", "49151"}, } expectedSlc := [][]string{ - []string{"TEST_DEST", "49"}, - []string{"TEST_DEST", "49176"}, - []string{"TEST_DEST", "49151"}, + {"TEST_DEST", "49"}, + {"TEST_DEST", "49176"}, + {"TEST_DEST", "49151"}, } mdst := APItoModelDestination(tpDst) var slc [][]string @@ -76,7 +76,7 @@ func TestTpDestinationsAsTPDestinations(t *testing.T) { tpd1 := TpDestination{Tpid: "TEST_TPID", Tag: "TEST_DEST", Prefix: "+491"} tpd2 := TpDestination{Tpid: "TEST_TPID", Tag: "TEST_DEST", Prefix: "+492"} tpd3 := TpDestination{Tpid: "TEST_TPID", Tag: "TEST_DEST", Prefix: "+493"} - eTPDestinations := []*utils.TPDestination{&utils.TPDestination{TPid: "TEST_TPID", ID: "TEST_DEST", + eTPDestinations := []*utils.TPDestination{{TPid: "TEST_TPID", ID: "TEST_DEST", Prefixes: []string{"+491", "+492", "+493"}}} if tpDst := TpDestinations([]TpDestination{tpd1, tpd2, tpd3}).AsTPDestinations(); !reflect.DeepEqual(eTPDestinations, tpDst) { t.Errorf("Expecting: %+v, received: %+v", eTPDestinations, tpDst) @@ -89,13 +89,13 @@ func TestTPRateAsExportSlice(t *testing.T) { TPid: "TEST_TPID", ID: "TEST_RATEID", RateSlots: []*utils.RateSlot{ - &utils.RateSlot{ + { ConnectFee: 0.100, Rate: 0.200, RateUnit: "60", RateIncrement: "60", GroupIntervalStart: "0"}, - &utils.RateSlot{ + { ConnectFee: 0.0, Rate: 0.1, RateUnit: "1", @@ -104,8 +104,8 @@ func TestTPRateAsExportSlice(t *testing.T) { }, } expectedSlc := [][]string{ - []string{"TEST_RATEID", "0.1", "0.2", "60", "60", "0"}, - []string{"TEST_RATEID", "0", "0.1", "1", "60", "60"}, + {"TEST_RATEID", "0.1", "0.2", "60", "60", "0"}, + {"TEST_RATEID", "0", "0.1", "1", "60", "60"}, } ms := APItoModelRate(tpRate) @@ -127,12 +127,12 @@ func TestTPDestinationRateAsExportSlice(t *testing.T) { TPid: "TEST_TPID", ID: "TEST_DSTRATE", DestinationRates: []*utils.DestinationRate{ - &utils.DestinationRate{ + { DestinationId: "TEST_DEST1", RateId: "TEST_RATE1", RoundingMethod: "*up", RoundingDecimals: 4}, - &utils.DestinationRate{ + { DestinationId: "TEST_DEST2", RateId: "TEST_RATE2", RoundingMethod: "*up", @@ -140,8 +140,8 @@ func TestTPDestinationRateAsExportSlice(t *testing.T) { }, } expectedSlc := [][]string{ - []string{"TEST_DSTRATE", "TEST_DEST1", "TEST_RATE1", "*up", "4", "0", ""}, - []string{"TEST_DSTRATE", "TEST_DEST2", "TEST_RATE2", "*up", "4", "0", ""}, + {"TEST_DSTRATE", "TEST_DEST1", "TEST_RATE1", "*up", "4", "0", ""}, + {"TEST_DSTRATE", "TEST_DEST2", "TEST_RATE2", "*up", "4", "0", ""}, } ms := APItoModelDestinationRate(tpDstRate) var slc [][]string @@ -169,7 +169,7 @@ func TestApierTPTimingAsExportSlice(t *testing.T) { WeekDays: "1;2;4", Time: "00:00:01"} expectedSlc := [][]string{ - []string{"TEST_TIMING", "*any", "*any", "*any", "1;2;4", "00:00:01"}, + {"TEST_TIMING", "*any", "*any", "*any", "1;2;4", "00:00:01"}, } ms := APItoModelTiming(tpTiming) var slc [][]string @@ -190,18 +190,18 @@ func TestTPRatingPlanAsExportSlice(t *testing.T) { TPid: "TEST_TPID", ID: "TEST_RPLAN", RatingPlanBindings: []*utils.TPRatingPlanBinding{ - &utils.TPRatingPlanBinding{ + { DestinationRatesId: "TEST_DSTRATE1", TimingId: "TEST_TIMING1", Weight: 10.0}, - &utils.TPRatingPlanBinding{ + { DestinationRatesId: "TEST_DSTRATE2", TimingId: "TEST_TIMING2", Weight: 20.0}, }} expectedSlc := [][]string{ - []string{"TEST_RPLAN", "TEST_DSTRATE1", "TEST_TIMING1", "10"}, - []string{"TEST_RPLAN", "TEST_DSTRATE2", "TEST_TIMING2", "20"}, + {"TEST_RPLAN", "TEST_DSTRATE1", "TEST_TIMING1", "10"}, + {"TEST_RPLAN", "TEST_DSTRATE2", "TEST_TIMING2", "20"}, } ms := APItoModelRatingPlan(tpRpln) @@ -226,19 +226,19 @@ func TestTPRatingProfileAsExportSlice(t *testing.T) { Category: "call", Subject: "*any", RatingPlanActivations: []*utils.TPRatingActivation{ - &utils.TPRatingActivation{ + { ActivationTime: "2014-01-14T00:00:00Z", RatingPlanId: "TEST_RPLAN1", FallbackSubjects: "subj1;subj2"}, - &utils.TPRatingActivation{ + { ActivationTime: "2014-01-15T00:00:00Z", RatingPlanId: "TEST_RPLAN2", FallbackSubjects: "subj1;subj2"}, }, } expectedSlc := [][]string{ - []string{"cgrates.org", "call", "*any", "2014-01-14T00:00:00Z", "TEST_RPLAN1", "subj1;subj2"}, - []string{"cgrates.org", "call", "*any", "2014-01-15T00:00:00Z", "TEST_RPLAN2", "subj1;subj2"}, + {"cgrates.org", "call", "*any", "2014-01-14T00:00:00Z", "TEST_RPLAN1", "subj1;subj2"}, + {"cgrates.org", "call", "*any", "2014-01-15T00:00:00Z", "TEST_RPLAN2", "subj1;subj2"}, } ms := APItoModelRatingProfile(tpRpf) @@ -261,7 +261,7 @@ func TestTPActionsAsExportSlice(t *testing.T) { TPid: "TEST_TPID", ID: "TEST_ACTIONS", Actions: []*utils.TPAction{ - &utils.TPAction{ + { Identifier: "*topup_reset", BalanceType: "*monetary", Units: "5.0", @@ -273,7 +273,7 @@ func TestTPActionsAsExportSlice(t *testing.T) { BalanceWeight: "10.0", ExtraParameters: "", Weight: 10.0}, - &utils.TPAction{ + { Identifier: "*http_post", BalanceType: "", Units: "0.0", @@ -288,8 +288,8 @@ func TestTPActionsAsExportSlice(t *testing.T) { }, } expectedSlc := [][]string{ - []string{"TEST_ACTIONS", "*topup_reset", "", "", "", "*monetary", "call", "*any", "special1", "GROUP1", "*never", "", "5.0", "10.0", "", "", "10"}, - []string{"TEST_ACTIONS", "*http_post", "http://localhost/¶m1=value1", "", "", "", "", "", "", "", "", "", "0.0", "0.0", "", "", "20"}, + {"TEST_ACTIONS", "*topup_reset", "", "", "", "*monetary", "call", "*any", "special1", "GROUP1", "*never", "", "5.0", "10.0", "", "", "10"}, + {"TEST_ACTIONS", "*http_post", "http://localhost/¶m1=value1", "", "", "", "", "", "", "", "", "", "0.0", "0.0", "", "", "20"}, } ms := APItoModelAction(tpActs) @@ -313,19 +313,19 @@ func TestTPSharedGroupsAsExportSlice(t *testing.T) { TPid: "TEST_TPID", ID: "SHARED_GROUP_TEST", SharedGroups: []*utils.TPSharedGroup{ - &utils.TPSharedGroup{ + { Account: "*any", Strategy: "*highest", RatingSubject: "special1"}, - &utils.TPSharedGroup{ + { Account: "second", Strategy: "*highest", RatingSubject: "special2"}, }, } expectedSlc := [][]string{ - []string{"SHARED_GROUP_TEST", "*any", "*highest", "special1"}, - []string{"SHARED_GROUP_TEST", "second", "*highest", "special2"}, + {"SHARED_GROUP_TEST", "*any", "*highest", "special1"}, + {"SHARED_GROUP_TEST", "second", "*highest", "special2"}, } ms := APItoModelSharedGroup(tpSGs) @@ -347,19 +347,19 @@ func TestTPActionTriggersAsExportSlice(t *testing.T) { TPid: "TEST_TPID", ID: "PACKAGE_10", ActionPlan: []*utils.TPActionTiming{ - &utils.TPActionTiming{ + { ActionsId: "TOPUP_RST_10", TimingId: "ASAP", Weight: 10.0}, - &utils.TPActionTiming{ + { ActionsId: "TOPUP_RST_5", TimingId: "ASAP", Weight: 20.0}, }, } expectedSlc := [][]string{ - []string{"PACKAGE_10", "TOPUP_RST_10", "ASAP", "10"}, - []string{"PACKAGE_10", "TOPUP_RST_5", "ASAP", "20"}, + {"PACKAGE_10", "TOPUP_RST_10", "ASAP", "10"}, + {"PACKAGE_10", "TOPUP_RST_5", "ASAP", "20"}, } ms := APItoModelActionPlan(ap) var slc [][]string @@ -380,7 +380,7 @@ func TestTPActionPlanAsExportSlice(t *testing.T) { TPid: "TEST_TPID", ID: "STANDARD_TRIGGERS", ActionTriggers: []*utils.TPActionTrigger{ - &utils.TPActionTrigger{ + { Id: "STANDARD_TRIGGERS", UniqueID: "1", ThresholdType: "*min_balance", @@ -400,7 +400,7 @@ func TestTPActionPlanAsExportSlice(t *testing.T) { BalanceDisabled: "false", ActionsId: "LOG_WARNING", Weight: 10}, - &utils.TPActionTrigger{ + { Id: "STANDARD_TRIGGERS", UniqueID: "2", ThresholdType: "*max_event_counter", @@ -423,8 +423,8 @@ func TestTPActionPlanAsExportSlice(t *testing.T) { }, } expectedSlc := [][]string{ - []string{"STANDARD_TRIGGERS", "1", "*min_balance", "2", "false", "0", "", "", "b1", "*monetary", "call", "", "special1", "SHARED_1", "*never", "T1", "0.0", "false", "false", "LOG_WARNING", "10"}, - []string{"STANDARD_TRIGGERS", "2", "*max_event_counter", "5", "false", "0", "", "", "b2", "*monetary", "call", "FS_USERS", "special1", "SHARED_1", "*never", "T1", "0.0", "false", "false", "LOG_WARNING", "10"}, + {"STANDARD_TRIGGERS", "1", "*min_balance", "2", "false", "0", "", "", "b1", "*monetary", "call", "", "special1", "SHARED_1", "*never", "T1", "0.0", "false", "false", "LOG_WARNING", "10"}, + {"STANDARD_TRIGGERS", "2", "*max_event_counter", "5", "false", "0", "", "", "b2", "*monetary", "call", "FS_USERS", "special1", "SHARED_1", "*never", "T1", "0.0", "false", "false", "LOG_WARNING", "10"}, } ms := APItoModelActionTrigger(at) var slc [][]string @@ -450,7 +450,7 @@ func TestTPAccountActionsAsExportSlice(t *testing.T) { ActionTriggersId: "STANDARD_TRIGGERS", } expectedSlc := [][]string{ - []string{"cgrates.org", "1001", "PACKAGE_10_SHARED_A_5", "STANDARD_TRIGGERS", "false", "false"}, + {"cgrates.org", "1001", "PACKAGE_10_SHARED_A_5", "STANDARD_TRIGGERS", "false", "false"}, } ms := APItoModelAccountAction(aa) var slc [][]string @@ -466,7 +466,7 @@ func TestTPAccountActionsAsExportSlice(t *testing.T) { func TestTpResourcesAsTpResources(t *testing.T) { tps := []*TpResource{ - &TpResource{ + { Tpid: "TEST_TPID", Tenant: "cgrates.org", ID: "ResGroup1", @@ -477,13 +477,13 @@ func TestTpResourcesAsTpResources(t *testing.T) { Weight: 10.0, Limit: "45", ThresholdIDs: "WARN_RES1;WARN_RES1"}, - &TpResource{ + { Tpid: "TEST_TPID", ID: "ResGroup1", Tenant: "cgrates.org", FilterIDs: "FLTR_RES_GR1", ThresholdIDs: "WARN3"}, - &TpResource{ + { Tpid: "TEST_TPID", Tenant: "cgrates.org", ID: "ResGroup2", @@ -495,7 +495,7 @@ func TestTpResourcesAsTpResources(t *testing.T) { Limit: "20"}, } eTPs := []*utils.TPResourceProfile{ - &utils.TPResourceProfile{ + { TPid: tps[0].Tpid, Tenant: tps[0].Tenant, ID: tps[0].ID, @@ -509,7 +509,7 @@ func TestTpResourcesAsTpResources(t *testing.T) { Limit: tps[0].Limit, ThresholdIDs: []string{"WARN_RES1", "WARN3"}, }, - &utils.TPResourceProfile{ + { TPid: tps[2].Tpid, Tenant: tps[2].Tenant, ID: tps[2].ID, @@ -694,13 +694,13 @@ func TestAPItoTPStats(t *testing.T) { QueueLength: 100, TTL: "1s", Metrics: []*utils.MetricWithFilters{ - &utils.MetricWithFilters{ + { MetricID: "*sum#BalanceValue", }, - &utils.MetricWithFilters{ + { MetricID: "*average#BalanceValue", }, - &utils.MetricWithFilters{ + { MetricID: "*tcc", }, }, @@ -713,13 +713,13 @@ func TestAPItoTPStats(t *testing.T) { eTPs := &StatQueueProfile{ID: tps.ID, QueueLength: tps.QueueLength, Metrics: []*MetricWithFilters{ - &MetricWithFilters{ + { MetricID: "*sum#BalanceValue", }, - &MetricWithFilters{ + { MetricID: "*average#BalanceValue", }, - &MetricWithFilters{ + { MetricID: "*tcc", }, }, @@ -752,13 +752,13 @@ func TestStatQueueProfileToAPI(t *testing.T) { QueueLength: 100, TTL: "1s", Metrics: []*utils.MetricWithFilters{ - &utils.MetricWithFilters{ + { MetricID: "*sum#BalanceValue", }, - &utils.MetricWithFilters{ + { MetricID: "*average#BalanceValue", }, - &utils.MetricWithFilters{ + { MetricID: "*tcc", }, }, @@ -774,13 +774,13 @@ func TestStatQueueProfileToAPI(t *testing.T) { ActivationTime: time.Date(2014, 7, 29, 15, 0, 0, 0, time.UTC), }, Metrics: []*MetricWithFilters{ - &MetricWithFilters{ + { MetricID: "*sum#BalanceValue", }, - &MetricWithFilters{ + { MetricID: "*average#BalanceValue", }, - &MetricWithFilters{ + { MetricID: "*tcc", }, }, @@ -809,10 +809,10 @@ func TestAPItoModelStats(t *testing.T) { QueueLength: 100, TTL: "1s", Metrics: []*utils.MetricWithFilters{ - &utils.MetricWithFilters{ + { MetricID: "*tcc", }, - &utils.MetricWithFilters{ + { MetricID: "*average#Usage", }, }, @@ -855,7 +855,7 @@ func TestAPItoModelStats(t *testing.T) { func TestTPThresholdsAsTPThreshold(t *testing.T) { tps := []*TpThreshold{ - &TpThreshold{ + { Tpid: "TEST_TPID", ID: "Threhold", FilterIDs: "FilterID1;FilterID2;FilterID1;FilterID2;FilterID2", @@ -869,7 +869,7 @@ func TestTPThresholdsAsTPThreshold(t *testing.T) { }, } eTPs := []*utils.TPThresholdProfile{ - &utils.TPThresholdProfile{ + { TPid: tps[0].Tpid, ID: tps[0].ID, FilterIDs: []string{"FilterID1", "FilterID2"}, @@ -883,7 +883,7 @@ func TestTPThresholdsAsTPThreshold(t *testing.T) { Weight: tps[0].Weight, ActionIDs: []string{"WARN3"}, }, - &utils.TPThresholdProfile{ + { TPid: tps[0].Tpid, ID: tps[0].ID, FilterIDs: []string{"FilterID2", "FilterID1"}, @@ -922,7 +922,7 @@ func TestAPItoModelTPThreshold(t *testing.T) { ActionIDs: []string{"WARN3"}, } models := TpThresholds{ - &TpThreshold{ + { Tpid: "TP1", Tenant: "cgrates.org", ID: "TH_1", @@ -960,7 +960,7 @@ func TestAPItoModelTPThreshold2(t *testing.T) { ActionIDs: []string{"WARN3"}, } models := TpThresholds{ - &TpThreshold{ + { Tpid: "TP1", Tenant: "cgrates.org", ID: "TH_1", @@ -973,7 +973,7 @@ func TestAPItoModelTPThreshold2(t *testing.T) { Weight: 20.0, ActionIDs: "WARN3", }, - &TpThreshold{ + { Tpid: "TP1", Tenant: "cgrates.org", ID: "TH_1", @@ -1004,7 +1004,7 @@ func TestAPItoModelTPThreshold3(t *testing.T) { ActionIDs: []string{"WARN3", "LOG"}, } models := TpThresholds{ - &TpThreshold{ + { Tpid: "TP1", Tenant: "cgrates.org", ID: "TH_1", @@ -1017,7 +1017,7 @@ func TestAPItoModelTPThreshold3(t *testing.T) { Weight: 20.0, ActionIDs: "WARN3", }, - &TpThreshold{ + { Tpid: "TP1", Tenant: "cgrates.org", ID: "TH_1", @@ -1048,7 +1048,7 @@ func TestAPItoModelTPThreshold4(t *testing.T) { ActionIDs: []string{"WARN3", "LOG"}, } models := TpThresholds{ - &TpThreshold{ + { Tpid: "TP1", Tenant: "cgrates.org", ID: "TH_1", @@ -1060,7 +1060,7 @@ func TestAPItoModelTPThreshold4(t *testing.T) { Weight: 20.0, ActionIDs: "WARN3", }, - &TpThreshold{ + { Tpid: "TP1", Tenant: "cgrates.org", ID: "TH_1", @@ -1166,7 +1166,7 @@ func TestThresholdProfileToAPI(t *testing.T) { func TestTPFilterAsTPFilter(t *testing.T) { tps := []*TpFilter{ - &TpFilter{ + { Tpid: "TEST_TPID", ID: "Filter1", Type: utils.MetaPrefix, @@ -1175,11 +1175,11 @@ func TestTPFilterAsTPFilter(t *testing.T) { }, } eTPs := []*utils.TPFilterProfile{ - &utils.TPFilterProfile{ + { TPid: tps[0].Tpid, ID: tps[0].ID, Filters: []*utils.TPFilter{ - &utils.TPFilter{ + { Type: utils.MetaPrefix, Element: "Account", Values: []string{"1001", "1002"}, @@ -1196,7 +1196,7 @@ func TestTPFilterAsTPFilter(t *testing.T) { func TestTPFilterAsTPFilter2(t *testing.T) { tps := []*TpFilter{ - &TpFilter{ + { Tpid: "TEST_TPID", Tenant: "cgrates.org", ID: "Filter1", @@ -1204,7 +1204,7 @@ func TestTPFilterAsTPFilter2(t *testing.T) { Element: "Account", Values: "1001;1002", }, - &TpFilter{ + { Tpid: "TEST_TPID", Tenant: "anotherTenant", ID: "Filter1", @@ -1214,24 +1214,24 @@ func TestTPFilterAsTPFilter2(t *testing.T) { }, } eTPs := []*utils.TPFilterProfile{ - &utils.TPFilterProfile{ + { TPid: tps[0].Tpid, Tenant: "cgrates.org", ID: tps[0].ID, Filters: []*utils.TPFilter{ - &utils.TPFilter{ + { Type: utils.MetaPrefix, Element: "Account", Values: []string{"1001", "1002"}, }, }, }, - &utils.TPFilterProfile{ + { TPid: tps[1].Tpid, Tenant: "anotherTenant", ID: tps[1].ID, Filters: []*utils.TPFilter{ - &utils.TPFilter{ + { Type: utils.MetaPrefix, Element: "Account", Values: []string{"1010"}, @@ -1252,7 +1252,7 @@ func TestAPItoTPFilter(t *testing.T) { Tenant: "cgrates.org", ID: "Filter1", Filters: []*utils.TPFilter{ - &utils.TPFilter{ + { Element: "Account", Type: utils.MetaString, Values: []string{"1001", "1002"}, @@ -1264,7 +1264,7 @@ func TestAPItoTPFilter(t *testing.T) { Tenant: "cgrates.org", ID: tps.ID, Rules: []*FilterRule{ - &FilterRule{ + { Element: "Account", Type: utils.MetaString, Values: []string{"1001", "1002"}, @@ -1287,7 +1287,7 @@ func TestFilterToTPFilter(t *testing.T) { ExpiryTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC), }, Rules: []*FilterRule{ - &FilterRule{ + { Element: "Account", Type: utils.MetaString, Values: []string{"1001", "1002"}, @@ -1302,7 +1302,7 @@ func TestFilterToTPFilter(t *testing.T) { ExpiryTime: "2014-01-14T00:00:00Z", }, Filters: []*utils.TPFilter{ - &utils.TPFilter{ + { Element: "Account", Type: utils.MetaString, Values: []string{"1001", "1002"}, @@ -1327,7 +1327,7 @@ func TestAPItoAttributeProfile(t *testing.T) { ExpiryTime: "", }, Attributes: []*utils.TPAttribute{ - &utils.TPAttribute{ + { Path: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", }, @@ -1343,7 +1343,7 @@ func TestAPItoAttributeProfile(t *testing.T) { ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC), }, Attributes: []*Attribute{ - &Attribute{ + { Path: utils.MetaReq + utils.NestingSep + "FL1", Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, @@ -1369,7 +1369,7 @@ func TestAttributeProfileToAPI(t *testing.T) { ExpiryTime: "", }, Attributes: []*utils.TPAttribute{ - &utils.TPAttribute{ + { Path: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", }, @@ -1385,7 +1385,7 @@ func TestAttributeProfileToAPI(t *testing.T) { ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC), }, Attributes: []*Attribute{ - &Attribute{ + { Path: utils.MetaReq + utils.NestingSep + "FL1", Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, @@ -1409,11 +1409,11 @@ func TestAttributeProfileToAPI2(t *testing.T) { ExpiryTime: "", }, Attributes: []*utils.TPAttribute{ - &utils.TPAttribute{ + { Path: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", }, - &utils.TPAttribute{ + { Path: utils.MetaReq + utils.NestingSep + "Test", Value: "~*req.Account", }, @@ -1429,11 +1429,11 @@ func TestAttributeProfileToAPI2(t *testing.T) { ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC), }, Attributes: []*Attribute{ - &Attribute{ + { Path: utils.MetaReq + utils.NestingSep + "FL1", Value: config.NewRSRParsersMustCompile("Al1", true, utils.INFIELD_SEP), }, - &Attribute{ + { Path: utils.MetaReq + utils.NestingSep + "Test", Value: config.NewRSRParsersMustCompile("~*req.Account", true, utils.INFIELD_SEP), }, @@ -1457,7 +1457,7 @@ func TestAPItoModelTPAttribute(t *testing.T) { ExpiryTime: "", }, Attributes: []*utils.TPAttribute{ - &utils.TPAttribute{ + { Path: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", }, @@ -1495,11 +1495,11 @@ func TestCsvDumpForAttributeModels(t *testing.T) { ExpiryTime: "", }, Attributes: []*utils.TPAttribute{ - &utils.TPAttribute{ + { Path: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", }, - &utils.TPAttribute{ + { Path: utils.MetaReq + utils.NestingSep + "FL2", Value: "Al2", }, @@ -1567,7 +1567,7 @@ func TestModelAsTPAttribute(t *testing.T) { ExpiryTime: "", }, Attributes: []*utils.TPAttribute{ - &utils.TPAttribute{ + { FilterIDs: []string{}, Path: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", @@ -1586,7 +1586,7 @@ func TestModelAsTPAttribute(t *testing.T) { ExpiryTime: "", }, Attributes: []*utils.TPAttribute{ - &utils.TPAttribute{ + { FilterIDs: []string{}, Path: utils.MetaReq + utils.NestingSep + "FL1", Value: "Al1", @@ -1936,7 +1936,7 @@ func TestAPItoDispatcherProfile(t *testing.T) { StrategyParams: []interface{}{}, Weight: 20, Hosts: []*utils.TPDispatcherHostProfile{ - &utils.TPDispatcherHostProfile{ + { ID: "C1", FilterIDs: []string{}, Weight: 10, @@ -1988,7 +1988,7 @@ func TestDispatcherProfileToAPI(t *testing.T) { StrategyParams: []interface{}{}, Weight: 20, Hosts: []*utils.TPDispatcherHostProfile{ - &utils.TPDispatcherHostProfile{ + { ID: "C1", FilterIDs: []string{}, Weight: 10, @@ -2010,7 +2010,7 @@ func TestDispatcherProfileToAPI(t *testing.T) { StrategyParams: []interface{}{}, Weight: 20, Hosts: []*utils.TPDispatcherHostProfile{ - &utils.TPDispatcherHostProfile{ + { ID: "C1", FilterIDs: []string{}, Weight: 10, @@ -2063,14 +2063,14 @@ func TestAPItoModelTPDispatcher(t *testing.T) { StrategyParams: []interface{}{}, Weight: 20, Hosts: []*utils.TPDispatcherHostProfile{ - &utils.TPDispatcherHostProfile{ + { ID: "C1", FilterIDs: []string{}, Weight: 10, Params: []interface{}{"192.168.54.203"}, Blocker: false, }, - &utils.TPDispatcherHostProfile{ + { ID: "C2", FilterIDs: []string{}, Weight: 10, @@ -2141,11 +2141,11 @@ func TestTPDispatcherHostsAsTPDispatcherHosts(t *testing.T) { Transport: utils.EmptyString, }} eOut := []*utils.TPDispatcherHost{ - &utils.TPDispatcherHost{ + { Tenant: "Tenant1", ID: "ID1", Conns: []*utils.TPDispatcherHostConn{ - &utils.TPDispatcherHostConn{ + { Address: "Address1", Transport: "*json", }, @@ -2164,11 +2164,11 @@ func TestTPDispatcherHostsAsTPDispatcherHosts(t *testing.T) { Transport: "*gob", }} eOut = []*utils.TPDispatcherHost{ - &utils.TPDispatcherHost{ + { Tenant: "Tenant2", ID: "ID2", Conns: []*utils.TPDispatcherHostConn{ - &utils.TPDispatcherHostConn{ + { Address: "Address2", Transport: "*gob", }, @@ -2194,15 +2194,15 @@ func TestTPDispatcherHostsAsTPDispatcherHosts(t *testing.T) { }, } eOut = []*utils.TPDispatcherHost{ - &utils.TPDispatcherHost{ + { Tenant: "Tenant3", ID: "ID3", Conns: []*utils.TPDispatcherHostConn{ - &utils.TPDispatcherHostConn{ + { Address: "Address3", Transport: "*gob", }, - &utils.TPDispatcherHostConn{ + { Address: "Address4", Transport: "*json", }, @@ -2228,21 +2228,21 @@ func TestTPDispatcherHostsAsTPDispatcherHosts(t *testing.T) { }, } eOut = []*utils.TPDispatcherHost{ - &utils.TPDispatcherHost{ + { Tenant: "Tenant4", ID: "ID4", Conns: []*utils.TPDispatcherHostConn{ - &utils.TPDispatcherHostConn{ + { Address: "Address4", Transport: "*gob", }, }, }, - &utils.TPDispatcherHost{ + { Tenant: "Tenant5", ID: "ID5", Conns: []*utils.TPDispatcherHostConn{ - &utils.TPDispatcherHostConn{ + { Address: "Address5", Transport: "*json", }, @@ -2274,11 +2274,11 @@ func TestAPItoModelTPDispatcherHost(t *testing.T) { Tenant: "Tenant", ID: "ID", Conns: []*utils.TPDispatcherHostConn{ - &utils.TPDispatcherHostConn{ + { Address: "Address1", Transport: "*json", }, - &utils.TPDispatcherHostConn{ + { Address: "Address2", Transport: "*gob", }, @@ -2314,11 +2314,11 @@ func TestAPItoDispatcherHost(t *testing.T) { Tenant: "Tenant1", ID: "ID1", Conns: []*utils.TPDispatcherHostConn{ - &utils.TPDispatcherHostConn{ + { Address: "Address1", Transport: "*json", }, - &utils.TPDispatcherHostConn{ + { Address: "Address2", Transport: "*gob", }, @@ -2329,11 +2329,11 @@ func TestAPItoDispatcherHost(t *testing.T) { Tenant: "Tenant1", ID: "ID1", Conns: []*config.RemoteHost{ - &config.RemoteHost{ + { Address: "Address1", Transport: "*json", }, - &config.RemoteHost{ + { Address: "Address2", Transport: "*gob", }, @@ -2347,7 +2347,7 @@ func TestAPItoDispatcherHost(t *testing.T) { Tenant: "Tenant2", ID: "ID2", Conns: []*utils.TPDispatcherHostConn{ - &utils.TPDispatcherHostConn{ + { Address: "Address1", Transport: "*json", TLS: true, @@ -2358,7 +2358,7 @@ func TestAPItoDispatcherHost(t *testing.T) { Tenant: "Tenant2", ID: "ID2", Conns: []*config.RemoteHost{ - &config.RemoteHost{ + { Address: "Address1", Transport: "*json", TLS: true, @@ -2375,7 +2375,7 @@ func TestDispatcherHostToAPI(t *testing.T) { Tenant: "Tenant1", ID: "ID1", Conns: []*config.RemoteHost{ - &config.RemoteHost{ + { Address: "Address1", Transport: "*json", TLS: true, @@ -2386,7 +2386,7 @@ func TestDispatcherHostToAPI(t *testing.T) { Tenant: "Tenant1", ID: "ID1", Conns: []*utils.TPDispatcherHostConn{ - &utils.TPDispatcherHostConn{ + { Address: "Address1", Transport: "*json", TLS: true, @@ -2400,12 +2400,12 @@ func TestDispatcherHostToAPI(t *testing.T) { Tenant: "Tenant1", ID: "ID1", Conns: []*config.RemoteHost{ - &config.RemoteHost{ + { Address: "Address1", Transport: "*json", TLS: false, }, - &config.RemoteHost{ + { Address: "Address2", Transport: "*gob", TLS: true, @@ -2416,12 +2416,12 @@ func TestDispatcherHostToAPI(t *testing.T) { Tenant: "Tenant1", ID: "ID1", Conns: []*utils.TPDispatcherHostConn{ - &utils.TPDispatcherHostConn{ + { Address: "Address1", Transport: "*json", TLS: false, }, - &utils.TPDispatcherHostConn{ + { Address: "Address2", Transport: "*gob", TLS: true, @@ -2479,7 +2479,7 @@ func TestTPRoutesAsTPRouteProfile(t *testing.T) { }, } expPrf := []*utils.TPRouteProfile{ - &utils.TPRouteProfile{ + { TPid: "TP", Tenant: "cgrates.org", ID: "RoutePrf", @@ -2491,11 +2491,11 @@ func TestTPRoutesAsTPRouteProfile(t *testing.T) { ExpiryTime: "", }, Routes: []*utils.TPRoute{ - &utils.TPRoute{ + { ID: "route1", Weight: 10.0, }, - &utils.TPRoute{ + { ID: "route2", Weight: 20.0, }, @@ -2556,7 +2556,7 @@ func TestTPRoutesAsTPRouteProfile(t *testing.T) { }, } expPrfRev := []*utils.TPRouteProfile{ - &utils.TPRouteProfile{ + { TPid: "TP", Tenant: "cgrates.org", ID: "RoutePrf", @@ -2568,11 +2568,11 @@ func TestTPRoutesAsTPRouteProfile(t *testing.T) { ExpiryTime: "", }, Routes: []*utils.TPRoute{ - &utils.TPRoute{ + { ID: "route1", Weight: 10.0, }, - &utils.TPRoute{ + { ID: "route2", Weight: 20.0, }, diff --git a/packages/debian/changelog b/packages/debian/changelog index 86eda22fe4..ed10e5ad1a 100644 --- a/packages/debian/changelog +++ b/packages/debian/changelog @@ -62,6 +62,7 @@ cgrates (0.11.0~dev) UNRELEASED; urgency=medium * [AgentS] Added SIPAgent for SIP redirection * [AgentS] Added *constant: prefix to do not proccess the value with RSRParsers + * [AgentS] Added DynamicDataProvider to AgentRequest -- DanB Wed, 19 Feb 2020 13:25:52 +0200 diff --git a/utils/dataprovider.go b/utils/dataprovider.go index 2f46668c44..f0c12cfb93 100644 --- a/utils/dataprovider.go +++ b/utils/dataprovider.go @@ -20,6 +20,7 @@ package utils import ( "net" + "strconv" "strings" ) @@ -93,7 +94,7 @@ func AppendNavMapVal(nm navMap, fldPath *FullPath, val NMInterface) (err error) } else { indx = prevItm.Len() } - fldPath.PathItems[len(fldPath.PathItems)-1].Index = &indx + fldPath.PathItems[len(fldPath.PathItems)-1].Index = StringPointer(strconv.Itoa(indx)) _, err = nm.Set(fldPath, val) return } @@ -109,7 +110,7 @@ func ComposeNavMapVal(nm navMap, fldPath *FullPath, val NMInterface) (err error) } else { indx = prevItmSlice.Len() - 1 var prevItm NMInterface - if prevItm, err = prevItmSlice.Field(PathItems{{Index: &indx}}); err != nil { + if prevItm, err = prevItmSlice.Field(PathItems{{Index: StringPointer(strconv.Itoa(indx))}}); err != nil { if err != ErrNotFound { return } @@ -117,7 +118,7 @@ func ComposeNavMapVal(nm navMap, fldPath *FullPath, val NMInterface) (err error) return } } - fldPath.PathItems[len(fldPath.PathItems)-1].Index = &indx + fldPath.PathItems[len(fldPath.PathItems)-1].Index = StringPointer(strconv.Itoa(indx)) _, err = nm.Set(fldPath, val) return } diff --git a/utils/mapstorage_test.go b/utils/mapstorage_test.go index c007a5d03d..79754efd04 100644 --- a/utils/mapstorage_test.go +++ b/utils/mapstorage_test.go @@ -189,12 +189,12 @@ func TestNavMapFieldAsInterface(t *testing.T) { nM := MapStorage{ "FirstLevel": map[string]interface{}{ "SecondLevel": []map[string]interface{}{ - map[string]interface{}{ + { "ThirdLevel": map[string]interface{}{ "Fld1": "Val1", }, }, - map[string]interface{}{ + { "Count": 10, "ThirdLevel2": map[string]interface{}{ "Fld2": []string{"Val1", "Val2", "Val3"}, @@ -297,9 +297,10 @@ func TestNavMapGetKeys(t *testing.T) { func TestNavMapFieldAsInterface2(t *testing.T) { nM := MapStorage{ - "Slice": &[]struct{}{{}}, - "SliceString": []string{"1", "2"}, - "SliceInterface": []interface{}{1, "2"}, + "AnotherFirstLevel": "ValAnotherFirstLevel", + "Slice": &[]struct{}{{}}, + "SliceString": []string{"1", "2"}, + "SliceInterface": []interface{}{1, "2"}, } path := []string{"Slice[1]"} @@ -379,12 +380,12 @@ func TestNavMapGetField2(t *testing.T) { }, "FirstLevel2": MapStorage{ "SecondLevel2": []MapStorage{ - MapStorage{ + { "ThirdLevel2": MapStorage{ "Fld1": "Val1", }, }, - MapStorage{ + { "Count": 10, "ThirdLevel2": MapStorage{ "Fld2": []string{"Val1", "Val2", "Val3"}, diff --git a/utils/navigablemap.go b/utils/navigablemap.go index 064ccd69a4..9f4dd1afa9 100644 --- a/utils/navigablemap.go +++ b/utils/navigablemap.go @@ -58,7 +58,9 @@ func (nm NavigableMap2) Field(path PathItems) (val NMInterface, err error) { return nil, ErrNotFound case NMMapType: if path[0].Index != nil { - return nil, ErrNotFound + path[0].Field = *path[0].Index + path[0].Index = nil + return el.Field(path) } return el.Field(path[1:]) case NMSliceType: diff --git a/utils/navigablemap_test.go b/utils/navigablemap_test.go index 4619a1193b..01895d0565 100644 --- a/utils/navigablemap_test.go +++ b/utils/navigablemap_test.go @@ -68,15 +68,15 @@ func TestNavigableMap2Field(t *testing.T) { t.Errorf("Expected %q ,received: %q", "1001", val.Interface()) } - if _, err := nm.Field(PathItems{{Field: "Field1", Index: IntPointer(0)}}); err != ErrNotFound { + if _, err := nm.Field(PathItems{{Field: "Field1", Index: StringPointer("0")}}); err != ErrNotFound { t.Error(err) } - if val, err := nm.Field(PathItems{{Field: "Field5", Index: IntPointer(0)}}); err != nil { + if val, err := nm.Field(PathItems{{Field: "Field5", Index: StringPointer("0")}}); err != nil { t.Error(err) } else if val.Interface() != 10 { t.Errorf("Expected %q ,received: %q", 10, val.Interface()) } - if _, err := nm.Field(PathItems{{Field: "Field3", Index: IntPointer(0)}}); err != ErrNotFound { + if _, err := nm.Field(PathItems{{Field: "Field3", Index: StringPointer("0")}}); err != ErrNotFound { t.Error(err) } if val, err := nm.Field(PathItems{{Field: "Field3"}, {Field: "Field4"}}); err != nil { @@ -91,11 +91,11 @@ func TestNavigableMap2Set(t *testing.T) { if _, err := nm.Set(nil, nil); err != ErrWrongPath { t.Error(err) } - if _, err := nm.Set(PathItems{{Field: "Field1", Index: IntPointer(10)}}, NewNMData("1001")); err != ErrWrongPath { + if _, err := nm.Set(PathItems{{Field: "Field1", Index: StringPointer("10")}}, NewNMData("1001")); err != ErrWrongPath { t.Error(err) } expected := NavigableMap2{"Field1": &NMSlice{NewNMData("1001")}} - if _, err := nm.Set(PathItems{{Field: "Field1", Index: IntPointer(0)}}, NewNMData("1001")); err != nil { + if _, err := nm.Set(PathItems{{Field: "Field1", Index: StringPointer("0")}}, NewNMData("1001")); err != nil { t.Error(err) } else if !reflect.DeepEqual(nm, expected) { t.Errorf("Expected %s ,received: %s", expected, nm) @@ -109,14 +109,14 @@ func TestNavigableMap2Set(t *testing.T) { } else if !reflect.DeepEqual(nm, expected) { t.Errorf("Expected %s ,received: %s", expected, nm) } - if _, err := nm.Set(PathItems{{Field: "Field2", Index: IntPointer(1)}}, NewNMData("1003")); err != ErrWrongPath { + if _, err := nm.Set(PathItems{{Field: "Field2", Index: StringPointer("1")}}, NewNMData("1003")); err != ErrWrongPath { t.Error(err) } expected = NavigableMap2{ "Field1": &NMSlice{NewNMData("1001"), NewNMData("1003")}, "Field2": NewNMData("1002"), } - if _, err := nm.Set(PathItems{{Field: "Field1", Index: IntPointer(1)}}, NewNMData("1003")); err != nil { + if _, err := nm.Set(PathItems{{Field: "Field1", Index: StringPointer("1")}}, NewNMData("1003")); err != nil { t.Error(err) } else if !reflect.DeepEqual(nm, expected) { t.Errorf("Expected %s ,received: %s", expected, nm) @@ -131,7 +131,7 @@ func TestNavigableMap2Set(t *testing.T) { t.Errorf("Expected %s ,received: %s", expected, nm) } - if _, err := nm.Set(PathItems{{Field: "Field3", Index: IntPointer(10)}, {}}, NewNMData("1001")); err != ErrWrongPath { + if _, err := nm.Set(PathItems{{Field: "Field3", Index: StringPointer("10")}, {}}, NewNMData("1001")); err != ErrWrongPath { t.Error(err) } expected = NavigableMap2{ @@ -139,13 +139,13 @@ func TestNavigableMap2Set(t *testing.T) { "Field2": NewNMData("1004"), "Field3": &NMSlice{NavigableMap2{"Field4": NewNMData("1005")}}, } - if _, err := nm.Set(PathItems{{Field: "Field3", Index: IntPointer(0)}, {Field: "Field4"}}, NewNMData("1005")); err != nil { + if _, err := nm.Set(PathItems{{Field: "Field3", Index: StringPointer("0")}, {Field: "Field4"}}, NewNMData("1005")); err != nil { t.Error(err) } else if !reflect.DeepEqual(nm, expected) { t.Errorf("Expected %s ,received: %s", expected, nm) } - if _, err := nm.Set(PathItems{{Field: "Field5"}, {Field: "Field6", Index: IntPointer(10)}}, NewNMData("1006")); err != ErrWrongPath { + if _, err := nm.Set(PathItems{{Field: "Field5"}, {Field: "Field6", Index: StringPointer("10")}}, NewNMData("1006")); err != ErrWrongPath { t.Error(err) } @@ -161,7 +161,7 @@ func TestNavigableMap2Set(t *testing.T) { t.Errorf("Expected %s ,received: %s", expected, nm) } - if _, err := nm.Set(PathItems{{Field: "Field2", Index: IntPointer(0)}, {}}, NewNMData("1006")); err != ErrWrongPath { + if _, err := nm.Set(PathItems{{Field: "Field2", Index: StringPointer("0")}, {}}, NewNMData("1006")); err != ErrWrongPath { t.Error(err) } expected = NavigableMap2{ @@ -170,7 +170,7 @@ func TestNavigableMap2Set(t *testing.T) { "Field3": &NMSlice{NavigableMap2{"Field4": NewNMData("1005")}}, "Field5": NavigableMap2{"Field6": NewNMData("1006")}, } - if _, err := nm.Set(PathItems{{Field: "Field1", Index: IntPointer(2)}, {Field: "Field6"}}, NewNMData("1006")); err != nil { + if _, err := nm.Set(PathItems{{Field: "Field1", Index: StringPointer("2")}, {Field: "Field6"}}, NewNMData("1006")); err != nil { t.Error(err) } else if !reflect.DeepEqual(nm, expected) { t.Errorf("Expected %s ,received: %s", expected, nm) @@ -238,7 +238,7 @@ func TestNavigableMap2Remove(t *testing.T) { t.Error(err) } - if err := nm.Remove(PathItems{{Index: IntPointer(-1)}, {}}); err != nil { + if err := nm.Remove(PathItems{{Index: StringPointer("-1")}, {}}); err != nil { t.Error(err) } expected := NavigableMap2{ @@ -269,13 +269,13 @@ func TestNavigableMap2Remove(t *testing.T) { "Field5": &NMSlice{NewNMData(101)}, } - if err := nm.Remove(PathItems{{Field: "Field5", Index: IntPointer(0)}}); err != nil { + if err := nm.Remove(PathItems{{Field: "Field5", Index: StringPointer("0")}}); err != nil { t.Error(err) } else if !reflect.DeepEqual(nm, expected) { t.Errorf("Expected %s ,received: %s", expected, nm) } - if err := nm.Remove(PathItems{{Field: "Field1", Index: IntPointer(0)}, {}}); err != ErrWrongPath { + if err := nm.Remove(PathItems{{Field: "Field1", Index: StringPointer("0")}, {}}); err != ErrWrongPath { t.Error(err) } @@ -284,7 +284,7 @@ func TestNavigableMap2Remove(t *testing.T) { "Field3": NavigableMap2{"Field4": NewNMData("Val")}, } - if err := nm.Remove(PathItems{{Field: "Field5", Index: IntPointer(0)}}); err != nil { + if err := nm.Remove(PathItems{{Field: "Field5", Index: StringPointer("0")}}); err != nil { t.Error(err) } else if !reflect.DeepEqual(nm, expected) { t.Errorf("Expected %s ,received: %s", expected, nm) @@ -295,7 +295,7 @@ func TestNavigableMap2Remove(t *testing.T) { "Field3": NavigableMap2{"Field4": NewNMData("Val")}, "Field5": &NMSlice{NavigableMap2{"Field42": NewNMData("Val2")}}, } - if err := nm.Remove(PathItems{{Field: "Field5", Index: IntPointer(0)}, {Field: "Field42", Index: IntPointer(0)}}); err != ErrWrongPath { + if err := nm.Remove(PathItems{{Field: "Field5", Index: StringPointer("0")}, {Field: "Field42", Index: StringPointer("0")}}); err != ErrWrongPath { t.Error(err) } @@ -305,7 +305,7 @@ func TestNavigableMap2Remove(t *testing.T) { "Field3": NavigableMap2{"Field4": NewNMData("Val")}, } - if err := nm.Remove(PathItems{{Field: "Field5", Index: IntPointer(0)}, {Field: "Field42"}}); err != nil { + if err := nm.Remove(PathItems{{Field: "Field5", Index: StringPointer("0")}, {Field: "Field42"}}); err != nil { t.Error(err) } else if !reflect.DeepEqual(nm, expected) { t.Errorf("Expected %s ,received: %s", expected, nm) @@ -314,7 +314,7 @@ func TestNavigableMap2Remove(t *testing.T) { if err := nm.Remove(PathItems{{Field: "Field1"}, {}}); err != ErrWrongPath { t.Error(err) } - if err := nm.Remove(PathItems{{Field: "Field3"}, {Field: "Field4", Index: IntPointer(0)}}); err != ErrWrongPath { + if err := nm.Remove(PathItems{{Field: "Field3"}, {Field: "Field4", Index: StringPointer("0")}}); err != ErrWrongPath { t.Error(err) } expected = NavigableMap2{ @@ -357,7 +357,7 @@ func TestNavigableMap2GetSet(t *testing.T) { t.Errorf("Expected %q ,received: %q", 5, val.Interface()) } - path = PathItems{{Field: "Field2", Index: IntPointer(2)}} + path = PathItems{{Field: "Field2", Index: StringPointer("2")}} if _, err := nm.Set(path, NewNMData("500")); err != nil { t.Error(err) } @@ -367,17 +367,17 @@ func TestNavigableMap2GetSet(t *testing.T) { t.Errorf("Expected %q ,received: %q", "500", val.Interface()) } - path = PathItems{{Field: "Field2", Index: IntPointer(1)}, {Field: "Account"}} + path = PathItems{{Field: "Field2", Index: StringPointer("1")}, {Field: "Account"}} if _, err := nm.Set(path, NewNMData("5")); err != nil { t.Error(err) } - path = PathItems{{Field: "Field2", Index: IntPointer(1)}, {Field: "Account"}} + path = PathItems{{Field: "Field2", Index: StringPointer("1")}, {Field: "Account"}} if val, err := nm.Field(path); err != nil { t.Error(err) } else if val.Interface() != "5" { t.Errorf("Expected %q ,received: %q", "5", val.Interface()) } - path = PathItems{{Field: "Field2", Index: IntPointer(1)}, {Field: "Account", Index: IntPointer(0)}} + path = PathItems{{Field: "Field2", Index: StringPointer("1")}, {Field: "Account", Index: StringPointer("0")}} if _, err := nm.Field(path); err != ErrNotFound { t.Error(err) } diff --git a/utils/nmslice.go b/utils/nmslice.go index e7f6bff6be..af3b2e5624 100644 --- a/utils/nmslice.go +++ b/utils/nmslice.go @@ -18,6 +18,8 @@ along with this program. If not, see package utils +import "strconv" + // NMSlice is the basic slice of NM interface type NMSlice []NMInterface @@ -46,7 +48,10 @@ func (nms *NMSlice) Field(path PathItems) (val NMInterface, err error) { if nms.Empty() || path[0].Index == nil { return nil, ErrNotFound } - idx := *path[0].Index + var idx int + if idx, err = strconv.Atoi(*path[0].Index); err != nil { + return + } if idx < 0 { idx = len(*nms) + idx } @@ -64,7 +69,10 @@ func (nms *NMSlice) Set(path PathItems, val NMInterface) (addedNew bool, err err if len(path) == 0 || path[0].Index == nil { return false, ErrWrongPath } - idx := *path[0].Index + var idx int + if idx, err = strconv.Atoi(*path[0].Index); err != nil { + return + } if idx == len(*nms) { // append element addedNew = true if len(path) == 1 { @@ -84,7 +92,7 @@ func (nms *NMSlice) Set(path PathItems, val NMInterface) (addedNew bool, err err if idx < 0 || idx >= len(*nms) { return false, ErrWrongPath } - path[0].Index = &idx + path[0].Index = StringPointer(strconv.Itoa(idx)) if len(path) == 1 { (*nms)[idx] = val return @@ -100,14 +108,17 @@ func (nms *NMSlice) Remove(path PathItems) (err error) { if len(path) == 0 || path[0].Index == nil { return ErrWrongPath } - idx := *path[0].Index + var idx int + if idx, err = strconv.Atoi(*path[0].Index); err != nil { + return + } if idx < 0 { idx = len(*nms) + idx } if idx < 0 || idx >= len(*nms) { // already removed return } - path[0].Index = &idx + path[0].Index = StringPointer(strconv.Itoa(idx)) if len(path) == 1 { *nms = append((*nms)[:idx], (*nms)[idx+1:]...) return diff --git a/utils/nmslice_test.go b/utils/nmslice_test.go index 65564d07e6..e864bac9a5 100644 --- a/utils/nmslice_test.go +++ b/utils/nmslice_test.go @@ -57,18 +57,18 @@ func TestNMSliceField(t *testing.T) { if _, err := nm.Field(PathItems{{}}); err != ErrNotFound { t.Error(err) } - if _, err := nm.Field(PathItems{{Index: IntPointer(4)}}); err != ErrNotFound { + if _, err := nm.Field(PathItems{{Index: StringPointer("4")}}); err != ErrNotFound { t.Error(err) } if _, err := nm.Field(nil); err != ErrWrongPath { t.Error(err) } - if val, err := nm.Field(PathItems{{Field: "None", Index: IntPointer(-1)}, {Field: "Field1"}}); err != nil { + if val, err := nm.Field(PathItems{{Field: "None", Index: StringPointer("-1")}, {Field: "Field1"}}); err != nil { t.Error(err) } else if val.Interface() != "Val" { t.Errorf("Expected %q ,received: %q", "Val", val.Interface()) } - if val, err := nm.Field(PathItems{{Field: "1234", Index: IntPointer(1)}}); err != nil { + if val, err := nm.Field(PathItems{{Field: "1234", Index: StringPointer("1")}}); err != nil { t.Error(err) } else if val.Interface() != "1003" { t.Errorf("Expected %q ,received: %q", "Val", val.Interface()) @@ -81,31 +81,31 @@ func TestNMSliceSet(t *testing.T) { t.Error(err) } expected := &NMSlice{NewNMData("1001")} - if _, err := nm.Set(PathItems{{Field: "1234", Index: IntPointer(0)}}, NewNMData("1001")); err != nil { + if _, err := nm.Set(PathItems{{Field: "1234", Index: StringPointer("0")}}, NewNMData("1001")); err != nil { t.Error(err) } else if !reflect.DeepEqual(nm, expected) { t.Errorf("Expected %s ,received: %s", expected, nm) } - if _, err := nm.Set(PathItems{{Field: "1234", Index: IntPointer(1)}, {Field: "Field1", Index: IntPointer(1)}}, + if _, err := nm.Set(PathItems{{Field: "1234", Index: StringPointer("1")}, {Field: "Field1", Index: StringPointer("1")}}, NewNMData("1001")); err != ErrWrongPath { t.Error(err) } expected = &NMSlice{NewNMData("1001"), NavigableMap2{"Field1": NewNMData("1001")}} - if _, err := nm.Set(PathItems{{Field: "1234", Index: IntPointer(1)}, {Field: "Field1"}}, + if _, err := nm.Set(PathItems{{Field: "1234", Index: StringPointer("1")}, {Field: "Field1"}}, NewNMData("1001")); err != nil { t.Error(err) } else if !reflect.DeepEqual(nm, expected) { t.Errorf("Expected %s ,received: %s", expected, nm) } expected = &NMSlice{NewNMData("1001"), NewNMData("1001")} - if _, err := nm.Set(PathItems{{Field: "1234", Index: IntPointer(-1)}}, NewNMData("1001")); err != nil { + if _, err := nm.Set(PathItems{{Field: "1234", Index: StringPointer("-1")}}, NewNMData("1001")); err != nil { t.Error(err) } else if !reflect.DeepEqual(nm, expected) { t.Errorf("Expected %s ,received: %s", expected, nm) } nm = &NMSlice{&NMSlice{}} - if _, err := nm.Set(PathItems{{Field: "1234", Index: IntPointer(0)}, {}}, NewNMData("1001")); err != ErrWrongPath { + if _, err := nm.Set(PathItems{{Field: "1234", Index: StringPointer("0")}, {}}, NewNMData("1001")); err != ErrWrongPath { t.Error(err) } } @@ -156,7 +156,7 @@ func TestNMSliceRemove(t *testing.T) { t.Error(err) } - if err := nm.Remove(PathItems{{Index: IntPointer(-1)}, {}}); err != ErrWrongPath { + if err := nm.Remove(PathItems{{Index: StringPointer("-1")}, {}}); err != ErrWrongPath { t.Error(err) } expected := &NMSlice{ @@ -165,13 +165,13 @@ func TestNMSliceRemove(t *testing.T) { &NavigableMap2{"Field1": NewNMData("Val")}, } - if err := nm.Remove(PathItems{{Index: IntPointer(-1)}}); err != nil { + if err := nm.Remove(PathItems{{Index: StringPointer("-1")}}); err != nil { t.Error(err) } else if !reflect.DeepEqual(nm, expected) { t.Errorf("Expected %s ,received: %s", expected, nm) } - if err := nm.Remove(PathItems{{Index: IntPointer(1)}, {}}); err != ErrWrongPath { + if err := nm.Remove(PathItems{{Index: StringPointer("1")}, {}}); err != ErrWrongPath { t.Error(err) } @@ -179,25 +179,25 @@ func TestNMSliceRemove(t *testing.T) { NewNMData("1001"), &NavigableMap2{"Field1": NewNMData("Val")}, } - if err := nm.Remove(PathItems{{Index: IntPointer(1)}}); err != nil { + if err := nm.Remove(PathItems{{Index: StringPointer("1")}}); err != nil { t.Error(err) } else if !reflect.DeepEqual(nm, expected) { t.Errorf("Expected %s ,received: %s", expected, nm) } - if err := nm.Remove(PathItems{{Index: IntPointer(10)}}); err != nil { + if err := nm.Remove(PathItems{{Index: StringPointer("10")}}); err != nil { t.Error(err) } else if !reflect.DeepEqual(nm, expected) { t.Errorf("Expected %s ,received: %s", expected, nm) } - if err := nm.Remove(PathItems{{Index: IntPointer(1)}, {Field: "Field1", Index: IntPointer(1)}}); err != ErrWrongPath { + if err := nm.Remove(PathItems{{Index: StringPointer("1")}, {Field: "Field1", Index: StringPointer("1")}}); err != ErrWrongPath { t.Error(err) } expected = &NMSlice{ NewNMData("1001"), } - if err := nm.Remove(PathItems{{Index: IntPointer(1)}, {Field: "Field1"}}); err != nil { + if err := nm.Remove(PathItems{{Index: StringPointer("1")}, {Field: "Field1"}}); err != nil { t.Error(err) } else if !reflect.DeepEqual(nm, expected) { t.Errorf("Expected %s ,received: %s", expected, nm) diff --git a/utils/orderednavigablemap.go b/utils/orderednavigablemap.go index b782927341..5c5e018c1a 100644 --- a/utils/orderednavigablemap.go +++ b/utils/orderednavigablemap.go @@ -20,6 +20,7 @@ package utils import ( "net" + "strconv" "strings" ) @@ -108,7 +109,7 @@ func (onm *OrderedNavigableMap) Set(fullPath *FullPath, val NMInterface) (addedN pathItmsSet = make([]PathItems, len(*val.(*NMSlice))) for i := 0; i < val.Len(); i++ { pathItms := fullPath.PathItems.Clone() - pathItms[len(pathItms)-1].Index = IntPointer(i) + pathItms[len(pathItms)-1].Index = StringPointer(strconv.Itoa(i)) pathItmsSet[i] = pathItms } } else { diff --git a/utils/orderednavigablemap_test.go b/utils/orderednavigablemap_test.go index 9f7838f638..75859ec46d 100644 --- a/utils/orderednavigablemap_test.go +++ b/utils/orderednavigablemap_test.go @@ -38,11 +38,11 @@ func TestOrderedNavigableMap(t *testing.T) { onm.Set(&FullPath{ Path: "Field2[0]", - PathItems: PathItems{{Field: "Field2", Index: IntPointer(0)}}, + PathItems: PathItems{{Field: "Field2", Index: StringPointer("0")}}, }, NewNMData("1001")) expOrder = []PathItems{ PathItems{{Field: "Field1"}}, - PathItems{{Field: "Field2", Index: IntPointer(0)}}, + PathItems{{Field: "Field2", Index: StringPointer("0")}}, } if !reflect.DeepEqual(expOrder, onm.GetOrder()) { t.Errorf("Expected %s ,received: %s", expOrder, ToJSON(onm.GetOrder())) @@ -51,15 +51,15 @@ func TestOrderedNavigableMap(t *testing.T) { onm.Set(&FullPath{ Path: "Field2[1].Account[0]", PathItems: PathItems{ - {Field: "Field2", Index: IntPointer(1)}, - {Field: "Account", Index: IntPointer(0)}}, + {Field: "Field2", Index: StringPointer("1")}, + {Field: "Account", Index: StringPointer("0")}}, }, NewNMData(10)) expOrder = []PathItems{ PathItems{{Field: "Field1"}}, - PathItems{{Field: "Field2", Index: IntPointer(0)}}, + PathItems{{Field: "Field2", Index: StringPointer("0")}}, PathItems{ - {Field: "Field2", Index: IntPointer(1)}, - {Field: "Account", Index: IntPointer(0)}}, + {Field: "Field2", Index: StringPointer("1")}, + {Field: "Account", Index: StringPointer("0")}}, } if !reflect.DeepEqual(expOrder, onm.GetOrder()) { t.Errorf("Expected %s ,received: %s", expOrder, ToJSON(onm.GetOrder())) @@ -68,18 +68,18 @@ func TestOrderedNavigableMap(t *testing.T) { onm.Set(&FullPath{ Path: "Field2[1].Account[1]", PathItems: PathItems{ - {Field: "Field2", Index: IntPointer(1)}, - {Field: "Account", Index: IntPointer(1)}}, + {Field: "Field2", Index: StringPointer("1")}, + {Field: "Account", Index: StringPointer("1")}}, }, NewNMData(11)) expOrder = []PathItems{ PathItems{{Field: "Field1"}}, - PathItems{{Field: "Field2", Index: IntPointer(0)}}, + PathItems{{Field: "Field2", Index: StringPointer("0")}}, PathItems{ - {Field: "Field2", Index: IntPointer(1)}, - {Field: "Account", Index: IntPointer(0)}}, + {Field: "Field2", Index: StringPointer("1")}, + {Field: "Account", Index: StringPointer("0")}}, PathItems{ - {Field: "Field2", Index: IntPointer(1)}, - {Field: "Account", Index: IntPointer(1)}}, + {Field: "Field2", Index: StringPointer("1")}, + {Field: "Account", Index: StringPointer("1")}}, } if !reflect.DeepEqual(expOrder, onm.GetOrder()) { t.Errorf("Expected %s ,received: %s", expOrder, ToJSON(onm.GetOrder())) @@ -87,18 +87,18 @@ func TestOrderedNavigableMap(t *testing.T) { onm.Set(&FullPath{ Path: "Field2[2]", - PathItems: PathItems{{Field: "Field2", Index: IntPointer(2)}}, + PathItems: PathItems{{Field: "Field2", Index: StringPointer("2")}}, }, NewNMData(111)) expOrder = []PathItems{ PathItems{{Field: "Field1"}}, - PathItems{{Field: "Field2", Index: IntPointer(0)}}, + PathItems{{Field: "Field2", Index: StringPointer("0")}}, PathItems{ - {Field: "Field2", Index: IntPointer(1)}, - {Field: "Account", Index: IntPointer(0)}}, + {Field: "Field2", Index: StringPointer("1")}, + {Field: "Account", Index: StringPointer("0")}}, PathItems{ - {Field: "Field2", Index: IntPointer(1)}, - {Field: "Account", Index: IntPointer(1)}}, - PathItems{{Field: "Field2", Index: IntPointer(2)}}, + {Field: "Field2", Index: StringPointer("1")}, + {Field: "Account", Index: StringPointer("1")}}, + PathItems{{Field: "Field2", Index: StringPointer("2")}}, } if !reflect.DeepEqual(expOrder, onm.GetOrder()) { t.Errorf("Expected %s ,received: %s", expOrder, ToJSON(onm.GetOrder())) @@ -113,14 +113,14 @@ func TestOrderedNavigableMap(t *testing.T) { }, NewNMData(5)) expOrder = []PathItems{ PathItems{{Field: "Field1"}}, - PathItems{{Field: "Field2", Index: IntPointer(0)}}, + PathItems{{Field: "Field2", Index: StringPointer("0")}}, PathItems{ - {Field: "Field2", Index: IntPointer(1)}, - {Field: "Account", Index: IntPointer(0)}}, + {Field: "Field2", Index: StringPointer("1")}, + {Field: "Account", Index: StringPointer("0")}}, PathItems{ - {Field: "Field2", Index: IntPointer(1)}, - {Field: "Account", Index: IntPointer(1)}}, - PathItems{{Field: "Field2", Index: IntPointer(2)}}, + {Field: "Field2", Index: StringPointer("1")}, + {Field: "Account", Index: StringPointer("1")}}, + PathItems{{Field: "Field2", Index: StringPointer("2")}}, PathItems{ {Field: "Field3"}, {Field: "Field4"}, @@ -173,14 +173,14 @@ func TestOrderedNavigableMap(t *testing.T) { {Field: "Field3"}, {Field: "Field4"}, {Field: "Field5"}}, - PathItems{{Field: "Field2", Index: IntPointer(0)}}, - PathItems{{Field: "Field2", Index: IntPointer(1)}}, + PathItems{{Field: "Field2", Index: StringPointer("0")}}, + PathItems{{Field: "Field2", Index: StringPointer("1")}}, } if !reflect.DeepEqual(expOrder, onm.GetOrder()) { t.Errorf("Expected %s ,received: %s", expOrder, onm.GetOrder()) } - path = PathItems{{Field: "Field2", Index: IntPointer(0)}} + path = PathItems{{Field: "Field2", Index: StringPointer("0")}} if val, err := onm.Field(path); err != nil { t.Error(err) } else if val.Interface() != "500" { @@ -248,15 +248,15 @@ func TestOrderedNavigableMapField(t *testing.T) { t.Errorf("Expected %q ,received: %q", "1001", val.Interface()) } - if _, err := nm.Field(PathItems{{Field: "Field1", Index: IntPointer(0)}}); err != ErrNotFound { + if _, err := nm.Field(PathItems{{Field: "Field1", Index: StringPointer("0")}}); err != ErrNotFound { t.Error(err) } - if val, err := nm.Field(PathItems{{Field: "Field5", Index: IntPointer(0)}}); err != nil { + if val, err := nm.Field(PathItems{{Field: "Field5", Index: StringPointer("0")}}); err != nil { t.Error(err) } else if val.Interface() != 10 { t.Errorf("Expected %q ,received: %q", 10, val.Interface()) } - if _, err := nm.Field(PathItems{{Field: "Field3", Index: IntPointer(0)}}); err != ErrNotFound { + if _, err := nm.Field(PathItems{{Field: "Field3", Index: StringPointer("0")}}); err != ErrNotFound { t.Error(err) } if val, err := nm.Field(PathItems{{Field: "Field3"}, {Field: "Field4"}}); err != nil { @@ -298,17 +298,17 @@ func TestOrderedNavigableMapLen(t *testing.T) { func TestOrderedNavigableMapGetSet(t *testing.T) { nm := NewOrderedNavigableMap() nm.Set(&FullPath{ - PathItems: PathItems{{Field: "Account", Index: IntPointer(0)}}, + PathItems: PathItems{{Field: "Account", Index: StringPointer("0")}}, Path: "Account", }, NewNMData(1001)) nm.Set(&FullPath{ - PathItems: PathItems{{Field: "Account", Index: IntPointer(1)}}, + PathItems: PathItems{{Field: "Account", Index: StringPointer("1")}}, Path: "Account", }, NewNMData("account_on_new_branch")) expectedOrder := []PathItems{ - {{Field: "Account", Index: IntPointer(0)}}, - {{Field: "Account", Index: IntPointer(1)}}, + {{Field: "Account", Index: StringPointer("0")}}, + {{Field: "Account", Index: StringPointer("1")}}, } if recivedOrder := nm.GetOrder(); !reflect.DeepEqual(expectedOrder, recivedOrder) { @@ -346,7 +346,7 @@ func TestOrderedNavigableMapGetSet(t *testing.T) { t.Errorf("Expected %q ,received: %q", 5, val.Interface()) } - path = PathItems{{Field: "Field2", Index: IntPointer(2)}} + path = PathItems{{Field: "Field2", Index: StringPointer("2")}} if _, err := nm.Set(&FullPath{Path: path.String(), PathItems: path}, NewNMData("500")); err != nil { t.Error(err) } @@ -356,17 +356,17 @@ func TestOrderedNavigableMapGetSet(t *testing.T) { t.Errorf("Expected %q ,received: %q", "500", val.Interface()) } - path = PathItems{{Field: "Field2", Index: IntPointer(1)}, {Field: "Account"}} + path = PathItems{{Field: "Field2", Index: StringPointer("1")}, {Field: "Account"}} if _, err := nm.Set(&FullPath{Path: path.String(), PathItems: path}, NewNMData("5")); err != nil { t.Error(err) } - path = PathItems{{Field: "Field2", Index: IntPointer(1)}, {Field: "Account"}} + path = PathItems{{Field: "Field2", Index: StringPointer("1")}, {Field: "Account"}} if val, err := nm.Field(path); err != nil { t.Error(err) } else if val.Interface() != "5" { t.Errorf("Expected %q ,received: %q", "5", val.Interface()) } - path = PathItems{{Field: "Field2", Index: IntPointer(1)}, {Field: "Account", Index: IntPointer(0)}} + path = PathItems{{Field: "Field2", Index: StringPointer("1")}, {Field: "Account", Index: StringPointer("0")}} if _, err := nm.Field(path); err != ErrNotFound { t.Error(err) } @@ -423,26 +423,26 @@ func TestOrderedNavigableMapFieldAsString(t *testing.T) { func TestOrderedNavigableMapGetOrder(t *testing.T) { nm := NewOrderedNavigableMap() nm.Set(&FullPath{ - PathItems: PathItems{{Field: "Field1"}, {Field: "Field2", Index: IntPointer(0)}}, + PathItems: PathItems{{Field: "Field1"}, {Field: "Field2", Index: StringPointer("0")}}, Path: "Field1.Field2[0]", }, NewNMData("1003")) nm.Set(&FullPath{ - PathItems: PathItems{{Field: "Field1"}, {Field: "Field2", Index: IntPointer(1)}}, + PathItems: PathItems{{Field: "Field1"}, {Field: "Field2", Index: StringPointer("1")}}, Path: "Field1.Field2[1]", }, NewNMData("Val")) nm.Set(&FullPath{ - PathItems: PathItems{{Field: "Field3"}, {Field: "Field4"}, {Field: "Field5", Index: IntPointer(0)}}, + PathItems: PathItems{{Field: "Field3"}, {Field: "Field4"}, {Field: "Field5", Index: StringPointer("0")}}, Path: "Field3.Field4.Field5", }, NewNMData("1001")) nm.Set(&FullPath{ - PathItems: PathItems{{Field: "Field1"}, {Field: "Field2", Index: IntPointer(2)}}, + PathItems: PathItems{{Field: "Field1"}, {Field: "Field2", Index: StringPointer("2")}}, Path: "Field1.Field2[2]", }, NewNMData(101)) expected := []PathItems{ - {{Field: "Field1"}, {Field: "Field2", Index: IntPointer(0)}}, - {{Field: "Field1"}, {Field: "Field2", Index: IntPointer(1)}}, - {{Field: "Field3"}, {Field: "Field4"}, {Field: "Field5", Index: IntPointer(0)}}, - {{Field: "Field1"}, {Field: "Field2", Index: IntPointer(2)}}, + {{Field: "Field1"}, {Field: "Field2", Index: StringPointer("0")}}, + {{Field: "Field1"}, {Field: "Field2", Index: StringPointer("1")}}, + {{Field: "Field3"}, {Field: "Field4"}, {Field: "Field5", Index: StringPointer("0")}}, + {{Field: "Field1"}, {Field: "Field2", Index: StringPointer("2")}}, } if rply := nm.GetOrder(); !reflect.DeepEqual(rply, expected) { t.Errorf("Expected %s ,received: %s", expected, rply) @@ -457,18 +457,18 @@ func TestOrderedNavigableMapSet(t *testing.T) { t.Error(err) } if _, err := nm.Set(&FullPath{ - PathItems: PathItems{{Field: "Field1", Index: IntPointer(10)}}, + PathItems: PathItems{{Field: "Field1", Index: StringPointer("10")}}, Path: "Field1[10]", }, NewNMData("1001")); err != ErrWrongPath { t.Error(err) } if _, err := nm.Set(&FullPath{ - PathItems: PathItems{{Field: "Field1", Index: IntPointer(10)}, {Field: "Field2"}}, + PathItems: PathItems{{Field: "Field1", Index: StringPointer("10")}, {Field: "Field2"}}, Path: "Field1[10].Field2", }, NewNMData("1001")); err != ErrWrongPath { t.Error(err) } - path := PathItems{{Field: "Field1", Index: IntPointer(0)}} + path := PathItems{{Field: "Field1", Index: StringPointer("0")}} if addedNew, err := nm.Set(&FullPath{ PathItems: path, Path: path.String(), @@ -486,26 +486,26 @@ func TestOrderedNavigableMapSet(t *testing.T) { t.Errorf("Expected %s ,received: %s", order, nm.GetOrder()) } if _, err := nm.Set(&FullPath{ - PathItems: PathItems{{Field: "Field1", Index: IntPointer(0)}, {}}, + PathItems: PathItems{{Field: "Field1", Index: StringPointer("0")}, {}}, Path: "Field1[0]", }, NewNMData("1001")); err != ErrWrongPath { t.Error(err) } if _, err := nm.Set(&FullPath{ - PathItems: PathItems{{Field: "Field1", Index: IntPointer(10)}}, + PathItems: PathItems{{Field: "Field1", Index: StringPointer("10")}}, Path: "Field1[10]", }, NewNMData("1001")); err != ErrWrongPath { t.Error(err) } if _, err := nm.Set(&FullPath{ - PathItems: PathItems{{Field: "Field1", Index: IntPointer(0)}, {}}, + PathItems: PathItems{{Field: "Field1", Index: StringPointer("0")}, {}}, Path: "Field1[0]", }, &NMSlice{}); err != ErrWrongPath { t.Error(err) } if _, err := nm.Set(&FullPath{ - PathItems: PathItems{{Field: "Field1", Index: IntPointer(10)}}, + PathItems: PathItems{{Field: "Field1", Index: StringPointer("10")}}, Path: "Field[10]", }, &NMSlice{}); err != ErrWrongPath { t.Error(err) @@ -547,7 +547,7 @@ func TestOrderedNavigableMapSet(t *testing.T) { if !reflect.DeepEqual(nm.GetOrder(), order) { t.Errorf("Expected %s ,received: %s", order, nm.GetOrder()) } - path = PathItems{{Field: "Field1", Index: IntPointer(1)}} + path = PathItems{{Field: "Field1", Index: StringPointer("1")}} nMap = NavigableMap2{ "Field1": &NMSlice{NewNMData("1002"), NewNMData("1003")}, "Field2": NewNMData("1002"), @@ -574,7 +574,7 @@ func TestOrderedNavigableMapSet(t *testing.T) { "Field2": NewNMData("1002"), "Field3": obj, } - order = append(order, PathItems{{Field: "Field3", Index: IntPointer(0)}}, PathItems{{Field: "Field3", Index: IntPointer(1)}}) + order = append(order, PathItems{{Field: "Field3", Index: StringPointer("0")}}, PathItems{{Field: "Field3", Index: StringPointer("1")}}) if addedNew, err := nm.Set(&FullPath{ PathItems: path, Path: path.String(), @@ -597,10 +597,10 @@ func TestOrderedNavigableMapSet(t *testing.T) { } order = []PathItems{ {{Field: "Field2"}}, - {{Field: "Field3", Index: IntPointer(0)}}, - {{Field: "Field3", Index: IntPointer(1)}}, - {{Field: "Field1", Index: IntPointer(0)}}, - {{Field: "Field1", Index: IntPointer(1)}}, + {{Field: "Field3", Index: StringPointer("0")}}, + {{Field: "Field3", Index: StringPointer("1")}}, + {{Field: "Field1", Index: StringPointer("0")}}, + {{Field: "Field1", Index: StringPointer("1")}}, } if addedNew, err := nm.Set(&FullPath{ PathItems: PathItems{{Field: "Field1"}}, @@ -624,13 +624,13 @@ func TestOrderedNavigableMapSet(t *testing.T) { } order = []PathItems{ {{Field: "Field2"}}, - {{Field: "Field3", Index: IntPointer(0)}}, - {{Field: "Field1", Index: IntPointer(0)}}, - {{Field: "Field1", Index: IntPointer(1)}}, - {{Field: "Field3", Index: IntPointer(1)}}, + {{Field: "Field3", Index: StringPointer("0")}}, + {{Field: "Field1", Index: StringPointer("0")}}, + {{Field: "Field1", Index: StringPointer("1")}}, + {{Field: "Field3", Index: StringPointer("1")}}, } if addedNew, err := nm.Set(&FullPath{ - PathItems: PathItems{{Field: "Field3", Index: IntPointer(-1)}}, + PathItems: PathItems{{Field: "Field3", Index: StringPointer("-1")}}, Path: "Field3[-1]", }, NewNMData("1007")); err != nil { t.Error(err) @@ -673,7 +673,7 @@ func TestOrderedNavigableMapRemove(t *testing.T) { t.Error(err) } - if err := nm.Remove(&FullPath{PathItems: PathItems{{Index: IntPointer(-1)}, {}}}); err != ErrWrongPath { + if err := nm.Remove(&FullPath{PathItems: PathItems{{Index: StringPointer("-1")}, {}}}); err != ErrWrongPath { t.Error(err) } nMap := NavigableMap2{ @@ -686,8 +686,8 @@ func TestOrderedNavigableMapRemove(t *testing.T) { {{Field: "Field2"}}, {{Field: "Field3"}, {Field: "Field4"}}, {{Field: "Field1"}}, - {{Field: "Field5", Index: IntPointer(0)}}, - {{Field: "Field5", Index: IntPointer(1)}}, + {{Field: "Field5", Index: StringPointer("0")}}, + {{Field: "Field5", Index: StringPointer("1")}}, } if !reflect.DeepEqual(nm.nm, nMap) { t.Errorf("Expected %s ,received: %s", nMap, nm) @@ -703,8 +703,8 @@ func TestOrderedNavigableMapRemove(t *testing.T) { order = []PathItems{ {{Field: "Field3"}, {Field: "Field4"}}, {{Field: "Field1"}}, - {{Field: "Field5", Index: IntPointer(0)}}, - {{Field: "Field5", Index: IntPointer(1)}}, + {{Field: "Field5", Index: StringPointer("0")}}, + {{Field: "Field5", Index: StringPointer("1")}}, } if err := nm.Remove(&FullPath{PathItems: PathItems{{Field: "Field2"}}, Path: "Field2"}); err != nil { @@ -734,7 +734,7 @@ func TestOrderedNavigableMapRemove(t *testing.T) { if !reflect.DeepEqual(nm.GetOrder(), order) { t.Errorf("Expected %s ,received: %s", order, nm.GetOrder()) } - if err := nm.Remove(&FullPath{PathItems: PathItems{{Field: "Field1", Index: IntPointer(0)}, {}}}); err != ErrWrongPath { + if err := nm.Remove(&FullPath{PathItems: PathItems{{Field: "Field1", Index: StringPointer("0")}, {}}}); err != ErrWrongPath { t.Error(err) } } diff --git a/utils/pathitem.go b/utils/pathitem.go index 3d16f173f5..eeb13aae1d 100644 --- a/utils/pathitem.go +++ b/utils/pathitem.go @@ -44,7 +44,7 @@ type FullPath struct { func NewPathItems(path []string) (pItms PathItems) { pItms = make(PathItems, len(path)) for i, v := range path { - field, indx := GetPathIndex(v) + field, indx := GetPathIndexString(v) pItms[i] = PathItem{ Field: field, Index: indx, @@ -82,7 +82,7 @@ func (path PathItems) String() (out string) { // PathItem used by the NM interface to store the path information type PathItem struct { Field string - Index *int + Index *string } // Equal returns true if p==p2 @@ -102,7 +102,7 @@ func (p PathItem) Equal(p2 PathItem) bool { func (p PathItem) String() (out string) { out = p.Field if p.Index != nil { - out += IdxStart + strconv.Itoa(*p.Index) + IdxEnd + out += IdxStart + *p.Index + IdxEnd } return } @@ -114,7 +114,7 @@ func (p PathItem) Clone() (c PathItem) { // } c.Field = p.Field if p.Index != nil { - c.Index = IntPointer(*p.Index) + c.Index = StringPointer(*p.Index) } return } @@ -148,6 +148,9 @@ func GetPathWithoutIndex(spath string) (opath string) { return } +// GetPathIndexString returns the path and index as string if index present +// path[index]=>path,index +// path=>path,nil func GetPathIndexString(spath string) (opath string, idx *string) { idxStart := strings.Index(spath, IdxStart) if idxStart == -1 || !strings.HasSuffix(spath, IdxEnd) { diff --git a/utils/pathitem_test.go b/utils/pathitem_test.go index b9bffe3004..20290af13f 100644 --- a/utils/pathitem_test.go +++ b/utils/pathitem_test.go @@ -56,7 +56,7 @@ func TestStripIdxFromLastPathElm(t *testing.T) { func TestNewPathItems(t *testing.T) { pathSlice := strings.Split("*req.Field1[0].Account", NestingSep) - expected := PathItems{{Field: MetaReq}, {Field: "Field1", Index: IntPointer(0)}, {Field: Account}} + expected := PathItems{{Field: MetaReq}, {Field: "Field1", Index: StringPointer("0")}, {Field: Account}} if rply := NewPathItems(pathSlice); !reflect.DeepEqual(expected, rply) { t.Errorf("Expected: %s, received: %s", ToJSON(expected), ToJSON(rply)) } @@ -73,7 +73,7 @@ func TestPathItemString(t *testing.T) { if rply := path.String(); expected != rply { t.Errorf("Expected: %q, received: %q", expected, rply) } - path = PathItem{Field: MetaReq, Index: IntPointer(10)} + path = PathItem{Field: MetaReq, Index: StringPointer("10")} expected = MetaReq + "[10]" if rply := path.String(); expected != rply { t.Errorf("Expected: %q, received: %q", expected, rply) @@ -90,21 +90,21 @@ func TestPathItemEqual(t *testing.T) { if path.Equal(p1) { t.Errorf("Expected %s to not be equal to %s", ToJSON(path), ToJSON(p1)) } - p1 = PathItem{Field: MetaReq, Index: IntPointer(0)} + p1 = PathItem{Field: MetaReq, Index: StringPointer("0")} if path.Equal(p1) { t.Errorf("Expected %s to not be equal to %s", ToJSON(path), ToJSON(p1)) } - path = PathItem{Field: MetaReq, Index: IntPointer(0)} + path = PathItem{Field: MetaReq, Index: StringPointer("0")} if !path.Equal(p1) { t.Errorf("Expected %s to be equal to %s", ToJSON(path), ToJSON(p1)) } } func TestPathItemClone(t *testing.T) { - path := PathItem{Field: MetaReq, Index: IntPointer(0)} - expected := PathItem{Field: MetaReq, Index: IntPointer(0)} + path := PathItem{Field: MetaReq, Index: StringPointer("0")} + expected := PathItem{Field: MetaReq, Index: StringPointer("0")} rply := path.Clone() - *path.Index = 1 + *path.Index = "1" if !reflect.DeepEqual(expected, rply) { t.Errorf("Expected: %s, received: %s", ToJSON(expected), ToJSON(rply)) }