diff --git a/apier/v1/suppliers_it_test.go b/apier/v1/suppliers_it_test.go index 9b3afc389..0fe469890 100644 --- a/apier/v1/suppliers_it_test.go +++ b/apier/v1/suppliers_it_test.go @@ -54,6 +54,8 @@ var sTestsSupplierSV1 = []func(t *testing.T){ testV1SplSGetLeastCostSuppliersWithMaxCost2, testV1SplSGetLeastCostSuppliersWithMaxCostNotFound, testV1SplSGetHighestCostSuppliers, + testV1SplSPolulateStatsForQOS, + testV1SplSGetQOSSuppliers, testV1SplSGetSupplierWithoutFilter, testV1SplSSetSupplierProfiles, testV1SplSUpdateSupplierProfiles, @@ -393,6 +395,147 @@ func testV1SplSGetHighestCostSuppliers(t *testing.T) { } } +func testV1SplSPolulateStatsForQOS(t *testing.T) { + var reply []string + expected := []string{"Stat_1"} + ev1 := utils.CGREvent{ + Tenant: "cgrates.org", + ID: "event1", + Event: map[string]interface{}{ + utils.Account: "1001", + utils.AnswerTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + utils.Usage: time.Duration(11 * time.Second), + utils.COST: 10.0, + }, + } + if err := splSv1Rpc.Call(utils.StatSv1ProcessEvent, &ev1, &reply); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(reply, expected) { + t.Errorf("Expecting: %+v, received: %+v", expected, reply) + } + + expected = []string{"Stat_1"} + ev1 = utils.CGREvent{ + Tenant: "cgrates.org", + ID: "event2", + Event: map[string]interface{}{ + utils.Account: "1001", + utils.AnswerTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + utils.Usage: time.Duration(11 * time.Second), + utils.COST: 10.5, + }, + } + if err := splSv1Rpc.Call(utils.StatSv1ProcessEvent, &ev1, &reply); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(reply, expected) { + t.Errorf("Expecting: %+v, received: %+v", expected, reply) + } + + expected = []string{"Stat_2"} + ev1 = utils.CGREvent{ + Tenant: "cgrates.org", + ID: "event2", + Event: map[string]interface{}{ + utils.Account: "1002", + utils.AnswerTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + utils.Usage: time.Duration(5 * time.Second), + utils.COST: 12.5, + }, + } + if err := splSv1Rpc.Call(utils.StatSv1ProcessEvent, &ev1, &reply); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(reply, expected) { + t.Errorf("Expecting: %+v, received: %+v", expected, reply) + } + + expected = []string{"Stat_2"} + ev1 = utils.CGREvent{ + Tenant: "cgrates.org", + ID: "event2", + Event: map[string]interface{}{ + utils.Account: "1002", + utils.AnswerTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + utils.Usage: time.Duration(6 * time.Second), + utils.COST: 17.5, + }, + } + if err := splSv1Rpc.Call(utils.StatSv1ProcessEvent, &ev1, &reply); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(reply, expected) { + t.Errorf("Expecting: %+v, received: %+v", expected, reply) + } + + expected = []string{"Stat_3"} + ev1 = utils.CGREvent{ + Tenant: "cgrates.org", + ID: "event3", + Event: map[string]interface{}{ + utils.Account: "1003", + utils.AnswerTime: time.Date(2014, 7, 14, 14, 25, 0, 0, time.UTC), + utils.Usage: time.Duration(11 * time.Second), + utils.COST: 12.5, + }, + } + if err := splSv1Rpc.Call(utils.StatSv1ProcessEvent, &ev1, &reply); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(reply, expected) { + t.Errorf("Expecting: %+v, received: %+v", expected, reply) + } +} + +func testV1SplSGetQOSSuppliers(t *testing.T) { + ev := &engine.ArgsGetSuppliers{ + CGREvent: utils.CGREvent{ + Tenant: "cgrates.org", + ID: "testV1SplSGetQOSSuppliers", + Event: map[string]interface{}{ + "DistincMatch": "*qos", + }, + }, + } + eSpls := engine.SortedSuppliers{ + ProfileID: "SPL_QOS_1", + Sorting: utils.MetaQOS, + SortedSuppliers: []*engine.SortedSupplier{ + &engine.SortedSupplier{ + SupplierID: "supplier1", + SortingData: map[string]interface{}{ + utils.MetaACD: 11.0, + utils.MetaASR: 100.0, + utils.MetaTCD: 22.0, + utils.Weight: 10.0, + }, + }, + &engine.SortedSupplier{ + SupplierID: "supplier3", + SortingData: map[string]interface{}{ + utils.MetaACD: 11.0, + utils.MetaASR: 100.0, + utils.MetaTCD: 11.0, + utils.Weight: 35.0, + }, + }, + &engine.SortedSupplier{ + SupplierID: "supplier2", + SortingData: map[string]interface{}{ + utils.MetaACD: 5.5, + utils.MetaASR: 100.0, + utils.MetaTCD: 11.0, + utils.Weight: 20.0, + }, + }, + }, + } + var suplsReply engine.SortedSuppliers + if err := splSv1Rpc.Call(utils.SupplierSv1GetSuppliers, + ev, &suplsReply); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(eSpls, suplsReply) { + t.Errorf("Expecting: %s, received: %s", + utils.ToJSON(eSpls), utils.ToJSON(suplsReply)) + } +} + func testV1SplSGetSupplierWithoutFilter(t *testing.T) { ev := &engine.ArgsGetSuppliers{ CGREvent: utils.CGREvent{ @@ -540,7 +683,9 @@ func testV1SplSRemSupplierProfiles(t *testing.T) { t.Error("Unexpected reply returned", resp) } var reply *engine.SupplierProfile - if err := splSv1Rpc.Call("ApierV1.GetAttributeProfile", &utils.TenantID{Tenant: "cgrates.org", ID: "TEST_PROFILE1"}, &reply); err == nil || err.Error() != utils.ErrNotFound.Error() { + if err := splSv1Rpc.Call("ApierV1.GetSupplierProfile", + &utils.TenantID{Tenant: "cgrates.org", ID: "TEST_PROFILE1"}, &reply); err == nil || + err.Error() != utils.ErrNotFound.Error() { t.Error(err) } } diff --git a/data/conf/samples/tutmongo/cgrates.json b/data/conf/samples/tutmongo/cgrates.json index 2e04f97ff..c764754a9 100644 --- a/data/conf/samples/tutmongo/cgrates.json +++ b/data/conf/samples/tutmongo/cgrates.json @@ -138,6 +138,9 @@ "suppliers": { "enabled": true, + "stats_conns": [ + {"address": "*internal"}, + ], }, diff --git a/data/conf/samples/tutmysql/cgrates.json b/data/conf/samples/tutmysql/cgrates.json index ad06e1929..0922f5a05 100644 --- a/data/conf/samples/tutmysql/cgrates.json +++ b/data/conf/samples/tutmysql/cgrates.json @@ -260,6 +260,9 @@ "suppliers": { "enabled": true, + "stats_conns": [ + {"address": "*internal"}, + ], }, diff --git a/data/tariffplans/testit/Filters.csv b/data/tariffplans/testit/Filters.csv index d8ffe685c..fcc1207f3 100644 --- a/data/tariffplans/testit/Filters.csv +++ b/data/tariffplans/testit/Filters.csv @@ -9,4 +9,8 @@ cgrates.org,FLTR_ACNT_dan,*string,Account,dan,2014-07-29T15:00:00Z cgrates.org,FLTR_SPP_2,*string,Account,1003;1002,2014-07-29T15:00:00Z cgrates.org,FLTR_SPP_2,*prefix,Destination,10;20, cgrates.org,FLTR_SPP_2,*rsr,,Subject(~^1.*1$);Destination(1002), -cgrates.org,FLTR_SPP_2,*string,DistincMatch,*highest_cost, \ No newline at end of file +cgrates.org,FLTR_SPP_2,*string,DistincMatch,*highest_cost, +cgrates.org,FLTR_SPP_3,*string,DistincMatch,*qos,2014-07-29T15:00:00Z +cgrates.org,FLTR_STAT_1,*string,Account,1001,2014-07-29T15:00:00Z +cgrates.org,FLTR_STAT_2,*string,Account,1002,2014-07-29T15:00:00Z +cgrates.org,FLTR_STAT_3,*string,Account,1003,2014-07-29T15:00:00Z \ No newline at end of file diff --git a/data/tariffplans/testit/Stats.csv b/data/tariffplans/testit/Stats.csv index 1e1ac34fa..b25eabc06 100644 --- a/data/tariffplans/testit/Stats.csv +++ b/data/tariffplans/testit/Stats.csv @@ -1 +1,4 @@ #Tenant[0],Id[1],FilterIDs[2],ActivationInterval[3],QueueLength[4],TTL[5],Metrics[6],MetricParams[7],Blocker[8],Stored[9],Weight[10],MinItems[11],ThresholdIDs[12] +cgrates.org,Stat_1,FLTR_STAT_1,2014-07-29T15:00:00Z,100,1s,*acd;*tcd;*asr,,false,true,30,0, +cgrates.org,Stat_2,FLTR_STAT_2,2014-07-29T15:00:00Z,100,1s,*acd;*tcd;*asr,,false,true,30,0, +cgrates.org,Stat_3,FLTR_STAT_3,2014-07-29T15:00:00Z,100,1s,*acd;*tcd;*asr,,false,true,30,0, \ No newline at end of file diff --git a/data/tariffplans/testit/Suppliers.csv b/data/tariffplans/testit/Suppliers.csv index ce3b712c3..db6a87747 100644 --- a/data/tariffplans/testit/Suppliers.csv +++ b/data/tariffplans/testit/Suppliers.csv @@ -11,4 +11,7 @@ cgrates.org,SPL_LEASTCOST_1,,,,,supplier3,,,RP_SPECIAL_1002,,,15,,, cgrates.org,SPL_HIGHESTCOST_1,FLTR_SPP_2,2017-11-27T00:00:00Z,*highest_cost,,supplier1,,,RP_SPECIAL_1002,,,10,false,,10 cgrates.org,SPL_HIGHESTCOST_1,,,,,supplier2,,,RP_RETAIL1,,,20,,, cgrates.org,SPL_HIGHESTCOST_1,,,,,supplier3,,,RP_SPECIAL_1002,,,15,,, +cgrates.org,SPL_QOS_1,FLTR_SPP_3,2017-11-27T00:00:00Z,*qos,*acd;*tcd;*asr,supplier1,,,,,Stat_1,10,false,,10 +cgrates.org,SPL_QOS_1,,,,,supplier2,,,,,Stat_2,20,,, +cgrates.org,SPL_QOS_1,,,,,supplier3,,,,,Stat_3,35,,, diff --git a/engine/libsuppliers.go b/engine/libsuppliers.go index de5e0b3bc..7ab7998d1 100644 --- a/engine/libsuppliers.go +++ b/engine/libsuppliers.go @@ -92,10 +92,31 @@ func (sSpls *SortedSuppliers) SortHighestCost() { // SortQOS is part of sort interface, // sort based on Stats -func (sSpls *SortedSuppliers) SortQOS() { +func (sSpls *SortedSuppliers) SortQOS(params []string) { sort.Slice(sSpls.SortedSuppliers, func(i, j int) bool { - //to be added - return true + for _, param := range params { + // if one of the supplier is missing the qos parram skip to next one + if _, exists := sSpls.SortedSuppliers[i].SortingData[param]; !exists { + continue + } + if _, exists := sSpls.SortedSuppliers[j].SortingData[param]; !exists { + continue + } + // skip to next param + if sSpls.SortedSuppliers[i].SortingData[param].(float64) == sSpls.SortedSuppliers[j].SortingData[param].(float64) { + continue + } + if sSpls.SortedSuppliers[i].SortingData[param].(float64) == -1 { + return false + } + switch param { + default: + return sSpls.SortedSuppliers[i].SortingData[param].(float64) > sSpls.SortedSuppliers[j].SortingData[param].(float64) + case utils.MetaPDD: + return sSpls.SortedSuppliers[i].SortingData[param].(float64) < sSpls.SortedSuppliers[j].SortingData[param].(float64) + } + } + return sSpls.SortedSuppliers[i].SortingData[utils.Weight].(float64) > sSpls.SortedSuppliers[j].SortingData[utils.Weight].(float64) }) } diff --git a/engine/libsuppliers_test.go b/engine/libsuppliers_test.go index 8560ea113..e1d04426c 100644 --- a/engine/libsuppliers_test.go +++ b/engine/libsuppliers_test.go @@ -312,18 +312,9 @@ func TestLibSuppliersSortQOS(t *testing.T) { }, }, } - sSpls.SortQOS() + sSpls.SortQOS([]string{utils.MetaACD, utils.MetaTCD}) eOrderedSpls := &SortedSuppliers{ SortedSuppliers: []*SortedSupplier{ - &SortedSupplier{ - SupplierID: "supplier3", - SortingData: map[string]interface{}{ - utils.MetaACD: 0.05, - utils.MetaTCD: 10.0, - }, - SupplierParameters: "param3", - }, - &SortedSupplier{ SupplierID: "supplier2", SortingData: map[string]interface{}{ @@ -340,6 +331,353 @@ func TestLibSuppliersSortQOS(t *testing.T) { }, SupplierParameters: "param1", }, + &SortedSupplier{ + SupplierID: "supplier3", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.05, + utils.MetaTCD: 10.0, + }, + SupplierParameters: "param3", + }, + }, + } + if !reflect.DeepEqual(eOrderedSpls, sSpls) { + t.Errorf("Expecting: %s, received: %s", + utils.ToJSON(eOrderedSpls), utils.ToJSON(sSpls)) + } +} + +func TestLibSuppliersSortQOS2(t *testing.T) { + sSpls := &SortedSuppliers{ + SortedSuppliers: []*SortedSupplier{ + &SortedSupplier{ + SupplierID: "supplier1", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.MetaTCD: 15.0, + }, + SupplierParameters: "param1", + }, + &SortedSupplier{ + SupplierID: "supplier2", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.MetaTCD: 20.0, + }, + SupplierParameters: "param2", + }, + &SortedSupplier{ + SupplierID: "supplier3", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.1, + utils.MetaTCD: 10.0, + }, + SupplierParameters: "param3", + }, + }, + } + sSpls.SortQOS([]string{utils.MetaACD, utils.MetaTCD}) + eOrderedSpls := &SortedSuppliers{ + SortedSuppliers: []*SortedSupplier{ + &SortedSupplier{ + SupplierID: "supplier2", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.MetaTCD: 20.0, + }, + SupplierParameters: "param2", + }, + &SortedSupplier{ + SupplierID: "supplier1", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.MetaTCD: 15.0, + }, + SupplierParameters: "param1", + }, + &SortedSupplier{ + SupplierID: "supplier3", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.1, + utils.MetaTCD: 10.0, + }, + SupplierParameters: "param3", + }, + }, + } + if !reflect.DeepEqual(eOrderedSpls, sSpls) { + t.Errorf("Expecting: %s, received: %s", + utils.ToJSON(eOrderedSpls), utils.ToJSON(sSpls)) + } +} + +func TestLibSuppliersSortQOS3(t *testing.T) { + sSpls := &SortedSuppliers{ + SortedSuppliers: []*SortedSupplier{ + &SortedSupplier{ + SupplierID: "supplier1", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.MetaTCD: 15.0, + utils.MetaASR: 1.2, + }, + SupplierParameters: "param1", + }, + &SortedSupplier{ + SupplierID: "supplier2", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.MetaTCD: 20.0, + utils.MetaASR: -1.0, + }, + SupplierParameters: "param2", + }, + &SortedSupplier{ + SupplierID: "supplier3", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.1, + utils.MetaTCD: 10.0, + utils.MetaASR: 1.2, + }, + SupplierParameters: "param3", + }, + }, + } + sSpls.SortQOS([]string{utils.MetaASR, utils.MetaACD, utils.MetaTCD}) + eOrderedSpls := &SortedSuppliers{ + SortedSuppliers: []*SortedSupplier{ + &SortedSupplier{ + SupplierID: "supplier1", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.MetaTCD: 15.0, + utils.MetaASR: 1.2, + }, + SupplierParameters: "param1", + }, + &SortedSupplier{ + SupplierID: "supplier3", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.1, + utils.MetaTCD: 10.0, + utils.MetaASR: 1.2, + }, + SupplierParameters: "param3", + }, + &SortedSupplier{ + SupplierID: "supplier2", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.MetaTCD: 20.0, + utils.MetaASR: -1.0, + }, + SupplierParameters: "param2", + }, + }, + } + if !reflect.DeepEqual(eOrderedSpls, sSpls) { + t.Errorf("Expecting: %s, received: %s", + utils.ToJSON(eOrderedSpls), utils.ToJSON(sSpls)) + } +} + +func TestLibSuppliersSortQOS4(t *testing.T) { + sSpls := &SortedSuppliers{ + SortedSuppliers: []*SortedSupplier{ + &SortedSupplier{ + SupplierID: "supplier1", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.MetaTCD: 15.0, + utils.MetaASR: -1.0, + utils.MetaTCC: 10.1, + }, + SupplierParameters: "param1", + }, + &SortedSupplier{ + SupplierID: "supplier2", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.MetaTCD: 20.0, + utils.MetaASR: 1.2, + utils.MetaTCC: 10.1, + }, + SupplierParameters: "param2", + }, + &SortedSupplier{ + SupplierID: "supplier3", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.1, + utils.MetaTCD: 10.0, + utils.MetaASR: 1.2, + utils.MetaTCC: 10.1, + }, + SupplierParameters: "param3", + }, + }, + } + sSpls.SortQOS([]string{utils.MetaTCC, utils.MetaASR, utils.MetaACD, utils.MetaTCD}) + eOrderedSpls := &SortedSuppliers{ + SortedSuppliers: []*SortedSupplier{ + &SortedSupplier{ + SupplierID: "supplier2", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.MetaTCD: 20.0, + utils.MetaASR: 1.2, + utils.MetaTCC: 10.1, + }, + SupplierParameters: "param2", + }, + &SortedSupplier{ + SupplierID: "supplier3", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.1, + utils.MetaTCD: 10.0, + utils.MetaASR: 1.2, + utils.MetaTCC: 10.1, + }, + SupplierParameters: "param3", + }, + &SortedSupplier{ + SupplierID: "supplier1", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.MetaTCD: 15.0, + utils.MetaASR: -1.0, + utils.MetaTCC: 10.1, + }, + SupplierParameters: "param1", + }, + }, + } + if !reflect.DeepEqual(eOrderedSpls, sSpls) { + t.Errorf("Expecting: %s, received: %s", + utils.ToJSON(eOrderedSpls), utils.ToJSON(sSpls)) + } +} + +func TestLibSuppliersSortQOS5(t *testing.T) { + sSpls := &SortedSuppliers{ + SortedSuppliers: []*SortedSupplier{ + &SortedSupplier{ + SupplierID: "supplier1", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.MetaPDD: 0.5, + }, + SupplierParameters: "param1", + }, + &SortedSupplier{ + SupplierID: "supplier2", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.MetaPDD: 0.6, + }, + SupplierParameters: "param2", + }, + &SortedSupplier{ + SupplierID: "supplier3", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.1, + utils.MetaPDD: 0.2, + }, + SupplierParameters: "param3", + }, + }, + } + sSpls.SortQOS([]string{utils.MetaPDD}) + eOrderedSpls := &SortedSuppliers{ + SortedSuppliers: []*SortedSupplier{ + &SortedSupplier{ + SupplierID: "supplier3", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.1, + utils.MetaPDD: 0.2, + }, + SupplierParameters: "param3", + }, + &SortedSupplier{ + SupplierID: "supplier1", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.MetaPDD: 0.5, + }, + SupplierParameters: "param1", + }, + &SortedSupplier{ + SupplierID: "supplier2", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.MetaPDD: 0.6, + }, + SupplierParameters: "param2", + }, + }, + } + if !reflect.DeepEqual(eOrderedSpls, sSpls) { + t.Errorf("Expecting: %s, received: %s", + utils.ToJSON(eOrderedSpls), utils.ToJSON(sSpls)) + } +} + +func TestLibSuppliersSortQOS6(t *testing.T) { + sSpls := &SortedSuppliers{ + SortedSuppliers: []*SortedSupplier{ + &SortedSupplier{ + SupplierID: "supplier1", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.Weight: 15.0, + }, + SupplierParameters: "param1", + }, + &SortedSupplier{ + SupplierID: "supplier2", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.Weight: 25.0, + }, + SupplierParameters: "param2", + }, + &SortedSupplier{ + SupplierID: "supplier3", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.1, + utils.Weight: 20.0, + }, + SupplierParameters: "param3", + }, + }, + } + sSpls.SortQOS([]string{utils.MetaACD}) + eOrderedSpls := &SortedSuppliers{ + SortedSuppliers: []*SortedSupplier{ + &SortedSupplier{ + SupplierID: "supplier2", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.Weight: 25.0, + }, + SupplierParameters: "param2", + }, + &SortedSupplier{ + SupplierID: "supplier1", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.2, + utils.Weight: 15.0, + }, + SupplierParameters: "param1", + }, + + &SortedSupplier{ + SupplierID: "supplier3", + SortingData: map[string]interface{}{ + utils.MetaACD: 0.1, + utils.Weight: 20.0, + }, + SupplierParameters: "param3", + }, }, } if !reflect.DeepEqual(eOrderedSpls, sSpls) { diff --git a/engine/spls_qos.go b/engine/spls_qos.go index fd5d6c2a4..9d340ecc9 100755 --- a/engine/spls_qos.go +++ b/engine/spls_qos.go @@ -41,7 +41,7 @@ func (lcs *QOSSupplierSorter) SortSuppliers(prflID string, suppls []*Supplier, Sorting: lcs.sorting, SortedSuppliers: make([]*SortedSupplier, 0)} for _, s := range suppls { - metricSupp, err := lcs.spS.statMetrics([]string{}, []string{}) //create metric map for suppier s + metricSupp, err := lcs.spS.statMetrics(s.StatIDs, ev.Tenant) //create metric map for suppier s if err != nil { if extraOpts.ignoreErrors { utils.Logger.Warning( @@ -69,6 +69,6 @@ func (lcs *QOSSupplierSorter) SortSuppliers(prflID string, suppls []*Supplier, if len(sortedSuppls.SortedSuppliers) == 0 { return nil, utils.ErrNotFound } - sortedSuppls.SortQOS() + sortedSuppls.SortQOS(extraOpts.sortingParameters) return } diff --git a/engine/suppliers.go b/engine/suppliers.go index 3d4a2c153..119c07e08 100644 --- a/engine/suppliers.go +++ b/engine/suppliers.go @@ -259,7 +259,22 @@ func (spS *SupplierService) costForEvent(ev *utils.CGREvent, // statMetrics will query a list of statIDs and return composed metric values // first metric found is always returned -func (spS *SupplierService) statMetrics(statIDs []string, metricIDs []string) (sms map[string]StatMetric, err error) { +func (spS *SupplierService) statMetrics(statIDs []string, tenant string) (stsMetric map[string]float64, err error) { + stsMetric = make(map[string]float64) + if spS.statS != nil { + for _, statID := range statIDs { + var metrics map[string]float64 + if err := spS.statS.Call(utils.StatSv1GetQueueFloatMetrics, + &utils.TenantID{Tenant: tenant, ID: statID}, &metrics); err != nil && + err.Error() != utils.ErrNotFound.Error() { + utils.Logger.Warning( + fmt.Sprintf(" error: %s getting statMetrics for stat : %s", err.Error(), statID)) + } + for key, val := range metrics { + stsMetric[key] = val + } + } + } return } @@ -297,6 +312,7 @@ func (spS *SupplierService) sortedSuppliersForEvent(args *ArgsGetSuppliers) (sor if err != nil { return nil, err } + extraOpts.sortingParameters = splPrfl.SortingParameters // populate sortingParameters in extraOpts sortedSuppliers, err := spS.sorter.SortSuppliers(splPrfl.ID, splPrfl.Sorting, spls, &args.CGREvent, extraOpts) if err != nil { @@ -348,8 +364,9 @@ func (args *ArgsGetSuppliers) asOptsGetSuppliers() (opts *optsGetSuppliers, err } type optsGetSuppliers struct { - ignoreErrors bool - maxCost float64 + ignoreErrors bool + maxCost float64 + sortingParameters []string //used for QOS strategy } // V1GetSuppliersForEvent returns the list of valid supplier IDs diff --git a/utils/consts.go b/utils/consts.go index f91a84331..26e10e2c1 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -716,6 +716,7 @@ const ( StatSv1ProcessEvent = "StatSv1.ProcessEvent" StatSv1GetQueueIDs = "StatSv1.GetQueueIDs" StatSv1GetQueueStringMetrics = "StatSv1.GetQueueStringMetrics" + StatSv1GetQueueFloatMetrics = "StatSv1.GetQueueFloatMetrics" StatSv1Ping = "StatSv1.Ping" StatSv1GetStatQueuesForEvent = "StatSv1.GetStatQueuesForEvent" )