diff --git a/.env b/.env index 8e29e83..d3cc9c6 100644 --- a/.env +++ b/.env @@ -1,3 +1 @@ JS_HOST="" -VALIDATOR_URL=http://validator_service:4567 -REDIS_URL=redis://redis:6379/0 diff --git a/.env.development b/.env.development index 994744e..e8690f6 100644 --- a/.env.development +++ b/.env.development @@ -1 +1,2 @@ -VALIDATOR_URL=http://validator_service:4567 \ No newline at end of file +FHIR_RESOURCE_VALIDATOR_URL=http://localhost/hl7validatorapi +REDIS_URL=redis://localhost:6379/0 \ No newline at end of file diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..719b168 --- /dev/null +++ b/.env.production @@ -0,0 +1,2 @@ +REDIS_URL=redis://redis:6379/0 +FHIR_RESOURCE_VALIDATOR_URL=http://hl7_validator_service:3500 \ No newline at end of file diff --git a/.env.test b/.env.test index 9e95769..325d504 100644 --- a/.env.test +++ b/.env.test @@ -1,2 +1,2 @@ -VALIDATOR_URL=https://example.com/validatorapi +FHIR_RESOURCE_VALIDATOR_URL=https://example.com/hl7validatorapi ASYNC_JOBS=false diff --git a/.ruby-version b/.ruby-version index e2bdf6e..6ebad14 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.7.3 \ No newline at end of file +3.1.2 \ No newline at end of file diff --git a/.tool-versions b/.tool-versions index fde9f5b..b8ab7ea 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1 +1 @@ -ruby 2.7.3 \ No newline at end of file +ruby 3.1.2 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 9eb5ec7..d32710c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:2.7.3 +FROM ruby:3.1.2 ENV INSTALL_PATH=/opt/inferno/ ENV APP_ENV=production diff --git a/Gemfile b/Gemfile index be173b2..382378e 100644 --- a/Gemfile +++ b/Gemfile @@ -3,3 +3,7 @@ source "https://rubygems.org" gemspec + +group :development, :test do + gem 'debug' +end diff --git a/Gemfile.lock b/Gemfile.lock index 75ee7b2..6802f3a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,74 +2,65 @@ PATH remote: . specs: inferno_template (0.0.1) - inferno_core (~> 0.3.0) + inferno_core (~> 0.4.38) GEM remote: https://rubygems.org/ specs: - activesupport (6.1.6) + activesupport (6.1.7.8) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) zeitwerk (~> 2.3) - addressable (2.8.0) - public_suffix (>= 2.0.2, < 5.0) + addressable (2.8.6) + public_suffix (>= 2.0.2, < 6.0) + base62-rb (0.3.1) + base64 (0.2.0) bcp47 (0.3.3) i18n + bigdecimal (3.1.8) blueprinter (0.25.2) byebug (11.1.3) coderay (1.1.3) - concurrent-ruby (1.1.10) - connection_pool (2.2.5) - crack (0.4.5) + concurrent-ruby (1.3.1) + connection_pool (2.4.1) + crack (1.0.0) + bigdecimal rexml database_cleaner (1.99.0) database_cleaner-sequel (1.99.0) database_cleaner (~> 1.99.0) sequel date_time_precision (0.8.1) - diff-lcs (1.5.0) - domain_name (0.5.20190701) - unf (>= 0.0.5, < 1.0.0) - dotenv (2.7.6) - dry-auto_inject (0.9.0) - dry-container (>= 0.3.4) - dry-configurable (0.12.0) + debug (1.9.2) + irb (~> 1.10) + reline (>= 0.3.8) + diff-lcs (1.5.1) + domain_name (0.6.20240107) + dotenv (2.8.1) + dry-auto_inject (1.0.1) + dry-core (~> 1.0) + zeitwerk (~> 2.6) + dry-configurable (1.0.0) + dry-core (~> 1.0, < 2) + zeitwerk (~> 2.6) + dry-container (0.10.0) concurrent-ruby (~> 1.0) - dry-core (~> 0.5, >= 0.5.0) - dry-container (0.8.0) + dry-core (1.0.0) concurrent-ruby (~> 1.0) - dry-configurable (~> 0.1, >= 0.1.3) - dry-core (0.7.1) - concurrent-ruby (~> 1.0) - dry-equalizer (0.3.0) - dry-inflector (0.2.1) - dry-logic (1.2.0) - concurrent-ruby (~> 1.0) - dry-core (~> 0.5, >= 0.5) - dry-struct (1.4.0) - dry-core (~> 0.5, >= 0.5) - dry-types (~> 1.5) - ice_nine (~> 0.11) - dry-system (0.18.1) - concurrent-ruby (~> 1.0) - dry-auto_inject (>= 0.4.0) - dry-configurable (~> 0.11, >= 0.11.1) - dry-container (~> 0.7, >= 0.7.2) - dry-core (~> 0.3, >= 0.3.1) - dry-equalizer (~> 0.2) - dry-inflector (~> 0.1, >= 0.1.2) - dry-struct (~> 1.0) - dry-types (1.5.1) - concurrent-ruby (~> 1.0) - dry-container (~> 0.3) - dry-core (~> 0.5, >= 0.5) - dry-inflector (~> 0.1, >= 0.1.2) - dry-logic (~> 1.0, >= 1.0.2) - factory_bot (6.2.0) + zeitwerk (~> 2.6) + dry-inflector (1.0.0) + dry-system (1.0.0) + dry-auto_inject (~> 1.0.0.rc1, < 2) + dry-configurable (~> 1.0, < 2) + dry-core (~> 1.0, < 2) + dry-inflector (~> 1.0, < 2) + dry-transformer (1.0.1) + zeitwerk (~> 2.6) + factory_bot (6.4.6) activesupport (>= 5.0.0) - faraday (1.10.0) + faraday (1.10.3) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) @@ -85,13 +76,15 @@ GEM faraday-em_synchrony (1.0.0) faraday-excon (1.1.0) faraday-httpclient (1.0.1) - faraday-multipart (1.0.3) - multipart-post (>= 1.2, < 3) + faraday-multipart (1.0.4) + multipart-post (~> 2) faraday-net_http (1.0.1) faraday-net_http_persistent (1.2.0) faraday-patron (1.0.0) faraday-rack (1.0.0) faraday-retry (1.0.3) + faraday_middleware (1.2.0) + faraday (~> 1.0) fhir_client (5.0.3) activesupport (>= 3) addressable (>= 2.3) @@ -103,149 +96,217 @@ GEM rack (>= 1.5) rest-client (~> 2.0) tilt (>= 1.1) - fhir_dstu2_models (1.1.1) + fhir_dstu2_models (1.2.0) bcp47 (>= 0.3) date_time_precision (>= 0.8) mime-types (>= 3.0) nokogiri (>= 1.11.4) - fhir_models (4.2.1) + fhir_models (4.3.0) bcp47 (>= 0.3) date_time_precision (>= 0.8) mime-types (>= 3.0) nokogiri (>= 1.11.4) - fhir_stu3_models (3.1.1) + fhir_stu3_models (3.2.0) bcp47 (>= 0.3) date_time_precision (>= 0.8) mime-types (>= 3.0) nokogiri (>= 1.11.4) - hanami-controller (1.3.3) - hanami-utils (~> 1.3) + hanami-controller (2.0.0) + dry-configurable (~> 1.0, < 2) + dry-core (~> 1.0) + hanami-utils (~> 2.0) rack (~> 2.0) - hanami-router (1.3.2) - hanami-utils (~> 1.3) - http_router (= 0.11.2) + zeitwerk (~> 2.6) + hanami-router (2.0.0) + mustermann (~> 1.0) + mustermann-contrib (~> 1.0) rack (~> 2.0) - hanami-utils (1.3.8) + hanami-utils (2.1.0) concurrent-ruby (~> 1.0) - transproc (~> 1.0) - hashdiff (1.0.1) + dry-core (~> 1.0, < 2) + dry-transformer (~> 1.0, < 2) + hansi (0.2.1) + hashdiff (1.1.0) http-accept (1.7.0) - http-cookie (1.0.5) + http-cookie (1.0.6) domain_name (~> 0.5) - http_router (0.11.2) - rack (>= 1.0.0) - url_mount (~> 0.2.1) - i18n (1.10.0) + i18n (1.14.5) concurrent-ruby (~> 1.0) - ice_nine (0.11.2) - inferno_core (0.3.3) - activesupport (~> 6.1) + inferno_core (0.4.38) + activesupport (~> 6.1.7.5) + base62-rb (= 0.3.1) blueprinter (= 0.25.2) dotenv (~> 2.7) - dry-configurable (= 0.12.0) - dry-system (= 0.18.1) + dry-configurable (= 1.0.0) + dry-container (= 0.10.0) + dry-core (= 1.0.0) + dry-inflector (= 1.0.0) + dry-system (= 1.0.0) faraday (~> 1.2) + faraday_middleware (~> 1.2) fhir_client (>= 5.0.3) - fhir_models (~> 4.2.0) - hanami-controller (~> 1.3) - hanami-router (~> 1.3) + fhir_models (>= 4.2.2) + hanami-controller (= 2.0.0) + hanami-router (= 2.0.0) oj (= 3.11.0) pry pry-byebug - puma (~> 5.3) + puma (~> 5.6.7) rake (~> 13.0) sequel (~> 5.42.0) - sidekiq (~> 6.4.0) + sidekiq (~> 7.2.4) sqlite3 (~> 1.4) - thor (~> 1.1.0) - jwt (2.3.0) - method_source (1.0.0) - mime-types (3.4.1) + thor (~> 1.2.1) + tty-markdown (~> 0.7.1) + io-console (0.7.2) + irb (1.13.1) + rdoc (>= 4.0.0) + reline (>= 0.4.2) + jwt (2.8.1) + base64 + kramdown (2.4.0) + rexml + method_source (1.1.0) + mime-types (3.5.2) mime-types-data (~> 3.2015) - mime-types-data (3.2022.0105) - minitest (5.15.0) + mime-types-data (3.2024.0507) + mini_portile2 (2.8.7) + minitest (5.23.1) multi_json (1.15.0) - multi_xml (0.6.0) - multipart-post (2.1.1) + multi_xml (0.7.1) + bigdecimal (~> 3.1) + multipart-post (2.4.1) + mustermann (1.1.2) + ruby2_keywords (~> 0.0.1) + mustermann-contrib (1.1.2) + hansi (~> 0.2.0) + mustermann (= 1.1.2) netrc (0.11.0) - nio4r (2.5.8) - nokogiri (1.13.6-x86_64-darwin) + nio4r (2.7.3) + nokogiri (1.16.5) + mini_portile2 (~> 2.8.2) + racc (~> 1.4) + nokogiri (1.16.5-aarch64-linux) racc (~> 1.4) - nokogiri (1.13.6-x86_64-linux) + nokogiri (1.16.5-arm-linux) racc (~> 1.4) - oauth2 (1.4.9) + nokogiri (1.16.5-arm64-darwin) + racc (~> 1.4) + nokogiri (1.16.5-x86-linux) + racc (~> 1.4) + nokogiri (1.16.5-x86_64-darwin) + racc (~> 1.4) + nokogiri (1.16.5-x86_64-linux) + racc (~> 1.4) + oauth2 (1.4.11) faraday (>= 0.17.3, < 3.0) jwt (>= 1.0, < 3.0) multi_json (~> 1.3) multi_xml (~> 0.5) - rack (>= 1.2, < 3) + rack (>= 1.2, < 4) oj (3.11.0) - pry (0.14.1) + pastel (0.8.0) + tty-color (~> 0.5) + pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) - pry-byebug (3.8.0) + pry-byebug (3.10.1) byebug (~> 11.0) - pry (~> 0.10) - public_suffix (4.0.7) - puma (5.6.4) + pry (>= 0.13, < 0.15) + psych (5.1.2) + stringio + public_suffix (5.0.5) + puma (5.6.8) nio4r (~> 2.0) - racc (1.6.0) - rack (2.2.3) - rake (13.0.6) - redis (4.6.0) + racc (1.8.0) + rack (2.2.9) + rake (13.2.1) + rdoc (6.7.0) + psych (>= 4.0.0) + redis-client (0.22.2) + connection_pool + reline (0.5.8) + io-console (~> 0.5) rest-client (2.1.0) http-accept (>= 1.7.0, < 2.0) http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 4.0) netrc (~> 0.8) - rexml (3.2.5) - rspec (3.11.0) - rspec-core (~> 3.11.0) - rspec-expectations (~> 3.11.0) - rspec-mocks (~> 3.11.0) - rspec-core (3.11.0) - rspec-support (~> 3.11.0) - rspec-expectations (3.11.0) + rexml (3.2.8) + strscan (>= 3.0.9) + rouge (4.2.1) + rspec (3.13.0) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.0) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.11.0) - rspec-mocks (3.11.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.11.0) - rspec-support (3.11.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.1) ruby2_keywords (0.0.5) sequel (5.42.0) - sidekiq (6.4.2) - connection_pool (>= 2.2.2) - rack (~> 2.0) - redis (>= 4.2.0) - sqlite3 (1.4.2) - thor (1.1.0) - tilt (2.0.10) - transproc (1.1.1) - tzinfo (2.0.4) + sidekiq (7.2.4) + concurrent-ruby (< 2) + connection_pool (>= 2.3.0) + rack (>= 2.2.4) + redis-client (>= 0.19.0) + sqlite3 (1.7.3) + mini_portile2 (~> 2.8.0) + sqlite3 (1.7.3-aarch64-linux) + sqlite3 (1.7.3-arm-linux) + sqlite3 (1.7.3-arm64-darwin) + sqlite3 (1.7.3-x86-linux) + sqlite3 (1.7.3-x86_64-darwin) + sqlite3 (1.7.3-x86_64-linux) + stringio (3.1.0) + strings (0.2.1) + strings-ansi (~> 0.2) + unicode-display_width (>= 1.5, < 3.0) + unicode_utils (~> 1.4) + strings-ansi (0.2.0) + strscan (3.1.0) + thor (1.2.2) + tilt (2.3.0) + tty-color (0.6.0) + tty-markdown (0.7.2) + kramdown (>= 1.16.2, < 3.0) + pastel (~> 0.8) + rouge (>= 3.14, < 5.0) + strings (~> 0.2.0) + tty-color (~> 0.5) + tty-screen (~> 0.8) + tty-screen (0.8.2) + tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unf (0.1.4) - unf_ext - unf_ext (0.0.8.1) - url_mount (0.2.1) - rack - webmock (3.14.0) + unicode-display_width (2.5.0) + unicode_utils (1.4.0) + webmock (3.23.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - zeitwerk (2.5.4) + zeitwerk (2.6.15) PLATFORMS - x86_64-darwin-19 - x86_64-darwin-20 + aarch64-linux + arm-linux + arm64-darwin + ruby + x86-linux + x86_64-darwin x86_64-linux DEPENDENCIES database_cleaner-sequel (~> 1.8) + debug factory_bot (~> 6.1) inferno_template! rspec (~> 3.10) webmock (~> 3.11) BUNDLED WITH - 2.3.14 + 2.5.11 diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..4f784b9 --- /dev/null +++ b/Procfile @@ -0,0 +1,2 @@ +web: bundle exec puma +worker: bundle exec sidekiq -r ./worker.rb diff --git a/README.md b/README.md index c3f6d26..6001f51 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,43 @@ -# Inferno Test Writing Tutorial +# Inferno Template Test Kit -This repository provides a step-by-step tutorial for users interested in writing -FHIR tests using the [Inferno Framework](https://inferno-framework.github.io/inferno-core/). +Inferno template [Inferno](https://github.com/inferno-community/inferno-core) Test Kit +for FHIR testing. -To get started, visit the [Tutorial Wiki](https://github.com/inferno-training/inferno-tutorial/wiki). +## Instructions for Developing Your Test Kit -This test kit was generated from the -[Inferno Test Kit Template](https://github.com/inferno-framework/inferno-template). +Refer to the Inferno documentation for information about [setting up +your development environment and running your Test Kit](https://inferno-framework.github.io/docs/getting-started/). + +More information about what is included in this repository can be [found here](https://inferno-framework.github.io/docs/getting-started/repo-layout-and-organization.html). + +## Documentation + +- [Inferno documentation](https://inferno-framework.github.io/docs/) +- [Ruby API documentation](https://inferno-framework.github.io/inferno-core/docs/) +- [JSON API documentation](https://inferno-framework.github.io/inferno-core/api-docs/) + +## Example Inferno Test Kits + +A list of all Test Kits registered with the Inferno Team can be found on the [Test Kit Registry](https://inferno-framework.github.io/community/test-kits.html) page. ## License -Copyright 2022 The MITRE Corporation + +Copyright 2024 The MITRE Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + ``` http://www.apache.org/licenses/LICENSE-2.0 ``` + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +## Trademark Notice + +HL7, FHIR and the FHIR [FLAME DESIGN] are the registered trademarks of Health +Level Seven International and their use does not constitute endorsement by HL7. diff --git a/config/nginx.background.conf b/config/nginx.background.conf new file mode 100644 index 0000000..7b31f62 --- /dev/null +++ b/config/nginx.background.conf @@ -0,0 +1,101 @@ +# this sets the user nginx will run as, +#and the number of worker processes +user nobody nogroup; +worker_processes 2; +#user www-data; +#worker_processes auto; + +# setup where nginx will log errors to +# and where the nginx process id resides +error_log /var/log/nginx/error.log; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; + # set to on if you have more than 1 worker_processes + accept_mutex on; +} + +http { + include /etc/nginx/mime.types; + + default_type application/octet-stream; + access_log /tmp/nginx.access.log combined; + + # use the kernel sendfile + # sendfile on; # this causes over-caching because modified timestamps lost in VM + # prepend http headers before sendfile() + tcp_nopush on; + + keepalive_timeout 600; + tcp_nodelay on; + + gzip on; + gzip_vary on; + gzip_min_length 500; + + gzip_disable "MSIE [1-6]\.(?!.*SV1)"; + gzip_types text/plain text/xml text/css + text/comma-separated-values + text/javascript application/x-javascript + application/atom+xml image/x-icon; + + # configure the virtual host + server { + # replace with your domain name + # server_name inferno-server; + + # port to listen for requests on + listen 80; + + # maximum accepted body size of client request + client_max_body_size 4G; + # the server will close connections after this time + keepalive_timeout 600; + + # location /validator { + # 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_pass http://fhir_validator_app; + # } + + # location /validatorapi/ { + # 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_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/config/nginx.conf b/config/nginx.conf index af4b461..15abd8b 100644 --- a/config/nginx.conf +++ b/config/nginx.conf @@ -68,7 +68,36 @@ http { proxy_pass http://inferno:4567; } - location /validator { + # location /validator { + # 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_pass http://fhir_validator_app; + # } + + # location /validatorapi/ { + # 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_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; @@ -79,23 +108,9 @@ http { chunked_transfer_encoding off; proxy_buffering off; proxy_cache off; + proxy_read_timeout 600s; - proxy_pass http://fhir_validator_app; - } - - location /validatorapi/ { - 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_pass http://validator_service:4567/; + proxy_pass http://hl7_validator_service:3500/; } } } diff --git a/docker-compose.background.yml b/docker-compose.background.yml new file mode 100644 index 0000000..6b090bc --- /dev/null +++ b/docker-compose.background.yml @@ -0,0 +1,42 @@ +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: + - ./lib/inferno_template/igs:/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 + # volumes: + # - ./lib/inferno_template/igs:/home/igs + # fhir_validator_app: + # image: infernocommunity/fhir-validator-app + # depends_on: + # - validator_service + # environment: + # EXTERNAL_VALIDATOR_URL: http://localhost/validatorapi + # VALIDATOR_BASE_PATH: /validator + nginx: + image: nginx + volumes: + - ./config/nginx.background.conf:/etc/nginx/nginx.conf + ports: + - "80:80" + command: [nginx, "-g", "daemon off;"] + depends_on: + - hl7_validator_service + # - fhir_validator_app + redis: + image: redis + ports: + - "6379:6379" + volumes: + - ./data/redis:/data + command: redis-server --appendonly yes diff --git a/docker-compose.yml b/docker-compose.yml index 8d25543..9944050 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,4 @@ -version: '3' +version: "3" services: inferno: build: @@ -6,33 +6,8 @@ services: volumes: - ./data:/opt/inferno/data depends_on: - - validator_service - validator_service: - image: infernocommunity/fhir-validator-service - # Update this path to match your directory structure - volumes: - - ./lib/inferno_template/igs:/home/igs - fhir_validator_app: - image: infernocommunity/fhir-validator-app - depends_on: - - validator_service - environment: - EXTERNAL_VALIDATOR_URL: http://localhost/validatorapi - VALIDATOR_BASE_PATH: /validator - nginx: - image: nginx - volumes: - - ./config/nginx.conf:/etc/nginx/nginx.conf - ports: - - "80:80" - command: [nginx, '-g', 'daemon off;'] - depends_on: - - fhir_validator_app - redis: - image: redis - volumes: - - ./data/redis:/data - command: redis-server --appendonly yes + # - validator_service + - hl7_validator_service worker: build: context: ./ @@ -41,3 +16,25 @@ 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 + # service: validator_service + # fhir_validator_app: + # extends: + # file: docker-compose.background.yml + # service: fhir_validator_app + nginx: + extends: + file: docker-compose.background.yml + service: nginx + volumes: + - ./config/nginx.conf:/etc/nginx/nginx.conf + redis: + extends: + file: docker-compose.background.yml + service: redis diff --git a/inferno_template.gemspec b/inferno_template.gemspec index 71df468..c4ccbba 100644 --- a/inferno_template.gemspec +++ b/inferno_template.gemspec @@ -1,21 +1,17 @@ Gem::Specification.new do |spec| spec.name = 'inferno_template' spec.version = '0.0.1' - spec.authors = ['Inferno Team'] - spec.email = ['inferno@groups.mitre.org'] + spec.authors = ["Inferno Template"] spec.date = Time.now.utc.strftime('%Y-%m-%d') - spec.summary = 'Inferno Test Kit Template' - spec.description = 'Inferno Test Kit Template' - spec.homepage = 'https://github.com/inferno-framework/inferno-template' + spec.summary = 'Inferno Template Test Kit' + spec.description = 'Inferno template Inferno test kit for FHIR' spec.license = 'Apache-2.0' - spec.add_runtime_dependency 'inferno_core', '~> 0.3.0' + spec.add_runtime_dependency 'inferno_core', '~> 0.4.38' spec.add_development_dependency 'database_cleaner-sequel', '~> 1.8' spec.add_development_dependency 'factory_bot', '~> 6.1' spec.add_development_dependency 'rspec', '~> 3.10' spec.add_development_dependency 'webmock', '~> 3.11' - spec.required_ruby_version = Gem::Requirement.new('>= 2.7.0') - spec.metadata['homepage_uri'] = spec.homepage - spec.metadata['source_code_uri'] = 'https://github.com/inferno-framework/inferno-template' + spec.required_ruby_version = Gem::Requirement.new('>= 3.1.2') spec.files = [ Dir['lib/**/*.rb'], Dir['lib/**/*.json'], diff --git a/lib/inferno_template.rb b/lib/inferno_template.rb index dd1cb5c..70ea1e6 100644 --- a/lib/inferno_template.rb +++ b/lib/inferno_template.rb @@ -2,20 +2,38 @@ module InfernoTemplate class Suite < Inferno::TestSuite - id :test_suite_template - title 'Inferno Test Suite Template' - description 'A basic test suite template for Inferno' + id :inferno_template_test_suite + title 'Inferno Template Test Suite' + description 'Inferno template test suite.' + + # These inputs will be available to all tests in this suite + input :url, + title: 'FHIR Server Base Url' - # This input will be available to all tests in this suite - input :url input :access_token + input :credentials, + title: 'OAuth Credentials', + type: :oauth_credentials, + optional: true + # All FHIR requests in this suite will use this FHIR client fhir_client do url :url + oauth_credentials :credentials bearer_token :access_token end + # All FHIR validation requsets will use this FHIR validator + 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 group do id :capability_statement diff --git a/lib/inferno_template/igs/.keep b/lib/inferno_template/igs/.keep new file mode 100644 index 0000000..e69de29 diff --git a/lib/inferno_template/igs/README.md b/lib/inferno_template/igs/README.md new file mode 100644 index 0000000..7ed8b27 --- /dev/null +++ b/lib/inferno_template/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_template/patient_group.rb b/lib/inferno_template/patient_group.rb index 6a975da..6efbf4d 100644 --- a/lib/inferno_template/patient_group.rb +++ b/lib/inferno_template/patient_group.rb @@ -1,6 +1,6 @@ module InfernoTemplate class PatientGroup < Inferno::TestGroup - title 'Patient Tests' + title 'Patient Tests' description 'Verify that the server makes Patient resources available' id :patient_group @@ -10,7 +10,9 @@ class PatientGroup < Inferno::TestGroup Verify that Patient resources can be read from the server. ) - input :patient_id + input :patient_id, + title: 'Patient ID' + # Named requests can be used by other tests makes_request :patient diff --git a/run.sh b/run.sh index 9430385..fde0a7e 100755 --- a/run.sh +++ b/run.sh @@ -1,3 +1,3 @@ #!/bin/sh -docker-compose build -docker-compose up +docker compose build +docker compose up diff --git a/setup.sh b/setup.sh index 2e99e25..6089f58 100755 --- a/setup.sh +++ b/setup.sh @@ -1,4 +1,4 @@ #!/bin/sh -docker-compose pull -docker-compose build -docker-compose run inferno bundle exec inferno migrate +docker compose pull +docker compose build +docker compose run inferno bundle exec inferno migrate diff --git a/spec/inferno_template/patient_group_spec.rb b/spec/inferno_template/patient_group_spec.rb index 63c694c..a7c8677 100644 --- a/spec/inferno_template/patient_group_spec.rb +++ b/spec/inferno_template/patient_group_spec.rb @@ -1,10 +1,30 @@ RSpec.describe InfernoTemplate::PatientGroup do - let(:suite) { Inferno::Repositories::TestSuites.new.find('test_suite_template') } + let(:suite) { Inferno::Repositories::TestSuites.new.find('inferno_template_test_suite') } let(:group) { suite.groups[1] } let(:session_data_repo) { Inferno::Repositories::SessionData.new } - let(:test_session) { repo_create(:test_session, test_suite_id: 'test_suite_template') } + let(:test_session) { repo_create(:test_session, test_suite_id: 'inferno_template_test_suite') } let(:url) { 'http://example.com/fhir' } - let(:error_outcome) { FHIR::OperationOutcome.new(issue: [{ severity: 'error' }]) } + let(:access_token) { 'SAMPLE_TOKEN' } + 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) @@ -24,7 +44,7 @@ def run(runnable, inputs = {}) stub_request(:get, "#{url}/Patient/#{patient_id}") .to_return(status: 200, body: resource.to_json) - result = run(test, url: url, patient_id: patient_id) + result = run(test, url: url, patient_id: patient_id, access_token: access_token) expect(result.result).to eq('pass') end @@ -34,7 +54,7 @@ def run(runnable, inputs = {}) stub_request(:get, "#{url}/Patient/#{patient_id}") .to_return(status: 201, body: resource.to_json) - result = run(test, url: url, patient_id: patient_id) + result = run(test, url: url, patient_id: patient_id, access_token: access_token) expect(result.result).to eq('fail') expect(result.result_message).to match(/200/) @@ -45,7 +65,7 @@ def run(runnable, inputs = {}) stub_request(:get, "#{url}/Patient/#{patient_id}") .to_return(status: 200, body: resource.to_json) - result = run(test, url: url, patient_id: patient_id) + result = run(test, url: url, patient_id: patient_id, access_token: access_token) expect(result.result).to eq('fail') expect(result.result_message).to match(/Patient/) @@ -56,7 +76,7 @@ def run(runnable, inputs = {}) stub_request(:get, "#{url}/Patient/#{patient_id}") .to_return(status: 200, body: resource.to_json) - result = run(test, url: url, patient_id: patient_id) + result = run(test, url: url, patient_id: patient_id, access_token: access_token) expect(result.result).to eq('fail') expect(result.result_message).to match(/resource with id/) @@ -67,9 +87,9 @@ def run(runnable, inputs = {}) 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 +99,13 @@ def run(runnable, inputs = {}) response_body: resource.to_json ) - result = run(test) + result = run(test, url: url, access_token: access_token) 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 +117,7 @@ def run(runnable, inputs = {}) response_body: resource.to_json ) - result = run(test) + result = run(test, url: url, access_token: access_token) expect(result.result).to eq('fail') end