fhir_client 3.0.2 → 3.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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