You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by ne...@apache.org on 2017/01/13 23:36:11 UTC
[15/29] incubator-trafficcontrol git commit: Add vendor directory
with current dependencies
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/4563a049/traffic_stats/vendor/github.com/apache/incubator-trafficcontrol/traffic_ops/client/traffic_ops.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/apache/incubator-trafficcontrol/traffic_ops/client/traffic_ops.go b/traffic_stats/vendor/github.com/apache/incubator-trafficcontrol/traffic_ops/client/traffic_ops.go
new file mode 100644
index 0000000..15d8cc8
--- /dev/null
+++ b/traffic_stats/vendor/github.com/apache/incubator-trafficcontrol/traffic_ops/client/traffic_ops.go
@@ -0,0 +1,306 @@
+/*
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package client
+
+import (
+ "bytes"
+ "crypto/tls"
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "strings"
+ "time"
+
+ "github.com/juju/persistent-cookiejar"
+ "golang.org/x/net/publicsuffix"
+)
+
+// Session ...
+type Session struct {
+ UserName string
+ Password string
+ URL string
+ UserAgent *http.Client
+ Cache map[string]CacheEntry
+}
+
+// HTTPError is returned on Update Session failure.
+type HTTPError struct {
+ HTTPStatusCode int
+ HTTPStatus string
+ URL string
+}
+
+// Error implements the error interface for our customer error type.
+func (e *HTTPError) Error() string {
+ return fmt.Sprintf("%s[%d] - Error requesting Traffic Ops %s", e.HTTPStatus, e.HTTPStatusCode, e.URL)
+}
+
+// Result {"response":[{"level":"success","text":"Successfully logged in."}],"version":"1.1"}
+type Result struct {
+ Alerts []Alert
+ Version string `json:"version"`
+}
+
+// Alert ...
+type Alert struct {
+ Level string `json:"level"`
+ Text string `json:"text"`
+}
+
+// CacheEntry ...
+type CacheEntry struct {
+ Entered int64
+ Bytes []byte
+}
+
+// Credentials contains Traffic Ops login credentials
+type Credentials struct {
+ Username string `json:"u"`
+ Password string `json:"p"`
+}
+
+// TODO JvD
+const tmPollingInterval = 60
+
+// loginCreds gathers login credentials for Traffic Ops.
+func loginCreds(toUser string, toPasswd string) ([]byte, error) {
+ credentials := Credentials{
+ Username: toUser,
+ Password: toPasswd,
+ }
+
+ js, err := json.Marshal(credentials)
+ if err != nil {
+ err := fmt.Errorf("Error creating login json: %v", err)
+ return nil, err
+ }
+ return js, nil
+}
+
+func ResumeSession(toURL string, insecure bool) (*Session, error) {
+ options := cookiejar.Options{
+ PublicSuffixList: publicsuffix.List,
+ }
+
+ jar, err := cookiejar.New(&options)
+
+ if err != nil {
+ return nil, err
+ }
+
+ to := Session{
+ UserAgent: &http.Client{
+ Transport: &http.Transport{
+ TLSClientConfig: &tls.Config{InsecureSkipVerify: insecure},
+ },
+ Jar: jar,
+ },
+ URL: toURL,
+ Cache: make(map[string]CacheEntry),
+ }
+
+ resp, err := to.request("GET", "/api/1.2/user/current.json", nil)
+
+ if err != nil {
+ return nil, err
+ }
+
+ jar.Save()
+ fmt.Printf("Traffic Ops Session Resumed (%s)\n", resp.Status)
+
+ return &to, nil
+}
+
+// Login to traffic_ops, the response should set the cookie for this session
+// automatically. Start with
+// to := traffic_ops.Login("user", "passwd", true)
+// subsequent calls like to.GetData("datadeliveryservice") will be authenticated.
+func Login(toURL string, toUser string, toPasswd string, insecure bool) (*Session, error) {
+ credentials, err := loginCreds(toUser, toPasswd)
+ if err != nil {
+ return nil, err
+ }
+
+ options := cookiejar.Options{
+ PublicSuffixList: publicsuffix.List,
+ }
+
+ jar, err := cookiejar.New(&options)
+ if err != nil {
+ return nil, err
+ }
+
+ to := Session{
+ UserAgent: &http.Client{
+ Transport: &http.Transport{
+ TLSClientConfig: &tls.Config{InsecureSkipVerify: insecure},
+ },
+ Jar: jar,
+ },
+ URL: toURL,
+ UserName: toUser,
+ Password: toPasswd,
+ Cache: make(map[string]CacheEntry),
+ }
+
+ path := "/api/1.2/user/login"
+ resp, err := to.request("POST", path, credentials)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result Result
+ if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
+ return nil, err
+ }
+
+ success := false
+ for _, alert := range result.Alerts {
+ if alert.Level == "success" && alert.Text == "Successfully logged in." {
+ success = true
+ break
+ }
+ }
+
+ if !success {
+ err := fmt.Errorf("Login failed, result string: %+v", result)
+ return nil, err
+ }
+
+ jar.Save()
+
+ return &to, nil
+}
+
+// request performs the actual HTTP request to Traffic Ops
+func (to *Session) request(method, path string, body []byte) (*http.Response, error) {
+ url := fmt.Sprintf("%s%s", to.URL, path)
+
+ var req *http.Request
+ var err error
+
+ if body != nil && method != "GET" {
+ req, err = http.NewRequest(method, url, bytes.NewBuffer(body))
+ if err != nil {
+ return nil, err
+ }
+ req.Header.Set("Content-Type", "application/json")
+ } else {
+ req, err = http.NewRequest("GET", url, nil)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ resp, err := to.UserAgent.Do(req)
+ if err != nil {
+ return nil, err
+ }
+
+ if resp.StatusCode != http.StatusOK {
+ e := HTTPError{
+ HTTPStatus: resp.Status,
+ HTTPStatusCode: resp.StatusCode,
+ URL: url,
+ }
+ return nil, &e
+ }
+
+ return resp, nil
+}
+
+type CacheHitStatus string
+
+const CacheHitStatusHit = CacheHitStatus("hit")
+const CacheHitStatusExpired = CacheHitStatus("expired")
+const CacheHitStatusMiss = CacheHitStatus("miss")
+const CacheHitStatusInvalid = CacheHitStatus("")
+
+func (s CacheHitStatus) String() string {
+ return string(s)
+}
+
+func StringToCacheHitStatus(s string) CacheHitStatus {
+ s = strings.ToLower(s)
+ switch s {
+ case "hit":
+ return CacheHitStatusHit
+ case "expired":
+ return CacheHitStatusExpired
+ case "miss":
+ return CacheHitStatusMiss
+ default:
+ return CacheHitStatusInvalid
+ }
+}
+
+// getBytesWithTTL - get the path, and cache in the session
+// return from cache is found and the ttl isn't expired, otherwise get it and
+// store it in cache
+func (to *Session) getBytesWithTTL(path string, ttl int64) ([]byte, CacheHitStatus, error) {
+ var body []byte
+ var err error
+ var cacheHitStatus CacheHitStatus
+ getFresh := false
+ if cacheEntry, ok := to.Cache[path]; ok {
+ if cacheEntry.Entered > time.Now().Unix()-ttl {
+ cacheHitStatus = CacheHitStatusHit
+ body = cacheEntry.Bytes
+ } else {
+ cacheHitStatus = CacheHitStatusExpired
+ getFresh = true
+ }
+ } else {
+ to.Cache = make(map[string]CacheEntry)
+ cacheHitStatus = CacheHitStatusMiss
+ getFresh = true
+ }
+
+ if getFresh {
+ body, err = to.getBytes(path)
+ if err != nil {
+ return nil, CacheHitStatusInvalid, err
+ }
+
+ newEntry := CacheEntry{
+ Entered: time.Now().Unix(),
+ Bytes: body,
+ }
+ to.Cache[path] = newEntry
+ }
+
+ return body, cacheHitStatus, nil
+}
+
+// GetBytes - get []bytes array for a certain path on the to session.
+// returns the raw body
+func (to *Session) getBytes(path string) ([]byte, error) {
+ resp, err := to.request("GET", path, nil)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return nil, err
+ }
+
+ return body, nil
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/4563a049/traffic_stats/vendor/github.com/apache/incubator-trafficcontrol/traffic_ops/client/traffic_router_config.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/apache/incubator-trafficcontrol/traffic_ops/client/traffic_router_config.go b/traffic_stats/vendor/github.com/apache/incubator-trafficcontrol/traffic_ops/client/traffic_router_config.go
new file mode 100644
index 0000000..aecd72d
--- /dev/null
+++ b/traffic_stats/vendor/github.com/apache/incubator-trafficcontrol/traffic_ops/client/traffic_router_config.go
@@ -0,0 +1,237 @@
+/*
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package client
+
+import (
+ "encoding/json"
+ "fmt"
+)
+
+// TRConfigResponse ...
+type TRConfigResponse struct {
+ Version string `json:"version"`
+ Response TrafficRouterConfig `json:"response"`
+}
+
+// TrafficRouterConfig is the json unmarshalled without any changes
+// note all structs are local to this file _except_ the TrafficRouterConfig struct.
+type TrafficRouterConfig struct {
+ TrafficServers []TrafficServer `json:"trafficServers,omitempty"`
+ TrafficMonitors []TrafficMonitor `json:"trafficMonitors,omitempty"`
+ TrafficRouters []TrafficRouter `json:"trafficRouters,omitempty"`
+ CacheGroups []TMCacheGroup `json:"cacheGroups,omitempty"`
+ DeliveryServices []TRDeliveryService `json:"deliveryServices,omitempty"`
+ Stats map[string]interface{} `json:"stats,omitempty"`
+ Config map[string]interface{} `json:"config,omitempty"`
+}
+
+// TrafficRouterConfigMap ...
+type TrafficRouterConfigMap struct {
+ TrafficServer map[string]TrafficServer
+ TrafficMonitor map[string]TrafficMonitor
+ TrafficRouter map[string]TrafficRouter
+ CacheGroup map[string]TMCacheGroup
+ DeliveryService map[string]TRDeliveryService
+ Config map[string]interface{}
+ Stat map[string]interface{}
+}
+
+// TrafficServer ...
+type TrafficServer struct {
+ Profile string `json:"profile"`
+ IP string `json:"ip"`
+ Status string `json:"status"`
+ CacheGroup string `json:"cacheGroup"`
+ IP6 string `json:"ip6"`
+ Port int `json:"port"`
+ HostName string `json:"hostName"`
+ FQDN string `json:"fqdn"`
+ InterfaceName string `json:"interfaceName"`
+ Type string `json:"type"`
+ HashID string `json:"hashId"`
+ DeliveryServices []tsdeliveryService `json:"deliveryServices,omitempty"` // the deliveryServices key does not exist on mids
+}
+
+type tsdeliveryService struct {
+ Xmlid string `json:"xmlId"`
+ Remaps []string `json:"remaps"`
+}
+
+// TrafficRouter ...
+type TrafficRouter struct {
+ Port int `json:"port"`
+ IP6 string `json:"ip6"`
+ IP string `json:"ip"`
+ FQDN string `json:"fqdn"`
+ Profile string `json:"profile"`
+ Location string `json:"location"`
+ Status string `json:"status"`
+ APIPort int `json:"apiPort"`
+}
+
+// TMCacheGroup ...
+// !!! Note the lowercase!!! this is local to this file, there's a CacheGroup definition in cachegroup.go!
+type TMCacheGroup struct {
+ Name string `json:"name"`
+ Coordinates Coordinates `json:"coordinates"`
+}
+
+// Coordinates ...
+type Coordinates struct {
+ Latitude float64 `json:"latitude"`
+ Longitude float64 `json:"longitude"`
+}
+
+// TRDeliveryService ...
+// TODO JvD: move to deliveryservice.go ??
+type TRDeliveryService struct {
+ XMLID string `json:"xmlId"`
+ Domains []string `json:"domains"`
+ MissLocation MissLocation `json:"missCoordinates"`
+ CoverageZoneOnly bool `json:"coverageZoneOnly"`
+ MatchSets []MatchSet `json:"matchSets"`
+ TTL int `json:"ttl"`
+ TTLs TTLS `json:"ttls"`
+ BypassDestination BypassDestination `json:"bypassDestination"`
+ StatcDNSEntries []StaticDNS `json:"statitDnsEntries"`
+ Soa SOA `json:"soa"`
+}
+
+// MissLocation ...
+type MissLocation struct {
+ Latitude float64 `json:"latitude"`
+ Longitude float64 `json:"longitudef"`
+}
+
+// MatchSet ...
+type MatchSet struct {
+ Protocol string `json:"protocol"`
+ MatchList []MatchList `json:"matchList"`
+}
+
+// MatchList ...
+type MatchList struct {
+ Regex string `json:"regex"`
+ MatchType string `json:"matchType"`
+}
+
+// BypassDestination ...
+type BypassDestination struct {
+ FQDN string `json:"fqdn"`
+ Type string `json:"type"`
+ Port int `json:"Port"`
+}
+
+// TTLS ...
+type TTLS struct {
+ Arecord int `json:"A"`
+ SoaRecord int `json:"SOA"`
+ NsRecord int `json:"NS"`
+ AaaaRecord int `json:"AAAA"`
+}
+
+// StaticDNS ...
+type StaticDNS struct {
+ Value string `json:"value"`
+ TTL int `json:"ttl"`
+ Name string `json:"name"`
+ Type string `json:"type"`
+}
+
+// SOA ...
+type SOA struct {
+ Admin string `json:"admin"`
+ Retry int `json:"retry"`
+ Minimum int `json:"minimum"`
+ Refresh int `json:"refresh"`
+ Expire int `json:"expire"`
+}
+
+// TrafficRouterConfigMap Deprecated: use GetTrafficRouterConfigMap instead.
+func (to *Session) TrafficRouterConfigMap(cdn string) (*TrafficRouterConfigMap, error) {
+ cfg, _, err := to.GetTrafficRouterConfigMap(cdn)
+ return cfg, err
+}
+
+// TrafficRouterConfigMap gets a bunch of maps
+func (to *Session) GetTrafficRouterConfigMap(cdn string) (*TrafficRouterConfigMap, CacheHitStatus, error) {
+ trConfig, cacheHitStatus, err := to.GetTrafficRouterConfig(cdn)
+ if err != nil {
+ return nil, CacheHitStatusInvalid, err
+ }
+
+ trConfigMap := TRTransformToMap(*trConfig)
+ return &trConfigMap, cacheHitStatus, nil
+}
+
+// TrafficRouterConfig Deprecated: use GetTrafficRouterConfig instead.
+func (to *Session) TrafficRouterConfig(cdn string) (*TrafficRouterConfig, error) {
+ cfg, _, err := to.GetTrafficRouterConfig(cdn)
+ return cfg, err
+}
+
+// GetTrafficRouterConfig gets the json arrays
+func (to *Session) GetTrafficRouterConfig(cdn string) (*TrafficRouterConfig, CacheHitStatus, error) {
+ url := fmt.Sprintf("/api/1.2/cdns/%s/configs/routing.json", cdn)
+ body, cacheHitStatus, err := to.getBytesWithTTL(url, tmPollingInterval)
+ if err != nil {
+ return nil, CacheHitStatusInvalid, err
+ }
+
+ var data TRConfigResponse
+ if err := json.Unmarshal(body, &data); err != nil {
+ return nil, CacheHitStatusInvalid, err
+ }
+ return &data.Response, cacheHitStatus, nil
+}
+
+// TRTransformToMap ...
+func TRTransformToMap(trConfig TrafficRouterConfig) TrafficRouterConfigMap {
+ var tr TrafficRouterConfigMap
+ tr.TrafficServer = make(map[string]TrafficServer)
+ tr.TrafficMonitor = make(map[string]TrafficMonitor)
+ tr.TrafficRouter = make(map[string]TrafficRouter)
+ tr.CacheGroup = make(map[string]TMCacheGroup)
+ tr.DeliveryService = make(map[string]TRDeliveryService)
+ tr.Config = make(map[string]interface{})
+ tr.Stat = make(map[string]interface{})
+
+ for _, trServer := range trConfig.TrafficServers {
+ tr.TrafficServer[trServer.HostName] = trServer
+ }
+ for _, trMonitor := range trConfig.TrafficMonitors {
+ tr.TrafficMonitor[trMonitor.HostName] = trMonitor
+ }
+ for _, trServer := range trConfig.TrafficServers {
+ tr.TrafficServer[trServer.HostName] = trServer
+ }
+ for _, trRouter := range trConfig.TrafficRouters {
+ tr.TrafficRouter[trRouter.FQDN] = trRouter
+ }
+ for _, trCacheGroup := range trConfig.CacheGroups {
+ tr.CacheGroup[trCacheGroup.Name] = trCacheGroup
+ }
+ for _, trDeliveryService := range trConfig.DeliveryServices {
+ tr.DeliveryService[trDeliveryService.XMLID] = trDeliveryService
+ }
+ for trSettingKey, trSettingVal := range trConfig.Config {
+ tr.Config[trSettingKey] = trSettingVal
+ }
+ for trStatKey, trStatVal := range trConfig.Stats {
+ tr.Stat[trStatKey] = trStatVal
+ }
+ return tr
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/4563a049/traffic_stats/vendor/github.com/apache/incubator-trafficcontrol/traffic_ops/client/type.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/apache/incubator-trafficcontrol/traffic_ops/client/type.go b/traffic_stats/vendor/github.com/apache/incubator-trafficcontrol/traffic_ops/client/type.go
new file mode 100644
index 0000000..f8242f3
--- /dev/null
+++ b/traffic_stats/vendor/github.com/apache/incubator-trafficcontrol/traffic_ops/client/type.go
@@ -0,0 +1,68 @@
+/*
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package client
+
+import (
+ "encoding/json"
+ "errors"
+)
+
+// TypeResponse ...
+type TypeResponse struct {
+ Version string `json:"version"`
+ Response []Type `json:"response"`
+}
+
+// Type contains information about a given Type in Traffic Ops.
+type Type struct {
+ Name string `json:"name,omitempty"`
+ Description string `json:"description,omitempty"`
+ UseInTable string `json:"useInTable,omitempt"`
+}
+
+// Types gets an array of Types.
+// optional parameter: userInTable
+func (to *Session) Types(useInTable ...string) ([]Type, error) {
+
+ if len(useInTable) > 1 {
+ return nil, errors.New("Please pass in a single value for the 'useInTable' parameter")
+ }
+
+ url := "/api/1.2/types.json"
+ resp, err := to.request("GET", url, nil)
+ if err != nil {
+ return nil, err
+ }
+ resp.Body.Close()
+
+ var data TypeResponse
+ if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
+ return nil, err
+ }
+
+ var types []Type
+ for _, d := range data.Response {
+ if useInTable != nil {
+ if d.UseInTable == useInTable[0] {
+ types = append(types, d)
+ }
+ } else {
+ types = append(types, d)
+ }
+ }
+
+ return types, nil
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/4563a049/traffic_stats/vendor/github.com/apache/incubator-trafficcontrol/traffic_ops/client/user.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/apache/incubator-trafficcontrol/traffic_ops/client/user.go b/traffic_stats/vendor/github.com/apache/incubator-trafficcontrol/traffic_ops/client/user.go
new file mode 100644
index 0000000..2819eab
--- /dev/null
+++ b/traffic_stats/vendor/github.com/apache/incubator-trafficcontrol/traffic_ops/client/user.go
@@ -0,0 +1,56 @@
+/*
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package client
+
+import "encoding/json"
+
+// UserResponse ...
+type UserResponse struct {
+ Version string `json:"version"`
+ Response []User `json:"response"`
+}
+
+// User contains information about a given user in Traffic Ops.
+type User struct {
+ Username string `json:"username,omitempty"`
+ PublicSSHKey string `json:"publicSshKey,omitempty"`
+ Role string `json:"role,omitempty"`
+ RoleName string `json:"rolename,omitempty"`
+ UID string `json:"uid,omitempty"`
+ GID string `json:"gid,omitempty"`
+ Company string `json:"company,omitempty"`
+ Email string `json:"email,omitempty"`
+ FullName string `json:"fullName,omitempty"`
+ NewUser bool `json:"newUser,omitempty"`
+ LastUpdated string `json:"lastUpdated,omitempty"`
+}
+
+// Users gets an array of Users.
+func (to *Session) Users() ([]User, error) {
+ url := "/api/1.2/users.json"
+ resp, err := to.request("GET", url, nil)
+ if err != nil {
+ return nil, err
+ }
+ resp.Body.Close()
+
+ var data UserResponse
+ if err := json.NewDecoder(resp.Body).Decode(&data.Response); err != nil {
+ return nil, err
+ }
+
+ return data.Response, nil
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/4563a049/traffic_stats/vendor/github.com/cihub/seelog
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
new file mode 160000
index 0000000..175e6e3
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog
@@ -0,0 +1 @@
+Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/4563a049/traffic_stats/vendor/github.com/influxdata/influxdb/client/v2/client.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/influxdata/influxdb/client/v2/client.go b/traffic_stats/vendor/github.com/influxdata/influxdb/client/v2/client.go
new file mode 100644
index 0000000..4d0ce60
--- /dev/null
+++ b/traffic_stats/vendor/github.com/influxdata/influxdb/client/v2/client.go
@@ -0,0 +1,526 @@
+// Package client (v2) is the current official Go client for InfluxDB.
+package client // import "github.com/influxdata/influxdb/client/v2"
+
+import (
+ "bytes"
+ "crypto/tls"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "time"
+
+ "github.com/influxdata/influxdb/models"
+)
+
+// HTTPConfig is the config data needed to create an HTTP Client.
+type HTTPConfig struct {
+ // Addr should be of the form "http://host:port"
+ // or "http://[ipv6-host%zone]:port".
+ Addr string
+
+ // Username is the influxdb username, optional.
+ Username string
+
+ // Password is the influxdb password, optional.
+ Password string
+
+ // UserAgent is the http User Agent, defaults to "InfluxDBClient".
+ UserAgent string
+
+ // Timeout for influxdb writes, defaults to no timeout.
+ Timeout time.Duration
+
+ // InsecureSkipVerify gets passed to the http client, if true, it will
+ // skip https certificate verification. Defaults to false.
+ InsecureSkipVerify bool
+
+ // TLSConfig allows the user to set their own TLS config for the HTTP
+ // Client. If set, this option overrides InsecureSkipVerify.
+ TLSConfig *tls.Config
+}
+
+// BatchPointsConfig is the config data needed to create an instance of the BatchPoints struct.
+type BatchPointsConfig struct {
+ // Precision is the write precision of the points, defaults to "ns".
+ Precision string
+
+ // Database is the database to write points to.
+ Database string
+
+ // RetentionPolicy is the retention policy of the points.
+ RetentionPolicy string
+
+ // Write consistency is the number of servers required to confirm write.
+ WriteConsistency string
+}
+
+// Client is a client interface for writing & querying the database.
+type Client interface {
+ // Ping checks that status of cluster, and will always return 0 time and no
+ // error for UDP clients.
+ Ping(timeout time.Duration) (time.Duration, string, error)
+
+ // Write takes a BatchPoints object and writes all Points to InfluxDB.
+ Write(bp BatchPoints) error
+
+ // Query makes an InfluxDB Query on the database. This will fail if using
+ // the UDP client.
+ Query(q Query) (*Response, error)
+
+ // Close releases any resources a Client may be using.
+ Close() error
+}
+
+// NewHTTPClient returns a new Client from the provided config.
+// Client is safe for concurrent use by multiple goroutines.
+func NewHTTPClient(conf HTTPConfig) (Client, error) {
+ if conf.UserAgent == "" {
+ conf.UserAgent = "InfluxDBClient"
+ }
+
+ u, err := url.Parse(conf.Addr)
+ if err != nil {
+ return nil, err
+ } else if u.Scheme != "http" && u.Scheme != "https" {
+ m := fmt.Sprintf("Unsupported protocol scheme: %s, your address"+
+ " must start with http:// or https://", u.Scheme)
+ return nil, errors.New(m)
+ }
+
+ tr := &http.Transport{
+ TLSClientConfig: &tls.Config{
+ InsecureSkipVerify: conf.InsecureSkipVerify,
+ },
+ }
+ if conf.TLSConfig != nil {
+ tr.TLSClientConfig = conf.TLSConfig
+ }
+ return &client{
+ url: *u,
+ username: conf.Username,
+ password: conf.Password,
+ useragent: conf.UserAgent,
+ httpClient: &http.Client{
+ Timeout: conf.Timeout,
+ Transport: tr,
+ },
+ transport: tr,
+ }, nil
+}
+
+// Ping will check to see if the server is up with an optional timeout on waiting for leader.
+// Ping returns how long the request took, the version of the server it connected to, and an error if one occurred.
+func (c *client) Ping(timeout time.Duration) (time.Duration, string, error) {
+ now := time.Now()
+ u := c.url
+ u.Path = "ping"
+
+ req, err := http.NewRequest("GET", u.String(), nil)
+ if err != nil {
+ return 0, "", err
+ }
+
+ req.Header.Set("User-Agent", c.useragent)
+
+ if c.username != "" {
+ req.SetBasicAuth(c.username, c.password)
+ }
+
+ if timeout > 0 {
+ params := req.URL.Query()
+ params.Set("wait_for_leader", fmt.Sprintf("%.0fs", timeout.Seconds()))
+ req.URL.RawQuery = params.Encode()
+ }
+
+ resp, err := c.httpClient.Do(req)
+ if err != nil {
+ return 0, "", err
+ }
+ defer resp.Body.Close()
+
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return 0, "", err
+ }
+
+ if resp.StatusCode != http.StatusNoContent {
+ var err = fmt.Errorf(string(body))
+ return 0, "", err
+ }
+
+ version := resp.Header.Get("X-Influxdb-Version")
+ return time.Since(now), version, nil
+}
+
+// Close releases the client's resources.
+func (c *client) Close() error {
+ c.transport.CloseIdleConnections()
+ return nil
+}
+
+// client is safe for concurrent use as the fields are all read-only
+// once the client is instantiated.
+type client struct {
+ // N.B - if url.UserInfo is accessed in future modifications to the
+ // methods on client, you will need to syncronise access to url.
+ url url.URL
+ username string
+ password string
+ useragent string
+ httpClient *http.Client
+ transport *http.Transport
+}
+
+// BatchPoints is an interface into a batched grouping of points to write into
+// InfluxDB together. BatchPoints is NOT thread-safe, you must create a separate
+// batch for each goroutine.
+type BatchPoints interface {
+ // AddPoint adds the given point to the Batch of points.
+ AddPoint(p *Point)
+ // AddPoints adds the given points to the Batch of points.
+ AddPoints(ps []*Point)
+ // Points lists the points in the Batch.
+ Points() []*Point
+
+ // Precision returns the currently set precision of this Batch.
+ Precision() string
+ // SetPrecision sets the precision of this batch.
+ SetPrecision(s string) error
+
+ // Database returns the currently set database of this Batch.
+ Database() string
+ // SetDatabase sets the database of this Batch.
+ SetDatabase(s string)
+
+ // WriteConsistency returns the currently set write consistency of this Batch.
+ WriteConsistency() string
+ // SetWriteConsistency sets the write consistency of this Batch.
+ SetWriteConsistency(s string)
+
+ // RetentionPolicy returns the currently set retention policy of this Batch.
+ RetentionPolicy() string
+ // SetRetentionPolicy sets the retention policy of this Batch.
+ SetRetentionPolicy(s string)
+}
+
+// NewBatchPoints returns a BatchPoints interface based on the given config.
+func NewBatchPoints(conf BatchPointsConfig) (BatchPoints, error) {
+ if conf.Precision == "" {
+ conf.Precision = "ns"
+ }
+ if _, err := time.ParseDuration("1" + conf.Precision); err != nil {
+ return nil, err
+ }
+ bp := &batchpoints{
+ database: conf.Database,
+ precision: conf.Precision,
+ retentionPolicy: conf.RetentionPolicy,
+ writeConsistency: conf.WriteConsistency,
+ }
+ return bp, nil
+}
+
+type batchpoints struct {
+ points []*Point
+ database string
+ precision string
+ retentionPolicy string
+ writeConsistency string
+}
+
+func (bp *batchpoints) AddPoint(p *Point) {
+ bp.points = append(bp.points, p)
+}
+
+func (bp *batchpoints) AddPoints(ps []*Point) {
+ bp.points = append(bp.points, ps...)
+}
+
+func (bp *batchpoints) Points() []*Point {
+ return bp.points
+}
+
+func (bp *batchpoints) Precision() string {
+ return bp.precision
+}
+
+func (bp *batchpoints) Database() string {
+ return bp.database
+}
+
+func (bp *batchpoints) WriteConsistency() string {
+ return bp.writeConsistency
+}
+
+func (bp *batchpoints) RetentionPolicy() string {
+ return bp.retentionPolicy
+}
+
+func (bp *batchpoints) SetPrecision(p string) error {
+ if _, err := time.ParseDuration("1" + p); err != nil {
+ return err
+ }
+ bp.precision = p
+ return nil
+}
+
+func (bp *batchpoints) SetDatabase(db string) {
+ bp.database = db
+}
+
+func (bp *batchpoints) SetWriteConsistency(wc string) {
+ bp.writeConsistency = wc
+}
+
+func (bp *batchpoints) SetRetentionPolicy(rp string) {
+ bp.retentionPolicy = rp
+}
+
+// Point represents a single data point.
+type Point struct {
+ pt models.Point
+}
+
+// NewPoint returns a point with the given timestamp. If a timestamp is not
+// given, then data is sent to the database without a timestamp, in which case
+// the server will assign local time upon reception. NOTE: it is recommended to
+// send data with a timestamp.
+func NewPoint(
+ name string,
+ tags map[string]string,
+ fields map[string]interface{},
+ t ...time.Time,
+) (*Point, error) {
+ var T time.Time
+ if len(t) > 0 {
+ T = t[0]
+ }
+
+ pt, err := models.NewPoint(name, models.NewTags(tags), fields, T)
+ if err != nil {
+ return nil, err
+ }
+ return &Point{
+ pt: pt,
+ }, nil
+}
+
+// String returns a line-protocol string of the Point.
+func (p *Point) String() string {
+ return p.pt.String()
+}
+
+// PrecisionString returns a line-protocol string of the Point,
+// with the timestamp formatted for the given precision.
+func (p *Point) PrecisionString(precison string) string {
+ return p.pt.PrecisionString(precison)
+}
+
+// Name returns the measurement name of the point.
+func (p *Point) Name() string {
+ return p.pt.Name()
+}
+
+// Tags returns the tags associated with the point.
+func (p *Point) Tags() map[string]string {
+ return p.pt.Tags().Map()
+}
+
+// Time return the timestamp for the point.
+func (p *Point) Time() time.Time {
+ return p.pt.Time()
+}
+
+// UnixNano returns timestamp of the point in nanoseconds since Unix epoch.
+func (p *Point) UnixNano() int64 {
+ return p.pt.UnixNano()
+}
+
+// Fields returns the fields for the point.
+func (p *Point) Fields() (map[string]interface{}, error) {
+ return p.pt.Fields()
+}
+
+// NewPointFrom returns a point from the provided models.Point.
+func NewPointFrom(pt models.Point) *Point {
+ return &Point{pt: pt}
+}
+
+func (c *client) Write(bp BatchPoints) error {
+ var b bytes.Buffer
+
+ for _, p := range bp.Points() {
+ if _, err := b.WriteString(p.pt.PrecisionString(bp.Precision())); err != nil {
+ return err
+ }
+
+ if err := b.WriteByte('\n'); err != nil {
+ return err
+ }
+ }
+
+ u := c.url
+ u.Path = "write"
+ req, err := http.NewRequest("POST", u.String(), &b)
+ if err != nil {
+ return err
+ }
+ req.Header.Set("Content-Type", "")
+ req.Header.Set("User-Agent", c.useragent)
+ if c.username != "" {
+ req.SetBasicAuth(c.username, c.password)
+ }
+
+ params := req.URL.Query()
+ params.Set("db", bp.Database())
+ params.Set("rp", bp.RetentionPolicy())
+ params.Set("precision", bp.Precision())
+ params.Set("consistency", bp.WriteConsistency())
+ req.URL.RawQuery = params.Encode()
+
+ resp, err := c.httpClient.Do(req)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return err
+ }
+
+ if resp.StatusCode != http.StatusNoContent && resp.StatusCode != http.StatusOK {
+ var err = fmt.Errorf(string(body))
+ return err
+ }
+
+ return nil
+}
+
+// Query defines a query to send to the server.
+type Query struct {
+ Command string
+ Database string
+ Precision string
+ Parameters map[string]interface{}
+}
+
+// NewQuery returns a query object.
+// The database and precision arguments can be empty strings if they are not needed for the query.
+func NewQuery(command, database, precision string) Query {
+ return Query{
+ Command: command,
+ Database: database,
+ Precision: precision,
+ Parameters: make(map[string]interface{}),
+ }
+}
+
+// NewQueryWithParameters returns a query object.
+// The database and precision arguments can be empty strings if they are not needed for the query.
+// parameters is a map of the parameter names used in the command to their values.
+func NewQueryWithParameters(command, database, precision string, parameters map[string]interface{}) Query {
+ return Query{
+ Command: command,
+ Database: database,
+ Precision: precision,
+ Parameters: parameters,
+ }
+}
+
+// Response represents a list of statement results.
+type Response struct {
+ Results []Result
+ Err string `json:"error,omitempty"`
+}
+
+// Error returns the first error from any statement.
+// It returns nil if no errors occurred on any statements.
+func (r *Response) Error() error {
+ if r.Err != "" {
+ return fmt.Errorf(r.Err)
+ }
+ for _, result := range r.Results {
+ if result.Err != "" {
+ return fmt.Errorf(result.Err)
+ }
+ }
+ return nil
+}
+
+// Message represents a user message.
+type Message struct {
+ Level string
+ Text string
+}
+
+// Result represents a resultset returned from a single statement.
+type Result struct {
+ Series []models.Row
+ Messages []*Message
+ Err string `json:"error,omitempty"`
+}
+
+// Query sends a command to the server and returns the Response.
+func (c *client) Query(q Query) (*Response, error) {
+ u := c.url
+ u.Path = "query"
+
+ jsonParameters, err := json.Marshal(q.Parameters)
+
+ if err != nil {
+ return nil, err
+ }
+
+ req, err := http.NewRequest("POST", u.String(), nil)
+ if err != nil {
+ return nil, err
+ }
+
+ req.Header.Set("Content-Type", "")
+ req.Header.Set("User-Agent", c.useragent)
+
+ if c.username != "" {
+ req.SetBasicAuth(c.username, c.password)
+ }
+
+ params := req.URL.Query()
+ params.Set("q", q.Command)
+ params.Set("db", q.Database)
+ params.Set("params", string(jsonParameters))
+
+ if q.Precision != "" {
+ params.Set("epoch", q.Precision)
+ }
+ req.URL.RawQuery = params.Encode()
+
+ resp, err := c.httpClient.Do(req)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var response Response
+ dec := json.NewDecoder(resp.Body)
+ dec.UseNumber()
+ decErr := dec.Decode(&response)
+
+ // ignore this error if we got an invalid status code
+ if decErr != nil && decErr.Error() == "EOF" && resp.StatusCode != http.StatusOK {
+ decErr = nil
+ }
+ // If we got a valid decode error, send that back
+ if decErr != nil {
+ return nil, fmt.Errorf("unable to decode json: received status code %d err: %s", resp.StatusCode, decErr)
+ }
+ // If we don't have an error in our json response, and didn't get statusOK
+ // then send back an error
+ if resp.StatusCode != http.StatusOK && response.Error() == nil {
+ return &response, fmt.Errorf("received status code %d from server",
+ resp.StatusCode)
+ }
+ return &response, nil
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/4563a049/traffic_stats/vendor/github.com/influxdata/influxdb/client/v2/client_test.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/influxdata/influxdb/client/v2/client_test.go b/traffic_stats/vendor/github.com/influxdata/influxdb/client/v2/client_test.go
new file mode 100644
index 0000000..d27c162
--- /dev/null
+++ b/traffic_stats/vendor/github.com/influxdata/influxdb/client/v2/client_test.go
@@ -0,0 +1,525 @@
+package client
+
+import (
+ "encoding/json"
+ "net/http"
+ "net/http/httptest"
+ "reflect"
+ "strings"
+ "sync"
+ "testing"
+ "time"
+)
+
+func TestUDPClient_Query(t *testing.T) {
+ config := UDPConfig{Addr: "localhost:8089"}
+ c, err := NewUDPClient(config)
+ if err != nil {
+ t.Errorf("unexpected error. expected %v, actual %v", nil, err)
+ }
+ defer c.Close()
+ query := Query{}
+ _, err = c.Query(query)
+ if err == nil {
+ t.Error("Querying UDP client should fail")
+ }
+}
+
+func TestUDPClient_Ping(t *testing.T) {
+ config := UDPConfig{Addr: "localhost:8089"}
+ c, err := NewUDPClient(config)
+ if err != nil {
+ t.Errorf("unexpected error. expected %v, actual %v", nil, err)
+ }
+ defer c.Close()
+
+ rtt, version, err := c.Ping(0)
+ if rtt != 0 || version != "" || err != nil {
+ t.Errorf("unexpected error. expected (%v, '%v', %v), actual (%v, '%v', %v)", 0, "", nil, rtt, version, err)
+ }
+}
+
+func TestUDPClient_Write(t *testing.T) {
+ config := UDPConfig{Addr: "localhost:8089"}
+ c, err := NewUDPClient(config)
+ if err != nil {
+ t.Errorf("unexpected error. expected %v, actual %v", nil, err)
+ }
+ defer c.Close()
+
+ bp, err := NewBatchPoints(BatchPointsConfig{})
+ if err != nil {
+ t.Errorf("unexpected error. expected %v, actual %v", nil, err)
+ }
+
+ fields := make(map[string]interface{})
+ fields["value"] = 1.0
+ pt, _ := NewPoint("cpu", make(map[string]string), fields)
+ bp.AddPoint(pt)
+
+ err = c.Write(bp)
+ if err != nil {
+ t.Errorf("unexpected error. expected %v, actual %v", nil, err)
+ }
+}
+
+func TestUDPClient_BadAddr(t *testing.T) {
+ config := UDPConfig{Addr: "foobar@wahoo"}
+ c, err := NewUDPClient(config)
+ if err == nil {
+ defer c.Close()
+ t.Error("Expected resolve error")
+ }
+}
+
+func TestUDPClient_Batches(t *testing.T) {
+ var logger writeLogger
+ var cl udpclient
+
+ cl.conn = &logger
+ cl.payloadSize = 20 // should allow for two points per batch
+
+ // expected point should look like this: "cpu a=1i"
+ fields := map[string]interface{}{"a": 1}
+
+ p, _ := NewPoint("cpu", nil, fields, time.Time{})
+
+ bp, _ := NewBatchPoints(BatchPointsConfig{})
+
+ for i := 0; i < 9; i++ {
+ bp.AddPoint(p)
+ }
+
+ if err := cl.Write(bp); err != nil {
+ t.Fatalf("Unexpected error during Write: %v", err)
+ }
+
+ if len(logger.writes) != 5 {
+ t.Errorf("Mismatched write count: got %v, exp %v", len(logger.writes), 5)
+ }
+}
+
+func TestUDPClient_Split(t *testing.T) {
+ var logger writeLogger
+ var cl udpclient
+
+ cl.conn = &logger
+ cl.payloadSize = 1 // force one field per point
+
+ fields := map[string]interface{}{"a": 1, "b": 2, "c": 3, "d": 4}
+
+ p, _ := NewPoint("cpu", nil, fields, time.Unix(1, 0))
+
+ bp, _ := NewBatchPoints(BatchPointsConfig{})
+
+ bp.AddPoint(p)
+
+ if err := cl.Write(bp); err != nil {
+ t.Fatalf("Unexpected error during Write: %v", err)
+ }
+
+ if len(logger.writes) != len(fields) {
+ t.Errorf("Mismatched write count: got %v, exp %v", len(logger.writes), len(fields))
+ }
+}
+
+type writeLogger struct {
+ writes [][]byte
+}
+
+func (w *writeLogger) Write(b []byte) (int, error) {
+ w.writes = append(w.writes, append([]byte(nil), b...))
+ return len(b), nil
+}
+
+func (w *writeLogger) Close() error { return nil }
+
+func TestClient_Query(t *testing.T) {
+ ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ var data Response
+ w.WriteHeader(http.StatusOK)
+ _ = json.NewEncoder(w).Encode(data)
+ }))
+ defer ts.Close()
+
+ config := HTTPConfig{Addr: ts.URL}
+ c, _ := NewHTTPClient(config)
+ defer c.Close()
+
+ query := Query{}
+ _, err := c.Query(query)
+ if err != nil {
+ t.Errorf("unexpected error. expected %v, actual %v", nil, err)
+ }
+}
+
+func TestClient_BoundParameters(t *testing.T) {
+ var parameterString string
+ ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ var data Response
+ r.ParseForm()
+ parameterString = r.FormValue("params")
+ w.WriteHeader(http.StatusOK)
+ _ = json.NewEncoder(w).Encode(data)
+ }))
+ defer ts.Close()
+
+ config := HTTPConfig{Addr: ts.URL}
+ c, _ := NewHTTPClient(config)
+ defer c.Close()
+
+ expectedParameters := map[string]interface{}{
+ "testStringParameter": "testStringValue",
+ "testNumberParameter": 12.3,
+ }
+
+ query := Query{
+ Parameters: expectedParameters,
+ }
+
+ _, err := c.Query(query)
+ if err != nil {
+ t.Errorf("unexpected error. expected %v, actual %v", nil, err)
+ }
+
+ var actualParameters map[string]interface{}
+
+ err = json.Unmarshal([]byte(parameterString), &actualParameters)
+ if err != nil {
+ t.Errorf("unexpected error. expected %v, actual %v", nil, err)
+ }
+
+ if !reflect.DeepEqual(expectedParameters, actualParameters) {
+ t.Errorf("unexpected parameters. expected %v, actual %v", expectedParameters, actualParameters)
+ }
+}
+
+func TestClient_BasicAuth(t *testing.T) {
+ ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ u, p, ok := r.BasicAuth()
+
+ if !ok {
+ t.Errorf("basic auth error")
+ }
+ if u != "username" {
+ t.Errorf("unexpected username, expected %q, actual %q", "username", u)
+ }
+ if p != "password" {
+ t.Errorf("unexpected password, expected %q, actual %q", "password", p)
+ }
+ var data Response
+ w.WriteHeader(http.StatusOK)
+ _ = json.NewEncoder(w).Encode(data)
+ }))
+ defer ts.Close()
+
+ config := HTTPConfig{Addr: ts.URL, Username: "username", Password: "password"}
+ c, _ := NewHTTPClient(config)
+ defer c.Close()
+
+ query := Query{}
+ _, err := c.Query(query)
+ if err != nil {
+ t.Errorf("unexpected error. expected %v, actual %v", nil, err)
+ }
+}
+
+func TestClient_Ping(t *testing.T) {
+ ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ var data Response
+ w.WriteHeader(http.StatusNoContent)
+ _ = json.NewEncoder(w).Encode(data)
+ }))
+ defer ts.Close()
+
+ config := HTTPConfig{Addr: ts.URL}
+ c, _ := NewHTTPClient(config)
+ defer c.Close()
+
+ _, _, err := c.Ping(0)
+ if err != nil {
+ t.Errorf("unexpected error. expected %v, actual %v", nil, err)
+ }
+}
+
+func TestClient_Concurrent_Use(t *testing.T) {
+ ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ w.WriteHeader(http.StatusOK)
+ w.Write([]byte(`{}`))
+ }))
+ defer ts.Close()
+
+ config := HTTPConfig{Addr: ts.URL}
+ c, _ := NewHTTPClient(config)
+ defer c.Close()
+
+ var wg sync.WaitGroup
+ wg.Add(3)
+ n := 1000
+
+ go func() {
+ defer wg.Done()
+ bp, err := NewBatchPoints(BatchPointsConfig{})
+ if err != nil {
+ t.Errorf("got error %v", err)
+ }
+
+ for i := 0; i < n; i++ {
+ if err = c.Write(bp); err != nil {
+ t.Fatalf("got error %v", err)
+ }
+ }
+ }()
+
+ go func() {
+ defer wg.Done()
+ var q Query
+ for i := 0; i < n; i++ {
+ if _, err := c.Query(q); err != nil {
+ t.Fatalf("got error %v", err)
+ }
+ }
+ }()
+
+ go func() {
+ defer wg.Done()
+ for i := 0; i < n; i++ {
+ c.Ping(time.Second)
+ }
+ }()
+ wg.Wait()
+}
+
+func TestClient_Write(t *testing.T) {
+ ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ var data Response
+ w.WriteHeader(http.StatusNoContent)
+ _ = json.NewEncoder(w).Encode(data)
+ }))
+ defer ts.Close()
+
+ config := HTTPConfig{Addr: ts.URL}
+ c, _ := NewHTTPClient(config)
+ defer c.Close()
+
+ bp, err := NewBatchPoints(BatchPointsConfig{})
+ if err != nil {
+ t.Errorf("unexpected error. expected %v, actual %v", nil, err)
+ }
+ err = c.Write(bp)
+ if err != nil {
+ t.Errorf("unexpected error. expected %v, actual %v", nil, err)
+ }
+}
+
+func TestClient_UserAgent(t *testing.T) {
+ receivedUserAgent := ""
+ ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ receivedUserAgent = r.UserAgent()
+
+ var data Response
+ w.WriteHeader(http.StatusOK)
+ _ = json.NewEncoder(w).Encode(data)
+ }))
+ defer ts.Close()
+
+ _, err := http.Get(ts.URL)
+ if err != nil {
+ t.Errorf("unexpected error. expected %v, actual %v", nil, err)
+ }
+
+ tests := []struct {
+ name string
+ userAgent string
+ expected string
+ }{
+ {
+ name: "Empty user agent",
+ userAgent: "",
+ expected: "InfluxDBClient",
+ },
+ {
+ name: "Custom user agent",
+ userAgent: "Test Influx Client",
+ expected: "Test Influx Client",
+ },
+ }
+
+ for _, test := range tests {
+
+ config := HTTPConfig{Addr: ts.URL, UserAgent: test.userAgent}
+ c, _ := NewHTTPClient(config)
+ defer c.Close()
+
+ receivedUserAgent = ""
+ query := Query{}
+ _, err = c.Query(query)
+ if err != nil {
+ t.Errorf("unexpected error. expected %v, actual %v", nil, err)
+ }
+ if !strings.HasPrefix(receivedUserAgent, test.expected) {
+ t.Errorf("Unexpected user agent. expected %v, actual %v", test.expected, receivedUserAgent)
+ }
+
+ receivedUserAgent = ""
+ bp, _ := NewBatchPoints(BatchPointsConfig{})
+ err = c.Write(bp)
+ if err != nil {
+ t.Errorf("unexpected error. expected %v, actual %v", nil, err)
+ }
+ if !strings.HasPrefix(receivedUserAgent, test.expected) {
+ t.Errorf("Unexpected user agent. expected %v, actual %v", test.expected, receivedUserAgent)
+ }
+
+ receivedUserAgent = ""
+ _, err := c.Query(query)
+ if err != nil {
+ t.Errorf("unexpected error. expected %v, actual %v", nil, err)
+ }
+ if receivedUserAgent != test.expected {
+ t.Errorf("Unexpected user agent. expected %v, actual %v", test.expected, receivedUserAgent)
+ }
+ }
+}
+
+func TestClient_PointString(t *testing.T) {
+ const shortForm = "2006-Jan-02"
+ time1, _ := time.Parse(shortForm, "2013-Feb-03")
+ tags := map[string]string{"cpu": "cpu-total"}
+ fields := map[string]interface{}{"idle": 10.1, "system": 50.9, "user": 39.0}
+ p, _ := NewPoint("cpu_usage", tags, fields, time1)
+
+ s := "cpu_usage,cpu=cpu-total idle=10.1,system=50.9,user=39 1359849600000000000"
+ if p.String() != s {
+ t.Errorf("Point String Error, got %s, expected %s", p.String(), s)
+ }
+
+ s = "cpu_usage,cpu=cpu-total idle=10.1,system=50.9,user=39 1359849600000"
+ if p.PrecisionString("ms") != s {
+ t.Errorf("Point String Error, got %s, expected %s",
+ p.PrecisionString("ms"), s)
+ }
+}
+
+func TestClient_PointWithoutTimeString(t *testing.T) {
+ tags := map[string]string{"cpu": "cpu-total"}
+ fields := map[string]interface{}{"idle": 10.1, "system": 50.9, "user": 39.0}
+ p, _ := NewPoint("cpu_usage", tags, fields)
+
+ s := "cpu_usage,cpu=cpu-total idle=10.1,system=50.9,user=39"
+ if p.String() != s {
+ t.Errorf("Point String Error, got %s, expected %s", p.String(), s)
+ }
+
+ if p.PrecisionString("ms") != s {
+ t.Errorf("Point String Error, got %s, expected %s",
+ p.PrecisionString("ms"), s)
+ }
+}
+
+func TestClient_PointName(t *testing.T) {
+ tags := map[string]string{"cpu": "cpu-total"}
+ fields := map[string]interface{}{"idle": 10.1, "system": 50.9, "user": 39.0}
+ p, _ := NewPoint("cpu_usage", tags, fields)
+
+ exp := "cpu_usage"
+ if p.Name() != exp {
+ t.Errorf("Error, got %s, expected %s",
+ p.Name(), exp)
+ }
+}
+
+func TestClient_PointTags(t *testing.T) {
+ tags := map[string]string{"cpu": "cpu-total"}
+ fields := map[string]interface{}{"idle": 10.1, "system": 50.9, "user": 39.0}
+ p, _ := NewPoint("cpu_usage", tags, fields)
+
+ if !reflect.DeepEqual(tags, p.Tags()) {
+ t.Errorf("Error, got %v, expected %v",
+ p.Tags(), tags)
+ }
+}
+
+func TestClient_PointUnixNano(t *testing.T) {
+ const shortForm = "2006-Jan-02"
+ time1, _ := time.Parse(shortForm, "2013-Feb-03")
+ tags := map[string]string{"cpu": "cpu-total"}
+ fields := map[string]interface{}{"idle": 10.1, "system": 50.9, "user": 39.0}
+ p, _ := NewPoint("cpu_usage", tags, fields, time1)
+
+ exp := int64(1359849600000000000)
+ if p.UnixNano() != exp {
+ t.Errorf("Error, got %d, expected %d",
+ p.UnixNano(), exp)
+ }
+}
+
+func TestClient_PointFields(t *testing.T) {
+ tags := map[string]string{"cpu": "cpu-total"}
+ fields := map[string]interface{}{"idle": 10.1, "system": 50.9, "user": 39.0}
+ p, _ := NewPoint("cpu_usage", tags, fields)
+
+ pfields, err := p.Fields()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !reflect.DeepEqual(fields, pfields) {
+ t.Errorf("Error, got %v, expected %v",
+ pfields, fields)
+ }
+}
+
+func TestBatchPoints_PrecisionError(t *testing.T) {
+ _, err := NewBatchPoints(BatchPointsConfig{Precision: "foobar"})
+ if err == nil {
+ t.Errorf("Precision: foobar should have errored")
+ }
+
+ bp, _ := NewBatchPoints(BatchPointsConfig{Precision: "ns"})
+ err = bp.SetPrecision("foobar")
+ if err == nil {
+ t.Errorf("Precision: foobar should have errored")
+ }
+}
+
+func TestBatchPoints_SettersGetters(t *testing.T) {
+ bp, _ := NewBatchPoints(BatchPointsConfig{
+ Precision: "ns",
+ Database: "db",
+ RetentionPolicy: "rp",
+ WriteConsistency: "wc",
+ })
+ if bp.Precision() != "ns" {
+ t.Errorf("Expected: %s, got %s", bp.Precision(), "ns")
+ }
+ if bp.Database() != "db" {
+ t.Errorf("Expected: %s, got %s", bp.Database(), "db")
+ }
+ if bp.RetentionPolicy() != "rp" {
+ t.Errorf("Expected: %s, got %s", bp.RetentionPolicy(), "rp")
+ }
+ if bp.WriteConsistency() != "wc" {
+ t.Errorf("Expected: %s, got %s", bp.WriteConsistency(), "wc")
+ }
+
+ bp.SetDatabase("db2")
+ bp.SetRetentionPolicy("rp2")
+ bp.SetWriteConsistency("wc2")
+ err := bp.SetPrecision("s")
+ if err != nil {
+ t.Errorf("Did not expect error: %s", err.Error())
+ }
+
+ if bp.Precision() != "s" {
+ t.Errorf("Expected: %s, got %s", bp.Precision(), "s")
+ }
+ if bp.Database() != "db2" {
+ t.Errorf("Expected: %s, got %s", bp.Database(), "db2")
+ }
+ if bp.RetentionPolicy() != "rp2" {
+ t.Errorf("Expected: %s, got %s", bp.RetentionPolicy(), "rp2")
+ }
+ if bp.WriteConsistency() != "wc2" {
+ t.Errorf("Expected: %s, got %s", bp.WriteConsistency(), "wc2")
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/4563a049/traffic_stats/vendor/github.com/influxdata/influxdb/client/v2/example_test.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/influxdata/influxdb/client/v2/example_test.go b/traffic_stats/vendor/github.com/influxdata/influxdb/client/v2/example_test.go
new file mode 100644
index 0000000..68bb24b
--- /dev/null
+++ b/traffic_stats/vendor/github.com/influxdata/influxdb/client/v2/example_test.go
@@ -0,0 +1,265 @@
+package client_test
+
+import (
+ "fmt"
+ "math/rand"
+ "os"
+ "time"
+
+ "github.com/influxdata/influxdb/client/v2"
+)
+
+// Create a new client
+func ExampleClient() {
+ // NOTE: this assumes you've setup a user and have setup shell env variables,
+ // namely INFLUX_USER/INFLUX_PWD. If not just omit Username/Password below.
+ _, err := client.NewHTTPClient(client.HTTPConfig{
+ Addr: "http://localhost:8086",
+ Username: os.Getenv("INFLUX_USER"),
+ Password: os.Getenv("INFLUX_PWD"),
+ })
+ if err != nil {
+ fmt.Println("Error creating InfluxDB Client: ", err.Error())
+ }
+}
+
+// Write a point using the UDP client
+func ExampleClient_uDP() {
+ // Make client
+ config := client.UDPConfig{Addr: "localhost:8089"}
+ c, err := client.NewUDPClient(config)
+ if err != nil {
+ fmt.Println("Error: ", err.Error())
+ }
+ defer c.Close()
+
+ // Create a new point batch
+ bp, _ := client.NewBatchPoints(client.BatchPointsConfig{
+ Precision: "s",
+ })
+
+ // Create a point and add to batch
+ tags := map[string]string{"cpu": "cpu-total"}
+ fields := map[string]interface{}{
+ "idle": 10.1,
+ "system": 53.3,
+ "user": 46.6,
+ }
+ pt, err := client.NewPoint("cpu_usage", tags, fields, time.Now())
+ if err != nil {
+ fmt.Println("Error: ", err.Error())
+ }
+ bp.AddPoint(pt)
+
+ // Write the batch
+ c.Write(bp)
+}
+
+// Ping the cluster using the HTTP client
+func ExampleClient_Ping() {
+ // Make client
+ c, err := client.NewHTTPClient(client.HTTPConfig{
+ Addr: "http://localhost:8086",
+ })
+ if err != nil {
+ fmt.Println("Error creating InfluxDB Client: ", err.Error())
+ }
+ defer c.Close()
+
+ _, _, err = c.Ping(0)
+ if err != nil {
+ fmt.Println("Error pinging InfluxDB Cluster: ", err.Error())
+ }
+}
+
+// Write a point using the HTTP client
+func ExampleClient_write() {
+ // Make client
+ c, err := client.NewHTTPClient(client.HTTPConfig{
+ Addr: "http://localhost:8086",
+ })
+ if err != nil {
+ fmt.Println("Error creating InfluxDB Client: ", err.Error())
+ }
+ defer c.Close()
+
+ // Create a new point batch
+ bp, _ := client.NewBatchPoints(client.BatchPointsConfig{
+ Database: "BumbleBeeTuna",
+ Precision: "s",
+ })
+
+ // Create a point and add to batch
+ tags := map[string]string{"cpu": "cpu-total"}
+ fields := map[string]interface{}{
+ "idle": 10.1,
+ "system": 53.3,
+ "user": 46.6,
+ }
+ pt, err := client.NewPoint("cpu_usage", tags, fields, time.Now())
+ if err != nil {
+ fmt.Println("Error: ", err.Error())
+ }
+ bp.AddPoint(pt)
+
+ // Write the batch
+ c.Write(bp)
+}
+
+// Create a batch and add a point
+func ExampleBatchPoints() {
+ // Create a new point batch
+ bp, _ := client.NewBatchPoints(client.BatchPointsConfig{
+ Database: "BumbleBeeTuna",
+ Precision: "s",
+ })
+
+ // Create a point and add to batch
+ tags := map[string]string{"cpu": "cpu-total"}
+ fields := map[string]interface{}{
+ "idle": 10.1,
+ "system": 53.3,
+ "user": 46.6,
+ }
+ pt, err := client.NewPoint("cpu_usage", tags, fields, time.Now())
+ if err != nil {
+ fmt.Println("Error: ", err.Error())
+ }
+ bp.AddPoint(pt)
+}
+
+// Using the BatchPoints setter functions
+func ExampleBatchPoints_setters() {
+ // Create a new point batch
+ bp, _ := client.NewBatchPoints(client.BatchPointsConfig{})
+ bp.SetDatabase("BumbleBeeTuna")
+ bp.SetPrecision("ms")
+
+ // Create a point and add to batch
+ tags := map[string]string{"cpu": "cpu-total"}
+ fields := map[string]interface{}{
+ "idle": 10.1,
+ "system": 53.3,
+ "user": 46.6,
+ }
+ pt, err := client.NewPoint("cpu_usage", tags, fields, time.Now())
+ if err != nil {
+ fmt.Println("Error: ", err.Error())
+ }
+ bp.AddPoint(pt)
+}
+
+// Create a new point with a timestamp
+func ExamplePoint() {
+ tags := map[string]string{"cpu": "cpu-total"}
+ fields := map[string]interface{}{
+ "idle": 10.1,
+ "system": 53.3,
+ "user": 46.6,
+ }
+ pt, err := client.NewPoint("cpu_usage", tags, fields, time.Now())
+ if err == nil {
+ fmt.Println("We created a point: ", pt.String())
+ }
+}
+
+// Create a new point without a timestamp
+func ExamplePoint_withoutTime() {
+ tags := map[string]string{"cpu": "cpu-total"}
+ fields := map[string]interface{}{
+ "idle": 10.1,
+ "system": 53.3,
+ "user": 46.6,
+ }
+ pt, err := client.NewPoint("cpu_usage", tags, fields)
+ if err == nil {
+ fmt.Println("We created a point w/o time: ", pt.String())
+ }
+}
+
+// Write 1000 points
+func ExampleClient_write1000() {
+ sampleSize := 1000
+
+ // Make client
+ c, err := client.NewHTTPClient(client.HTTPConfig{
+ Addr: "http://localhost:8086",
+ })
+ if err != nil {
+ fmt.Println("Error creating InfluxDB Client: ", err.Error())
+ }
+ defer c.Close()
+
+ rand.Seed(42)
+
+ bp, _ := client.NewBatchPoints(client.BatchPointsConfig{
+ Database: "systemstats",
+ Precision: "us",
+ })
+
+ for i := 0; i < sampleSize; i++ {
+ regions := []string{"us-west1", "us-west2", "us-west3", "us-east1"}
+ tags := map[string]string{
+ "cpu": "cpu-total",
+ "host": fmt.Sprintf("host%d", rand.Intn(1000)),
+ "region": regions[rand.Intn(len(regions))],
+ }
+
+ idle := rand.Float64() * 100.0
+ fields := map[string]interface{}{
+ "idle": idle,
+ "busy": 100.0 - idle,
+ }
+
+ pt, err := client.NewPoint(
+ "cpu_usage",
+ tags,
+ fields,
+ time.Now(),
+ )
+ if err != nil {
+ println("Error:", err.Error())
+ continue
+ }
+ bp.AddPoint(pt)
+ }
+
+ err = c.Write(bp)
+ if err != nil {
+ fmt.Println("Error: ", err.Error())
+ }
+}
+
+// Make a Query
+func ExampleClient_query() {
+ // Make client
+ c, err := client.NewHTTPClient(client.HTTPConfig{
+ Addr: "http://localhost:8086",
+ })
+ if err != nil {
+ fmt.Println("Error creating InfluxDB Client: ", err.Error())
+ }
+ defer c.Close()
+
+ q := client.NewQuery("SELECT count(value) FROM shapes", "square_holes", "ns")
+ if response, err := c.Query(q); err == nil && response.Error() == nil {
+ fmt.Println(response.Results)
+ }
+}
+
+// Create a Database with a query
+func ExampleClient_createDatabase() {
+ // Make client
+ c, err := client.NewHTTPClient(client.HTTPConfig{
+ Addr: "http://localhost:8086",
+ })
+ if err != nil {
+ fmt.Println("Error creating InfluxDB Client: ", err.Error())
+ }
+ defer c.Close()
+
+ q := client.NewQuery("CREATE DATABASE telegraf", "", "")
+ if response, err := c.Query(q); err == nil && response.Error() == nil {
+ fmt.Println(response.Results)
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/4563a049/traffic_stats/vendor/github.com/influxdata/influxdb/client/v2/udp.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/influxdata/influxdb/client/v2/udp.go b/traffic_stats/vendor/github.com/influxdata/influxdb/client/v2/udp.go
new file mode 100644
index 0000000..779a28b
--- /dev/null
+++ b/traffic_stats/vendor/github.com/influxdata/influxdb/client/v2/udp.go
@@ -0,0 +1,112 @@
+package client
+
+import (
+ "fmt"
+ "io"
+ "net"
+ "time"
+)
+
+const (
+ // UDPPayloadSize is a reasonable default payload size for UDP packets that
+ // could be travelling over the internet.
+ UDPPayloadSize = 512
+)
+
+// UDPConfig is the config data needed to create a UDP Client.
+type UDPConfig struct {
+ // Addr should be of the form "host:port"
+ // or "[ipv6-host%zone]:port".
+ Addr string
+
+ // PayloadSize is the maximum size of a UDP client message, optional
+ // Tune this based on your network. Defaults to UDPPayloadSize.
+ PayloadSize int
+}
+
+// NewUDPClient returns a client interface for writing to an InfluxDB UDP
+// service from the given config.
+func NewUDPClient(conf UDPConfig) (Client, error) {
+ var udpAddr *net.UDPAddr
+ udpAddr, err := net.ResolveUDPAddr("udp", conf.Addr)
+ if err != nil {
+ return nil, err
+ }
+
+ conn, err := net.DialUDP("udp", nil, udpAddr)
+ if err != nil {
+ return nil, err
+ }
+
+ payloadSize := conf.PayloadSize
+ if payloadSize == 0 {
+ payloadSize = UDPPayloadSize
+ }
+
+ return &udpclient{
+ conn: conn,
+ payloadSize: payloadSize,
+ }, nil
+}
+
+// Close releases the udpclient's resources.
+func (uc *udpclient) Close() error {
+ return uc.conn.Close()
+}
+
+type udpclient struct {
+ conn io.WriteCloser
+ payloadSize int
+}
+
+func (uc *udpclient) Write(bp BatchPoints) error {
+ var b = make([]byte, 0, uc.payloadSize) // initial buffer size, it will grow as needed
+ var d, _ = time.ParseDuration("1" + bp.Precision())
+
+ var delayedError error
+
+ var checkBuffer = func(n int) {
+ if len(b) > 0 && len(b)+n > uc.payloadSize {
+ if _, err := uc.conn.Write(b); err != nil {
+ delayedError = err
+ }
+ b = b[:0]
+ }
+ }
+
+ for _, p := range bp.Points() {
+ p.pt.Round(d)
+ pointSize := p.pt.StringSize() + 1 // include newline in size
+ //point := p.pt.RoundedString(d) + "\n"
+
+ checkBuffer(pointSize)
+
+ if p.Time().IsZero() || pointSize <= uc.payloadSize {
+ b = p.pt.AppendString(b)
+ b = append(b, '\n')
+ continue
+ }
+
+ points := p.pt.Split(uc.payloadSize - 1) // account for newline character
+ for _, sp := range points {
+ checkBuffer(sp.StringSize() + 1)
+ b = sp.AppendString(b)
+ b = append(b, '\n')
+ }
+ }
+
+ if len(b) > 0 {
+ if _, err := uc.conn.Write(b); err != nil {
+ return err
+ }
+ }
+ return delayedError
+}
+
+func (uc *udpclient) Query(q Query) (*Response, error) {
+ return nil, fmt.Errorf("Querying via UDP is not supported")
+}
+
+func (uc *udpclient) Ping(timeout time.Duration) (time.Duration, string, error) {
+ return 0, "", nil
+}