diff --git a/analyzers/analyzers.go b/analyzers/analyzers.go index 54c9241d5..a5d6b8a69 100755 --- a/analyzers/analyzers.go +++ b/analyzers/analyzers.go @@ -175,6 +175,7 @@ func (aS *AnalyzerService) V1StringQuery(args *QueryArgs, reply *[]map[string]in args.ContentFilters, utils.MapStorage{ utils.MetaReq: reqDP, utils.MetaRep: repDP, + utils.MetaHdr: utils.MapStorage(obj.Fields), }); err != nil { return err } else if !pass { diff --git a/analyzers/analyzers_it_test.go b/analyzers/analyzers_it_test.go index 79d598dcc..09e16d60c 100644 --- a/analyzers/analyzers_it_test.go +++ b/analyzers/analyzers_it_test.go @@ -52,6 +52,7 @@ var ( testAnalyzerSChargerSv1ProcessEvent, testAnalyzerSV1Search, testAnalyzerSV1Search2, + testAnalyzerSV1SearchWithContentFilters, testAnalyzerSKillEngine, } ) @@ -214,6 +215,18 @@ func testAnalyzerSV1Search2(t *testing.T) { } } +func testAnalyzerSV1SearchWithContentFilters(t *testing.T) { + var result []map[string]interface{} + if err := anzRPC.Call(utils.AnalyzerSv1StringQuery, &QueryArgs{ + HeaderFilters: `+RequestEncoding:\*json`, + ContentFilters: []string{"*string:~*req.Event.Account:1010"}, + }, &result); err != nil { + t.Error(err) + } else if len(result) != 1 { + t.Errorf("Unexpected result: %s", utils.ToJSON(result)) + } +} + func testAnalyzerSKillEngine(t *testing.T) { if err := engine.KillEngine(100); err != nil { t.Error(err) diff --git a/analyzers/analyzers_test.go b/analyzers/analyzers_test.go index 399bea629..1a4030dd8 100644 --- a/analyzers/analyzers_test.go +++ b/analyzers/analyzers_test.go @@ -30,6 +30,7 @@ import ( "github.com/blevesearch/bleve" "github.com/blevesearch/bleve/search" "github.com/cgrates/cgrates/config" + "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" ) @@ -199,7 +200,11 @@ func TestAnalyzersV1Search(t *testing.T) { if err = os.MkdirAll(cfg.AnalyzerSCfg().DBPath, 0700); err != nil { t.Fatal(err) } - anz, err := NewAnalyzerService(cfg, nil) + dm := engine.NewDataManager(engine.NewInternalDB(nil, nil, true), cfg.CacheCfg(), nil) + fs := engine.NewFilterS(cfg, nil, dm) + fsChan := make(chan *engine.FilterS, 1) + fsChan <- fs + anz, err := NewAnalyzerService(cfg, fsChan) if err != nil { t.Fatal(err) } @@ -294,6 +299,100 @@ func TestAnalyzersV1Search(t *testing.T) { t.Errorf("Expected %s received: %s", utils.ToJSON(expRply), utils.ToJSON(reply)) } + reply = []map[string]interface{}{} + if err = anz.V1StringQuery(&QueryArgs{ + HeaderFilters: "RequestEncoding:*gob", + ContentFilters: []string{"*string:~*rep:Pong"}, + }, &reply); err != nil { + t.Fatal(err) + } else if !reflect.DeepEqual(expRply, reply) { + t.Errorf("Expected %s received: %s", utils.ToJSON(expRply), utils.ToJSON(reply)) + } + reply = []map[string]interface{}{} + if err = anz.V1StringQuery(&QueryArgs{ + HeaderFilters: "RequestEncoding:*gob", + ContentFilters: []string{"*string:~*req.Opts.EventSource:*attributes"}, + }, &reply); err != nil { + t.Fatal(err) + } else if !reflect.DeepEqual(expRply, reply) { + t.Errorf("Expected %s received: %s", utils.ToJSON(expRply), utils.ToJSON(reply)) + } + if err = anz.V1StringQuery(&QueryArgs{ + HeaderFilters: "RequestEncoding:*gob", + ContentFilters: []string{"*gt:~*hdr.RequestDuration:1m"}, + }, &reply); err != nil { + t.Fatal(err) + } else if !reflect.DeepEqual(expRply, reply) { + t.Errorf("Expected %s received: %s", utils.ToJSON(expRply), utils.ToJSON(reply)) + } + + expRply = []map[string]interface{}{} + reply = []map[string]interface{}{} + if err = anz.V1StringQuery(&QueryArgs{ + HeaderFilters: "RequestEncoding:*gob", + ContentFilters: []string{"*string:~*req.Opts.EventSource:*cdrs"}, + }, &reply); err != nil { + t.Fatal(err) + } else if !reflect.DeepEqual(expRply, reply) { + t.Errorf("Expected %s received: %s", utils.ToJSON(expRply), utils.ToJSON(reply)) + } + if err = anz.V1StringQuery(&QueryArgs{ + HeaderFilters: "RequestEncoding:*gob", + ContentFilters: []string{"*notstring:~*req.Opts.EventSource:*attributes"}, + }, &reply); err != nil { + t.Fatal(err) + } else if !reflect.DeepEqual(expRply, reply) { + t.Errorf("Expected %s received: %s", utils.ToJSON(expRply), utils.ToJSON(reply)) + } + + expErr := utils.ErrPrefixNotErrNotImplemented("*type") + if err = anz.V1StringQuery(&QueryArgs{ + HeaderFilters: "RequestEncoding:*gob", + ContentFilters: []string{"*type:~*opts.EventSource:*cdrs"}, + }, &reply); err == nil || err.Error() != expErr.Error() { + t.Errorf("Expected error: %s,received:%v", expErr, err) + } + + sTime := time.Now() + if err = anz.db.Index(utils.ConcatenatedKey(utils.AttributeSv1Ping, strconv.FormatInt(sTime.Unix(), 10)), + &InfoRPC{ + RequestDuration: time.Second, + RequestStartTime: sTime, + RequestEncoding: utils.MetaJSON, + RequestID: 0, + RequestMethod: utils.AttributeSv1Ping, + RequestParams: `a`, + Reply: `{}`, + }); err != nil { + t.Fatal(err) + } + + expErr = new(json.SyntaxError) + if err = anz.V1StringQuery(&QueryArgs{ + HeaderFilters: "RequestMethod:" + utils.AttributeSv1Ping, + ContentFilters: []string{"*type:~*opts.EventSource:*cdrs"}, + }, &reply); err == nil || err.Error() != expErr.Error() { + t.Errorf("Expected error: %s,received:%v", expErr, err) + } + if err = anz.db.Index(utils.ConcatenatedKey(utils.AttributeSv1Ping, strconv.FormatInt(sTime.Unix(), 10)), + &InfoRPC{ + RequestDuration: time.Second, + RequestStartTime: sTime, + RequestEncoding: utils.MetaJSON, + RequestID: 0, + RequestMethod: utils.AttributeSv1Ping, + RequestParams: `{}`, + Reply: `a`, + }); err != nil { + t.Fatal(err) + } + if err = anz.V1StringQuery(&QueryArgs{ + HeaderFilters: "RequestMethod:" + utils.AttributeSv1Ping, + ContentFilters: []string{"*type:~*opts.EventSource:*cdrs"}, + }, &reply); err == nil || err.Error() != expErr.Error() { + t.Errorf("Expected error: %s,received:%v", expErr, err) + } + if err = anz.db.Close(); err != nil { t.Fatal(err) } diff --git a/analyzers/libanalyzers_test.go b/analyzers/libanalyzers_test.go index dd6f9dc94..7d6cac4ee 100644 --- a/analyzers/libanalyzers_test.go +++ b/analyzers/libanalyzers_test.go @@ -100,7 +100,7 @@ func TestNewInfoRPC(t *testing.T) { func TestUnmarshalJSON(t *testing.T) { expErr := new(json.SyntaxError) - if _, err := unmarshalJSON(json.RawMessage(`a`)); errors.Is(err, expErr) { + if _, err := unmarshalJSON(json.RawMessage(`a`)); err == nil || err.Error() != expErr.Error() { t.Errorf("Expected error: %s,received %+v", expErr, err) } var exp interface{} = true diff --git a/engine/dynamicdp.go b/engine/dynamicdp.go index b9fada387..9972facad 100644 --- a/engine/dynamicdp.go +++ b/engine/dynamicdp.go @@ -63,7 +63,8 @@ func (dDP *dynamicDP) RemoteHost() net.Addr { var initialDPPrefixes = utils.NewStringSet([]string{utils.MetaReq, utils.MetaVars, utils.MetaCgreq, utils.MetaCgrep, utils.MetaRep, utils.MetaCGRAReq, - utils.MetaAct, utils.MetaEC, utils.MetaUCH, utils.MetaOpts}) + utils.MetaAct, utils.MetaEC, utils.MetaUCH, utils.MetaOpts, + utils.MetaHdr, utils.MetaTrl}) func (dDP *dynamicDP) FieldAsInterface(fldPath []string) (val interface{}, err error) { if len(fldPath) == 0 { diff --git a/engine/filters.go b/engine/filters.go index 01dcd7169..27c26d99c 100644 --- a/engine/filters.go +++ b/engine/filters.go @@ -516,11 +516,8 @@ func (fltr *FilterRule) passGreaterThan(dDP utils.DataProvider) (bool, error) { if fldStr, castStr := fldIf.(string); castStr { // attempt converting string since deserialization fails here (ie: time.Time fields) fldIf = utils.StringToInterface(fldStr) } - orEqual := false - if fltr.Type == utils.MetaGreaterOrEqual || - fltr.Type == utils.MetaLessThan { - orEqual = true - } + orEqual := fltr.Type == utils.MetaGreaterOrEqual || + fltr.Type == utils.MetaLessThan for _, val := range fltr.rsrValues { valPath, err := val.CompileDynRule(dDP) if err != nil { @@ -532,9 +529,9 @@ func (fltr *FilterRule) passGreaterThan(dDP utils.DataProvider) (bool, error) { } if gte, err := utils.GreaterThan(fldIf, sval, orEqual); err != nil { return false, err - } else if utils.SliceHasMember([]string{utils.MetaGreaterThan, utils.MetaGreaterOrEqual}, fltr.Type) && gte { + } else if (utils.MetaGreaterThan == fltr.Type || utils.MetaGreaterOrEqual == fltr.Type) && gte { return true, nil - } else if utils.SliceHasMember([]string{utils.MetaLessThan, utils.MetaLessOrEqual}, fltr.Type) && !gte { + } else if (utils.MetaLessThan == fltr.Type || utils.MetaLessOrEqual == fltr.Type) && !gte { return true, nil } }