Beispiel #1
0
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
}
Beispiel #2
0
// 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
}
Beispiel #4
0
// 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
}
Beispiel #5
0
// 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
}
Beispiel #6
0
// 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
Beispiel #7
0
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
Beispiel #8
0
// 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
}
Beispiel #9
0
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
}