From 849052327c8ee6e9d9ae446344a19977a61b6c78 Mon Sep 17 00:00:00 2001 From: bot Date: Mon, 8 Apr 2024 16:08:19 +0000 Subject: [PATCH 01/32] updated version to 2.10.0-SNAPSHOT --- CHANGELOG.md | 5 +++++ aql/pom.xml | 2 +- bom/pom.xml | 2 +- client/pom.xml | 2 +- example-generator/pom.xml | 2 +- generator-commons/pom.xml | 2 +- generator-maven-plugin/pom.xml | 2 +- generator/pom.xml | 2 +- opt-1.4/pom.xml | 2 +- pom.xml | 4 ++-- response-dto/pom.xml | 2 +- serialisation/pom.xml | 2 +- serialisation_conformance_test/pom.xml | 2 +- terminology/pom.xml | 2 +- test-coverage/pom.xml | 2 +- test-data/pom.xml | 2 +- util/pom.xml | 2 +- validation/pom.xml | 2 +- web-template/pom.xml | 2 +- 19 files changed, 24 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7321c688..4ac2b2094 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ Note: version releases in the 0.x.y range may introduce breaking changes. +## [unreleased] + ### Added + ### Fixed + ## [2.9.1] ### Added ### Fixed @@ -391,3 +395,4 @@ Note: version releases in the 0.x.y range may introduce breaking changes. [2.8.0]: https://github.com/ehrbase/openEHR_SDK/compare/v2.7.0...v2.8.0 [2.9.0]: https://github.com/ehrbase/openEHR_SDK/compare/v2.8.0...v2.9.0 [2.9.1]: https://github.com/ehrbase/openEHR_SDK/compare/v2.9.0...v2.9.1 +[unreleased]: https://github.com/ehrbase/openEHR_SDK/compare/v2.9.1...HEAD diff --git a/aql/pom.xml b/aql/pom.xml index 59b9d235f..997f3b610 100644 --- a/aql/pom.xml +++ b/aql/pom.xml @@ -25,7 +25,7 @@ org.ehrbase.openehr.sdk sdk-parent - 2.9.1 + 2.10.0-SNAPSHOT aql diff --git a/bom/pom.xml b/bom/pom.xml index a7de05fe3..7680ac9cb 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -8,7 +8,7 @@ bom org.ehrbase.openehr.sdk - 2.9.1 + 2.10.0-SNAPSHOT pom openEHR SDK diff --git a/client/pom.xml b/client/pom.xml index 695a856cb..232040078 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -26,7 +26,7 @@ org.ehrbase.openehr.sdk sdk-parent - 2.9.1 + 2.10.0-SNAPSHOT client diff --git a/example-generator/pom.xml b/example-generator/pom.xml index 87a4ff2ee..dac0a6b1a 100644 --- a/example-generator/pom.xml +++ b/example-generator/pom.xml @@ -5,7 +5,7 @@ sdk-parent org.ehrbase.openehr.sdk - 2.9.1 + 2.10.0-SNAPSHOT 4.0.0 diff --git a/generator-commons/pom.xml b/generator-commons/pom.xml index 18a0b1cb3..cb407b842 100644 --- a/generator-commons/pom.xml +++ b/generator-commons/pom.xml @@ -6,7 +6,7 @@ org.ehrbase.openehr.sdk sdk-parent - 2.9.1 + 2.10.0-SNAPSHOT generator-commons diff --git a/generator-maven-plugin/pom.xml b/generator-maven-plugin/pom.xml index fff579f5e..5faecd42f 100644 --- a/generator-maven-plugin/pom.xml +++ b/generator-maven-plugin/pom.xml @@ -5,7 +5,7 @@ sdk-parent org.ehrbase.openehr.sdk - 2.9.1 + 2.10.0-SNAPSHOT 4.0.0 diff --git a/generator/pom.xml b/generator/pom.xml index 433d35e9a..16e2fe00b 100644 --- a/generator/pom.xml +++ b/generator/pom.xml @@ -25,7 +25,7 @@ org.ehrbase.openehr.sdk sdk-parent - 2.9.1 + 2.10.0-SNAPSHOT generator diff --git a/opt-1.4/pom.xml b/opt-1.4/pom.xml index 9fbef9c6c..20cae60cf 100644 --- a/opt-1.4/pom.xml +++ b/opt-1.4/pom.xml @@ -26,7 +26,7 @@ org.ehrbase.openehr.sdk sdk-parent - 2.9.1 + 2.10.0-SNAPSHOT opt-1.4 diff --git a/pom.xml b/pom.xml index 5129fdfd1..7f3c93da6 100644 --- a/pom.xml +++ b/pom.xml @@ -25,13 +25,13 @@ org.ehrbase.openehr.sdk bom - 2.9.1 + 2.10.0-SNAPSHOT ./bom/pom.xml org.ehrbase.openehr.sdk sdk-parent - 2.9.1 + 2.10.0-SNAPSHOT pom openEHR SDK diff --git a/response-dto/pom.xml b/response-dto/pom.xml index ddae35b07..c67aa2bf4 100644 --- a/response-dto/pom.xml +++ b/response-dto/pom.xml @@ -26,7 +26,7 @@ org.ehrbase.openehr.sdk sdk-parent - 2.9.1 + 2.10.0-SNAPSHOT response-dto diff --git a/serialisation/pom.xml b/serialisation/pom.xml index 6de07c768..3a2be3a79 100644 --- a/serialisation/pom.xml +++ b/serialisation/pom.xml @@ -26,7 +26,7 @@ org.ehrbase.openehr.sdk sdk-parent - 2.9.1 + 2.10.0-SNAPSHOT serialisation diff --git a/serialisation_conformance_test/pom.xml b/serialisation_conformance_test/pom.xml index 282598721..82ba4b509 100644 --- a/serialisation_conformance_test/pom.xml +++ b/serialisation_conformance_test/pom.xml @@ -26,7 +26,7 @@ org.ehrbase.openehr.sdk sdk-parent - 2.9.1 + 2.10.0-SNAPSHOT serialisation_conformance_test diff --git a/terminology/pom.xml b/terminology/pom.xml index 06b3f6c7d..4b1cb64d9 100644 --- a/terminology/pom.xml +++ b/terminology/pom.xml @@ -26,7 +26,7 @@ org.ehrbase.openehr.sdk sdk-parent - 2.9.1 + 2.10.0-SNAPSHOT terminology diff --git a/test-coverage/pom.xml b/test-coverage/pom.xml index 711b91566..d4ae94aa4 100644 --- a/test-coverage/pom.xml +++ b/test-coverage/pom.xml @@ -8,7 +8,7 @@ org.ehrbase.openehr.sdk sdk-parent - 2.9.1 + 2.10.0-SNAPSHOT test-coverage diff --git a/test-data/pom.xml b/test-data/pom.xml index 52fec2ff8..5e7a36881 100644 --- a/test-data/pom.xml +++ b/test-data/pom.xml @@ -26,7 +26,7 @@ org.ehrbase.openehr.sdk sdk-parent - 2.9.1 + 2.10.0-SNAPSHOT test-data diff --git a/util/pom.xml b/util/pom.xml index 3b6d9997b..9ac147909 100644 --- a/util/pom.xml +++ b/util/pom.xml @@ -25,7 +25,7 @@ org.ehrbase.openehr.sdk sdk-parent - 2.9.1 + 2.10.0-SNAPSHOT util diff --git a/validation/pom.xml b/validation/pom.xml index 4b9fd3eb8..18e3224d9 100644 --- a/validation/pom.xml +++ b/validation/pom.xml @@ -24,7 +24,7 @@ org.ehrbase.openehr.sdk sdk-parent - 2.9.1 + 2.10.0-SNAPSHOT validation diff --git a/web-template/pom.xml b/web-template/pom.xml index 13d7bd06d..682d63c10 100644 --- a/web-template/pom.xml +++ b/web-template/pom.xml @@ -25,7 +25,7 @@ org.ehrbase.openehr.sdk sdk-parent - 2.9.1 + 2.10.0-SNAPSHOT web-template From 910ff20e29b54e9154efcdb425f28f34f6caf82e Mon Sep 17 00:00:00 2001 From: vmueller-vg <100680528+vmueller-vg@users.noreply.github.com> Date: Mon, 8 Apr 2024 18:10:57 +0200 Subject: [PATCH 02/32] Update publish.yml --- .github/workflows/publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6662f53f4..b037ba7e1 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -45,7 +45,7 @@ jobs: OSSRH_TOKEN: ${{ secrets.S01_OSSRH_TOKEN }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - - name: 'Trigger ehrbase:next build' + - name: 'Trigger ehrbase build' if: github.ref == 'refs/heads/develop' run: | curl \ @@ -53,4 +53,4 @@ jobs: -H "Authorization: token ${{ secrets.PERSONAL_ACCESS_TOKEN }}" \ -H "Content-Type: application/json" \ https://api.github.com/repos/ehrbase/ehrbase/dispatches \ - -d '{"event_type":"build-ehrbase-next"}' + -d '{"event_type":"build-and-test-postgres"}' From 06f1d69451087beb3f4dec703641ff94a662a83a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 12:39:31 +0200 Subject: [PATCH 03/32] Bump org.apache.maven.plugin-tools:maven-plugin-annotations (#578) Bumps [org.apache.maven.plugin-tools:maven-plugin-annotations](https://github.com/apache/maven-plugin-tools) from 3.10.2 to 3.12.0. - [Release notes](https://github.com/apache/maven-plugin-tools/releases) - [Commits](https://github.com/apache/maven-plugin-tools/compare/maven-plugin-tools-3.10.2...maven-plugin-tools-3.12.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugin-tools:maven-plugin-annotations dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- generator-maven-plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generator-maven-plugin/pom.xml b/generator-maven-plugin/pom.xml index 5faecd42f..6587f2fd6 100644 --- a/generator-maven-plugin/pom.xml +++ b/generator-maven-plugin/pom.xml @@ -26,7 +26,7 @@ org.apache.maven.plugin-tools maven-plugin-annotations - 3.10.2 + 3.12.0 provided From fa82c0a4dd31635cc143f8a34b60e6329459dc7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 12:39:44 +0200 Subject: [PATCH 04/32] Bump org.apache.maven.plugins:maven-plugin-plugin from 3.10.2 to 3.12.0 (#577) Bumps [org.apache.maven.plugins:maven-plugin-plugin](https://github.com/apache/maven-plugin-tools) from 3.10.2 to 3.12.0. - [Release notes](https://github.com/apache/maven-plugin-tools/releases) - [Commits](https://github.com/apache/maven-plugin-tools/compare/maven-plugin-tools-3.10.2...maven-plugin-tools-3.12.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-plugin-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- generator-maven-plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generator-maven-plugin/pom.xml b/generator-maven-plugin/pom.xml index 6587f2fd6..812f6b914 100644 --- a/generator-maven-plugin/pom.xml +++ b/generator-maven-plugin/pom.xml @@ -47,7 +47,7 @@ maven-plugin-plugin - 3.10.2 + 3.12.0 generator From 7fadf1eaf410c2ab66068c931fd8f93f53f428fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 12:39:50 +0200 Subject: [PATCH 05/32] Bump org.apache.maven.plugins:maven-surefire-plugin from 3.2.2 to 3.2.5 (#572) Bumps [org.apache.maven.plugins:maven-surefire-plugin](https://github.com/apache/maven-surefire) from 3.2.2 to 3.2.5. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.2.2...surefire-3.2.5) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-surefire-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- bom/pom.xml | 2 +- client/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bom/pom.xml b/bom/pom.xml index 7680ac9cb..975a908a0 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -73,7 +73,7 @@ 2.22.2 3.6.3 3.3.0 - 3.2.2 + 3.2.5 0.8.11 1.7.2 2.3.9 diff --git a/client/pom.xml b/client/pom.xml index 232040078..a39d4d371 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -40,7 +40,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.2.2 + 3.2.5 com.github.better-care:web-template-tests From 84ae798943e2379e7edbfde8a43292313d5bd3c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 12:40:11 +0200 Subject: [PATCH 06/32] Bump org.springframework:spring-core from 5.3.31 to 6.0.15 in /client (#561) Bumps [org.springframework:spring-core](https://github.com/spring-projects/spring-framework) from 5.3.31 to 6.0.15. - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v5.3.31...v6.0.15) --- updated-dependencies: - dependency-name: org.springframework:spring-core dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- client/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/pom.xml b/client/pom.xml index a39d4d371..7fd58002e 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -174,7 +174,7 @@ org.springframework spring-core - 5.3.31 + 6.0.15 test From a40785549dfe68e5e1be358d522277a4bbec5d17 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 12:40:23 +0200 Subject: [PATCH 07/32] Bump org.junit:junit-bom from 5.10.0 to 5.10.2 (#571) Bumps [org.junit:junit-bom](https://github.com/junit-team/junit5) from 5.10.0 to 5.10.2. - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.10.0...r5.10.2) --- updated-dependencies: - dependency-name: org.junit:junit-bom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index 975a908a0..1a60604bf 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -63,7 +63,7 @@ 2.9.0 2.5.0 1.5.1 - 5.10.0 + 5.10.2 4.11.0 1.7.36 3.1.0 From 2bbabea37256b47afa30f2406eca4f1fdc7bc723 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 13:11:02 +0200 Subject: [PATCH 08/32] Bump org.springframework:spring-core from 6.0.15 to 6.0.16 in /client (#579) Bumps [org.springframework:spring-core](https://github.com/spring-projects/spring-framework) from 6.0.15 to 6.0.16. - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.0.15...v6.0.16) --- updated-dependencies: - dependency-name: org.springframework:spring-core dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- client/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/pom.xml b/client/pom.xml index 7fd58002e..db0335a8d 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -174,7 +174,7 @@ org.springframework spring-core - 6.0.15 + 6.0.16 test From 889eb4a56673c1879ca28db80556d2286b2b1dc9 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 15 Apr 2024 15:47:26 +0300 Subject: [PATCH 09/32] CDR-1382 Add sonar support --- .github/workflows/build.yml | 15 ++++++++++-- bom/pom.xml | 6 +++++ sonar-project.properties | 46 ------------------------------------- 3 files changed, 19 insertions(+), 48 deletions(-) delete mode 100644 sonar-project.properties diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d87c3e207..fc6757315 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,7 +2,9 @@ name: build on: push: + branches: [ develop, release/* ] pull_request: + branches: [ develop ] workflow_dispatch: jobs: @@ -25,6 +27,15 @@ jobs: - name: Spotless run: mvn -B spotless:apply - - name: Build with Maven - run: mvn -B verify + - name: Run Checks + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: | + mvn clean verify test jacoco:report-aggregate package sonar:sonar \ + -Dsonar.host.url=https://sonarcloud.io \ + -Dsonar.organization=ehrbase \ + -Dsonar.projectKey=ehrbase_openEHR_SDK \ + -Dsonar.exclusions=test/** \ + -Dsonar.coverage.exclusions=test/**,test-data/**/*,opt-14/**/*,response-dto/**/* \ + -Dsonar.coverage.jacoco.xmlReportPaths=${{ github.workspace }}/test-coverage/target/site/jacoco-overall-coverage/jacoco.xml diff --git a/bom/pom.xml b/bom/pom.xml index 1a60604bf..d176129ee 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -77,6 +77,7 @@ 0.8.11 1.7.2 2.3.9 + 3.11.0.3922 @@ -454,6 +455,11 @@ nexus-staging-maven-plugin ${nexus-staging-maven-plugin.version} + + org.sonarsource.scanner.maven + sonar-maven-plugin + ${sonar.scanner.version} + diff --git a/sonar-project.properties b/sonar-project.properties deleted file mode 100644 index 62bb18945..000000000 --- a/sonar-project.properties +++ /dev/null @@ -1,46 +0,0 @@ -# -# Copyright (c) 2020 Wladislaw Wagner (Vitasystems GmbH) and Hannover Medical School. -# -# This file is part of project EHRBase -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -sonar.organization=ehrbase -sonar.projectKey=ehrbase_openEHR_SDK -# sonar.host.url=https://sonarcloud.io - -# Most of these settings can be configured in the SonarCloud UI as well. -sonar.projectName=openEHR_SDK -sonar.projectVersion=0.3.5 - -sonar.coverage.jacoco.xmlReportPaths=test-coverage/target/site/jacoco-overall-coverage/jacoco.xml - -# Comma-separated paths to folders containing the *.xml JUnit reports. -sonar.junit.reportPaths=/home/circleci/test-results/unit-tests/, \ - /home/circleci/test-results/integration-tests/ - - -sonar.java.binaries=**/target/** - -# Patterns used to exclude some files from coverage report. -sonar.coverage.exclusions=**/test/**, test-data/**/*, opt-14/**/*, response-dto/**/* - -# Patterns used to exclude some source files from analysis. -sonar.exclusions=**/test/** - -# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. -#sonar.sources=. - -# Encoding of the source code. Default is default system encoding -#sonar.sourceEncoding=UTF-8 From c742c3fe6a53590f7c35e58ae0beceda30063f26 Mon Sep 17 00:00:00 2001 From: Alexander Lehnert Date: Tue, 16 Apr 2024 10:27:08 +0200 Subject: [PATCH 10/32] CDR-1388 Update flat marshalling of DvOrdered to be more resilient --- README.md | 6 +-- .../std/marshal/config/DvOrdinalConfig.java | 34 +++++------- .../marshal/config/DvOrdinalConfigTest.java | 53 +++++++++++++++++++ 3 files changed, 69 insertions(+), 24 deletions(-) create mode 100644 serialisation/src/test/java/org/ehrbase/openehr/sdk/serialisation/flatencoding/std/marshal/config/DvOrdinalConfigTest.java diff --git a/README.md b/README.md index ffc095c17..65742bd4e 100644 --- a/README.md +++ b/README.md @@ -167,16 +167,16 @@ In case there is a section of code that you carefully formatted in a special way ``` everything here will be reformatted.. -// @formatter:off +// @format:off This is not affected by spotless-plugin reformatting... And will stay as is it is! -// @formatter:on +// @format:on everything here will be reformatted.. ``` -Please be aware that `@formatter:off/on` should only be used on rare occasions to increase readability of complex code and shall be looked at critically when reviewing merge requests. +Please be aware that `@format:off/on` should only be used on rare occasions to increase readability of complex code and shall be looked at critically when reviewing merge requests. ---- diff --git a/serialisation/src/main/java/org/ehrbase/openehr/sdk/serialisation/flatencoding/std/marshal/config/DvOrdinalConfig.java b/serialisation/src/main/java/org/ehrbase/openehr/sdk/serialisation/flatencoding/std/marshal/config/DvOrdinalConfig.java index 8dc54550b..d1fffcb69 100644 --- a/serialisation/src/main/java/org/ehrbase/openehr/sdk/serialisation/flatencoding/std/marshal/config/DvOrdinalConfig.java +++ b/serialisation/src/main/java/org/ehrbase/openehr/sdk/serialisation/flatencoding/std/marshal/config/DvOrdinalConfig.java @@ -17,44 +17,36 @@ */ package org.ehrbase.openehr.sdk.serialisation.flatencoding.std.marshal.config; -import com.nedap.archie.rm.datatypes.CodePhrase; -import com.nedap.archie.rm.datavalues.DvCodedText; import com.nedap.archie.rm.datavalues.quantity.DvOrdinal; import java.util.HashMap; import java.util.Map; import java.util.Optional; import org.ehrbase.openehr.sdk.serialisation.walker.Context; -import org.ehrbase.openehr.sdk.util.exception.SdkException; -import org.ehrbase.openehr.sdk.webtemplate.model.WebTemplateInputValue; public class DvOrdinalConfig extends AbstractsStdConfig { - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ @Override public Class getAssociatedClass() { return DvOrdinal.class; } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ @Override public Map buildChildValues( - String currentTerm, DvOrdinal rmObject, Context> context) { - Map result = new HashMap<>(); - String codeString = Optional.of(rmObject) - .map(DvOrdinal::getSymbol) - .map(DvCodedText::getDefiningCode) - .map(CodePhrase::getCodeString) - .orElse(null); - addValue(result, currentTerm, "code", codeString); - - WebTemplateInputValue value = context.getNodeDeque().peek().getInputs().get(0).getList().stream() - .filter(o -> o.getValue().equals(codeString)) - .findAny() - .orElseThrow(() -> new SdkException(String.format("Unknown Ordinal with code %s", codeString))); + String currentTerm, DvOrdinal ordinal, Context> context) { - addValue(result, currentTerm, "ordinal", value.getOrdinal()); - addValue(result, currentTerm, "value", value.getLabel()); + Map result = new HashMap<>(); + Optional.ofNullable(ordinal.getSymbol()).ifPresent(symbol -> { + addValue(result, currentTerm, "code", symbol.getDefiningCode().getCodeString()); + addValue(result, currentTerm, "value", symbol.getValue()); + }); + addValue(result, currentTerm, "ordinal", ordinal.getValue()); return result; } } diff --git a/serialisation/src/test/java/org/ehrbase/openehr/sdk/serialisation/flatencoding/std/marshal/config/DvOrdinalConfigTest.java b/serialisation/src/test/java/org/ehrbase/openehr/sdk/serialisation/flatencoding/std/marshal/config/DvOrdinalConfigTest.java new file mode 100644 index 000000000..44b6b62b5 --- /dev/null +++ b/serialisation/src/test/java/org/ehrbase/openehr/sdk/serialisation/flatencoding/std/marshal/config/DvOrdinalConfigTest.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 vitasystems GmbH and Hannover Medical School. + * + * This file is part of project openEHR_SDK + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.ehrbase.openehr.sdk.serialisation.flatencoding.std.marshal.config; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.nedap.archie.rm.datavalues.DvCodedText; +import com.nedap.archie.rm.datavalues.quantity.DvOrdinal; +import java.util.Map; +import org.ehrbase.openehr.sdk.serialisation.walker.Context; +import org.junit.jupiter.api.Test; + +class DvOrdinalConfigTest { + + private Map buildChildValues(String currentTerm, DvOrdinal dvOrdinal) { + return new DvOrdinalConfig().buildChildValues(currentTerm, dvOrdinal, new Context<>()); + } + + @Test + void buildChildValuesOrdinalOnlySymbolNullSafe() { + + Map childValues = + buildChildValues("nested:0/current_activity/ordinal", new DvOrdinal(1L, null)); + assertThat(childValues).hasSize(1).containsEntry("nested:0/current_activity/ordinal|ordinal", 1L); + } + + @Test + void buildChildValuesWithSymbol() { + + Map childValues = buildChildValues( + "some_other/current_activity/ordinal", new DvOrdinal(42L, new DvCodedText("lorem ipsum", "PWVGUTHASM"))); + assertThat(childValues) + .hasSize(3) + .containsEntry("some_other/current_activity/ordinal|ordinal", 42L) + .containsEntry("some_other/current_activity/ordinal|code", "PWVGUTHASM") + .containsEntry("some_other/current_activity/ordinal|value", "lorem ipsum"); + } +} From 6f7455d01245962816b9a9f7795a18c8585c68cc Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 17 Apr 2024 13:11:13 +0300 Subject: [PATCH 11/32] Disable sonar for dependabot (#587) * Disable sonar for Dependabot PRs * Apply spotless * Rename sonar step in the build workflow --- .github/workflows/build.yml | 15 ++++++++++----- .../std/marshal/config/DvOrdinalConfigTest.java | 3 ++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fc6757315..1568b01da 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,7 @@ jobs: with: fetch-depth: 0 - - name: Setup Java + - name: Setup - Java 17 uses: actions/setup-java@v4 with: distribution: 'temurin' @@ -24,14 +24,19 @@ jobs: cache: 'maven' - - name: Spotless - run: mvn -B spotless:apply + - name: Spotless - Check + run: mvn -B spotless:check - - name: Run Checks + - name: Maven - Verify, Jacoco and Package + run: mvn --batch-mode -U verify test jacoco:report-aggregate package + + - name: Sonar - Analyze + # Dependabot has no access to the SONAR_TOKEN secret, so we need to skip sonar. + if: ${{ github.actor != 'dependabot[bot]' }} env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | - mvn clean verify test jacoco:report-aggregate package sonar:sonar \ + mvn --batch-mode sonar:sonar \ -Dsonar.host.url=https://sonarcloud.io \ -Dsonar.organization=ehrbase \ -Dsonar.projectKey=ehrbase_openEHR_SDK \ diff --git a/serialisation/src/test/java/org/ehrbase/openehr/sdk/serialisation/flatencoding/std/marshal/config/DvOrdinalConfigTest.java b/serialisation/src/test/java/org/ehrbase/openehr/sdk/serialisation/flatencoding/std/marshal/config/DvOrdinalConfigTest.java index 44b6b62b5..b0352f999 100644 --- a/serialisation/src/test/java/org/ehrbase/openehr/sdk/serialisation/flatencoding/std/marshal/config/DvOrdinalConfigTest.java +++ b/serialisation/src/test/java/org/ehrbase/openehr/sdk/serialisation/flatencoding/std/marshal/config/DvOrdinalConfigTest.java @@ -43,7 +43,8 @@ void buildChildValuesOrdinalOnlySymbolNullSafe() { void buildChildValuesWithSymbol() { Map childValues = buildChildValues( - "some_other/current_activity/ordinal", new DvOrdinal(42L, new DvCodedText("lorem ipsum", "PWVGUTHASM"))); + "some_other/current_activity/ordinal", + new DvOrdinal(42L, new DvCodedText("lorem ipsum", "PWVGUTHASM"))); assertThat(childValues) .hasSize(3) .containsEntry("some_other/current_activity/ordinal|ordinal", 42L) From 7ae1235e0d0805cc6e281ada2ad4ba94496a343b Mon Sep 17 00:00:00 2001 From: Alex Vidrean Date: Fri, 19 Apr 2024 10:52:03 +0300 Subject: [PATCH 12/32] Separate codestyle in a standalone workflow as it's done in EHRbase --- .github/workflows/build.yml | 12 ++++++++---- .github/workflows/codeql.yml | 3 +++ .github/workflows/codestyle.yml | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/codestyle.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fc6757315..020aa8a97 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,5 +1,8 @@ name: build +# we have multiple workflows - this helps to distinguish for them +run-name: "${{ github.event.pull_request.title || github.head_ref }} - Codestyle" + on: push: branches: [ develop, release/* ] @@ -23,11 +26,12 @@ jobs: java-version: '17' cache: 'maven' + - name: Maven - Verify, Jacoco and Package + run: mvn --batch-mode -U verify test jacoco:report-aggregate package - - name: Spotless - run: mvn -B spotless:apply - - - name: Run Checks + - name: Sonar - Analyze + # Dependabot has no access to the SONAR_TOKEN secret, so we need to skip sonar. + if: ${{ github.actor != 'dependabot[bot]' }} env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3a67b1f93..e544dafc2 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -11,6 +11,9 @@ # name: "CodeQL" +# we have multiple workflows - this helps to distinguish for them +run-name: "${{ github.event.pull_request.title || github.head_ref }} - Codestyle" + on: push: branches: [ "develop" ] diff --git a/.github/workflows/codestyle.yml b/.github/workflows/codestyle.yml new file mode 100644 index 000000000..f605bb3d0 --- /dev/null +++ b/.github/workflows/codestyle.yml @@ -0,0 +1,32 @@ +name: "Codestyle" + +# we have multiple workflows - this helps to distinguish for them +run-name: "${{ github.event.pull_request.title || github.head_ref }} - Codestyle" + +on: + push: + branches: [ develop, release/* ] + workflow_dispatch: + pull_request: + branches: [ develop ] + +# +# Style-check it's a dedicated workflow. This allows us to open a PR, run all tests and fix styling issue later ;). +# +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' + cache: 'maven' + + - name: Spotless + run: mvn spotless:check From 8caf4923e77db6fd2ae626712b977f564fc6066b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 14:42:09 +0200 Subject: [PATCH 13/32] Bump org.assertj:assertj-core from 3.24.2 to 3.25.3 (#581) Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.24.2 to 3.25.3. - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.24.2...assertj-build-3.25.3) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index d176129ee..f13717f1a 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -40,7 +40,7 @@ 4.11.1 3.3.0 - 3.24.2 + 3.25.3 3.3.0 4.8.165 1.6.0 From 168827aeaa6c181a901cf2c3e453c575c7334a5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 14:42:17 +0200 Subject: [PATCH 14/32] Bump org.apache.maven.plugins:maven-source-plugin from 3.3.0 to 3.3.1 (#583) Bumps [org.apache.maven.plugins:maven-source-plugin](https://github.com/apache/maven-source-plugin) from 3.3.0 to 3.3.1. - [Commits](https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-3.3.0...maven-source-plugin-3.3.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-source-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index f13717f1a..9e5deb729 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -72,7 +72,7 @@ 3.4.1 2.22.2 3.6.3 - 3.3.0 + 3.3.1 3.2.5 0.8.11 1.7.2 From e0f745ab2ab83a507b3eb7d4f5ff1516c176ea61 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 14:42:22 +0200 Subject: [PATCH 15/32] Bump net.minidev:json-smart from 2.5.0 to 2.5.1 (#584) Bumps [net.minidev:json-smart](https://github.com/netplex/json-smart-v2) from 2.5.0 to 2.5.1. - [Release notes](https://github.com/netplex/json-smart-v2/releases) - [Commits](https://github.com/netplex/json-smart-v2/compare/2.5.0...2.5.1) --- updated-dependencies: - dependency-name: net.minidev:json-smart dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index 9e5deb729..dc505956e 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -61,7 +61,7 @@ 2.3.1 20231013 2.9.0 - 2.5.0 + 2.5.1 1.5.1 5.10.2 4.11.0 From e39f254a0307798f5856687698c3cb8e6f11fd11 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 14:42:43 +0200 Subject: [PATCH 16/32] Bump org.apache.maven:maven-core from 3.9.5 to 3.9.6 (#585) Bumps [org.apache.maven:maven-core](https://github.com/apache/maven) from 3.9.5 to 3.9.6. - [Release notes](https://github.com/apache/maven/releases) - [Commits](https://github.com/apache/maven/compare/maven-3.9.5...maven-3.9.6) --- updated-dependencies: - dependency-name: org.apache.maven:maven-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- generator-maven-plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generator-maven-plugin/pom.xml b/generator-maven-plugin/pom.xml index 812f6b914..6722f8706 100644 --- a/generator-maven-plugin/pom.xml +++ b/generator-maven-plugin/pom.xml @@ -38,7 +38,7 @@ org.apache.maven maven-core - 3.9.5 + 3.9.6 provided From 8b81ee4fa5e6947ce77d4d24f7db7098e3fff064 Mon Sep 17 00:00:00 2001 From: Alex Vidrean Date: Tue, 23 Apr 2024 14:45:26 +0300 Subject: [PATCH 17/32] Inherit secrets for github action workflow_call --- .github/workflows/build.yml | 2 +- .github/workflows/codeql.yml | 2 +- .github/workflows/codestyle.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d08be64c5..97179f204 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,7 +1,7 @@ name: build # we have multiple workflows - this helps to distinguish for them -run-name: "${{ github.event.pull_request.title || github.head_ref }} - Codestyle" +run-name: "${{ github.event_name == 'pull_request' && github.event.pull_request.title || github.head_ref }} - Build & Test" on: push: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index e544dafc2..c45f67c30 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -12,7 +12,7 @@ name: "CodeQL" # we have multiple workflows - this helps to distinguish for them -run-name: "${{ github.event.pull_request.title || github.head_ref }} - Codestyle" +run-name: "${{ github.event_name == 'pull_request' && github.event.pull_request.title || github.head_ref }} - CodeQL" on: push: diff --git a/.github/workflows/codestyle.yml b/.github/workflows/codestyle.yml index f605bb3d0..cad512c58 100644 --- a/.github/workflows/codestyle.yml +++ b/.github/workflows/codestyle.yml @@ -1,7 +1,7 @@ name: "Codestyle" # we have multiple workflows - this helps to distinguish for them -run-name: "${{ github.event.pull_request.title || github.head_ref }} - Codestyle" +run-name: "${{ github.event_name == 'pull_request' && github.event.pull_request.title || github.head_ref }} - Codestyle" on: push: From 005f67fcc89330b97fb098e40fba1b2a2c6b9207 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:12:01 +0200 Subject: [PATCH 18/32] Bump commons-io:commons-io from 2.15.1 to 2.16.1 (#592) Bumps commons-io:commons-io from 2.15.1 to 2.16.1. --- updated-dependencies: - dependency-name: commons-io:commons-io dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index dc505956e..692449308 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -46,7 +46,7 @@ 1.6.0 4.4 3.14.0 - 2.15.1 + 2.16.1 1.10.0 1.11.0 3.10.8 From d287e902919975f3f5aaf8178f282f7319dad712 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:12:24 +0200 Subject: [PATCH 19/32] Bump com.diffplug.spotless:spotless-maven-plugin from 2.41.1 to 2.43.0 (#590) Bumps [com.diffplug.spotless:spotless-maven-plugin](https://github.com/diffplug/spotless) from 2.41.1 to 2.43.0. - [Changelog](https://github.com/diffplug/spotless/blob/main/CHANGES.md) - [Commits](https://github.com/diffplug/spotless/compare/maven/2.41.1...lib/2.43.0) --- updated-dependencies: - dependency-name: com.diffplug.spotless:spotless-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index 692449308..7816ad616 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -408,7 +408,7 @@ com.diffplug.spotless spotless-maven-plugin - 2.41.1 + 2.43.0 org.antlr From dca30bb2678cd148fd391bbd8147010fef481c40 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:12:41 +0200 Subject: [PATCH 20/32] Bump org.springframework:spring-core from 6.0.16 to 6.1.6 (#591) Bumps [org.springframework:spring-core](https://github.com/spring-projects/spring-framework) from 6.0.16 to 6.1.6. - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.0.16...v6.1.6) --- updated-dependencies: - dependency-name: org.springframework:spring-core dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- client/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/pom.xml b/client/pom.xml index db0335a8d..0dc14c268 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -174,7 +174,7 @@ org.springframework spring-core - 6.0.16 + 6.1.6 test From 60789986489404fe9f3d86ae8241ec96b6319805 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:12:59 +0200 Subject: [PATCH 21/32] Bump org.jacoco:jacoco-maven-plugin from 0.8.11 to 0.8.12 (#593) Bumps [org.jacoco:jacoco-maven-plugin](https://github.com/jacoco/jacoco) from 0.8.11 to 0.8.12. - [Release notes](https://github.com/jacoco/jacoco/releases) - [Commits](https://github.com/jacoco/jacoco/compare/v0.8.11...v0.8.12) --- updated-dependencies: - dependency-name: org.jacoco:jacoco-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index 7816ad616..2eaf564b0 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -74,7 +74,7 @@ 3.6.3 3.3.1 3.2.5 - 0.8.11 + 0.8.12 1.7.2 2.3.9 3.11.0.3922 From 2e506db7d3f9e4f1a8ad14e3ab4bb079848efd1d Mon Sep 17 00:00:00 2001 From: stefanspiska Date: Wed, 24 Apr 2024 09:07:37 +0200 Subject: [PATCH 22/32] migrate sdk to ehrbase v2.0.0 (#588) * migrate sdk to erhbase v2.0.0 * update changelog * Add explicit unit tests and integration tests jacoco steps (#589) * Separate codestyle in a standalone workflow as it's done in EHRbase * Add explicit unit tests and integration tests jacoco steps * Remove client from surfire tests and update it command * Remove aggregate separate step --------- Co-authored-by: Alex --- .github/workflows/build.yml | 7 +- CHANGELOG.md | 4 + client/pom.xml | 16 -- .../client/openehrclient/OpenEhrClient.java | 2 - .../builder/ContributionBuilder.java | 5 + .../defaultrestclient/DefaultRestClient.java | 6 - .../DefaultRestDirectoryEndpoint.java | 150 --------------- .../DefaultRestFolderDAO.java | 175 ------------------ .../DefaultRestAqlEndpointTestIT.java | 114 ++---------- .../DefaultRestContributionEndpointIT.java | 53 ++++-- .../DefaultRestDirectoryEndpointIT.java | 120 ------------ .../DefaultRestEhrFieldsEndpointIT.java | 4 +- .../defaultrestclient/EHRbaseContainer.java | 2 +- .../EHRbasePostgresContainer.java | 2 +- pom.xml | 4 + .../canonical_json/ehr_other_details.json | 8 +- 16 files changed, 72 insertions(+), 600 deletions(-) delete mode 100644 client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestDirectoryEndpoint.java delete mode 100644 client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestFolderDAO.java delete mode 100644 client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestDirectoryEndpointIT.java diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 97179f204..60dc160a8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,8 +26,11 @@ jobs: java-version: '17' cache: 'maven' - - name: Maven - Verify, Jacoco and Package - run: mvn --batch-mode -U verify test jacoco:report-aggregate package + - name: Jacoco - Unit Tests + run: mvn --batch-mode clean jacoco:prepare-agent package jacoco:report + + - name: Jacoco - Integration Tests + run: mvn --batch-mode jacoco:prepare-agent-integration failsafe:integration-test failsafe:verify verify jacoco:report - name: Sonar - Analyze # Dependabot has no access to the SONAR_TOKEN secret, so we need to skip sonar. diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ac2b2094..89bd2b79d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,11 @@ Note: version releases in the 0.x.y range may introduce breaking changes. ## [unreleased] ### Added + ### Changed +- Removed OpenEhrClient::getFolder (use directoryCrudEndpoint()::getFolder instead) ([#588](https://github.com/ehrbase/openEHR_SDK/pull/588)) ### Fixed +- Migrated test to run against EHRbase v2 ([#588](https://github.com/ehrbase/openEHR_SDK/pull/588)) +- ContributionBuilder: set VERSION.lifecycle_state to 'complete'" ([#588](https://github.com/ehrbase/openEHR_SDK/pull/588)) ## [2.9.1] ### Added diff --git a/client/pom.xml b/client/pom.xml index 0dc14c268..852ca02a1 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -35,22 +35,6 @@ ../ - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.2.5 - - com.github.better-care:web-template-tests - - ${include.tests} - - - - - - javax.cache diff --git a/client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/OpenEhrClient.java b/client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/OpenEhrClient.java index ab3eb9921..11fb3521a 100644 --- a/client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/OpenEhrClient.java +++ b/client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/OpenEhrClient.java @@ -46,8 +46,6 @@ public interface OpenEhrClient { DirectoryCrudEndpoint directoryCrudEndpoint(UUID ehrId); - FolderDAO folder(UUID ehrId, String path); - /** * Get the {@link TemplateEndpoint} * diff --git a/client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/builder/ContributionBuilder.java b/client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/builder/ContributionBuilder.java index 91511dc32..40aacbeab 100644 --- a/client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/builder/ContributionBuilder.java +++ b/client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/builder/ContributionBuilder.java @@ -23,9 +23,12 @@ import com.nedap.archie.rm.archetyped.Locatable; import com.nedap.archie.rm.changecontrol.OriginalVersion; import com.nedap.archie.rm.composition.Composition; +import com.nedap.archie.rm.datatypes.CodePhrase; +import com.nedap.archie.rm.datavalues.DvCodedText; import com.nedap.archie.rm.directory.Folder; import com.nedap.archie.rm.generic.AuditDetails; import com.nedap.archie.rm.support.identification.ObjectVersionId; +import com.nedap.archie.rm.support.identification.TerminologyId; import com.nedap.archie.rm.support.identification.UIDBasedId; import javax.annotation.Nullable; import org.ehrbase.openehr.sdk.client.openehrclient.ContributionChangeType; @@ -192,6 +195,8 @@ private void updateContribution( updateMetadataById(precedingVersionUid, originalVersion, compositionAudit); originalVersion.setCommitAudit(compositionAudit); + originalVersion.setLifecycleState( + new DvCodedText("complete", new CodePhrase(new TerminologyId("openehr"), "532"))); this.contributionCreateDto.getVersions().add(originalVersion); } diff --git a/client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestClient.java b/client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestClient.java index e109746c7..814fc6cfa 100644 --- a/client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestClient.java +++ b/client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestClient.java @@ -59,7 +59,6 @@ import org.ehrbase.openehr.sdk.client.openehrclient.CompositionEndpoint; import org.ehrbase.openehr.sdk.client.openehrclient.ContributionEndpoint; import org.ehrbase.openehr.sdk.client.openehrclient.DirectoryCrudEndpoint; -import org.ehrbase.openehr.sdk.client.openehrclient.FolderDAO; import org.ehrbase.openehr.sdk.client.openehrclient.OpenEhrClient; import org.ehrbase.openehr.sdk.client.openehrclient.OpenEhrClientConfig; import org.ehrbase.openehr.sdk.client.openehrclient.TemplateEndpoint; @@ -330,11 +329,6 @@ public DirectoryCrudEndpoint directoryCrudEndpoint(UUID ehrId) { return new DefaultCrudEndpoint(this, ehrId); } - @Override - public FolderDAO folder(UUID ehrId, String path) { - return new DefaultRestDirectoryEndpoint(this, ehrId).getFolder(path); - } - @Override public TemplateEndpoint templateEndpoint() { return new DefaultRestTemplateEndpoint(this); diff --git a/client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestDirectoryEndpoint.java b/client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestDirectoryEndpoint.java deleted file mode 100644 index 4ed4e7dce..000000000 --- a/client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestDirectoryEndpoint.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2019 vitasystems GmbH and Hannover Medical School. - * - * This file is part of project openEHR_SDK - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.ehrbase.openehr.sdk.client.openehrclient.defaultrestclient; - -import static org.ehrbase.openehr.sdk.client.openehrclient.defaultrestclient.DefaultRestEhrEndpoint.EHR_PATH; - -import com.nedap.archie.rm.datavalues.DvText; -import com.nedap.archie.rm.directory.Folder; -import com.nedap.archie.rm.support.identification.ObjectVersionId; -import java.net.URI; -import java.util.ArrayList; -import java.util.Optional; -import java.util.UUID; -import org.apache.commons.lang3.StringUtils; -import org.ehrbase.openehr.sdk.client.openehrclient.CompositionEndpoint; -import org.ehrbase.openehr.sdk.client.openehrclient.FolderDAO; -import org.ehrbase.openehr.sdk.response.dto.DirectoryResponseData; -import org.ehrbase.openehr.sdk.util.exception.WrongStatusCodeException; - -public class DefaultRestDirectoryEndpoint { - - static final String FOLDER_DIVIDER = "/"; - private static final String DIRECTORY_PATH = "/directory/"; - private final DefaultRestClient defaultRestClient; - private final UUID ehrId; - private ObjectVersionId rootVersion; - private Folder root; - - DefaultRestDirectoryEndpoint(DefaultRestClient defaultRestClient, UUID ehrId) { - this.defaultRestClient = defaultRestClient; - this.ehrId = ehrId; - syncFromDb(); - } - - public FolderDAO getFolder(String path) { - DefaultRestFolderDAO folderDAO = new DefaultRestFolderDAO(this, path); - folderDAO.sync(); - return folderDAO; - } - - synchronized void syncFromDb() { - try { - retrieveRootFolder(); - } catch (WrongStatusCodeException e) { - createRootFolder(); - } - } - - synchronized void saveToDb() { - rootVersion = defaultRestClient.httpPut(resolve(""), root, rootVersion); - syncFromDb(); - } - - synchronized Folder find(String path) { - if (StringUtils.isBlank(path)) { - return root; - } - String[] split = path.split(FOLDER_DIVIDER); - Folder current = root; - for (String folderName : split) { - Folder newFolder = Optional.of(current) - .map(Folder::getFolders) - .flatMap(l -> l.stream() - .filter(f -> folderName.equals(f.getName().getValue())) - .findAny()) - .orElse(null); - if (newFolder == null) { - newFolder = new Folder(); - newFolder.setArchetypeNodeId("openEHR-EHR-FOLDER.generic.v1"); - newFolder.setName(new DvText(folderName)); - if (current.getFolders() == null) { - current.setFolders(new ArrayList<>()); - } - current.addFolder(newFolder); - } - current = newFolder; - } - - return current; - } - - CompositionEndpoint getCompositionEndpoint() { - return defaultRestClient.compositionEndpoint(ehrId); - } - - DefaultRestClient getDefaultRestClient() { - return defaultRestClient; - } - - UUID getEhrId() { - return ehrId; - } - - private void copyToFolder(Folder folder, DirectoryResponseData responseData) { - folder.setUid(responseData.getUid()); - folder.setName(responseData.getName()); - folder.setDetails(responseData.getDetails()); - folder.setFolders(responseData.getFolders()); - folder.setItems(responseData.getItems()); - } - - private void retrieveRootFolder() throws WrongStatusCodeException { - Optional directoryResponseData = - defaultRestClient.httpGet(resolve(StringUtils.EMPTY), DirectoryResponseData.class); - if (root == null) { - root = initRootFolder(); - } - copyToFolder( - root, directoryResponseData.orElseThrow(() -> new WrongStatusCodeException("Not Found", 404, 200))); - rootVersion = new ObjectVersionId(root.getUid().toString()); - } - - private void createRootFolder() { - root = initRootFolder(); - rootVersion = defaultRestClient.httpPost(resolve(""), root); - } - - private Folder initRootFolder() { - var folder = new Folder(); - folder.setName(new DvText("root")); - folder.setArchetypeNodeId("openEHR-EHR-FOLDER.generic.v1"); - return folder; - } - - private URI resolve(String subPath) { - if (StringUtils.isBlank(subPath)) { - return defaultRestClient.getConfig().getBaseUri().resolve(EHR_PATH + ehrId.toString() + DIRECTORY_PATH); - } else { - return defaultRestClient - .getConfig() - .getBaseUri() - .resolve(EHR_PATH + ehrId.toString() + DIRECTORY_PATH + subPath); - } - } -} diff --git a/client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestFolderDAO.java b/client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestFolderDAO.java deleted file mode 100644 index adb38b438..000000000 --- a/client/src/main/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestFolderDAO.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2019 vitasystems GmbH and Hannover Medical School. - * - * This file is part of project openEHR_SDK - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.ehrbase.openehr.sdk.client.openehrclient.defaultrestclient; - -import com.nedap.archie.rm.composition.Composition; -import com.nedap.archie.rm.datavalues.DvText; -import com.nedap.archie.rm.directory.Folder; -import com.nedap.archie.rm.support.identification.ObjectId; -import com.nedap.archie.rm.support.identification.ObjectRef; -import com.nedap.archie.rm.support.identification.ObjectVersionId; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import org.apache.commons.lang3.StringUtils; -import org.ehrbase.openehr.sdk.client.openehrclient.FolderDAO; -import org.ehrbase.openehr.sdk.generator.commons.annotations.Template; -import org.ehrbase.openehr.sdk.generator.commons.aql.condition.Condition; -import org.ehrbase.openehr.sdk.generator.commons.aql.containment.Containment; -import org.ehrbase.openehr.sdk.generator.commons.aql.field.EhrFields; -import org.ehrbase.openehr.sdk.generator.commons.aql.field.NativeSelectAqlField; -import org.ehrbase.openehr.sdk.generator.commons.aql.query.EntityQuery; -import org.ehrbase.openehr.sdk.generator.commons.aql.query.Query; -import org.ehrbase.openehr.sdk.generator.commons.aql.record.Record1; -import org.ehrbase.openehr.sdk.util.exception.ClientException; - -public class DefaultRestFolderDAO implements FolderDAO { - - private final DefaultRestDirectoryEndpoint directoryEndpoint; - private final String path; - - public DefaultRestFolderDAO(DefaultRestDirectoryEndpoint directoryEndpoint, String path) { - this.directoryEndpoint = directoryEndpoint; - this.path = path; - } - - @Override - public String getName() { - directoryEndpoint.syncFromDb(); - return getRmFolder().getName().getValue(); - } - - @Override - public void setName(String name) { - directoryEndpoint.syncFromDb(); - getRmFolder().setName(new DvText(name)); - directoryEndpoint.saveToDb(); - } - - @Override - public Set listSubFolderNames() { - directoryEndpoint.syncFromDb(); - return Optional.of(getRmFolder()).stream() - .map(Folder::getFolders) - .filter(Objects::nonNull) - .flatMap(List::stream) - .map(Folder::getName) - .map(DvText::getValue) - .collect(Collectors.toSet()); - } - - @Override - public Folder getRmFolder() { - return directoryEndpoint.find(path); - } - - @Override - public FolderDAO getSubFolder(String path) { - DefaultRestFolderDAO folderDAO = new DefaultRestFolderDAO( - directoryEndpoint, - Stream.of(this.path, path).filter(StringUtils::isNotBlank).collect(Collectors.joining("//"))); - folderDAO.sync(); - return folderDAO; - } - - @Override - public T addCompositionEntity(T entity) { - T updatedEntity = directoryEndpoint.getCompositionEndpoint().mergeCompositionEntity(entity); - var versionId = DefaultRestCompositionEndpoint.extractVersionUid(updatedEntity) - .orElseThrow(() -> new ClientException(String.format("No Id Element for %s", entity.getClass()))); - addToFolder(versionId); - return updatedEntity; - } - - @Override - public ObjectVersionId addRaw(Composition composition) { - ObjectVersionId versionId = directoryEndpoint.getCompositionEndpoint().mergeRaw(composition); - addToFolder(versionId); - return versionId; - } - - @Override - public List find(Class clazz) { - - Containment compositionContainment = new Containment("COMPOSITION"); - - EntityQuery> query = Query.buildEntityQuery( - compositionContainment, new NativeSelectAqlField<>(compositionContainment, "", clazz)); - - query.where(Condition.equal(EhrFields.EHR_ID(), directoryEndpoint.getEhrId()) - .and(Condition.equal( - new NativeSelectAqlField<>(compositionContainment, "/template_id", String.class), - extractTemplateId(clazz))) - .and(Condition.matches( - new NativeSelectAqlField<>(compositionContainment, "/uid/value", String.class), - getRmFolder().getItems().stream() - .map(ObjectRef::getId) - .map(Object::toString) - .toArray(String[]::new)))); - - List> execute = - directoryEndpoint.getDefaultRestClient().aqlEndpoint().execute(query); - - return execute.stream().map(Record1::value1).collect(Collectors.toList()); - } - - /** - * Returns the items stored in the current folder - * @return The items of the current folder. - */ - @Override - public List> getItems() { - return getRmFolder().getItems(); - } - - void sync() { - getRmFolder(); - directoryEndpoint.saveToDb(); - } - - private String extractTemplateId(Class clazz) { - Template annotation = (Template) clazz.getAnnotation(Template.class); - return annotation.value(); - } - - private void addToFolder(ObjectVersionId versionId) { - addItemToFolder(versionId); - } - - private void addItemToFolder(ObjectVersionId versionId) { - Folder folder = getRmFolder(); - if (folder.getItems() == null) { - folder.setItems(new ArrayList<>()); - } - folder.getItems() - .add(new ObjectRef<>( - new ObjectVersionId(versionId.getObjectId().getValue()), - versionId.getCreatingSystemId().getValue(), - "VERSIONED_COMPOSITION")); - directoryEndpoint.saveToDb(); - } - - @Override - public void addItemToRmFolder(ObjectVersionId versionId) { - addItemToFolder(versionId); - } -} diff --git a/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestAqlEndpointTestIT.java b/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestAqlEndpointTestIT.java index 4ef47f077..84bd53cc6 100644 --- a/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestAqlEndpointTestIT.java +++ b/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestAqlEndpointTestIT.java @@ -39,7 +39,6 @@ import org.ehrbase.openehr.sdk.generator.commons.aql.record.Record1; import org.ehrbase.openehr.sdk.generator.commons.aql.record.Record2; import org.ehrbase.openehr.sdk.generator.commons.aql.record.Record3; -import org.ehrbase.openehr.sdk.generator.commons.aql.top.TopExpresion; import org.ehrbase.openehr.sdk.generator.commons.test_data.dto.BloodPressureTrainingSampleObservationProxy; import org.ehrbase.openehr.sdk.generator.commons.test_data.dto.TestData; import org.ehrbase.openehr.sdk.generator.commons.test_data.dto.ehrbasebloodpressuresimpledev0composition.EhrbaseBloodPressureSimpleDeV0Composition; @@ -61,7 +60,7 @@ void testExecute() { openEhrClient.compositionEndpoint(ehr).mergeCompositionEntity(TestData.buildEhrbaseBloodPressureSimpleDeV0()); Query> query = Query.buildNativeQuery( - "select a/template_id, a/context/start_time from EHR e[ehr_id/value = $ehr_id] contains COMPOSITION a [openEHR-EHR-COMPOSITION.sample_encounter.v1]", + "select a/archetype_details/template_id/value, a/context/start_time from EHR e[ehr_id/value = $ehr_id] contains COMPOSITION a [openEHR-EHR-COMPOSITION.sample_encounter.v1]", String.class, DvDateTime.class); @@ -79,7 +78,7 @@ void testExecuteProxy() { openEhrClient.compositionEndpoint(ehr).mergeCompositionEntity(TestData.buildEhrbaseBloodPressureSimpleDeV0()); Query> query = Query.buildNativeQuery( - "select a/template_id, o from EHR e[ehr_id/value = $ehr_id] contains COMPOSITION a [openEHR-EHR-COMPOSITION.sample_encounter.v1] contains OBSERVATION o ", + "select a/archetype_details/template_id/value, o from EHR e[ehr_id/value = $ehr_id] contains COMPOSITION a [openEHR-EHR-COMPOSITION.sample_encounter.v1] contains OBSERVATION o ", String.class, BloodPressureTrainingSampleObservationProxy.class); @@ -245,12 +244,6 @@ class TestCase { UUID.fromString(comp1.getVersionUid().getObjectId().getValue()), UUID.fromString(comp2.getVersionUid().getObjectId().getValue()))); - testCases.add(new TestCase( - 3, - Condition.exists(containmentObservation.DEVICE).not(), - UUID.fromString(comp1.getVersionUid().getObjectId().getValue()), - UUID.fromString(comp2.getVersionUid().getObjectId().getValue()))); - testCases.forEach(t -> { EntityQuery> entityQuery = Query.buildEntityQuery( containmentComposition, containmentComposition.EHRBASE_BLOOD_PRESSURE_SIMPLE_DE_V0_COMPOSITION); @@ -351,104 +344,19 @@ class TestCase { UUID.fromString(comp3.getVersionUid().getObjectId().getValue()))); testCases.forEach(t -> { - EntityQuery> entityQuery = Query.buildEntityQuery( - containmentComposition, containmentComposition.EHRBASE_BLOOD_PRESSURE_SIMPLE_DE_V0_COMPOSITION); + EntityQuery> entityQuery = + Query.buildEntityQuery( + containmentComposition, + containmentComposition.EHRBASE_BLOOD_PRESSURE_SIMPLE_DE_V0_COMPOSITION, + containmentObservation.SYSTOLIC_MAGNITUDE, + containmentObservation.DIASTOLIC_MAGNITUDE); Parameter ehrIdParameter = entityQuery.buildParameter(); Condition where = Condition.equal(EhrFields.EHR_ID(), ehrIdParameter); entityQuery.where(where).orderBy(t.orderBy); assertThat(openEhrClient.aqlEndpoint().execute(entityQuery, ehrIdParameter.setValue(ehr))) - .extracting(Record1::value1) - .extracting(EhrbaseBloodPressureSimpleDeV0Composition::getVersionUid) - .extracting(ObjectVersionId::getObjectId) - .extracting(UID::getValue) - .extracting(UUID::fromString) - .as("TestCase %s", t.id) - .containsExactly(t.uuids); - }); - } - - @Test - void testExecuteEntityTOP() { - - ehr = openEhrClient.ehrEndpoint().createEhr(); - - EhrbaseBloodPressureSimpleDeV0Composition comp1 = openEhrClient - .compositionEndpoint(ehr) - .mergeCompositionEntity(TestData.buildEhrbaseBloodPressureSimpleDeV0()); - - EhrbaseBloodPressureSimpleDeV0Composition ehrbaseBloodPressureSimpleDeV0Composition = - TestData.buildEhrbaseBloodPressureSimpleDeV0(); - ehrbaseBloodPressureSimpleDeV0Composition - .getBloodPressureTrainingSample() - .get(0) - .setSystolicMagnitude(44d); - EhrbaseBloodPressureSimpleDeV0Composition comp2 = openEhrClient - .compositionEndpoint(ehr) - .mergeCompositionEntity(ehrbaseBloodPressureSimpleDeV0Composition); - - EhrbaseBloodPressureSimpleDeV0Composition ehrbaseBloodPressureSimpleDeV0Composition2 = - TestData.buildEhrbaseBloodPressureSimpleDeV0(); - ehrbaseBloodPressureSimpleDeV0Composition2 - .getBloodPressureTrainingSample() - .get(0) - .setSystolicMagnitude(44d); - ehrbaseBloodPressureSimpleDeV0Composition2 - .getBloodPressureTrainingSample() - .get(0) - .setDiastolicMagnitude(44d); - EhrbaseBloodPressureSimpleDeV0Composition comp3 = openEhrClient - .compositionEndpoint(ehr) - .mergeCompositionEntity(ehrbaseBloodPressureSimpleDeV0Composition2); - - EhrbaseBloodPressureSimpleDeV0CompositionContainment containmentComposition = - EhrbaseBloodPressureSimpleDeV0CompositionContainment.getInstance(); - - BloodPressureTrainingSampleObservationContainment containmentObservation = - BloodPressureTrainingSampleObservationContainment.getInstance(); - - containmentComposition.setContains(containmentObservation); - - class TestCase { - int id; - TopExpresion topExpresion; - UUID[] uuids; - - TestCase(int id, TopExpresion topExpresion, UUID... uuids) { - this.id = id; - this.topExpresion = topExpresion; - this.uuids = uuids; - } - } - - List testCases = new ArrayList<>(); - - testCases.add(new TestCase( - 1, - TopExpresion.forward(1), - UUID.fromString(comp3.getVersionUid().getObjectId().getValue()))); - - /* TODO: Direction is ignored in ehrbase. See https://github.com/ehrbase/ehrbase/issues/265 - testCases.add(new TestCase(2, - TopExpresion.backward(1), - (UUID.fromString(comp1.getVersionUid().getObjectId().getValue()))); - */ - testCases.forEach(t -> { - EntityQuery> entityQuery = Query.buildEntityQuery( - containmentComposition, containmentComposition.EHRBASE_BLOOD_PRESSURE_SIMPLE_DE_V0_COMPOSITION); - - Parameter ehrIdParameter = entityQuery.buildParameter(); - - Condition where = Condition.equal(EhrFields.EHR_ID(), ehrIdParameter); - entityQuery - .top(t.topExpresion) - .where(where) - .orderBy(OrderByExpression.descending(containmentObservation.SYSTOLIC_MAGNITUDE) - .andThenDescending(containmentObservation.DIASTOLIC_MAGNITUDE)); - - assertThat(openEhrClient.aqlEndpoint().execute(entityQuery, ehrIdParameter.setValue(ehr))) - .extracting(Record1::value1) + .extracting(Record3::value1) .extracting(EhrbaseBloodPressureSimpleDeV0Composition::getVersionUid) .extracting(ObjectVersionId::getObjectId) .extracting(UID::getValue) @@ -495,12 +403,12 @@ void testQueryCount() { openEhrClient.compositionEndpoint(ehr).mergeCompositionEntity(TestData.buildEhrbaseBloodPressureSimpleDeV0()); Query> query = Query.buildNativeQuery( - "select count(e/ehr_id/value) from EHR e contains composition c", Integer.class); + "select count(e/ehr_id/value) from EHR e contains COMPOSITION c", Integer.class); List> result = openEhrClient.aqlEndpoint().execute(query); assertThat(result).isNotNull(); - query = Query.buildNativeQuery("select count(c/uid/value) from EHR e contains composition c", Integer.class); + query = Query.buildNativeQuery("select count(c/uid/value) from EHR e contains COMPOSITION c", Integer.class); result = openEhrClient.aqlEndpoint().execute(query); assertThat(result).isNotNull().hasSize(1); diff --git a/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestContributionEndpointIT.java b/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestContributionEndpointIT.java index 2a6f60d25..bf0e32d98 100644 --- a/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestContributionEndpointIT.java +++ b/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestContributionEndpointIT.java @@ -25,17 +25,21 @@ import com.nedap.archie.rm.changecontrol.Contribution; import com.nedap.archie.rm.composition.Composition; +import com.nedap.archie.rm.datatypes.CodePhrase; +import com.nedap.archie.rm.datavalues.DvCodedText; import com.nedap.archie.rm.datavalues.DvText; import com.nedap.archie.rm.directory.Folder; import com.nedap.archie.rm.generic.AuditDetails; +import com.nedap.archie.rm.generic.PartyIdentified; +import com.nedap.archie.rm.support.identification.ObjectRef; import com.nedap.archie.rm.support.identification.ObjectVersionId; +import com.nedap.archie.rm.support.identification.TerminologyId; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Optional; import java.util.UUID; import org.apache.commons.io.IOUtils; import org.ehrbase.openehr.sdk.client.openehrclient.ContributionEndpoint; -import org.ehrbase.openehr.sdk.client.openehrclient.FolderDAO; import org.ehrbase.openehr.sdk.client.openehrclient.builder.ContributionBuilder; import org.ehrbase.openehr.sdk.client.templateprovider.TestDataTemplateProvider; import org.ehrbase.openehr.sdk.generator.commons.test_data.dto.ProxyEhrbaseBloodPressureSimpleDeV0Composition; @@ -58,6 +62,13 @@ public void testSaveAndGetContribution() throws IOException { ContributionCreateDto contributionDto = new CanonicalJson().unmarshal(contribution, ContributionCreateDto.class); + contributionDto.setUid(null); + contributionDto.getAudit().setTimeCommitted(null); + contributionDto.getVersions().stream().forEach(v -> { + v.getCommitAudit().setTimeCommitted(null); + v.setContribution(null); + }); + UUID contributionEntity = openEhrClient.contributionEndpoint(ehr).saveContribution(contributionDto); Optional remoteContribution = @@ -440,9 +451,11 @@ public void testSaveContributionWithFolderCreationModification() throws IOExcept public void testSaveContributionWithFolderModification() throws IOException { ehr = openEhrClient.ehrEndpoint().createEhr(); + Folder rootFolder = new Folder(); // Create root folder - FolderDAO folder = openEhrClient.folder(ehr, ""); - Folder rootFolder = folder.getRmFolder(); + ObjectVersionId directory = openEhrClient.directoryCrudEndpoint(ehr).createDirectory(rootFolder); + + rootFolder.setUid(directory); // Prepare first composition GeneratedDtoToRmConverter generatedDtoToRmConverter = @@ -454,7 +467,10 @@ public void testSaveContributionWithFolderModification() throws IOException { (Composition) generatedDtoToRmConverter.toRMObject(mergeMinimalEvaluationEnV1Composition()); // Add first composition to folder - folder.addItemToRmFolder(new ObjectVersionId((compositionWithId.getUid().toString()))); + rootFolder + .getItems() + .add(new ObjectRef<>( + new ObjectVersionId((compositionWithId.getUid().toString())), "local", "Composition")); // Prepare second composition GeneratedDtoToRmConverter cut = new GeneratedDtoToRmConverter(new TestDataTemplateProvider()); @@ -462,11 +478,14 @@ public void testSaveContributionWithFolderModification() throws IOException { ProxyEhrbaseBloodPressureSimpleDeV0Composition proxyComposition = openEhrClient.compositionEndpoint(ehr).mergeCompositionEntity(proxyDto); Composition unflattenSecondComposition = (Composition) cut.toRMObject(proxyComposition); - unflattenSecondComposition.setUid(null); + unflattenSecondComposition.setUid(new ObjectVersionId(UUID.randomUUID().toString(), "local.ehrbase.org", "1")); - // Add second composition to new folder - FolderDAO subFolder = folder.getSubFolder("test/contribution"); - subFolder.addItemToRmFolder(proxyComposition.getVersionUid()); + // Add second composition + + rootFolder + .getItems() + .add(new ObjectRef<>( + new ObjectVersionId((unflattenSecondComposition.getUid().toString())), "local", "Composition")); // Create contribution ContributionCreateDto contribution = ContributionBuilder.builder(createAuditDetails()) @@ -495,11 +514,8 @@ public void testSaveContributionWithFolderModification() throws IOException { expectedCompositionsCreatedTimes, countNumberOfChangedLocatableObjectByVersion(remoteContribution.get(), "1")); assertEquals( - expectedCompositionsModifiedTimes, + expectedCompositionsModifiedTimes + expectedFolderModifiedTimes, countNumberOfChangedLocatableObjectByVersion(remoteContribution.get(), "2")); - assertEquals( - expectedFolderModifiedTimes, - countNumberOfChangedLocatableObjectByVersion(remoteContribution.get(), "6")); } private static String getCompositionVersion(Contribution remoteContribution) { @@ -514,13 +530,14 @@ private static UUID getCompositionUuid(Composition composition) { return UUID.fromString(compositionId.substring(0, compositionId.indexOf("::"))); } - private static AuditDetails createAuditDetails() throws IOException { - String contributionModificationJson = - IOUtils.toString(ONE_ENTRY_COMPOSITION_MODIFICATION_LATEST.getStream(), StandardCharsets.UTF_8); - ContributionCreateDto contributionDto = - new CanonicalJson().unmarshal(contributionModificationJson, ContributionCreateDto.class); + private static AuditDetails createAuditDetails() { - return contributionDto.getVersions().get(0).getCommitAudit(); + AuditDetails auditDetails = new AuditDetails(); + auditDetails.setChangeType( + new DvCodedText("modification", new CodePhrase(new TerminologyId("openehr"), "251"))); + auditDetails.setCommitter(new PartyIdentified(null, "Dr. Yamamoto", null)); + auditDetails.setSystemId("ehrbase"); + return auditDetails; } private MinimalEvaluationEnV1Composition mergeMinimalEvaluationEnV1Composition() throws IOException { diff --git a/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestDirectoryEndpointIT.java b/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestDirectoryEndpointIT.java deleted file mode 100644 index e04b021cb..000000000 --- a/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestDirectoryEndpointIT.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2019 vitasystems GmbH and Hannover Medical School. - * - * This file is part of project openEHR_SDK - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.ehrbase.openehr.sdk.client.openehrclient.defaultrestclient; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.nedap.archie.rm.composition.Composition; -import java.net.URISyntaxException; -import java.util.List; -import org.ehrbase.openehr.sdk.client.openehrclient.FolderDAO; -import org.ehrbase.openehr.sdk.generator.commons.test_data.dto.TestData; -import org.ehrbase.openehr.sdk.generator.commons.test_data.dto.ehrbasebloodpressuresimpledev0composition.EhrbaseBloodPressureSimpleDeV0Composition; -import org.ehrbase.openehr.sdk.generator.commons.test_data.dto.ehrbasemultioccurrencedev1composition.EhrbaseMultiOccurrenceDeV1Composition; -import org.ehrbase.openehr.sdk.serialisation.dto.GeneratedDtoToRmConverter; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -public class DefaultRestDirectoryEndpointIT extends SdkClientTestIT { - - private static DefaultRestClient defaultRestClient; - - @BeforeAll - public static void setup() throws URISyntaxException { - - SdkClientTestIT.setup(); - defaultRestClient = SdkClientTestIT.setupRestClientWithDefaultTemplateProvider(); - } - - @Test - void testSetName() { - ehr = openEhrClient.ehrEndpoint().createEhr(); - FolderDAO root = openEhrClient.folder(ehr, ""); - assertThat(root.getName()).isEqualTo("root"); - root.setName("case1"); - assertThat(root.getName()).isEqualTo("case1"); - } - - @Test - void testGetSubFolder() { - ehr = openEhrClient.ehrEndpoint().createEhr(); - FolderDAO root = openEhrClient.folder(ehr, ""); - FolderDAO visit = root.getSubFolder("case1/visit1"); - assertThat(visit.getName()).isEqualTo("visit1"); - } - - @Test - void testSaveEntity() { - ehr = openEhrClient.ehrEndpoint().createEhr(); - - FolderDAO root = openEhrClient.folder(ehr, ""); - - FolderDAO visit = root.getSubFolder("case1/visit1"); - - EhrbaseBloodPressureSimpleDeV0Composition bloodPressureSimpleDeV01 = - TestData.buildEhrbaseBloodPressureSimpleDeV0(); - visit.addCompositionEntity(bloodPressureSimpleDeV01); - - EhrbaseBloodPressureSimpleDeV0Composition bloodPressureSimpleDeV02 = - TestData.buildEhrbaseBloodPressureSimpleDeV0(); - visit.addCompositionEntity(bloodPressureSimpleDeV02); - - EhrbaseMultiOccurrenceDeV1Composition ehrbaseMultiOccurrenceDeV1 = TestData.buildEhrbaseMultiOccurrenceDeV1(); - visit.addCompositionEntity(ehrbaseMultiOccurrenceDeV1); - - List actual = - visit.find(EhrbaseBloodPressureSimpleDeV0Composition.class); - assertThat(actual).size().isEqualTo(2); - - List actual2 = visit.find(EhrbaseMultiOccurrenceDeV1Composition.class); - assertThat(actual2).size().isEqualTo(1); - } - - @Test - void testSaveRaw() { - ehr = openEhrClient.ehrEndpoint().createEhr(); - - FolderDAO root = openEhrClient.folder(ehr, ""); - - FolderDAO visit = root.getSubFolder("case1/visit1"); - - Composition composition = (Composition) new GeneratedDtoToRmConverter( - defaultRestClient.getTemplateProvider(), defaultRestClient.getDefaultValuesProvider()) - .toRMObject(TestData.buildEhrbaseBloodPressureSimpleDeV0()); - visit.addRaw(composition); - - List actual = - visit.find(EhrbaseBloodPressureSimpleDeV0Composition.class); - assertThat(actual).size().isEqualTo(1); - } - - @Test - void testListSubFolderNames() { - ehr = openEhrClient.ehrEndpoint().createEhr(); - - FolderDAO root = openEhrClient.folder(ehr, ""); - root.getSubFolder("case1"); - root.getSubFolder("case2"); - root.getSubFolder("case3/visit1"); - root.getSubFolder("case3/visit2"); - - assertThat(root.listSubFolderNames()).containsExactlyInAnyOrder("case1", "case2", "case3"); - - assertThat(root.getSubFolder("case3").listSubFolderNames()).containsExactlyInAnyOrder("visit1", "visit2"); - } -} diff --git a/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestEhrFieldsEndpointIT.java b/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestEhrFieldsEndpointIT.java index 01499f27f..ac65601cb 100644 --- a/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestEhrFieldsEndpointIT.java +++ b/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/DefaultRestEhrFieldsEndpointIT.java @@ -60,7 +60,7 @@ void testCreateEhrWithStatus() { HierObjectId subjectId = new HierObjectId(UUID.randomUUID().toString()); ehrStatus.setSubject(new PartySelf(new PartyRef(subjectId, "default", "PERSON"))); - ehrStatus.setArchetypeNodeId("just-a-status"); + ehrStatus.setArchetypeNodeId("openEHR-EHR-EHR_STATUS.generic.v1"); ehrStatus.setName(new DvText("Status")); ehr = openEhrClient.ehrEndpoint().createEhr(ehrStatus); @@ -83,7 +83,7 @@ void testUpdateEhrStatus() throws IOException { String value = IOUtils.toString(ItemStruktureTestDataCanonicalJson.SIMPLE_EHR_OTHER_Details.getStream(), UTF_8); ehrStatus.setOtherDetails(new CanonicalJson().unmarshal(value, ItemTree.class)); - ehrStatus.getOtherDetails().setArchetypeNodeId("other-details-test"); + ehrStatus.getOtherDetails().setArchetypeNodeId("openEHR-EHR-EHR_STATUS.generic.v1"); ehrStatus.getOtherDetails().setName(new DvText("test")); openEhrClient.ehrEndpoint().updateEhrStatus(ehr, ehrStatus); diff --git a/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/EHRbaseContainer.java b/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/EHRbaseContainer.java index 60894082b..148ae4908 100644 --- a/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/EHRbaseContainer.java +++ b/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/EHRbaseContainer.java @@ -45,7 +45,7 @@ public class EHRbaseContainer extends GenericContainer { protected static final String EHRBASE_PASSWORD = "ehrbase_restricted"; - private static final String IMAGE = "ehrbase/ehrbase:0.32.0"; + private static final String IMAGE = "ehrbase/ehrbase:2.0.0"; private final Logger log = LoggerFactory.getLogger(this.getClass()); diff --git a/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/EHRbasePostgresContainer.java b/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/EHRbasePostgresContainer.java index 2d0abe120..8ec623f8e 100644 --- a/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/EHRbasePostgresContainer.java +++ b/client/src/test/java/org/ehrbase/openehr/sdk/client/openehrclient/defaultrestclient/EHRbasePostgresContainer.java @@ -35,7 +35,7 @@ public class EHRbasePostgresContainer extends GenericContainer { protected static final Integer PORT = 5432; protected static final String CONTAINER_NAME = "postgres"; - private static final String IMAGE = "ehrbase/ehrbase-postgres:13.4.v2"; + private static final String IMAGE = "ehrbase/ehrbase-v2-postgres:16.2"; private static final String POSTGRES_MAPPING_USER = "postgres"; private static final String POSTGRES_MAPPING_PW = "postgres"; diff --git a/pom.xml b/pom.xml index 7f3c93da6..cd1e2213d 100644 --- a/pom.xml +++ b/pom.xml @@ -183,7 +183,11 @@ maven-surefire-plugin + com.github.better-care:web-template-tests ${surefireArgLine} + + **/*Test.java + diff --git a/test-data/src/main/resources/item_structure/canonical_json/ehr_other_details.json b/test-data/src/main/resources/item_structure/canonical_json/ehr_other_details.json index 6a1c99b69..4f4a191fa 100644 --- a/test-data/src/main/resources/item_structure/canonical_json/ehr_other_details.json +++ b/test-data/src/main/resources/item_structure/canonical_json/ehr_other_details.json @@ -11,11 +11,11 @@ "_type": "ARCHETYPED", "archetype_id": { "_type": "ARCHETYPE_ID", - "value": "openEHR-DEMOGRAPHIC-CLUSTER.person_death_data_iso.v0" + "value": "openEHR-EHR-CLUSTER.person_death_data_iso.v0" }, "rm_version": "1.0.2" }, - "archetype_node_id": "openEHR-DEMOGRAPHIC-CLUSTER.person_death_data_iso.v0", + "archetype_node_id": "openEHR-EHR-CLUSTER.person_death_data_iso.v0", "items": [ { "_type": "ELEMENT", @@ -41,11 +41,11 @@ "_type": "ARCHETYPED", "archetype_id": { "_type": "ARCHETYPE_ID", - "value": "openEHR-DEMOGRAPHIC-CLUSTER.person_birth_data_iso.v0" + "value": "openEHR-EHR-CLUSTER.person_birth_data_iso.v0" }, "rm_version": "1.0.2" }, - "archetype_node_id": "openEHR-DEMOGRAPHIC-CLUSTER.person_birth_data_iso.v0", + "archetype_node_id": "openEHR-EHR-CLUSTER.person_birth_data_iso.v0", "items": [ { "_type": "ELEMENT", From 8506b102e6940b5a46871671e041cdca1ed96b01 Mon Sep 17 00:00:00 2001 From: alexlehn Date: Fri, 26 Apr 2024 11:15:35 +0200 Subject: [PATCH 23/32] CDR-1397 Add Execution info to MetaData (#594) --- CHANGELOG.md | 3 +- .../openehr/sdk/response/dto/MetaData.java | 43 ++++++++++++ .../sdk/response/dto/MetaDataTest.java | 70 +++++++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89bd2b79d..2cbba568a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ Note: version releases in the 0.x.y range may introduce breaking changes. ## [unreleased] - ### Added + ### Added +- Added EHRbase AQL `MeataData` debug execution data ([594](https://github.com/ehrbase/openEHR_SDK/pull/594)) ### Changed - Removed OpenEhrClient::getFolder (use directoryCrudEndpoint()::getFolder instead) ([#588](https://github.com/ehrbase/openEHR_SDK/pull/588)) ### Fixed diff --git a/response-dto/src/main/java/org/ehrbase/openehr/sdk/response/dto/MetaData.java b/response-dto/src/main/java/org/ehrbase/openehr/sdk/response/dto/MetaData.java index 04dddd6e0..b163a2d0c 100644 --- a/response-dto/src/main/java/org/ehrbase/openehr/sdk/response/dto/MetaData.java +++ b/response-dto/src/main/java/org/ehrbase/openehr/sdk/response/dto/MetaData.java @@ -51,6 +51,15 @@ public interface AdditionalProperty extends Function { */ String getName(); + @FunctionalInterface + interface BooleanProperty extends MetaData.AdditionalProperty { + + @Override + default Boolean apply(Object o) { + return o instanceof Boolean ? (Boolean) o : null; + } + } + @FunctionalInterface interface IntegerProperty extends AdditionalProperty { @@ -60,6 +69,25 @@ default Integer apply(Object o) { } } + @FunctionalInterface + interface StringProperty extends MetaData.AdditionalProperty { + + @Override + default String apply(Object o) { + return o instanceof String ? (String) o : null; + } + } + + @FunctionalInterface + interface JSONProperty extends MetaData.AdditionalProperty> { + + @SuppressWarnings("unchecked") + @Override + default Map apply(Object o) { + return o instanceof Map ? (Map) o : null; + } + } + /** * Extracted from the query fetch parameter or from the server default. *
@@ -80,6 +108,21 @@ default Integer apply(Object o) {
          * Size of the returned rows.
          */
         IntegerProperty resultSize = () -> "resultsize";
+
+        /**
+         * ehrbase execution-option result - dry_run status
+         */
+        BooleanProperty dryRun = () -> "_dry_run";
+
+        /**
+         * ehrbase execution-option result - executed SQL
+         */
+        StringProperty executedSQL = () -> "_executed_sql";
+
+        /**
+         * ehrbase execution-option result - query plan json
+         */
+        JSONProperty queryPlan = () -> "_query_plan";
     }
 
     @JsonProperty(value = "_href")
diff --git a/response-dto/src/test/java/org/ehrbase/openehr/sdk/response/dto/MetaDataTest.java b/response-dto/src/test/java/org/ehrbase/openehr/sdk/response/dto/MetaDataTest.java
index 05e9c9c5d..eb0adb1de 100644
--- a/response-dto/src/test/java/org/ehrbase/openehr/sdk/response/dto/MetaDataTest.java
+++ b/response-dto/src/test/java/org/ehrbase/openehr/sdk/response/dto/MetaDataTest.java
@@ -28,6 +28,7 @@
 import java.io.IOException;
 import java.time.OffsetDateTime;
 import java.time.ZoneOffset;
+import java.util.Map;
 import org.apache.commons.io.IOUtils;
 import org.ehrbase.openehr.sdk.response.dto.util.DTOFixtures;
 import org.junit.jupiter.api.Test;
@@ -89,6 +90,41 @@ void serializedJSON() throws JsonProcessingException {
                         }""");
     }
 
+    @Test
+    void serializedJSONWithExecutionData() throws JsonProcessingException {
+
+        MetaData metaData = new MetaData();
+        metaData.setHref("https://example.com/subpath/ehrbase/rest/openehr/v1/query/aql");
+        metaData.setType(MetaData.RESULTSET);
+        metaData.setSchemaVersion("1.0.4");
+        metaData.setCreated(OffsetDateTime.parse("2017-08-19T12:30:00.568+02:00"));
+        metaData.setGenerator("DIPS.OpenEhr.ResultSets.Serialization.Json.ResultSetJsonWriter (5.0.0.0)");
+        metaData.setExecutedAql("SELECT e/ehr_id/value FROM EHR e");
+        // debug info
+        metaData.setAdditionalProperty(MetaData.AdditionalProperty.dryRun, true);
+        metaData.setAdditionalProperty(MetaData.AdditionalProperty.executedSQL, "SELECT TRUE");
+        metaData.setAdditionalProperty(MetaData.AdditionalProperty.queryPlan, Map.of("key", "value"));
+
+        String json = objectMapper.writeValueAsString(metaData);
+
+        assertThat(json)
+                .isEqualToNormalizingWhitespace(
+                        """
+                        {
+                          "_href" : "https://example.com/subpath/ehrbase/rest/openehr/v1/query/aql",
+                          "_type" : "RESULTSET",
+                          "_schema_version" : "1.0.4",
+                          "_created" : "2017-08-19T12:30:00.568+02:00",
+                          "_generator" : "DIPS.OpenEhr.ResultSets.Serialization.Json.ResultSetJsonWriter (5.0.0.0)",
+                          "_executed_aql" : "SELECT e/ehr_id/value FROM EHR e",
+                          "_dry_run" : true,
+                          "_executed_sql" : "SELECT TRUE",
+                          "_query_plan" : {
+                            "key" : "value"
+                          }
+                        }""");
+    }
+
     @Test
     void deserializedJSONMinimal() throws JsonProcessingException {
 
@@ -148,6 +184,40 @@ void deserializeJSON() throws JsonProcessingException {
         assertEquals(20, metaData.getAdditionalProperty(MetaData.AdditionalProperty.resultSize));
     }
 
+    @Test
+    void deserializeJSONWithExecutionData() throws JsonProcessingException {
+
+        MetaData metaData = objectMapper.readValue(
+                """
+                        {
+                          "_href" : "https://example.com/ehrbase/rest/openehr/v1/query/aql",
+                          "_type" : "RESULTSET",
+                          "_schema_version" : "1.0.4",
+                          "_created" : "2017-08-19T00:25:47.568+02:00",
+                          "_generator" : "DIPS.OpenEhr.ResultSets.Serialization.Json.ResultSetJsonWriter (5.0.0.0)",
+                          "_executed_aql" : "SELECT e/ehr_id/value FROM EHR e",
+                          "_dry_run" : true,
+                          "_executed_sql" : "SELECT TRUE",
+                          "_query_plan" : {
+                            "key" : "value"
+                          }
+                        }""",
+                MetaData.class);
+
+        assertEquals("https://example.com/ehrbase/rest/openehr/v1/query/aql", metaData.getHref());
+        assertEquals(MetaData.RESULTSET, metaData.getType());
+        assertEquals("1.0.4", metaData.getSchemaVersion());
+        assertEquals(
+                OffsetDateTime.parse("2017-08-19T00:25:47.568+02:00").atZoneSameInstant(ZoneOffset.UTC),
+                metaData.getCreated().atZoneSameInstant(ZoneOffset.UTC));
+        assertEquals(
+                "DIPS.OpenEhr.ResultSets.Serialization.Json.ResultSetJsonWriter (5.0.0.0)", metaData.getGenerator());
+        assertEquals("SELECT e/ehr_id/value FROM EHR e", metaData.getExecutedAql());
+        assertEquals(true, metaData.getAdditionalProperty(MetaData.AdditionalProperty.dryRun));
+        assertEquals("SELECT TRUE", metaData.getAdditionalProperty(MetaData.AdditionalProperty.executedSQL));
+        assertEquals(Map.of("key", "value"), metaData.getAdditionalProperty(MetaData.AdditionalProperty.queryPlan));
+    }
+
     @Test
     void deserializeRealWorldExample() throws IOException {
 

From eae879858024d203ccf886a1135f23d9e88636d5 Mon Sep 17 00:00:00 2001
From: Alex Vidrean 
Date: Fri, 26 Apr 2024 16:29:49 +0300
Subject: [PATCH 24/32] Fix invalid github action naming

---
 .github/workflows/build.yml     | 2 +-
 .github/workflows/codeql.yml    | 2 +-
 .github/workflows/codestyle.yml | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 60dc160a8..6da034c0d 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,7 +1,7 @@
 name: build
 
 # we have multiple workflows - this helps to distinguish for them
-run-name: "${{ github.event_name == 'pull_request' && github.event.pull_request.title || github.head_ref }} - Build & Test"
+run-name: "${{ github.event.pull_request.title && github.event.pull_request.title || github.ref_name }} - Build & Test"
 
 on:
   push:
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index c45f67c30..eb4d0e510 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -12,7 +12,7 @@
 name: "CodeQL"
 
 # we have multiple workflows - this helps to distinguish for them
-run-name: "${{ github.event_name == 'pull_request' && github.event.pull_request.title || github.head_ref }} - CodeQL"
+run-name: "${{ github.event.pull_request.title && github.event.pull_request.title || github.ref_name }} - CodeQL"
 
 on:
   push:
diff --git a/.github/workflows/codestyle.yml b/.github/workflows/codestyle.yml
index cad512c58..db76b6522 100644
--- a/.github/workflows/codestyle.yml
+++ b/.github/workflows/codestyle.yml
@@ -1,7 +1,7 @@
 name: "Codestyle"
 
 # we have multiple workflows - this helps to distinguish for them
-run-name: "${{ github.event_name == 'pull_request' && github.event.pull_request.title || github.head_ref }} - Codestyle"
+run-name: "${{ github.event.pull_request.title && github.event.pull_request.title || github.ref_name }} - Codestyle"
 
 on:
   push:

From 46cad9ec007a0fb38edb223d36e6664372254d58 Mon Sep 17 00:00:00 2001
From: "vinzenz.mueller" 
Date: Thu, 25 Apr 2024 12:03:12 +0200
Subject: [PATCH 25/32] CDR-1341 ignore node_id for non locatables in OPT

---
 .../openehr/sdk/webtemplate/parser/OPTParser.java    | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/web-template/src/main/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParser.java b/web-template/src/main/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParser.java
index f559da184..7b7ff41a4 100644
--- a/web-template/src/main/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParser.java
+++ b/web-template/src/main/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParser.java
@@ -109,6 +109,11 @@ public class OPTParser {
     public static final String OPENEHR = "openehr";
     public static final String CURRENT_STATE = "current_state";
 
+    private static final Set LOCATABLE_TYPES =
+            ArchieRMInfoLookup.getInstance().getTypeInfo(Locatable.class).getAllDescendantClasses().stream()
+                    .map(RMTypeInfo::getRmName)
+                    .collect(Collectors.toSet());
+
     private final OPERATIONALTEMPLATE operationaltemplate;
     private final String defaultLanguage;
     private final Map defaultValues = new HashMap<>();
@@ -851,7 +856,7 @@ private List parseCOBJECT(
             return parseCARCHETYPEROO((CARCHETYPEROOT) cobject, pathLoop);
 
         } else if (cobject instanceof CCOMPLEXOBJECT) {
-            String nodeId = cobject.getNodeId();
+            String nodeId = LOCATABLE_TYPES.contains(cobject.getRmTypeName()) ? cobject.getNodeId() : null;
             final AqlPath pathLoop;
             if (StringUtils.isNotBlank(nodeId)) {
                 pathLoop = aqlPath.replaceLastNode(n -> n.withAtCode(nodeId));
@@ -1114,7 +1119,10 @@ private WebTemplateNode buildNode(
         IntervalOfInteger occurrences = cobject.getOccurrences();
         node.setMin(occurrences.getLowerUnbounded() ? -1 : occurrences.getLower());
         node.setMax(occurrences.getUpperUnbounded() ? -1 : occurrences.getUpper());
-        String nodeId = cobject.getNodeId();
+
+        /*This check is a workaround for a bug in the archetype designer, due to which non-LOCATABLEs may have a node_id.
+        The generated opt is invalid, but we still accept it and ignore the node_id in this case.*/
+        String nodeId = LOCATABLE_TYPES.contains(cobject.getRmTypeName()) ? cobject.getNodeId() : null;
         if (StringUtils.isNotBlank(nodeId)) {
 
             Optional expliziteName =

From 558a6446b6fc71d7e65f275fad62170c6edd6a69 Mon Sep 17 00:00:00 2001
From: "vinzenz.mueller" 
Date: Thu, 25 Apr 2024 12:44:46 +0200
Subject: [PATCH 26/32] CDR-1341 Workaround check as method

---
 .../sdk/webtemplate/parser/OPTParser.java       | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/web-template/src/main/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParser.java b/web-template/src/main/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParser.java
index 7b7ff41a4..cdd21bf67 100644
--- a/web-template/src/main/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParser.java
+++ b/web-template/src/main/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParser.java
@@ -856,7 +856,7 @@ private List parseCOBJECT(
             return parseCARCHETYPEROO((CARCHETYPEROOT) cobject, pathLoop);
 
         } else if (cobject instanceof CCOMPLEXOBJECT) {
-            String nodeId = LOCATABLE_TYPES.contains(cobject.getRmTypeName()) ? cobject.getNodeId() : null;
+            String nodeId = isLocatableNode(cobject) ? cobject.getNodeId() : null;
             final AqlPath pathLoop;
             if (StringUtils.isNotBlank(nodeId)) {
                 pathLoop = aqlPath.replaceLastNode(n -> n.withAtCode(nodeId));
@@ -866,7 +866,7 @@ private List parseCOBJECT(
             return parseCCOMPLEXOBJECT((CCOMPLEXOBJECT) cobject, pathLoop, termDefinitionMap, rmAttributeName);
 
         } else if (cobject instanceof CDOMAINTYPE) {
-            String nodeId = cobject.getNodeId();
+            String nodeId = isLocatableNode(cobject) ? cobject.getNodeId() : null;
             final AqlPath pathLoop;
             if (StringUtils.isNotBlank(nodeId)) {
                 pathLoop = aqlPath.replaceLastNode(n -> n.withAtCode(nodeId));
@@ -896,6 +896,15 @@ private List parseCOBJECT(
         return null;
     }
 
+    /**
+     * This check is a workaround for a bug in the archetype designer, due to which non-LOCATABLEs may have a node_id.
+     * The generated opt is invalid, but we still accept it and ignore the node_id in this case.
+     * @return true if the given nodes rm_type_name is a LOCATABLE type name
+     */
+    private static boolean isLocatableNode(final COBJECT cobject) {
+        return LOCATABLE_TYPES.contains(cobject.getRmTypeName());
+    }
+
     private WebTemplateNode parseARCHETYPESLOT(
             ARCHETYPESLOT cobject,
             AqlPath pathLoop,
@@ -1120,9 +1129,7 @@ private WebTemplateNode buildNode(
         node.setMin(occurrences.getLowerUnbounded() ? -1 : occurrences.getLower());
         node.setMax(occurrences.getUpperUnbounded() ? -1 : occurrences.getUpper());
 
-        /*This check is a workaround for a bug in the archetype designer, due to which non-LOCATABLEs may have a node_id.
-        The generated opt is invalid, but we still accept it and ignore the node_id in this case.*/
-        String nodeId = LOCATABLE_TYPES.contains(cobject.getRmTypeName()) ? cobject.getNodeId() : null;
+        String nodeId = isLocatableNode(cobject) ? cobject.getNodeId() : null;
         if (StringUtils.isNotBlank(nodeId)) {
 
             Optional expliziteName =

From 9754d1392e8573f10c01682e4401692a7c33d9d2 Mon Sep 17 00:00:00 2001
From: "vinzenz.mueller" 
Date: Mon, 29 Apr 2024 13:51:53 +0200
Subject: [PATCH 27/32] CDR-1341 add test template + unit test

---
 .../OperationalTemplateTestData.java          |   3 +-
 .../webtemplate/WebTemplateTestData.java      |   3 +-
 .../skipped_invalid_node_ids.opt              | 834 ++++++++++++++++++
 .../webtemplate/skipped_invalid_node_ids.json | 358 ++++++++
 .../sdk/webtemplate/parser/OPTParser.java     |   6 +-
 .../sdk/webtemplate/parser/OPTParserTest.java |  38 +-
 6 files changed, 1233 insertions(+), 9 deletions(-)
 create mode 100644 test-data/src/main/resources/operationaltemplate/skipped_invalid_node_ids.opt
 create mode 100644 test-data/src/main/resources/webtemplate/skipped_invalid_node_ids.json

diff --git a/test-data/src/main/java/org/ehrbase/openehr/sdk/test_data/operationaltemplate/OperationalTemplateTestData.java b/test-data/src/main/java/org/ehrbase/openehr/sdk/test_data/operationaltemplate/OperationalTemplateTestData.java
index b18a2a073..8bb871e95 100644
--- a/test-data/src/main/java/org/ehrbase/openehr/sdk/test_data/operationaltemplate/OperationalTemplateTestData.java
+++ b/test-data/src/main/java/org/ehrbase/openehr/sdk/test_data/operationaltemplate/OperationalTemplateTestData.java
@@ -100,7 +100,8 @@ public enum OperationalTemplateTestData {
             "Template with an used archetypeslot of type ITEM",
             "used-item-archetypeslot.opt",
             "used-item-archetypeslot"),
-    AQL_EXAMPLE("AQL_EXAMPLE", "aql_example.opt", "aql_example");
+    AQL_EXAMPLE("AQL_EXAMPLE", "aql_example.opt", "aql_example"),
+    SKIPPED_INVALID_NODE_IDS("Small template (Schwangerschaftsstatus.opt) with node_id set for non-locatables (/category and /context)","skipped_invalid_node_ids.opt", "skipped_invalid_node_ids");
     //  TEST_ISM("ISM transition test", "test-ism.vitagroup.de.v1.opt", "test-ism.vitagroup.de.v1");
 
     public static final String OPERATIONALTEMPLATE_PATH_SEGMENT = "operationaltemplate";
diff --git a/test-data/src/main/java/org/ehrbase/openehr/sdk/test_data/webtemplate/WebTemplateTestData.java b/test-data/src/main/java/org/ehrbase/openehr/sdk/test_data/webtemplate/WebTemplateTestData.java
index 21627df25..3db524fe8 100644
--- a/test-data/src/main/java/org/ehrbase/openehr/sdk/test_data/webtemplate/WebTemplateTestData.java
+++ b/test-data/src/main/java/org/ehrbase/openehr/sdk/test_data/webtemplate/WebTemplateTestData.java
@@ -31,7 +31,8 @@ public enum WebTemplateTestData {
     ADDICTION("example with multiple languages", "addiction.json"),
     GECCO_DIAGNOSE("example with snomed terminologies", "GECCO_Diagnose.json"),
     TESTING_TEMPLATE_N("Template with fixed values", "Testing_Template_N.json"),
-    IPS_TEMPLATE("IPS Template", "ips_template.json");
+    IPS_TEMPLATE("IPS Template", "ips_template.json"),
+    SKIPPED_INVALID_NODE_IDS("webtemplate for a template containing invalid node_id's (/category and /context)", "skipped_invalid_node_ids.json");
 
     private final String filename;
     private final String description;
diff --git a/test-data/src/main/resources/operationaltemplate/skipped_invalid_node_ids.opt b/test-data/src/main/resources/operationaltemplate/skipped_invalid_node_ids.opt
new file mode 100644
index 000000000..c9579a2ca
--- /dev/null
+++ b/test-data/src/main/resources/operationaltemplate/skipped_invalid_node_ids.opt
@@ -0,0 +1,834 @@
+
+
diff --git a/test-data/src/main/resources/webtemplate/skipped_invalid_node_ids.json b/test-data/src/main/resources/webtemplate/skipped_invalid_node_ids.json
new file mode 100644
index 000000000..a3243061e
--- /dev/null
+++ b/test-data/src/main/resources/webtemplate/skipped_invalid_node_ids.json
@@ -0,0 +1,358 @@
+{
+  "templateId": "skipped_invalid_node_ids",
+  "version": "2.3",
+  "defaultLanguage": "de",
+  "languages": [
+    "de"
+  ],
+  "tree": {
+    "id": "skipped_invalid_node_ids",
+    "name": "skipped_invalid_node_ids",
+    "localizedName": "skipped_invalid_node_ids",
+    "rmType": "COMPOSITION",
+    "nodeId": "openEHR-EHR-COMPOSITION.registereintrag.v1",
+    "min": 1,
+    "max": 1,
+    "localizedNames": {
+      "de": "skipped_invalid_node_ids"
+    },
+    "localizedDescriptions": {
+      "de": "Generische Zusammenstellung zur Darstellung eines Datensatzes für Forschungszwecke."
+    },
+    "children": [
+      {
+        "id": "category",
+        "name": "category",
+        "localizedName": "category",
+        "rmType": "DV_CODED_TEXT",
+        "min": 1,
+        "max": 1,
+        "aqlPath": "/category",
+        "inputs": [
+          {
+            "suffix": "code",
+            "type": "CODED_TEXT",
+            "list": [
+              {
+                "value": "433",
+                "label": "event",
+                "localizedLabels": {
+                  "de": "event"
+                }
+              }
+            ],
+            "terminology": "openehr"
+          }
+        ],
+        "inContext": true
+      },
+      {
+        "id": "context",
+        "name": "context",
+        "localizedName": "context",
+        "rmType": "EVENT_CONTEXT",
+        "min": 1,
+        "max": 1,
+        "aqlPath": "/context",
+        "children": [
+          {
+            "id": "status",
+            "name": "Status",
+            "localizedName": "Status",
+            "rmType": "DV_CODED_TEXT",
+            "nodeId": "at0004",
+            "min": 1,
+            "max": 1,
+            "localizedNames": {
+              "de": "Status"
+            },
+            "localizedDescriptions": {
+              "de": "Status der gelieferten Daten für den Registereintrag. Hinweis: Dies ist nicht der Status einzelner Komponenten."
+            },
+            "aqlPath": "/context/other_context[at0001]/items[at0004]/value",
+            "inputs": [
+              {
+                "suffix": "code",
+                "type": "CODED_TEXT",
+                "list": [
+                  {
+                    "value": "at0010",
+                    "label": "registriert",
+                    "localizedLabels": {
+                      "de": "registriert"
+                    },
+                    "localizedDescriptions": {
+                      "de": "*"
+                    }
+                  },
+                  {
+                    "value": "at0011",
+                    "label": "vorläufig",
+                    "localizedLabels": {
+                      "de": "vorläufig"
+                    },
+                    "localizedDescriptions": {
+                      "de": "*"
+                    }
+                  },
+                  {
+                    "value": "at0012",
+                    "label": "final",
+                    "localizedLabels": {
+                      "de": "final"
+                    },
+                    "localizedDescriptions": {
+                      "de": "*"
+                    }
+                  },
+                  {
+                    "value": "at0013",
+                    "label": "geändert",
+                    "localizedLabels": {
+                      "de": "geändert"
+                    },
+                    "localizedDescriptions": {
+                      "de": "*"
+                    }
+                  }
+                ],
+                "terminology": "local"
+              }
+            ]
+          },
+          {
+            "id": "kategorie",
+            "name": "Kategorie",
+            "localizedName": "Kategorie",
+            "rmType": "DV_TEXT",
+            "nodeId": "at0005",
+            "min": 0,
+            "max": 1,
+            "localizedNames": {
+              "de": "Kategorie"
+            },
+            "localizedDescriptions": {
+              "de": "Die Klassifikation des Registereintrags (z.B. Typ der Observation des FHIR-Profils)."
+            },
+            "aqlPath": "/context/other_context[at0001]/items[at0005]/value",
+            "inputs": [
+              {
+                "type": "TEXT"
+              }
+            ]
+          },
+          {
+            "id": "start_time",
+            "name": "start_time",
+            "rmType": "DV_DATE_TIME",
+            "min": 1,
+            "max": 1,
+            "aqlPath": "/context/start_time",
+            "inputs": [
+              {
+                "type": "DATETIME"
+              }
+            ],
+            "inContext": true
+          },
+          {
+            "id": "setting",
+            "name": "setting",
+            "rmType": "DV_CODED_TEXT",
+            "min": 1,
+            "max": 1,
+            "aqlPath": "/context/setting",
+            "inputs": [
+              {
+                "suffix": "code",
+                "type": "TEXT"
+              },
+              {
+                "suffix": "value",
+                "type": "TEXT"
+              }
+            ],
+            "inContext": true
+          }
+        ]
+      },
+      {
+        "id": "skipped_invalid_node_ids",
+        "name": "skipped_invalid_node_ids",
+        "localizedName": "skipped_invalid_node_ids",
+        "rmType": "OBSERVATION",
+        "nodeId": "openEHR-EHR-OBSERVATION.pregnancy_status.v0",
+        "min": 1,
+        "max": 1,
+        "localizedNames": {
+          "de": "skipped_invalid_node_ids"
+        },
+        "localizedDescriptions": {
+          "de": "Angabe darüber, ob die Person schwanger ist oder schwanger sein könnte oder nicht."
+        },
+        "aqlPath": "/content[openEHR-EHR-OBSERVATION.pregnancy_status.v0]",
+        "children": [
+          {
+            "id": "status",
+            "name": "Status",
+            "localizedName": "Status",
+            "rmType": "DV_CODED_TEXT",
+            "nodeId": "at0011",
+            "min": 1,
+            "max": 1,
+            "localizedNames": {
+              "de": "Status"
+            },
+            "localizedDescriptions": {
+              "de": "Liegt eine Schwangerschaft vor?"
+            },
+            "aqlPath": "/content[openEHR-EHR-OBSERVATION.pregnancy_status.v0]/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value",
+            "inputs": [
+              {
+                "suffix": "code",
+                "type": "CODED_TEXT",
+                "list": [
+                  {
+                    "value": "at0012",
+                    "label": "Schwanger",
+                    "localizedLabels": {
+                      "de": "Schwanger"
+                    },
+                    "localizedDescriptions": {
+                      "de": "Die Person ist schwanger."
+                    }
+                  },
+                  {
+                    "value": "at0013",
+                    "label": "Nicht schwanger",
+                    "localizedLabels": {
+                      "de": "Nicht schwanger"
+                    },
+                    "localizedDescriptions": {
+                      "de": "Die Person ist nicht schwanger."
+                    }
+                  },
+                  {
+                    "value": "at0014",
+                    "label": "Unbekannt",
+                    "localizedLabels": {
+                      "de": "Unbekannt"
+                    },
+                    "localizedDescriptions": {
+                      "de": "Es ist nicht bekannt, ob die Person schwanger ist oder nicht."
+                    }
+                  }
+                ],
+                "terminology": "local"
+              }
+            ]
+          },
+          {
+            "id": "time",
+            "name": "time",
+            "rmType": "DV_DATE_TIME",
+            "min": 1,
+            "max": 1,
+            "aqlPath": "/content[openEHR-EHR-OBSERVATION.pregnancy_status.v0]/data[at0001]/events[at0002]/time",
+            "inputs": [
+              {
+                "type": "DATETIME"
+              }
+            ],
+            "inContext": true
+          },
+          {
+            "id": "subject",
+            "name": "subject",
+            "rmType": "PARTY_PROXY",
+            "min": 1,
+            "max": 1,
+            "aqlPath": "/content[openEHR-EHR-OBSERVATION.pregnancy_status.v0]/subject",
+            "inputs": [
+              {
+                "suffix": "id",
+                "type": "TEXT"
+              },
+              {
+                "suffix": "id_scheme",
+                "type": "TEXT"
+              },
+              {
+                "suffix": "id_namespace",
+                "type": "TEXT"
+              },
+              {
+                "suffix": "name",
+                "type": "TEXT"
+              }
+            ],
+            "inContext": true
+          },
+          {
+            "id": "language",
+            "name": "language",
+            "rmType": "CODE_PHRASE",
+            "min": 1,
+            "max": 1,
+            "aqlPath": "/content[openEHR-EHR-OBSERVATION.pregnancy_status.v0]/language",
+            "inContext": true
+          },
+          {
+            "id": "encoding",
+            "name": "encoding",
+            "rmType": "CODE_PHRASE",
+            "min": 1,
+            "max": 1,
+            "aqlPath": "/content[openEHR-EHR-OBSERVATION.pregnancy_status.v0]/encoding",
+            "inContext": true
+          }
+        ]
+      },
+      {
+        "id": "composer",
+        "name": "composer",
+        "rmType": "PARTY_PROXY",
+        "min": 1,
+        "max": 1,
+        "aqlPath": "/composer",
+        "inputs": [
+          {
+            "suffix": "id",
+            "type": "TEXT"
+          },
+          {
+            "suffix": "id_scheme",
+            "type": "TEXT"
+          },
+          {
+            "suffix": "id_namespace",
+            "type": "TEXT"
+          },
+          {
+            "suffix": "name",
+            "type": "TEXT"
+          }
+        ],
+        "inContext": true
+      },
+      {
+        "id": "language",
+        "name": "language",
+        "rmType": "CODE_PHRASE",
+        "min": 1,
+        "max": 1,
+        "aqlPath": "/language",
+        "inContext": true
+      },
+      {
+        "id": "territory",
+        "name": "territory",
+        "rmType": "CODE_PHRASE",
+        "min": 1,
+        "max": 1,
+        "aqlPath": "/territory",
+        "inContext": true
+      }
+    ]
+  }
+}
diff --git a/web-template/src/main/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParser.java b/web-template/src/main/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParser.java
index cdd21bf67..24aa9c427 100644
--- a/web-template/src/main/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParser.java
+++ b/web-template/src/main/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParser.java
@@ -167,7 +167,7 @@ public WebTemplate parse() {
             annotationMap.put(annotation.getPath().replaceAll("^[^/]+", ""), items);
         }
 
-        webTemplate.setTree(parseCARCHETYPEROO(operationaltemplate.getDefinition(), AqlPath.EMPTY_PATH)
+        webTemplate.setTree(parseCARCHETYPEROOT(operationaltemplate.getDefinition(), AqlPath.EMPTY_PATH)
                 .get(0));
         return webTemplate;
     }
@@ -237,7 +237,7 @@ private List buildList(NodeList list) {
         return nodes;
     }
 
-    private List parseCARCHETYPEROO(CARCHETYPEROOT carchetyperoot, AqlPath aqlPath) {
+    private List parseCARCHETYPEROOT(CARCHETYPEROOT carchetyperoot, AqlPath aqlPath) {
 
         // extract local Terminologies
         Map> termDefinitionMap = new HashMap<>();
@@ -853,7 +853,7 @@ private List parseCOBJECT(
             } else {
                 pathLoop = aqlPath;
             }
-            return parseCARCHETYPEROO((CARCHETYPEROOT) cobject, pathLoop);
+            return parseCARCHETYPEROOT((CARCHETYPEROOT) cobject, pathLoop);
 
         } else if (cobject instanceof CCOMPLEXOBJECT) {
             String nodeId = isLocatableNode(cobject) ? cobject.getNodeId() : null;
diff --git a/web-template/src/test/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParserTest.java b/web-template/src/test/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParserTest.java
index 66be8b5c6..b95dc38ca 100644
--- a/web-template/src/test/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParserTest.java
+++ b/web-template/src/test/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParserTest.java
@@ -23,7 +23,12 @@
 import com.fasterxml.jackson.databind.ObjectMapper;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
@@ -36,9 +41,13 @@
 import org.ehrbase.openehr.sdk.test_data.operationaltemplate.OperationalTemplateTestData;
 import org.ehrbase.openehr.sdk.test_data.webtemplate.WebTemplateTestData;
 import org.ehrbase.openehr.sdk.webtemplate.filter.Filter;
-import org.ehrbase.openehr.sdk.webtemplate.model.*;
-import org.junit.Test;
+import org.ehrbase.openehr.sdk.webtemplate.model.WebTemplate;
+import org.ehrbase.openehr.sdk.webtemplate.model.WebTemplateAnnotation;
+import org.ehrbase.openehr.sdk.webtemplate.model.WebTemplateInput;
+import org.ehrbase.openehr.sdk.webtemplate.model.WebTemplateInputValue;
+import org.ehrbase.openehr.sdk.webtemplate.model.WebTemplateNode;
 import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
 import org.openehr.schemas.v1.OPERATIONALTEMPLATE;
 import org.openehr.schemas.v1.TemplateDocument;
 
@@ -48,6 +57,27 @@
  */
 public class OPTParserTest {
 
+
+    @Test
+    void parsingSkipsInvalidNodeIds() throws XmlException, IOException {
+        OPERATIONALTEMPLATE template = TemplateDocument.Factory.parse(
+                        OperationalTemplateTestData.SKIPPED_INVALID_NODE_IDS.getStream())
+                .getTemplate();
+
+        OPTParser cut = new OPTParser(template);
+        WebTemplate actual = cut.parse();
+        actual = new Filter().filter(actual);
+        assertThat(actual).isNotNull();
+
+        ObjectMapper objectMapper = new ObjectMapper();
+        WebTemplate expected = objectMapper.readValue(
+                IOUtils.toString(WebTemplateTestData.SKIPPED_INVALID_NODE_IDS.getStream(), StandardCharsets.UTF_8), WebTemplate.class);
+
+        List errors = compareWebTemplate(actual, expected);
+
+        checkErrors(errors);
+    }
+
     @Test
     public void parseCoronaAnamnese() throws IOException, XmlException {
         OPERATIONALTEMPLATE template = TemplateDocument.Factory.parse(
@@ -408,7 +438,7 @@ public void parseMultimediaTest() throws Exception {
         assertThat(nodes).hasSize(2);
     }
 
-    public void checkErrors(List errors, String[] expectedErrors) {
+    public void checkErrors(List errors, String... expectedErrors) {
 
         SoftAssertions softAssertions = new SoftAssertions();
 

From c88aed874179c32d03b29dd53c2b79a689ed666b Mon Sep 17 00:00:00 2001
From: "vinzenz.mueller" 
Date: Mon, 29 Apr 2024 14:50:36 +0200
Subject: [PATCH 28/32] CDR-1341 Fix test from Better failing due to flat-json
 based on template with context having a node_id

---
 .../conformance_test/extern/CompositionConverterImp.java    | 6 ++++++
 .../operationaltemplate/OperationalTemplateTestData.java    | 5 ++++-
 .../sdk/test_data/webtemplate/WebTemplateTestData.java      | 4 +++-
 .../openehr/sdk/webtemplate/parser/OPTParserTest.java       | 4 ++--
 4 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/serialisation_conformance_test/src/test/java/org/ehrbase/openehr/sdk/conformance_test/extern/CompositionConverterImp.java b/serialisation_conformance_test/src/test/java/org/ehrbase/openehr/sdk/conformance_test/extern/CompositionConverterImp.java
index c1a8f4587..2e519d6be 100644
--- a/serialisation_conformance_test/src/test/java/org/ehrbase/openehr/sdk/conformance_test/extern/CompositionConverterImp.java
+++ b/serialisation_conformance_test/src/test/java/org/ehrbase/openehr/sdk/conformance_test/extern/CompositionConverterImp.java
@@ -296,6 +296,12 @@ public String convertFlatToRaw(
         replaceKey(currentValues, "cda_document/cda_component:0/name", "cda_document/cda_component:0/_name");
         replaceKey(currentValues, "cda_document/cda_component:1/name", "cda_document/cda_component:1/_name");
 
+        // fix context having id event_context due to node_id being present in OPT
+        replaceKey(
+                currentValues,
+                "multidisciplinary_individualised_falls_care_plan/event_context/xds_metadata:0/author_specialty",
+                "multidisciplinary_individualised_falls_care_plan/context/xds_metadata:0/author_specialty");
+
         Composition composition = flatJson.unmarshal(OBJECT_MAPPER.writeValueAsString(currentValues));
         String raw = new CanonicalJson().marshal(composition).replace("\"_type\"", "\"@class\"");
 
diff --git a/test-data/src/main/java/org/ehrbase/openehr/sdk/test_data/operationaltemplate/OperationalTemplateTestData.java b/test-data/src/main/java/org/ehrbase/openehr/sdk/test_data/operationaltemplate/OperationalTemplateTestData.java
index 8bb871e95..06be90e98 100644
--- a/test-data/src/main/java/org/ehrbase/openehr/sdk/test_data/operationaltemplate/OperationalTemplateTestData.java
+++ b/test-data/src/main/java/org/ehrbase/openehr/sdk/test_data/operationaltemplate/OperationalTemplateTestData.java
@@ -101,7 +101,10 @@ public enum OperationalTemplateTestData {
             "used-item-archetypeslot.opt",
             "used-item-archetypeslot"),
     AQL_EXAMPLE("AQL_EXAMPLE", "aql_example.opt", "aql_example"),
-    SKIPPED_INVALID_NODE_IDS("Small template (Schwangerschaftsstatus.opt) with node_id set for non-locatables (/category and /context)","skipped_invalid_node_ids.opt", "skipped_invalid_node_ids");
+    SKIPPED_INVALID_NODE_IDS(
+            "Small template (Schwangerschaftsstatus.opt) with node_id set for non-locatables (/category and /context)",
+            "skipped_invalid_node_ids.opt",
+            "skipped_invalid_node_ids");
     //  TEST_ISM("ISM transition test", "test-ism.vitagroup.de.v1.opt", "test-ism.vitagroup.de.v1");
 
     public static final String OPERATIONALTEMPLATE_PATH_SEGMENT = "operationaltemplate";
diff --git a/test-data/src/main/java/org/ehrbase/openehr/sdk/test_data/webtemplate/WebTemplateTestData.java b/test-data/src/main/java/org/ehrbase/openehr/sdk/test_data/webtemplate/WebTemplateTestData.java
index 3db524fe8..53ed47d6f 100644
--- a/test-data/src/main/java/org/ehrbase/openehr/sdk/test_data/webtemplate/WebTemplateTestData.java
+++ b/test-data/src/main/java/org/ehrbase/openehr/sdk/test_data/webtemplate/WebTemplateTestData.java
@@ -32,7 +32,9 @@ public enum WebTemplateTestData {
     GECCO_DIAGNOSE("example with snomed terminologies", "GECCO_Diagnose.json"),
     TESTING_TEMPLATE_N("Template with fixed values", "Testing_Template_N.json"),
     IPS_TEMPLATE("IPS Template", "ips_template.json"),
-    SKIPPED_INVALID_NODE_IDS("webtemplate for a template containing invalid node_id's (/category and /context)", "skipped_invalid_node_ids.json");
+    SKIPPED_INVALID_NODE_IDS(
+            "webtemplate for a template containing invalid node_id's (/category and /context)",
+            "skipped_invalid_node_ids.json");
 
     private final String filename;
     private final String description;
diff --git a/web-template/src/test/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParserTest.java b/web-template/src/test/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParserTest.java
index b95dc38ca..11b3fd26b 100644
--- a/web-template/src/test/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParserTest.java
+++ b/web-template/src/test/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParserTest.java
@@ -57,7 +57,6 @@
  */
 public class OPTParserTest {
 
-
     @Test
     void parsingSkipsInvalidNodeIds() throws XmlException, IOException {
         OPERATIONALTEMPLATE template = TemplateDocument.Factory.parse(
@@ -71,7 +70,8 @@ void parsingSkipsInvalidNodeIds() throws XmlException, IOException {
 
         ObjectMapper objectMapper = new ObjectMapper();
         WebTemplate expected = objectMapper.readValue(
-                IOUtils.toString(WebTemplateTestData.SKIPPED_INVALID_NODE_IDS.getStream(), StandardCharsets.UTF_8), WebTemplate.class);
+                IOUtils.toString(WebTemplateTestData.SKIPPED_INVALID_NODE_IDS.getStream(), StandardCharsets.UTF_8),
+                WebTemplate.class);
 
         List errors = compareWebTemplate(actual, expected);
 

From cdde7b253661e1bd6eec4de4b4cad6fd856031b9 Mon Sep 17 00:00:00 2001
From: "vinzenz.mueller" 
Date: Mon, 29 Apr 2024 15:14:26 +0200
Subject: [PATCH 29/32] Update CHANGELOG.md

---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2cbba568a..d8984a516 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@ Note: version releases in the 0.x.y range may introduce breaking changes.
  ### Added
 - Added EHRbase AQL `MeataData` debug execution data ([594](https://github.com/ehrbase/openEHR_SDK/pull/594))
  ### Changed
+- OptParser now ignores node_id tags for all RM types that are not subtypes of LOCATABLE ([#596](https://github.com/ehrbase/openEHR_SDK/pull/596))
 - Removed OpenEhrClient::getFolder (use directoryCrudEndpoint()::getFolder instead) ([#588](https://github.com/ehrbase/openEHR_SDK/pull/588))
  ### Fixed 
 - Migrated test to run against EHRbase v2 ([#588](https://github.com/ehrbase/openEHR_SDK/pull/588))

From e071bb707b88daa79aa32d7060da30f0957b3633 Mon Sep 17 00:00:00 2001
From: "vinzenz.mueller" 
Date: Mon, 29 Apr 2024 15:17:40 +0200
Subject: [PATCH 30/32] Cleanup public modifiers in test class after switching
 it to JUnit 5

---
 .../sdk/webtemplate/parser/OPTParserTest.java | 36 +++++++++----------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/web-template/src/test/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParserTest.java b/web-template/src/test/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParserTest.java
index 11b3fd26b..7bc492081 100644
--- a/web-template/src/test/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParserTest.java
+++ b/web-template/src/test/java/org/ehrbase/openehr/sdk/webtemplate/parser/OPTParserTest.java
@@ -55,7 +55,7 @@
  * @author Stefan Spiska
  * @since 1.0
  */
-public class OPTParserTest {
+class OPTParserTest {
 
     @Test
     void parsingSkipsInvalidNodeIds() throws XmlException, IOException {
@@ -79,7 +79,7 @@ void parsingSkipsInvalidNodeIds() throws XmlException, IOException {
     }
 
     @Test
-    public void parseCoronaAnamnese() throws IOException, XmlException {
+    void parseCoronaAnamnese() throws IOException, XmlException {
         OPERATIONALTEMPLATE template = TemplateDocument.Factory.parse(
                         OperationalTemplateTestData.CORONA_ANAMNESE.getStream())
                 .getTemplate();
@@ -103,7 +103,7 @@ public void parseCoronaAnamnese() throws IOException, XmlException {
     }
 
     @Test
-    public void parseAQLExample() throws IOException, XmlException {
+    void parseAQLExample() throws IOException, XmlException {
         OPERATIONALTEMPLATE template = TemplateDocument.Factory.parse(
                         OperationalTemplateTestData.AQL_EXAMPLE.getStream())
                 .getTemplate();
@@ -115,7 +115,7 @@ public void parseAQLExample() throws IOException, XmlException {
     }
 
     @Test
-    public void parseTestingTemplateN() throws IOException, XmlException {
+    void parseTestingTemplateN() throws IOException, XmlException {
 
         OPERATIONALTEMPLATE template = TemplateDocument.Factory.parse(
                         OperationalTemplateTestData.TESTING_TEMPLATE_N.getStream())
@@ -145,7 +145,7 @@ public void parseTestingTemplateN() throws IOException, XmlException {
     }
 
     @Test
-    public void parseGECCODiagnose() throws IOException, XmlException {
+    void parseGECCODiagnose() throws IOException, XmlException {
         OPERATIONALTEMPLATE template = TemplateDocument.Factory.parse(
                         OperationalTemplateTestData.GECCO_DIAGNOSE.getStream())
                 .getTemplate();
@@ -173,7 +173,7 @@ public void parseGECCODiagnose() throws IOException, XmlException {
     }
 
     @Test
-    public void parseAltEvents() throws IOException, XmlException {
+    void parseAltEvents() throws IOException, XmlException {
         OPERATIONALTEMPLATE template = TemplateDocument.Factory.parse(
                         OperationalTemplateTestData.ALT_EVENTS.getStream())
                 .getTemplate();
@@ -203,7 +203,7 @@ public void parseAltEvents() throws IOException, XmlException {
     }
 
     @Test
-    public void parseMultiOccurrence() throws IOException, XmlException {
+    void parseMultiOccurrence() throws IOException, XmlException {
         OPERATIONALTEMPLATE template = TemplateDocument.Factory.parse(
                         OperationalTemplateTestData.MULTI_OCCURRENCE.getStream())
                 .getTemplate();
@@ -226,7 +226,7 @@ public void parseMultiOccurrence() throws IOException, XmlException {
     }
 
     @Test
-    public void parseAny() throws IOException, XmlException {
+    void parseAny() throws IOException, XmlException {
         OPERATIONALTEMPLATE template = TemplateDocument.Factory.parse(
                         OperationalTemplateTestData.GECCO_SEROLOGISCHER_BEFUND.getStream())
                 .getTemplate();
@@ -255,7 +255,7 @@ public void parseAny() throws IOException, XmlException {
     }
 
     @Test
-    public void testUnsupportedDataTypes() throws IOException, XmlException {
+    void testUnsupportedDataTypes() throws IOException, XmlException {
         OPERATIONALTEMPLATE template = TemplateDocument.Factory.parse(getClass()
                         .getResourceAsStream(
                                 "/" + OPERATIONALTEMPLATE_PATH_SEGMENT + "/unsupported_data_type_dv_scale.opt"))
@@ -269,7 +269,7 @@ public void testUnsupportedDataTypes() throws IOException, XmlException {
     }
 
     @Test
-    public void parseInitialAssessment() throws IOException, XmlException {
+    void parseInitialAssessment() throws IOException, XmlException {
         OPERATIONALTEMPLATE template = TemplateDocument.Factory.parse(
                         OperationalTemplateTestData.INITIAL_ASSESSMENT.getStream())
                 .getTemplate();
@@ -289,7 +289,7 @@ public void parseInitialAssessment() throws IOException, XmlException {
     }
 
     @Test
-    public void parseAddiction() throws IOException, XmlException {
+    void parseAddiction() throws IOException, XmlException {
         OPERATIONALTEMPLATE template = TemplateDocument.Factory.parse(OperationalTemplateTestData.ADDICTION.getStream())
                 .getTemplate();
 
@@ -309,7 +309,7 @@ public void parseAddiction() throws IOException, XmlException {
     }
 
     @Test
-    public void parseConstrainTest() throws IOException, XmlException {
+    void parseConstrainTest() throws IOException, XmlException {
         OPERATIONALTEMPLATE template = TemplateDocument.Factory.parse(
                         OperationalTemplateTestData.CONSTRAIN_TEST.getStream())
                 .getTemplate();
@@ -331,7 +331,7 @@ public void parseConstrainTest() throws IOException, XmlException {
     }
 
     @Test
-    public void parseLanguageTest() throws IOException, XmlException {
+    void parseLanguageTest() throws IOException, XmlException {
         OPERATIONALTEMPLATE template = TemplateDocument.Factory.parse(
                         OperationalTemplateTestData.LANGUAGE_TEST.getStream())
                 .getTemplate();
@@ -355,7 +355,7 @@ public void parseLanguageTest() throws IOException, XmlException {
     }
 
     @Test
-    public void parseAllTypes() throws IOException, XmlException {
+    void parseAllTypes() throws IOException, XmlException {
         OPERATIONALTEMPLATE template = TemplateDocument.Factory.parse(OperationalTemplateTestData.ALL_TYPES.getStream())
                 .getTemplate();
 
@@ -426,7 +426,7 @@ public void parseAllTypes() throws IOException, XmlException {
     }
 
     @Test
-    public void parseMultimediaTest() throws Exception {
+    void parseMultimediaTest() throws Exception {
         var optTemplate = TemplateDocument.Factory.parse(OperationalTemplateTestData.MULTIMEDIA_TEST.getStream())
                 .getTemplate();
         var parser = new OPTParser(optTemplate);
@@ -438,7 +438,7 @@ public void parseMultimediaTest() throws Exception {
         assertThat(nodes).hasSize(2);
     }
 
-    public void checkErrors(List errors, String... expectedErrors) {
+    void checkErrors(List errors, String... expectedErrors) {
 
         SoftAssertions softAssertions = new SoftAssertions();
 
@@ -763,7 +763,7 @@ private Collection compareInputValue(
     }
 
     @Test
-    public void testReadWrite() throws IOException, XmlException {
+    void testReadWrite() throws IOException, XmlException {
         var template = TemplateDocument.Factory.parse(OperationalTemplateTestData.CORONA_ANAMNESE.getStream())
                 .getTemplate();
 
@@ -776,7 +776,7 @@ public void testReadWrite() throws IOException, XmlException {
     }
 
     @Test
-    public void missingNodeIdAndAnnotationsTest() throws IOException, XmlException {
+    void missingNodeIdAndAnnotationsTest() throws IOException, XmlException {
         OPERATIONALTEMPLATE template = TemplateDocument.Factory.parse(OperationalTemplateTestData.NULLID.getStream())
                 .getTemplate();
 

From bcbb53a3fdaba306089d46ef47a08d3420359280 Mon Sep 17 00:00:00 2001
From: vmueller-vg <100680528+vmueller-vg@users.noreply.github.com>
Date: Tue, 30 Apr 2024 10:48:56 +0200
Subject: [PATCH 31/32] Update codestyle.yml

---
 .github/workflows/codestyle.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/codestyle.yml b/.github/workflows/codestyle.yml
index db76b6522..421f092b9 100644
--- a/.github/workflows/codestyle.yml
+++ b/.github/workflows/codestyle.yml
@@ -14,7 +14,7 @@ on:
 # Style-check it's a dedicated workflow. This allows us to open a PR, run all tests and fix styling issue later ;).
 #
 jobs:
-  build:
+  check-codestyle:
     runs-on: ubuntu-latest
 
     steps:

From 00f64479bcc3ffc75ceca576117bcb844553faa2 Mon Sep 17 00:00:00 2001
From: bot 
Date: Tue, 7 May 2024 10:39:37 +0000
Subject: [PATCH 32/32] release 2.10.0: updated version to 2.10.0

---
 CHANGELOG.md                           | 4 ++--
 aql/pom.xml                            | 2 +-
 bom/pom.xml                            | 2 +-
 client/pom.xml                         | 2 +-
 example-generator/pom.xml              | 2 +-
 generator-commons/pom.xml              | 2 +-
 generator-maven-plugin/pom.xml         | 2 +-
 generator/pom.xml                      | 2 +-
 opt-1.4/pom.xml                        | 2 +-
 pom.xml                                | 4 ++--
 response-dto/pom.xml                   | 2 +-
 serialisation/pom.xml                  | 2 +-
 serialisation_conformance_test/pom.xml | 2 +-
 terminology/pom.xml                    | 2 +-
 test-coverage/pom.xml                  | 2 +-
 test-data/pom.xml                      | 2 +-
 util/pom.xml                           | 2 +-
 validation/pom.xml                     | 2 +-
 web-template/pom.xml                   | 2 +-
 19 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index d8984a516..38460bcbb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,7 @@
 
 Note: version releases in the 0.x.y range may introduce breaking changes.
 
-## [unreleased]
+## [2.10.0]
  ### Added
 - Added EHRbase AQL `MeataData` debug execution data ([594](https://github.com/ehrbase/openEHR_SDK/pull/594))
  ### Changed
@@ -401,4 +401,4 @@ Note: version releases in the 0.x.y range may introduce breaking changes.
 [2.8.0]: https://github.com/ehrbase/openEHR_SDK/compare/v2.7.0...v2.8.0
 [2.9.0]: https://github.com/ehrbase/openEHR_SDK/compare/v2.8.0...v2.9.0
 [2.9.1]: https://github.com/ehrbase/openEHR_SDK/compare/v2.9.0...v2.9.1
-[unreleased]: https://github.com/ehrbase/openEHR_SDK/compare/v2.9.1...HEAD
+[2.10.0]: https://github.com/ehrbase/openEHR_SDK/compare/v2.9.1...v2.10.0
diff --git a/aql/pom.xml b/aql/pom.xml
index 997f3b610..d9c5e2097 100644
--- a/aql/pom.xml
+++ b/aql/pom.xml
@@ -25,7 +25,7 @@
     
         org.ehrbase.openehr.sdk
         sdk-parent
-        2.10.0-SNAPSHOT
+        2.10.0
     
 
     aql
diff --git a/bom/pom.xml b/bom/pom.xml
index 2eaf564b0..f53667207 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -8,7 +8,7 @@
 
     bom
     org.ehrbase.openehr.sdk
-    2.10.0-SNAPSHOT
+    2.10.0
     pom
 
     openEHR SDK
diff --git a/client/pom.xml b/client/pom.xml
index 852ca02a1..2a1556f04 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -26,7 +26,7 @@
     
         org.ehrbase.openehr.sdk
         sdk-parent
-        2.10.0-SNAPSHOT
+        2.10.0
     
 
     client
diff --git a/example-generator/pom.xml b/example-generator/pom.xml
index dac0a6b1a..2a0631889 100644
--- a/example-generator/pom.xml
+++ b/example-generator/pom.xml
@@ -5,7 +5,7 @@
     
         sdk-parent
         org.ehrbase.openehr.sdk
-        2.10.0-SNAPSHOT
+        2.10.0
     
     4.0.0
 
diff --git a/generator-commons/pom.xml b/generator-commons/pom.xml
index cb407b842..e2f55f2a3 100644
--- a/generator-commons/pom.xml
+++ b/generator-commons/pom.xml
@@ -6,7 +6,7 @@
     
         org.ehrbase.openehr.sdk
         sdk-parent
-        2.10.0-SNAPSHOT
+        2.10.0
     
 
     generator-commons
diff --git a/generator-maven-plugin/pom.xml b/generator-maven-plugin/pom.xml
index 6722f8706..6d0caa0a3 100644
--- a/generator-maven-plugin/pom.xml
+++ b/generator-maven-plugin/pom.xml
@@ -5,7 +5,7 @@
   
     sdk-parent
     org.ehrbase.openehr.sdk
-    2.10.0-SNAPSHOT
+    2.10.0
   
   4.0.0
 
diff --git a/generator/pom.xml b/generator/pom.xml
index 16e2fe00b..e4966288c 100644
--- a/generator/pom.xml
+++ b/generator/pom.xml
@@ -25,7 +25,7 @@
     
         org.ehrbase.openehr.sdk
         sdk-parent
-        2.10.0-SNAPSHOT
+        2.10.0
     
 
     generator
diff --git a/opt-1.4/pom.xml b/opt-1.4/pom.xml
index 20cae60cf..575d52849 100644
--- a/opt-1.4/pom.xml
+++ b/opt-1.4/pom.xml
@@ -26,7 +26,7 @@
     
         org.ehrbase.openehr.sdk
         sdk-parent
-        2.10.0-SNAPSHOT
+        2.10.0
     
 
     opt-1.4
diff --git a/pom.xml b/pom.xml
index cd1e2213d..8057b62ec 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,13 +25,13 @@
     
         org.ehrbase.openehr.sdk
         bom
-        2.10.0-SNAPSHOT
+        2.10.0
         ./bom/pom.xml
     
 
     org.ehrbase.openehr.sdk
     sdk-parent
-    2.10.0-SNAPSHOT
+    2.10.0
     pom
     openEHR SDK
 
diff --git a/response-dto/pom.xml b/response-dto/pom.xml
index c67aa2bf4..cb667e599 100644
--- a/response-dto/pom.xml
+++ b/response-dto/pom.xml
@@ -26,7 +26,7 @@
   
     org.ehrbase.openehr.sdk
     sdk-parent
-    2.10.0-SNAPSHOT
+    2.10.0
   
 
   response-dto
diff --git a/serialisation/pom.xml b/serialisation/pom.xml
index 3a2be3a79..ca682c8b5 100644
--- a/serialisation/pom.xml
+++ b/serialisation/pom.xml
@@ -26,7 +26,7 @@
     
         org.ehrbase.openehr.sdk
         sdk-parent
-        2.10.0-SNAPSHOT
+        2.10.0
     
 
     serialisation
diff --git a/serialisation_conformance_test/pom.xml b/serialisation_conformance_test/pom.xml
index 82ba4b509..ac9e22cd3 100644
--- a/serialisation_conformance_test/pom.xml
+++ b/serialisation_conformance_test/pom.xml
@@ -26,7 +26,7 @@
     
         org.ehrbase.openehr.sdk
         sdk-parent
-        2.10.0-SNAPSHOT
+        2.10.0
     
 
     serialisation_conformance_test
diff --git a/terminology/pom.xml b/terminology/pom.xml
index 4b1cb64d9..e763da5c5 100644
--- a/terminology/pom.xml
+++ b/terminology/pom.xml
@@ -26,7 +26,7 @@
     
         org.ehrbase.openehr.sdk
         sdk-parent
-        2.10.0-SNAPSHOT
+        2.10.0
     
 
     terminology
diff --git a/test-coverage/pom.xml b/test-coverage/pom.xml
index d4ae94aa4..ef4a7873d 100644
--- a/test-coverage/pom.xml
+++ b/test-coverage/pom.xml
@@ -8,7 +8,7 @@
     
         org.ehrbase.openehr.sdk
         sdk-parent
-        2.10.0-SNAPSHOT
+        2.10.0
     
 
     test-coverage
diff --git a/test-data/pom.xml b/test-data/pom.xml
index 5e7a36881..1900fa78d 100644
--- a/test-data/pom.xml
+++ b/test-data/pom.xml
@@ -26,7 +26,7 @@
     
         org.ehrbase.openehr.sdk
         sdk-parent
-        2.10.0-SNAPSHOT
+        2.10.0
     
 
     test-data
diff --git a/util/pom.xml b/util/pom.xml
index 9ac147909..a0d6a7fa3 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -25,7 +25,7 @@
     
         org.ehrbase.openehr.sdk
         sdk-parent
-        2.10.0-SNAPSHOT
+        2.10.0
     
 
     util
diff --git a/validation/pom.xml b/validation/pom.xml
index 18e3224d9..848da5557 100644
--- a/validation/pom.xml
+++ b/validation/pom.xml
@@ -24,7 +24,7 @@
     
         org.ehrbase.openehr.sdk
         sdk-parent
-        2.10.0-SNAPSHOT
+        2.10.0
     
 
     validation
diff --git a/web-template/pom.xml b/web-template/pom.xml
index 682d63c10..b0d7dd569 100644
--- a/web-template/pom.xml
+++ b/web-template/pom.xml
@@ -25,7 +25,7 @@
     
         org.ehrbase.openehr.sdk
         sdk-parent
-        2.10.0-SNAPSHOT
+        2.10.0
     
 
     web-template