my_john_deere_api 2.3.7 → 2.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/lib/my_john_deere_api.rb +1 -0
  3. data/lib/my_john_deere_api/client.rb +13 -3
  4. data/lib/my_john_deere_api/net_http_retry.rb +2 -0
  5. data/lib/my_john_deere_api/net_http_retry/decorator.rb +53 -0
  6. data/lib/my_john_deere_api/net_http_retry/max_retries_exceeded_error.rb +20 -0
  7. data/lib/my_john_deere_api/version.rb +1 -1
  8. data/test/lib/my_john_deere_api/client_test.rb +20 -3
  9. data/test/lib/my_john_deere_api/errors/max_retries_exceeded_error_test.rb +13 -0
  10. data/test/lib/my_john_deere_api/net_http_retry/decorator_test.rb +163 -0
  11. data/test/support/helper.rb +1 -0
  12. data/test/support/vcr/accessor/delete_failed.yml +327 -0
  13. data/test/support/vcr/accessor/delete_max_failed.yml +615 -0
  14. data/test/support/vcr/accessor/delete_retry.yml +191 -0
  15. data/test/support/vcr/accessor/delete_retry_too_soon.yml +191 -0
  16. data/test/support/vcr/accessor/get_failed.yml +390 -0
  17. data/test/support/vcr/accessor/get_max_failed.yml +734 -0
  18. data/test/support/vcr/accessor/get_retry.yml +226 -0
  19. data/test/support/vcr/accessor/get_retry_too_soon.yml +226 -0
  20. data/test/support/vcr/accessor/post_failed.yml +417 -0
  21. data/test/support/vcr/accessor/post_max_failed.yml +785 -0
  22. data/test/support/vcr/accessor/post_retry.yml +241 -0
  23. data/test/support/vcr/accessor/post_retry_too_soon.yml +241 -0
  24. data/test/support/vcr/accessor/put_failed.yml +372 -0
  25. data/test/support/vcr/accessor/put_max_failed.yml +700 -0
  26. data/test/support/vcr/accessor/put_retry.yml +216 -0
  27. data/test/support/vcr/accessor/put_retry_too_soon.yml +216 -0
  28. metadata +23 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4494019454f9ba67d67a7e26d25dc0c74e0872ba1085635ca2f02591a206cb72
4
- data.tar.gz: e4a48bf533688951723917da61a2e3b2e568d9aafbe1220039ffeadd3428e950
3
+ metadata.gz: 75b86b9b093f4aa0cc586ce56fb961654b1b91577947acf48392d8d2294c85b9
4
+ data.tar.gz: b5879b20c85891180747ba42657ffa399da981596820c813a7049d680240dd39
5
5
  SHA512:
6
- metadata.gz: f2b0c778f634a120cbb5af43b4e583f2b8e86bedf593083716ae7942792f2502e2658601fae1129f99a158ca2ec68facaedbcda190347b2068704a31923acd30
7
- data.tar.gz: 737f85d452fdf4720467369a680f358bddb5d7a7d6d57ba03e092a543fa708df08f2ed27fecfc9512bb84d03e1f024d0a2ae37e25f2bb2621a9eadfa7db013c8
6
+ metadata.gz: 6a8c729311baa853f8ae1039573f673cb01cc084d0fc9b662ce592dd1b907a85b153f04d07ebd6bf346558efb708242f5c13f3464f3c4c5b03a4c21a2479c2d9
7
+ data.tar.gz: cf5dd0b1e590baeb06ead7ffeffb4a7501de17b8b56596a297797186f1bc85aa33b196f58f19162f6027e40a27b023f9ad18ad3aa25e07b61fcd383612c0bbaa
@@ -13,4 +13,5 @@ module MyJohnDeereApi
13
13
  autoload :Validators, 'my_john_deere_api/validators'
14
14
 
15
15
  require 'my_john_deere_api/errors'
16
+ require 'my_john_deere_api/net_http_retry'
16
17
  end
@@ -4,10 +4,11 @@ module MyJohnDeereApi
4
4
  include Helpers::CaseConversion
5
5
 
6
6
  attr_accessor :contribution_definition_id
7
- attr_reader :api_key, :api_secret, :access_token, :access_secret
7
+ attr_reader :api_key, :api_secret, :access_token, :access_secret, :http_retry_options
8
8
 
9
9
  DEFAULTS = {
10
- environment: :live
10
+ environment: :live,
11
+ http_retry: {}
11
12
  }
12
13
 
13
14
  ##
@@ -37,6 +38,7 @@ module MyJohnDeereApi
37
38
 
38
39
  self.environment = options[:environment]
39
40
  @contribution_definition_id = options[:contribution_definition_id]
41
+ @http_retry_options = options[:http_retry]
40
42
  end
41
43
 
42
44
  ##
@@ -45,7 +47,15 @@ module MyJohnDeereApi
45
47
 
46
48
  def accessor
47
49
  return @accessor if defined?(@accessor)
48
- @accessor = OAuth::AccessToken.new(consumer.user_get, access_token, access_secret)
50
+
51
+ @accessor = NetHttpRetry::Decorator.new(
52
+ OAuth::AccessToken.new(
53
+ consumer.user_get,
54
+ access_token,
55
+ access_secret
56
+ ),
57
+ http_retry_options
58
+ )
49
59
  end
50
60
 
51
61
  ##
@@ -0,0 +1,2 @@
1
+ require 'my_john_deere_api/net_http_retry/decorator'
2
+ require 'my_john_deere_api/net_http_retry/max_retries_exceeded_error'
@@ -0,0 +1,53 @@
1
+ module MyJohnDeereApi
2
+ module NetHttpRetry
3
+ class Decorator
4
+ attr_reader :object, :request_methods, :retry_delay_exponent, :max_retries, :response_codes
5
+
6
+ DEFAULTS = {
7
+ request_methods: [:get, :post, :put, :delete],
8
+ retry_delay_exponent: 2,
9
+ max_retries: 12,
10
+ response_codes: ['429', '503']
11
+ }
12
+
13
+ def initialize(object, options={})
14
+ @object = object
15
+
16
+ [:request_methods, :retry_delay_exponent, :max_retries].each do |option|
17
+ instance_variable_set(:"@#{option}", options[option] || DEFAULTS[option])
18
+ end
19
+
20
+ @response_codes = (options[:response_codes] || DEFAULTS[:response_codes]).map(&:to_s)
21
+ end
22
+
23
+ def request(method_name, *args)
24
+ retries = 0
25
+ result = object.send(method_name, *args)
26
+
27
+ while response_codes.include?(result.code)
28
+ if retries >= max_retries
29
+ raise MaxRetriesExceededError.new(method_name, "#{result.code} #{result.message}")
30
+ end
31
+
32
+ delay = [result['retry-after'].to_i, retry_delay_exponent ** retries].max
33
+ sleep(delay)
34
+
35
+ result = object.send(method_name, *args)
36
+ retries += 1
37
+ end
38
+
39
+ result
40
+ end
41
+
42
+ private
43
+
44
+ def method_missing(method_name, *args, &block)
45
+ if request_methods.include?(method_name)
46
+ request(method_name, *args)
47
+ else
48
+ object.send(method_name, *args, &block)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,20 @@
1
+ module MyJohnDeereApi
2
+ module NetHttpRetry
3
+ ##
4
+ # This error is used when a single request has exceeded
5
+ # the number of retries allowed by NetHttpRetry::Decorator::MAX_RETRIES.
6
+
7
+ class MaxRetriesExceededError < StandardError
8
+
9
+ ##
10
+ # argument is a string which describes the attempted request
11
+
12
+ def initialize(request_method, response_message)
13
+ message = "Max retries exceeded for #{request_method.to_s.upcase} " +
14
+ "request: #{response_message}"
15
+
16
+ super(message)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,3 +1,3 @@
1
1
  module MyJohnDeereApi
2
- VERSION='2.3.7'
2
+ VERSION='2.4.1'
3
3
  end
@@ -6,7 +6,7 @@ describe 'MyJohnDeereApi::Client' do
6
6
  assert_equal 'thisIsATest', client.send(:camelize, :this_is_a_test)
7
7
  end
8
8
 
9
- describe '#initialize(api_key, api_secret)' do
9
+ describe '#initialize(api_key, api_secret, options={})' do
10
10
  it 'sets the api key/secret' do
11
11
  client = JD::Client.new(api_key, api_secret)
12
12
 
@@ -35,6 +35,23 @@ describe 'MyJohnDeereApi::Client' do
35
35
  client = JD::Client.new(api_key, api_secret, contribution_definition_id: contribution_definition_id)
36
36
  assert_equal contribution_definition_id, client.contribution_definition_id
37
37
  end
38
+
39
+ it 'accepts a list of parameters for NetHttpRetry' do
40
+ custom_retries = JD::NetHttpRetry::Decorator::DEFAULTS[:max_retries] + 10
41
+
42
+ VCR.use_cassette('catalog') do
43
+ new_client = JD::Client.new(
44
+ api_key,
45
+ api_secret,
46
+ contribution_definition_id: contribution_definition_id,
47
+ environment: :sandbox,
48
+ access: [access_token, access_secret],
49
+ http_retry: {max_retries: custom_retries}
50
+ )
51
+
52
+ assert_equal custom_retries, new_client.accessor.max_retries
53
+ end
54
+ end
38
55
  end
39
56
 
40
57
  describe '#contribution_definition_id' do
@@ -130,7 +147,7 @@ describe 'MyJohnDeereApi::Client' do
130
147
 
131
148
  it 'sends the request' do
132
149
  response = VCR.use_cassette('put_asset') { client.put("/assets/#{asset_id}", attributes) }
133
- puts "HASH!! #{response.inspect}" if response.is_a?(Hash)
150
+
134
151
  assert_equal '204', response.code
135
152
  assert_equal 'No Content', response.message
136
153
  end
@@ -199,7 +216,7 @@ describe 'MyJohnDeereApi::Client' do
199
216
 
200
217
  describe '#accessor' do
201
218
  it 'returns an object that can make user-specific requests' do
202
- assert_kind_of OAuth::AccessToken, accessor
219
+ assert_kind_of JD::NetHttpRetry::Decorator, accessor
203
220
  assert_kind_of OAuth::Consumer, accessor.consumer
204
221
  assert_equal access_token, accessor.token
205
222
  assert_equal access_secret, accessor.secret
@@ -0,0 +1,13 @@
1
+ require 'support/helper'
2
+
3
+ describe 'JD::NetHttpRetry::MaxRetriesExceededError' do
4
+ it 'inherits from StandardError' do
5
+ error = JD::NetHttpRetry::MaxRetriesExceededError.new(:get, '503')
6
+ assert_kind_of StandardError, error
7
+ end
8
+
9
+ it 'accepts a request description, and includes in message' do
10
+ message = JD::NetHttpRetry::MaxRetriesExceededError.new(:get, '503 Service Unavailable').message
11
+ assert_equal message, "Max retries exceeded for GET request: 503 Service Unavailable"
12
+ end
13
+ end
@@ -0,0 +1,163 @@
1
+ require 'support/helper'
2
+
3
+ describe 'JD::NetHttpRetry::Decorator' do
4
+ REQUESTS = {
5
+ get: '/',
6
+ post: '/organizations/000000/assets',
7
+ put: '/assets/00000000-0000-0000-0000-000000000000',
8
+ delete: '/assets/00000000-0000-0000-0000-000000000000'
9
+ }
10
+
11
+ REQUEST_METHODS = REQUESTS.keys
12
+
13
+ let(:klass) { JD::NetHttpRetry::Decorator }
14
+ let(:object) { klass.new(mock, options) }
15
+
16
+ let(:options) do
17
+ {
18
+ request_methods: request_methods,
19
+ retry_delay_exponent: retry_delay_exponent,
20
+ max_retries: max_retries,
21
+ response_codes: response_codes
22
+ }
23
+ end
24
+
25
+ let(:request_methods) { nil }
26
+ let(:retry_delay_exponent) { nil }
27
+ let(:max_retries) { nil }
28
+ let(:response_codes) { nil }
29
+
30
+ let(:retry_values) { [13, 17, 19, 23] }
31
+ let(:exponential_retries) { (0..klass::DEFAULTS[:max_retries]-1).map{|i| 2 ** i} }
32
+
33
+ it 'wraps a "net-http"-responsive object' do
34
+ assert_kind_of OAuth::AccessToken, accessor.object
35
+ end
36
+
37
+ describe '#initialize' do
38
+ describe 'when request methods are specified' do
39
+ let(:request_methods) { [:banana, :fana, :fofana] }
40
+
41
+ it 'uses the supplied values' do
42
+ assert_equal request_methods, object.request_methods
43
+ end
44
+ end
45
+
46
+ describe 'when request methods are not specified' do
47
+ it 'uses the default values' do
48
+ assert_equal klass::DEFAULTS[:request_methods], object.request_methods
49
+ end
50
+ end
51
+
52
+ describe 'when retry_delay_exponent is specified' do
53
+ let(:retry_delay_exponent) { 42 }
54
+
55
+ it 'uses the supplied value' do
56
+ assert_equal retry_delay_exponent, object.retry_delay_exponent
57
+ end
58
+ end
59
+
60
+ describe 'when retry_delay_exponent is not specified' do
61
+ it 'uses the default value' do
62
+ assert_equal klass::DEFAULTS[:retry_delay_exponent], object.retry_delay_exponent
63
+ end
64
+ end
65
+
66
+ describe 'when max_retries is specified' do
67
+ let(:max_retries) { 42 }
68
+
69
+ it 'uses the supplied value' do
70
+ assert_equal max_retries, object.max_retries
71
+ end
72
+ end
73
+
74
+ describe 'when max_retries is not specified' do
75
+ it 'uses the default value' do
76
+ assert_equal klass::DEFAULTS[:max_retries], object.max_retries
77
+ end
78
+ end
79
+
80
+ describe 'when response_codes are specified' do
81
+ let(:response_codes) { ['200', '201'] }
82
+
83
+ it 'uses the supplied values' do
84
+ assert_equal response_codes, object.response_codes
85
+ end
86
+ end
87
+
88
+ describe 'when response_codes are specified as integers' do
89
+ let(:response_codes) { [200, 201] }
90
+
91
+ it 'uses the stringified versions of the supplied values' do
92
+ assert_equal response_codes.map(&:to_s), object.response_codes
93
+ end
94
+ end
95
+
96
+ describe 'when response_codes are not specified' do
97
+ it 'uses the default values' do
98
+ assert_equal klass::DEFAULTS[:response_codes], object.response_codes
99
+ end
100
+ end
101
+ end
102
+
103
+ describe "honors Retry-After headers" do
104
+ REQUEST_METHODS.each do |request_method|
105
+ it "in #{request_method.to_s.upcase} requests" do
106
+ retry_values.each do |retry_seconds|
107
+ accessor.expects(:sleep).with(retry_seconds)
108
+ end
109
+
110
+ VCR.use_cassette("accessor/#{request_method}_retry") do
111
+ accessor.send(request_method, REQUESTS[request_method])
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ describe 'employs exponential wait times for automatic retries' do
118
+ REQUEST_METHODS.each do |request_method|
119
+ it "in #{request_method.to_s.upcase} requests" do
120
+ exponential_retries[0,8].each do |retry_seconds|
121
+ accessor.expects(:sleep).with(retry_seconds)
122
+ end
123
+
124
+ VCR.use_cassette("accessor/#{request_method}_failed") do
125
+ accessor.send(request_method, REQUESTS[request_method])
126
+ end
127
+ end
128
+ end
129
+ end
130
+
131
+ describe 'when Retry-After is shorter than exponential wait time' do
132
+ REQUEST_METHODS.each do |request_method|
133
+ it "chooses longer exponential time in #{request_method.to_s.upcase} requests" do
134
+ exponential_retries[0,4].each do |retry_seconds|
135
+ accessor.expects(:sleep).with(retry_seconds)
136
+ end
137
+
138
+ VCR.use_cassette("accessor/#{request_method}_retry_too_soon") do
139
+ accessor.send(request_method, REQUESTS[request_method])
140
+ end
141
+ end
142
+ end
143
+ end
144
+
145
+ describe 'when max retries have been reached' do
146
+ REQUEST_METHODS.each do |request_method|
147
+ it "returns an error for #{request_method.to_s.upcase} requests" do
148
+ exponential_retries.each do |retry_seconds|
149
+ accessor.expects(:sleep).with(retry_seconds)
150
+ end
151
+
152
+ exception = assert_raises(JD::NetHttpRetry::MaxRetriesExceededError) do
153
+ VCR.use_cassette("accessor/#{request_method}_max_failed") do
154
+ accessor.send(request_method, REQUESTS[request_method])
155
+ end
156
+ end
157
+
158
+ expected_error = "Max retries exceeded for #{request_method.to_s.upcase} request: 429 Too Many Requests"
159
+ assert_equal expected_error, exception.message
160
+ end
161
+ end
162
+ end
163
+ end
@@ -4,6 +4,7 @@ require 'dotenv/load'
4
4
  require 'minitest/autorun'
5
5
  require 'minitest/reporters'
6
6
  require 'my_john_deere_api'
7
+ require 'mocha/minitest'
7
8
 
8
9
  require 'support/vcr_setup'
9
10
 
@@ -0,0 +1,327 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: delete
5
+ uri: https://sandboxapi.deere.com/platform/assets/00000000-0000-0000-0000-000000000000
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - application/vnd.deere.axiom.v3+json
12
+ Accept-Encoding:
13
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
14
+ User-Agent:
15
+ - OAuth gem v0.5.4
16
+ Authorization:
17
+ - OAuth oauth_consumer_key="johndeere-0000000000000000000000000000000000000000",
18
+ oauth_nonce="000000000000000000000000000000000000000000", oauth_signature="0000000000000000000000000000",
19
+ oauth_signature_method="HMAC-SHA1", oauth_timestamp="1581334172", oauth_token="00000000-0000-0000-0000-000000000000",
20
+ oauth_version="1.0"
21
+ response:
22
+ status:
23
+ code: 429
24
+ message: Too Many Requests
25
+ headers:
26
+ Date:
27
+ - Mon, 10 Feb 2020 17:29:36 GMT
28
+ X-Deere-Handling-Server:
29
+ - ip-10-214-45-99
30
+ X-Frame-Options:
31
+ - SAMEORIGIN
32
+ X-Deere-Elapsed-Ms:
33
+ - '96'
34
+ body:
35
+ encoding: UTF-8
36
+ string: ''
37
+ http_version:
38
+ recorded_at: Mon, 10 Feb 2020 17:29:36 GMT
39
+ - request:
40
+ method: delete
41
+ uri: https://sandboxapi.deere.com/platform/assets/00000000-0000-0000-0000-000000000000
42
+ body:
43
+ encoding: US-ASCII
44
+ string: ''
45
+ headers:
46
+ Accept:
47
+ - application/vnd.deere.axiom.v3+json
48
+ Accept-Encoding:
49
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
50
+ User-Agent:
51
+ - OAuth gem v0.5.4
52
+ Authorization:
53
+ - OAuth oauth_consumer_key="johndeere-0000000000000000000000000000000000000000",
54
+ oauth_nonce="000000000000000000000000000000000000000000", oauth_signature="0000000000000000000000000000",
55
+ oauth_signature_method="HMAC-SHA1", oauth_timestamp="1581334172", oauth_token="00000000-0000-0000-0000-000000000000",
56
+ oauth_version="1.0"
57
+ response:
58
+ status:
59
+ code: 429
60
+ message: Too Many Requests
61
+ headers:
62
+ Date:
63
+ - Mon, 10 Feb 2020 17:29:36 GMT
64
+ X-Deere-Handling-Server:
65
+ - ip-10-214-45-99
66
+ X-Frame-Options:
67
+ - SAMEORIGIN
68
+ X-Deere-Elapsed-Ms:
69
+ - '96'
70
+ body:
71
+ encoding: UTF-8
72
+ string: ''
73
+ http_version:
74
+ recorded_at: Mon, 10 Feb 2020 17:29:36 GMT
75
+ - request:
76
+ method: delete
77
+ uri: https://sandboxapi.deere.com/platform/assets/00000000-0000-0000-0000-000000000000
78
+ body:
79
+ encoding: US-ASCII
80
+ string: ''
81
+ headers:
82
+ Accept:
83
+ - application/vnd.deere.axiom.v3+json
84
+ Accept-Encoding:
85
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
86
+ User-Agent:
87
+ - OAuth gem v0.5.4
88
+ Authorization:
89
+ - OAuth oauth_consumer_key="johndeere-0000000000000000000000000000000000000000",
90
+ oauth_nonce="000000000000000000000000000000000000000000", oauth_signature="0000000000000000000000000000",
91
+ oauth_signature_method="HMAC-SHA1", oauth_timestamp="1581334172", oauth_token="00000000-0000-0000-0000-000000000000",
92
+ oauth_version="1.0"
93
+ response:
94
+ status:
95
+ code: 503
96
+ message: Service Unavailable
97
+ headers:
98
+ Date:
99
+ - Mon, 10 Feb 2020 17:29:36 GMT
100
+ X-Deere-Handling-Server:
101
+ - ip-10-214-45-99
102
+ X-Frame-Options:
103
+ - SAMEORIGIN
104
+ X-Deere-Elapsed-Ms:
105
+ - '96'
106
+ body:
107
+ encoding: UTF-8
108
+ string: ''
109
+ http_version:
110
+ recorded_at: Mon, 10 Feb 2020 17:29:36 GMT
111
+ - request:
112
+ method: delete
113
+ uri: https://sandboxapi.deere.com/platform/assets/00000000-0000-0000-0000-000000000000
114
+ body:
115
+ encoding: US-ASCII
116
+ string: ''
117
+ headers:
118
+ Accept:
119
+ - application/vnd.deere.axiom.v3+json
120
+ Accept-Encoding:
121
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
122
+ User-Agent:
123
+ - OAuth gem v0.5.4
124
+ Authorization:
125
+ - OAuth oauth_consumer_key="johndeere-0000000000000000000000000000000000000000",
126
+ oauth_nonce="000000000000000000000000000000000000000000", oauth_signature="0000000000000000000000000000",
127
+ oauth_signature_method="HMAC-SHA1", oauth_timestamp="1581334172", oauth_token="00000000-0000-0000-0000-000000000000",
128
+ oauth_version="1.0"
129
+ response:
130
+ status:
131
+ code: 503
132
+ message: Service Unavailable
133
+ headers:
134
+ Date:
135
+ - Mon, 10 Feb 2020 17:29:36 GMT
136
+ X-Deere-Handling-Server:
137
+ - ip-10-214-45-99
138
+ X-Frame-Options:
139
+ - SAMEORIGIN
140
+ X-Deere-Elapsed-Ms:
141
+ - '96'
142
+ body:
143
+ encoding: UTF-8
144
+ string: ''
145
+ http_version:
146
+ recorded_at: Mon, 10 Feb 2020 17:29:36 GMT
147
+ - request:
148
+ method: delete
149
+ uri: https://sandboxapi.deere.com/platform/assets/00000000-0000-0000-0000-000000000000
150
+ body:
151
+ encoding: US-ASCII
152
+ string: ''
153
+ headers:
154
+ Accept:
155
+ - application/vnd.deere.axiom.v3+json
156
+ Accept-Encoding:
157
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
158
+ User-Agent:
159
+ - OAuth gem v0.5.4
160
+ Authorization:
161
+ - OAuth oauth_consumer_key="johndeere-0000000000000000000000000000000000000000",
162
+ oauth_nonce="000000000000000000000000000000000000000000", oauth_signature="0000000000000000000000000000",
163
+ oauth_signature_method="HMAC-SHA1", oauth_timestamp="1581334172", oauth_token="00000000-0000-0000-0000-000000000000",
164
+ oauth_version="1.0"
165
+ response:
166
+ status:
167
+ code: 429
168
+ message: Too Many Requests
169
+ headers:
170
+ Date:
171
+ - Mon, 10 Feb 2020 17:29:36 GMT
172
+ X-Deere-Handling-Server:
173
+ - ip-10-214-45-99
174
+ X-Frame-Options:
175
+ - SAMEORIGIN
176
+ X-Deere-Elapsed-Ms:
177
+ - '96'
178
+ body:
179
+ encoding: UTF-8
180
+ string: ''
181
+ http_version:
182
+ recorded_at: Mon, 10 Feb 2020 17:29:36 GMT
183
+ - request:
184
+ method: delete
185
+ uri: https://sandboxapi.deere.com/platform/assets/00000000-0000-0000-0000-000000000000
186
+ body:
187
+ encoding: US-ASCII
188
+ string: ''
189
+ headers:
190
+ Accept:
191
+ - application/vnd.deere.axiom.v3+json
192
+ Accept-Encoding:
193
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
194
+ User-Agent:
195
+ - OAuth gem v0.5.4
196
+ Authorization:
197
+ - OAuth oauth_consumer_key="johndeere-0000000000000000000000000000000000000000",
198
+ oauth_nonce="000000000000000000000000000000000000000000", oauth_signature="0000000000000000000000000000",
199
+ oauth_signature_method="HMAC-SHA1", oauth_timestamp="1581334172", oauth_token="00000000-0000-0000-0000-000000000000",
200
+ oauth_version="1.0"
201
+ response:
202
+ status:
203
+ code: 429
204
+ message: Too Many Requests
205
+ headers:
206
+ Date:
207
+ - Mon, 10 Feb 2020 17:29:36 GMT
208
+ X-Deere-Handling-Server:
209
+ - ip-10-214-45-99
210
+ X-Frame-Options:
211
+ - SAMEORIGIN
212
+ X-Deere-Elapsed-Ms:
213
+ - '96'
214
+ body:
215
+ encoding: UTF-8
216
+ string: ''
217
+ http_version:
218
+ recorded_at: Mon, 10 Feb 2020 17:29:36 GMT
219
+ - request:
220
+ method: delete
221
+ uri: https://sandboxapi.deere.com/platform/assets/00000000-0000-0000-0000-000000000000
222
+ body:
223
+ encoding: US-ASCII
224
+ string: ''
225
+ headers:
226
+ Accept:
227
+ - application/vnd.deere.axiom.v3+json
228
+ Accept-Encoding:
229
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
230
+ User-Agent:
231
+ - OAuth gem v0.5.4
232
+ Authorization:
233
+ - OAuth oauth_consumer_key="johndeere-0000000000000000000000000000000000000000",
234
+ oauth_nonce="000000000000000000000000000000000000000000", oauth_signature="0000000000000000000000000000",
235
+ oauth_signature_method="HMAC-SHA1", oauth_timestamp="1581334172", oauth_token="00000000-0000-0000-0000-000000000000",
236
+ oauth_version="1.0"
237
+ response:
238
+ status:
239
+ code: 503
240
+ message: Service Unavailable
241
+ headers:
242
+ Date:
243
+ - Mon, 10 Feb 2020 17:29:36 GMT
244
+ X-Deere-Handling-Server:
245
+ - ip-10-214-45-99
246
+ X-Frame-Options:
247
+ - SAMEORIGIN
248
+ X-Deere-Elapsed-Ms:
249
+ - '96'
250
+ body:
251
+ encoding: UTF-8
252
+ string: ''
253
+ http_version:
254
+ recorded_at: Mon, 10 Feb 2020 17:29:36 GMT
255
+ - request:
256
+ method: delete
257
+ uri: https://sandboxapi.deere.com/platform/assets/00000000-0000-0000-0000-000000000000
258
+ body:
259
+ encoding: US-ASCII
260
+ string: ''
261
+ headers:
262
+ Accept:
263
+ - application/vnd.deere.axiom.v3+json
264
+ Accept-Encoding:
265
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
266
+ User-Agent:
267
+ - OAuth gem v0.5.4
268
+ Authorization:
269
+ - OAuth oauth_consumer_key="johndeere-0000000000000000000000000000000000000000",
270
+ oauth_nonce="000000000000000000000000000000000000000000", oauth_signature="0000000000000000000000000000",
271
+ oauth_signature_method="HMAC-SHA1", oauth_timestamp="1581334172", oauth_token="00000000-0000-0000-0000-000000000000",
272
+ oauth_version="1.0"
273
+ response:
274
+ status:
275
+ code: 503
276
+ message: Service Unavailable
277
+ headers:
278
+ Date:
279
+ - Mon, 10 Feb 2020 17:29:36 GMT
280
+ X-Deere-Handling-Server:
281
+ - ip-10-214-45-99
282
+ X-Frame-Options:
283
+ - SAMEORIGIN
284
+ X-Deere-Elapsed-Ms:
285
+ - '96'
286
+ body:
287
+ encoding: UTF-8
288
+ string: ''
289
+ http_version:
290
+ recorded_at: Mon, 10 Feb 2020 17:29:36 GMT
291
+ - request:
292
+ method: delete
293
+ uri: https://sandboxapi.deere.com/platform/assets/00000000-0000-0000-0000-000000000000
294
+ body:
295
+ encoding: US-ASCII
296
+ string: ''
297
+ headers:
298
+ Accept:
299
+ - application/vnd.deere.axiom.v3+json
300
+ Accept-Encoding:
301
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
302
+ User-Agent:
303
+ - OAuth gem v0.5.4
304
+ Authorization:
305
+ - OAuth oauth_consumer_key="johndeere-0000000000000000000000000000000000000000",
306
+ oauth_nonce="000000000000000000000000000000000000000000", oauth_signature="0000000000000000000000000000",
307
+ oauth_signature_method="HMAC-SHA1", oauth_timestamp="1581334172", oauth_token="00000000-0000-0000-0000-000000000000",
308
+ oauth_version="1.0"
309
+ response:
310
+ status:
311
+ code: 204
312
+ message: No Content
313
+ headers:
314
+ Date:
315
+ - Mon, 10 Feb 2020 17:29:36 GMT
316
+ X-Deere-Handling-Server:
317
+ - ip-10-214-45-99
318
+ X-Frame-Options:
319
+ - SAMEORIGIN
320
+ X-Deere-Elapsed-Ms:
321
+ - '96'
322
+ body:
323
+ encoding: UTF-8
324
+ string: ''
325
+ http_version:
326
+ recorded_at: Mon, 10 Feb 2020 17:29:36 GMT
327
+ recorded_with: VCR 5.0.0