From 6a087122debb77369ee97842e26575faa17302b9 Mon Sep 17 00:00:00 2001 From: DanB Date: Tue, 17 Dec 2024 20:45:45 +0100 Subject: [PATCH] RatingProfile fallback functionality --- rates/apis.go | 35 +++++++++++++++++++++++------------ rates/rates.go | 6 +++++- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/rates/apis.go b/rates/apis.go index 16ae01a7a..8d16b1b96 100644 --- a/rates/apis.go +++ b/rates/apis.go @@ -140,20 +140,31 @@ func (rS *RateS) V1CostForEvent(ctx *context.Context, args *utils.CGREvent, rpCo config.RatesProfileIgnoreFiltersDftOpt, utils.MetaProfileIgnoreFilters); err != nil { return } - var rtPrl *utils.RateProfile - if rtPrl, err = rS.matchingRateProfileForEvent(ctx, args.Tenant, rPfIDs, args, ignFilters); err != nil { - if err != utils.ErrNotFound { - err = utils.NewErrServerError(err) + ignoredRPfIDs := utils.NewStringSet([]string{}) + var firstError error + for i := 0; i < rS.cfg.RateSCfg().Verbosity; i++ { + var rtPrl *utils.RateProfile + if rtPrl, err = rS.matchingRateProfileForEvent(ctx, args.Tenant, rPfIDs, args, ignFilters, ignoredRPfIDs); err != nil { + if err != utils.ErrNotFound { + err = utils.NewErrServerError(err) + } else if i != 0 { // no more fallback rating profiles, return the original error + err = utils.NewErrServerError(firstError) + } + return } - return - } - var rcvCost *utils.RateProfileCost - if rcvCost, err = rS.rateProfileCostForEvent(ctx, rtPrl, args, rS.cfg.RateSCfg().Verbosity); err != nil { - if err != utils.ErrNotFound { - err = utils.NewErrServerError(err) + var rcvCost *utils.RateProfileCost + if rcvCost, err = rS.rateProfileCostForEvent(ctx, rtPrl, args, rS.cfg.RateSCfg().Verbosity); err != nil { + if err != utils.ErrNotFound { + //err = utils.NewErrServerError(err) + if i == 0 { + firstError = err + } + ignoredRPfIDs.Add(rtPrl.ID) + continue // no cost, go to the next matching RatingProfile + } + return } - return + *rpCost = *rcvCost } - *rpCost = *rcvCost return } diff --git a/rates/rates.go b/rates/rates.go index 2bf3d27ee..91df2ce48 100644 --- a/rates/rates.go +++ b/rates/rates.go @@ -67,7 +67,8 @@ func (rS *RateS) Shutdown() (err error) { } // matchingRateProfileForEvent returns the matched RateProfile for the given event -func (rS *RateS) matchingRateProfileForEvent(ctx *context.Context, tnt string, rPfIDs []string, args *utils.CGREvent, ignoreFilters bool) (rtPfl *utils.RateProfile, err error) { +func (rS *RateS) matchingRateProfileForEvent(ctx *context.Context, tnt string, rPfIDs []string, args *utils.CGREvent, + ignoreFilters bool, ignoredRPfIDs utils.StringSet) (rtPfl *utils.RateProfile, err error) { evNm := utils.MapStorage{ utils.MetaReq: args.Event, utils.MetaOpts: args.APIOpts, @@ -94,6 +95,9 @@ func (rS *RateS) matchingRateProfileForEvent(ctx *context.Context, tnt string, r } var rpWw *rpWithWeight for _, rPfID := range rPfIDs { + if ignoredRPfIDs.Has(rPfID) { // already processed and gave errors or not appropriate for our request + continue + } var rPf *utils.RateProfile if rPf, err = rS.dm.GetRateProfile(ctx, tnt, rPfID, true, true, utils.NonTransactional); err != nil {