From 007240bd732f58e37d592d4994e79bd822ce3c8b Mon Sep 17 00:00:00 2001 From: DanB Date: Wed, 23 Dec 2020 13:30:54 +0100 Subject: [PATCH] Unique Routes based on ID returned, using OrderedNavigableMap mechanism --- apier/v1/actions.go | 2 +- engine/routes.go | 32 ++++++++++++++++++++++++-------- utils/orderednavigablemap.go | 12 ++++++++++-- utils/pathitem.go | 8 ++++++++ 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/apier/v1/actions.go b/apier/v1/actions.go index a2932e0df..a8a3d1c72 100644 --- a/apier/v1/actions.go +++ b/apier/v1/actions.go @@ -166,7 +166,7 @@ func (aSv1 *ActionSv1) Ping(ign *utils.CGREventWithOpts, reply *string) error { // ScheduleActions will be called to schedule actions matching the arguments func (aSv1 *ActionSv1) ScheduleActions(args *utils.ArgActionSv1ScheduleActions, rpl *string) error { - return aSv1.aS.V1ExecuteActions(args, rpl) + return aSv1.aS.V1ScheduleActions(args, rpl) } // ExecuteActions will be called to execute ASAP action profiles, ignoring their Schedule field diff --git a/engine/routes.go b/engine/routes.go index f068536a4..ab57bc1b0 100644 --- a/engine/routes.go +++ b/engine/routes.go @@ -548,24 +548,40 @@ func (rpS *RouteService) sortedRoutesForEvent(tnt string, args *ArgsGetRoutes) ( //construct the DP and pass it to filterS nM := utils.MapStorage{utils.MetaReq: args.CGREvent.Event} - routeNew := make([]*Route, 0) + passedRoutes := utils.NewOrderedNavigableMap() // 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}) + 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 } + nmFpth := utils.NewFullPath(route.ID, utils.NestingSep) + var prevRt *Route + if prevRtIface, errPth := passedRoutes.Field(nmFpth.PathItems); errPth == nil { + prevRt = prevRtIface.Interface().(*Route) + } + if prevRt != nil && prevRt.Weight >= route.Weight { + continue // ignoring the new route due to duplication + } + if _, err = passedRoutes.Set(nmFpth, utils.NewNMData(route)); err != nil { + return nil, err + } route.lazyCheckRules = lazyCheckRules - routeNew = append(routeNew, route) } - + ordRts := passedRoutes.OrderedFields() + routesAllowed := make([]*Route, len(ordRts)) + for i, rtIface := range ordRts { + routesAllowed[i] = rtIface.(*Route) + } sortedRoutes, err = rpS.sorter.SortRoutes(rPrfl.ID, rPrfl.Sorting, - routeNew, args.CGREvent, extraOpts) + routesAllowed, args.CGREvent, extraOpts) if err != nil { return nil, err } diff --git a/utils/orderednavigablemap.go b/utils/orderednavigablemap.go index ca7883285..a7a861274 100644 --- a/utils/orderednavigablemap.go +++ b/utils/orderednavigablemap.go @@ -154,7 +154,7 @@ func (onm *OrderedNavigableMap) FieldAsString(fldPath []string) (str string, err } // FieldAsInterface returns the interface at the path -func (onm *OrderedNavigableMap) FieldAsInterface(fldPath []string) (str interface{}, err error) { +func (onm *OrderedNavigableMap) FieldAsInterface(fldPath []string) (iface interface{}, err error) { var val NMInterface val, err = onm.nm.Field(NewPathItems(fldPath)) if err != nil { @@ -169,7 +169,6 @@ func (OrderedNavigableMap) RemoteHost() net.Addr { } // GetOrder returns the elements order as a slice -// use this only for testing func (onm *OrderedNavigableMap) GetOrder() (order []PathItems) { for el := onm.GetFirstElement(); el != nil; el = el.Next() { order = append(order, el.Value) @@ -177,6 +176,15 @@ func (onm *OrderedNavigableMap) GetOrder() (order []PathItems) { return } +// OrderedFields returns the elements in order they were inserted +func (onm *OrderedNavigableMap) OrderedFields() (flds []interface{}) { + for el := onm.GetFirstElement(); el != nil; el = el.Next() { + fld, _ := onm.Field(el.Value) + flds = append(flds, fld.Interface()) + } + return +} + // RemoveAll will clean the data and the odrder from OrderedNavigableMap func (onm *OrderedNavigableMap) RemoveAll() { onm.nm = NavigableMap2{} diff --git a/utils/pathitem.go b/utils/pathitem.go index 4d22ee867..9e0c97795 100644 --- a/utils/pathitem.go +++ b/utils/pathitem.go @@ -34,6 +34,14 @@ func stripIdxFromLastPathElm(path string) string { return path[:lastIdxStart] } +// NewFullPath is a constructor for FullPath out of string and separator +func NewFullPath(pth string, sep string) *FullPath { + return &FullPath{ + Path: pth, + PathItems: NewPathItems(strings.Split(pth, sep)), + } +} + // FullPath is the path to the item with all the needed fields type FullPath struct { PathItems PathItems