Add QOS as strategy + tests

This commit is contained in:
TeoV
2018-07-27 04:32:40 -04:00
committed by Dan Christian Bogos
parent f8733d6ced
commit bf334c3340
11 changed files with 558 additions and 20 deletions

View File

@@ -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)
}
}

View File

@@ -138,6 +138,9 @@
"suppliers": {
"enabled": true,
"stats_conns": [
{"address": "*internal"},
],
},

View File

@@ -260,6 +260,9 @@
"suppliers": {
"enabled": true,
"stats_conns": [
{"address": "*internal"},
],
},

View File

@@ -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,
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
1 #Tenant[0] ID[1] FilterType[2] FilterFieldName[3] FilterFieldValues[4] ActivationInterval[5]
9 cgrates.org FLTR_SPP_2 *string Account 1003;1002 2014-07-29T15:00:00Z
10 cgrates.org FLTR_SPP_2 *prefix Destination 10;20
11 cgrates.org FLTR_SPP_2 *rsr Subject(~^1.*1$);Destination(1002)
12 cgrates.org FLTR_SPP_2 *string DistincMatch *highest_cost
13 cgrates.org FLTR_SPP_3 *string DistincMatch *qos 2014-07-29T15:00:00Z
14 cgrates.org FLTR_STAT_1 *string Account 1001 2014-07-29T15:00:00Z
15 cgrates.org FLTR_STAT_2 *string Account 1002 2014-07-29T15:00:00Z
16 cgrates.org FLTR_STAT_3 *string Account 1003 2014-07-29T15:00:00Z

View File

@@ -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,
1 #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]
2 cgrates.org Stat_1 FLTR_STAT_1 2014-07-29T15:00:00Z 100 1s *acd;*tcd;*asr false true 30 0
3 cgrates.org Stat_2 FLTR_STAT_2 2014-07-29T15:00:00Z 100 1s *acd;*tcd;*asr false true 30 0
4 cgrates.org Stat_3 FLTR_STAT_3 2014-07-29T15:00:00Z 100 1s *acd;*tcd;*asr false true 30 0

View File

@@ -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,,,
1 #Tenant ID FilterIDs ActivationInterval Sorting SortingParameters SupplierID SupplierFilterIDs SupplierAccountIDs SupplierRatingPlanIDs SupplierResourceIDs SupplierStatIDs SupplierWeight SupplierBlocker SupplierParameters Weight
11 cgrates.org SPL_HIGHESTCOST_1 FLTR_SPP_2 2017-11-27T00:00:00Z *highest_cost supplier1 RP_SPECIAL_1002 10 false 10
12 cgrates.org SPL_HIGHESTCOST_1 supplier2 RP_RETAIL1 20
13 cgrates.org SPL_HIGHESTCOST_1 supplier3 RP_SPECIAL_1002 15
14 cgrates.org SPL_QOS_1 FLTR_SPP_3 2017-11-27T00:00:00Z *qos *acd;*tcd;*asr supplier1 Stat_1 10 false 10
15 cgrates.org SPL_QOS_1 supplier2 Stat_2 20
16 cgrates.org SPL_QOS_1 supplier3 Stat_3 35
17

View File

@@ -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)
})
}

View File

@@ -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) {

View File

@@ -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
}

View File

@@ -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("<SupplierS> 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

View File

@@ -716,6 +716,7 @@ const (
StatSv1ProcessEvent = "StatSv1.ProcessEvent"
StatSv1GetQueueIDs = "StatSv1.GetQueueIDs"
StatSv1GetQueueStringMetrics = "StatSv1.GetQueueStringMetrics"
StatSv1GetQueueFloatMetrics = "StatSv1.GetQueueFloatMetrics"
StatSv1Ping = "StatSv1.Ping"
StatSv1GetStatQueuesForEvent = "StatSv1.GetStatQueuesForEvent"
)