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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f3959d17316a51405355769df7a3bd596599676b
4
- data.tar.gz: 4d4192a2c29410a69420e98e611c9c56ab590e3d
3
+ metadata.gz: 72774ae40a9addc4ac31ab7ee7470b9ad251bf5f
4
+ data.tar.gz: 4f867af413282b3ac97041bd8a56b5f95a492025
5
5
  SHA512:
6
- metadata.gz: 9977ba10cb3b7b6f267231f8f910713fb989614019d6d44b4cc2c09e6ca9671924b80373c30e33a78d331dae3599dd2761a2005fefa1cebba5c389220eac9df9
7
- data.tar.gz: 7241aae05b61c2f276f86ba5ce34c24b3abd8ee788084ac1e7cd746788ef7469be58643084dd25c4790e0e8087a9fc704c680599e1296b266fede1a88f57a205
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
@@ -23,7 +23,7 @@ MethodLength:
23
23
  SignalException:
24
24
  Enabled: False
25
25
 
26
- Style/EmptyLineAfterMagicComment:
26
+ Layout/EmptyLineAfterMagicComment:
27
27
  Enabled: False
28
28
 
29
29
  Style/FileName:
data/Gemfile CHANGED
@@ -7,3 +7,6 @@ gemspec
7
7
  # Normal development dependencies should go in the gemspec. People shouldn't
8
8
  # need to use bundler to develop on our gem.
9
9
  gem "codeclimate-test-reporter", "~> 1.0.0", group: :test, require: nil
10
+
11
+ gem 'builder'
12
+ gem 'rest-client'
File without changes
data/lib/roqua/healthy.rb CHANGED
@@ -4,6 +4,7 @@ require 'roqua/support'
4
4
  require 'roqua/healthy/version'
5
5
  require 'roqua/healthy/message_cleaner'
6
6
  require 'roqua/healthy/a19'
7
+ require 'roqua/healthy/oru'
7
8
  require 'roqua/healthy/client'
8
9
  require 'roqua/healthy/errors'
9
10
 
@@ -25,18 +25,14 @@ module Roqua
25
25
  end
26
26
 
27
27
  def mirth_response
28
- Net::HTTP.start(remote_url.host, remote_url.port, use_ssl: use_ssl?) do |http|
29
- request = Net::HTTP::Post.new(remote_url.path)
30
- request.basic_auth(@client.a19_username, @client.a19_password) if @client.use_basic_auth?
31
- request.set_form_data(mirth_params)
32
- http.request request
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
 
@@ -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,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roqua
4
+ module Healthy
5
+ module Oru
6
+ end
7
+ end
8
+ end
9
+
10
+ require_relative 'oru/client'
@@ -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
@@ -2,6 +2,6 @@
2
2
  module Roqua
3
3
  module Healthy
4
4
  # healthy version
5
- VERSION = "1.5.0"
5
+ VERSION = "1.5.1"
6
6
  end
7
7
  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.0
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-04-18 00:00:00.000000000 Z
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