Class: Inferno::DSL::FHIRResourceValidation::Validator

Inherits:
Object
  • Object
show all
Defined in:
lib/inferno/dsl/fhir_resource_validation.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name = nil, test_suite_id = nil, requirements = nil) ⇒ Validator

Returns a new instance of Validator.



45
46
47
48
49
50
# File 'lib/inferno/dsl/fhir_resource_validation.rb', line 45

def initialize(name = nil, test_suite_id = nil, requirements = nil, &)
  @name = name
  @test_suite_id = test_suite_id
  instance_eval(&)
  @requirements = requirements
end

Instance Attribute Details

#nameObject

Returns the value of attribute name.



43
44
45
# File 'lib/inferno/dsl/fhir_resource_validation.rb', line 43

def name
  @name
end

#requirementsObject (readonly)

Returns the value of attribute requirements.



42
43
44
# File 'lib/inferno/dsl/fhir_resource_validation.rb', line 42

def requirements
  @requirements
end

#session_idObject

Returns the value of attribute session_id.



43
44
45
# File 'lib/inferno/dsl/fhir_resource_validation.rb', line 43

def session_id
  @session_id
end

#test_suite_idObject

Returns the value of attribute test_suite_id.



43
44
45
# File 'lib/inferno/dsl/fhir_resource_validation.rb', line 43

def test_suite_id
  @test_suite_id
end

Instance Method Details

#exclude_message {|message| ... } ⇒ Object

Filter out unwanted validation messages. Any messages for which the block evalutates to a truthy value will be excluded.

Examples:

validator do
  exclude_message { |message| message.type == 'info' }
end

Yield Parameters:



157
158
159
160
# File 'lib/inferno/dsl/fhir_resource_validation.rb', line 157

def exclude_message(&block)
  @exclude_message = block if block_given?
  @exclude_message
end

#igs(*validator_igs) ⇒ Object

Set the IGs that the validator will need to load

Examples:

igs "hl7.fhir.us.core#4.0.0"
igs("hl7.fhir.us.core#3.1.1", "hl7.fhir.us.core#6.0.0")

Parameters:

  • validator_igs (Array<String>)


71
72
73
74
75
# File 'lib/inferno/dsl/fhir_resource_validation.rb', line 71

def igs(*validator_igs)
  validation_context(igs: validator_igs) if validator_igs.any?

  validation_context.igs
end

#perform_additional_validation {|resource, profile_url| ... } ⇒ Object

Perform validation steps in addition to FHIR validation.

Examples:

perform_additional_validation do |resource, profile_url|
  if something_is_wrong
    { type: 'error', message: 'something is wrong' }
  else
    { type: 'info', message: 'everything is ok' }
  end
end

Yield Parameters:

  • resource (FHIR::Model)

    the resource being validated

  • profile_url (String)

    the profile the resource is being validated against

Yield Returns:

  • (Array<Hash<Symbol, String>>, Hash<Symbol, String>)

    The block should return a Hash or an Array of Hashes if any validation messages should be added. The Hash must contain two keys: :type and :message. :type can have a value of 'info', 'warning', or 'error'. A type of 'error' means the resource is invalid. :message contains the message string itself.



145
146
147
# File 'lib/inferno/dsl/fhir_resource_validation.rb', line 145

def perform_additional_validation(&block)
  additional_validations << block
end

#resource_is_valid?(resource, profile_url, runnable, add_messages_to_runnable: true, validator_response_details: nil) ⇒ Boolean

Validate a FHIR resource and determine if it’s valid. Adds validation messages to the runnable if add_messages_to_runnable is true.

Parameters:

  • resource (FHIR::Model)

    the resource to validate

  • profile_url (String)

    the profile URL to validate against

  • runnable (Object)

    the runnable context (test/group/suite)

  • add_messages_to_runnable (Boolean) (defaults to: true)

    whether to add messages to the runnable

  • validator_response_details (Array, nil) (defaults to: nil)

    if not nil, the service will populate this array with the detailed response message from the validator service. Can be used by test kits to perform custom handling of error messages.

Returns:

  • (Boolean)

    true if the resource is valid

See Also:

  • Inferno::DSL::FHIRResourceValidation#resource_is_valid?


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

def resource_is_valid?(resource, profile_url, runnable, add_messages_to_runnable: true,
                       validator_response_details: nil)
  profile_url ||= FHIR::Definitions.resource_definition(resource.resourceType).url

  # 1. Get raw content from validator
  response = get_raw_validator_content(resource, profile_url, runnable)

  # 2. Convert to validation issues
  issues = get_issues_from_validator_response(response, resource)

  # 3. Add additional validation messages
  issues = join_additional_validation_messages(issues, resource, profile_url)

  # 4. Mark resources as filtered
  mark_issues_for_filtering(issues)

  # 5. Add error messages to runnable
  filtered_issues = issues.reject(&:filtered)
  add_validation_messages_to_runnable(runnable, filtered_issues) if add_messages_to_runnable
  validator_response_details&.concat(issues)

  # 6. Return validity
  filtered_issues.none? { |issue| issue.severity == 'error' }
rescue Inferno::Exceptions::ErrorInValidatorException
  raise
rescue StandardError => e
  runnable.add_message('error', e.message)
  raise Inferno::Exceptions::ErrorInValidatorException,
        'Error occurred in the validator. Review Messages tab or validator service logs for more information.'
end

#url(validator_url = nil) ⇒ Object

Set the url of the validator service

Parameters:

  • validator_url (String) (defaults to: nil)


59
60
61
62
63
# File 'lib/inferno/dsl/fhir_resource_validation.rb', line 59

def url(validator_url = nil)
  @url = validator_url if validator_url
  @url ||= ENV.fetch('FHIR_RESOURCE_VALIDATOR_URL')
  @url
end

#validation_context(definition = nil) ⇒ Object Also known as: cli_context

Set the validationContext used as part of each validation request. Fields may be passed as either a Hash or block. Note that all fields included here will be sent directly in requests, there is no check that the fields are correct.

Examples:

# Passing fields in a block
fhir_resource_validator do
  url 'http://example.com/validator'
  validation_context do
    noExtensibleBindingMessages true
    allowExampleUrls true
    txServer nil
  end
end
# Passing fields in a Hash
fhir_resource_validator do
  url 'http://example.org/validator'
  validation_context({
    noExtensibleBindingMessages: true,
    allowExampleUrls: true,
    txServer: nil
  })
end

Parameters:

  • definition (Hash) (defaults to: nil)

    raw fields to set, optional



105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/inferno/dsl/fhir_resource_validation.rb', line 105

def validation_context(definition = nil, &)
  if @validation_context
    if definition
      @validation_context.definition.merge!(definition.deep_symbolize_keys)
    elsif block_given?
      @validation_context.instance_eval(&)
    end
  else
    @validation_context = ValidationContext.new(definition || {}, &)
  end
  @validation_context
end

#validator_session_repoObject



52
53
54
# File 'lib/inferno/dsl/fhir_resource_validation.rb', line 52

def validator_session_repo
  @validator_session_repo ||= Inferno::Repositories::ValidatorSessions.new
end

#warm_up(resource, profile_url) ⇒ Object

Warm up the validator session by sending a test validation request. This initializes the validator session and persists it for future use.

Parameters:

  • resource (FHIR::Model)

    the resource to validate

  • profile_url (String)

    the profile URL to validate against



239
240
241
242
243
244
245
246
247
248
249
# File 'lib/inferno/dsl/fhir_resource_validation.rb', line 239

def warm_up(resource, profile_url)
  response_body = validate(resource, profile_url)
  res = JSON.parse(response_body)
  session_id = res['sessionId']
  validator_session_repo.save(test_suite_id:, validator_session_id: session_id,
                              validator_name: name.to_s, suite_options: requirements)
  self.session_id = session_id
rescue JSON::ParserError
  Application[:logger]
    .error("Validator warm_up - error unexpected response format from validator: #{response_body}")
end