-
Notifications
You must be signed in to change notification settings - Fork 0
/
config.go
162 lines (145 loc) · 4.44 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// Incomplete support for schema description and data generation
// using TOML format as supported by influx_tools in branch 1.7+
package common
import (
"bytes"
"encoding/json"
"fmt"
"github.com/pelletier/go-toml"
"log"
"math/rand"
"net/http"
"reflect"
"strings"
)
type Source interface{}
var DefaultValueGenerator = map[string]interface{}{
"type": "default",
}
func getSourceValue(s *Source, measurementName, itemKey string, itemDefaultValue interface{}) interface{} {
switch reflect.Indirect(reflect.ValueOf(s)).Elem().Kind() {
case reflect.Array:
array := (*s).([]interface{})
return array[rand.Int63n(int64(len(array)))]
case reflect.Map:
m := (*s).(map[string]interface{})
if reflect.DeepEqual(m, DefaultValueGenerator) {
return itemDefaultValue
}
log.Fatalf("generators are not supported (yet) ['%s/%s']", measurementName, itemKey)
default: // primitive types
return *s
}
panic("unreachable")
}
type Tag struct {
Name string
Source Source
}
type Field struct {
Count int
Name string
Source Source
}
type Measurement struct {
Name string
Sample float32
Tags []Tag
Fields []Field
}
type ExternalConfig struct {
measurements []Measurement
}
var Config *ExternalConfig
func (c *ExternalConfig) String() string {
var buf bytes.Buffer
for _,m := range c.measurements {
buf.WriteString(fmt.Sprintf("definition: %s, sample: %f\n", m.Name, m.Sample))
buf.WriteString(fmt.Sprintf(" tags:\n"))
for _,tag := range m.Tags {
buf.WriteString(fmt.Sprintf(" tag: %s\n", tag.Name))
buf.WriteString(fmt.Sprintf(" source: %v\n", tag.Source))
}
buf.WriteString(fmt.Sprintf(" fields:\n"))
for _,field := range m.Fields {
buf.WriteString(fmt.Sprintf(" field: %s, count: %d\n", field.Name, field.Count))
buf.WriteString(fmt.Sprintf(" source: %v\n", field.Source))
}
}
return buf.String()
}
func (c *ExternalConfig) GetTagBytesValue(measurementName, tagKey []byte, failIfNotFound bool, defaultValue []byte) []byte {
return []byte(c.GetTagValue(string(measurementName), string(tagKey), failIfNotFound, string(defaultValue)))
}
func (c *ExternalConfig) GetTagValue(measurementName, tagKey string, failIfNotFound bool, defaultValue string) string {
for _,m := range c.measurements {
if "" == measurementName || m.Name == measurementName {
for _,tag := range m.Tags {
if tag.Name == tagKey {
return fmt.Sprintf("%v", getSourceValue(&tag.Source, m.Name, tag.Name, defaultValue))
}
}
}
}
if failIfNotFound {
log.Fatalf("value for tag '%s/%s' not found", measurementName, tagKey)
}
return "" // defaultValue ?
}
func (c *ExternalConfig) GetFieldBytesValue(measurementName, tagKey []byte, failIfNotFound bool, defaultValue interface{}) interface{} {
return c.GetFieldValue(string(measurementName), string(tagKey), failIfNotFound, defaultValue)
}
func (c *ExternalConfig) GetFieldValue(measurementName, fieldKey string, failIfNotFound bool, defaultValue interface{}) interface{} {
for _,m := range c.measurements {
if "" == measurementName || m.Name == measurementName {
for _,field := range m.Fields {
if field.Name == fieldKey {
return getSourceValue(&field.Source, m.Name, field.Name, defaultValue)
}
}
}
}
if failIfNotFound {
log.Fatalf("value for field '%s/%s' not found", measurementName, fieldKey)
}
return nil // defaultValue ?
}
func NewConfig(path string) (*ExternalConfig, error) {
var tree *toml.Tree
var err error
if strings.HasPrefix(path, "http://") || strings.HasPrefix(path,"https://") {
tree, err = LoadURL(path)
} else {
tree, err = toml.LoadFile(path)
}
if err != nil {
return nil, fmt.Errorf("config loading failed: %v", err)
}
obj := tree.ToMap()["measurements"]
b, err := json.Marshal(obj)
if err != nil {
return nil, fmt.Errorf("config marshall failed: %v", err)
}
config := ExternalConfig{}
err = json.Unmarshal(b, &config.measurements)
if err != nil {
return nil, fmt.Errorf("config unmarshall failed: %v", err)
}
return &config, nil
}
// LoadURL creates a Tree from a URL resource.
func LoadURL(url string) (tree *toml.Tree, err error) {
resp, err := http.Get(url)
if err != nil {
return nil, fmt.Errorf("config loading failed: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusOK {
tree, err := toml.LoadReader(resp.Body)
if err != nil {
return nil, fmt.Errorf("config parsing failed: %v", err)
}
return tree, nil
}
return nil, fmt.Errorf("config loading failed: response status code is: %s", resp.Status)
}