Add Blockers field for RouteProfiles

This commit is contained in:
ionutboangiu
2022-04-21 18:59:19 +03:00
committed by Dan Christian Bogos
parent 729c5ca29b
commit 147cc8f8f0
23 changed files with 475 additions and 344 deletions

View File

@@ -113,11 +113,11 @@ cgrates.org,FLTR_DST_DE,*destinations,~*req.Destination,DST_DE
cgrates.org,FLTR_DST_NL,*destinations,~*req.Destination,DST_NL
`
RoutesCSVContent = `
#Tenant[0],ID[1],FilterIDs[2],Weights[3],Sorting[4],SortingParameters[5],RouteID[6],RouteFilterIDs[7],RouteAccountIDs[8],RouteRateProfileIDs[9],RouteResourceIDs[10],RouteStatIDs[11],RouteWeights[12],RouteBlocker[13],RouteParameters[14]
cgrates.org,RoutePrf1,*string:~*req.Account:dan,;20,*lc,,route1,FLTR_ACNT_dan,Account1;Account1_1,RPL_1,ResGroup1,Stat1,;10,true,param1
cgrates.org,RoutePrf1,,,,,route1,,,RPL_2,ResGroup2,,;10,,
cgrates.org,RoutePrf1,,,,,route1,FLTR_DST_DE,Account2,RPL_3,ResGroup3,Stat2,;10,,
cgrates.org,RoutePrf1,,,,,route1,,,,ResGroup4,Stat3,;10,,
#Tenant[0],ID[1],FilterIDs[2],Weights[3],Sorting[4],SortingParameters[5],Blockers[6],RouteID[7],RouteFilterIDs[8],RouteAccountIDs[9],RouteRateProfileIDs[10],RouteResourceIDs[11],RouteStatIDs[12],RouteWeights[13],RouteBlocker[14],RouteParameters[15]
cgrates.org,RoutePrf1,*string:~*req.Account:dan,;20,*lc,,,route1,FLTR_ACNT_dan,Account1;Account1_1,RPL_1,ResGroup1,Stat1,;10,true,param1
cgrates.org,RoutePrf1,,,,,,route1,,,RPL_2,ResGroup2,,;10,,
cgrates.org,RoutePrf1,,,,,,route1,FLTR_DST_DE,Account2,RPL_3,ResGroup3,Stat2,;10,,
cgrates.org,RoutePrf1,,,,,,route1,,,,ResGroup4,Stat3,;10,,
`
AttributesCSVContent = `
#Tenant,ID,FilterIDs,Weights,Blockers,AttributeFilterIDs,Path,Type,Value,AttributeBlockers

View File

@@ -829,14 +829,14 @@ func (tps RouteMdls) CSVHeader() (result []string) {
func (tps RouteMdls) AsTPRouteProfile() (result []*utils.TPRouteProfile) {
filterMap := make(map[string]utils.StringSet)
mst := make(map[string]*utils.TPRouteProfile)
tpRouteProfileMap := make(map[string]*utils.TPRouteProfile)
routeMap := make(map[string]map[string]*utils.TPRoute)
sortingParameterMap := make(map[string]utils.StringSet)
for _, tp := range tps {
tenID := (&utils.TenantID{Tenant: tp.Tenant, ID: tp.ID}).TenantID()
th, found := mst[tenID]
tpRouteProfile, found := tpRouteProfileMap[tenID]
if !found {
th = &utils.TPRouteProfile{
tpRouteProfile = &utils.TPRouteProfile{
TPid: tp.Tpid,
Tenant: tp.Tenant,
ID: tp.ID,
@@ -852,9 +852,9 @@ func (tps RouteMdls) AsTPRouteProfile() (result []*utils.TPRouteProfile) {
routeID = utils.ConcatenatedKey(routeID,
utils.NewStringSet(strings.Split(tp.RouteFilterIDs, utils.InfieldSep)).Sha1())
}
sup, found := routeMap[tenID][routeID]
tpRoute, found := routeMap[tenID][routeID]
if !found {
sup = &utils.TPRoute{
tpRoute = &utils.TPRoute{
ID: tp.RouteID,
Weights: tp.RouteWeights,
Blocker: tp.RouteBlocker,
@@ -862,29 +862,29 @@ func (tps RouteMdls) AsTPRouteProfile() (result []*utils.TPRouteProfile) {
}
}
if tp.RouteFilterIDs != utils.EmptyString {
supFilterSplit := strings.Split(tp.RouteFilterIDs, utils.InfieldSep)
sup.FilterIDs = append(sup.FilterIDs, supFilterSplit...)
routeFilterSplit := strings.Split(tp.RouteFilterIDs, utils.InfieldSep)
tpRoute.FilterIDs = append(tpRoute.FilterIDs, routeFilterSplit...)
}
if tp.RouteRateProfileIDs != utils.EmptyString {
ratingPlanSplit := strings.Split(tp.RouteRateProfileIDs, utils.InfieldSep)
sup.RateProfileIDs = append(sup.RateProfileIDs, ratingPlanSplit...)
tpRoute.RateProfileIDs = append(tpRoute.RateProfileIDs, ratingPlanSplit...)
}
if tp.RouteResourceIDs != utils.EmptyString {
resSplit := strings.Split(tp.RouteResourceIDs, utils.InfieldSep)
sup.ResourceIDs = append(sup.ResourceIDs, resSplit...)
tpRoute.ResourceIDs = append(tpRoute.ResourceIDs, resSplit...)
}
if tp.RouteStatIDs != utils.EmptyString {
statSplit := strings.Split(tp.RouteStatIDs, utils.InfieldSep)
sup.StatIDs = append(sup.StatIDs, statSplit...)
tpRoute.StatIDs = append(tpRoute.StatIDs, statSplit...)
}
if tp.RouteAccountIDs != utils.EmptyString {
accSplit := strings.Split(tp.RouteAccountIDs, utils.InfieldSep)
sup.AccountIDs = append(sup.AccountIDs, accSplit...)
tpRoute.AccountIDs = append(tpRoute.AccountIDs, accSplit...)
}
routeMap[tenID][routeID] = sup
routeMap[tenID][routeID] = tpRoute
}
if tp.Sorting != utils.EmptyString {
th.Sorting = tp.Sorting
tpRouteProfile.Sorting = tp.Sorting
}
if tp.SortingParameters != utils.EmptyString {
if _, has := sortingParameterMap[tenID]; !has {
@@ -893,7 +893,10 @@ func (tps RouteMdls) AsTPRouteProfile() (result []*utils.TPRouteProfile) {
sortingParameterMap[tenID].AddSlice(strings.Split(tp.SortingParameters, utils.InfieldSep))
}
if tp.Weights != utils.EmptyString {
th.Weights = tp.Weights
tpRouteProfile.Weights = tp.Weights
}
if tp.Blockers != utils.EmptyString {
tpRouteProfile.Blockers = tp.Blockers
}
if tp.FilterIDs != utils.EmptyString {
if _, has := filterMap[tenID]; !has {
@@ -901,14 +904,14 @@ func (tps RouteMdls) AsTPRouteProfile() (result []*utils.TPRouteProfile) {
}
filterMap[tenID].AddSlice(strings.Split(tp.FilterIDs, utils.InfieldSep))
}
mst[tenID] = th
tpRouteProfileMap[tenID] = tpRouteProfile
}
result = make([]*utils.TPRouteProfile, len(mst))
result = make([]*utils.TPRouteProfile, len(tpRouteProfileMap))
i := 0
for tntID, th := range mst {
result[i] = th
for _, supData := range routeMap[tntID] {
result[i].Routes = append(result[i].Routes, supData)
for tntID, tpRouteProfile := range tpRouteProfileMap {
result[i] = tpRouteProfile
for _, routeData := range routeMap[tntID] {
result[i].Routes = append(result[i].Routes, routeData)
}
result[i].FilterIDs = filterMap[tntID].AsSlice()
result[i].SortingParameters = sortingParameterMap[tntID].AsSlice()
@@ -921,7 +924,7 @@ func APItoModelTPRoutes(st *utils.TPRouteProfile) (mdls RouteMdls) {
if len(st.Routes) == 0 {
return
}
for i, supl := range st.Routes {
for i, route := range st.Routes {
mdl := &RouteMdl{
Tenant: st.Tenant,
Tpid: st.TPid,
@@ -930,6 +933,7 @@ func APItoModelTPRoutes(st *utils.TPRouteProfile) (mdls RouteMdls) {
if i == 0 {
mdl.Sorting = st.Sorting
mdl.Weights = st.Weights
mdl.Blockers = st.Blockers
for i, val := range st.FilterIDs {
if i != 0 {
mdl.FilterIDs += utils.InfieldSep
@@ -943,40 +947,40 @@ func APItoModelTPRoutes(st *utils.TPRouteProfile) (mdls RouteMdls) {
mdl.SortingParameters += val
}
}
mdl.RouteID = supl.ID
for i, val := range supl.AccountIDs {
mdl.RouteID = route.ID
for i, val := range route.AccountIDs {
if i != 0 {
mdl.RouteAccountIDs += utils.InfieldSep
}
mdl.RouteAccountIDs += val
}
for i, val := range supl.RateProfileIDs {
for i, val := range route.RateProfileIDs {
if i != 0 {
mdl.RouteRateProfileIDs += utils.InfieldSep
}
mdl.RouteRateProfileIDs += val
}
for i, val := range supl.FilterIDs {
for i, val := range route.FilterIDs {
if i != 0 {
mdl.RouteFilterIDs += utils.InfieldSep
}
mdl.RouteFilterIDs += val
}
for i, val := range supl.ResourceIDs {
for i, val := range route.ResourceIDs {
if i != 0 {
mdl.RouteResourceIDs += utils.InfieldSep
}
mdl.RouteResourceIDs += val
}
for i, val := range supl.StatIDs {
for i, val := range route.StatIDs {
if i != 0 {
mdl.RouteStatIDs += utils.InfieldSep
}
mdl.RouteStatIDs += val
}
mdl.RouteWeights = supl.Weights
mdl.RouteParameters = supl.RouteParameters
mdl.RouteBlocker = supl.Blocker
mdl.RouteWeights = route.Weights
mdl.RouteParameters = route.RouteParameters
mdl.RouteBlocker = route.Blocker
mdls = append(mdls, mdl)
}
return
@@ -992,11 +996,18 @@ func APItoRouteProfile(tpRp *utils.TPRouteProfile, timezone string) (rp *RoutePr
FilterIDs: make([]string, len(tpRp.FilterIDs)),
}
if tpRp.Weights != utils.EmptyString {
weight, err := utils.NewDynamicWeightsFromString(tpRp.Weights, utils.InfieldSep, utils.ANDSep)
weights, err := utils.NewDynamicWeightsFromString(tpRp.Weights, utils.InfieldSep, utils.ANDSep)
if err != nil {
return nil, err
}
rp.Weights = weight
rp.Weights = weights
}
if tpRp.Blockers != utils.EmptyString {
blockers, err := utils.NewBlockersFromString(tpRp.Blockers, utils.InfieldSep, utils.ANDSep)
if err != nil {
return nil, err
}
rp.Blockers = blockers
}
for i, stp := range tpRp.SortingParameters {
rp.SortingParameters[i] = stp
@@ -1035,6 +1046,7 @@ func RouteProfileToAPI(rp *RouteProfile) (tpRp *utils.TPRouteProfile) {
SortingParameters: make([]string, len(rp.SortingParameters)),
Routes: make([]*utils.TPRoute, len(rp.Routes)),
Weights: rp.Weights.String(utils.InfieldSep, utils.ANDSep),
Blockers: rp.Blockers.String(utils.InfieldSep, utils.ANDSep),
}
for i, route := range rp.Routes {

View File

@@ -199,15 +199,16 @@ type RouteMdl struct {
Weights string `index:"3" re:""`
Sorting string `index:"4" re:""`
SortingParameters string `index:"5" re:""`
RouteID string `index:"6" re:""`
RouteFilterIDs string `index:"7" re:""`
RouteAccountIDs string `index:"8" re:""`
RouteRateProfileIDs string `index:"9" re:""`
RouteResourceIDs string `index:"10" re:""`
RouteStatIDs string `index:"11" re:""`
RouteWeights string `index:"12" re:""`
RouteBlocker bool `index:"13" re:""`
RouteParameters string `index:"14" re:""`
Blockers string `index:"6" re:""`
RouteID string `index:"7" re:""`
RouteFilterIDs string `index:"8" re:""`
RouteAccountIDs string `index:"9" re:""`
RouteRateProfileIDs string `index:"10" re:""`
RouteResourceIDs string `index:"11" re:""`
RouteStatIDs string `index:"12" re:""`
RouteWeights string `index:"13" re:""`
RouteBlocker bool `index:"14" re:""`
RouteParameters string `index:"15" re:""`
CreatedAt time.Time
}

View File

@@ -50,6 +50,7 @@ type RouteProfile struct {
FilterIDs []string
Sorting string // Sorting strategy
SortingParameters []string
Blockers utils.Blockers
Routes []*Route
Weights utils.DynamicWeights
}
@@ -182,6 +183,16 @@ func (rpS *RouteS) matchingRouteProfilesForEvent(ctx *context.Context, tnt strin
return nil, utils.ErrNotFound
}
matchingRPrf.Sort()
for i, rp := range matchingRPrf {
var blocker bool
if blocker, err = BlockerFromDynamics(ctx, rp.Blockers, rpS.fltrS, ev.Tenant, evNm); err != nil {
return
}
if blocker {
matchingRPrf = matchingRPrf[0 : i+1]
break
}
}
return
}
@@ -496,6 +507,10 @@ func (rp *RouteProfile) Set(path []string, val interface{}, newBranch bool, _ st
if val != utils.EmptyString {
rp.Weights, err = utils.NewDynamicWeightsFromString(utils.IfaceAsString(val), utils.InfieldSep, utils.ANDSep)
}
case utils.BlockersField:
if val != utils.EmptyString {
rp.Blockers, err = utils.NewBlockersFromString(utils.IfaceAsString(val), utils.InfieldSep, utils.ANDSep)
}
}
case 2:
if val == utils.EmptyString {
@@ -569,6 +584,7 @@ func (rp *RouteProfile) Merge(v2 interface{}) {
equal = false
}
rp.Weights = append(rp.Weights, vi.Weights...)
rp.Blockers = append(rp.Blockers, vi.Blockers...)
if len(vi.Sorting) != 0 {
rp.Sorting = vi.Sorting
}
@@ -634,6 +650,8 @@ func (rp *RouteProfile) FieldAsInterface(fldPath []string) (_ interface{}, err e
return rp.SortingParameters, nil
case utils.Sorting:
return rp.Sorting, nil
case utils.BlockersField:
return rp.Blockers.String(utils.InfieldSep, utils.ANDSep), nil
case utils.Routes:
return rp.Routes, nil
}