diff --git a/CHANGELOG.md b/CHANGELOG.md index 516e41b59..d0a71bba1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## v0.17.3 + +### Bugfixes + +* Fix Content Negotiation ([#710](https://github.com/samply/blaze/pull/710)) + +The full changelog can be found [here](https://github.com/samply/blaze/milestone/41?closed=1). + ## v0.17.2 ### Bugfixes diff --git a/README.md b/README.md index 1e500db14..bd8130a0f 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The goal of this project is to provide a FHIR® Store with an internal CQL Evalu Blaze passes all [Touchstone FHIR 4.0.1 Basic Tests][12] and almost all [CQL Tests][3]. Please refer to the [Conformance](docs/conformance.md) section and report any issues you encounter during evaluation. -Latest release: [v0.17.2][5] +Latest release: [v0.17.3][5] ## Quick Start @@ -72,7 +72,7 @@ Unless required by applicable law or agreed to in writing, software distributed [3]: [4]: -[5]: +[5]: [6]: [7]: [8]: diff --git a/docs/deployment/docker-deployment.md b/docs/deployment/docker-deployment.md index 0fc663a95..58b41dc53 100644 --- a/docs/deployment/docker-deployment.md +++ b/docs/deployment/docker-deployment.md @@ -27,7 +27,7 @@ Blaze should log something 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.17.2 in 8.2 seconds +2021-06-27T11:02:37.836Z ee086ef908c1 main INFO [blaze.core:67] - Successfully started Blaze version 0.17.3 in 8.2 seconds ``` In order to test connectivity, query the health endpoint: @@ -47,7 +47,7 @@ that should return: ```json { "name": "Blaze", - "version": "0.17.2" + "version": "0.17.3" } ``` diff --git a/docs/deployment/manual-deployment.md b/docs/deployment/manual-deployment.md index 49905b770..d0cfe6e24 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. Blaze is tested with [AdoptOpenJDK][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.17.2). Look for `blaze-0.17.2-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.17.3). Look for `blaze-0.17.3-standalone.jar`. After the download, you can start blaze with the following command (Linux, macOS): ```sh -java -jar blaze-0.17.2-standalone.jar -m blaze.core +java -jar blaze-0.17.3-standalone.jar -m blaze.core ``` 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.17.2-standalone.jar -m blaze.core +STORAGE=standalone java -jar blaze-0.17.3-standalone.jar -m blaze.core ``` Under Windows, you need to set the Environment variables in the PowerShell before starting Blaze: ```powershell $Env:STORAGE="standalone" -java -jar blaze-0.17.2-standalone.jar -m blaze.core +java -jar blaze-0.17.3-standalone.jar -m blaze.core ``` 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.17.2 in 8.2 seconds +2021-06-27T11:02:37.836Z ee086ef908c1 main INFO [blaze.core:67] - Successfully started Blaze version 0.17.3 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.17.2" + "version": "0.17.3" } ``` diff --git a/modules/rest-api/src/blaze/rest_api/capabilities.clj b/modules/rest-api/src/blaze/rest_api/capabilities.clj index c5d125e28..dc4ca2347 100644 --- a/modules/rest-api/src/blaze/rest_api/capabilities.clj +++ b/modules/rest-api/src/blaze/rest_api/capabilities.clj @@ -117,7 +117,7 @@ :copyright #fhir/markdown"Copyright 2019 - 2022 The Samply Community\n\nLicensed 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\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless 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." :kind #fhir/code"instance" - :date #fhir/dateTime"2022-05-07" + :date #fhir/dateTime"2022-05-10" :software {:name "Blaze" :version version} diff --git a/modules/rest-api/src/blaze/rest_api/middleware/output.clj b/modules/rest-api/src/blaze/rest_api/middleware/output.clj index f8ad56654..b131777be 100644 --- a/modules/rest-api/src/blaze/rest_api/middleware/output.clj +++ b/modules/rest-api/src/blaze/rest_api/middleware/output.clj @@ -4,7 +4,6 @@ [blaze.fhir.spec :as fhir-spec] [clojure.data.xml :as xml] [clojure.java.io :as io] - [clojure.string :as str] [muuntaja.parse :as parse] [prometheus.alpha :as prom] [ring.util.response :as ring] @@ -42,38 +41,48 @@ (generate-xml* body))) -(defn- encode-response-json [response] +(defn- encode-response-json [response content-type] (-> (update response :body generate-json) - (ring/content-type "application/fhir+json;charset=utf-8"))) + (ring/content-type content-type))) -(defn- encode-response-xml [response] +(defn- encode-response-xml [response content-type] (-> (update response :body generate-xml) - (ring/content-type "application/fhir+xml;charset=utf-8"))) - - -(defn- json-format? [format] - (or (str/includes? format "json") (#{"*/*" "application/*" "text/*"} format))) + (ring/content-type content-type))) (defn- format-key [format] - (cond - (json-format? format) :json - (str/includes? format "xml") :xml)) + (condp = format + "application/fhir+json" :fhir+json + "application/fhir+xml" :fhir+xml + "application/json" :json + "application/xml" :xml + "text/json" :text-json + "text/xml" :text-xml + "*/*" :fhir+json + "application/*" :fhir+json + "text/*" :text-json + "json" :fhir+json + "xml" :fhir+xml + nil)) (defn- request-format [{{:strs [accept]} :headers {format "_format"} :query-params}] (or (some-> format format-key) - (if-let [first-accept (first (parse-accept accept))] - (format-key first-accept) - :json))) + (if-let [accept (parse-accept accept)] + (some format-key accept) + :fhir+json))) (defn- encode-response [opts request response] (case (request-format request) - :json (encode-response-json response) - :xml (encode-response-xml response) + :fhir+json (encode-response-json response "application/fhir+json;charset=utf-8") + :fhir+xml (encode-response-xml response "application/fhir+xml;charset=utf-8") + :json (encode-response-json response "application/json;charset=utf-8") + :xml (encode-response-xml response "application/xml;charset=utf-8") + :text-json (encode-response-json response "text/json;charset=utf-8") + :text-xml (encode-response-xml response "text/xml;charset=utf-8") (when (:accept-all? opts) (dissoc response :body)))) diff --git a/modules/rest-api/test/blaze/rest_api/middleware/output_test.clj b/modules/rest-api/test/blaze/rest_api/middleware/output_test.clj index a5d01c14c..3cb055f7a 100644 --- a/modules/rest-api/test/blaze/rest_api/middleware/output_test.clj +++ b/modules/rest-api/test/blaze/rest_api/middleware/output_test.clj @@ -1,16 +1,17 @@ (ns blaze.rest-api.middleware.output-test (:require + [blaze.fhir.spec :as fhir-spec] [blaze.fhir.spec-spec] [blaze.rest-api.middleware.output :refer [wrap-output]] [blaze.test-util :as tu] [blaze.test-util.ring :refer [call]] + [clojure.data.xml :as xml] + [clojure.java.io :as io] [clojure.spec.test.alpha :as st] [clojure.test :as test :refer [are deftest is testing]] [juxt.iota :refer [given]] [ring.util.response :as ring] - [taoensso.timbre :as log]) - (:import - [java.nio.charset StandardCharsets])) + [taoensso.timbre :as log])) (st/instrument) @@ -34,74 +35,153 @@ (respond (ring/response {:fhir/type :fhir/Patient :id "0"}))))) -(defn- bytes->str [^bytes bs] - (String. bs StandardCharsets/UTF_8)) +(defn- parse-json [body] + (fhir-spec/conform-json (fhir-spec/parse-json body))) (deftest json-test (testing "JSON is the default" (testing "without accept header" (given (call resource-handler {}) - [:body bytes->str] := "{\"id\":\"0\",\"resourceType\":\"Patient\"}")) + [:headers "Content-Type"] := "application/fhir+json;charset=utf-8" + [:body parse-json] := {:fhir/type :fhir/Patient :id "0"})) (testing "with accept header" - (are [accept] (given (call resource-handler {:headers {"accept" accept}}) - [:body bytes->str] := "{\"id\":\"0\",\"resourceType\":\"Patient\"}") - "*/*" - "application/*" - "text/*"))) + (are [accept content-type] + (given (call resource-handler {:headers {"accept" accept}}) + [:headers "Content-Type"] := content-type + [:body parse-json] := {:fhir/type :fhir/Patient :id "0"}) + "*/*" "application/fhir+json;charset=utf-8" + "application/*" "application/fhir+json;charset=utf-8" + "text/*" "text/json;charset=utf-8"))) (testing "possible accept headers" - (are [accept] + (are [accept content-type] (given (call resource-handler {:headers {"accept" accept}}) - [:body bytes->str] := "{\"id\":\"0\",\"resourceType\":\"Patient\"}") - "application/fhir+json" - "application/json" - "text/json" - "application/fhir+xml;q=0.9, application/fhir+json;q=1.0")) + [:headers "Content-Type"] := content-type + [:body parse-json] := {:fhir/type :fhir/Patient :id "0"}) + "application/fhir+json" "application/fhir+json;charset=utf-8" + "application/json" "application/json;charset=utf-8" + "text/json" "text/json;charset=utf-8" + "application/fhir+xml;q=0.9, application/fhir+json;q=1.0" "application/fhir+json;charset=utf-8")) (testing "_format overrides" - (are [accept format] + (are [accept format content-type] (given (call resource-handler {:headers {"accept" accept} :query-params {"_format" format}}) - [:body bytes->str] := "{\"id\":\"0\",\"resourceType\":\"Patient\"}") - "application/fhir+xml" "application/fhir+json" - "application/fhir+xml" "application/json" - "application/fhir+xml" "text/json" - "application/fhir+xml" "json" - "*/*" "application/fhir+json" - "*/*" "application/json" - "*/*" "text/json" - "*/*" "json"))) + [:headers "Content-Type"] := content-type + [:body parse-json] := {:fhir/type :fhir/Patient :id "0"}) + "application/fhir+xml" + "application/fhir+json" + "application/fhir+json;charset=utf-8" + + "application/fhir+xml" + "application/json" + "application/json;charset=utf-8" + + "application/fhir+xml" + "text/json" + "text/json;charset=utf-8" + + "application/fhir+xml" + "json" + "application/fhir+json;charset=utf-8" + + "*/*" + "application/fhir+json" + "application/fhir+json;charset=utf-8" + + "*/*" + "application/json" + "application/json;charset=utf-8" + + "*/*" + "text/json" + "text/json;charset=utf-8" + + "*/*" + "json" + "application/fhir+json;charset=utf-8"))) + + +(defn- parse-xml [body] + (with-open [reader (io/reader body)] + (fhir-spec/conform-xml (xml/parse reader)))) (deftest xml-test (testing "possible accept headers" - (are [accept] + (are [accept content-type] (given (call resource-handler {:headers {"accept" accept}}) - [:body bytes->str] := - "") + [:headers "Content-Type"] := content-type + [:body parse-xml] := {:fhir/type :fhir/Patient :id "0"}) "application/fhir+xml" + "application/fhir+xml;charset=utf-8" + "application/xml" + "application/xml;charset=utf-8" + "text/xml" - "application/fhir+json;q=0.9, application/fhir+xml;q=1.0")) + "text/xml;charset=utf-8" + + "application/fhir+json;q=0.9, application/fhir+xml;q=1.0" + "application/fhir+xml;charset=utf-8" + + ;; Safari + "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" + "application/xml;charset=utf-8" + + ;; Chrome + "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" + "application/xml;charset=utf-8" + + ;; Edge + "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" + "application/xml;charset=utf-8" + + ;; Firefox + "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8" + "application/xml;charset=utf-8")) (testing "_format overrides" - (are [accept format] + (are [accept format content-type] (given (call resource-handler {:headers {"accept" accept} :query-params {"_format" format}}) - [:body bytes->str] := - "") - "application/fhir+json" "application/fhir+xml" - "application/fhir+json" "application/xml" - "application/fhir+json" "text/xml" - "application/fhir+json" "xml" - "*/*" "application/fhir+xml" - "*/*" "application/xml" - "*/*" "text/xml" - "*/*" "xml"))) + [:headers "Content-Type"] := content-type + [:body parse-xml] := {:fhir/type :fhir/Patient :id "0"}) + "application/fhir+json" + "application/fhir+xml" + "application/fhir+xml;charset=utf-8" + + "application/fhir+json" + "application/xml" + "application/xml;charset=utf-8" + + "application/fhir+json" + "text/xml" + "text/xml;charset=utf-8" + + "application/fhir+json" + "xml" + "application/fhir+xml;charset=utf-8" + + "*/*" + "application/fhir+xml" + "application/fhir+xml;charset=utf-8" + + "*/*" + "application/xml" + "application/xml;charset=utf-8" + + "*/*" + "text/xml" + "text/xml;charset=utf-8" + + "*/*" + "xml" + "application/fhir+xml;charset=utf-8"))) (deftest not-acceptable-test diff --git a/perf-test/gatling/pom.xml b/perf-test/gatling/pom.xml index 819b7adb3..5cee3d9e7 100644 --- a/perf-test/gatling/pom.xml +++ b/perf-test/gatling/pom.xml @@ -5,7 +5,7 @@ samply.blaze gatling - 0.17.2 + 0.17.3 1.8 diff --git a/pom.xml b/pom.xml index 5b87b2b97..f54c2fada 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 samply blaze - 0.17.2 + 0.17.3 blaze A FHIR Store with internal, fast CQL Evaluation Engine diff --git a/src/blaze/system.clj b/src/blaze/system.clj index 6abaa59ce..43b79f640 100644 --- a/src/blaze/system.clj +++ b/src/blaze/system.clj @@ -85,7 +85,7 @@ (def ^:private root-config - {:blaze/version "0.17.2" + {:blaze/version "0.17.3" :blaze/clock {}