reso_transport 1.5.7 → 1.5.12

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 49293478c0827ccb4bdca1bb6c9974900f8c0c16853b247487120a0ed3bb79df
4
- data.tar.gz: c9d8c93979377ed18d22a179bae44175961b44e8641eb091930f99542d1e610f
3
+ metadata.gz: d84554084d4c2159db65df37c4c8fc71d0b19c2ee36d7a61d53f66687ef0efd2
4
+ data.tar.gz: 8d6dfb63550e4b2cb530f6448c65f5a6b88c28ca05e21c4c840ea74eb4d47731
5
5
  SHA512:
6
- metadata.gz: 4464fe0a9aa0006f25c5eab29dab8422401ac2ebf435b712e65d5727e43606bb0df4fdf895e5a1d6a1e3e44d4937d19c42389577d28568351832ccae64d55ebb
7
- data.tar.gz: 729d643455ddd8e7a827ddc6aea2a8512f93bc65a3e469993da5d2cd5085ecdc5eed4befee4f376cd9986f51a81d363fdeb042a1f8f51e2e51d7230f265c2d7a
6
+ metadata.gz: 52e67a29c2d0723728f5a168f8eacee86de0ccec979a22512a98fe822f164ee277a3774cef8a2412a60ab35469a4c4268076547714323c8f451592daa898e2cc
7
+ data.tar.gz: 329115fb2899789885463fb0756213b434b147aaa47babb63cc5be9d6e37b363922d219ca1970a16c6bf1abedba15c01d49ca9e59f673054ab58df6a5ad22d23
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- reso_transport (1.5.5)
4
+ reso_transport (1.5.10)
5
5
  faraday (~> 1.0.1)
6
6
 
7
7
  GEM
@@ -22,7 +22,7 @@ PLATFORMS
22
22
 
23
23
  DEPENDENCIES
24
24
  bundler (~> 2)
25
- byebug
25
+ byebug (~> 11)
26
26
  minitest (~> 5.0)
27
27
  minitest-rg (~> 5.0)
28
28
  rake (~> 13)
data/README.md CHANGED
@@ -93,8 +93,13 @@ If the connection requires requesting a new token periodically, it's easy to pro
93
93
 
94
94
  This will pre-fetch a token from the provided endpoint when the current token is either non-existent or has expired.
95
95
 
96
- The `use_replication_endpoint` flag will append `/replication` to all resource queries if set to `true`. This is required
97
- by some data sources to query resources beyond 10,000 records.
96
+ The `use_replication_endpoint` flag will append `/replication` to all resource queries if set to `true`. This is required by some data sources to query resources beyond 10,000 records.
97
+
98
+ When using this feature, you can retrieve the next link by accessing `next_link` after gettings results:
99
+ ```
100
+ results = @client.resources["Property"].query.results
101
+ next_link = @client.resources["Property"].query.next_link
102
+ ```
98
103
 
99
104
  ### Caching Metadata
100
105
 
@@ -278,6 +283,19 @@ When querying for an enumeration value, you can provide either the system name,
278
283
  #=> {"$top"=>1, "$filter"=>"StandardStatus eq 'ActiveUnderContract'"}
279
284
  ```
280
285
 
286
+ ### Troubleshooting
287
+
288
+ In the event there are connection issues, the following errors are raised:
289
+
290
+ * `ResoTransport::NoResponse` - The server did not respond to the request
291
+ * `ResoTransport::RequestError` - The server responded with a status code outside the 200 range
292
+ * `ResoTransport::ResponseError` - The server responded with errors in the body
293
+ * `ResoTransport::AccessDenied` - Check your authentication details
294
+ * `ResoTransport::LocalizationRequired` - Provide one of the required localizations through the `localization` method
295
+ * `ResoTransport::EncodeError` - No match was found for one or more of the properties
296
+
297
+ The Faraday Request hash is attached to the error for `NoResponse`, `RequestError`, `ResponseError`, and `AccessDenied`. A Faraday Response is attached on `RequestError`, `ResponseError`, and `AccessDenied`.
298
+
281
299
  ## Development
282
300
 
283
301
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -19,6 +19,7 @@ module ResoTransport
19
19
  @endpoint = options.fetch(:endpoint)
20
20
  @username = options.fetch(:username, nil)
21
21
  @password = options.fetch(:password, nil)
22
+ @request = nil
22
23
  end
23
24
 
24
25
  def connection
@@ -31,13 +32,10 @@ module ResoTransport
31
32
  end
32
33
 
33
34
  def authenticate
34
- response = connection.post nil, auth_params
35
+ response = connection.post(nil, auth_params { |req| @request = req })
35
36
  json = JSON.parse response.body
36
37
 
37
- unless response.success?
38
- message = "#{response.reason_phrase}: #{json['error'] || response.body}"
39
- raise ResoTransport::AccessDenied, response: response, message: message
40
- end
38
+ raise AccessDenied.new(request, response, 'token') unless response.success?
41
39
 
42
40
  Access.new({
43
41
  access_token: json.fetch('access_token'),
@@ -46,6 +44,12 @@ module ResoTransport
46
44
  })
47
45
  end
48
46
 
47
+ def request
48
+ return @request.to_h if @request.respond_to? :to_h
49
+
50
+ {}
51
+ end
52
+
49
53
  private
50
54
 
51
55
  def auth_params
@@ -18,10 +18,11 @@ module ResoTransport
18
18
  authorize_request(request_env)
19
19
 
20
20
  @app.call(request_env).on_complete do |response_env|
21
- raise_if_unauthorized(response_env)
21
+ raise_if_unauthorized(request_env, response_env)
22
22
  end
23
23
  rescue ResoTransport::AccessDenied
24
- raise if retries == 0
24
+ raise if retries.zero?
25
+
25
26
  @auth.reset
26
27
  retries -= 1
27
28
  retry
@@ -38,8 +39,8 @@ module ResoTransport
38
39
  )
39
40
  end
40
41
 
41
- def raise_if_unauthorized(response_env)
42
- raise ResoTransport::AccessDenied if response_env[:status] == 401
42
+ def raise_if_unauthorized(request_env, response_env)
43
+ raise ResoTransport::AccessDenied.new(request_env.to_h, response_env) if response_env[:status] == 401
43
44
  end
44
45
  end
45
46
  end
@@ -46,16 +46,19 @@ module ResoTransport
46
46
  end
47
47
 
48
48
  def raw
49
- if response.success?
50
- response.body
51
- else
52
- puts response.body
53
- raise "Error getting #{classname}!"
54
- end
49
+ return response.body if response.success?
50
+
51
+ raise RequestError.new(request, response, classname)
55
52
  end
56
53
 
57
54
  def response
58
55
  raise 'Must implement response method'
59
56
  end
57
+
58
+ def request
59
+ return @request.to_h if @request.respond_to? :to_h
60
+
61
+ {}
62
+ end
60
63
  end
61
64
  end
@@ -16,7 +16,10 @@ module ResoTransport
16
16
  def response
17
17
  @response ||= client.connection.get('DataSystem') do |req|
18
18
  req.headers['Accept'] = 'application/json'
19
+ @request = req
19
20
  end
21
+ rescue Faraday::ConnectionFailed
22
+ raise NoResponse.new(request, nil, 'DataSystem')
20
23
  end
21
24
  end
22
25
  end
@@ -0,0 +1,69 @@
1
+ module ResoTransport
2
+ class ResourceError < StandardError
3
+ attr_reader :resource
4
+
5
+ def initialize(resource)
6
+ @resource = resource
7
+ super message
8
+ end
9
+
10
+ def resource_name
11
+ return resource.name if resource.respond_to?(:name)
12
+
13
+ resource || 'unknown'
14
+ end
15
+
16
+ def message
17
+ "Request error for #{resource_name}"
18
+ end
19
+ end
20
+
21
+ class EncodeError < ResourceError
22
+ def initialize(resource, property)
23
+ @property = property
24
+ super resource
25
+ end
26
+
27
+ def message
28
+ "Property #{@property} not found for #{resource_name}"
29
+ end
30
+ end
31
+
32
+ class LocalizationRequired < ResourceError
33
+ def message
34
+ "Localization required for #{resource_name}"
35
+ end
36
+ end
37
+
38
+ class RequestError < ResourceError
39
+ attr_reader :request, :response
40
+
41
+ def initialize(request, response, resource = nil)
42
+ @response = response.respond_to?(:to_hash) ? response.to_hash : response
43
+ @request = request
44
+ super resource
45
+ end
46
+
47
+ def message
48
+ "Received #{response[:status]} for #{resource_name}"
49
+ end
50
+ end
51
+
52
+ class NoResponse < RequestError
53
+ def message
54
+ "No response for #{resource_name}"
55
+ end
56
+ end
57
+
58
+ class ResponseError < RequestError
59
+ def message
60
+ "Request succeeded for #{resource_name} with response errors"
61
+ end
62
+ end
63
+
64
+ class AccessDenied < RequestError
65
+ def message
66
+ "Access denied: #{response.reason_phrase}"
67
+ end
68
+ end
69
+ end
@@ -23,7 +23,10 @@ module ResoTransport
23
23
  def response
24
24
  @response ||= client.connection.get('$metadata') do |req|
25
25
  req.headers['Accept'] = MIME_TYPES[client.vendor.fetch(:metadata_format, :xml).to_sym]
26
+ @request = req
26
27
  end
28
+ rescue Faraday::ConnectionFailed
29
+ raise NoResponse.new(request, nil, '$metadata')
27
30
  end
28
31
  end
29
32
  end
@@ -43,6 +43,11 @@ module ResoTransport
43
43
  self
44
44
  end
45
45
 
46
+ def page(token)
47
+ options[:next] = token
48
+ self
49
+ end
50
+
46
51
  def select(*fields)
47
52
  os = options.fetch(:select, '').split(',')
48
53
  options[:select] = (os + Array(fields)).uniq.join(',')
@@ -58,41 +63,37 @@ module ResoTransport
58
63
  end
59
64
 
60
65
  def count
61
- p compile_params
62
66
  limit(1).include_count
63
- resp = resource.get(compile_params)
64
- parsed_body = JSON.parse(resp.body)
65
- parsed_body.fetch('@odata.count', 0)
67
+ parsed = handle_response response
68
+ parsed.fetch('@odata.count', 0)
66
69
  end
67
70
 
68
71
  def results
69
- resp = execute
72
+ parsed = handle_response response
70
73
 
71
- if resp[:success]
72
- resp[:results]
73
- else
74
- puts resp[:meta]
75
- raise 'Request Failed'
76
- end
74
+ @next_link = parsed.fetch('@odata.nextLink', nil)
75
+ results = Array(parsed.delete('value'))
76
+ resource.parse(results)
77
77
  end
78
78
 
79
- def execute
80
- resp = resource.get(compile_params)
81
- if resp.success?
82
- parsed_body = JSON.parse(resp.body)
83
- results = Array(parsed_body.delete('value'))
84
-
85
- {
86
- success: resp.success? && !parsed_body.key?('error'),
87
- meta: parsed_body,
88
- results: resource.parse(results)
89
- }
90
- else
91
- {
92
- success: false,
93
- meta: resp.body
94
- }
95
- end
79
+ # Can only be accessed after results call
80
+ def next_link
81
+ @next_link
82
+ end
83
+
84
+ def response
85
+ resource.get(compile_params)
86
+ rescue Faraday::ConnectionFailed
87
+ raise NoResponse.new(resource.request, nil, resource)
88
+ end
89
+
90
+ def handle_response(response)
91
+ raise RequestError.new(resource.request, response, resource) unless response.success?
92
+
93
+ parsed = JSON.parse(response.body)
94
+ raise ResponseError.new(resource.request, response, resource) if parsed.key?('error')
95
+
96
+ parsed
96
97
  end
97
98
 
98
99
  def new_query_context(context)
@@ -149,7 +150,7 @@ module ResoTransport
149
150
 
150
151
  def encode_value(key, val)
151
152
  field = resource.property(key.to_s)
152
- raise "Couldn't find property #{key} for #{resource.name}" if field.nil?
153
+ raise EncodeError.new(resource, key) if field.nil?
153
154
 
154
155
  field.encode(val)
155
156
  end
@@ -39,13 +39,14 @@ module ResoTransport
39
39
  def get(params)
40
40
  client.connection.get(url, params) do |req|
41
41
  req.headers['Accept'] = 'application/json'
42
+ @request = req
42
43
  end
43
44
  end
44
45
 
45
46
  def url
46
47
  return local['ResourcePath'].gsub(%r{^/}, '') if local
47
48
 
48
- raise 'Localization required' if localizations.any? && local.nil?
49
+ raise LocalizationRequired, self if localizations.any? && local.nil?
49
50
 
50
51
  return "#{name}/replication" if client.use_replication_endpoint
51
52
 
@@ -64,5 +65,11 @@ module ResoTransport
64
65
  def inspect
65
66
  to_s
66
67
  end
68
+
69
+ def request
70
+ return @request.to_h if @request.respond_to? :to_h
71
+
72
+ {}
73
+ end
67
74
  end
68
75
  end
@@ -1,3 +1,3 @@
1
1
  module ResoTransport
2
- VERSION = '1.5.7'.freeze
2
+ VERSION = '1.5.12'.freeze
3
3
  end
@@ -21,13 +21,11 @@ require 'reso_transport/entity_type'
21
21
  require 'reso_transport/enum'
22
22
  require 'reso_transport/property'
23
23
  require 'reso_transport/query'
24
+ require 'reso_transport/errors'
24
25
 
25
26
  Faraday::Utils.default_space_encoding = '%20'
26
27
 
27
28
  module ResoTransport
28
- class Error < StandardError; end
29
-
30
- class AccessDenied < StandardError; end
31
29
  ODATA_TIME_FORMAT = '%Y-%m-%dT%H:%M:%SZ'.freeze
32
30
 
33
31
  class << self
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reso_transport
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.7
4
+ version: 1.5.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Druse
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-18 00:00:00.000000000 Z
11
+ date: 2021-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -144,6 +144,7 @@ files:
144
144
  - lib/reso_transport/entity_set.rb
145
145
  - lib/reso_transport/entity_type.rb
146
146
  - lib/reso_transport/enum.rb
147
+ - lib/reso_transport/errors.rb
147
148
  - lib/reso_transport/metadata.rb
148
149
  - lib/reso_transport/metadata_cache.rb
149
150
  - lib/reso_transport/metadata_parser.rb