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.
@@ -1,5 +1,5 @@
1
1
  module FHIR
2
- class Bundle
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
- iteration = @entry.map(&:resource).each(&block)
32
- iteration += next_bundle.each(&block) if next_bundle
33
- iteration
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
- class Model
3
- cattr_accessor :client, instance_accessor: false
2
+ module ModelExtras
4
3
 
5
- def client
6
- @@client
4
+ def self.included base
5
+ base.send :include, InstanceMethods
6
+ base.extend ClassMethods
7
7
  end
8
8
 
9
- def client=(client)
10
- @@client = client
9
+ module InstanceMethods
10
+ def client
11
+ FHIR::Model.client
12
+ end
11
13
 
12
- # Ensure the client-setting cascades to all child models
13
- instance_values.each do |_key, values|
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
- def self.read(id, client = @@client)
23
- handle_response client.read(self, id)
24
- end
18
+ def vread(version_id)
19
+ self.class.vread(id, version_id, client)
20
+ end
25
21
 
26
- def self.read_with_summary(id, summary, client = @@client)
27
- handle_response client.read(self, id, client.default_format, summary)
28
- end
22
+ def create
23
+ handle_response client.create(self)
24
+ end
29
25
 
30
- def self.vread(id, version_id, client = @@client)
31
- handle_response client.vread(self, id, version_id)
32
- end
26
+ def conditional_create(params)
27
+ handle_response client.conditional_create(self, params)
28
+ end
33
29
 
34
- def self.resource_history(client = @@client)
35
- handle_response client.resource_history(self)
36
- end
30
+ def update
31
+ handle_response client.update(self, id)
32
+ end
37
33
 
38
- def self.resource_history_as_of(last_update, client = @@client)
39
- handle_response client.resource_history_as_of(self, last_update)
40
- end
34
+ def conditional_update(params)
35
+ handle_response client.conditional_update(self, id, params)
36
+ end
41
37
 
42
- def self.resource_instance_history(id, client = @@client)
43
- handle_response client.resource_instance_history(self, id)
44
- end
38
+ def destroy
39
+ handle_response client.destroy(self.class, id) unless id.nil?
40
+ nil
41
+ end
45
42
 
46
- def self.resource_instance_history_as_of(id, last_update, client = @@client)
47
- handle_response client.resource_instance_history_as_of(self, id, last_update)
48
- end
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
- def self.search(params = {}, client = @@client)
51
- handle_response client.search(self, search: { parameters: params })
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
- def self.create(model, client = @@client)
55
- model = new(model) unless model.is_a?(self)
56
- handle_response client.create(model)
57
- end
58
+ module ClassMethods
59
+
60
+ def client
61
+ FHIR::Model.client
62
+ end
58
63
 
59
- def self.conditional_create(model, params, client = @@client)
60
- model = new(model) unless model.is_a?(self)
61
- handle_response client.conditional_create(model, params)
62
- end
64
+ def client=(client)
65
+ FHIR::Model.client = client
66
+ end
63
67
 
64
- def self.all(client = @@client)
65
- handle_response client.read_feed(self)
66
- end
68
+ def read(id, client = self.client)
69
+ handle_response client.read(self, id)
70
+ end
67
71
 
68
- def vread(version_id)
69
- self.class.vread(id, version_id, client)
70
- end
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
- def create
73
- handle_response client.create(self)
74
- end
76
+ def vread(id, version_id, client = self.client)
77
+ handle_response client.vread(self, id, version_id)
78
+ end
75
79
 
76
- def conditional_create(params)
77
- handle_response client.conditional_create(self, params)
78
- end
80
+ def resource_history(client = self.client)
81
+ handle_response client.resource_history(self)
82
+ end
79
83
 
80
- def update
81
- handle_response client.update(self, id)
82
- end
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
- def conditional_update(params)
85
- handle_response client.conditional_update(self, id, params)
86
- end
88
+ def resource_instance_history(id, client = self.client)
89
+ handle_response client.resource_instance_history(self, id)
90
+ end
87
91
 
88
- def destroy
89
- handle_response client.destroy(self.class, id) unless id.nil?
90
- nil
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
- def resolve(reference)
94
- if reference.contained?
95
- contained.detect { |c| c.id == reference.id }
96
- else
97
- reference.read
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
- private
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
- def self.handle_response(response)
104
- raise ClientException.new "Server returned #{response.code}.", response if response.code.between?(400, 599)
105
- response.resource
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
- def handle_response(response)
109
- self.class.handle_response(response)
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
- class Reference
2
+ module ReferenceExtras
3
3
  def contained?
4
4
  reference.to_s.start_with?('#')
5
5
  end
6
6
 
7
- def id
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
- def read
24
- return if contained? || type.blank? || id.blank?
25
- resource_class.read(id, client)
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
@@ -200,7 +200,7 @@
200
200
  "ETag": false,
201
201
  "Last-Modified": false
202
202
  },
203
- "body": { "types": ["CapabilityStatement"] }
203
+ "body": { "types": ["CapabilityStatement","Conformance"] }
204
204
  }
205
205
  },{
206
206
  "interaction": "transaction",
@@ -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 = FHIR.from_contents(body)
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' && FHIR::RESOURCES.include?(content.resourceType)
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
- private :validate_headers, :validate_body
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
- reply = get resource_url(options), fhir_headers(options)
40
- reply.body
39
+ get resource_url(options), fhir_headers(options)
41
40
  end
42
41
 
43
- def raw_read_url(url)
44
- reply = get url, fhir_headers({})
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 format == FHIR::Formats::ResourceFormat::RESOURCE_XML
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 format == FHIR::Formats::ResourceFormat::RESOURCE_JSON
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, nil, format)
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
- FHIR::Xml.from_xml(reply.body)
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
- FHIR::Json.from_json(reply.body)
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], @default_format, reply)
29
+ reply.resource = parse_reply(options[:resource], options[:format], reply)
29
30
  reply.resource_class = options[:resource]
30
31
  reply
31
32
  end