mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-16 05:39:54 +05:00
Add QOS as strategy + tests
This commit is contained in:
committed by
Dan Christian Bogos
parent
f8733d6ced
commit
bf334c3340
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,6 +138,9 @@
|
||||
|
||||
"suppliers": {
|
||||
"enabled": true,
|
||||
"stats_conns": [
|
||||
{"address": "*internal"},
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
|
||||
@@ -260,6 +260,9 @@
|
||||
|
||||
"suppliers": {
|
||||
"enabled": true,
|
||||
"stats_conns": [
|
||||
{"address": "*internal"},
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
|
||||
@@ -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 +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,
|
||||
|
@@ -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,,,
|
||||
|
||||
|
||||
|
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -716,6 +716,7 @@ const (
|
||||
StatSv1ProcessEvent = "StatSv1.ProcessEvent"
|
||||
StatSv1GetQueueIDs = "StatSv1.GetQueueIDs"
|
||||
StatSv1GetQueueStringMetrics = "StatSv1.GetQueueStringMetrics"
|
||||
StatSv1GetQueueFloatMetrics = "StatSv1.GetQueueFloatMetrics"
|
||||
StatSv1Ping = "StatSv1.Ping"
|
||||
StatSv1GetStatQueuesForEvent = "StatSv1.GetStatQueuesForEvent"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user