Added new filter "*contains"

This commit is contained in:
gezimbll
2023-12-12 10:19:49 -05:00
committed by Dan Christian Bogos
parent b4ef61d6f2
commit 422d9196b4
4 changed files with 124 additions and 3 deletions

View File

@@ -5014,3 +5014,66 @@ func TestDmUpdateReverseDestination(t *testing.T) {
}
}
}
func TestIndxFilterContains(t *testing.T) {
cfg := config.NewDefaultCGRConfig()
dm := NewDataManager(NewInternalDB(nil, nil, true, cfg.DataDbCfg().Items), cfg.CacheCfg(), nil)
ft := &Filter{
Tenant: "cgrates.org",
ID: "Filter1",
Rules: []*FilterRule{
{
Type: utils.MetaContains,
Element: "~*req.EventType",
Values: []string{"Ev"},
},
},
}
if err := dm.SetFilter(ft, true); err != nil {
t.Error(err)
}
fs := &Filter{
Tenant: "cgrates.org",
ID: "Filter2",
Rules: []*FilterRule{
{
Type: utils.MetaString,
Element: "~*req.EventType",
Values: []string{"Event1"},
},
},
}
if err := dm.SetFilter(fs, true); err != nil {
t.Error(err)
}
th := &ThresholdProfile{
Tenant: "cgrates.org",
ID: "THD_Test",
ActivationInterval: &utils.ActivationInterval{},
FilterIDs: []string{"Filter1", "Filter2"},
MaxHits: 12,
MinSleep: 0,
Blocker: true,
Weight: 1.4,
ActionIDs: []string{},
}
if err := dm.SetThresholdProfile(th, true); err != nil {
t.Error(err)
}
eIdxes := map[string]utils.StringSet{
"*string:*req.EventType:Event1": {
"THD_Test": struct{}{},
},
}
if rcvIdx, err := dm.GetIndexes(
utils.CacheThresholdFilterIndexes, th.Tenant,
utils.EmptyString, false, false); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eIdxes, rcvIdx) {
t.Errorf("Expecting %+v, received: %+v", eIdxes, rcvIdx)
}
}

View File

@@ -225,20 +225,20 @@ func (fltr *Filter) Compile() (err error) {
}
var supportedFiltersType utils.StringSet = utils.NewStringSet([]string{
utils.MetaString, utils.MetaPrefix, utils.MetaSuffix,
utils.MetaString, utils.MetaContains, utils.MetaPrefix, utils.MetaSuffix,
utils.MetaTimings, utils.MetaRSR, utils.MetaDestinations,
utils.MetaEmpty, utils.MetaExists, utils.MetaLessThan, utils.MetaLessOrEqual,
utils.MetaGreaterThan, utils.MetaGreaterOrEqual, utils.MetaEqual,
utils.MetaIPNet, utils.MetaAPIBan, utils.MetaSentryPeer, utils.MetaActivationInterval,
utils.MetaRegex})
var needsFieldName utils.StringSet = utils.NewStringSet([]string{
utils.MetaString, utils.MetaPrefix, utils.MetaSuffix,
utils.MetaString, utils.MetaContains, utils.MetaPrefix, utils.MetaSuffix,
utils.MetaTimings, utils.MetaRSR, utils.MetaDestinations, utils.MetaLessThan,
utils.MetaEmpty, utils.MetaExists, utils.MetaLessOrEqual, utils.MetaGreaterThan,
utils.MetaGreaterOrEqual, utils.MetaEqual, utils.MetaIPNet, utils.MetaAPIBan, utils.MetaSentryPeer,
utils.MetaActivationInterval,
utils.MetaRegex})
var needsValues utils.StringSet = utils.NewStringSet([]string{utils.MetaString, utils.MetaPrefix,
var needsValues utils.StringSet = utils.NewStringSet([]string{utils.MetaString, utils.MetaContains, utils.MetaPrefix,
utils.MetaSuffix, utils.MetaTimings, utils.MetaRSR, utils.MetaDestinations,
utils.MetaLessThan, utils.MetaLessOrEqual, utils.MetaGreaterThan, utils.MetaGreaterOrEqual,
utils.MetaEqual, utils.MetaIPNet, utils.MetaAPIBan, utils.MetaSentryPeer, utils.MetaActivationInterval,
@@ -330,6 +330,8 @@ func (fltr *FilterRule) Pass(dDP utils.DataProvider) (result bool, err error) {
switch fltr.Type {
case utils.MetaString, utils.MetaNotString:
result, err = fltr.passString(dDP)
case utils.MetaContains, utils.MetaNotContains:
result, err = fltr.passContains(dDP)
case utils.MetaEmpty, utils.MetaNotEmpty:
result, err = fltr.passEmpty(dDP)
case utils.MetaExists, utils.MetaNotExists:
@@ -387,6 +389,26 @@ func (fltr *FilterRule) passString(dDP utils.DataProvider) (bool, error) {
return false, nil
}
func (fltr *FilterRule) passContains(dDP utils.DataProvider) (bool, error) {
strVal, err := fltr.rsrElement.ParseDataProvider(dDP)
if err != nil {
if err == utils.ErrNotFound {
return false, nil
}
return false, err
}
for _, val := range fltr.rsrValues {
sval, err := val.ParseDataProvider(dDP)
if err != nil {
continue
}
if strings.Contains(strVal, sval) {
return true, nil
}
}
return false, nil
}
func (fltr *FilterRule) passExists(dDP utils.DataProvider) (bool, error) {
path, err := fltr.rsrElement.CompileDynRule(dDP)
if err != nil {

View File

@@ -89,6 +89,40 @@ func TestFilterPassString(t *testing.T) {
}
}
func TestFilterPassContains(t *testing.T) {
dp := utils.MapStorage{
utils.MetaReq: map[string]any{
"Attribute": "AttributeProfile1",
utils.AnswerTime: time.Date(2014, 7, 14, 14, 30, 0, 0, time.UTC),
"UsageInterval": "1s",
utils.Weight: "20.0",
"Account": "1001",
"OriginHost": "22.15.81.122",
}}
rF, _ := NewFilterRule(utils.MetaContains, "~*req.Attribute", []string{"Profile"})
if pass, err := rF.passContains(dp); err != nil {
t.Error(err)
} else if !pass {
t.Error("FilterRule should pass")
}
rF, _ = NewFilterRule(utils.MetaContains, "~*req.OriginHost", []string{"81"})
if pass, err := rF.passContains(dp); err != nil {
t.Error(err)
} else if !pass {
t.Error("FilterRule should pass")
}
rF, _ = NewFilterRule(utils.MetaContains, "~*req.Account", []string{"200"})
if pass, err := rF.passContains(dp); err != nil {
t.Error(err)
} else if pass {
t.Error("FilterRule should not pass")
}
}
func TestFilterPassRegex(t *testing.T) {
cd := &CallDescriptor{
Category: "call",

View File

@@ -1177,6 +1177,7 @@ const (
MetaNumber = "*number"
MetaActivationInterval = "*ai"
MetaRegex = "*regex"
MetaContains = "*contains"
MetaNotString = "*notstring"
MetaNotPrefix = "*notprefix"
@@ -1194,6 +1195,7 @@ const (
MetaNotSentryPeer = "*notsentrypeer"
MetaNotActivationInterval = "*notai"
MetaNotRegex = "*notregex"
MetaNotContains = "*notcontains"
MetaEC = "*ec"
)