mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-22 23:58:44 +05:00
Updated RouteS APIs
This commit is contained in:
committed by
Dan Christian Bogos
parent
bdf66c2d6b
commit
d4e2d79cad
@@ -35,16 +35,16 @@ type SortedRoute struct {
|
||||
|
||||
// SortedRoutes is returned as part of GetRoutes call
|
||||
type SortedRoutes struct {
|
||||
ProfileID string // Profile matched
|
||||
Sorting string // Sorting algorithm
|
||||
Count int // number of routes returned
|
||||
SortedRoutes []*SortedRoute // list of route IDs and SortingData data
|
||||
ProfileID string // Profile matched
|
||||
Sorting string // Sorting algorithm
|
||||
Count int // number of routes returned
|
||||
Routes []*SortedRoute // list of route IDs and SortingData data
|
||||
}
|
||||
|
||||
// RouteIDs returns a list of route IDs
|
||||
func (sRoutes *SortedRoutes) RouteIDs() (rIDs []string) {
|
||||
rIDs = make([]string, len(sRoutes.SortedRoutes))
|
||||
for i, sRoute := range sRoutes.SortedRoutes {
|
||||
rIDs = make([]string, len(sRoutes.Routes))
|
||||
for i, sRoute := range sRoutes.Routes {
|
||||
rIDs[i] = sRoute.RouteID
|
||||
}
|
||||
return
|
||||
@@ -52,8 +52,8 @@ func (sRoutes *SortedRoutes) RouteIDs() (rIDs []string) {
|
||||
|
||||
// RoutesWithParams returns a list of routes IDs with Parameters
|
||||
func (sRoutes *SortedRoutes) RoutesWithParams() (sPs []string) {
|
||||
sPs = make([]string, len(sRoutes.SortedRoutes))
|
||||
for i, spl := range sRoutes.SortedRoutes {
|
||||
sPs = make([]string, len(sRoutes.Routes))
|
||||
for i, spl := range sRoutes.Routes {
|
||||
sPs[i] = spl.RouteID
|
||||
if spl.RouteParameters != "" {
|
||||
sPs[i] += utils.InInFieldSep + spl.RouteParameters
|
||||
@@ -64,39 +64,39 @@ func (sRoutes *SortedRoutes) RoutesWithParams() (sPs []string) {
|
||||
|
||||
// SortWeight is part of sort interface, sort based on Weight
|
||||
func (sRoutes *SortedRoutes) SortWeight() {
|
||||
sort.Slice(sRoutes.SortedRoutes, func(i, j int) bool {
|
||||
if sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) == sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64) {
|
||||
sort.Slice(sRoutes.Routes, func(i, j int) bool {
|
||||
if sRoutes.Routes[i].SortingData[utils.Weight].(float64) == sRoutes.Routes[j].SortingData[utils.Weight].(float64) {
|
||||
return utils.BoolGenerator().RandomBool()
|
||||
}
|
||||
return sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) > sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64)
|
||||
return sRoutes.Routes[i].SortingData[utils.Weight].(float64) > sRoutes.Routes[j].SortingData[utils.Weight].(float64)
|
||||
})
|
||||
}
|
||||
|
||||
// SortLeastCost is part of sort interface,
|
||||
// sort ascendent based on Cost with fallback on Weight
|
||||
func (sRoutes *SortedRoutes) SortLeastCost() {
|
||||
sort.Slice(sRoutes.SortedRoutes, func(i, j int) bool {
|
||||
if sRoutes.SortedRoutes[i].SortingData[utils.Cost].(float64) == sRoutes.SortedRoutes[j].SortingData[utils.Cost].(float64) {
|
||||
if sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) == sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64) {
|
||||
sort.Slice(sRoutes.Routes, func(i, j int) bool {
|
||||
if sRoutes.Routes[i].SortingData[utils.Cost].(float64) == sRoutes.Routes[j].SortingData[utils.Cost].(float64) {
|
||||
if sRoutes.Routes[i].SortingData[utils.Weight].(float64) == sRoutes.Routes[j].SortingData[utils.Weight].(float64) {
|
||||
return utils.BoolGenerator().RandomBool()
|
||||
}
|
||||
return sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) > sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64)
|
||||
return sRoutes.Routes[i].SortingData[utils.Weight].(float64) > sRoutes.Routes[j].SortingData[utils.Weight].(float64)
|
||||
}
|
||||
return sRoutes.SortedRoutes[i].SortingData[utils.Cost].(float64) < sRoutes.SortedRoutes[j].SortingData[utils.Cost].(float64)
|
||||
return sRoutes.Routes[i].SortingData[utils.Cost].(float64) < sRoutes.Routes[j].SortingData[utils.Cost].(float64)
|
||||
})
|
||||
}
|
||||
|
||||
// SortHighestCost is part of sort interface,
|
||||
// sort descendent based on Cost with fallback on Weight
|
||||
func (sRoutes *SortedRoutes) SortHighestCost() {
|
||||
sort.Slice(sRoutes.SortedRoutes, func(i, j int) bool {
|
||||
if sRoutes.SortedRoutes[i].SortingData[utils.Cost].(float64) == sRoutes.SortedRoutes[j].SortingData[utils.Cost].(float64) {
|
||||
if sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) == sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64) {
|
||||
sort.Slice(sRoutes.Routes, func(i, j int) bool {
|
||||
if sRoutes.Routes[i].SortingData[utils.Cost].(float64) == sRoutes.Routes[j].SortingData[utils.Cost].(float64) {
|
||||
if sRoutes.Routes[i].SortingData[utils.Weight].(float64) == sRoutes.Routes[j].SortingData[utils.Weight].(float64) {
|
||||
return utils.BoolGenerator().RandomBool()
|
||||
}
|
||||
return sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) > sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64)
|
||||
return sRoutes.Routes[i].SortingData[utils.Weight].(float64) > sRoutes.Routes[j].SortingData[utils.Weight].(float64)
|
||||
}
|
||||
return sRoutes.SortedRoutes[i].SortingData[utils.Cost].(float64) > sRoutes.SortedRoutes[j].SortingData[utils.Cost].(float64)
|
||||
return sRoutes.Routes[i].SortingData[utils.Cost].(float64) > sRoutes.Routes[j].SortingData[utils.Cost].(float64)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -104,20 +104,20 @@ func (sRoutes *SortedRoutes) SortHighestCost() {
|
||||
// sort based on Stats
|
||||
func (sRoutes *SortedRoutes) SortQOS(params []string) {
|
||||
//sort routes
|
||||
sort.Slice(sRoutes.SortedRoutes, func(i, j int) bool {
|
||||
sort.Slice(sRoutes.Routes, 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 sRoutes.SortedRoutes[i].SortingData[param].(float64) == sRoutes.SortedRoutes[j].SortingData[param].(float64) {
|
||||
if sRoutes.Routes[i].SortingData[param].(float64) == sRoutes.Routes[j].SortingData[param].(float64) {
|
||||
continue
|
||||
}
|
||||
switch param {
|
||||
default:
|
||||
if sRoutes.SortedRoutes[i].SortingData[param].(float64) > sRoutes.SortedRoutes[j].SortingData[param].(float64) {
|
||||
if sRoutes.Routes[i].SortingData[param].(float64) > sRoutes.Routes[j].SortingData[param].(float64) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
case utils.MetaPDD: //in case of pdd the smallest value if the best
|
||||
if sRoutes.SortedRoutes[i].SortingData[param].(float64) < sRoutes.SortedRoutes[j].SortingData[param].(float64) {
|
||||
if sRoutes.Routes[i].SortingData[param].(float64) < sRoutes.Routes[j].SortingData[param].(float64) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -125,52 +125,52 @@ func (sRoutes *SortedRoutes) SortQOS(params []string) {
|
||||
|
||||
}
|
||||
//in case that we have the same value for all params we sort base on weight
|
||||
if sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) == sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64) {
|
||||
if sRoutes.Routes[i].SortingData[utils.Weight].(float64) == sRoutes.Routes[j].SortingData[utils.Weight].(float64) {
|
||||
return utils.BoolGenerator().RandomBool()
|
||||
}
|
||||
return sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) > sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64)
|
||||
return sRoutes.Routes[i].SortingData[utils.Weight].(float64) > sRoutes.Routes[j].SortingData[utils.Weight].(float64)
|
||||
})
|
||||
}
|
||||
|
||||
// SortResourceAscendent is part of sort interface,
|
||||
// sort ascendent based on ResourceUsage with fallback on Weight
|
||||
func (sRoutes *SortedRoutes) SortResourceAscendent() {
|
||||
sort.Slice(sRoutes.SortedRoutes, func(i, j int) bool {
|
||||
if sRoutes.SortedRoutes[i].SortingData[utils.ResourceUsage].(float64) == sRoutes.SortedRoutes[j].SortingData[utils.ResourceUsage].(float64) {
|
||||
if sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) == sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64) {
|
||||
sort.Slice(sRoutes.Routes, func(i, j int) bool {
|
||||
if sRoutes.Routes[i].SortingData[utils.ResourceUsage].(float64) == sRoutes.Routes[j].SortingData[utils.ResourceUsage].(float64) {
|
||||
if sRoutes.Routes[i].SortingData[utils.Weight].(float64) == sRoutes.Routes[j].SortingData[utils.Weight].(float64) {
|
||||
return utils.BoolGenerator().RandomBool()
|
||||
}
|
||||
return sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) > sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64)
|
||||
return sRoutes.Routes[i].SortingData[utils.Weight].(float64) > sRoutes.Routes[j].SortingData[utils.Weight].(float64)
|
||||
}
|
||||
return sRoutes.SortedRoutes[i].SortingData[utils.ResourceUsage].(float64) < sRoutes.SortedRoutes[j].SortingData[utils.ResourceUsage].(float64)
|
||||
return sRoutes.Routes[i].SortingData[utils.ResourceUsage].(float64) < sRoutes.Routes[j].SortingData[utils.ResourceUsage].(float64)
|
||||
})
|
||||
}
|
||||
|
||||
// SortResourceDescendent is part of sort interface,
|
||||
// sort descendent based on ResourceUsage with fallback on Weight
|
||||
func (sRoutes *SortedRoutes) SortResourceDescendent() {
|
||||
sort.Slice(sRoutes.SortedRoutes, func(i, j int) bool {
|
||||
if sRoutes.SortedRoutes[i].SortingData[utils.ResourceUsage].(float64) == sRoutes.SortedRoutes[j].SortingData[utils.ResourceUsage].(float64) {
|
||||
if sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) == sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64) {
|
||||
sort.Slice(sRoutes.Routes, func(i, j int) bool {
|
||||
if sRoutes.Routes[i].SortingData[utils.ResourceUsage].(float64) == sRoutes.Routes[j].SortingData[utils.ResourceUsage].(float64) {
|
||||
if sRoutes.Routes[i].SortingData[utils.Weight].(float64) == sRoutes.Routes[j].SortingData[utils.Weight].(float64) {
|
||||
return utils.BoolGenerator().RandomBool()
|
||||
}
|
||||
return sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) > sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64)
|
||||
return sRoutes.Routes[i].SortingData[utils.Weight].(float64) > sRoutes.Routes[j].SortingData[utils.Weight].(float64)
|
||||
}
|
||||
return sRoutes.SortedRoutes[i].SortingData[utils.ResourceUsage].(float64) > sRoutes.SortedRoutes[j].SortingData[utils.ResourceUsage].(float64)
|
||||
return sRoutes.Routes[i].SortingData[utils.ResourceUsage].(float64) > sRoutes.Routes[j].SortingData[utils.ResourceUsage].(float64)
|
||||
})
|
||||
}
|
||||
|
||||
// SortLoadDistribution is part of sort interface,
|
||||
// sort based on the following formula (float64(ratio + metricVal) / float64(ratio)) -1 with fallback on Weight
|
||||
func (sRoutes *SortedRoutes) SortLoadDistribution() {
|
||||
sort.Slice(sRoutes.SortedRoutes, func(i, j int) bool {
|
||||
splIVal := ((sRoutes.SortedRoutes[i].SortingData[utils.Ratio].(float64)+sRoutes.SortedRoutes[i].SortingData[utils.Load].(float64))/sRoutes.SortedRoutes[i].SortingData[utils.Ratio].(float64) - 1.0)
|
||||
splJVal := ((sRoutes.SortedRoutes[j].SortingData[utils.Ratio].(float64)+sRoutes.SortedRoutes[j].SortingData[utils.Load].(float64))/sRoutes.SortedRoutes[j].SortingData[utils.Ratio].(float64) - 1.0)
|
||||
sort.Slice(sRoutes.Routes, func(i, j int) bool {
|
||||
splIVal := ((sRoutes.Routes[i].SortingData[utils.Ratio].(float64)+sRoutes.Routes[i].SortingData[utils.Load].(float64))/sRoutes.Routes[i].SortingData[utils.Ratio].(float64) - 1.0)
|
||||
splJVal := ((sRoutes.Routes[j].SortingData[utils.Ratio].(float64)+sRoutes.Routes[j].SortingData[utils.Load].(float64))/sRoutes.Routes[j].SortingData[utils.Ratio].(float64) - 1.0)
|
||||
if splIVal == splJVal {
|
||||
if sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) == sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64) {
|
||||
if sRoutes.Routes[i].SortingData[utils.Weight].(float64) == sRoutes.Routes[j].SortingData[utils.Weight].(float64) {
|
||||
return utils.BoolGenerator().RandomBool()
|
||||
}
|
||||
return sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) > sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64)
|
||||
return sRoutes.Routes[i].SortingData[utils.Weight].(float64) > sRoutes.Routes[j].SortingData[utils.Weight].(float64)
|
||||
}
|
||||
return splIVal < splJVal
|
||||
})
|
||||
@@ -201,8 +201,8 @@ func (sRoutes *SortedRoutes) AsNavigableMap() (nm utils.NavigableMap2) {
|
||||
utils.Sorting: utils.NewNMData(sRoutes.Sorting),
|
||||
utils.Count: utils.NewNMData(sRoutes.Count),
|
||||
}
|
||||
sr := make(utils.NMSlice, len(sRoutes.SortedRoutes))
|
||||
for i, ss := range sRoutes.SortedRoutes {
|
||||
sr := make(utils.NMSlice, len(sRoutes.Routes))
|
||||
for i, ss := range sRoutes.Routes {
|
||||
sr[i] = ss.AsNavigableMap()
|
||||
}
|
||||
nm[utils.SortedRoutes] = &sr
|
||||
@@ -240,8 +240,50 @@ func (ssd RouteSortDispatcher) SortRoutes(prflID, strategy string,
|
||||
if sortedRoutes, err = sd.SortRoutes(prflID, suppls, suplEv, extraOpts); err != nil {
|
||||
return
|
||||
}
|
||||
if len(sortedRoutes.SortedRoutes) == 0 {
|
||||
if len(sortedRoutes.Routes) == 0 {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SortedRoutesSet represents the list of matched routes grouped based of profile
|
||||
type SortedRoutesSet []*SortedRoutes
|
||||
|
||||
// RouteIDs returns a list of route IDs
|
||||
func (sRs SortedRoutesSet) RouteIDs() (rIDs []string) {
|
||||
for _, sR := range sRs {
|
||||
for _, r := range sR.Routes {
|
||||
rIDs = append(rIDs, r.RouteID)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// RoutesWithParams returns a list of routes IDs with Parameters
|
||||
func (sRs SortedRoutesSet) RoutesWithParams() (sPs []string) {
|
||||
for _, sR := range sRs {
|
||||
for _, spl := range sR.Routes {
|
||||
route := spl.RouteID
|
||||
if spl.RouteParameters != "" {
|
||||
route += utils.InInFieldSep + spl.RouteParameters
|
||||
}
|
||||
sPs = append(sPs, route)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Digest returns list of routeIDs + parameters for easier outside access
|
||||
// format route1:route1params,route2:route2params
|
||||
func (sRs SortedRoutesSet) Digest() string {
|
||||
return strings.Join(sRs.RoutesWithParams(), utils.FieldsSep)
|
||||
}
|
||||
|
||||
// AsNavigableMap returns the SortedRoutesSet as NMInterface object
|
||||
func (sRs SortedRoutesSet) AsNavigableMap() (nm utils.NMSlice) {
|
||||
nm = make(utils.NMSlice, len(sRs))
|
||||
for i, ss := range sRs {
|
||||
nm[i] = ss.AsNavigableMap()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import (
|
||||
|
||||
func TestLibSuppliersSortCost(t *testing.T) {
|
||||
sSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route1",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -57,7 +57,7 @@ func TestLibSuppliersSortCost(t *testing.T) {
|
||||
}
|
||||
sSpls.SortLeastCost()
|
||||
eOrderedSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route3",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -92,7 +92,7 @@ func TestLibSuppliersSortCost(t *testing.T) {
|
||||
|
||||
func TestLibRoutesSortWeight(t *testing.T) {
|
||||
sSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route1",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -118,7 +118,7 @@ func TestLibRoutesSortWeight(t *testing.T) {
|
||||
}
|
||||
sSpls.SortWeight()
|
||||
eOrderedSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route2",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -152,7 +152,7 @@ func TestSortedRoutesDigest(t *testing.T) {
|
||||
eSpls := SortedRoutes{
|
||||
ProfileID: "SPL_WEIGHT_1",
|
||||
Sorting: utils.MetaWeight,
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route2",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -180,7 +180,7 @@ func TestSortedRoutesDigest2(t *testing.T) {
|
||||
eSpls := SortedRoutes{
|
||||
ProfileID: "SPL_WEIGHT_1",
|
||||
Sorting: utils.MetaWeight,
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route1",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -206,9 +206,9 @@ func TestSortedRoutesDigest2(t *testing.T) {
|
||||
|
||||
func TestSortedRoutesDigest3(t *testing.T) {
|
||||
eSpls := SortedRoutes{
|
||||
ProfileID: "SPL_WEIGHT_1",
|
||||
Sorting: utils.MetaWeight,
|
||||
SortedRoutes: []*SortedRoute{},
|
||||
ProfileID: "SPL_WEIGHT_1",
|
||||
Sorting: utils.MetaWeight,
|
||||
Routes: []*SortedRoute{},
|
||||
}
|
||||
exp := ""
|
||||
rcv := eSpls.Digest()
|
||||
@@ -219,7 +219,7 @@ func TestSortedRoutesDigest3(t *testing.T) {
|
||||
|
||||
func TestLibRoutesSortHighestCost(t *testing.T) {
|
||||
sSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route1",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -248,7 +248,7 @@ func TestLibRoutesSortHighestCost(t *testing.T) {
|
||||
}
|
||||
sSpls.SortHighestCost()
|
||||
eOrderedSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route2",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -284,7 +284,7 @@ func TestLibRoutesSortHighestCost(t *testing.T) {
|
||||
//sort based on *acd and *tcd
|
||||
func TestLibRoutesSortQOS(t *testing.T) {
|
||||
sSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
//the average value for route1 for *acd is 0.5 , *tcd 1.1
|
||||
RouteID: "route1",
|
||||
@@ -320,9 +320,9 @@ func TestLibRoutesSortQOS(t *testing.T) {
|
||||
|
||||
//sort base on *acd and *tcd
|
||||
sSpls.SortQOS([]string{utils.MetaACD, utils.MetaTCD})
|
||||
rcv := make([]string, len(sSpls.SortedRoutes))
|
||||
rcv := make([]string, len(sSpls.Routes))
|
||||
eIds := []string{"route2", "route1", "route3"}
|
||||
for i, spl := range sSpls.SortedRoutes {
|
||||
for i, spl := range sSpls.Routes {
|
||||
rcv[i] = spl.RouteID
|
||||
|
||||
}
|
||||
@@ -335,7 +335,7 @@ func TestLibRoutesSortQOS(t *testing.T) {
|
||||
//sort based on *acd and *tcd
|
||||
func TestLibRoutesSortQOS2(t *testing.T) {
|
||||
sSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
//the average value for route1 for *acd is 0.5 , *tcd 1.1
|
||||
RouteID: "route1",
|
||||
@@ -369,9 +369,9 @@ func TestLibRoutesSortQOS2(t *testing.T) {
|
||||
},
|
||||
}
|
||||
sSpls.SortQOS([]string{utils.MetaACD, utils.MetaTCD})
|
||||
rcv := make([]string, len(sSpls.SortedRoutes))
|
||||
rcv := make([]string, len(sSpls.Routes))
|
||||
eIds := []string{"route3", "route2", "route1"}
|
||||
for i, spl := range sSpls.SortedRoutes {
|
||||
for i, spl := range sSpls.Routes {
|
||||
rcv[i] = spl.RouteID
|
||||
|
||||
}
|
||||
@@ -384,7 +384,7 @@ func TestLibRoutesSortQOS2(t *testing.T) {
|
||||
//sort based on *pdd
|
||||
func TestLibRoutesSortQOS3(t *testing.T) {
|
||||
sSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
//the worst value for route1 for *pdd is 0.7 , *tcd 1.1
|
||||
//route1 and route3 have the same value for *pdd
|
||||
@@ -417,9 +417,9 @@ func TestLibRoutesSortQOS3(t *testing.T) {
|
||||
},
|
||||
}
|
||||
sSpls.SortQOS([]string{utils.MetaPDD})
|
||||
rcv := make([]string, len(sSpls.SortedRoutes))
|
||||
rcv := make([]string, len(sSpls.Routes))
|
||||
eIds := []string{"route1", "route3", "route2"}
|
||||
for i, spl := range sSpls.SortedRoutes {
|
||||
for i, spl := range sSpls.Routes {
|
||||
rcv[i] = spl.RouteID
|
||||
|
||||
}
|
||||
@@ -431,7 +431,7 @@ func TestLibRoutesSortQOS3(t *testing.T) {
|
||||
|
||||
func TestLibRoutesSortQOS4(t *testing.T) {
|
||||
sSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route1",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -459,9 +459,9 @@ func TestLibRoutesSortQOS4(t *testing.T) {
|
||||
},
|
||||
}
|
||||
sSpls.SortQOS([]string{utils.MetaASR, utils.MetaACD, utils.MetaTCD})
|
||||
rcv := make([]string, len(sSpls.SortedRoutes))
|
||||
rcv := make([]string, len(sSpls.Routes))
|
||||
eIds := []string{"route1", "route3", "route2"}
|
||||
for i, spl := range sSpls.SortedRoutes {
|
||||
for i, spl := range sSpls.Routes {
|
||||
rcv[i] = spl.RouteID
|
||||
|
||||
}
|
||||
@@ -473,7 +473,7 @@ func TestLibRoutesSortQOS4(t *testing.T) {
|
||||
|
||||
func TestLibRoutesSortQOS5(t *testing.T) {
|
||||
sSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route1",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -504,9 +504,9 @@ func TestLibRoutesSortQOS5(t *testing.T) {
|
||||
},
|
||||
}
|
||||
sSpls.SortQOS([]string{utils.MetaTCC, utils.MetaASR, utils.MetaACD, utils.MetaTCD})
|
||||
rcv := make([]string, len(sSpls.SortedRoutes))
|
||||
rcv := make([]string, len(sSpls.Routes))
|
||||
eIds := []string{"route2", "route3", "route1"}
|
||||
for i, spl := range sSpls.SortedRoutes {
|
||||
for i, spl := range sSpls.Routes {
|
||||
rcv[i] = spl.RouteID
|
||||
|
||||
}
|
||||
@@ -518,7 +518,7 @@ func TestLibRoutesSortQOS5(t *testing.T) {
|
||||
|
||||
func TestLibRoutesSortQOS6(t *testing.T) {
|
||||
sSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route1",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -543,9 +543,9 @@ func TestLibRoutesSortQOS6(t *testing.T) {
|
||||
},
|
||||
}
|
||||
sSpls.SortQOS([]string{utils.MetaACD})
|
||||
rcv := make([]string, len(sSpls.SortedRoutes))
|
||||
rcv := make([]string, len(sSpls.Routes))
|
||||
eIds := []string{"route2", "route1", "route3"}
|
||||
for i, spl := range sSpls.SortedRoutes {
|
||||
for i, spl := range sSpls.Routes {
|
||||
rcv[i] = spl.RouteID
|
||||
|
||||
}
|
||||
@@ -557,7 +557,7 @@ func TestLibRoutesSortQOS6(t *testing.T) {
|
||||
|
||||
func TestLibRoutesSortQOS7(t *testing.T) {
|
||||
sSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route1",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -582,9 +582,9 @@ func TestLibRoutesSortQOS7(t *testing.T) {
|
||||
},
|
||||
}
|
||||
sSpls.SortQOS([]string{utils.MetaACD})
|
||||
rcv := make([]string, len(sSpls.SortedRoutes))
|
||||
rcv := make([]string, len(sSpls.Routes))
|
||||
eIds := []string{"route2", "route3", "route1"}
|
||||
for i, spl := range sSpls.SortedRoutes {
|
||||
for i, spl := range sSpls.Routes {
|
||||
rcv[i] = spl.RouteID
|
||||
|
||||
}
|
||||
@@ -596,7 +596,7 @@ func TestLibRoutesSortQOS7(t *testing.T) {
|
||||
|
||||
func TestLibRoutesSortQOS8(t *testing.T) {
|
||||
sSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route1",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -621,9 +621,9 @@ func TestLibRoutesSortQOS8(t *testing.T) {
|
||||
},
|
||||
}
|
||||
sSpls.SortQOS([]string{utils.MetaACD})
|
||||
rcv := make([]string, len(sSpls.SortedRoutes))
|
||||
rcv := make([]string, len(sSpls.Routes))
|
||||
eIds := []string{"route3", "route2", "route1"}
|
||||
for i, spl := range sSpls.SortedRoutes {
|
||||
for i, spl := range sSpls.Routes {
|
||||
rcv[i] = spl.RouteID
|
||||
|
||||
}
|
||||
@@ -635,7 +635,7 @@ func TestLibRoutesSortQOS8(t *testing.T) {
|
||||
|
||||
func TestLibRoutesSortLoadDistribution(t *testing.T) {
|
||||
sSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route1",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -663,9 +663,9 @@ func TestLibRoutesSortLoadDistribution(t *testing.T) {
|
||||
},
|
||||
}
|
||||
sSpls.SortLoadDistribution()
|
||||
rcv := make([]string, len(sSpls.SortedRoutes))
|
||||
rcv := make([]string, len(sSpls.Routes))
|
||||
eIds := []string{"route2", "route1", "route3"}
|
||||
for i, spl := range sSpls.SortedRoutes {
|
||||
for i, spl := range sSpls.Routes {
|
||||
rcv[i] = spl.RouteID
|
||||
}
|
||||
if !reflect.DeepEqual(eIds, rcv) {
|
||||
@@ -682,8 +682,8 @@ func TestLibRoutesLCSameWeight(t *testing.T) {
|
||||
utils.Cost: 0.1,
|
||||
utils.Weight: 10.0,
|
||||
}}
|
||||
sSpls.SortedRoutes = append(sSpls.SortedRoutes, route)
|
||||
sortedSlice.SortedRoutes = append(sortedSlice.SortedRoutes, route)
|
||||
sSpls.Routes = append(sSpls.Routes, route)
|
||||
sortedSlice.Routes = append(sortedSlice.Routes, route)
|
||||
}
|
||||
for i := 0; i < 3; i++ {
|
||||
sSpls.SortLeastCost()
|
||||
@@ -704,8 +704,8 @@ func TestLibRoutesHCSameWeight(t *testing.T) {
|
||||
utils.Cost: 0.1,
|
||||
utils.Weight: 10.0,
|
||||
}}
|
||||
sSpls.SortedRoutes = append(sSpls.SortedRoutes, route)
|
||||
sortedSlice.SortedRoutes = append(sortedSlice.SortedRoutes, route)
|
||||
sSpls.Routes = append(sSpls.Routes, route)
|
||||
sortedSlice.Routes = append(sortedSlice.Routes, route)
|
||||
}
|
||||
for i := 0; i < 3; i++ {
|
||||
sSpls.SortHighestCost()
|
||||
@@ -726,8 +726,8 @@ func TestLibRoutesResAscSameWeight(t *testing.T) {
|
||||
utils.ResourceUsage: 5.0,
|
||||
utils.Weight: 10.0,
|
||||
}}
|
||||
sSpls.SortedRoutes = append(sSpls.SortedRoutes, route)
|
||||
sortedSlice.SortedRoutes = append(sortedSlice.SortedRoutes, route)
|
||||
sSpls.Routes = append(sSpls.Routes, route)
|
||||
sortedSlice.Routes = append(sortedSlice.Routes, route)
|
||||
}
|
||||
for i := 0; i < 3; i++ {
|
||||
sSpls.SortResourceAscendent()
|
||||
@@ -748,8 +748,8 @@ func TestLibRoutesResDescSameWeight(t *testing.T) {
|
||||
utils.ResourceUsage: 5.0,
|
||||
utils.Weight: 10.0,
|
||||
}}
|
||||
sSpls.SortedRoutes = append(sSpls.SortedRoutes, route)
|
||||
sortedSlice.SortedRoutes = append(sortedSlice.SortedRoutes, route)
|
||||
sSpls.Routes = append(sSpls.Routes, route)
|
||||
sortedSlice.Routes = append(sortedSlice.Routes, route)
|
||||
}
|
||||
for i := 0; i < 3; i++ {
|
||||
sSpls.SortResourceDescendent()
|
||||
@@ -772,8 +772,8 @@ func TestLibRoutesLoadDistSameWeight(t *testing.T) {
|
||||
utils.Load: 3.0,
|
||||
utils.Weight: 10.0,
|
||||
}}
|
||||
sSpls.SortedRoutes = append(sSpls.SortedRoutes, route)
|
||||
sortedSlice.SortedRoutes = append(sortedSlice.SortedRoutes, route)
|
||||
sSpls.Routes = append(sSpls.Routes, route)
|
||||
sortedSlice.Routes = append(sortedSlice.Routes, route)
|
||||
}
|
||||
for i := 0; i < 3; i++ {
|
||||
sSpls.SortLoadDistribution()
|
||||
@@ -794,8 +794,8 @@ func TestLibRoutesQOSSameWeight(t *testing.T) {
|
||||
utils.Weight: 10.0,
|
||||
utils.MetaACD: -1.0,
|
||||
}}
|
||||
sSpls.SortedRoutes = append(sSpls.SortedRoutes, route)
|
||||
sortedSlice.SortedRoutes = append(sortedSlice.SortedRoutes, route)
|
||||
sSpls.Routes = append(sSpls.Routes, route)
|
||||
sortedSlice.Routes = append(sortedSlice.Routes, route)
|
||||
}
|
||||
for i := 0; i < 3; i++ {
|
||||
sSpls.SortQOS([]string{utils.MetaACD})
|
||||
@@ -815,8 +815,8 @@ func TestLibRoutesSameWeight(t *testing.T) {
|
||||
route := &SortedRoute{RouteID: strconv.Itoa(i), SortingData: map[string]interface{}{
|
||||
utils.Weight: 10.0,
|
||||
}}
|
||||
sSpls.SortedRoutes = append(sSpls.SortedRoutes, route)
|
||||
sortedSlice.SortedRoutes = append(sortedSlice.SortedRoutes, route)
|
||||
sSpls.Routes = append(sSpls.Routes, route)
|
||||
sortedSlice.Routes = append(sortedSlice.Routes, route)
|
||||
}
|
||||
for i := 0; i < 3; i++ {
|
||||
sSpls.SortWeight()
|
||||
@@ -831,7 +831,7 @@ func TestLibRoutesSameWeight(t *testing.T) {
|
||||
|
||||
func BenchmarkRouteSortCost(b *testing.B) {
|
||||
sSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route1",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -866,7 +866,7 @@ func BenchmarkRouteSortCost(b *testing.B) {
|
||||
|
||||
func TestRouteIDsGetIDs(t *testing.T) {
|
||||
sSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route1",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -904,7 +904,7 @@ func TestRouteIDsGetIDs(t *testing.T) {
|
||||
|
||||
func TestSortHighestCost(t *testing.T) {
|
||||
sSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route1",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -930,7 +930,7 @@ func TestSortHighestCost(t *testing.T) {
|
||||
|
||||
func TestSortResourceAscendentDescendent(t *testing.T) {
|
||||
sSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route2",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -961,7 +961,7 @@ func TestSortResourceAscendentDescendent(t *testing.T) {
|
||||
}
|
||||
|
||||
//SortingResourceAscendent/Descendent while ResourceUsages are not equal
|
||||
sSpls.SortedRoutes[0].SortingData[utils.ResourceUsage] = 11.0
|
||||
sSpls.Routes[0].SortingData[utils.ResourceUsage] = 11.0
|
||||
expSRts = sSpls
|
||||
sSpls.SortResourceAscendent()
|
||||
if !reflect.DeepEqual(expSRts, sSpls) {
|
||||
@@ -976,7 +976,7 @@ func TestSortResourceAscendentDescendent(t *testing.T) {
|
||||
|
||||
func TestSortLoadDistribution(t *testing.T) {
|
||||
sSpls := &SortedRoutes{
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "ROUTE1",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -1031,7 +1031,7 @@ func TestSortedRoutesAsNavigableMap(t *testing.T) {
|
||||
ProfileID: "TEST_ID1",
|
||||
Sorting: utils.MetaWeight,
|
||||
Count: 100,
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "ROUTE1",
|
||||
RouteParameters: "SORTING_PARAMETER",
|
||||
|
||||
@@ -38,8 +38,8 @@ type HightCostSorter struct {
|
||||
func (hcs *HightCostSorter) SortRoutes(prflID string, routes map[string]*Route,
|
||||
ev *utils.CGREvent, extraOpts *optsGetRoutes) (sortedRoutes *SortedRoutes, err error) {
|
||||
sortedRoutes = &SortedRoutes{ProfileID: prflID,
|
||||
Sorting: hcs.sorting,
|
||||
SortedRoutes: make([]*SortedRoute, 0)}
|
||||
Sorting: hcs.sorting,
|
||||
Routes: make([]*SortedRoute, 0)}
|
||||
for _, route := range routes {
|
||||
if len(route.RatingPlanIDs) == 0 && len(route.AccountIDs) == 0 {
|
||||
utils.Logger.Warning(
|
||||
@@ -50,7 +50,7 @@ func (hcs *HightCostSorter) SortRoutes(prflID string, routes map[string]*Route,
|
||||
if srtSpl, pass, err := hcs.rS.populateSortingData(ev, route, extraOpts); err != nil {
|
||||
return nil, err
|
||||
} else if pass && srtSpl != nil {
|
||||
sortedRoutes.SortedRoutes = append(sortedRoutes.SortedRoutes, srtSpl)
|
||||
sortedRoutes.Routes = append(sortedRoutes.Routes, srtSpl)
|
||||
}
|
||||
}
|
||||
sortedRoutes.SortHighestCost()
|
||||
|
||||
@@ -38,8 +38,8 @@ type LeastCostSorter struct {
|
||||
func (lcs *LeastCostSorter) SortRoutes(prflID string, routes map[string]*Route,
|
||||
ev *utils.CGREvent, extraOpts *optsGetRoutes) (sortedRoutes *SortedRoutes, err error) {
|
||||
sortedRoutes = &SortedRoutes{ProfileID: prflID,
|
||||
Sorting: lcs.sorting,
|
||||
SortedRoutes: make([]*SortedRoute, 0)}
|
||||
Sorting: lcs.sorting,
|
||||
Routes: make([]*SortedRoute, 0)}
|
||||
for _, s := range routes {
|
||||
if len(s.RatingPlanIDs) == 0 && len(s.AccountIDs) == 0 {
|
||||
utils.Logger.Warning(
|
||||
@@ -50,7 +50,7 @@ func (lcs *LeastCostSorter) SortRoutes(prflID string, routes map[string]*Route,
|
||||
if srtSpl, pass, err := lcs.rS.populateSortingData(ev, s, extraOpts); err != nil {
|
||||
return nil, err
|
||||
} else if pass && srtSpl != nil {
|
||||
sortedRoutes.SortedRoutes = append(sortedRoutes.SortedRoutes, srtSpl)
|
||||
sortedRoutes.Routes = append(sortedRoutes.Routes, srtSpl)
|
||||
}
|
||||
}
|
||||
sortedRoutes.SortLeastCost()
|
||||
|
||||
@@ -39,9 +39,11 @@ type LoadDistributionSorter struct {
|
||||
// SortRoutes .
|
||||
func (ws *LoadDistributionSorter) SortRoutes(prflID string,
|
||||
routes map[string]*Route, suplEv *utils.CGREvent, extraOpts *optsGetRoutes) (sortedRoutes *SortedRoutes, err error) {
|
||||
sortedRoutes = &SortedRoutes{ProfileID: prflID,
|
||||
Sorting: ws.sorting,
|
||||
SortedRoutes: make([]*SortedRoute, 0)}
|
||||
sortedRoutes = &SortedRoutes{
|
||||
ProfileID: prflID,
|
||||
Sorting: ws.sorting,
|
||||
Routes: make([]*SortedRoute, 0),
|
||||
}
|
||||
for _, route := range routes {
|
||||
// we should have at least 1 statID defined for counting CDR (a.k.a *sum:1)
|
||||
if len(route.StatIDs) == 0 {
|
||||
@@ -61,7 +63,7 @@ func (ws *LoadDistributionSorter) SortRoutes(prflID string,
|
||||
utils.RouteS, route.cacheRoute[utils.MetaRatio], route.ID))
|
||||
}
|
||||
srtSpl.SortingData[utils.Ratio] = floatRatio
|
||||
sortedRoutes.SortedRoutes = append(sortedRoutes.SortedRoutes, srtSpl)
|
||||
sortedRoutes.Routes = append(sortedRoutes.Routes, srtSpl)
|
||||
}
|
||||
}
|
||||
sortedRoutes.SortLoadDistribution()
|
||||
|
||||
@@ -36,13 +36,13 @@ type QOSRouteSorter struct {
|
||||
func (qos *QOSRouteSorter) SortRoutes(prflID string, routes map[string]*Route,
|
||||
ev *utils.CGREvent, extraOpts *optsGetRoutes) (sortedRoutes *SortedRoutes, err error) {
|
||||
sortedRoutes = &SortedRoutes{ProfileID: prflID,
|
||||
Sorting: qos.sorting,
|
||||
SortedRoutes: make([]*SortedRoute, 0)}
|
||||
Sorting: qos.sorting,
|
||||
Routes: make([]*SortedRoute, 0)}
|
||||
for _, route := range routes {
|
||||
if srtSpl, pass, err := qos.rS.populateSortingData(ev, route, extraOpts); err != nil {
|
||||
return nil, err
|
||||
} else if pass && srtSpl != nil {
|
||||
sortedRoutes.SortedRoutes = append(sortedRoutes.SortedRoutes, srtSpl)
|
||||
sortedRoutes.Routes = append(sortedRoutes.Routes, srtSpl)
|
||||
}
|
||||
}
|
||||
sortedRoutes.SortQOS(extraOpts.sortingParameters)
|
||||
|
||||
@@ -38,8 +38,8 @@ type ResourceAscendentSorter struct {
|
||||
func (ws *ResourceAscendentSorter) SortRoutes(prflID string,
|
||||
routes map[string]*Route, suplEv *utils.CGREvent, extraOpts *optsGetRoutes) (sortedRoutes *SortedRoutes, err error) {
|
||||
sortedRoutes = &SortedRoutes{ProfileID: prflID,
|
||||
Sorting: ws.sorting,
|
||||
SortedRoutes: make([]*SortedRoute, 0)}
|
||||
Sorting: ws.sorting,
|
||||
Routes: make([]*SortedRoute, 0)}
|
||||
for _, route := range routes {
|
||||
if len(route.ResourceIDs) == 0 {
|
||||
utils.Logger.Warning(
|
||||
@@ -50,7 +50,7 @@ func (ws *ResourceAscendentSorter) SortRoutes(prflID string,
|
||||
if srtSpl, pass, err := ws.rS.populateSortingData(suplEv, route, extraOpts); err != nil {
|
||||
return nil, err
|
||||
} else if pass && srtSpl != nil {
|
||||
sortedRoutes.SortedRoutes = append(sortedRoutes.SortedRoutes, srtSpl)
|
||||
sortedRoutes.Routes = append(sortedRoutes.Routes, srtSpl)
|
||||
}
|
||||
}
|
||||
sortedRoutes.SortResourceAscendent()
|
||||
|
||||
@@ -38,8 +38,8 @@ type ResourceDescendentSorter struct {
|
||||
func (ws *ResourceDescendentSorter) SortRoutes(prflID string,
|
||||
routes map[string]*Route, suplEv *utils.CGREvent, extraOpts *optsGetRoutes) (sortedRoutes *SortedRoutes, err error) {
|
||||
sortedRoutes = &SortedRoutes{ProfileID: prflID,
|
||||
Sorting: ws.sorting,
|
||||
SortedRoutes: make([]*SortedRoute, 0)}
|
||||
Sorting: ws.sorting,
|
||||
Routes: make([]*SortedRoute, 0)}
|
||||
for _, route := range routes {
|
||||
if len(route.ResourceIDs) == 0 {
|
||||
utils.Logger.Warning(
|
||||
@@ -50,7 +50,7 @@ func (ws *ResourceDescendentSorter) SortRoutes(prflID string,
|
||||
if srtSpl, pass, err := ws.rS.populateSortingData(suplEv, route, extraOpts); err != nil {
|
||||
return nil, err
|
||||
} else if pass && srtSpl != nil {
|
||||
sortedRoutes.SortedRoutes = append(sortedRoutes.SortedRoutes, srtSpl)
|
||||
sortedRoutes.Routes = append(sortedRoutes.Routes, srtSpl)
|
||||
}
|
||||
}
|
||||
sortedRoutes.SortResourceDescendent()
|
||||
|
||||
@@ -36,13 +36,13 @@ type WeightSorter struct {
|
||||
func (ws *WeightSorter) SortRoutes(prflID string,
|
||||
routes map[string]*Route, suplEv *utils.CGREvent, extraOpts *optsGetRoutes) (sortedRoutes *SortedRoutes, err error) {
|
||||
sortedRoutes = &SortedRoutes{ProfileID: prflID,
|
||||
Sorting: ws.sorting,
|
||||
SortedRoutes: make([]*SortedRoute, 0)}
|
||||
Sorting: ws.sorting,
|
||||
Routes: make([]*SortedRoute, 0)}
|
||||
for _, route := range routes {
|
||||
if srtRoute, pass, err := ws.rS.populateSortingData(suplEv, route, extraOpts); err != nil {
|
||||
return nil, err
|
||||
} else if pass && srtRoute != nil {
|
||||
sortedRoutes.SortedRoutes = append(sortedRoutes.SortedRoutes, srtRoute)
|
||||
sortedRoutes.Routes = append(sortedRoutes.Routes, srtRoute)
|
||||
}
|
||||
}
|
||||
sortedRoutes.SortWeight()
|
||||
|
||||
173
engine/routes.go
173
engine/routes.go
@@ -505,65 +505,6 @@ func (rpS *RouteService) populateSortingData(ev *utils.CGREvent, route *Route,
|
||||
return sortedSpl, true, nil
|
||||
}
|
||||
|
||||
// sortedRoutesForEvent will return the list of valid route IDs
|
||||
// for event based on filters and sorting algorithms
|
||||
func (rpS *RouteService) sortedRoutesForEvent(tnt string, args *ArgsGetRoutes) (sortedRoutes *SortedRoutes, err error) {
|
||||
if _, has := args.CGREvent.Event[utils.Usage]; !has {
|
||||
args.CGREvent.Event[utils.Usage] = time.Minute // make sure we have default set for Usage
|
||||
}
|
||||
var rPrfs []*RouteProfile
|
||||
if rPrfs, err = rpS.matchingRouteProfilesForEvent(tnt, args.CGREvent, true); err != nil {
|
||||
return
|
||||
}
|
||||
rPrfl := rPrfs[0]
|
||||
extraOpts, err := args.asOptsGetRoutes() // convert routes arguments into internal options used to limit data
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
extraOpts.sortingParameters = rPrfl.SortingParameters // populate sortingParameters in extraOpts
|
||||
extraOpts.sortingStragety = rPrfl.Sorting // populate sortingStrategy in extraOpts
|
||||
|
||||
//construct the DP and pass it to filterS
|
||||
nM := utils.MapStorage{utils.MetaReq: args.Event}
|
||||
passedRoutes := make(map[string]*Route)
|
||||
// apply filters for event
|
||||
for _, route := range rPrfl.Routes {
|
||||
pass, lazyCheckRules, err := rpS.filterS.LazyPass(tnt,
|
||||
route.FilterIDs, nM,
|
||||
[]string{utils.DynamicDataPrefix + utils.MetaReq,
|
||||
utils.DynamicDataPrefix + utils.MetaAccounts,
|
||||
utils.DynamicDataPrefix + utils.MetaResources,
|
||||
utils.DynamicDataPrefix + utils.MetaStats})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !pass {
|
||||
continue
|
||||
}
|
||||
route.lazyCheckRules = lazyCheckRules
|
||||
if prev, has := passedRoutes[route.ID]; has && prev.Weight >= route.Weight {
|
||||
continue
|
||||
}
|
||||
passedRoutes[route.ID] = route
|
||||
}
|
||||
sortedRoutes, err = rpS.sorter.SortRoutes(rPrfl.ID, rPrfl.Sorting,
|
||||
passedRoutes, args.CGREvent, extraOpts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if args.Paginator.Offset != nil {
|
||||
if *args.Paginator.Offset <= len(sortedRoutes.SortedRoutes) {
|
||||
sortedRoutes.SortedRoutes = sortedRoutes.SortedRoutes[*args.Paginator.Offset:]
|
||||
}
|
||||
}
|
||||
if args.Paginator.Limit != nil {
|
||||
if *args.Paginator.Limit <= len(sortedRoutes.SortedRoutes) {
|
||||
sortedRoutes.SortedRoutes = sortedRoutes.SortedRoutes[:*args.Paginator.Limit]
|
||||
}
|
||||
}
|
||||
sortedRoutes.Count = len(sortedRoutes.SortedRoutes)
|
||||
return
|
||||
}
|
||||
|
||||
// ArgsGetRoutes the argument for GetRoutes API
|
||||
type ArgsGetRoutes struct {
|
||||
IgnoreErrors bool
|
||||
@@ -630,7 +571,7 @@ type optsGetRoutes struct {
|
||||
}
|
||||
|
||||
// V1GetRoutes returns the list of valid routes
|
||||
func (rpS *RouteService) V1GetRoutes(args *ArgsGetRoutes, reply *SortedRoutes) (err error) {
|
||||
func (rpS *RouteService) V1GetRoutes(args *ArgsGetRoutes, reply *SortedRoutesSet) (err error) {
|
||||
if args.CGREvent == nil {
|
||||
return utils.NewErrMandatoryIeMissing(utils.CGREventString)
|
||||
}
|
||||
@@ -677,7 +618,7 @@ func (rpS *RouteService) V1GetRoutes(args *ArgsGetRoutes, reply *SortedRoutes) (
|
||||
}
|
||||
return err
|
||||
}
|
||||
*reply = *sSps
|
||||
*reply = sSps
|
||||
return
|
||||
}
|
||||
|
||||
@@ -702,3 +643,113 @@ func (rpS *RouteService) V1GetRouteProfilesForEvent(args *utils.CGREvent, reply
|
||||
*reply = sPs
|
||||
return
|
||||
}
|
||||
|
||||
// sortedRoutesForEvent will return the list of valid route IDs
|
||||
// for event based on filters and sorting algorithms
|
||||
func (rpS *RouteService) sortedRoutesForProfile(tnt string, rPrfl *RouteProfile, ev *utils.CGREvent, pag utils.Paginator, extraOpts *optsGetRoutes) (sortedRoutes *SortedRoutes, err error) {
|
||||
extraOpts.sortingParameters = rPrfl.SortingParameters // populate sortingParameters in extraOpts
|
||||
extraOpts.sortingStragety = rPrfl.Sorting // populate sortingStrategy in extraOpts
|
||||
//construct the DP and pass it to filterS
|
||||
nM := utils.MapStorage{
|
||||
utils.MetaReq: ev.Event,
|
||||
utils.MetaOpts: ev.Opts,
|
||||
}
|
||||
passedRoutes := make(map[string]*Route)
|
||||
// apply filters for event
|
||||
for _, route := range rPrfl.Routes {
|
||||
pass, lazyCheckRules, err := rpS.filterS.LazyPass(tnt,
|
||||
route.FilterIDs, nM,
|
||||
[]string{utils.DynamicDataPrefix + utils.MetaReq,
|
||||
utils.DynamicDataPrefix + utils.MetaAccounts,
|
||||
utils.DynamicDataPrefix + utils.MetaResources,
|
||||
utils.DynamicDataPrefix + utils.MetaStats})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !pass {
|
||||
continue
|
||||
}
|
||||
route.lazyCheckRules = lazyCheckRules
|
||||
if prev, has := passedRoutes[route.ID]; has && prev.Weight >= route.Weight {
|
||||
continue
|
||||
}
|
||||
passedRoutes[route.ID] = route
|
||||
}
|
||||
|
||||
if sortedRoutes, err = rpS.sorter.SortRoutes(rPrfl.ID, rPrfl.Sorting,
|
||||
passedRoutes, ev, extraOpts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if pag.Offset != nil {
|
||||
if *pag.Offset <= len(sortedRoutes.Routes) {
|
||||
sortedRoutes.Routes = sortedRoutes.Routes[*pag.Offset:]
|
||||
}
|
||||
}
|
||||
if pag.Limit != nil {
|
||||
if *pag.Limit <= len(sortedRoutes.Routes) {
|
||||
sortedRoutes.Routes = sortedRoutes.Routes[:*pag.Limit]
|
||||
}
|
||||
}
|
||||
sortedRoutes.Count = len(sortedRoutes.Routes)
|
||||
return
|
||||
}
|
||||
|
||||
// sortedRoutesForEvent will return the list of valid route IDs
|
||||
// for event based on filters and sorting algorithms
|
||||
func (rpS *RouteService) sortedRoutesForEvent(tnt string, args *ArgsGetRoutes) (sortedRoutes SortedRoutesSet, err error) {
|
||||
if _, has := args.CGREvent.Event[utils.Usage]; !has {
|
||||
args.CGREvent.Event[utils.Usage] = time.Minute // make sure we have default set for Usage
|
||||
}
|
||||
var rPrfs []*RouteProfile
|
||||
if rPrfs, err = rpS.matchingRouteProfilesForEvent(tnt, args.CGREvent, true); err != nil {
|
||||
return
|
||||
}
|
||||
prfCount := len(rPrfs) // if the option is not present return for all profiles
|
||||
if prfCountOpt, err := args.OptAsInt64(utils.OptsRouteProfilesCount); err != nil {
|
||||
if err != utils.ErrNotFound { // is an conversion error
|
||||
return nil, err
|
||||
}
|
||||
} else if prfCount > int(prfCountOpt) { // it has the option and is smaller that the current number of profiles
|
||||
prfCount = int(prfCountOpt)
|
||||
}
|
||||
var extraOpts *optsGetRoutes
|
||||
if extraOpts, err = args.asOptsGetRoutes(); err != nil { // convert routes arguments into internal options used to limit data
|
||||
return
|
||||
}
|
||||
|
||||
var startIdx, noSrtRoutes int
|
||||
if args.Paginator.Offset != nil { // save the offset in a varible to not duble check if we have offset and is still not 0
|
||||
startIdx = *args.Paginator.Offset
|
||||
}
|
||||
sortedRoutes = make(SortedRoutesSet, 0, prfCount)
|
||||
for _, rPrfl := range rPrfs {
|
||||
var prfPag utils.Paginator
|
||||
if args.Paginator.Limit != nil { // we have a limit
|
||||
if noSrtRoutes >= *args.Paginator.Limit { // the limit was reached return
|
||||
return
|
||||
}
|
||||
if noSrtRoutes+len(rPrfl.Routes) > *args.Paginator.Limit { // the limit will be reached in this profile
|
||||
limit := *args.Paginator.Limit - noSrtRoutes // make it relative to current profile
|
||||
prfPag.Limit = &limit // add the limit to the paginator
|
||||
}
|
||||
}
|
||||
if startIdx > 0 { // we have offest
|
||||
if startIdx -= len(rPrfl.Routes); startIdx >= 0 { // we still have offset so try the next profile
|
||||
continue
|
||||
}
|
||||
// we have offset but is in the range of this profile
|
||||
offset := -startIdx
|
||||
prfPag.Offset = &offset
|
||||
}
|
||||
var sr *SortedRoutes
|
||||
if sr, err = rpS.sortedRoutesForProfile(tnt, rPrfl, args.CGREvent, prfPag, extraOpts); err != nil {
|
||||
return
|
||||
}
|
||||
noSrtRoutes += sr.Count
|
||||
sortedRoutes = append(sortedRoutes, sr)
|
||||
if len(sortedRoutes) == prfCount { // the profile count was reached
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -800,7 +800,7 @@ func TestRoutesSortedForEvent(t *testing.T) {
|
||||
ProfileID: "RouteProfile1",
|
||||
Sorting: utils.MetaWeight,
|
||||
Count: 1,
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route1",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -822,7 +822,7 @@ func TestRoutesSortedForEvent(t *testing.T) {
|
||||
ProfileID: "RouteProfile2",
|
||||
Sorting: utils.MetaWeight,
|
||||
Count: 3,
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route1",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -859,7 +859,7 @@ func TestRoutesSortedForEvent(t *testing.T) {
|
||||
ProfileID: "RouteProfilePrefix",
|
||||
Sorting: utils.MetaWeight,
|
||||
Count: 1,
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route1",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -1111,7 +1111,7 @@ func TestRoutesSortedForEventWithLimit(t *testing.T) {
|
||||
ProfileID: "RouteProfile2",
|
||||
Sorting: utils.MetaWeight,
|
||||
Count: 2,
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route1",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -1372,7 +1372,7 @@ func TestRoutesSortedForEventWithOffset(t *testing.T) {
|
||||
ProfileID: "RouteProfile2",
|
||||
Sorting: utils.MetaWeight,
|
||||
Count: 1,
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route3",
|
||||
SortingData: map[string]interface{}{
|
||||
@@ -1626,7 +1626,7 @@ func TestRoutesSortedForEventWithLimitAndOffset(t *testing.T) {
|
||||
ProfileID: "RouteProfile2",
|
||||
Sorting: utils.MetaWeight,
|
||||
Count: 1,
|
||||
SortedRoutes: []*SortedRoute{
|
||||
Routes: []*SortedRoute{
|
||||
{
|
||||
RouteID: "route2",
|
||||
SortingData: map[string]interface{}{
|
||||
|
||||
Reference in New Issue
Block a user