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:

  • Documentation for the client configuration DSL

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Instance Method Details

#fhir_class_from_resource_type(resource_type) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

TODO:

Make this a FHIR class method? Something like FHIR.class_for(resource_type)



163
164
165
# File 'lib/inferno/dsl/fhir_client.rb', line 163

def fhir_class_from_resource_type(resource_type)
  FHIR.const_get(resource_type.to_s.camelize)
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:

  • FHIRClientBuilder


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

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

#fhir_delete(resource_type, id, client: :default, name: nil) ⇒ 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

Returns:



152
153
154
155
156
157
158
# File 'lib/inferno/dsl/fhir_client.rb', line 152

def fhir_delete(resource_type, id, client: :default, name: nil)
  store_request('outgoing', name) 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) ⇒ 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

Returns:



94
95
96
97
98
99
100
101
# File 'lib/inferno/dsl/fhir_client.rb', line 94

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

#fhir_operation(path, body: nil, client: :default, name: nil, headers: {}) ⇒ Inferno::Entities::Request

Note:

This is a placeholder method until the FHIR::Client supports general operations

Perform a FHIR operation

Parameters:

  • path (String)
  • body (FHIR::Parameters) (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

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

    custom headers for this operation

Returns:



76
77
78
79
80
81
82
83
84
85
86
# File 'lib/inferno/dsl/fhir_client.rb', line 76

def fhir_operation(path, body: nil, client: :default, name: nil, headers: {})
  store_request_and_refresh_token(fhir_client(client), name) 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?

      fhir_client(client).send(:post, path, body, operation_headers)
    end
  end
end

#fhir_read(resource_type, id, client: :default, name: nil) ⇒ 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

Returns:



111
112
113
114
115
116
117
# File 'lib/inferno/dsl/fhir_client.rb', line 111

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

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

Perform a FHIR search interaction.

Parameters:

  • resource_type (String, Symbol, Class)
  • 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

Returns:



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/inferno/dsl/fhir_client.rb', line 128

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

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

#perform_refresh(client) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/inferno/dsl/fhir_client.rb', line 179

def perform_refresh(client)
  credentials = client.oauth_credentials

  post(
    credentials.token_url,
    body: credentials.oauth2_refresh_params,
    headers: credentials.oauth2_refresh_headers
  )

  return if request.status != 200

  credentials.update_from_response_body(request)

  if credentials.name.present?
    Inferno::Repositories::SessionData.new.save(
      name: credentials.name,
      value: credentials,
      type: 'oauth_credentials',
      test_session_id: test_session_id
    )
  end
rescue StandardError => e
  Inferno::Application[:logger].error "Unable to refresh token: #{e.message}"
end

#store_request_and_refresh_token(client, name, &block) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method wraps a request to automatically refresh its access token if expired. It's combined with store_request so that all of the fhir request methods don't have to be wrapped twice.



171
172
173
174
175
176
# File 'lib/inferno/dsl/fhir_client.rb', line 171

def store_request_and_refresh_token(client, name, &block)
  store_request('outgoing', name) do
    perform_refresh(client) if client.need_to_refresh? && client.able_to_refresh?
    block.call
  end
end