diff --git a/engine/libsuppliers.go b/engine/libsuppliers.go index 2c019273a..f3576c774 100644 --- a/engine/libsuppliers.go +++ b/engine/libsuppliers.go @@ -20,11 +20,9 @@ package engine import ( "fmt" - "net" "sort" "strings" - "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/utils" ) @@ -95,29 +93,21 @@ func (sSpls *SortedSuppliers) SortHighestCost() { // SortQOS is part of sort interface, // sort based on Stats func (sSpls *SortedSuppliers) SortQOS(params []string) { - //sort the metrics before sorting the suppliers - for _, val := range sSpls.SortedSuppliers { - for _, iface := range val.SortingData { - if castedVal, canCast := iface.(SplStatMetrics); canCast { - castedVal.Sort() - } - } - } //sort suppliers sort.Slice(sSpls.SortedSuppliers, func(i, j int) bool { for _, param := range params { //in case we have the same value for the current param we skip to the next one - if sSpls.SortedSuppliers[i].SortingData[param].(SplStatMetrics)[0].MetricValue == sSpls.SortedSuppliers[j].SortingData[param].(SplStatMetrics)[0].MetricValue { + if sSpls.SortedSuppliers[i].SortingData[param].(float64) == sSpls.SortedSuppliers[j].SortingData[param].(float64) { continue } - switch sSpls.SortedSuppliers[i].SortingData[param].(SplStatMetrics)[0].metricType { + switch param { default: - if sSpls.SortedSuppliers[i].SortingData[param].(SplStatMetrics)[0].MetricValue > sSpls.SortedSuppliers[j].SortingData[param].(SplStatMetrics)[0].MetricValue { + if sSpls.SortedSuppliers[i].SortingData[param].(float64) > sSpls.SortedSuppliers[j].SortingData[param].(float64) { return true } return false case utils.MetaPDD: //in case of pdd the smalles value if the best - if sSpls.SortedSuppliers[i].SortingData[param].(SplStatMetrics)[0].MetricValue < sSpls.SortedSuppliers[j].SortingData[param].(SplStatMetrics)[0].MetricValue { + if sSpls.SortedSuppliers[i].SortingData[param].(float64) < sSpls.SortedSuppliers[j].SortingData[param].(float64) { return true } return false @@ -191,98 +181,3 @@ func (ssd SupplierSortDispatcher) SortSuppliers(prflID, strategy string, } return sd.SortSuppliers(prflID, suppls, suplEv, extraOpts) } - -//StatMetric used to store the statID and the metric value -type SplStatMetric struct { - StatID string - MetricValue float64 - - metricType string -} - -//StatMetrics is a sortable list of StatMetric -type SplStatMetrics []*SplStatMetric - -// Sort is part of sort interface, sort based on Weight -func (sm SplStatMetrics) Sort() { - sort.Slice(sm, func(i, j int) bool { - switch sm[i].metricType { - default: - return sm[i].MetricValue < sm[j].MetricValue - case utils.MetaPDD: // in case of PDD we take the greater value - return sm[i].MetricValue > sm[j].MetricValue - } - }) -} - -// newSplDataProvider constructs a DataProvider -func newSplDataProvider(event, sortingData map[string]interface{}) (dP config.DataProvider) { - for _, iface := range sortingData { - if castedVal, canCast := iface.(SplStatMetrics); canCast { - castedVal.Sort() - } - } - dP = &supplierDP{event: config.NewNavigableMap(event), sortingData: sortingData, cache: config.NewNavigableMap(nil)} - return -} - -// supplierDP implements engine.DataProvider -type supplierDP struct { - event *config.NavigableMap - sortingData map[string]interface{} - cache *config.NavigableMap -} - -// String is part of engine.DataProvider interface -// when called, it will display the already parsed values out of cache -func (sDP *supplierDP) String() string { - return "" -} - -// FieldAsInterface is part of engine.DataProvider interface -func (sDP *supplierDP) FieldAsInterface(fldPath []string) (data interface{}, err error) { - if data, err = sDP.cache.FieldAsInterface(fldPath); err != nil { - if err != utils.ErrNotFound { // item found in cache - return - } - err = nil // cancel previous err - } else { - return // data found in cache - } - switch fldPath[0] { - default: - return nil, fmt.Errorf("unsupported field prefix: <%s>", fldPath[0]) - case utils.MetaReq: - data, err = sDP.event.FieldAsInterface(fldPath[1:]) - case utils.MetaVars: - if _, canCast := sDP.sortingData[fldPath[1]].(SplStatMetrics); canCast { - data = sDP.sortingData[fldPath[1]].(SplStatMetrics)[0].MetricValue - } else { - data = sDP.sortingData[fldPath[1]] - } - } - sDP.cache.Set(fldPath, data, false, false) - return -} - -// FieldAsString is part of engine.DataProvider interface -func (sDP *supplierDP) FieldAsString(fldPath []string) (data string, err error) { - var valIface interface{} - valIface, err = sDP.FieldAsInterface(fldPath) - if err != nil { - return - } - data, err = utils.IfaceAsString(valIface) - return -} - -// AsNavigableMap is part of engine.DataProvider interface -func (sDP *supplierDP) AsNavigableMap([]*config.FCTemplate) ( - nm *config.NavigableMap, err error) { - return nil, utils.ErrNotImplemented -} - -// RemoteHost is part of engine.DataProvider interface -func (sDP *supplierDP) RemoteHost() net.Addr { - return nil -} diff --git a/engine/libsuppliers_test.go b/engine/libsuppliers_test.go index fe62fa904..666cfb123 100644 --- a/engine/libsuppliers_test.go +++ b/engine/libsuppliers_test.go @@ -279,204 +279,38 @@ func TestLibSuppliersSortHighestCost(t *testing.T) { } } -func TestLibSuppliersStatMetricSort(t *testing.T) { - sm := SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: 10.1}, - &SplStatMetric{StatID: "SampleStat2", - metricType: utils.MetaACD, - MetricValue: 23.1}, - &SplStatMetric{StatID: "SampleStat3", - metricType: utils.MetaACD, - MetricValue: 10.0}, - } - sm.Sort() - exp := SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat3", - metricType: utils.MetaACD, - MetricValue: 10.0}, - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: 10.1}, - &SplStatMetric{StatID: "SampleStat2", - metricType: utils.MetaACD, - MetricValue: 23.1}, - } - if !reflect.DeepEqual(exp, sm) { - t.Errorf("Expecting: %s, received: %s", - utils.ToJSON(exp), utils.ToJSON(sm)) - } -} - -func TestLibSuppliersStatMetricSort2(t *testing.T) { - sm := SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaPDD, - MetricValue: 10.1}, - &SplStatMetric{StatID: "SampleStat2", - metricType: utils.MetaPDD, - MetricValue: 23.1}, - &SplStatMetric{StatID: "SampleStat3", - metricType: utils.MetaPDD, - MetricValue: 10.0}, - } - sm.Sort() - exp := SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat2", - metricType: utils.MetaPDD, - MetricValue: 23.1}, - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaPDD, - MetricValue: 10.1}, - &SplStatMetric{StatID: "SampleStat3", - metricType: utils.MetaPDD, - MetricValue: 10.0}, - } - if !reflect.DeepEqual(exp, sm) { - t.Errorf("Expecting: %s, received: %s", - utils.ToJSON(exp), utils.ToJSON(sm)) - } -} - -func TestLibSuppliersSplDataProvide(t *testing.T) { - //simulatedData simulate sortingData - simulatedData := map[string]interface{}{ - utils.Cost: 12.45, - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{ - StatID: utils.META_NONE, - metricType: utils.MetaACD, - MetricValue: 9.0}, - &SplStatMetric{ - StatID: utils.META_NONE, - metricType: utils.MetaACD, - MetricValue: 10.0}, - }, - utils.MetaPDD: SplStatMetrics{ - &SplStatMetric{ - StatID: utils.META_NONE, - metricType: utils.MetaPDD, - MetricValue: 12.0}, - &SplStatMetric{ - StatID: utils.META_NONE, - metricType: utils.MetaPDD, - MetricValue: 5.0}, - }, - } - ev := map[string]interface{}{ - utils.Account: "1001", - } - sDP := newSplDataProvider(ev, simulatedData) - exp := "1001" - if rcv, err := sDP.FieldAsInterface([]string{utils.MetaReq, utils.Account}); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(rcv, exp) { - t.Errorf("Expecting: %+v, received: %+v", exp, rcv) - } - exp2 := 12.45 - if rcv, err := sDP.FieldAsInterface([]string{utils.MetaVars, utils.Cost}); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(rcv, exp2) { - t.Errorf("Expecting: %+v, received: %+v", exp2, rcv) - } - exp3 := 9.0 - if rcv, err := sDP.FieldAsInterface([]string{utils.MetaVars, utils.MetaACD}); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(rcv, exp3) { - t.Errorf("Expecting: %+v, received: %+v", exp3, rcv) - } - exp4 := 12.0 - if rcv, err := sDP.FieldAsInterface([]string{utils.MetaVars, utils.MetaPDD}); err != nil { - t.Error(err) - } else if !reflect.DeepEqual(rcv, exp4) { - t.Errorf("Expecting: %+v, received: %+v", exp4, rcv) - } -} - //sort based on *acd and *tcd func TestLibSuppliersSortQOS(t *testing.T) { sSpls := &SortedSuppliers{ SortedSuppliers: []*SortedSupplier{ &SortedSupplier{ - //the worst value for supplier1 for *acd is 0.5 , *tcd 1.1 + //the average value for supplier1 for *acd is 0.5 , *tcd 1.1 SupplierID: "supplier1", SortingData: map[string]interface{}{ - utils.Cost: 0.5, - utils.Weight: 10.0, - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: 0.5}, - &SplStatMetric{StatID: "SampleStat2", - metricType: utils.MetaACD, - MetricValue: 23.1}, - &SplStatMetric{StatID: "SampleStat3", - metricType: utils.MetaACD, - MetricValue: 10.0}, - }, - utils.MetaTCD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaTCD, - MetricValue: 1.1}, - &SplStatMetric{StatID: "SampleStat2", - metricType: utils.MetaTCD, - MetricValue: 12.1}, - }, + utils.Cost: 0.5, + utils.Weight: 10.0, + utils.MetaACD: 0.5, + utils.MetaTCD: 1.1, }, }, &SortedSupplier{ - //the worst value for supplier2 for *acd is 0.5 , *tcd 4.1 + //the average value for supplier2 for *acd is 0.5 , *tcd 4.1 SupplierID: "supplier2", SortingData: map[string]interface{}{ - utils.Cost: 0.1, - utils.Weight: 15.0, - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: 1.1}, - &SplStatMetric{StatID: "SampleStat2", - metricType: utils.MetaACD, - MetricValue: 12.1}, - &SplStatMetric{StatID: "SampleStat3", - metricType: utils.MetaACD, - MetricValue: 0.5}, - }, - utils.MetaTCD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaTCD, - MetricValue: 12.1}, - &SplStatMetric{StatID: "SampleStat2", - metricType: utils.MetaTCD, - MetricValue: 4.1}, - }, + utils.Cost: 0.1, + utils.Weight: 15.0, + utils.MetaACD: 0.5, + utils.MetaTCD: 4.1, }, }, &SortedSupplier{ - //the worst value for supplier3 for *acd is 0.4 , *tcd 5.1 + //the average value for supplier3 for *acd is 0.4 , *tcd 5.1 SupplierID: "supplier3", SortingData: map[string]interface{}{ - utils.Cost: 1.1, - utils.Weight: 17.8, - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: 0.4}, - &SplStatMetric{StatID: "SampleStat2", - metricType: utils.MetaACD, - MetricValue: 2.1}, - &SplStatMetric{StatID: "SampleStat3", - metricType: utils.MetaACD, - MetricValue: 0.5}, - }, - utils.MetaTCD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaTCD, - MetricValue: 6.1}, - &SplStatMetric{StatID: "SampleStat2", - metricType: utils.MetaTCD, - MetricValue: 5.1}, - }, + utils.Cost: 1.1, + utils.Weight: 17.8, + utils.MetaACD: 0.4, + utils.MetaTCD: 5.1, }, }, }, @@ -501,29 +335,12 @@ func TestLibSuppliersSortQOS2(t *testing.T) { sSpls := &SortedSuppliers{ SortedSuppliers: []*SortedSupplier{ &SortedSupplier{ - //the worst value for supplier1 for *acd is 0.5 , *tcd 1.1 + //the average value for supplier1 for *acd is 0.5 , *tcd 1.1 SupplierID: "supplier1", SortingData: map[string]interface{}{ - utils.Weight: 10.0, - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: 0.5}, - &SplStatMetric{StatID: "SampleStat2", - metricType: utils.MetaACD, - MetricValue: 0.7}, - &SplStatMetric{StatID: "SampleStat3", - metricType: utils.MetaACD, - MetricValue: 0.6}, - }, - utils.MetaTCD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaTCD, - MetricValue: 1.1}, - &SplStatMetric{StatID: "SampleStat2", - metricType: utils.MetaTCD, - MetricValue: 12.1}, - }, + utils.Weight: 10.0, + utils.MetaACD: 0.5, + utils.MetaTCD: 1.1, }, }, &SortedSupplier{ @@ -532,50 +349,19 @@ func TestLibSuppliersSortQOS2(t *testing.T) { //will be sorted based on weight SupplierID: "supplier2", SortingData: map[string]interface{}{ - utils.Weight: 17.0, - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: 0.5}, - &SplStatMetric{StatID: "SampleStat2", - metricType: utils.MetaACD, - MetricValue: 0.5}, - &SplStatMetric{StatID: "SampleStat3", - metricType: utils.MetaACD, - MetricValue: 0.5}, - }, - utils.MetaTCD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaTCD, - MetricValue: 1.1}, - &SplStatMetric{StatID: "SampleStat2", - metricType: utils.MetaTCD, - MetricValue: 12.1}, - }, + utils.Weight: 17.0, + utils.MetaACD: 0.5, + utils.MetaTCD: 1.1, }, }, &SortedSupplier{ - //the worst value for supplier1 for *acd is 0.5 , *tcd 1.1 + SupplierID: "supplier3", SortingData: map[string]interface{}{ - utils.Cost: 0.5, - utils.Weight: 10.0, - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: 0.5}, - &SplStatMetric{StatID: "SampleStat2", - metricType: utils.MetaACD, - MetricValue: 0.5}, - &SplStatMetric{StatID: "SampleStat3", - metricType: utils.MetaACD, - MetricValue: 0.5}, - }, - utils.MetaTCD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaTCD, - MetricValue: 1.2}, - }, + utils.Cost: 0.5, + utils.Weight: 10.0, + utils.MetaACD: 0.7, + utils.MetaTCD: 1.1, }, }, }, @@ -603,60 +389,27 @@ func TestLibSuppliersSortQOS3(t *testing.T) { //will be sorted based on weight SupplierID: "supplier1", SortingData: map[string]interface{}{ - utils.Weight: 15.0, - utils.MetaPDD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaPDD, - MetricValue: 0.5}, - &SplStatMetric{StatID: "SampleStat2", - metricType: utils.MetaACD, - MetricValue: 0.7}, - }, - utils.MetaTCD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaTCD, - MetricValue: 1.1}, - &SplStatMetric{StatID: "SampleStat2", - metricType: utils.MetaTCD, - MetricValue: 12.1}, - }, + utils.Weight: 15.0, + utils.MetaPDD: 0.7, + utils.MetaTCD: 1.1, }, }, &SortedSupplier{ //the worst value for supplier2 for *pdd is 1.2, *tcd 1.1 SupplierID: "supplier2", SortingData: map[string]interface{}{ - utils.Weight: 10.0, - utils.MetaPDD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaPDD, - MetricValue: 0.9}, - &SplStatMetric{StatID: "SampleStat2", - metricType: utils.MetaACD, - MetricValue: 1.2}, - }, - utils.MetaTCD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaTCD, - MetricValue: 1.1}, - }, + utils.Weight: 10.0, + utils.MetaPDD: 1.2, + utils.MetaTCD: 1.1, }, }, &SortedSupplier{ //the worst value for supplier3 for *pdd is 0.7, *tcd 10.1 SupplierID: "supplier3", SortingData: map[string]interface{}{ - utils.Weight: 10.0, - utils.MetaPDD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaPDD, - MetricValue: 0.7}, - }, - utils.MetaTCD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaTCD, - MetricValue: 10.1}, - }, + utils.Weight: 10.0, + utils.MetaPDD: 0.7, + utils.MetaTCD: 10.1, }, }, }, @@ -680,61 +433,25 @@ func TestLibSuppliersSortQOS4(t *testing.T) { &SortedSupplier{ SupplierID: "supplier1", SortingData: map[string]interface{}{ - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: 0.2}, - }, - utils.MetaTCD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaTCD, - MetricValue: 15.0}, - }, - utils.MetaASR: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaASR, - MetricValue: 1.2}, - }, + utils.MetaACD: 0.2, + utils.MetaTCD: 15.0, + utils.MetaASR: 1.2, }, }, &SortedSupplier{ SupplierID: "supplier2", SortingData: map[string]interface{}{ - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: 0.2}, - }, - utils.MetaTCD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaTCD, - MetricValue: 20.0}, - }, - utils.MetaASR: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaASR, - MetricValue: -1.0}, - }, + utils.MetaACD: 0.2, + utils.MetaTCD: 20.0, + utils.MetaASR: -1.0, }, }, &SortedSupplier{ SupplierID: "supplier3", SortingData: map[string]interface{}{ - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: 0.1}, - }, - utils.MetaTCD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaTCD, - MetricValue: 10.0}, - }, - utils.MetaASR: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaASR, - MetricValue: 1.2}, - }, + utils.MetaACD: 0.1, + utils.MetaTCD: 10.0, + utils.MetaASR: 1.2, }, }, }, @@ -758,76 +475,28 @@ func TestLibSuppliersSortQOS5(t *testing.T) { &SortedSupplier{ SupplierID: "supplier1", SortingData: map[string]interface{}{ - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: 0.2}, - }, - utils.MetaTCD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaTCD, - MetricValue: 15.0}, - }, - utils.MetaASR: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaASR, - MetricValue: -1.0}, - }, - utils.MetaTCC: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaTCC, - MetricValue: 10.1}, - }, + utils.MetaACD: 0.2, + utils.MetaTCD: 15.0, + utils.MetaASR: -1.0, + utils.MetaTCC: 10.1, }, }, &SortedSupplier{ SupplierID: "supplier2", SortingData: map[string]interface{}{ - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: 0.2}, - }, - utils.MetaTCD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaTCD, - MetricValue: 20.0}, - }, - utils.MetaASR: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaASR, - MetricValue: 1.2}, - }, - utils.MetaTCC: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaTCC, - MetricValue: 10.1}, - }, + utils.MetaACD: 0.2, + utils.MetaTCD: 20.0, + utils.MetaASR: 1.2, + utils.MetaTCC: 10.1, }, }, &SortedSupplier{ SupplierID: "supplier3", SortingData: map[string]interface{}{ - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: 0.1}, - }, - utils.MetaTCD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaTCD, - MetricValue: 10.0}, - }, - utils.MetaASR: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaASR, - MetricValue: 1.2}, - }, - utils.MetaTCC: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaTCC, - MetricValue: 10.1}, - }, + utils.MetaACD: 0.1, + utils.MetaTCD: 10.0, + utils.MetaASR: 1.2, + utils.MetaTCC: 10.1, }, }, }, @@ -851,34 +520,22 @@ func TestLibSuppliersSortQOS6(t *testing.T) { &SortedSupplier{ SupplierID: "supplier1", SortingData: map[string]interface{}{ - utils.Weight: 15.0, - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: 0.2}, - }, + utils.Weight: 15.0, + utils.MetaACD: 0.2, }, }, &SortedSupplier{ SupplierID: "supplier2", SortingData: map[string]interface{}{ - utils.Weight: 25.0, - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: 0.2}, - }, + utils.Weight: 25.0, + utils.MetaACD: 0.2, }, }, &SortedSupplier{ SupplierID: "supplier3", SortingData: map[string]interface{}{ - utils.Weight: 20.0, - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: 0.1}, - }, + utils.Weight: 20.0, + utils.MetaACD: 0.1, }, }, }, @@ -902,34 +559,22 @@ func TestLibSuppliersSortQOS7(t *testing.T) { &SortedSupplier{ SupplierID: "supplier1", SortingData: map[string]interface{}{ - utils.Weight: 15.0, - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: -1.0}, - }, + utils.Weight: 15.0, + utils.MetaACD: -1.0, }, }, &SortedSupplier{ SupplierID: "supplier2", SortingData: map[string]interface{}{ - utils.Weight: 25.0, - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: -1.0}, - }, + utils.Weight: 25.0, + utils.MetaACD: -1.0, }, }, &SortedSupplier{ SupplierID: "supplier3", SortingData: map[string]interface{}{ - utils.Weight: 20.0, - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: -1.0}, - }, + utils.Weight: 20.0, + utils.MetaACD: -1.0, }, }, }, @@ -953,35 +598,22 @@ func TestLibSuppliersSortQOS8(t *testing.T) { &SortedSupplier{ SupplierID: "supplier1", SortingData: map[string]interface{}{ - utils.Weight: 15.0, - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: -1.0}, - }, + utils.Weight: 15.0, + utils.MetaACD: -1.0, }, }, &SortedSupplier{ SupplierID: "supplier2", SortingData: map[string]interface{}{ - utils.Weight: 25.0, - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: -1.0}, - }, + utils.Weight: 25.0, + utils.MetaACD: -1.0, }, - SupplierParameters: "param2", }, &SortedSupplier{ SupplierID: "supplier3", SortingData: map[string]interface{}{ - utils.Weight: 20.0, - utils.MetaACD: SplStatMetrics{ - &SplStatMetric{StatID: "SampleStat", - metricType: utils.MetaACD, - MetricValue: 10.0}, - }, + utils.Weight: 20.0, + utils.MetaACD: 10.0, }, }, }, diff --git a/engine/suppliers.go b/engine/suppliers.go index 2dce35ac4..9211a6218 100644 --- a/engine/suppliers.go +++ b/engine/suppliers.go @@ -253,8 +253,9 @@ 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, tenant string) (stsMetric map[string]SplStatMetrics, err error) { - stsMetric = make(map[string]SplStatMetrics) +func (spS *SupplierService) statMetrics(statIDs []string, tenant string) (stsMetric map[string]float64, err error) { + stsMetric = make(map[string]float64) + provStsMetrics := make(map[string][]float64) if spS.statS != nil { for _, statID := range statIDs { var metrics map[string]float64 @@ -265,9 +266,17 @@ func (spS *SupplierService) statMetrics(statIDs []string, tenant string) (stsMet fmt.Sprintf(" error: %s getting statMetrics for stat : %s", err.Error(), statID)) } for key, val := range metrics { - stsMetric[key] = append(stsMetric[key], &SplStatMetric{StatID: statID, metricType: key, MetricValue: val}) + //add value of metric in a slice in case that we get the same metric from different stat + provStsMetrics[key] = append(provStsMetrics[key], val) } } + for metric, slice := range provStsMetrics { + sum := 0.0 + for _, val := range slice { + sum += val + } + stsMetric[metric] = sum / float64(len(slice)) + } } return } @@ -348,9 +357,9 @@ func (spS *SupplierService) populateSortingData(ev *utils.CGREvent, spl *Supplie if _, hasMetric := metricSupp[metric]; !hasMetric { switch metric { default: - sortedSpl.SortingData[metric] = SplStatMetrics{&SplStatMetric{StatID: utils.META_NONE, metricType: metric, MetricValue: -1.0}} + sortedSpl.SortingData[metric] = -1.0 case utils.MetaPDD: - sortedSpl.SortingData[metric] = SplStatMetrics{&SplStatMetric{StatID: utils.META_NONE, metricType: metric, MetricValue: 10000000.0}} + sortedSpl.SortingData[metric] = 10000000.0 } } } @@ -373,10 +382,12 @@ func (spS *SupplierService) populateSortingData(ev *utils.CGREvent, spl *Supplie //filter the supplier if len(spl.FilterIDs) != 0 { //construct the DP and pass it to filterS - sDP := newSplDataProvider(ev.Event, sortedSpl.SortingData) + nM := config.NewNavigableMap(nil) + nM.Set([]string{utils.MetaReq}, ev.Event, false, false) + nM.Set([]string{utils.MetaVars}, sortedSpl.SortingData, false, false) if pass, err = spS.filterS.Pass(ev.Tenant, spl.FilterIDs, - sDP); err != nil { + nM); err != nil { return nil, false, err } else if !pass { return nil, false, nil