nypl_sierra_api_client 1.0.2 → 1.2.0

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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/nypl_sierra_api_client.rb +64 -18
  3. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f83a3d06d4010dd2b229b09358e70ff5c4afadbffb92c0d6407b6cf79b41d7dc
4
- data.tar.gz: 2dab1288ee02fe238c9517a4bddb7ddcde36dc3a036ed61890c57854186d0dc0
3
+ metadata.gz: caabcc105e5fa564b09906a50a7c2c83781435ae2997aeb5b1b546c2a5d5196d
4
+ data.tar.gz: ee28dd954ac82a925c01d4b3c386d7116c45a3a4a9901c19c725f3570c6dd51e
5
5
  SHA512:
6
- metadata.gz: a349f8a998f13cce0180ecce092f79601c06cc376059fc349add4e98d802532bc8dcf487c0dd2ce574bffa16e70e2c6bce9f4a50e92f392258670a63eb3157af
7
- data.tar.gz: 46cb45de0dbb360f12177af4d51102d84e056f7f223d6545a3ff3bc5d1a700f1c5a06115747b00cb6583283a2f28367e95cd8851a25bf90d7205807e9fe09987
6
+ metadata.gz: 02744457c93e208183dfd10a918ab47bd2be2945b1ab3877ac4af15648da4636e71edde276d73dcc2f9f5e971d72c6cf027c9ac2bad99f58f1ae6d7de9c7946d
7
+ data.tar.gz: bc02013959688226a4e115deb6ed7dce14c2e4e15b136905d79a5371d9e84450982662cbbbcdf9ee14d8258385cc680be0f2c2b2e83100e93f0e08af1d3a0c52
@@ -20,13 +20,32 @@ class SierraApiClient
20
20
  }
21
21
  }
22
22
 
23
- @config = config_defaults[:env].map {|k,v| [k, ENV[k]]}.to_h
23
+ @config = config_defaults[:env].map {|k,v| [k, ENV[v]]}.to_h
24
24
  .merge config_defaults[:static]
25
25
  .merge config
26
26
 
27
27
  config_defaults[:env].each do |key, value|
28
- raise SierraApiClient.new "Missing config: neither config.#{key} nor ENV.#{value} are set" unless @config[key]
28
+ raise SierraApiClientError.new "Missing config: neither config.#{key} nor ENV.#{value} are set" unless @config[key]
29
29
  end
30
+
31
+ @retries = 0
32
+ end
33
+
34
+ def put (path, body, options = {})
35
+ options = parse_http_options options
36
+ # Default to POSTing JSON unless explicitly stated otherwise
37
+ options[:headers]['Content-Type'] = 'application/json' unless options[:headers]['Content-Type']
38
+
39
+ do_request 'put', path, options do |request|
40
+ request.body = body
41
+ request.body = request.body.to_json unless options[:headers]['Content-Type'] != 'application/json'
42
+ end
43
+ end
44
+
45
+ def delete (path, options = {})
46
+ options = parse_http_options options
47
+
48
+ do_request 'delete', path, options
30
49
  end
31
50
 
32
51
  def get (path, options = {})
@@ -50,22 +69,19 @@ class SierraApiClient
50
69
  private
51
70
 
52
71
  def do_request (method, path, options = {})
53
- # For now, these are the methods we support:
54
- raise SierraApiClientError, "Unsupported method: #{method}" unless ['get', 'post'].include? method.downcase
55
72
 
56
- authenticate! if options[:authenticated]
73
+ raise SierraApiClientError, "Unsupported method: #{method}" unless ['get', 'post', 'put', 'delete'].include? method.downcase
57
74
 
58
- uri = URI.parse("#{@config[:base_url]}#{path}")
75
+ authenticate! if options[:authenticated]
59
76
 
60
- http = Net::HTTP.new(uri.host, uri.port)
61
- http.use_ssl = uri.scheme === 'https'
77
+ @uri = URI.parse("#{@config[:base_url]}#{path}")
62
78
 
63
79
  # Build request headers:
64
80
  request_headers = {}
65
81
  request_headers['Content-Type'] = options[:headers]['Content-Type'] unless options.dig(:headers, 'Content-Type').nil?
66
82
 
67
83
  # Create HTTP::Get or HTTP::Post
68
- request = Net::HTTP.const_get(method.capitalize).new(uri, request_headers)
84
+ request = Net::HTTP.const_get(method.capitalize).new(@uri, request_headers)
69
85
 
70
86
  # Add bearer token header
71
87
  request['Authorization'] = "Bearer #{@access_token}" if options[:authenticated]
@@ -73,31 +89,57 @@ class SierraApiClient
73
89
  # Allow caller to modify the request before we send it off:
74
90
  yield request if block_given?
75
91
 
76
- logger.debug "SierraApiClient: #{method} to Sierra api", { uri: uri, body: request.body }
92
+ logger.debug "SierraApiClient: #{method} to Sierra api", { uri: @uri, body: request.body }
93
+
94
+ execute request, options
95
+ end
96
+
97
+ def execute (request, options)
98
+ http = Net::HTTP.new(@uri.host, @uri.port)
99
+ http.use_ssl = @uri.scheme === 'https'
77
100
 
78
101
  begin
79
- # Execute request:
80
102
  response = http.request(request)
103
+ logger.debug "SierraApiClient: Got Sierra api response", { code: response.code, body: response.body }
81
104
  rescue => e
82
- raise SierraApiClientError.new(e), "Failed to #{method} to #{path}: #{e.message}"
105
+ raise SierraApiClientError.new "Failed to #{request.method} to #{request.path}: #{e.message}"
83
106
  end
84
107
 
85
- logger.debug "SierraApiClient: Got Sierra api response", { code: response.code, body: response.body }
86
-
87
- parse_response response
108
+ handle_response response, request, options
88
109
  end
89
110
 
90
- def parse_response (response)
111
+ def handle_response (response, request, options)
91
112
  if response.code == "401"
92
113
  # Likely an expired access-token; Wipe it for next run
93
- # TODO: Implement token refresh
94
114
  @access_token = nil
95
- raise SierraApiClientTokenError.new("Got a 401: #{response.body}")
115
+ if @retries < 3
116
+ if options[:authenticated]
117
+ logger.debug "SierraApiClient: Refreshing oauth token for 401", { code: 401, body: response.body, retry: @retries }
118
+
119
+ return reauthenticate_and_reattempt request, options
120
+ end
121
+ else
122
+ retries_exceeded = true
123
+ end
124
+
125
+ reset_retries
126
+ message = "Got a 401: #{retries_exceeded ? "Maximum retries exceeded, " : ''}#{response.body}"
127
+ raise SierraApiClientTokenError.new(message)
96
128
  end
97
129
 
130
+ reset_retries if @retries > 0
98
131
  SierraApiResponse.new(response)
99
132
  end
100
133
 
134
+ def reauthenticate_and_reattempt request, options
135
+ @retries += 1
136
+ authenticate!
137
+ # Reset bearer token header
138
+ request['Authorization'] = "Bearer #{@access_token}"
139
+
140
+ execute request, options
141
+ end
142
+
101
143
  def parse_http_options (_options)
102
144
  options = {
103
145
  authenticated: true
@@ -143,4 +185,8 @@ class SierraApiClient
143
185
  def logger
144
186
  @logger ||= NyplLogFormatter.new(STDOUT, level: @config[:log_level])
145
187
  end
188
+
189
+ def reset_retries
190
+ @retries = 0
191
+ end
146
192
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nypl_sierra_api_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - nonword