diff --git a/.github/distributed-test/docker-compose.yml b/.github/distributed-test/docker-compose.yml index 7ce32097b..72e2689b8 100644 --- a/.github/distributed-test/docker-compose.yml +++ b/.github/distributed-test/docker-compose.yml @@ -125,6 +125,8 @@ services: DB_RESOURCE_CACHE_SIZE: "100000" DB_RESOURCE_INDEXER_THREADS: "8" ALLOW_MULTIPLE_DELETE: "true" + ENABLE_INTERACTION_DELETE_HISTORY: "true" + ENABLE_OPERATION_PATIENT_PURGE: "true" ports: - "8081:8081" volumes: @@ -156,6 +158,8 @@ services: DB_RESOURCE_CACHE_SIZE: "100000" DB_RESOURCE_INDEXER_THREADS: "8" ALLOW_MULTIPLE_DELETE: "true" + ENABLE_INTERACTION_DELETE_HISTORY: "true" + ENABLE_OPERATION_PATIENT_PURGE: "true" ports: - "8082:8081" volumes: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5206caf2f..b808d6916 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -293,7 +293,7 @@ jobs: uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4 with: path: ~/.m2/repository - key: ${{ runner.os }}-temurin-17-maven-build-${{ hashFiles('**/deps.edn') }} + key: ${{ runner.os }}-temurin-21-maven-build-${{ hashFiles('**/deps.edn') }} - name: Download Job IG Profiles uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4 @@ -575,7 +575,7 @@ jobs: run: docker load --input /tmp/blaze.tar - name: Run Blaze - run: docker run --name blaze -d -e JAVA_TOOL_OPTIONS=-Xmx2g -e ALLOW_MULTIPLE_DELETE=true -p 8080:8080 -p 8081:8081 --read-only --tmpfs /tmp:exec -v blaze-data:/app/data blaze:latest + run: docker run --name blaze -d -e JAVA_TOOL_OPTIONS=-Xmx2g -e ALLOW_MULTIPLE_DELETE=true -e ENABLE_INTERACTION_DELETE_HISTORY=true -e ENABLE_OPERATION_PATIENT_PURGE=true -p 8080:8080 -p 8081:8081 --read-only --tmpfs /tmp:exec -v blaze-data:/app/data blaze:latest if: ${{ matrix.variant == 'standalone' }} - name: Run Kafka, Cassandra and Blaze @@ -1475,7 +1475,7 @@ jobs: uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4 with: path: ~/.m2/repository - key: ${{ runner.os }}-temurin-17-maven-jepsen-${{ hashFiles('modules/jepsen/deps.edn') }} + key: ${{ runner.os }}-temurin-21-maven-jepsen-${{ hashFiles('modules/jepsen/deps.edn') }} - name: APT Update run: sudo apt-get update @@ -1493,7 +1493,7 @@ jobs: run: docker load --input /tmp/blaze.tar - name: Run Blaze - run: docker run --name blaze -d -e JAVA_TOOL_OPTIONS=-Xmx2g -p 8080:8080 --read-only --tmpfs /tmp:exec -v blaze-data:/app/data blaze:latest + run: docker run --name blaze -d -e JAVA_TOOL_OPTIONS=-Xmx2g -e ENABLE_INTERACTION_DELETE_HISTORY=true -p 8080:8080 --read-only --tmpfs /tmp:exec -v blaze-data:/app/data blaze:latest - name: Wait for Blaze run: .github/scripts/wait-for-url.sh http://localhost:8080/health @@ -1867,7 +1867,7 @@ jobs: uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4 with: path: ~/.m2/repository - key: ${{ runner.os }}-temurin-17-maven-jepsen-${{ hashFiles('modules/jepsen/deps.edn') }} + key: ${{ runner.os }}-temurin-21-maven-jepsen-${{ hashFiles('modules/jepsen/deps.edn') }} - name: APT Update run: sudo apt-get update diff --git a/CHANGELOG.md b/CHANGELOG.md index 7da82d3a6..2dfbbcfab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## v0.30.1 + +### Bugfixes + +* Fix Returning Resources with Non-Matching Identifier ([#2111](https://github.com/samply/blaze/issues/2111)) + +### Enhancements (alpha) + +* Implement the delete-history Command ([#1382](https://github.com/samply/blaze/issues/1382)) ([docs](https://github.com/samply/blaze/blob/main/docs/api.md#delete-history)) +* Implement Operation $purge on Patient ([#1298](https://github.com/samply/blaze/issues/1298)) ([docs](https://github.com/samply/blaze/blob/main/docs/api/operation-patient-purge.md)) + +The full changelog can be found [here](https://github.com/samply/blaze/milestone/99?closed=1). + ## v0.30.0 ### Enhancements diff --git a/Dockerfile b/Dockerfile index e2dc3da6d..bb2388af6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ RUN apt-get update && apt-get upgrade -y && \ rm -rf /var/lib/apt/lists/ RUN mkdir -p /app/data && chown 1001:1001 /app/data -COPY target/blaze-0.30.0-standalone.jar /app/ +COPY target/blaze-0.30.1-standalone.jar /app/ WORKDIR /app USER 1001 @@ -20,4 +20,4 @@ ENV RESOURCE_DB_DIR="/app/data/resource" ENV ADMIN_INDEX_DB_DIR="/app/data/admin-index" ENV ADMIN_TRANSACTION_DB_DIR="/app/data/admin-transaction" -CMD ["java", "-jar", "blaze-0.30.0-standalone.jar"] +CMD ["java", "-jar", "blaze-0.30.1-standalone.jar"] diff --git a/README.md b/README.md index ffb1a75ef..c43bda8ee 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ A demo installation can be found [here](https://blaze.life.uni-leipzig.de/fhir) Blaze is widely used in the [Medical Informatics Initiative](https://www.medizininformatik-initiative.de) in Germany and in [Biobanks](https://www.bbmri-eric.eu) across Europe. A 1.0 version is expected in the next months. -Latest release: [v0.30.0][5] +Latest release: [v0.30.1][5] ## Quick Start @@ -76,7 +76,7 @@ Unless required by applicable law or agreed to in writing, software distributed [3]: [4]: -[5]: +[5]: [6]: [7]: [8]: diff --git a/build.clj b/build.clj index c8302071d..b88f3b0e9 100644 --- a/build.clj +++ b/build.clj @@ -5,7 +5,7 @@ [java.time LocalDate])) (def lib 'samply/blaze) -(def version "0.30.0") +(def version "0.30.1") (def class-dir "target/classes") (def basis (b/create-basis {:project "deps.edn"})) (def uber-file (format "target/%s-%s-standalone.jar" (name lib) version)) diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 3ce8ff11b..19e4dd41d 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -27,7 +27,7 @@ export default defineConfig({ nav: [ {text: 'Home', link: '/'}, { - text: "v0.30.0", + text: "v0.30.1", items: [ { text: 'Changelog', diff --git a/docs/api.md b/docs/api.md index 788970851..e3b9c04b4 100644 --- a/docs/api.md +++ b/docs/api.md @@ -52,6 +52,9 @@ By default Blaze enforces referential integrity while deleting resources. So res ### Delete History +> [!CAUTION] +> The delete history interaction is currently **alpha** and has to be enabled explicitly by setting the env var `ENABLE_INTERACTION_DELETE_HISTORY` to true. Please don't use it in production. Please be aware that the database might not be able to migrate to a newer version of Blaze if the operation was used. + > [!CAUTION] > The delete history interaction is trial use in the unreleased next version of FHIR. So it is subject to change. Please use it with care. diff --git a/docs/api/operation-patient-purge.md b/docs/api/operation-patient-purge.md index 2313427af..84b42ff61 100644 --- a/docs/api/operation-patient-purge.md +++ b/docs/api/operation-patient-purge.md @@ -1,7 +1,10 @@ -# Operation Patient Purge +# Operation \$purge on Patient > [!CAUTION] -> The patient $purge operation is trial use in the unreleased next version of FHIR. So it is subject to change. Please use it with care. +> The operation \$purge on patient is currently **alpha** and has to be enabled explicitly by setting the env var `ENABLE_OPERATION_PATIENT_PURGE` to true. Please don't use it in production. Please be aware that the database might not be able to migrate to a newer version of Blaze if the operation was used. + +> [!CAUTION] +> The operation \$purge on patient is trial use in the unreleased next version of FHIR (R6). So it is subject to change. Please use it with care. The patient \$purge operation is used to request the removal of all current and historical versions for all resources in a patient compartment. The return is an OperationOutcome with results and/or details about execution. The `code` of the first issue of the OperationOutcome is either `success` on successful purging of all resources or an error. diff --git a/docs/deployment/environment-variables.md b/docs/deployment/environment-variables.md index 8e0392a9c..4bf3e6ba9 100644 --- a/docs/deployment/environment-variables.md +++ b/docs/deployment/environment-variables.md @@ -86,34 +86,36 @@ More information about distributed deployment are available [here](distributed-b ### Other Environment Variables -| Name | Default | Since | Depr ¹ | Description | -|:----------------------------------------|:---------------------------|:-------|--------|:------------------------------------------------------------------------------------------------------------| -| PROXY_HOST | — | v0.6 | — | REMOVED: use -Dhttp.proxyHost | -| PROXY_PORT | — | v0.6 | — | REMOVED: use -Dhttp.proxyPort | -| PROXY_USER | — | v0.6.1 | — | REMOVED: try [SOCKS Options][1] | -| PROXY_PASSWORD | — | v0.6.1 | — | REMOVED: try [SOCKS Options][1] | -| CONNECTION_TIMEOUT | 5 s | v0.6.3 | — | connection timeout for outbound HTTP requests | -| REQUEST_TIMEOUT | 30 s | v0.6.3 | — | REMOVED | -| TERM_SERVICE_URI | [http://tx.fhir.org/r4][6] | v0.6 | v0.11 | Base URI of the terminology service | -| BASE_URL | `http://localhost:8080` | — | — | The URL under which Blaze is accessible by clients. | -| CONTEXT_PATH | /fhir | v0.11 | — | Context path under which the FHIR RESTful API will be accessible. | -| SERVER_PORT | 8080 | — | — | The port of the main HTTP server | -| METRICS_SERVER_PORT | 8081 | v0.6 | — | The port of the Prometheus metrics server | -| LOG_LEVEL | info | v0.6 | — | one of trace, debug, info, warn or error | -| JAVA_TOOL_OPTIONS | — | — | — | JVM options \(Docker only\) | -| FHIR_OPERATION_EVALUATE_MEASURE_THREADS | number of CPUs | v0.8 | — | The number threads used for $evaluate-measure executions. | -| FHIR_OPERATION_EVALUATE_MEASURE_TIMEOUT | 3600000 (1h) | v0.19 | — | Timeout in milliseconds for synchronous $evaluate-measure executions. | -| OPENID_PROVIDER_URL | — | v0.11 | — | [OpenID Connect][4] provider URL to enable [authentication][5] | -| OPENID_CLIENT_TRUST_STORE | — | v0.26 | — | A PKCS #12 trust store containing CA certificates needed for the [OpenID Connect][4] provider. | -| OPENID_CLIENT_TRUST_STORE_PASS | — | v0.26 | — | The password for the PKCS #12 trust store. | -| ENFORCE_REFERENTIAL_INTEGRITY | true | v0.14 | — | Enforce referential integrity on resource create, update and delete. | -| DB_SYNC_TIMEOUT | 10000 | v0.15 | — | Timeout in milliseconds for all reading FHIR interactions acquiring the newest database state. | -| DB_SEARCH_PARAM_BUNDLE | — | v0.21 | — | Name of a custom search parameter bundle file. | -| ENABLE_ADMIN_API | — | v0.26 | — | Set to `true` if the optional Admin API should be enabled. Needed by the frontend. | -| CQL_EXPR_CACHE_SIZE | — | v0.28 | — | Size of the CQL expression cache in MiB. This cache is part of the JVM heap. Will be disabled if not given. | -| CQL_EXPR_CACHE_REFRESH | PT24H | v0.28 | — | The duration after which a Bloom filter of the CQL expression cache will be refreshed. | -| CQL_EXPR_CACHE_THREADS | 4 | v0.28 | — | The maximum number of parallel Bloom filter calculations for the CQL expression cache. | -| ALLOW_MULTIPLE_DELETE | false | v0.30 | — | Allow deleting multiple resources using [Conditional Delete](../api.md#conditional-delete). | +| Name | Default | Since | Depr ¹ | Description | +|:----------------------------------------|:---------------------------|:--------|--------|:------------------------------------------------------------------------------------------------------------| +| PROXY_HOST | — | v0.6 | — | REMOVED: use -Dhttp.proxyHost | +| PROXY_PORT | — | v0.6 | — | REMOVED: use -Dhttp.proxyPort | +| PROXY_USER | — | v0.6.1 | — | REMOVED: try [SOCKS Options][1] | +| PROXY_PASSWORD | — | v0.6.1 | — | REMOVED: try [SOCKS Options][1] | +| CONNECTION_TIMEOUT | 5 s | v0.6.3 | — | connection timeout for outbound HTTP requests | +| REQUEST_TIMEOUT | 30 s | v0.6.3 | — | REMOVED | +| TERM_SERVICE_URI | [http://tx.fhir.org/r4][6] | v0.6 | v0.11 | Base URI of the terminology service | +| BASE_URL | `http://localhost:8080` | — | — | The URL under which Blaze is accessible by clients. | +| CONTEXT_PATH | /fhir | v0.11 | — | Context path under which the FHIR RESTful API will be accessible. | +| SERVER_PORT | 8080 | — | — | The port of the main HTTP server | +| METRICS_SERVER_PORT | 8081 | v0.6 | — | The port of the Prometheus metrics server | +| LOG_LEVEL | info | v0.6 | — | one of trace, debug, info, warn or error | +| JAVA_TOOL_OPTIONS | — | — | — | JVM options \(Docker only\) | +| FHIR_OPERATION_EVALUATE_MEASURE_THREADS | number of CPUs | v0.8 | — | The number threads used for $evaluate-measure executions. | +| FHIR_OPERATION_EVALUATE_MEASURE_TIMEOUT | 3600000 (1h) | v0.19 | — | Timeout in milliseconds for synchronous $evaluate-measure executions. | +| OPENID_PROVIDER_URL | — | v0.11 | — | [OpenID Connect][4] provider URL to enable [authentication][5] | +| OPENID_CLIENT_TRUST_STORE | — | v0.26 | — | A PKCS #12 trust store containing CA certificates needed for the [OpenID Connect][4] provider. | +| OPENID_CLIENT_TRUST_STORE_PASS | — | v0.26 | — | The password for the PKCS #12 trust store. | +| ENFORCE_REFERENTIAL_INTEGRITY | true | v0.14 | — | Enforce referential integrity on resource create, update and delete. | +| DB_SYNC_TIMEOUT | 10000 | v0.15 | — | Timeout in milliseconds for all reading FHIR interactions acquiring the newest database state. | +| DB_SEARCH_PARAM_BUNDLE | — | v0.21 | — | Name of a custom search parameter bundle file. | +| ENABLE_ADMIN_API | — | v0.26 | — | Set to `true` if the optional Admin API should be enabled. Needed by the frontend. | +| CQL_EXPR_CACHE_SIZE | — | v0.28 | — | Size of the CQL expression cache in MiB. This cache is part of the JVM heap. Will be disabled if not given. | +| CQL_EXPR_CACHE_REFRESH | PT24H | v0.28 | — | The duration after which a Bloom filter of the CQL expression cache will be refreshed. | +| CQL_EXPR_CACHE_THREADS | 4 | v0.28 | — | The maximum number of parallel Bloom filter calculations for the CQL expression cache. | +| ALLOW_MULTIPLE_DELETE | false | v0.30 | — | Allow deleting multiple resources using [Conditional Delete](../api.md#conditional-delete). | +| ENABLE_INTERACTION_DELETE_HISTORY | - | v0.30.1 | — | Enable the [Delete History](../api.md#delete-history) interaction. | +| ENABLE_OPERATION_PATIENT_PURGE | - | v0.30.1 | — | Enable the [Operation \$purge on Patient](../api/operation-patient-purge.md). | ¹ Deprecated diff --git a/docs/deployment/manual-deployment.md b/docs/deployment/manual-deployment.md index bea01126c..c4281bdcd 100644 --- a/docs/deployment/manual-deployment.md +++ b/docs/deployment/manual-deployment.md @@ -2,12 +2,12 @@ The installation works under Windows, Linux and macOS. The only dependency is an installed OpenJDK 11 or 17 with 17 recommended. Blaze is tested with [Eclipse Temurin][1]. -Blaze runs on the JVM and comes as single JAR file. Download the most recent version [here](https://github.com/samply/blaze/releases/tag/v0.30.0). Look for `blaze-0.30.0-standalone.jar`. +Blaze runs on the JVM and comes as single JAR file. Download the most recent version [here](https://github.com/samply/blaze/releases/tag/v0.30.1). Look for `blaze-0.30.1-standalone.jar`. After the download, you can start blaze with the following command (Linux, macOS): ```sh -java -jar blaze-0.30.0-standalone.jar +java -jar blaze-0.30.1-standalone.jar ``` Blaze will run with an in-memory, volatile database for testing and demo purposes. @@ -17,14 +17,14 @@ Blaze can be run with durable storage by setting the environment variables `STOR Under Linux/macOS: ```sh -STORAGE=standalone java -jar blaze-0.30.0-standalone.jar +STORAGE=standalone java -jar blaze-0.30.1-standalone.jar ``` Under Windows, you need to set the Environment variables in the PowerShell before starting Blaze: ```powershell $Env:STORAGE="standalone" -java -jar blaze-0.30.0-standalone.jar +java -jar blaze-0.30.1-standalone.jar ``` This will create three directories called `index`, `transaction` and `resource` inside the current working directory, one for each database part used. @@ -42,7 +42,7 @@ The output should look like this: 2021-06-27T11:02:37.834Z ee086ef908c1 main INFO [blaze.core:64] - JVM version: 16.0.2 2021-06-27T11:02:37.834Z ee086ef908c1 main INFO [blaze.core:65] - Maximum available memory: 1738 MiB 2021-06-27T11:02:37.835Z ee086ef908c1 main INFO [blaze.core:66] - Number of available processors: 8 -2021-06-27T11:02:37.836Z ee086ef908c1 main INFO [blaze.core:67] - Successfully started Blaze version 0.30.0 in 8.2 seconds +2021-06-27T11:02:37.836Z ee086ef908c1 main INFO [blaze.core:67] - Successfully started Blaze version 0.30.1 in 8.2 seconds ``` In order to test connectivity, query the health endpoint: @@ -62,7 +62,7 @@ that should return: ```json { "name": "Blaze", - "version": "0.30.0" + "version": "0.30.1" } ``` diff --git a/docs/deployment/standalone-backend.md b/docs/deployment/standalone-backend.md index 152dab4b7..dd0a67008 100644 --- a/docs/deployment/standalone-backend.md +++ b/docs/deployment/standalone-backend.md @@ -27,7 +27,7 @@ Blaze should log something like this: 2023-06-09T08:30:30.126Z b45689460ff3 main INFO [blaze.core:67] - JVM version: 17.0.7 2023-06-09T08:30:30.126Z b45689460ff3 main INFO [blaze.core:68] - Maximum available memory: 1738 MiB 2023-06-09T08:30:30.126Z b45689460ff3 main INFO [blaze.core:69] - Number of available processors: 2 -2023-06-09T08:30:30.126Z b45689460ff3 main INFO [blaze.core:70] - Successfully started 🔥 Blaze version 0.30.0 in 9.0 seconds +2023-06-09T08:30:30.126Z b45689460ff3 main INFO [blaze.core:70] - Successfully started 🔥 Blaze version 0.30.1 in 9.0 seconds ``` In order to test connectivity, query the health endpoint: @@ -47,7 +47,7 @@ that should return: ```json { "name": "Blaze", - "version": "0.30.0" + "version": "0.30.1" } ``` diff --git a/modules/frontend/package-lock.json b/modules/frontend/package-lock.json index e6d6e9825..8563e266d 100644 --- a/modules/frontend/package-lock.json +++ b/modules/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "blaze-frontend", - "version": "0.30.0", + "version": "0.30.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "blaze-frontend", - "version": "0.30.0", + "version": "0.30.1", "dependencies": { "@auth/sveltekit": "^1.0.0", "@fontsource-variable/inter": "^5.0.8", diff --git a/modules/frontend/package.json b/modules/frontend/package.json index ed83c9e5e..48fbf732e 100644 --- a/modules/frontend/package.json +++ b/modules/frontend/package.json @@ -1,6 +1,6 @@ { "name": "blaze-frontend", - "version": "0.30.0", + "version": "0.30.1", "private": true, "scripts": { "dev": "vite dev", diff --git a/modules/rest-api/src/blaze/rest_api.clj b/modules/rest-api/src/blaze/rest_api.clj index b3a7b6ea6..3f5d9f15b 100644 --- a/modules/rest-api/src/blaze/rest_api.clj +++ b/modules/rest-api/src/blaze/rest_api.clj @@ -116,7 +116,12 @@ (defmethod ig/init-key :blaze.rest-api/resource-patterns [_ patterns] - patterns) + (into + [] + (map + (fn [[type interactions]] + #:blaze.rest-api.resource-pattern{:type type :interactions interactions})) + patterns)) (defmethod ig/init-key :blaze.rest-api/operations [_ operations] diff --git a/modules/rest-api/test/blaze/rest_api_test.clj b/modules/rest-api/test/blaze/rest_api_test.clj index bea4a7c6d..9fc6cc521 100644 --- a/modules/rest-api/test/blaze/rest_api_test.clj +++ b/modules/rest-api/test/blaze/rest_api_test.clj @@ -88,8 +88,8 @@ (is (s/valid? :blaze.metrics/collector collector)))) (deftest resource-patterns-init-test - (with-system [{::rest-api/keys [resource-patterns]} {::rest-api/resource-patterns ::patterns}] - (is (= ::patterns resource-patterns)))) + (with-system [{::rest-api/keys [resource-patterns]} {::rest-api/resource-patterns {:default ::interactions}}] + (is (= [#:blaze.rest-api.resource-pattern{:type :default :interactions ::interactions}] resource-patterns)))) (deftest operations-init-test (with-system [{::rest-api/keys [operations]} {::rest-api/operations ::operations}] @@ -116,22 +116,21 @@ :page-id-cipher (ig/ref :blaze.test/page-id-cipher) :search-system-handler success-handler :transaction-handler success-handler - :resource-patterns - [#:blaze.rest-api.resource-pattern - {:type :default - :interactions - {:read - #:blaze.rest-api.interaction - {:handler success-handler} - :delete - #:blaze.rest-api.interaction - {:handler success-handler} - :conditional-delete-type - #:blaze.rest-api.interaction - {:handler success-handler} - :search-type - #:blaze.rest-api.interaction - {:handler success-handler}}}]} + :resource-patterns (ig/ref ::rest-api/resource-patterns)} + ::rest-api/resource-patterns + {:default + {:read + #:blaze.rest-api.interaction + {:handler success-handler} + :delete + #:blaze.rest-api.interaction + {:handler success-handler} + :conditional-delete-type + #:blaze.rest-api.interaction + {:handler success-handler} + :search-type + #:blaze.rest-api.interaction + {:handler success-handler}}} :blaze/job-scheduler {:node (ig/ref :blaze.db/node) :clock (ig/ref :blaze.test/fixed-clock) diff --git a/resources/blaze.edn b/resources/blaze.edn index 4f28d8b3f..9c6d97f0e 100644 --- a/resources/blaze.edn +++ b/resources/blaze.edn @@ -52,39 +52,34 @@ ;; all resource types. ;; :blaze.rest-api/resource-patterns - [#:blaze.rest-api.resource-pattern - {:type :default - :interactions - {:read - #:blaze.rest-api.interaction - {:handler #blaze/ref :blaze.interaction/read} - :vread - #:blaze.rest-api.interaction - {:handler #blaze/ref :blaze.interaction/vread} - :update - #:blaze.rest-api.interaction - {:handler #blaze/ref :blaze.interaction/update} - :delete - #:blaze.rest-api.interaction - {:handler #blaze/ref :blaze.interaction/delete} - :delete-history - #:blaze.rest-api.interaction - {:handler #blaze/ref :blaze.interaction/delete-history} - :conditional-delete-type - #:blaze.rest-api.interaction - {:handler #blaze/ref :blaze.interaction/conditional-delete-type} - :history-instance - #:blaze.rest-api.interaction - {:handler #blaze/ref :blaze.interaction.history/instance} - :history-type - #:blaze.rest-api.interaction - {:handler #blaze/ref :blaze.interaction.history/type} - :create - #:blaze.rest-api.interaction - {:handler #blaze/ref :blaze.interaction.main/create} - :search-type - #:blaze.rest-api.interaction - {:handler #blaze/ref :blaze.interaction/search-type}}}] + {:default + {:read + #:blaze.rest-api.interaction + {:handler #blaze/ref :blaze.interaction/read} + :vread + #:blaze.rest-api.interaction + {:handler #blaze/ref :blaze.interaction/vread} + :update + #:blaze.rest-api.interaction + {:handler #blaze/ref :blaze.interaction/update} + :delete + #:blaze.rest-api.interaction + {:handler #blaze/ref :blaze.interaction/delete} + :conditional-delete-type + #:blaze.rest-api.interaction + {:handler #blaze/ref :blaze.interaction/conditional-delete-type} + :history-instance + #:blaze.rest-api.interaction + {:handler #blaze/ref :blaze.interaction.history/instance} + :history-type + #:blaze.rest-api.interaction + {:handler #blaze/ref :blaze.interaction.history/type} + :create + #:blaze.rest-api.interaction + {:handler #blaze/ref :blaze.interaction.main/create} + :search-type + #:blaze.rest-api.interaction + {:handler #blaze/ref :blaze.interaction/search-type}}} :blaze.rest-api/operations [#:blaze.rest-api.operation @@ -109,13 +104,6 @@ :instance-handler #blaze/ref :blaze.operation.patient/everything :instance-page-handler #blaze/ref :blaze.operation.patient/everything :documentation "Returns all resources from the patient compartment of one concrete patient including the patient. Has a fix limit of 10,000 resources if paging isn't used. Paging is supported when the _count parameter is used. No other params are supported."} - #:blaze.rest-api.operation - {:code "purge" - :def-uri "http://hl7.org/fhir/OperationDefinition/Patient-purge" - :affects-state true - :resource-types ["Patient"] - :instance-handler #blaze/ref :blaze.operation.patient/purge - :documentation "This operation is used to request the removal of all current and historical versions for all resources in a patient compartment or from a Group of patient compartments. The return is an OperationOutcome with results and/or details about execution."} #:blaze.rest-api.operation {:code "totals" :def-uri "https://samply.github.io/blaze/fhir/OperationDefinition/totals" @@ -269,12 +257,6 @@ :rng-fn #blaze/ref :blaze/rng-fn :page-id-cipher #blaze/ref :blaze/page-id-cipher} - ;; - ;; FHIR Operation Patient Purge - ;; - :blaze.operation.patient/purge - {:node #blaze/ref :blaze.db.main/node} - ;; ;; FHIR Operation Totals ;; @@ -1339,4 +1321,33 @@ {"cql-expr-cache" #blaze/ref :blaze.elm.expression/cache}} :blaze/admin-api - {:blaze.elm.expression/cache #blaze/ref :blaze.elm.expression/cache}}}]} + {:blaze.elm.expression/cache #blaze/ref :blaze.elm.expression/cache}}} + + {:key :delete-history + :name "Interaction delete-history" + :toggle "ENABLE_INTERACTION_DELETE_HISTORY" + :config + {:blaze.rest-api/resource-patterns + {:default + {:delete-history + #:blaze.rest-api.interaction + {:handler #blaze/ref :blaze.interaction/delete-history}}} + + :blaze.interaction/delete-history + {:node #blaze/ref :blaze.db.main/node}}} + + {:key :patient-purge + :name "Operation $purge on Patient" + :toggle "ENABLE_OPERATION_PATIENT_PURGE" + :config + {:blaze.rest-api/operations + [#:blaze.rest-api.operation + {:code "purge" + :def-uri "http://hl7.org/fhir/OperationDefinition/Patient-purge" + :affects-state true + :resource-types ["Patient"] + :instance-handler #blaze/ref :blaze.operation.patient/purge + :documentation "This operation is used to request the removal of all current and historical versions for all resources in a patient compartment or from a Group of patient compartments. The return is an OperationOutcome with results and/or details about execution."}] + + :blaze.operation.patient/purge + {:node #blaze/ref :blaze.db.main/node}}}]} diff --git a/src/blaze/system.clj b/src/blaze/system.clj index 490d90a11..5420f0f7a 100644 --- a/src/blaze/system.clj +++ b/src/blaze/system.clj @@ -175,7 +175,7 @@ {:key (clojure.core/name key) :name name :toggle toggle :enabled enabled?})) -(defn- merge-features +(defn merge-features "Merges feature config portions of enabled features into `base-config`." {:arglists '([blaze-edn env])} [{:keys [base-config features]} env] @@ -185,7 +185,12 @@ res (conj-feature res feature enabled?)] (log/info "Feature" name (if enabled? "enabled" "disabled")) (if enabled? - (merge-with (partial merge-with merge) res config) + (merge-with + (fn [v1 v2] + (cond + (and (vector? v1) (vector? v2)) (into v1 v2) + :else (merge-with merge v1 v2))) + res config) res))) base-config features)) diff --git a/test/blaze/system_test.clj b/test/blaze/system_test.clj index 8bfafd958..6696ea977 100644 --- a/test/blaze/system_test.clj +++ b/test/blaze/system_test.clj @@ -9,6 +9,7 @@ [blaze.interaction.delete-history] [blaze.interaction.history.type] [blaze.interaction.read] + [blaze.interaction.search-compartment] [blaze.interaction.search-system] [blaze.interaction.search-type] [blaze.interaction.transaction] @@ -99,6 +100,22 @@ :value "default" :default-value "default"}]}}))) +(deftest merge-features-test + (testing "vector" + (given (system/merge-features + {:base-config {:foo [:a]} + :features [{:key :bar :name "bar" :toggle "T" :config {:foo [:b]}}]} + {"T" "true"}) + :foo := [:a :b])) + + (testing "nested map" + (given (system/merge-features + {:base-config {:foo {:default {:read {}}}} + :features [{:key :bar :name "bar" :toggle "T" :config {:foo {:default {:delete-history {}}}}}]} + {"T" "true"}) + :foo := {:default {:read {} + :delete-history {}}}))) + (def config (assoc mem-node-config @@ -116,6 +133,10 @@ :async-status-cancel-handler (ig/ref ::rest-api/async-status-cancel-handler) :capabilities-handler (ig/ref ::rest-api/capabilities-handler) :resource-patterns (ig/ref ::rest-api/resource-patterns) + :compartments + [#:blaze.rest-api.compartment + {:code "Patient" + :search-handler (ig/ref :blaze.interaction/search-compartment)}] :job-scheduler (ig/ref :blaze/job-scheduler) :clock (ig/ref :blaze.test/fixed-clock) :rng-fn (ig/ref :blaze.test/fixed-rng-fn)} @@ -142,6 +163,11 @@ :page-store (ig/ref ::page-store) :page-id-cipher (ig/ref :blaze.test/page-id-cipher)} :blaze.interaction/search-type + {:clock (ig/ref :blaze.test/fixed-clock) + :rng-fn (ig/ref :blaze.test/fixed-rng-fn) + :page-store (ig/ref ::page-store) + :page-id-cipher (ig/ref :blaze.test/page-id-cipher)} + :blaze.interaction/search-compartment {:clock (ig/ref :blaze.test/fixed-clock) :rng-fn (ig/ref :blaze.test/fixed-rng-fn) :page-store (ig/ref ::page-store) @@ -171,30 +197,28 @@ :clock (ig/ref :blaze.test/fixed-clock) :rng-fn (ig/ref :blaze.test/fixed-rng-fn)} ::rest-api/resource-patterns - [#:blaze.rest-api.resource-pattern - {:type :default - :interactions - {:read - #:blaze.rest-api.interaction - {:handler (ig/ref :blaze.interaction/read)} - :vread - #:blaze.rest-api.interaction - {:handler (ig/ref :blaze.interaction/vread)} - :delete - #:blaze.rest-api.interaction - {:handler (ig/ref :blaze.interaction/delete)} - :delete-history - #:blaze.rest-api.interaction - {:handler (ig/ref :blaze.interaction/delete-history)} - :conditional-delete-type - #:blaze.rest-api.interaction - {:handler (ig/ref :blaze.interaction/conditional-delete-type)} - :search-type - #:blaze.rest-api.interaction - {:handler (ig/ref :blaze.interaction/search-type)} - :history-type - #:blaze.rest-api.interaction - {:handler (ig/ref :blaze.interaction.history/type)}}}] + {:default + {:read + #:blaze.rest-api.interaction + {:handler (ig/ref :blaze.interaction/read)} + :vread + #:blaze.rest-api.interaction + {:handler (ig/ref :blaze.interaction/vread)} + :delete + #:blaze.rest-api.interaction + {:handler (ig/ref :blaze.interaction/delete)} + :delete-history + #:blaze.rest-api.interaction + {:handler (ig/ref :blaze.interaction/delete-history)} + :conditional-delete-type + #:blaze.rest-api.interaction + {:handler (ig/ref :blaze.interaction/conditional-delete-type)} + :search-type + #:blaze.rest-api.interaction + {:handler (ig/ref :blaze.interaction/search-type)} + :history-type + #:blaze.rest-api.interaction + {:handler (ig/ref :blaze.interaction.history/type)}}} :blaze.test/executor {} :blaze.test/fixed-clock {} :blaze.test/fixed-rng-fn {} @@ -473,6 +497,14 @@ [:body fhir-spec/parse-json :resourceType] := "OperationOutcome")))))) +(deftest search-compartment-test + (with-system-data [{:blaze/keys [rest-api]} config] + [[[:put {:fhir/type :fhir/Patient :id "0"}]]] + + (given (call rest-api {:request-method :get :uri "/Patient/0/Observation"}) + :status := 200 + [:body fhir-spec/parse-json :resourceType] := "Bundle"))) + (deftest history-type-test (with-system [{:blaze/keys [rest-api]} config] (given (call rest-api {:request-method :get :uri "/Patient/_history"})