Module: Inferno::DSL::FHIRClient

Includes:
Messages
Defined in:
lib/inferno/dsl/fhir_client.rb

Overview

This module contains the FHIR DSL available to test writers.

Examples:

class MyTestGroup < Inferno::TestGroup
  # create a "default" client for a group
  fhir_client do
    url 'https://example.com/fhir'
  end

  # create a named client for a group
  fhir_client :with_custom_header do
    url 'https://example.com/fhir'
    headers 'X-my-custom-header': 'ABC123'
  end

  test :some_test do
    run do
      # uses the default client
      fhir_read('Patient', 5)

      # uses a named client
      fhir_read('Patient', 5, client: :with_custom_header)

      request  # the most recent request
      response # the most recent response
      resource # the resource from the most recent response
      requests # all of the requests which have been made in this test
    end
  end
end

See Also:

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Methods included from Messages

#add_message, #error_messages?, #info, #warning

Instance Method Details

#fetch_all_bundled_resources(resource_type:, bundle: resource, reply_handler: nil, client: :default, max_pages: 20, additional_resource_types: [], tags: []) ⇒ Array<FHIR::Resource>

Fetch all resources from a paginated FHIR bundle

Parameters:

  • resource_type (String)

    The expected resource type to fetch.

  • bundle (FHIR::Bundle) (defaults to: resource)

    The initial FHIR bundle to process. Defaults to self.resource.

  • reply_handler (Proc, nil) (defaults to: nil)

    A handler for processing replies. Optional.

  • client (Symbol) (defaults to: :default)

    Defaults to :default.

  • max_pages (Integer) (defaults to: 20)

    Maximum number of pages to fetch. Defaults to 20.

  • additional_resource_types (Array<String>) (defaults to: [])

    Additional resource types acceptable in the results.

  • tags (Array<String>) (defaults to: [])

    for request tagging. Optional.

Returns:

  • (Array<FHIR::Resource>)

    An array of fetched FHIR resources.



348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
# File 'lib/inferno/dsl/fhir_client.rb', line 348

def fetch_all_bundled_resources( # rubocop:disable Metrics/CyclomaticComplexity
  resource_type:,
  bundle: resource,
  reply_handler: nil,
  client: :default,
  max_pages: 20,
  additional_resource_types: [],
  tags: []
)
  page_count = 1
  resources = []

  while bundle && page_count <= max_pages
    resources += bundle.entry&.map { |entry| entry&.resource } || []
    reply_handler&.call(response)

    break if next_bundle_link(bundle).blank?

    bundle = fetch_next_bundle(bundle, client, tags)

    page_count += 1
  end

  if resources.any?(&:nil?)
    warning 'Inferno detected one or more bundle entries with no `resource` element, ' \
            'which is not allowed for a FHIR Bundle with `type` = "searchset".'
  end

  valid_resource_types = [resource_type, 'OperationOutcome'].concat(additional_resource_types)

  resources.compact!

  invalid_resource_types =
    resources.reject { |entry| valid_resource_types.include? entry.resourceType }
      .map(&:resourceType)
      .uniq
  if invalid_resource_types.any?
    info "Received resource type(s) #{invalid_resource_types.join(', ')} in search bundle, " \
         "but only expected resource types #{valid_resource_types.join(', ')}. " \
         'This is unusual but allowed if the server believes additional resource types are relevant.'
  end

  resources
rescue JSON::ParserError
  Inferno::Application[:logger].error "Could not resolve next bundle: #{next_bundle_link(bundle)}"
  resources
end

#fhir_client(client = :default) ⇒ FHIR::Client

Return a previously defined FHIR client

Parameters:

  • client (Symbol) (defaults to: :default)

    the name of the client

Returns:

See Also:



56
57
58
59
# File 'lib/inferno/dsl/fhir_client.rb', line 56

def fhir_client(client = :default)
  fhir_clients[client] ||=
    FHIRClientBuilder.new.build(self, find_fhir_client_definition(client))
end

#fhir_create(resource, client: :default, name: nil, tags: []) ⇒ Inferno::Entities::Request

Perform a FHIR create interaction.

Parameters:

  • resource (FHIR::Model)
  • client (Symbol) (defaults to: :default)
  • name (Symbol) (defaults to: nil)

    Name for this request to allow it to be used by other tests

  • tags (Array<String>) (defaults to: [])

    a list of tags to assign to the request

Returns:



165
166
167
168
169
170
171
# File 'lib/inferno/dsl/fhir_client.rb', line 165

def fhir_create(resource, client: :default, name: nil, tags: [])
  store_request_and_refresh_token(fhir_client(client), name, tags) do
    tcp_exception_handler do
      fhir_client(client).create(resource)
    end
  end
end

#fhir_delete(resource_type, id, client: :default, name: nil, tags: []) ⇒ Inferno::Entities::Request

Perform a FHIR delete interaction.

Parameters:

  • resource_type (String, Symbol, Class)
  • id (String)
  • client (Symbol) (defaults to: :default)
  • name (Symbol) (defaults to: nil)

    Name for this request to allow it to be used by other tests

  • tags (Array<String>) (defaults to: [])

    a list of tags to assign to the request

Returns:



312
313
314
315
316
317
318
# File 'lib/inferno/dsl/fhir_client.rb', line 312

def fhir_delete(resource_type, id, client: :default, name: nil, tags: [])
  store_request('outgoing', name:, tags:) do
    tcp_exception_handler do
      fhir_client(client).destroy(fhir_class_from_resource_type(resource_type), id)
    end
  end
end

#fhir_get_capability_statement(client: :default, name: nil, tags: []) ⇒ Inferno::Entities::Request

Fetch the capability statement.

Parameters:

  • client (Symbol) (defaults to: :default)
  • name (Symbol) (defaults to: nil)

    Name for this request to allow it to be used by other tests

  • tags (Array<String>) (defaults to: [])

    a list of tags to assign to the request

Returns:



148
149
150
151
152
153
154
155
# File 'lib/inferno/dsl/fhir_client.rb', line 148

def fhir_get_capability_statement(client: :default, name: nil, tags: [])
  store_request_and_refresh_token(fhir_client(client), name, tags) do
    tcp_exception_handler do
      fhir_client(client).conformance_statement
      fhir_client(client).reply
    end
  end
end

#fhir_history(resource_type = nil, id = nil, client: :default, name: nil, tags: []) ⇒ Inferno::Entities::Request

Perform a FHIR history interaction.

Parameters:

  • resource_type (String, Symbol, Class) (defaults to: nil)
  • id (String) (defaults to: nil)
  • client (Symbol) (defaults to: :default)
  • name (Symbol) (defaults to: nil)

    Name for this request to allow it to be used by other tests

  • tags (Array<String>) (defaults to: [])

    a list of tags to assign to the request

Returns:



252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/inferno/dsl/fhir_client.rb', line 252

def fhir_history(resource_type = nil, id = nil, client: :default, name: nil, tags: [])
  store_request_and_refresh_token(fhir_client(client), name, tags) do
    tcp_exception_handler do
      if id
        fhir_client(client).resource_instance_history(fhir_class_from_resource_type(resource_type), id)
      elsif resource_type
        fhir_client(client).resource_history(fhir_class_from_resource_type(resource_type))
      else
        fhir_client(client).all_history
      end
    end
  end
end

#fhir_operation(path, body: nil, client: :default, name: nil, headers: {}, operation_method: :post, tags: []) ⇒ Inferno::Entities::Request

Note:

This is a placeholder method until the FHIR::Client supports general operations. Note that while both POST and GET methods are allowed, GET is only allowed when the operation does not affect the server’s state. See https://build.fhir.org/operationdefinition-definitions.html#OperationDefinition.affectsState

Note:

Currently does not allow for repeated parameters if using GET

Perform a FHIR operation

Parameters:

  • path (String)
  • body (FHIR::Parameters) (defaults to: nil)

    Must all be primitive if making GET request

  • client (Symbol) (defaults to: :default)
  • name (Symbol) (defaults to: nil)

    Name for this request to allow it to be used by other tests

  • headers (Hash) (defaults to: {})

    custom headers for this operation

  • operation_method (Symbol) (defaults to: :post)

    indicates which request type to use for the operation

  • tags (Array<String>) (defaults to: [])

    a list of tags to assign to the request

Returns:



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/inferno/dsl/fhir_client.rb', line 113

def fhir_operation(
  path,
  body: nil,
  client: :default,
  name: nil,
  headers: {},
  operation_method: :post,
  tags: []
)
  store_request_and_refresh_token(fhir_client(client), name, tags) do
    tcp_exception_handler do
      operation_headers = fhir_client(client).fhir_headers
      operation_headers.merge!('Content-Type' => 'application/fhir+json') if body.present?
      operation_headers.merge!(headers) if headers.present?
      case operation_method
      when :post
        fhir_client(client).send(:post, path, body, operation_headers)
      when :get
        path = "#{path}?#{body_to_path(body)}" if body.present?
        fhir_client(client).send(:get, path, operation_headers)
      else
        Inferno::Application[:logger].error "Cannot perform #{operation_method} requests, use GET or POST"
        raise ArgumentError, "Cannot perform #{operation_method} requests, use GET or POST"
      end
    end
  end
end

#fhir_patch(resource_type, id, patchset, client: :default, name: nil, tags: []) ⇒ Inferno::Entities::Request

Perform a FHIR patch interaction.

Parameters:

  • resource_type (String, Symbol, Class)
  • id (String)
  • patchset (Array)
  • client (Symbol) (defaults to: :default)
  • name (Symbol) (defaults to: nil)

    Name for this request to allow it to be used by other tests

  • tags (Array<String>) (defaults to: [])

    a list of tags to assign to the request

Returns:



235
236
237
238
239
240
241
# File 'lib/inferno/dsl/fhir_client.rb', line 235

def fhir_patch(resource_type, id, patchset, client: :default, name: nil, tags: [])
  store_request_and_refresh_token(fhir_client(client), name, tags) do
    tcp_exception_handler do
      fhir_client(client).partial_update(fhir_class_from_resource_type(resource_type), id, patchset)
    end
  end
end

#fhir_read(resource_type, id, client: :default, name: nil, tags: []) ⇒ Inferno::Entities::Request

Perform a FHIR read interaction.

Parameters:

  • resource_type (String, Symbol, Class)
  • id (String)
  • client (Symbol) (defaults to: :default)
  • name (Symbol) (defaults to: nil)

    Name for this request to allow it to be used by other tests

  • tags (Array<String>) (defaults to: [])

    a list of tags to assign to the request

Returns:



182
183
184
185
186
187
188
# File 'lib/inferno/dsl/fhir_client.rb', line 182

def fhir_read(resource_type, id, client: :default, name: nil, tags: [])
  store_request_and_refresh_token(fhir_client(client), name, tags) do
    tcp_exception_handler do
      fhir_client(client).read(fhir_class_from_resource_type(resource_type), id)
    end
  end
end

#fhir_search(resource_type = nil, client: :default, params: {}, name: nil, search_method: :get, tags: []) ⇒ Inferno::Entities::Request

Perform a FHIR search interaction.

Parameters:

  • resource_type (String, Symbol, Class) (defaults to: nil)
  • client (Symbol) (defaults to: :default)
  • params (Hash) (defaults to: {})

    the search params

  • name (Symbol) (defaults to: nil)

    Name for this request to allow it to be used by other tests

  • search_method (Symbol) (defaults to: :get)

    Use :post to search via POST

  • tags (Array<String>) (defaults to: [])

    a list of tags to assign to the request

Returns:



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'lib/inferno/dsl/fhir_client.rb', line 276

def fhir_search(
  resource_type = nil,
  client: :default,
  params: {},
  name: nil,
  search_method: :get,
  tags: []
)
  search =
    if search_method == :post
      { body: params }
    else
      { parameters: params }
    end

  store_request_and_refresh_token(fhir_client(client), name, tags) do
    tcp_exception_handler do
      if resource_type
        fhir_client(client)
          .search(fhir_class_from_resource_type(resource_type), { search: })
      else
        fhir_client(client).search_all({ search: })
      end
    end
  end
end

#fhir_transaction(bundle = nil, client: :default, name: nil, tags: []) ⇒ Inferno::Entities::Request

Perform a FHIR batch/transaction interaction.

Parameters:

  • bundle (FHIR::Bundle) (defaults to: nil)

    the FHIR batch/transaction Bundle

  • client (Symbol) (defaults to: :default)
  • name (Symbol) (defaults to: nil)

    Name for this request to allow it to be used by other tests

  • tags (Array<String>) (defaults to: [])

    a list of tags to assign to the request

Returns:



328
329
330
331
332
333
334
335
# File 'lib/inferno/dsl/fhir_client.rb', line 328

def fhir_transaction(bundle = nil, client: :default, name: nil, tags: [])
  store_request('outgoing', name:, tags:) do
    tcp_exception_handler do
      fhir_client(client).transaction_bundle = bundle if bundle.present?
      fhir_client(client).end_transaction
    end
  end
end

#fhir_update(resource, id, client: :default, name: nil, tags: []) ⇒ Inferno::Entities::Request

Perform a FHIR update interaction.

Parameters:

  • resource (FHIR::Model)
  • id (String)
  • client (Symbol) (defaults to: :default)
  • name (Symbol) (defaults to: nil)

    Name for this request to allow it to be used by other tests

  • tags (Array<String>) (defaults to: [])

    a list of tags to assign to the request

Returns:



217
218
219
220
221
222
223
# File 'lib/inferno/dsl/fhir_client.rb', line 217

def fhir_update(resource, id, client: :default, name: nil, tags: [])
  store_request_and_refresh_token(fhir_client(client), name, tags) do
    tcp_exception_handler do
      fhir_client(client).update(resource, id)
    end
  end
end

#fhir_vread(resource_type, id, version_id, client: :default, name: nil, tags: []) ⇒ Inferno::Entities::Request

Perform a FHIR vread interaction.

Parameters:

  • resource_type (String, Symbol, Class)
  • id (String)
  • version_id (String)
  • client (Symbol) (defaults to: :default)
  • name (Symbol) (defaults to: nil)

    Name for this request to allow it to be used by other tests

  • tags (Array<String>) (defaults to: [])

    a list of tags to assign to the request

Returns:



200
201
202
203
204
205
206
# File 'lib/inferno/dsl/fhir_client.rb', line 200

def fhir_vread(resource_type, id, version_id, client: :default, name: nil, tags: [])
  store_request_and_refresh_token(fhir_client(client), name, tags) do
    tcp_exception_handler do
      fhir_client(client).vread(fhir_class_from_resource_type(resource_type), id, version_id)
    end
  end
end

#find_fhir_client_definition(client) ⇒ Object



61
62
63
# File 'lib/inferno/dsl/fhir_client.rb', line 61

def find_fhir_client_definition(client)
  self.class.find_fhir_client_definition(client)
end