Skip to content

Commit

Permalink
Trigger time based escalations
Browse files Browse the repository at this point in the history
  • Loading branch information
yhabteab committed May 26, 2023
1 parent 0030bfd commit 14f0014
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 62 deletions.
1 change: 1 addition & 0 deletions internal/event/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Event struct {
const (
TypeState = "state"
TypeAcknowledgement = "acknowledgement"
TypeInternal = "internal"
)

func (e *Event) String() string {
Expand Down
1 change: 1 addition & 0 deletions internal/filter/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ type Filterable interface {
// Filter is implemented by every filter chains and filter conditions.
type Filter interface {
Eval(filterable Filterable) (bool, error)
ExtractConditions() []Condition
}
16 changes: 8 additions & 8 deletions internal/filter/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,24 +257,24 @@ func (p *Parser) createCondition(column string, operator string, value string) (
switch operator {
case "=":
if strings.Contains(value, "*") {
return &Like{column: column, value: value}, nil
return &Like{Condition{Column: column, Value: value}}, nil
}

return &Equal{column: column, value: value}, nil
return &Equal{Condition{Column: column, Value: value}}, nil
case "!=":
if strings.Contains(value, "*") {
return &Unlike{column: column, value: value}, nil
return &Unlike{Condition{Column: column, Value: value}}, nil
}

return &UnEqual{column: column, value: value}, nil
return &UnEqual{Condition{Column: column, Value: value}}, nil
case ">":
return &GreaterThan{column: column, value: value}, nil
return &GreaterThan{Condition{Column: column, Value: value}}, nil
case ">=":
return &GreaterThanOrEqual{column: column, value: value}, nil
return &GreaterThanOrEqual{Condition{Column: column, Value: value}}, nil
case "<":
return &LessThan{column: column, value: value}, nil
return &LessThan{Condition{Column: column, Value: value}}, nil
case "<=":
return &LessThanOrEqual{column: column, value: value}, nil
return &LessThanOrEqual{Condition{Column: column, Value: value}}, nil
default:
return nil, fmt.Errorf("invalid operator %s provided", operator)
}
Expand Down
20 changes: 10 additions & 10 deletions internal/filter/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,12 @@ func TestFilter(t *testing.T) {

expected := &All{rules: []Filter{
&None{rules: []Filter{
&Equal{column: "foo", value: "bar"},
&Equal{column: "bar", value: "foo"},
&Equal{Condition{Column: "foo", Value: "bar"}},
&Equal{Condition{Column: "bar", Value: "foo"}},
}},
&Any{rules: []Filter{
&Equal{column: "foo", value: "bar"},
&Equal{column: "bar", value: "foo"},
&Equal{Condition{Column: "foo", Value: "bar"}},
&Equal{Condition{Column: "bar", Value: "foo"}},
}},
}}
assert.Equal(t, expected, rule)
Expand All @@ -133,30 +133,30 @@ func TestFilter(t *testing.T) {
rule, err := Parse("foo=bar")
assert.Nil(t, err, "There should be no errors but got: %s", err)

expected := &Equal{column: "foo", value: "bar"}
expected := &Equal{Condition{Column: "foo", Value: "bar"}}
assert.Equal(t, expected, rule, "Parser doesn't parse single condition correctly")
})

t.Run("UrlEncodedFilterExpression", func(t *testing.T) {
rule, err := Parse("col%3Cumn<val%3Cue")
assert.Nil(t, err, "There should be no errors but got: %s", err)
assert.Equal(t, &LessThan{column: "col<umn", value: "val<ue"}, rule)
assert.Equal(t, &LessThan{Condition{Column: "col<umn", Value: "val<ue"}}, rule)

rule, err = Parse("col%7Cumn=val%7Cue")
assert.Nil(t, err, "There should be no errors but got: %s", err)
assert.Equal(t, &Equal{column: "col|umn", value: "val|ue"}, rule)
assert.Equal(t, &Equal{Condition{Column: "col|umn", Value: "val|ue"}}, rule)

rule, err = Parse("col%26umn<=val%26ue")
assert.Nil(t, err, "There should be no errors but got: %s", err)
assert.Equal(t, &LessThanOrEqual{column: "col&umn", value: "val&ue"}, rule)
assert.Equal(t, &LessThanOrEqual{Condition{Column: "col&umn", Value: "val&ue"}}, rule)

rule, err = Parse("col%28umn>val%28ue")
assert.Nil(t, err, "There should be no errors but got: %s", err)
assert.Equal(t, &GreaterThan{column: "col(umn", value: "val(ue"}, rule)
assert.Equal(t, &GreaterThan{Condition{Column: "col(umn", Value: "val(ue"}}, rule)

rule, err = Parse("col%29umn>=val%29ue")
assert.Nil(t, err, "There should be no errors but got: %s", err)
assert.Equal(t, &GreaterThanOrEqual{column: "col)umn", value: "val)ue"}, rule)
assert.Equal(t, &GreaterThanOrEqual{Condition{Column: "col)umn", Value: "val)ue"}}, rule)
})
}

Expand Down
102 changes: 73 additions & 29 deletions internal/filter/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ func (a *All) Eval(filterable Filterable) (bool, error) {
return true, nil
}

func (a *All) ExtractConditions() []Condition {
return extractConditions(a.rules)
}

// Any represents a filter chain type that matches when at least one of its Rules matches.
type Any struct {
rules []Filter
Expand All @@ -40,6 +44,10 @@ func (a *Any) Eval(filterable Filterable) (bool, error) {
return false, nil
}

func (a *Any) ExtractConditions() []Condition {
return extractConditions(a.rules)
}

// None represents a filter chain type that matches when none of its Rules matches.
type None struct {
rules []Filter
Expand All @@ -60,115 +68,151 @@ func (n *None) Eval(filterable Filterable) (bool, error) {
return true, nil
}

func (n *None) ExtractConditions() []Condition {
return extractConditions(n.rules)
}

// Condition represents a single filter condition.
type Condition struct {
column string
value string
Column string
Value string
}

func NewCondition(column string, value string) *Condition {
return &Condition{
column: column,
value: value,
func NewCondition(column string, value string) Condition {
return Condition{
Column: column,
Value: value,
}
}

type Exists Condition
func (e Condition) ExtractConditions() []Condition {
return []Condition{e}
}

type Exists struct {
Condition
}

func NewExists(column string) *Exists {
return &Exists{column: column}
return &Exists{Condition{Column: column}}
}

func (e *Exists) Eval(filterable Filterable) (bool, error) {
return filterable.EvalExists(e.column), nil
return filterable.EvalExists(e.Column), nil
}

type Equal Condition
type Equal struct {
Condition
}

func (e *Equal) Eval(filterable Filterable) (bool, error) {
match, err := filterable.EvalEqual(e.column, e.value)
match, err := filterable.EvalEqual(e.Column, e.Value)
if err != nil {
return false, err
}

return match, nil
}

type UnEqual Condition
type UnEqual struct {
Condition
}

func (u *UnEqual) Eval(filterable Filterable) (bool, error) {
match, err := filterable.EvalEqual(u.column, u.value)
match, err := filterable.EvalEqual(u.Column, u.Value)
if err != nil {
return false, err
}

return filterable.EvalExists(u.column) && !match, nil
return filterable.EvalExists(u.Column) && !match, nil
}

type Like Condition
type Like struct {
Condition
}

func (l *Like) Eval(filterable Filterable) (bool, error) {
match, err := filterable.EvalLike(l.column, l.value)
match, err := filterable.EvalLike(l.Column, l.Value)
if err != nil {
return false, err
}

return match, nil
}

type Unlike Condition
type Unlike struct {
Condition
}

func (u *Unlike) Eval(filterable Filterable) (bool, error) {
match, err := filterable.EvalLike(u.column, u.value)
match, err := filterable.EvalLike(u.Column, u.Value)
if err != nil {
return false, err
}

return filterable.EvalExists(u.column) && !match, nil
return filterable.EvalExists(u.Column) && !match, nil
}

type LessThan Condition
type LessThan struct {
Condition
}

func (less *LessThan) Eval(filterable Filterable) (bool, error) {
match, err := filterable.EvalLess(less.column, less.value)
match, err := filterable.EvalLess(less.Column, less.Value)
if err != nil {
return false, err
}

return match, nil
}

type LessThanOrEqual Condition
type LessThanOrEqual struct {
Condition
}

func (loe *LessThanOrEqual) Eval(filterable Filterable) (bool, error) {
match, err := filterable.EvalLessOrEqual(loe.column, loe.value)
match, err := filterable.EvalLessOrEqual(loe.Column, loe.Value)
if err != nil {
return false, err
}

return match, nil
}

type GreaterThan Condition
type GreaterThan struct {
Condition
}

func (g *GreaterThan) Eval(filterable Filterable) (bool, error) {
match, err := filterable.EvalLessOrEqual(g.column, g.value)
match, err := filterable.EvalLessOrEqual(g.Column, g.Value)
if err != nil {
return false, err
}

return filterable.EvalExists(g.column) && !match, nil
return filterable.EvalExists(g.Column) && !match, nil
}

type GreaterThanOrEqual Condition
type GreaterThanOrEqual struct {
Condition
}

func (goe *GreaterThanOrEqual) Eval(filterable Filterable) (bool, error) {
match, err := filterable.EvalLess(goe.column, goe.value)
match, err := filterable.EvalLess(goe.Column, goe.Value)
if err != nil {
return false, err
}

return filterable.EvalExists(goe.column) && !match, nil
return filterable.EvalExists(goe.Column) && !match, nil
}

// extractConditions extracts filter conditions from the specified filter rules.
func extractConditions(rules []Filter) []Condition {
var conditions []Condition
for _, rule := range rules {
conditions = append(conditions, rule.ExtractConditions()...)
}

return conditions
}

var (
Expand Down
Loading

0 comments on commit 14f0014

Please sign in to comment.