diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 821318c752c..c2d6f6be0e9 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -869,6 +869,7 @@ lib/lgy/service.rb @department-of-veterans-affairs/benefits-non-disability @depa lib/lgy/tag_sentry.rb @department-of-veterans-affairs/benefits-non-disability @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group lib/lighthouse @department-of-veterans-affairs/backend-review-group lib/lighthouse/benefit_claims @department-of-veterans-affairs/benefits-management-tools-be @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group +lib/lighthouse/benefits_intake @department-of-veterans-affairs/pensions @department-of-veterans-affairs/backend-review-group lib/lighthouse/letters_generator @department-of-veterans-affairs/benefits-management-tools-be @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group lib/mail_automation @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group lib/map/ @department-of-veterans-affairs/octo-identity @@ -1320,6 +1321,7 @@ spec/lib/lighthouse/auth @department-of-veterans-affairs/benefits-management-too spec/lib/lighthouse/benefits_claims @department-of-veterans-affairs/benefits-management-tools-be @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group spec/lib/lighthouse/benefits_documents @department-of-veterans-affairs/backend-review-group spec/lib/lighthouse/benefits_documents/service_spec.rb @department-of-veterans-affairs/backend-review-group +spec/lib/lighthouse/benefits_intake @department-of-veterans-affairs/pensions @department-of-veterans-affairs/backend-review-group spec/lib/lighthouse/direct_deposit @department-of-veterans-affairs/vfs-authenticated-experience-backend @department-of-veterans-affairs/dbex-trex @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group spec/lib/lighthouse/direct_deposit/payment_account_spec.rb @department-of-veterans-affairs/vfs-authenticated-experience-backend @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group spec/lib/lighthouse/facilities @department-of-veterans-affairs/vfs-facilities diff --git a/config/settings.yml b/config/settings.yml index 6658613b94d..88fac504297 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -988,6 +988,12 @@ lighthouse: rsa_key: ~ aud_claim_url: https://deptva-eval.okta.com/oauth2/ausln2mo4jCAYRrlR2p7/v1/token use_mocks: false + benefits_intake: + host: https://sandbox-api.va.gov + path: /services/vba_documents + version: v1 + use_mocks: false + api_key: ~ letters_generator: url: https://sandbox-api.va.gov path: /services/va-letter-generator/v1/ diff --git a/lib/lighthouse/benefits_intake/configuration.rb b/lib/lighthouse/benefits_intake/configuration.rb new file mode 100644 index 00000000000..58121c930e4 --- /dev/null +++ b/lib/lighthouse/benefits_intake/configuration.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +require 'common/client/configuration/rest' +require 'faraday/multipart' + +module BenefitsIntake + ## + # HTTP client configuration for the {BenefitsIntake::Service}, + # sets the base path, the base request headers, and a service name for breakers and metrics. + # + class Configuration < Common::Client::Configuration::REST + self.read_timeout = Settings.lighthouse.benefits_intake.timeout || 20 + + ## + # @return [Config::Options] Settings for benefits_claims API. + # + def intake_settings + Settings.lighthouse.benefits_intake + end + + ## + # @return [String] Base path. + # + def service_path + url = [intake_settings.host, intake_settings.path, intake_settings.version] + url.map { |segment| segment.sub(%r{^/}, '').chomp('/') }.join('/') + end + + ## + # @return [String] Service name to use in breakers and metrics. + # + def service_name + 'BenefitsIntake' + end + + ## + # @return [Hash] The basic headers required for any Lighthouse API call + # + def self.base_request_headers + key = Settings.lighthouse.benefits_intake.api_key + raise "No api_key set for benefits_intake. Please set 'lighthouse.benefits_intake.api_key'" if key.nil? + + super.merge('apikey' => key) + end + + ## + # Creates a connection with json parsing and breaker functionality. + # + # @return [Faraday::Connection] a Faraday connection instance. + # + def connection + @conn ||= Faraday.new(service_path, headers: base_request_headers, request: request_options) do |faraday| + faraday.use :breakers + faraday.use Faraday::Response::RaiseError + + faraday.request :multipart + faraday.request :json + + faraday.response :betamocks if use_mocks? + faraday.response :json + faraday.adapter Faraday.default_adapter + end + end + + ## + # @return [Boolean] Should the service use mock data in lower environments. + # + def use_mocks? + intake_settings.use_mocks || false + end + + def breakers_error_threshold + 80 # breakers will be tripped if error rate reaches 80% over a two minute period. + end + end +end diff --git a/spec/lib/lighthouse/benefits_intake/configuration_spec.rb b/spec/lib/lighthouse/benefits_intake/configuration_spec.rb new file mode 100644 index 00000000000..d5ce23e2fa0 --- /dev/null +++ b/spec/lib/lighthouse/benefits_intake/configuration_spec.rb @@ -0,0 +1,104 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'common/client/configuration/rest' +require 'lighthouse/benefits_intake/configuration' + +RSpec.describe BenefitsIntake::Configuration do + let(:base) { Common::Client::Configuration::REST } + let(:config) { BenefitsIntake::Configuration.send(:new) } + let(:settings) do + OpenStruct.new({ + host: 'https://sandbox-api.va.gov', + path: '/services/vba_documents', + version: 'v1', + use_mocks: false, + api_key: 'some-long-hash-api-key' + }) + end + + before do + allow(Settings.lighthouse).to receive(:benefits_intake).and_return(settings) + end + + context 'valid settings' do + it 'returns settings' do + expect(config.intake_settings).to eq(settings) + end + + it 'has correct api_key' do + expect(config.intake_settings.api_key).to eq(settings.api_key) + end + + it 'returns service_path' do + valid_path = 'https://sandbox-api.va.gov/services/vba_documents/v1' + expect(config.service_path).to eq(valid_path) + end + + it 'returns use_mocks' do + expect(config.use_mocks?).to eq(settings.use_mocks) + end + end + + context 'expected constants' do + it 'returns service_name' do + expect(config.service_name).to eq('BenefitsIntake') + end + + it 'returns breakers_error_threshold' do + expect(config.breakers_error_threshold).to eq(80) + end + end + + describe '#base_request_headers' do + it 'returns expected headers' do + headers = config.base_request_headers + expected = base.base_request_headers.merge({ 'apikey' => settings.api_key }) + expect(headers).to eq(expected) + end + + it 'errors if missing api_key' do + allow(Settings.lighthouse.benefits_intake).to receive(:api_key).and_return(nil) + expect { config.base_request_headers }.to raise_error StandardError, /^No api_key set.+/ + end + end + + describe '#connection' do + let(:faraday) { double('faraday') } + + before do + allow(Faraday).to receive(:new).and_yield(faraday) + + allow(config).to receive(:service_path).and_return('service_path') + allow(config).to receive(:base_request_headers).and_return('base_request_headers') + allow(config).to receive(:request_options).and_return('request_options') + allow(config).to receive(:use_mocks?).and_return(true) + end + + it 'returns existing connection' do + config.instance_variable_set(:@conn, 'TEST') + + expect(Faraday).not_to receive(:new) + expect(config.connection).to eq('TEST') + end + + it 'creates the connection' do + expect(Faraday).to receive(:new).with('service_path', headers: 'base_request_headers', request: 'request_options') + + expect(faraday).to receive(:use).once.with(:breakers) + expect(faraday).to receive(:use).once.with(Faraday::Response::RaiseError) + + expect(faraday).to receive(:request).once.with(:multipart) + expect(faraday).to receive(:request).once.with(:json) + + expect(faraday).to receive(:response).once.with(:betamocks) # use_mocks? => true + expect(faraday).to receive(:response).once.with(:json) + + expect(faraday).to receive(:adapter).once.with(Faraday.default_adapter) + + config.connection + end + end + + # end RSpec.describe +end