diff --git a/.bandit.yml b/.bandit.yml
new file mode 100644
index 0000000..2bba86a
--- /dev/null
+++ b/.bandit.yml
@@ -0,0 +1,2 @@
+assert_used:
+ skips: ["*test*.py"]
diff --git a/.checkstyle/checkstyle.xml b/.checkstyle/checkstyle.xml
index ee59903..696e2b3 100644
--- a/.checkstyle/checkstyle.xml
+++ b/.checkstyle/checkstyle.xml
@@ -1,323 +1,388 @@
-
+
-
-
+
+
-
+
-
+
+
+
-
+
-
-
+
+
-
+
-
-
-
+
+
+
-
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+ OBJBLOCK, STATIC_INIT, RECORD_DEF, COMPACT_CTOR_DEF" />
-
-
+
+
-
-
-
+
+
+ COMPACT_CTOR_DEF" />
-
-
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+ SR_ASSIGN, STAR, STAR_ASSIGN, LITERAL_ASSERT, TYPE_EXTENSION_AND" />
+
+
+
+
+
+
+
+
+
+
-
-
+ COMPACT_CTOR_DEF" />
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+ RECORD_COMPONENT_DEF" />
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
+
-
-
+
+
-
+ RECORD_DEF" />
-
-
+
+ TYPE_EXTENSION_AND " />
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 93b568d..c0f51be 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,4 +1,4 @@
-name: CI
+name: ci
on:
push:
@@ -8,29 +8,25 @@ on:
pull_request:
branches: [master]
+permissions: read-all
+
+env:
+ IMAGE_NAME: ghcr.io/${{ github.repository }}
+
jobs:
- lint:
- name: Lint Code Base
- runs-on: ubuntu-20.04
+ trivy:
+ name: trivy scan Code Base
+ runs-on: ubuntu-22.04
+ permissions:
+ security-events: write
steps:
- name: Checkout Code
- uses: actions/checkout@v3
+ uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3
with:
fetch-depth: 0
- - uses: actions/setup-python@v4
- - name: Run pre-commit
- uses: pre-commit/action@v3.0.0
- - name: Lint code base
- uses: github/super-linter@v4
- env:
- VALIDATE_ALL_CODEBASE: false
- VALIDATE_DOCKERFILE: false
- DEFAULT_BRANCH: master
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- FILTER_REGEX_EXCLUDE: "gradlew"
- VALIDATE_JAVA: false
+
- name: Run Trivy vulnerability scanner in repo mode
- uses: aquasecurity/trivy-action@master
+ uses: aquasecurity/trivy-action@9ab158e8597f3b310480b9a69402b419bc03dbd5 # 0.8.0
with:
scan-type: "fs"
ignore-unfixed: true
@@ -38,123 +34,158 @@ jobs:
template: "@/contrib/sarif.tpl"
output: "trivy-results.sarif"
severity: "CRITICAL"
+
- name: Upload Trivy scan results to GitHub Security tab
- uses: github/codeql-action/upload-sarif@v2
+ uses: github/codeql-action/upload-sarif@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
with:
sarif_file: "trivy-results.sarif"
+
build:
- name: Build
- runs-on: ubuntu-20.04
- needs: lint
+ name: build
+ runs-on: ubuntu-22.04
+ outputs:
+ image-tags: ${{ steps.container_meta.outputs.tags }}
+ image-digest: ${{ steps.build.outputs.digest }}
+ image-name: ${{ env.IMAGE_NAME }}
steps:
- name: Checkout code
- uses: actions/checkout@v3
- - name: Docker meta
- id: docker_meta
- uses: docker/metadata-action@v4
- with:
- images: |
- ghcr.io/${{ github.repository }}
- harbor.miracum.org/miracum-etl/fhir-gateway
+ uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3
+
+ - name: Validate Gradle wrapper
+ uses: gradle/wrapper-validation-action@55e685c48d84285a5b0418cd094606e199cca3b6 # v1
+
- name: Set up QEMU
- uses: docker/setup-qemu-action@v2
+ uses: docker/setup-qemu-action@e81a89b1732b9c48d79cd809d8d81d79c4647a18 # v2
+
- name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v2
+ uses: docker/setup-buildx-action@8c0edbc76e98fa90f69d9a2c020dcb50019dc325 # v2
+
+ - name: Container meta
+ id: container_meta
+ uses: docker/metadata-action@57396166ad8aefe6098280995947635806a0e6ea # v4
+ with:
+ images: |
+ ${{ env.IMAGE_NAME }}
+
- name: Login to GitHub Container Registry
- uses: docker/login-action@v2
+ uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # v2
if: ${{ github.event_name != 'pull_request' }}
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- - name: Login to MIRACUM Container Registry
- uses: docker/login-action@v2
- if: ${{ github.event_name != 'pull_request' }}
- with:
- registry: harbor.miracum.org
- username: "robot$miracum-etl+github-actions"
- password: ${{ secrets.MIRACUM_HARBOR_ETL_TOKEN }}
- - name: Cache Docker layers
- uses: actions/cache@v3
- with:
- path: /tmp/.buildx-cache
- key: ${{ runner.os }}-buildx-${{ github.sha }}
- restore-keys: |
- ${{ runner.os }}-buildx-
+
- name: Get platforms to build
id: platforms
run: |
if [ "$IS_PULL_REQUEST" == "true" ]; then
- echo "::set-output name=platforms::linux/amd64"
+ echo "{platforms}={linux/amd64}" >> "$GITHUB_OUTPUT"
else
- echo "::set-output name=platforms::linux/amd64"
+ echo "{platforms}={linux/amd64}" >> "$GITHUB_OUTPUT"
fi
env:
IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }}
+
- name: Build and push
- id: docker_build
- uses: docker/build-push-action@v3
+ id: build
+ uses: docker/build-push-action@c56af957549030174b10d6867f20e78cfd7debc5 # v3
with:
- cache-from: type=local,src=/tmp/.buildx-cache
- cache-to: type=local,dest=/tmp/.buildx-cache
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
push: ${{ github.event_name != 'pull_request' }}
- tags: ${{ steps.docker_meta.outputs.tags }}
- labels: ${{ steps.docker_meta.outputs.labels }}
+ tags: ${{ steps.container_meta.outputs.tags }}
+ labels: ${{ steps.container_meta.outputs.labels }}
load: ${{ github.event_name == 'pull_request' }}
platforms: ${{ steps.platforms.outputs.platforms }}
- - name: List images
- id: list_images
- run: |
- docker image ls
- IMAGES=(${{ steps.docker_meta.outputs.tags }})
- echo "##[set-output name=image_name;]${IMAGES[0]}"
+
+ - uses: KengoTODA/actions-setup-docker-compose@main
+ with:
+ version: '2.14.2' # the full version of `docker-compose` command
+
- name: Run E2E tests
env:
- FHIR_GATEWAY_IMAGE_NAME: "${{ steps.list_images.outputs.image_name }}"
+ FHIR_GATEWAY_IMAGE_NAME: "${{ fromJson(steps.container_meta.outputs.json).tags[0] }}"
run: |
- docker-compose -p "$GITHUB_JOB-e2e" -f deploy/docker-compose.yml -f deploy/docker-compose.gw-deps.yml -f tests/e2e/docker-compose.yml --project-directory=tests/e2e build
- docker-compose -p "$GITHUB_JOB-e2e" -f deploy/docker-compose.yml -f deploy/docker-compose.gw-deps.yml -f tests/e2e/docker-compose.yml --project-directory=tests/e2e run gpasinit
- docker-compose -p "$GITHUB_JOB-e2e" -f deploy/docker-compose.yml -f deploy/docker-compose.gw-deps.yml -f tests/e2e/docker-compose.yml --project-directory=tests/e2e run tester
+ docker-compose -p e2e -f deploy/docker-compose.yml -f deploy/docker-compose.gw-deps.yml -f tests/e2e/docker-compose.yml --project-directory=tests/e2e build
+ docker-compose -p e2e -f deploy/docker-compose.yml -f deploy/docker-compose.gw-deps.yml --project-directory=tests/e2e up -d
+ docker-compose -p e2e -f deploy/docker-compose.yml -f deploy/docker-compose.gw-deps.yml -f tests/e2e/docker-compose.yml --project-directory=tests/e2e run tester
+
- name: Print E2E logs
- if: always()
+ env:
+ FHIR_GATEWAY_IMAGE_NAME: "${{ fromJson(steps.container_meta.outputs.json).tags[0] }}"
+ if: ${{ always() }}
run: |
- docker-compose -p "$GITHUB_JOB-e2e" -f deploy/docker-compose.yml -f deploy/docker-compose.gw-deps.yml -f tests/e2e/docker-compose.yml logs
- docker-compose -p "$GITHUB_JOB-e2e" -f deploy/docker-compose.yml -f deploy/docker-compose.gw-deps.yml -f tests/e2e/docker-compose.yml down --volumes --remove-orphans
+ docker-compose -p e2e -f deploy/docker-compose.yml -f deploy/docker-compose.gw-deps.yml -f tests/e2e/docker-compose.yml logs
+ docker-compose -p e2e -f deploy/docker-compose.yml -f deploy/docker-compose.gw-deps.yml -f tests/e2e/docker-compose.yml down --volumes --remove-orphans
+
+ sign-images:
+ name: sign images
+ runs-on: ubuntu-22.04
+ if: ${{ github.event_name != 'pull_request' }}
+ needs:
+ - build
+ permissions:
+ id-token: write
+ packages: write
+ steps:
+ - name: Login to GitHub Container Registry
+ uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # v2
+ with:
+ registry: ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
- name: Install Cosign
- if: ${{ github.event_name != 'pull_request' }}
- uses: sigstore/cosign-installer@main
- - name: Store signing key in tmp file
- if: ${{ github.event_name != 'pull_request' }}
- env:
- COSIGN_KEY: ${{ secrets.MIRACUM_COSIGN_PRIVATE_KEY }}
- run: echo "$COSIGN_KEY" > /tmp/cosign.key
- - name: Sign images
- if: ${{ github.event_name != 'pull_request' }}
+ uses: sigstore/cosign-installer@9becc617647dfa20ae7b1151972e9b3a2c338a2b # v2.8.1
+
+ - name: Sign image
env:
- COSIGN_PASSWORD: ${{ secrets.MIRACUM_COSIGN_PASSWORD }}
- IMAGES: ${{ steps.docker_meta.outputs.tags }}
+ IMAGES: ${{ needs.build.outputs.image-tags }}
+ DIGEST: ${{ needs.build.outputs.image-digest }}
+ COSIGN_EXPERIMENTAL: "true"
run: |
while read -r image; do
- echo "Signing $image"
- cosign sign --key /tmp/cosign.key "$image"
+ echo "Signing '$image' using keyless approach"
+ cosign sign "$image@$DIGEST"
done <<< "$IMAGES"
+
+ container-provenance:
+ if: ${{ startsWith(github.ref, 'refs/tags/') }}
+ needs:
+ - build
+ permissions:
+ actions: read # for detecting the Github Actions environment.
+ id-token: write # for creating OIDC tokens for signing.
+ packages: write # for uploading attestations.
+ uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.4.0
+ with:
+ image: ${{ needs.build.outputs.image-name }}
+ digest: ${{ needs.build.outputs.image-digest }}
+ registry-username: ${{ github.actor }}
+ # TODO(https://github.com/slsa-framework/slsa-github-generator/issues/492): Remove after GA release.
+ compile-generator: true
+ secrets:
+ registry-password: ${{ secrets.GITHUB_TOKEN }}
+
release:
- needs: build
- name: Release
- runs-on: ubuntu-20.04
+ needs:
+ - build
+ name: release
+ runs-on: ubuntu-22.04
if: ${{ github.event_name != 'pull_request' }}
+ permissions:
+ contents: write
+ pull-requests: write
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3
with:
fetch-depth: 0
- - name: Setup Node.js
- uses: actions/setup-node@v3
+
+ - name: Semantic Release
+ uses: cycjimmy/semantic-release-action@3b88c82b34098e8b51e401c1082c9170b0a3ec3c # tag=v3
with:
- node-version: 14
- - name: Install semantic release
- run: npm install -g semantic-release@17 @semantic-release/github @semantic-release/exec @semantic-release/error @semantic-release/changelog @commitlint/cli @semantic-release/commit-analyzer @semantic-release/release-notes-generator conventional-changelog-conventionalcommits
- - name: Release
+ extra_plugins: |
+ conventional-changelog-conventionalcommits@5.0.0
env:
GITHUB_TOKEN: ${{ secrets.MIRACUM_BOT_SEMANTIC_RELEASE_TOKEN }}
- run: npx semantic-release
diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml
new file mode 100644
index 0000000..aefd434
--- /dev/null
+++ b/.github/workflows/codeql.yaml
@@ -0,0 +1,84 @@
+# For most projects, this workflow file will not need changing; you simply need
+# to commit it to your repository.
+#
+# You may wish to alter this file to override the set of languages analyzed,
+# or to provide custom queries or build logic.
+#
+# ******** NOTE ********
+# We have attempted to detect the languages in your repository. Please check
+# the `language` matrix defined below to confirm you have the correct set of
+# supported CodeQL languages.
+#
+name: "CodeQL"
+
+permissions: read-all
+
+on:
+ push:
+ branches: ["master"]
+ pull_request:
+ # The branches below must be a subset of the branches above
+ branches: ["master"]
+ schedule:
+ - cron: "32 16 * * 3"
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-22.04
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: ["java"]
+ # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
+ # Use only 'java' to analyze code written in Java, Kotlin or both
+ # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
+ # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3
+
+ - name: Set up Java
+ uses: actions/setup-java@1df8dbefe2a8cbc99770194893dd902763bee34b # v3
+ with:
+ java-version: "17"
+ distribution: "adopt"
+ cache: gradle
+
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@896079047b4bb059ba6f150a5d87d47dde99e6e5 # v2
+ with:
+ languages: ${{ matrix.language }}
+ # If you wish to specify custom queries, you can do so here or in a config file.
+ # By default, queries listed here will override any specified in a config file.
+ # Prefix the list here with "+" to use these queries and those in the config file.
+
+ # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
+ # queries: security-extended,security-and-quality
+
+ # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
+ # If this step fails, then you should remove it and run the build manually (see below)
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@896079047b4bb059ba6f150a5d87d47dde99e6e5 # v2
+
+ # âšī¸ Command-line programs to run using the OS shell.
+ # đ See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
+
+ # If the Autobuild fails above, remove it and uncomment the following three lines.
+ # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
+
+ # - run: |
+ # echo "Run, Build Application using script"
+ # ./location_of_script_within_repo/buildscript.sh
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@896079047b4bb059ba6f150a5d87d47dde99e6e5 # v2
+ with:
+ category: "/language:${{matrix.language}}"
diff --git a/.github/workflows/mega-linter.yaml b/.github/workflows/mega-linter.yaml
new file mode 100644
index 0000000..d72f97b
--- /dev/null
+++ b/.github/workflows/mega-linter.yaml
@@ -0,0 +1,59 @@
+---
+# MegaLinter GitHub Action configuration file
+# More info at https://oxsecurity.github.io/megalinter
+name: MegaLinter
+
+on:
+ # Trigger mega-linter at every push. Action will also be visible from Pull Requests to master
+ pull_request:
+ branches: [master]
+
+permissions: read-all
+
+env: # Comment env block if you do not want to apply fixes
+ # Apply linter fixes configuration
+ APPLY_FIXES: none # When active, APPLY_FIXES must also be defined as environment variable (in github/workflows/mega-linter.yml or other CI tool)
+ APPLY_FIXES_EVENT: pull_request # Decide which event triggers application of fixes in a commit or a PR (pull_request, push, all)
+ APPLY_FIXES_MODE: commit # If APPLY_FIXES is used, defines if the fixes are directly committed (commit) or posted in a PR (pull_request)
+
+concurrency:
+ group: ${{ github.ref }}-${{ github.workflow }}
+ cancel-in-progress: true
+
+jobs:
+ build:
+ name: MegaLinter
+ runs-on: ubuntu-22.04
+ permissions:
+ contents: read
+ pull-requests: write
+ steps:
+ # Git Checkout
+ - name: Checkout Code
+ uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3
+ with:
+ token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }}
+ fetch-depth: 0 # If you use VALIDATE_ALL_CODEBASE = true, you can remove this line to improve performances
+
+ # MegaLinter
+ - name: MegaLinter
+ id: ml
+ # You can override MegaLinter flavor used to have faster performances
+ # More info at https://oxsecurity.github.io/megalinter/flavors/
+ uses: oxsecurity/megalinter@d9cc1b4179f513fcb50fa438babf54816f8037d5 # v6.17.0
+ env:
+ # All available variables are described in documentation
+ # https://oxsecurity.github.io/megalinter/configuration/
+ VALIDATE_ALL_CODEBASE: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} # Validates all source when push on main, else just the git diff with main. Set 'true' if you always want to lint all sources
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ # ADD YOUR CUSTOM ENV VARIABLES HERE TO OVERRIDE VALUES OF .mega-linter.yml AT THE ROOT OF YOUR REPOSITORY
+
+ # Upload MegaLinter artifacts
+ - name: Archive production artifacts
+ if: ${{ always() }}
+ uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v3.1.1
+ with:
+ name: MegaLinter reports
+ path: |
+ megalinter-reports
+ mega-linter.log
diff --git a/.github/workflows/scorecard.yaml b/.github/workflows/scorecard.yaml
new file mode 100644
index 0000000..f780f2a
--- /dev/null
+++ b/.github/workflows/scorecard.yaml
@@ -0,0 +1,72 @@
+# This workflow uses actions that are not certified by GitHub. They are provided
+# by a third-party and are governed by separate terms of service, privacy
+# policy, and support documentation.
+
+name: Scorecards supply-chain security
+on:
+ # For Branch-Protection check. Only the default branch is supported. See
+ # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
+ branch_protection_rule:
+ # To guarantee Maintained check is occasionally updated. See
+ # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
+ schedule:
+ - cron: "38 22 * * 0"
+ push:
+ branches: ["master"]
+
+# Declare default permissions as read only.
+permissions: read-all
+
+jobs:
+ analysis:
+ name: Scorecards analysis
+ runs-on: ubuntu-latest
+ permissions:
+ # Needed to upload the results to code-scanning dashboard.
+ security-events: write
+ # Needed to publish results and get a badge (see publish_results below).
+ id-token: write
+ # Uncomment the permissions below if installing in a private repository.
+ # contents: read
+ # actions: read
+
+ steps:
+ - name: "Checkout code"
+ uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0
+ with:
+ persist-credentials: false
+
+ - name: "Run analysis"
+ uses: ossf/scorecard-action@e38b1902ae4f44df626f11ba0734b14fb91f8f86 # v2.1.2
+ with:
+ results_file: results.sarif
+ results_format: sarif
+ # (Optional) Read-only PAT token. Uncomment the `repo_token` line below if:
+ # - you want to enable the Branch-Protection check on a *public* repository, or
+ # - you are installing Scorecards on a *private* repository
+ # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
+ # repo_token: ${{ secrets.SCORECARD_READ_TOKEN }}
+
+ # Public repositories:
+ # - Publish results to OpenSSF REST API for easy access by consumers
+ # - Allows the repository to include the Scorecard badge.
+ # - See https://github.com/ossf/scorecard-action#publishing-results.
+ # For private repositories:
+ # - `publish_results` will always be set to `false`, regardless
+ # of the value entered here.
+ publish_results: true
+
+ # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
+ # format to the repository Actions tab.
+ - name: "Upload artifact"
+ uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v3.1.1
+ with:
+ name: SARIF file
+ path: results.sarif
+ retention-days: 5
+
+ # Upload the results to GitHub's code scanning dashboard.
+ - name: "Upload to code-scanning"
+ uses: github/codeql-action/upload-sarif@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
+ with:
+ sarif_file: results.sarif
diff --git a/.gitignore b/.gitignore
index 53ddcf3..6305bf0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -141,3 +141,38 @@ dmypy.json
.pyre/
# End of https://www.gitignore.io/api/python
+
+# Created by https://www.toptal.com/developers/gitignore/api/java
+# Edit at https://www.toptal.com/developers/gitignore?templates=java
+
+### Java ###
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+replay_pid*
+
+# End of https://www.toptal.com/developers/gitignore/api/java
+
+bin/
+
+megalinter-reports/
diff --git a/.mega-linter.yml b/.mega-linter.yml
new file mode 100644
index 0000000..3a6d831
--- /dev/null
+++ b/.mega-linter.yml
@@ -0,0 +1,30 @@
+# Configuration file for MegaLinter
+# See all available variables at https://megalinter.io/configuration/ and in linters documentation
+
+APPLY_FIXES: none # all, none, or list of linter keys
+# ENABLE: # If you use ENABLE variable, all other languages/formats/tooling-formats will be disabled by default
+# ENABLE_LINTERS: # If you use ENABLE_LINTERS variable, all other linters will be disabled by default
+DISABLE:
+ - COPYPASTE # Uncomment to disable checks of excessive copy-pastes
+ - SPELL # Uncomment to disable checks of spelling mistakes
+SHOW_ELAPSED_TIME: true
+FILEIO_REPORTER: false
+# DISABLE_ERRORS: true # Uncomment if you want MegaLinter to detect errors but not block CI to pass
+
+DISABLE_LINTERS:
+ - JAVA_PMD
+ - MARKDOWN_MARKDOWN_LINK_CHECK
+ - PYTHON_PYRIGHT
+ - PYTHON_PYLINT
+ - REPOSITORY_DEVSKIM
+ - REPOSITORY_DUSTILOCK
+ - SQL_TSQLLINT
+
+GROOVY_NPM_GROOVY_LINT_ARGUMENTS:
+ - "--failon=warning"
+
+REPOSITORY_TRIVY_ARGUMENTS:
+ - "--severity=MEDIUM,HIGH,CRITICAL"
+ - "--ignore-unfixed"
+
+JAVA_CHECKSTYLE_CONFIG_FILE: .checkstyle/checkstyle.xml
diff --git a/.renovaterc.json b/.renovaterc.json
new file mode 100644
index 0000000..9f2ffd5
--- /dev/null
+++ b/.renovaterc.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
+ "extends": ["github>miracum/.github//renovate/default"]
+}
diff --git a/Dockerfile b/Dockerfile
index 66a77a5..9edc281 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,26 +1,28 @@
-FROM gradle:7.5.1-jdk17 AS build
+# syntax=docker/dockerfile:1.4
+FROM docker.io/library/gradle:7.6.0-jdk17@sha256:9073fad2045e28b86d2d1669bc219739a84771635f033aed0fa293835dd5fad0 AS build
WORKDIR /home/gradle/src
ENV GRADLE_USER_HOME /gradle
-COPY build.gradle settings.gradle ./
+COPY build.gradle settings.gradle gradle.properties ./
-# Only download dependencies
-# see https://zwbetz.com/why-is-my-gradle-build-in-docker-so-slow/
-RUN gradle clean build --no-daemon > /dev/null 2>&1 || true
+RUN gradle --no-daemon build || true
COPY --chown=gradle:gradle . .
-RUN gradle build --info && \
- gradle jacocoTestReport && \
- awk -F"," '{ instructions += $4 + $5; covered += $5 } END { print covered, "/", instructions, " instructions covered"; print 100*covered/instructions, "% covered" }' build/jacoco/coverage.csv && \
- java -Djarmode=layertools -jar build/libs/*.jar extract
-FROM gcr.io/distroless/java17-debian11:nonroot
+RUN <
"while true; do
- kafkacat -b kafka1:19092 -K: -t fhir.all -P -l /data/mock-data.ndjson;
- kafkacat -b kafka1:19092 -K: -t fhir.all-2 -P -l /data/mock-data-2.ndjson;
+ kcat -b kafka1:19092 -K: -t fhir.all -P -l /data/mock-data.ndjson;
+ kcat -b kafka1:19092 -K: -t fhir.all-2 -P -l /data/mock-data-2.ndjson;
sleep 10;
done"
volumes:
@@ -17,7 +15,7 @@ services:
- kafka1
kafka1:
- image: docker.vectorized.io/vectorized/redpanda:v22.2.6
+ image: docker.io/vectorized/redpanda:v22.3.9
container_name: kafka1
command:
- redpanda
@@ -39,7 +37,7 @@ services:
- 9644:9644
akhq:
- image: tchiotludo/akhq:0.22.0
+ image: tchiotludo/akhq:0.23.0
environment:
AKHQ_CONFIGURATION: |
akhq:
diff --git a/deploy/docker-compose.exposed.yml b/deploy/docker-compose.exposed.yml
index 50fc7b1..fae3113 100644
--- a/deploy/docker-compose.exposed.yml
+++ b/deploy/docker-compose.exposed.yml
@@ -1,5 +1,3 @@
-version: "3.7"
-
services:
jaeger:
ports:
@@ -10,9 +8,9 @@ services:
ports:
- 127.0.0.1:15432:5432
- gpas:
+ vfps:
ports:
- - 127.0.0.1:18081:8080
+ - "127.0.0.1:8083:8080"
fhir-server:
ports:
diff --git a/deploy/docker-compose.gw-deps.yml b/deploy/docker-compose.gw-deps.yml
index 9d2fe4c..f09561e 100644
--- a/deploy/docker-compose.gw-deps.yml
+++ b/deploy/docker-compose.gw-deps.yml
@@ -1,102 +1,117 @@
-version: "3.9"
-
services:
jaeger:
- image: jaegertracing/all-in-one:1.38
+ image: jaegertracing/all-in-one:1.40
fhir-pseudonymizer:
- image: harbor.miracum.org/miracum-etl/fhir-pseudonymizer:v1.6.0
+ image: ghcr.io/miracum/fhir-pseudonymizer:v2.15.0@sha256:8953eb45d1c66d52631fab51a525b0479df7a7811fa4ac0aef0ef2e6515fb12f
environment:
- JAEGER__HOST: jaeger
- JAEGER__PORT: 6831
- GPAS__URL: ${GPAS_URL:-http://gpas:8080/gpas/gpasService}
+ Tracing__Enabled: "true"
+ Tracing__Jaeger__AgentHost: jaeger
+ Tracing__Jaeger__AgentPort: 6831
+ Vfps__Address: "dns:///vfps:8081"
+ UseSystemTextJsonFhirSerializer: "true"
+ PseudonymizationService: "Vfps"
volumes:
- - ./anonymization.yaml:/etc/anonymization.yaml:ro
+ - ${PWD}/deploy/anonymization.yaml:/etc/anonymization.yaml:ro
depends_on:
- jaeger
- - gpas
+ - vfps
loinc-converter:
- image: harbor.miracum.org/miracum-etl/loinc-conversion:v1.13.3
+ image: harbor.miracum.org/miracum-etl/loinc-conversion:v1.13.4@sha256:3522a3e463239c80a0d4ac7751fe188b160681a7e5dbeea3d998499eb7570125
environment:
JAEGER_AGENT_HOST: jaeger
depends_on:
- jaeger
- fhir-db:
- image: postgres:14.5
+ vfps-db:
+ image: docker.io/library/postgres:15.1@sha256:f4cd32e7a418d9c9ba043e7d561243388202b654c740bcc85ca40b41d9fb4f1e
+ restart: unless-stopped
+ deploy:
+ resources:
+ limits:
+ memory: 1g
+ cpus: "1"
+ reservations:
+ memory: 1g
+ cpus: "1"
+ ipc: private
+ security_opt:
+ - "no-new-privileges:true"
+ privileged: false
environment:
POSTGRES_PASSWORD: postgres
- POSTGRES_DB: fhir
+ POSTGRES_DB: vfps
- gpas:
- image: tmfev/gpas:1.9.1
+ vfps:
+ image: ghcr.io/miracum/vfps:v1.1.3@sha256:a4940766829e5d5f330030e8813049d2f074651876853f672f45de0709e35fbf
+ restart: unless-stopped
+ deploy:
+ resources:
+ limits:
+ memory: 512m
+ cpus: "2"
+ reservations:
+ memory: 512m
+ cpus: "2"
+ ipc: none
+ cap_drop:
+ - ALL
+ read_only: true
+ privileged: false
+ security_opt:
+ - "no-new-privileges:true"
environment:
- JAVA_OPTS: >-
- -Xms512m
- -Xmx1G
- -XX:MetaspaceSize=96M
- -XX:MaxMetaspaceSize=256m
- -Djava.net.preferIPv4Stack=true
- -Djava.awt.headless=true
+ COMPlus_EnableDiagnostics: "0"
+ ForceRunDatabaseMigrations: "true"
+ ConnectionStrings__PostgreSQL: "Host=vfps-db:5432;Database=vfps;Timeout=60;Max Auto Prepare=5;Application Name=vfps;Maximum Pool Size=50;"
+ PGUSER: postgres
+ PGPASSWORD: postgres
+ Tracing__IsEnabled: "true"
+ Tracing__Jaeger__AgentHost: "jaeger"
+ Pseudonymization__Caching__Namespaces__IsEnabled: "true"
+ depends_on:
+ - vfps-db
fhir-server:
- image: docker.io/hapiproject/hapi:v5.6.0-distroless
+ image: docker.io/hapiproject/hapi:v6.2.2@sha256:9c4e8af94d81ac0049dbb589e4cd855bf78c9c13be6f6844e814c63d63545b44
+
+ fhir-db:
+ image: docker.io/library/postgres:15.1@sha256:f4cd32e7a418d9c9ba043e7d561243388202b654c740bcc85ca40b41d9fb4f1e
+ environment:
+ POSTGRES_PASSWORD: postgres
+ POSTGRES_DB: fhir
- gpasinit-patient:
- image: curlimages/curl:7.85.0
+ vfps-init-patient:
+ image: docker.io/curlimages/curl:7.87.0
command: |
-X POST
- -H 'Content-Type:application/xml'
- -d '
-
-
-
-
-
- PATIENT
- org.emau.icmvc.ganimed.ttp.psn.generator.ReedSolomonLagrange
- org.emau.icmvc.ganimed.ttp.psn.alphabets.Symbol31
- PSN_LENGTH=31;PSN_PREFIX=p;INCLUDE_PREFIX_IN_CHECK_DIGIT_CALCULATION=false;PSNS_DELETABLE=true;MAX_DETECTED_ERRORS=2;
- PATIENT Domain
-
-
-
- '
+ -H 'Content-Type: application/json'
+ --fail
--retry-connrefuse
--connect-timeout 10
--max-time 120
--retry 10
--retry-delay 10
- http://gpas:8080/gpas/DomainService
+ -d '{"name": "PATIENT", "pseudonymGenerationMethod": 0, "pseudonymLength": 32, "pseudonymPrefix": "p-"}'
+ http://vfps:8080/v1/namespaces
depends_on:
- - gpas
+ vfps:
+ condition: service_started
- gpasinit-fall:
- image: curlimages/curl:7.85.0
+ vfps-init-fall:
+ image: docker.io/curlimages/curl:7.87.0
command: |
-X POST
- -H 'Content-Type:application/xml'
- -d '
-
-
-
-
-
- FALL
- org.emau.icmvc.ganimed.ttp.psn.generator.ReedSolomonLagrange
- org.emau.icmvc.ganimed.ttp.psn.alphabets.Symbol31
- PSN_LENGTH=31;PSN_PREFIX=f;INCLUDE_PREFIX_IN_CHECK_DIGIT_CALCULATION=false;PSNS_DELETABLE=true;MAX_DETECTED_ERRORS=2;
- FALL Domain
-
-
-
- '
+ -H 'Content-Type: application/json'
+ --fail
--retry-connrefuse
--connect-timeout 10
--max-time 120
--retry 10
--retry-delay 10
- http://gpas:8080/gpas/DomainService
+ -d '{"name": "FALL", "pseudonymGenerationMethod": 0, "pseudonymLength": 32, "pseudonymPrefix": "f-"}'
+ http://vfps:8080/v1/namespaces
depends_on:
- - gpas
+ vfps:
+ condition: service_started
diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml
index 52e9cc0..65a1c0a 100644
--- a/deploy/docker-compose.yml
+++ b/deploy/docker-compose.yml
@@ -1,8 +1,6 @@
-version: "3.9"
-
services:
gateway:
- image: ${FHIR_GATEWAY_IMAGE_NAME:-ghcr.io/miracum/fhir-gateway:v3.10.5}
+ image: ${FHIR_GATEWAY_IMAGE_NAME:-ghcr.io/miracum/fhir-gateway:v3.10.6}
restart: on-failure
environment:
SPRING_DATASOURCE_URL: ${SPRING_DATASOURCE_URL:-jdbc:postgresql://fhir-db:5432/fhir}
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 249e583..943f0cb 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 8fad3f5..2b22d05 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip
+networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index a69d9cb..65dcd68 100644
--- a/gradlew
+++ b/gradlew
@@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
-# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -80,10 +80,10 @@ do
esac
done
-APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
-
-APP_NAME="Gradle"
+# This is normally unused
+# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
@@ -143,12 +143,16 @@ fi
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
diff --git a/gradlew.bat b/gradlew.bat
index 53a6b23..6689b85 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
diff --git a/renovate.json b/renovate.json
deleted file mode 100644
index b627478..0000000
--- a/renovate.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "$schema": "https://docs.renovatebot.com/renovate-schema.json",
- "extends": [
- "github>whitesource/merge-confidence:beta",
- "config:base",
- "group:allNonMajor",
- ":disableDependencyDashboard"
- ]
-}
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
index dae1b46..7f285ce 100644
--- a/src/main/resources/application-dev.yml
+++ b/src/main/resources/application-dev.yml
@@ -7,7 +7,7 @@ services:
loinc:
conversions:
url: "http://localhost:19090/api/v1"
- enabled: true
+ enabled: false
failOnError: false
pseudonymizer:
enabled: true
diff --git a/src/main/resources/static/fhir-metadata.json b/src/main/resources/static/fhir-metadata.json
index d8dfaec..2c9479f 100644
--- a/src/main/resources/static/fhir-metadata.json
+++ b/src/main/resources/static/fhir-metadata.json
@@ -13,10 +13,7 @@
"url": "http://localhost:8080/fhir"
},
"fhirVersion": "4.0.0",
- "format": [
- "application/fhir+xml",
- "application/fhir+json"
- ],
+ "format": ["application/fhir+xml", "application/fhir+json"],
"rest": [
{
"extension": [
@@ -1046,9 +1043,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -1098,9 +1093,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -1150,10 +1143,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "BodyStructure:patient"
- ],
+ "searchInclude": ["*", "BodyStructure:patient"],
"searchParam": [
{
"name": "_language",
@@ -1223,11 +1213,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "Bundle:composition",
- "Bundle:message"
- ],
+ "searchInclude": ["*", "Bundle:composition", "Bundle:message"],
"searchParam": [
{
"name": "_language",
@@ -1732,9 +1718,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -1930,9 +1914,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -2443,10 +2425,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "CodeSystem:supplements"
- ],
+ "searchInclude": ["*", "CodeSystem:supplements"],
"searchParam": [
{
"name": "_language",
@@ -2871,9 +2850,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -4235,10 +4212,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "DeviceDefinition:parent"
- ],
+ "searchInclude": ["*", "DeviceDefinition:parent"],
"searchParam": [
{
"name": "_language",
@@ -4303,11 +4277,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "DeviceMetric:parent",
- "DeviceMetric:source"
- ],
+ "searchInclude": ["*", "DeviceMetric:parent", "DeviceMetric:source"],
"searchParam": [
{
"name": "_language",
@@ -5058,9 +5028,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -5370,10 +5338,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "Endpoint:organization"
- ],
+ "searchInclude": ["*", "Endpoint:organization"],
"searchParam": [
{
"name": "_language",
@@ -5527,10 +5492,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "EnrollmentResponse:request"
- ],
+ "searchInclude": ["*", "EnrollmentResponse:request"],
"searchParam": [
{
"name": "_language",
@@ -6198,9 +6160,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -6650,11 +6610,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "Goal:patient",
- "Goal:subject"
- ],
+ "searchInclude": ["*", "Goal:patient", "Goal:subject"],
"searchParam": [
{
"name": "_language",
@@ -6744,9 +6700,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -6866,11 +6820,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "Group:managing-entity",
- "Group:member"
- ],
+ "searchInclude": ["*", "Group:managing-entity", "Group:member"],
"searchParam": [
{
"name": "_language",
@@ -9637,9 +9587,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -9783,10 +9731,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "MedicinalProductContraindication:subject"
- ],
+ "searchInclude": ["*", "MedicinalProductContraindication:subject"],
"searchParam": [
{
"name": "_language",
@@ -9841,10 +9786,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "MedicinalProductIndication:subject"
- ],
+ "searchInclude": ["*", "MedicinalProductIndication:subject"],
"searchParam": [
{
"name": "_language",
@@ -9899,9 +9841,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -9951,10 +9891,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "MedicinalProductInteraction:subject"
- ],
+ "searchInclude": ["*", "MedicinalProductInteraction:subject"],
"searchParam": [
{
"name": "_language",
@@ -10009,9 +9946,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -10061,10 +9996,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "MedicinalProductPackaged:subject"
- ],
+ "searchInclude": ["*", "MedicinalProductPackaged:subject"],
"searchParam": [
{
"name": "_language",
@@ -10124,9 +10056,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -10191,10 +10121,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "MedicinalProductUndesirableEffect:subject"
- ],
+ "searchInclude": ["*", "MedicinalProductUndesirableEffect:subject"],
"searchParam": [
{
"name": "_language",
@@ -10249,9 +10176,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -10525,10 +10450,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "MolecularSequence:patient"
- ],
+ "searchInclude": ["*", "MolecularSequence:patient"],
"searchParam": [
{
"name": "_language",
@@ -10643,9 +10565,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -11159,9 +11079,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -11376,9 +11294,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -11675,9 +11591,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -12412,9 +12326,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -12919,9 +12831,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -13181,10 +13091,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "RelatedPerson:patient"
- ],
+ "searchInclude": ["*", "RelatedPerson:patient"],
"searchParam": [
{
"name": "_language",
@@ -14095,9 +14002,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -14227,10 +14132,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "Schedule:actor"
- ],
+ "searchInclude": ["*", "Schedule:actor"],
"searchParam": [
{
"name": "_language",
@@ -14630,10 +14532,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "Slot:schedule"
- ],
+ "searchInclude": ["*", "Slot:schedule"],
"searchParam": [
{
"name": "_language",
@@ -14839,9 +14738,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -15090,9 +14987,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -15217,9 +15112,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -15304,10 +15197,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "Substance:substance-reference"
- ],
+ "searchInclude": ["*", "Substance:substance-reference"],
"searchParam": [
{
"name": "_language",
@@ -15397,9 +15287,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -15449,9 +15337,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -15501,9 +15387,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -15553,9 +15437,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -15605,9 +15487,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -15657,9 +15537,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -16039,9 +15917,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -16161,10 +16037,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "TestReport:testscript"
- ],
+ "searchInclude": ["*", "TestReport:testscript"],
"searchParam": [
{
"name": "_language",
@@ -16244,9 +16117,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -16376,9 +16247,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*"
- ],
+ "searchInclude": ["*"],
"searchParam": [
{
"name": "_language",
@@ -16518,10 +16387,7 @@
"conditionalCreate": true,
"conditionalUpdate": true,
"conditionalDelete": "multiple",
- "searchInclude": [
- "*",
- "VerificationResult:target"
- ],
+ "searchInclude": ["*", "VerificationResult:target"],
"searchParam": [
{
"name": "_language",
diff --git a/tests/e2e/Dockerfile b/tests/e2e/Dockerfile
index 24b1c82..102a617 100644
--- a/tests/e2e/Dockerfile
+++ b/tests/e2e/Dockerfile
@@ -1,12 +1,13 @@
-FROM python:3.9-alpine
+FROM docker.io/library/python:3.11-alpine@sha256:af8fef83397b3886ed93d2c81bf3b4e70d39c0789c1c6feb1ecb86ca9bc42a0a
# hadolint ignore=DL3018
RUN apk --no-cache add git
WORKDIR /opt/tests
COPY requirements.txt .
-RUN pip install -r requirements.txt
+RUN pip install --require-hashes --no-cache-dir -r requirements.txt
COPY . .
+USER 65534:65534
ENTRYPOINT ["pytest"]
-CMD [ "test.py" ]
+CMD [ "-p", "no:cacheprovider", "test.py" ]
diff --git a/tests/e2e/data/anonymization.yaml b/tests/e2e/data/anonymization.yaml
deleted file mode 100644
index 90cdb7a..0000000
--- a/tests/e2e/data/anonymization.yaml
+++ /dev/null
@@ -1,49 +0,0 @@
----
-fhirVersion: R4
-fhirPathRules:
- - path: Patient.id
- method: pseudonymize
- domain: TEST
- - path: Encounter.id
- method: pseudonymize
- domain: TEST
- - path: nodesByType('Reference').where(reference.startsWith('Encounter/')).reference
- method: pseudonymize
- domain: TEST
- - path: nodesByType('Reference').where(reference.startsWith('Patient/')).reference
- method: pseudonymize
- domain: TEST
- # Bundle.entry.where(resource.ofType(Patient)).fullUrl is unfortunately not supported by the FhirPath implementation
- - path: Bundle.entry.where(fullUrl.startsWith('Patient/')).fullUrl
- method: pseudonymize
- domain: TEST
- - path: Bundle.entry.request.where(url.startsWith('Patient/')).url
- method: pseudonymize
- domain: TEST
- - path: Bundle.entry.where(fullUrl.startsWith('Encounter/')).fullUrl
- method: pseudonymize
- domain: TEST
- - path: Bundle.entry.request.where(url.startsWith('Encounter/')).url
- method: pseudonymize
- domain: TEST
- - path: nodesByType('Reference').display
- method: redact
- - path: nodesByType('HumanName')
- method: redact
- - path: nodesByType('Identifier').where(type.coding.system='http://terminology.hl7.org/CodeSystem/v2-0203' and type.coding.code='VN').value
- method: pseudonymize
- domain: TEST
- - path: nodesByType('Identifier').where(type.coding.system='http://terminology.hl7.org/CodeSystem/v2-0203' and type.coding.code='MR').value
- method: pseudonymize
- domain: TEST
- - path: nodesByType('Identifier').where(type.coding.system='http://fhir.de/CodeSystem/identifier-type-de-basis' and type.coding.code='GKV' or type.coding.code='PKV')
- method: redact
-parameters:
- dateShiftKey: ""
- dateShiftScope: resource
- cryptoHashKey: miracum
- encryptKey: ""
- enablePartialAgesForRedact: true
- enablePartialDatesForRedact: true
- enablePartialZipCodesForRedact: true
- restrictedZipCodeTabulationAreas: []
diff --git a/tests/e2e/data/bundle.json b/tests/e2e/data/bundle.json
index 0e6d4de..1339a3e 100644
--- a/tests/e2e/data/bundle.json
+++ b/tests/e2e/data/bundle.json
@@ -94,9 +94,7 @@
"name": [
{
"family": "Wisozk",
- "given": [
- "Mariana"
- ]
+ "given": ["Mariana"]
}
],
"gender": "male",
diff --git a/tests/e2e/docker-compose.yml b/tests/e2e/docker-compose.yml
index 9a26987..afca9c3 100644
--- a/tests/e2e/docker-compose.yml
+++ b/tests/e2e/docker-compose.yml
@@ -1,5 +1,3 @@
-version: "3.7"
-
services:
tester:
build: .
@@ -7,35 +5,3 @@ services:
FHIR_SERVER_URL: "http://gateway:8080/fhir"
depends_on:
- gateway
-
- fhir-pseudonymizer:
- volumes:
- - ${PWD}/tests/e2e/data/anonymization.yaml:/etc/anonymization.yaml:ro
-
- gpasinit:
- image: curlimages/curl:7.77.0
- command: -X POST
- -H 'Content-Type:application/xml'
- -d '
-
-
-
-
-
- TEST
- org.emau.icmvc.ganimed.ttp.psn.generator.ReedSolomonLagrange
- org.emau.icmvc.ganimed.ttp.psn.alphabets.Symbol31
- PSN_LENGTH=10;PSN_PREFIX=TEST-ID.;INCLUDE_PREFIX_IN_CHECK_DIGIT_CALCULATION=false;PSNS_DELETABLE=true;MAX_DETECTED_ERRORS=2;
- TEST Domain
-
-
-
- '
- --retry-connrefuse
- --connect-timeout 10
- --max-time 60
- --retry 5
- --retry-delay 10
- http://gpas:8080/gpas/DomainService
- depends_on:
- - gpas
diff --git a/tests/e2e/requirements.in b/tests/e2e/requirements.in
new file mode 100644
index 0000000..5c2fd8a
--- /dev/null
+++ b/tests/e2e/requirements.in
@@ -0,0 +1,3 @@
+fhirclient==4.1.0
+retrying==1.3.3
+pytest==7.2.0
diff --git a/tests/e2e/requirements.txt b/tests/e2e/requirements.txt
index 1ad5c03..259af11 100644
--- a/tests/e2e/requirements.txt
+++ b/tests/e2e/requirements.txt
@@ -1,3 +1,67 @@
-git+http://github.com/smart-on-fhir/client-py@v4.0.0#egg=fhirclient
-pytest==6.2.4
-retrying==1.3.3
+#
+# This file is autogenerated by pip-compile with Python 3.11
+# by the following command:
+#
+# pip-compile --generate-hashes requirements.in
+#
+attrs==22.2.0 \
+ --hash=sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836 \
+ --hash=sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99
+ # via pytest
+certifi==2022.12.7 \
+ --hash=sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3 \
+ --hash=sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18
+ # via requests
+charset-normalizer==2.1.1 \
+ --hash=sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845 \
+ --hash=sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f
+ # via requests
+colorama==0.4.6 \
+ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \
+ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
+ # via pytest
+fhirclient==4.1.0 \
+ --hash=sha256:4f64f7967c9fe5f74cce068f29b0e5e4485848a73ec327765a8f3c188b9948a4 \
+ --hash=sha256:fe9c92b3649a4d2829d91c40cd7765c6f729971d12d1dec39a7ee6e81f83384c
+ # via -r requirements.in
+idna==3.4 \
+ --hash=sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4 \
+ --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2
+ # via requests
+iniconfig==1.1.1 \
+ --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \
+ --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32
+ # via pytest
+isodate==0.6.1 \
+ --hash=sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96 \
+ --hash=sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9
+ # via fhirclient
+packaging==22.0 \
+ --hash=sha256:2198ec20bd4c017b8f9717e00f0c8714076fc2fd93816750ab48e2c41de2cfd3 \
+ --hash=sha256:957e2148ba0e1a3b282772e791ef1d8083648bc131c8ab0c1feba110ce1146c3
+ # via pytest
+pluggy==1.0.0 \
+ --hash=sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159 \
+ --hash=sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3
+ # via pytest
+pytest==7.2.0 \
+ --hash=sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71 \
+ --hash=sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59
+ # via -r requirements.in
+requests==2.28.1 \
+ --hash=sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983 \
+ --hash=sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349
+ # via fhirclient
+retrying==1.3.3 \
+ --hash=sha256:08c039560a6da2fe4f2c426d0766e284d3b736e355f8dd24b37367b0bb41973b
+ # via -r requirements.in
+six==1.16.0 \
+ --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
+ --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
+ # via
+ # isodate
+ # retrying
+urllib3==1.26.13 \
+ --hash=sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc \
+ --hash=sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8
+ # via requests
diff --git a/tests/e2e/test.py b/tests/e2e/test.py
index 654982c..37e190f 100644
--- a/tests/e2e/test.py
+++ b/tests/e2e/test.py
@@ -1,7 +1,8 @@
-import fhirclient.models.bundle as b
import json
import logging
import os
+
+import fhirclient.models.bundle as b
import pytest
import requests
from fhirclient import client
@@ -75,13 +76,13 @@ def test_observation_is_pseudonymized(smart, bundle):
observation_response = bundle_response.entry[0].resource
assert (
- not encounter_id_part
- in observation_response.encounter.processedReferenceIdentifier()
+ encounter_id_part
+ not in observation_response.encounter.processedReferenceIdentifier()
)
assert (
- not subject_id_part
- in observation_response.subject.processedReferenceIdentifier()
+ subject_id_part
+ not in observation_response.subject.processedReferenceIdentifier()
)
@@ -90,7 +91,7 @@ def test_patient_is_pseudonymized(smart, bundle):
response_json = bundle.create(smart.server)
bundle_response = b.Bundle(response_json)
- assert not original_patient_id in bundle_response.entry[1].resource.id
+ assert original_patient_id not in bundle_response.entry[1].resource.id
def test_send_delete_bundle(smart, delete_bundle):