inferno_core 0.4.19 → 0.4.21
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/lib/inferno/dsl/fhir_client.rb +43 -5
- data/lib/inferno/dsl/fhir_validation.rb +21 -17
- data/lib/inferno/exceptions.rb +7 -4
- data/lib/inferno/public/bundle.js +12 -12
- data/lib/inferno/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13f75c775423384dd5bf4a2b13081bc05a155155fca9a6bcea1986d2baf09b15
|
4
|
+
data.tar.gz: 7b6c586b121fad54caa57fb5ae8d8c7300467b543ece25c4222c21cc65ac83c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f0ab91414e4554a430972dd25543339cd39245c0d154dcc42d0a623c83b4aeaccf32709d08074abd4dcae07cf3deb75144a2db3cd3af548a37ddc552b0df909
|
7
|
+
data.tar.gz: 2f328c92cb3d66853eccde4aee267be6e8e668b778f75e1d278a3b5d4ba86840e4f0e260fbc5bf941017ee8bde1cd20699a53153cd9e26ee8e9bee8fa730ab7c
|
@@ -60,26 +60,64 @@ module Inferno
|
|
60
60
|
@fhir_clients ||= {}
|
61
61
|
end
|
62
62
|
|
63
|
+
# Wrapper for checking if parameter contents are primitive
|
64
|
+
#
|
65
|
+
# @param param [FHIR::Parameters::Parameter] Parameter to be checked
|
66
|
+
# @private
|
67
|
+
def primitive_parameter?(param)
|
68
|
+
param_val = param.to_hash.except('name')
|
69
|
+
param_val.any? { |datatype, param_value| FHIR.primitive?(datatype: datatype[5..], value: param_value) }
|
70
|
+
end
|
71
|
+
|
72
|
+
# Converts a list of FHIR Parameters into a query string for GET requests
|
73
|
+
#
|
74
|
+
# @param body [FHIR::Parameters] Must all be primitive if making GET request
|
75
|
+
# @private
|
76
|
+
def body_to_path(body)
|
77
|
+
query_hashes = body.parameter.map do |param|
|
78
|
+
if primitive_parameter?(param)
|
79
|
+
{ param.name => param.to_hash.except('name').values[0] }
|
80
|
+
else
|
81
|
+
Inferno::Application[:logger].error "Cannot use GET request with non-primitive datatype #{param.name}"
|
82
|
+
raise ArgumentError, "Cannot use GET request with non-primitive datatype #{param.name}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
query_hashes.map(&:to_query).join('&')
|
86
|
+
end
|
87
|
+
|
63
88
|
# Perform a FHIR operation
|
64
89
|
#
|
65
90
|
# @note This is a placeholder method until the FHIR::Client supports
|
66
|
-
# general operations
|
91
|
+
# general operations. Note that while both POST and GET methods are allowed,
|
92
|
+
# GET is only allowed when the operation does not affect the server's state.
|
93
|
+
# See https://build.fhir.org/operationdefinition-definitions.html#OperationDefinition.affectsState
|
94
|
+
#
|
95
|
+
# @note Currently does not allow for repeated parameters if using GET
|
67
96
|
#
|
68
97
|
# @param path [String]
|
69
|
-
# @param body [FHIR::Parameters]
|
98
|
+
# @param body [FHIR::Parameters] Must all be primitive if making GET request
|
70
99
|
# @param client [Symbol]
|
71
100
|
# @param name [Symbol] Name for this request to allow it to be used by
|
72
101
|
# other tests
|
73
102
|
# @param headers [Hash] custom headers for this operation
|
103
|
+
# @param operation_method [Symbol] indicates which request type to use for the operation
|
74
104
|
# @return [Inferno::Entities::Request]
|
75
|
-
def fhir_operation(path, body: nil, client: :default, name: nil, headers: {})
|
105
|
+
def fhir_operation(path, body: nil, client: :default, name: nil, headers: {}, operation_method: :post)
|
76
106
|
store_request_and_refresh_token(fhir_client(client), name) do
|
77
107
|
tcp_exception_handler do
|
78
108
|
operation_headers = fhir_client(client).fhir_headers
|
79
109
|
operation_headers.merge!('Content-Type' => 'application/fhir+json') if body.present?
|
80
110
|
operation_headers.merge!(headers) if headers.present?
|
81
|
-
|
82
|
-
|
111
|
+
case operation_method
|
112
|
+
when :post
|
113
|
+
fhir_client(client).send(:post, path, body, operation_headers)
|
114
|
+
when :get
|
115
|
+
path = "#{path}?#{body_to_path(body)}" if body.present?
|
116
|
+
fhir_client(client).send(:get, path, operation_headers)
|
117
|
+
else
|
118
|
+
Inferno::Application[:logger].error "Cannot perform #{operation_method} requests, use GET or POST"
|
119
|
+
raise ArgumentError, "Cannot perform #{operation_method} requests, use GET or POST"
|
120
|
+
end
|
83
121
|
end
|
84
122
|
end
|
85
123
|
end
|
@@ -116,14 +116,22 @@ module Inferno
|
|
116
116
|
def resource_is_valid?(resource, profile_url, runnable)
|
117
117
|
profile_url ||= FHIR::Definitions.resource_definition(resource.resourceType).url
|
118
118
|
|
119
|
-
|
119
|
+
begin
|
120
|
+
response = call_validator(resource, profile_url)
|
121
|
+
rescue StandardError => e
|
122
|
+
# This could be a complete failure to connect (validator isn't running)
|
123
|
+
# or a timeout (validator took too long to respond).
|
124
|
+
runnable.add_message('error', e.message)
|
125
|
+
raise Inferno::Exceptions::ErrorInValidatorException, "Unable to connect to validator at #{url}."
|
126
|
+
end
|
127
|
+
outcome = operation_outcome_from_validator_response(response.body, runnable)
|
120
128
|
|
121
129
|
message_hashes = message_hashes_from_outcome(outcome, resource, profile_url)
|
122
130
|
|
123
131
|
message_hashes
|
124
132
|
.each { |message_hash| runnable.add_message(message_hash[:type], message_hash[:message]) }
|
125
133
|
|
126
|
-
unless
|
134
|
+
unless response.status == 200
|
127
135
|
raise Inferno::Exceptions::ErrorInValidatorException,
|
128
136
|
'Error occurred in the validator. Review Messages tab or validator service logs for more information.'
|
129
137
|
end
|
@@ -191,21 +199,17 @@ module Inferno
|
|
191
199
|
#
|
192
200
|
# @param resource [FHIR::Model]
|
193
201
|
# @param profile_url [String]
|
194
|
-
# @
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
response = Faraday.new(
|
199
|
-
url,
|
200
|
-
params: { profile: profile_url }
|
201
|
-
).post('validate', resource.source_contents)
|
202
|
-
rescue StandardError => e
|
203
|
-
runnable.add_message('error', e.message)
|
204
|
-
raise Inferno::Exceptions::ErrorInValidatorException, "Unable to connect to validator at #{url}."
|
205
|
-
end
|
206
|
-
outcome = operation_outcome_from_validator_response(response.body, runnable)
|
202
|
+
# @return [String] the body of the validation response
|
203
|
+
def validate(resource, profile_url)
|
204
|
+
call_validator(resource, profile_url).body
|
205
|
+
end
|
207
206
|
|
208
|
-
|
207
|
+
# @private
|
208
|
+
def call_validator(resource, profile_url)
|
209
|
+
Faraday.new(
|
210
|
+
url,
|
211
|
+
params: { profile: profile_url }
|
212
|
+
).post('validate', resource.source_contents)
|
209
213
|
end
|
210
214
|
|
211
215
|
# @private
|
@@ -213,7 +217,7 @@ module Inferno
|
|
213
217
|
if response.start_with? '{'
|
214
218
|
FHIR::OperationOutcome.new(JSON.parse(response))
|
215
219
|
else
|
216
|
-
runnable.add_message('error', "Validator Response
|
220
|
+
runnable.add_message('error', "Validator Response:\n#{response}")
|
217
221
|
raise Inferno::Exceptions::ErrorInValidatorException,
|
218
222
|
'Validator response was an unexpected format. '\
|
219
223
|
'Review Messages tab or validator service logs for more information.'
|
data/lib/inferno/exceptions.rb
CHANGED
@@ -39,11 +39,14 @@ module Inferno
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
+
# ErrorInValidatorException is used when an exception occurred in
|
43
|
+
# calling the validator service, for example a connection timeout
|
44
|
+
# or an unexpected response format.
|
45
|
+
# Note: This class extends TestResultException instead of RuntimeError
|
46
|
+
# to bypass printing the stack trace in the UI, since
|
47
|
+
# the stack trace of this exception is not likely be useful.
|
48
|
+
# Instead the message should point to where in the validator an error occurred.
|
42
49
|
class ErrorInValidatorException < TestResultException
|
43
|
-
# This extends TestResultException instead of RuntimeError
|
44
|
-
# to bypass printing the stack trace in the UI.
|
45
|
-
# (The stack trace of this exception may not be useful,
|
46
|
-
# instead the message should point to where in the validator an error occurred)
|
47
50
|
def result
|
48
51
|
'error'
|
49
52
|
end
|