Created
April 18, 2017 16:32
-
-
Save d33d33/5bde33770baf718446130e783ddc6efe to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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