func (cs *CypherStreamer) Scan(vs ...interface{}) error { if err := consumeExpectedToken(cs.decoder, json.Delim('[')); err != nil { return err } for _, v := range vs { if err := cs.decoder.Decode(v); err != nil { return err } } if err := consumeExpectedToken(cs.decoder, json.Delim(']')); err != nil { return err } return nil }
// paranoidUnmarshalJSONObject unmarshals data as a JSON object, but failing on the slightest unexpected aspect // (including duplicated keys, unrecognized keys, and non-matching types). Uses fieldResolver to // determine the destination for a field value, which should return a pointer to the destination if valid, or nil if the key is rejected. // // The fieldResolver approach is useful for decoding the Policy.Specific map; using it for structs is a bit lazy, // we could use reflection to automate this. Later? func paranoidUnmarshalJSONObject(data []byte, fieldResolver func(string) interface{}) error { seenKeys := map[string]struct{}{} dec := json.NewDecoder(bytes.NewReader(data)) t, err := dec.Token() if err != nil { return jsonFormatError(err.Error()) } if t != json.Delim('{') { return jsonFormatError(fmt.Sprintf("JSON object expected, got \"%s\"", t)) } for { t, err := dec.Token() if err != nil { return jsonFormatError(err.Error()) } if t == json.Delim('}') { break } key, ok := t.(string) if !ok { // Coverage: This should never happen, dec.Token() rejects non-string-literals in this state. return jsonFormatError(fmt.Sprintf("Key string literal expected, got \"%s\"", t)) } if _, ok := seenKeys[key]; ok { return jsonFormatError(fmt.Sprintf("Duplicate key \"%s\"", key)) } seenKeys[key] = struct{}{} valuePtr := fieldResolver(key) if valuePtr == nil { return jsonFormatError(fmt.Sprintf("Unknown key \"%s\"", key)) } // This works like json.Unmarshal, in particular it allows us to implement UnmarshalJSON to implement strict parsing of the field value. if err := dec.Decode(valuePtr); err != nil { return jsonFormatError(err.Error()) } } if _, err := dec.Token(); err != io.EOF { return jsonFormatError("Unexpected data after JSON object") } return nil }
func (pc *SocketClient) response(resp []byte) error { dec := json.NewDecoder(bytes.NewReader(resp)) t, err := dec.Token() if err != nil { return err } if t != json.Delim('[') { return errors.New("line not starting with [") } var reqidf float64 if !dec.More() { return errors.New("response abruptly before request id") } err = dec.Decode(&reqidf) if err != nil { return err } reqid := int64(reqidf) if !dec.More() { return errors.New("response abruptly before error object") } var resErr interface{} err = dec.Decode(&resErr) if err != nil { return err } if !dec.More() { return errors.New("response abruptly before result object") } pc.changes.Lock() defer pc.changes.Unlock() request, ok := pc.queue[reqid] if !ok { return errors.New("Unknown request id " + strconv.FormatInt(reqid, 10)) } defer delete(pc.queue, reqid) if resErr == nil { err = dec.Decode(request.result) request.responseChan <- err return err } request.responseChan <- &SocketRemoteError{resErr} return nil }
// Token is equivalent to the Token() method on json.Decoder. The primary difference is that it distinguishes // between strings that are keys and and strings that are values. String tokens that are object keys are returned as the // KeyString type rather than as a bare string type. func (d *Decoder) Token() (json.Token, error) { t, err := d.Decoder.Token() if err != nil { return t, err } if t == nil { switch d.context { case objValue: d.context = objKey break case arrValue: d.path.incTop() break } return t, err } switch t := t.(type) { case json.Delim: switch t { case json.Delim('{'): if d.context == arrValue { d.path.incTop() } d.path.push("") d.context = objKey break case json.Delim('}'): d.path.pop() d.context = d.path.inferContext() break case json.Delim('['): if d.context == arrValue { d.path.incTop() } d.path.push(-1) d.context = arrValue break case json.Delim(']'): d.path.pop() d.context = d.path.inferContext() break } case float64, json.Number, bool: switch d.context { case objValue: d.context = objKey break case arrValue: d.path.incTop() break } break case string: switch d.context { case objKey: d.path.nameTop(t) d.context = objValue return KeyString(t), err case objValue: d.context = objKey case arrValue: d.path.incTop() } break } return t, err }
// Gathers data from a particular URL // Parameters: // acc : The telegraf Accumulator to use // url : endpoint to send request to // // Returns: // error: Any error that may have occurred func (i *InfluxDB) gatherURL( acc telegraf.Accumulator, url string, ) error { shardCounter := 0 now := time.Now() resp, err := i.client.Get(url) if err != nil { return err } defer resp.Body.Close() // It would be nice to be able to decode into a map[string]point, but // we'll get a decoder error like: // `json: cannot unmarshal array into Go value of type influxdb.point` // if any of the values aren't objects. // To avoid that error, we decode by hand. dec := json.NewDecoder(resp.Body) // Parse beginning of object if t, err := dec.Token(); err != nil { return err } else if t != json.Delim('{') { return errors.New("document root must be a JSON object") } // Loop through rest of object for { // Nothing left in this object, we're done if !dec.More() { break } // Read in a string key. We don't do anything with the top-level keys, // so it's discarded. key, err := dec.Token() if err != nil { return err } if keyStr, ok := key.(string); ok { if keyStr == "memstats" { var m memstats if err := dec.Decode(&m); err != nil { continue } acc.AddFields("influxdb_memstats", map[string]interface{}{ "alloc": m.Alloc, "total_alloc": m.TotalAlloc, "sys": m.Sys, "lookups": m.Lookups, "mallocs": m.Mallocs, "frees": m.Frees, "heap_alloc": m.HeapAlloc, "heap_sys": m.HeapSys, "heap_idle": m.HeapIdle, "heap_inuse": m.HeapInuse, "heap_released": m.HeapReleased, "heap_objects": m.HeapObjects, "stack_inuse": m.StackInuse, "stack_sys": m.StackSys, "mspan_inuse": m.MSpanInuse, "mspan_sys": m.MSpanSys, "mcache_inuse": m.MCacheInuse, "mcache_sys": m.MCacheSys, "buck_hash_sys": m.BuckHashSys, "gc_sys": m.GCSys, "other_sys": m.OtherSys, "next_gc": m.NextGC, "last_gc": m.LastGC, "pause_total_ns": m.PauseTotalNs, "num_gc": m.NumGC, "gcc_pu_fraction": m.GCCPUFraction, }, map[string]string{ "url": url, }) } } // Attempt to parse a whole object into a point. // It might be a non-object, like a string or array. // If we fail to decode it into a point, ignore it and move on. var p point if err := dec.Decode(&p); err != nil { continue } if p.Tags == nil { p.Tags = make(map[string]string) } // If the object was a point, but was not fully initialized, // ignore it and move on. if p.Name == "" || p.Values == nil || len(p.Values) == 0 { continue } if p.Name == "shard" { shardCounter++ } // Add a tag to indicate the source of the data. p.Tags["url"] = url acc.AddFields( "influxdb_"+p.Name, p.Values, p.Tags, now, ) } acc.AddFields("influxdb", map[string]interface{}{ "n_shards": shardCounter, }, nil, now, ) return nil }
// Pairs is a set of key-value pairs. type mapPairs []*Pair func (m mapPairs) MarshalJSON() ([]byte, error) { aux := make(map[string]json.Token, len(m)) for _, p := range m { aux[p.Key] = p.Value } return json.Marshal(aux) } // JSON delimiters. var ( lbrace = json.Delim('{') rbrace = json.Delim('}') lsquare = json.Delim('[') rsquare = json.Delim(']') pathd = "." ) // parseJSON decodes a JSON-encoded value into a set of pairs. func parseJSON(r io.Reader) ([]*Pair, error) { var ( // Current token. tok json.Token // Current converted key-value Pair. key string
package converter import ( "encoding/csv" "encoding/json" "fmt" cx "github.com/cyService/cxtool/cx" "io" "strconv" ) const ( arrayStart = json.Delim('[') ) type Cx2Sif struct { } func (cx2sif Cx2Sif) Convert(r io.Reader, w io.Writer) { cxDecoder := json.NewDecoder(r) csvWriter := csv.NewWriter(w) csvWriter.Comma = ' ' parseSif(cxDecoder, csvWriter) } func parseSif(cxDecoder *json.Decoder, w *csv.Writer) { // Edge slice used for later mapping var edges []cx.Edge
// Gathers data from a particular URL // Parameters: // acc : The telegraf Accumulator to use // url : endpoint to send request to // // Returns: // error: Any error that may have occurred func (i *InfluxDB) gatherURL( acc inputs.Accumulator, url string, ) error { resp, err := http.Get(url) if err != nil { return err } defer resp.Body.Close() // It would be nice to be able to decode into a map[string]point, but // we'll get a decoder error like: // `json: cannot unmarshal array into Go value of type influxdb.point` // if any of the values aren't objects. // To avoid that error, we decode by hand. dec := json.NewDecoder(resp.Body) // Parse beginning of object if t, err := dec.Token(); err != nil { return err } else if t != json.Delim('{') { return errors.New("document root must be a JSON object") } // Loop through rest of object for { // Nothing left in this object, we're done if !dec.More() { break } // Read in a string key. We don't do anything with the top-level keys, so it's discarded. _, err := dec.Token() if err != nil { return err } // Attempt to parse a whole object into a point. // It might be a non-object, like a string or array. // If we fail to decode it into a point, ignore it and move on. var p point if err := dec.Decode(&p); err != nil { continue } // If the object was a point, but was not fully initialized, ignore it and move on. if p.Name == "" || p.Tags == nil || p.Values == nil || len(p.Values) == 0 { continue } // Add a tag to indicate the source of the data. p.Tags["url"] = url acc.AddFields( "influxdb_"+p.Name, p.Values, p.Tags, ) } return nil }
func (db *Database) StreamCypher(q *CypherQuery) (*CypherStreamer, error) { payload := cypherRequest{ Query: q.Statement, Parameters: q.Parameters, } payloadBytes, err := json.Marshal(payload) if err != nil { return nil, err } req, err := http.NewRequest( "POST", db.HrefCypher, bytes.NewReader(payloadBytes), ) if err != nil { return nil, err } req.Header.Set("Content-Type", "application/json") req.Header.Set("X-Stream", "true") if db.Session.Userinfo != nil { username := db.Session.Userinfo.Username() password, _ := db.Session.Userinfo.Password() req.SetBasicAuth(username, password) } res, err := http.DefaultClient.Do(req) if err != nil { return nil, err } else if res.StatusCode != 200 { return nil, fmt.Errorf("Status %q", res.Status) } decoder := json.NewDecoder(res.Body) if err := consumeExpectedToken(decoder, json.Delim('{')); err != nil { return nil, err } if err := consumeExpectedToken(decoder, "columns"); err != nil { return nil, err } var columns []string if err = decoder.Decode(&columns); err != nil { return nil, err } if err := consumeExpectedToken(decoder, "data"); err != nil { return nil, err } if err := consumeExpectedToken(decoder, json.Delim('[')); err != nil { return nil, err } return &CypherStreamer{ Columns: columns, body: res.Body, decoder: decoder, }, nil }