Update QOS strategy for SupplierS ( consider the worst value for stats)

This commit is contained in:
TeoV
2019-02-25 15:02:32 +02:00
committed by Dan Christian Bogos
parent 4c7ab559a9
commit 2a77a1036c
6 changed files with 374 additions and 584 deletions

View File

@@ -57,6 +57,8 @@ func (rsv1 *ResourceSv1) ReleaseResources(args utils.ArgRSv1ResourceUsage, reply
return rsv1.rls.V1ReleaseResource(args, reply)
}
//func for getResource
// GetResourceProfile returns a resource configuration
func (apierV1 *ApierV1) GetResourceProfile(arg utils.TenantID, reply *engine.ResourceProfile) error {
if missing := utils.MissingStructFields(&arg, []string{"Tenant", "ID"}); len(missing) != 0 { //Params missing

View File

@@ -46,6 +46,7 @@ const (
MetaLessOrEqual = "*lte"
MetaGreaterThan = "*gt"
MetaGreaterOrEqual = "*gte"
MetaResources = "*resources"
MetaNotString = "*notstring"
MetaNotPrefix = "*notprefix"
@@ -62,6 +63,7 @@ const (
MetaNotLessOrEqual = "*notlte"
MetaNotGreaterThan = "*notgt"
MetaNotGreaterOrEqual = "*notgte"
MetaNotResources = "*notresources"
)
func NewFilterS(cfg *config.CGRConfig,
@@ -204,8 +206,9 @@ func NewFilterRule(rfType, fieldName string, vals []string) (*FilterRule, error)
negative = true
}
if !utils.IsSliceMember([]string{MetaString, MetaPrefix, MetaSuffix,
MetaTimings, MetaRSR, MetaStatS, MetaDestinations, MetaEmpty, MetaExists,
MetaLessThan, MetaLessOrEqual, MetaGreaterThan, MetaGreaterOrEqual}, rType) {
MetaTimings, MetaRSR, MetaStatS, MetaDestinations, MetaEmpty,
MetaExists, MetaLessThan, MetaLessOrEqual, MetaGreaterThan,
MetaGreaterOrEqual, MetaResources}, rType) {
return nil, fmt.Errorf("Unsupported filter Type: %s", rfType)
}
if fieldName == "" && utils.IsSliceMember([]string{MetaString, MetaPrefix, MetaSuffix,
@@ -307,6 +310,8 @@ func (fltr *FilterRule) Pass(dP config.DataProvider,
case MetaLessThan, MetaLessOrEqual, MetaGreaterThan, MetaGreaterOrEqual,
MetaNotLessThan, MetaNotLessOrEqual, MetaNotGreaterThan, MetaNotGreaterOrEqual:
result, err = fltr.passGreaterThan(dP)
case MetaResources, MetaNotResources:
result, err = fltr.passResourceS(dP, rpcClnt, tenant)
default:
err = utils.ErrPrefixNotErrNotImplemented(fltr.Type)
}
@@ -495,3 +500,33 @@ func (fltr *FilterRule) passGreaterThan(dP config.DataProvider) (bool, error) {
}
return false, nil
}
//
//Type *resources
//FieldName
//Value ResourceID:
func (fltr *FilterRule) passResourceS(dP config.DataProvider,
resourceS rpcclient.RpcClientConnection, tenant string) (bool, error) {
// if resourceS == nil || reflect.ValueOf(resourceS).IsNil() {
// return false, errors.New("Missing ResourceS information")
// }
// for _, threshold := range fltr.statSThresholds {
// statValues := make(map[string]float64)
// if err := resourceS.Call(utils.StatSv1GetQueueFloatMetrics, &utils.TenantID{Tenant: tenant, ID: threshold.QueueID}, &statValues); err != nil {
// return false, err
// }
// val, hasIt := statValues[utils.Meta+threshold.ThresholdType[len(MetaMinCapPrefix):]]
// if !hasIt {
// continue
// }
// if strings.HasPrefix(threshold.ThresholdType, MetaMinCapPrefix) &&
// val >= threshold.ThresholdValue {
// return true, nil
// } else if strings.HasPrefix(threshold.ThresholdType, MetaMaxCapPrefix) &&
// val < threshold.ThresholdValue {
// return true, nil
// }
// }
return false, nil
}

View File

@@ -921,23 +921,18 @@ func TestPassFilterNavigableMap(t *testing.T) {
dm: dmFilterPass,
}
//ev1 simulate event
ev1 := map[string]interface{}{
"sampleField": "sampleValue",
"test": "call",
}
//ev2 simulate sortingData
ev2 := map[string]interface{}{
utils.Cost: 12.45,
utils.MetaACD: SplStatMetrics{
&SplStatMetric{
StatID: utils.META_NONE,
metricType: utils.MetaACD,
MetricValue: 10.0},
},
}
//ev3 simulate sortingData
ev3 := map[string]SplStatMetrics{
utils.MetaACD: SplStatMetrics{
MetricValue: 9.0},
&SplStatMetric{
StatID: utils.META_NONE,
metricType: utils.MetaACD,
@@ -948,27 +943,34 @@ func TestPassFilterNavigableMap(t *testing.T) {
//nM simulate the DP sent to filterS in SupplierS
nM := config.NewNavigableMap(nil)
nM.Set([]string{utils.MetaReq}, ev1, false, false)
nM.Set([]string{utils.MetaVars}, ev2, false, false)
nM.Set([]string{"*metrics"}, newSplStsDP(ev3), false, false)
nM.Set([]string{utils.MetaVars}, convertSortingData(ev2), false, false)
if pass, err := filterS.Pass("cgrates.org",
[]string{"*string:*req.sampleField:sampleValue"}, nM); err != nil {
[]string{"*string:*req.test:call"}, nM); err != nil {
t.Errorf(err.Error())
} else if !pass {
t.Errorf("Expecting: true , received: %+v", pass)
}
if pass, err := filterS.Pass("cgrates.org",
[]string{"*gte:*metrics.*acd:10"}, nM); err != nil {
[]string{"*gte:*vars.Cost:10.0"}, nM); err != nil {
t.Errorf(err.Error())
} else if !pass {
t.Errorf("Expecting: true , received: %+v", pass)
}
if pass, err := filterS.Pass("cgrates.org",
[]string{"*gte:*vars.*acd:10.0"}, nM); err != nil {
t.Errorf(err.Error())
} else if pass {
t.Errorf("Expecting: false , received: %+v", pass)
}
if pass, err := filterS.Pass("cgrates.org",
[]string{"*gte:*vars.*acd:9.0"}, nM); err != nil {
t.Errorf(err.Error())
} else if !pass {
t.Errorf("Expecting: true , received: %+v", pass)
}
// if pass, err := filterS.Pass("cgrates.org",
// []string{"*gte:*vars.*acd:10"}, nM); err != nil {
// t.Errorf(err.Error())
// } else if !pass {
// t.Errorf("Expecting: true , received: %+v", pass)
// }
}

View File

@@ -20,11 +20,9 @@ package engine
import (
"fmt"
"net"
"sort"
"strings"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/utils"
)
@@ -94,15 +92,11 @@ func (sSpls *SortedSuppliers) SortHighestCost() {
// SortQOS is part of sort interface,
// sort based on Stats
//map[*acd][]float64{10,20} => 10
//map[*tcd][]float64{40,50} => 40
//map[*pdd][]float64{40,50} => 50
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 {
if castedVal, canCast := iface.(SplStatMetrics); canCast {
castedVal.Sort()
}
}
@@ -195,60 +189,17 @@ func (sm SplStatMetrics) Sort() {
})
}
// newRADataProvider constructs a DataProvider
func newSplStsDP(req map[string]SplStatMetrics) (dP config.DataProvider) {
for key, _ := range req {
req[key].Sort()
}
dP = &splStsDP{req: req, cache: config.NewNavigableMap(nil)}
return
}
type splStsDP struct {
req map[string]SplStatMetrics
cache *config.NavigableMap
}
// String is part of engine.DataProvider interface
// when called, it will display the already parsed values out of cache
func (sm *splStsDP) String() string {
return ""
}
// FieldAsInterface is part of engine.DataProvider interface
func (sm *splStsDP) FieldAsInterface(fldPath []string) (data interface{}, err error) {
fmt.Println("enter here ??? ")
if data, err = sm.cache.FieldAsInterface(fldPath); err != nil {
if err != utils.ErrNotFound { // item found in cache
return
// convert SortingData to map[string]interface{} with the worst value in case of stats
func convertSortingData(req map[string]interface{}) (reply map[string]interface{}) {
reply = make(map[string]interface{})
// in case that we have metrics sort them
for key, iface := range req {
if castedVal, canCast := iface.(SplStatMetrics); canCast {
castedVal.Sort()
reply[key] = castedVal[0].MetricValue
} else {
reply[key] = iface
}
err = nil // cancel previous err
} else {
return // data found in cache
}
data = sm.req[fldPath[0]][0].MetricValue
sm.cache.Set(fldPath, data, false, false)
return
}
// FieldAsString is part of engine.DataProvider interface
func (sm *splStsDP) FieldAsString(fldPath []string) (data string, err error) {
var valIface interface{}
valIface, err = sm.FieldAsInterface(fldPath)
if err != nil {
return
}
data, err = utils.IfaceAsString(valIface)
return
}
// AsNavigableMap is part of engine.DataProvider interface
func (sm *splStsDP) AsNavigableMap([]*config.FCTemplate) (
nm *config.NavigableMap, err error) {
return nil, utils.ErrNotImplemented
}
// RemoteHost is part of engine.DataProvider interface
func (sm *splStsDP) RemoteHost() net.Addr {
return nil
}

View File

@@ -339,6 +339,71 @@ func TestLibSuppliersStatMetricSort2(t *testing.T) {
}
}
func TestLibSuppliersConvertSortingData(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},
},
}
rcv := convertSortingData(simulatedData)
expected := map[string]interface{}{
utils.Cost: 12.45,
utils.MetaACD: 9.0,
}
if !reflect.DeepEqual(expected, rcv) {
t.Errorf("Expecting: %s, received: %s",
expected, rcv)
}
}
func TestLibSuppliersConvertSortingData2(t *testing.T) {
//simulatedData simulate sortingData
simulatedData := map[string]interface{}{
utils.Cost: 12.45,
utils.Weight: 12.0,
utils.MetaACD: SplStatMetrics{
&SplStatMetric{
StatID: utils.META_NONE,
metricType: utils.MetaACD,
MetricValue: 19.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},
},
}
rcv := convertSortingData(simulatedData)
expected := map[string]interface{}{
utils.Cost: 12.45,
utils.MetaACD: 10.0,
utils.MetaPDD: 12.0,
utils.Weight: 12.0,
}
if !reflect.DeepEqual(expected, rcv) {
t.Errorf("Expecting: %+v, received: %+v",
expected, rcv)
}
}
//sort based on *acd and *tcd
func TestLibSuppliersSortQOS(t *testing.T) {
sSpls := &SortedSuppliers{
@@ -429,92 +494,15 @@ func TestLibSuppliersSortQOS(t *testing.T) {
//sort base on *acd and *tcd
sSpls.SortQOS([]string{utils.MetaACD, utils.MetaTCD})
rcv := make([]string, len(sSpls.SortedSuppliers))
eIds := []string{"supplier2", "supplier1", "supplier3"}
for i, spl := range sSpls.SortedSuppliers {
rcv[i] = spl.SupplierID
eOrderedSpls := &SortedSuppliers{
SortedSuppliers: []*SortedSupplier{
&SortedSupplier{
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},
},
},
},
&SortedSupplier{
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},
},
},
},
&SortedSupplier{
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},
},
},
},
},
}
if !reflect.DeepEqual(eOrderedSpls, sSpls) {
t.Errorf("Expecting: %s, \n received: %s",
utils.ToJSON(eOrderedSpls), utils.ToJSON(sSpls))
if !reflect.DeepEqual(eIds, rcv) {
t.Errorf("Expecting: %+v, \n received: %+v",
eIds, rcv)
}
}
@@ -603,86 +591,15 @@ func TestLibSuppliersSortQOS2(t *testing.T) {
},
}
sSpls.SortQOS([]string{utils.MetaACD, utils.MetaTCD})
eOrderedSpls := &SortedSuppliers{
SortedSuppliers: []*SortedSupplier{
&SortedSupplier{
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},
},
},
},
&SortedSupplier{
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},
},
},
},
&SortedSupplier{
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},
},
},
},
},
rcv := make([]string, len(sSpls.SortedSuppliers))
eIds := []string{"supplier3", "supplier2", "supplier1"}
for i, spl := range sSpls.SortedSuppliers {
rcv[i] = spl.SupplierID
}
if !reflect.DeepEqual(eOrderedSpls, sSpls) {
t.Errorf("Expecting: %s, received: %s",
utils.ToJSON(eOrderedSpls), utils.ToJSON(sSpls))
if !reflect.DeepEqual(eIds, rcv) {
t.Errorf("Expecting: %+v, \n received: %+v",
eIds, rcv)
}
}
@@ -755,143 +672,15 @@ func TestLibSuppliersSortQOS3(t *testing.T) {
},
}
sSpls.SortQOS([]string{utils.MetaPDD})
eOrderedSpls := &SortedSuppliers{
SortedSuppliers: []*SortedSupplier{
&SortedSupplier{
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},
},
},
},
&SortedSupplier{
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},
},
},
},
&SortedSupplier{
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},
},
},
},
},
}
if !reflect.DeepEqual(eOrderedSpls, sSpls) {
t.Errorf("Expecting: %s, received: %s",
utils.ToJSON(eOrderedSpls), utils.ToJSON(sSpls))
}
}
rcv := make([]string, len(sSpls.SortedSuppliers))
eIds := []string{"supplier1", "supplier3", "supplier2"}
for i, spl := range sSpls.SortedSuppliers {
rcv[i] = spl.SupplierID
//Modify the rest of the test
//to cover multiple cases
/*
func TestLibSuppliersSortQOS3(t *testing.T) {
sSpls := &SortedSuppliers{
SortedSuppliers: []*SortedSupplier{
&SortedSupplier{
SupplierID: "supplier1",
globalStats: map[string]float64{
utils.MetaACD: 0.2,
utils.MetaTCD: 15.0,
utils.MetaASR: 1.2,
},
SupplierParameters: "param1",
},
&SortedSupplier{
SupplierID: "supplier2",
globalStats: map[string]float64{
utils.MetaACD: 0.2,
utils.MetaTCD: 20.0,
utils.MetaASR: -1.0,
},
SupplierParameters: "param2",
},
&SortedSupplier{
SupplierID: "supplier3",
globalStats: map[string]float64{
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",
globalStats: map[string]float64{
utils.MetaACD: 0.2,
utils.MetaTCD: 15.0,
utils.MetaASR: 1.2,
},
SupplierParameters: "param1",
},
&SortedSupplier{
SupplierID: "supplier3",
globalStats: map[string]float64{
utils.MetaACD: 0.1,
utils.MetaTCD: 10.0,
utils.MetaASR: 1.2,
},
SupplierParameters: "param3",
},
&SortedSupplier{
SupplierID: "supplier2",
globalStats: map[string]float64{
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))
if !reflect.DeepEqual(eIds, rcv) {
t.Errorf("Expecting: %+v, \n received: %+v",
eIds, rcv)
}
}
@@ -900,74 +689,169 @@ func TestLibSuppliersSortQOS4(t *testing.T) {
SortedSuppliers: []*SortedSupplier{
&SortedSupplier{
SupplierID: "supplier1",
globalStats: map[string]float64{
utils.MetaACD: 0.2,
utils.MetaTCD: 15.0,
utils.MetaASR: -1.0,
utils.MetaTCC: 10.1,
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},
},
},
SupplierParameters: "param1",
},
&SortedSupplier{
SupplierID: "supplier2",
globalStats: map[string]float64{
utils.MetaACD: 0.2,
utils.MetaTCD: 20.0,
utils.MetaASR: 1.2,
utils.MetaTCC: 10.1,
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},
},
},
SupplierParameters: "param2",
},
&SortedSupplier{
SupplierID: "supplier3",
globalStats: map[string]float64{
utils.MetaACD: 0.1,
utils.MetaTCD: 10.0,
utils.MetaASR: 1.2,
utils.MetaTCC: 10.1,
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},
},
},
},
},
}
sSpls.SortQOS([]string{utils.MetaASR, utils.MetaACD, utils.MetaTCD})
rcv := make([]string, len(sSpls.SortedSuppliers))
eIds := []string{"supplier1", "supplier3", "supplier2"}
for i, spl := range sSpls.SortedSuppliers {
rcv[i] = spl.SupplierID
}
if !reflect.DeepEqual(eIds, rcv) {
t.Errorf("Expecting: %+v, \n received: %+v",
eIds, rcv)
}
}
func TestLibSuppliersSortQOS5(t *testing.T) {
sSpls := &SortedSuppliers{
SortedSuppliers: []*SortedSupplier{
&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},
},
},
},
&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},
},
},
},
&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},
},
},
SupplierParameters: "param3",
},
},
}
sSpls.SortQOS([]string{utils.MetaTCC, utils.MetaASR, utils.MetaACD, utils.MetaTCD})
eOrderedSpls := &SortedSuppliers{
SortedSuppliers: []*SortedSupplier{
&SortedSupplier{
SupplierID: "supplier2",
globalStats: map[string]float64{
utils.MetaACD: 0.2,
utils.MetaTCD: 20.0,
utils.MetaASR: 1.2,
utils.MetaTCC: 10.1,
},
SupplierParameters: "param2",
},
&SortedSupplier{
SupplierID: "supplier3",
globalStats: map[string]float64{
utils.MetaACD: 0.1,
utils.MetaTCD: 10.0,
utils.MetaASR: 1.2,
utils.MetaTCC: 10.1,
},
SupplierParameters: "param3",
},
&SortedSupplier{
SupplierID: "supplier1",
globalStats: map[string]float64{
utils.MetaACD: 0.2,
utils.MetaTCD: 15.0,
utils.MetaASR: -1.0,
utils.MetaTCC: 10.1,
},
SupplierParameters: "param1",
},
},
rcv := make([]string, len(sSpls.SortedSuppliers))
eIds := []string{"supplier2", "supplier3", "supplier1"}
for i, spl := range sSpls.SortedSuppliers {
rcv[i] = spl.SupplierID
}
if !reflect.DeepEqual(eOrderedSpls, sSpls) {
t.Errorf("Expecting: %s, received: %s",
utils.ToJSON(eOrderedSpls), utils.ToJSON(sSpls))
if !reflect.DeepEqual(eIds, rcv) {
t.Errorf("Expecting: %+v, \n received: %+v",
eIds, rcv)
}
}
@@ -976,75 +860,49 @@ func TestLibSuppliersSortQOS6(t *testing.T) {
SortedSuppliers: []*SortedSupplier{
&SortedSupplier{
SupplierID: "supplier1",
globalStats: map[string]float64{
utils.MetaACD: 0.2,
},
SortingData: map[string]interface{}{
utils.Weight: 15.0,
utils.MetaACD: SplStatMetrics{
&SplStatMetric{StatID: "SampleStat",
metricType: utils.MetaACD,
MetricValue: 0.2},
},
},
SupplierParameters: "param1",
},
&SortedSupplier{
SupplierID: "supplier2",
globalStats: map[string]float64{
utils.MetaACD: 0.2,
},
SortingData: map[string]interface{}{
utils.Weight: 25.0,
utils.MetaACD: SplStatMetrics{
&SplStatMetric{StatID: "SampleStat",
metricType: utils.MetaACD,
MetricValue: 0.2},
},
},
SupplierParameters: "param2",
},
&SortedSupplier{
SupplierID: "supplier3",
globalStats: map[string]float64{
utils.MetaACD: 0.1,
},
SortingData: map[string]interface{}{
utils.Weight: 20.0,
utils.MetaACD: SplStatMetrics{
&SplStatMetric{StatID: "SampleStat",
metricType: utils.MetaACD,
MetricValue: 0.1},
},
},
SupplierParameters: "param3",
},
},
}
sSpls.SortQOS([]string{utils.MetaACD})
eOrderedSpls := &SortedSuppliers{
SortedSuppliers: []*SortedSupplier{
&SortedSupplier{
SupplierID: "supplier2",
globalStats: map[string]float64{
utils.MetaACD: 0.2,
},
SortingData: map[string]interface{}{
utils.Weight: 25.0,
},
SupplierParameters: "param2",
},
&SortedSupplier{
SupplierID: "supplier1",
globalStats: map[string]float64{
utils.MetaACD: 0.2,
},
SortingData: map[string]interface{}{
utils.Weight: 15.0,
},
SupplierParameters: "param1",
},
rcv := make([]string, len(sSpls.SortedSuppliers))
eIds := []string{"supplier2", "supplier1", "supplier3"}
for i, spl := range sSpls.SortedSuppliers {
rcv[i] = spl.SupplierID
&SortedSupplier{
SupplierID: "supplier3",
globalStats: map[string]float64{
utils.MetaACD: 0.1,
},
SortingData: map[string]interface{}{
utils.Weight: 20.0,
},
SupplierParameters: "param3",
},
},
}
if !reflect.DeepEqual(eOrderedSpls, sSpls) {
t.Errorf("Expecting: %s, received: %s",
utils.ToJSON(eOrderedSpls), utils.ToJSON(sSpls))
if !reflect.DeepEqual(eIds, rcv) {
t.Errorf("Expecting: %+v, \n received: %+v",
eIds, rcv)
}
}
@@ -1053,74 +911,49 @@ func TestLibSuppliersSortQOS7(t *testing.T) {
SortedSuppliers: []*SortedSupplier{
&SortedSupplier{
SupplierID: "supplier1",
globalStats: map[string]float64{
utils.MetaACD: -1.0,
},
SortingData: map[string]interface{}{
utils.Weight: 15.0,
utils.MetaACD: SplStatMetrics{
&SplStatMetric{StatID: "SampleStat",
metricType: utils.MetaACD,
MetricValue: -1.0},
},
},
SupplierParameters: "param1",
},
&SortedSupplier{
SupplierID: "supplier2",
globalStats: map[string]float64{
utils.MetaACD: -1.0,
},
SortingData: map[string]interface{}{
utils.Weight: 25.0,
utils.MetaACD: SplStatMetrics{
&SplStatMetric{StatID: "SampleStat",
metricType: utils.MetaACD,
MetricValue: -1.0},
},
},
SupplierParameters: "param2",
},
&SortedSupplier{
SupplierID: "supplier3",
globalStats: map[string]float64{
utils.MetaACD: -1.0,
},
SortingData: map[string]interface{}{
utils.Weight: 20.0,
utils.MetaACD: SplStatMetrics{
&SplStatMetric{StatID: "SampleStat",
metricType: utils.MetaACD,
MetricValue: -1.0},
},
},
SupplierParameters: "param3",
},
},
}
sSpls.SortQOS([]string{utils.MetaACD})
eOrderedSpls := &SortedSuppliers{
SortedSuppliers: []*SortedSupplier{
&SortedSupplier{
SupplierID: "supplier2",
globalStats: map[string]float64{
utils.MetaACD: -1.0,
},
SortingData: map[string]interface{}{
utils.Weight: 25.0,
},
SupplierParameters: "param2",
},
&SortedSupplier{
SupplierID: "supplier3",
globalStats: map[string]float64{
utils.MetaACD: -1.0,
},
SortingData: map[string]interface{}{
utils.Weight: 20.0,
},
SupplierParameters: "param3",
},
&SortedSupplier{
SupplierID: "supplier1",
globalStats: map[string]float64{
utils.MetaACD: -1.0,
},
SortingData: map[string]interface{}{
utils.Weight: 15.0,
},
SupplierParameters: "param1",
},
},
rcv := make([]string, len(sSpls.SortedSuppliers))
eIds := []string{"supplier2", "supplier3", "supplier1"}
for i, spl := range sSpls.SortedSuppliers {
rcv[i] = spl.SupplierID
}
if !reflect.DeepEqual(eOrderedSpls, sSpls) {
t.Errorf("Expecting: %s, received: %s",
utils.ToJSON(eOrderedSpls), utils.ToJSON(sSpls))
if !reflect.DeepEqual(eIds, rcv) {
t.Errorf("Expecting: %+v, \n received: %+v",
eIds, rcv)
}
}
@@ -1129,75 +962,49 @@ func TestLibSuppliersSortQOS8(t *testing.T) {
SortedSuppliers: []*SortedSupplier{
&SortedSupplier{
SupplierID: "supplier1",
globalStats: map[string]float64{
utils.MetaACD: -1.0,
},
SortingData: map[string]interface{}{
utils.Weight: 15.0,
utils.MetaACD: SplStatMetrics{
&SplStatMetric{StatID: "SampleStat",
metricType: utils.MetaACD,
MetricValue: -1.0},
},
},
SupplierParameters: "param1",
},
&SortedSupplier{
SupplierID: "supplier2",
globalStats: map[string]float64{
utils.MetaACD: -1.0,
},
SortingData: map[string]interface{}{
utils.Weight: 25.0,
utils.MetaACD: SplStatMetrics{
&SplStatMetric{StatID: "SampleStat",
metricType: utils.MetaACD,
MetricValue: -1.0},
},
},
SupplierParameters: "param2",
},
&SortedSupplier{
SupplierID: "supplier3",
globalStats: map[string]float64{
utils.MetaACD: 10.0,
},
SortingData: map[string]interface{}{
utils.Weight: 20.0,
utils.MetaACD: SplStatMetrics{
&SplStatMetric{StatID: "SampleStat",
metricType: utils.MetaACD,
MetricValue: 10.0},
},
},
SupplierParameters: "param3",
},
},
}
sSpls.SortQOS([]string{utils.MetaACD})
eOrderedSpls := &SortedSuppliers{
SortedSuppliers: []*SortedSupplier{
&SortedSupplier{
SupplierID: "supplier3",
globalStats: map[string]float64{
utils.MetaACD: 10.0,
},
SortingData: map[string]interface{}{
utils.Weight: 20.0,
},
SupplierParameters: "param3",
},
&SortedSupplier{
SupplierID: "supplier2",
globalStats: map[string]float64{
utils.MetaACD: -1.0,
},
SortingData: map[string]interface{}{
utils.Weight: 25.0,
},
SupplierParameters: "param2",
},
rcv := make([]string, len(sSpls.SortedSuppliers))
eIds := []string{"supplier3", "supplier2", "supplier1"}
for i, spl := range sSpls.SortedSuppliers {
rcv[i] = spl.SupplierID
&SortedSupplier{
SupplierID: "supplier1",
globalStats: map[string]float64{
utils.MetaACD: -1.0,
},
SortingData: map[string]interface{}{
utils.Weight: 15.0,
},
SupplierParameters: "param1",
},
},
}
if !reflect.DeepEqual(eOrderedSpls, sSpls) {
t.Errorf("Expecting: %s, received: %s",
utils.ToJSON(eOrderedSpls), utils.ToJSON(sSpls))
if !reflect.DeepEqual(eIds, rcv) {
t.Errorf("Expecting: %+v, \n received: %+v",
eIds, rcv)
}
}
*/

View File

@@ -312,7 +312,6 @@ func (spS *SupplierService) populateSortingData(ev *utils.CGREvent, spl *Supplie
}
}
}
provStatsMetrics := make(map[string]SplStatMetrics)
//calculate metrics
if len(spl.StatIDs) != 0 {
metricSupp, err := spS.statMetrics(spl.StatIDs, ev.Tenant) //create metric map for suppier
@@ -332,25 +331,19 @@ func (spS *SupplierService) populateSortingData(ev *utils.CGREvent, spl *Supplie
switch metric {
default:
sortedSpl.SortingData[metric] = SplStatMetrics{&SplStatMetric{StatID: utils.META_NONE, metricType: metric, MetricValue: -1.0}}
provStatsMetrics[metric] = SplStatMetrics{&SplStatMetric{StatID: utils.META_NONE, metricType: metric, MetricValue: -1.0}}
case utils.MetaPDD:
sortedSpl.SortingData[metric] = SplStatMetrics{&SplStatMetric{StatID: utils.META_NONE, metricType: metric, MetricValue: 10000000.0}}
provStatsMetrics[metric] = SplStatMetrics{&SplStatMetric{StatID: utils.META_NONE, metricType: metric, MetricValue: 10000000.0}}
}
} else {
sortedSpl.SortingData[metric] = val
provStatsMetrics[metric] = val
}
}
}
//reas
//reds
//filter the supplier
if len(spl.FilterIDs) != 0 {
nM := config.NewNavigableMap(nil)
nM.Set([]string{utils.MetaReq}, ev.Event, false, false)
nM.Set([]string{utils.MetaVars}, sortedSpl.SortingData, false, false)
nM.Set([]string{"*metrics"}, newSplStsDP(provStatsMetrics), false, false)
nM.Set([]string{utils.MetaVars}, convertSortingData(sortedSpl.SortingData), false, false)
if pass, err = spS.filterS.Pass(ev.Tenant, spl.FilterIDs,
nM); err != nil {