influxdb-client 1.2.0.pre.591 → 1.3.0.pre.716

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: ab9dc109c0da3edd23cb1d54412a102e47f21a2c149c359637051be8aa9b894f
4
- data.tar.gz: c2985b21be98321a305fe68dc4ffa40fcb89b5456605ca014c24767de4563085
3
+ metadata.gz: 0c1a5b7d8cbd5e2eaab2671332a11643b6ca8a8ee8498dcba18221ccd977c264
4
+ data.tar.gz: 2739279c947e40774385ab5e74db30efa149e3679085b431359cdf38bd78283d
5
5
  SHA512:
6
- metadata.gz: d83d15691520858955c0f800d9cc753c2a5a1f83e2321fbab81068a576e9cd20b8146c39309d9ba3d5b1ee97030396d43da27a8f34e342286da13b27b4f555be
7
- data.tar.gz: 4c5ad67e4d11d4665881ea29f42e09b2d3d7800a62b2e664cce202d4c61144d55028f21de1e0f9581e64a3b80d96ed701e2739e0c39a9ba5b8fe2828a19f0076
6
+ metadata.gz: 9bd655b519db1270283620fa7130eb2a9b30c0127dcf4aa73f8f5a5ef84572a5091abb263b35cad299c13221272643fd7eeb07c113189100015ef93dcaa49fd3
7
+ data.tar.gz: 45c0a04e7c8d75f89d3ef733aa0a0e31f7a51dbf7a4ce2e5a08cb880627873901018a875671d790e1b0f48c6a9812fe9394e9f11325a55a966e443c32ff1f35a
@@ -27,7 +27,7 @@ AllCops:
27
27
  Metrics/LineLength:
28
28
  Max: 120
29
29
  Metrics/MethodLength:
30
- Max: 30
30
+ Max: 50
31
31
  Metrics/ClassLength:
32
32
  Max: 200
33
33
  Metrics/AbcSize:
@@ -1,12 +1,22 @@
1
- ## 1.2.0 [unreleased]
1
+ ## 1.3.0 [unreleased]
2
+
3
+ ### Features
4
+ 1. [#32](https://github.com/influxdata/influxdb-client-ruby/pull/32): Checks the health of a running InfluxDB instance by querying the /health
5
+
6
+ ## 1.2.0 [2020-03-13]
2
7
 
3
8
  ### Features
4
9
  1. [#23](https://github.com/influxdata/influxdb-client-ruby/issues/23): Added DeleteApi to delete time series data from InfluxDB.
5
10
  1. [#24](https://github.com/influxdata/influxdb-client-ruby/issues/24): Added jitter_interval and retry_interval to WriteApi
6
11
  1. [#26](https://github.com/influxdata/influxdb-client-ruby/issues/26): Set User-Agent to influxdb-client-ruby/VERSION for all requests
7
12
 
13
+ ### Security
14
+ 1. [#29](https://github.com/influxdata/influxdb-client-ruby/pull/29): Upgrade rake to version 12.3.3 - [CVE-2020-8130](https://github.com/advisories/GHSA-jppv-gw3r-w3q8)
15
+
8
16
  ### Bugs
9
17
  1. [#22](https://github.com/influxdata/influxdb-client-ruby/pull/22): Fixed batch write
18
+ 1. [#28](https://github.com/influxdata/influxdb-client-ruby/pull/28): Correctly parse CSV where multiple results include multiple tables
19
+ 1. [#30](https://github.com/influxdata/influxdb-client-ruby/pull/30): Send Content-Type headers
10
20
 
11
21
  ## 1.1.0 [2020-02-14]
12
22
 
data/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  This repository contains the reference Ruby client for the InfluxDB 2.0.
12
12
 
13
- #### Note: This library is for use with InfluxDB 2.x. For connecting to InfluxDB 1.x instances, please use the [influxdb-ruby](https://github.com/influxdata/influxdb-ruby) client.
13
+ #### Note: Use this client library with InfluxDB 2.x and InfluxDB 1.8+. For connecting to InfluxDB 1.7 or earlier instances, use the [influxdb-ruby](https://github.com/influxdata/influxdb-ruby) client library.
14
14
 
15
15
  ## Installation
16
16
 
@@ -23,7 +23,7 @@ The client can be installed manually or with bundler.
23
23
  To install the client gem manually:
24
24
 
25
25
  ```
26
- gem install influxdb-client -v 1.1.0
26
+ gem install influxdb-client -v 1.2.0
27
27
  ```
28
28
 
29
29
  ## Usage
@@ -231,6 +231,12 @@ The time range could be specified as:
231
231
  1. DateTime - `DateTime.rfc3339('2019-03-03T04:05:06+07:00')`
232
232
  1. Time - `Time.utc(2015, 10, 16, 8, 20, 15)`
233
233
 
234
+ ## Advanced Usage
235
+
236
+ ### Check the server status
237
+
238
+ Server availability can be checked using the `client.health` method. That is equivalent of the [influx ping](https://v2.docs.influxdata.com/v2.0/reference/cli/influx/ping/).
239
+
234
240
  ## Local tests
235
241
 
236
242
  ```
@@ -16,7 +16,7 @@ mkdir -p "${SCRIPT_PATH}"/../lib/influxdb2/client/models
16
16
  mv "${SCRIPT_PATH}"/../lib/influx_db2/models/* "${SCRIPT_PATH}"/../lib/influxdb2/client/models
17
17
 
18
18
  cd "${SCRIPT_PATH}"/../lib/influxdb2/client/models || exit
19
- rm -r $(ls | grep -v "\<dialect.rb\>\|\<query.rb\>\|\<delete_predicate_request.rb\>")
19
+ rm -r $(ls | grep -v "\<health_check.rb\>\|\<dialect.rb\>\|\<query.rb\>\|\<delete_predicate_request.rb\>")
20
20
 
21
21
  # Clean
22
22
  rmdir "${SCRIPT_PATH}"/../lib/influx_db2/models
@@ -46,7 +46,7 @@ Gem::Specification.new do |spec|
46
46
  spec.add_development_dependency 'codecov', '~> 0.1.16'
47
47
  spec.add_development_dependency 'minitest', '~> 5.0'
48
48
  spec.add_development_dependency 'minitest-reporters', '~> 1.4'
49
- spec.add_development_dependency 'rake', '~> 10.0'
49
+ spec.add_development_dependency 'rake', '>= 12.3.3'
50
50
  spec.add_development_dependency 'rubocop', '~> 0.66.0'
51
51
  spec.add_development_dependency 'simplecov', '~> 0.17.1'
52
52
  spec.add_development_dependency 'webmock', '~> 3.7'
@@ -25,5 +25,6 @@ require 'influxdb2/client/influx_error'
25
25
  require 'influxdb2/client/write_api'
26
26
  require 'influxdb2/client/query_api'
27
27
  require 'influxdb2/client/delete_api'
28
+ require 'influxdb2/client/health_api'
28
29
  require 'influxdb2/client/point'
29
30
  require 'influxdb2/client/flux_table'
@@ -77,6 +77,13 @@ module InfluxDB2
77
77
  DeleteApi.new(options: @options)
78
78
  end
79
79
 
80
+ # Get the health of an instance.
81
+ #
82
+ # @return [HealthCheck]
83
+ def health
84
+ HealthApi.new(options: @options).health
85
+ end
86
+
80
87
  # Close all connections into InfluxDB 2.
81
88
  #
82
89
  # @return [ true ] Always true.
@@ -24,6 +24,8 @@ module InfluxDB2
24
24
  DEFAULT_TIMEOUT = 10
25
25
  DEFAULT_REDIRECT_COUNT = 10
26
26
 
27
+ HEADER_CONTENT_TYPE = 'Content-Type'.freeze
28
+
27
29
  # @param [Hash] options The options to be used by the client.
28
30
  def initialize(options:)
29
31
  @options = options
@@ -32,7 +34,25 @@ module InfluxDB2
32
34
 
33
35
  private
34
36
 
35
- def _post(payload, uri, limit = @max_redirect_count)
37
+ def _post_json(payload, uri, headers: {})
38
+ _check_arg_type(:headers, headers, Hash)
39
+ _post(payload, uri, headers: headers.merge(HEADER_CONTENT_TYPE => 'application/json'))
40
+ end
41
+
42
+ def _post_text(payload, uri, headers: {})
43
+ _check_arg_type(:headers, headers, Hash)
44
+ _post(payload, uri, headers: headers.merge(HEADER_CONTENT_TYPE => 'text/plain'))
45
+ end
46
+
47
+ def _post(payload, uri, limit: @max_redirect_count, headers: {})
48
+ _request(payload, uri, limit: limit, headers: headers, request: Net::HTTP::Post)
49
+ end
50
+
51
+ def _get(uri, limit: @max_redirect_count, headers: {})
52
+ _request(nil, uri, limit: limit, headers: headers.merge('Accept' => 'application/json'), request: Net::HTTP::Get)
53
+ end
54
+
55
+ def _request(payload, uri, limit: @max_redirect_count, headers: {}, request: Net::HTTP::Post)
36
56
  raise InfluxError.from_message("Too many HTTP redirects. Exceeded limit: #{@max_redirect_count}") if limit.zero?
37
57
 
38
58
  http = Net::HTTP.new(uri.host, uri.port)
@@ -41,9 +61,11 @@ module InfluxDB2
41
61
  http.read_timeout = @options[:read_timeout] || DEFAULT_TIMEOUT
42
62
  http.use_ssl = @options[:use_ssl].nil? ? true : @options[:use_ssl]
43
63
 
44
- request = Net::HTTP::Post.new(uri.request_uri)
64
+ request = request.new(uri.request_uri)
45
65
  request['Authorization'] = "Token #{@options[:token]}"
46
66
  request['User-Agent'] = "influxdb-client-ruby/#{InfluxDB2::VERSION}"
67
+ headers.each { |k, v| request[k] = v }
68
+
47
69
  request.body = payload
48
70
 
49
71
  begin
@@ -53,7 +75,7 @@ module InfluxDB2
53
75
  response
54
76
  when Net::HTTPRedirection then
55
77
  location = response['location']
56
- _post(payload, URI.parse(location), limit - 1)
78
+ _post(payload, URI.parse(location), limit: limit - 1, headers: headers)
57
79
  else
58
80
  raise InfluxError.from_response(response)
59
81
  end
@@ -62,6 +84,10 @@ module InfluxDB2
62
84
  end
63
85
  end
64
86
 
87
+ def _check_arg_type(name, value, klass)
88
+ raise TypeError, "expected a #{klass.name} for #{name}; got #{value.class.name}" unless value.is_a?(klass)
89
+ end
90
+
65
91
  def _check(key, value)
66
92
  raise ArgumentError, "The '#{key}' should be defined as argument or default option: #{@options}" if value.nil?
67
93
  end
@@ -64,7 +64,7 @@ module InfluxDB2
64
64
  uri = URI.parse(File.join(@options[:url], '/api/v2/delete'))
65
65
  uri.query = URI.encode_www_form(org: org_param, bucket: bucket_param)
66
66
 
67
- _post(delete_request.to_body.to_json, uri)
67
+ _post_json(delete_request.to_body.to_json, uri)
68
68
  end
69
69
 
70
70
  def _to_rfc3339(time)
@@ -51,6 +51,7 @@ module InfluxDB2
51
51
  @tables = {}
52
52
 
53
53
  @table_index = 0
54
+ @table_id = -1
54
55
  @start_new_table = false
55
56
  @table = nil
56
57
  @parsing_state_error = false
@@ -113,6 +114,7 @@ module InfluxDB2
113
114
  @tables[@table_index] = @table unless @stream
114
115
 
115
116
  @table_index += 1
117
+ @table_id = -1
116
118
  elsif @table.nil?
117
119
  raise FluxCsvParserError, 'Unable to parse CSV response. FluxTable definition was not found.'
118
120
  end
@@ -173,9 +175,10 @@ module InfluxDB2
173
175
  return
174
176
  end
175
177
 
176
- @current_index = csv[2].to_i
178
+ current_id = csv[2].to_i
179
+ @table_id = current_id if @table_id == -1
177
180
 
178
- if @current_index > (@table_index - 1)
181
+ if @table_id != current_id
179
182
  # create new table with previous column headers settings
180
183
  @flux_columns = @table.columns
181
184
  @table = InfluxDB2::FluxTable.new
@@ -186,6 +189,7 @@ module InfluxDB2
186
189
 
187
190
  @tables[@table_index] = @table unless @stream
188
191
  @table_index += 1
192
+ @table_id = current_id
189
193
  end
190
194
 
191
195
  flux_record = _parse_record(@table_index - 1, @table, csv)
@@ -0,0 +1,49 @@
1
+ # The MIT License
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+ require_relative 'models/health_check'
21
+
22
+ module InfluxDB2
23
+ # The client of the InfluxDB 2.0 that implement Health HTTP API endpoint.
24
+ #
25
+ class HealthApi < DefaultApi
26
+ # @param [Hash] options The options to be used by the client.
27
+ def initialize(options:)
28
+ super(options: options)
29
+ end
30
+
31
+ # Get the health of an instance.
32
+ #
33
+ # @return [HealthCheck]
34
+ def health
35
+ uri = URI.parse(File.join(@options[:url], '/health'))
36
+ body = _get(uri).body
37
+ data = JSON.parse("[#{body}]", symbolize_names: true)[0]
38
+ HealthCheck.new.tap do |model|
39
+ model.build_from_hash data
40
+ end
41
+ rescue StandardError => e
42
+ HealthCheck.new.tap do |model|
43
+ model.name = 'influxdb'
44
+ model.status = 'fail'
45
+ model.message = e.message
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,256 @@
1
+ =begin
2
+ #Influx API Service
3
+
4
+ #No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
5
+
6
+ OpenAPI spec version: 0.1.0
7
+
8
+ Generated by: https://openapi-generator.tech
9
+ OpenAPI Generator version: 3.3.4
10
+
11
+ =end
12
+
13
+ require 'date'
14
+
15
+ module InfluxDB2
16
+ class HealthCheck
17
+ attr_accessor :name
18
+
19
+ attr_accessor :message
20
+
21
+ attr_accessor :checks
22
+
23
+ attr_accessor :status
24
+
25
+ class EnumAttributeValidator
26
+ attr_reader :datatype
27
+ attr_reader :allowable_values
28
+
29
+ def initialize(datatype, allowable_values)
30
+ @allowable_values = allowable_values.map do |value|
31
+ case datatype.to_s
32
+ when /Integer/i
33
+ value.to_i
34
+ when /Float/i
35
+ value.to_f
36
+ else
37
+ value
38
+ end
39
+ end
40
+ end
41
+
42
+ def valid?(value)
43
+ !value || allowable_values.include?(value)
44
+ end
45
+ end
46
+
47
+ # Attribute mapping from ruby-style variable name to JSON key.
48
+ def self.attribute_map
49
+ {
50
+ :'name' => :'name',
51
+ :'message' => :'message',
52
+ :'checks' => :'checks',
53
+ :'status' => :'status'
54
+ }
55
+ end
56
+
57
+ # Attribute type mapping.
58
+ def self.openapi_types
59
+ {
60
+ :'name' => :'String',
61
+ :'message' => :'String',
62
+ :'checks' => :'Array<HealthCheck>',
63
+ :'status' => :'String'
64
+ }
65
+ end
66
+
67
+ # Initializes the object
68
+ # @param [Hash] attributes Model attributes in the form of hash
69
+ def initialize(attributes = {})
70
+ return unless attributes.is_a?(Hash)
71
+
72
+ # convert string to symbol for hash key
73
+ attributes = attributes.each_with_object({}) { |(k, v), h| h[k.to_sym] = v }
74
+
75
+ if attributes.has_key?(:'name')
76
+ self.name = attributes[:'name']
77
+ end
78
+
79
+ if attributes.has_key?(:'message')
80
+ self.message = attributes[:'message']
81
+ end
82
+
83
+ if attributes.has_key?(:'checks')
84
+ if (value = attributes[:'checks']).is_a?(Array)
85
+ self.checks = value
86
+ end
87
+ end
88
+
89
+ if attributes.has_key?(:'status')
90
+ self.status = attributes[:'status']
91
+ end
92
+ end
93
+
94
+ # Show invalid properties with the reasons. Usually used together with valid?
95
+ # @return Array for valid properties with the reasons
96
+ def list_invalid_properties
97
+ invalid_properties = Array.new
98
+ if @name.nil?
99
+ invalid_properties.push('invalid value for "name", name cannot be nil.')
100
+ end
101
+
102
+ if @status.nil?
103
+ invalid_properties.push('invalid value for "status", status cannot be nil.')
104
+ end
105
+
106
+ invalid_properties
107
+ end
108
+
109
+ # Check to see if the all the properties in the model are valid
110
+ # @return true if the model is valid
111
+ def valid?
112
+ return false if @name.nil?
113
+ return false if @status.nil?
114
+ status_validator = EnumAttributeValidator.new('String', ['pass', 'fail'])
115
+ return false unless status_validator.valid?(@status)
116
+ true
117
+ end
118
+
119
+ # Custom attribute writer method checking allowed values (enum).
120
+ # @param [Object] status Object to be assigned
121
+ def status=(status)
122
+ validator = EnumAttributeValidator.new('String', ['pass', 'fail'])
123
+ unless validator.valid?(status)
124
+ fail ArgumentError, 'invalid value for "status", must be one of #{validator.allowable_values}.'
125
+ end
126
+ @status = status
127
+ end
128
+
129
+ # Checks equality by comparing each attribute.
130
+ # @param [Object] Object to be compared
131
+ def ==(o)
132
+ return true if self.equal?(o)
133
+ self.class == o.class &&
134
+ name == o.name &&
135
+ message == o.message &&
136
+ checks == o.checks &&
137
+ status == o.status
138
+ end
139
+
140
+ # @see the `==` method
141
+ # @param [Object] Object to be compared
142
+ def eql?(o)
143
+ self == o
144
+ end
145
+
146
+ # Calculates hash code according to all attributes.
147
+ # @return [Fixnum] Hash code
148
+ def hash
149
+ [name, message, checks, status].hash
150
+ end
151
+
152
+ # Builds the object from hash
153
+ # @param [Hash] attributes Model attributes in the form of hash
154
+ # @return [Object] Returns the model itself
155
+ def build_from_hash(attributes)
156
+ return nil unless attributes.is_a?(Hash)
157
+ self.class.openapi_types.each_pair do |key, type|
158
+ if type =~ /\AArray<(.*)>/i
159
+ # check to ensure the input is an array given that the the attribute
160
+ # is documented as an array but the input is not
161
+ if attributes[self.class.attribute_map[key]].is_a?(Array)
162
+ self.send("#{key}=", attributes[self.class.attribute_map[key]].map { |v| _deserialize($1, v) })
163
+ end
164
+ elsif !attributes[self.class.attribute_map[key]].nil?
165
+ self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]]))
166
+ end # or else data not found in attributes(hash), not an issue as the data can be optional
167
+ end
168
+
169
+ self
170
+ end
171
+
172
+ # Deserializes the data based on type
173
+ # @param string type Data type
174
+ # @param string value Value to be deserialized
175
+ # @return [Object] Deserialized data
176
+ def _deserialize(type, value)
177
+ case type.to_sym
178
+ when :DateTime
179
+ DateTime.parse(value)
180
+ when :Date
181
+ Date.parse(value)
182
+ when :String
183
+ value.to_s
184
+ when :Integer
185
+ value.to_i
186
+ when :Float
187
+ value.to_f
188
+ when :BOOLEAN
189
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
190
+ true
191
+ else
192
+ false
193
+ end
194
+ when :Object
195
+ # generic object (usually a Hash), return directly
196
+ value
197
+ when /\AArray<(?<inner_type>.+)>\z/
198
+ inner_type = Regexp.last_match[:inner_type]
199
+ value.map { |v| _deserialize(inner_type, v) }
200
+ when /\AHash<(?<k_type>.+?), (?<v_type>.+)>\z/
201
+ k_type = Regexp.last_match[:k_type]
202
+ v_type = Regexp.last_match[:v_type]
203
+ {}.tap do |hash|
204
+ value.each do |k, v|
205
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
206
+ end
207
+ end
208
+ else # model
209
+ temp_model = InfluxDB2.const_get(type).new
210
+ temp_model.build_from_hash(value)
211
+ end
212
+ end
213
+
214
+ # Returns the string representation of the object
215
+ # @return [String] String presentation of the object
216
+ def to_s
217
+ to_hash.to_s
218
+ end
219
+
220
+ # to_body is an alias to to_hash (backward compatibility)
221
+ # @return [Hash] Returns the object in the form of hash
222
+ def to_body
223
+ to_hash
224
+ end
225
+
226
+ # Returns the object in the form of hash
227
+ # @return [Hash] Returns the object in the form of hash
228
+ def to_hash
229
+ hash = {}
230
+ self.class.attribute_map.each_pair do |attr, param|
231
+ value = self.send(attr)
232
+ next if value.nil?
233
+ hash[param] = _to_hash(value)
234
+ end
235
+ hash
236
+ end
237
+
238
+ # Outputs non-array value in the form of hash
239
+ # For object, use to_hash. Otherwise, just return the value
240
+ # @param [Object] value Any valid value
241
+ # @return [Hash] Returns the value in the form of hash
242
+ def _to_hash(value)
243
+ if value.is_a?(Array)
244
+ value.compact.map { |v| _to_hash(v) }
245
+ elsif value.is_a?(Hash)
246
+ {}.tap do |hash|
247
+ value.each { |k, v| hash[k] = _to_hash(v) }
248
+ end
249
+ elsif value.respond_to? :to_hash
250
+ value.to_hash
251
+ else
252
+ value
253
+ end
254
+ end
255
+ end
256
+ end
@@ -73,7 +73,7 @@ module InfluxDB2
73
73
  uri = URI.parse(File.join(@options[:url], '/api/v2/query'))
74
74
  uri.query = URI.encode_www_form(org: org_param)
75
75
 
76
- _post(payload.to_body.to_json, uri)
76
+ _post_json(payload.to_body.to_json, uri)
77
77
  end
78
78
 
79
79
  def _generate_payload(query, dialect)
@@ -19,5 +19,5 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module InfluxDB2
22
- VERSION = '1.2.0'.freeze
22
+ VERSION = '1.3.0'.freeze
23
23
  end
@@ -163,7 +163,7 @@ module InfluxDB2
163
163
  uri = URI.parse(File.join(@options[:url], '/api/v2/write'))
164
164
  uri.query = URI.encode_www_form(bucket: bucket_param, org: org_param, precision: precision_param.to_s)
165
165
 
166
- _post(payload, uri)
166
+ _post_text(payload, uri)
167
167
  end
168
168
 
169
169
  # Item for batching queue
@@ -21,6 +21,10 @@
21
21
  require 'test_helper'
22
22
 
23
23
  class ClientTest < Minitest::Test
24
+ def setup
25
+ WebMock.allow_net_connect!
26
+ end
27
+
24
28
  def test_defined_version_number
25
29
  refute_nil ::InfluxDB2::VERSION
26
30
  end
@@ -67,4 +71,22 @@ class ClientTest < Minitest::Test
67
71
  refute_nil write_api
68
72
  assert_instance_of InfluxDB2::WriteApi, write_api
69
73
  end
74
+
75
+ def test_health
76
+ client = InfluxDB2::Client.new('http://localhost:9999', 'my-token', use_ssl: false)
77
+
78
+ health = client.health
79
+ assert_equal 'ready for queries and writes', health.message
80
+ assert_equal 'influxdb', health.name
81
+ assert_equal 'pass', health.status
82
+ end
83
+
84
+ def test_health_not_running
85
+ client_not_running = InfluxDB2::Client.new('http://localhost:8099', 'my-token', use_ssl: false)
86
+ health = client_not_running.health
87
+
88
+ assert_match 'Failed to open TCP connection to localhost:8099', health.message
89
+ assert_equal 'influxdb', health.name
90
+ assert_equal 'fail', health.status
91
+ end
70
92
  end
@@ -112,7 +112,8 @@ class DeleteApiTest < MiniTest::Test
112
112
  body = '{"start":"2019-02-03T04:05:06+07:00","stop":"2019-04-03T04:05:06+07:00"}'
113
113
  headers = {
114
114
  'Authorization' => 'Token my-token',
115
- 'User-Agent' => "influxdb-client-ruby/#{InfluxDB2::VERSION}"
115
+ 'User-Agent' => "influxdb-client-ruby/#{InfluxDB2::VERSION}",
116
+ 'Content-Type' => 'application/json'
116
117
  }
117
118
  assert_requested(:post, 'http://localhost:9999/api/v2/delete?bucket=my-bucket&org=my-org',
118
119
  times: 1, body: body, headers: headers)
@@ -323,4 +323,79 @@ class FluxCsvParserErrorTest < MiniTest::Test
323
323
 
324
324
  assert_equal 'Unable to parse CSV response. FluxTable definition was not found.', error.message
325
325
  end
326
+
327
+ def test_multiple_queries
328
+ data = "#datatype,string,long,string,string,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,double,string\n" \
329
+ "#group,false,false,true,true,true,true,false,false,true\n" \
330
+ "#default,t1,,,,,,,,\n" \
331
+ ",result,table,_field,_measurement,_start,_stop,_time,_value,tag\n" \
332
+ ",,0,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:20:00Z,2,test1\n" \
333
+ ",,0,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:21:40Z,2,test1\n" \
334
+ ",,0,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:23:20Z,2,test1\n" \
335
+ ",,0,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:25:00Z,2,test1\n" \
336
+ ",,0,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:26:40Z,2,test1\n" \
337
+ ",,0,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:28:20Z,2,test1\n" \
338
+ ",,0,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:30:00Z,2,test1\n" \
339
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:20:00Z,2,test2\n" \
340
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:21:40Z,2,test2\n" \
341
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:23:20Z,2,test2\n" \
342
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:25:00Z,2,test2\n" \
343
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:26:40Z,2,test2\n" \
344
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:28:20Z,2,test2\n" \
345
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:30:00Z,2,test2\n" \
346
+ "\n" \
347
+ "#datatype,string,long,string,string,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,double,string\n" \
348
+ "#group,false,false,true,true,true,true,false,false,true\n" \
349
+ "#default,t2,,,,,,,,\n" \
350
+ ",result,table,_field,_measurement,_start,_stop,_time,_value,tag\n" \
351
+ ",,0,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:20:00Z,2,test1\n" \
352
+ ",,0,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:21:40Z,2,test1\n" \
353
+ ",,0,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:23:20Z,2,test1\n" \
354
+ ",,0,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:25:00Z,2,test1\n" \
355
+ ",,0,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:26:40Z,2,test1\n" \
356
+ ",,0,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:28:20Z,2,test1\n" \
357
+ ",,0,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:30:00Z,2,test1\n" \
358
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:20:00Z,2,test2\n" \
359
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:21:40Z,2,test2\n" \
360
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:23:20Z,2,test2\n" \
361
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:25:00Z,2,test2\n" \
362
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:26:40Z,2,test2\n" \
363
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:28:20Z,2,test2\n" \
364
+ ',,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:30:00Z,2,test2'
365
+
366
+ tables = InfluxDB2::FluxCsvParser.new(data).parse.tables
367
+
368
+ assert_equal 4, tables.size
369
+ assert_equal 7, tables[0].records.size
370
+ assert_equal 7, tables[1].records.size
371
+ assert_equal 7, tables[2].records.size
372
+ assert_equal 7, tables[3].records.size
373
+ end
374
+
375
+ def test_table_not_start_at_zero
376
+ data = "#datatype,string,long,string,string,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,double,string\n" \
377
+ "#group,false,false,true,true,true,true,false,false,true\n" \
378
+ "#default,t1,,,,,,,,\n" \
379
+ ",result,table,_field,_measurement,_start,_stop,_time,_value,tag\n" \
380
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:20:00Z,2,test1\n" \
381
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:21:40Z,2,test1\n" \
382
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:23:20Z,2,test1\n" \
383
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:25:00Z,2,test1\n" \
384
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:26:40Z,2,test1\n" \
385
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:28:20Z,2,test1\n" \
386
+ ",,1,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:30:00Z,2,test1\n" \
387
+ ",,2,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:20:00Z,2,test2\n" \
388
+ ",,2,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:21:40Z,2,test2\n" \
389
+ ",,2,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:23:20Z,2,test2\n" \
390
+ ",,2,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:25:00Z,2,test2\n" \
391
+ ",,2,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:26:40Z,2,test2\n" \
392
+ ",,2,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:28:20Z,2,test2\n" \
393
+ ',,2,value,pct,2010-02-27T04:48:32.752600083Z,2020-02-27T16:48:32.752600083Z,2020-02-27T16:30:00Z,2,test2\n'
394
+
395
+ tables = InfluxDB2::FluxCsvParser.new(data).parse.tables
396
+
397
+ assert_equal 2, tables.size
398
+ assert_equal 7, tables[0].records.size
399
+ assert_equal 7, tables[1].records.size
400
+ end
326
401
  end
@@ -73,7 +73,7 @@ class QueryApiTest < MiniTest::Test
73
73
  assert_equal 'free', record1.field
74
74
  end
75
75
 
76
- def test_user_agent_header
76
+ def test_headers
77
77
  stub_request(:post, 'http://localhost:9999/api/v2/query?org=my-org')
78
78
  .to_return(body: SUCCESS_DATA)
79
79
 
@@ -87,7 +87,8 @@ class QueryApiTest < MiniTest::Test
87
87
 
88
88
  headers = {
89
89
  'Authorization' => 'Token my-token',
90
- 'User-Agent' => "influxdb-client-ruby/#{InfluxDB2::VERSION}"
90
+ 'User-Agent' => "influxdb-client-ruby/#{InfluxDB2::VERSION}",
91
+ 'Content-Type' => 'application/json'
91
92
  }
92
93
  assert_requested(:post, 'http://localhost:9999/api/v2/query?org=my-org',
93
94
  times: 1, headers: headers)
@@ -61,6 +61,7 @@ class WriteApiIntegrationTest < MiniTest::Test
61
61
  uri = URI.parse('http://localhost:9999/api/v2/query?org=my-org')
62
62
  request = Net::HTTP::Post.new(uri.request_uri)
63
63
  request['Authorization'] = 'Token my-token'
64
+ request[InfluxDB2::DefaultApi::HEADER_CONTENT_TYPE] = 'application/json'
64
65
  request.body = query.to_json
65
66
 
66
67
  http = Net::HTTP.new(uri.host, uri.port)
@@ -252,7 +252,7 @@ class WriteApiTest < MiniTest::Test
252
252
  assert_equal 'The time precision not_supported is not supported.', error.message
253
253
  end
254
254
 
255
- def test_user_agent_header
255
+ def test_headers
256
256
  stub_request(:any, 'http://localhost:9999/api/v2/write?bucket=my-bucket&org=my-org&precision=ns')
257
257
  .to_return(status: 204)
258
258
 
@@ -266,7 +266,8 @@ class WriteApiTest < MiniTest::Test
266
266
 
267
267
  headers = {
268
268
  'Authorization' => 'Token my-token',
269
- 'User-Agent' => "influxdb-client-ruby/#{InfluxDB2::VERSION}"
269
+ 'User-Agent' => "influxdb-client-ruby/#{InfluxDB2::VERSION}",
270
+ 'Content-Type' => 'text/plain'
270
271
  }
271
272
  assert_requested(:post, 'http://localhost:9999/api/v2/write?bucket=my-bucket&org=my-org&precision=ns',
272
273
  times: 1, body: 'h2o,location=west value=33i 15', headers: headers)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: influxdb-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0.pre.591
4
+ version: 1.3.0.pre.716
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jakub Bednar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-27 00:00:00.000000000 Z
11
+ date: 2020-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -70,16 +70,16 @@ dependencies:
70
70
  name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '10.0'
75
+ version: 12.3.3
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '10.0'
82
+ version: 12.3.3
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rubocop
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -152,9 +152,11 @@ files:
152
152
  - lib/influxdb2/client/delete_api.rb
153
153
  - lib/influxdb2/client/flux_csv_parser.rb
154
154
  - lib/influxdb2/client/flux_table.rb
155
+ - lib/influxdb2/client/health_api.rb
155
156
  - lib/influxdb2/client/influx_error.rb
156
157
  - lib/influxdb2/client/models/delete_predicate_request.rb
157
158
  - lib/influxdb2/client/models/dialect.rb
159
+ - lib/influxdb2/client/models/health_check.rb
158
160
  - lib/influxdb2/client/models/query.rb
159
161
  - lib/influxdb2/client/point.rb
160
162
  - lib/influxdb2/client/query_api.rb