diff --git a/config/attributescfg.go b/config/attributescfg.go index 87c1db5b6..a591fe3ae 100644 --- a/config/attributescfg.go +++ b/config/attributescfg.go @@ -53,6 +53,9 @@ func (attrOpts *AttributesOpts) loadFromJSONCfg(jsnCfg *AttributesOptsJson) { if jsnCfg.ProfileRuns != nil { attrOpts.ProfileRuns = *jsnCfg.ProfileRuns } + if jsnCfg.ProfileIgnoreFilters != nil { + attrOpts.ProfileIgnoreFilters = *jsnCfg.ProfileIgnoreFilters + } if jsnCfg.ProcessRuns != nil { attrOpts.ProcessRuns = *jsnCfg.ProcessRuns } diff --git a/engine/attributes.go b/engine/attributes.go index 77d60b762..542fe75c0 100644 --- a/engine/attributes.go +++ b/engine/attributes.go @@ -55,7 +55,7 @@ func (alS *AttributeService) Shutdown() { // attributeProfileForEvent returns the matching attribute func (alS *AttributeService) attributeProfileForEvent(tnt string, ctx *string, attrsIDs []string, actTime *time.Time, evNm utils.MapStorage, - lastID string, processedPrfNo map[string]int, profileRuns int) (matchAttrPrfl *AttributeProfile, err error) { + lastID string, processedPrfNo map[string]int, profileRuns int, ignoreFilters bool) (matchAttrPrfl *AttributeProfile, err error) { var attrIDs []string contextVal := utils.MetaDefault if ctx != nil && *ctx != "" { @@ -65,6 +65,7 @@ func (alS *AttributeService) attributeProfileForEvent(tnt string, ctx *string, a if len(attrsIDs) != 0 { attrIDs = attrsIDs } else { + ignoreFilters = false aPrflIDs, err := MatchingItemIDsForEvent(evNm, alS.cgrcfg.AttributeSCfg().StringIndexedFields, alS.cgrcfg.AttributeSCfg().PrefixIndexedFields, @@ -116,11 +117,13 @@ func (alS *AttributeService) attributeProfileForEvent(tnt string, ctx *string, a } tntID := aPrfl.TenantIDInline() (evNm[utils.MetaVars].(utils.MapStorage))[utils.MetaAttrPrfTenantID] = tntID - if pass, err := alS.filterS.Pass(tnt, aPrfl.FilterIDs, - evNm); err != nil { - return nil, err - } else if !pass { - continue + if !ignoreFilters { + if pass, err := alS.filterS.Pass(tnt, aPrfl.FilterIDs, + evNm); err != nil { + return nil, err + } else if !pass { + continue + } } if (matchAttrPrfl == nil || matchAttrPrfl.Weight < aPrfl.Weight) && tntID != lastID && @@ -175,8 +178,14 @@ func (alS *AttributeService) processEvent(tnt string, args *utils.CGREvent, evNm return } } + ignFilters := alS.cgrcfg.AttributeSCfg().Opts.ProfileIgnoreFilters + if opt, has := args.APIOpts[utils.OptsAttributesProfileIgnoreFilters]; has { + if ignFilters, err = utils.IfaceAsBool(opt); err != nil { + return + } + } var attrPrf *AttributeProfile - if attrPrf, err = alS.attributeProfileForEvent(tnt, context, attrIDs, args.Time, evNm, lastID, processedPrfNo, profileRuns); err != nil { + if attrPrf, err = alS.attributeProfileForEvent(tnt, context, attrIDs, args.Time, evNm, lastID, processedPrfNo, profileRuns, ignFilters); err != nil { return } rply = &AttrSProcessEventReply{ @@ -255,13 +264,19 @@ func (alS *AttributeService) V1GetAttributeForEvent(args *utils.CGREvent, return } } + ignFilters := alS.cgrcfg.AttributeSCfg().Opts.ProfileIgnoreFilters + if opt, has := args.APIOpts[utils.OptsAttributesProfileIgnoreFilters]; has { + if ignFilters, err = utils.IfaceAsBool(opt); err != nil { + return + } + } attrPrf, err := alS.attributeProfileForEvent(tnt, context, attrIDs, args.Time, utils.MapStorage{ utils.MetaReq: args.Event, utils.MetaOpts: args.APIOpts, utils.MetaVars: utils.MapStorage{ utils.MetaProcessRuns: 0, }, - }, utils.EmptyString, make(map[string]int), 0) + }, utils.EmptyString, make(map[string]int), 0, ignFilters) if err != nil { if err != utils.ErrNotFound { err = utils.NewErrServerError(err) diff --git a/engine/attributes_test.go b/engine/attributes_test.go index 4f93be2f9..0c476b415 100644 --- a/engine/attributes_test.go +++ b/engine/attributes_test.go @@ -392,7 +392,7 @@ func TestAttributesattributeProfileForEventAnyCtxFalseNotFound(t *testing.T) { lastID := "" if rcv, err := alS.attributeProfileForEvent(tnt, ctx, nil, nil, evNm, - lastID, make(map[string]int), 0); err != nil { + lastID, make(map[string]int), 0, false); err != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) } else if !reflect.DeepEqual(rcv, ap2) { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", ap2, rcv) @@ -401,7 +401,7 @@ func TestAttributesattributeProfileForEventAnyCtxFalseNotFound(t *testing.T) { lastID = "cgrates.org:ATTR_2" if rcv, err := alS.attributeProfileForEvent(tnt, ctx, nil, nil, evNm, - lastID, make(map[string]int), 0); err == nil || err != utils.ErrNotFound { + lastID, make(map[string]int), 0, false); err == nil || err != utils.ErrNotFound { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) } else if rcv != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, rcv) @@ -473,7 +473,7 @@ func TestAttributesattributeProfileForEventAnyCtxFalseFound(t *testing.T) { lastID := "" if rcv, err := alS.attributeProfileForEvent(tnt, ctx, nil, nil, evNm, - lastID, make(map[string]int), 0); err != nil { + lastID, make(map[string]int), 0, false); err != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) } else if !reflect.DeepEqual(rcv, ap1) { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", ap1, rcv) @@ -544,7 +544,7 @@ func TestAttributesattributeProfileForEventAnyCtxTrueBothFound(t *testing.T) { lastID := "" if rcv, err := alS.attributeProfileForEvent(tnt, ctx, nil, nil, evNm, - lastID, make(map[string]int), 0); err != nil { + lastID, make(map[string]int), 0, false); err != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) } else if !reflect.DeepEqual(rcv, ap1) { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", ap1, rcv) @@ -557,7 +557,7 @@ func TestAttributesattributeProfileForEventAnyCtxTrueBothFound(t *testing.T) { } if rcv, err := alS.attributeProfileForEvent(tnt, ctx, nil, nil, evNm, - lastID, make(map[string]int), 0); err != nil { + lastID, make(map[string]int), 0, false); err != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, err) } else if !reflect.DeepEqual(rcv, ap2) { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", ap2, rcv) @@ -636,7 +636,7 @@ func TestAttributesattributeProfileForEventAnyCtxTrueErrMatching(t *testing.T) { alS.dm = NewDataManager(dbm, cfg.CacheCfg(), nil) if rcv, err := alS.attributeProfileForEvent(tnt, ctx, nil, nil, evNm, - lastID, make(map[string]int), 0); err == nil || err != utils.ErrExists { + lastID, make(map[string]int), 0, false); err == nil || err != utils.ErrExists { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", utils.ErrExists, err) } else if rcv != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, rcv) @@ -707,7 +707,7 @@ func TestAttributesattributeProfileForEventAnyCtxTrueNotFound(t *testing.T) { lastID := "" if rcv, err := alS.attributeProfileForEvent(tnt, ctx, nil, nil, evNm, - lastID, make(map[string]int), 0); err == nil || err != utils.ErrNotFound { + lastID, make(map[string]int), 0, false); err == nil || err != utils.ErrNotFound { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) } else if rcv != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, rcv) @@ -779,7 +779,7 @@ func TestAttributesattributeProfileForEventNoDBConn(t *testing.T) { alS.dm = nil if rcv, err := alS.attributeProfileForEvent(tnt, ctx, []string{"ATTR_3"}, nil, evNm, - lastID, make(map[string]int), 0); err == nil || err != utils.ErrNoDatabaseConn { + lastID, make(map[string]int), 0, false); err == nil || err != utils.ErrNoDatabaseConn { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", utils.ErrNoDatabaseConn, err) } else if rcv != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, rcv) @@ -814,7 +814,7 @@ func TestAttributesattributeProfileForEventErrNotFound(t *testing.T) { lastID := "" if rcv, err := alS.attributeProfileForEvent(tnt, ctx, []string{"ATTR_3"}, nil, evNm, - lastID, make(map[string]int), 0); err == nil || err != utils.ErrNotFound { + lastID, make(map[string]int), 0, false); err == nil || err != utils.ErrNotFound { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) } else if rcv != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, rcv) @@ -870,7 +870,7 @@ func TestAttributesattributeProfileForEventNotActive(t *testing.T) { tnt := "cgrates.org" if rcv, err := alS.attributeProfileForEvent(tnt, ctx, nil, actTime, evNm, - lastID, make(map[string]int), 0); err == nil || err != utils.ErrNotFound { + lastID, make(map[string]int), 0, false); err == nil || err != utils.ErrNotFound { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) } else if rcv != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, rcv) @@ -926,7 +926,7 @@ func TestAttributesattributeProfileForEventErrPass(t *testing.T) { } if rcv, err := alS.attributeProfileForEvent(tnt, ctx, []string{"ATTR_1"}, nil, evNm, - lastID, make(map[string]int), 0); err == nil || err != utils.ErrWrongPath { + lastID, make(map[string]int), 0, false); err == nil || err != utils.ErrWrongPath { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", utils.ErrWrongPath, err) } else if rcv != nil { t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>", nil, rcv) diff --git a/engine/z_attributes_test.go b/engine/z_attributes_test.go index 3a3dfb720..e47daf33b 100644 --- a/engine/z_attributes_test.go +++ b/engine/z_attributes_test.go @@ -250,7 +250,7 @@ func TestAttributeProfileForEvent(t *testing.T) { utils.MetaVars: utils.MapStorage{ utils.OptsAttributesProcessRuns: 0, }, - }, utils.EmptyString, make(map[string]int), 0) + }, utils.EmptyString, make(map[string]int), 0, false) if err != nil { t.Errorf("Error: %+v", err) } @@ -268,7 +268,7 @@ func TestAttributeProfileForEvent(t *testing.T) { utils.MetaVars: utils.MapStorage{ utils.OptsAttributesProcessRuns: 0, }, - }, utils.EmptyString, make(map[string]int), 0) + }, utils.EmptyString, make(map[string]int), 0, false) if err != nil { t.Errorf("Error: %+v", err) } @@ -286,7 +286,7 @@ func TestAttributeProfileForEvent(t *testing.T) { utils.MetaVars: utils.MapStorage{ utils.OptsAttributesProcessRuns: 0, }, - }, utils.EmptyString, make(map[string]int), 0) + }, utils.EmptyString, make(map[string]int), 0, false) if err != nil { t.Errorf("Error: %+v", err) } diff --git a/utils/consts.go b/utils/consts.go index a92a4d93c..837399d1f 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -2391,7 +2391,7 @@ var ( ) // CGROptionsSet the possible cgr options -var CGROptionsSet = NewStringSet([]string{OptsRatesStartTime, OptsRatesUsage, OptsSessionsTTL, +var CGROptionsSet = NewStringSet([]string{OptsSessionsTTL, OptsSessionsTTLMaxDelay, OptsSessionsTTLLastUsed, OptsSessionsTTLLastUsage, OptsSessionsTTLUsage, OptsDebitInterval, OptsStirATest, OptsStirPayloadMaxDuration, OptsStirIdentity, OptsStirOriginatorTn, OptsStirOriginatorURI, OptsStirDestinationTn, OptsStirDestinationURI, @@ -2423,8 +2423,6 @@ const ( OptsRoutesProfilesCount = "*routesProfilesCount" OptsRoutesLimit = "*routes_limit" OptsRoutesOffset = "*routes_offset" - OptsRatesStartTime = "*ratesStartTime" - OptsRatesUsage = "*ratesUsage" OptsSessionsTTL = "*sessionsTTL" OptsSessionsTTLMaxDelay = "*sessionsTTLMaxDelay" OptsSessionsTTLLastUsed = "*sessionsTTLLastUsed" @@ -2449,15 +2447,16 @@ const ( // EEs OptsEEsVerbose = "*eesVerbose" // Others - OptsContext = "*context" - Subsys = "*subsys" - MetaMethod = "*reqMethod" - OptsAttributesProfileIDs = "*attrProfileIDs" - OptsAttributesProcessRuns = "*attrProcessRuns" - OptsAttributesProfileRuns = "*attrProfileRuns" - MetaEventType = "*eventType" - EventType = "EventType" - SchedulerInit = "SchedulerInit" + OptsContext = "*context" + Subsys = "*subsys" + MetaMethod = "*reqMethod" + OptsAttributesProfileIDs = "*attrProfileIDs" + OptsAttributesProcessRuns = "*attrProcessRuns" + OptsAttributesProfileRuns = "*attrProfileRuns" + OptsAttributesProfileIgnoreFilters = "*attrProfileIgnoreFilters" + MetaEventType = "*eventType" + EventType = "EventType" + SchedulerInit = "SchedulerInit" RemoteHostOpt = "*rmtHost" CacheOpt = "*cache"