diff --git a/engine/filters.go b/engine/filters.go index 27c26d99c..38f94254f 100644 --- a/engine/filters.go +++ b/engine/filters.go @@ -224,16 +224,19 @@ var supportedFiltersType utils.StringSet = utils.NewStringSet([]string{ utils.MetaTimings, utils.MetaRSR, utils.MetaDestinations, utils.MetaEmpty, utils.MetaExists, utils.MetaLessThan, utils.MetaLessOrEqual, utils.MetaGreaterThan, utils.MetaGreaterOrEqual, utils.MetaEqual, - utils.MetaNotEqual, utils.MetaIPNet, utils.MetaAPIBan}) + utils.MetaNotEqual, utils.MetaIPNet, utils.MetaAPIBan, + utils.MetaActivationInterval}) var needsFieldName utils.StringSet = utils.NewStringSet([]string{ utils.MetaString, 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.MetaNotEqual, utils.MetaIPNet, utils.MetaAPIBan}) + utils.MetaGreaterOrEqual, utils.MetaEqual, utils.MetaNotEqual, utils.MetaIPNet, utils.MetaAPIBan, + utils.MetaActivationInterval}) var needsValues utils.StringSet = utils.NewStringSet([]string{utils.MetaString, utils.MetaPrefix, utils.MetaSuffix, utils.MetaTimings, utils.MetaRSR, utils.MetaDestinations, utils.MetaLessThan, utils.MetaLessOrEqual, utils.MetaGreaterThan, utils.MetaGreaterOrEqual, - utils.MetaEqual, utils.MetaNotEqual, utils.MetaIPNet, utils.MetaAPIBan}) + utils.MetaEqual, utils.MetaNotEqual, utils.MetaIPNet, utils.MetaAPIBan, + utils.MetaActivationInterval}) // NewFilterRule returns a new filter func NewFilterRule(rfType, fieldName string, vals []string) (*FilterRule, error) { @@ -294,6 +297,19 @@ func (fltr *FilterRule) CompileValues() (err error) { } else if fltr.rsrElement == nil { return fmt.Errorf("emtpy RSRParser in rule: <%s>", fltr.Element) } + case utils.MetaActivationInterval, utils.MetaNotActivationInterval: + if fltr.rsrElement, err = config.NewRSRParser(fltr.Element); err != nil { + return + } else if fltr.rsrElement == nil { + return fmt.Errorf("emtpy RSRParser in rule: <%s>", fltr.Element) + } + for _, strVal := range fltr.Values { + rsrPrsr, err := config.NewRSRParser(strVal) + if err != nil { + return err + } + fltr.rsrValues = append(fltr.rsrValues, rsrPrsr) + } default: if fltr.rsrValues, err = config.NewRSRParsersFromSlice(fltr.Values); err != nil { return @@ -338,6 +354,8 @@ func (fltr *FilterRule) Pass(dDP utils.DataProvider) (result bool, err error) { result, err = fltr.passIPNet(dDP) case utils.MetaAPIBan, utils.MetaNotAPIBan: result, err = fltr.passAPIBan(dDP) + case utils.MetaActivationInterval, utils.MetaNotActivationInterval: + result, err = fltr.passActivationInterval(dDP) default: err = utils.ErrPrefixNotErrNotImplemented(fltr.Type) } @@ -615,6 +633,52 @@ func (fltr *FilterRule) passAPIBan(dDP utils.DataProvider) (bool, error) { return dm.GetAPIBan(strVal, config.CgrConfig().APIBanCfg().Keys, fltr.Values[0] != utils.MetaAll, true, true) } +func (fltr *FilterRule) passActivationInterval(dDp utils.DataProvider) (bool, error) { + strVal, err := fltr.rsrElement.ParseDataProvider(dDp) + if err != nil { + if err == utils.ErrNotFound { + return false, nil + } + return false, err + } + timeStrVal, err := utils.ParseTimeDetectLayout(strVal, config.CgrConfig().GeneralCfg().DefaultTimezone) + if err != nil { + return false, err + } + if len(fltr.rsrValues) == 2 { + val2, err := fltr.rsrValues[1].CompileDynRule(dDp) + if err != nil { + return false, err + } + endTime, err := utils.ParseTimeDetectLayout(val2, config.CgrConfig().GeneralCfg().DefaultTimezone) + if err != nil { + return false, err + } + if fltr.rsrValues[0] == nil { + return timeStrVal.Before(endTime), nil + } + val1, err := fltr.rsrValues[0].CompileDynRule(dDp) + if err != nil { + return false, err + } + startTime, err := utils.ParseTimeDetectLayout(val1, config.CgrConfig().GeneralCfg().DefaultTimezone) + if err != nil { + return false, err + } + return startTime.Before(timeStrVal) && timeStrVal.Before(endTime), nil + } else { + val1, err := fltr.rsrValues[0].CompileDynRule(dDp) + if err != nil { + return false, err + } + startTime, err := utils.ParseTimeDetectLayout(val1, config.CgrConfig().GeneralCfg().DefaultTimezone) + if err != nil { + return false, err + } + return startTime.Before(timeStrVal), nil + } +} + func verifyInlineFilterS(fltrs []string) (err error) { for _, fl := range fltrs { if strings.HasPrefix(fl, utils.Meta) { diff --git a/engine/filters_test.go b/engine/filters_test.go index 1e5c824c0..4aae1d3b4 100644 --- a/engine/filters_test.go +++ b/engine/filters_test.go @@ -47,6 +47,7 @@ func TestFilterPassString(t *testing.T) { } else if !passes { t.Error("Not passes filter") } + rf = &FilterRule{Type: utils.MetaString, Element: "~Category", Values: []string{"cal"}} if err := rf.CompileValues(); err != nil { @@ -1372,6 +1373,62 @@ func TestVerifyInlineFilterS(t *testing.T) { } } +func TestActivationIntervalPass(t *testing.T) { + cfg := config.NewDefaultCGRConfig() + data := NewInternalDB(nil, nil, true) + dmFilterPass := NewDataManager(data, config.CgrConfig().CacheCfg(), nil) + filterS := FilterS{ + cfg: cfg, + dm: dmFilterPass, + } + passEvent := map[string]interface{}{ + "CustomTime": time.Date(2013, time.July, 1, 0, 0, 0, 0, time.UTC), + } + fEv := utils.MapStorage{} + fEv.Set([]string{utils.MetaReq}, passEvent) + if pass, err := filterS.Pass("cgrates.org", + []string{"*ai:~*req.CustomTime:2013-06-01T00:00:00Z"}, fEv); err != nil { + t.Error(err) + } else if !pass { + t.Errorf("Expecting: %+v, received: %+v", true, pass) + } + + if pass, err := filterS.Pass("cgrates.org", + []string{"*ai:~*req.CustomTime:2013-09-01T00:00:00Z"}, fEv); err != nil { + t.Error(err) + } else if pass { + t.Errorf("Expecting: %+v, received: %+v", false, pass) + } + + if pass, err := filterS.Pass("cgrates.org", + []string{"*ai:~*req.CustomTime:;2013-09-01T00:00:00Z"}, fEv); err != nil { + t.Error(err) + } else if !pass { + t.Errorf("Expecting: %+v, received: %+v", true, pass) + } + + if pass, err := filterS.Pass("cgrates.org", + []string{"*ai:~*req.CustomTime:;2013-06-01T00:00:00Z"}, fEv); err != nil { + t.Error(err) + } else if pass { + t.Errorf("Expecting: %+v, received: %+v", false, pass) + } + + if pass, err := filterS.Pass("cgrates.org", + []string{"*ai:~*req.CustomTime:2013-06-01T00:00:00Z;2013-09-01T00:00:00Z"}, fEv); err != nil { + t.Error(err) + } else if !pass { + t.Errorf("Expecting: %+v, received: %+v", true, pass) + } + + if pass, err := filterS.Pass("cgrates.org", + []string{"*ai:~*req.CustomTime:2013-08-01T00:00:00Z;2013-09-01T00:00:00Z"}, fEv); err != nil { + t.Error(err) + } else if pass { + t.Errorf("Expecting: %+v, received: %+v", false, pass) + } +} + func TestFilterPassIPNet(t *testing.T) { cd := utils.MapStorage{ "IP": "192.0.2.0", diff --git a/utils/consts.go b/utils/consts.go index 5adebba9f..f28f03e66 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -1151,38 +1151,40 @@ const ( //Filter types const ( - MetaNot = "*not" - MetaString = "*string" - MetaPrefix = "*prefix" - MetaSuffix = "*suffix" - MetaEmpty = "*empty" - MetaExists = "*exists" - MetaTimings = "*timings" - MetaRSR = "*rsr" - MetaStatS = "*stats" - MetaDestinations = "*destinations" - MetaLessThan = "*lt" - MetaLessOrEqual = "*lte" - MetaGreaterThan = "*gt" - MetaGreaterOrEqual = "*gte" - MetaResources = "*resources" - MetaEqual = "*eq" - MetaIPNet = "*ipnet" - MetaAPIBan = "*apiban" + MetaNot = "*not" + MetaString = "*string" + MetaPrefix = "*prefix" + MetaSuffix = "*suffix" + MetaEmpty = "*empty" + MetaExists = "*exists" + MetaTimings = "*timings" + MetaRSR = "*rsr" + MetaStatS = "*stats" + MetaDestinations = "*destinations" + MetaLessThan = "*lt" + MetaLessOrEqual = "*lte" + MetaGreaterThan = "*gt" + MetaGreaterOrEqual = "*gte" + MetaResources = "*resources" + MetaEqual = "*eq" + MetaIPNet = "*ipnet" + MetaAPIBan = "*apiban" + MetaActivationInterval = "*ai" - MetaNotString = "*notstring" - MetaNotPrefix = "*notprefix" - MetaNotSuffix = "*notsuffix" - MetaNotEmpty = "*notempty" - MetaNotExists = "*notexists" - MetaNotTimings = "*nottimings" - MetaNotRSR = "*notrsr" - MetaNotStatS = "*notstats" - MetaNotDestinations = "*notdestinations" - MetaNotResources = "*notresources" - MetaNotEqual = "*noteq" - MetaNotIPNet = "*notipnet" - MetaNotAPIBan = "*notapiban" + MetaNotString = "*notstring" + MetaNotPrefix = "*notprefix" + MetaNotSuffix = "*notsuffix" + MetaNotEmpty = "*notempty" + MetaNotExists = "*notexists" + MetaNotTimings = "*nottimings" + MetaNotRSR = "*notrsr" + MetaNotStatS = "*notstats" + MetaNotDestinations = "*notdestinations" + MetaNotResources = "*notresources" + MetaNotEqual = "*noteq" + MetaNotIPNet = "*notipnet" + MetaNotAPIBan = "*notapiban" + MetaNotActivationInterval = "*notai" MetaEC = "*ec" )