From b2764ddf224430d016e0bd2ec5904ef3217c8034 Mon Sep 17 00:00:00 2001 From: DanB Date: Sat, 21 Jul 2018 09:51:20 +0200 Subject: [PATCH] Completing methods for RSRParser with ParseValue and ParseEvent --- utils/rsrfield.go | 16 +++--- utils/rsrparser.go | 114 +++++++++++++++++++++++++++++++++------- utils/rsrparser_test.go | 16 +++++- 3 files changed, 119 insertions(+), 27 deletions(-) diff --git a/utils/rsrfield.go b/utils/rsrfield.go index 044266f26..aaf2a557b 100644 --- a/utils/rsrfield.go +++ b/utils/rsrfield.go @@ -282,19 +282,21 @@ func ParseRSRFiltersFromSlice(fltrStrs []string) (RSRFilters, error) { type RSRFilters []*RSRFilter // @all: specifies whether all filters should match or at least one -func (fltrs RSRFilters) Pass(val string, allMustMatch bool) bool { +func (fltrs RSRFilters) Pass(val string, allMustMatch bool) (matched bool) { if len(fltrs) == 0 { return true } - var matched bool for _, fltr := range fltrs { - if fltr.Pass(val) { - matched = true - } else if allMustMatch { - return false + matched = fltr.Pass(val) + if allMustMatch { + if !matched { + return + } + } else if matched { + return } } - return matched + return } func ParseRSRFieldsFromSlice(flds []string) (RSRFields, error) { diff --git a/utils/rsrparser.go b/utils/rsrparser.go index c1c93104d..77a873fc2 100644 --- a/utils/rsrparser.go +++ b/utils/rsrparser.go @@ -24,7 +24,63 @@ import ( "strings" ) -func NewRSRParser(parserRules string) (rsrParser *RSRParser, err error) { +func NewRSRParsers(parsersRules string, allFiltersMatch bool) (prsrs RSRParsers, err error) { + if parsersRules == "" { + return + } + return NewRSRParsersFromSlice(strings.Split(parsersRules, INFIELD_SEP), allFiltersMatch) +} + +func NewRSRParsersFromSlice(parsersRules []string, allFiltersMatch bool) (prsrs RSRParsers, err error) { + prsrs = make(RSRParsers, len(parsersRules)) + for i, rlStr := range parsersRules { + if rsrPrsr, err := NewRSRParser(rlStr, allFiltersMatch); err != nil { + return nil, err + } else if rsrPrsr == nil { + return nil, fmt.Errorf("emtpy RSRParser in rule: <%s>", rlStr) + } else { + prsrs[i] = rsrPrsr + } + } + return +} + +func NewRSRParsersMustCompile(parsersRules string, allFiltersMatch bool) (prsrs RSRParsers) { + var err error + if prsrs, err = NewRSRParsers(parsersRules, allFiltersMatch); err != nil { + panic(fmt.Sprintf("rule: <%s>, error: %s", parsersRules, err.Error())) + } + return +} + +// RSRParsers is a set of RSRParser +type RSRParsers []*RSRParser + +// ParseValue will parse the value out considering converters and filters +func (prsrs RSRParsers) ParseValue(value interface{}) (out string, err error) { + for _, prsr := range prsrs { + if outPrsr, err := prsr.ParseValue(value); err != nil { + return "", err + } else { + out += outPrsr + } + } + return +} + +// ParseEvent will parse the event values into one output +func (prsrs RSRParsers) ParseEvent(ev map[string]interface{}) (out string, err error) { + for _, prsr := range prsrs { + if outPrsr, err := prsr.ParseEvent(ev); err != nil { + return "", err + } else { + out += outPrsr + } + } + return +} + +func NewRSRParser(parserRules string, allFiltersMatch bool) (rsrParser *RSRParser, err error) { if len(parserRules) == 0 { return } @@ -98,9 +154,18 @@ func NewRSRParser(parserRules string) (rsrParser *RSRParser, err error) { return } +func NewRSRParserMustCompile(parserRules string, allFiltersMatch bool) (rsrPrsr *RSRParser) { + var err error + if rsrPrsr, err = NewRSRParser(parserRules, allFiltersMatch); err != nil { + panic(fmt.Sprintf("compiling rules: <%s>, error: %s", parserRules, err.Error())) + } + return +} + // RSRParser is a parser for data coming from various sources type RSRParser struct { - Rules string // Rules container holding the string rules, public so it can be stored + Rules string // Rules container holding the string rules, public so it can be stored + AllFiltersMatch bool // all filters must match policy attrName string // instruct extracting info out of header in event attrValue string // if populated, enforces parsing always to this value @@ -112,7 +177,7 @@ type RSRParser struct { // Compile parses Rules string and repopulates other fields func (prsr *RSRParser) Compile() (err error) { var newPrsr *RSRParser - if newPrsr, err = NewRSRParser(prsr.Rules); err != nil { + if newPrsr, err = NewRSRParser(prsr.Rules, prsr.AllFiltersMatch); err != nil { return } *prsr = *newPrsr @@ -129,26 +194,37 @@ func (prsr *RSRParser) RegexpMatched() bool { return false } -func NewRSRParsers(parsersRules string) (prsrs RSRParsers, err error) { - if parsersRules == "" { - return +// parseValue the field value from a string +func (prsr *RSRParser) parseValue(value string) string { + if prsr.attrValue != "" { // Enforce parsing of static values + return prsr.attrValue } - return NewRSRParsersFromSlice(strings.Split(parsersRules, INFIELD_SEP)) + for _, rsRule := range prsr.rsrRules { + value = rsRule.Process(value) + } + return value } -func NewRSRParsersFromSlice(parsersRules []string) (prsrs RSRParsers, err error) { - prsrs = make(RSRParsers, len(parsersRules)) - for i, rlStr := range parsersRules { - if rsrPrsr, err := NewRSRParser(rlStr); err != nil { - return nil, err - } else if rsrPrsr == nil { - return nil, fmt.Errorf("emtpy RSRParser in rule: <%s>", rlStr) - } else { - prsrs[i] = rsrPrsr - } +// ParseValue will parse the value out considering converters and filters +func (prsr *RSRParser) ParseValue(value interface{}) (out string, err error) { + if out, err = IfaceAsString(value); err != nil { + return + } + out = prsr.parseValue(out) + if out, err = prsr.converters.ConvertString(out); err != nil { + return + } + if !prsr.filters.Pass(out, prsr.AllFiltersMatch) { + return "", ErrFilterNotPassingNoCaps } return } -// RSRParsers is a set of RSRParser -type RSRParsers []*RSRParser +// ParseEvent will parse the value out considering converters and filters +func (prsr *RSRParser) ParseEvent(ev map[string]interface{}) (out string, err error) { + val, has := ev[prsr.attrName] + if !has && prsr.attrValue == "" { + return "", ErrNotFound + } + return prsr.ParseValue(val) +} diff --git a/utils/rsrparser_test.go b/utils/rsrparser_test.go index a9a7df710..aea0eadee 100644 --- a/utils/rsrparser_test.go +++ b/utils/rsrparser_test.go @@ -48,7 +48,7 @@ func TestNewRSRParsers(t *testing.T) { NewDataConverterMustCompile("*round:2")}, }, } - if rsrParsers, err := NewRSRParsers(ruleStr); err != nil { + if rsrParsers, err := NewRSRParsers(ruleStr, true); err != nil { t.Error("Unexpected error: ", err.Error()) } else if !reflect.DeepEqual(eRSRParsers, rsrParsers) { t.Errorf("expecting: %+v, received: %+v", eRSRParsers, rsrParsers) @@ -77,3 +77,17 @@ func TestRSRParserCompile(t *testing.T) { t.Errorf("expecting: %+v, received: %+v", ePrsr, prsr) } } + +func TestRSRParsersParseEvent(t *testing.T) { + prsrs := NewRSRParsersMustCompile("~Header1;|;~Header2", true) + ev := map[string]interface{}{ + "Header1": "Value1", + "Header2": "Value2", + } + eOut := "Value1|Value2" + if out, err := prsrs.ParseEvent(ev); err != nil { + t.Error(err) + } else if eOut != out { + t.Errorf("expecting: %s, received: %s", eOut, out) + } +}