Working dynamic json Unmarshaling

pull/4934/head
Tim Raymond 2017-06-07 11:16:09 -04:00
parent c5872bba41
commit 6a672cfd94
2 changed files with 48 additions and 20 deletions

View File

@ -1,6 +1,7 @@
package chronograf
import (
"bytes"
"context"
"encoding/json"
"errors"
@ -171,10 +172,10 @@ func (t BasicTemplateVar) String() string {
}
type GroupByVar struct {
Var string // the name of the variable as present in the query
Duration time.Duration // the Duration supplied by the query
Resolution uint // the available screen resolution to render the results of this query
ReportingInterval time.Duration // the interval at which data is reported to this series
Var string `json:"tempVar"` // the name of the variable as present in the query
Duration time.Duration `json:"duration"` // the Duration supplied by the query
Resolution uint `json:"resolution"` // the available screen resolution to render the results of this query
ReportingInterval time.Duration `json:"reportingInterval"` // the interval at which data is reported to this series
}
func (g *GroupByVar) String() string {
@ -218,26 +219,48 @@ type Query struct {
type TemplateVars []TemplateVariable
func (t *TemplateVars) UnmarshalJSON(text []byte) error {
var rawVars []interface{}
err := json.Unmarshal(text, &rawVars)
rawVars := bytes.NewReader(text)
dec := json.NewDecoder(rawVars)
// read open bracket
rawTok, err := dec.Token()
if err != nil {
return err
}
for _, rawVar := range rawVars {
halfBakedVar, ok := rawVar.(map[string]interface{})
if !ok {
return errors.New("error decoding template variables. Expected a map")
tok, isDelim := rawTok.(json.Delim)
if !isDelim || tok != '[' {
return errors.New("Expected JSON array, but found " + tok.String())
}
for dec.More() {
var halfBakedVar json.RawMessage
err := dec.Decode(&halfBakedVar)
if err != nil {
return err
}
switch halfBakedVar["tempVar"] {
case "autoGroupBy":
(*t) = append(*t, &GroupByVar{
Duration: 180 * 24 * time.Hour,
Resolution: 1000,
ReportingInterval: 10 * time.Second,
})
default:
(*t) = append(*t, &BasicTemplateVar{})
var agb GroupByVar
err = json.Unmarshal(halfBakedVar, &agb)
if err != nil {
return err
}
// ensure that we really have a GroupByVar
if agb.Resolution != 0 {
(*t) = append(*t, &agb)
continue
}
var tvar BasicTemplateVar
err = json.Unmarshal(halfBakedVar, &tvar)
if err != nil {
return err
}
// ensure that we really have a BasicTemplateVar
if len(tvar.Values) != 0 {
(*t) = append(*t, tvar)
}
}
return nil

View File

@ -160,7 +160,8 @@ func Test_TemplateVarsUnmarshalling(t *testing.T) {
"values": [
{
"type": "tagValue",
"value": "cpu-total"
"value": "cpu-total",
"selected": false
}
]
}
@ -177,6 +178,10 @@ func Test_TemplateVarsUnmarshalling(t *testing.T) {
t.Fatal("Err unmarshaling:", err)
}
if len(tvars) != len(expected) {
t.Fatal("Expected", len(expected), "vars but found", len(tvars))
}
for idx, tvar := range tvars {
if actual := tvar.String(); expected[idx] != actual {
t.Error("Unexpected tvar. Want:", expected[idx], "Got:", actual)