Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RT-749] raise timeout error for circuit breaker #17

Merged
merged 4 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/factiva/authentication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ def make_request(params)
end

response_body
rescue HTTP::TimeoutError
# This error should be handled before HTTP::Error which is a superclass of HTTP::TimeoutError
# Raising Factiva::TimeoutError is required for CircuitBreaker to work properly
raise Factiva::TimeoutError
end

def expired?(timestamp)
Expand Down
4 changes: 3 additions & 1 deletion lib/factiva/errors.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module Factiva
class RequestError < StandardError; end
class Error < StandardError; end
class RequestError < Error; end
class TimeoutError < Error; end
end
4 changes: 4 additions & 0 deletions lib/factiva/monitoring.rb
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,10 @@ def make_request(http_method, url, params = nil)
else
Failure({ code: response.code, error: response_body["error"] }.to_s)
end
rescue HTTP::TimeoutError
# This error should be handled before HTTP::Error which is a superclass of HTTP::TimeoutError
# Raising Factiva::TimeoutError is required for CircuitBreaker to work properly
raise Factiva::TimeoutError
rescue SocketError, HTTP::Error => error
Failure("Failed to connect to Factiva: #{error.message}")
rescue JSON::ParserError => error
Expand Down
4 changes: 4 additions & 0 deletions lib/factiva/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ def make_request(method, url, params = nil)
else
Failure({ code: response.code, error: response_body["error"] }.to_s)
end
rescue HTTP::TimeoutError
# This error should be handled before HTTP::Error which is a superclass of HTTP::TimeoutError
# Raising Factiva::TimeoutError is required for CircuitBreaker to work properly
raise Factiva::TimeoutError
rescue SocketError, HTTP::Error => error
Failure("Failed to connect to Factiva: #{error.message}")
rescue JSON::ParserError => error
Expand Down
10 changes: 10 additions & 0 deletions spec/factiva/authentication_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ module Factiva
}.to raise_error(RequestError, { code: 400, error: "request_validation_error" }.to_s)
end
end

context "Factiva connection timed out" do
before do
WebMock.stub_request(:post, /oauth2\/v1\/token/).to_timeout
end

it "raises Factiva::TimeoutError for CircuitBreaker" do
expect { subject.token }.to raise_error(Factiva::TimeoutError)
end
end
end

context "Already authenticated" do
Expand Down
12 changes: 12 additions & 0 deletions spec/factiva/monitoring_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,18 @@ module Factiva
expect(result["data"][1]["attributes"]["matches"][0]).to eq(valid_match)
end
end

context "Factiva connection timed out", vcr: "monitoring/authentication_only" do
before do
WebMock.stub_request(:get, /risk-entity-screening-cases/).to_timeout
end

it "raises Factiva::TimeoutError for CircuitBreaker" do
expect {
subject.get_matches(case_id: "id")
}.to raise_error(Factiva::TimeoutError)
end
end
end

describe "#log_decision", vcr: "monitoring/log_decision" do
Expand Down
24 changes: 24 additions & 0 deletions spec/factiva/request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,18 @@ module Factiva
}.to raise_error(RequestError, "Failed to connect to Factiva: SocketError")
end
end

context "Factiva connection timed out", vcr: "search/authentication_only" do
before do
WebMock.stub_request(:post, /riskentities\/search/).to_timeout
end

it "raises Factiva::TimeoutError for CircuitBreaker" do
expect {
subject.search(**params)
}.to raise_error(Factiva::TimeoutError)
end
end
end

context "#Profile" do
Expand Down Expand Up @@ -166,6 +178,18 @@ module Factiva
}.to raise_error(RequestError, "Failed to connect to Factiva: SocketError")
end
end

context "Factiva connection timed out", vcr: "profile/authentication_only" do
before do
WebMock.stub_request(:get, /riskentities\/profiles/).to_timeout
end

it "raises Factiva::TimeoutError for CircuitBreaker" do
expect {
subject.profile(profile_id)
}.to raise_error(Factiva::TimeoutError)
end
end
end

context "#Stub!" do
Expand Down
4 changes: 4 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@
config.expect_with :rspec do |c|
c.syntax = :expect
end

config.after(:each) do
WebMock.reset!
end
end
156 changes: 156 additions & 0 deletions spec/vcr/monitoring/authentication_only.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
---
http_interactions:
- request:
method: post
uri: https://accounts.dowjones.com/oauth2/v1/token
body:
encoding: UTF-8
string: client_id=<SECRET_CLIENT_ID>&connection=service-account&grant_type=password&password=<SECRET_PASSWORD>&scope=openid+service_account_id+offline_access%3A&username=<SECRET_USERNAME>&device=testdevice
headers:
Connection:
- close
Content-Type:
- application/x-www-form-urlencoded
Host:
- accounts.dowjones.com
User-Agent:
- http.rb/5.1.0
response:
status:
code: 200
message: OK
headers:
Content-Type:
- application/json; charset=utf-8
Content-Length:
- '873'
Connection:
- close
Access-Control-Allow-Methods:
- POST, GET, OPTIONS
Access-Control-Allow-Origin:
- "*"
Date:
- Wed, 22 Jun 2022 07:47:23 GMT
Server:
- Apache
Set-Cookie:
- djcs_route=76fc7bb7-f551-4e6f-8a3e-c5f63f96be7f; domain=.dowjones.com; path=/;
Expires=Sat Jun 19 07:47:23 2032; max-age=315360000;Secure; SameSite=none
X-P-Cache-Control:
- no-store
X-P-Connection:
- keep-alive
X-P-Content-Length:
- '873'
X-P-Content-Type:
- application/json; charset=utf-8
X-P-Date:
- Wed, 22 Jun 2022 07:47:23 GMT
X-P-P3p:
- CP="CAO DSP COR CURa ADMa DEVi TAIo PSAa PSDa IVDi CONi OTPi OUR OTRi BUS
PHY ONL UNI PUR COM NAV INT DEM CNT STA OTC"
X-P-Pragma:
- no-cache
X-P-Server:
- Microsoft-IIS/8.5
X-P-Via:
- 1.1 adb1632aa800f446f3f4e7b45c9dfd3e.cloudfront.net (CloudFront)
X-P-X-Amz-Cf-Id:
- cFsWb5PSIemUXKqN0oNEtJagitdH0EevR6brAIwFZ1iych834FXlcw==
X-P-X-Amz-Cf-Pop:
- IAD89-P2
X-P-X-Cache:
- Miss from cloudfront
X-P-X-Powered-By:
- ASP.NET
X-Cache:
- Miss from cloudfront
Via:
- 1.1 c0e2ae682a5570bf4332731523d68828.cloudfront.net (CloudFront)
X-Amz-Cf-Pop:
- LIS50-C1
X-Amz-Cf-Id:
- 4hJ8EPIkr08RRDx8QnwfhyRY0JLqHem2XdE5orWcHHr4hPA_704o8w==
body:
encoding: UTF-8
string: '{"id_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik4wSTJRekJEUWpRM04wUkJSakJFUkRVM05qaEZNREF5T0VWRlJqWkRSVVl4TWtFMU5ERXdSUSJ9.eyJzZXJ2aWNlX2FjY291bnRfaWQiOiI5U0VRMDAwMzAwIiwiaXNzIjoiaHR0cHM6Ly9hdXRoLmFjY291bnRzLmRvd2pvbmVzLmNvbS8iLCJzdWIiOiJhdXRoMHw2MmE4ZGU5NzEwOGVjZTViODgxYWQxMmMiLCJhdWQiOiJ0emVXSmhhMVc1TndyVUJSQ1N3T2R0Q0dxSVE1bXpBSSIsImlhdCI6MTY1NTg4NDA0MywiZXhwIjoxNjU1OTIwMDQzfQ.fQ4LVRmMaqVRk1y5U37FCGkMz1CPMSsqOS7SSxxncpn0298pzSsH4MabbPOwzjmJ5pOJIJUgj2nHNmgLbRFH94xuWae40aENoWNxsp53UM1g9CTBGbUYj1ErxGmOQutw5yDR4ZFAjni3Lhj6s9pcvRFshNa0nDVtoOh53rz5NBfsN4kGNMUR31xyTPmlCZIbyJ2d3nR2vQv-OEbknoBQ9sBFxWwWkrTYjyZ28w6VGyAH2zC06zKSNgoMbC9GuXYoH5C8RXOu0EOcF6Q01mUABosGwOwJ02cg1DthIBssJ6BAkyegkQHupSXb5FZ45Z3Zwh16MZD_ig8oVi64-573bA","access_token":"SvXvu7ftOhw5UaMzhuHAQrqCZskUn3Wp","refresh_token":"GjZC_up_ctheOU6B2_eouvhq8LyLEtqBdFewcDbUUU6po","token_type":"bearer"}'
recorded_at: Wed, 22 Jun 2022 07:47:23 GMT
- request:
method: post
uri: https://accounts.dowjones.com/oauth2/v1/token
body:
encoding: UTF-8
string: assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik4wSTJRekJEUWpRM04wUkJSakJFUkRVM05qaEZNREF5T0VWRlJqWkRSVVl4TWtFMU5ERXdSUSJ9.eyJzZXJ2aWNlX2FjY291bnRfaWQiOiI5U0VRMDAwMzAwIiwiaXNzIjoiaHR0cHM6Ly9hdXRoLmFjY291bnRzLmRvd2pvbmVzLmNvbS8iLCJzdWIiOiJhdXRoMHw2MmE4ZGU5NzEwOGVjZTViODgxYWQxMmMiLCJhdWQiOiJ0emVXSmhhMVc1TndyVUJSQ1N3T2R0Q0dxSVE1bXpBSSIsImlhdCI6MTY1NTg4NDA0MywiZXhwIjoxNjU1OTIwMDQzfQ.fQ4LVRmMaqVRk1y5U37FCGkMz1CPMSsqOS7SSxxncpn0298pzSsH4MabbPOwzjmJ5pOJIJUgj2nHNmgLbRFH94xuWae40aENoWNxsp53UM1g9CTBGbUYj1ErxGmOQutw5yDR4ZFAjni3Lhj6s9pcvRFshNa0nDVtoOh53rz5NBfsN4kGNMUR31xyTPmlCZIbyJ2d3nR2vQv-OEbknoBQ9sBFxWwWkrTYjyZ28w6VGyAH2zC06zKSNgoMbC9GuXYoH5C8RXOu0EOcF6Q01mUABosGwOwJ02cg1DthIBssJ6BAkyegkQHupSXb5FZ45Z3Zwh16MZD_ig8oVi64-573bA&client_id=<SECRET_CLIENT_ID>&grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&scope=openid+pib
headers:
Connection:
- close
Content-Type:
- application/x-www-form-urlencoded
Host:
- accounts.dowjones.com
User-Agent:
- http.rb/5.1.0
response:
status:
code: 200
message: OK
headers:
Content-Type:
- application/json; charset=utf-8
Content-Length:
- '1223'
Connection:
- close
Access-Control-Allow-Methods:
- POST, GET, OPTIONS
Access-Control-Allow-Origin:
- "*"
Date:
- Wed, 22 Jun 2022 07:47:23 GMT
Server:
- Apache
Set-Cookie:
- djcs_route=7e5f01e9-291b-4f83-931b-fc119bc8e54b; domain=.dowjones.com; path=/;
Expires=Sat Jun 19 07:47:23 2032; max-age=315360000;Secure; SameSite=none
Vary:
- Accept-Encoding
X-P-Cache-Control:
- no-store
X-P-Connection:
- keep-alive
X-P-Content-Length:
- '1223'
X-P-Content-Type:
- application/json; charset=utf-8
X-P-Date:
- Wed, 22 Jun 2022 07:47:23 GMT
X-P-P3p:
- CP="CAO DSP COR CURa ADMa DEVi TAIo PSAa PSDa IVDi CONi OTPi OUR OTRi BUS
PHY ONL UNI PUR COM NAV INT DEM CNT STA OTC"
X-P-Pragma:
- no-cache
X-P-Server:
- Microsoft-IIS/8.5
X-P-Via:
- 1.1 ec18462cf9d88c8bdb0cd5e50dbe442a.cloudfront.net (CloudFront)
X-P-X-Amz-Cf-Id:
- 5_lYlJfT5lKlqwLkg6KDNg12rR_giklC0SelFnfNOHut2e5qg--e-g==
X-P-X-Amz-Cf-Pop:
- IAD89-P2
X-P-X-Cache:
- Miss from cloudfront
X-P-X-Powered-By:
- ASP.NET
X-Cache:
- Miss from cloudfront
Via:
- 1.1 9b77256cb4a2caf313b1650e5e0805f8.cloudfront.net (CloudFront)
X-Amz-Cf-Pop:
- LIS50-C1
X-Amz-Cf-Id:
- PZLUnPMv75_oAyMtRBBE4AKARDB1gdf-URp8aLy34L3yXUAiSkUz0Q==
body:
encoding: UTF-8
string: '{"access_token":"eyJhbGciOiJSUzI1NiIsImtpZCI6IjJEN0IwQTFERkJCNzlDRDFBQjM4NzNCMTcyODMyRjkxMENEQkRBREIiLCJ0eXAiOiJKV1QifQ.eyJwaWIiOnsiYXBjIjoiUk5DIiwiY3RjIjoiUCIsIm1hc3Rlcl9hcHBfaWQiOiJ0emVXSmhhMVc1TndyVUJSQ1N3T2R0Q0dxSVE1bXpBSSIsInNlcnZpY2VfYWNjb3VudF9pZCI6IjlTRVEwMDAzMDAiLCJlbmNyeXB0ZWRfdG9rZW4iOiJJMDBfSlVZVE1OSlZIQTREQU1SU0hBWFZRV1JWSU5FR0MzTEtJSkhXRzJTWEs1UVZLTVRDRk5UVk1OTDJKVlJGT01DUk9STEhVTlNOSUpZRkEyU1pNUkFWTVUyUUdNWFVHMkRDR0IyVUdaQ0hJSkhYQTVDUUtKVUUyWkxMSlEzWEEySllGTlVEUzZLWk41SFZNNDNESlJYRUtUMzJHWlFYU1YyQ0tOWVdHSzJKSk5VVE1WWlBOQjJVUzVMVk5RWFdPVEo1STQifSwiaXNzIjoiaHR0cHM6Ly9hY2NvdW50cy5kb3dqb25lcy5jb20vb2F1dGgyL3YyIiwic3ViIjoiYXV0aDB8NjJhOGRlOTcxMDhlY2U1Yjg4MWFkMTJjIiwiYXVkIjoidHplV0poYTFXNU53clVCUkNTd09kdENHcUlRNW16QUkiLCJhenAiOiJ0emVXSmhhMVc1TndyVUJSQ1N3T2R0Q0dxSVE1bXpBSSIsImlhdCI6MTY1NTg4NDA0NCwiZXhwIjoxNjU1ODg3NjQ0fQ.SfbDxkzrH8sJveJh9cnCckCofdfGTBvwhHkpdLctlrL2lQ8KepNysE_lABkxEhGvMCRKYqNVYivGRpL-6EdCmt84ica2x9RclOEnJDfAgrA0sfXIlMF5fIBYVhbxvsxs38f08x_qCp45mQ3nZcHvT4MOHtseiduWxyR9lXiZ4JGWu0vAtoGU20rRC_5XZrLP9fYSHAZtlkhJnE2wwUdsc5jQh1gL4o2GZSxzdl-p5bY_1wxa_vuCOt2eWxqvuwYaNpDJv7eyTUwnnaLoQeJDI7hJOvZb6BekZ3kOtlOWoO1jvap2oQ6LA8IOtQKKy6a9W2Qqv2uUqYKtJrTjJ7m9Zg","token_type":"Bearer","expires_in":3600}'
recorded_at: Wed, 22 Jun 2022 07:47:24 GMT
Loading
Loading