Skip to content

Commit

Permalink
added command filter for geofences
Browse files Browse the repository at this point in the history
It's now possible to mask the fence notifications based on the
command. For example, if we only want "set" and "del" commands.

NEARBY fleet FENCE COMMANDS set,del POINT 33 -115 10000

Suggested by @amorskoy, closes #99
  • Loading branch information
tidwall committed Dec 15, 2016
1 parent b6c6457 commit 6c52f3f
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
19 changes: 17 additions & 2 deletions controller/fence.go
Expand Up @@ -5,6 +5,7 @@ import (
"strconv"
"strings"

"github.com/tidwall/gjson"
"github.com/tidwall/tile38/controller/glob"
"github.com/tidwall/tile38/controller/server"
"github.com/tidwall/tile38/geojson"
Expand All @@ -14,11 +15,25 @@ var tmfmt = "2006-01-02T15:04:05.999999999Z07:00"

// FenceMatch executes a fence match returns back json messages for fence detection.
func FenceMatch(hookName string, sw *scanWriter, fence *liveFenceSwitches, details *commandDetailsT) []string {
msgs := fenceMatch(hookName, sw, fence, details)
if len(fence.accept) == 0 {
return msgs
}
nmsgs := make([]string, 0, len(msgs))
for _, msg := range msgs {
if fence.accept[gjson.Get(msg, "command").String()] {
nmsgs = append(nmsgs, msg)
}
}
return nmsgs
}

func fenceMatch(hookName string, sw *scanWriter, fence *liveFenceSwitches, details *commandDetailsT) []string {
jshookName := jsonString(hookName)
jstime := jsonString(details.timestamp.Format(tmfmt))
pattern := fence.glob
if details.command == "drop" {
return []string{`{"cmd":"drop","hook":` + jshookName + `,"time":` + jstime + `}`}
return []string{`{"command":"drop","hook":` + jshookName + `,"time":` + jstime + `}`}
}
match := true
if pattern != "" && pattern != "*" {
Expand Down Expand Up @@ -150,7 +165,7 @@ func FenceMatch(hookName string, sw *scanWriter, fence *liveFenceSwitches, detai
jskey := jsonString(details.key)

ores := res
msgs := make([]string, 0, 2)
msgs := make([]string, 0, 4)
if fence.detect == nil || fence.detect[detect] {
if strings.HasPrefix(ores, "{") {
res = `{"command":"` + details.command + `","group":"` + group + `","detect":"` + detect + `","hook":` + jshookName + `,"key":` + jskey + `,"time":` + jstime + `,` + ores[1:]
Expand Down
25 changes: 25 additions & 0 deletions controller/token.go
Expand Up @@ -164,6 +164,7 @@ type searchScanBaseTokens struct {
lineout string
fence bool
detect map[string]bool
accept map[string]bool
glob string
wheres []whereT
nofields bool
Expand Down Expand Up @@ -279,6 +280,30 @@ func parseSearchScanBaseTokens(cmd string, vs []resp.Value) (vsout []resp.Value,
}
t.fence = true
continue
} else if (wtok[0] == 'C' || wtok[0] == 'c') && strings.ToLower(wtok) == "commands" {
vs = nvs
if t.accept != nil {
err = errDuplicateArgument(strings.ToUpper(wtok))
return
}
t.accept = make(map[string]bool)
var peek string
if vs, peek, ok = tokenval(vs); !ok || peek == "" {
err = errInvalidNumberOfArguments
return
}
for _, s := range strings.Split(peek, ",") {
part := strings.TrimSpace(strings.ToLower(s))
if t.accept[part] {
err = errDuplicateArgument(s)
return
}
t.accept[part] = true
}
if len(t.accept) == 0 {
t.accept = nil
}
continue
} else if (wtok[0] == 'D' || wtok[0] == 'd') && strings.ToLower(wtok) == "detect" {
vs = nvs
if t.detect != nil {
Expand Down

0 comments on commit 6c52f3f

Please sign in to comment.