nypl_sierra_api_client 1.0.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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