roqua-healthy 1.5.0 → 1.5.1
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.
- checksums.yaml +4 -4
- data/.gitlab-ci.yml +18 -0
- data/.rubocop.yml +1 -1
- data/Gemfile +3 -0
- data/lib/roqua/errors.rb +0 -0
- data/lib/roqua/healthy.rb +1 -0
- data/lib/roqua/healthy/a19/fetcher.rb +7 -11
- data/lib/roqua/healthy/a19/response_validator.rb +1 -16
- data/lib/roqua/healthy/errors.rb +30 -0
- data/lib/roqua/healthy/oru.rb +10 -0
- data/lib/roqua/healthy/oru/client.rb +45 -0
- data/lib/roqua/healthy/version.rb +1 -1
- data/spec/unit/oru/client_spec.rb +131 -0
- metadata +8 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 72774ae40a9addc4ac31ab7ee7470b9ad251bf5f
|
|
4
|
+
data.tar.gz: 4f867af413282b3ac97041bd8a56b5f95a492025
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 48b2c55af9044ccc8395c87d71e9e1d4f201f98643646f0f70fdd5b2fabbe3d200293e61a6607909b52d9cdd533fc6cc3f285d2026a39b98218a270b03c51eb8
|
|
7
|
+
data.tar.gz: 6034a23f518d4db1d59aa7430c5c0ad594312f0e6bd50f09c50a1eb87828742f01cf8eb7de42eddac596c9aabc6a0201ee93ac4e9ab47e540a4999d8a9fa2451
|
data/.gitlab-ci.yml
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
image: "roqua/roqua-build-images:ruby-2.3.3-phantomjs-2.1.1-bundler-gemnasium"
|
|
2
|
+
|
|
3
|
+
before_script:
|
|
4
|
+
- ruby -v
|
|
5
|
+
- bundle-cache
|
|
6
|
+
- gem install appraisal
|
|
7
|
+
- bundle exec appraisal
|
|
8
|
+
|
|
9
|
+
rubocop:
|
|
10
|
+
script:
|
|
11
|
+
- bundle exec rubocop -D
|
|
12
|
+
|
|
13
|
+
rspec:
|
|
14
|
+
script:
|
|
15
|
+
- bundle exec appraisal rails41 bundle exec rspec
|
|
16
|
+
- bundle exec appraisal rails42 bundle exec rspec
|
|
17
|
+
- bundle exec appraisal rails50 bundle exec rspec
|
|
18
|
+
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
data/lib/roqua/errors.rb
ADDED
|
File without changes
|
data/lib/roqua/healthy.rb
CHANGED
|
@@ -25,18 +25,14 @@ module Roqua
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def mirth_response
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
Roqua::Healthy.convert_generic_errors_to_healthy_errors do
|
|
29
|
+
Net::HTTP.start(remote_url.host, remote_url.port, use_ssl: use_ssl?) do |http|
|
|
30
|
+
request = Net::HTTP::Post.new(remote_url.path)
|
|
31
|
+
request.basic_auth(@client.a19_username, @client.a19_password) if @client.use_basic_auth?
|
|
32
|
+
request.set_form_data(mirth_params)
|
|
33
|
+
http.request request
|
|
34
|
+
end
|
|
33
35
|
end
|
|
34
|
-
rescue ::Timeout::Error, Errno::ETIMEDOUT => error
|
|
35
|
-
raise ::Roqua::Healthy::Timeout, error.message
|
|
36
|
-
rescue Errno::EHOSTUNREACH => error
|
|
37
|
-
raise ::Roqua::Healthy::HostUnreachable, error.message
|
|
38
|
-
rescue Errno::ECONNREFUSED => error
|
|
39
|
-
raise ::Roqua::Healthy::ConnectionRefused, error.message
|
|
40
36
|
end
|
|
41
37
|
|
|
42
38
|
private
|
|
@@ -11,21 +11,6 @@ module Roqua
|
|
|
11
11
|
attr_reader :parser
|
|
12
12
|
attr_reader :patient_id
|
|
13
13
|
|
|
14
|
-
ERRORS = {
|
|
15
|
-
'Timeout waiting for ACK' =>
|
|
16
|
-
::Roqua::Healthy::Timeout,
|
|
17
|
-
"Unable to connect to destination\tSocketTimeoutException\tconnect timed out" =>
|
|
18
|
-
::Roqua::Healthy::Timeout,
|
|
19
|
-
'ERROR: Timeout waiting for response' =>
|
|
20
|
-
::Roqua::Healthy::Timeout,
|
|
21
|
-
'ERROR: SocketTimeoutException: connect timed out' =>
|
|
22
|
-
::Roqua::Healthy::Timeout,
|
|
23
|
-
"Unable to connect to destination\tConnectException\tConnection refused" =>
|
|
24
|
-
::Roqua::Healthy::ConnectionRefused,
|
|
25
|
-
'ERROR: ConnectException: Connection refused' =>
|
|
26
|
-
::Roqua::Healthy::ConnectionRefused
|
|
27
|
-
}.freeze
|
|
28
|
-
|
|
29
14
|
def initialize(response_code, parser, patient_id)
|
|
30
15
|
@response_code = response_code
|
|
31
16
|
@parser = parser
|
|
@@ -64,7 +49,7 @@ module Roqua
|
|
|
64
49
|
|
|
65
50
|
def validate_500
|
|
66
51
|
error = parser.fetch('failure')['error']
|
|
67
|
-
raise ERRORS[error], error if ERRORS[error]
|
|
52
|
+
raise ::Roqua::Healthy::ERRORS[error], error if ::Roqua::Healthy::ERRORS[error]
|
|
68
53
|
raise ::Roqua::Healthy::UnknownFailure, error
|
|
69
54
|
end
|
|
70
55
|
|
data/lib/roqua/healthy/errors.rb
CHANGED
|
@@ -3,6 +3,7 @@ module Roqua
|
|
|
3
3
|
module Healthy
|
|
4
4
|
class Error < StandardError; end
|
|
5
5
|
class ConnectionError < Error; end
|
|
6
|
+
class NACK < Error; end
|
|
6
7
|
|
|
7
8
|
class IllegalMirthResponse < ConnectionError; end
|
|
8
9
|
class Timeout < ConnectionError; end
|
|
@@ -17,5 +18,34 @@ module Roqua
|
|
|
17
18
|
module MirthErrors
|
|
18
19
|
class WrongPatient < Error; end
|
|
19
20
|
end
|
|
21
|
+
|
|
22
|
+
def self.convert_generic_errors_to_healthy_errors
|
|
23
|
+
yield
|
|
24
|
+
rescue RestClient::Exceptions::ReadTimeout, RestClient::Exceptions::OpenTimeout => error
|
|
25
|
+
raise ::Roqua::Healthy::Timeout, error.message
|
|
26
|
+
rescue ::Timeout::Error => error
|
|
27
|
+
raise ::Roqua::Healthy::Timeout, error.message
|
|
28
|
+
rescue Errno::ETIMEDOUT => error
|
|
29
|
+
raise ::Roqua::Healthy::Timeout, error.message
|
|
30
|
+
rescue Errno::EHOSTUNREACH => error
|
|
31
|
+
raise ::Roqua::Healthy::HostUnreachable, error.message
|
|
32
|
+
rescue Errno::ECONNREFUSED => error
|
|
33
|
+
raise ::Roqua::Healthy::ConnectionRefused, error.message
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
ERRORS = {
|
|
37
|
+
'Timeout waiting for ACK' =>
|
|
38
|
+
::Roqua::Healthy::Timeout,
|
|
39
|
+
"Unable to connect to destination\tSocketTimeoutException\tconnect timed out" =>
|
|
40
|
+
::Roqua::Healthy::Timeout,
|
|
41
|
+
'ERROR: Timeout waiting for response' =>
|
|
42
|
+
::Roqua::Healthy::Timeout,
|
|
43
|
+
'ERROR: SocketTimeoutException: connect timed out' =>
|
|
44
|
+
::Roqua::Healthy::Timeout,
|
|
45
|
+
"Unable to connect to destination\tConnectException\tConnection refused" =>
|
|
46
|
+
::Roqua::Healthy::ConnectionRefused,
|
|
47
|
+
'ERROR: ConnectException: Connection refused' =>
|
|
48
|
+
::Roqua::Healthy::ConnectionRefused
|
|
49
|
+
}.freeze
|
|
20
50
|
end
|
|
21
51
|
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'cgi'
|
|
4
|
+
require 'rest-client'
|
|
5
|
+
|
|
6
|
+
module Roqua
|
|
7
|
+
module Healthy
|
|
8
|
+
module Oru
|
|
9
|
+
class Client
|
|
10
|
+
def self.execute(url, data, timeout:)
|
|
11
|
+
Roqua::Healthy.convert_generic_errors_to_healthy_errors do
|
|
12
|
+
deliver_data(url, data, timeout: timeout)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.deliver_data(url, data, timeout:)
|
|
17
|
+
xml = CGI.escape(data.to_xml)
|
|
18
|
+
RestClient::Request.execute(
|
|
19
|
+
method: :post,
|
|
20
|
+
url: url.to_s,
|
|
21
|
+
payload: xml,
|
|
22
|
+
headers: {content_type: 'text/xml'},
|
|
23
|
+
timeout: timeout.to_i
|
|
24
|
+
) do |response, _request, _result|
|
|
25
|
+
|
|
26
|
+
xml_response = Hash.from_xml(response.body)
|
|
27
|
+
|
|
28
|
+
if response.code == 200 && xml_response['oru']['status'] == 'ACK'
|
|
29
|
+
response.body
|
|
30
|
+
else
|
|
31
|
+
handle_error(response, xml_response)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.handle_error(response, xml_response)
|
|
37
|
+
error = xml_response.dig('oru', 'error')
|
|
38
|
+
raise ::Roqua::Healthy::ERRORS[error], error if ::Roqua::Healthy::ERRORS[error]
|
|
39
|
+
raise ::Roqua::Healthy::NACK, error if error.present?
|
|
40
|
+
raise ::Roqua::Healthy::UnknownFailure, response.body
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
RSpec.describe Roqua::Healthy::Oru::Client do
|
|
5
|
+
def stub_oru_response(status, body = '<oru><status>ACK</status></oru>')
|
|
6
|
+
stub_request(:post, oru_url)
|
|
7
|
+
.with(
|
|
8
|
+
body: \
|
|
9
|
+
'%3C%3Fxml+version%3D%221.0%22+encoding%3D%22UTF-8%22%3F%3E%0A%3C' \
|
|
10
|
+
'hash%3E%0A++%3Coru+type%3D%22symbol%22%3Edata%3C%2Foru%3E%0A%3C%2Fhash%3E%0A',
|
|
11
|
+
headers: {
|
|
12
|
+
'Accept' => '*/*',
|
|
13
|
+
'Accept-Encoding' => 'gzip, deflate',
|
|
14
|
+
'Content-Length' => '140',
|
|
15
|
+
'Content-Type' => 'text/xml'
|
|
16
|
+
}
|
|
17
|
+
)
|
|
18
|
+
.to_return(status: status, body: body, headers: {})
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def stub_500_response
|
|
22
|
+
stub_request(:post, oru_url)
|
|
23
|
+
.to_return(status: 500, body: '<oru><status>NACK</status><error>ERROR</error></oru>', headers: {})
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def stub_404_response
|
|
27
|
+
stub_request(:post, oru_url)
|
|
28
|
+
.to_return(status: 404, body: '<oru><status>NACK</status><error>ERROR</error></oru>', headers: {})
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
let(:subject) { Roqua::Healthy::Oru::Client }
|
|
32
|
+
let(:oru_url) { 'https://example.com' }
|
|
33
|
+
let(:timeout) { 5.seconds }
|
|
34
|
+
|
|
35
|
+
def execute_request
|
|
36
|
+
subject.execute(oru_url, {oru: :data}, timeout: timeout)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context 'when Errno::ETIMEDOUT is triggered' do
|
|
40
|
+
it 'will raise an ::Roqua::Healthy::Timeout exception' do
|
|
41
|
+
expect(Roqua::Healthy::Oru::Client).to receive(:deliver_data).and_raise(Errno::ETIMEDOUT)
|
|
42
|
+
expect { execute_request }.to raise_error(::Roqua::Healthy::Timeout)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'sets the correct timeout' do
|
|
47
|
+
expect(RestClient::Request).to receive(:execute).with(
|
|
48
|
+
method: :post,
|
|
49
|
+
url: 'https://example.com',
|
|
50
|
+
payload: '%3C%3Fxml+version%3D%221.0%22+encoding%3D%22UTF-8%22%3F%3E%0A%3Chash%3E%0A++%3C' \
|
|
51
|
+
'oru+type%3D%22symbol%22%3Edata%3C%2Foru%3E%0A%3C%2Fhash%3E%0A',
|
|
52
|
+
headers: {content_type: 'text/xml'},
|
|
53
|
+
timeout: timeout.to_i
|
|
54
|
+
).and_return(double(body: '<oru><status>ACK</status></oru>'))
|
|
55
|
+
|
|
56
|
+
execute_request
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
context "when upstream is responding" do
|
|
60
|
+
it "does not raise an exception" do
|
|
61
|
+
stub_oru_response 200, '<oru><status>ACK</status></oru>'
|
|
62
|
+
execute_request
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context 'when a nack is received' do
|
|
66
|
+
before { stub_oru_response 200, '<oru><status>NACK</status><error>NACK</error></oru>' }
|
|
67
|
+
|
|
68
|
+
it 'raises a NACK exception' do
|
|
69
|
+
expect { execute_request }.to raise_error(Roqua::Healthy::NACK)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
context "when upstream is giving connection refused" do
|
|
75
|
+
before do
|
|
76
|
+
stub_request(:any, oru_url).to_raise Errno::ECONNREFUSED
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "should raise Oru::ConnectionRefused" do
|
|
80
|
+
expect { execute_request }.to raise_exception(Roqua::Healthy::ConnectionRefused)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
context "when upstream is giving connection timeouts" do
|
|
85
|
+
before do
|
|
86
|
+
stub_request(:any, oru_url).to_timeout
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "should raise Oru::Timeout" do
|
|
90
|
+
expect { execute_request }.to raise_exception(Roqua::Healthy::Timeout)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
context "when upstream is giving waiting for ack timeouts" do
|
|
95
|
+
before do
|
|
96
|
+
stub_oru_response \
|
|
97
|
+
500,
|
|
98
|
+
"<oru><status>FAILURE</status><channel>RGOC - Outbound port 60102</channel>" \
|
|
99
|
+
"<error>Timeout waiting for ACK</error></oru>"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "raises a NACK exception" do
|
|
103
|
+
expect { execute_request }.to raise_error(::Roqua::Healthy::Timeout, /Timeout waiting for ACK/)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
context 'when upstream responds with a 500 status' do
|
|
108
|
+
before { stub_500_response }
|
|
109
|
+
|
|
110
|
+
it 'transforms the exception to a NACK' do
|
|
111
|
+
expect { execute_request }.to raise_error Roqua::Healthy::NACK
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
context 'when upstream responds with a 404 status' do
|
|
116
|
+
before { stub_404_response }
|
|
117
|
+
|
|
118
|
+
it 'transforms the exception to a NACK' do
|
|
119
|
+
expect { execute_request }.to raise_error Roqua::Healthy::NACK
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
context "when the response doesn't contain an error portion" do
|
|
124
|
+
it 'will raise a ... exception' do
|
|
125
|
+
stub_request(:post, oru_url)
|
|
126
|
+
.to_return(status: 500, body: '<oru><status>Internal server error</status></oru>', headers: {})
|
|
127
|
+
|
|
128
|
+
expect { execute_request }.to raise_error Roqua::Healthy::UnknownFailure
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: roqua-healthy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.5.
|
|
4
|
+
version: 1.5.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Marten Veldthuis
|
|
@@ -11,7 +11,7 @@ authors:
|
|
|
11
11
|
autorequire:
|
|
12
12
|
bindir: bin
|
|
13
13
|
cert_chain: []
|
|
14
|
-
date: 2017-
|
|
14
|
+
date: 2017-07-05 00:00:00.000000000 Z
|
|
15
15
|
dependencies:
|
|
16
16
|
- !ruby/object:Gem::Dependency
|
|
17
17
|
name: activesupport
|
|
@@ -266,6 +266,7 @@ extra_rdoc_files: []
|
|
|
266
266
|
files:
|
|
267
267
|
- ".document"
|
|
268
268
|
- ".gitignore"
|
|
269
|
+
- ".gitlab-ci.yml"
|
|
269
270
|
- ".rspec"
|
|
270
271
|
- ".rubocop.yml"
|
|
271
272
|
- ".rubocop_todo.yml"
|
|
@@ -285,6 +286,7 @@ files:
|
|
|
285
286
|
- gemfiles/rails41.gemfile
|
|
286
287
|
- gemfiles/rails42.gemfile
|
|
287
288
|
- gemfiles/rails50.gemfile
|
|
289
|
+
- lib/roqua/errors.rb
|
|
288
290
|
- lib/roqua/healthy.rb
|
|
289
291
|
- lib/roqua/healthy/a19.rb
|
|
290
292
|
- lib/roqua/healthy/a19/address_parser.rb
|
|
@@ -299,6 +301,8 @@ files:
|
|
|
299
301
|
- lib/roqua/healthy/client.rb
|
|
300
302
|
- lib/roqua/healthy/errors.rb
|
|
301
303
|
- lib/roqua/healthy/message_cleaner.rb
|
|
304
|
+
- lib/roqua/healthy/oru.rb
|
|
305
|
+
- lib/roqua/healthy/oru/client.rb
|
|
302
306
|
- lib/roqua/healthy/version.rb
|
|
303
307
|
- lib/roqua_healthy.rb
|
|
304
308
|
- roqua-healthy.gemspec
|
|
@@ -350,6 +354,7 @@ files:
|
|
|
350
354
|
- spec/unit/a19_spec.rb
|
|
351
355
|
- spec/unit/client_spec.rb
|
|
352
356
|
- spec/unit/message_cleaner_spec.rb
|
|
357
|
+
- spec/unit/oru/client_spec.rb
|
|
353
358
|
homepage: https://github.com/roqua/healthy
|
|
354
359
|
licenses:
|
|
355
360
|
- MIT
|
|
@@ -423,3 +428,4 @@ test_files:
|
|
|
423
428
|
- spec/unit/a19_spec.rb
|
|
424
429
|
- spec/unit/client_spec.rb
|
|
425
430
|
- spec/unit/message_cleaner_spec.rb
|
|
431
|
+
- spec/unit/oru/client_spec.rb
|