fhir_client 3.0.2 → 3.0.3
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/.rubocop.yml +11 -1147
- data/Gemfile +1 -1
- data/README.md +31 -2
- data/fhir_client.gemspec +2 -1
- data/lib/fhir_client.rb +1 -0
- data/lib/fhir_client/client.rb +160 -38
- data/lib/fhir_client/ext/bundle.rb +25 -5
- data/lib/fhir_client/ext/model.rb +104 -79
- data/lib/fhir_client/ext/reference.rb +24 -5
- data/lib/fhir_client/fhir_api_validation.json +1 -1
- data/lib/fhir_client/model/client_reply.rb +20 -4
- data/lib/fhir_client/resource_address.rb +2 -0
- data/lib/fhir_client/sections/crud.rb +17 -11
- data/lib/fhir_client/sections/history.rb +2 -1
- data/lib/fhir_client/sections/operations.rb +22 -17
- data/lib/fhir_client/sections/transactions.rb +7 -7
- data/lib/fhir_client/tasks/tasks.rake +1 -1
- data/lib/fhir_client/version.rb +1 -1
- metadata +18 -4
@@ -1,5 +1,5 @@
|
|
1
1
|
module FHIR
|
2
|
-
|
2
|
+
module BundleExtras
|
3
3
|
def self_link
|
4
4
|
link.select { |n| n.relation == 'self' }.first
|
5
5
|
end
|
@@ -28,15 +28,35 @@ module FHIR
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def each(&block)
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
iterator = @entry.map(&:resource).each(&block)
|
32
|
+
if next_bundle
|
33
|
+
next_iterator = next_bundle.each(&block)
|
34
|
+
Enumerator.new do |y|
|
35
|
+
iterator.each { |r| y << r }
|
36
|
+
next_iterator.each { |r| y << r }
|
37
|
+
end
|
38
|
+
else
|
39
|
+
iterator
|
40
|
+
end
|
34
41
|
end
|
35
42
|
|
36
43
|
def next_bundle
|
37
|
-
# TODO: test this
|
38
44
|
return nil unless client && next_link.try(:url)
|
39
45
|
@next_bundle ||= client.parse_reply(self.class, client.default_format, client.raw_read_url(next_link.url))
|
40
46
|
end
|
41
47
|
end
|
42
48
|
end
|
49
|
+
|
50
|
+
module FHIR
|
51
|
+
class Bundle
|
52
|
+
include FHIR::BundleExtras
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
module FHIR
|
57
|
+
module DSTU2
|
58
|
+
class Bundle
|
59
|
+
include FHIR::BundleExtras
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -1,112 +1,137 @@
|
|
1
1
|
module FHIR
|
2
|
-
|
3
|
-
cattr_accessor :client, instance_accessor: false
|
2
|
+
module ModelExtras
|
4
3
|
|
5
|
-
def
|
6
|
-
|
4
|
+
def self.included base
|
5
|
+
base.send :include, InstanceMethods
|
6
|
+
base.extend ClassMethods
|
7
7
|
end
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
module InstanceMethods
|
10
|
+
def client
|
11
|
+
FHIR::Model.client
|
12
|
+
end
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
Array.wrap(values).each do |value|
|
15
|
-
next unless value.is_a?(FHIR::Model)
|
16
|
-
next if value.client == client
|
17
|
-
value.client = client
|
18
|
-
end
|
14
|
+
def client=(client)
|
15
|
+
FHIR::Model.client = client
|
19
16
|
end
|
20
|
-
end
|
21
17
|
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
def vread(version_id)
|
19
|
+
self.class.vread(id, version_id, client)
|
20
|
+
end
|
25
21
|
|
26
|
-
|
27
|
-
|
28
|
-
|
22
|
+
def create
|
23
|
+
handle_response client.create(self)
|
24
|
+
end
|
29
25
|
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
def conditional_create(params)
|
27
|
+
handle_response client.conditional_create(self, params)
|
28
|
+
end
|
33
29
|
|
34
|
-
|
35
|
-
|
36
|
-
|
30
|
+
def update
|
31
|
+
handle_response client.update(self, id)
|
32
|
+
end
|
37
33
|
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
def conditional_update(params)
|
35
|
+
handle_response client.conditional_update(self, id, params)
|
36
|
+
end
|
41
37
|
|
42
|
-
|
43
|
-
|
44
|
-
|
38
|
+
def destroy
|
39
|
+
handle_response client.destroy(self.class, id) unless id.nil?
|
40
|
+
nil
|
41
|
+
end
|
45
42
|
|
46
|
-
|
47
|
-
|
48
|
-
|
43
|
+
def resolve(reference)
|
44
|
+
if reference.contained?
|
45
|
+
contained.detect { |c| c.id == reference.id }
|
46
|
+
else
|
47
|
+
reference.read
|
48
|
+
end
|
49
|
+
end
|
49
50
|
|
50
|
-
|
51
|
-
handle_response
|
51
|
+
private
|
52
|
+
def handle_response(response)
|
53
|
+
raise ClientException.new "Server returned #{response.code}.", response if response.code.between?(400, 599)
|
54
|
+
response.resource
|
55
|
+
end
|
52
56
|
end
|
53
57
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
+
module ClassMethods
|
59
|
+
|
60
|
+
def client
|
61
|
+
FHIR::Model.client
|
62
|
+
end
|
58
63
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
end
|
64
|
+
def client=(client)
|
65
|
+
FHIR::Model.client = client
|
66
|
+
end
|
63
67
|
|
64
|
-
|
65
|
-
|
66
|
-
|
68
|
+
def read(id, client = self.client)
|
69
|
+
handle_response client.read(self, id)
|
70
|
+
end
|
67
71
|
|
68
|
-
|
69
|
-
|
70
|
-
|
72
|
+
def read_with_summary(id, summary, client = self.client)
|
73
|
+
handle_response client.read(self, id, client.default_format, summary)
|
74
|
+
end
|
71
75
|
|
72
|
-
|
73
|
-
|
74
|
-
|
76
|
+
def vread(id, version_id, client = self.client)
|
77
|
+
handle_response client.vread(self, id, version_id)
|
78
|
+
end
|
75
79
|
|
76
|
-
|
77
|
-
|
78
|
-
|
80
|
+
def resource_history(client = self.client)
|
81
|
+
handle_response client.resource_history(self)
|
82
|
+
end
|
79
83
|
|
80
|
-
|
81
|
-
|
82
|
-
|
84
|
+
def resource_history_as_of(last_update, client = self.client)
|
85
|
+
handle_response client.resource_history_as_of(self, last_update)
|
86
|
+
end
|
83
87
|
|
84
|
-
|
85
|
-
|
86
|
-
|
88
|
+
def resource_instance_history(id, client = self.client)
|
89
|
+
handle_response client.resource_instance_history(self, id)
|
90
|
+
end
|
87
91
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
end
|
92
|
+
def resource_instance_history_as_of(id, last_update, client = self.client)
|
93
|
+
handle_response client.resource_instance_history_as_of(self, id, last_update)
|
94
|
+
end
|
92
95
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
96
|
+
def search(params = {}, client = self.client)
|
97
|
+
handle_response client.search(self, search: { parameters: params })
|
98
|
+
end
|
99
|
+
|
100
|
+
def create(model, client = self.client)
|
101
|
+
model = new(model) unless model.is_a?(self)
|
102
|
+
handle_response client.create(model)
|
98
103
|
end
|
99
|
-
end
|
100
104
|
|
101
|
-
|
105
|
+
def conditional_create(model, params, client = self.client)
|
106
|
+
model = new(model) unless model.is_a?(self)
|
107
|
+
handle_response client.conditional_create(model, params)
|
108
|
+
end
|
109
|
+
|
110
|
+
def all(client = self.client)
|
111
|
+
handle_response client.read_feed(self)
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
102
115
|
|
103
|
-
|
104
|
-
|
105
|
-
|
116
|
+
def handle_response(response)
|
117
|
+
raise ClientException.new "Server returned #{response.code}.", response if response.code.between?(400, 599)
|
118
|
+
response.resource
|
119
|
+
end
|
106
120
|
end
|
121
|
+
end
|
122
|
+
end
|
107
123
|
|
108
|
-
|
109
|
-
|
124
|
+
module FHIR
|
125
|
+
class Model
|
126
|
+
include FHIR::ModelExtras
|
127
|
+
cattr_accessor :client, instance_accessor: false
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
module FHIR
|
132
|
+
module DSTU2
|
133
|
+
class Model
|
134
|
+
include FHIR::ModelExtras
|
110
135
|
end
|
111
136
|
end
|
112
137
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module FHIR
|
2
|
-
|
2
|
+
module ReferenceExtras
|
3
3
|
def contained?
|
4
4
|
reference.to_s.start_with?('#')
|
5
5
|
end
|
6
6
|
|
7
|
-
def
|
7
|
+
def reference_id
|
8
8
|
if contained?
|
9
9
|
reference.to_s[1..-1]
|
10
10
|
else
|
@@ -16,13 +16,32 @@ module FHIR
|
|
16
16
|
reference.to_s.split('/').first unless contained?
|
17
17
|
end
|
18
18
|
|
19
|
+
def read
|
20
|
+
return if contained? || type.blank? || (id.blank? && reference.blank?)
|
21
|
+
rid = id || reference_id
|
22
|
+
resource_class.read(rid, client)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module FHIR
|
28
|
+
class Reference
|
29
|
+
include FHIR::ReferenceExtras
|
30
|
+
|
19
31
|
def resource_class
|
20
32
|
"FHIR::#{type}".constantize unless contained?
|
21
33
|
end
|
34
|
+
end
|
35
|
+
end
|
22
36
|
|
23
|
-
|
24
|
-
|
25
|
-
|
37
|
+
module FHIR
|
38
|
+
module DSTU2
|
39
|
+
class Reference
|
40
|
+
include FHIR::ReferenceExtras
|
41
|
+
|
42
|
+
def resource_class
|
43
|
+
"FHIR::DSTU2::#{type}".constantize unless contained?
|
44
|
+
end
|
26
45
|
end
|
27
46
|
end
|
28
47
|
end
|
@@ -46,10 +46,13 @@ module FHIR
|
|
46
46
|
attr_accessor :response
|
47
47
|
attr_accessor :resource # a FHIR resource
|
48
48
|
attr_accessor :resource_class # class of the :resource
|
49
|
+
attr_accessor :fhir_version
|
49
50
|
|
50
|
-
def initialize(request, response)
|
51
|
+
def initialize(request, response, client)
|
51
52
|
@request = request
|
52
53
|
@response = response
|
54
|
+
@fhir_version = :stu3
|
55
|
+
@fhir_version = client.fhir_version
|
53
56
|
end
|
54
57
|
|
55
58
|
def code
|
@@ -154,10 +157,14 @@ module FHIR
|
|
154
157
|
if body_rules['types']
|
155
158
|
body_type_match = false
|
156
159
|
begin
|
157
|
-
content =
|
160
|
+
content = if @fhir_version == :stu3
|
161
|
+
FHIR.from_contents(body)
|
162
|
+
else
|
163
|
+
FHIR::DSTU2.from_contents(body)
|
164
|
+
end
|
158
165
|
body_rules['types'].each do |type|
|
159
166
|
body_type_match = true if content.resourceType == type
|
160
|
-
body_type_match = true if type == 'Resource' &&
|
167
|
+
body_type_match = true if type == 'Resource' && validate_resource(content.resourceType)
|
161
168
|
end
|
162
169
|
rescue
|
163
170
|
FHIR.logger.warn "ClientReply was unable to validate response body: #{body}"
|
@@ -174,6 +181,15 @@ module FHIR
|
|
174
181
|
errors
|
175
182
|
end
|
176
183
|
|
177
|
-
|
184
|
+
def validate_resource(resource_type)
|
185
|
+
if @fhir_version == :stu3
|
186
|
+
return true if FHIR::RESOURCES.include?(resource_type)
|
187
|
+
else
|
188
|
+
return true if FHIR::DSTU2::RESOURCES.include?(resource_type)
|
189
|
+
end
|
190
|
+
false
|
191
|
+
end
|
192
|
+
|
193
|
+
private :validate_headers, :validate_body, :validate_resource
|
178
194
|
end
|
179
195
|
end
|
@@ -40,6 +40,8 @@ module FHIR
|
|
40
40
|
|
41
41
|
fhir_headers.merge!(options) unless options.empty?
|
42
42
|
fhir_headers[:operation] = options[:operation][:name] if options[:operation] && options[:operation][:name]
|
43
|
+
fhir_headers.delete('id')
|
44
|
+
fhir_headers.delete('resource')
|
43
45
|
fhir_headers
|
44
46
|
end
|
45
47
|
|
@@ -36,13 +36,11 @@ module FHIR
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def raw_read(options)
|
39
|
-
|
40
|
-
reply.body
|
39
|
+
get resource_url(options), fhir_headers(options)
|
41
40
|
end
|
42
41
|
|
43
|
-
def raw_read_url(url)
|
44
|
-
|
45
|
-
reply.body
|
42
|
+
def raw_read_url(url, format = @default_format)
|
43
|
+
get url, fhir_headers(format: format)
|
46
44
|
end
|
47
45
|
|
48
46
|
#
|
@@ -89,10 +87,10 @@ module FHIR
|
|
89
87
|
def partial_update(klass, id, patchset, options = {}, format = @default_format)
|
90
88
|
options = { resource: klass, id: id, format: format }.merge options
|
91
89
|
|
92
|
-
if
|
90
|
+
if [FHIR::Formats::ResourceFormat::RESOURCE_XML, FHIR::Formats::ResourceFormat::RESOURCE_XML_DSTU2].include?(format)
|
93
91
|
options[:format] = FHIR::Formats::PatchFormat::PATCH_XML
|
94
92
|
options[:Accept] = format
|
95
|
-
elsif
|
93
|
+
elsif [FHIR::Formats::ResourceFormat::RESOURCE_JSON, FHIR::Formats::ResourceFormat::RESOURCE_JSON_DSTU2].include?(format)
|
96
94
|
options[:format] = FHIR::Formats::PatchFormat::PATCH_JSON
|
97
95
|
options[:Accept] = format
|
98
96
|
end
|
@@ -119,8 +117,8 @@ module FHIR
|
|
119
117
|
# Create a new resource with a server assigned id. Return the newly created
|
120
118
|
# resource with the id the server assigned.
|
121
119
|
#
|
122
|
-
def create(resource, format = @default_format)
|
123
|
-
base_create(resource,
|
120
|
+
def create(resource, options = {}, format = @default_format)
|
121
|
+
base_create(resource, options, format)
|
124
122
|
end
|
125
123
|
|
126
124
|
#
|
@@ -150,9 +148,17 @@ module FHIR
|
|
150
148
|
type = reply.response[:headers].detect{|x, _y| x.downcase=='content-type'}.try(:last)
|
151
149
|
if !type.nil?
|
152
150
|
reply.resource = if type.include?('xml') && !reply.body.empty?
|
153
|
-
|
151
|
+
if @fhir_version == :stu3
|
152
|
+
FHIR::Xml.from_xml(reply.body)
|
153
|
+
else
|
154
|
+
FHIR::DSTU2::Xml.from_xml(reply.body)
|
155
|
+
end
|
154
156
|
elsif type.include?('json') && !reply.body.empty?
|
155
|
-
|
157
|
+
if @fhir_version == :stu3
|
158
|
+
FHIR::Json.from_json(reply.body)
|
159
|
+
else
|
160
|
+
FHIR::DSTU2::Json.from_json(reply.body)
|
161
|
+
end
|
156
162
|
else
|
157
163
|
resource # just send back the submitted resource
|
158
164
|
end
|
@@ -24,8 +24,9 @@ module FHIR
|
|
24
24
|
# public <T extends Resource> AtomFeed history(DateAndTime last_update, Class<T> resourceClass, String id);
|
25
25
|
|
26
26
|
def history(options)
|
27
|
+
options = {format: @default_format}.merge(options)
|
27
28
|
reply = get resource_url(options), fhir_headers(options).except(:history)
|
28
|
-
reply.resource = parse_reply(options[:resource],
|
29
|
+
reply.resource = parse_reply(options[:resource], options[:format], reply)
|
29
30
|
reply.resource_class = options[:resource]
|
30
31
|
reply
|
31
32
|
end
|