From 09e44a0e6b9207d2b389e1ac9331febdd61afb52 Mon Sep 17 00:00:00 2001 From: andronache98 Date: Wed, 2 Feb 2022 17:23:46 +0200 Subject: [PATCH] Stat has Weights in DynamicWeights now --- apis/actions_it_test.go | 20 +- apis/filter_indexes_it_test.go | 18 +- apis/filters_test.go | 12 +- apis/loaders_it_test.go | 7 + apis/stats_it_test.go | 74 +++- apis/stats_test.go | 24 +- cmd/cgr-loader/cgr-loader_remove_it_test.go | 12 +- engine/libstats.go | 22 +- engine/libstats_test.go | 109 ++++-- engine/loader_csv_test.go | 4 +- engine/model_helpers.go | 16 +- engine/model_helpers_test.go | 50 ++- engine/models.go | 40 +- engine/stats.go | 1 + engine/stats_test.go | 408 +++++++++++++------- engine/tpreader_test.go | 2 +- engine/z_libindex_health_test.go | 12 +- engine/z_stordb_it_test.go | 4 +- general_tests/export_it_test.go | 10 +- migrator/attributes_it_test.go | 66 +++- migrator/filters_it_test.go | 24 +- migrator/stats_it_test.go | 8 +- migrator/tp_stats_it_test.go | 2 +- utils/apitpdata.go | 2 +- 24 files changed, 665 insertions(+), 282 deletions(-) diff --git a/apis/actions_it_test.go b/apis/actions_it_test.go index 14f0b98e4..279cbb19e 100644 --- a/apis/actions_it_test.go +++ b/apis/actions_it_test.go @@ -490,9 +490,13 @@ func testActionsExecuteActionsHTTPPost(t *testing.T) { func testActionsSetStatQueueProfileBeforeExecuteResetSQ(t *testing.T) { sqPrf := &engine.StatQueueProfileWithAPIOpts{ StatQueueProfile: &engine.StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ_ID", - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ_ID", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, QueueLength: 100, TTL: time.Duration(1 * time.Minute), MinItems: 0, @@ -514,9 +518,13 @@ func testActionsSetStatQueueProfileBeforeExecuteResetSQ(t *testing.T) { } expSqPrf := engine.StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ_ID", - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ_ID", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, QueueLength: 100, TTL: time.Duration(1 * time.Minute), MinItems: 0, diff --git a/apis/filter_indexes_it_test.go b/apis/filter_indexes_it_test.go index abfd67217..8cb59d077 100644 --- a/apis/filter_indexes_it_test.go +++ b/apis/filter_indexes_it_test.go @@ -4221,7 +4221,11 @@ func testV1FIdxSetStatSProfileWithFltr(t *testing.T) { }, }, Stored: true, - Weight: 30, + Weights: utils.DynamicWeights{ + { + Weight: 30, + }, + }, ThresholdIDs: []string{utils.MetaNone}, }, } @@ -4322,7 +4326,11 @@ func testV1FIdxSetStatSMoreFltrsMoreIndexing(t *testing.T) { }, }, Stored: true, - Weight: 30, + Weights: utils.DynamicWeights{ + { + Weight: 30, + }, + }, ThresholdIDs: []string{utils.MetaNone}, }, } @@ -4429,7 +4437,11 @@ func testV1FIdxStatSMoreProfilesForFltrs(t *testing.T) { }, }, Stored: true, - Weight: 30, + Weights: utils.DynamicWeights{ + { + Weight: 30, + }, + }, ThresholdIDs: []string{utils.MetaNone}, }, } diff --git a/apis/filters_test.go b/apis/filters_test.go index 758d5abae..b6c291886 100644 --- a/apis/filters_test.go +++ b/apis/filters_test.go @@ -864,7 +864,11 @@ func TestFiltersSetFilterReloadCache(t *testing.T) { StatQueueProfile: &engine.StatQueueProfile{ ID: "SQ_ID", FilterIDs: []string{"FLTR_ID"}, - Weight: 10, + Weights: utils.DynamicWeights{ + { + Weight: 10.0, + }, + }, }, APIOpts: map[string]interface{}{ utils.MetaCache: utils.MetaNone, @@ -1021,7 +1025,11 @@ func TestFiltersSetFilterClearCache(t *testing.T) { StatQueueProfile: &engine.StatQueueProfile{ ID: "SQ_ID", FilterIDs: []string{"FLTR_ID"}, - Weight: 10, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, }, APIOpts: map[string]interface{}{ utils.MetaCache: utils.MetaNone, diff --git a/apis/loaders_it_test.go b/apis/loaders_it_test.go index f79534fc0..a2180dba0 100644 --- a/apis/loaders_it_test.go +++ b/apis/loaders_it_test.go @@ -1162,6 +1162,13 @@ func testLoadersGetStatQueueProfiles(t *testing.T) { Weight: 20, MinItems: 2, }, + Stored: true, + Weights: utils.DynamicWeights{ + { + Weight: 30, + }, + }, + ThresholdIDs: []string{utils.MetaNone}, } var sqPrfs []*engine.StatQueueProfile if err := ldrRPC.Call(context.Background(), utils.AdminSv1GetStatQueueProfiles, diff --git a/apis/stats_it_test.go b/apis/stats_it_test.go index 3503816a6..f3892febd 100644 --- a/apis/stats_it_test.go +++ b/apis/stats_it_test.go @@ -179,9 +179,13 @@ func testStatsGetStatQueueProfilesBeforeSet(t *testing.T) { func testStatsSetStatQueueProfiles(t *testing.T) { sqPrf1 := &engine.StatQueueProfileWithAPIOpts{ StatQueueProfile: &engine.StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ_1", - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ_1", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, QueueLength: 100, TTL: time.Duration(1 * time.Minute), MinItems: 5, @@ -218,7 +222,11 @@ func testStatsSetStatQueueProfiles(t *testing.T) { StatQueueProfile: &engine.StatQueueProfile{ Tenant: "cgrates.org", ID: "SQ_2", - Weight: 20, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, Metrics: []*engine.MetricWithFilters{ { MetricID: utils.MetaASR, @@ -265,9 +273,13 @@ func testStatsGetStatQueueAfterSet(t *testing.T) { utils.MetaTCD: -1, } expSqPrf := engine.StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ_1", - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ_1", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, QueueLength: 100, TTL: time.Duration(1 * time.Minute), MinItems: 5, @@ -345,7 +357,11 @@ func testStatsGetStatQueueAfterSet(t *testing.T) { expSqPrf = engine.StatQueueProfile{ Tenant: "cgrates.org", ID: "SQ_2", - Weight: 20, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, Metrics: []*engine.MetricWithFilters{ { MetricID: utils.MetaASR, @@ -443,9 +459,13 @@ func testStatsGetStatQueueProfiles1(t *testing.T) { var args *utils.ArgsItemIDs exp := []*engine.StatQueueProfile{ { - Tenant: "cgrates.org", - ID: "SQ_1", - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ_1", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, QueueLength: 100, TTL: time.Duration(1 * time.Minute), MinItems: 5, @@ -471,7 +491,11 @@ func testStatsGetStatQueueProfiles1(t *testing.T) { { Tenant: "cgrates.org", ID: "SQ_2", - Weight: 20, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, Metrics: []*engine.MetricWithFilters{ { MetricID: utils.MetaASR, @@ -513,7 +537,11 @@ func testStatsGetStatQueueProfilesWithPrefix(t *testing.T) { { Tenant: "cgrates.org", ID: "SQ_2", - Weight: 20, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, Metrics: []*engine.MetricWithFilters{ { MetricID: utils.MetaASR, @@ -722,9 +750,13 @@ func testStatsSetThresholdProfilesBeforeProcessEv(t *testing.T) { func testStatsSetStatQueueProfileBeforeProcessEv(t *testing.T) { sqPrf := &engine.StatQueueProfileWithAPIOpts{ StatQueueProfile: &engine.StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ_3", - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ_3", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, QueueLength: 100, TTL: time.Duration(1 * time.Minute), MinItems: 0, @@ -746,9 +778,13 @@ func testStatsSetStatQueueProfileBeforeProcessEv(t *testing.T) { } expSqPrf := engine.StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ_3", - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ_3", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, QueueLength: 100, TTL: time.Duration(1 * time.Minute), MinItems: 0, diff --git a/apis/stats_test.go b/apis/stats_test.go index 8a496cf8e..eed9b2285 100644 --- a/apis/stats_test.go +++ b/apis/stats_test.go @@ -54,7 +54,11 @@ func TestStatsSetGetRemStatQueueProfile(t *testing.T) { StatQueueProfile: &engine.StatQueueProfile{ Tenant: "cgrates.org", ID: "sqID", - Weight: 10, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, }, } @@ -227,7 +231,11 @@ func TestStatsRemoveStatQueueProfileCheckErrors(t *testing.T) { StatQueueProfile: &engine.StatQueueProfile{ ID: "TestStatsRemoveStatQueueProfileCheckErrors", Tenant: "cgrates.org", - Weight: 10, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, }, } var reply string @@ -581,7 +589,11 @@ func TestStatsAPIs(t *testing.T) { }, Blocker: true, ThresholdIDs: []string{utils.MetaNone}, - Weight: 20, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, }, } @@ -611,7 +623,11 @@ func TestStatsAPIs(t *testing.T) { }, Blocker: true, ThresholdIDs: []string{"thdID"}, - Weight: 20, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, }, } diff --git a/cmd/cgr-loader/cgr-loader_remove_it_test.go b/cmd/cgr-loader/cgr-loader_remove_it_test.go index c87972380..29bda4abf 100644 --- a/cmd/cgr-loader/cgr-loader_remove_it_test.go +++ b/cmd/cgr-loader/cgr-loader_remove_it_test.go @@ -584,10 +584,14 @@ func testCgrLdrGetRouteProfileAfterLoad(t *testing.T) { func testCgrLdrGetStatsProfileAfterLoad(t *testing.T) { expStatsprf := &engine.StatQueueProfile{ - Tenant: utils.CGRateSorg, - ID: "Stat_1", - FilterIDs: []string{"FLTR_STAT_1"}, - Weight: 30, + Tenant: utils.CGRateSorg, + ID: "Stat_1", + FilterIDs: []string{"FLTR_STAT_1"}, + Weights: utils.DynamicWeights{ + { + Weight: 30, + }, + }, QueueLength: 100, TTL: 10 * time.Second, MinItems: 0, diff --git a/engine/libstats.go b/engine/libstats.go index 7f7678a46..fa662211d 100644 --- a/engine/libstats.go +++ b/engine/libstats.go @@ -44,12 +44,17 @@ type StatQueueProfile struct { Metrics []*MetricWithFilters // list of metrics to build Stored bool Blocker bool // blocker flag to stop processing on filters matched - Weight float64 + Weights utils.DynamicWeights ThresholdIDs []string // list of thresholds to be checked after changes lkID string // holds the reference towards guardian lock key } +type statprfWithWeight struct { + *StatQueueProfile + weight float64 +} + // StatQueueProfileWithAPIOpts is used in replicatorV1 for dispatcher type StatQueueProfileWithAPIOpts struct { *StatQueueProfile @@ -391,7 +396,9 @@ type StatQueues []*StatQueue // Sort is part of sort interface, sort based on Weight func (sis StatQueues) Sort() { - sort.Slice(sis, func(i, j int) bool { return sis[i].sqPrfl.Weight > sis[j].sqPrfl.Weight }) + sort.Slice(sis, func(i, j int) bool { + return sis[i].sqPrfl.Weights[i].Weight > sis[j].sqPrfl.Weights[j].Weight + }) } func (sq *StatQueue) MarshalJSON() (rply []byte, err error) { @@ -566,10 +573,11 @@ func (sqp *StatQueueProfile) Set(path []string, val interface{}, newBranch bool, sqp.Stored, err = utils.IfaceAsBool(val) case utils.Blocker: sqp.Blocker, err = utils.IfaceAsBool(val) - case utils.Weight: + case utils.Weights: if val != utils.EmptyString { - sqp.Weight, err = utils.IfaceAsFloat64(val) + sqp.Weights, err = utils.NewDynamicWeightsFromString(utils.IfaceAsString(val), utils.InfieldSep, utils.ANDSep) } + case utils.FilterIDs: var valA []string valA, err = utils.IfaceAsStringSlice(val) @@ -634,9 +642,7 @@ func (sqp *StatQueueProfile) Merge(v2 interface{}) { if vi.Stored { sqp.Stored = vi.Stored } - if vi.Weight != 0 { - sqp.Weight = vi.Weight - } + sqp.Weights = append(sqp.Weights, vi.Weights...) } func (sqp *StatQueueProfile) String() string { return utils.ToJSON(sqp) } @@ -676,7 +682,7 @@ func (sqp *StatQueueProfile) FieldAsInterface(fldPath []string) (_ interface{}, case utils.FilterIDs: return sqp.FilterIDs, nil case utils.Weight: - return sqp.Weight, nil + return sqp.Weights, nil case utils.ThresholdIDs: return sqp.ThresholdIDs, nil case utils.QueueLength: diff --git a/engine/libstats_test.go b/engine/libstats_test.go index 583f736bb..4c33758a4 100644 --- a/engine/libstats_test.go +++ b/engine/libstats_test.go @@ -34,18 +34,51 @@ var sq *StatQueue func TestStatQueuesSort(t *testing.T) { sInsts := StatQueues{ - &StatQueue{sqPrfl: &StatQueueProfile{ID: "FIRST", Weight: 30.0}}, - &StatQueue{sqPrfl: &StatQueueProfile{ID: "SECOND", Weight: 40.0}}, - &StatQueue{sqPrfl: &StatQueueProfile{ID: "THIRD", Weight: 30.0}}, - &StatQueue{sqPrfl: &StatQueueProfile{ID: "FOURTH", Weight: 35.0}}, + &StatQueue{sqPrfl: &StatQueueProfile{ID: "FIRST", Weights: utils.DynamicWeights{ + { + Weight: 30.0, + }, + }}}, + &StatQueue{sqPrfl: &StatQueueProfile{ID: "SECOND", Weights: utils.DynamicWeights{ + { + Weight: 40.0, + }, + }}}, + &StatQueue{sqPrfl: &StatQueueProfile{ID: "THIRD", Weights: utils.DynamicWeights{ + { + Weight: 30.0, + }, + }}}, + &StatQueue{sqPrfl: &StatQueueProfile{ID: "FOURTH", Weights: utils.DynamicWeights{ + { + Weight: 35.0, + }, + }}}, } sInsts.Sort() eSInst := StatQueues{ - &StatQueue{sqPrfl: &StatQueueProfile{ID: "SECOND", Weight: 40.0}}, - &StatQueue{sqPrfl: &StatQueueProfile{ID: "FOURTH", Weight: 35.0}}, - &StatQueue{sqPrfl: &StatQueueProfile{ID: "FIRST", Weight: 30.0}}, - &StatQueue{sqPrfl: &StatQueueProfile{ID: "THIRD", Weight: 30.0}}, + &StatQueue{sqPrfl: &StatQueueProfile{ID: "SECOND", Weights: utils.DynamicWeights{ + { + Weight: 40.0, + }, + }}}, + &StatQueue{sqPrfl: &StatQueueProfile{ID: "FOURTH", Weights: utils.DynamicWeights{ + { + Weight: 35.0, + }, + }}}, + &StatQueue{sqPrfl: &StatQueueProfile{ID: "FIRST", Weights: utils.DynamicWeights{ + { + Weight: 30.0, + }, + }}}, + &StatQueue{sqPrfl: &StatQueueProfile{ID: "THIRD", Weights: utils.DynamicWeights{ + { + Weight: 30.0, + }, + }}}, } + if !reflect.DeepEqual(eSInst, sInsts) { t.Errorf("expecting: %+v, received: %+v", eSInst, sInsts) } @@ -1303,9 +1336,13 @@ func TestStatQueueWithAPIOptsJSONMarshall(t *testing.T) { func TestStatQueueLockUnlockStatQueueProfiles(t *testing.T) { sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, QueueLength: 10, } @@ -1374,10 +1411,14 @@ func TestStatQueueLockUnlockStatQueues(t *testing.T) { func TestStatQueueProfileSet(t *testing.T) { sq := StatQueueProfile{} exp := StatQueueProfile{ - Tenant: "cgrates.org", - ID: "ID", - FilterIDs: []string{"fltr1", "*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "ID", + FilterIDs: []string{"fltr1", "*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, QueueLength: 10, TTL: 10, MinItems: 10, @@ -1452,10 +1493,14 @@ func TestStatQueueProfileSet(t *testing.T) { func TestStatQueueProfileAsInterface(t *testing.T) { sqp := StatQueueProfile{ - Tenant: "cgrates.org", - ID: "ID", - FilterIDs: []string{"fltr1", "*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "ID", + FilterIDs: []string{"fltr1", "*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, QueueLength: 10, TTL: 10, MinItems: 10, @@ -1500,7 +1545,7 @@ func TestStatQueueProfileAsInterface(t *testing.T) { } if val, err := sqp.FieldAsInterface([]string{utils.Weight}); err != nil { t.Fatal(err) - } else if exp := sqp.Weight; !reflect.DeepEqual(exp, val) { + } else if exp := sqp.Weights; !reflect.DeepEqual(exp, val) { t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(exp), utils.ToJSON(val)) } if val, err := sqp.FieldAsInterface([]string{utils.ThresholdIDs}); err != nil { @@ -1610,10 +1655,14 @@ func TestStatQueueProfileAsInterface(t *testing.T) { func TestStatQueueProfileMerge(t *testing.T) { sqp := &StatQueueProfile{} exp := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "ID", - FilterIDs: []string{"fltr1", "*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "ID", + FilterIDs: []string{"fltr1", "*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, QueueLength: 10, TTL: 10, MinItems: 10, @@ -1628,10 +1677,14 @@ func TestStatQueueProfileMerge(t *testing.T) { }}, } if sqp.Merge(&StatQueueProfile{ - Tenant: "cgrates.org", - ID: "ID", - FilterIDs: []string{"fltr1", "*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "ID", + FilterIDs: []string{"fltr1", "*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, QueueLength: 10, TTL: 10, MinItems: 10, diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index af634f077..f24edab61 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -143,7 +143,7 @@ func TestLoadStatQueueProfiles(t *testing.T) { ThresholdIDs: []string{"Th1", "Th2"}, Blocker: true, Stored: true, - Weight: 20, + Weights: ";20", MinItems: 2, }, {Tenant: "cgrates.org", ID: "TestStats2"}: { @@ -178,7 +178,7 @@ func TestLoadStatQueueProfiles(t *testing.T) { ThresholdIDs: []string{"Th"}, Blocker: true, Stored: true, - Weight: 20, + Weights: ";20", MinItems: 2, }, } diff --git a/engine/model_helpers.go b/engine/model_helpers.go index e9b04741b..6cd01b851 100644 --- a/engine/model_helpers.go +++ b/engine/model_helpers.go @@ -338,7 +338,7 @@ func (tps StatMdls) AsTPStats() (result []*utils.TPStatProfile) { ID: model.ID, Blocker: model.Blocker, Stored: model.Stored, - Weight: model.Weight, + Weights: model.Weights, MinItems: model.MinItems, TTL: model.TTL, QueueLength: model.QueueLength, @@ -350,8 +350,8 @@ func (tps StatMdls) AsTPStats() (result []*utils.TPStatProfile) { if model.Stored { st.Stored = model.Stored } - if model.Weight != 0 { - st.Weight = model.Weight + if model.Weights != "" { + st.Weights = model.Weights } if model.MinItems != 0 { st.MinItems = model.MinItems @@ -429,7 +429,7 @@ func APItoModelStats(st *utils.TPStatProfile) (mdls StatMdls) { mdl.MinItems = st.MinItems mdl.Stored = st.Stored mdl.Blocker = st.Blocker - mdl.Weight = st.Weight + mdl.Weights = st.Weights for i, val := range st.ThresholdIDs { if i != 0 { mdl.ThresholdIDs += utils.InfieldSep @@ -460,9 +460,13 @@ func APItoStats(tpST *utils.TPStatProfile, timezone string) (st *StatQueueProfil Metrics: make([]*MetricWithFilters, len(tpST.Metrics)), Stored: tpST.Stored, Blocker: tpST.Blocker, - Weight: tpST.Weight, ThresholdIDs: make([]string, len(tpST.ThresholdIDs)), } + if tpST.Weights != utils.EmptyString { + if st.Weights, err = utils.NewDynamicWeightsFromString(tpST.Weights, utils.InfieldSep, utils.ANDSep); err != nil { + return + } + } if tpST.TTL != utils.EmptyString { if st.TTL, err = utils.ParseDurationWithNanosecs(tpST.TTL); err != nil { return nil, err @@ -492,7 +496,7 @@ func StatQueueProfileToAPI(st *StatQueueProfile) (tpST *utils.TPStatProfile) { Metrics: make([]*utils.MetricWithFilters, len(st.Metrics)), Blocker: st.Blocker, Stored: st.Stored, - Weight: st.Weight, + Weights: st.Weights.String(utils.InfieldSep, utils.ANDSep), MinItems: st.MinItems, ThresholdIDs: make([]string, len(st.ThresholdIDs)), } diff --git a/engine/model_helpers_test.go b/engine/model_helpers_test.go index 46f730138..794225aaa 100644 --- a/engine/model_helpers_test.go +++ b/engine/model_helpers_test.go @@ -184,7 +184,7 @@ func TestTPStatsAsTPStats(t *testing.T) { MetricIDs: "*asr;*acc;*tcc;*acd;*tcd;*pdd", Stored: true, Blocker: true, - Weight: 20.0, + Weights: ";20", }, &StatMdl{ Tpid: "TEST_TPID", @@ -198,7 +198,7 @@ func TestTPStatsAsTPStats(t *testing.T) { ThresholdIDs: "THRESH3", Stored: true, Blocker: true, - Weight: 20.0, + Weights: ";20", }, &StatMdl{ Tpid: "TEST_TPID", @@ -212,7 +212,7 @@ func TestTPStatsAsTPStats(t *testing.T) { ThresholdIDs: "THRESH4", Stored: true, Blocker: true, - Weight: 20.0, + Weights: ";20", }, } rcvTPs := tps.AsTPStats() @@ -254,7 +254,7 @@ func TestAPItoTPStats(t *testing.T) { ThresholdIDs: []string{"THRESH1", "THRESH2"}, Stored: false, Blocker: false, - Weight: 20.0, + Weights: ";20.0", } eTPs := &StatQueueProfile{ID: tps.ID, QueueLength: tps.QueueLength, @@ -273,8 +273,12 @@ func TestAPItoTPStats(t *testing.T) { FilterIDs: []string{"FLTR_1", "*ai:~*req.AnswerTime:2014-07-29T15:00:00Z"}, Stored: tps.Stored, Blocker: tps.Blocker, - Weight: 20.0, - MinItems: tps.MinItems, + Weights: utils.DynamicWeights{ + { + Weight: 20.0, + }, + }, + MinItems: tps.MinItems, } if eTPs.TTL, err = utils.ParseDurationWithNanosecs(tps.TTL); err != nil { t.Errorf("Got error: %+v", err) @@ -307,7 +311,7 @@ func TestStatQueueProfileToAPI(t *testing.T) { }, MinItems: 1, ThresholdIDs: []string{"THRESH1", "THRESH2"}, - Weight: 20.0, + Weights: ";20", } sqPrf := &StatQueueProfile{ Tenant: "cgrates.org", @@ -327,8 +331,12 @@ func TestStatQueueProfileToAPI(t *testing.T) { TTL: time.Second, ThresholdIDs: []string{"THRESH1", "THRESH2"}, FilterIDs: []string{"FLTR_1", "*ai:~*req.AnswerTime:2014-07-29T15:00:00Z"}, - Weight: 20.0, - MinItems: 1, + Weights: utils.DynamicWeights{ + { + Weight: 20.0, + }, + }, + MinItems: 1, } if rcv := StatQueueProfileToAPI(sqPrf); !reflect.DeepEqual(expected, rcv) { @@ -354,7 +362,7 @@ func TestAPItoModelStats(t *testing.T) { }, Blocker: true, Stored: true, - Weight: 20, + Weights: ";20", MinItems: 2, ThresholdIDs: []string{"Th1"}, } @@ -371,7 +379,7 @@ func TestAPItoModelStats(t *testing.T) { MetricIDs: "*tcc", Stored: true, Blocker: true, - Weight: 20.0, + Weights: ";20", ThresholdIDs: "Th1", }, &StatMdl{ @@ -4258,9 +4266,13 @@ func TestModelHelpersStatQueueProfileToAPIFilterIds(t *testing.T) { FilterIDs: []string{"test_id"}, }, }, - Stored: false, - Blocker: false, - Weight: 0, + Stored: false, + Blocker: false, + Weights: utils.DynamicWeights{ + { + Weight: 0, + }, + }, ThresholdIDs: []string{"threshold_id"}, } expStruct := &utils.TPStatProfile{ @@ -4276,7 +4288,7 @@ func TestModelHelpersStatQueueProfileToAPIFilterIds(t *testing.T) { }, Blocker: false, Stored: false, - Weight: 0, + Weights: ";0", ThresholdIDs: []string{"threshold_id"}, } result := StatQueueProfileToAPI(testStruct) @@ -4294,7 +4306,7 @@ func TestModelHelpersAPItoStatsError1(t *testing.T) { TTL: "cat", Blocker: false, Stored: false, - Weight: 0, + Weights: ";0", MinItems: 0, ThresholdIDs: nil, } @@ -4320,7 +4332,7 @@ func TestModelHelpersAPItoModelStatsCase2(t *testing.T) { }, Blocker: true, Stored: true, - Weight: 20, + Weights: ";20", MinItems: 2, ThresholdIDs: []string{"Th1", "Th2"}, } @@ -4337,7 +4349,7 @@ func TestModelHelpersAPItoModelStatsCase2(t *testing.T) { MetricFilterIDs: "test_filter_id1;test_filter_id2", Stored: true, Blocker: true, - Weight: 20.0, + Weights: ";20", ThresholdIDs: "Th1;Th2", }, } @@ -4382,7 +4394,7 @@ func TestStatMdlsCSVHeader(t *testing.T) { MetricFilterIDs: "", Stored: false, Blocker: false, - Weight: 0, + Weights: ";0", ThresholdIDs: "", CreatedAt: time.Time{}, }} diff --git a/engine/models.go b/engine/models.go index 2f96680f4..f28f653c1 100644 --- a/engine/models.go +++ b/engine/models.go @@ -50,18 +50,18 @@ func (ResourceMdl) TableName() string { type StatMdl struct { PK uint `gorm:"primary_key"` Tpid string - Tenant string `index:"0" re:""` - ID string `index:"1" re:""` - FilterIDs string `index:"2" re:""` - Weight float64 `index:"3" re:"\d+\.?\d*"` - QueueLength int `index:"4" re:""` - TTL string `index:"5" re:""` - MinItems int `index:"6" re:""` - MetricIDs string `index:"7" re:""` - MetricFilterIDs string `index:"8" re:""` - Stored bool `index:"9" re:""` - Blocker bool `index:"10" re:""` - ThresholdIDs string `index:"11" re:""` + Tenant string `index:"0" re:""` + ID string `index:"1" re:""` + FilterIDs string `index:"2" re:""` + Weights string `index:"3" re:"\d+\.?\d*"` + QueueLength int `index:"4" re:""` + TTL string `index:"5" re:""` + MinItems int `index:"6" re:""` + MetricIDs string `index:"7" re:""` + MetricFilterIDs string `index:"8" re:""` + Stored bool `index:"9" re:""` + Blocker bool `index:"10" re:""` + ThresholdIDs string `index:"11" re:""` CreatedAt time.Time } @@ -218,15 +218,15 @@ func (RouteMdl) TableName() string { type AttributeMdl struct { PK uint `gorm:"primary_key"` Tpid string - Tenant string `index:"0" re:""` - ID string `index:"1" re:""` - FilterIDs string `index:"2" re:""` + Tenant string `index:"0" re:""` + ID string `index:"1" re:""` + FilterIDs string `index:"2" re:""` Weights string `index:"3" re:"\d+\.?\d*"` - AttributeFilterIDs string `index:"4" re:""` - Path string `index:"5" re:""` - Type string `index:"6" re:""` - Value string `index:"7" re:""` - Blocker bool `index:"8" re:""` + AttributeFilterIDs string `index:"4" re:""` + Path string `index:"5" re:""` + Type string `index:"6" re:""` + Value string `index:"7" re:""` + Blocker bool `index:"8" re:""` CreatedAt time.Time } diff --git a/engine/stats.go b/engine/stats.go index a661677b9..731f3b5f7 100644 --- a/engine/stats.go +++ b/engine/stats.go @@ -176,6 +176,7 @@ func (sS *StatS) matchingStatQueuesForEvent(ctx *context.Context, tnt string, st } } sqs = make(StatQueues, 0, len(sqIDs)) + for sqID := range sqIDs { lkPrflID := guardian.Guardian.GuardIDs("", config.CgrConfig().GeneralCfg().LockingTimeout, diff --git a/engine/stats_test.go b/engine/stats_test.go index 638ad6963..a9b82c318 100644 --- a/engine/stats_test.go +++ b/engine/stats_test.go @@ -48,8 +48,12 @@ var ( ThresholdIDs: []string{}, Blocker: false, Stored: true, - Weight: 20, - MinItems: 1, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, + MinItems: 1, }, { Tenant: "cgrates.org", @@ -65,8 +69,12 @@ var ( ThresholdIDs: []string{}, Blocker: false, Stored: true, - Weight: 20, - MinItems: 1, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, + MinItems: 1, }, { Tenant: "cgrates.org", @@ -82,8 +90,12 @@ var ( ThresholdIDs: []string{}, Blocker: false, Stored: true, - Weight: 20, - MinItems: 1, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, + MinItems: 1, }, } testStatsQ = []*StatQueue{ @@ -427,8 +439,12 @@ func TestStatQueuesV1ProcessEvent(t *testing.T) { }, ThresholdIDs: []string{}, Stored: true, - Weight: 20, - MinItems: 1, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, + MinItems: 1, } sq := &StatQueue{Tenant: "cgrates.org", ID: "StatQueueProfile3", sqPrfl: sqPrf, SQMetrics: make(map[string]StatMetric)} if err := dmSTS.SetStatQueueProfile(context.TODO(), sqPrf, true); err != nil { @@ -673,9 +689,13 @@ func TestStatQueueMatchingStatQueuesForEventLocks(t *testing.T) { ids := utils.StringSet{} for i := 0; i < 10; i++ { rPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: fmt.Sprintf("STS%d", i), - Weight: 20.00, + Tenant: "cgrates.org", + ID: fmt.Sprintf("STS%d", i), + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }, + }, ThresholdIDs: []string{utils.MetaNone}, QueueLength: 1, Stored: true, @@ -722,11 +742,15 @@ func TestStatQueueMatchingStatQueuesForEventLocks2(t *testing.T) { ids := utils.StringSet{} for i := 0; i < 10; i++ { rPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: fmt.Sprintf("STS%d", i), - QueueLength: 1, - Stored: true, - Weight: 20.00, + Tenant: "cgrates.org", + ID: fmt.Sprintf("STS%d", i), + QueueLength: 1, + Stored: true, + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }, + }, ThresholdIDs: []string{utils.MetaNone}, } dm.SetStatQueueProfile(context.Background(), rPrf, true) @@ -734,12 +758,16 @@ func TestStatQueueMatchingStatQueuesForEventLocks2(t *testing.T) { ids.Add(rPrf.ID) } rPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "STS20", - FilterIDs: []string{"FLTR_RES_201"}, - QueueLength: 1, - Stored: true, - Weight: 20.00, + Tenant: "cgrates.org", + ID: "STS20", + FilterIDs: []string{"FLTR_RES_201"}, + QueueLength: 1, + Stored: true, + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }, + }, ThresholdIDs: []string{utils.MetaNone}, } err = db.SetStatQueueProfileDrv(context.Background(), rPrf) @@ -785,11 +813,15 @@ func TestStatQueueMatchingStatQueuesForEventLocksBlocker(t *testing.T) { ids := utils.StringSet{} for i := 0; i < 10; i++ { rPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: fmt.Sprintf("STS%d", i), - QueueLength: 1, - Stored: true, - Weight: float64(10 - i), + Tenant: "cgrates.org", + ID: fmt.Sprintf("STS%d", i), + QueueLength: 1, + Stored: true, + Weights: utils.DynamicWeights{ + { + Weight: float64(10 - i), + }, + }, Blocker: i == 4, ThresholdIDs: []string{utils.MetaNone}, } @@ -839,11 +871,15 @@ func TestStatQueueMatchingStatQueuesForEventLocks3(t *testing.T) { return nil, utils.ErrNotImplemented } rPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: id, - QueueLength: 1, - Stored: true, - Weight: 20.00, + Tenant: "cgrates.org", + ID: id, + QueueLength: 1, + Stored: true, + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }, + }, ThresholdIDs: []string{utils.MetaNone}, } Cache.Set(ctx, utils.CacheStatQueues, rPrf.TenantID(), &StatQueue{ @@ -895,9 +931,13 @@ func TestStatQueueMatchingStatQueuesForEventLocks4(t *testing.T) { ids := utils.StringSet{} for i := 0; i < 10; i++ { rPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: fmt.Sprintf("STS%d", i), - Weight: 20.00, + Tenant: "cgrates.org", + ID: fmt.Sprintf("STS%d", i), + Weights: utils.DynamicWeights{ + { + Weight: 20.00, + }, + }, ThresholdIDs: []string{utils.MetaNone}, QueueLength: 1, Stored: true, @@ -1167,10 +1207,14 @@ func TestStatQueueProcessEventOK(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -1228,10 +1272,14 @@ func TestStatQueueProcessEventProcessThPartExec(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -1356,10 +1404,14 @@ func TestStatQueueV1ProcessEventMissingArgs(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -1446,10 +1498,14 @@ func TestStatQueueV1GetQueueIDsOK(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -1550,10 +1606,14 @@ func TestStatQueueV1GetStatQueueOK(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -1639,10 +1699,14 @@ func TestStatQueueV1GetStatQueueMissingArgs(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -1699,10 +1763,14 @@ func TestStatQueueV1GetStatQueuesForEventOK(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf1 := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -1719,9 +1787,13 @@ func TestStatQueueV1GetStatQueuesForEventOK(t *testing.T) { } sqPrf2 := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ2", - Weight: 20, + Tenant: "cgrates.org", + ID: "SQ2", + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, Blocker: false, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -1772,10 +1844,14 @@ func TestStatQueueV1GetStatQueuesForEventNotFoundErr(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -1821,10 +1897,14 @@ func TestStatQueueV1GetStatQueuesForEventMissingArgs(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -1891,10 +1971,14 @@ func TestStatQueueV1ResetStatQueueOK(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -1982,10 +2066,14 @@ func TestStatQueueV1ResetStatQueueNotFoundErr(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -2048,10 +2136,14 @@ func TestStatQueueV1ResetStatQueueMissingArgs(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -2112,10 +2204,14 @@ func TestStatQueueV1ResetStatQueueUnsupportedMetricType(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -2183,10 +2279,14 @@ func TestStatQueueProcessThresholdsOKNoThIDs(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -2282,10 +2382,14 @@ func TestStatQueueProcessThresholdsOK(t *testing.T) { sS := NewStatService(dm, cfg, filterS, connMgr) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"TH1"}, @@ -2364,10 +2468,14 @@ func TestStatQueueProcessThresholdsErrPartExec(t *testing.T) { sS := NewStatService(dm, cfg, filterS, connMgr) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"TH1"}, @@ -2433,10 +2541,14 @@ func TestStatQueueV1GetQueueFloatMetricsOK(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -2502,10 +2614,14 @@ func TestStatQueueV1GetQueueFloatMetricsErrNotFound(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -2566,10 +2682,14 @@ func TestStatQueueV1GetQueueFloatMetricsMissingArgs(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -2651,10 +2771,14 @@ func TestStatQueueV1GetQueueStringMetricsOK(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -2720,10 +2844,14 @@ func TestStatQueueV1GetQueueStringMetricsErrNotFound(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -2782,10 +2910,14 @@ func TestStatQueueV1GetQueueStringMetricsMissingArgs(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -2901,10 +3033,14 @@ func TestStatQueueGetStatQueueOK(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, @@ -3102,10 +3238,14 @@ func TestStatQueueV1GetStatQueuesForEventProfileIgnoreFilters(t *testing.T) { sS := NewStatService(dm, cfg, filterS, nil) sqPrf1 := &StatQueueProfile{ - Tenant: "cgrates.org", - ID: "SQ1", - FilterIDs: []string{"*string:~*req.Account:1001"}, - Weight: 10, + Tenant: "cgrates.org", + ID: "SQ1", + FilterIDs: []string{"*string:~*req.Account:1001"}, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, Blocker: true, QueueLength: 10, ThresholdIDs: []string{"*none"}, diff --git a/engine/tpreader_test.go b/engine/tpreader_test.go index 6ff298e82..b7524971e 100644 --- a/engine/tpreader_test.go +++ b/engine/tpreader_test.go @@ -433,7 +433,7 @@ func TestTPReaderGetLoadedIdsStatQueueProfiles(t *testing.T) { Tenant: "cgrates.org", ID: "ResGroup1", FilterIDs: []string{"*string:~*req.Account:1001", "*ai:~*req.AnswerTime:2014-07-29T15:00:00Z"}, - Weight: 10, + Weights: ";10", Blocker: true, Stored: true, }, diff --git a/engine/z_libindex_health_test.go b/engine/z_libindex_health_test.go index c152cabb7..fe80d0ddc 100644 --- a/engine/z_libindex_health_test.go +++ b/engine/z_libindex_health_test.go @@ -521,7 +521,11 @@ func TestHealthIndexStats(t *testing.T) { "*prefix:~*resources.RES_GRP1.Available:10", // *resources will not be indexing "*suffix:BrokenFilter:Invalid", }, - Weight: 30, + Weights: utils.DynamicWeights{ + { + Weight: 30, + }, + }, QueueLength: 100, TTL: 10 * time.Second, MinItems: 0, @@ -608,7 +612,11 @@ func TestHealthIndexStats(t *testing.T) { "*suffix:BrokenFilter:Invalid", "FLTR_1_NOT_EXIST", }, - Weight: 30, + Weights: utils.DynamicWeights{ + { + Weight: 30, + }, + }, QueueLength: 100, TTL: 10 * time.Second, MinItems: 0, diff --git a/engine/z_stordb_it_test.go b/engine/z_stordb_it_test.go index 964854308..2049b185d 100644 --- a/engine/z_stordb_it_test.go +++ b/engine/z_stordb_it_test.go @@ -983,7 +983,7 @@ func testStorDBitCRUDTpStats(t *testing.T) { }, }, ThresholdIDs: []string{"*none"}, - Weight: 20.0, + Weights: ";20", Stored: true, MinItems: 1, }, @@ -1028,7 +1028,7 @@ func testStorDBitCRUDTpStats(t *testing.T) { }, }, ThresholdIDs: []string{"*none"}, - Weight: 20.0, + Weights: ";20", Stored: true, MinItems: 1, }, diff --git a/general_tests/export_it_test.go b/general_tests/export_it_test.go index 9b0a2c3e2..efa2ef90e 100644 --- a/general_tests/export_it_test.go +++ b/general_tests/export_it_test.go @@ -290,9 +290,13 @@ func testExpVerifyStats(t *testing.T) { MetricID: utils.MetaTCD, }, }, - Blocker: true, - Stored: false, - Weight: 30, + Blocker: true, + Stored: false, + Weights: utils.DynamicWeights{ + { + Weight: 40, + }, + }, MinItems: 0, ThresholdIDs: []string{utils.MetaNone}, } diff --git a/migrator/attributes_it_test.go b/migrator/attributes_it_test.go index b1d944cf5..26f932910 100644 --- a/migrator/attributes_it_test.go +++ b/migrator/attributes_it_test.go @@ -316,7 +316,11 @@ func testAttrITMigrateAndMove(t *testing.T) { Value: config.NewRSRParsersMustCompile("Al1", utils.InfieldSep), }, }, - Weight: 20, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, } attrPrf2 := &engine.AttributeProfile{ Tenant: "cgrates.com", @@ -330,7 +334,11 @@ func testAttrITMigrateAndMove(t *testing.T) { Value: config.NewRSRParsersMustCompile("Al1", utils.InfieldSep), }, }, - Weight: 20, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, } switch attrAction { case utils.Migrate: @@ -471,7 +479,11 @@ func testAttrITMigrateV2(t *testing.T) { Value: config.NewRSRParsersMustCompile("Al1", utils.InfieldSep), }, }, - Weight: 20, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, } err := attrMigrator.dmIN.setV2AttributeProfile(v2attr) @@ -548,7 +560,11 @@ func testAttrITMigrateV3(t *testing.T) { Value: config.NewRSRParsersMustCompile("Al1", utils.InfieldSep), }, }, - Weight: 20, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, } err := attrMigrator.dmIN.setV3AttributeProfile(v3attr) @@ -629,7 +645,11 @@ func testAttrITMigrateV4(t *testing.T) { Value: config.NewRSRParsersMustCompile("~*req.Category:s/(.*)/${1}_UK_Mobile_Vodafone_GBRVF/", utils.InfieldSep), }, }, - Weight: 20, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, } err := attrMigrator.dmIN.setV4AttributeProfile(v4attr) @@ -732,7 +752,11 @@ func testAttrITV1ToV5(t *testing.T) { Type: utils.MetaVariable, Value: sbstPrsr, }}, - Weight: 20, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, } eOut2 := &engine.AttributeProfile{ Tenant: "cgrates.org", @@ -745,7 +769,11 @@ func testAttrITV1ToV5(t *testing.T) { Type: utils.MetaVariable, Value: sbstPrsr, }}, - Weight: 20, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, } // Migrate to latest version @@ -861,7 +889,11 @@ func testAttrITV2ToV5(t *testing.T) { Type: utils.MetaVariable, Value: sbstPrsr, }}, - Weight: 20, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, } eOut2 := &engine.AttributeProfile{ Tenant: "cgrates.org", @@ -874,7 +906,11 @@ func testAttrITV2ToV5(t *testing.T) { Type: utils.MetaVariable, Value: sbstPrsr, }}, - Weight: 20, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, } //Migrate to latest version @@ -979,7 +1015,11 @@ func testAttrITV3ToV5(t *testing.T) { Type: utils.MetaVariable, Value: sbstPrsr, }}, - Weight: 20, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, } eOut2 := &engine.AttributeProfile{ Tenant: "cgrates.org", @@ -992,7 +1032,11 @@ func testAttrITV3ToV5(t *testing.T) { Type: utils.MetaVariable, Value: sbstPrsr, }}, - Weight: 20, + Weights: utils.DynamicWeights{ + { + Weight: 20, + }, + }, } //Migrate to latest version diff --git a/migrator/filters_it_test.go b/migrator/filters_it_test.go index abf4c2eed..7a78a2540 100644 --- a/migrator/filters_it_test.go +++ b/migrator/filters_it_test.go @@ -172,7 +172,11 @@ func testFltrITMigrateAndMove(t *testing.T) { Value: config.NewRSRParsersMustCompile("1002", utils.InfieldSep), }, }, - Weight: 10, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, } expAttrProf := &engine.AttributeProfile{ Tenant: "cgrates.org", @@ -185,7 +189,11 @@ func testFltrITMigrateAndMove(t *testing.T) { Value: config.NewRSRParsersMustCompile("1002", utils.InfieldSep), }, }, - Weight: 10, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, } expAttrProf.Compile() attrProf.Compile() @@ -364,7 +372,11 @@ func testFltrITMigratev2(t *testing.T) { Value: config.NewRSRParsersMustCompile("1002", utils.InfieldSep), }, }, - Weight: 10, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, } expAttrProf := &engine.AttributeProfile{ Tenant: "cgrates.org", @@ -377,7 +389,11 @@ func testFltrITMigratev2(t *testing.T) { Value: config.NewRSRParsersMustCompile("1002", utils.InfieldSep), }, }, - Weight: 10, + Weights: utils.DynamicWeights{ + { + Weight: 10, + }, + }, } expAttrProf.Compile() attrProf.Compile() diff --git a/migrator/stats_it_test.go b/migrator/stats_it_test.go index 059ec39d3..0566c7816 100644 --- a/migrator/stats_it_test.go +++ b/migrator/stats_it_test.go @@ -435,8 +435,12 @@ func testStsITMigrateFromv1(t *testing.T) { t.Error(err) } else if statQueueProfile.ThresholdIDs[0] != "Test" { t.Errorf("Expecting: 'Test', received: %+v", statQueueProfile.ThresholdIDs[0]) - } else if statQueueProfile.Weight != 0 { - t.Errorf("Expecting: '0', received: %+v", statQueueProfile.Weight) + } else if reflect.DeepEqual(statQueueProfile.Weights, utils.DynamicWeights{ + { + Weight: 0, + }, + }) { + t.Errorf("Expecting: '0', received: %+v", statQueueProfile.Weights) } else if !statQueueProfile.Stored { t.Errorf("Expecting: 'true', received: %+v", statQueueProfile.Stored) } else if statQueueProfile.Blocker { diff --git a/migrator/tp_stats_it_test.go b/migrator/tp_stats_it_test.go index 5698d0035..f31649b92 100644 --- a/migrator/tp_stats_it_test.go +++ b/migrator/tp_stats_it_test.go @@ -121,7 +121,7 @@ func testTpStatsITPopulate(t *testing.T) { }, Blocker: false, Stored: false, - Weight: 20, + Weights: ";20", MinItems: 1, ThresholdIDs: []string{"ThreshValueTwo"}, }, diff --git a/utils/apitpdata.go b/utils/apitpdata.go index 9a112c224..788b3c874 100644 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -238,7 +238,7 @@ type TPStatProfile struct { Metrics []*MetricWithFilters Blocker bool // blocker flag to stop processing on filters matched Stored bool - Weight float64 + Weights string MinItems int ThresholdIDs []string }