Module: Inferno::DSL::FHIRClient

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

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.



345
346
347
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
# File 'lib/inferno/dsl/fhir_client.rb', line 345

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

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

  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:



53
54
55
56
# File 'lib/inferno/dsl/fhir_client.rb', line 53

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:



162
163
164
165
166
167
168
# File 'lib/inferno/dsl/fhir_client.rb', line 162

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:



309
310
311
312
313
314
315
# File 'lib/inferno/dsl/fhir_client.rb', line 309

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:



145
146
147
148
149
150
151
152
# File 'lib/inferno/dsl/fhir_client.rb', line 145

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:



249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/inferno/dsl/fhir_client.rb', line 249

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:



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

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:



232
233
234
235
236
237
238
# File 'lib/inferno/dsl/fhir_client.rb', line 232

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:



179
180
181
182
183
184
185
# File 'lib/inferno/dsl/fhir_client.rb', line 179

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:



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

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:



325
326
327
328
329
330
331
332
# File 'lib/inferno/dsl/fhir_client.rb', line 325

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:



214
215
216
217
218
219
220
# File 'lib/inferno/dsl/fhir_client.rb', line 214

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:



197
198
199
200
201
202
203
# File 'lib/inferno/dsl/fhir_client.rb', line 197

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



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

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