roqua-healthy 1.5.0 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
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