diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index d2e704b9d..168cb5589 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,12 +1,10 @@ -name: "CodeQL" +name: Java 21 CodeQL on: push: - branches: [ "main", "develop", "hotfix/*", "release/*" ] + branches: develop_2 pull_request: - branches: [ "main", "develop", "hotfix/*", "release/*" ] - schedule: - - cron: '21 15 * * 0' # Sundays, 15:21 + branches: develop_2 jobs: analyze: @@ -25,12 +23,12 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 if: ${{ matrix.language == 'java-kotlin' }} uses: actions/setup-java@v3 with: distribution: 'zulu' - java-version: 17 + java-version: 21 cache: 'maven' - name: Initialize CodeQL diff --git a/.github/workflows/maven-build.yml b/.github/workflows/maven-build.yml index 07e9cf265..71ce31358 100644 --- a/.github/workflows/maven-build.yml +++ b/.github/workflows/maven-build.yml @@ -1,6 +1,8 @@ -name: Java CI Build with Maven +name: Java 21 CI Build with Maven -on: push +on: + pull_request: + branches: develop_2 jobs: build: @@ -9,11 +11,11 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v3 with: distribution: 'zulu' - java-version: 17 + java-version: 21 cache: 'maven' - name: Build with Maven run: mvn --batch-mode --fail-at-end --threads 1C -DforkCount=2 -Dgpg.skip clean verify diff --git a/.github/workflows/maven-publish.yml b/.github/workflows/maven-publish.yml index 7102be434..6b65e2fc8 100644 --- a/.github/workflows/maven-publish.yml +++ b/.github/workflows/maven-publish.yml @@ -1,9 +1,9 @@ -name: Java CI Publish with Maven +name: Java 21 CI Publish with Maven on: pull_request: types: closed - branches: develop + branches: develop_2 jobs: publish: @@ -15,11 +15,11 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v3 with: distribution: 'zulu' - java-version: 17 + java-version: 21 cache: 'maven' check-latest: true - name: Publish with Maven diff --git a/CITATION.cff b/CITATION.cff index a21478c74..ec5bb64c2 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -24,8 +24,8 @@ preferred-citation: doi: 10.3233/SHTI210060 type: proceedings title: "Data Sharing Framework (DSF)" -version: 1.5.2 -date-released: 2024-04-17 +version: 2.0.0 +date-released: 2024-06-10 url: https://dsf.dev repository-code: https://github.com/datasharingframework/dsf repository-artifact: https://github.com/datasharingframework/dsf/releases diff --git a/dsf-bpe/dsf-bpe-process-api-v1/pom.xml b/dsf-bpe/dsf-bpe-process-api-v1/pom.xml index 40e0bb5ac..ce9c58b2f 100644 --- a/dsf-bpe/dsf-bpe-process-api-v1/pom.xml +++ b/dsf-bpe/dsf-bpe-process-api-v1/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-bpe-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-bpe/dsf-bpe-server-jetty/docker/Dockerfile b/dsf-bpe/dsf-bpe-server-jetty/docker/Dockerfile index fa80c6f33..3a8c7d93e 100755 --- a/dsf-bpe/dsf-bpe-server-jetty/docker/Dockerfile +++ b/dsf-bpe/dsf-bpe-server-jetty/docker/Dockerfile @@ -8,7 +8,7 @@ RUN chown root:java ./ && \ chmod 1775 ./log -FROM azul/zulu-openjdk:17-jre-headless +FROM azul/zulu-openjdk:21-jre-headless LABEL org.opencontainers.image.source=https://github.com/datasharingframework/dsf LABEL org.opencontainers.image.description="DSF BPE Server" LABEL org.opencontainers.image.licenses="Apache License, Version 2.0" diff --git a/dsf-bpe/dsf-bpe-server-jetty/pom.xml b/dsf-bpe/dsf-bpe-server-jetty/pom.xml index ada30be6e..0b60e3a68 100755 --- a/dsf-bpe/dsf-bpe-server-jetty/pom.xml +++ b/dsf-bpe/dsf-bpe-server-jetty/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-bpe-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-bpe/dsf-bpe-server/pom.xml b/dsf-bpe/dsf-bpe-server/pom.xml index c65224bc8..51e7cc740 100755 --- a/dsf-bpe/dsf-bpe-server/pom.xml +++ b/dsf-bpe/dsf-bpe-server/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-bpe-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/spring/config/PropertiesConfig.java b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/spring/config/PropertiesConfig.java index 22d27a35e..b7160a084 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/spring/config/PropertiesConfig.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/spring/config/PropertiesConfig.java @@ -1,5 +1,6 @@ package dev.dsf.bpe.spring.config; +import java.net.URI; import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; @@ -296,7 +297,7 @@ public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderCon @Override public void afterPropertiesSet() throws Exception { - URL url = new URL(fhirServerBaseUrl); + URL url = new URI(fhirServerBaseUrl).toURL(); if (!Arrays.asList("http", "https").contains(url.getProtocol())) { logger.warn("Invalid DSF FHIR server base URL: '{}', URL not starting with 'http://' or 'https://'", diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/ui/ThymeleafTemplateServiceImpl.java b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/ui/ThymeleafTemplateServiceImpl.java index 5744631c1..00abdace4 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/ui/ThymeleafTemplateServiceImpl.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/ui/ThymeleafTemplateServiceImpl.java @@ -1,8 +1,7 @@ package dev.dsf.bpe.ui; import java.io.OutputStreamWriter; -import java.net.MalformedURLException; -import java.net.URL; +import java.net.URI; import java.util.Objects; import org.springframework.beans.factory.InitializingBean; @@ -53,18 +52,6 @@ public void afterPropertiesSet() throws Exception Objects.requireNonNull(serverBaseUrl, "serverBaseUrl"); } - private String getServerBaseUrlPathWithLeadingSlash() - { - try - { - return new URL(serverBaseUrl).getPath(); - } - catch (MalformedURLException e) - { - throw new RuntimeException(e); - } - } - @Override public StreamingOutput write(Context context, MainValues mainValues) { @@ -78,7 +65,7 @@ public StreamingOutput write(Context context, MainValues mainValues) context.setVariable("username", mainValues.username()); context.setVariable("openid", mainValues.openid()); - context.setVariable("basePath", getServerBaseUrlPathWithLeadingSlash()); + context.setVariable("basePath", URI.create(serverBaseUrl).getPath()); context.setVariable("modCssExists", modCssExists); context.setVariable("theme", theme == null ? null : theme.toString()); diff --git a/dsf-bpe/pom.xml b/dsf-bpe/pom.xml index 6c9260a14..3095b4336 100755 --- a/dsf-bpe/pom.xml +++ b/dsf-bpe/pom.xml @@ -7,7 +7,7 @@ dev.dsf dsf-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-common/dsf-common-auth/pom.xml b/dsf-common/dsf-common-auth/pom.xml index 869d6a816..4b1af4b33 100644 --- a/dsf-common/dsf-common-auth/pom.xml +++ b/dsf-common/dsf-common-auth/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-common-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-common/dsf-common-auth/src/main/java/dev/dsf/common/auth/conf/AbstractIdentityProvider.java b/dsf-common/dsf-common-auth/src/main/java/dev/dsf/common/auth/conf/AbstractIdentityProvider.java index 2abcd9019..78dd77ff2 100644 --- a/dsf-common/dsf-common-auth/src/main/java/dev/dsf/common/auth/conf/AbstractIdentityProvider.java +++ b/dsf-common/dsf-common-auth/src/main/java/dev/dsf/common/auth/conf/AbstractIdentityProvider.java @@ -1,7 +1,7 @@ package dev.dsf.common.auth.conf; -import java.net.MalformedURLException; -import java.net.URL; +import java.net.URI; +import java.net.URISyntaxException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateEncodingException; @@ -261,9 +261,9 @@ private String toEmail(String iss, String sub) try { - return sub + "@" + new URL(iss).getHost(); + return sub + "@" + new URI(iss).getHost(); } - catch (MalformedURLException e) + catch (URISyntaxException e) { return null; } diff --git a/dsf-common/dsf-common-config/pom.xml b/dsf-common/dsf-common-config/pom.xml index 9af8993b6..8a17e9cd7 100644 --- a/dsf-common/dsf-common-config/pom.xml +++ b/dsf-common/dsf-common-config/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-common-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-common/dsf-common-config/src/main/java/dev/dsf/common/config/ProxyConfigImpl.java b/dsf-common/dsf-common-config/src/main/java/dev/dsf/common/config/ProxyConfigImpl.java index da9dfaaeb..5018bd887 100644 --- a/dsf-common/dsf-common-config/src/main/java/dev/dsf/common/config/ProxyConfigImpl.java +++ b/dsf-common/dsf-common-config/src/main/java/dev/dsf/common/config/ProxyConfigImpl.java @@ -42,7 +42,7 @@ private static String nullIfUrlInvalid(String url) try { - URL u = new URL(url); + URL u = new URI(url).toURL(); if (u.getHost() == null || u.getHost().isBlank()) { logger.warn("Forward proxy url '{}' malformed: no host name", u); @@ -56,7 +56,7 @@ else if (!"http".equals(u.getProtocol()) && !"https".equals(u.getProtocol())) return url; } - catch (MalformedURLException e) + catch (IllegalArgumentException | MalformedURLException | URISyntaxException e) { logger.warn("Forward proxy url '{}' malformed: {}", url, e.getMessage()); return null; diff --git a/dsf-common/dsf-common-db/pom.xml b/dsf-common/dsf-common-db/pom.xml index e8515c921..bf3e16750 100644 --- a/dsf-common/dsf-common-db/pom.xml +++ b/dsf-common/dsf-common-db/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-common-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-common/dsf-common-documentation/pom.xml b/dsf-common/dsf-common-documentation/pom.xml index 147a24bcd..6fde75b6c 100644 --- a/dsf-common/dsf-common-documentation/pom.xml +++ b/dsf-common/dsf-common-documentation/pom.xml @@ -6,6 +6,6 @@ dev.dsf dsf-common-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT \ No newline at end of file diff --git a/dsf-common/dsf-common-jetty/pom.xml b/dsf-common/dsf-common-jetty/pom.xml index 708af7964..b7ca4894b 100644 --- a/dsf-common/dsf-common-jetty/pom.xml +++ b/dsf-common/dsf-common-jetty/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-common-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-common/dsf-common-jetty/src/main/java/dev/dsf/common/config/AbstractJettyConfig.java b/dsf-common/dsf-common-jetty/src/main/java/dev/dsf/common/config/AbstractJettyConfig.java index a68f0302f..9cdd253fe 100644 --- a/dsf-common/dsf-common-jetty/src/main/java/dev/dsf/common/config/AbstractJettyConfig.java +++ b/dsf-common/dsf-common-jetty/src/main/java/dev/dsf/common/config/AbstractJettyConfig.java @@ -3,6 +3,8 @@ import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; @@ -433,13 +435,13 @@ private Proxy oidcClientProxy() { try { - URL proxyUrl = new URL(config.getUrl()); + URL proxyUrl = new URI(config.getUrl()).toURL(); Address address = new Address(proxyUrl.getHost(), proxyUrl.getPort() < 0 ? proxyUrl.getDefaultPort() : proxyUrl.getPort()); return new HttpProxy(address, "https".equals(proxyUrl.getProtocol())); } - catch (MalformedURLException e) + catch (MalformedURLException | URISyntaxException e) { throw new RuntimeException(e); } diff --git a/dsf-common/dsf-common-status/pom.xml b/dsf-common/dsf-common-status/pom.xml index 30d6bf018..c764ccf34 100644 --- a/dsf-common/dsf-common-status/pom.xml +++ b/dsf-common/dsf-common-status/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-common-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-common/dsf-common-ui/pom.xml b/dsf-common/dsf-common-ui/pom.xml index 8cdc46e29..d6692f557 100644 --- a/dsf-common/dsf-common-ui/pom.xml +++ b/dsf-common/dsf-common-ui/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-common-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-common/pom.xml b/dsf-common/pom.xml index 53952444c..449f2a8a8 100644 --- a/dsf-common/pom.xml +++ b/dsf-common/pom.xml @@ -7,7 +7,7 @@ dev.dsf dsf-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-fhir/dsf-fhir-auth/pom.xml b/dsf-fhir/dsf-fhir-auth/pom.xml index 328610e7c..9e78860ca 100644 --- a/dsf-fhir/dsf-fhir-auth/pom.xml +++ b/dsf-fhir/dsf-fhir-auth/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-fhir-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-fhir/dsf-fhir-rest-adapter/pom.xml b/dsf-fhir/dsf-fhir-rest-adapter/pom.xml index a19c99613..3208437f1 100755 --- a/dsf-fhir/dsf-fhir-rest-adapter/pom.xml +++ b/dsf-fhir/dsf-fhir-rest-adapter/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-fhir-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-fhir/dsf-fhir-server-jetty/docker/Dockerfile b/dsf-fhir/dsf-fhir-server-jetty/docker/Dockerfile index 7890c9840..99edc087f 100755 --- a/dsf-fhir/dsf-fhir-server-jetty/docker/Dockerfile +++ b/dsf-fhir/dsf-fhir-server-jetty/docker/Dockerfile @@ -8,7 +8,7 @@ RUN chown root:java ./ && \ chmod 1775 ./log -FROM azul/zulu-openjdk:17-jre-headless +FROM azul/zulu-openjdk:21-jre-headless LABEL org.opencontainers.image.source=https://github.com/datasharingframework/dsf LABEL org.opencontainers.image.description="DSF FHIR Server" LABEL org.opencontainers.image.licenses="Apache License, Version 2.0" diff --git a/dsf-fhir/dsf-fhir-server-jetty/pom.xml b/dsf-fhir/dsf-fhir-server-jetty/pom.xml index b0e5d3679..8f278734d 100755 --- a/dsf-fhir/dsf-fhir-server-jetty/pom.xml +++ b/dsf-fhir/dsf-fhir-server-jetty/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-fhir-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-fhir/dsf-fhir-server/pom.xml b/dsf-fhir/dsf-fhir-server/pom.xml index a3d2d1f68..c9ff62843 100755 --- a/dsf-fhir/dsf-fhir-server/pom.xml +++ b/dsf-fhir/dsf-fhir-server/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-fhir-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/ThymeleafTemplateServiceImpl.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/ThymeleafTemplateServiceImpl.java index 8466d332c..46a0c6e9d 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/ThymeleafTemplateServiceImpl.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/ThymeleafTemplateServiceImpl.java @@ -5,10 +5,8 @@ import java.io.OutputStreamWriter; import java.io.StringReader; import java.io.StringWriter; -import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; -import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; @@ -175,9 +173,9 @@ private String getServerBaseUrlPathWithLeadingSlash() { try { - return new URL(serverBaseUrl).getPath(); + return new URI(serverBaseUrl).getPath(); } - catch (MalformedURLException e) + catch (URISyntaxException e) { throw new RuntimeException(e); } diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/CreateCommand.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/CreateCommand.java index 5134b3e67..18e034148 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/CreateCommand.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/CreateCommand.java @@ -85,14 +85,22 @@ public void preExecute(Map idTranslationTable, Connection connec if (eruComponentes.getPathSegments().size() == 1 && eruComponentes.getQueryParams().isEmpty()) { if (!entry.hasFullUrl() || !entry.getFullUrl().startsWith(URL_UUID_PREFIX)) - throw new WebApplicationException( - responseGenerator.badCreateRequestUrl(index, entry.getRequest().getUrl())); + { + Response response = responseGenerator.badCreateRequestUrl(index, entry.getRequest().getUrl()); + throw new WebApplicationException(response); + } else if (resource.hasIdElement() && !resource.getIdElement().getValue().startsWith(URL_UUID_PREFIX)) - throw new WebApplicationException( - responseGenerator.bundleEntryBadResourceId(index, getResourceTypeName(), URL_UUID_PREFIX)); + { + Response response = responseGenerator.bundleEntryBadResourceId(index, getResourceTypeName(), + URL_UUID_PREFIX); + throw new WebApplicationException(response); + } else if (resource.hasIdElement() && !entry.getFullUrl().equals(resource.getIdElement().getValue())) - throw new WebApplicationException(responseGenerator.badBundleEntryFullUrlVsResourceId(index, - entry.getFullUrl(), resource.getIdElement().getValue())); + { + Response response = responseGenerator.badBundleEntryFullUrlVsResourceId(index, entry.getFullUrl(), + resource.getIdElement().getValue()); + throw new WebApplicationException(response); + } // add new or existing id to the id translation table addToIdTranslationTable(idTranslationTable, connection); @@ -100,8 +108,10 @@ else if (resource.hasIdElement() && !entry.getFullUrl().equals(resource.getIdEle // all other request urls else - throw new WebApplicationException( - responseGenerator.badCreateRequestUrl(index, entry.getRequest().getUrl())); + { + Response response = responseGenerator.badCreateRequestUrl(index, entry.getRequest().getUrl()); + throw new WebApplicationException(response); + } } private void addToIdTranslationTable(Map idTranslationTable, Connection connection) @@ -177,7 +187,10 @@ private Optional checkAlreadyExists(Connection connection, String ifNo return Optional.empty(); if (ifNoneExist.isBlank()) - throw new WebApplicationException(responseGenerator.badIfNoneExistHeaderValue("blank", ifNoneExist)); + { + Response response = responseGenerator.badIfNoneExistHeaderValue("blank", ifNoneExist); + throw new WebApplicationException(response); + } if (!ifNoneExist.contains("?")) ifNoneExist = '?' + ifNoneExist; @@ -185,7 +198,10 @@ private Optional checkAlreadyExists(Connection connection, String ifNo UriComponents componentes = UriComponentsBuilder.fromUriString(ifNoneExist).build(); String path = componentes.getPath(); if (path != null && !path.isBlank()) - throw new WebApplicationException(responseGenerator.badIfNoneExistHeaderValue("no resource", ifNoneExist)); + { + Response response = responseGenerator.badIfNoneExistHeaderValue("no resource", ifNoneExist); + throw new WebApplicationException(response); + } Map> queryParameters = parameterConverter .urlDecodeQueryParameters(componentes.getQueryParams()); @@ -205,15 +221,20 @@ private Optional checkAlreadyExists(Connection connection, String ifNo List unsupportedQueryParameters = query.getUnsupportedQueryParameters(); if (!unsupportedQueryParameters.isEmpty()) - throw new WebApplicationException( - responseGenerator.badIfNoneExistHeaderValue(ifNoneExist, unsupportedQueryParameters)); + { + Response response = responseGenerator.badIfNoneExistHeaderValue(ifNoneExist, unsupportedQueryParameters); + throw new WebApplicationException(response); + } PartialResult result = exceptionHandler .handleSqlException(() -> dao.searchWithTransaction(connection, query)); if (result.getTotal() == 1) return Optional.of(result.getPartialResult().get(0)); else if (result.getTotal() > 1) - throw new WebApplicationException(responseGenerator.multipleExists(resourceTypeName, ifNoneExist)); + { + Response response = responseGenerator.multipleExists(resourceTypeName, ifNoneExist); + throw new WebApplicationException(response); + } return Optional.empty(); } diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/CreateStructureDefinitionCommand.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/CreateStructureDefinitionCommand.java index 2610344dd..d79591aa7 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/CreateStructureDefinitionCommand.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/CreateStructureDefinitionCommand.java @@ -26,6 +26,7 @@ import dev.dsf.fhir.validation.SnapshotGenerator; import dev.dsf.fhir.validation.SnapshotGenerator.SnapshotWithValidationMessages; import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response; public class CreateStructureDefinitionCommand extends CreateCommand { @@ -68,8 +69,8 @@ private StructureDefinition generateSnapshot(SnapshotGenerator snapshotGenerator if (s.getMessages().stream() .anyMatch(m -> IssueSeverity.FATAL.equals(m.getLevel()) || IssueSeverity.ERROR.equals(m.getLevel()))) { - throw new WebApplicationException( - responseGenerator.unableToGenerateSnapshot(resource, index, s.getMessages())); + Response response = responseGenerator.unableToGenerateSnapshot(resource, index, s.getMessages()); + throw new WebApplicationException(response); } return s.getSnapshot(); diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/DeleteCommand.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/DeleteCommand.java index d1ce790c3..e508be4f8 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/DeleteCommand.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/DeleteCommand.java @@ -37,6 +37,7 @@ import dev.dsf.fhir.search.SearchQueryParameterError; import dev.dsf.fhir.validation.SnapshotGenerator; import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; public class DeleteCommand extends AbstractCommand implements ModifyingCommand @@ -83,8 +84,10 @@ else if (componentes.getPathSegments().size() == 1 && !componentes.getQueryParam deleteByCondition(idTranslationTable, connection, componentes.getPathSegments().get(0), parameterConverter.urlDecodeQueryParameters(componentes.getQueryParams())); else - throw new WebApplicationException( - responseGenerator.badDeleteRequestUrl(index, entry.getRequest().getUrl())); + { + Response response = responseGenerator.badDeleteRequestUrl(index, entry.getRequest().getUrl()); + throw new WebApplicationException(response); + } } private void deleteById(Map idTranslationTable, Connection connection, String resourceTypeName, @@ -93,8 +96,10 @@ private void deleteById(Map idTranslationTable, Connection conne Optional> optDao = daoProvider.getDao(resourceTypeName); if (optDao.isEmpty()) - throw new WebApplicationException( - responseGenerator.resourceTypeNotSupportedByImplementation(index, resourceTypeName)); + { + Response response = responseGenerator.resourceTypeNotSupportedByImplementation(index, resourceTypeName); + throw new WebApplicationException(response); + } else { @SuppressWarnings("unchecked") @@ -123,8 +128,10 @@ private void deleteByCondition(Map idTranslationTable, Connectio Optional> dao = daoProvider.getDao(resourceTypeName); if (dao.isEmpty()) - throw new WebApplicationException( - responseGenerator.resourceTypeNotSupportedByImplementation(index, resourceTypeName)); + { + Response response = responseGenerator.resourceTypeNotSupportedByImplementation(index, resourceTypeName); + throw new WebApplicationException(response); + } else { Optional resourceToDelete = search(connection, dao.get(), queryParameters); @@ -178,10 +185,13 @@ private Optional search(Connection connection, ResourceDao dao, List unsupportedQueryParameters = query.getUnsupportedQueryParameters(); if (!unsupportedQueryParameters.isEmpty()) - throw new WebApplicationException(responseGenerator.badConditionalDeleteRequest(index, + { + Response response = responseGenerator.badConditionalDeleteRequest(index, UriComponentsBuilder.newInstance() .replaceQueryParams(CollectionUtils.toMultiValueMap(queryParameters)).toUriString(), - unsupportedQueryParameters)); + unsupportedQueryParameters); + throw new WebApplicationException(response); + } PartialResult result = exceptionHandler .handleSqlException(() -> dao.searchWithTransaction(connection, query)); @@ -196,9 +206,10 @@ else if (result.getTotal() == 1) } else // if (result.getOverallCount() > 1) { - throw new WebApplicationException(responseGenerator.badConditionalDeleteRequestMultipleMatches(index, - resourceTypeName, UriComponentsBuilder.newInstance() - .replaceQueryParams(CollectionUtils.toMultiValueMap(queryParameters)).toUriString())); + Response response = responseGenerator.badConditionalDeleteRequestMultipleMatches(index, resourceTypeName, + UriComponentsBuilder.newInstance() + .replaceQueryParams(CollectionUtils.toMultiValueMap(queryParameters)).toUriString()); + throw new WebApplicationException(response); } } diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/ReadCommand.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/ReadCommand.java index e23704f73..3fe3ac2c0 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/ReadCommand.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/ReadCommand.java @@ -114,7 +114,10 @@ else if (componentes.getPathSegments().size() == 1 && !componentes.getQueryParam readByCondition(connection, resourceTypeName, parameterConverter.urlDecodeQueryParameters(componentes.getQueryParams())); else - throw new WebApplicationException(responseGenerator.badReadRequestUrl(index, requestUrl)); + { + Response response = responseGenerator.badReadRequestUrl(index, requestUrl); + throw new WebApplicationException(response); + } } private void readById(Connection connection, String resourceTypeName, String id) @@ -200,8 +203,11 @@ private void readByCondition(Connection connection, String resourceTypeName, List errors = query.getUnsupportedQueryParameters(); if (!errors.isEmpty() && PreferHandlingType.STRICT.equals(handlingType)) - throw new WebApplicationException(responseGenerator.response(Status.BAD_REQUEST, - responseGenerator.toOperationOutcomeError(errors), MediaType.APPLICATION_XML_TYPE).build()); + { + Response response = responseGenerator.response(Status.BAD_REQUEST, + responseGenerator.toOperationOutcomeError(errors), MediaType.APPLICATION_XML_TYPE).build(); + throw new WebApplicationException(response); + } PartialResult result = exceptionHandler .handleSqlException(() -> optDao.get().searchWithTransaction(connection, query)); diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/TransactionCommandList.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/TransactionCommandList.java index be6894026..3497b0ecb 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/TransactionCommandList.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/TransactionCommandList.java @@ -220,8 +220,8 @@ public Bundle execute() throws WebApplicationException if (e.getResponse() != null && Status.FORBIDDEN.getStatusCode() == e.getResponse().getStatus()) throw e; - throw new WebApplicationException( - Response.status(Status.BAD_REQUEST).entity(e.getResponse().getEntity()).build()); + Response response = Response.status(Status.BAD_REQUEST).entity(e.getResponse().getEntity()).build(); + throw new WebApplicationException(response); } catch (Exception e) { diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/UpdateCommand.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/UpdateCommand.java index b5cd55580..5748301c7 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/UpdateCommand.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/UpdateCommand.java @@ -45,6 +45,7 @@ import dev.dsf.fhir.validation.SnapshotGenerator; import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.EntityTag; +import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; import jakarta.ws.rs.ext.RuntimeDelegate; @@ -86,14 +87,21 @@ public void preExecute(Map idTranslationTable, Connection connec if (eruComponentes.getPathSegments().size() == 2 && eruComponentes.getQueryParams().isEmpty()) { if (!entry.hasFullUrl() || entry.getFullUrl().startsWith(URL_UUID_PREFIX)) - throw new WebApplicationException( - responseGenerator.badUpdateRequestUrl(index, entry.getRequest().getUrl())); + { + Response response = responseGenerator.badUpdateRequestUrl(index, entry.getRequest().getUrl()); + throw new WebApplicationException(response); + } else if (!resource.hasIdElement() || !resource.getIdElement().hasIdPart()) - throw new WebApplicationException( - responseGenerator.bundleEntryResouceMissingId(index, resource.getResourceType().name())); + { + Response response = responseGenerator.bundleEntryResouceMissingId(index, + resource.getResourceType().name()); + throw new WebApplicationException(response); + } else if (resource.getIdElement().getIdPart().startsWith(URL_UUID_PREFIX)) - throw new WebApplicationException( - responseGenerator.badUpdateRequestUrl(index, entry.getRequest().getUrl())); + { + Response response = responseGenerator.badUpdateRequestUrl(index, entry.getRequest().getUrl()); + throw new WebApplicationException(response); + } String expectedBaseUrl = serverBase; String expectedResourceTypeName = resource.getResourceType().name(); @@ -101,25 +109,38 @@ else if (resource.getIdElement().getIdPart().startsWith(URL_UUID_PREFIX)) String expectedfullUrl = new IdType(expectedBaseUrl, expectedResourceTypeName, expectedId, null).getValue(); if (!expectedfullUrl.equals(entry.getFullUrl())) - throw new WebApplicationException(responseGenerator.badBundleEntryFullUrl(index, entry.getFullUrl())); + { + Response response = responseGenerator.badBundleEntryFullUrl(index, entry.getFullUrl()); + throw new WebApplicationException(response); + } else if (!expectedResourceTypeName.equals(eruComponentes.getPathSegments().get(0)) || !expectedId.equals(eruComponentes.getPathSegments().get(1))) - throw new WebApplicationException( - responseGenerator.badUpdateRequestUrl(index, entry.getRequest().getUrl())); + { + Response response = responseGenerator.badUpdateRequestUrl(index, entry.getRequest().getUrl()); + throw new WebApplicationException(response); + } } // check conditional update request url: e.g. Patient?... else if (eruComponentes.getPathSegments().size() == 1 && !eruComponentes.getQueryParams().isEmpty()) { if (!entry.getFullUrl().startsWith(URL_UUID_PREFIX)) - throw new WebApplicationException( - responseGenerator.badUpdateRequestUrl(index, entry.getRequest().getUrl())); + { + Response response = responseGenerator.badUpdateRequestUrl(index, entry.getRequest().getUrl()); + throw new WebApplicationException(response); + } else if (resource.hasIdElement() && !resource.getIdElement().getValue().startsWith(URL_UUID_PREFIX)) - throw new WebApplicationException(responseGenerator.bundleEntryBadResourceId(index, - resource.getResourceType().name(), URL_UUID_PREFIX)); + { + Response response = responseGenerator.bundleEntryBadResourceId(index, resource.getResourceType().name(), + URL_UUID_PREFIX); + throw new WebApplicationException(response); + } else if (resource.hasIdElement() && !entry.getFullUrl().equals(resource.getIdElement().getValue())) - throw new WebApplicationException(responseGenerator.badBundleEntryFullUrlVsResourceId(index, - entry.getFullUrl(), resource.getIdElement().getValue())); + { + Response response = responseGenerator.badBundleEntryFullUrlVsResourceId(index, entry.getFullUrl(), + resource.getIdElement().getValue()); + throw new WebApplicationException(response); + } // add new or existing id to the id translation table addMissingIdToTranslationTableAndCheckConditionFindsResource(idTranslationTable, connection); @@ -127,8 +148,10 @@ else if (resource.hasIdElement() && !entry.getFullUrl().equals(resource.getIdEle // all other request urls else - throw new WebApplicationException( - responseGenerator.badUpdateRequestUrl(index, entry.getRequest().getUrl())); + { + Response response = responseGenerator.badUpdateRequestUrl(index, entry.getRequest().getUrl()); + throw new WebApplicationException(response); + } } private boolean addMissingIdToTranslationTableAndCheckConditionFindsResource(Map idTranslationTable, @@ -157,8 +180,11 @@ private boolean addMissingIdToTranslationTableAndCheckConditionFindsResource(Map List unsupportedParams = query.getUnsupportedQueryParameters(); if (!unsupportedParams.isEmpty()) - throw new WebApplicationException(responseGenerator.unsupportedConditionalUpdateQuery(index, - entry.getRequest().getUrl(), unsupportedParams)); + { + Response response = responseGenerator.unsupportedConditionalUpdateQuery(index, entry.getRequest().getUrl(), + unsupportedParams); + throw new WebApplicationException(response); + } PartialResult result = exceptionHandler .handleSqlException(() -> dao.searchWithTransaction(connection, query)); @@ -180,8 +206,11 @@ private boolean addMissingIdToTranslationTableAndCheckConditionFindsResource(Map // No matches, id provided: The server treats the interaction as an Update as Create interaction (or rejects it, // if it does not support Update as Create) -> reject else if (result.getTotal() <= 0 && resource.hasId()) + { // TODO bundle specific error - throw new WebApplicationException(responseGenerator.updateAsCreateNotAllowed(resourceTypeName)); + Response response = responseGenerator.updateAsCreateNotAllowed(resourceTypeName); + throw new WebApplicationException(response); + } // One Match, no resource id provided OR (resource id provided and it matches the found resource): // The server performs the update against the matching resource @@ -212,18 +241,24 @@ else if (resource.hasId() return true; } else + { // TODO bundle specific error - throw new WebApplicationException(responseGenerator.badRequestIdsNotMatching( + Response response = responseGenerator.badRequestIdsNotMatching( dbResourceId.withServerBase(serverBase, resourceTypeName), resource.getIdElement().hasBaseUrl() && resource.getIdElement().hasResourceType() ? resource.getIdElement() - : resource.getIdElement().withServerBase(serverBase, resourceTypeName))); + : resource.getIdElement().withServerBase(serverBase, resourceTypeName)); + throw new WebApplicationException(response); + } } // Multiple matches: The server returns a 412 Precondition Failed error indicating the client's criteria were // not selective enough preferably with an OperationOutcome else // if (result.getOverallCount() > 1) - throw new WebApplicationException(responseGenerator.multipleExists(resourceTypeName, UriComponentsBuilder - .newInstance().replaceQueryParams(CollectionUtils.toMultiValueMap(queryParameters)).toUriString())); + { + Response response = responseGenerator.multipleExists(resourceTypeName, UriComponentsBuilder.newInstance() + .replaceQueryParams(CollectionUtils.toMultiValueMap(queryParameters)).toUriString()); + throw new WebApplicationException(response); + } } @Override @@ -239,8 +274,10 @@ public void execute(Map idTranslationTable, Connection connectio else if (componentes.getPathSegments().size() == 1 && !componentes.getQueryParams().isEmpty()) updateByCondition(idTranslationTable, connection, validationHelper, componentes.getPathSegments().get(0)); else - throw new WebApplicationException( - responseGenerator.badUpdateRequestUrl(index, entry.getRequest().getUrl())); + { + Response response = responseGenerator.badUpdateRequestUrl(index, entry.getRequest().getUrl()); + throw new WebApplicationException(response); + } } private void updateById(Map idTranslationTable, Connection connection, @@ -249,15 +286,22 @@ private void updateById(Map idTranslationTable, Connection conne IdType resourceId = resource.getIdElement(); if (!Objects.equals(pathId, resourceId.getIdPart())) - throw new WebApplicationException( - responseGenerator.pathVsElementIdInBundle(index, resourceTypeName, pathId, resourceId)); + { + Response response = responseGenerator.pathVsElementIdInBundle(index, resourceTypeName, pathId, resourceId); + throw new WebApplicationException(response); + } if (resourceId.getBaseUrl() != null && !serverBase.equals(resourceId.getBaseUrl())) - throw new WebApplicationException( - responseGenerator.invalidBaseUrlInBundle(index, resourceTypeName, resourceId)); + { + Response response = responseGenerator.invalidBaseUrlInBundle(index, resourceTypeName, resourceId); + throw new WebApplicationException(response); + } if (!Objects.equals(resourceTypeName, resource.getResourceType().name())) - throw new WebApplicationException(responseGenerator.nonMatchingResourceTypeAndRequestUrlInBundle(index, - resourceTypeName, entry.getRequest().getUrl())); + { + Response response = responseGenerator.nonMatchingResourceTypeAndRequestUrlInBundle(index, resourceTypeName, + entry.getRequest().getUrl()); + throw new WebApplicationException(response); + } @SuppressWarnings("unchecked") R copy = (R) resource.copy(); @@ -289,7 +333,8 @@ private void checkUpdateAllowed(Map idTranslationTable, Connecti { audit.info("Update as create of non existing {} denied for identity '{}'", resourceTypeName, identity.getName()); - throw new WebApplicationException(responseGenerator.updateAsCreateNotAllowed(resourceTypeName)); + Response response = responseGenerator.updateAsCreateNotAllowed(resourceTypeName); + throw new WebApplicationException(response); } else { diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/UpdateStructureDefinitionCommand.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/UpdateStructureDefinitionCommand.java index 5f69f4610..b4d852756 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/UpdateStructureDefinitionCommand.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/UpdateStructureDefinitionCommand.java @@ -28,6 +28,7 @@ import dev.dsf.fhir.validation.SnapshotGenerator; import dev.dsf.fhir.validation.SnapshotGenerator.SnapshotWithValidationMessages; import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response; public class UpdateStructureDefinitionCommand extends UpdateCommand implements Command @@ -71,8 +72,8 @@ private StructureDefinition generateSnapshot(SnapshotGenerator snapshotGenerator if (s.getMessages().stream() .anyMatch(m -> IssueSeverity.FATAL.equals(m.getLevel()) || IssueSeverity.ERROR.equals(m.getLevel()))) { - throw new WebApplicationException( - responseGenerator.unableToGenerateSnapshot(resource, index, s.getMessages())); + Response response = responseGenerator.unableToGenerateSnapshot(resource, index, s.getMessages()); + throw new WebApplicationException(response); } return s.getSnapshot(); diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/ValidationHelperImpl.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/ValidationHelperImpl.java index efb8f7440..90650ae9b 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/ValidationHelperImpl.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/command/ValidationHelperImpl.java @@ -12,6 +12,7 @@ import dev.dsf.fhir.help.ResponseGenerator; import dev.dsf.fhir.validation.ResourceValidator; import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response; public class ValidationHelperImpl implements ValidationHelper { @@ -48,8 +49,9 @@ private ValidationResult checkResourceValid(Identity identity, Resource resource logger.warn("{} of {} unauthorized, resource not valid: {}", method, resource.fhirType(), toValidationLogMessage(validationResult)); - throw new WebApplicationException( - responseGenerator.forbiddenNotValid(method, identity, resource.fhirType(), validationResult)); + Response response = responseGenerator.forbiddenNotValid(method, identity, resource.fhirType(), + validationResult); + throw new WebApplicationException(response); } else if (!validationResult.getMessages().isEmpty()) logger.info("Resource {} validated with messages: {}", resource.fhirType(), diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/help/ExceptionHandler.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/help/ExceptionHandler.java index 3c8afef73..75acd3649 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/help/ExceptionHandler.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/help/ExceptionHandler.java @@ -126,7 +126,8 @@ public T handleSqlExAndResourceNotFoundExAndResouceVersionNonMatchEx(String } catch (ResourceNotFoundException e) { - throw new WebApplicationException(responseGenerator.notFound(e.getId(), resourceTypeName)); + Response response = responseGenerator.notFound(e.getId(), resourceTypeName); + throw new WebApplicationException(response); } catch (ResourceVersionNoMatchException e) { @@ -361,7 +362,8 @@ public CommandList handleBadBundleException(Supplier commandListCre logger.debug("Error while creating command list for bundle", e); logger.warn("Error while creating command list for bundle: {}", e.getMessage()); - throw new WebApplicationException(responseGenerator.badBundleRequest(e.getMessage())); + Response response = responseGenerator.badBundleRequest(e.getMessage()); + throw new WebApplicationException(response); } } } diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/history/HistoryServiceImpl.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/history/HistoryServiceImpl.java index b2681fcda..4d84eee63 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/history/HistoryServiceImpl.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/history/HistoryServiceImpl.java @@ -28,6 +28,7 @@ import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.HttpHeaders; import jakarta.ws.rs.core.MultivaluedMap; +import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; import jakarta.ws.rs.core.UriBuilder; import jakarta.ws.rs.core.UriInfo; @@ -129,9 +130,13 @@ else if (resourceType != null) throw new WebApplicationException(); if (!errors.isEmpty() && PreferHandlingType.STRICT.equals(parameterConverter.getPreferHandling(headers))) - throw new WebApplicationException( - responseGenerator.response(Status.BAD_REQUEST, responseGenerator.toOperationOutcomeError(errors), - parameterConverter.getMediaTypeThrowIfNotSupported(uri, headers)).build()); + { + Response response = responseGenerator + .response(Status.BAD_REQUEST, responseGenerator.toOperationOutcomeError(errors), + parameterConverter.getMediaTypeThrowIfNotSupported(uri, headers)) + .build(); + throw new WebApplicationException(response); + } String format = queryParameters.getFirst(SearchQuery.PARAMETER_FORMAT); String pretty = queryParameters.getFirst(SearchQuery.PARAMETER_PRETTY); diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/spring/config/PropertiesConfig.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/spring/config/PropertiesConfig.java index 6e4933a2e..4f15f28f8 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/spring/config/PropertiesConfig.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/spring/config/PropertiesConfig.java @@ -1,6 +1,8 @@ package dev.dsf.fhir.spring.config; import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.util.Arrays; import java.util.List; @@ -157,7 +159,7 @@ private static void injectEndpointProperties(ConfigurableEnvironment environment { try { - URL baseUrl = new URL(environment.getRequiredProperty("dev.dsf.fhir.server.base.url")); + URL baseUrl = new URI(environment.getRequiredProperty("dev.dsf.fhir.server.base.url")).toURL(); if (baseUrl.getHost() == null || baseUrl.getHost().isBlank()) throw new IllegalStateException("No hostname defined in FHIR server base url"); @@ -167,7 +169,7 @@ private static void injectEndpointProperties(ConfigurableEnvironment environment environment.getPropertySources().addFirst(new PropertiesPropertySource("enpoint-properties", properties)); } - catch (MalformedURLException | IllegalStateException e) + catch (MalformedURLException | IllegalStateException | URISyntaxException e) { throw new RuntimeException(e); } @@ -176,7 +178,7 @@ private static void injectEndpointProperties(ConfigurableEnvironment environment @Override public void afterPropertiesSet() throws Exception { - URL url = new URL(serverBaseUrl); + URL url = new URI(serverBaseUrl).toURL(); if (!Arrays.asList("http", "https").contains(url.getProtocol())) { logger.warn("Invalid DSF FHIR server base URL: '{}', URL not starting with 'http://' or 'https://'", diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/webservice/impl/AbstractResourceServiceImpl.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/webservice/impl/AbstractResourceServiceImpl.java index 1778674d7..4f89bdf48 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/webservice/impl/AbstractResourceServiceImpl.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/webservice/impl/AbstractResourceServiceImpl.java @@ -286,8 +286,10 @@ private void checkAlreadyExists(HttpHeaders headers) throws WebApplicationExcept return; // header not found, nothing to check against if (ifNoneExistHeader.get().isBlank()) - throw new WebApplicationException( - responseGenerator.badIfNoneExistHeaderValue("blank", ifNoneExistHeader.get())); + { + Response response = responseGenerator.badIfNoneExistHeaderValue("blank", ifNoneExistHeader.get()); + throw new WebApplicationException(response); + } String ifNoneExistHeaderValue = ifNoneExistHeader.get(); if (!ifNoneExistHeaderValue.contains("?")) @@ -296,8 +298,10 @@ private void checkAlreadyExists(HttpHeaders headers) throws WebApplicationExcept UriComponents componentes = UriComponentsBuilder.fromUriString(ifNoneExistHeaderValue).build(); String path = componentes.getPath(); if (path != null && !path.isBlank()) - throw new WebApplicationException( - responseGenerator.badIfNoneExistHeaderValue("no resource", ifNoneExistHeader.get())); + { + Response response = responseGenerator.badIfNoneExistHeaderValue("no resource", ifNoneExistHeader.get()); + throw new WebApplicationException(response); + } Map> queryParameters = parameterConverter .urlDecodeQueryParameters(componentes.getQueryParams()); @@ -317,16 +321,23 @@ private void checkAlreadyExists(HttpHeaders headers) throws WebApplicationExcept List unsupportedQueryParameters = query.getUnsupportedQueryParameters(); if (!unsupportedQueryParameters.isEmpty()) - throw new WebApplicationException( - responseGenerator.badIfNoneExistHeaderValue(ifNoneExistHeader.get(), unsupportedQueryParameters)); + { + Response response = responseGenerator.badIfNoneExistHeaderValue(ifNoneExistHeader.get(), + unsupportedQueryParameters); + throw new WebApplicationException(response); + } PartialResult result = exceptionHandler.handleSqlException(() -> dao.search(query)); if (result.getTotal() == 1) - throw new WebApplicationException( - responseGenerator.oneExists(result.getPartialResult().get(0), ifNoneExistHeader.get())); + { + Response response = responseGenerator.oneExists(result.getPartialResult().get(0), ifNoneExistHeader.get()); + throw new WebApplicationException(response); + } else if (result.getTotal() > 1) - throw new WebApplicationException( - responseGenerator.multipleExists(resourceTypeName, ifNoneExistHeader.get())); + { + Response response = responseGenerator.multipleExists(resourceTypeName, ifNoneExistHeader.get()); + throw new WebApplicationException(response); + } } private Optional getHeaderString(HttpHeaders headers, String... headerNames) @@ -384,7 +395,12 @@ else if (ifNoneMatch.isEmpty() && ifModifiedSince else return responseGenerator.response(Status.OK, resource, getMediaTypeForRead(uri, headers)).build(); - }).orElseGet(() -> Response.status(Status.NOT_FOUND).build()); // TODO return OperationOutcome + }).orElseGet(() -> + { + // TODO return OperationOutcome + Response response = Response.status(Status.NOT_FOUND).build(); + return response; + }); } private boolean afterWithSecondsPrecision(Date a, Date b) @@ -460,7 +476,12 @@ else if (ifNoneMatch.isEmpty() && ifModifiedSince } else return responseGenerator.response(Status.OK, resource, getMediaTypeForVRead(uri, headers)).build(); - }).orElseGet(() -> Response.status(Status.NOT_FOUND).build()); // TODO return OperationOutcome + }).orElseGet(() -> + { + // TODO return OperationOutcome + Response response = Response.status(Status.NOT_FOUND).build(); + return response; + }); } protected MediaType getMediaTypeForVRead(UriInfo uri, HttpHeaders headers) diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/webservice/impl/StructureDefinitionServiceImpl.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/webservice/impl/StructureDefinitionServiceImpl.java index 6d775e3d3..437d829fa 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/webservice/impl/StructureDefinitionServiceImpl.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/webservice/impl/StructureDefinitionServiceImpl.java @@ -292,7 +292,9 @@ private StructureDefinition generateSnapshot(StructureDefinition differential) .setCode(IssueType.STRUCTURE).setDiagnostics(vm.getMessage())) .collect(Collectors.toList()); outcome.setIssue(issues); - throw new WebApplicationException(Response.status(Status.INTERNAL_SERVER_ERROR).entity(outcome).build()); + + Response response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(outcome).build(); + throw new WebApplicationException(response); } } } diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/webservice/secure/AbstractResourceServiceSecure.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/webservice/secure/AbstractResourceServiceSecure.java index fbc3613e0..fb8ceba59 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/webservice/secure/AbstractResourceServiceSecure.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/webservice/secure/AbstractResourceServiceSecure.java @@ -153,10 +153,13 @@ public Response create(R resource, UriInfo uri, HttpHeaders headers) audit.info("Create of resource {} allowed for user '{}', reason: {}", resourceTypeName, getCurrentIdentity().getName(), reasonCreateAllowed.get()); - Response created = logResultStatus(() -> delegate.create(resource, uri, headers), - status -> audit.info("Create of resource {} for user '{}' successful, status: {} {}", - resourceTypeName, getCurrentIdentity().getName(), status.getStatusCode(), - status.getReasonPhrase()), + Response created = logResultStatus(() -> + { + Response response = delegate.create(resource, uri, headers); + return response; + }, status -> audit.info("Create of resource {} for user '{}' successful, status: {} {}", + resourceTypeName, getCurrentIdentity().getName(), status.getStatusCode(), + status.getReasonPhrase()), status -> audit.info("Create of resource {} for user '{}' failed, status: {} {}", resourceTypeName, getCurrentIdentity().getName(), status.getStatusCode(), status.getReasonPhrase())); @@ -346,9 +349,12 @@ public Response history(UriInfo uri, HttpHeaders headers) { audit.info("History of {} allowed for identity '{}', reason: {}", resourceTypeName, getCurrentIdentity().getName(), reasonHistoryAllowed.get()); - return logResultStatus(() -> delegate.history(uri, headers), - status -> audit.info("History of {} for identity '{}' successful: {} {}", resourceTypeName, - getCurrentIdentity().getName(), status.getStatusCode(), status.getReasonPhrase()), + return logResultStatus(() -> + { + Response response = delegate.history(uri, headers); + return response; + }, status -> audit.info("History of {} for identity '{}' successful: {} {}", resourceTypeName, + getCurrentIdentity().getName(), status.getStatusCode(), status.getReasonPhrase()), status -> audit.info("History of {} for identity '{}' failed: {} {}", resourceTypeName, getCurrentIdentity().getName(), status.getStatusCode(), status.getReasonPhrase())); } @@ -367,9 +373,12 @@ public Response history(String id, UriInfo uri, HttpHeaders headers) { audit.info("History of {} allowed for identity '{}', reason: {}", resourceTypeName, getCurrentIdentity().getName(), reasonHistoryAllowed.get()); - return logResultStatus(() -> delegate.history(id, uri, headers), - status -> audit.info("History of {} for identity '{}' successful: {} {}", resourceTypeName, - getCurrentIdentity().getName(), status.getStatusCode(), status.getReasonPhrase()), + return logResultStatus(() -> + { + Response response = delegate.history(id, uri, headers); + return response; + }, status -> audit.info("History of {} for identity '{}' successful: {} {}", resourceTypeName, + getCurrentIdentity().getName(), status.getStatusCode(), status.getReasonPhrase()), status -> audit.info("History of {} for identity '{}' failed: {} {}", resourceTypeName, getCurrentIdentity().getName(), status.getStatusCode(), status.getReasonPhrase())); } @@ -415,10 +424,13 @@ private Response update(String id, R newResource, UriInfo uri, HttpHeaders heade { audit.info("Update of {}/{}/_history/{} allowed for identity '{}', reason: {}", resourceTypeName, resourceId, resourceVersion, getCurrentIdentity().getName(), reasonUpdateAllowed.get()); - Response updated = logResultStatus(() -> delegate.update(id, newResource, uri, headers), - status -> audit.info("Update of {}/{}/_history/{} for identity '{}' successful, status: {} {}", - resourceTypeName, resourceId, resourceVersion, getCurrentIdentity().getName(), - status.getStatusCode(), status.getReasonPhrase()), + Response updated = logResultStatus(() -> + { + Response response = delegate.update(id, newResource, uri, headers); + return response; + }, status -> audit.info("Update of {}/{}/_history/{} for identity '{}' successful, status: {} {}", + resourceTypeName, resourceId, resourceVersion, getCurrentIdentity().getName(), + status.getStatusCode(), status.getReasonPhrase()), status -> audit.info("Update of {}/{}/_history/{} for identity '{}' failed, status: {} {}", resourceTypeName, resourceId, resourceVersion, getCurrentIdentity().getName(), status.getStatusCode(), status.getReasonPhrase())); @@ -535,10 +547,12 @@ private PartialResult getExisting(Map> queryParameters) audit.info( "Update of resource {} denied for identity '{}', conditional update criteria contains unsupported parameters", resourceTypeName, getCurrentIdentity().getName()); - throw new WebApplicationException(responseGenerator.badRequest( + + Response response = responseGenerator.badRequest( UriComponentsBuilder.newInstance() .replaceQueryParams(CollectionUtils.toMultiValueMap(queryParameters)).toUriString(), - unsupportedQueryParameters)); + unsupportedQueryParameters); + throw new WebApplicationException(response); } return exceptionHandler.handleSqlException(() -> dao.search(query)); @@ -569,10 +583,13 @@ public Response delete(String id, UriInfo uri, HttpHeaders headers) { audit.info("Delete of {}/{}/_history/{} allowed for identity '{}', reason: {}", resourceTypeName, resourceId, resourceVersion, getCurrentIdentity().getName(), reasonDeleteAllowed.get()); - return logResultStatus(() -> delegate.delete(id, uri, headers), - status -> audit.info("Delete of {}/{}/_history/{} for identity '{}' successful, status: {} {}", - resourceTypeName, resourceId, resourceVersion, getCurrentIdentity().getName(), - status.getStatusCode(), status.getReasonPhrase()), + return logResultStatus(() -> + { + Response response = delegate.delete(id, uri, headers); + return response; + }, status -> audit.info("Delete of {}/{}/_history/{} for identity '{}' successful, status: {} {}", + resourceTypeName, resourceId, resourceVersion, getCurrentIdentity().getName(), + status.getStatusCode(), status.getReasonPhrase()), status -> audit.info("Delete of {}/{}/_history/{} for identity '{}' failed, status: {} {}", resourceTypeName, resourceId, resourceVersion, getCurrentIdentity().getName(), status.getStatusCode(), status.getReasonPhrase())); @@ -661,9 +678,12 @@ public Response search(UriInfo uri, HttpHeaders headers) { audit.info("Search of {} allowed for identity '{}', reason: {}", resourceTypeName, getCurrentIdentity().getName(), reasonSearchAllowed.get()); - return logResultStatus(() -> delegate.search(uri, headers), - status -> audit.info("Search of {} for identity '{} successful, status: {} {}'", resourceTypeName, - getCurrentIdentity().getName(), status.getStatusCode(), status.getReasonPhrase()), + return logResultStatus(() -> + { + Response response = delegate.search(uri, headers); + return response; + }, status -> audit.info("Search of {} for identity '{} successful, status: {} {}'", resourceTypeName, + getCurrentIdentity().getName(), status.getStatusCode(), status.getReasonPhrase()), status -> audit.info("Search of {} for identity '{}' failed, status: {} {}", resourceTypeName, getCurrentIdentity().getName(), status.getStatusCode(), status.getReasonPhrase())); } @@ -694,11 +714,14 @@ public Response deletePermanently(String deletePath, String id, UriInfo uri, Htt resourceTypeName, resourceId, resourceVersion, getCurrentIdentity().getName(), reasonDeleteAllowed.get()); - return logResultStatus(() -> delegate.deletePermanently(deletePath, id, uri, headers), - status -> audit.info( - "Permanent delete of {}/{}/_history/{} by identity '{}' successful, status: {} {}", - resourceTypeName, resourceId, resourceVersion, getCurrentIdentity().getName(), - status.getStatusCode(), status.getReasonPhrase()), + return logResultStatus(() -> + { + Response response = delegate.deletePermanently(deletePath, id, uri, headers); + return response; + }, status -> audit.info( + "Permanent delete of {}/{}/_history/{} by identity '{}' successful, status: {} {}", + resourceTypeName, resourceId, resourceVersion, getCurrentIdentity().getName(), + status.getStatusCode(), status.getReasonPhrase()), status -> audit.info( "Permanent delete of {}/{}/_history/{} by identity '{}' failed, status: {} {}", resourceTypeName, resourceId, resourceVersion, getCurrentIdentity().getName(), diff --git a/dsf-fhir/dsf-fhir-validation/pom.xml b/dsf-fhir/dsf-fhir-validation/pom.xml index 0b622df6e..1875ffe39 100644 --- a/dsf-fhir/dsf-fhir-validation/pom.xml +++ b/dsf-fhir/dsf-fhir-validation/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-fhir-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT @@ -104,7 +104,7 @@ - diff --git a/dsf-fhir/dsf-fhir-webservice-client/pom.xml b/dsf-fhir/dsf-fhir-webservice-client/pom.xml index 69d73752d..b027b2c26 100755 --- a/dsf-fhir/dsf-fhir-webservice-client/pom.xml +++ b/dsf-fhir/dsf-fhir-webservice-client/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-fhir-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-fhir/dsf-fhir-webservice-client/src/main/java/dev/dsf/fhir/client/BasicFhirWebserviceCientWithRetryImpl.java b/dsf-fhir/dsf-fhir-webservice-client/src/main/java/dev/dsf/fhir/client/BasicFhirWebserviceCientWithRetryImpl.java index 92927695d..782932d58 100644 --- a/dsf-fhir/dsf-fhir-webservice-client/src/main/java/dev/dsf/fhir/client/BasicFhirWebserviceCientWithRetryImpl.java +++ b/dsf-fhir/dsf-fhir-webservice-client/src/main/java/dev/dsf/fhir/client/BasicFhirWebserviceCientWithRetryImpl.java @@ -79,13 +79,21 @@ public Bundle search(Class resourceType, Map delegate.readBinary(id, version, mediaType)); + return retry(nTimes, delayMillis, () -> + { + InputStream in = delegate.readBinary(id, version, mediaType); + return in; + }); } @Override public InputStream readBinary(String id, MediaType mediaType) { - return retry(nTimes, delayMillis, () -> delegate.readBinary(id, mediaType)); + return retry(nTimes, delayMillis, () -> + { + InputStream in = delegate.readBinary(id, mediaType); + return in; + }); } @Override diff --git a/dsf-fhir/dsf-fhir-websocket-client/pom.xml b/dsf-fhir/dsf-fhir-websocket-client/pom.xml index a95b561f5..d7f2a5104 100755 --- a/dsf-fhir/dsf-fhir-websocket-client/pom.xml +++ b/dsf-fhir/dsf-fhir-websocket-client/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-fhir-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-fhir/pom.xml b/dsf-fhir/pom.xml index 4deadbc18..540e38ef9 100755 --- a/dsf-fhir/pom.xml +++ b/dsf-fhir/pom.xml @@ -7,7 +7,7 @@ dev.dsf dsf-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-tools/dsf-tools-build-info-reader/pom.xml b/dsf-tools/dsf-tools-build-info-reader/pom.xml index c7f022f71..3c9d03c93 100644 --- a/dsf-tools/dsf-tools-build-info-reader/pom.xml +++ b/dsf-tools/dsf-tools-build-info-reader/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-tools-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-tools/dsf-tools-bundle-generator/pom.xml b/dsf-tools/dsf-tools-bundle-generator/pom.xml index 7ac880e68..7e5575f19 100755 --- a/dsf-tools/dsf-tools-bundle-generator/pom.xml +++ b/dsf-tools/dsf-tools-bundle-generator/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-tools-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-tools/dsf-tools-db-migration/pom.xml b/dsf-tools/dsf-tools-db-migration/pom.xml index 7f481c1de..89e0a7d1f 100755 --- a/dsf-tools/dsf-tools-db-migration/pom.xml +++ b/dsf-tools/dsf-tools-db-migration/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-tools-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-tools/dsf-tools-docker-secrets-reader/pom.xml b/dsf-tools/dsf-tools-docker-secrets-reader/pom.xml index 8653fec00..aee6e7c05 100644 --- a/dsf-tools/dsf-tools-docker-secrets-reader/pom.xml +++ b/dsf-tools/dsf-tools-docker-secrets-reader/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-tools-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-tools/dsf-tools-documentation-generator/pom.xml b/dsf-tools/dsf-tools-documentation-generator/pom.xml index 82b8054fa..30decf6b8 100644 --- a/dsf-tools/dsf-tools-documentation-generator/pom.xml +++ b/dsf-tools/dsf-tools-documentation-generator/pom.xml @@ -7,7 +7,7 @@ dev.dsf dsf-tools-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-tools/dsf-tools-proxy-test/pom.xml b/dsf-tools/dsf-tools-proxy-test/pom.xml index f8deb2fa9..7d50a7f74 100755 --- a/dsf-tools/dsf-tools-proxy-test/pom.xml +++ b/dsf-tools/dsf-tools-proxy-test/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-tools-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-tools/dsf-tools-test-data-generator/pom.xml b/dsf-tools/dsf-tools-test-data-generator/pom.xml index 67c973410..4e3db6f03 100755 --- a/dsf-tools/dsf-tools-test-data-generator/pom.xml +++ b/dsf-tools/dsf-tools-test-data-generator/pom.xml @@ -6,7 +6,7 @@ dev.dsf dsf-tools-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/dsf-tools/pom.xml b/dsf-tools/pom.xml index 47c84b6ef..84f1c41a1 100755 --- a/dsf-tools/pom.xml +++ b/dsf-tools/pom.xml @@ -7,7 +7,7 @@ dev.dsf dsf-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index 1fab1b54e..2aa3ddba5 100755 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ dev.dsf dsf-pom - 1.5.2-SNAPSHOT + 2.0.0-SNAPSHOT pom @@ -15,9 +15,9 @@ UTF-8 - 17 - 17 - 17 + 21 + 21 + 21 ${project.basedir} @@ -562,7 +562,7 @@ net.revelc.code impsort-maven-plugin - 1.9.0 + 1.10.0 org.apache.maven.plugins @@ -665,6 +665,9 @@ java.,javax.,org.,com. java,* + + 18 + true