persistence-providers 0.0.3.5 → 0.0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/state/component/providers/influxdb.rb +3 -2
- data/lib/state/component/providers/influxdb/client.rb +7 -3
- data/lib/state/component/providers/influxdb/measurement.rb +1 -1
- data/lib/state/component/providers/influxdb/semantictype.rb +221 -0
- data/persistence-providers.gemspec +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a18d9fbe5a1507dfde899dc0bf467a6148ae7bda7ed58995854ecc372ef4efa5
|
4
|
+
data.tar.gz: 32cf0fa8b1433d55c7f79da8767ed7de1b8d1daa66f8c1e409d6b8978914c938
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bebb1b072b268c17fff5e2430e37b4fa8dd771cbbdb10930d3e7cf852c008d1d4d49c5f30a5fcce8afa9930da6e06707c9c7bfe3d58f12c13c2101ecf55ec15a
|
7
|
+
data.tar.gz: 05126ad2c6f92ab855877e71929cf00f6955e21873b6782a9805c05884ec6e0e08ad53bdb7314589039acef82b96abf8bf376557252314aacefda8359c3c4070
|
@@ -3,6 +3,7 @@ module DTK::State
|
|
3
3
|
class Influxdb < self
|
4
4
|
require_relative('influxdb/client')
|
5
5
|
require_relative('influxdb/measurement')
|
6
|
+
require_relative('influxdb/semantictype')
|
6
7
|
|
7
8
|
attr_reader :client, :measurement
|
8
9
|
|
@@ -49,7 +50,7 @@ module DTK::State
|
|
49
50
|
}
|
50
51
|
measurement.write(value_to_write.to_s, required_tags, timestamp)
|
51
52
|
rescue => error
|
52
|
-
|
53
|
+
fail error
|
53
54
|
end
|
54
55
|
end
|
55
56
|
|
@@ -80,7 +81,7 @@ module DTK::State
|
|
80
81
|
}
|
81
82
|
measurement.write(value_to_write.to_s, required_tags, timestamp)
|
82
83
|
rescue => error
|
83
|
-
|
84
|
+
fail error
|
84
85
|
end
|
85
86
|
end
|
86
87
|
|
@@ -10,8 +10,12 @@ module DTK::State
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def query(query_expression)
|
13
|
-
|
14
|
-
|
13
|
+
begin
|
14
|
+
query_api = self.connection.create_query_api
|
15
|
+
query_api.query(query_expression)
|
16
|
+
rescue => error
|
17
|
+
fail "Failed in query"
|
18
|
+
end
|
15
19
|
end
|
16
20
|
|
17
21
|
def write_point(data)
|
@@ -28,7 +32,7 @@ module DTK::State
|
|
28
32
|
klass = Measurement.const_get(measurement_name.to_sym.capitalize)
|
29
33
|
klass.new(measurement_name, self)
|
30
34
|
rescue => error
|
31
|
-
|
35
|
+
fail error
|
32
36
|
end
|
33
37
|
end
|
34
38
|
|
@@ -23,7 +23,7 @@ module DTK::State
|
|
23
23
|
begin
|
24
24
|
check_params_hash(params_hash)
|
25
25
|
flux_query = 'from(bucket:"' + client.connection_parameters[:bucket] + '") |> range(start:-5) |> filter(fn: (r) => r._measurement == "' + name.to_s + '")' + flux_filter(params_hash) + ' |> last()' + '|> drop(columns: ["_start", "_stop", "_field", "_measurement", "attribute_name", "assembly_name", "task_id", "component_name", "namespace"])'
|
26
|
-
result = self.client.query(flux_query)
|
26
|
+
result = self.client.query(query: flux_query)
|
27
27
|
result.values.map(&:records).flatten.map(&:values)
|
28
28
|
rescue => error
|
29
29
|
fail error
|
@@ -0,0 +1,221 @@
|
|
1
|
+
module DTK::State
|
2
|
+
class Component::Attribute::Influxdb
|
3
|
+
class SemanticType
|
4
|
+
require_relative './client'
|
5
|
+
attr_reader :name, :crd_content, :namespace, :client
|
6
|
+
attr_accessor :content_to_write
|
7
|
+
|
8
|
+
def initialize(name, namespace)
|
9
|
+
@name = name
|
10
|
+
@namespace = namespace
|
11
|
+
@client = Client.new
|
12
|
+
@crd_content = get(name, namespace)
|
13
|
+
@content_to_write = []
|
14
|
+
end
|
15
|
+
|
16
|
+
# no namespace because semantictype instances are going to be unique in cluster
|
17
|
+
def get(name, namespace, opts = {})
|
18
|
+
begin
|
19
|
+
semantictype = ::DTK::CrdClient.get_kubeclient(opts).get_semantictype(name, namespace)
|
20
|
+
semantictype.spec[:openAPIV3Schema]
|
21
|
+
rescue => error
|
22
|
+
fail "SemanticType attribute with name '#{name}' not found on the cluster!. Error: #{error}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def write_semantictype_inventory(inventory, component_id)
|
27
|
+
begin
|
28
|
+
get_influxdb_properties(inventory)
|
29
|
+
content_to_write.each do |point|
|
30
|
+
point[:tags].merge!({ component_id: component_id, attribute_name: @name })
|
31
|
+
@client.write_point({
|
32
|
+
name: point[:name],
|
33
|
+
tags: point[:tags],
|
34
|
+
fields: point[:fields],
|
35
|
+
time: (Time.new.to_f * 1000).to_i
|
36
|
+
})
|
37
|
+
end
|
38
|
+
"Inventory for attribute #{name} written to InfluxDB"
|
39
|
+
rescue => error
|
40
|
+
fail "#{name} inventory write failed. Error: #{error}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def partial_write_update(component_and_attribute, path, field_name, field_value)
|
45
|
+
parent, child = validate_parameter(path)
|
46
|
+
component_id, attribute_name = component_and_attribute.split('/')
|
47
|
+
# getting previous value for given parameters
|
48
|
+
previous_value = { }
|
49
|
+
begin
|
50
|
+
flux_query = 'from(bucket:"' + @client.connection_parameters[:bucket] + '") |> range(start:-5) |> filter(fn:(r) => r._measurement == "' + attribute_name + "_" + child[:type] + '") |> filter(fn: (r) => r.parent == "' + parent[:name] + '") |> filter(fn: (r) => r.name == "' + child[:name] + '")|> last()'
|
51
|
+
result = @client.query(query: flux_query)
|
52
|
+
previous_value = result.values.map(&:records).flatten.map(&:values)
|
53
|
+
rescue => error
|
54
|
+
fail "Partial write could not be completed. Previous point for given parameters not found!"
|
55
|
+
end
|
56
|
+
update_current(previous_value[0], get_path_to_object(path), field_name, field_value)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def update_current(previous_value, path, field_name, field_value)
|
62
|
+
tags = { }
|
63
|
+
previous_value.each_pair do |key, value|
|
64
|
+
tags[key] = value if key[0..0] != "_" && key != "result" && key != "table"
|
65
|
+
end
|
66
|
+
fields = Hash.new
|
67
|
+
fields[field_name.to_sym] = field_value
|
68
|
+
validate_fields(get_partial_definition(path), fields)
|
69
|
+
@client.write_point({
|
70
|
+
name: previous_value["_measurement"],
|
71
|
+
tags: tags,
|
72
|
+
fields: fields,
|
73
|
+
time: (Time.new.to_f * 1000).to_i
|
74
|
+
})
|
75
|
+
"Partial write update successful"
|
76
|
+
end
|
77
|
+
|
78
|
+
def get_influxdb_properties(inventory, parent_type = [:top], parent_name = nil)
|
79
|
+
content_to_write = []
|
80
|
+
properties = { }
|
81
|
+
inventory.each_pair do |key, value|
|
82
|
+
if value.class.to_s == "Array"
|
83
|
+
inventory[key].each do |element|
|
84
|
+
get_influxdb_properties(element, parent_type.push(key), inventory[:name])
|
85
|
+
end
|
86
|
+
else
|
87
|
+
properties[key] = value
|
88
|
+
end
|
89
|
+
end
|
90
|
+
resolve_property(parent_type, parent_name, properties)
|
91
|
+
parent_type.pop
|
92
|
+
"Attribute successfully validated!"
|
93
|
+
end
|
94
|
+
|
95
|
+
def resolve_property(parent_type, parent_name, properties)
|
96
|
+
definition = get_partial_definition(parent_type)
|
97
|
+
request = get_tags_and_fields(definition, properties)
|
98
|
+
validate_request(definition, request)
|
99
|
+
request[:name] = name + "_" + parent_type.last.to_s
|
100
|
+
request[:tags][:parent] = parent_name unless parent_name.nil?
|
101
|
+
content_to_write.push(request)
|
102
|
+
end
|
103
|
+
|
104
|
+
def validate_request(partial_definition, request)
|
105
|
+
begin
|
106
|
+
validate_tags(partial_definition, request[:tags])
|
107
|
+
validate_fields(partial_definition, request[:fields])
|
108
|
+
rescue => error
|
109
|
+
fail error
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def get_tags_and_fields(partial_definition, properties)
|
114
|
+
tags = { }
|
115
|
+
fields = { }
|
116
|
+
properties.each_pair do |key, value|
|
117
|
+
if partial_definition[key].nil?
|
118
|
+
fail "Property '#{key}' not found in the definition of attribute"
|
119
|
+
else
|
120
|
+
if partial_definition[key][:metric].nil? || partial_definition[key][:metric] == false
|
121
|
+
tags[key] = value
|
122
|
+
else
|
123
|
+
fields[key] = value
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
{
|
128
|
+
tags: tags,
|
129
|
+
fields: fields
|
130
|
+
}
|
131
|
+
end
|
132
|
+
|
133
|
+
def validate_fields(partial_definition, fields)
|
134
|
+
|
135
|
+
partial_definition.each_pair do |key, value|
|
136
|
+
next if key == :required || value[:metric] == (false || nil)
|
137
|
+
|
138
|
+
if fields[key].nil?
|
139
|
+
fail "Field #{key} is missing. Validation of request failed!"
|
140
|
+
elsif value[:type].capitalize != fields[key].class.to_s
|
141
|
+
fail "Defined type for SemanticType attribute property '#{key}' is #{value[:type].capitalize}, #{fields[key].class} provided"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def validate_tags(partial_definition, tags)
|
147
|
+
partial_definition.each_pair do |key, value|
|
148
|
+
next if key == :required || value[:metric] == true
|
149
|
+
|
150
|
+
if tags[key].nil?
|
151
|
+
if value[:default].nil?
|
152
|
+
fail "Property #{key} is missing. Validation of request failed!"
|
153
|
+
else
|
154
|
+
tags[key] = value[:default]
|
155
|
+
end
|
156
|
+
else
|
157
|
+
type = tags[key].class
|
158
|
+
type = "Boolean" if type == TrueClass || type == FalseClass
|
159
|
+
if value[:type].capitalize == type.to_s
|
160
|
+
next
|
161
|
+
else
|
162
|
+
fail "Defined type for SemanticType attribute property '#{key}' is #{value[:type].capitalize}, #{type} provided"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def get_partial_definition(path)
|
169
|
+
i = 0
|
170
|
+
definition = { }
|
171
|
+
semantictype_crd = crd_content[:properties]
|
172
|
+
while i < path.length
|
173
|
+
if path[i].to_sym == :top
|
174
|
+
semantictype_crd.each_pair do |key, value|
|
175
|
+
if key == :required
|
176
|
+
definition[key] = value
|
177
|
+
else
|
178
|
+
definition[key] = value if value[:type] != "array"
|
179
|
+
end
|
180
|
+
end
|
181
|
+
else
|
182
|
+
definition = {}
|
183
|
+
definition[:required] = semantictype_crd[path[i].to_sym][:items][:required]
|
184
|
+
semantictype_crd[path[i].to_sym][:items][:properties].each_pair do |key, value|
|
185
|
+
definition[key] = value if value[:type] != "array"
|
186
|
+
end
|
187
|
+
semantictype_crd = semantictype_crd[path[i].to_sym][:items][:properties]
|
188
|
+
end
|
189
|
+
i+=1
|
190
|
+
end
|
191
|
+
definition
|
192
|
+
end
|
193
|
+
|
194
|
+
def get_path_to_object(parameter)
|
195
|
+
path = ["top"]
|
196
|
+
array = parameter.split('/')
|
197
|
+
array.each do |element|
|
198
|
+
path.push(element.split(':')[1])
|
199
|
+
end
|
200
|
+
path
|
201
|
+
end
|
202
|
+
|
203
|
+
def validate_parameter(parameter)
|
204
|
+
array_of_parameters = []
|
205
|
+
begin
|
206
|
+
parameter.split('/').each_with_index do |param, index|
|
207
|
+
name, type = param.split(':')
|
208
|
+
fail unless name && type
|
209
|
+
array_of_parameters.push({
|
210
|
+
name: name,
|
211
|
+
type: type
|
212
|
+
})
|
213
|
+
end
|
214
|
+
array_of_parameters
|
215
|
+
rescue => error
|
216
|
+
fail "Could not resolve parameter '#{parameter}'. It should be in format: 'parent:type/child:type'"
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: persistence-providers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.3.
|
4
|
+
version: 0.0.3.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Reactor8
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05-
|
11
|
+
date: 2020-05-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: kubeclient
|
@@ -70,6 +70,7 @@ files:
|
|
70
70
|
- lib/state/component/providers/influxdb/measurement/errors.rb
|
71
71
|
- lib/state/component/providers/influxdb/measurement/events.rb
|
72
72
|
- lib/state/component/providers/influxdb/measurement/states.rb
|
73
|
+
- lib/state/component/providers/influxdb/semantictype.rb
|
73
74
|
- lib/state/component/providers/kube_crd.rb
|
74
75
|
- lib/state/component_def.rb
|
75
76
|
- lib/state/component_def/attribute_type_info.rb
|