redox 0.1.5 → 0.1.6

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
  SHA256:
3
- metadata.gz: b6ab25d3f19478659e8b289237cfc384ac214d2ac2fe880a4e5ea324b16488e0
4
- data.tar.gz: 035f903ba8152429b06c1ab2e1a6a17bc7639974bd483440448a391bab7c7763
3
+ metadata.gz: 4cf3d701269f03a48d3cd1fe870e2f124aeb705c643c4cd3826ad5b352317276
4
+ data.tar.gz: 562cc78ba951b7a58a3365612e09e38f114d7a7ab8ceb80b6e0e1c73b5592c7a
5
5
  SHA512:
6
- metadata.gz: de4c1669a46c1cc4257d84ae12a8a3243679bf6d264e58383519a57cc405ab71fa870d098903b92edd322a672f6901481e9e824d259c6f1d86e8223d642f25e7
7
- data.tar.gz: e98d7dfdfd023b845dcffadfcf46e17f8e21d2f1357f88cc0e0454cb377d2f7e6dad179a9c206f75be9432630cc6ccfcb6ec6ab6d73da8e06f73f43657e88de4
6
+ metadata.gz: fdd640751e3226609ac29cf6be385b7ae52487df1e46fa925e8e984cdf1e0458066f14e16a464dfa43d1201f9b0efcd988442c4eea26fd770a9b57d10e5cfd48
7
+ data.tar.gz: a339571774b1058f4b646d0d2667bee605def7683c2aa47e152f41bfb3cb51872915a91d120a8b7da5e75c89da0ff0b46ef7292931c3da9cd5941b74fd31b73e
@@ -4,9 +4,15 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
- ## [Unreleased]
7
+ ## [0.1.6] - Unreleased
8
8
  ### Added
9
- - <TBD>
9
+ - Meta model
10
+ - Response and Authentication classes
11
+
12
+ ### Changed
13
+ - Created a single request method
14
+ - Allow caller to override all Meta
15
+ - Made calls consistent in return and call signature
10
16
 
11
17
  ## [0.1.5] - 2019-04-09
12
18
  ### Added
@@ -4,7 +4,10 @@ require 'uri'
4
4
  require 'openssl'
5
5
  require 'redox/version'
6
6
  require 'redox/redox_exception'
7
+ require 'redox/authentication'
8
+ require 'redox/response'
7
9
  require 'redox/models/model'
10
+ require 'redox/models/meta'
8
11
  require 'redox/models/patient'
9
12
  require 'redox/models/demographics'
10
13
  require 'redox/models/identifiers'
@@ -12,6 +15,8 @@ require 'redox/models/identifiers'
12
15
  module Redox
13
16
  # Redox API client
14
17
  class Redox
18
+ DEFAULT_URI = 'https://api.redoxengine.com/'.freeze
19
+
15
20
  # Instantiates a new Redox connection object
16
21
  #
17
22
  # @param [String] api_key API key for the connection
@@ -27,15 +32,17 @@ module Redox
27
32
  # destinations: destinations,
28
33
  # test: true
29
34
  # )
30
- def initialize(api_key:, secret:, source:, destinations:, facility_code: nil, test: true)
35
+ def initialize(api_key:, secret:, source: nil, destinations: nil, facility_code: nil, test: true, uri: DEFAULT_URI)
31
36
  @api_key = api_key
32
37
  @secret = secret
33
- @source = source
34
- @destinations = destinations
35
- @facility_code = facility_code
36
- @test = test
38
+ @meta = Models::Meta.new
39
+ destinations.each {|dest| @meta.add_destination(dest['Name'], dest['ID']) } if destinations
40
+ @meta.source = source if source
41
+ @meta.facility_code = facility_code if facility_code
42
+ @meta.test = test
37
43
  @connection = nil
38
- @access_token = nil
44
+ @authentication = nil
45
+ @uri = uri
39
46
  end
40
47
 
41
48
  # Send NewPatient message
@@ -49,16 +56,15 @@ module Redox
49
56
  # FirstName: 'Joe'
50
57
  # }
51
58
  # )
52
- def add_patient(patient_params)
53
- patient_request = Net::HTTP::Post.new('/endpoint', auth_header)
54
- request_body = request_meta(
55
- data_model: 'PatientAdmin', event_type: 'NewPatient'
56
- ).merge(Patient: patient_params)
57
- patient_request.body = request_body.to_json
58
-
59
- response = connection.request(patient_request)
60
-
61
- JSON.parse(response.body)
59
+ def add_patient(patient_params, meta = nil)
60
+ meta = @meta.merge(Models::Meta.from_h(Models::Patient::ADD[:meta]).merge(meta))
61
+ body = meta.to_h.merge(Patient: patient_params)
62
+
63
+ return request(
64
+ endpoint: Models::Patient::ADD[:endpoint],
65
+ body: body.to_json,
66
+ model: Models::Patient
67
+ )
62
68
  end
63
69
 
64
70
  # Send PatientUpdate message
@@ -72,16 +78,15 @@ module Redox
72
78
  # FirstName: 'Joe'
73
79
  # }
74
80
  # )
75
- def update_patient(patient_params)
76
- patient_request = Net::HTTP::Post.new('/endpoint', auth_header)
77
- request_body = request_meta(
78
- data_model: 'PatientAdmin', event_type: 'PatientUpdate'
79
- ).merge(Patient: patient_params)
80
- patient_request.body = request_body.to_json
81
-
82
- response = connection.request(patient_request)
83
-
84
- JSON.parse(response.body)
81
+ def update_patient(patient_params, meta = nil)
82
+ meta = @meta.merge(Models::Meta.from_h(Models::Patient::UPDATE[:meta]).merge(meta))
83
+ body = meta.to_h.merge(Patient: patient_params)
84
+
85
+ return request(
86
+ endpoint: Models::Patient::UPDATE[:endpoint],
87
+ body: body.to_json,
88
+ model: Models::Patient
89
+ )
85
90
  end
86
91
 
87
92
  # Send PatientSearch query
@@ -95,43 +100,55 @@ module Redox
95
100
  # FirstName: 'Joe'
96
101
  # }
97
102
  # )
98
- def search_patients(patient_params)
99
- patient_request = Net::HTTP::Post.new(Models::Patient::SEARCH[:endpoint], auth_header)
100
- request_body = request_meta(Models::Patient::SEARCH[:meta])
101
- .merge(Patient: patient_params)
102
- patient_request.body = request_body.to_json
103
-
104
- response = connection.request(patient_request)
105
-
106
- return Models::Patient.new(JSON.parse(response.body))
103
+ def search_patients(patient_params, meta = nil)
104
+ meta = @meta.merge(Models::Meta.from_h(Models::Patient::SEARCH[:meta]).merge(meta))
105
+ body = meta.to_h.merge(Patient: patient_params)
106
+
107
+ return request(
108
+ endpoint: Models::Patient::SEARCH[:endpoint],
109
+ body: body.to_json,
110
+ model: Models::Patient
111
+ )
107
112
  end
108
113
 
109
114
  private
110
115
 
111
- attr_reader :api_key, :secret, :source, :destinations, :facility_code, :test
116
+ attr_reader :api_key, :secret, :meta
117
+
118
+ def request(endpoint: , body: , header: {}, model: nil, authorize: true)
119
+ header = {
120
+ 'Content-Type' => 'application/json'
121
+ }.merge(header)
122
+
123
+ header = header.merge(authenticate.access_header) if authorize
124
+
125
+ request = Net::HTTP::Post.new(endpoint, header)
126
+ request.body = body
112
127
 
113
- def access_token
114
- return @access_token if @access_token
128
+ return Response.new(connection.request(request), model)
129
+ end
130
+
131
+ def authenticate
132
+ return @authentication if @authentication
115
133
 
116
- login_request = Net::HTTP::Post.new(
117
- '/auth/authenticate', 'Content-Type' => 'application/json'
134
+ redox_response = request(
135
+ endpoint: Authentication::ENDPOINT,
136
+ body: { apiKey: api_key, secret: secret }.to_json,
137
+ model: Authentication,
138
+ authorize: false
118
139
  )
119
- login_request.body = { apiKey: api_key, secret: secret }.to_json
120
- response = connection.request(login_request)
121
140
 
122
- if (false == response.is_a?(Net::HTTPOK))
123
- raise RedoxException.from_response(response, msg: 'Authentication')
141
+ if (false == redox_response.success?)
142
+ raise RedoxException.from_response(redox_response.http_response, msg: 'Authentication')
124
143
  end
125
144
 
126
- body = JSON.parse(response.body)
127
-
128
- @access_token = body['accessToken']
145
+ @authentication = redox_response.model
129
146
  end
130
147
 
131
148
  def connection
132
149
  return @connection if @connection
133
150
 
134
- uri = URI.parse('https://api.redoxengine.com/')
151
+ uri = URI.parse(@uri)
135
152
  http = Net::HTTP.new(uri.host, uri.port)
136
153
  http.use_ssl = true
137
154
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
@@ -139,29 +156,5 @@ module Redox
139
156
 
140
157
  @connection = http
141
158
  end
142
-
143
- def auth_header
144
- {
145
- 'Authorization' => "Bearer #{access_token}",
146
- 'Content-Type' => 'application/json'
147
- }
148
- end
149
-
150
- def request_meta(data_model:, event_type:)
151
- meta_object = {
152
- Meta: {
153
- DataModel: data_model,
154
- EventType: event_type,
155
- EventDateTime: nil,
156
- Test: test,
157
- }
158
- }
159
-
160
- meta_object[:Meta][:FacilityCode] = facility_code if facility_code
161
- meta_object[:Meta][:Source] = source if source
162
- meta_object[:Meta][:Destinations] = destinations if destinations && !destinations.empty?
163
-
164
- meta_object
165
- end
166
159
  end
167
160
  end
@@ -0,0 +1,19 @@
1
+ module Redox
2
+ class Authentication
3
+ ENDPOINT = '/auth/authenticate'.freeze
4
+
5
+ def initialize(response_body)
6
+ @body = response_body
7
+ end
8
+
9
+ def access_token
10
+ return @body['accessToken']
11
+ end
12
+
13
+ def access_header
14
+ return {
15
+ 'Authorization' => "Bearer #{access_token}",
16
+ }
17
+ end
18
+ end
19
+ end
@@ -1,7 +1,7 @@
1
1
  module Redox
2
2
  module Models
3
3
  class Demographics < Model
4
- KEY = 'Demographics'
4
+ KEY = 'Demographics'.freeze
5
5
  end
6
6
  end
7
7
  end
@@ -1,7 +1,7 @@
1
1
  module Redox
2
2
  module Models
3
3
  class Identifiers < Model
4
- KEY = 'Identifiers'
4
+ KEY = 'Identifiers'.freeze
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,80 @@
1
+ module Redox
2
+ module Models
3
+ class Meta < Model
4
+ KEY = 'Meta'.freeze
5
+
6
+ DEFAULT = -> () {
7
+ return {
8
+ KEY => {
9
+ 'DataModel' => nil,
10
+ 'EventType' => nil,
11
+ 'EventDateTime' => Time.now.strftime("%Y-%m-%dT%H:%M:%S.%6NZ"),
12
+ 'Test' => true,
13
+ 'Source' => {},
14
+ 'Destinations' => [],
15
+ 'FacilityCode' => nil
16
+ }
17
+ }
18
+ }
19
+
20
+ def initialize(data = DEFAULT.call)
21
+ super(data)
22
+ end
23
+
24
+ def add_destination(name, id)
25
+ self.inner['Destinations'] << Meta.build_subscription(name, id)
26
+
27
+ return self
28
+ end
29
+
30
+ def set_source(name, id)
31
+ self.source = Meta.build_subscription(name, id)
32
+
33
+ return self
34
+ end
35
+
36
+ def source=(source)
37
+ self.inner['Source'] = source
38
+ end
39
+
40
+ def facility_code=(facility_code)
41
+ self.inner['FacilityCode'] = facility_code.to_s
42
+ end
43
+
44
+ def test=(test)
45
+ self.inner['Test'] = (true == test)
46
+ end
47
+
48
+ def merge(other)
49
+ if (other.is_a?(Hash))
50
+ if (other.include?(KEY))
51
+ self.inner.merge!(other[KEY])
52
+ else
53
+ self.inner.merge!(other)
54
+ end
55
+ elsif (other.is_a?(self.class))
56
+ self.inner.merge!(other.inner.select {|k,v| !v.nil?})
57
+ end
58
+
59
+ return self
60
+ end
61
+
62
+ def to_h
63
+ return JSON.parse(@data.to_json)
64
+ end
65
+
66
+ class << self
67
+ def build_subscription(name, id)
68
+ return {
69
+ 'ID' => id,
70
+ 'Name' => name
71
+ }
72
+ end
73
+
74
+ def from_h(hash)
75
+ return Meta.new.merge(hash)
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -11,39 +11,17 @@ module Redox
11
11
  return @data.is_a?(Hash) && @data.include?(self.class::KEY)
12
12
  end
13
13
 
14
- def raw(key: self.class::KEY)
14
+ def raw
15
+ return self.inner(key: nil)
16
+ end
17
+
18
+ def inner(key: self.class::KEY)
15
19
  if key.nil?
16
20
  return @data
17
21
  else
18
22
  return @data[key]
19
23
  end
20
24
  end
21
-
22
- def map(mapper: {}, data: self.raw)
23
- result = {}
24
-
25
- if (true == mapper.is_a?(Hash))
26
- mapper.each do |key, value|
27
- if (true == value.is_a?(Hash))
28
- result = result.merge(self.map(data: data[key], mapper: value))
29
- elsif (true == value.respond_to?(:call))
30
- lambda_result = value.call(data[key])
31
-
32
- if (true == lambda_result.is_a?(Hash))
33
- result = result.merge(lambda_result)
34
- else
35
- raise "lambda must return hash"
36
- end
37
- else
38
- result[value] = data[key]
39
- end
40
- end
41
- else
42
- raise "mapper must be a hash, got '#{mapper}'"
43
- end
44
-
45
- return result
46
- end
47
25
  end
48
26
  end
49
27
  end
@@ -3,22 +3,38 @@ module Redox
3
3
  class Patient < Model
4
4
  attr_reader :demographics, :identifiers
5
5
 
6
- KEY = 'Patient'
6
+ KEY = 'Patient'.freeze
7
7
 
8
8
  SEARCH = {
9
9
  meta: {
10
- data_model: 'PatientSearch',
11
- event_type: 'Query'
10
+ 'DataModel' => 'PatientSearch',
11
+ 'EventType' => 'Query'
12
12
  },
13
13
  endpoint: '/query'
14
14
  }
15
15
 
16
+ ADD = {
17
+ meta: {
18
+ 'DataModel' => 'PatientAdmin',
19
+ 'EventType' => 'NewPatient'
20
+ },
21
+ endpoint: '/endpoint'
22
+ }
23
+
24
+ UPDATE = {
25
+ meta: {
26
+ 'DataModel' => 'PatientAdmin',
27
+ 'EventType' => 'PatientUpdate'
28
+ },
29
+ endpoint: '/endpoint'
30
+ }
31
+
16
32
  def initialize(data)
17
33
  super(data)
18
34
 
19
35
  if (self.valid?)
20
- @demographics = Demographics.new(self.raw)
21
- @identifiers = Identifiers.new(self.raw)
36
+ @demographics = Demographics.new(self.inner)
37
+ @identifiers = Identifiers.new(self.inner)
22
38
  end
23
39
  end
24
40
  end
@@ -0,0 +1,14 @@
1
+ module Redox
2
+ class Response
3
+ attr_reader :model, :http_response
4
+
5
+ def initialize(response, model_class = nil)
6
+ @http_response = response
7
+ @model = model_class.new(JSON.parse(response.body)) if !model_class.nil? && self.success?
8
+ end
9
+
10
+ def success?
11
+ return @http_response.is_a?(Net::HTTPOK)
12
+ end
13
+ end
14
+ end
@@ -1,3 +1,3 @@
1
1
  module Redox
2
- VERSION = '0.1.5'.freeze
2
+ VERSION = '0.1.6'.freeze
3
3
  end
@@ -27,6 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.require_paths = ['lib']
28
28
 
29
29
  spec.add_development_dependency 'bundler'
30
+ spec.add_development_dependency 'byebug'
30
31
  spec.add_development_dependency 'minitest', '~> 5.0'
31
32
  spec.add_development_dependency 'rake', '~> 10.0'
32
33
  spec.add_development_dependency 'webmock', '~> 3.1'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Clark
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-04-09 00:00:00.000000000 Z
11
+ date: 2019-04-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: byebug
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: minitest
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -98,11 +112,14 @@ files:
98
112
  - bin/console
99
113
  - bin/setup
100
114
  - lib/redox.rb
115
+ - lib/redox/authentication.rb
101
116
  - lib/redox/models/demographics.rb
102
117
  - lib/redox/models/identifiers.rb
118
+ - lib/redox/models/meta.rb
103
119
  - lib/redox/models/model.rb
104
120
  - lib/redox/models/patient.rb
105
121
  - lib/redox/redox_exception.rb
122
+ - lib/redox/response.rb
106
123
  - lib/redox/version.rb
107
124
  - redox.gemspec
108
125
  homepage: https://github.com/WeInfuse/redox