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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 62b3d49ea7a138d6f1f9e99e0b8f776dcc0212ea24e8fba1bc35a2876f466951
4
- data.tar.gz: 4fecccfff86f73b5b9ab5f647294bb5b866b465bfcc2f59c1991722da5cc0b68
3
+ metadata.gz: a18d9fbe5a1507dfde899dc0bf467a6148ae7bda7ed58995854ecc372ef4efa5
4
+ data.tar.gz: 32cf0fa8b1433d55c7f79da8767ed7de1b8d1daa66f8c1e409d6b8978914c938
5
5
  SHA512:
6
- metadata.gz: 7be9867552f0c0cc2cf66cdea3295b6c02c41909d92c645178244b256b4a67079f595ead4a48c91c33a116ba4323498001665ea9e089d68b37941c1618111a7e
7
- data.tar.gz: 7bc22d498ec484b7466853e5ca550554f6567769596417b41f086e515fb58ac20b62b2074638cebee00a7f0c5af396dce8f68684b098374407d673338d6749e7
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
- puts error
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
- puts error
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
- query_api = self.connection.create_query_api
14
- query_api.query(query_expression)
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
- puts error
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
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = 'persistence-providers'
3
- spec.version = '0.0.3.5'
3
+ spec.version = '0.0.3.6'
4
4
  spec.author = 'Reactor8'
5
5
  spec.email = 'support@reactor8.com'
6
6
  spec.description = %q{Persistence providers plugin}
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.5
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-12 00:00:00.000000000 Z
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