added command filter for geofences

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
This commit is contained in:
Josh Baker 2016-12-15 10:00:08 -07:00
parent b6c645791f
commit 6c52f3f3f1
2 changed files with 42 additions and 2 deletions

View File

@ -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"
@ -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 != "*" {
@ -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:]

View File

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