tempoiq 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: cfdc25fdc88fdd73576dd4e68649facbf463be7d
4
- data.tar.gz: 00605f70755dae0ff641342fe726104d446ca4d6
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ OGVkZjI1ZjdiM2QxOTQyMjI2ODUxOWFhM2VmNjRhNTQwZmM4ODY1YQ==
5
+ data.tar.gz: !binary |-
6
+ YjI0NzM1OWQ0NDljYzRjODkxZDcwNGM4YWY4MTNiYTdiZWZkMmM2MA==
5
7
  SHA512:
6
- metadata.gz: 8a52391dfe9959ea2c258baceb688e5e65171cc46a4e1d77f36b0d4d3ba05632cdae3e9feb1ca61e81010febbc8ce6267248aa407a532107eb131f415f208d9f
7
- data.tar.gz: 892f02d33742ed6a08fedcf3f03576c6abe114198778430dc6154818aa995f1a9925287b1f9804a4238b7fc8c6a8258a33af6b19abb9dee1bfd403f32c5500df
8
+ metadata.gz: !binary |-
9
+ OGQzZDg4Mzc3ZDA0NDU5YTJjNzIxOThjOGIzZWVmZThkNDI5NTQzOTFjY2Rh
10
+ M2Y2NDI4OTlkMjM1N2YzOTI2YTFjMWU4OTdkNzFmOWFmZmI4ZTdiYTc0Njc4
11
+ YjEyZjBlMTc4ZDA4MGNhNDQxM2E1NTNiMzk5YjVlYzY3NTJkZjE=
12
+ data.tar.gz: !binary |-
13
+ M2Q0NmQxMDI4ZGNjMzJhYzY1NmI0ZTU1ZGE0MzNhZmRmZjY1ZDYyM2YxNzlm
14
+ NzIxZTIyNWI2NzAwM2JlY2I4MDhjZDE4ZDhiMDc0MDFhMzI4YWIyMzIwOTEy
15
+ YWZmMjMzZmJhMzU3ZGE4YjBkZTk1MzlhZDNjMjIxMmRmNzY2OWE=
@@ -8,7 +8,7 @@ require 'tempoiq/models/datapoint'
8
8
  require 'tempoiq/models/delete_summary'
9
9
  require 'tempoiq/models/device'
10
10
  require 'tempoiq/models/find'
11
- require 'tempoiq/models/multi_status'
11
+ require 'tempoiq/models/write_response'
12
12
  require 'tempoiq/models/pipeline'
13
13
  require 'tempoiq/models/query'
14
14
  require 'tempoiq/models/read'
@@ -148,7 +148,7 @@ module TempoIQ
148
148
  query = Query.new(Search.new("devices", selection),
149
149
  Find.new(opts[:limit]),
150
150
  nil)
151
- Cursor.new(Device, remoter, "/v2/devices", query, media_types(:accept => [media_type("error", "v1"), media_type("device-collection", "v2")],
151
+ Cursor.new(Device, remoter, "/v2/devices", query, media_types(:accept => [media_type("device-collection", "v2"), media_type("error", "v1")],
152
152
  :content => media_type("query", "v1")))
153
153
  end
154
154
 
@@ -233,9 +233,9 @@ module TempoIQ
233
233
  # * +bulk_write+ - The write request to send to the backend. Yielded to the block.
234
234
  #
235
235
  # On success:
236
- # - Returns MultiStatus
236
+ # - Returns WriteResponse
237
237
  # On partial success:
238
- # - Returns MultiStatus
238
+ # - Returns WriteResponse
239
239
  # On failure:
240
240
  # - Raises HttpException
241
241
  #
@@ -263,11 +263,10 @@ module TempoIQ
263
263
  end
264
264
 
265
265
  result = remoter.post("/v2/write", JSON.dump(bulk.to_hash))
266
- if result.code == HttpResult::OK
267
- MultiStatus.new
268
- elsif result.code == HttpResult::MULTI
269
- json = JSON.parse(result.body)
270
- MultiStatus.new(json)
266
+ if result.code == HttpResult::OK || result.code == HttpResult::MULTI
267
+ body = result.body.empty? ? "{}" : result.body
268
+ json = JSON.parse(body)
269
+ WriteResponse.new(json)
271
270
  else
272
271
  raise HttpException.new(result)
273
272
  end
@@ -342,7 +341,7 @@ module TempoIQ
342
341
  Read.new(start, stop, opts[:limit]),
343
342
  pipeline)
344
343
 
345
- Cursor.new(Row, remoter, "/v2/read", query, media_types(:accept => [media_type("error", "v1"), media_type("datapoint-collection", "v2")],
344
+ Cursor.new(Row, remoter, "/v2/read", query, media_types(:accept => [media_type("datapoint-collection", "v2"), media_type("error", "v1")],
346
345
  :content => media_type("query", "v1")))
347
346
  end
348
347
 
@@ -409,7 +408,7 @@ module TempoIQ
409
408
  Single.new(function, timestamp),
410
409
  pipeline)
411
410
 
412
- Cursor.new(Row, remoter, "/v2/single", query, media_types(:accept => [media_type("error", "v1"), media_type("datapoint-collection", "v1")],
411
+ Cursor.new(Row, remoter, "/v2/single", query, media_types(:accept => [media_type("datapoint-collection", "v1"), media_type("error", "v1")],
413
412
  :content => media_type("query", "v1")))
414
413
  end
415
414
 
@@ -1,6 +1,6 @@
1
1
  module TempoIQ
2
2
  module Constants
3
- VERSION = "1.0.2"
3
+ VERSION = "1.0.3"
4
4
  TRUSTED_CERT_FILE = File.join(File.dirname(__FILE__), "..", "trusted-certs.crt")
5
5
  end
6
6
  end
@@ -0,0 +1,58 @@
1
+ module TempoIQ
2
+ # WriteResponse is used to track the status of a write. Because writes
3
+ # are bulk in nature (writing to multiple devices and sensors at once),
4
+ # there are instances where some writes device writes may succeed and
5
+ # some might fail in the same write call.
6
+ #
7
+ # [High level introspection]
8
+ # - #success?
9
+ # - #partial_success?
10
+ #
11
+ # [Device level introspection]
12
+ # - #failures
13
+ # - #created
14
+ # - #existing
15
+ # - #modified
16
+ class WriteResponse
17
+ attr_reader :status
18
+
19
+ def initialize(status = nil)
20
+ @status = status
21
+ end
22
+
23
+ # Was the write a total success?
24
+ def success?
25
+ status.each do |key,device_status|
26
+ if device_status['successful'] == false
27
+ return false
28
+ end
29
+ end
30
+ true
31
+ end
32
+
33
+ # Did the write have partial failures?
34
+ def partial_success?
35
+ !success?
36
+ end
37
+
38
+ # Retrieve the failures, key => message [Hash]
39
+ def failures
40
+ status.select { |device_key, v| v["successful"] == false }
41
+ end
42
+
43
+ # Devices that already existed before the write
44
+ def existing
45
+ status.select { |device_key, v| v["device_state"] == "existing" }
46
+ end
47
+
48
+ # Devices that were created during the write
49
+ def created
50
+ status.select { |device_key, v| v["device_state"] == "created" }
51
+ end
52
+
53
+ # Devices that were modified (eg - sensors added) during the write
54
+ def modified
55
+ status.select { |device_key, v| v["device_state"] == "modified" }
56
+ end
57
+ end
58
+ end
@@ -140,7 +140,14 @@ module ClientTest
140
140
  device_key = device.key
141
141
  sensor_key = device.sensors.first.key
142
142
 
143
- client.remoter.stub(:post, "/v2/write", 200)
143
+ stubbed_body = {"device1" =>
144
+ {"success" => true,
145
+ "message" => nil,
146
+ "device_state" => "existing"
147
+ }
148
+ }
149
+
150
+ client.remoter.stub(:post, "/v2/write", 207, JSON.dump(stubbed_body))
144
151
 
145
152
  status = client.write_bulk do |write|
146
153
  write.add(device_key, sensor_key, TempoIQ::DataPoint.new(ts, 1.23))
@@ -158,25 +165,48 @@ module ClientTest
158
165
  end
159
166
  end
160
167
 
161
- def test_write_with_partial_failure
162
- device = create_device
168
+ def test_write_with_upsert
169
+ device1 = create_device
170
+ device2 = create_device(key="device2")
163
171
  client = get_client
164
172
  ts = Time.utc(2012, 1, 1)
165
173
 
166
- device_key = device.key
167
- sensor_key = device.sensors.first.key
174
+ device_key1 = device1.key
175
+ sensor_key = device1.sensors.first.key
176
+ device_key2 = device2.key
177
+ device_key3 = "device3"
168
178
 
169
- stubbed_body = {"device1" => {"success" => false, "message" => "error writing to storage: FERR_NO_SENSOR: No sensor with key found in device."}}
179
+ stubbed_body = {"device1" =>
180
+ {"success" => true,
181
+ "message" => nil,
182
+ "device_state" => "existing"
183
+ },
184
+ "device2" =>
185
+ {"success" => true,
186
+ "message" => nil,
187
+ "device_state" => "modified"
188
+ },
189
+ "device3" =>
190
+ {"success" => true,
191
+ "message" => nil,
192
+ "device_state" => "created"
193
+ }
194
+ }
170
195
  client.remoter.stub(:post, "/v2/write", 207, JSON.dump(stubbed_body))
171
196
 
172
197
  status = client.write_bulk do |write|
173
- write.add(device_key, sensor_key, TempoIQ::DataPoint.new(ts, 1.23))
174
- write.add(device_key, "not_here", TempoIQ::DataPoint.new(ts, 2.34))
198
+ write.add(device_key1, sensor_key, TempoIQ::DataPoint.new(ts, 1.23))
199
+ write.add(device_key2, "not_here", TempoIQ::DataPoint.new(ts, 2.34))
200
+ write.add(device_key3, "not_here", TempoIQ::DataPoint.new(ts, 2.34))
175
201
  end
176
202
 
177
- assert(!status.success?)
178
- assert(status.partial_success?)
179
- assert_equal(1, status.failures.size)
203
+ assert(status.success?)
204
+ assert_equal(1, status.existing.size)
205
+ assert_equal("device1", status.existing.keys.first)
206
+ assert_equal(1, status.modified.size)
207
+ assert_equal("device2", status.modified.keys.first)
208
+ assert_equal(1, status.created.size)
209
+ assert_equal("device3", status.created.keys.first)
180
210
  end
181
211
 
182
212
  def test_write_device
@@ -187,7 +217,14 @@ module ClientTest
187
217
  device_key = device.key
188
218
  sensor_key = device.sensors.first.key
189
219
 
190
- client.remoter.stub(:post, "/v2/write", 200)
220
+ stubbed_body = {"device1" =>
221
+ {"success" => true,
222
+ "message" => nil,
223
+ "device_state" => "existing"
224
+ }
225
+ }
226
+
227
+ client.remoter.stub(:post, "/v2/write", 207, JSON.dump(stubbed_body))
191
228
 
192
229
  written = client.write_device(device_key, ts, sensor_key => 1.23)
193
230
 
@@ -204,9 +241,16 @@ module ClientTest
204
241
  device_key = device.key
205
242
  sensor_key1 = device.sensors[0].key
206
243
  sensor_key2 = device.sensors[1].key
207
-
208
- client.remoter.stub(:post, "/v2/write", 200)
209
244
 
245
+ stubbed_body = {"device1" =>
246
+ {"success" => true,
247
+ "message" => nil,
248
+ "device_state" => "existing"
249
+ }
250
+ }
251
+
252
+ client.remoter.stub(:post, "/v2/write", 207, JSON.dump(stubbed_body))
253
+
210
254
  write_result = client.write_device(device_key, Time.utc(2012, 1, 1, 1), sensor_key1 => 4.0, sensor_key2 => 2.0)
211
255
  assert_equal(true, write_result)
212
256
  write_result = client.write_device(device_key, Time.utc(2012, 1, 1, 2), sensor_key1 => 4.0, sensor_key2 => 2.0)
@@ -248,7 +292,14 @@ module ClientTest
248
292
  device_key = device.key
249
293
  sensor_key = device.sensors[0].key
250
294
 
251
- client.remoter.stub(:post, "/v2/write", 200)
295
+ stubbed_body = {"device1" =>
296
+ {"success" => true,
297
+ "message" => nil,
298
+ "device_state" => "existing"
299
+ }
300
+ }
301
+
302
+ client.remoter.stub(:post, "/v2/write", 207, JSON.dump(stubbed_body))
252
303
 
253
304
  write_result = client.write_device(device_key, Time.utc(2012, 1, 1, 1, 0, 5, 0), sensor_key => 4.0)
254
305
  assert_equal(true, write_result)
@@ -330,8 +381,14 @@ module ClientTest
330
381
 
331
382
  device_key = device.key
332
383
  sensor_key = device.sensors[0].key
384
+ stubbed_body = {"device1" =>
385
+ {"success" => true,
386
+ "message" => nil,
387
+ "device_state" => "existing"
388
+ }
389
+ }
333
390
 
334
- client.remoter.stub(:post, "/v2/write", 200)
391
+ client.remoter.stub(:post, "/v2/write", 207, JSON.dump(stubbed_body))
335
392
 
336
393
  write_result = client.write_device(device_key, ts, sensor_key => 4.0)
337
394
  assert_equal(true, write_result)
@@ -372,7 +429,14 @@ module ClientTest
372
429
  sensor_key1 = device.sensors[0].key
373
430
  sensor_key2 = device.sensors[1].key
374
431
 
375
- client.remoter.stub(:post, "/v2/write", 200)
432
+ stubbed_body = {"device1" =>
433
+ {"success" => true,
434
+ "message" => nil,
435
+ "device_state" => "existing"
436
+ }
437
+ }
438
+
439
+ client.remoter.stub(:post, "/v2/write", 207, JSON.dump(stubbed_body))
376
440
 
377
441
  write_result = client.write_device(device_key, ts, sensor_key1 => 4.0, sensor_key2 => 2.0)
378
442
  assert_equal(true, write_result)
@@ -416,8 +480,15 @@ module ClientTest
416
480
  sensor_key1 = device.sensors[0].key
417
481
  sensor_key2 = device.sensors[1].key
418
482
 
419
- client.remoter.stub(:post, "/v2/write", 200)
420
- client.remoter.stub(:post, "/v2/write", 200)
483
+ stubbed_body = {"device1" =>
484
+ {"success" => true,
485
+ "message" => nil,
486
+ "device_state" => "existing"
487
+ }
488
+ }
489
+
490
+ client.remoter.stub(:post, "/v2/write", 207, JSON.dump(stubbed_body))
491
+ client.remoter.stub(:post, "/v2/write", 207, JSON.dump(stubbed_body))
421
492
 
422
493
  assert_equal(true, client.write_device(device_key, ts, sensor_key1 => 4.0, sensor_key2 => 2.0))
423
494
  assert_equal(true, client.write_device(device_key, ts2, sensor_key1 => 4.0, sensor_key2 => 2.0))
@@ -510,7 +581,14 @@ module ClientTest
510
581
  }
511
582
 
512
583
  client.remoter.stub(:get, "/v2/single", 200, JSON.dump(stubbed_single))
513
- client.remoter.stub(:post, "/v2/write", 200)
584
+ stubbed_body = {"device1" =>
585
+ {"success" => true,
586
+ "message" => nil,
587
+ "device_state" => "existing"
588
+ }
589
+ }
590
+
591
+ client.remoter.stub(:post, "/v2/write", 207, JSON.dump(stubbed_body))
514
592
 
515
593
  client.write_bulk do |write|
516
594
  write.add(device_key, sensor_key1, TempoIQ::DataPoint.new(ts, 4.0))
@@ -553,7 +631,14 @@ module ClientTest
553
631
  }
554
632
 
555
633
  client.remoter.stub(:get, "/v2/single", 200, JSON.dump(stubbed_single))
556
- client.remoter.stub(:post, "/v2/write", 200)
634
+ stubbed_body = {"device1" =>
635
+ {"success" => true,
636
+ "message" => nil,
637
+ "device_state" => "existing"
638
+ }
639
+ }
640
+
641
+ client.remoter.stub(:post, "/v2/write", 207, JSON.dump(stubbed_body))
557
642
 
558
643
  client.write_bulk do |write|
559
644
  write.add(device_key, sensor_key1, TempoIQ::DataPoint.new(ts, 4.0))
@@ -598,7 +683,14 @@ module ClientTest
598
683
  }
599
684
 
600
685
  client.remoter.stub(:get, "/v2/single", 200, JSON.dump(stubbed_single))
601
- client.remoter.stub(:post, "/v2/write", 200)
686
+ stubbed_body = {"device1" =>
687
+ {"success" => true,
688
+ "message" => nil,
689
+ "device_state" => "existing"
690
+ }
691
+ }
692
+
693
+ client.remoter.stub(:post, "/v2/write", 207, JSON.dump(stubbed_body))
602
694
 
603
695
  client.write_bulk do |write|
604
696
  write.add(device_key, sensor_key1, TempoIQ::DataPoint.new(ts_before, 4.0))
@@ -643,7 +735,14 @@ module ClientTest
643
735
  }
644
736
 
645
737
  client.remoter.stub(:get, "/v2/single", 200, JSON.dump(stubbed_single))
646
- client.remoter.stub(:post, "/v2/write", 200)
738
+ stubbed_body = {"device1" =>
739
+ {"success" => true,
740
+ "message" => nil,
741
+ "device_state" => "existing"
742
+ }
743
+ }
744
+
745
+ client.remoter.stub(:post, "/v2/write", 207, JSON.dump(stubbed_body))
647
746
 
648
747
  client.write_bulk do |write|
649
748
  write.add(device_key, sensor_key1, TempoIQ::DataPoint.new(ts, 4.0))
@@ -686,7 +785,14 @@ module ClientTest
686
785
  }
687
786
 
688
787
  client.remoter.stub(:get, "/v2/single", 200, JSON.dump(stubbed_single))
689
- client.remoter.stub(:post, "/v2/write", 200)
788
+ stubbed_body = {"device1" =>
789
+ {"success" => true,
790
+ "message" => nil,
791
+ "device_state" => "existing"
792
+ }
793
+ }
794
+
795
+ client.remoter.stub(:post, "/v2/write", 207, JSON.dump(stubbed_body))
690
796
 
691
797
  client.write_bulk do |write|
692
798
  write.add(device_key, sensor_key1, TempoIQ::DataPoint.new(ts, 4.0))
@@ -729,7 +835,14 @@ module ClientTest
729
835
  }
730
836
 
731
837
  client.remoter.stub(:get, "/v2/single", 200, JSON.dump(stubbed_single))
732
- client.remoter.stub(:post, "/v2/write", 200)
838
+ stubbed_body = {"device1" =>
839
+ {"success" => true,
840
+ "message" => nil,
841
+ "device_state" => "existing"
842
+ }
843
+ }
844
+
845
+ client.remoter.stub(:post, "/v2/write", 207, JSON.dump(stubbed_body))
733
846
 
734
847
  client.write_bulk do |write|
735
848
  write.add(device_key, sensor_key1, TempoIQ::DataPoint.new(ts, 4.0))
@@ -757,7 +870,14 @@ module ClientTest
757
870
 
758
871
  ts = Time.utc(2012, 1, 1)
759
872
 
760
- client.remoter.stub(:post, "/v2/write", 200)
873
+ stubbed_body = {"device1" =>
874
+ {"success" => true,
875
+ "message" => nil,
876
+ "device_state" => "existing"
877
+ }
878
+ }
879
+
880
+ client.remoter.stub(:post, "/v2/write", 207, JSON.dump(stubbed_body))
761
881
 
762
882
  client.write_bulk do |write|
763
883
  write.add(device_key, sensor_key1, TempoIQ::DataPoint.new(ts, 4.0))
@@ -847,6 +967,7 @@ module ClientTest
847
967
  }
848
968
 
849
969
  client.remoter.stub(:delete, "/v2/devices", 200, JSON.dump(stubbed_body))
850
- summary = client.delete_devices(:devices => {:attribute_key => TEMPO_TEST_ATTR})
970
+ summary1 = client.delete_devices(:devices => {:attribute_key => TEMPO_TEST_ATTR})
971
+ summary2 = client.delete_devices(:devices => {:key => "device3"})
851
972
  end
852
973
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tempoiq
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - TempoIQ Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-07 00:00:00.000000000 Z
11
+ date: 2015-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: test-unit
@@ -59,7 +59,7 @@ dependencies:
59
59
  - - ~>
60
60
  - !ruby/object:Gem::Version
61
61
  version: '2.4'
62
- - - '>='
62
+ - - ! '>='
63
63
  - !ruby/object:Gem::Version
64
64
  version: 2.4.0
65
65
  type: :runtime
@@ -69,7 +69,7 @@ dependencies:
69
69
  - - ~>
70
70
  - !ruby/object:Gem::Version
71
71
  version: '2.4'
72
- - - '>='
72
+ - - ! '>='
73
73
  - !ruby/object:Gem::Version
74
74
  version: 2.4.0
75
75
  - !ruby/object:Gem::Dependency
@@ -105,7 +105,6 @@ files:
105
105
  - lib/tempoiq/models/delete_summary.rb
106
106
  - lib/tempoiq/models/device.rb
107
107
  - lib/tempoiq/models/find.rb
108
- - lib/tempoiq/models/multi_status.rb
109
108
  - lib/tempoiq/models/pipeline.rb
110
109
  - lib/tempoiq/models/query.rb
111
110
  - lib/tempoiq/models/read.rb
@@ -114,6 +113,7 @@ files:
114
113
  - lib/tempoiq/models/selection.rb
115
114
  - lib/tempoiq/models/sensor.rb
116
115
  - lib/tempoiq/models/single.rb
116
+ - lib/tempoiq/models/write_response.rb
117
117
  - lib/tempoiq/remoter/http_result.rb
118
118
  - lib/tempoiq/remoter/live_remoter.rb
119
119
  - lib/tempoiq/remoter/stubbed_remoter.rb
@@ -134,12 +134,12 @@ require_paths:
134
134
  - lib
135
135
  required_ruby_version: !ruby/object:Gem::Requirement
136
136
  requirements:
137
- - - '>='
137
+ - - ! '>='
138
138
  - !ruby/object:Gem::Version
139
139
  version: '0'
140
140
  required_rubygems_version: !ruby/object:Gem::Requirement
141
141
  requirements:
142
- - - '>='
142
+ - - ! '>='
143
143
  - !ruby/object:Gem::Version
144
144
  version: '0'
145
145
  requirements: []
@@ -1,27 +0,0 @@
1
- module TempoIQ
2
- # MultiStatus is used in cases where an operation might partially succeed
3
- # and partially fail. It provides several helper functions to introspect the
4
- # failure and take appropriate action. (Log failure, resend DataPoints, etc.)
5
- class MultiStatus
6
- attr_reader :status
7
-
8
- def initialize(status = nil)
9
- @status = status
10
- end
11
-
12
- # Was the request a total success?
13
- def success?
14
- status.nil?
15
- end
16
-
17
- # Did the request have partial failures?
18
- def partial_success?
19
- !success?
20
- end
21
-
22
- # Retrieve the failures, key => message [Hash]
23
- def failures
24
- Hash[status.map { |device_key, v| [device_key, v["message"]] } ]
25
- end
26
- end
27
- end