mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-12 18:46:24 +05:00
Added *profileIgnoreFilters for actions
This commit is contained in:
committed by
Dan Christian Bogos
parent
27d1882b09
commit
56f5ce07f3
@@ -92,11 +92,11 @@ func (aS *ActionS) schedInit() {
|
||||
},
|
||||
}
|
||||
}
|
||||
aS.scheduleActions(context.Background(), cgrEvs, nil, true)
|
||||
aS.scheduleActions(context.Background(), cgrEvs, nil, false, true)
|
||||
}
|
||||
|
||||
// scheduleActions will set up cron and load the matching data
|
||||
func (aS *ActionS) scheduleActions(ctx *context.Context, cgrEvs []*utils.CGREvent, aPrflIDs []string, crnReset bool) (err error) {
|
||||
func (aS *ActionS) scheduleActions(ctx *context.Context, cgrEvs []*utils.CGREvent, aPrflIDs []string, ignFilters, crnReset bool) (err error) {
|
||||
aS.crnLk.Lock() // make sure we don't have parallel processes running setu
|
||||
defer aS.crnLk.Unlock()
|
||||
crn := aS.crn
|
||||
@@ -106,7 +106,7 @@ func (aS *ActionS) scheduleActions(ctx *context.Context, cgrEvs []*utils.CGREven
|
||||
var partExec bool
|
||||
for _, cgrEv := range cgrEvs {
|
||||
var schedActSet []*scheduledActs
|
||||
if schedActSet, err = aS.scheduledActions(ctx, cgrEv.Tenant, cgrEv, aPrflIDs, false); err != nil {
|
||||
if schedActSet, err = aS.scheduledActions(ctx, cgrEv.Tenant, cgrEv, aPrflIDs, ignFilters, false); err != nil {
|
||||
utils.Logger.Warning(
|
||||
fmt.Sprintf(
|
||||
"<%s> scheduler init, ignoring tenant: <%s>, error: <%s>",
|
||||
@@ -144,8 +144,9 @@ func (aS *ActionS) scheduleActions(ctx *context.Context, cgrEvs []*utils.CGREven
|
||||
|
||||
// matchingActionProfilesForEvent returns the matched ActionProfiles for the given event
|
||||
func (aS *ActionS) matchingActionProfilesForEvent(ctx *context.Context, tnt string,
|
||||
evNm utils.MapStorage, aPrflIDs []string) (aPfs engine.ActionProfiles, err error) {
|
||||
evNm utils.MapStorage, aPrflIDs []string, ignoreFilters bool) (aPfs engine.ActionProfiles, err error) {
|
||||
if len(aPrflIDs) == 0 {
|
||||
ignoreFilters = false
|
||||
var aPfIDMp utils.StringSet
|
||||
if aPfIDMp, err = engine.MatchingItemIDsForEvent(
|
||||
ctx,
|
||||
@@ -173,11 +174,13 @@ func (aS *ActionS) matchingActionProfilesForEvent(ctx *context.Context, tnt stri
|
||||
}
|
||||
return
|
||||
}
|
||||
var pass bool
|
||||
if pass, err = aS.fltrS.Pass(ctx, tnt, aPf.FilterIDs, evNm); err != nil {
|
||||
return
|
||||
} else if !pass {
|
||||
continue
|
||||
if !ignoreFilters {
|
||||
var pass bool
|
||||
if pass, err = aS.fltrS.Pass(ctx, tnt, aPf.FilterIDs, evNm); err != nil {
|
||||
return
|
||||
} else if !pass {
|
||||
continue
|
||||
}
|
||||
}
|
||||
aPfs = append(aPfs, aPf)
|
||||
}
|
||||
@@ -190,10 +193,10 @@ func (aS *ActionS) matchingActionProfilesForEvent(ctx *context.Context, tnt stri
|
||||
|
||||
// scheduledActions is responsible for scheduling the action profiles matching cgrEv
|
||||
func (aS *ActionS) scheduledActions(ctx *context.Context, tnt string, cgrEv *utils.CGREvent, aPrflIDs []string,
|
||||
forceASAP bool) (schedActs []*scheduledActs, err error) {
|
||||
ignoreFilters, forceASAP bool) (schedActs []*scheduledActs, err error) {
|
||||
var aPfs engine.ActionProfiles
|
||||
evNm := cgrEv.AsDataProvider()
|
||||
if aPfs, err = aS.matchingActionProfilesForEvent(ctx, tnt, evNm, aPrflIDs); err != nil {
|
||||
if aPfs, err = aS.matchingActionProfilesForEvent(ctx, tnt, evNm, aPrflIDs, ignoreFilters); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -265,8 +268,13 @@ func (aS *ActionS) V1ScheduleActions(ctx *context.Context, args *utils.CGREvent,
|
||||
utils.OptsActionsActionProfileIDs); err != nil {
|
||||
return
|
||||
}
|
||||
var ignFilters bool
|
||||
if ignFilters, err = engine.GetBoolOpts(ctx, args.Tenant, args, aS.fltrS, aS.cfg.ActionSCfg().Opts.ProfileIgnoreFilters,
|
||||
utils.MetaProfileIgnoreFilters); err != nil {
|
||||
return
|
||||
}
|
||||
if err = aS.scheduleActions(ctx, []*utils.CGREvent{args},
|
||||
actPrfIDs, false); err != nil {
|
||||
actPrfIDs, ignFilters, false); err != nil {
|
||||
return
|
||||
}
|
||||
*rpl = utils.OK
|
||||
@@ -280,9 +288,14 @@ func (aS *ActionS) V1ExecuteActions(ctx *context.Context, args *utils.CGREvent,
|
||||
utils.OptsActionsActionProfileIDs); err != nil {
|
||||
return
|
||||
}
|
||||
var ignFilters bool
|
||||
if ignFilters, err = engine.GetBoolOpts(ctx, args.Tenant, args, aS.fltrS, aS.cfg.ActionSCfg().Opts.ProfileIgnoreFilters,
|
||||
utils.MetaProfileIgnoreFilters); err != nil {
|
||||
return
|
||||
}
|
||||
var schedActSet []*scheduledActs
|
||||
if schedActSet, err = aS.scheduledActions(ctx, args.Tenant,
|
||||
args, actPrfIDs, true); err != nil {
|
||||
args, actPrfIDs, ignFilters, true); err != nil {
|
||||
return
|
||||
}
|
||||
var partExec bool
|
||||
|
||||
@@ -78,7 +78,7 @@ func TestMatchingActionProfilesForEvent(t *testing.T) {
|
||||
expActionPrf := engine.ActionProfiles{actPrf}
|
||||
|
||||
if rcv, err := acts.matchingActionProfilesForEvent(context.Background(), "cgrates.org",
|
||||
evNM, []string{}); err != nil {
|
||||
evNM, []string{}, false); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(rcv, expActionPrf) {
|
||||
t.Errorf("Expected %+v, received %+v", utils.ToJSON(expActionPrf), utils.ToJSON(rcv))
|
||||
@@ -92,7 +92,7 @@ func TestMatchingActionProfilesForEvent(t *testing.T) {
|
||||
}
|
||||
//This Event is not matching with our filter
|
||||
if _, err := acts.matchingActionProfilesForEvent(context.Background(), "cgrates.org",
|
||||
evNM, []string{}); err == nil || err != utils.ErrNotFound {
|
||||
evNM, []string{}, false); err == nil || err != utils.ErrNotFound {
|
||||
t.Errorf("Expected %+v, received %+v", utils.ErrNotFound, err)
|
||||
}
|
||||
|
||||
@@ -105,26 +105,26 @@ func TestMatchingActionProfilesForEvent(t *testing.T) {
|
||||
actPrfIDs := []string{"inexisting_id"}
|
||||
//Unable to get from database an ActionProfile if the ID won't match
|
||||
if _, err := acts.matchingActionProfilesForEvent(context.Background(), "cgrates.org",
|
||||
evNM, actPrfIDs); err == nil || err != utils.ErrNotFound {
|
||||
evNM, actPrfIDs, false); err == nil || err != utils.ErrNotFound {
|
||||
t.Errorf("Expected %+v, received %+v", utils.ErrNotFound, err)
|
||||
}
|
||||
|
||||
actPrfIDs = []string{"test_id1"}
|
||||
if _, err := acts.matchingActionProfilesForEvent(context.Background(), "cgrates.org",
|
||||
evNM, actPrfIDs); err == nil || err != utils.ErrNotFound {
|
||||
evNM, actPrfIDs, false); err == nil || err != utils.ErrNotFound {
|
||||
t.Errorf("Expected %+v, received %+v", utils.ErrNotFound, err)
|
||||
}
|
||||
actPrf.FilterIDs = append(actPrf.FilterIDs, "*ai:~*req.AnswerTime:2012-07-21T00:00:00Z|2012-08-21T00:00:00Z")
|
||||
//this event is not active in this interval time
|
||||
if _, err := acts.matchingActionProfilesForEvent(context.Background(), "cgrates.org",
|
||||
evNM, actPrfIDs); err == nil || err != utils.ErrNotFound {
|
||||
evNM, actPrfIDs, false); err == nil || err != utils.ErrNotFound {
|
||||
t.Errorf("Expected %+v, received %+v", utils.ErrNotFound, err)
|
||||
}
|
||||
|
||||
//when dataManager is nil, it won't be able to get ActionsProfile from database
|
||||
acts.dm = nil
|
||||
if _, err := acts.matchingActionProfilesForEvent(context.Background(), "INVALID_TENANT",
|
||||
evNM, actPrfIDs); err == nil || err != utils.ErrNoDatabaseConn {
|
||||
evNM, actPrfIDs, false); err == nil || err != utils.ErrNoDatabaseConn {
|
||||
t.Errorf("Expected %+v, received %+v", utils.ErrNoDatabaseConn, err)
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ func TestMatchingActionProfilesForEvent(t *testing.T) {
|
||||
}
|
||||
expected := "NOT_FOUND:invalid_filters"
|
||||
if _, err := acts.matchingActionProfilesForEvent(context.Background(), "cgrates.org",
|
||||
evNM, actPrfIDs); err == nil || err.Error() != expected {
|
||||
evNM, actPrfIDs, false); err == nil || err.Error() != expected {
|
||||
t.Errorf("Expected %+v, received %+v", expected, err)
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ func TestScheduledActions(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if rcv, err := acts.scheduledActions(context.Background(), cgrEv.Tenant, cgrEv, []string{}, false); err != nil {
|
||||
if rcv, err := acts.scheduledActions(context.Background(), cgrEv.Tenant, cgrEv, []string{}, false, false); err != nil {
|
||||
t.Error(err)
|
||||
} else {
|
||||
expSchedActs := newScheduledActs(context.Background(), cgrEv.Tenant, cgrEv.ID, utils.MetaNone, utils.EmptyString,
|
||||
@@ -204,7 +204,7 @@ func TestScheduledActions(t *testing.T) {
|
||||
utils.Accounts: "10",
|
||||
},
|
||||
}
|
||||
if _, err := acts.scheduledActions(context.Background(), cgrEv.Tenant, cgrEv, []string{}, false); err == nil || err != utils.ErrNotFound {
|
||||
if _, err := acts.scheduledActions(context.Background(), cgrEv.Tenant, cgrEv, []string{}, false, false); err == nil || err != utils.ErrNotFound {
|
||||
t.Errorf("Expected %+v, received %+v", utils.ErrNotFound, err)
|
||||
}
|
||||
}
|
||||
@@ -248,12 +248,12 @@ func TestScheduleAction(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if err := acts.scheduleActions(context.Background(), cgrEv, []string{}, true); err != nil {
|
||||
if err := acts.scheduleActions(context.Background(), cgrEv, []string{}, false, true); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
//Cannot schedule an action if the ID is invalid
|
||||
if err := acts.scheduleActions(context.Background(), cgrEv, []string{"INVALID_ID1"}, true); err == nil || err != utils.ErrPartiallyExecuted {
|
||||
if err := acts.scheduleActions(context.Background(), cgrEv, []string{"INVALID_ID1"}, false, true); err == nil || err != utils.ErrPartiallyExecuted {
|
||||
t.Errorf("Expected %+v, received %+v", utils.ErrPartiallyExecuted, err)
|
||||
}
|
||||
|
||||
@@ -262,7 +262,7 @@ func TestScheduleAction(t *testing.T) {
|
||||
if err := acts.dm.SetActionProfile(context.Background(), actPrf, true); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if err := acts.scheduleActions(context.Background(), cgrEv, []string{}, true); err != nil {
|
||||
if err := acts.scheduleActions(context.Background(), cgrEv, []string{}, false, true); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@@ -271,7 +271,7 @@ func TestScheduleAction(t *testing.T) {
|
||||
if err := acts.dm.SetActionProfile(context.Background(), actPrf, true); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if err := acts.scheduleActions(context.Background(), cgrEv, []string{}, true); err == nil || err != utils.ErrPartiallyExecuted {
|
||||
if err := acts.scheduleActions(context.Background(), cgrEv, []string{}, false, true); err == nil || err != utils.ErrPartiallyExecuted {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
@@ -1084,7 +1084,7 @@ func TestACScheduledActions(t *testing.T) {
|
||||
|
||||
acts := NewActionS(cfg, fltrs, dm, nil)
|
||||
expected := "WARNING] <ActionS> ignoring ActionProfile with id: <cgrates.org:TestACScheduledActions> creating action: <TOPUP>, error: <unsupported action type: <inexistent_type>>"
|
||||
if _, err := acts.scheduledActions(context.Background(), "cgrates.org", cgrEv, []string{}, true); err != nil {
|
||||
if _, err := acts.scheduledActions(context.Background(), "cgrates.org", cgrEv, []string{}, false, true); err != nil {
|
||||
t.Error(err)
|
||||
} else if rcv := buff.String(); !strings.Contains(rcv, expected) {
|
||||
t.Errorf("Expected %+v, received %+v", expected, rcv)
|
||||
@@ -1117,7 +1117,7 @@ func TestACScheduledActions(t *testing.T) {
|
||||
},
|
||||
}
|
||||
var schedActs []*scheduledActs
|
||||
if schedActs, err = acts.scheduledActions(context.Background(), "cgrates.org", cgrEv, []string{}, true); err != nil {
|
||||
if schedActs, err = acts.scheduledActions(context.Background(), "cgrates.org", cgrEv, []string{}, false, true); err != nil {
|
||||
t.Error(err)
|
||||
} else {
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ import (
|
||||
)
|
||||
|
||||
type ActionsOpts struct {
|
||||
ActionProfileIDs []*utils.DynamicStringSliceOpt
|
||||
ActionProfileIDs []*utils.DynamicStringSliceOpt
|
||||
ProfileIgnoreFilters []*utils.DynamicBoolOpt
|
||||
}
|
||||
|
||||
// ActionSCfg is the configuration of ActionS
|
||||
@@ -61,6 +62,9 @@ func (actOpts *ActionsOpts) loadFromJSONCfg(jsnCfg *ActionsOptsJson) {
|
||||
if jsnCfg.ActionProfileIDs != nil {
|
||||
actOpts.ActionProfileIDs = append(actOpts.ActionProfileIDs, utils.MapToDynamicStringSliceOpts(jsnCfg.ActionProfileIDs)...)
|
||||
}
|
||||
if jsnCfg.ProfileIgnoreFilters != nil {
|
||||
actOpts.ProfileIgnoreFilters = append(actOpts.ProfileIgnoreFilters, utils.MapToDynamicBoolOpts(jsnCfg.ProfileIgnoreFilters)...)
|
||||
}
|
||||
}
|
||||
|
||||
func (acS *ActionSCfg) loadFromJSONCfg(jsnCfg *ActionSJsonCfg) (err error) {
|
||||
@@ -118,7 +122,8 @@ func (acS *ActionSCfg) loadFromJSONCfg(jsnCfg *ActionSJsonCfg) (err error) {
|
||||
// AsMapInterface returns the config as a map[string]interface{}
|
||||
func (acS ActionSCfg) AsMapInterface(string) interface{} {
|
||||
opts := map[string]interface{}{
|
||||
utils.MetaActionProfileIDsCfg: utils.DynamicStringSliceOptsToMap(acS.Opts.ActionProfileIDs),
|
||||
utils.MetaActionProfileIDsCfg: utils.DynamicStringSliceOptsToMap(acS.Opts.ActionProfileIDs),
|
||||
utils.MetaProfileIgnoreFilters: utils.DynamicBoolOptsToMap(acS.Opts.ProfileIgnoreFilters),
|
||||
}
|
||||
mp := map[string]interface{}{
|
||||
utils.EnabledCfg: acS.Enabled,
|
||||
@@ -165,8 +170,13 @@ func (actOpts *ActionsOpts) Clone() *ActionsOpts {
|
||||
if actOpts.ActionProfileIDs != nil {
|
||||
actPrfIDs = utils.CloneDynamicStringSliceOpt(actOpts.ActionProfileIDs)
|
||||
}
|
||||
var profileIgnoreFilters []*utils.DynamicBoolOpt
|
||||
if actOpts.ProfileIgnoreFilters != nil {
|
||||
profileIgnoreFilters = utils.CloneDynamicBoolOpt(actOpts.ProfileIgnoreFilters)
|
||||
}
|
||||
return &ActionsOpts{
|
||||
ActionProfileIDs: actPrfIDs,
|
||||
ActionProfileIDs: actPrfIDs,
|
||||
ProfileIgnoreFilters: profileIgnoreFilters,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,7 +225,8 @@ func (acS ActionSCfg) Clone() (cln *ActionSCfg) {
|
||||
}
|
||||
|
||||
type ActionsOptsJson struct {
|
||||
ActionProfileIDs map[string][]string `json:"*actionProfileIDs"`
|
||||
ActionProfileIDs map[string][]string `json:"*actionProfileIDs"`
|
||||
ProfileIgnoreFilters map[string]bool `json:"*profileIgnoreFilters"`
|
||||
}
|
||||
|
||||
// Action service config section
|
||||
@@ -243,6 +254,9 @@ func diffActionsOptsJsonCfg(d *ActionsOptsJson, v1, v2 *ActionsOpts) *ActionsOpt
|
||||
if !utils.DynamicStringSliceOptEqual(v1.ActionProfileIDs, v2.ActionProfileIDs) {
|
||||
d.ActionProfileIDs = utils.DynamicStringSliceOptsToMap(v2.ActionProfileIDs)
|
||||
}
|
||||
if !utils.DynamicBoolOptEqual(v1.ProfileIgnoreFilters, v2.ProfileIgnoreFilters) {
|
||||
d.ProfileIgnoreFilters = utils.DynamicBoolOptsToMap(v2.ProfileIgnoreFilters)
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,12 @@ func TestActionSCfgLoadFromJSONCfg(t *testing.T) {
|
||||
Value: []string{},
|
||||
},
|
||||
},
|
||||
ProfileIgnoreFilters: []*utils.DynamicBoolOpt{
|
||||
{
|
||||
FilterIDs: []string{utils.MetaDefault},
|
||||
Value: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
jsnCfg := NewDefaultCGRConfig()
|
||||
@@ -109,6 +115,9 @@ func TestActionSCfgAsMapInterface(t *testing.T) {
|
||||
utils.MetaActionProfileIDsCfg: map[string][]string{
|
||||
utils.MetaDefault: {},
|
||||
},
|
||||
utils.MetaProfileIgnoreFilters: map[string]bool{
|
||||
utils.MetaDefault: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
if cgrCfg, err := NewCGRConfigFromJSONStringWithDefaults(cfgJSONStr); err != nil {
|
||||
|
||||
@@ -1326,7 +1326,10 @@ const CGRATES_CFG_JSON = `
|
||||
"opts":{ //
|
||||
"*actionProfileIDs": { //
|
||||
"*default": [],
|
||||
},
|
||||
},
|
||||
"*profileIgnoreFilters": { // if we should check the filters
|
||||
"*default": false,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -2344,6 +2344,9 @@ func TestDfActionSJsonCfg(t *testing.T) {
|
||||
ActionProfileIDs: map[string][]string{
|
||||
utils.MetaDefault: {},
|
||||
},
|
||||
ProfileIgnoreFilters: map[string]bool{
|
||||
utils.MetaDefault: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON))
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user