Skip to content

Instantly share code, notes, and snippets.

@d33d33
Created April 18, 2017 16:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save d33d33/5bde33770baf718446130e783ddc6efe to your computer and use it in GitHub Desktop.
Save d33d33/5bde33770baf718446130e783ddc6efe to your computer and use it in GitHub Desktop.
// Time
rnow := false
now := time.Now().UnixNano() / 1000
// Get NOW header
nowh := req.Header.Get("X-Warp10-Now")
if nowh == "*" {
rnow = true
} else if strings.HasPrefix(nowh, "+") || strings.HasPrefix(nowh, "-") {
delta, err := strconv.ParseInt(nowh, 10, 64)
if err != nil {
code = http.StatusUnprocessableEntity
msg = "Invalid base timestamp."
log.WithFields(log.Fields{
"ip": req.Header.Get("X-Forwarded-For"),
"data": "X-Warp10-Now: " + nowh,
"err": err.Error(),
}).Warn("Invalid base timestamp")
c.errCounter.Inc()
return
}
now += delta
}
// handle request
scan := bufio.NewScanner(reader)
var dp *core.GTS
for scan.Scan() {
metric := strings.TrimSpace(scan.Text())
str := metric
if strings.HasPrefix(str, "#") {
continue
}
if str == "" {
continue
}
// https://github.com/cityzendata/warp10-platform/blob/master/warp10/src/main/java/io/warp10/continuum/gts/GTSHelper.java#L1733
idx := 0
tsoffset := 0
if str[0] == '=' {
if dp == nil {
code = http.StatusUnprocessableEntity
msg = "Invalid continuation at \"" + metric + "\""
log.WithFields(log.Fields{
"ip": req.Header.Get("X-Forwarded-For"),
"data": metric,
"err": err.Error(),
}).Warn("Invalid continuation")
c.errCounter.Inc()
return
}
tsoffset = 1
}
idx = strings.Index(str, "/")
if -1 == idx {
code = http.StatusUnprocessableEntity
msg = "Missing timestamp separator at \"" + metric + "\""
log.WithFields(log.Fields{
"ip": req.Header.Get("X-Forwarded-For"),
"data": metric,
"err": err.Error(),
}).Warn("Missing timestamp separator")
c.errCounter.Inc()
return
}
timestamp := int64(0)
if tsoffset == idx {
// No timestamp provided, use 'now'
if !rnow {
timestamp = now
} else {
timestamp = time.Now().UnixNano() / 1000
}
} else {
if 'T' == str[tsoffset] {
// Support T-XXX to record timestamps which are relative to 'now', useful for
// devices with no time reference but only relative timestamps
if !rnow {
timestamp = now
} else {
timestamp = time.Now().UnixNano() / 1000
}
delta, err := strconv.ParseInt(str[tsoffset+1:idx], 10, 64)
if err != nil {
code = http.StatusUnprocessableEntity
msg = "Invalid timestamp at \"" + metric + "\""
log.WithFields(log.Fields{
"ip": req.Header.Get("X-Forwarded-For"),
"data": metric,
"err": err.Error(),
}).Warn("Invalid timestamp")
c.errCounter.Inc()
return
}
timestamp += delta
} else {
t, err := strconv.ParseInt(str[tsoffset:idx], 10, 64)
if err != nil {
code = http.StatusUnprocessableEntity
msg = "Invalid timestamp at \"" + metric + "\""
log.WithFields(log.Fields{
"ip": req.Header.Get("X-Forwarded-For"),
"data": metric,
"err": err.Error(),
}).Warn("Invalid timestamp")
c.errCounter.Inc()
return
}
timestamp = t
}
}
// Advance past the '/'
idx++
str = str[idx:len(str)]
idx2 := strings.Index(str, "/")
if -1 == idx2 {
code = http.StatusUnprocessableEntity
msg = "Missing location/elevation separator at \"" + metric + "\""
log.WithFields(log.Fields{
"ip": req.Header.Get("X-Forwarded-For"),
"data": metric,
"err": err.Error(),
}).Warn("Missing location/elevation separator")
c.errCounter.Inc()
return
}
if idx2 == 0 {
// We have a location (lat:lon)
}
// TO BE CONTINUED
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment