-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* Introduce Alerts API interface NOTE: base class currently duplicates the NomisClient::Base - refactor / DRY up * Migrate Alerts to use the new AlertsApiClient * DRY up the Oauth client * Update the NomisAlerts Importer * Prefer HMPPS over DPS for the oauth token * Add ALERTS_API_BASE_URL to the test environment * Fix specs to support the new AlertsApi::Client * Generate wiremock responses for the AlertsApiClient * Resolve Wiremock `__files` not found on CI * Add: ALERTS_API_BASE_URL: alerts_api_base_url_key * Add ALERTS_API_BASE_URL to .env.example
- Loading branch information
1 parent
b3e4d93
commit 7045f7e
Showing
63 changed files
with
584 additions
and
744 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# frozen_string_literal: true | ||
|
||
module AlertsApiClient | ||
class AlertTypes < AlertsApiClient::Base | ||
class << self | ||
def get | ||
fetch_response.map { |alert_type| | ||
alert_type['alertCodes'].map do |alert_code| | ||
attributes_for(alert_type, alert_code) | ||
end | ||
}.flatten | ||
end | ||
|
||
def fetch_response | ||
AlertsApiClient::Base.get( | ||
'alert-types', | ||
headers: { 'Page-Limit' => '1000' }, | ||
).parsed | ||
end | ||
|
||
def attributes_for(alert_type, alert_code) | ||
{ | ||
code: alert_code['code'], | ||
type_code: alert_type['code'], | ||
description: alert_code['description'], | ||
type_description: alert_type['description'], | ||
active_flag: alert_type['isActive'], | ||
} | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# frozen_string_literal: true | ||
|
||
module AlertsApiClient | ||
class Alerts < AlertsApiClient::Base | ||
class << self | ||
def get(prison_number) | ||
JSON.parse(fetch_response(prison_number).body)['content'].map do |alert| | ||
attributes_for(alert) | ||
end | ||
end | ||
|
||
def fetch_response(prison_number) | ||
AlertsApiClient::Base.get( | ||
"/prisoners/#{prison_number}/alerts?isActive=true", | ||
) | ||
end | ||
|
||
def attributes_for(alert) | ||
{ | ||
alert_id: alert['alertUuid'], | ||
alert_type: alert['alertCode']['alertTypeCode'], | ||
alert_type_description: alert['alertCode']['alertTypeDescription'], | ||
alert_code: alert['alertCode']['code'], | ||
alert_code_description: alert['alertCode']['description'], | ||
comment: (alert['comments'] || []).join('. '), | ||
created_at: alert['createdAt'], | ||
expires_at: alert['activeTo'], | ||
expired: !alert['isActive'], | ||
active: alert['isActive'], | ||
prison_number: alert['prisonNumber'], | ||
} | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# frozen_string_literal: true | ||
|
||
module AlertsApiClient | ||
class Base < HmppsApiClient | ||
class << self | ||
protected | ||
|
||
def site_for_api | ||
ENV['ALERTS_API_BASE_URL'] | ||
end | ||
|
||
def token_request_path_prefix | ||
'' | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
# frozen_string_literal: true | ||
|
||
class HmppsApiClient | ||
HMPPS_TIMEOUT = 10 # in seconds | ||
|
||
class << self | ||
def get(path, params = {}) | ||
token_request(:get, path, params) | ||
end | ||
|
||
def post(path, params = {}) | ||
params = update_json_headers(params) | ||
token_request(:post, path, params) | ||
end | ||
|
||
def put(path, params = {}) | ||
params = update_json_headers(params) | ||
token_request(:put, path, params) | ||
end | ||
|
||
protected | ||
|
||
def site_for_api | ||
# expect a value in the subclass | ||
end | ||
|
||
def token_request_path_prefix | ||
# expect a value in the subclass | ||
end | ||
|
||
private | ||
|
||
REFRESH_TOKEN_TIMEFRAME_IN_SECONDS = 5 | ||
|
||
def token_request(method, path, params) | ||
token.send(method, "#{token_request_path_prefix}#{path}", params) | ||
rescue Faraday::ConnectionFailed, Faraday::TimeoutError => e | ||
Rails.logger.warn "HMPPS Connection Error: #{e.message}" | ||
raise e | ||
rescue OAuth2::Error => e | ||
Rails.logger.warn "HMPPS OAuth Client Error: #{e.message}" | ||
raise e | ||
end | ||
|
||
def token | ||
return @token if @token && !token_expired_or_to_expire? | ||
|
||
@token = client.client_credentials.get_token | ||
end | ||
|
||
def client | ||
@client ||= OAuth2::Client.new( | ||
ENV['NOMIS_CLIENT_ID'], | ||
ENV['NOMIS_CLIENT_SECRET'], | ||
site: site_for_api, | ||
auth_scheme: ENV['NOMIS_AUTH_SCHEME'], | ||
token_url: "#{ENV['NOMIS_SITE_FOR_AUTH']}/oauth/token", | ||
raise_errors: true, | ||
connection_opts: { request: { timeout: HMPPS_TIMEOUT, open_timeout: HMPPS_TIMEOUT } }, | ||
) | ||
end | ||
|
||
def token_expired_or_to_expire? | ||
# rubocop:disable Rails/TimeZone | ||
@token.expires? && | ||
(@token.expires_at - REFRESH_TOKEN_TIMEFRAME_IN_SECONDS < Time.now.to_i) | ||
# rubocop:enable Rails/TimeZone | ||
end | ||
|
||
def update_json_headers(params) | ||
return unless params | ||
|
||
{ | ||
headers: | ||
{ | ||
'Accept': 'application/json', | ||
'Content-Type': 'application/json', | ||
}, | ||
}.deep_merge(params) | ||
end | ||
|
||
def sentry_extra(path, params, exception) | ||
response = exception.response | ||
|
||
message = begin | ||
ActiveSupport::JSON.decode(response.body)['developerMessage'] | ||
rescue StandardError | ||
nil | ||
end | ||
|
||
{ | ||
route: path, | ||
body_params: params, | ||
nomis_response_status: response.status, | ||
nomis_response_body: response.body, | ||
nomis_response_message: message, | ||
} | ||
end | ||
|
||
def log_exception(description, path, params, exception) | ||
Sentry.capture_message( | ||
description, | ||
extra: sentry_extra(path, params, exception), | ||
level: 'error', | ||
) | ||
end | ||
end | ||
end |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.