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" "strconv"
"strings" "strings"
"github.com/tidwall/gjson"
"github.com/tidwall/tile38/controller/glob" "github.com/tidwall/tile38/controller/glob"
"github.com/tidwall/tile38/controller/server" "github.com/tidwall/tile38/controller/server"
"github.com/tidwall/tile38/geojson" "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. // FenceMatch executes a fence match returns back json messages for fence detection.
func FenceMatch(hookName string, sw *scanWriter, fence *liveFenceSwitches, details *commandDetailsT) []string { 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) jshookName := jsonString(hookName)
jstime := jsonString(details.timestamp.Format(tmfmt)) jstime := jsonString(details.timestamp.Format(tmfmt))
pattern := fence.glob pattern := fence.glob
if details.command == "drop" { if details.command == "drop" {
return []string{`{"cmd":"drop","hook":` + jshookName + `,"time":` + jstime + `}`} return []string{`{"command":"drop","hook":` + jshookName + `,"time":` + jstime + `}`}
} }
match := true match := true
if pattern != "" && pattern != "*" { if pattern != "" && pattern != "*" {
@ -150,7 +165,7 @@ func FenceMatch(hookName string, sw *scanWriter, fence *liveFenceSwitches, detai
jskey := jsonString(details.key) jskey := jsonString(details.key)
ores := res ores := res
msgs := make([]string, 0, 2) msgs := make([]string, 0, 4)
if fence.detect == nil || fence.detect[detect] { if fence.detect == nil || fence.detect[detect] {
if strings.HasPrefix(ores, "{") { if strings.HasPrefix(ores, "{") {
res = `{"command":"` + details.command + `","group":"` + group + `","detect":"` + detect + `","hook":` + jshookName + `,"key":` + jskey + `,"time":` + jstime + `,` + ores[1:] 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 lineout string
fence bool fence bool
detect map[string]bool detect map[string]bool
accept map[string]bool
glob string glob string
wheres []whereT wheres []whereT
nofields bool nofields bool
@ -279,6 +280,30 @@ func parseSearchScanBaseTokens(cmd string, vs []resp.Value) (vsout []resp.Value,
} }
t.fence = true t.fence = true
continue 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" { } else if (wtok[0] == 'D' || wtok[0] == 'd') && strings.ToLower(wtok) == "detect" {
vs = nvs vs = nvs
if t.detect != nil { if t.detect != nil {