From 7dcc1688929c2351c332d93e9e1799b66e73d395 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 11 Jan 2021 18:14:31 +0200 Subject: [PATCH] Updated engine integration tests --- dispatchers/dispatchers.go | 2 +- dispatchers/utils.go | 6 +- engine/loader_csv_test.go | 62 ++++----- engine/model_helpers.go | 252 +++++++++++------------------------ engine/model_helpers_test.go | 10 +- engine/z_stordb_it_test.go | 116 +++++++++------- utils/orderednavigablemap.go | 1 + 7 files changed, 181 insertions(+), 268 deletions(-) diff --git a/dispatchers/dispatchers.go b/dispatchers/dispatchers.go index 5353a7438..6f5fb9611 100755 --- a/dispatchers/dispatchers.go +++ b/dispatchers/dispatchers.go @@ -96,7 +96,7 @@ func (dS *DispatcherService) authorize(method, tenant string, apiKey string, evT if apiMethods, err = rplyEv.CGREvent.FieldAsString(utils.APIMethods); err != nil { return } - if !ParseStringMap(apiMethods).HasKey(method) { + if !ParseStringSet(apiMethods).Has(method) { return utils.ErrUnauthorizedApi } return diff --git a/dispatchers/utils.go b/dispatchers/utils.go index ed5487342..bbfb7b363 100755 --- a/dispatchers/utils.go +++ b/dispatchers/utils.go @@ -57,11 +57,11 @@ type ArgStartServiceWithOpts struct { servmanager.ArgStartService } -func ParseStringMap(s string) utils.StringMap { +func ParseStringSet(s string) utils.StringSet { if s == utils.MetaZero { - return make(utils.StringMap) + return make(utils.StringSet) } - return utils.StringMapFromSlice(strings.Split(s, utils.ANDSep)) + return utils.NewStringSet(strings.Split(s, utils.ANDSep)) } type RatingPlanCost struct { diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 3ff77f21a..cbcea1a6b 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -960,6 +960,7 @@ func TestLoadResourceProfiles(t *testing.T) { Limit: "2", Blocker: true, Stored: true, + ThresholdIDs: make([]string, 0), }, {Tenant: "cgrates.org", ID: "ResGroup22"}: { TPid: testTPID, @@ -975,13 +976,14 @@ func TestLoadResourceProfiles(t *testing.T) { Stored: true, Weight: 10, Limit: "2", + ThresholdIDs: make([]string, 0), }, } resKey := utils.TenantID{Tenant: "cgrates.org", ID: "ResGroup21"} if len(csvr.resProfiles) != len(eResProfiles) { t.Errorf("Failed to load ResourceProfiles: %s", utils.ToIJSON(csvr.resProfiles)) } else if !reflect.DeepEqual(eResProfiles[resKey], csvr.resProfiles[resKey]) { - t.Errorf("Expecting: %+v, received: %+v", eResProfiles[resKey], csvr.resProfiles[resKey]) + t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eResProfiles[resKey]), utils.ToJSON(csvr.resProfiles[resKey])) } } @@ -1485,17 +1487,17 @@ func TestLoadActionProfiles(t *testing.T) { TPid: testTPID, Tenant: "cgrates.org", ID: "ONE_TIME_ACT", - FilterIDs: nil, + FilterIDs: make([]string, 0), Weight: 10, Schedule: utils.MetaASAP, Targets: []*utils.TPActionTarget{ - &utils.TPActionTarget{ + { TargetType: utils.MetaAccounts, TargetIDs: []string{"1001", "1002"}, }, }, Actions: []*utils.TPAPAction{ - &utils.TPAPAction{ + { ID: "TOPUP", FilterIDs: []string{}, TTL: "0s", @@ -1503,7 +1505,7 @@ func TestLoadActionProfiles(t *testing.T) { Path: "~*balance.TestBalance.Value", Value: "10", }, - &utils.TPAPAction{ + { ID: "SET_BALANCE_TEST_DATA", FilterIDs: []string{}, TTL: "0s", @@ -1511,7 +1513,7 @@ func TestLoadActionProfiles(t *testing.T) { Path: "~*balance.TestDataBalance.Type", Value: "*data", }, - &utils.TPAPAction{ + { ID: "TOPUP_TEST_DATA", FilterIDs: []string{}, TTL: "0s", @@ -1519,7 +1521,7 @@ func TestLoadActionProfiles(t *testing.T) { Path: "~*balance.TestDataBalance.Value", Value: "1024", }, - &utils.TPAPAction{ + { ID: "SET_BALANCE_TEST_VOICE", FilterIDs: []string{}, TTL: "0s", @@ -1527,7 +1529,7 @@ func TestLoadActionProfiles(t *testing.T) { Path: "~*balance.TestVoiceBalance.Type", Value: "*voice", }, - &utils.TPAPAction{ + { ID: "TOPUP_TEST_VOICE", FilterIDs: []string{}, TTL: "0s", @@ -1584,14 +1586,8 @@ func TestLoadDispatcherHosts(t *testing.T) { func TestLoadResource(t *testing.T) { eResources := []*utils.TenantID{ - { - Tenant: "cgrates.org", - ID: "ResGroup21", - }, - { - Tenant: "cgrates.org", - ID: "ResGroup22", - }, + {Tenant: "cgrates.org", ID: "ResGroup21"}, + {Tenant: "cgrates.org", ID: "ResGroup22"}, } if len(csvr.resources) != len(eResources) { t.Errorf("Failed to load resources expecting 2 but received : %+v", len(csvr.resources)) @@ -1600,14 +1596,8 @@ func TestLoadResource(t *testing.T) { func TestLoadstatQueues(t *testing.T) { eStatQueues := []*utils.TenantID{ - { - Tenant: "cgrates.org", - ID: "TestStats", - }, - { - Tenant: "cgrates.org", - ID: "TestStats2", - }, + {Tenant: "cgrates.org", ID: "TestStats"}, + {Tenant: "cgrates.org", ID: "TestStats2"}, } if len(csvr.statQueues) != len(eStatQueues) { t.Errorf("Failed to load statQueues: %s", utils.ToIJSON(csvr.statQueues)) @@ -1616,10 +1606,7 @@ func TestLoadstatQueues(t *testing.T) { func TestLoadThresholds(t *testing.T) { eThresholds := []*utils.TenantID{ - { - Tenant: "cgrates.org", - ID: "Threshold1", - }, + {Tenant: "cgrates.org", ID: "Threshold1"}, } if len(csvr.thresholds) != len(eThresholds) { t.Errorf("Failed to load thresholds: %s", utils.ToIJSON(csvr.thresholds)) @@ -1628,18 +1615,19 @@ func TestLoadThresholds(t *testing.T) { func TestLoadAccountProfiles(t *testing.T) { expected := &utils.TPAccountProfile{ - TPid: testTPID, - Tenant: "cgrates.org", - ID: "1001", - Weight: 20, + TPid: testTPID, + Tenant: "cgrates.org", + ID: "1001", + FilterIDs: make([]string, 0), + Weight: 20, Balances: map[string]*utils.TPAccountBalance{ - "MonetaryBalance": &utils.TPAccountBalance{ + "MonetaryBalance": { ID: "MonetaryBalance", FilterIDs: []string{}, Weight: 10, Type: utils.MetaMonetary, CostIncrement: []*utils.TPBalanceCostIncrement{ - &utils.TPBalanceCostIncrement{ + { FilterIDs: []string{"fltr1", "fltr2"}, Increment: utils.Float64Pointer(1.3), FixedFee: utils.Float64Pointer(2.3), @@ -1648,18 +1636,18 @@ func TestLoadAccountProfiles(t *testing.T) { }, CostAttributes: []string{"attr1", "attr2"}, UnitFactors: []*utils.TPBalanceUnitFactor{ - &utils.TPBalanceUnitFactor{ + { FilterIDs: []string{"fltr1", "fltr2"}, Factor: 100, }, - &utils.TPBalanceUnitFactor{ + { FilterIDs: []string{"fltr3"}, Factor: 200, }, }, Units: 14, }, - "VoiceBalance": &utils.TPAccountBalance{ + "VoiceBalance": { ID: "VoiceBalance", FilterIDs: []string{}, Weight: 10, diff --git a/engine/model_helpers.go b/engine/model_helpers.go index aeb9c2f72..e7b8b6da6 100644 --- a/engine/model_helpers.go +++ b/engine/model_helpers.go @@ -1052,8 +1052,8 @@ func (tps ResourceMdls) CSVHeader() (result []string) { func (tps ResourceMdls) AsTPResources() (result []*utils.TPResourceProfile) { mrl := make(map[string]*utils.TPResourceProfile) - filterMap := make(map[string]utils.StringMap) - thresholdMap := make(map[string]utils.StringMap) + filterMap := make(map[string]utils.StringSet) + thresholdMap := make(map[string]utils.StringSet) for _, tp := range tps { tenID := (&utils.TenantID{Tenant: tp.Tenant, ID: tp.ID}).TenantID() rl, found := mrl[tenID] @@ -1092,21 +1092,15 @@ func (tps ResourceMdls) AsTPResources() (result []*utils.TPResourceProfile) { } if tp.ThresholdIDs != utils.EmptyString { if _, has := thresholdMap[tenID]; !has { - thresholdMap[tenID] = make(utils.StringMap) - } - trshSplt := strings.Split(tp.ThresholdIDs, utils.InfieldSep) - for _, trsh := range trshSplt { - thresholdMap[tenID][trsh] = true + thresholdMap[tenID] = make(utils.StringSet) } + thresholdMap[tenID].AddSlice(strings.Split(tp.ThresholdIDs, utils.InfieldSep)) } if tp.FilterIDs != utils.EmptyString { if _, has := filterMap[tenID]; !has { - filterMap[tenID] = make(utils.StringMap) - } - filterSplit := strings.Split(tp.FilterIDs, utils.InfieldSep) - for _, filter := range filterSplit { - filterMap[tenID][filter] = true + filterMap[tenID] = make(utils.StringSet) } + filterMap[tenID].AddSlice(strings.Split(tp.FilterIDs, utils.InfieldSep)) } mrl[tenID] = rl } @@ -1114,12 +1108,8 @@ func (tps ResourceMdls) AsTPResources() (result []*utils.TPResourceProfile) { i := 0 for tntID, rl := range mrl { result[i] = rl - for filter := range filterMap[tntID] { - result[i].FilterIDs = append(result[i].FilterIDs, filter) - } - for threshold := range thresholdMap[tntID] { - result[i].ThresholdIDs = append(result[i].ThresholdIDs, threshold) - } + result[i].FilterIDs = filterMap[tntID].AsSlice() + result[i].ThresholdIDs = thresholdMap[tntID].AsSlice() i++ } return @@ -1271,8 +1261,8 @@ func (tps StatMdls) CSVHeader() (result []string) { } func (models StatMdls) AsTPStats() (result []*utils.TPStatProfile) { - filterMap := make(map[string]utils.StringMap) - thresholdMap := make(map[string]utils.StringMap) + filterMap := make(map[string]utils.StringSet) + thresholdMap := make(map[string]utils.StringSet) statMetricsMap := make(map[string]map[string]*utils.MetricWithFilters) mst := make(map[string]*utils.TPStatProfile) for _, model := range models { @@ -1311,12 +1301,9 @@ func (models StatMdls) AsTPStats() (result []*utils.TPStatProfile) { } if model.ThresholdIDs != utils.EmptyString { if _, has := thresholdMap[key.TenantID()]; !has { - thresholdMap[key.TenantID()] = make(utils.StringMap) - } - trshSplt := strings.Split(model.ThresholdIDs, utils.InfieldSep) - for _, trsh := range trshSplt { - thresholdMap[key.TenantID()][trsh] = true + thresholdMap[key.TenantID()] = make(utils.StringSet) } + thresholdMap[key.TenantID()].AddSlice(strings.Split(model.ThresholdIDs, utils.InfieldSep)) } if len(model.ActivationInterval) != 0 { st.ActivationInterval = new(utils.TPActivationInterval) @@ -1330,12 +1317,9 @@ func (models StatMdls) AsTPStats() (result []*utils.TPStatProfile) { } if model.FilterIDs != utils.EmptyString { if _, has := filterMap[key.TenantID()]; !has { - filterMap[key.TenantID()] = make(utils.StringMap) - } - filterSplit := strings.Split(model.FilterIDs, utils.InfieldSep) - for _, filter := range filterSplit { - filterMap[key.TenantID()][filter] = true + filterMap[key.TenantID()] = make(utils.StringSet) } + filterMap[key.TenantID()].AddSlice(strings.Split(model.FilterIDs, utils.InfieldSep)) } if model.MetricIDs != utils.EmptyString { if _, has := statMetricsMap[key.TenantID()]; !has { @@ -1362,12 +1346,8 @@ func (models StatMdls) AsTPStats() (result []*utils.TPStatProfile) { i := 0 for tntID, st := range mst { result[i] = st - for filter := range filterMap[tntID] { - result[i].FilterIDs = append(result[i].FilterIDs, filter) - } - for threshold := range thresholdMap[tntID] { - result[i].ThresholdIDs = append(result[i].ThresholdIDs, threshold) - } + result[i].FilterIDs = filterMap[tntID].AsSlice() + result[i].ThresholdIDs = thresholdMap[tntID].AsSlice() for _, metric := range statMetricsMap[tntID] { result[i].Metrics = append(result[i].Metrics, metric) } @@ -1521,8 +1501,8 @@ func (tps ThresholdMdls) CSVHeader() (result []string) { func (tps ThresholdMdls) AsTPThreshold() (result []*utils.TPThresholdProfile) { mst := make(map[string]*utils.TPThresholdProfile) - filterMap := make(map[string]utils.StringMap) - actionMap := make(map[string]utils.StringMap) + filterMap := make(map[string]utils.StringSet) + actionMap := make(map[string]utils.StringSet) for _, tp := range tps { tenID := (&utils.TenantID{Tenant: tp.Tenant, ID: tp.ID}).TenantID() th, found := mst[tenID] @@ -1540,12 +1520,9 @@ func (tps ThresholdMdls) AsTPThreshold() (result []*utils.TPThresholdProfile) { } if tp.ActionIDs != utils.EmptyString { if _, has := actionMap[tenID]; !has { - actionMap[tenID] = make(utils.StringMap) - } - actionSplit := strings.Split(tp.ActionIDs, utils.InfieldSep) - for _, action := range actionSplit { - actionMap[tenID][action] = true + actionMap[tenID] = make(utils.StringSet) } + actionMap[tenID].AddSlice(strings.Split(tp.ActionIDs, utils.InfieldSep)) } if tp.Weight != 0 { th.Weight = tp.Weight @@ -1562,12 +1539,9 @@ func (tps ThresholdMdls) AsTPThreshold() (result []*utils.TPThresholdProfile) { } if tp.FilterIDs != utils.EmptyString { if _, has := filterMap[tenID]; !has { - filterMap[tenID] = make(utils.StringMap) - } - filterSplit := strings.Split(tp.FilterIDs, utils.InfieldSep) - for _, filter := range filterSplit { - filterMap[tenID][filter] = true + filterMap[tenID] = make(utils.StringSet) } + filterMap[tenID].AddSlice(strings.Split(tp.FilterIDs, utils.InfieldSep)) } mst[tenID] = th @@ -1576,12 +1550,8 @@ func (tps ThresholdMdls) AsTPThreshold() (result []*utils.TPThresholdProfile) { i := 0 for tntID, th := range mst { result[i] = th - for filter := range filterMap[tntID] { - result[i].FilterIDs = append(result[i].FilterIDs, filter) - } - for action := range actionMap[tntID] { - result[i].ActionIDs = append(result[i].ActionIDs, action) - } + result[i].FilterIDs = filterMap[tntID].AsSlice() + result[i].ActionIDs = actionMap[tntID].AsSlice() i++ } return @@ -1874,10 +1844,10 @@ func (tps RouteMdls) CSVHeader() (result []string) { } func (tps RouteMdls) AsTPRouteProfile() (result []*utils.TPRouteProfile) { - filterMap := make(map[string]utils.StringMap) + filterMap := make(map[string]utils.StringSet) mst := make(map[string]*utils.TPRouteProfile) routeMap := make(map[string]map[string]*utils.TPRoute) - sortingParameterMap := make(map[string]utils.StringMap) + sortingParameterMap := make(map[string]utils.StringSet) for _, tp := range tps { tenID := (&utils.TenantID{Tenant: tp.Tenant, ID: tp.ID}).TenantID() th, found := mst[tenID] @@ -1938,12 +1908,9 @@ func (tps RouteMdls) AsTPRouteProfile() (result []*utils.TPRouteProfile) { } if tp.SortingParameters != utils.EmptyString { if _, has := sortingParameterMap[tenID]; !has { - sortingParameterMap[tenID] = make(utils.StringMap) - } - sortingParamSplit := strings.Split(tp.SortingParameters, utils.InfieldSep) - for _, sortingParam := range sortingParamSplit { - sortingParameterMap[tenID][sortingParam] = true + sortingParameterMap[tenID] = make(utils.StringSet) } + sortingParameterMap[tenID].AddSlice(strings.Split(tp.SortingParameters, utils.InfieldSep)) } if tp.Weight != 0 { th.Weight = tp.Weight @@ -1960,12 +1927,9 @@ func (tps RouteMdls) AsTPRouteProfile() (result []*utils.TPRouteProfile) { } if tp.FilterIDs != utils.EmptyString { if _, has := filterMap[tenID]; !has { - filterMap[tenID] = make(utils.StringMap) - } - filterSplit := strings.Split(tp.FilterIDs, utils.InfieldSep) - for _, filter := range filterSplit { - filterMap[tenID][filter] = true + filterMap[tenID] = make(utils.StringSet) } + filterMap[tenID].AddSlice(strings.Split(tp.FilterIDs, utils.InfieldSep)) } mst[tenID] = th } @@ -1976,12 +1940,8 @@ func (tps RouteMdls) AsTPRouteProfile() (result []*utils.TPRouteProfile) { for _, supData := range routeMap[tntID] { result[i].Routes = append(result[i].Routes, supData) } - for filterData := range filterMap[tntID] { - result[i].FilterIDs = append(result[i].FilterIDs, filterData) - } - for sortingParam := range sortingParameterMap[tntID] { - result[i].SortingParameters = append(result[i].SortingParameters, sortingParam) - } + result[i].FilterIDs = filterMap[tntID].AsSlice() + result[i].SortingParameters = sortingParameterMap[tntID].AsSlice() i++ } return @@ -2157,8 +2117,8 @@ func (tps AttributeMdls) CSVHeader() (result []string) { func (tps AttributeMdls) AsTPAttributes() (result []*utils.TPAttributeProfile) { mst := make(map[string]*utils.TPAttributeProfile) - filterMap := make(map[string]utils.StringMap) - contextMap := make(map[string]utils.StringMap) + filterMap := make(map[string]utils.StringSet) + contextMap := make(map[string]utils.StringSet) for _, tp := range tps { key := &utils.TenantID{Tenant: tp.Tenant, ID: tp.ID} tenID := (&utils.TenantID{Tenant: tp.Tenant, ID: tp.ID}).TenantID() @@ -2186,21 +2146,15 @@ func (tps AttributeMdls) AsTPAttributes() (result []*utils.TPAttributeProfile) { } if tp.FilterIDs != utils.EmptyString { if _, has := filterMap[key.TenantID()]; !has { - filterMap[key.TenantID()] = make(utils.StringMap) - } - filterSplit := strings.Split(tp.FilterIDs, utils.InfieldSep) - for _, filter := range filterSplit { - filterMap[key.TenantID()][filter] = true + filterMap[key.TenantID()] = make(utils.StringSet) } + filterMap[key.TenantID()].AddSlice(strings.Split(tp.FilterIDs, utils.InfieldSep)) } if tp.Contexts != utils.EmptyString { if _, has := contextMap[tenID]; !has { - contextMap[key.TenantID()] = make(utils.StringMap) - } - contextSplit := strings.Split(tp.Contexts, utils.InfieldSep) - for _, context := range contextSplit { - contextMap[key.TenantID()][context] = true + contextMap[key.TenantID()] = make(utils.StringSet) } + contextMap[key.TenantID()].AddSlice(strings.Split(tp.Contexts, utils.InfieldSep)) } if tp.Path != utils.EmptyString { filterIDs := make([]string, 0) @@ -2223,12 +2177,8 @@ func (tps AttributeMdls) AsTPAttributes() (result []*utils.TPAttributeProfile) { i := 0 for tntID, th := range mst { result[i] = th - for filterID := range filterMap[tntID] { - result[i].FilterIDs = append(result[i].FilterIDs, filterID) - } - for context := range contextMap[tntID] { - result[i].Contexts = append(result[i].Contexts, context) - } + result[i].FilterIDs = filterMap[tntID].AsSlice() + result[i].Contexts = contextMap[tntID].AsSlice() i++ } return @@ -2269,16 +2219,11 @@ func APItoModelTPAttribute(th *utils.TPAttributeProfile) (mdls AttributeMdls) { if th.Weight != 0 { mdl.Weight = th.Weight } - for i, val := range reqAttribute.FilterIDs { - if i != 0 { - mdl.AttributeFilterIDs += utils.InfieldSep - } - mdl.AttributeFilterIDs += val - } } mdl.Path = reqAttribute.Path mdl.Value = reqAttribute.Value mdl.Type = reqAttribute.Type + mdl.AttributeFilterIDs = strings.Join(reqAttribute.FilterIDs, utils.InfieldSep) mdls = append(mdls, mdl) } return @@ -2370,7 +2315,7 @@ func (tps ChargerMdls) CSVHeader() (result []string) { func (tps ChargerMdls) AsTPChargers() (result []*utils.TPChargerProfile) { mst := make(map[string]*utils.TPChargerProfile) - filterMap := make(map[string]utils.StringMap) + filterMap := make(map[string]utils.StringSet) attributeMap := make(map[string][]string) for _, tp := range tps { tntID := (&utils.TenantID{Tenant: tp.Tenant, ID: tp.ID}).TenantID() @@ -2397,12 +2342,9 @@ func (tps ChargerMdls) AsTPChargers() (result []*utils.TPChargerProfile) { } if tp.FilterIDs != utils.EmptyString { if _, has := filterMap[tntID]; !has { - filterMap[tntID] = make(utils.StringMap) - } - filterSplit := strings.Split(tp.FilterIDs, utils.InfieldSep) - for _, filter := range filterSplit { - filterMap[tntID][filter] = true + filterMap[tntID] = make(utils.StringSet) } + filterMap[tntID].AddSlice(strings.Split(tp.FilterIDs, utils.InfieldSep)) } if tp.RunID != utils.EmptyString { tpCPP.RunID = tp.RunID @@ -2432,10 +2374,7 @@ func (tps ChargerMdls) AsTPChargers() (result []*utils.TPChargerProfile) { i := 0 for tntID, tp := range mst { result[i] = tp - result[i].FilterIDs = make([]string, 0, len(filterMap[tntID])) - for filterID := range filterMap[tntID] { - result[i].FilterIDs = append(result[i].FilterIDs, filterID) - } + result[i].FilterIDs = filterMap[tntID].AsSlice() result[i].AttributeIDs = make([]string, 0, len(attributeMap[tntID])) for _, attributeID := range attributeMap[tntID] { result[i].AttributeIDs = append(result[i].AttributeIDs, attributeID) @@ -2588,10 +2527,10 @@ func (tps DispatcherProfileMdls) CSVHeader() (result []string) { func (tps DispatcherProfileMdls) AsTPDispatcherProfiles() (result []*utils.TPDispatcherProfile) { mst := make(map[string]*utils.TPDispatcherProfile) - filterMap := make(map[string]utils.StringMap) - contextMap := make(map[string]utils.StringMap) + filterMap := make(map[string]utils.StringSet) + contextMap := make(map[string]utils.StringSet) connsMap := make(map[string]map[string]utils.TPDispatcherHostProfile) - connsFilterMap := make(map[string]map[string]utils.StringMap) + connsFilterMap := make(map[string]map[string]utils.StringSet) for _, tp := range tps { tenantID := (&utils.TenantID{Tenant: tp.Tenant, ID: tp.ID}).TenantID() tpDPP, found := mst[tenantID] @@ -2604,21 +2543,15 @@ func (tps DispatcherProfileMdls) AsTPDispatcherProfiles() (result []*utils.TPDis } if tp.Subsystems != utils.EmptyString { if _, has := contextMap[tenantID]; !has { - contextMap[tenantID] = make(utils.StringMap) - } - contextSplit := strings.Split(tp.Subsystems, utils.InfieldSep) - for _, context := range contextSplit { - contextMap[tenantID][context] = true + contextMap[tenantID] = make(utils.StringSet) } + contextMap[tenantID].AddSlice(strings.Split(tp.Subsystems, utils.InfieldSep)) } if tp.FilterIDs != utils.EmptyString { if _, has := filterMap[tenantID]; !has { - filterMap[tenantID] = make(utils.StringMap) - } - filterSplit := strings.Split(tp.FilterIDs, utils.InfieldSep) - for _, filter := range filterSplit { - filterMap[tenantID][filter] = true + filterMap[tenantID] = make(utils.StringSet) } + filterMap[tenantID].AddSlice(strings.Split(tp.FilterIDs, utils.InfieldSep)) } if len(tp.ActivationInterval) != 0 { tpDPP.ActivationInterval = new(utils.TPActivationInterval) @@ -2656,14 +2589,13 @@ func (tps DispatcherProfileMdls) AsTPDispatcherProfiles() (result []*utils.TPDis connsMap[tenantID][tp.ConnID] = conn if dFilter, has := connsFilterMap[tenantID]; !has { - connsFilterMap[tenantID] = make(map[string]utils.StringMap) - connsFilterMap[tenantID][tp.ConnID] = make(utils.StringMap) + connsFilterMap[tenantID] = make(map[string]utils.StringSet) + connsFilterMap[tenantID][tp.ConnID] = make(utils.StringSet) } else if _, has := dFilter[tp.ConnID]; !has { - connsFilterMap[tenantID][tp.ConnID] = make(utils.StringMap) + connsFilterMap[tenantID][tp.ConnID] = make(utils.StringSet) } - - for _, filter := range strings.Split(tp.ConnFilterIDs, utils.InfieldSep) { - connsFilterMap[tenantID][tp.ConnID][filter] = true + if tp.ConnFilterIDs != utils.EmptyString { + connsFilterMap[tenantID][tp.ConnID].AddSlice(strings.Split(tp.ConnFilterIDs, utils.InfieldSep)) } } @@ -2676,22 +2608,10 @@ func (tps DispatcherProfileMdls) AsTPDispatcherProfiles() (result []*utils.TPDis i := 0 for tntID, tp := range mst { result[i] = tp - for filterID := range filterMap[tntID] { - if filterID != utils.EmptyString { - result[i].FilterIDs = append(result[i].FilterIDs, filterID) - } - } - for context := range contextMap[tntID] { - if context != utils.EmptyString { - result[i].Subsystems = append(result[i].Subsystems, context) - } - } + result[i].FilterIDs = filterMap[tntID].AsSlice() + result[i].Subsystems = contextMap[tntID].AsSlice() for conID, conn := range connsMap[tntID] { - for filter := range connsFilterMap[tntID][conID] { - if filter != utils.EmptyString { - conn.FilterIDs = append(conn.FilterIDs, filter) - } - } + conn.FilterIDs = connsFilterMap[tntID][conID].AsSlice() result[i].Hosts = append(result[i].Hosts, &utils.TPDispatcherHostProfile{ ID: conn.ID, @@ -2990,7 +2910,7 @@ func (tps RateProfileMdls) CSVHeader() (result []string) { } func (tps RateProfileMdls) AsTPRateProfile() (result []*utils.TPRateProfile) { - filterMap := make(map[string]utils.StringMap) + filterMap := make(map[string]utils.StringSet) mst := make(map[string]*utils.TPRateProfile) rateMap := make(map[string]map[string]*utils.TPRate) for _, tp := range tps { @@ -3076,12 +2996,9 @@ func (tps RateProfileMdls) AsTPRateProfile() (result []*utils.TPRateProfile) { } if tp.FilterIDs != utils.EmptyString { if _, has := filterMap[tenID]; !has { - filterMap[tenID] = make(utils.StringMap) - } - filterSplit := strings.Split(tp.FilterIDs, utils.InfieldSep) - for _, filter := range filterSplit { - filterMap[tenID][filter] = true + filterMap[tenID] = make(utils.StringSet) } + filterMap[tenID].AddSlice(strings.Split(tp.FilterIDs, utils.InfieldSep)) } mst[tenID] = rPrf } @@ -3090,9 +3007,7 @@ func (tps RateProfileMdls) AsTPRateProfile() (result []*utils.TPRateProfile) { for tntID, th := range mst { result[i] = th result[i].Rates = rateMap[tntID] - for filterData := range filterMap[tntID] { - result[i].FilterIDs = append(result[i].FilterIDs, filterData) - } + result[i].FilterIDs = filterMap[tntID].AsSlice() i++ } return @@ -3299,7 +3214,7 @@ func (apm ActionProfileMdls) CSVHeader() (result []string) { } func (tps ActionProfileMdls) AsTPActionProfile() (result []*utils.TPActionProfile) { - filterIDsMap := make(map[string]utils.StringMap) + filterIDsMap := make(map[string]utils.StringSet) targetIDsMap := make(map[string]map[string]utils.StringSet) actPrfMap := make(map[string]*utils.TPActionProfile) for _, tp := range tps { @@ -3314,12 +3229,9 @@ func (tps ActionProfileMdls) AsTPActionProfile() (result []*utils.TPActionProfil } if tp.FilterIDs != utils.EmptyString { if _, has := filterIDsMap[tenID]; !has { - filterIDsMap[tenID] = make(utils.StringMap) - } - filterSplit := strings.Split(tp.FilterIDs, utils.InfieldSep) - for _, filter := range filterSplit { - filterIDsMap[tenID][filter] = true + filterIDsMap[tenID] = make(utils.StringSet) } + filterIDsMap[tenID].AddSlice(strings.Split(tp.FilterIDs, utils.InfieldSep)) } if tp.ActivationInterval != utils.EmptyString { aPrf.ActivationInterval = new(utils.TPActivationInterval) @@ -3369,9 +3281,7 @@ func (tps ActionProfileMdls) AsTPActionProfile() (result []*utils.TPActionProfil i := 0 for tntID, th := range actPrfMap { result[i] = th - for filterID := range filterIDsMap[tntID] { - result[i].FilterIDs = append(result[i].FilterIDs, filterID) - } + result[i].FilterIDs = filterIDsMap[tntID].AsSlice() for targetType, targetIDs := range targetIDsMap[tntID] { result[i].Targets = append(result[i].Targets, &utils.TPActionTarget{TargetType: targetType, TargetIDs: targetIDs.AsSlice()}) } @@ -3544,8 +3454,8 @@ func (apm AccountProfileMdls) CSVHeader() (result []string) { } func (tps AccountProfileMdls) AsTPAccountProfile() (result []*utils.TPAccountProfile, err error) { - filterIDsMap := make(map[string]utils.StringMap) - thresholdIDsMap := make(map[string]utils.StringMap) + filterIDsMap := make(map[string]utils.StringSet) + thresholdIDsMap := make(map[string]utils.StringSet) actPrfMap := make(map[string]*utils.TPAccountProfile) for _, tp := range tps { tenID := (&utils.TenantID{Tenant: tp.Tenant, ID: tp.ID}).TenantID() @@ -3560,21 +3470,15 @@ func (tps AccountProfileMdls) AsTPAccountProfile() (result []*utils.TPAccountPro } if tp.FilterIDs != utils.EmptyString { if _, has := filterIDsMap[tenID]; !has { - filterIDsMap[tenID] = make(utils.StringMap) - } - filterSplit := strings.Split(tp.FilterIDs, utils.InfieldSep) - for _, filter := range filterSplit { - filterIDsMap[tenID][filter] = true + filterIDsMap[tenID] = make(utils.StringSet) } + filterIDsMap[tenID].AddSlice(strings.Split(tp.FilterIDs, utils.InfieldSep)) } if tp.ThresholdIDs != utils.EmptyString { if _, has := thresholdIDsMap[tenID]; !has { - thresholdIDsMap[tenID] = make(utils.StringMap) - } - thresholdSplit := strings.Split(tp.ThresholdIDs, utils.InfieldSep) - for _, thresholdID := range thresholdSplit { - thresholdIDsMap[tenID][thresholdID] = true + thresholdIDsMap[tenID] = make(utils.StringSet) } + thresholdIDsMap[tenID].AddSlice(strings.Split(tp.ThresholdIDs, utils.InfieldSep)) } if tp.ActivationInterval != utils.EmptyString { aPrf.ActivationInterval = new(utils.TPActivationInterval) @@ -3653,12 +3557,8 @@ func (tps AccountProfileMdls) AsTPAccountProfile() (result []*utils.TPAccountPro i := 0 for tntID, th := range actPrfMap { result[i] = th - for filterID := range filterIDsMap[tntID] { - result[i].FilterIDs = append(result[i].FilterIDs, filterID) - } - for thresholdID := range thresholdIDsMap[tntID] { - result[i].ThresholdIDs = append(result[i].ThresholdIDs, thresholdID) - } + result[i].FilterIDs = filterIDsMap[tntID].AsSlice() + result[i].ThresholdIDs = thresholdIDsMap[tntID].AsSlice() i++ } return diff --git a/engine/model_helpers_test.go b/engine/model_helpers_test.go index d61771cc5..787368fa9 100644 --- a/engine/model_helpers_test.go +++ b/engine/model_helpers_test.go @@ -5275,6 +5275,8 @@ func TestModelHelpersAsTPDispatcherProfiles(t *testing.T) { ActivationTime: "2014-07-29T15:00:00Z", ExpiryTime: "2014-08-29T15:00:00Z", }, + FilterIDs: make([]string, 0), + Subsystems: make([]string, 0), StrategyParams: []interface{}{"Param1"}, }, } @@ -6322,7 +6324,7 @@ func TestThresholdMdlsAsTPThresholdActivationTime(t *testing.T) { TPid: "", Tenant: "", ID: "", - FilterIDs: nil, + FilterIDs: make([]string, 0), ActivationInterval: &utils.TPActivationInterval{ ActivationTime: "2014-07-14T14:35:00Z", ExpiryTime: "2014-07-15T14:35:00Z", @@ -6332,7 +6334,7 @@ func TestThresholdMdlsAsTPThresholdActivationTime(t *testing.T) { MinSleep: "", Blocker: false, Weight: 0, - ActionIDs: nil, + ActionIDs: make([]string, 0), Async: false, }, } @@ -6494,12 +6496,14 @@ func TestStatMdlsAsTPStatsCase2(t *testing.T) { ActivationTime: "2014-07-25T15:00:00Z", ExpiryTime: "2014-07-26T15:00:00Z", }, + FilterIDs: make([]string, 0), Metrics: []*utils.MetricWithFilters{ { MetricID: "test_id", FilterIDs: []string{"test_filter_id"}, }, }, + ThresholdIDs: make([]string, 0), }} result := testStruct.AsTPStats() if !reflect.DeepEqual(result, expStruct) { @@ -7156,7 +7160,7 @@ func TestApitoAccountProfileCaseTimeError(t *testing.T) { "VoiceBalance": { ID: "VoiceBalance", FilterIDs: []string{"FLTR_RES_GR2"}, - Weight: 10, + Weight: 10, Type: utils.MetaVoice, Units: 3600000000000, }, diff --git a/engine/z_stordb_it_test.go b/engine/z_stordb_it_test.go index adaab8b0b..d7f48b30a 100644 --- a/engine/z_stordb_it_test.go +++ b/engine/z_stordb_it_test.go @@ -154,18 +154,19 @@ func testStorDBitCRUDTPAccountProfiles(t *testing.T) { //WRITE var actPrf = []*utils.TPAccountProfile{ &utils.TPAccountProfile{ - TPid: testTPID, - Tenant: "cgrates.org", - ID: "1001", - Weight: 20, + TPid: testTPID, + Tenant: "cgrates.org", + ID: "1001", + Weight: 20, + FilterIDs: make([]string, 0), Balances: map[string]*utils.TPAccountBalance{ - "MonetaryBalance": &utils.TPAccountBalance{ + "MonetaryBalance": { ID: "MonetaryBalance", FilterIDs: []string{}, Weight: 10, Type: utils.MetaMonetary, CostIncrement: []*utils.TPBalanceCostIncrement{ - &utils.TPBalanceCostIncrement{ + { FilterIDs: []string{"fltr1", "fltr2"}, Increment: utils.Float64Pointer(1.3), FixedFee: utils.Float64Pointer(2.3), @@ -174,11 +175,11 @@ func testStorDBitCRUDTPAccountProfiles(t *testing.T) { }, CostAttributes: []string{"attr1", "attr2"}, UnitFactors: []*utils.TPBalanceUnitFactor{ - &utils.TPBalanceUnitFactor{ + { FilterIDs: []string{"fltr1", "fltr2"}, Factor: 100, }, - &utils.TPBalanceUnitFactor{ + { FilterIDs: []string{"fltr3"}, Factor: 200, }, @@ -300,10 +301,11 @@ func testStorDBitCRUDTPDispatcherProfiles(t *testing.T) { //WRITE var dsp = []*utils.TPDispatcherProfile{ { - TPid: "TP1", - Tenant: "cgrates.org", - ID: "Dsp1", - FilterIDs: []string{"*string:~*req.Account:1002"}, + TPid: "TP1", + Tenant: "cgrates.org", + ID: "Dsp1", + FilterIDs: []string{"*string:~*req.Account:1002"}, + Subsystems: make([]string, 0), ActivationInterval: &utils.TPActivationInterval{ ActivationTime: "2014-07-29T15:00:00Z", ExpiryTime: "", @@ -312,10 +314,11 @@ func testStorDBitCRUDTPDispatcherProfiles(t *testing.T) { Weight: 10, }, { - TPid: "TP1", - Tenant: "cgrates.org", - ID: "Dsp2", - FilterIDs: []string{"*string:~*req.Destination:10"}, + TPid: "TP1", + Tenant: "cgrates.org", + ID: "Dsp2", + FilterIDs: []string{"*string:~*req.Destination:10"}, + Subsystems: make([]string, 0), ActivationInterval: &utils.TPActivationInterval{ ActivationTime: "2014-08-15T14:00:00Z", }, @@ -720,11 +723,14 @@ func testStorDBitCRUDTPThresholds(t *testing.T) { //READ if rcv, err := storDB.GetTPThresholds(tpThresholds[0].TPid, utils.EmptyString, utils.EmptyString); err != nil { t.Error(err) - } else if !(reflect.DeepEqual(tpThresholds[0], rcv[0]) || - reflect.DeepEqual(tpThresholds[0], rcv[1])) { - t.Errorf("Expecting:\n%+v\nReceived:\n%+v\n||\n%+v", - utils.ToIJSON(tpThresholds[0]), utils.ToIJSON(rcv[0]), utils.ToIJSON(rcv[1])) - + } else { + sort.Strings(rcv[0].FilterIDs) + sort.Strings(rcv[1].FilterIDs) + if !(reflect.DeepEqual(tpThresholds[0], rcv[0]) || + reflect.DeepEqual(tpThresholds[0], rcv[1])) { + t.Errorf("Expecting:\n%+v\nReceived:\n%+v\n||\n%+v", + utils.ToIJSON(tpThresholds[0]), utils.ToIJSON(rcv[0]), utils.ToIJSON(rcv[1])) + } } //UPDATE @@ -761,55 +767,63 @@ func testStorDBitCRUDTPAttributes(t *testing.T) { //WRITE tpAProfile := []*utils.TPAttributeProfile{ { - TPid: "TP_ID", - Tenant: "cgrates.org", - ID: "APROFILE_ID1", + TPid: "TP_ID", + Tenant: "cgrates.org", + ID: "APROFILE_ID1", + FilterIDs: make([]string, 0), + Contexts: make([]string, 0), Attributes: []*utils.TPAttribute{ - { - Type: utils.MetaString, - Path: utils.MetaReq + utils.NestingSep + utils.AccountField + utils.InInFieldSep, - Value: "102", - FilterIDs: []string{"*string:~*req.Account:102"}, - }, { Type: utils.MetaString, Path: utils.MetaReq + utils.NestingSep + utils.AccountField + utils.InInFieldSep, Value: "101", FilterIDs: []string{"*string:~*req.Account:101"}, }, + { + Type: utils.MetaString, + Path: utils.MetaReq + utils.NestingSep + utils.AccountField + utils.InInFieldSep, + Value: "108", + FilterIDs: []string{"*string:~*req.Account:102"}, + }, }, }, { - TPid: "TP_ID", - Tenant: "cgrates.org", - ID: "APROFILE_ID2", + TPid: "TP_ID", + Tenant: "cgrates.org", + ID: "APROFILE_ID2", + FilterIDs: make([]string, 0), + Contexts: make([]string, 0), Attributes: []*utils.TPAttribute{ { Type: utils.MetaString, Path: utils.MetaReq + utils.NestingSep + utils.Destination + utils.InInFieldSep, - Value: "11", + Value: "12", FilterIDs: []string{"*string:~*req.Destination:11"}, }, { Type: utils.MetaString, Path: utils.MetaReq + utils.NestingSep + utils.Destination + utils.InInFieldSep, - Value: "11", + Value: "13", FilterIDs: []string{"*string:~*req.Destination:10"}, }, }, }, } if err := storDB.SetTPAttributes(tpAProfile); err != nil { - t.Errorf("Unable to set TPActionProfile") + t.Errorf("Unable to set TPActionProfile:%s", err) } //READ if rcv, err := storDB.GetTPAttributes(tpAProfile[0].TPid, utils.EmptyString, utils.EmptyString); err != nil { t.Error(err) - } else if !(reflect.DeepEqual(rcv[0], tpAProfile[0]) || - reflect.DeepEqual(rcv[1], tpAProfile[0])) { - t.Errorf("Expecting:\n%+v\nReceived:\n%+v\n||\n%+v", - utils.ToIJSON(tpAProfile[0]), utils.ToJSON(rcv[0]), utils.ToJSON(rcv[1])) + } else { + sort.Slice(rcv[0].Attributes, func(i, j int) bool { return rcv[0].Attributes[i].Value < rcv[0].Attributes[j].Value }) + sort.Slice(rcv[1].Attributes, func(i, j int) bool { return rcv[1].Attributes[i].Value < rcv[1].Attributes[j].Value }) + if !(reflect.DeepEqual(rcv[0], tpAProfile[0]) || + reflect.DeepEqual(rcv[1], tpAProfile[0])) { + t.Errorf("Expecting:\n%+v\nReceived:\n%+v\n||\n%+v", + utils.ToIJSON(tpAProfile[0]), utils.ToJSON(rcv[0]), utils.ToJSON(rcv[1])) + } } //UPDATE @@ -822,10 +836,14 @@ func testStorDBitCRUDTPAttributes(t *testing.T) { //READ if rcv, err := storDB.GetTPAttributes(tpAProfile[0].TPid, utils.EmptyString, utils.EmptyString); err != nil { t.Error(err) - } else if !(reflect.DeepEqual(rcv[0], tpAProfile[0]) || - reflect.DeepEqual(rcv[1], tpAProfile[0])) { - t.Errorf("Expecting:\n%+v\nReceived:\n%+v\n||\n%+v", - utils.ToIJSON(tpAProfile[0]), utils.ToIJSON(rcv[0]), utils.ToIJSON(rcv[1])) + } else { + sort.Slice(rcv[0].Attributes, func(i, j int) bool { return rcv[0].Attributes[i].Value < rcv[0].Attributes[j].Value }) + sort.Slice(rcv[1].Attributes, func(i, j int) bool { return rcv[1].Attributes[i].Value < rcv[1].Attributes[j].Value }) + if !(reflect.DeepEqual(rcv[0], tpAProfile[0]) || + reflect.DeepEqual(rcv[1], tpAProfile[0])) { + t.Errorf("Expecting:\n%+v\nReceived:\n%+v\n||\n%+v", + utils.ToIJSON(tpAProfile[0]), utils.ToIJSON(rcv[0]), utils.ToIJSON(rcv[1])) + } } //REMOVE and READ @@ -853,8 +871,9 @@ func testStorDBitCRUDTPChargers(t *testing.T) { ActivationTime: "2014-07-29T15:00:00Z", ExpiryTime: "", }, - RunID: utils.MetaDefault, - Weight: 20, + AttributeIDs: make([]string, 0), + RunID: utils.MetaDefault, + Weight: 20, }, { TPid: "TP_id", @@ -865,8 +884,9 @@ func testStorDBitCRUDTPChargers(t *testing.T) { ActivationTime: "2014-07-29T15:00:00Z", ExpiryTime: "", }, - RunID: utils.MetaDefault, - Weight: 10, + AttributeIDs: make([]string, 0), + RunID: utils.MetaDefault, + Weight: 10, }, } if err := storDB.SetTPChargers(tpChargers); err != nil { diff --git a/utils/orderednavigablemap.go b/utils/orderednavigablemap.go index a7a861274..83f26e6bb 100644 --- a/utils/orderednavigablemap.go +++ b/utils/orderednavigablemap.go @@ -178,6 +178,7 @@ func (onm *OrderedNavigableMap) GetOrder() (order []PathItems) { // OrderedFields returns the elements in order they were inserted func (onm *OrderedNavigableMap) OrderedFields() (flds []interface{}) { + flds = make([]interface{}, 0, onm.Len()) for el := onm.GetFirstElement(); el != nil; el = el.Next() { fld, _ := onm.Field(el.Value) flds = append(flds, fld.Interface())