Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FI-2236: Support arbitrary fields in HL7 validator cliContext #413

Merged
merged 4 commits into from
Dec 19, 2023

Conversation

dehall
Copy link
Contributor

@dehall dehall commented Dec 4, 2023

Summary

This PR enables test kits to specify settings for the HL7 validator wrapper via the cliContext field of the validation request. The cliContext is used to define settings for a validator session such as FHIR version, whether to disable terminology checks, whether code display issues should be a warning or error, etc.

Example request:

{
  "cliContext": {
    "sv": "4.0.1",
    "ig": [
      "hl7.fhir.us.core#4.0.0"
    ],
    "locale": "en"
  },
  "filesToValidate": [
    {
      "fileName": "manually_entered_file.json",
      "fileContent": "{\"resourceType\": \"Patient\"}",
      "fileType": "json"
    }
  ],
  "sessionId": "32fc25cf-020e-4492-ace5-03fe904d22e0"
}

Essentially every option from the validator CLI is also available here (though unfortunately the names don't always match exactly and there's no full list of option names. The HL7 validator wrapper has a little doco here but it doesn't appear to list everything. We may have to refer to the CliContext source code for the full list and field names to use)

The approach here is to define method_missing so that arbitrary fields can be set on cliContext without Inferno having to specifically add support for them. The other approach I considered was just having test kits set the raw cliContext in the validator block. Anything else would require us to define the set of options we support.

Also as part of this PR I set defaults for the "doNative" and "extensions" fields to match what we are using in our wrapper: https://github.com/inferno-framework/fhir-validator-wrapper/blob/main/src/main/java/org/mitre/inferno/Validator.java#L104

Testing Guidance

To use the HL7 validator:

  • enable the hl7_validator_service in docker-compose.background.yml and nginx.background.conf
  • In your test suite, use fhir_resource_validator instead of validator and make sure it points to the hl7 wrapper. An easy place to do this is in the demo suite dev_suites/dev_demo_ig_stu1/demo_suite.rb:
    fhir_resource_validator do
      url ENV.fetch('FHIR_RESOURCE_VALIDATOR_URL')
      exclude_message { |message| message.type == 'info' }
    end

Then add whatever other cliContext settings you want, for example:

    fhir_resource_validator do
      url ENV.fetch('FHIR_RESOURCE_VALIDATOR_URL')
      cli_context do
        txServer nil
        displayWarnings true
      end
      exclude_message { |message| message.type == 'info' }
    end

Run the test and ensure the validator is using those settings based on the returned messages (or print the actual request to console somewhere)

Copy link

codecov bot commented Dec 4, 2023

Codecov Report

Attention: 2 lines in your changes are missing coverage. Please review.

Comparison is base (367dab9) 76.98% compared to head (dedac17) 77.03%.

Files Patch % Lines
lib/inferno/dsl/fhir_resource_validation.rb 90.90% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #413      +/-   ##
==========================================
+ Coverage   76.98%   77.03%   +0.04%     
==========================================
  Files         218      218              
  Lines       10894    10913      +19     
  Branches     1019     1026       +7     
==========================================
+ Hits         8387     8407      +20     
+ Misses       1928     1927       -1     
  Partials      579      579              
Flag Coverage Δ
backend 93.89% <90.90%> (+0.06%) ⬆️
frontend 69.60% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@dehall
Copy link
Contributor Author

dehall commented Dec 8, 2023

@Jammjammjamm I updated this to move the method_missing aspect into a new CliContext helper class and it's ready for re-review.

I wanted flexibility in terms of the order things could be called in (for example, I didn't want to say "you have to call cli_context before igs in a fhir_resource_validator block"), so it feels a little messy and I'm sure there are ways to do it better. (Especially the Validator.cli_context method)

@@ -51,11 +51,39 @@ def url(validator_url = nil)

# Set the IGs that the validator will need to load
# Example: ["hl7.fhir.us.core#4.0.0"]
# @param igs [Array<String>]
# @param validator_igs [Array<String>]
def igs(validator_igs = nil)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about making this def igs(*validator_igs)? That way users could pass in a single ig or multiple igs without having to wrap them in an Array.

Copy link
Contributor Author

@dehall dehall Dec 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this idea but I'm realizing that if you set IGs via cli_context with a block then you still need to wrap it into an array. I'm not sure if that difference is confusing.
Example:

Validator.new do
        url 'http://example.com'
        igs 'hl7.fhir.us.core#1.0.1'
      end

vs

Validator.new do
        url 'http://example.com'
        cli_context do
          igs ['hl7.fhir.us.core#1.0.1']
        end
      end

CliContext.method_missing could deal with this, but other than looking for the "igs" field specifically I'm not sure how we could say "wrap this single value in an array" in a way that doesn't break any other field we want to set.

lib/inferno/dsl/fhir_resource_validation.rb Show resolved Hide resolved
lib/inferno/dsl/fhir_resource_validation.rb Outdated Show resolved Hide resolved
# args will be an empty array if no value is provided.
unless args.empty?
new_val = args[0]
old_val = definition[method_name]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will be vulnerable to a symbol/string mismatch if the cli context is initialized with a Hash with String keys, so line 323 should be @definition = CLICONTEXT_DEFAULTS.merge(definition.deep_symbolize_keys).

# take the union of the 2
old_val | new_val
when Hash
old_val.merge(new_val)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Hash and Array handling could raise a TypeError if the types don't match. We should rescue TypeError so that we can provide a more helpful error message with the key and values. I don't think the default error message is helpful enough on its own:

[1] pry(main)> {a: 1}.merge('abc')
TypeError: no implicit conversion of String into Hash
[2] pry(main)> [1,2] | 3
TypeError: no implicit conversion of Integer into Array

@dehall
Copy link
Contributor Author

dehall commented Dec 15, 2023

@Jammjammjamm Updated per review comments and offline discussion. Latest has the following changes:

  • Revert the "merging" logic. The biggest driver for this is the "extensions" field which defaults to an array ['any'], and the merge approach would have made this difficult to override.
  • Change instances of resource.to_json to resource.source_contents
  • Called .deep_symbolize_keys on hashes passed into CliContext to ensure keys are always symbols not strings.
  • Tweaked the unit tests to exercise the above situations a little more

@dehall dehall merged commit b3d66d5 into main Dec 19, 2023
10 checks passed
@dehall dehall deleted the fi-2236-clicontext branch December 19, 2023 17:31
@rpassas rpassas mentioned this pull request Dec 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants