diff --git a/lib/inferno/apps/cli/templates/.env.development b/lib/inferno/apps/cli/templates/.env.development index da8a32249..e8690f6a4 100644 --- a/lib/inferno/apps/cli/templates/.env.development +++ b/lib/inferno/apps/cli/templates/.env.development @@ -1,2 +1,2 @@ -VALIDATOR_URL=http://localhost/validatorapi +FHIR_RESOURCE_VALIDATOR_URL=http://localhost/hl7validatorapi REDIS_URL=redis://localhost:6379/0 \ No newline at end of file diff --git a/lib/inferno/apps/cli/templates/.env.production b/lib/inferno/apps/cli/templates/.env.production index 0f832e3e2..719b168be 100644 --- a/lib/inferno/apps/cli/templates/.env.production +++ b/lib/inferno/apps/cli/templates/.env.production @@ -1,2 +1,2 @@ REDIS_URL=redis://redis:6379/0 -VALIDATOR_URL=http://validator_service:4567 \ No newline at end of file +FHIR_RESOURCE_VALIDATOR_URL=http://hl7_validator_service:3500 \ No newline at end of file diff --git a/lib/inferno/apps/cli/templates/.env.test b/lib/inferno/apps/cli/templates/.env.test index 9e95769c3..1545bfc1f 100644 --- a/lib/inferno/apps/cli/templates/.env.test +++ b/lib/inferno/apps/cli/templates/.env.test @@ -1,2 +1,2 @@ -VALIDATOR_URL=https://example.com/validatorapi +FHIR_RESOURCE_VALIDATOR_URL=https://example.com/validatorapi ASYNC_JOBS=false diff --git a/lib/inferno/apps/cli/templates/config/nginx.background.conf.tt b/lib/inferno/apps/cli/templates/config/nginx.background.conf.tt index f89747207..885866bb4 100644 --- a/lib/inferno/apps/cli/templates/config/nginx.background.conf.tt +++ b/lib/inferno/apps/cli/templates/config/nginx.background.conf.tt @@ -82,5 +82,21 @@ http { proxy_pass http://validator_service:4567/; } + + location /hl7validatorapi/ { + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Port $server_port; + proxy_redirect off; + proxy_set_header Connection ''; + proxy_http_version 1.1; + chunked_transfer_encoding off; + proxy_buffering off; + proxy_cache off; + proxy_read_timeout 600s; + + proxy_pass http://hl7_validator_service:3500/; + } } } diff --git a/lib/inferno/apps/cli/templates/config/nginx.conf.tt b/lib/inferno/apps/cli/templates/config/nginx.conf.tt index af4b46141..a0d60007e 100644 --- a/lib/inferno/apps/cli/templates/config/nginx.conf.tt +++ b/lib/inferno/apps/cli/templates/config/nginx.conf.tt @@ -97,5 +97,21 @@ http { proxy_pass http://validator_service:4567/; } + + location /hl7validatorapi/ { + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Port $server_port; + proxy_redirect off; + proxy_set_header Connection ''; + proxy_http_version 1.1; + chunked_transfer_encoding off; + proxy_buffering off; + proxy_cache off; + proxy_read_timeout 600s; + + proxy_pass http://hl7_validator_service:3500/; + } } } diff --git a/lib/inferno/apps/cli/templates/docker-compose.background.yml.tt b/lib/inferno/apps/cli/templates/docker-compose.background.yml.tt index 423f723e3..8bce4dc0b 100644 --- a/lib/inferno/apps/cli/templates/docker-compose.background.yml.tt +++ b/lib/inferno/apps/cli/templates/docker-compose.background.yml.tt @@ -1,5 +1,16 @@ version: '3' services: + hl7_validator_service: + image: infernocommunity/inferno-resource-validator + environment: + # Defines how long validator sessions last if unused, in minutes: + # Negative values mean sessions never expire, 0 means sessions immediately expire + SESSION_CACHE_DURATION: -1 + volumes: + - ./<%= ig_path %>:/app/igs + # To let the service share your local FHIR package cache, + # uncomment the below line + # - ~/.fhir:/home/ktor/.fhir validator_service: image: infernocommunity/fhir-validator-service # Update this path to match your directory structure diff --git a/lib/inferno/apps/cli/templates/docker-compose.yml.tt b/lib/inferno/apps/cli/templates/docker-compose.yml.tt index c93760781..eaa6736ce 100644 --- a/lib/inferno/apps/cli/templates/docker-compose.yml.tt +++ b/lib/inferno/apps/cli/templates/docker-compose.yml.tt @@ -15,6 +15,10 @@ services: command: bundle exec sidekiq -r ./worker.rb depends_on: - redis + hl7_validator_service: + extends: + file: docker-compose.background.yml + service: hl7_validator_service validator_service: extends: file: docker-compose.background.yml diff --git a/lib/inferno/apps/cli/templates/lib/%library_name%.rb.tt b/lib/inferno/apps/cli/templates/lib/%library_name%.rb.tt index 1dd1710a1..511e487da 100644 --- a/lib/inferno/apps/cli/templates/lib/%library_name%.rb.tt +++ b/lib/inferno/apps/cli/templates/lib/%library_name%.rb.tt @@ -22,8 +22,13 @@ module <%= module_name %> end # All FHIR validation requsets will use this FHIR validator - validator do - url ENV.fetch('VALIDATOR_URL') + fhir_resource_validator do + # igs 'identifier#version' # Use this method for published IGs/versions + # igs 'igs/filename.tgz' # Use this otherwise + + exclude_message do |message| + message.message.match?(/\A\S+: \S+: URL value '.*' does not resolve/) + end end # Tests and TestGroups can be defined inline diff --git a/lib/inferno/apps/cli/templates/lib/%library_name%/igs/README.md b/lib/inferno/apps/cli/templates/lib/%library_name%/igs/README.md new file mode 100644 index 000000000..7ed8b2712 --- /dev/null +++ b/lib/inferno/apps/cli/templates/lib/%library_name%/igs/README.md @@ -0,0 +1,21 @@ +# Note on this IGs folder + +There are three reasons why it would be necessary to put an IG package.tgz in this folder. If none of these apply, you do not need to put any files here, or can consider removing any existing files to make it clear they are unused. + +## 1. Generated Test Suites +Some test kits use a "generator" to automatically generate the contents of a test suite for an IG. The IG files are required every time the test suites need to be regenerated. Examples of test kits that use this approach are the US Core Test Kit and CARIN IG for Blue ButtonĀ® Test Kit. + + +## 2. Non-published IG +If your IG, or the specific version of the IG you want to test against, is not published, then the validator service needs to load the IG from file in order to be able to validate resources with it. The IG must be referenced in the `fhir_resource_validator` block in the test suite definition by filename, ie: + +```ruby + fhir_resource_validator do + igs 'igs/filename.tgz' + + ... + end +``` + +## 3. Inferno Validator UI +The Inferno Validator UI is configured to auto-load any IGs present in the igs folder and include them in all validations. In general, the Inferno team is currently leaving IGs in this folder even if not otherwise necessary to make it easy to re-enable the validator UI. \ No newline at end of file diff --git a/lib/inferno/apps/cli/templates/spec/%library_name%/patient_group_spec.rb.tt b/lib/inferno/apps/cli/templates/spec/%library_name%/patient_group_spec.rb.tt index 408f2b7b6..58c462d7c 100644 --- a/lib/inferno/apps/cli/templates/spec/%library_name%/patient_group_spec.rb.tt +++ b/lib/inferno/apps/cli/templates/spec/%library_name%/patient_group_spec.rb.tt @@ -4,7 +4,26 @@ RSpec.describe <%= module_name %>::PatientGroup do let(:session_data_repo) { Inferno::Repositories::SessionData.new } let(:test_session) { repo_create(:test_session, test_suite_id: '<%= test_suite_id %>') } let(:url) { 'http://example.com/fhir' } - let(:error_outcome) { FHIR::OperationOutcome.new(issue: [{ severity: 'error' }]) } + let(:success_outcome) do + { + outcomes: [{ + issues: [] + }], + sessionId: '' + } + end + let(:error_outcome) do + { + outcomes: [{ + issues: [{ + location: 'Patient.identifier[0]', + message: 'Identifier.system must be an absolute reference, not a local reference', + level: 'ERROR' + }] + }], + sessionId: '' + } + end def run(runnable, inputs = {}) test_run_params = { test_session_id: test_session.id }.merge(runnable.reference_hash) @@ -67,9 +86,9 @@ RSpec.describe <%= module_name %>::PatientGroup do let(:test) { group.tests.last } it 'passes if the resource is valid' do - stub_request(:post, "#{ENV.fetch('VALIDATOR_URL')}/validate") + stub_request(:post, "#{ENV.fetch('FHIR_RESOURCE_VALIDATOR_URL')}/validate") .with(query: hash_including({})) - .to_return(status: 200, body: FHIR::OperationOutcome.new.to_json) + .to_return(status: 200, body: success_outcome.to_json) resource = FHIR::Patient.new repo_create( @@ -79,13 +98,13 @@ RSpec.describe <%= module_name %>::PatientGroup do response_body: resource.to_json ) - result = run(test) + result = run(test, url: url) expect(result.result).to eq('pass') end it 'fails if the resource is not valid' do - stub_request(:post, "#{ENV.fetch('VALIDATOR_URL')}/validate") + stub_request(:post, "#{ENV.fetch('FHIR_RESOURCE_VALIDATOR_URL')}/validate") .with(query: hash_including({})) .to_return(status: 200, body: error_outcome.to_json) @@ -97,7 +116,7 @@ RSpec.describe <%= module_name %>::PatientGroup do response_body: resource.to_json ) - result = run(test) + result = run(test, url: url) expect(result.result).to eq('fail') end