Completing methods for RSRParser with ParseValue and ParseEvent

This commit is contained in:
DanB
2018-07-21 09:51:20 +02:00
parent 6a45fb0fc6
commit b2764ddf22
3 changed files with 119 additions and 27 deletions

View File

@@ -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) {

View File

@@ -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)
}

View File

@@ -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)
}
}