fhir_client 1.0.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 +7 -0
- data/.gitignore +38 -0
- data/.travis.yml +10 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +98 -0
- data/LICENSE +201 -0
- data/README.md +135 -0
- data/Rakefile +25 -0
- data/fhir_client.gemspec +21 -0
- data/lib/client_interface.rb +525 -0
- data/lib/feed_format.rb +10 -0
- data/lib/fhir_api_validation.json +360 -0
- data/lib/fhir_client.rb +41 -0
- data/lib/model/bundle.rb +32 -0
- data/lib/model/client_reply.rb +172 -0
- data/lib/model/tag.rb +57 -0
- data/lib/patch_format.rb +10 -0
- data/lib/resource_address.rb +133 -0
- data/lib/resource_format.rb +10 -0
- data/lib/sections/crud.rb +170 -0
- data/lib/sections/feed.rb +23 -0
- data/lib/sections/history.rb +78 -0
- data/lib/sections/operations.rb +118 -0
- data/lib/sections/search.rb +53 -0
- data/lib/sections/tags.rb +64 -0
- data/lib/sections/transactions.rb +83 -0
- data/lib/sections/validate.rb +49 -0
- data/lib/tasks/tasks.rake +73 -0
- data/test/fixtures/bundle-example.xml +79 -0
- data/test/fixtures/parameters-example.json +18 -0
- data/test/fixtures/parameters-example.xml +17 -0
- data/test/simplecov.rb +17 -0
- data/test/test_helper.rb +8 -0
- data/test/unit/basic_test.rb +17 -0
- data/test/unit/bundle_test.rb +21 -0
- data/test/unit/parameters_test.rb +44 -0
- metadata +177 -0
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'pry'
|
5
|
+
|
6
|
+
require_relative 'lib/fhir_client'
|
7
|
+
|
8
|
+
# Pull in any rake task defined in lib/tasks
|
9
|
+
Dir['lib/tasks/**/*.rake'].sort.each do |ext|
|
10
|
+
load ext
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Run basic tests"
|
14
|
+
Rake::TestTask.new(:test_unit) do |t|
|
15
|
+
t.libs << "test"
|
16
|
+
t.test_files = FileList['test/**/*_test.rb']
|
17
|
+
t.verbose = true
|
18
|
+
t.warning = false
|
19
|
+
end
|
20
|
+
|
21
|
+
task :test => [:test_unit] do
|
22
|
+
system("open coverage/index.html")
|
23
|
+
end
|
24
|
+
|
25
|
+
task :default => [:test]
|
data/fhir_client.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "fhir_client"
|
5
|
+
s.summary = "A Gem for handling FHIR client requests in ruby"
|
6
|
+
s.description = "A Gem for handling FHIR client requests in ruby"
|
7
|
+
s.email = "aquina@mitre.org"
|
8
|
+
s.homepage = "https://github.com/hl7-fhir/fhir-svn"
|
9
|
+
s.authors = ["Andre Quina", "Jason Walonoski", "Janoo Fernandes"]
|
10
|
+
s.version = '1.0.1'
|
11
|
+
|
12
|
+
s.files = s.files = `git ls-files`.split("\n")
|
13
|
+
|
14
|
+
s.add_dependency 'fhir_models', '~> 0.3'
|
15
|
+
s.add_dependency 'tilt', '>= 1.1'
|
16
|
+
s.add_dependency 'rest-client', '~> 1.8'
|
17
|
+
s.add_dependency 'oauth2', '~> 1.1'
|
18
|
+
s.add_dependency 'activesupport', '>= 3'
|
19
|
+
s.add_dependency 'addressable', '>= 2.3'
|
20
|
+
s.add_development_dependency 'pry'
|
21
|
+
end
|
@@ -0,0 +1,525 @@
|
|
1
|
+
module FHIR
|
2
|
+
|
3
|
+
class Client
|
4
|
+
|
5
|
+
include FHIR::Sections::History
|
6
|
+
include FHIR::Sections::Crud
|
7
|
+
include FHIR::Sections::Validate
|
8
|
+
include FHIR::Sections::Tags
|
9
|
+
include FHIR::Sections::Feed
|
10
|
+
include FHIR::Sections::Search
|
11
|
+
include FHIR::Sections::Operations
|
12
|
+
include FHIR::Sections::Transactions
|
13
|
+
|
14
|
+
attr_accessor :reply
|
15
|
+
attr_accessor :use_format_param
|
16
|
+
attr_accessor :use_basic_auth
|
17
|
+
attr_accessor :use_oauth2_auth
|
18
|
+
attr_accessor :security_headers
|
19
|
+
attr_accessor :client
|
20
|
+
|
21
|
+
attr_accessor :default_format
|
22
|
+
attr_accessor :default_format_bundle
|
23
|
+
|
24
|
+
attr_accessor :cached_conformance
|
25
|
+
|
26
|
+
# Call method to initialize FHIR client. This method must be invoked
|
27
|
+
# with a valid base server URL prior to using the client.
|
28
|
+
#
|
29
|
+
# @param baseServiceUrl Base service URL for FHIR Service.
|
30
|
+
# @return
|
31
|
+
#
|
32
|
+
def initialize(baseServiceUrl)
|
33
|
+
$LOG.info "Initializing client with #{@baseServiceUrl}"
|
34
|
+
@baseServiceUrl = baseServiceUrl
|
35
|
+
@use_format_param = false
|
36
|
+
@default_format = FHIR::Formats::ResourceFormat::RESOURCE_XML
|
37
|
+
@default_format_bundle = FHIR::Formats::FeedFormat::FEED_XML
|
38
|
+
set_no_auth
|
39
|
+
end
|
40
|
+
|
41
|
+
# Set the client to use no authentication mechanisms
|
42
|
+
def set_no_auth
|
43
|
+
$LOG.info "Configuring the client to use no authentication."
|
44
|
+
@use_oauth2_auth = false
|
45
|
+
@use_basic_auth = false
|
46
|
+
@security_headers = {}
|
47
|
+
@client = RestClient
|
48
|
+
end
|
49
|
+
|
50
|
+
# Set the client to use HTTP Basic Authentication
|
51
|
+
def set_basic_auth(client,secret)
|
52
|
+
$LOG.info "Configuring the client to use HTTP Basic authentication."
|
53
|
+
token = Base64.encode64("#{client}:#{secret}")
|
54
|
+
value = "Basic #{token}"
|
55
|
+
@security_headers = { 'Authorization' => value }
|
56
|
+
@use_oauth2_auth = false
|
57
|
+
@use_basic_auth = true
|
58
|
+
@client = RestClient
|
59
|
+
end
|
60
|
+
|
61
|
+
# Set the client to use Bearer Token Authentication
|
62
|
+
def set_bearer_token(token)
|
63
|
+
$LOG.info "Configuring the client to use Bearer Token authentication."
|
64
|
+
value = "Bearer #{token}"
|
65
|
+
@security_headers = { 'Authorization' => value }
|
66
|
+
@use_oauth2_auth = false
|
67
|
+
@use_basic_auth = true
|
68
|
+
@client = RestClient
|
69
|
+
end
|
70
|
+
|
71
|
+
# Set the client to use OpenID Connect OAuth2 Authentication
|
72
|
+
# client -- client id
|
73
|
+
# secret -- client secret
|
74
|
+
# authorizePath -- absolute path of authorization endpoint
|
75
|
+
# tokenPath -- absolute path of token endpoint
|
76
|
+
def set_oauth2_auth(client,secret,authorizePath,tokenPath)
|
77
|
+
$LOG.info "Configuring the client to use OpenID Connect OAuth2 authentication."
|
78
|
+
@use_oauth2_auth = true
|
79
|
+
@use_basic_auth = false
|
80
|
+
@security_headers = {}
|
81
|
+
options = {
|
82
|
+
:site => @baseServiceUrl,
|
83
|
+
:authorize_url => authorizePath,
|
84
|
+
:token_url => tokenPath,
|
85
|
+
:raise_errors => true
|
86
|
+
}
|
87
|
+
client = OAuth2::Client.new(client,secret,options)
|
88
|
+
@client = client.client_credentials.get_token
|
89
|
+
end
|
90
|
+
|
91
|
+
# Get the OAuth2 server and endpoints from the conformance statement
|
92
|
+
# (the server should not require OAuth2 or other special security to access
|
93
|
+
# the conformance statement).
|
94
|
+
# <rest>
|
95
|
+
# <mode value="server"/>
|
96
|
+
# <documentation value="All the functionality defined in FHIR"/>
|
97
|
+
# <security>
|
98
|
+
# <extension url="http://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris">
|
99
|
+
# <extension url="register">
|
100
|
+
# <valueUri value="https://authorize-dstu2.smarthealthit.org/register"/>
|
101
|
+
# </extension>
|
102
|
+
# <extension url="authorize">
|
103
|
+
# <valueUri value="https://authorize-dstu2.smarthealthit.org/authorize"/>
|
104
|
+
# </extension>
|
105
|
+
# <extension url="token">
|
106
|
+
# <valueUri value="https://authorize-dstu2.smarthealthit.org/token"/>
|
107
|
+
# </extension>
|
108
|
+
# </extension>
|
109
|
+
# <service>
|
110
|
+
# <coding>
|
111
|
+
# <system value="http://hl7.org/fhir/vs/restful-security-service"/>
|
112
|
+
# <code value="OAuth2"/>
|
113
|
+
# </coding>
|
114
|
+
# <text value="OAuth version 2 (see oauth.net)."/>
|
115
|
+
# </service>
|
116
|
+
# <description value="SMART on FHIR uses OAuth2 for authorization"/>
|
117
|
+
# </security>
|
118
|
+
def get_oauth2_metadata_from_conformance
|
119
|
+
options = {
|
120
|
+
:authorize_url => nil,
|
121
|
+
:token_url => nil
|
122
|
+
}
|
123
|
+
oauth_extension = 'http://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris'
|
124
|
+
authorize_extension = 'authorize'
|
125
|
+
token_extension = 'token'
|
126
|
+
begin
|
127
|
+
conformance = conformanceStatement
|
128
|
+
conformance.rest.each do |rest|
|
129
|
+
rest.security.service.each do |service|
|
130
|
+
service.coding.each do |coding|
|
131
|
+
if coding.code == 'SMART-on-FHIR'
|
132
|
+
rest.security.extension.where({url: oauth_extension}).first.extension.each do |ext|
|
133
|
+
case ext.url
|
134
|
+
when authorize_extension
|
135
|
+
options[:authorize_url] = ext.value.value
|
136
|
+
when "#{oauth_extension}\##{authorize_extension}"
|
137
|
+
options[:authorize_url] = ext.value.value
|
138
|
+
when token_extension
|
139
|
+
options[:token_url] = ext.value.value
|
140
|
+
when "#{oauth_extension}\##{token_extension}"
|
141
|
+
options[:token_url] = ext.value.value
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
rescue Exception => e
|
149
|
+
$LOG.error 'Failed to locate SMART-on-FHIR OAuth2 Security Extensions.'
|
150
|
+
end
|
151
|
+
options.delete_if{|k,v|v.nil?}
|
152
|
+
options.clear if options.keys.size!=2
|
153
|
+
options
|
154
|
+
end
|
155
|
+
|
156
|
+
# Method returns a conformance statement for the system queried.
|
157
|
+
# @return
|
158
|
+
def conformanceStatement(format=FHIR::Formats::ResourceFormat::RESOURCE_XML)
|
159
|
+
if (@cached_conformance.nil? || format!=@default_format)
|
160
|
+
format = try_conformance_formats(format)
|
161
|
+
end
|
162
|
+
@cached_conformance
|
163
|
+
end
|
164
|
+
|
165
|
+
def try_conformance_formats(default_format)
|
166
|
+
formats = [ FHIR::Formats::ResourceFormat::RESOURCE_XML,
|
167
|
+
FHIR::Formats::ResourceFormat::RESOURCE_JSON,
|
168
|
+
'application/xml',
|
169
|
+
'application/json']
|
170
|
+
formats.insert(0,default_format)
|
171
|
+
|
172
|
+
@cached_conformance = nil
|
173
|
+
@default_format = nil
|
174
|
+
@default_format_bundle = nil
|
175
|
+
|
176
|
+
formats.each do |frmt|
|
177
|
+
reply = get 'metadata', fhir_headers({format: frmt})
|
178
|
+
if reply.code == 200
|
179
|
+
@cached_conformance = parse_reply(FHIR::Conformance, frmt, reply)
|
180
|
+
@default_format = frmt
|
181
|
+
@default_format_bundle = frmt
|
182
|
+
break
|
183
|
+
end
|
184
|
+
end
|
185
|
+
@default_format = default_format if @default_format.nil?
|
186
|
+
@default_format
|
187
|
+
end
|
188
|
+
|
189
|
+
def resource_url(options)
|
190
|
+
FHIR::ResourceAddress.new.resource_url(options, @use_format_param)
|
191
|
+
end
|
192
|
+
|
193
|
+
def full_resource_url(options)
|
194
|
+
@baseServiceUrl + resource_url(options)
|
195
|
+
end
|
196
|
+
|
197
|
+
def fhir_headers(options={})
|
198
|
+
FHIR::ResourceAddress.new.fhir_headers(options, @use_format_param)
|
199
|
+
end
|
200
|
+
|
201
|
+
def parse_reply(klass, format, response)
|
202
|
+
$LOG.info "Parsing response with {klass: #{klass}, format: #{format}, code: #{response.code}}."
|
203
|
+
return nil if ![200,201].include? response.code
|
204
|
+
res = nil
|
205
|
+
begin
|
206
|
+
res = nil
|
207
|
+
if(format.downcase.include?('xml'))
|
208
|
+
res = FHIR::Xml.from_xml(response.body)
|
209
|
+
else
|
210
|
+
res = FHIR::Json.from_json(response.body)
|
211
|
+
end
|
212
|
+
$LOG.warn "Expected #{klass} but got #{res.class}" if res.class!=klass
|
213
|
+
rescue Exception => e
|
214
|
+
$LOG.error "Failed to parse #{format} as resource #{klass}: #{e.message} %n #{e.backtrace.join("\n")} #{response}"
|
215
|
+
nil
|
216
|
+
end
|
217
|
+
res
|
218
|
+
end
|
219
|
+
|
220
|
+
def strip_base(path)
|
221
|
+
path.gsub(@baseServiceUrl, '')
|
222
|
+
end
|
223
|
+
|
224
|
+
def reissue_request(request)
|
225
|
+
if [:get, :delete, :head].include?(request['method'])
|
226
|
+
method(request['method']).call(request['url'], request['headers'])
|
227
|
+
elsif [:post, :put].include?(request['method'])
|
228
|
+
resource = request['headers']['resource'].constantize.from_xml(request['payload'])
|
229
|
+
method(request['method']).call(request['url'], resource, request['headers'])
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
private
|
234
|
+
|
235
|
+
def base_path(path)
|
236
|
+
if path.start_with?('/')
|
237
|
+
if @baseServiceUrl.end_with?('/')
|
238
|
+
@baseServiceUrl.chop
|
239
|
+
else
|
240
|
+
@baseServiceUrl
|
241
|
+
end
|
242
|
+
else
|
243
|
+
@baseServiceUrl + '/'
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
# Extract the request payload in the specified format, defaults to XML
|
248
|
+
def request_payload(resource, headers)
|
249
|
+
if headers
|
250
|
+
case headers["format"]
|
251
|
+
when FHIR::Formats::ResourceFormat::RESOURCE_XML
|
252
|
+
resource.to_xml
|
253
|
+
when FHIR::Formats::ResourceFormat::RESOURCE_JSON
|
254
|
+
resource.to_json
|
255
|
+
else
|
256
|
+
resource.to_xml
|
257
|
+
end
|
258
|
+
else
|
259
|
+
resource.to_xml
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
def request_patch_payload(patchset, format)
|
264
|
+
if (format == FHIR::Formats::PatchFormat::PATCH_JSON)
|
265
|
+
patchset.each do |patch|
|
266
|
+
# remove the resource name from the patch path, since the JSON representation doesn't have that
|
267
|
+
patch[:path] = patch[:path].slice(patch[:path].index('/')..-1)
|
268
|
+
end
|
269
|
+
patchset.to_json
|
270
|
+
elsif (format == FHIR::Formats::PatchFormat::PATCH_XML)
|
271
|
+
builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
|
272
|
+
patchset.each do |patch|
|
273
|
+
xml.diff {
|
274
|
+
# TODO: support other kinds besides just replace
|
275
|
+
xml.replace(patch[:value], sel: patch[:path] + '/@value') if patch[:op] == 'replace'
|
276
|
+
}
|
277
|
+
end
|
278
|
+
end
|
279
|
+
builder.to_xml
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
def clean_headers(headers)
|
284
|
+
headers.delete_if{|k,v|(k.nil? || v.nil?)}
|
285
|
+
headers.inject({}){|h,(k,v)| h[k.to_s]=v.to_s; h}
|
286
|
+
end
|
287
|
+
|
288
|
+
def scrubbed_response_headers(result)
|
289
|
+
result.each_key do |k|
|
290
|
+
v = result[k]
|
291
|
+
result[k] = v[0] if (v.is_a? Array)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
def get(path, headers)
|
296
|
+
url = URI(build_url(path)).to_s
|
297
|
+
puts "GETTING: #{url}"
|
298
|
+
headers = clean_headers(headers)
|
299
|
+
if @use_oauth2_auth
|
300
|
+
# @client.refresh!
|
301
|
+
begin
|
302
|
+
response = @client.get(url, {:headers=>headers})
|
303
|
+
rescue Exception => e
|
304
|
+
response = e.response if e.response
|
305
|
+
end
|
306
|
+
req = {
|
307
|
+
:method => :get,
|
308
|
+
:url => url,
|
309
|
+
:path => url.gsub(@baseServiceUrl,''),
|
310
|
+
:headers => headers,
|
311
|
+
:payload => nil
|
312
|
+
}
|
313
|
+
res = {
|
314
|
+
:code => response.status.to_s,
|
315
|
+
:headers => response.headers,
|
316
|
+
:body => response.body
|
317
|
+
}
|
318
|
+
$LOG.info "GET - Request: #{req.to_s}, Response: #{response.body.force_encoding("UTF-8")}"
|
319
|
+
@reply = FHIR::ClientReply.new(req, res)
|
320
|
+
else
|
321
|
+
headers.merge!(@security_headers) if @use_basic_auth
|
322
|
+
@client.get(url, headers){ |response, request, result|
|
323
|
+
$LOG.info "GET - Request: #{request.to_json}, Response: #{response.force_encoding("UTF-8")}"
|
324
|
+
request.args[:path] = url.gsub(@baseServiceUrl,'')
|
325
|
+
res = {
|
326
|
+
:code => result.code,
|
327
|
+
:headers => scrubbed_response_headers(result.each_key{}),
|
328
|
+
:body => response
|
329
|
+
}
|
330
|
+
@reply = FHIR::ClientReply.new(request.args, res)
|
331
|
+
}
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
def post(path, resource, headers)
|
336
|
+
url = URI(build_url(path)).to_s
|
337
|
+
puts "POSTING: #{url}"
|
338
|
+
headers = clean_headers(headers)
|
339
|
+
payload = request_payload(resource, headers) if resource
|
340
|
+
if @use_oauth2_auth
|
341
|
+
# @client.refresh!
|
342
|
+
begin
|
343
|
+
response = @client.post(url, {:headers=>headers,:body=>payload})
|
344
|
+
rescue Exception => e
|
345
|
+
response = e.response if e.response
|
346
|
+
end
|
347
|
+
req = {
|
348
|
+
:method => :post,
|
349
|
+
:url => url,
|
350
|
+
:path => url.gsub(@baseServiceUrl,''),
|
351
|
+
:headers => headers,
|
352
|
+
:payload => payload
|
353
|
+
}
|
354
|
+
res = {
|
355
|
+
:code => response.status.to_s,
|
356
|
+
:headers => response.headers,
|
357
|
+
:body => response.body
|
358
|
+
}
|
359
|
+
$LOG.info "POST - Request: #{req.to_s}, Response: #{response.body.force_encoding("UTF-8")}"
|
360
|
+
@reply = FHIR::ClientReply.new(req, res)
|
361
|
+
else
|
362
|
+
headers.merge!(@security_headers) if @use_basic_auth
|
363
|
+
@client.post(url, payload, headers){ |response, request, result|
|
364
|
+
$LOG.info "POST - Request: #{request.to_json}, Response: #{response.force_encoding("UTF-8")}"
|
365
|
+
request.args[:path] = url.gsub(@baseServiceUrl,'')
|
366
|
+
res = {
|
367
|
+
:code => result.code,
|
368
|
+
:headers => scrubbed_response_headers(result.each_key{}),
|
369
|
+
:body => response
|
370
|
+
}
|
371
|
+
@reply = FHIR::ClientReply.new(request.args, res)
|
372
|
+
}
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
def put(path, resource, headers)
|
377
|
+
url = URI(build_url(path)).to_s
|
378
|
+
puts "PUTTING: #{url}"
|
379
|
+
headers = clean_headers(headers)
|
380
|
+
payload = request_payload(resource, headers) if resource
|
381
|
+
if @use_oauth2_auth
|
382
|
+
# @client.refresh!
|
383
|
+
begin
|
384
|
+
response = @client.put(url, {:headers=>headers,:body=>payload})
|
385
|
+
rescue Exception => e
|
386
|
+
response = e.response if e.response
|
387
|
+
end
|
388
|
+
req = {
|
389
|
+
:method => :put,
|
390
|
+
:url => url,
|
391
|
+
:path => url.gsub(@baseServiceUrl,''),
|
392
|
+
:headers => headers,
|
393
|
+
:payload => payload
|
394
|
+
}
|
395
|
+
res = {
|
396
|
+
:code => response.status.to_s,
|
397
|
+
:headers => response.headers,
|
398
|
+
:body => response.body
|
399
|
+
}
|
400
|
+
$LOG.info "PUT - Request: #{req.to_s}, Response: #{response.body.force_encoding("UTF-8")}"
|
401
|
+
@reply = FHIR::ClientReply.new(req, res)
|
402
|
+
else
|
403
|
+
headers.merge!(@security_headers) if @use_basic_auth
|
404
|
+
@client.put(url, payload, headers){ |response, request, result|
|
405
|
+
$LOG.info "PUT - Request: #{request.to_json}, Response: #{response.force_encoding("UTF-8")}"
|
406
|
+
request.args[:path] = url.gsub(@baseServiceUrl,'')
|
407
|
+
res = {
|
408
|
+
:code => result.code,
|
409
|
+
:headers => scrubbed_response_headers(result.each_key{}),
|
410
|
+
:body => response
|
411
|
+
}
|
412
|
+
@reply = FHIR::ClientReply.new(request.args, res)
|
413
|
+
}
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
def patch(path, patchset, headers)
|
418
|
+
url = URI(build_url(path)).to_s
|
419
|
+
puts "PATCHING: #{url}"
|
420
|
+
headers = clean_headers(headers)
|
421
|
+
payload = request_patch_payload(patchset, headers['format'])
|
422
|
+
if @use_oauth2_auth
|
423
|
+
# @client.refresh!
|
424
|
+
begin
|
425
|
+
response = @client.patch(url, {:headers=>headers,:body=>payload})
|
426
|
+
rescue Exception => e
|
427
|
+
response = e.response if e.response
|
428
|
+
end
|
429
|
+
req = {
|
430
|
+
:method => :patch,
|
431
|
+
:url => url,
|
432
|
+
:path => url.gsub(@baseServiceUrl,''),
|
433
|
+
:headers => headers,
|
434
|
+
:payload => payload
|
435
|
+
}
|
436
|
+
res = {
|
437
|
+
:code => response.status.to_s,
|
438
|
+
:headers => response.headers,
|
439
|
+
:body => response.body
|
440
|
+
}
|
441
|
+
$LOG.info "PATCH - Request: #{req.to_s}, Response: #{response.body.force_encoding("UTF-8")}"
|
442
|
+
@reply = FHIR::ClientReply.new(req, res)
|
443
|
+
else
|
444
|
+
headers.merge!(@security_headers) if @use_basic_auth
|
445
|
+
# url = 'http://requestb.in/o8juy3o8'
|
446
|
+
@client.patch(url, payload, headers){ |response, request, result|
|
447
|
+
$LOG.info "PATCH - Request: #{request.to_json}, Response: #{response.force_encoding("UTF-8")}"
|
448
|
+
request.args[:path] = url.gsub(@baseServiceUrl,'')
|
449
|
+
res = {
|
450
|
+
:code => result.code,
|
451
|
+
:headers => scrubbed_response_headers(result.each_key{}),
|
452
|
+
:body => response
|
453
|
+
}
|
454
|
+
@reply = FHIR::ClientReply.new(request.args, res)
|
455
|
+
}
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
459
|
+
def delete(path, headers)
|
460
|
+
url = URI(build_url(path)).to_s
|
461
|
+
puts "DELETING: #{url}"
|
462
|
+
headers = clean_headers(headers)
|
463
|
+
if @use_oauth2_auth
|
464
|
+
# @client.refresh!
|
465
|
+
begin
|
466
|
+
response = @client.delete(url, {:headers=>headers})
|
467
|
+
rescue Exception => e
|
468
|
+
response = e.response if e.response
|
469
|
+
end
|
470
|
+
req = {
|
471
|
+
:method => :delete,
|
472
|
+
:url => url,
|
473
|
+
:path => url.gsub(@baseServiceUrl,''),
|
474
|
+
:headers => headers,
|
475
|
+
:payload => nil
|
476
|
+
}
|
477
|
+
res = {
|
478
|
+
:code => response.status.to_s,
|
479
|
+
:headers => response.headers,
|
480
|
+
:body => response.body
|
481
|
+
}
|
482
|
+
$LOG.info "DELETE - Request: #{req.to_s}, Response: #{response.body.force_encoding("UTF-8")}"
|
483
|
+
@reply = FHIR::ClientReply.new(req, res)
|
484
|
+
else
|
485
|
+
headers.merge!(@security_headers) if @use_basic_auth
|
486
|
+
@client.delete(url, headers){ |response, request, result|
|
487
|
+
$LOG.info "DELETE - Request: #{request.to_json}, Response: #{response.force_encoding("UTF-8")}"
|
488
|
+
request.args[:path] = url.gsub(@baseServiceUrl,'')
|
489
|
+
res = {
|
490
|
+
:code => result.code,
|
491
|
+
:headers => scrubbed_response_headers(result.each_key{}),
|
492
|
+
:body => response
|
493
|
+
}
|
494
|
+
@reply = FHIR::ClientReply.new(request.args, res)
|
495
|
+
}
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
def head(path, headers)
|
500
|
+
headers.merge!(@security_headers) unless @security_headers.blank?
|
501
|
+
url = URI(build_url(path)).to_s
|
502
|
+
puts "HEADING: #{url}"
|
503
|
+
RestClient.head(url, headers){ |response, request, result|
|
504
|
+
$LOG.info "HEAD - Request: #{request.to_json}, Response: #{response.force_encoding("UTF-8")}"
|
505
|
+
request.args[:path] = url.gsub(@baseServiceUrl,'')
|
506
|
+
res = {
|
507
|
+
:code => result.code,
|
508
|
+
:headers => scrubbed_response_headers(result.each_key{}),
|
509
|
+
:body => response
|
510
|
+
}
|
511
|
+
@reply = FHIR::ClientReply.new(request.args, res)
|
512
|
+
}
|
513
|
+
end
|
514
|
+
|
515
|
+
def build_url(path)
|
516
|
+
if path =~ /^\w+:\/\//
|
517
|
+
path
|
518
|
+
else
|
519
|
+
"#{base_path(path)}#{path}"
|
520
|
+
end
|
521
|
+
end
|
522
|
+
|
523
|
+
end
|
524
|
+
|
525
|
+
end
|