Added *routes_maxcost flag. Fixes #2563

This commit is contained in:
Trial97
2021-02-08 17:04:27 +02:00
committed by Dan Christian Bogos
parent 0389c6be11
commit eb743a45cc
14 changed files with 239 additions and 68 deletions

View File

@@ -357,11 +357,12 @@ func (da *DiameterAgent) processRequest(reqProcessor *config.RequestProcessor,
reqProcessor.Flags.ParamsSlice(utils.MetaStats, utils.MetaIDs),
reqProcessor.Flags.GetBool(utils.MetaResources),
reqProcessor.Flags.Has(utils.MetaAccounts),
reqProcessor.Flags.Has(utils.MetaRoutes),
reqProcessor.Flags.GetBool(utils.MetaRoutes),
reqProcessor.Flags.Has(utils.MetaRoutesIgnoreErrors),
reqProcessor.Flags.Has(utils.MetaRoutesEventCost),
cgrEv, cgrArgs,
reqProcessor.Flags.Has(utils.MetaFD),
reqProcessor.Flags.ParamValue(utils.MetaRoutesMaxCost),
)
rply := new(sessions.V1AuthorizeReply)
err = da.connMgr.Call(da.cgrCfg.DiameterAgentCfg().SessionSConns, da, utils.SessionSv1AuthorizeEvent,
@@ -427,7 +428,9 @@ func (da *DiameterAgent) processRequest(reqProcessor *config.RequestProcessor,
reqProcessor.Flags.Has(utils.MetaRoutesIgnoreErrors),
reqProcessor.Flags.Has(utils.MetaRoutesEventCost),
cgrEv, cgrArgs,
reqProcessor.Flags.Has(utils.MetaFD))
reqProcessor.Flags.Has(utils.MetaFD),
reqProcessor.Flags.ParamValue(utils.MetaRoutesMaxCost),
)
rply := new(sessions.V1ProcessMessageReply)
err = da.connMgr.Call(da.cgrCfg.DiameterAgentCfg().SessionSConns, da, utils.SessionSv1ProcessMessage,
msgArgs, rply)

View File

@@ -226,6 +226,7 @@ func (da *DNSAgent) processRequest(reqProcessor *config.RequestProcessor,
reqProcessor.Flags.Has(utils.MetaRoutesIgnoreErrors),
reqProcessor.Flags.Has(utils.MetaRoutesEventCost),
cgrEv, cgrArgs, reqProcessor.Flags.Has(utils.MetaFD),
reqProcessor.Flags.ParamValue(utils.MetaRoutesMaxCost),
)
rply := new(sessions.V1AuthorizeReply)
err = da.connMgr.Call(da.cgrCfg.DNSAgentCfg().SessionSConns, nil,
@@ -294,7 +295,9 @@ func (da *DNSAgent) processRequest(reqProcessor *config.RequestProcessor,
reqProcessor.Flags.GetBool(utils.MetaRoutes),
reqProcessor.Flags.Has(utils.MetaRoutesIgnoreErrors),
reqProcessor.Flags.Has(utils.MetaRoutesEventCost),
cgrEv, cgrArgs, reqProcessor.Flags.Has(utils.MetaFD))
cgrEv, cgrArgs, reqProcessor.Flags.Has(utils.MetaFD),
reqProcessor.Flags.ParamValue(utils.MetaRoutesMaxCost),
)
rply := new(sessions.V1ProcessMessageReply) // need it so rpcclient can clone
err = da.connMgr.Call(da.cgrCfg.DNSAgentCfg().SessionSConns, nil,
utils.SessionSv1ProcessMessage,

View File

@@ -160,7 +160,9 @@ func (ha *HTTPAgent) processRequest(reqProcessor *config.RequestProcessor,
reqProcessor.Flags.GetBool(utils.MetaRoutes),
reqProcessor.Flags.Has(utils.MetaRoutesIgnoreErrors),
reqProcessor.Flags.Has(utils.MetaRoutesEventCost),
cgrEv, cgrArgs, reqProcessor.Flags.Has(utils.MetaFD))
cgrEv, cgrArgs, reqProcessor.Flags.Has(utils.MetaFD),
reqProcessor.Flags.ParamValue(utils.MetaRoutesMaxCost),
)
rply := new(sessions.V1AuthorizeReply)
err = ha.connMgr.Call(ha.sessionConns, nil, utils.SessionSv1AuthorizeEvent,
authArgs, rply)
@@ -224,7 +226,9 @@ func (ha *HTTPAgent) processRequest(reqProcessor *config.RequestProcessor,
reqProcessor.Flags.GetBool(utils.MetaRoutes),
reqProcessor.Flags.Has(utils.MetaRoutesIgnoreErrors),
reqProcessor.Flags.Has(utils.MetaRoutesEventCost),
cgrEv, cgrArgs, reqProcessor.Flags.Has(utils.MetaFD))
cgrEv, cgrArgs, reqProcessor.Flags.Has(utils.MetaFD),
reqProcessor.Flags.ParamValue(utils.MetaRoutesMaxCost),
)
rply := new(sessions.V1ProcessMessageReply)
err = ha.connMgr.Call(ha.sessionConns, nil, utils.SessionSv1ProcessMessage,
evArgs, rply)

View File

@@ -219,6 +219,7 @@ func (ra *RadiusAgent) processRequest(req *radigo.Packet, reqProcessor *config.R
reqProcessor.Flags.Has(utils.MetaRoutesIgnoreErrors),
reqProcessor.Flags.Has(utils.MetaRoutesEventCost),
cgrEv, cgrArgs, reqProcessor.Flags.Has(utils.MetaFD),
reqProcessor.Flags.ParamValue(utils.MetaRoutesMaxCost),
)
rply := new(sessions.V1AuthorizeReply)
err = ra.connMgr.Call(ra.cgrCfg.RadiusAgentCfg().SessionSConns, nil, utils.SessionSv1AuthorizeEvent,
@@ -283,7 +284,9 @@ func (ra *RadiusAgent) processRequest(req *radigo.Packet, reqProcessor *config.R
reqProcessor.Flags.GetBool(utils.MetaRoutes),
reqProcessor.Flags.Has(utils.MetaRoutesIgnoreErrors),
reqProcessor.Flags.Has(utils.MetaRoutesEventCost),
cgrEv, cgrArgs, reqProcessor.Flags.Has(utils.MetaFD))
cgrEv, cgrArgs, reqProcessor.Flags.Has(utils.MetaFD),
reqProcessor.Flags.ParamValue(utils.MetaRoutesMaxCost),
)
rply := new(sessions.V1ProcessMessageReply)
err = ra.connMgr.Call(ra.cgrCfg.RadiusAgentCfg().SessionSConns, nil, utils.SessionSv1ProcessMessage, evArgs, rply)
if utils.ErrHasPrefix(err, utils.RalsErrorPrfx) {

View File

@@ -426,6 +426,7 @@ func (sa *SIPAgent) processRequest(reqProcessor *config.RequestProcessor,
reqProcessor.Flags.Has(utils.MetaRoutesIgnoreErrors),
reqProcessor.Flags.Has(utils.MetaRoutesEventCost),
cgrEv, cgrArgs, reqProcessor.Flags.Has(utils.MetaFD),
reqProcessor.Flags.ParamValue(utils.MetaRoutesMaxCost),
)
rply := new(sessions.V1AuthorizeReply)
err = sa.connMgr.Call(sa.cfg.SIPAgentCfg().SessionSConns, nil, utils.SessionSv1AuthorizeEvent,
@@ -494,6 +495,7 @@ func (sa *SIPAgent) processRequest(reqProcessor *config.RequestProcessor,
// reqProcessor.Flags.Has(utils.MetaRoutesIgnoreErrors),
// reqProcessor.Flags.Has(utils.MetaRoutesEventCost),
// cgrEv, cgrArgs, // reqProcessor.Flags.Has(utils.MetaFD),
// reqProcessor.Flags.ParamValue(utils.MetaRoutesMaxCost),
// opts)
// rply := new(sessions.V1ProcessMessageReply)
// err = sa.connMgr.Call(sa.cfg.SIPAgentCfg().SessionSConns, nil, utils.SessionSv1ProcessMessage,

View File

@@ -19,8 +19,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package engine
import (
"fmt"
"github.com/cgrates/cgrates/utils"
)
@@ -277,7 +275,6 @@ func (dbM *DataDBMock) RemStatQueueDrv(tenant, id string) (err error) {
}
func (dbM *DataDBMock) GetThresholdProfileDrv(tenant string, ID string) (tp *ThresholdProfile, err error) {
fmt.Println(4)
return nil, utils.ErrNotImplemented
}

View File

@@ -74,50 +74,50 @@ func (sRoutes *SortedRoutes) SortWeight() {
// SortLeastCost is part of sort interface,
// sort ascendent based on Cost with fallback on Weight
func (sSpls *SortedRoutes) SortLeastCost() {
sort.Slice(sSpls.SortedRoutes, func(i, j int) bool {
if sSpls.SortedRoutes[i].SortingData[utils.Cost].(float64) == sSpls.SortedRoutes[j].SortingData[utils.Cost].(float64) {
if sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) == sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64) {
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) {
return utils.BoolGenerator().RandomBool()
}
return sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) > sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64)
return sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) > sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64)
}
return sSpls.SortedRoutes[i].SortingData[utils.Cost].(float64) < sSpls.SortedRoutes[j].SortingData[utils.Cost].(float64)
return sRoutes.SortedRoutes[i].SortingData[utils.Cost].(float64) < sRoutes.SortedRoutes[j].SortingData[utils.Cost].(float64)
})
}
// SortHighestCost is part of sort interface,
// sort descendent based on Cost with fallback on Weight
func (sSpls *SortedRoutes) SortHighestCost() {
sort.Slice(sSpls.SortedRoutes, func(i, j int) bool {
if sSpls.SortedRoutes[i].SortingData[utils.Cost].(float64) == sSpls.SortedRoutes[j].SortingData[utils.Cost].(float64) {
if sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) == sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64) {
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) {
return utils.BoolGenerator().RandomBool()
}
return sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) > sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64)
return sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) > sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64)
}
return sSpls.SortedRoutes[i].SortingData[utils.Cost].(float64) > sSpls.SortedRoutes[j].SortingData[utils.Cost].(float64)
return sRoutes.SortedRoutes[i].SortingData[utils.Cost].(float64) > sRoutes.SortedRoutes[j].SortingData[utils.Cost].(float64)
})
}
// SortQOS is part of sort interface,
// sort based on Stats
func (sSpls *SortedRoutes) SortQOS(params []string) {
func (sRoutes *SortedRoutes) SortQOS(params []string) {
//sort routes
sort.Slice(sSpls.SortedRoutes, func(i, j int) bool {
sort.Slice(sRoutes.SortedRoutes, func(i, j int) bool {
for _, param := range params {
//in case we have the same value for the current param we skip to the next one
if sSpls.SortedRoutes[i].SortingData[param].(float64) == sSpls.SortedRoutes[j].SortingData[param].(float64) {
if sRoutes.SortedRoutes[i].SortingData[param].(float64) == sRoutes.SortedRoutes[j].SortingData[param].(float64) {
continue
}
switch param {
default:
if sSpls.SortedRoutes[i].SortingData[param].(float64) > sSpls.SortedRoutes[j].SortingData[param].(float64) {
if sRoutes.SortedRoutes[i].SortingData[param].(float64) > sRoutes.SortedRoutes[j].SortingData[param].(float64) {
return true
}
return false
case utils.MetaPDD: //in case of pdd the smallest value if the best
if sSpls.SortedRoutes[i].SortingData[param].(float64) < sSpls.SortedRoutes[j].SortingData[param].(float64) {
if sRoutes.SortedRoutes[i].SortingData[param].(float64) < sRoutes.SortedRoutes[j].SortingData[param].(float64) {
return true
}
return false
@@ -125,52 +125,52 @@ func (sSpls *SortedRoutes) SortQOS(params []string) {
}
//in case that we have the same value for all params we sort base on weight
if sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) == sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64) {
if sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) == sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64) {
return utils.BoolGenerator().RandomBool()
}
return sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) > sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64)
return sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) > sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64)
})
}
// SortResourceAscendent is part of sort interface,
// sort ascendent based on ResourceUsage with fallback on Weight
func (sSpls *SortedRoutes) SortResourceAscendent() {
sort.Slice(sSpls.SortedRoutes, func(i, j int) bool {
if sSpls.SortedRoutes[i].SortingData[utils.ResourceUsage].(float64) == sSpls.SortedRoutes[j].SortingData[utils.ResourceUsage].(float64) {
if sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) == sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64) {
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) {
return utils.BoolGenerator().RandomBool()
}
return sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) > sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64)
return sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) > sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64)
}
return sSpls.SortedRoutes[i].SortingData[utils.ResourceUsage].(float64) < sSpls.SortedRoutes[j].SortingData[utils.ResourceUsage].(float64)
return sRoutes.SortedRoutes[i].SortingData[utils.ResourceUsage].(float64) < sRoutes.SortedRoutes[j].SortingData[utils.ResourceUsage].(float64)
})
}
// SortResourceDescendent is part of sort interface,
// sort descendent based on ResourceUsage with fallback on Weight
func (sSpls *SortedRoutes) SortResourceDescendent() {
sort.Slice(sSpls.SortedRoutes, func(i, j int) bool {
if sSpls.SortedRoutes[i].SortingData[utils.ResourceUsage].(float64) == sSpls.SortedRoutes[j].SortingData[utils.ResourceUsage].(float64) {
if sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) == sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64) {
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) {
return utils.BoolGenerator().RandomBool()
}
return sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) > sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64)
return sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) > sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64)
}
return sSpls.SortedRoutes[i].SortingData[utils.ResourceUsage].(float64) > sSpls.SortedRoutes[j].SortingData[utils.ResourceUsage].(float64)
return sRoutes.SortedRoutes[i].SortingData[utils.ResourceUsage].(float64) > sRoutes.SortedRoutes[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 (sSpls *SortedRoutes) SortLoadDistribution() {
sort.Slice(sSpls.SortedRoutes, func(i, j int) bool {
splIVal := ((sSpls.SortedRoutes[i].SortingData[utils.Ratio].(float64)+sSpls.SortedRoutes[i].SortingData[utils.Load].(float64))/sSpls.SortedRoutes[i].SortingData[utils.Ratio].(float64) - 1.0)
splJVal := ((sSpls.SortedRoutes[j].SortingData[utils.Ratio].(float64)+sSpls.SortedRoutes[j].SortingData[utils.Load].(float64))/sSpls.SortedRoutes[j].SortingData[utils.Ratio].(float64) - 1.0)
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)
if splIVal == splJVal {
if sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) == sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64) {
if sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) == sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64) {
return utils.BoolGenerator().RandomBool()
}
return sSpls.SortedRoutes[i].SortingData[utils.Weight].(float64) > sSpls.SortedRoutes[j].SortingData[utils.Weight].(float64)
return sRoutes.SortedRoutes[i].SortingData[utils.Weight].(float64) > sRoutes.SortedRoutes[j].SortingData[utils.Weight].(float64)
}
return splIVal < splJVal
})
@@ -178,8 +178,8 @@ func (sSpls *SortedRoutes) SortLoadDistribution() {
// Digest returns list of routeIDs + parameters for easier outside access
// format route1:route1params,route2:route2params
func (sSpls *SortedRoutes) Digest() string {
return strings.Join(sSpls.RoutesWithParams(), utils.FieldsSep)
func (sRoutes *SortedRoutes) Digest() string {
return strings.Join(sRoutes.RoutesWithParams(), utils.FieldsSep)
}
func (ss *SortedRoute) AsNavigableMap() (nm utils.NavigableMap2) {
@@ -194,14 +194,15 @@ func (ss *SortedRoute) AsNavigableMap() (nm utils.NavigableMap2) {
nm[utils.SortingData] = sd
return
}
func (sSpls *SortedRoutes) AsNavigableMap() (nm utils.NavigableMap2) {
func (sRoutes *SortedRoutes) AsNavigableMap() (nm utils.NavigableMap2) {
nm = utils.NavigableMap2{
utils.ProfileID: utils.NewNMData(sSpls.ProfileID),
utils.Sorting: utils.NewNMData(sSpls.Sorting),
utils.Count: utils.NewNMData(sSpls.Count),
utils.ProfileID: utils.NewNMData(sRoutes.ProfileID),
utils.Sorting: utils.NewNMData(sRoutes.Sorting),
utils.Count: utils.NewNMData(sRoutes.Count),
}
sr := make(utils.NMSlice, len(sSpls.SortedRoutes))
for i, ss := range sSpls.SortedRoutes {
sr := make(utils.NMSlice, len(sRoutes.SortedRoutes))
for i, ss := range sRoutes.SortedRoutes {
sr[i] = ss.AsNavigableMap()
}
nm[utils.SortedRoutes] = &sr

View File

@@ -203,6 +203,7 @@ func (erS *ERService) processEvent(cgrEv *utils.CGREvent,
rdrCfg.Flags.Has(utils.MetaRoutesEventCost),
cgrEv, cgrArgs,
rdrCfg.Flags.Has(utils.MetaFD),
rdrCfg.Flags.ParamValue(utils.MetaRoutesMaxCost),
)
rply := new(sessions.V1AuthorizeReply)
err = erS.connMgr.Call(erS.cfg.ERsCfg().SessionSConns, nil, utils.SessionSv1AuthorizeEvent,
@@ -256,7 +257,9 @@ func (erS *ERService) processEvent(cgrEv *utils.CGREvent,
rdrCfg.Flags.Has(utils.MetaRoutesIgnoreErrors),
rdrCfg.Flags.Has(utils.MetaRoutesEventCost),
cgrEv, cgrArgs,
rdrCfg.Flags.Has(utils.MetaFD))
rdrCfg.Flags.Has(utils.MetaFD),
rdrCfg.Flags.ParamValue(utils.MetaRoutesMaxCost),
)
rply := new(sessions.V1ProcessMessageReply) // need it so rpcclient can clone
err = erS.connMgr.Call(erS.cfg.ERsCfg().SessionSConns, nil, utils.SessionSv1ProcessMessage,
evArgs, rply)

View File

@@ -141,6 +141,7 @@ cgrates (0.11.0~dev) UNRELEASED; urgency=medium
* [SessionS] Cloned the charging interval added on EventCost merge
* [FilterS] Optimized the automated index fields matching
* [AgentS] Added *cfg as DataProvider for AgentRequest
* [AgentS] Added *routes_maxcost flag
-- DanB <danb@cgrates.org> Wed, 19 Feb 2020 13:25:52 +0200

View File

@@ -1758,7 +1758,7 @@ func NewV1AuthorizeArgs(attrs bool, attributeIDs []string,
thrslds bool, thresholdIDs []string, statQueues bool, statIDs []string,
res, maxUsage, routes, routesIgnoreErrs, routesEventCost bool,
cgrEv *utils.CGREvent, routePaginator utils.Paginator,
forceDuration bool) (args *V1AuthorizeArgs) {
forceDuration bool, routesMaxCost string) (args *V1AuthorizeArgs) {
args = &V1AuthorizeArgs{
GetAttributes: attrs,
AuthorizeResources: res,
@@ -1772,6 +1772,8 @@ func NewV1AuthorizeArgs(attrs bool, attributeIDs []string,
}
if routesEventCost {
args.RoutesMaxCost = utils.MetaRoutesEventCost
} else {
args.RoutesMaxCost = routesMaxCost
}
args.Paginator = routePaginator
if len(attributeIDs) != 0 {
@@ -1819,6 +1821,8 @@ func (args *V1AuthorizeArgs) ParseFlags(flags string) {
args.RoutesIgnoreErrors = true
case subsystem == utils.MetaRoutesEventCost:
args.RoutesMaxCost = utils.MetaEventCost
case strings.HasPrefix(subsystem, utils.MetaRoutesMaxCost):
args.RoutesMaxCost = strings.TrimPrefix(subsystem, utils.MetaRoutesMaxCost+utils.InInFieldSep)
case strings.HasPrefix(subsystem, utils.MetaAttributes):
args.GetAttributes = true
args.AttributeIDs = getFlagIDs(subsystem)
@@ -2683,7 +2687,7 @@ func (sS *SessionS) BiRPCv1ProcessCDR(clnt rpcclient.ClientConnector,
func NewV1ProcessMessageArgs(attrs bool, attributeIDs []string,
thds bool, thresholdIDs []string, stats bool, statIDs []string, resrc, acnts,
routes, routesIgnoreErrs, routesEventCost bool, cgrEv *utils.CGREvent,
routePaginator utils.Paginator, forceDuration bool) (args *V1ProcessMessageArgs) {
routePaginator utils.Paginator, forceDuration bool, routesMaxCost string) (args *V1ProcessMessageArgs) {
args = &V1ProcessMessageArgs{
AllocateResources: resrc,
Debit: acnts,
@@ -2697,6 +2701,8 @@ func NewV1ProcessMessageArgs(attrs bool, attributeIDs []string,
}
if routesEventCost {
args.RoutesMaxCost = utils.MetaRoutesEventCost
} else {
args.RoutesMaxCost = routesMaxCost
}
args.Paginator = routePaginator
if len(attributeIDs) != 0 {
@@ -2743,6 +2749,8 @@ func (args *V1ProcessMessageArgs) ParseFlags(flags string) {
args.RoutesIgnoreErrors = true
case subsystem == utils.MetaRoutesEventCost:
args.RoutesMaxCost = utils.MetaEventCost
case strings.HasPrefix(subsystem, utils.MetaRoutesMaxCost):
args.RoutesMaxCost = strings.TrimPrefix(subsystem, utils.MetaRoutesMaxCost+utils.InInFieldSep)
case strings.Index(subsystem, utils.MetaAttributes) != -1:
args.GetAttributes = true
args.AttributeIDs = getFlagIDs(subsystem)
@@ -3093,6 +3101,8 @@ func (sS *SessionS) BiRPCv1ProcessEvent(clnt rpcclient.ClientConnector,
var maxCost string
if flags.Has(utils.MetaEventCost) {
maxCost = utils.MetaRoutesEventCost
} else {
maxCost = flags.ParamValue(utils.MetaRoutesMaxCost)
}
for runID, cgrEv := range getDerivedEvents(events, flags.Has(utils.MetaDerivedReply)) {
routesReply, err := sS.getRoutes(cgrEv.Clone(), args.Paginator, ignoreErrors, maxCost, false)

View File

@@ -906,7 +906,7 @@ func TestSessionSNewV1AuthorizeArgs(t *testing.T) {
CGREvent: cgrEv,
ForceDuration: true,
}
rply := NewV1AuthorizeArgs(true, nil, false, nil, false, nil, true, false, false, false, false, cgrEv, utils.Paginator{}, true)
rply := NewV1AuthorizeArgs(true, nil, false, nil, false, nil, true, false, false, false, false, cgrEv, utils.Paginator{}, true, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v, received: %+v", expected, rply)
}
@@ -922,7 +922,7 @@ func TestSessionSNewV1AuthorizeArgs(t *testing.T) {
CGREvent: cgrEv,
ForceDuration: true,
}
rply = NewV1AuthorizeArgs(true, nil, false, nil, true, nil, false, true, false, true, true, cgrEv, utils.Paginator{}, true)
rply = NewV1AuthorizeArgs(true, nil, false, nil, true, nil, false, true, false, true, true, cgrEv, utils.Paginator{}, true, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v,\n received: %+v", expected, rply)
}
@@ -945,7 +945,26 @@ func TestSessionSNewV1AuthorizeArgs(t *testing.T) {
StatIDs: []string{"test3", "test4"},
}
rply = NewV1AuthorizeArgs(true, attributeIDs, false, thresholdIDs,
true, statIDs, false, true, false, true, true, cgrEv, utils.Paginator{}, false)
true, statIDs, false, true, false, true, true, cgrEv, utils.Paginator{}, false, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v,\n received: %+v", expected, rply)
}
expected = &V1AuthorizeArgs{
GetAttributes: true,
AuthorizeResources: false,
GetMaxUsage: true,
ProcessThresholds: false,
ProcessStats: true,
GetRoutes: false,
RoutesIgnoreErrors: true,
RoutesMaxCost: "100",
CGREvent: cgrEv,
AttributeIDs: []string{"ATTR1", "ATTR2"},
ThresholdIDs: []string{"ID1", "ID2"},
StatIDs: []string{"test3", "test4"},
}
rply = NewV1AuthorizeArgs(true, attributeIDs, false, thresholdIDs,
true, statIDs, false, true, false, true, false, cgrEv, utils.Paginator{}, false, "100")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v,\n received: %+v", expected, rply)
}
@@ -982,6 +1001,8 @@ func TestV1AuthorizeArgsParseFlags(t *testing.T) {
}
strArg = "*accounts,*fd,*resources,*routes,*routes_ignore_errors,*routes_event_cost,*attributes:Attr1;Attr2,*thresholds:tr1;tr2;tr3,*stats:st1;st2;st3"
v1authArgs = new(V1AuthorizeArgs)
v1authArgs.CGREvent = new(utils.CGREvent)
v1authArgs.ParseFlags(strArg)
if !reflect.DeepEqual(eOut, v1authArgs) {
t.Errorf("Expecting %+v,\n received: %+v\n", utils.ToJSON(eOut), utils.ToJSON(v1authArgs))
@@ -1006,6 +1027,32 @@ func TestV1AuthorizeArgsParseFlags(t *testing.T) {
}
strArg = "*accounts,*fd,*resources,,*dispatchers,*routes,*routes_ignore_errors,*routes_event_cost,*attributes:Attr1;Attr2,*thresholds:tr1;tr2;tr3,*stats:st1;st2;st3"
v1authArgs = new(V1AuthorizeArgs)
v1authArgs.CGREvent = new(utils.CGREvent)
v1authArgs.ParseFlags(strArg)
if !reflect.DeepEqual(eOut, v1authArgs) {
t.Errorf("Expecting %+v,\n received: %+v\n", utils.ToJSON(eOut), utils.ToJSON(v1authArgs))
}
eOut = &V1AuthorizeArgs{
GetMaxUsage: true,
AuthorizeResources: true,
GetRoutes: true,
RoutesIgnoreErrors: true,
RoutesMaxCost: "100",
GetAttributes: true,
AttributeIDs: []string{"Attr1", "Attr2"},
ProcessThresholds: true,
ThresholdIDs: []string{"tr1", "tr2", "tr3"},
ProcessStats: true,
StatIDs: []string{"st1", "st2", "st3"},
Paginator: cgrArgs,
CGREvent: eOut.CGREvent,
ForceDuration: true,
}
strArg = "*accounts,*fd,*resources,,*dispatchers,*routes,*routes_ignore_errors,*routes_maxcost:100,*attributes:Attr1;Attr2,*thresholds:tr1;tr2;tr3,*stats:st1;st2;st3"
v1authArgs = new(V1AuthorizeArgs)
v1authArgs.CGREvent = new(utils.CGREvent)
v1authArgs.ParseFlags(strArg)
if !reflect.DeepEqual(eOut, v1authArgs) {
t.Errorf("Expecting %+v,\n received: %+v\n", utils.ToJSON(eOut), utils.ToJSON(v1authArgs))
@@ -1111,7 +1158,7 @@ func TestSessionSNewV1ProcessMessageArgs(t *testing.T) {
ForceDuration: true,
}
rply := NewV1ProcessMessageArgs(true, nil, false, nil, false,
nil, true, true, true, false, false, cgrEv, utils.Paginator{}, true)
nil, true, true, true, false, false, cgrEv, utils.Paginator{}, true, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v, received: %+v", expected, rply)
}
@@ -1125,7 +1172,7 @@ func TestSessionSNewV1ProcessMessageArgs(t *testing.T) {
ForceDuration: true,
}
rply = NewV1ProcessMessageArgs(true, nil, false, nil, false,
nil, true, false, true, true, true, cgrEv, utils.Paginator{}, true)
nil, true, false, true, true, true, cgrEv, utils.Paginator{}, true, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v, received: %+v", expected, rply)
}
@@ -1147,11 +1194,24 @@ func TestSessionSNewV1ProcessMessageArgs(t *testing.T) {
ForceDuration: true,
}
rply = NewV1ProcessMessageArgs(true, attributeIDs, false, thresholdIDs, false, statIDs,
true, false, true, true, true, cgrEv, utils.Paginator{}, true)
true, false, true, true, true, cgrEv, utils.Paginator{}, true, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v, received: %+v", expected, rply)
}
expected = &V1ProcessMessageArgs{
AllocateResources: true,
GetAttributes: true,
CGREvent: cgrEv,
GetRoutes: true,
RoutesMaxCost: "100",
RoutesIgnoreErrors: true,
ForceDuration: true,
}
rply = NewV1ProcessMessageArgs(true, nil, false, nil, false,
nil, true, false, true, true, false, cgrEv, utils.Paginator{}, true, "100")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v, received: %+v", expected, rply)
}
}
func TestSessionSNewV1InitSessionArgs(t *testing.T) {
@@ -1552,7 +1612,7 @@ func TestSessionSNewV1AuthorizeArgsWithOpts(t *testing.T) {
}
cgrArgs, _ := utils.GetRoutePaginatorFromOpts(cgrEv.Opts)
rply := NewV1AuthorizeArgs(true, nil, false, nil, false, nil, true, false,
false, false, false, cgrEv, cgrArgs, true)
false, false, false, cgrEv, cgrArgs, true, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v, received: %+v", utils.ToJSON(expected), utils.ToJSON(rply))
}
@@ -1569,7 +1629,7 @@ func TestSessionSNewV1AuthorizeArgsWithOpts(t *testing.T) {
ForceDuration: true,
}
rply = NewV1AuthorizeArgs(true, nil, false, nil, true, nil, false, true,
false, true, true, cgrEv, cgrArgs, true)
false, true, true, cgrEv, cgrArgs, true, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v, received: %+v", utils.ToJSON(expected), utils.ToJSON(rply))
}
@@ -1596,7 +1656,7 @@ func TestSessionSNewV1AuthorizeArgsWithOpts2(t *testing.T) {
}
cgrArgs, _ := utils.GetRoutePaginatorFromOpts(cgrEv.Opts)
rply := NewV1AuthorizeArgs(true, nil, false, nil, false, nil, true, false, false,
false, false, cgrEv, cgrArgs, true)
false, false, cgrEv, cgrArgs, true, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v, received: %+v", utils.ToJSON(expected), utils.ToJSON(rply))
}
@@ -1613,7 +1673,7 @@ func TestSessionSNewV1AuthorizeArgsWithOpts2(t *testing.T) {
ForceDuration: true,
}
rply = NewV1AuthorizeArgs(true, nil, false, nil, true, nil, false, true, false,
true, true, cgrEv, cgrArgs, true)
true, true, cgrEv, cgrArgs, true, "")
if !reflect.DeepEqual(expected, rply) {
t.Errorf("Expecting %+v, received: %+v", utils.ToJSON(expected), utils.ToJSON(rply))
}
@@ -1922,6 +1982,8 @@ func TestV1ProcessMessageArgsParseFlags(t *testing.T) {
}
strArg = "*accounts,*resources,*routes,*routes_ignore_errors,*routes_event_cost,*attributes:Attr1;Attr2,*thresholds:tr1;tr2;tr3,*stats:st1;st2;st3"
v1ProcessMsgArgs = new(V1ProcessMessageArgs)
v1ProcessMsgArgs.CGREvent = new(utils.CGREvent)
v1ProcessMsgArgs.ParseFlags(strArg)
if !reflect.DeepEqual(eOut, v1ProcessMsgArgs) {
t.Errorf("Expecting %+v,\n received: %+v\n", utils.ToJSON(eOut), utils.ToJSON(v1ProcessMsgArgs))
@@ -1944,6 +2006,31 @@ func TestV1ProcessMessageArgsParseFlags(t *testing.T) {
}
strArg = "*accounts,*resources,*dispatchers,*routes,*routes_ignore_errors,*routes_event_cost,*attributes:Attr1;Attr2,*thresholds:tr1;tr2;tr3,*stats:st1;st2;st3"
v1ProcessMsgArgs = new(V1ProcessMessageArgs)
v1ProcessMsgArgs.CGREvent = new(utils.CGREvent)
v1ProcessMsgArgs.ParseFlags(strArg)
if !reflect.DeepEqual(eOut, v1ProcessMsgArgs) {
t.Errorf("Expecting %+v,\n received: %+v\n", utils.ToJSON(eOut), utils.ToJSON(v1ProcessMsgArgs))
}
eOut = &V1ProcessMessageArgs{
Debit: true,
AllocateResources: true,
GetRoutes: true,
RoutesIgnoreErrors: true,
RoutesMaxCost: "100",
GetAttributes: true,
AttributeIDs: []string{"Attr1", "Attr2"},
ProcessThresholds: true,
ThresholdIDs: []string{"tr1", "tr2", "tr3"},
ProcessStats: true,
StatIDs: []string{"st1", "st2", "st3"},
CGREvent: eOut.CGREvent,
}
strArg = "*accounts,*resources,*dispatchers,*routes,*routes_ignore_errors,*routes_maxcost:100,*attributes:Attr1;Attr2,*thresholds:tr1;tr2;tr3,*stats:st1;st2;st3"
v1ProcessMsgArgs = new(V1ProcessMessageArgs)
v1ProcessMsgArgs.CGREvent = new(utils.CGREvent)
v1ProcessMsgArgs.ParseFlags(strArg)
if !reflect.DeepEqual(eOut, v1ProcessMsgArgs) {
t.Errorf("Expecting %+v,\n received: %+v\n", utils.ToJSON(eOut), utils.ToJSON(v1ProcessMsgArgs))

View File

@@ -735,6 +735,7 @@ const (
MetaPositiveExports = "*positive_exports"
MetaNegativeExports = "*negative_exports"
MetaRoutesEventCost = "*routes_event_cost"
MetaRoutesMaxCost = "*routes_maxcost"
MetaRoutesIgnoreErrors = "*routes_ignore_errors"
Freeswitch = "freeswitch"
Kamailio = "kamailio"

View File

@@ -167,6 +167,16 @@ func (fWp FlagParams) Has(opt string) (has bool) {
return
}
// ParamValue returns the value of the flag
func (fWp FlagParams) ParamValue(opt string) (ps string) {
for _, ps = range fWp[opt] {
if ps != EmptyString {
return
}
}
return
}
// Add adds the options to the flag
func (fWp FlagParams) Add(opts []string) {
switch len(opts) {
@@ -234,6 +244,14 @@ func (fWp FlagsWithParams) ParamsSlice(subs, opt string) (ps []string) {
return
}
// ParamValue returns the value of the flag
func (fWp FlagsWithParams) ParamValue(subs string) (ps string) {
for ps = range fWp[subs] {
return
}
return
}
// SliceFlags converts from FlagsWithParams back to []string
func (fWp FlagsWithParams) SliceFlags() (sls []string) {
for key, sub := range fWp {

View File

@@ -207,6 +207,44 @@ func TestFlagsWithParamsGetBool(t *testing.T) {
}
}
func TestFlagsWithParamsValue(t *testing.T) {
flagsWithParams := &FlagsWithParams{
"test": map[string][]string{"string2": {}},
"empty": map[string][]string{},
}
key := "notpresent"
if rcv := flagsWithParams.ParamValue(key); rcv != EmptyString {
t.Errorf("Expecting: %q, received: %+v", EmptyString, rcv)
}
key = "empty"
if rcv := flagsWithParams.ParamValue(key); rcv != EmptyString {
t.Errorf("Expecting: %q, received: %+v", EmptyString, rcv)
}
key = "test"
if rcv := flagsWithParams.ParamValue(key); rcv != "string2" {
t.Errorf("Expecting: string2, received: %+v", rcv)
}
}
func TestFlagParamsValue(t *testing.T) {
flagsWithParams := &FlagParams{
"test": []string{"string2"},
"empty": []string{},
}
key := "notpresent"
if rcv := flagsWithParams.ParamValue(key); rcv != EmptyString {
t.Errorf("Expecting: %q, received: %+v", EmptyString, rcv)
}
key = "empty"
if rcv := flagsWithParams.ParamValue(key); rcv != EmptyString {
t.Errorf("Expecting: %q, received: %+v", EmptyString, rcv)
}
key = "test"
if rcv := flagsWithParams.ParamValue(key); rcv != "string2" {
t.Errorf("Expecting: string2, received: %+v", rcv)
}
}
func TestFlagParamsAdd(t *testing.T) {
flgs := make(FlagParams)
exp := FlagParams{