diff --git a/.gitattributes b/.gitattributes index c1587406e..de781ea1f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10,6 +10,7 @@ # Declare files that will always have certain line endings on checkout. *.bat text eol=crlf *.sh text eol=lf +*.conf text eol=lf # Denote all files that are truly binary and should not be modified. *.png binary diff --git a/.github/workflows/maven-build.yml b/.github/workflows/maven-build.yml index 71ce31358..76cf8b828 100644 --- a/.github/workflows/maven-build.yml +++ b/.github/workflows/maven-build.yml @@ -18,4 +18,4 @@ jobs: java-version: 21 cache: 'maven' - name: Build with Maven - run: mvn --batch-mode --fail-at-end --threads 1C -DforkCount=2 -Dgpg.skip clean verify + run: mvn --batch-mode --fail-at-end -DforkCount=2 -Dgpg.skip clean verify diff --git a/.github/workflows/maven-publish.yml b/.github/workflows/maven-publish.yml index 6b65e2fc8..82d10590e 100644 --- a/.github/workflows/maven-publish.yml +++ b/.github/workflows/maven-publish.yml @@ -25,4 +25,4 @@ jobs: - name: Publish with Maven env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: mvn --batch-mode --fail-at-end --threads 1C -DforkCount=2 -Dgpg.skip clean deploy + run: mvn --batch-mode --fail-at-end -DforkCount=2 -Dgpg.skip clean deploy diff --git a/.gitignore b/.gitignore index 4ab205c7a..6b29325a5 100755 --- a/.gitignore +++ b/.gitignore @@ -12,8 +12,6 @@ ### # dsf-bpe ignores ### -dsf-bpe/dsf-bpe-server-jetty/api/v1/*.jar -dsf-bpe/dsf-bpe-server-jetty/api/v2/*.jar dsf-bpe/dsf-bpe-server-jetty/conf/config.properties dsf-bpe/dsf-bpe-server-jetty/docker/api/v1/*.jar dsf-bpe/dsf-bpe-server-jetty/docker/api/v2/*.jar diff --git a/dsf-bpe/dsf-bpe-process-api-v1-impl/pom.xml b/dsf-bpe/dsf-bpe-process-api-v1-impl/pom.xml index d27cfd40c..89d5ee886 100644 --- a/dsf-bpe/dsf-bpe-process-api-v1-impl/pom.xml +++ b/dsf-bpe/dsf-bpe-process-api-v1-impl/pom.xml @@ -8,7 +8,7 @@ dsf-bpe-pom 2.0.0-SNAPSHOT - + dev.dsf @@ -27,10 +27,6 @@ org.glassfish.jersey.inject jersey-hk2 - - org.glassfish.jersey.media - jersey-media-jaxb - org.glassfish.jersey.media jersey-media-json-jackson @@ -48,10 +44,10 @@ ca.uhn.hapi.fhir - hapi-fhir-structures-r4 + hapi-fhir-validation-resources-r4 ${hapi.fhir.version.v1} - + org.apache.logging.log4j log4j-slf4j2-impl @@ -63,4 +59,146 @@ test + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-api-v1-dependencies-to-docker + pre-integration-test + + copy + + + ../dsf-bpe-server-jetty/docker/api/v1 + + + dev.dsf + dsf-bpe-process-api-v1 + + + dev.dsf + dsf-bpe-process-api-v1-impl + + + ca.uhn.hapi.fhir + hapi-fhir-structures-r4 + ${hapi.fhir.version.v1} + + + ca.uhn.hapi.fhir + org.hl7.fhir.utilities + ${hapi.fhir.version.v1} + + + ca.uhn.hapi.fhir + org.hl7.fhir.r4 + ${hapi.fhir.version.v1} + + + ca.uhn.hapi.fhir + hapi-fhir-validation + ${hapi.fhir.version.v1} + + + ca.uhn.hapi.fhir + hapi-fhir-converter + ${hapi.fhir.version.v1} + + + ca.uhn.hapi.fhir + org.hl7.fhir.convertors + ${hapi.fhir.version.v1} + + + ca.uhn.hapi.fhir + org.hl7.fhir.r5 + ${hapi.fhir.version.v1} + + + net.sf.saxon + Saxon-HE + 9.5.1-5 + + + ca.uhn.hapi.fhir + org.hl7.fhir.validation + ${hapi.fhir.version.v1} + + + + org.apache.commons + commons-compress + + + org.fhir + ucum + 1.0.2 + + + com.github.ben-manes.caffeine + caffeine + 2.7.0 + + + org.checkerframework + checker-qual + 2.6.0 + + + com.google.errorprone + error_prone_annotations + 2.3.3 + + + com.google.code.gson + gson + + + de.hs-heilbronn.mi + crypto-utils + + + ca.uhn.hapi.fhir + hapi-fhir-validation-resources-r4 + + + ca.uhn.hapi.fhir + hapi-fhir-base + ${hapi.fhir.version.v1} + + + + + + + + org.apache.maven.plugins + maven-clean-plugin + + + + ../dsf-bpe-server-jetty/docker/api + + v1/*.jar + + false + + + + + + \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/listener/ContinueListener.java b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/listener/ContinueListener.java index 3f160d899..a77f2bf23 100644 --- a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/listener/ContinueListener.java +++ b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/listener/ContinueListener.java @@ -72,6 +72,5 @@ processUrl, getCurrentTime(), continueTaskUrl, requester, businessKey, correlati logger.info("Continuing process {} at {} [task: {}, requester: {}, business-key: {}, message: {}]", processUrl, getCurrentTime(), continueTaskUrl, requester, businessKey, messageName); } - } } diff --git a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/plugin/ProcessPluginImpl.java b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/plugin/ProcessPluginImpl.java index d45c4506b..1f663c3a8 100644 --- a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/plugin/ProcessPluginImpl.java +++ b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/plugin/ProcessPluginImpl.java @@ -41,7 +41,7 @@ import dev.dsf.bpe.v1.ProcessPluginApi; import dev.dsf.bpe.v1.ProcessPluginDefinition; import dev.dsf.bpe.v1.ProcessPluginDeploymentStateListener; -import dev.dsf.bpe.v1.constants.CodeSystems; +import dev.dsf.bpe.v1.constants.CodeSystems.BpmnMessage; import dev.dsf.bpe.v1.constants.NamingSystems.OrganizationIdentifier; import dev.dsf.bpe.v1.constants.NamingSystems.TaskIdentifier; import dev.dsf.bpe.v1.variables.FhirResourceValues; @@ -143,21 +143,18 @@ else if (filename.endsWith(XML_SUFFIX)) }) : Optional.empty(); - Predicate hasTaskInputMessageName = t -> t - .getInput().stream().filter( - i -> i.getType().getCoding().stream() - .anyMatch(c -> CodeSystems.BpmnMessage.URL.equals(c.getSystem()) - && CodeSystems.BpmnMessage.Codes.MESSAGE_NAME.equals(c.getCode()))) + Predicate hasTaskInputMessageName = t -> t.getInput().stream() + .filter(i -> i.getType().getCoding().stream().anyMatch(c -> BpmnMessage.URL.equals(c.getSystem()) + && BpmnMessage.Codes.MESSAGE_NAME.equals(c.getCode()))) .count() == 1; return new ProcessPluginFhirConfig<>(ActivityDefinition.class, CodeSystem.class, Library.class, Measure.class, NamingSystem.class, Questionnaire.class, StructureDefinition.class, Task.class, ValueSet.class, - OrganizationIdentifier.SID, TaskIdentifier.SID, TaskStatus.DRAFT.toCode(), CodeSystems.BpmnMessage.URL, - CodeSystems.BpmnMessage.Codes.MESSAGE_NAME, parseResource, encodeResource, getResourceName, - hasMetadataResourceUrl, hasMetadataResourceVersion, getMetadataResourceVersion, - getActivityDefinitionUrl, NamingSystem::hasName, getTaskInstantiatesCanonical, getTaskIdentifierValue, - isTaskStatusDraft, getRequester, getRecipient, Task::hasInput, hasTaskInputMessageName, - Task::hasOutput); + OrganizationIdentifier.SID, TaskIdentifier.SID, TaskStatus.DRAFT.toCode(), BpmnMessage.URL, + BpmnMessage.Codes.MESSAGE_NAME, parseResource, encodeResource, getResourceName, hasMetadataResourceUrl, + hasMetadataResourceVersion, getMetadataResourceVersion, getActivityDefinitionUrl, NamingSystem::hasName, + getTaskInstantiatesCanonical, getTaskIdentifierValue, isTaskStatusDraft, getRequester, getRecipient, + Task::hasInput, hasTaskInputMessageName, Task::hasOutput); } private IParser newXmlParser() diff --git a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/service/AbstractResourceProvider.java b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/service/AbstractResourceProvider.java index cea3491b9..69d49254b 100644 --- a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/service/AbstractResourceProvider.java +++ b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/service/AbstractResourceProvider.java @@ -3,7 +3,6 @@ import static org.hl7.fhir.instance.model.api.IBaseBundle.LINK_NEXT; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -72,9 +71,9 @@ protected final List search(Class se private Bundle search(Class searchType, Map> parameters, int page) { Map> parametersAndPage = new HashMap<>(parameters); - parametersAndPage.put("_page", Collections.singletonList(String.valueOf(page))); + parametersAndPage.put("_page", List.of(String.valueOf(page))); if (!parameters.containsKey("_sort")) - parametersAndPage.put("_sort", Collections.singletonList("_id")); + parametersAndPage.put("_sort", List.of("_id")); return clientProvider.getLocalWebserviceClient().searchWithStrictHandling(searchType, parametersAndPage); } diff --git a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/service/EndpointProviderImpl.java b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/service/EndpointProviderImpl.java index 02e9119ca..70d856713 100644 --- a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/service/EndpointProviderImpl.java +++ b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/service/EndpointProviderImpl.java @@ -1,6 +1,5 @@ package dev.dsf.bpe.v1.service; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; @@ -30,8 +29,7 @@ public EndpointProviderImpl(FhirWebserviceClientProvider clientProvider, String public Optional getLocalEndpoint() { Bundle resultBundle = clientProvider.getLocalWebserviceClient().searchWithStrictHandling(Endpoint.class, - Map.of("status", Collections.singletonList("active"), "address", - Collections.singletonList(localEndpointAddress))); + Map.of("status", List.of("active"), "address", List.of(localEndpointAddress))); if (resultBundle == null || resultBundle.getEntry() == null || resultBundle.getEntry().size() != 1 || resultBundle.getEntryFirstRep().getResource() == null @@ -61,8 +59,8 @@ public Optional getEndpoint(Identifier endpointIdentifier) String endpointIdSp = toSearchParameter(endpointIdentifier); - Bundle resultBundle = clientProvider.getLocalWebserviceClient().searchWithStrictHandling(Endpoint.class, Map.of( - "status", Collections.singletonList("active"), "identifier", Collections.singletonList(endpointIdSp))); + Bundle resultBundle = clientProvider.getLocalWebserviceClient().searchWithStrictHandling(Endpoint.class, + Map.of("status", List.of("active"), "identifier", List.of(endpointIdSp))); if (resultBundle == null || resultBundle.getEntry() == null || resultBundle.getTotal() != 1 || resultBundle.getEntryFirstRep().getResource() == null @@ -81,17 +79,17 @@ public Optional getEndpoint(Identifier parentOrganizationIdentifier, { if (parentOrganizationIdentifier == null) { - logger.debug("Parent organiztion identifier is null"); + logger.debug("Parent organization identifier is null"); return Optional.empty(); } else if (memberOrganizationIdentifier == null) { - logger.debug("Member organiztion identifier is null"); + logger.debug("Member organization identifier is null"); return Optional.empty(); } else if (memberOrganizationRole == null) { - logger.debug("Member organiztion role is null"); + logger.debug("Member organization role is null"); return Optional.empty(); } @@ -101,11 +99,9 @@ else if (memberOrganizationRole == null) Bundle resultBundle = clientProvider.getLocalWebserviceClient().searchWithStrictHandling( OrganizationAffiliation.class, - Map.of("active", Collections.singletonList("true"), "primary-organization:identifier", - Collections.singletonList(parentOrganizationIdSp), "participating-organization:identifier", - Collections.singletonList(memberOrganizationIdSp), "role", - Collections.singletonList(memberOrganizationRoleSp), "_include", - Collections.singletonList("OrganizationAffiliation:endpoint"))); + Map.of("active", List.of("true"), "primary-organization:identifier", List.of(parentOrganizationIdSp), + "participating-organization:identifier", List.of(memberOrganizationIdSp), "role", + List.of(memberOrganizationRoleSp), "_include", List.of("OrganizationAffiliation:endpoint"))); if (resultBundle == null || resultBundle.getEntry() == null || resultBundle.getTotal() != 1 || resultBundle.getEntryFirstRep().getResource() == null @@ -141,22 +137,21 @@ public List getEndpoints(Identifier parentOrganizationIdentifier, Codi { if (parentOrganizationIdentifier == null) { - logger.debug("Parent organiztion identifier is null"); - return Collections.emptyList(); + logger.debug("Parent organization identifier is null"); + return List.of(); } else if (memberOrganizationRole == null) { - logger.debug("Member organiztion role is null"); - return Collections.emptyList(); + logger.debug("Member organization role is null"); + return List.of(); } String parentOrganizationIdSp = toSearchParameter(parentOrganizationIdentifier); String memberOrganizationRoleSp = toSearchParameter(memberOrganizationRole); - Map> parameters = Map.of("active", Collections.singletonList("true"), - "primary-organization:identifier", Collections.singletonList(parentOrganizationIdSp), "role", - Collections.singletonList(memberOrganizationRoleSp), "_include", - Collections.singletonList("OrganizationAffiliation:endpoint")); + Map> parameters = Map.of("active", List.of("true"), "primary-organization:identifier", + List.of(parentOrganizationIdSp), "role", List.of(memberOrganizationRoleSp), "_include", + List.of("OrganizationAffiliation:endpoint")); return search(OrganizationAffiliation.class, parameters, SearchEntryMode.INCLUDE, Endpoint.class, e -> EndpointStatus.ACTIVE.equals(e.getStatus())); diff --git a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/service/OrganizationProviderImpl.java b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/service/OrganizationProviderImpl.java index 32174025b..d7a7b892c 100644 --- a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/service/OrganizationProviderImpl.java +++ b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/service/OrganizationProviderImpl.java @@ -1,6 +1,5 @@ package dev.dsf.bpe.v1.service; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; @@ -30,9 +29,8 @@ public OrganizationProviderImpl(FhirWebserviceClientProvider clientProvider, Str public Optional getLocalOrganization() { Bundle resultBundle = clientProvider.getLocalWebserviceClient().searchWithStrictHandling(Endpoint.class, - Map.of("status", Collections.singletonList("active"), "address", - Collections.singletonList(localEndpointAddress), "_include", - Collections.singletonList("Endpoint:organization"))); + Map.of("status", List.of("active"), "address", List.of(localEndpointAddress), "_include", + List.of("Endpoint:organization"))); if (resultBundle == null || resultBundle.getEntry() == null || resultBundle.getEntry().size() != 2 || resultBundle.getEntry().get(0).getResource() == null @@ -40,12 +38,12 @@ public Optional getLocalOrganization() || resultBundle.getEntry().get(1).getResource() == null || !(resultBundle.getEntry().get(1).getResource() instanceof Organization)) { - logger.warn("No active (or more than one) Endpoint found for address '{}'", localEndpointAddress); + logger.warn("No active (or more than one) endpoint found for address '{}'", localEndpointAddress); return Optional.empty(); } else if (getActiveOrganizationFromIncludes(resultBundle).count() != 1) { - logger.warn("No active (or more than one) Organization found by active Endpoint with address '{}'", + logger.warn("No active (or more than one) organization found by active endpoint with address '{}'", localEndpointAddress); return Optional.empty(); } @@ -73,14 +71,13 @@ public Optional getOrganization(Identifier organizationIdentifier) String organizationIdSp = toSearchParameter(organizationIdentifier); Bundle resultBundle = clientProvider.getLocalWebserviceClient().searchWithStrictHandling(Organization.class, - Map.of("active", Collections.singletonList("true"), "identifier", - Collections.singletonList(organizationIdSp))); + Map.of("active", List.of("true"), "identifier", List.of(organizationIdSp))); if (resultBundle == null || resultBundle.getEntry() == null || resultBundle.getTotal() != 1 || resultBundle.getEntryFirstRep().getResource() == null || !(resultBundle.getEntryFirstRep().getResource() instanceof Organization)) { - logger.warn("No active (or more than one) Organization found for identifier '{}'", organizationIdSp); + logger.warn("No active (or more than one) organization found for identifier '{}'", organizationIdSp); return Optional.empty(); } @@ -92,15 +89,15 @@ public List getOrganizations(Identifier parentOrganizationIdentifi { if (parentOrganizationIdentifier == null) { - logger.debug("Parent organiztion identifier is null"); - return Collections.emptyList(); + logger.debug("Parent organization identifier is null"); + return List.of(); } String parentOrganizationIdSp = toSearchParameter(parentOrganizationIdentifier); - Map> parameters = Map.of("active", Collections.singletonList("true"), - "primary-organization:identifier", Collections.singletonList(parentOrganizationIdSp), "_include", - Collections.singletonList("OrganizationAffiliation:participating-organization")); + Map> parameters = Map.of("active", List.of("true"), "primary-organization:identifier", + List.of(parentOrganizationIdSp), "_include", + List.of("OrganizationAffiliation:participating-organization")); return search(OrganizationAffiliation.class, parameters, SearchEntryMode.INCLUDE, Organization.class, Organization::getActive); @@ -111,22 +108,21 @@ public List getOrganizations(Identifier parentOrganizationIdentifi { if (parentOrganizationIdentifier == null) { - logger.debug("Parent organiztion identifier is null"); - return Collections.emptyList(); + logger.debug("Parent organization identifier is null"); + return List.of(); } else if (memberOrganizationRole == null) { - logger.debug("Member organiztion role is null"); - return Collections.emptyList(); + logger.debug("Member organization role is null"); + return List.of(); } String parentOrganizationIdSp = toSearchParameter(parentOrganizationIdentifier); String memberOrganizationRoleSp = toSearchParameter(memberOrganizationRole); - Map> parameters = Map.of("active", Collections.singletonList("true"), - "primary-organization:identifier", Collections.singletonList(parentOrganizationIdSp), "role", - Collections.singletonList(memberOrganizationRoleSp), "_include", - Collections.singletonList("OrganizationAffiliation:participating-organization")); + Map> parameters = Map.of("active", List.of("true"), "primary-organization:identifier", + List.of(parentOrganizationIdSp), "role", List.of(memberOrganizationRoleSp), "_include", + List.of("OrganizationAffiliation:participating-organization")); return search(OrganizationAffiliation.class, parameters, SearchEntryMode.INCLUDE, Organization.class, Organization::getActive); @@ -139,12 +135,12 @@ public List getRemoteOrganizations() if (localOrganizationIdentifier.isEmpty()) { - logger.debug("Local organiztion identifier unknown"); - return Collections.emptyList(); + logger.debug("Local organization identifier unknown"); + return List.of(); } - Map> searchParameters = Map.of("active", Collections.singletonList("true"), - "identifier:not", Collections.singletonList(toSearchParameter(localOrganizationIdentifier.get()))); + Map> searchParameters = Map.of("active", List.of("true"), "identifier:not", + List.of(toSearchParameter(localOrganizationIdentifier.get()))); return search(Organization.class, searchParameters, SearchEntryMode.MATCH, Organization.class, o -> true); } } diff --git a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/spring/ApiServiceConfig.java b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/spring/ApiServiceConfig.java index 8873ece3b..18e83a0a2 100644 --- a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/spring/ApiServiceConfig.java +++ b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/spring/ApiServiceConfig.java @@ -126,6 +126,7 @@ public ReferenceExtractor referenceExtractor() public FhirContext fhirContext() { // workaround for https://github.com/hapifhir/hapi-fhir/issues/5205 + // Do not remove as HAPI dependency of v1 will not be upgraded to a fixed version StreamReadConstraints.overrideDefaultStreamReadConstraints( StreamReadConstraints.builder().maxStringLength(Integer.MAX_VALUE).build()); diff --git a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/variables/FhirResourcesList.java b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/variables/FhirResourcesList.java index a4c93d881..e26d9b132 100644 --- a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/variables/FhirResourcesList.java +++ b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/bpe/v1/variables/FhirResourcesList.java @@ -1,7 +1,6 @@ package dev.dsf.bpe.v1.variables; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -26,7 +25,7 @@ public FhirResourcesList(@JsonProperty("resources") Collection targets) { if (targets == null) - return new TargetsImpl(Collections.emptyList()); + return new TargetsImpl(List.of()); Optional firstNonMatch = targets.stream().filter(t -> !(t instanceof TargetImpl)).findFirst(); if (firstNonMatch.isPresent()) @@ -219,7 +219,7 @@ public List getCurrentTasks() Stream start = execution.getParentId() == null ? Stream.of(getStartTask()) : Stream.empty(); Stream current = getResourceListOrDefault(TASKS_PREFIX + execution.getParentActivityInstanceId(), - Collections. emptyList()).stream(); + List. of()).stream(); return Collections.unmodifiableList(Stream.concat(start, current).toList()); } @@ -237,7 +237,7 @@ public void updateTask(Task task) else { String instanceId = execution.getParentActivityInstanceId(); - List tasks = getResourceListOrDefault(TASKS_PREFIX + instanceId, Collections.emptyList()); + List tasks = getResourceListOrDefault(TASKS_PREFIX + instanceId, List.of()); if (tasks.stream().anyMatch(t -> t.getIdElement().getIdPart().equals(task.getIdElement().getIdPart()))) setResourceList(TASKS_PREFIX + instanceId, tasks); @@ -292,8 +292,7 @@ public void onContinue(Task task) { String instanceId = execution.getParentActivityInstanceId(); - List tasks = new ArrayList<>( - getResourceListOrDefault(TASKS_PREFIX + instanceId, Collections.emptyList())); + List tasks = new ArrayList<>(getResourceListOrDefault(TASKS_PREFIX + instanceId, List.of())); tasks.add(task); setResourceList(TASKS_PREFIX + instanceId, tasks); @@ -308,8 +307,7 @@ public void onEnd() logger.trace("onEnd"); String instanceId = execution.getParentActivityInstanceId(); - List tasks = new ArrayList<>( - getResourceListOrDefault(TASKS_PREFIX + instanceId, Collections.emptyList())); + List tasks = new ArrayList<>(getResourceListOrDefault(TASKS_PREFIX + instanceId, List.of())); tasks.removeAll(getCurrentTasks()); setResourceList(TASKS_PREFIX + instanceId, tasks); } diff --git a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/fhir/authorization/read/ReadAccessHelperImpl.java b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/fhir/authorization/read/ReadAccessHelperImpl.java index 5996978a5..8d758f312 100644 --- a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/fhir/authorization/read/ReadAccessHelperImpl.java +++ b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/fhir/authorization/read/ReadAccessHelperImpl.java @@ -1,6 +1,5 @@ package dev.dsf.fhir.authorization.read; -import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -19,7 +18,7 @@ public class ReadAccessHelperImpl implements ReadAccessHelper { - private static final List READ_ACCESS_TAG_VALUES = Arrays.asList(READ_ACCESS_TAG_VALUE_LOCAL, + private static final List READ_ACCESS_TAG_VALUES = List.of(READ_ACCESS_TAG_VALUE_LOCAL, READ_ACCESS_TAG_VALUE_ORGANIZATION, READ_ACCESS_TAG_VALUE_ROLE, READ_ACCESS_TAG_VALUE_ALL); private Predicate matchesTagValue(String value) diff --git a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/fhir/client/FhirWebserviceClientJersey.java b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/fhir/client/FhirWebserviceClientJersey.java index 8a1257ad8..b94236618 100644 --- a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/fhir/client/FhirWebserviceClientJersey.java +++ b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/main/java/dev/dsf/fhir/client/FhirWebserviceClientJersey.java @@ -3,7 +3,6 @@ import java.io.InputStream; import java.security.KeyStore; import java.text.SimpleDateFormat; -import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Locale; @@ -80,8 +79,8 @@ public FhirWebserviceClientJersey(String baseUrl, KeyStore trustStore, KeyStore ReferenceCleaner referenceCleaner) { super(baseUrl, trustStore, keyStore, keyStorePassword, objectMapper, - Collections.singleton(new FhirAdapter(fhirContext, referenceCleaner)), proxySchemeHostPort, - proxyUserName, proxyPassword, connectTimeout, readTimeout, logRequests, userAgentValue); + List.of(new FhirAdapter(fhirContext, referenceCleaner)), proxySchemeHostPort, proxyUserName, + proxyPassword, connectTimeout, readTimeout, logRequests, userAgentValue); preferReturnMinimal = new PreferReturnMinimalWithRetryImpl(this); preferReturnOutcome = new PreferReturnOutcomeWithRetryImpl(this); diff --git a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/test/java/dev/dsf/bpe/v1/plugin/ProcessPluginImplTest.java b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/test/java/dev/dsf/bpe/v1/plugin/ProcessPluginImplTest.java index 0d10752de..f9131f4ec 100644 --- a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/test/java/dev/dsf/bpe/v1/plugin/ProcessPluginImplTest.java +++ b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/test/java/dev/dsf/bpe/v1/plugin/ProcessPluginImplTest.java @@ -10,7 +10,6 @@ import java.nio.file.Paths; import java.time.LocalDate; import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Map; @@ -207,8 +206,7 @@ public void testInitializeAndValidateResourcesAllNull() throws Exception @Test public void testInitializeAndValidateResourcesEmptySpringConfigBpmnAndFhirResources() throws Exception { - var definition = createPluginDefinition("1.0.0.0", LocalDate.now(), Collections.emptyList(), - Collections.emptyList(), Collections.emptyMap()); + var definition = createPluginDefinition("1.0.0.0", LocalDate.now(), List.of(), List.of(), Map.of()); AbstractProcessPlugin plugin = createPlugin(definition, false); assertFalse(plugin.initializeAndValidateResources(null)); diff --git a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/test/java/dev/dsf/bpe/v1/variables/TargetsJsonSerializationTest.java b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/test/java/dev/dsf/bpe/v1/variables/TargetsJsonSerializationTest.java index cdf251b1f..746594233 100644 --- a/dsf-bpe/dsf-bpe-process-api-v1-impl/src/test/java/dev/dsf/bpe/v1/variables/TargetsJsonSerializationTest.java +++ b/dsf-bpe/dsf-bpe-process-api-v1-impl/src/test/java/dev/dsf/bpe/v1/variables/TargetsJsonSerializationTest.java @@ -5,7 +5,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import java.util.Collections; +import java.util.List; import java.util.UUID; import org.junit.Test; @@ -25,7 +25,7 @@ public void testEmptyTargetsSerialization() throws Exception { ObjectMapper mapper = ObjectMapperFactory.createObjectMapper(FhirContext.forR4()); - Targets targets = new TargetsImpl(Collections.emptyList()); + Targets targets = new TargetsImpl(List.of()); String targetsAsString = mapper.writeValueAsString(targets); assertNotNull(targetsAsString); @@ -44,7 +44,7 @@ public void testTargetsWithBiDirectionalTargetSerialization() throws Exception TargetImpl target = new TargetImpl("target.org", "endpoint.target.org", "https://endpoint.target.org/fhir", UUID.randomUUID().toString()); - Targets targets = new TargetsImpl(Collections.singletonList(target)); + Targets targets = new TargetsImpl(List.of(target)); String targetsAsString = mapper.writeValueAsString(targets); assertNotNull(targetsAsString); @@ -67,7 +67,7 @@ public void testTargetsWithUniDirectionalTargetSerialization() throws Exception TargetImpl target = new TargetImpl("target.org", "endpoint.target.org", "https://endpoint.target.org/fhir", null); - Targets targets = new TargetsImpl(Collections.singletonList(target)); + Targets targets = new TargetsImpl(List.of(target)); String targetsAsString = mapper.writeValueAsString(targets); assertNotNull(targetsAsString); diff --git a/dsf-bpe/dsf-bpe-process-api-v1/pom.xml b/dsf-bpe/dsf-bpe-process-api-v1/pom.xml index ffd49153a..0ff93958d 100644 --- a/dsf-bpe/dsf-bpe-process-api-v1/pom.xml +++ b/dsf-bpe/dsf-bpe-process-api-v1/pom.xml @@ -8,7 +8,7 @@ dsf-bpe-pom 2.0.0-SNAPSHOT - + ca.uhn.hapi.fhir @@ -33,7 +33,7 @@ jakarta.ws.rs-api - jakarta.ws.rs + jakarta.ws.rs @@ -47,5 +47,17 @@ crypto-utils true + + ca.uhn.hapi.fhir + hapi-fhir-validation + ${hapi.fhir.version.v1} + true + + + commons-logging + commons-logging + + + \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-process-api-v1/src/main/java/dev/dsf/bpe/v1/activity/DefaultUserTaskListener.java b/dsf-bpe/dsf-bpe-process-api-v1/src/main/java/dev/dsf/bpe/v1/activity/DefaultUserTaskListener.java index b17fe985b..244977ed7 100644 --- a/dsf-bpe/dsf-bpe-process-api-v1/src/main/java/dev/dsf/bpe/v1/activity/DefaultUserTaskListener.java +++ b/dsf-bpe/dsf-bpe-process-api-v1/src/main/java/dev/dsf/bpe/v1/activity/DefaultUserTaskListener.java @@ -130,7 +130,6 @@ private Questionnaire readQuestionnaire(String urlWithVersion) return questionnaires.get(0); } - private QuestionnaireResponse createDefaultQuestionnaireResponse(String questionnaireUrlWithVersion, String businessKey, String userTaskId) { diff --git a/dsf-bpe/dsf-bpe-process-api-v1/src/main/java/dev/dsf/bpe/v1/service/EndpointProvider.java b/dsf-bpe/dsf-bpe-process-api-v1/src/main/java/dev/dsf/bpe/v1/service/EndpointProvider.java index 2a2995ffb..2a7658c08 100644 --- a/dsf-bpe/dsf-bpe-process-api-v1/src/main/java/dev/dsf/bpe/v1/service/EndpointProvider.java +++ b/dsf-bpe/dsf-bpe-process-api-v1/src/main/java/dev/dsf/bpe/v1/service/EndpointProvider.java @@ -6,6 +6,7 @@ import org.hl7.fhir.r4.model.Coding; import org.hl7.fhir.r4.model.Endpoint; import org.hl7.fhir.r4.model.Identifier; +import org.hl7.fhir.r4.model.OrganizationAffiliation; import dev.dsf.bpe.v1.constants.NamingSystems.EndpointIdentifier; import dev.dsf.bpe.v1.constants.NamingSystems.OrganizationIdentifier; @@ -52,15 +53,15 @@ default Optional getLocalEndpointIdentifierValue() /** * @param endpointIdentifier * may be null - * @return {@link Endpoint} resource from the local DSF FHIR server with the given endpointIdentifier, empty - * {@link Optional} if no such resource exists or the given identifier is null + * @return Active {@link Endpoint} resource from the local DSF FHIR server with the given endpointIdentifier, + * empty {@link Optional} if no such resource exists or the given identifier is null */ Optional getEndpoint(Identifier endpointIdentifier); /** * @param endpointIdentifierValue * may be null - * @return {@link Endpoint} resource from the local DSF FHIR server with the given DSF + * @return Active {@link Endpoint} resource from the local DSF FHIR server with the given DSF * endpointIdentifierValue, empty {@link Optional} if no such resource exists or the given identifier * value is null * @see EndpointIdentifier @@ -74,7 +75,7 @@ default Optional getEndpoint(String endpointIdentifierValue) /** * @param endpointIdentifier * may be null - * @return Address (base URL) of the {@link Endpoint} resource from the local DSF FHIR server with the given + * @return Address (base URL) of the active {@link Endpoint} resource from the local DSF FHIR server with the given * endpointIdentifier, empty {@link Optional} if no such resource exists or the given identifier is * null */ @@ -86,9 +87,9 @@ default Optional getEndpointAddress(Identifier endpointIdentifier) /** * @param endpointIdentifierValue * may be null - * @return Address (base URL) of the {@link Endpoint} resource from the local DSF FHIR server with the given DSF - * endpointIdentifierValue, empty {@link Optional} if no such resource exists or the given identifier - * value is null + * @return Address (base URL) of the active {@link Endpoint} resource from the local DSF FHIR server with the given + * DSF endpointIdentifierValue, empty {@link Optional} if no such resource exists or the given + * identifier value is null */ default Optional getEndpointAddress(String endpointIdentifierValue) { @@ -103,10 +104,11 @@ default Optional getEndpointAddress(String endpointIdentifierValue) * may be null * @param memberOrganizationRole * may be null - * @return {@link Endpoint} resource from the local DSF FHIR server associated with the given + * @return Active {@link Endpoint} resource from the local DSF FHIR server associated with the given * memberOrganizationIdentifier and memberOrganizationRole in a parent organization with the * given parentOrganizationIdentifier, empty {@link Optional} if no such resource exists or one of - * the parameters is null + * the parameters is null; only considers Endpoints from active {@link OrganizationAffiliation} + * resources */ Optional getEndpoint(Identifier parentOrganizationIdentifier, Identifier memberOrganizationIdentifier, Coding memberOrganizationRole); @@ -118,10 +120,11 @@ Optional getEndpoint(Identifier parentOrganizationIdentifier, Identifi * may be null * @param memberOrganizationRole * may be null - * @return {@link Endpoint} resource from the local DSF FHIR server associated with the given DSF + * @return Active {@link Endpoint} resource from the local DSF FHIR server associated with the given DSF * memberOrganizationIdentifierValue and memberOrganizationRole in a parent organization with * the given DSF parentOrganizationIdentifierValue, empty {@link Optional} if no such resource exists - * or one of the parameters is null + * or one of the parameters is null; only considers Endpoints from active + * {@link OrganizationAffiliation} resources * @see OrganizationIdentifier */ default Optional getEndpoint(String parentOrganizationIdentifierValue, @@ -142,10 +145,11 @@ default Optional getEndpoint(String parentOrganizationIdentifierValue, * may be null * @param memberOrganizationRole * may be null - * @return Address (base URL) of the {@link Endpoint} resource from the local DSF FHIR server associated with the - * given memberOrganizationIdentifier and memberOrganizationRole in a parent organization with - * the given parentOrganizationIdentifier, empty {@link Optional} if no such resource exists or one - * of the parameters is null + * @return Address (base URL) of the active {@link Endpoint} resource from the local DSF FHIR server associated with + * the given memberOrganizationIdentifier and memberOrganizationRole in a parent organization + * with the given parentOrganizationIdentifier, empty {@link Optional} if no such resource exists or + * one of the parameters is null; only considers Endpoints from active + * {@link OrganizationAffiliation} resources */ default Optional getEndpointAddress(Identifier parentOrganizationIdentifier, Identifier memberOrganizationIdentifier, Coding memberOrganizationRole) @@ -161,10 +165,11 @@ default Optional getEndpointAddress(Identifier parentOrganizationIdentif * may be null * @param memberOrganizationRole * may be null - * @return Address (base URL) of the {@link Endpoint} resource from the local DSF FHIR server associated with the - * given DSF memberOrganizationIdentifierValue and memberOrganizationRole in a parent + * @return Address (base URL) of the active {@link Endpoint} resource from the local DSF FHIR server associated with + * the given DSF memberOrganizationIdentifierValue and memberOrganizationRole in a parent * organization with the given DSF parentOrganizationIdentifierValue, empty {@link Optional} if no - * such resource exists or one of the parameters is null + * such resource exists or one of the parameters is null; only considers Endpoints from active + * {@link OrganizationAffiliation} resources * @see OrganizationIdentifier */ default Optional getEndpointAddress(String parentOrganizationIdentifierValue, @@ -183,10 +188,10 @@ default Optional getEndpointAddress(String parentOrganizationIdentifierV * may be null * @param memberOrganizationRole * may be null - * @return {@link Endpoint} resources from the local DSF FHIR server associated with the given + * @return Active {@link Endpoint} resources from the local DSF FHIR server associated with the given * memberOrganizationRole in a parent organization with the given * parentOrganizationIdentifier, empty {@link List} if no resources exist or one of the parameters is - * null + * null; only considers Endpoints from active {@link OrganizationAffiliation} resources */ List getEndpoints(Identifier parentOrganizationIdentifier, Coding memberOrganizationRole); @@ -195,10 +200,11 @@ default Optional getEndpointAddress(String parentOrganizationIdentifierV * may be null * @param memberOrganizationRole * may be null - * @return {@link Endpoint} resources from the local DSF FHIR server associated with the given + * @return Active {@link Endpoint} resources from the local DSF FHIR server associated with the given * memberOrganizationRole in a parent organization with the given DSF * parentOrganizationIdentifierValue, empty {@link List} if no resources exist or one of the - * parameters is null + * parameters is null; only considers Endpoints from active {@link OrganizationAffiliation} + * resources * @see OrganizationIdentifier */ default List getEndpoints(String parentOrganizationIdentifierValue, Coding memberOrganizationRole) diff --git a/dsf-bpe/dsf-bpe-process-api-v1/src/main/java/dev/dsf/bpe/v1/service/OrganizationProvider.java b/dsf-bpe/dsf-bpe-process-api-v1/src/main/java/dev/dsf/bpe/v1/service/OrganizationProvider.java index b6a13643b..4f41ba12b 100644 --- a/dsf-bpe/dsf-bpe-process-api-v1/src/main/java/dev/dsf/bpe/v1/service/OrganizationProvider.java +++ b/dsf-bpe/dsf-bpe-process-api-v1/src/main/java/dev/dsf/bpe/v1/service/OrganizationProvider.java @@ -52,16 +52,16 @@ default Optional getLocalOrganizationIdentifierValue() /** * @param organizationIdentifier * may be null - * @return {@link Organization} with the given organizationIdentifier, empty {@link Optional} if no such - * resource exists or the given identifier is null + * @return Active {@link Organization} with the given organizationIdentifier, empty {@link Optional} if no + * such resource exists or the given identifier is null */ Optional getOrganization(Identifier organizationIdentifier); /** * @param organizationIdentifierValue * may be null - * @return {@link Organization} with the given DSF organizationIdentifier, empty {@link Optional} if no such - * resource exists or the given identifier value is null + * @return Active {@link Organization} with the given DSF organizationIdentifier, empty {@link Optional} if + * no such resource exists or the given identifier value is null * @see OrganizationIdentifier */ default Optional getOrganization(String organizationIdentifierValue) @@ -73,20 +73,20 @@ default Optional getOrganization(String organizationIdentifierValu /** * @param parentOrganizationIdentifier * may be null - * @return Organizations configured as participatingOrganization for a parent {@link Organization} with the given - * parentOrganizationIdentifier, empty {@link List} if no parent organization found, parent has no - * participating organizations configured via {@link OrganizationAffiliation} resources or the given - * identifier is null + * @return Active Organizations configured as participatingOrganization for an active parent {@link Organization} + * with the given parentOrganizationIdentifier, empty {@link List} if no parent organization found, + * parent has no participating organizations configured via {@link OrganizationAffiliation} resources or the + * given identifier is null */ List getOrganizations(Identifier parentOrganizationIdentifier); /** * @param parentOrganizationIdentifierValue * may be null - * @return Organizations configured as participatingOrganization for a parent {@link Organization} with the given - * DSF parentOrganizationIdentifierValue, empty {@link List} if no parent organization found, parent - * has no participating organizations configured via {@link OrganizationAffiliation} resources or the given - * identifier is null + * @return Active Organizations configured as participatingOrganization for an active parent {@link Organization} + * with the given DSF parentOrganizationIdentifierValue, empty {@link List} if no parent organization + * found, parent has no participating organizations configured via {@link OrganizationAffiliation} resources + * or the given identifier is null * @see OrganizationIdentifier */ default List getOrganizations(String parentOrganizationIdentifierValue) @@ -100,11 +100,11 @@ default List getOrganizations(String parentOrganizationIdentifierV * may be null * @param memberOrganizationRole * may be null - * @return Organizations configured as participatingOrganization for a parent {@link Organization} with the given - * parentOrganizationIdentifier and role equal to the given memberOrganizationRole, empty - * {@link List} if no parent organization found, parent has no participating organizations configured via - * {@link OrganizationAffiliation} resources with the given role or the given identifier is - * null + * @return Active Organizations configured as participatingOrganization for an active parent {@link Organization} + * with the given parentOrganizationIdentifier and role equal to the given + * memberOrganizationRole, empty {@link List} if no parent organization found, parent has no + * participating organizations configured via {@link OrganizationAffiliation} resources with the given role + * or the given identifier is null */ List getOrganizations(Identifier parentOrganizationIdentifier, Coding memberOrganizationRole); @@ -113,11 +113,11 @@ default List getOrganizations(String parentOrganizationIdentifierV * may be null * @param memberOrganizationRole * may be null - * @return Organizations configured as participatingOrganization for a parent {@link Organization} with the given - * parentOrganizationIdentifier and role equal to the given memberOrganizationRole, empty - * {@link List} if no parent organization found, parent has no participating organizations configured via - * {@link OrganizationAffiliation} resources with the given role or the given identifier is - * null + * @return Active Organizations configured as participatingOrganization for an active parent {@link Organization} + * with the given parentOrganizationIdentifier and role equal to the given + * memberOrganizationRole, empty {@link List} if no parent organization found, parent has no + * participating organizations configured via {@link OrganizationAffiliation} resources with the given role + * or the given identifier is null * @see OrganizationIdentifier */ default List getOrganizations(String parentOrganizationIdentifierValue, Coding memberOrganizationRole) @@ -127,7 +127,7 @@ default List getOrganizations(String parentOrganizationIdentifierV } /** - * @return All {@link Organization} resources except the local {@link Organization} + * @return All active {@link Organization} resources except the local {@link Organization} * @see #getLocalOrganization() */ List getRemoteOrganizations(); diff --git a/dsf-bpe/dsf-bpe-process-api-v2-impl/pom.xml b/dsf-bpe/dsf-bpe-process-api-v2-impl/pom.xml index 9018032a9..e87edf5ea 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2-impl/pom.xml +++ b/dsf-bpe/dsf-bpe-process-api-v2-impl/pom.xml @@ -8,7 +8,7 @@ dsf-bpe-pom 2.0.0-SNAPSHOT - + dev.dsf @@ -27,10 +27,6 @@ org.glassfish.jersey.inject jersey-hk2 - - org.glassfish.jersey.media - jersey-media-jaxb - org.glassfish.jersey.media jersey-media-json-jackson @@ -48,10 +44,10 @@ ca.uhn.hapi.fhir - hapi-fhir-structures-r4 + hapi-fhir-validation-resources-r4 ${hapi.fhir.version.v2} - + org.apache.logging.log4j log4j-slf4j2-impl @@ -63,4 +59,197 @@ test + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-api-v2-dependencies-to-docker + pre-integration-test + + copy + + + ../dsf-bpe-server-jetty/docker/api/v2 + + + dev.dsf + dsf-bpe-process-api-v2 + + + dev.dsf + dsf-bpe-process-api-v2-impl + + + ca.uhn.hapi.fhir + hapi-fhir-structures-r4 + ${hapi.fhir.version.v2} + + + ca.uhn.hapi.fhir + org.hl7.fhir.utilities + ${hapi.fhir.org.hl7.version.v2} + + + com.ibm.icu + icu4j + 72.1 + + + ca.uhn.hapi.fhir + org.hl7.fhir.r4 + ${hapi.fhir.org.hl7.version.v2} + + + ca.uhn.hapi.fhir + hapi-fhir-caching-api + ${hapi.fhir.version.v2} + + + ca.uhn.hapi.fhir + hapi-fhir-validation + ${hapi.fhir.version.v2} + + + ca.uhn.hapi.fhir + hapi-fhir-converter + ${hapi.fhir.version.v2} + + + ca.uhn.hapi.fhir + org.hl7.fhir.convertors + ${hapi.fhir.org.hl7.version.v2} + + + org.xerial + sqlite-jdbc + 3.45.1.0 + + + ca.uhn.hapi.fhir + org.hl7.fhir.validation + ${hapi.fhir.org.hl7.version.v2} + + + ca.uhn.hapi.fhir + org.hl7.fhir.r5 + ${hapi.fhir.org.hl7.version.v2} + + + com.nimbusds + nimbus-jose-jwt + 9.37.3 + + + com.github.stephenc.jcip + jcip-annotations + 1.0-1 + + + net.sourceforge.plantuml + plantuml-mit + 1.2023.9 + + + net.sf.saxon + Saxon-HE + 9.8.0-15 + + + + jakarta-regexp + jakarta-regexp + 1.4 + + + org.apache.commons + commons-compress + + + org.fhir + ucum + 1.0.8 + + + com.google.code.gson + gson + + + com.google.errorprone + error_prone_annotations + 2.27.0 + + + ca.uhn.hapi.fhir + hapi-fhir-structures-r5 + ${hapi.fhir.version.v2} + + + ca.uhn.hapi.fhir + hapi-fhir-client + ${hapi.fhir.version.v2} + + + ca.uhn.hapi.fhir + hapi-fhir-validation-resources-r4 + + + ca.uhn.hapi.fhir + hapi-fhir-base + ${hapi.fhir.version.v2} + + + org.checkerframework + checker-qual + 3.43.0 + + + com.google.j2objc + j2objc-annotations + 3.0.0 + + + io.opentelemetry + opentelemetry-api + 1.38.0 + + + io.opentelemetry + opentelemetry-context + 1.38.0 + + + io.opentelemetry.instrumentation + opentelemetry-instrumentation-annotations + 2.4.0 + + + + + + + + org.apache.maven.plugins + maven-clean-plugin + + + + ../dsf-bpe-server-jetty/docker/api + + v2/*.jar + + false + + + + + + \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/client/FhirWebserviceClientJersey.java b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/client/FhirWebserviceClientJersey.java index 99f28560d..a911fa8ad 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/client/FhirWebserviceClientJersey.java +++ b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/client/FhirWebserviceClientJersey.java @@ -3,7 +3,6 @@ import java.io.InputStream; import java.security.KeyStore; import java.text.SimpleDateFormat; -import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Locale; @@ -76,8 +75,8 @@ public FhirWebserviceClientJersey(String baseUrl, KeyStore trustStore, KeyStore ReferenceCleaner referenceCleaner) { super(baseUrl, trustStore, keyStore, keyStorePassword, objectMapper, - Collections.singleton(new FhirAdapter(fhirContext, referenceCleaner)), proxySchemeHostPort, - proxyUserName, proxyPassword, connectTimeout, readTimeout, logRequests, userAgentValue); + List.of(new FhirAdapter(fhirContext, referenceCleaner)), proxySchemeHostPort, proxyUserName, + proxyPassword, connectTimeout, readTimeout, logRequests, userAgentValue); preferReturnMinimal = new PreferReturnMinimalWithRetryImpl(this); preferReturnOutcome = new PreferReturnOutcomeWithRetryImpl(this); diff --git a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/listener/ContinueListener.java b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/listener/ContinueListener.java index 1e39e6798..3320bf8e9 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/listener/ContinueListener.java +++ b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/listener/ContinueListener.java @@ -72,6 +72,5 @@ processUrl, getCurrentTime(), continueTaskUrl, requester, businessKey, correlati logger.info("Continuing process {} at {} [task: {}, requester: {}, business-key: {}, message: {}]", processUrl, getCurrentTime(), continueTaskUrl, requester, businessKey, messageName); } - } } diff --git a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/plugin/ProcessPluginImpl.java b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/plugin/ProcessPluginImpl.java index e193b232a..919e82ea0 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/plugin/ProcessPluginImpl.java +++ b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/plugin/ProcessPluginImpl.java @@ -40,7 +40,7 @@ import dev.dsf.bpe.v2.ProcessPluginApi; import dev.dsf.bpe.v2.ProcessPluginDefinition; import dev.dsf.bpe.v2.ProcessPluginDeploymentListener; -import dev.dsf.bpe.v2.constants.CodeSystems; +import dev.dsf.bpe.v2.constants.CodeSystems.BpmnMessage; import dev.dsf.bpe.v2.constants.NamingSystems.OrganizationIdentifier; import dev.dsf.bpe.v2.constants.NamingSystems.TaskIdentifier; import dev.dsf.bpe.v2.variables.FhirResourceValues; @@ -142,21 +142,16 @@ else if (filename.endsWith(XML_SUFFIX)) }) : Optional.empty(); - Predicate hasTaskInputMessageName = t -> t - .getInput().stream().filter( - i -> i.getType().getCoding().stream() - .anyMatch(c -> CodeSystems.BpmnMessage.URL.equals(c.getSystem()) - && CodeSystems.BpmnMessage.Codes.MESSAGE_NAME.equals(c.getCode()))) - .count() == 1; + Predicate hasTaskInputMessageName = t -> t.getInput().stream() + .filter(i -> i.getType().getCoding().stream().anyMatch(BpmnMessage::isMessageName)).count() == 1; return new ProcessPluginFhirConfig<>(ActivityDefinition.class, CodeSystem.class, Library.class, Measure.class, NamingSystem.class, Questionnaire.class, StructureDefinition.class, Task.class, ValueSet.class, - OrganizationIdentifier.SID, TaskIdentifier.SID, TaskStatus.DRAFT.toCode(), CodeSystems.BpmnMessage.URL, - CodeSystems.BpmnMessage.Codes.MESSAGE_NAME, parseResource, encodeResource, getResourceName, - hasMetadataResourceUrl, hasMetadataResourceVersion, getMetadataResourceVersion, - getActivityDefinitionUrl, NamingSystem::hasName, getTaskInstantiatesCanonical, getTaskIdentifierValue, - isTaskStatusDraft, getRequester, getRecipient, Task::hasInput, hasTaskInputMessageName, - Task::hasOutput); + OrganizationIdentifier.SID, TaskIdentifier.SID, TaskStatus.DRAFT.toCode(), BpmnMessage.SYSTEM, + BpmnMessage.Codes.MESSAGE_NAME, parseResource, encodeResource, getResourceName, hasMetadataResourceUrl, + hasMetadataResourceVersion, getMetadataResourceVersion, getActivityDefinitionUrl, NamingSystem::hasName, + getTaskInstantiatesCanonical, getTaskIdentifierValue, isTaskStatusDraft, getRequester, getRecipient, + Task::hasInput, hasTaskInputMessageName, Task::hasOutput); } private IParser newXmlParser() diff --git a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/AbstractResourceProvider.java b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/AbstractResourceProvider.java index 8817b17f5..2f26cbf0b 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/AbstractResourceProvider.java +++ b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/AbstractResourceProvider.java @@ -3,7 +3,6 @@ import static org.hl7.fhir.instance.model.api.IBaseBundle.LINK_NEXT; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -72,9 +71,9 @@ protected final List search(Class se private Bundle search(Class searchType, Map> parameters, int page) { Map> parametersAndPage = new HashMap<>(parameters); - parametersAndPage.put("_page", Collections.singletonList(String.valueOf(page))); + parametersAndPage.put("_page", List.of(String.valueOf(page))); if (!parameters.containsKey("_sort")) - parametersAndPage.put("_sort", Collections.singletonList("_id")); + parametersAndPage.put("_sort", List.of("_id")); return clientProvider.getLocalWebserviceClient().searchWithStrictHandling(searchType, parametersAndPage); } diff --git a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/EndpointProviderImpl.java b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/EndpointProviderImpl.java index dfcee39c5..8ed9f82ab 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/EndpointProviderImpl.java +++ b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/EndpointProviderImpl.java @@ -1,6 +1,5 @@ package dev.dsf.bpe.v2.service; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; @@ -30,8 +29,7 @@ public EndpointProviderImpl(FhirWebserviceClientProvider clientProvider, String public Optional getLocalEndpoint() { Bundle resultBundle = clientProvider.getLocalWebserviceClient().searchWithStrictHandling(Endpoint.class, - Map.of("status", Collections.singletonList("active"), "address", - Collections.singletonList(localEndpointAddress))); + Map.of("status", List.of("active"), "address", List.of(localEndpointAddress))); if (resultBundle == null || resultBundle.getEntry() == null || resultBundle.getEntry().size() != 1 || resultBundle.getEntryFirstRep().getResource() == null @@ -61,8 +59,8 @@ public Optional getEndpoint(Identifier endpointIdentifier) String endpointIdSp = toSearchParameter(endpointIdentifier); - Bundle resultBundle = clientProvider.getLocalWebserviceClient().searchWithStrictHandling(Endpoint.class, Map.of( - "status", Collections.singletonList("active"), "identifier", Collections.singletonList(endpointIdSp))); + Bundle resultBundle = clientProvider.getLocalWebserviceClient().searchWithStrictHandling(Endpoint.class, + Map.of("status", List.of("active"), "identifier", List.of(endpointIdSp))); if (resultBundle == null || resultBundle.getEntry() == null || resultBundle.getTotal() != 1 || resultBundle.getEntryFirstRep().getResource() == null @@ -81,17 +79,17 @@ public Optional getEndpoint(Identifier parentOrganizationIdentifier, { if (parentOrganizationIdentifier == null) { - logger.debug("Parent organiztion identifier is null"); + logger.debug("Parent organization identifier is null"); return Optional.empty(); } else if (memberOrganizationIdentifier == null) { - logger.debug("Member organiztion identifier is null"); + logger.debug("Member organization identifier is null"); return Optional.empty(); } else if (memberOrganizationRole == null) { - logger.debug("Member organiztion role is null"); + logger.debug("Member organization role is null"); return Optional.empty(); } @@ -101,11 +99,9 @@ else if (memberOrganizationRole == null) Bundle resultBundle = clientProvider.getLocalWebserviceClient().searchWithStrictHandling( OrganizationAffiliation.class, - Map.of("active", Collections.singletonList("true"), "primary-organization:identifier", - Collections.singletonList(parentOrganizationIdSp), "participating-organization:identifier", - Collections.singletonList(memberOrganizationIdSp), "role", - Collections.singletonList(memberOrganizationRoleSp), "_include", - Collections.singletonList("OrganizationAffiliation:endpoint"))); + Map.of("active", List.of("true"), "primary-organization:identifier", List.of(parentOrganizationIdSp), + "participating-organization:identifier", List.of(memberOrganizationIdSp), "role", + List.of(memberOrganizationRoleSp), "_include", List.of("OrganizationAffiliation:endpoint"))); if (resultBundle == null || resultBundle.getEntry() == null || resultBundle.getTotal() != 1 || resultBundle.getEntryFirstRep().getResource() == null @@ -141,22 +137,21 @@ public List getEndpoints(Identifier parentOrganizationIdentifier, Codi { if (parentOrganizationIdentifier == null) { - logger.debug("Parent organiztion identifier is null"); - return Collections.emptyList(); + logger.debug("Parent organization identifier is null"); + return List.of(); } else if (memberOrganizationRole == null) { - logger.debug("Member organiztion role is null"); - return Collections.emptyList(); + logger.debug("Member organization role is null"); + return List.of(); } String parentOrganizationIdSp = toSearchParameter(parentOrganizationIdentifier); String memberOrganizationRoleSp = toSearchParameter(memberOrganizationRole); - Map> parameters = Map.of("active", Collections.singletonList("true"), - "primary-organization:identifier", Collections.singletonList(parentOrganizationIdSp), "role", - Collections.singletonList(memberOrganizationRoleSp), "_include", - Collections.singletonList("OrganizationAffiliation:endpoint")); + Map> parameters = Map.of("active", List.of("true"), "primary-organization:identifier", + List.of(parentOrganizationIdSp), "role", List.of(memberOrganizationRoleSp), "_include", + List.of("OrganizationAffiliation:endpoint")); return search(OrganizationAffiliation.class, parameters, SearchEntryMode.INCLUDE, Endpoint.class, e -> EndpointStatus.ACTIVE.equals(e.getStatus())); diff --git a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/OrganizationProviderImpl.java b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/OrganizationProviderImpl.java index a077b97e5..0c81c1f57 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/OrganizationProviderImpl.java +++ b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/OrganizationProviderImpl.java @@ -1,6 +1,5 @@ package dev.dsf.bpe.v2.service; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; @@ -30,9 +29,8 @@ public OrganizationProviderImpl(FhirWebserviceClientProvider clientProvider, Str public Optional getLocalOrganization() { Bundle resultBundle = clientProvider.getLocalWebserviceClient().searchWithStrictHandling(Endpoint.class, - Map.of("status", Collections.singletonList("active"), "address", - Collections.singletonList(localEndpointAddress), "_include", - Collections.singletonList("Endpoint:organization"))); + Map.of("status", List.of("active"), "address", List.of(localEndpointAddress), "_include", + List.of("Endpoint:organization"))); if (resultBundle == null || resultBundle.getEntry() == null || resultBundle.getEntry().size() != 2 || resultBundle.getEntry().get(0).getResource() == null @@ -40,12 +38,12 @@ public Optional getLocalOrganization() || resultBundle.getEntry().get(1).getResource() == null || !(resultBundle.getEntry().get(1).getResource() instanceof Organization)) { - logger.warn("No active (or more than one) Endpoint found for address '{}'", localEndpointAddress); + logger.warn("No active (or more than one) endpoint found for address '{}'", localEndpointAddress); return Optional.empty(); } else if (getActiveOrganizationFromIncludes(resultBundle).count() != 1) { - logger.warn("No active (or more than one) Organization found by active Endpoint with address '{}'", + logger.warn("No active (or more than one) organization found by active endpoint with address '{}'", localEndpointAddress); return Optional.empty(); } @@ -73,14 +71,13 @@ public Optional getOrganization(Identifier organizationIdentifier) String organizationIdSp = toSearchParameter(organizationIdentifier); Bundle resultBundle = clientProvider.getLocalWebserviceClient().searchWithStrictHandling(Organization.class, - Map.of("active", Collections.singletonList("true"), "identifier", - Collections.singletonList(organizationIdSp))); + Map.of("active", List.of("true"), "identifier", List.of(organizationIdSp))); if (resultBundle == null || resultBundle.getEntry() == null || resultBundle.getTotal() != 1 || resultBundle.getEntryFirstRep().getResource() == null || !(resultBundle.getEntryFirstRep().getResource() instanceof Organization)) { - logger.warn("No active (or more than one) Organization found for identifier '{}'", organizationIdSp); + logger.warn("No active (or more than one) organization found for identifier '{}'", organizationIdSp); return Optional.empty(); } @@ -92,15 +89,15 @@ public List getOrganizations(Identifier parentOrganizationIdentifi { if (parentOrganizationIdentifier == null) { - logger.debug("Parent organiztion identifier is null"); - return Collections.emptyList(); + logger.debug("Parent organization identifier is null"); + return List.of(); } String parentOrganizationIdSp = toSearchParameter(parentOrganizationIdentifier); - Map> parameters = Map.of("active", Collections.singletonList("true"), - "primary-organization:identifier", Collections.singletonList(parentOrganizationIdSp), "_include", - Collections.singletonList("OrganizationAffiliation:participating-organization")); + Map> parameters = Map.of("active", List.of("true"), "primary-organization:identifier", + List.of(parentOrganizationIdSp), "_include", + List.of("OrganizationAffiliation:participating-organization")); return search(OrganizationAffiliation.class, parameters, SearchEntryMode.INCLUDE, Organization.class, Organization::getActive); @@ -111,22 +108,21 @@ public List getOrganizations(Identifier parentOrganizationIdentifi { if (parentOrganizationIdentifier == null) { - logger.debug("Parent organiztion identifier is null"); - return Collections.emptyList(); + logger.debug("Parent organization identifier is null"); + return List.of(); } else if (memberOrganizationRole == null) { - logger.debug("Member organiztion role is null"); - return Collections.emptyList(); + logger.debug("Member organization role is null"); + return List.of(); } String parentOrganizationIdSp = toSearchParameter(parentOrganizationIdentifier); String memberOrganizationRoleSp = toSearchParameter(memberOrganizationRole); - Map> parameters = Map.of("active", Collections.singletonList("true"), - "primary-organization:identifier", Collections.singletonList(parentOrganizationIdSp), "role", - Collections.singletonList(memberOrganizationRoleSp), "_include", - Collections.singletonList("OrganizationAffiliation:participating-organization")); + Map> parameters = Map.of("active", List.of("true"), "primary-organization:identifier", + List.of(parentOrganizationIdSp), "role", List.of(memberOrganizationRoleSp), "_include", + List.of("OrganizationAffiliation:participating-organization")); return search(OrganizationAffiliation.class, parameters, SearchEntryMode.INCLUDE, Organization.class, Organization::getActive); @@ -139,12 +135,21 @@ public List getRemoteOrganizations() if (localOrganizationIdentifier.isEmpty()) { - logger.debug("Local organiztion identifier unknown"); - return Collections.emptyList(); + logger.debug("Local organization identifier unknown"); + return List.of(); } - Map> searchParameters = Map.of("active", Collections.singletonList("true"), - "identifier:not", Collections.singletonList(toSearchParameter(localOrganizationIdentifier.get()))); + Map> searchParameters = Map.of("active", List.of("true"), "identifier:not", + List.of(toSearchParameter(localOrganizationIdentifier.get())), "_profile", + List.of("http://dsf.dev/fhir/StructureDefinition/organization")); + return search(Organization.class, searchParameters, SearchEntryMode.MATCH, Organization.class, o -> true); + } + + @Override + public List getParentOrganizations() + { + Map> searchParameters = Map.of("active", List.of("true"), "_profile", + List.of("http://dsf.dev/fhir/StructureDefinition/organization-parent")); return search(Organization.class, searchParameters, SearchEntryMode.MATCH, Organization.class, o -> true); } } diff --git a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/ReadAccessHelperImpl.java b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/ReadAccessHelperImpl.java index 66a6d315c..e56ffccbf 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/ReadAccessHelperImpl.java +++ b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/ReadAccessHelperImpl.java @@ -1,6 +1,5 @@ package dev.dsf.bpe.v2.service; -import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -33,7 +32,7 @@ public class ReadAccessHelperImpl implements ReadAccessHelper private static final String EXTENSION_READ_ACCESS_PARENT_ORGANIZATION_ROLE_PARENT_ORGANIZATION = "parent-organization"; private static final String EXTENSION_READ_ACCESS_PARENT_ORGANIZATION_ROLE_ORGANIZATION_ROLE = "organization-role"; - private static final List READ_ACCESS_TAG_VALUES = Arrays.asList(READ_ACCESS_TAG_VALUE_LOCAL, + private static final List READ_ACCESS_TAG_VALUES = List.of(READ_ACCESS_TAG_VALUE_LOCAL, READ_ACCESS_TAG_VALUE_ORGANIZATION, READ_ACCESS_TAG_VALUE_ROLE, READ_ACCESS_TAG_VALUE_ALL); private Predicate matchesTagValue(String value) diff --git a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/process/All.java b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/process/All.java index fb71c7982..f66ac5a74 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/process/All.java +++ b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/process/All.java @@ -1,6 +1,5 @@ package dev.dsf.bpe.v2.service.process; -import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.Set; @@ -64,7 +63,7 @@ private Set getPractitionerRoles(Identity identity) if (identity instanceof PractitionerIdentity p) return p.getPractionerRoles(); else - return Collections.emptySet(); + return Set.of(); } private boolean hasPractitionerRole(Set practitionerRoles) diff --git a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/process/Organization.java b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/process/Organization.java index 77f945885..443ad7a35 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/process/Organization.java +++ b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/process/Organization.java @@ -1,6 +1,5 @@ package dev.dsf.bpe.v2.service.process; -import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -85,7 +84,7 @@ private Set getPractitionerRoles(Identity identity) if (identity instanceof PractitionerIdentity p) return p.getPractionerRoles(); else - return Collections.emptySet(); + return Set.of(); } private boolean hasPractitionerRole(Set practitionerRoles) diff --git a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/process/Role.java b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/process/Role.java index 35fa19017..169772d80 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/process/Role.java +++ b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/service/process/Role.java @@ -1,6 +1,5 @@ package dev.dsf.bpe.v2.service.process; -import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -126,7 +125,7 @@ private Set getPractitionerRoles(Identity identity) if (identity instanceof PractitionerIdentity p) return p.getPractionerRoles(); else - return Collections.emptySet(); + return Set.of(); } private boolean hasPractitionerRole(Set practitionerRoles) diff --git a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/variables/FhirResourcesList.java b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/variables/FhirResourcesList.java index 0bc87a9c9..f081f9297 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/variables/FhirResourcesList.java +++ b/dsf-bpe/dsf-bpe-process-api-v2-impl/src/main/java/dev/dsf/bpe/v2/variables/FhirResourcesList.java @@ -1,7 +1,6 @@ package dev.dsf.bpe.v2.variables; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -26,7 +25,7 @@ public FhirResourcesList(@JsonProperty("resources") Collection targets) { if (targets == null) - return new TargetsImpl(Collections.emptyList()); + return new TargetsImpl(List.of()); Optional firstNonMatch = targets.stream().filter(t -> !(t instanceof TargetImpl)).findFirst(); if (firstNonMatch.isPresent()) @@ -219,7 +219,7 @@ public List getCurrentTasks() Stream start = execution.getParentId() == null ? Stream.of(getStartTask()) : Stream.empty(); Stream current = getResourceListOrDefault(TASKS_PREFIX + execution.getParentActivityInstanceId(), - Collections. emptyList()).stream(); + List. of()).stream(); return Collections.unmodifiableList(Stream.concat(start, current).toList()); } @@ -237,7 +237,7 @@ public void updateTask(Task task) else { String instanceId = execution.getParentActivityInstanceId(); - List tasks = getResourceListOrDefault(TASKS_PREFIX + instanceId, Collections.emptyList()); + List tasks = getResourceListOrDefault(TASKS_PREFIX + instanceId, List.of()); if (tasks.stream().anyMatch(t -> t.getIdElement().getIdPart().equals(task.getIdElement().getIdPart()))) setResourceList(TASKS_PREFIX + instanceId, tasks); @@ -292,8 +292,7 @@ public void onContinue(Task task) { String instanceId = execution.getParentActivityInstanceId(); - List tasks = new ArrayList<>( - getResourceListOrDefault(TASKS_PREFIX + instanceId, Collections.emptyList())); + List tasks = new ArrayList<>(getResourceListOrDefault(TASKS_PREFIX + instanceId, List.of())); tasks.add(task); setResourceList(TASKS_PREFIX + instanceId, tasks); @@ -308,8 +307,7 @@ public void onEnd() logger.trace("onEnd"); String instanceId = execution.getParentActivityInstanceId(); - List tasks = new ArrayList<>( - getResourceListOrDefault(TASKS_PREFIX + instanceId, Collections.emptyList())); + List tasks = new ArrayList<>(getResourceListOrDefault(TASKS_PREFIX + instanceId, List.of())); tasks.removeAll(getCurrentTasks()); setResourceList(TASKS_PREFIX + instanceId, tasks); } diff --git a/dsf-bpe/dsf-bpe-process-api-v2/pom.xml b/dsf-bpe/dsf-bpe-process-api-v2/pom.xml index ca81616fa..1ea0db433 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2/pom.xml +++ b/dsf-bpe/dsf-bpe-process-api-v2/pom.xml @@ -8,13 +8,29 @@ dsf-bpe-pom 2.0.0-SNAPSHOT - + ca.uhn.hapi.fhir hapi-fhir-structures-r4 ${hapi.fhir.version.v2} + + ca.uhn.hapi.fhir + hapi-fhir-validation + ${hapi.fhir.version.v2} + + + commons-logging + commons-logging + + + + + ca.uhn.hapi.fhir + hapi-fhir-client + ${hapi.fhir.version.v2} + org.camunda.bpm camunda-engine @@ -33,7 +49,7 @@ jakarta.ws.rs-api - jakarta.ws.rs + jakarta.ws.rs \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/activity/DefaultUserTaskListener.java b/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/activity/DefaultUserTaskListener.java index 4669272f2..0bbd092d9 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/activity/DefaultUserTaskListener.java +++ b/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/activity/DefaultUserTaskListener.java @@ -1,6 +1,5 @@ package dev.dsf.bpe.v2.activity; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; @@ -26,7 +25,6 @@ import org.springframework.context.annotation.Bean; import dev.dsf.bpe.v2.ProcessPluginApi; -import dev.dsf.bpe.v2.activity.DefaultUserTaskListener; import dev.dsf.bpe.v2.constants.CodeSystems.BpmnMessage; import dev.dsf.bpe.v2.constants.CodeSystems.BpmnUserTask; import dev.dsf.bpe.v2.variables.Variables; @@ -116,7 +114,7 @@ public final void notify(DelegateTask userTask) private Questionnaire readQuestionnaire(String urlWithVersion) { Bundle search = api.getFhirWebserviceClientProvider().getLocalWebserviceClient().search(Questionnaire.class, - Map.of("url", Collections.singletonList(urlWithVersion))); + Map.of("url", List.of(urlWithVersion))); List questionnaires = search.getEntry().stream().filter(Bundle.BundleEntryComponent::hasResource) .map(Bundle.BundleEntryComponent::getResource).filter(r -> r instanceof Questionnaire) @@ -132,7 +130,6 @@ private Questionnaire readQuestionnaire(String urlWithVersion) return questionnaires.get(0); } - private QuestionnaireResponse createDefaultQuestionnaireResponse(String questionnaireUrlWithVersion, String businessKey, String userTaskId) { diff --git a/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/constants/CodeSystems.java b/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/constants/CodeSystems.java index 035c50f16..be5c6c5b1 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/constants/CodeSystems.java +++ b/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/constants/CodeSystems.java @@ -23,7 +23,12 @@ private BpmnMessage() { } - public static final String URL = "http://dsf.dev/fhir/CodeSystem/bpmn-message"; + public static final String SYSTEM = "http://dsf.dev/fhir/CodeSystem/bpmn-message"; + + public static Coding withCode(String code) + { + return new Coding().setSystem(SYSTEM).setCode(code); + } public static final class Codes { @@ -39,22 +44,42 @@ private Codes() public static final Coding messageName() { - return new Coding(URL, Codes.MESSAGE_NAME, null); + return new Coding(SYSTEM, Codes.MESSAGE_NAME, null); } public static final Coding businessKey() { - return new Coding(URL, Codes.BUSINESS_KEY, null); + return new Coding(SYSTEM, Codes.BUSINESS_KEY, null); } public static final Coding correlationKey() { - return new Coding(URL, Codes.CORRELATION_KEY, null); + return new Coding(SYSTEM, Codes.CORRELATION_KEY, null); } public static final Coding error() { - return new Coding(URL, Codes.ERROR, null); + return new Coding(SYSTEM, Codes.ERROR, null); + } + + public static final boolean isMessageName(Coding coding) + { + return isSame(SYSTEM, Codes.MESSAGE_NAME, coding); + } + + public static final boolean isBusinessKey(Coding coding) + { + return isSame(SYSTEM, Codes.BUSINESS_KEY, coding); + } + + public static final boolean isCorrelationKey(Coding coding) + { + return isSame(SYSTEM, Codes.CORRELATION_KEY, coding); + } + + public static final boolean isError(Coding coding) + { + return isSame(SYSTEM, Codes.ERROR, coding); } } @@ -64,7 +89,12 @@ private BpmnUserTask() { } - public static final String URL = "http://dsf.dev/fhir/CodeSystem/bpmn-user-task"; + public static final String SYSTEM = "http://dsf.dev/fhir/CodeSystem/bpmn-user-task"; + + public static Coding withCode(String code) + { + return new Coding().setSystem(SYSTEM).setCode(code); + } public static final class Codes { @@ -78,12 +108,22 @@ private Codes() public static final Coding businessKey() { - return new Coding(URL, Codes.BUSINESS_KEY, null); + return new Coding(SYSTEM, Codes.BUSINESS_KEY, null); } public static final Coding userTaskId() { - return new Coding(URL, Codes.USER_TASK_ID, null); + return new Coding(SYSTEM, Codes.USER_TASK_ID, null); + } + + public static final boolean isBusinessKey(Coding coding) + { + return isSame(SYSTEM, Codes.BUSINESS_KEY, coding); + } + + public static final boolean isUserTaskId(Coding coding) + { + return isSame(SYSTEM, Codes.USER_TASK_ID, coding); } } @@ -93,7 +133,12 @@ private ProcessAuthorization() { } - public static final String URL = "http://dsf.dev/fhir/CodeSystem/process-authorization"; + public static final String SYSTEM = "http://dsf.dev/fhir/CodeSystem/process-authorization"; + + public static Coding withCode(String code) + { + return new Coding().setSystem(SYSTEM).setCode(code); + } public static final class Codes { @@ -114,92 +159,345 @@ private Codes() public static final Coding localOrganization() { - return new Coding(URL, Codes.LOCAL_ORGANIZATION, null); + return new Coding(SYSTEM, Codes.LOCAL_ORGANIZATION, null); } public static final Coding localOrganizationPractitioner() { - return new Coding(URL, Codes.LOCAL_ORGANIZATION_PRACTITIONER, null); + return new Coding(SYSTEM, Codes.LOCAL_ORGANIZATION_PRACTITIONER, null); } public static final Coding remoteOrganization() { - return new Coding(URL, Codes.REMOTE_ORGANIZATION, null); + return new Coding(SYSTEM, Codes.REMOTE_ORGANIZATION, null); } public static final Coding localRole() { - return new Coding(URL, Codes.LOCAL_ROLE, null); + return new Coding(SYSTEM, Codes.LOCAL_ROLE, null); } public static final Coding localRolePractitioner() { - return new Coding(URL, Codes.LOCAL_ROLE_PRACTITIONER, null); + return new Coding(SYSTEM, Codes.LOCAL_ROLE_PRACTITIONER, null); } public static final Coding remoteRole() { - return new Coding(URL, Codes.REMOTE_ROLE, null); + return new Coding(SYSTEM, Codes.REMOTE_ROLE, null); } public static final Coding localAll() { - return new Coding(URL, Codes.LOCAL_ALL, null); + return new Coding(SYSTEM, Codes.LOCAL_ALL, null); } public static final Coding localAllPractitioner() { - return new Coding(URL, Codes.LOCAL_ALL_PRACTITIONER, null); + return new Coding(SYSTEM, Codes.LOCAL_ALL_PRACTITIONER, null); } public static final Coding remoteAll() { - return new Coding(URL, Codes.REMOTE_ALL, null); + return new Coding(SYSTEM, Codes.REMOTE_ALL, null); } public static final boolean isLocalOrganization(Coding coding) { - return isSame(URL, Codes.LOCAL_ORGANIZATION, coding); + return isSame(SYSTEM, Codes.LOCAL_ORGANIZATION, coding); } public static final boolean isLocalOrganizationPractitioner(Coding coding) { - return isSame(URL, Codes.LOCAL_ORGANIZATION_PRACTITIONER, coding); + return isSame(SYSTEM, Codes.LOCAL_ORGANIZATION_PRACTITIONER, coding); } public static final boolean isRemoteOrganization(Coding coding) { - return isSame(URL, Codes.REMOTE_ORGANIZATION, coding); + return isSame(SYSTEM, Codes.REMOTE_ORGANIZATION, coding); } public static final boolean isLocalRole(Coding coding) { - return isSame(URL, Codes.LOCAL_ROLE, coding); + return isSame(SYSTEM, Codes.LOCAL_ROLE, coding); } public static final boolean isLocalRolePractitioner(Coding coding) { - return isSame(URL, Codes.LOCAL_ROLE_PRACTITIONER, coding); + return isSame(SYSTEM, Codes.LOCAL_ROLE_PRACTITIONER, coding); } public static final boolean isRemoteRole(Coding coding) { - return isSame(URL, Codes.REMOTE_ROLE, coding); + return isSame(SYSTEM, Codes.REMOTE_ROLE, coding); } public static final boolean isLocalAll(Coding coding) { - return isSame(URL, Codes.LOCAL_ALL, coding); + return isSame(SYSTEM, Codes.LOCAL_ALL, coding); } public static final boolean isLocalAllPractitioner(Coding coding) { - return isSame(URL, Codes.LOCAL_ALL_PRACTITIONER, coding); + return isSame(SYSTEM, Codes.LOCAL_ALL_PRACTITIONER, coding); } public static final boolean isRemoteAll(Coding coding) { - return isSame(URL, Codes.REMOTE_ALL, coding); + return isSame(SYSTEM, Codes.REMOTE_ALL, coding); + } + } + + public static final class OrganizationRole + { + private OrganizationRole() + { + } + + public static final String SYSTEM = "http://dsf.dev/fhir/CodeSystem/organization-role"; + + public static Coding withCode(String code) + { + return new Coding().setSystem(SYSTEM).setCode(code); + } + + public static final class Codes + { + private Codes() + { + } + + public static final String UAC = "UAC"; + public static final String COS = "COS"; + public static final String CRR = "CRR"; + public static final String DIC = "DIC"; + public static final String DMS = "DMS"; + public static final String DTS = "DTS"; + public static final String HRP = "HRP"; + public static final String TTP = "TTP"; + public static final String AMS = "AMS"; + } + + public static final Coding uac() + { + return new Coding(SYSTEM, Codes.UAC, "Use-and-Access Committee"); + } + + public static final Coding cos() + { + return new Coding(SYSTEM, Codes.COS, "Coordinating Site"); + } + + public static final Coding crr() + { + return new Coding(SYSTEM, Codes.CRR, "Central Research Repository"); + } + + public static final Coding dic() + { + return new Coding(SYSTEM, Codes.DIC, "Data Integration Center"); + } + + public static final Coding dms() + { + return new Coding(SYSTEM, Codes.DMS, "Data Management Site"); + } + + public static final Coding dts() + { + return new Coding(SYSTEM, Codes.DTS, "Data Transfer Site"); + } + + public static final Coding hrp() + { + return new Coding(SYSTEM, Codes.HRP, "Health Research Platform"); + } + + public static final Coding ttp() + { + return new Coding(SYSTEM, Codes.TTP, "Trusted Third Party"); + } + + public static final Coding ams() + { + return new Coding(SYSTEM, Codes.AMS, "Allowlist Management Site"); + } + + public static final boolean isUac(Coding coding) + { + return isSame(SYSTEM, Codes.UAC, coding); + } + + public static final boolean isCos(Coding coding) + { + return isSame(SYSTEM, Codes.COS, coding); + } + + public static final boolean isCrr(Coding coding) + { + return isSame(SYSTEM, Codes.CRR, coding); + } + + public static final boolean isDic(Coding coding) + { + return isSame(SYSTEM, Codes.DIC, coding); + } + + public static final boolean isDms(Coding coding) + { + return isSame(SYSTEM, Codes.DMS, coding); + } + + public static final boolean isDts(Coding coding) + { + return isSame(SYSTEM, Codes.DTS, coding); + } + + public static final boolean isHrp(Coding coding) + { + return isSame(SYSTEM, Codes.HRP, coding); + } + + public static final boolean isTtp(Coding coding) + { + return isSame(SYSTEM, Codes.TTP, coding); + } + + public static final boolean isAms(Coding coding) + { + return isSame(SYSTEM, Codes.AMS, coding); + } + } + + public static final class PractitionerRole + { + private PractitionerRole() + { + } + + public static final String SYSTEM = "http://dsf.dev/fhir/CodeSystem/practitioner-role"; + + public static Coding withCode(String code) + { + return new Coding().setSystem(SYSTEM).setCode(code); + } + + public static final class Codes + { + private Codes() + { + } + + public static final String UAC_USER = "UAC_USER"; + public static final String COS_USER = "COS_USER"; + public static final String CRR_USER = "CRR_USER"; + public static final String DIC_USER = "DIC_USER"; + public static final String DMS_USER = "DMS_USER"; + public static final String DTS_USER = "DTS_USER"; + public static final String HRP_USER = "HRP_USER"; + public static final String TTP_USER = "TTP_USER"; + public static final String AMS_USER = "AMS_USER"; + public static final String DSF_ADMIN = "DSF_ADMIN"; + } + + public static final Coding uacUser() + { + return new Coding(SYSTEM, Codes.UAC_USER, "Use-and-Access Committee Member"); + } + + public static final Coding cosUser() + { + return new Coding(SYSTEM, Codes.COS_USER, "Coordinating Site Member"); + } + + public static final Coding crrUser() + { + return new Coding(SYSTEM, Codes.CRR_USER, "Central Research Repository Member"); + } + + public static final Coding dicUser() + { + return new Coding(SYSTEM, Codes.DIC_USER, "Data Integration Center Member"); + } + + public static final Coding dmsUser() + { + return new Coding(SYSTEM, Codes.DMS_USER, "Data Management Site Member"); + } + + public static final Coding dtsUser() + { + return new Coding(SYSTEM, Codes.DTS_USER, "Data Transfer Site Member"); + } + + public static final Coding hrpUser() + { + return new Coding(SYSTEM, Codes.HRP_USER, "Health Research Platform Member"); + } + + public static final Coding ttpUser() + { + return new Coding(SYSTEM, Codes.TTP_USER, "Trusted Third Party Member"); + } + + public static final Coding amsUser() + { + return new Coding(SYSTEM, Codes.AMS_USER, "Allowlist Management Site Member"); + } + + public static final Coding dsfAdmin() + { + return new Coding(SYSTEM, Codes.DSF_ADMIN, "DSF Administrator"); + } + + public static final boolean isUacUser(Coding coding) + { + return isSame(SYSTEM, Codes.UAC_USER, coding); + } + + public static final boolean isCosUser(Coding coding) + { + return isSame(SYSTEM, Codes.COS_USER, coding); + } + + public static final boolean isCrrUser(Coding coding) + { + return isSame(SYSTEM, Codes.CRR_USER, coding); + } + + public static final boolean isDicUser(Coding coding) + { + return isSame(SYSTEM, Codes.DIC_USER, coding); + } + + public static final boolean isDmsUser(Coding coding) + { + return isSame(SYSTEM, Codes.DMS_USER, coding); + } + + public static final boolean isDtsUser(Coding coding) + { + return isSame(SYSTEM, Codes.DTS_USER, coding); + } + + public static final boolean isHrpUser(Coding coding) + { + return isSame(SYSTEM, Codes.HRP_USER, coding); + } + + public static final boolean isTtpUser(Coding coding) + { + return isSame(SYSTEM, Codes.TTP_USER, coding); + } + + public static final boolean isAmsUser(Coding coding) + { + return isSame(SYSTEM, Codes.AMS_USER, coding); + } + + public static final boolean isDsfAdmin(Coding coding) + { + return isSame(SYSTEM, Codes.DSF_ADMIN, coding); } } } \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/service/EndpointProvider.java b/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/service/EndpointProvider.java index 6902043e9..ef6131b28 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/service/EndpointProvider.java +++ b/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/service/EndpointProvider.java @@ -6,7 +6,9 @@ import org.hl7.fhir.r4.model.Coding; import org.hl7.fhir.r4.model.Endpoint; import org.hl7.fhir.r4.model.Identifier; +import org.hl7.fhir.r4.model.OrganizationAffiliation; +import dev.dsf.bpe.v2.constants.CodeSystems.OrganizationRole; import dev.dsf.bpe.v2.constants.NamingSystems.EndpointIdentifier; import dev.dsf.bpe.v2.constants.NamingSystems.OrganizationIdentifier; @@ -52,18 +54,19 @@ default Optional getLocalEndpointIdentifierValue() /** * @param endpointIdentifier * may be null - * @return {@link Endpoint} resource from the local DSF FHIR server with the given endpointIdentifier, empty - * {@link Optional} if no such resource exists or the given identifier is null + * @return Active {@link Endpoint} resource from the local DSF FHIR server with the given endpointIdentifier, + * empty {@link Optional} if no such resource exists or the given identifier is null + * @see EndpointIdentifier#withValue(String) */ Optional getEndpoint(Identifier endpointIdentifier); /** * @param endpointIdentifierValue * may be null - * @return {@link Endpoint} resource from the local DSF FHIR server with the given DSF + * @return Active {@link Endpoint} resource from the local DSF FHIR server with the given DSF * endpointIdentifierValue, empty {@link Optional} if no such resource exists or the given identifier * value is null - * @see EndpointIdentifier + * @see EndpointIdentifier#withValue(String) */ default Optional getEndpoint(String endpointIdentifierValue) { @@ -74,9 +77,10 @@ default Optional getEndpoint(String endpointIdentifierValue) /** * @param endpointIdentifier * may be null - * @return Address (base URL) of the {@link Endpoint} resource from the local DSF FHIR server with the given + * @return Address (base URL) of the active {@link Endpoint} resource from the local DSF FHIR server with the given * endpointIdentifier, empty {@link Optional} if no such resource exists or the given identifier is * null + * @see EndpointIdentifier#withValue(String) */ default Optional getEndpointAddress(Identifier endpointIdentifier) { @@ -86,9 +90,10 @@ default Optional getEndpointAddress(Identifier endpointIdentifier) /** * @param endpointIdentifierValue * may be null - * @return Address (base URL) of the {@link Endpoint} resource from the local DSF FHIR server with the given DSF - * endpointIdentifierValue, empty {@link Optional} if no such resource exists or the given identifier - * value is null + * @return Address (base URL) of the active {@link Endpoint} resource from the local DSF FHIR server with the given + * DSF endpointIdentifierValue, empty {@link Optional} if no such resource exists or the given + * identifier value is null + * @see EndpointIdentifier#withValue(String) */ default Optional getEndpointAddress(String endpointIdentifierValue) { @@ -103,10 +108,13 @@ default Optional getEndpointAddress(String endpointIdentifierValue) * may be null * @param memberOrganizationRole * may be null - * @return {@link Endpoint} resource from the local DSF FHIR server associated with the given + * @return Active {@link Endpoint} resource from the local DSF FHIR server associated with the given * memberOrganizationIdentifier and memberOrganizationRole in a parent organization with the * given parentOrganizationIdentifier, empty {@link Optional} if no such resource exists or one of - * the parameters is null + * the parameters is null; only considers Endpoints from active {@link OrganizationAffiliation} + * resources + * @see OrganizationIdentifier#withValue(String) + * @see OrganizationRole#withCode(String) */ Optional getEndpoint(Identifier parentOrganizationIdentifier, Identifier memberOrganizationIdentifier, Coding memberOrganizationRole); @@ -116,23 +124,25 @@ Optional getEndpoint(Identifier parentOrganizationIdentifier, Identifi * may be null * @param memberOrganizationIdentifierValue * may be null - * @param memberOrganizationRole + * @param memberOrganizationRoleCode * may be null - * @return {@link Endpoint} resource from the local DSF FHIR server associated with the given DSF - * memberOrganizationIdentifierValue and memberOrganizationRole in a parent organization with - * the given DSF parentOrganizationIdentifierValue, empty {@link Optional} if no such resource exists - * or one of the parameters is null - * @see OrganizationIdentifier + * @return Active {@link Endpoint} resource from the local DSF FHIR server associated with the given DSF + * memberOrganizationIdentifierValue and memberOrganizationRoleCode in a parent organization + * with the given DSF parentOrganizationIdentifierValue, empty {@link Optional} if no such resource + * exists or one of the parameters is null; only considers Endpoints from active + * {@link OrganizationAffiliation} resources + * @see OrganizationIdentifier#withValue(String) + * @see OrganizationRole#withCode(String) */ default Optional getEndpoint(String parentOrganizationIdentifierValue, - String memberOrganizationIdentifierValue, Coding memberOrganizationRole) + String memberOrganizationIdentifierValue, String memberOrganizationRoleCode) { return getEndpoint( parentOrganizationIdentifierValue == null ? null : OrganizationIdentifier.withValue(parentOrganizationIdentifierValue), memberOrganizationIdentifierValue == null ? null : OrganizationIdentifier.withValue(memberOrganizationIdentifierValue), - memberOrganizationRole); + memberOrganizationRoleCode == null ? null : OrganizationRole.withCode(memberOrganizationRoleCode)); } /** @@ -142,10 +152,13 @@ default Optional getEndpoint(String parentOrganizationIdentifierValue, * may be null * @param memberOrganizationRole * may be null - * @return Address (base URL) of the {@link Endpoint} resource from the local DSF FHIR server associated with the - * given memberOrganizationIdentifier and memberOrganizationRole in a parent organization with - * the given parentOrganizationIdentifier, empty {@link Optional} if no such resource exists or one - * of the parameters is null + * @return Address (base URL) of the active {@link Endpoint} resource from the local DSF FHIR server associated with + * the given memberOrganizationIdentifier and memberOrganizationRole in a parent organization + * with the given parentOrganizationIdentifier, empty {@link Optional} if no such resource exists or + * one of the parameters is null; only considers Endpoints from active + * {@link OrganizationAffiliation} resources + * @see OrganizationIdentifier#withValue(String) + * @see OrganizationRole#withCode(String) */ default Optional getEndpointAddress(Identifier parentOrganizationIdentifier, Identifier memberOrganizationIdentifier, Coding memberOrganizationRole) @@ -159,23 +172,25 @@ default Optional getEndpointAddress(Identifier parentOrganizationIdentif * may be null * @param memberOrganizationIdentifierValue * may be null - * @param memberOrganizationRole + * @param memberOrganizationRoleCode * may be null - * @return Address (base URL) of the {@link Endpoint} resource from the local DSF FHIR server associated with the - * given DSF memberOrganizationIdentifierValue and memberOrganizationRole in a parent + * @return Address (base URL) of the active {@link Endpoint} resource from the local DSF FHIR server associated with + * the given DSF memberOrganizationIdentifierValue and memberOrganizationRoleCode in a parent * organization with the given DSF parentOrganizationIdentifierValue, empty {@link Optional} if no - * such resource exists or one of the parameters is null - * @see OrganizationIdentifier + * such resource exists or one of the parameters is null; only considers Endpoints from active + * {@link OrganizationAffiliation} resources + * @see OrganizationIdentifier#withValue(String) + * @see OrganizationRole#withCode(String) */ default Optional getEndpointAddress(String parentOrganizationIdentifierValue, - String memberOrganizationIdentifierValue, Coding memberOrganizationRole) + String memberOrganizationIdentifierValue, String memberOrganizationRoleCode) { return getEndpointAddress( parentOrganizationIdentifierValue == null ? null : OrganizationIdentifier.withValue(parentOrganizationIdentifierValue), memberOrganizationIdentifierValue == null ? null : OrganizationIdentifier.withValue(memberOrganizationIdentifierValue), - memberOrganizationRole); + memberOrganizationRoleCode == null ? null : OrganizationRole.withCode(memberOrganizationRoleCode)); } /** @@ -183,27 +198,33 @@ default Optional getEndpointAddress(String parentOrganizationIdentifierV * may be null * @param memberOrganizationRole * may be null - * @return {@link Endpoint} resources from the local DSF FHIR server associated with the given + * @return Active {@link Endpoint} resources from the local DSF FHIR server associated with the given * memberOrganizationRole in a parent organization with the given * parentOrganizationIdentifier, empty {@link List} if no resources exist or one of the parameters is - * null + * null; only considers Endpoints from active {@link OrganizationAffiliation} resources + * @see OrganizationIdentifier#withValue(String) + * @see OrganizationRole#withCode(String) */ List getEndpoints(Identifier parentOrganizationIdentifier, Coding memberOrganizationRole); /** * @param parentOrganizationIdentifierValue * may be null - * @param memberOrganizationRole + * @param memberOrganizationRoleCode * may be null - * @return {@link Endpoint} resources from the local DSF FHIR server associated with the given - * memberOrganizationRole in a parent organization with the given DSF + * @return Active {@link Endpoint} resources from the local DSF FHIR server associated with the given + * memberOrganizationRoleCode in a parent organization with the given DSF * parentOrganizationIdentifierValue, empty {@link List} if no resources exist or one of the - * parameters is null - * @see OrganizationIdentifier + * parameters is null; only considers Endpoints from active {@link OrganizationAffiliation} + * resources + * @see OrganizationIdentifier#withValue(String) + * @see OrganizationRole#withCode(String) */ - default List getEndpoints(String parentOrganizationIdentifierValue, Coding memberOrganizationRole) + default List getEndpoints(String parentOrganizationIdentifierValue, String memberOrganizationRoleCode) { - return getEndpoints(parentOrganizationIdentifierValue == null ? null - : OrganizationIdentifier.withValue(parentOrganizationIdentifierValue), memberOrganizationRole); + return getEndpoints( + parentOrganizationIdentifierValue == null ? null + : OrganizationIdentifier.withValue(parentOrganizationIdentifierValue), + memberOrganizationRoleCode == null ? null : OrganizationRole.withCode(memberOrganizationRoleCode)); } } diff --git a/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/service/MailService.java b/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/service/MailService.java index 70f25aa7c..5f99062b1 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/service/MailService.java +++ b/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/service/MailService.java @@ -2,7 +2,7 @@ import java.nio.charset.StandardCharsets; import java.util.Collection; -import java.util.Collections; +import java.util.List; import java.util.function.Consumer; import javax.mail.Message.RecipientType; @@ -40,7 +40,7 @@ default void send(String subject, String message) */ default void send(String subject, String message, String to) { - send(subject, message, to == null ? null : Collections.singleton(to)); + send(subject, message, to == null ? null : List.of(to)); } /** @@ -95,7 +95,7 @@ default void send(String subject, MimeBodyPart body) */ default void send(String subject, MimeBodyPart body, String to) { - send(subject, body, to == null ? null : Collections.singleton(to)); + send(subject, body, to == null ? null : List.of(to)); } /** diff --git a/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/service/OrganizationProvider.java b/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/service/OrganizationProvider.java index 6f38b827c..5a9046cc9 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/service/OrganizationProvider.java +++ b/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/service/OrganizationProvider.java @@ -9,6 +9,7 @@ import org.hl7.fhir.r4.model.Organization; import org.hl7.fhir.r4.model.OrganizationAffiliation; +import dev.dsf.bpe.v2.constants.CodeSystems.OrganizationRole; import dev.dsf.bpe.v2.constants.NamingSystems.OrganizationIdentifier; /** @@ -52,16 +53,16 @@ default Optional getLocalOrganizationIdentifierValue() /** * @param organizationIdentifier * may be null - * @return {@link Organization} with the given organizationIdentifier, empty {@link Optional} if no such - * resource exists or the given identifier is null + * @return Active {@link Organization} with the given organizationIdentifier, empty {@link Optional} if no + * such resource exists or the given identifier is null */ Optional getOrganization(Identifier organizationIdentifier); /** * @param organizationIdentifierValue * may be null - * @return {@link Organization} with the given DSF organizationIdentifier, empty {@link Optional} if no such - * resource exists or the given identifier value is null + * @return Active {@link Organization} with the given DSF organizationIdentifier, empty {@link Optional} if + * no such resource exists or the given identifier value is null * @see OrganizationIdentifier */ default Optional getOrganization(String organizationIdentifierValue) @@ -73,20 +74,20 @@ default Optional getOrganization(String organizationIdentifierValu /** * @param parentOrganizationIdentifier * may be null - * @return Organizations configured as participatingOrganization for a parent {@link Organization} with the given - * parentOrganizationIdentifier, empty {@link List} if no parent organization found, parent has no - * participating organizations configured via {@link OrganizationAffiliation} resources or the given - * identifier is null + * @return Active Organizations configured as participatingOrganization for an active parent {@link Organization} + * with the given parentOrganizationIdentifier, empty {@link List} if no parent organization found, + * parent has no participating organizations configured via {@link OrganizationAffiliation} resources or the + * given identifier is null */ List getOrganizations(Identifier parentOrganizationIdentifier); /** * @param parentOrganizationIdentifierValue * may be null - * @return Organizations configured as participatingOrganization for a parent {@link Organization} with the given - * DSF parentOrganizationIdentifierValue, empty {@link List} if no parent organization found, parent - * has no participating organizations configured via {@link OrganizationAffiliation} resources or the given - * identifier is null + * @return Active Organizations configured as participatingOrganization for an active parent {@link Organization} + * with the given DSF parentOrganizationIdentifierValue, empty {@link List} if no parent organization + * found, parent has no participating organizations configured via {@link OrganizationAffiliation} resources + * or the given identifier is null * @see OrganizationIdentifier */ default List getOrganizations(String parentOrganizationIdentifierValue) @@ -100,35 +101,47 @@ default List getOrganizations(String parentOrganizationIdentifierV * may be null * @param memberOrganizationRole * may be null - * @return Organizations configured as participatingOrganization for a parent {@link Organization} with the given - * parentOrganizationIdentifier and role equal to the given memberOrganizationRole, empty - * {@link List} if no parent organization found, parent has no participating organizations configured via - * {@link OrganizationAffiliation} resources with the given role or the given identifier is - * null + * @return Active Organizations configured as participatingOrganization for an active parent {@link Organization} + * with the given parentOrganizationIdentifier and role equal to the given + * memberOrganizationRole, empty {@link List} if no parent organization found, parent has no + * participating organizations configured via {@link OrganizationAffiliation} resources with the given role + * or the given identifier is null */ List getOrganizations(Identifier parentOrganizationIdentifier, Coding memberOrganizationRole); /** * @param parentOrganizationIdentifierValue * may be null - * @param memberOrganizationRole + * @param memberOrganizationRoleCode * may be null - * @return Organizations configured as participatingOrganization for a parent {@link Organization} with the given - * parentOrganizationIdentifier and role equal to the given memberOrganizationRole, empty - * {@link List} if no parent organization found, parent has no participating organizations configured via - * {@link OrganizationAffiliation} resources with the given role or the given identifier is - * null + * @return Active Organizations configured as participatingOrganization for an active parent {@link Organization} + * with the given parentOrganizationIdentifier and role equal to the given + * memberOrganizationRole, empty {@link List} if no parent organization found, parent has no + * participating organizations configured via {@link OrganizationAffiliation} resources with the given role + * or the given identifier is null * @see OrganizationIdentifier */ - default List getOrganizations(String parentOrganizationIdentifierValue, Coding memberOrganizationRole) + default List getOrganizations(String parentOrganizationIdentifierValue, + String memberOrganizationRoleCode) { - return getOrganizations(parentOrganizationIdentifierValue == null ? null - : OrganizationIdentifier.withValue(parentOrganizationIdentifierValue), memberOrganizationRole); + return getOrganizations( + parentOrganizationIdentifierValue == null ? null + : OrganizationIdentifier.withValue(parentOrganizationIdentifierValue), + memberOrganizationRoleCode == null ? null : OrganizationRole.withCode(memberOrganizationRoleCode)); } /** - * @return All {@link Organization} resources except the local {@link Organization} + * @return All active {@link Organization} resources except the local {@link Organization} and parent + * {@link Organization} resources * @see #getLocalOrganization() + * @see #getParentOrganizations() */ List getRemoteOrganizations(); + + /** + * @return All active parent {@link Organization} resources + * @see #getLocalOrganization() + * @see #getRemoteOrganizations() + */ + List getParentOrganizations(); } diff --git a/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/service/process/ProcessAuthorizationHelper.java b/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/service/process/ProcessAuthorizationHelper.java index 6d198a041..61634e6aa 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/service/process/ProcessAuthorizationHelper.java +++ b/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/service/process/ProcessAuthorizationHelper.java @@ -1,7 +1,7 @@ package dev.dsf.bpe.v2.service.process; import java.util.Collection; -import java.util.Collections; +import java.util.List; import java.util.function.Predicate; import java.util.stream.Stream; @@ -63,8 +63,7 @@ boolean isValid(ActivityDefinition activityDefinition, Predicate default Stream getRequesters(ActivityDefinition activityDefinition, String processUrl, String processVersion, String messageName, String taskProfile) { - return getRequesters(activityDefinition, processUrl, processVersion, messageName, - Collections.singleton(taskProfile)); + return getRequesters(activityDefinition, processUrl, processVersion, messageName, List.of(taskProfile)); } Stream getRequesters(ActivityDefinition activityDefinition, String processUrl, String processVersion, @@ -73,8 +72,7 @@ Stream getRequesters(ActivityDefinition activityDefinition, String pr default Stream getRecipients(ActivityDefinition activityDefinition, String processUrl, String processVersion, String messageName, String taskProfiles) { - return getRecipients(activityDefinition, processUrl, processVersion, messageName, - Collections.singleton(taskProfiles)); + return getRecipients(activityDefinition, processUrl, processVersion, messageName, List.of(taskProfiles)); } Stream getRecipients(ActivityDefinition activityDefinition, String processUrl, String processVersion, diff --git a/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/variables/Variables.java b/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/variables/Variables.java index 5f374d67a..cc7753428 100644 --- a/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/variables/Variables.java +++ b/dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/variables/Variables.java @@ -1,7 +1,6 @@ package dev.dsf.bpe.v2.variables; import java.io.File; -import java.util.Arrays; import java.util.Date; import java.util.List; @@ -117,7 +116,7 @@ default Target createTarget(String organizationIdentifierValue, String endpointI */ default Targets createTargets(Target... targets) { - return createTargets(Arrays.asList(targets)); + return createTargets(List.of(targets)); } /** diff --git a/dsf-bpe/dsf-bpe-process-api/pom.xml b/dsf-bpe/dsf-bpe-process-api/pom.xml index 2be786d6e..5a60e94a7 100644 --- a/dsf-bpe/dsf-bpe-process-api/pom.xml +++ b/dsf-bpe/dsf-bpe-process-api/pom.xml @@ -24,9 +24,5 @@ org.springframework spring-context - - commons-io - commons-io - \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-process-api/src/main/java/dev/dsf/bpe/api/plugin/AbstractProcessPlugin.java b/dsf-bpe/dsf-bpe-process-api/src/main/java/dev/dsf/bpe/api/plugin/AbstractProcessPlugin.java index 75a488f01..195294e9c 100644 --- a/dsf-bpe/dsf-bpe-process-api/src/main/java/dev/dsf/bpe/api/plugin/AbstractProcessPlugin.java +++ b/dsf-bpe/dsf-bpe-process-api/src/main/java/dev/dsf/bpe/api/plugin/AbstractProcessPlugin.java @@ -22,7 +22,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import org.apache.commons.io.IOUtils; import org.camunda.bpm.engine.delegate.ExecutionListener; import org.camunda.bpm.engine.delegate.JavaDelegate; import org.camunda.bpm.engine.delegate.TaskListener; @@ -584,7 +583,7 @@ file, getDefinitionName(), getDefinitionVersion(), VERSION_PLACEHOLDER_PATTERN_S return null; } - String content = IOUtils.toString(in, StandardCharsets.UTF_8); + String content = new String(in.readAllBytes(), StandardCharsets.UTF_8); content = VERSION_PLACEHOLDER_PATTERN.matcher(content).replaceAll(getDefinitionResourceVersion()); content = DATE_PLACEHOLDER_PATTERN.matcher(content).replaceAll(resourceDateValue); @@ -795,7 +794,7 @@ && taskFieldsAvailable(process, "MessageEndEvent", e.getId(), public boolean taskFieldsAvailable(Process process, String elementType, String elementId, ExtensionElements extensionElements) { - Collection fields = extensionElements == null ? Collections.emptySet() + Collection fields = extensionElements == null ? List.of() : extensionElements.getChildElementsByType(CamundaField.class); String instantiatesCanonical = null; @@ -954,7 +953,7 @@ file, getDefinitionName(), getDefinitionVersion(), VERSION_PLACEHOLDER_PATTERN_S return null; } - String content = IOUtils.toString(in, StandardCharsets.UTF_8); + String content = new String(in.readAllBytes(), StandardCharsets.UTF_8); content = VERSION_PLACEHOLDER_PATTERN.matcher(content).replaceAll(getDefinitionResourceVersion()); content = DATE_PLACEHOLDER_PATTERN.matcher(content).replaceAll(resourceDateValue); @@ -1241,7 +1240,7 @@ private Predicate hasMatchingActivityDefinition( { ProcessIdAndVersion processIdAndVersion = model.getProcessIdAndVersion(); - List resources = fhirResources.getOrDefault(processIdAndVersion, Collections.emptyList()); + List resources = fhirResources.getOrDefault(processIdAndVersion, List.of()); if (resources.isEmpty()) { logger.warn( diff --git a/dsf-bpe/dsf-bpe-process-api/src/main/java/dev/dsf/bpe/api/plugin/AbstractProcessPluginFactory.java b/dsf-bpe/dsf-bpe-process-api/src/main/java/dev/dsf/bpe/api/plugin/AbstractProcessPluginFactory.java index 86c3e557d..746e787dd 100644 --- a/dsf-bpe/dsf-bpe-process-api/src/main/java/dev/dsf/bpe/api/plugin/AbstractProcessPluginFactory.java +++ b/dsf-bpe/dsf-bpe-process-api/src/main/java/dev/dsf/bpe/api/plugin/AbstractProcessPluginFactory.java @@ -67,12 +67,12 @@ public Class getDefaultUserTaskListener() } @Override - public ProcessPlugin load(Path jar) + public ProcessPlugin load(Path pluginPath) { try { - URLClassLoader pluginClassLoader = new URLClassLoader(jar.getFileName().toString(), - new URL[] { toUrl(jar) }, apiClassLoader); + URLClassLoader pluginClassLoader = new URLClassLoader(pluginPath.getFileName().toString(), + new URL[] { toUrl(pluginPath) }, apiClassLoader); List> definitions = ServiceLoader.load(processPluginDefinitionType, pluginClassLoader).stream() .collect(Collectors.toList()); @@ -80,20 +80,20 @@ public ProcessPlugin load(Path jar) if (definitions.size() != 1) return null; - String filename = jar.getFileName().toString(); + String filename = pluginPath.getFileName().toString(); boolean isSnapshot = filename.endsWith(SNAPSHOT_FILE_SUFFIX); boolean isMilestone = filename.matches(MILESTONE_FILE_PATTERN); boolean isReleaseCandidate = filename.matches(RELEASE_CANDIDATE_FILE_PATTERN); boolean draft = isSnapshot || isMilestone || isReleaseCandidate; - return createProcessPlugin(definitions.get(0).get(), draft, jar, pluginClassLoader); + return createProcessPlugin(definitions.get(0).get(), draft, pluginPath, pluginClassLoader); } catch (Exception e) { - logger.debug("Ignoring {}: Unable to load process plugin", jar.toString(), e); - logger.warn("Ignoring {}: Unable to load process plugin: {} - {}", jar.toString(), e.getClass().getName(), - e.getMessage()); + logger.debug("Ignoring {}: Unable to load process plugin", pluginPath.toString(), e); + logger.warn("Ignoring {}: Unable to load process plugin: {} - {}", pluginPath.toString(), + e.getClass().getName(), e.getMessage()); return null; } diff --git a/dsf-bpe/dsf-bpe-process-api/src/main/java/dev/dsf/bpe/api/plugin/ProcessPluginFactory.java b/dsf-bpe/dsf-bpe-process-api/src/main/java/dev/dsf/bpe/api/plugin/ProcessPluginFactory.java index 1886345f4..4fa6247e1 100644 --- a/dsf-bpe/dsf-bpe-process-api/src/main/java/dev/dsf/bpe/api/plugin/ProcessPluginFactory.java +++ b/dsf-bpe/dsf-bpe-process-api/src/main/java/dev/dsf/bpe/api/plugin/ProcessPluginFactory.java @@ -19,5 +19,5 @@ public interface ProcessPluginFactory Class getDefaultUserTaskListener(); - ProcessPlugin load(Path jar); + ProcessPlugin load(Path pluginPath); } \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-process-api/src/main/java/dev/dsf/bpe/api/service/BpeMailService.java b/dsf-bpe/dsf-bpe-process-api/src/main/java/dev/dsf/bpe/api/service/BpeMailService.java index f6b740967..f7dd2a9f8 100644 --- a/dsf-bpe/dsf-bpe-process-api/src/main/java/dev/dsf/bpe/api/service/BpeMailService.java +++ b/dsf-bpe/dsf-bpe-process-api/src/main/java/dev/dsf/bpe/api/service/BpeMailService.java @@ -2,7 +2,7 @@ import java.nio.charset.StandardCharsets; import java.util.Collection; -import java.util.Collections; +import java.util.List; import java.util.function.Consumer; import javax.mail.Message.RecipientType; @@ -40,7 +40,7 @@ default void send(String subject, String message) */ default void send(String subject, String message, String to) { - send(subject, message, to == null ? null : Collections.singleton(to)); + send(subject, message, to == null ? null : List.of(to)); } /** @@ -95,7 +95,7 @@ default void send(String subject, MimeBodyPart body) */ default void send(String subject, MimeBodyPart body, String to) { - send(subject, body, to == null ? null : Collections.singleton(to)); + send(subject, body, to == null ? null : List.of(to)); } /** diff --git a/dsf-bpe/dsf-bpe-server-jetty/api/v1/README.md b/dsf-bpe/dsf-bpe-server-jetty/api/v1/README.md deleted file mode 100644 index 1cde66f27..000000000 --- a/dsf-bpe/dsf-bpe-server-jetty/api/v1/README.md +++ /dev/null @@ -1 +0,0 @@ -Empty v1 directory for jar-files used in dev setup diff --git a/dsf-bpe/dsf-bpe-server-jetty/api/v2/README.md b/dsf-bpe/dsf-bpe-server-jetty/api/v2/README.md deleted file mode 100644 index 851b656a2..000000000 --- a/dsf-bpe/dsf-bpe-server-jetty/api/v2/README.md +++ /dev/null @@ -1 +0,0 @@ -Empty v2 directory for jar-files used in dev setup diff --git a/dsf-bpe/dsf-bpe-server-jetty/conf/jetty.properties b/dsf-bpe/dsf-bpe-server-jetty/conf/jetty.properties index c672ed4c0..31b3a527e 100755 --- a/dsf-bpe/dsf-bpe-server-jetty/conf/jetty.properties +++ b/dsf-bpe/dsf-bpe-server-jetty/conf/jetty.properties @@ -1,9 +1,9 @@ -dev.dsf.server.api.port=8002 -dev.dsf.server.status.port=10002 -dev.dsf.server.context.path=/bpe - -dev.dsf.server.certificate=target/localhost_certificate.pem -dev.dsf.server.certificate.key=target/localhost_private-key.pem -dev.dsf.server.certificate.key.password=password - +dev.dsf.server.api.port=8002 +dev.dsf.server.status.port=10002 +dev.dsf.server.context.path=/bpe + +dev.dsf.server.certificate=target/localhost_certificate.pem +dev.dsf.server.certificate.key=target/localhost_private-key.pem +dev.dsf.server.certificate.key.password=password + dev.dsf.server.auth.trust.client.certificate.cas=target/testca_certificate.pem \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-server-jetty/pom.xml b/dsf-bpe/dsf-bpe-server-jetty/pom.xml index d193662fa..a676e7b7c 100755 --- a/dsf-bpe/dsf-bpe-server-jetty/pom.xml +++ b/dsf-bpe/dsf-bpe-server-jetty/pom.xml @@ -89,436 +89,6 @@ compile - - copy-api-v1-dependencies-to-docker - install - - copy - - - - - dev.dsf - dsf-bpe-process-api-v1 - - - dev.dsf - dsf-bpe-process-api-v1-impl - - - ca.uhn.hapi.fhir - hapi-fhir-structures-r4 - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - hapi-fhir-base - ${hapi.fhir.version.v1} - - - com.google.j2objc - j2objc-annotations - 2.8 - - - ca.uhn.hapi.fhir - org.hl7.fhir.utilities - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - org.hl7.fhir.r4 - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - hapi-fhir-structures-r5 - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - org.hl7.fhir.r5 - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - hapi-fhir-validation - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - hapi-fhir-converter - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - org.hl7.fhir.convertors - ${hapi.fhir.version.v1} - - - net.sf.saxon - Saxon-HE - 9.5.1-5 - - - ca.uhn.hapi.fhir - org.hl7.fhir.validation - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - org.hl7.fhir.dstu2 - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - org.hl7.fhir.dstu2016may - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - org.hl7.fhir.dstu3 - ${hapi.fhir.version.v1} - - - org.apache.commons - commons-compress - 1.27.1 - - - org.fhir - ucum - 1.0.2 - - - com.github.ben-manes.caffeine - caffeine - 2.7.0 - - - org.checkerframework - checker-qual - 2.6.0 - - - com.google.errorprone - error_prone_annotations - 2.3.3 - - - com.google.code.gson - gson - 2.11.0 - - - ca.uhn.hapi.fhir - hapi-fhir-validation-resources-r4 - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - hapi-fhir-validation-resources-r5 - ${hapi.fhir.version.v1} - - - docker/api/v1 - - - - copy-api-v1-dependencies-to-server-jetty - generate-sources - - copy - - - - - dev.dsf - dsf-bpe-process-api-v1 - - - dev.dsf - dsf-bpe-process-api-v1-impl - - - ca.uhn.hapi.fhir - hapi-fhir-structures-r4 - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - hapi-fhir-base - ${hapi.fhir.version.v1} - - - com.google.j2objc - j2objc-annotations - 2.8 - - - ca.uhn.hapi.fhir - org.hl7.fhir.utilities - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - org.hl7.fhir.r4 - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - hapi-fhir-structures-r5 - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - org.hl7.fhir.r5 - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - hapi-fhir-validation - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - hapi-fhir-converter - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - org.hl7.fhir.convertors - ${hapi.fhir.version.v1} - - - net.sf.saxon - Saxon-HE - 9.5.1-5 - - - ca.uhn.hapi.fhir - org.hl7.fhir.validation - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - org.hl7.fhir.dstu2 - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - org.hl7.fhir.dstu2016may - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - org.hl7.fhir.dstu3 - ${hapi.fhir.version.v1} - - - org.apache.commons - commons-compress - 1.26.2 - - - org.fhir - ucum - 1.0.2 - - - com.github.ben-manes.caffeine - caffeine - 2.7.0 - - - org.checkerframework - checker-qual - 2.6.0 - - - com.google.errorprone - error_prone_annotations - 2.3.3 - - - com.google.code.gson - gson - 2.11.0 - - - ca.uhn.hapi.fhir - hapi-fhir-validation-resources-r4 - ${hapi.fhir.version.v1} - - - ca.uhn.hapi.fhir - hapi-fhir-validation-resources-r5 - ${hapi.fhir.version.v1} - - - api/v1 - - - - copy-api-v2-dependencies-to-docker - install - - copy - - - - - dev.dsf - dsf-bpe-process-api-v2 - - - dev.dsf - dsf-bpe-process-api-v2-impl - - - org.checkerframework - checker-qual - 3.43.0 - - - com.google.errorprone - error_prone_annotations - 2.28.0 - - - ca.uhn.hapi.fhir - hapi-fhir-base - ${hapi.fhir.version.v2} - - - ca.uhn.hapi.fhir - hapi-fhir-caching-api - ${hapi.fhir.version.v2} - - - ca.uhn.hapi.fhir - hapi-fhir-structures-r4 - ${hapi.fhir.version.v2} - - - com.ibm.icu - icu4j - 72.1 - - - com.google.j2objc - j2objc-annotations - 3.0.0 - - - io.opentelemetry - opentelemetry-api - 1.38.0 - - - io.opentelemetry - opentelemetry-context - 1.38.0 - - - io.opentelemetry.instrumentation - opentelemetry-instrumentation-annotations - 2.4.0 - - - ca.uhn.hapi.fhir - org.hl7.fhir.r4 - 6.3.11 - - - ca.uhn.hapi.fhir - org.hl7.fhir.utilities - 6.3.11 - - - docker/api/v2 - - - - copy-api-v2-dependencies-to-server-jetty - generate-sources - - copy - - - - - dev.dsf - dsf-bpe-process-api-v2 - - - dev.dsf - dsf-bpe-process-api-v2-impl - - - org.checkerframework - checker-qual - 3.43.0 - - - com.google.errorprone - error_prone_annotations - 2.28.0 - - - ca.uhn.hapi.fhir - hapi-fhir-base - ${hapi.fhir.version.v2} - - - ca.uhn.hapi.fhir - hapi-fhir-caching-api - ${hapi.fhir.version.v2} - - - ca.uhn.hapi.fhir - hapi-fhir-structures-r4 - ${hapi.fhir.version.v2} - - - com.ibm.icu - icu4j - 72.1 - - - com.google.j2objc - j2objc-annotations - 3.0.0 - - - io.opentelemetry - opentelemetry-api - 1.38.0 - - - io.opentelemetry - opentelemetry-context - 1.38.0 - - - io.opentelemetry.instrumentation - opentelemetry-instrumentation-annotations - 2.4.0 - - - ca.uhn.hapi.fhir - org.hl7.fhir.r4 - 6.3.11 - - - ca.uhn.hapi.fhir - org.hl7.fhir.utilities - 6.3.11 - - - api/v2 - - copy-server-jar-to-docker install @@ -549,23 +119,6 @@ dsf_bpe.jar lib/*.jar - api/v1/*.jar - api/v2/*.jar - - false - - - process - - *.jar - - false - - - api - - v1/*.jar - v2/*.jar false diff --git a/dsf-bpe/dsf-bpe-server-jetty/src/main/java/dev/dsf/bpe/BpeJettyServer.java b/dsf-bpe/dsf-bpe-server-jetty/src/main/java/dev/dsf/bpe/BpeJettyServer.java index 2179eced6..805907d70 100755 --- a/dsf-bpe/dsf-bpe-server-jetty/src/main/java/dev/dsf/bpe/BpeJettyServer.java +++ b/dsf-bpe/dsf-bpe-server-jetty/src/main/java/dev/dsf/bpe/BpeJettyServer.java @@ -36,6 +36,8 @@ public static void main(String[] args) BpeHttpJettyConfig.class)) { JettyServer server = context.getBean(JettyServer.class); + + server.addShutdownHook(); server.start(); } } diff --git a/dsf-bpe/dsf-bpe-server-jetty/src/main/java/dev/dsf/bpe/BpeJettyServerHttps.java b/dsf-bpe/dsf-bpe-server-jetty/src/main/java/dev/dsf/bpe/BpeJettyServerHttps.java index eda4803f4..efb93ee66 100755 --- a/dsf-bpe/dsf-bpe-server-jetty/src/main/java/dev/dsf/bpe/BpeJettyServerHttps.java +++ b/dsf-bpe/dsf-bpe-server-jetty/src/main/java/dev/dsf/bpe/BpeJettyServerHttps.java @@ -36,6 +36,8 @@ public static void main(String[] args) BpeHttpsJettyConfig.class)) { JettyServer server = context.getBean(JettyServer.class); + + server.addShutdownHook(); server.start(); } } diff --git a/dsf-bpe/dsf-bpe-server-jetty/src/main/java/dev/dsf/bpe/config/BpeDbMigratorConfig.java b/dsf-bpe/dsf-bpe-server-jetty/src/main/java/dev/dsf/bpe/config/BpeDbMigratorConfig.java index dda8e1ed3..ef5a66e0a 100644 --- a/dsf-bpe/dsf-bpe-server-jetty/src/main/java/dev/dsf/bpe/config/BpeDbMigratorConfig.java +++ b/dsf-bpe/dsf-bpe-server-jetty/src/main/java/dev/dsf/bpe/config/BpeDbMigratorConfig.java @@ -97,6 +97,12 @@ public char[] getDbLiquibasePassword() return dbLiquibasePassword; } + @Override + public String getChangelogFile() + { + return "bpe/db/db.changelog.xml"; + } + @Override public Map getChangeLogParameters() { diff --git a/dsf-bpe/dsf-bpe-server/pom.xml b/dsf-bpe/dsf-bpe-server/pom.xml index 6ed75ff12..a7544798b 100755 --- a/dsf-bpe/dsf-bpe-server/pom.xml +++ b/dsf-bpe/dsf-bpe-server/pom.xml @@ -108,6 +108,10 @@ org.glassfish.jersey.media jersey-media-json-jackson + + org.glassfish.jersey.media + jersey-media-jaxb + org.glassfish.jersey.containers jersey-container-servlet @@ -160,8 +164,8 @@ - org.mockito - mockito-core + dev.dsf + dsf-common-jetty test @@ -169,6 +173,16 @@ db-test-utils test + + org.mockito + mockito-core + test + + + org.slf4j + jul-to-slf4j + test + org.apache.logging.log4j log4j-slf4j2-impl @@ -180,6 +194,31 @@ disruptor test + + + dev.dsf + dsf-fhir-server + test + + + + + dev.dsf + dsf-bpe-test-plugin + test + + + + + dev.dsf + dsf-bpe-test-plugin-v1 + test + + + dev.dsf + dsf-bpe-test-plugin-v2 + test + diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/camunda/FallbackSerializerFactoryImpl.java b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/camunda/FallbackSerializerFactoryImpl.java index 4cb47fa2b..0b62334e3 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/camunda/FallbackSerializerFactoryImpl.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/camunda/FallbackSerializerFactoryImpl.java @@ -1,6 +1,5 @@ package dev.dsf.bpe.camunda; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -116,7 +115,7 @@ public TypedValueSerializer getSerializer(TypedValue value) { logger.debug("Getting serializer for {} from class loader {}", getName(value), classLoader.getName()); - return serializersByClassLoader.getOrDefault(classLoader, Collections.emptyList()).stream() + return serializersByClassLoader.getOrDefault(classLoader, List.of()).stream() .filter(s -> s.canHandle(value)).findFirst().orElse(null); } else diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/client/FhirWebserviceClientJersey.java b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/client/FhirWebserviceClientJersey.java index 8f9ebe55e..953faa77a 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/client/FhirWebserviceClientJersey.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/client/FhirWebserviceClientJersey.java @@ -2,7 +2,6 @@ import java.io.InputStream; import java.security.KeyStore; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -43,9 +42,9 @@ public FhirWebserviceClientJersey(String baseUrl, KeyStore trustStore, KeyStore ObjectMapper objectMapper, String proxySchemeHostPort, String proxyUserName, char[] proxyPassword, int connectTimeout, int readTimeout, boolean logRequests, String userAgentValue, FhirContext fhirContext) { - super(baseUrl, trustStore, keyStore, keyStorePassword, objectMapper, - Collections.singleton(new FhirAdapter(fhirContext)), proxySchemeHostPort, proxyUserName, proxyPassword, - connectTimeout, readTimeout, logRequests, userAgentValue); + super(baseUrl, trustStore, keyStore, keyStorePassword, objectMapper, List.of(new FhirAdapter(fhirContext)), + proxySchemeHostPort, proxyUserName, proxyPassword, connectTimeout, readTimeout, logRequests, + userAgentValue); preferReturnMinimal = new PreferReturnMinimalWithRetryImpl(this); } diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/mail/BpeMailService.java b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/mail/BpeMailService.java index c53c3044e..a541dcd84 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/mail/BpeMailService.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/mail/BpeMailService.java @@ -2,7 +2,7 @@ import java.nio.charset.StandardCharsets; import java.util.Collection; -import java.util.Collections; +import java.util.List; import java.util.function.Consumer; import javax.mail.Message.RecipientType; @@ -40,7 +40,7 @@ default void send(String subject, String message) */ default void send(String subject, String message, String to) { - send(subject, message, to == null ? null : Collections.singleton(to)); + send(subject, message, to == null ? null : List.of(to)); } /** @@ -95,7 +95,7 @@ default void send(String subject, MimeBodyPart body) */ default void send(String subject, MimeBodyPart body, String to) { - send(subject, body, to == null ? null : Collections.singleton(to)); + send(subject, body, to == null ? null : List.of(to)); } /** diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/FhirResourceHandlerImpl.java b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/FhirResourceHandlerImpl.java index 9dcff0ab2..1597946aa 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/FhirResourceHandlerImpl.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/FhirResourceHandlerImpl.java @@ -3,7 +3,6 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; @@ -227,7 +226,7 @@ private void addResourcesRemovedFromDraftProcess(List && ProcessState.DRAFT.equals(change.getNewProcessState())) { List dbResources = dbResourcesByProcess.getOrDefault(change.getProcessKeyAndVersion(), - Collections.emptyList()); + List.of()); dbResources.forEach(dbRes -> { @@ -366,7 +365,7 @@ private Stream getCurrentOrOldResources( if (resources == null) { logger.debug("No resources found in BPE DB for process {}", process); - resources = Collections.emptyList(); + resources = List.of(); } return resources.stream().map(info -> ProcessesResource.from(info).add(process)); @@ -391,8 +390,8 @@ private Stream getResources(ProcessIdAndVersion process, private Optional getResourceId(Map> dbResourcesByProcess, ProcessIdAndVersion process, ResourceInfo resourceInfo) { - return dbResourcesByProcess.getOrDefault(process, Collections.emptyList()).stream() - .filter(r -> r.equals(resourceInfo)).findFirst().map(ResourceInfo::getResourceId); + return dbResourcesByProcess.getOrDefault(process, List.of()).stream().filter(r -> r.equals(resourceInfo)) + .findFirst().map(ResourceInfo::getResourceId); } private Map> getResourceInfosFromDb() diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginApiClassLoader.java b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginApiClassLoader.java index bc41776ae..dd72bc452 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginApiClassLoader.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginApiClassLoader.java @@ -23,19 +23,19 @@ public class ProcessPluginApiClassLoader extends URLClassLoader private static final Logger logger = LoggerFactory.getLogger(ProcessPluginApiClassLoader.class); private final Set allowedBpeClasses = new HashSet<>(); - private final Set apiResourcesWithPriority = new HashSet<>(); + private final Set resourcesWithPriority = new HashSet<>(); private final Set allowedBpeResources = new HashSet<>(); public ProcessPluginApiClassLoader(String name, URL[] urls, ClassLoader bpeLoader, Set allowedBpeClasses, - Set apiResourcesWithPriority, Set allowedBpeResources) + Set resourcesWithPriority, Set allowedBpeResources) { super(name, urls, bpeLoader); if (allowedBpeClasses != null) this.allowedBpeClasses.addAll(allowedBpeClasses); - if (apiResourcesWithPriority != null) - this.apiResourcesWithPriority.addAll(apiResourcesWithPriority); + if (resourcesWithPriority != null) + this.resourcesWithPriority.addAll(resourcesWithPriority); if (allowedBpeResources != null) this.allowedBpeResources.addAll(allowedBpeResources); @@ -67,7 +67,7 @@ protected Class loadClass(String className, boolean resolve) throws ClassNotF if (isBpeClassAllowed(bpeClass)) return bpeClass; - logger.warn("Class " + className + " not found or hidden"); + logger.debug("Class " + className + " not found or hidden"); throw new ClassNotFoundException(className); } } @@ -152,21 +152,22 @@ private boolean isBpeClassAllowed(Class clazz) || allowedBpeClasses.contains(className)) return true; - logger.debug("{} TODO: Should bpe class {} be allowed?", getName(), className); + logger.debug("{} TODO: Should bpe class {} be allowed? [default: false]", getName(), className); return false; } /** * @param name * @param apiResourceUrl - * @return true if resource from from api or process plugins has priority over resource from bpe + * @return true if resource from api or process plugins has priority over resource from bpe */ private boolean hasApiResourcePriority(String name, URL apiResourceUrl) { - if ("jar".equals(apiResourceUrl.getProtocol()) && apiResourcesWithPriority.contains(name)) + if ("jar".equals(apiResourceUrl.getProtocol()) && resourcesWithPriority.contains(name)) return true; - logger.debug("{} TODO: Should api resource {} / {} have priority?", getName(), name, apiResourceUrl); + logger.debug("{} TODO: Should api resource {} / {} have priority? [default: false]", getName(), name, + apiResourceUrl); return false; } @@ -180,7 +181,8 @@ private boolean isBpeResourceAllowed(String name, URL bpeResourcetUrl) if ("jar".equals(bpeResourcetUrl.getProtocol()) && allowedBpeResources.contains(name)) return true; - logger.debug("{} TODO: Should bpe resource {} / {} be allowed?", getName(), name, bpeResourcetUrl); + logger.debug("{} TODO: Should bpe resource {} / {} be allowed? [default: false]", getName(), name, + bpeResourcetUrl); return false; } } diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginApiClassLoaderFactory.java b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginApiClassLoaderFactory.java index 0dabb92e8..a18f6bc2c 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginApiClassLoaderFactory.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginApiClassLoaderFactory.java @@ -9,37 +9,73 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.Set; +import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; -public class ProcessPluginApiClassLoaderFactory +public class ProcessPluginApiClassLoaderFactory implements InitializingBean { private static final Logger logger = LoggerFactory.getLogger(ProcessPluginApiClassLoaderFactory.class); private static final String ALLOWED_BPE_CLASSES_LIST = "allowed-bpe-classes.list"; - private static final String API_RESOURCES_WITH_PRIORITY_LIST = "api-resources-with-priority.list"; + private static final String RESOURCES_WITH_PRIORITY_LIST = "resources-with-priority.list"; private static final String ALLOWED_BPE_RESOURCES = "allowed-bpe-resources.list"; - private URL[] getApiClassPath(String apiVersion) + private final Path apiClassPathBaseDirectory; + + private final Map allowedBpeClasses = new HashMap<>(); + private final Map resourcesWithPriority = new HashMap<>(); + private final Map allowedBpeResources = new HashMap<>(); + + public ProcessPluginApiClassLoaderFactory(Path apiClassPathBaseDirectory, Map allowedBpeClasses, + Map resourcesWithPriority, Map allowedBpeResources) { - Path apiClassPathFolder = Paths.get("api/v" + apiVersion); + this.apiClassPathBaseDirectory = apiClassPathBaseDirectory; + + if (allowedBpeClasses != null) + this.allowedBpeClasses.putAll(allowedBpeClasses); + if (resourcesWithPriority != null) + this.resourcesWithPriority.putAll(resourcesWithPriority); + if (allowedBpeResources != null) + this.allowedBpeResources.putAll(allowedBpeResources); + } + + @Override + public void afterPropertiesSet() throws Exception + { + Objects.requireNonNull(apiClassPathBaseDirectory, "apiClassPathBaseDirectory"); + // list files may be null + } + + private List getApiClassPath(int apiVersion) + { + Path apiClassPathDirectory = apiClassPathBaseDirectory.resolve("v" + apiVersion); try { - return Files.list(apiClassPathFolder).filter(p -> p.getFileName().toString().endsWith(".jar")) - .map(this::toUrl).toArray(URL[]::new); + List files = Files.list(apiClassPathDirectory) + .filter(p -> p.getFileName().toString().endsWith(".jar")).toList(); + + if (files.isEmpty()) + throw new IllegalArgumentException("No jar files found for API v" + apiVersion + " class-path at " + + apiClassPathDirectory.toAbsolutePath().normalize().toString()); + + return files; } catch (IOException e) { - logger.warn("Unable to iterate files in api class path folder {}", apiClassPathFolder); + logger.warn("Unable to iterate files in api class path directory {}", apiClassPathDirectory); throw new RuntimeException( - "Unable to iterate files in api class path folder " + apiClassPathFolder.toString(), e); + "Unable to iterate files in api class path directory " + apiClassPathDirectory.toString(), e); } } @@ -55,50 +91,66 @@ private URL toUrl(Path p) } } - private Set readList(String apiVersion, String file) + private Set readList(int apiVersion, String file) { Path externalFile = getExternalFileIfReadable(apiVersion, file); - return externalFile == null ? readInternal(apiVersion, file) : readExternal(externalFile); + return externalFile == null ? readInternal(apiVersion, file) : readExternal(apiVersion, file, externalFile); } - private Path getExternalFileIfReadable(String apiVersion, String file) + private Path getExternalFileIfReadable(int apiVersion, String file) { - Path externalFile = Paths.get("api/v" + apiVersion + "/" + file); + Path externalFile = switch (file) + { + case ALLOWED_BPE_CLASSES_LIST -> allowedBpeClasses.get(apiVersion); + case RESOURCES_WITH_PRIORITY_LIST -> resourcesWithPriority.get(apiVersion); + case ALLOWED_BPE_RESOURCES -> allowedBpeResources.get(apiVersion); + + default -> throw new IllegalArgumentException("Unexpected file value: " + file); + }; + + if (externalFile == null) + { + logger.debug("External file for api v{} not configured, using {} from jar", apiVersion, file); + return null; + } if (!Files.exists(externalFile)) { - logger.debug("External file {} does not exist, using file from jar", - externalFile.toAbsolutePath().toString()); + logger.debug("External file for api v{} {} does not exist, using {} from jar", apiVersion, + externalFile.toAbsolutePath().normalize().toString(), file); return null; } if (!Files.isReadable(externalFile)) { - logger.debug("External file {} is not readable, using file from jar", - externalFile.toAbsolutePath().toString()); + logger.debug("External file for api v{} {} is not readable, using {} from jar", apiVersion, + externalFile.toAbsolutePath().normalize().toString(), file); return null; } return externalFile; } - private Set readExternal(Path file) + private Set readExternal(int apiVersion, String file, Path externalFile) { try { - logger.debug("Reading {} ...", file.toAbsolutePath().toString()); - return new HashSet<>(Files.readAllLines(file)); + logger.debug("Reading api v{} file {} from {} ...", apiVersion, file, + externalFile.toAbsolutePath().normalize().toString()); + return new HashSet<>(Files.readAllLines(externalFile)); } catch (IOException e) { - logger.warn("Unable to read external file {}", file.toAbsolutePath().toString()); - throw new RuntimeException("Unable to read external file " + file.toAbsolutePath().toString(), e); + logger.warn("Unable to read api v{} file {} from external file {}", apiVersion, file, + externalFile.toAbsolutePath().normalize().toString()); + throw new RuntimeException( + "Unable to read external file " + externalFile.toAbsolutePath().normalize().toString(), e); } } - private Set readInternal(String apiVersion, String file) + private Set readInternal(int apiVersion, String file) { - final String path = "api/v" + apiVersion + "/" + file; + final String path = "bpe/api/v" + apiVersion + "/" + file; try (InputStream in = ProcessPluginApiClassLoaderFactory.class.getClassLoader().getResourceAsStream(path); InputStreamReader inReader = new InputStreamReader(in, StandardCharsets.UTF_8); @@ -121,15 +173,20 @@ private Set readInternal(String apiVersion, String file) } } - public ProcessPluginApiClassLoader createApiClassLoader(String apiVersion) + public ProcessPluginApiClassLoader createApiClassLoader(int apiVersion) { - URL[] apiClassPath = getApiClassPath(apiVersion); + List apiClassPath = getApiClassPath(apiVersion); Set allowedBpeClasses = readList(apiVersion, ALLOWED_BPE_CLASSES_LIST); - Set apiResourcesWithPriority = readList(apiVersion, API_RESOURCES_WITH_PRIORITY_LIST); + Set resourcesWithPriority = readList(apiVersion, RESOURCES_WITH_PRIORITY_LIST); Set allowedBpeResources = readList(apiVersion, ALLOWED_BPE_RESOURCES); - return new ProcessPluginApiClassLoader("Plugin API v" + apiVersion, apiClassPath, - ClassLoader.getSystemClassLoader(), allowedBpeClasses, apiResourcesWithPriority, allowedBpeResources); + logger.debug("Creating Plugin API class loader for v{} with jar files from {}: {}", apiVersion, + apiClassPathBaseDirectory.resolve("v" + apiVersion).toAbsolutePath().normalize(), apiClassPath.stream() + .map(Path::getFileName).map(Path::toString).collect(Collectors.joining(", ", "[", "]"))); + + return new ProcessPluginApiClassLoader("Plugin API v" + apiVersion, + apiClassPath.stream().map(this::toUrl).toArray(URL[]::new), ClassLoader.getSystemClassLoader(), + allowedBpeClasses, resourcesWithPriority, allowedBpeResources); } } diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginApiFactory.java b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginApiFactory.java index 39b66db99..05c0177a5 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginApiFactory.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginApiFactory.java @@ -4,7 +4,7 @@ import java.util.Objects; import java.util.ServiceLoader; import java.util.ServiceLoader.Provider; -import java.util.stream.Stream; +import java.util.stream.IntStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,10 +58,10 @@ public void afterPropertiesSet() throws Exception public List initialize() { - return Stream.of("1", "2").map(this::init).toList(); + return IntStream.of(1, 2).mapToObj(this::init).toList(); } - private ProcessPluginFactory init(String apiVersion) + private ProcessPluginFactory init(int apiVersion) { ClassLoader apiClassLoader = classLoaderFactory.createApiClassLoader(apiVersion); ProcessPluginApiBuilder apiBuilder = loadProcessPluginApiBuilder(apiClassLoader); @@ -77,7 +77,7 @@ private ProcessPluginApiBuilder loadProcessPluginApiBuilder(ClassLoader apiClass .get(); } - private ApplicationContext createApiApplicationContext(String apiVersion, ClassLoader apiClassLoader, + private ApplicationContext createApiApplicationContext(int apiVersion, ClassLoader apiClassLoader, Class springServiceConfigClass) { try diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginLoaderImpl.java b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginLoaderImpl.java index 532b921b2..6385c19ae 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginLoaderImpl.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginLoaderImpl.java @@ -22,20 +22,24 @@ public class ProcessPluginLoaderImpl implements ProcessPluginLoader, Initializin { private static final Logger logger = LoggerFactory.getLogger(ProcessPluginLoaderImpl.class); - private final Path pluginDirectory; private final List processPluginFactories = new ArrayList<>(); + private final Path pluginDirectory; + private final List explodedPluginDirectories = new ArrayList<>(); + public ProcessPluginLoaderImpl(Collection processPluginFactories, - Path pluginDirectory) + Path pluginDirectory, Collection explodedPluginDirectories) { - this.pluginDirectory = pluginDirectory; - if (processPluginFactories != null) { this.processPluginFactories.addAll(processPluginFactories); this.processPluginFactories.sort( Comparator. comparingInt(ProcessPluginFactory::getApiVersion).reversed()); } + + this.pluginDirectory = pluginDirectory; + if (explodedPluginDirectories != null) + this.explodedPluginDirectories.addAll(explodedPluginDirectories); } @Override @@ -47,16 +51,16 @@ public void afterPropertiesSet() throws Exception @Override public List loadPlugins() { + List plugins = new ArrayList<>(); + try (DirectoryStream directoryStream = Files.newDirectoryStream(pluginDirectory)) { - List plugins = new ArrayList<>(); - directoryStream.forEach(p -> { if (!Files.isReadable(p)) - logger.warn("Ignoring {}: {}", p.toAbsolutePath().toString(), "Not readable"); + logger.warn("Ignoring {}: Not readable", p.toAbsolutePath().normalize().toString()); else if (!p.getFileName().toString().endsWith(".jar")) - logger.warn("Ignoring {}: {}", p.toAbsolutePath().toString(), "Not a .jar file"); + logger.warn("Ignoring {}: Not a .jar file", p.toAbsolutePath().normalize().toString()); else { ProcessPlugin plugin = load(p); @@ -64,8 +68,6 @@ else if (!p.getFileName().toString().endsWith(".jar")) plugins.add(plugin); } }); - - return plugins; } catch (IOException e) { @@ -74,19 +76,33 @@ else if (!p.getFileName().toString().endsWith(".jar")) throw new RuntimeException(e); } + + for (Path e : explodedPluginDirectories) + { + if (!Files.isDirectory(e)) + logger.warn("Ignoring {}: Not a directory", e.toAbsolutePath().normalize().toString()); + else + { + ProcessPlugin plugin = load(e); + if (plugin != null) + plugins.add(plugin); + } + } + + return plugins; } - private ProcessPlugin load(Path jar) + private ProcessPlugin load(Path pluginPath) { for (ProcessPluginFactory factory : processPluginFactories) { - ProcessPlugin plugin = factory.load(jar); + ProcessPlugin plugin = factory.load(pluginPath); if (plugin != null) return plugin; } - logger.warn("Ignoring {}: No process plugin definition for API version{} {} found", jar.toString(), + logger.warn("Ignoring {}: No process plugin definition for API version{} {} found", pluginPath.toString(), processPluginFactories.size() != 1 ? "s" : "", processPluginFactories.size() == 1 ? processPluginFactories.get(0).getApiVersion() : processPluginFactories.stream().map(f -> String.valueOf(f.getApiVersion())) diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginManagerImpl.java b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginManagerImpl.java index b3002d14e..2fa266e3f 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginManagerImpl.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessPluginManagerImpl.java @@ -2,7 +2,6 @@ import java.nio.file.Path; import java.util.ArrayList; -import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; import java.util.List; @@ -127,10 +126,8 @@ private BasicFhirWebserviceClient retryClient() private Optional getLocalOrganizationIdentifierValue() { - Bundle resultBundle = retryClient().searchWithStrictHandling(Endpoint.class, - Map.of("status", Collections.singletonList("active"), "address", - Collections.singletonList(localEndpointAddress), "_include", - Collections.singletonList("Endpoint:organization"))); + Bundle resultBundle = retryClient().searchWithStrictHandling(Endpoint.class, Map.of("status", List.of("active"), + "address", List.of(localEndpointAddress), "_include", List.of("Endpoint:organization"))); if (resultBundle == null || resultBundle.getEntry() == null || resultBundle.getEntry().size() != 2 || resultBundle.getEntry().get(0).getResource() == null diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessesResource.java b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessesResource.java index 2978abb18..c5aeaafcc 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessesResource.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/plugin/ProcessesResource.java @@ -3,7 +3,6 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; -import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -369,9 +368,9 @@ public List getExpectedStatus() case MISSING -> switch (getNewProcessState()) { // conditional create NamingSystem: name=..., Task: identifier=..., others: url=...&version=... - case ACTIVE -> Arrays.asList("200", "201"); + case ACTIVE -> List.of("200", "201"); // conditional create NamingSystem: name=..., Task: identifier=..., others: url=...&version=... - case RETIRED -> Arrays.asList("200", "201"); + case RETIRED -> List.of("200", "201"); default -> throw new RuntimeException( "State change " + getOldProcessState() + " -> " + getNewProcessState() + " not supported"); @@ -379,11 +378,11 @@ public List getExpectedStatus() case NEW -> switch (getNewProcessState()) { // conditional create NamingSystem: name=..., Task: identifier=..., others: url=...&version=... - case ACTIVE -> Arrays.asList("200", "201"); + case ACTIVE -> List.of("200", "201"); // conditional create NamingSystem: name=..., Task: identifier=..., others: url=...&version=... - case DRAFT -> Arrays.asList("200", "201"); + case DRAFT -> List.of("200", "201"); // conditional create NamingSystem: name=..., Task: identifier=..., others: url=...&version=... - case RETIRED -> Arrays.asList("200", "201"); + case RETIRED -> List.of("200", "201"); default -> throw new RuntimeException( "State change " + getOldProcessState() + " -> " + getNewProcessState() + " not supported"); @@ -391,11 +390,11 @@ public List getExpectedStatus() case ACTIVE -> switch (getNewProcessState()) { // standard update with resource id - case DRAFT -> Collections.singletonList("200"); + case DRAFT -> List.of("200"); // standard update with resource id - case RETIRED -> Collections.singletonList("200"); + case RETIRED -> List.of("200"); // standard delete with resource id - case EXCLUDED -> Arrays.asList("200", "204"); + case EXCLUDED -> List.of("200", "204"); default -> throw new RuntimeException( "State change " + getOldProcessState() + " -> " + getNewProcessState() + " not supported"); @@ -403,13 +402,13 @@ public List getExpectedStatus() case DRAFT -> switch (getNewProcessState()) { // standard update with resource id - case ACTIVE -> Collections.singletonList("200"); + case ACTIVE -> List.of("200"); // standard update with resource id - case DRAFT -> Collections.singletonList("200"); + case DRAFT -> List.of("200"); // standard update with resource id - case RETIRED -> Collections.singletonList("200"); + case RETIRED -> List.of("200"); // standard delete with resource id - case EXCLUDED -> Arrays.asList("200", "204"); + case EXCLUDED -> List.of("200", "204"); default -> throw new RuntimeException( "State change " + getOldProcessState() + " -> " + getNewProcessState() + " not supported"); @@ -417,11 +416,11 @@ public List getExpectedStatus() case RETIRED -> switch (getNewProcessState()) { // standard update with resource id - case ACTIVE -> Collections.singletonList("200"); + case ACTIVE -> List.of("200"); // standard update with resource id - case DRAFT -> Collections.singletonList("200"); + case DRAFT -> List.of("200"); // standard delete with resource id - case EXCLUDED -> Arrays.asList("200", "204"); + case EXCLUDED -> List.of("200", "204"); default -> throw new RuntimeException( "State change " + getOldProcessState() + " -> " + getNewProcessState() + " not supported"); @@ -429,11 +428,11 @@ public List getExpectedStatus() case EXCLUDED -> switch (getNewProcessState()) { // conditional create NamingSystem: name=..., Task: identifier=..., others: url=...&version=... - case ACTIVE -> Arrays.asList("200", "201"); + case ACTIVE -> List.of("200", "201"); // conditional create NamingSystem: name=..., Task: identifier=..., others: url=...&version=... - case DRAFT -> Arrays.asList("200", "201"); + case DRAFT -> List.of("200", "201"); // conditional create NamingSystem: name=..., Task: identifier=..., others: url=...&version=... - case RETIRED -> Arrays.asList("200", "201"); + case RETIRED -> List.of("200", "201"); default -> throw new RuntimeException( "State change " + getOldProcessState() + " -> " + getNewProcessState() + " not supported"); diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/service/LocalOrganizationProviderImpl.java b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/service/LocalOrganizationProviderImpl.java index f617b408d..97bab0e24 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/service/LocalOrganizationProviderImpl.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/service/LocalOrganizationProviderImpl.java @@ -2,7 +2,7 @@ import java.time.LocalDateTime; import java.time.temporal.TemporalAmount; -import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -70,9 +70,8 @@ public Optional getLocalOrganization() private Optional doGetLocalOrganization() { Bundle resultBundle = clientProvider.getLocalWebserviceClient().searchWithStrictHandling(Endpoint.class, - Map.of("status", Collections.singletonList("active"), "address", - Collections.singletonList(localEndpointAddress), "_include", - Collections.singletonList("Endpoint:organization"))); + Map.of("status", List.of("active"), "address", List.of(localEndpointAddress), "_include", + List.of("Endpoint:organization"))); if (resultBundle == null || resultBundle.getEntry() == null || resultBundle.getEntry().size() != 2 || resultBundle.getEntry().get(0).getResource() == null diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/spring/config/PluginConfig.java b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/spring/config/PluginConfig.java index d682565e7..6e8a2a3dc 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/spring/config/PluginConfig.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/spring/config/PluginConfig.java @@ -44,12 +44,20 @@ public class PluginConfig public ProcessPluginLoader processPluginLoader() { Path processPluginDirectoryPath = propertiesConfig.getProcessPluginDirectory(); + List explodedPluginDirectories = propertiesConfig.getExplodedPluginDirectories(); if (!Files.isDirectory(processPluginDirectoryPath)) throw new RuntimeException( - "Process plug in directory '" + processPluginDirectoryPath.toString() + "' not readable"); + "Process plugin directory '" + processPluginDirectoryPath.toString() + "' not readable"); - return new ProcessPluginLoaderImpl(processPluginFactories, processPluginDirectoryPath); + explodedPluginDirectories.stream().forEach(p -> + { + if (!Files.isDirectory(p)) + throw new RuntimeException("Exploded process plugin directory '" + p.toString() + "' not readable"); + }); + + return new ProcessPluginLoaderImpl(processPluginFactories, processPluginDirectoryPath, + explodedPluginDirectories); } @Bean diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/spring/config/PluginFactoryConfig.java b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/spring/config/PluginFactoryConfig.java index 2fdba90c2..9d7465d66 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/spring/config/PluginFactoryConfig.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/spring/config/PluginFactoryConfig.java @@ -44,7 +44,9 @@ public class PluginFactoryConfig extends AbstractConfig @Bean public ProcessPluginApiClassLoaderFactory pluginApiClassLoaderFactory() { - return new ProcessPluginApiClassLoaderFactory(); + return new ProcessPluginApiClassLoaderFactory(propertiesConfig.getApiClassPathBaseDirectory(), + propertiesConfig.getApiAllowedBpeClasses(), propertiesConfig.getApiResourcesWithPriority(), + propertiesConfig.getApiAllowedBpeResources()); } @Bean 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 0d87055a7..4f218797f 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 @@ -4,9 +4,13 @@ import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,6 +34,9 @@ public class PropertiesConfig implements InitializingBean { private static final Logger logger = LoggerFactory.getLogger(PropertiesConfig.class); + private static final String API_VERSION_PATTERN_STRING = "v([1-9]+[0-9]*)"; + private static final Pattern API_VERSION_PATTERN = Pattern.compile(API_VERSION_PATTERN_STRING); + // documentation in dev.dsf.bpe.config.BpeDbMigratorConfig @Value("${dev.dsf.bpe.db.url}") private String dbUrl; @@ -111,11 +118,11 @@ public class PropertiesConfig implements InitializingBean private boolean webserviceClientLocalVerbose; @Documentation(description = "Subscription to receive notifications about task resources from the DSF FHIR server") - @Value("${dev.dsf.bpe.fhir.task.subscription.search.parameter:?criteria=Task%3Fstatus%3Drequested&status=active&type=websocket&payload=application/fhir%2Bjson}") + @Value("${dev.dsf.bpe.fhir.task.subscription.search.parameter:?criteria:exact=Task%3Fstatus%3Drequested&status=active&type=websocket&payload=application/fhir%2Bjson}") private String taskSubscriptionSearchParameter; @Documentation(description = "Subscription to receive notifications about questionnaire response resources from the DSF FHIR server") - @Value("${dev.dsf.bpe.fhir.questionnaire.response.subscription.search.parameter:?criteria=QuestionnaireResponse%3Fstatus%3Dcompleted&status=active&type=websocket&payload=application/fhir%2Bjson}") + @Value("${dev.dsf.bpe.fhir.questionnaire.response.subscription.search.parameter:?criteria:exact=QuestionnaireResponse%3Fstatus%3Dcompleted&status=active&type=websocket&payload=application/fhir%2Bjson}") private String questionnaireResponseSubscriptionSearchParameter; @Documentation(description = "Number of retries until a websocket connection can be established with the DSF FHIR server, `-1` means infinite number of retries") @@ -127,9 +134,32 @@ public class PropertiesConfig implements InitializingBean private long websocketRetrySleepMillis; @Documentation(description = "Directory containing the DSF BPE process plugins for deployment on startup of the DSF BPE server", recommendation = "Change only if you don't use the provided directory structure from the installation guide or made changes to tit") - @Value("${dev.dsf.bpe.process.plugin.directroy:process}") + @Value("${dev.dsf.bpe.process.plugin.directory:process}") private String processPluginDirectory; + @Documentation(description = "Directories containing exploded DSF BPE process plugins for deployment on startup of the DSF BPE server; comma or space separated list, YAML block scalars supported", recommendation = "Only for testing") + @Value("#{'${dev.dsf.bpe.process.plugin.exploded:}'.trim().split('(,[ ]?)|(\\n)')}") + private List explodedPluginDirectories; + + @Documentation(description = "Directory containing the DSF BPE process plugin api jar files", recommendation = "Change only during development") + @Value("${dev.dsf.bpe.process.api.directory:api}") + private String apiClassPathBaseDirectory; + + @Documentation(description = "Map with files containing qualified classs names allowed to be loaded by plugins for api versions; map key must match " + + API_VERSION_PATTERN_STRING, recommendation = "Change only during development", example = "{v1: 'some/example.file', v2: 'other.file'}") + @Value("#{${dev.dsf.bpe.process.api.allowed.bpe.classes:{:}}}") + private Map apiAllowedBpeClasses; + + @Documentation(description = "Map with files containing api/plugin resource with priority over bpe resources for plugins for api versions; map key must match " + + API_VERSION_PATTERN_STRING, recommendation = "Change only during development", example = "{v1: 'some/example.file', v2: 'other.file'}") + @Value("#{${dev.dsf.bpe.process.api.resources.with.priority:{:}}}") + private Map apiResourcesWithPriority; + + @Documentation(description = "Map with files containing resources allowed to be loaded by plugins for api versions; map key must match " + + API_VERSION_PATTERN_STRING, recommendation = "Change only during development", example = "{v1: 'some/example.file', v2: 'other.file'}") + @Value("#{${dev.dsf.bpe.process.api.allowed.bpe.resource:{:}}}") + private Map apiAllowedBpeResources; + @Documentation(description = "List of process names that should be excluded from deployment during startup of the DSF BPE server; comma or space separated list, YAML block scalars supported", recommendation = "Only deploy processes that can be started depending on your organization's roles in the Allow-List", example = "dsfdev_updateAllowList|1.0, another_process|x.y") @Value("#{'${dev.dsf.bpe.process.excluded:}'.trim().split('(,[ ]?)|(\\n)')}") private List processExcluded; @@ -299,7 +329,7 @@ public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderCon public void afterPropertiesSet() throws Exception { URL url = new URI(fhirServerBaseUrl).toURL(); - if (!Arrays.asList("http", "https").contains(url.getProtocol())) + if (!List.of("http", "https").contains(url.getProtocol())) { logger.warn("Invalid DSF FHIR server base URL: '{}', URL not starting with 'http://' or 'https://'", fhirServerBaseUrl); @@ -455,6 +485,63 @@ public Path getProcessPluginDirectory() return Paths.get(processPluginDirectory); } + public List getExplodedPluginDirectories() + { + return explodedPluginDirectories.stream().filter(s -> s != null && !s.isBlank()).map(Paths::get).toList(); + } + + public Path getApiClassPathBaseDirectory() + { + return Paths.get(apiClassPathBaseDirectory); + } + + public Map getApiAllowedBpeClasses() + { + return apiAllowedBpeClasses.entrySet().stream().filter(this::hasVersionKeyAndNotBlankValue) + .collect(Collectors.toMap(this::toVersion, this::toPath)); + } + + public Map getApiAllowedBpeResources() + { + return apiAllowedBpeResources.entrySet().stream().filter(this::hasVersionKeyAndNotBlankValue) + .collect(Collectors.toMap(this::toVersion, this::toPath)); + } + + public Map getApiResourcesWithPriority() + { + return apiResourcesWithPriority.entrySet().stream().filter(this::hasVersionKeyAndNotBlankValue) + .collect(Collectors.toMap(this::toVersion, this::toPath)); + } + + private boolean hasVersionKeyAndNotBlankValue(Entry entry) + { + return toVersion(entry) > 0 && toPath(entry) != null; + } + + private int toVersion(Entry entry) + { + if (entry == null || entry.getKey() == null || entry.getKey().isBlank()) + return Integer.MIN_VALUE; + + try + { + Matcher matcher = API_VERSION_PATTERN.matcher(entry.getKey()); + return matcher.matches() ? Integer.parseInt(matcher.group(1)) : Integer.MIN_VALUE; + } + catch (NumberFormatException e) + { + return Integer.MIN_VALUE; + } + } + + private Path toPath(Entry entry) + { + if (entry == null || entry.getValue() == null || entry.getValue().isBlank()) + return null; + else + return Paths.get(entry.getValue()); + } + public List getProcessExcluded() { return Collections.unmodifiableList(processExcluded); diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/spring/config/WebserviceConfig.java b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/spring/config/WebserviceConfig.java index 81af32731..ee9d07b63 100755 --- a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/spring/config/WebserviceConfig.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/spring/config/WebserviceConfig.java @@ -62,7 +62,7 @@ public RootService rootService() @Bean public StaticResourcesService staticResourcesService() { - return new StaticResourcesService(propertiesConfig.getStaticResourceCacheEnabled()); + return new StaticResourcesService("/bpe", propertiesConfig.getStaticResourceCacheEnabled()); } @Bean diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/subscription/ExistingResourceLoaderImpl.java b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/subscription/ExistingResourceLoaderImpl.java index 8acc74678..74a441465 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/subscription/ExistingResourceLoaderImpl.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/subscription/ExistingResourceLoaderImpl.java @@ -3,7 +3,6 @@ import java.sql.SQLException; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -61,11 +60,11 @@ private boolean doReadExistingResources(Map> searchCriteria Optional readLastEventTime = readLastEventTime(); readLastEventTime.ifPresent(lastEventTime -> queryParams.put(PARAM_LAST_UPDATED, - Collections.singletonList("gt" + lastEventTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)))); + List.of("gt" + lastEventTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)))); - queryParams.put(PARAM_COUNT, Collections.singletonList(String.valueOf(RESULT_PAGE_COUNT))); - queryParams.put(PARAM_PAGE, Collections.singletonList("1")); - queryParams.put(PARAM_SORT, Collections.singletonList(PARAM_LAST_UPDATED)); + queryParams.put(PARAM_COUNT, List.of(String.valueOf(RESULT_PAGE_COUNT))); + queryParams.put(PARAM_PAGE, List.of("1")); + queryParams.put(PARAM_SORT, List.of(PARAM_LAST_UPDATED)); UriBuilder builder = UriBuilder.fromPath(resourceName); queryParams.forEach((k, v) -> builder.replaceQueryParam(k, v.toArray())); diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/subscription/QuestionnaireResponseHandler.java b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/subscription/QuestionnaireResponseHandler.java index aa965006d..e7eb69f54 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/subscription/QuestionnaireResponseHandler.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/subscription/QuestionnaireResponseHandler.java @@ -11,6 +11,7 @@ import org.camunda.bpm.engine.repository.ProcessDefinition; import org.camunda.bpm.engine.variable.value.PrimitiveValue; import org.hl7.fhir.r4.model.QuestionnaireResponse; +import org.hl7.fhir.r4.model.QuestionnaireResponse.QuestionnaireResponseStatus; import org.hl7.fhir.r4.model.StringType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,6 +48,12 @@ public void afterPropertiesSet() throws Exception @Override public void onResource(QuestionnaireResponse questionnaireResponse) { + Objects.requireNonNull(questionnaireResponse, "questionnaireResponse"); + + if (!QuestionnaireResponseStatus.COMPLETED.equals(questionnaireResponse.getStatus())) + throw new IllegalArgumentException( + "QuestionnaireResponse.status != " + QuestionnaireResponseStatus.COMPLETED.toCode()); + try { List items = questionnaireResponse.getItem(); diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/subscription/TaskHandler.java b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/subscription/TaskHandler.java index bd6707cde..f30e46113 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/subscription/TaskHandler.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/dev/dsf/bpe/subscription/TaskHandler.java @@ -1,7 +1,6 @@ package dev.dsf.bpe.subscription; import java.util.Collection; -import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; @@ -30,6 +29,7 @@ import org.hl7.fhir.r4.model.StringType; import org.hl7.fhir.r4.model.Task; import org.hl7.fhir.r4.model.Task.ParameterComponent; +import org.hl7.fhir.r4.model.Task.TaskStatus; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; @@ -123,6 +123,9 @@ public void onResource(Task task) Objects.requireNonNull(task, "task"); Objects.requireNonNull(task.getInstantiatesCanonical(), "task.instantiatesCanonical"); + if (!TaskStatus.REQUESTED.equals(task.getStatus())) + throw new IllegalArgumentException("Task.status != " + TaskStatus.REQUESTED.toCode()); + Matcher matcher = INSTANTIATES_CANONICAL_PATTERN.matcher(task.getInstantiatesCanonical()); if (!matcher.matches()) throw new IllegalStateException("InstantiatesCanonical of Task with id " + task.getIdElement().getIdPart() @@ -262,7 +265,7 @@ protected void onMessage(String businessKey, String correlationKey, String proce Objects.requireNonNull(processDefinitionId, "processDefinitionId"); if (variables == null) - variables = Collections.emptyMap(); + variables = Map.of(); if (businessKey == null) { @@ -283,7 +286,7 @@ protected void onMessage(String businessKey, String correlationKey, String proce if (instances.size() + instancesWithAlternativeBusinessKey.size() <= 0) { BpmnModelInstance model = repositoryService.getBpmnModelInstance(processDefinitionId); - Collection startEvents = model == null ? Collections.emptySet() + Collection startEvents = model == null ? List.of() : model.getModelElementsByType(StartEvent.class); Stream startEventMesssageNames = startEvents.stream().flatMap(e -> { 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 00abdace4..b4572c6d7 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 @@ -39,7 +39,7 @@ public ThymeleafTemplateServiceImpl(String serverBaseUrl, Theme theme, boolean c ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver(); resolver.setTemplateMode(TemplateMode.HTML); - resolver.setPrefix("/template/"); + resolver.setPrefix("/bpe/template/"); resolver.setSuffix(".html"); resolver.setCacheable(cacheEnabled); diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/api/v1/allowed-bpe-classes.list b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/api/v1/allowed-bpe-classes.list similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/api/v1/allowed-bpe-classes.list rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/api/v1/allowed-bpe-classes.list diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/api/v1/allowed-bpe-resources.list b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/api/v1/allowed-bpe-resources.list similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/api/v1/allowed-bpe-resources.list rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/api/v1/allowed-bpe-resources.list diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/api/v1/api-resources-with-priority.list b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/api/v1/resources-with-priority.list similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/api/v1/api-resources-with-priority.list rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/api/v1/resources-with-priority.list diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/api/v2/allowed-bpe-classes.list b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/api/v2/allowed-bpe-classes.list similarity index 99% rename from dsf-bpe/dsf-bpe-server/src/main/resources/api/v2/allowed-bpe-classes.list rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/api/v2/allowed-bpe-classes.list index 8bc43a914..cc7c5203a 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/resources/api/v2/allowed-bpe-classes.list +++ b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/api/v2/allowed-bpe-classes.list @@ -82,6 +82,7 @@ org.camunda.bpm.engine.delegate.TaskListener org.camunda.bpm.engine.impl.variable.serializer.PrimitiveValueSerializer org.camunda.bpm.engine.impl.variable.serializer.TypedValueSerializer org.camunda.bpm.engine.impl.variable.serializer.ValueFields +org.camunda.bpm.engine.variable.Variables org.camunda.bpm.engine.variable.impl.type.PrimitiveValueTypeImpl org.camunda.bpm.engine.variable.impl.value.PrimitiveTypeValueImpl org.camunda.bpm.engine.variable.impl.value.UntypedValueImpl diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/api/v2/allowed-bpe-resources.list b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/api/v2/allowed-bpe-resources.list similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/api/v2/allowed-bpe-resources.list rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/api/v2/allowed-bpe-resources.list diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/api/v2/api-resources-with-priority.list b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/api/v2/resources-with-priority.list similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/api/v2/api-resources-with-priority.list rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/api/v2/resources-with-priority.list diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/db/camunda/postgres_engine_7.19.0.sql b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/camunda/postgres_engine_7.19.0.sql similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/db/camunda/postgres_engine_7.19.0.sql rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/camunda/postgres_engine_7.19.0.sql diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/db/camunda/postgres_engine_7.19_to_7.20.sql b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/camunda/postgres_engine_7.19_to_7.20.sql similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/db/camunda/postgres_engine_7.19_to_7.20.sql rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/camunda/postgres_engine_7.19_to_7.20.sql diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/db/camunda/postgres_engine_7.20_to_7.21.sql b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/camunda/postgres_engine_7.20_to_7.21.sql similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/db/camunda/postgres_engine_7.20_to_7.21.sql rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/camunda/postgres_engine_7.20_to_7.21.sql diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/db/camunda/postgres_engine_7.21_to_7.22.sql b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/camunda/postgres_engine_7.21_to_7.22.sql similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/db/camunda/postgres_engine_7.21_to_7.22.sql rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/camunda/postgres_engine_7.21_to_7.22.sql diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/db/camunda/postgres_identity_7.19.0.sql b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/camunda/postgres_identity_7.19.0.sql similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/db/camunda/postgres_identity_7.19.0.sql rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/camunda/postgres_identity_7.19.0.sql diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.camunda_engine.changelog-1.0.0.xml b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.camunda_engine.changelog-1.0.0.xml similarity index 97% rename from dsf-bpe/dsf-bpe-server/src/main/resources/db/db.camunda_engine.changelog-1.0.0.xml rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.camunda_engine.changelog-1.0.0.xml index 6e38c7c62..66a6b3fe7 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.camunda_engine.changelog-1.0.0.xml +++ b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.camunda_engine.changelog-1.0.0.xml @@ -3,10 +3,11 @@ xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.camunda_engine.changelog-1.0.0.xml"> - + GRANT ALL ON TABLE ACT_GE_SCHEMA_LOG TO ${db.liquibase_user}; diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.camunda_engine.changelog-1.3.0.xml b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.camunda_engine.changelog-1.3.0.xml similarity index 68% rename from dsf-bpe/dsf-bpe-server/src/main/resources/db/db.camunda_engine.changelog-1.3.0.xml rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.camunda_engine.changelog-1.3.0.xml index 969939545..aac5c759a 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.camunda_engine.changelog-1.3.0.xml +++ b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.camunda_engine.changelog-1.3.0.xml @@ -3,10 +3,11 @@ xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.camunda_engine.changelog-1.3.0.xml"> - + \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.camunda_engine.changelog-1.5.1.xml b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.camunda_engine.changelog-1.5.1.xml similarity index 68% rename from dsf-bpe/dsf-bpe-server/src/main/resources/db/db.camunda_engine.changelog-1.5.1.xml rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.camunda_engine.changelog-1.5.1.xml index 6994af46a..42cca0b36 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.camunda_engine.changelog-1.5.1.xml +++ b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.camunda_engine.changelog-1.5.1.xml @@ -3,10 +3,11 @@ xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.camunda_engine.changelog-1.5.1.xml"> - + \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.camunda_engine.changelog-1.6.0.xml b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.camunda_engine.changelog-1.6.0.xml similarity index 68% rename from dsf-bpe/dsf-bpe-server/src/main/resources/db/db.camunda_engine.changelog-1.6.0.xml rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.camunda_engine.changelog-1.6.0.xml index c6967db93..c73ac0b05 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.camunda_engine.changelog-1.6.0.xml +++ b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.camunda_engine.changelog-1.6.0.xml @@ -3,10 +3,11 @@ xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.camunda_engine.changelog-1.6.0.xml"> - + \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.camunda_identity.changelog-1.0.0.xml b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.camunda_identity.changelog-1.0.0.xml similarity index 88% rename from dsf-bpe/dsf-bpe-server/src/main/resources/db/db.camunda_identity.changelog-1.0.0.xml rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.camunda_identity.changelog-1.0.0.xml index 0757f226a..d45b6ebc9 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.camunda_identity.changelog-1.0.0.xml +++ b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.camunda_identity.changelog-1.0.0.xml @@ -3,10 +3,11 @@ xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.camunda_identity.changelog-1.0.0.xml"> - + GRANT ALL ON TABLE ACT_ID_GROUP TO ${db.liquibase_user}; diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.changelog.xml b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.changelog.xml new file mode 100644 index 000000000..bb4745933 --- /dev/null +++ b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.changelog.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.create-db-users.changelog-1.0.0.xml b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.create-db-users.changelog-1.0.0.xml similarity index 94% rename from dsf-bpe/dsf-bpe-server/src/main/resources/db/db.create-db-users.changelog-1.0.0.xml rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.create-db-users.changelog-1.0.0.xml index f77af3433..ed94d3759 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.create-db-users.changelog-1.0.0.xml +++ b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.create-db-users.changelog-1.0.0.xml @@ -2,7 +2,8 @@ + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.create-db-users.changelog-1.0.0.xml"> diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.last_event.changelog-1.0.0.xml b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.last_event.changelog-1.0.0.xml similarity index 92% rename from dsf-bpe/dsf-bpe-server/src/main/resources/db/db.last_event.changelog-1.0.0.xml rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.last_event.changelog-1.0.0.xml index 23d272109..70353128f 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.last_event.changelog-1.0.0.xml +++ b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.last_event.changelog-1.0.0.xml @@ -3,7 +3,8 @@ xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.last_event.changelog-1.0.0.xml"> diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.process_plugin_resources.changelog-1.0.0.xml b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.process_plugin_resources.changelog-1.0.0.xml similarity index 96% rename from dsf-bpe/dsf-bpe-server/src/main/resources/db/db.process_plugin_resources.changelog-1.0.0.xml rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.process_plugin_resources.changelog-1.0.0.xml index 9bbf67178..f4c4a9de7 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.process_plugin_resources.changelog-1.0.0.xml +++ b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.process_plugin_resources.changelog-1.0.0.xml @@ -3,7 +3,8 @@ xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.process_plugin_resources.changelog-1.0.0.xml"> diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.process_states.changelog-1.0.0.xml b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.process_states.changelog-1.0.0.xml similarity index 92% rename from dsf-bpe/dsf-bpe-server/src/main/resources/db/db.process_states.changelog-1.0.0.xml rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.process_states.changelog-1.0.0.xml index 52eb4d243..6f5098f71 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.process_states.changelog-1.0.0.xml +++ b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/db/db.process_states.changelog-1.0.0.xml @@ -3,7 +3,8 @@ xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.process_states.changelog-1.0.0.xml"> diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/static/bpmn-viewer-dev.js b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/bpmn-viewer-dev.js similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/static/bpmn-viewer-dev.js rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/bpmn-viewer-dev.js diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/static/bpmn-viewer-prod.js b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/bpmn-viewer-prod.js similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/static/bpmn-viewer-prod.js rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/bpmn-viewer-prod.js diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/static/bpmn-viewer.css b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/bpmn-viewer.css similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/static/bpmn-viewer.css rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/bpmn-viewer.css diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/static/bpmn.js b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/bpmn.js similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/static/bpmn.js rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/bpmn.js diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/static/dsf.css b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/dsf.css similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/static/dsf.css rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/dsf.css diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/static/favicon.svg b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/favicon.svg similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/static/favicon.svg rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/favicon.svg diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/static/favicon_32x32.png b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/favicon_32x32.png similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/static/favicon_32x32.png rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/favicon_32x32.png diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/static/favicon_96x96.png b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/favicon_96x96.png similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/static/favicon_96x96.png rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/favicon_96x96.png diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/static/logo.svg b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/logo.svg similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/static/logo.svg rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/logo.svg diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/static/main.js b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/main.js similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/static/main.js rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/static/main.js diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/template/Process.html b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/template/Process.html similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/template/Process.html rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/template/Process.html diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/template/main.html b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/template/main.html similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/template/main.html rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/template/main.html diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/template/root.html b/dsf-bpe/dsf-bpe-server/src/main/resources/bpe/template/root.html similarity index 100% rename from dsf-bpe/dsf-bpe-server/src/main/resources/template/root.html rename to dsf-bpe/dsf-bpe-server/src/main/resources/bpe/template/root.html diff --git a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.changelog.xml b/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.changelog.xml deleted file mode 100644 index 865d2bd97..000000000 --- a/dsf-bpe/dsf-bpe-server/src/main/resources/db/db.changelog.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/dao/AbstractDaoTest.java b/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/dao/AbstractDaoTest.java index 6d0158a9a..5cc1dc54e 100644 --- a/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/dao/AbstractDaoTest.java +++ b/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/dao/AbstractDaoTest.java @@ -1,5 +1,7 @@ package dev.dsf.bpe.dao; +import javax.sql.DataSource; + import org.apache.commons.dbcp2.BasicDataSource; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -14,13 +16,13 @@ public class AbstractDaoTest extends AbstractDbTest { public static final String DAO_DB_TEMPLATE_NAME = "dao_template"; - protected static BasicDataSource defaultDataSource; - protected static BasicDataSource camundaDataSource; + protected static DataSource defaultDataSource; + protected static DataSource camundaDataSource; @ClassRule public static final PostgreSqlContainerLiquibaseTemplateClassRule liquibaseRule = new PostgreSqlContainerLiquibaseTemplateClassRule( - DockerImageName.parse("postgres:15"), ROOT_USER, "bpe", "bpe_template", CHANGE_LOG_FILE, - CHANGE_LOG_PARAMETERS, true); + DockerImageName.parse("postgres:15"), ROOT_USER, "bpe", "bpe_template", BPE_CHANGE_LOG_FILE, + BPE_CHANGE_LOG_PARAMETERS, true); @Rule public final PostgresTemplateRule templateRule = new PostgresTemplateRule(liquibaseRule); @@ -28,22 +30,22 @@ public class AbstractDaoTest extends AbstractDbTest @BeforeClass public static void beforeClass() throws Exception { - defaultDataSource = createDefaultDataSource(liquibaseRule.getHost(), liquibaseRule.getMappedPort(5432), + defaultDataSource = createBpeDefaultDataSource(liquibaseRule.getHost(), liquibaseRule.getMappedPort(5432), liquibaseRule.getDatabaseName()); - defaultDataSource.start(); + defaultDataSource.unwrap(BasicDataSource.class).start(); - camundaDataSource = createCamundaDataSource(liquibaseRule.getHost(), liquibaseRule.getMappedPort(5432), + camundaDataSource = createBpeCamundaDataSource(liquibaseRule.getHost(), liquibaseRule.getMappedPort(5432), liquibaseRule.getDatabaseName()); - camundaDataSource.start(); + camundaDataSource.unwrap(BasicDataSource.class).start(); } @AfterClass public static void afterClass() throws Exception { if (defaultDataSource != null) - defaultDataSource.close(); + defaultDataSource.unwrap(BasicDataSource.class).close(); if (camundaDataSource != null) - camundaDataSource.close(); + camundaDataSource.unwrap(BasicDataSource.class).close(); } } diff --git a/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/dao/AbstractDbTest.java b/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/dao/AbstractDbTest.java index a2f9b8f9e..7909145b2 100644 --- a/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/dao/AbstractDbTest.java +++ b/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/dao/AbstractDbTest.java @@ -2,10 +2,14 @@ import java.util.Map; +import javax.sql.DataSource; + import org.apache.commons.dbcp2.BasicDataSource; import org.postgresql.Driver; import org.slf4j.bridge.SLF4JBridgeHandler; +import dev.dsf.common.db.DataSourceWithLogger; + public abstract class AbstractDbTest { static @@ -14,50 +18,99 @@ public abstract class AbstractDbTest SLF4JBridgeHandler.install(); } - protected static final String CHANGE_LOG_FILE = "db/db.changelog.xml"; + protected static final boolean LOG_DB_STATEMENTS = true; + + protected static final String BPE_CHANGE_LOG_FILE = "bpe/db/db.changelog.xml"; + + protected static final String BPE_DATABASE_USERS_GROUP = "server_users_group"; + protected static final String BPE_DATABASE_USER = "server_user"; + protected static final String BPE_DATABASE_USER_PASSWORD = "server_user_password"; - protected static final String DATABASE_USERS_GROUP = "server_users_group"; - protected static final String DATABASE_USER = "server_user"; - protected static final String DATABASE_USER_PASSWORD = "server_user_password"; + protected static final String BPE_DATABASE_CAMUNDA_USERS_GROUP = "camunda_users_group"; + protected static final String BPE_DATABASE_CAMUNDA_USER = "camunda_user"; + protected static final String BPE_DATABASE_CAMUNDA_USER_PASSWORD = "camunda_user_password"; - protected static final String DATABASE_CAMUNDA_USERS_GROUP = "camunda_users_group"; - protected static final String DATABASE_CAMUNDA_USER = "camunda_user"; - protected static final String DATABASE_CAMUNDA_USER_PASSWORD = "camunda_user_password"; + protected static final String FHIR_CHANGE_LOG_FILE = "fhir/db/db.changelog.xml"; + + protected static final String FHIR_DATABASE_USERS_GROUP = "server_users_group"; + protected static final String FHIR_DATABASE_USER = "server_user"; + protected static final String FHIR_DATABASE_USER_PASSWORD = "server_user_password"; + + protected static final String FHIR_DATABASE_DELETE_USERS_GROUP = "server_permanent_delete_users_group"; + protected static final String FHIR_DATABASE_DELETE_USER = "server_permanent_delete_user"; + protected static final String FHIR_DATABASE_DELETE_USER_PASSWORD = "server_permanent_delete_user_password"; protected static final String ROOT_USER = "postgres"; - protected static final Map CHANGE_LOG_PARAMETERS = Map.of("db.liquibase_user", ROOT_USER, - "db.server_users_group", DATABASE_USERS_GROUP, "db.server_user", DATABASE_USER, "db.server_user_password", - DATABASE_USER_PASSWORD, "db.camunda_users_group", DATABASE_CAMUNDA_USERS_GROUP, "db.camunda_user", - DATABASE_CAMUNDA_USER, "db.camunda_user_password", DATABASE_CAMUNDA_USER_PASSWORD); + protected static final Map BPE_CHANGE_LOG_PARAMETERS = Map.of("db.liquibase_user", ROOT_USER, + "db.server_users_group", BPE_DATABASE_USERS_GROUP, "db.server_user", BPE_DATABASE_USER, + "db.server_user_password", BPE_DATABASE_USER_PASSWORD, "db.camunda_users_group", + BPE_DATABASE_CAMUNDA_USERS_GROUP, "db.camunda_user", BPE_DATABASE_CAMUNDA_USER, "db.camunda_user_password", + BPE_DATABASE_CAMUNDA_USER_PASSWORD); + + protected static final Map FHIR_CHANGE_LOG_PARAMETERS = Map.of("db.liquibase_user", ROOT_USER, + "db.server_users_group", FHIR_DATABASE_USERS_GROUP, "db.server_user", FHIR_DATABASE_USER, + "db.server_user_password", FHIR_DATABASE_USER_PASSWORD, "db.server_permanent_delete_users_group", + FHIR_DATABASE_DELETE_USERS_GROUP, "db.server_permanent_delete_user", FHIR_DATABASE_DELETE_USER, + "db.server_permanent_delete_user_password", FHIR_DATABASE_DELETE_USER_PASSWORD); + + public static DataSource createBpeDefaultDataSource(String host, int port, String databaseName) + { + BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(Driver.class.getName()); + dataSource.setUrl("jdbc:postgresql://" + host + ":" + port + "/" + databaseName); + dataSource.setUsername(BPE_DATABASE_USER); + dataSource.setPassword(BPE_DATABASE_USER_PASSWORD); + dataSource.setDefaultReadOnly(true); + + dataSource.setTestOnBorrow(true); + dataSource.setValidationQuery("SELECT 1"); + + return new DataSourceWithLogger(LOG_DB_STATEMENTS, dataSource); + } + + public static DataSource createBpeCamundaDataSource(String host, int port, String databaseName) + { + BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(Driver.class.getName()); + dataSource.setUrl("jdbc:postgresql://" + host + ":" + port + "/" + databaseName); + dataSource.setUsername(BPE_DATABASE_CAMUNDA_USER); + dataSource.setPassword(BPE_DATABASE_CAMUNDA_USER_PASSWORD); + dataSource.setDefaultReadOnly(true); + + dataSource.setTestOnBorrow(true); + dataSource.setValidationQuery("SELECT 1"); + + return new DataSourceWithLogger(LOG_DB_STATEMENTS, dataSource); + } - public static BasicDataSource createDefaultDataSource(String host, int port, String databaseName) + public static DataSource createFhirDefaultDataSource(String host, int port, String databaseName) { BasicDataSource dataSource = new BasicDataSource(); dataSource.setDriverClassName(Driver.class.getName()); dataSource.setUrl("jdbc:postgresql://" + host + ":" + port + "/" + databaseName); - dataSource.setUsername(DATABASE_USER); - dataSource.setPassword(DATABASE_USER_PASSWORD); + dataSource.setUsername(FHIR_DATABASE_USER); + dataSource.setPassword(FHIR_DATABASE_USER_PASSWORD); dataSource.setDefaultReadOnly(true); dataSource.setTestOnBorrow(true); dataSource.setValidationQuery("SELECT 1"); - return dataSource; + return new DataSourceWithLogger(LOG_DB_STATEMENTS, dataSource); } - public static BasicDataSource createCamundaDataSource(String host, int port, String databaseName) + public static DataSource createFhirPermanentDeleteDataSource(String host, int port, String databaseName) { BasicDataSource dataSource = new BasicDataSource(); dataSource.setDriverClassName(Driver.class.getName()); dataSource.setUrl("jdbc:postgresql://" + host + ":" + port + "/" + databaseName); - dataSource.setUsername(DATABASE_CAMUNDA_USER); - dataSource.setPassword(DATABASE_CAMUNDA_USER_PASSWORD); + dataSource.setUsername(FHIR_DATABASE_DELETE_USER); + dataSource.setPassword(FHIR_DATABASE_DELETE_USER_PASSWORD); dataSource.setDefaultReadOnly(true); dataSource.setTestOnBorrow(true); dataSource.setValidationQuery("SELECT 1"); - return dataSource; + return new DataSourceWithLogger(LOG_DB_STATEMENTS, dataSource); } } diff --git a/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/integration/AbstractIntegrationTest.java b/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/integration/AbstractIntegrationTest.java new file mode 100644 index 000000000..28fc0ce73 --- /dev/null +++ b/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/integration/AbstractIntegrationTest.java @@ -0,0 +1,556 @@ +package dev.dsf.bpe.integration; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.net.URI; +import java.nio.channels.ServerSocketChannel; +import java.nio.charset.StandardCharsets; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; + +import javax.sql.DataSource; + +import org.apache.commons.dbcp2.BasicDataSource; +import org.eclipse.jetty.ee10.servlet.SessionHandler; +import org.eclipse.jetty.ee10.webapp.WebAppContext; +import org.eclipse.jetty.ee10.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer; +import org.eclipse.jetty.security.SecurityHandler; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.glassfish.jersey.servlet.init.JerseyServletContainerInitializer; +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.Endpoint; +import org.hl7.fhir.r4.model.Extension; +import org.hl7.fhir.r4.model.Organization; +import org.hl7.fhir.r4.model.StringType; +import org.hl7.fhir.r4.model.Subscription; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Rule; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.SpringServletContainerInitializer; +import org.testcontainers.utility.DockerImageName; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.parser.IParser; +import de.hsheilbronn.mi.utils.test.PostgreSqlContainerLiquibaseTemplateClassRule; +import de.hsheilbronn.mi.utils.test.PostgresTemplateRule; +import de.rwh.utils.crypto.CertificateHelper; +import de.rwh.utils.crypto.io.CertificateReader; +import de.rwh.utils.crypto.io.PemIo; +import dev.dsf.bpe.dao.AbstractDbTest; +import dev.dsf.bpe.integration.X509Certificates.ClientCertificate; +import dev.dsf.common.auth.ClientCertificateAuthenticator; +import dev.dsf.common.auth.DelegatingAuthenticator; +import dev.dsf.common.auth.DsfLoginService; +import dev.dsf.common.auth.DsfSecurityHandler; +import dev.dsf.common.auth.StatusPortAuthenticator; +import dev.dsf.common.jetty.JettyServer; +import dev.dsf.fhir.client.FhirWebserviceClient; +import dev.dsf.fhir.client.FhirWebserviceClientJersey; +import dev.dsf.fhir.client.WebsocketClient; +import dev.dsf.fhir.client.WebsocketClientTyrus; +import dev.dsf.fhir.service.ReferenceCleaner; +import dev.dsf.fhir.service.ReferenceCleanerImpl; +import dev.dsf.fhir.service.ReferenceExtractorImpl; +import jakarta.servlet.ServletContainerInitializer; + +public abstract class AbstractIntegrationTest extends AbstractDbTest +{ + @ClassRule + public static final X509Certificates certificates = new X509Certificates(); + + protected static DataSource fhirDefaultDataSource; + protected static DataSource bpeDefaultDataSource; + + @ClassRule + public static final PostgreSqlContainerLiquibaseTemplateClassRule bpeLiquibaseRule = new PostgreSqlContainerLiquibaseTemplateClassRule( + DockerImageName.parse("postgres:15"), ROOT_USER, "bpe", "bpe_template", BPE_CHANGE_LOG_FILE, + BPE_CHANGE_LOG_PARAMETERS, false); + + @Rule + public final PostgresTemplateRule bpeTemplateRule = new PostgresTemplateRule(bpeLiquibaseRule); + + @ClassRule + public static final PostgreSqlContainerLiquibaseTemplateClassRule fhirLiquibaseRule = new PostgreSqlContainerLiquibaseTemplateClassRule( + DockerImageName.parse("postgres:15"), ROOT_USER, "fhir", "fhir_template", FHIR_CHANGE_LOG_FILE, + FHIR_CHANGE_LOG_PARAMETERS, false); + + @Rule + public final PostgresTemplateRule fhirTemplateRule = new PostgresTemplateRule(fhirLiquibaseRule); + + @Rule + public final TestNameLoggerRule testNameLoggerRule = new TestNameLoggerRule(); + + private static final Logger logger = LoggerFactory.getLogger(AbstractIntegrationTest.class); + + protected static final String FHIR_CONTEXT_PATH = "/fhir"; + protected static final String BPE_CONTEXT_PATH = "/bpe"; + + private static final Path EMPTY_PROCESS_DIRECTORY = Paths.get("target", UUID.randomUUID().toString()); + private static final List DIRECTORIES_TO_DELETE = List.of(EMPTY_PROCESS_DIRECTORY); + + private static final Path FHIR_BUNDLE_FILE = Paths.get("target", UUID.randomUUID().toString() + ".xml"); + private static final Path ALLOWED_BPE_CLASSES_LIST_FILE_V1 = Paths.get("target", + UUID.randomUUID().toString() + ".list"); + private static final Path ALLOWED_BPE_CLASSES_LIST_FILE_V2 = Paths.get("target", + UUID.randomUUID().toString() + ".list"); + private static final List FILES_TO_DELETE = List.of(FHIR_BUNDLE_FILE, ALLOWED_BPE_CLASSES_LIST_FILE_V1, + ALLOWED_BPE_CLASSES_LIST_FILE_V2); + + protected static final FhirContext fhirContext = FhirContext.forR4(); + + private static final ReferenceCleaner referenceCleaner = new ReferenceCleanerImpl(new ReferenceExtractorImpl()); + + private static JettyServer fhirServer; + private static FhirWebserviceClient webserviceClient; + private static JettyServer bpeServer; + + @BeforeClass + public static void beforeClass() throws Exception + { + fhirDefaultDataSource = createFhirDefaultDataSource(fhirLiquibaseRule.getHost(), + fhirLiquibaseRule.getMappedPort(5432), fhirLiquibaseRule.getDatabaseName()); + fhirDefaultDataSource.unwrap(BasicDataSource.class).start(); + + ServerSocketChannel fhirStatusConnectorChannel = JettyServer.serverSocketChannel("127.0.0.1"); + ServerSocketChannel fhirApiConnectorChannel = JettyServer.serverSocketChannel("127.0.0.1"); + + logger.info("Creating FHIR Bundle ..."); + createTestBundle(certificates.getClientCertificate(), certificates.getExternalClientCertificate(), + fhirApiConnectorChannel.socket().getLocalPort()); + + String fhirBaseUrl = "https://localhost:" + fhirApiConnectorChannel.socket().getLocalPort() + FHIR_CONTEXT_PATH; + + logger.info("Creating webservice client ..."); + webserviceClient = createWebserviceClient(fhirBaseUrl, certificates.getClientCertificate().getTrustStore(), + certificates.getClientCertificate().getKeyStore(), + certificates.getClientCertificate().getKeyStorePassword(), fhirContext, referenceCleaner); + + logger.info("Starting FHIR Server ..."); + fhirServer = startFhirServer(fhirStatusConnectorChannel, fhirApiConnectorChannel, fhirBaseUrl); + + // --- bpe --- + + // allowed bpe classes override to enable access to classes from dsf-bpe-test-plugin module for v1 test plugins + List allowedBpeClassesV1 = readListFile( + Paths.get("src/main/resources/bpe/api/v1/allowed-bpe-classes.list")); + allowedBpeClassesV1.add("dev.dsf.bpe.test.PluginTest"); + allowedBpeClassesV1.add("dev.dsf.bpe.test.PluginTestExecutor"); + writeListFile(ALLOWED_BPE_CLASSES_LIST_FILE_V1, allowedBpeClassesV1); + + // allowed bpe classes override to enable access to classes from dsf-bpe-test-plugin module for v2 test plugins + List allowedBpeClassesV2 = readListFile( + Paths.get("src/main/resources/bpe/api/v2/allowed-bpe-classes.list")); + allowedBpeClassesV2.add("dev.dsf.bpe.test.PluginTest"); + allowedBpeClassesV2.add("dev.dsf.bpe.test.PluginTestExecutor"); + writeListFile(ALLOWED_BPE_CLASSES_LIST_FILE_V2, allowedBpeClassesV2); + + bpeDefaultDataSource = createBpeDefaultDataSource(bpeLiquibaseRule.getHost(), + bpeLiquibaseRule.getMappedPort(5432), bpeLiquibaseRule.getDatabaseName()); + bpeDefaultDataSource.unwrap(BasicDataSource.class).start(); + + ServerSocketChannel bpeStatusConnectorChannel = JettyServer.serverSocketChannel("127.0.0.1"); + ServerSocketChannel bpeApiConnectorChannel = JettyServer.serverSocketChannel("127.0.0.1"); + + String bpeBaseUrl = "https://localhost:" + bpeApiConnectorChannel.socket().getLocalPort() + BPE_CONTEXT_PATH; + + Files.createDirectories(EMPTY_PROCESS_DIRECTORY); + + logger.info("Starting BPE Server ..."); + bpeServer = startBpeServer(bpeStatusConnectorChannel, bpeApiConnectorChannel, bpeBaseUrl, fhirBaseUrl); + + logger.info("Creating FHIR template database ..."); + fhirLiquibaseRule.createTemplateDatabase(); + + logger.info("Creating BPE template database ..."); + bpeLiquibaseRule.createTemplateDatabase(); + + // wait for bpe to fhir websocket connections + Thread.sleep(Duration.ofSeconds(1)); + } + + private static FhirWebserviceClient createWebserviceClient(String fhirBaseUrl, KeyStore trustStore, + KeyStore keyStore, char[] keyStorePassword, FhirContext fhirContext, ReferenceCleaner referenceCleaner) + { + return new FhirWebserviceClientJersey(fhirBaseUrl, trustStore, keyStore, keyStorePassword, null, null, null, + null, 0, 0, false, "DSF Integration Test Client", fhirContext, referenceCleaner); + } + + protected static FhirWebserviceClient getWebserviceClient() + { + return webserviceClient; + } + + protected static WebsocketClient getWebsocketClient() + { + Bundle bundle = getWebserviceClient().searchWithStrictHandling(Subscription.class, + Map.of("criteria:exact", List.of("Task"), "status", List.of("active"), "type", List.of("websocket"), + "payload", List.of("application/fhir+json"))); + + assertNotNull(bundle); + assertEquals(1, bundle.getTotal()); + assertNotNull(bundle.getEntryFirstRep()); + assertTrue(bundle.getEntryFirstRep().getResource() instanceof Subscription); + + Subscription subscription = (Subscription) bundle.getEntryFirstRep().getResource(); + assertNotNull(subscription.getIdElement()); + assertNotNull(subscription.getIdElement().getIdPart()); + + return createWebsocketClient(fhirServer.getApiPort(), certificates.getClientCertificate().getTrustStore(), + certificates.getClientCertificate().getKeyStore(), + certificates.getClientCertificate().getKeyStorePassword(), subscription.getIdElement().getIdPart()); + } + + private static WebsocketClient createWebsocketClient(int fhirApiPort, KeyStore trustStore, KeyStore keyStore, + char[] keyStorePassword, String subscriptionIdPart) + { + return new WebsocketClientTyrus(() -> + {}, URI.create("wss://localhost:" + fhirApiPort + FHIR_CONTEXT_PATH + "/ws"), trustStore, keyStore, + keyStorePassword, null, null, null, "Integration Test Client", subscriptionIdPart); + } + + protected static IParser newXmlParser() + { + return newParser(fhirContext::newXmlParser); + } + + protected static IParser newJsonParser() + { + return newParser(fhirContext::newJsonParser); + } + + private static IParser newParser(Supplier supplier) + { + IParser p = supplier.get(); + p.setStripVersionsFromReferences(false); + p.setOverrideResourceIdWithBundleEntryFullUrl(false); + p.setPrettyPrint(true); + return p; + } + + private static void createTestBundle(ClientCertificate clientCertificate, + ClientCertificate externalClientCertificate, int fhirApiPort) + { + Path testBundleTemplateFile = Paths.get("src/test/resources/integration/test-bundle.xml"); + + Bundle testBundle = readBundle(testBundleTemplateFile, newXmlParser()); + + Organization organization = (Organization) testBundle.getEntry().get(0).getResource(); + Extension thumbprintExtension = organization + .getExtensionByUrl("http://dsf.dev/fhir/StructureDefinition/extension-certificate-thumbprint"); + thumbprintExtension.setValue(new StringType(clientCertificate.getCertificateSha512ThumbprintHex())); + + Endpoint endpoint = (Endpoint) testBundle.getEntry().get(1).getResource(); + endpoint.setAddress("https://localhost:" + fhirApiPort + "/fhir"); + + Organization externalOrganization = (Organization) testBundle.getEntry().get(2).getResource(); + Extension externalThumbprintExtension = externalOrganization + .getExtensionByUrl("http://dsf.dev/fhir/StructureDefinition/extension-certificate-thumbprint"); + externalThumbprintExtension + .setValue(new StringType(externalClientCertificate.getCertificateSha512ThumbprintHex())); + + writeBundle(FHIR_BUNDLE_FILE, testBundle); + } + + private static Bundle readBundle(Path bundleTemplateFile, IParser parser) + { + try (InputStream in = Files.newInputStream(bundleTemplateFile)) + { + Bundle bundle = parser.parseResource(Bundle.class, in); + return referenceCleaner.cleanReferenceResourcesIfBundle(bundle); + } + catch (IOException e) + { + logger.error("Error while reading bundle from {}", bundleTemplateFile.toString(), e); + throw new RuntimeException(e); + } + } + + private static void writeBundle(Path bundleFile, Bundle bundle) + { + try (OutputStream out = Files.newOutputStream(bundleFile); + OutputStreamWriter writer = new OutputStreamWriter(out)) + { + newXmlParser().encodeResourceToWriter(bundle, writer); + } + catch (IOException e) + { + logger.error("Error while writing bundle to {}", bundleFile.toString(), e); + throw new RuntimeException(e); + } + } + + private static JettyServer startFhirServer(ServerSocketChannel statusConnectorChannel, + ServerSocketChannel apiConnectorChannel, String baseUrl) throws Exception + { + Map initParameters = new HashMap<>(); + initParameters.put("dev.dsf.server.status.port", + Integer.toString(statusConnectorChannel.socket().getLocalPort())); + + initParameters.put("dev.dsf.fhir.db.url", "jdbc:postgresql://" + fhirLiquibaseRule.getHost() + ":" + + fhirLiquibaseRule.getMappedPort(5432) + "/" + fhirLiquibaseRule.getDatabaseName()); + initParameters.put("dev.dsf.fhir.db.user.username", FHIR_DATABASE_USER); + initParameters.put("dev.dsf.fhir.db.user.password", FHIR_DATABASE_USER_PASSWORD); + initParameters.put("dev.dsf.fhir.db.user.permanent.delete.username", FHIR_DATABASE_DELETE_USER); + initParameters.put("dev.dsf.fhir.db.user.permanent.delete.password", FHIR_DATABASE_DELETE_USER_PASSWORD); + + initParameters.put("dev.dsf.fhir.server.base.url", baseUrl); + initParameters.put("dev.dsf.fhir.server.organization.identifier.value", "Test_Organization"); + initParameters.put("dev.dsf.fhir.server.init.bundle", FHIR_BUNDLE_FILE.toString()); + + initParameters.put("dev.dsf.fhir.client.trust.server.certificate.cas", + certificates.getCaCertificateFile().toString()); + initParameters.put("dev.dsf.fhir.client.certificate", certificates.getClientCertificateFile().toString()); + initParameters.put("dev.dsf.fhir.client.certificate.private.key", + certificates.getClientCertificatePrivateKeyFile().toString()); + initParameters.put("dev.dsf.fhir.client.certificate.private.key.password", + String.valueOf(X509Certificates.PASSWORD)); + + initParameters.put("dev.dsf.fhir.server.roleConfig", String.format(""" + - practitioner-test-user: + thumbprint: %s + dsf-role: + - CREATE + - READ + - UPDATE + - DELETE + - SEARCH + - HISTORY + practitioner-role: + - http://dsf.dev/fhir/CodeSystem/practitioner-role|DIC_USER + """, certificates.getPractitionerClientCertificate().getCertificateSha512ThumbprintHex())); + + KeyStore caCertificate = CertificateReader.allFromCer(certificates.getCaCertificateFile()); + PrivateKey privateKey = PemIo.readPrivateKeyFromPem(certificates.getFhirServerCertificatePrivateKeyFile(), + X509Certificates.PASSWORD); + X509Certificate certificate = PemIo.readX509CertificateFromPem(certificates.getFhirServerCertificateFile()); + char[] keyStorePassword = UUID.randomUUID().toString().toCharArray(); + KeyStore serverCertificateKeyStore = CertificateHelper.toJksKeyStore(privateKey, + new Certificate[] { certificate }, UUID.randomUUID().toString(), keyStorePassword); + + Function apiConnector = JettyServer.httpsConnector(apiConnectorChannel, caCertificate, + serverCertificateKeyStore, keyStorePassword, false); + Function statusConnector = JettyServer.statusConnector(statusConnectorChannel); + List> servletContainerInitializers = List.of( + JakartaWebSocketServletContainerInitializer.class, JerseyServletContainerInitializer.class, + SpringServletContainerInitializer.class); + + BiConsumer> securityHandlerConfigurer = (webAppContext, statusPortSupplier) -> + { + SessionHandler sessionHandler = webAppContext.getSessionHandler(); + DsfLoginService dsfLoginService = new DsfLoginService(webAppContext); + + StatusPortAuthenticator statusPortAuthenticator = new StatusPortAuthenticator(statusPortSupplier); + ClientCertificateAuthenticator clientCertificateAuthenticator = new ClientCertificateAuthenticator( + caCertificate); + DelegatingAuthenticator delegatingAuthenticator = new DelegatingAuthenticator(sessionHandler, + statusPortAuthenticator, clientCertificateAuthenticator, null, null, null, null); + + SecurityHandler securityHandler = new DsfSecurityHandler(dsfLoginService, delegatingAuthenticator, null); + securityHandler.setSessionRenewedOnAuthentication(true); + + webAppContext.setSecurityHandler(securityHandler); + }; + + JettyServer server = new JettyServer(apiConnector, statusConnector, "dsf-fhir-server", FHIR_CONTEXT_PATH, + servletContainerInitializers, initParameters, securityHandlerConfigurer); + + server.start(); + + return server; + } + + private static JettyServer startBpeServer(ServerSocketChannel statusConnectorChannel, + ServerSocketChannel apiConnectorChannel, String bpeBaseUrl, String fhirBaseUrl) throws Exception + { + Map initParameters = new HashMap<>(); + initParameters.put("dev.dsf.server.status.port", + Integer.toString(statusConnectorChannel.socket().getLocalPort())); + + initParameters.put("dev.dsf.bpe.db.url", "jdbc:postgresql://" + bpeLiquibaseRule.getHost() + ":" + + bpeLiquibaseRule.getMappedPort(5432) + "/" + bpeLiquibaseRule.getDatabaseName()); + + initParameters.put("dev.dsf.bpe.db.user.username", BPE_DATABASE_USER); + initParameters.put("dev.dsf.bpe.db.user.password", BPE_DATABASE_USER_PASSWORD); + initParameters.put("dev.dsf.bpe.db.user.camunda.username", BPE_DATABASE_CAMUNDA_USER); + initParameters.put("dev.dsf.bpe.db.user.camunda.password", BPE_DATABASE_CAMUNDA_USER_PASSWORD); + + initParameters.put("dev.dsf.bpe.fhir.client.certificate", certificates.getClientCertificateFile().toString()); + initParameters.put("dev.dsf.bpe.fhir.client.certificate.private.key", + certificates.getClientCertificatePrivateKeyFile().toString()); + initParameters.put("dev.dsf.bpe.fhir.client.certificate.private.key.password", + String.valueOf(X509Certificates.PASSWORD)); + initParameters.put("dev.dsf.bpe.fhir.client.trust.server.certificate.cas", + certificates.getCaCertificateFile().toString()); + + initParameters.put("dev.dsf.bpe.server.base.url", bpeBaseUrl); + initParameters.put("dev.dsf.bpe.fhir.server.base.url", fhirBaseUrl); + + initParameters.put("dev.dsf.bpe.process.api.directory", "../dsf-bpe-server-jetty/docker/api"); + initParameters.put("dev.dsf.bpe.process.plugin.directory", EMPTY_PROCESS_DIRECTORY.toString()); + initParameters.put("dev.dsf.bpe.process.plugin.exploded", + "../dsf-bpe-test-plugin-v1/target/classes, ../dsf-bpe-test-plugin-v2/target/classes"); + + initParameters.put("dev.dsf.bpe.process.api.allowed.bpe.classes", + "{v1: '" + ALLOWED_BPE_CLASSES_LIST_FILE_V1 + "', v2: '" + ALLOWED_BPE_CLASSES_LIST_FILE_V2 + "'}"); + + initParameters.put("dev.dsf.proxy.url", "http://proxy:8080"); + initParameters.put("dev.dsf.proxy.username", "proxy_username"); + initParameters.put("dev.dsf.proxy.password", "proxy_password"); + initParameters.put("dev.dsf.proxy.noProxy", "localhost, noproxy:443"); + + KeyStore caCertificate = CertificateReader.allFromCer(certificates.getCaCertificateFile()); + PrivateKey privateKey = PemIo.readPrivateKeyFromPem(certificates.getBpeServerCertificatePrivateKeyFile(), + X509Certificates.PASSWORD); + X509Certificate certificate = PemIo.readX509CertificateFromPem(certificates.getBpeServerCertificateFile()); + char[] keyStorePassword = UUID.randomUUID().toString().toCharArray(); + KeyStore serverCertificateKeyStore = CertificateHelper.toJksKeyStore(privateKey, + new Certificate[] { certificate }, UUID.randomUUID().toString(), keyStorePassword); + + Function apiConnector = JettyServer.httpsConnector(apiConnectorChannel, caCertificate, + serverCertificateKeyStore, keyStorePassword, false); + Function statusConnector = JettyServer.statusConnector(statusConnectorChannel); + List> servletContainerInitializers = Arrays + .asList(JerseyServletContainerInitializer.class, SpringServletContainerInitializer.class); + + BiConsumer> securityHandlerConfigurer = (webAppContext, statusPortSupplier) -> + { + SessionHandler sessionHandler = webAppContext.getSessionHandler(); + DsfLoginService dsfLoginService = new DsfLoginService(webAppContext); + + StatusPortAuthenticator statusPortAuthenticator = new StatusPortAuthenticator(statusPortSupplier); + ClientCertificateAuthenticator clientCertificateAuthenticator = new ClientCertificateAuthenticator( + caCertificate); + DelegatingAuthenticator delegatingAuthenticator = new DelegatingAuthenticator(sessionHandler, + statusPortAuthenticator, clientCertificateAuthenticator, null, null, null, null); + + SecurityHandler securityHandler = new DsfSecurityHandler(dsfLoginService, delegatingAuthenticator, null); + securityHandler.setSessionRenewedOnAuthentication(true); + + webAppContext.setSecurityHandler(securityHandler); + }; + + JettyServer server = new JettyServer(apiConnector, statusConnector, "dsf-bpe-server", BPE_CONTEXT_PATH, + servletContainerInitializers, initParameters, securityHandlerConfigurer); + + server.start(); + + return server; + } + + private static List readListFile(Path file) throws IOException + { + return new ArrayList<>(Files.readAllLines(file)); + } + + private static void writeListFile(Path file, List entries) throws IOException + { + Files.write(file, entries, StandardCharsets.UTF_8); + } + + @AfterClass + public static void afterClass() throws Exception + { + try + { + if (bpeServer != null) + { + logger.info("Stopping BPE Server ..."); + bpeServer.stop(); + } + } + catch (Exception e) + { + logger.error("Error while stopping BPE Server", e); + } + + bpeDefaultDataSource.unwrap(BasicDataSource.class).close(); + + try + { + if (fhirServer != null) + { + logger.info("Stopping FHIR Server ..."); + fhirServer.stop(); + } + } + catch (Exception e) + { + logger.error("Error while stopping FHIR Server", e); + } + + fhirDefaultDataSource.unwrap(BasicDataSource.class).close(); + + logger.info("Deleting files {} ...", FILES_TO_DELETE); + FILES_TO_DELETE.forEach(AbstractIntegrationTest::deleteFile); + + logger.info("Deleting directories {} ...", DIRECTORIES_TO_DELETE); + DIRECTORIES_TO_DELETE.forEach(AbstractIntegrationTest::deleteDirectory); + } + + private static void deleteFile(Path file) + { + try + { + Files.delete(file); + } + catch (IOException e) + { + logger.error("Error while deleting test file {}, error: {}", file.toString(), e.toString()); + } + } + + private static void deleteDirectory(Path directory) + { + try + { + Files.walkFileTree(directory, new SimpleFileVisitor() + { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException + { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException + { + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + }); + } + catch (IOException e) + { + logger.error("Error while deleting directory {}, error: {}", directory.toString(), e.toString()); + } + } +} diff --git a/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/integration/AbstractPluginIntegrationTest.java b/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/integration/AbstractPluginIntegrationTest.java new file mode 100644 index 000000000..70db5e24f --- /dev/null +++ b/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/integration/AbstractPluginIntegrationTest.java @@ -0,0 +1,205 @@ +package dev.dsf.bpe.integration; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.time.Duration; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.BlockingDeque; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import org.hl7.fhir.r4.model.ActivityDefinition; +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.CodeSystem; +import org.hl7.fhir.r4.model.Resource; +import org.hl7.fhir.r4.model.StringType; +import org.hl7.fhir.r4.model.StructureDefinition; +import org.hl7.fhir.r4.model.Task; +import org.hl7.fhir.r4.model.Task.ParameterComponent; +import org.hl7.fhir.r4.model.Task.TaskIntent; +import org.hl7.fhir.r4.model.Task.TaskOutputComponent; +import org.hl7.fhir.r4.model.Task.TaskStatus; +import org.hl7.fhir.r4.model.ValueSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import dev.dsf.fhir.client.WebsocketClient; + +public abstract class AbstractPluginIntegrationTest extends AbstractIntegrationTest +{ + private static final Logger logger = LoggerFactory.getLogger(PluginV1IntegrationTest.class); + + private final Pattern UUID_PATTERN = Pattern + .compile("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"); + + private final String processVersion; + + protected AbstractPluginIntegrationTest(String processVersion) + { + this.processVersion = processVersion; + } + + protected static void verifyProcessPluginResourcesExistForVersion(String version) throws Exception + { + Bundle aBundle = getWebserviceClient().search(ActivityDefinition.class, Map.of("url", + List.of("http://dsf.dev/bpe/Process/test"), "version", List.of(version), "_count", List.of("0"))); + assertNotNull(aBundle); + assertEquals(1, aBundle.getTotal()); + assertEquals(0, aBundle.getEntry().size()); + + Bundle cBundle = getWebserviceClient().search(CodeSystem.class, + Map.of("url", List.of("http://dsf.dev/fhir/CodeSystem/test"), "version", List.of(version))); + assertNotNull(cBundle); + assertEquals(1, cBundle.getTotal()); + assertEquals(1, cBundle.getEntry().size()); + assertNotNull(cBundle.getEntry().get(0).getResource()); + assertTrue(cBundle.getEntry().get(0).getResource() instanceof CodeSystem); + assertEquals(3, ((CodeSystem) cBundle.getEntry().get(0).getResource()).getConcept().size()); + + Bundle sBundle = getWebserviceClient().search(StructureDefinition.class, + Map.of("url", List.of("http://dsf.dev/fhir/StructureDefinition/task-test"), "version", List.of(version), + "_count", List.of("0"))); + assertNotNull(sBundle); + assertEquals(1, sBundle.getTotal()); + assertEquals(0, sBundle.getEntry().size()); + + Bundle vBundle = getWebserviceClient().search(ValueSet.class, Map.of("url", + List.of("http://dsf.dev/fhir/ValueSet/test"), "version", List.of(version), "_count", List.of("0"))); + assertNotNull(vBundle); + assertEquals(1, vBundle.getTotal()); + assertEquals(0, vBundle.getEntry().size()); + } + + protected final void executePluginTest(Task task) throws InterruptedException + { + BlockingDeque events = new LinkedBlockingDeque<>(); + WebsocketClient websocketClient = getWebsocketClient(); + websocketClient.setResourceHandler(events::add, PluginV1IntegrationTest::newJsonParser); + websocketClient.connect(); + + try + { + Task createdTask = getWebserviceClient().create(task); + assertNotNull(createdTask); + assertEquals("1", createdTask.getMeta().getVersionId()); + assertEquals(TaskStatus.REQUESTED, createdTask.getStatus()); + + Resource requested = events.pollFirst(10, TimeUnit.SECONDS); + assertNotNull(requested); + assertTrue(requested instanceof Task); + assertEquals(TaskStatus.REQUESTED, ((Task) requested).getStatus()); + + Resource inProgress = events.pollFirst(10, TimeUnit.SECONDS); + assertNotNull(inProgress); + assertTrue(inProgress instanceof Task); + assertEquals(TaskStatus.INPROGRESS, ((Task) inProgress).getStatus()); + assertEquals(1, ((Task) inProgress).getInput().stream().filter(isBusinessKey()).count()); + + UUID businessKeyInProgress = getBusinessKey((Task) inProgress); + + Resource completed = events.pollFirst(10, TimeUnit.SECONDS); + assertNotNull(completed); + assertTrue(completed instanceof Task); + assertEquals(TaskStatus.COMPLETED, ((Task) completed).getStatus()); + assertEquals(1, ((Task) completed).getInput().stream().filter(isBusinessKey()).count()); + + UUID businessKeyCompleted = getBusinessKey((Task) inProgress); + + assertEquals(businessKeyInProgress, businessKeyCompleted); + + Task readTask = getWebserviceClient().read(Task.class, createdTask.getIdElement().getIdPart()); + assertNotNull(readTask); + assertEquals("3", readTask.getMeta().getVersionId()); + assertEquals(TaskStatus.COMPLETED, readTask.getStatus()); + assertEquals(1, ((Task) completed).getInput().stream().filter(isBusinessKey()).count()); + + UUID businessKeyCompleted2 = getBusinessKey((Task) inProgress); + + assertEquals(businessKeyCompleted, businessKeyCompleted2); + + List testMethodSucceeded = getTestMethodSucceeded(readTask); + List testMethodFailed = getTestMethodFailed(readTask); + + logger.info("Succeeded Tests: {}", testMethodSucceeded); + logger.info("Failed Tests: {}", testMethodFailed); + + assertTrue(testMethodFailed.stream().collect(Collectors.joining(", ", "Failed Tests: [", "]")), + testMethodFailed.isEmpty()); + } + finally + { + // wait for bpe to flush transactions + Thread.sleep(Duration.ofMillis(500)); + + if (websocketClient != null) + websocketClient.disconnect(); + } + } + + protected final Task createTestTask(String testActivity) + { + Task task = new Task(); + task.getMeta().addProfile("http://dsf.dev/fhir/StructureDefinition/task-test|" + processVersion); + task.setInstantiatesCanonical("http://dsf.dev/bpe/Process/test|" + processVersion); + task.setStatus(TaskStatus.REQUESTED); + task.setIntent(TaskIntent.ORDER); + task.setAuthoredOn(new Date()); + task.getRequester().setType("Organization").getIdentifier() + .setSystem("http://dsf.dev/sid/organization-identifier").setValue("Test_Organization"); + task.getRestriction().addRecipient().setType("Organization").getIdentifier() + .setSystem("http://dsf.dev/sid/organization-identifier").setValue("Test_Organization"); + task.addInput().setValue(new StringType("start")).getType().getCodingFirstRep() + .setSystem("http://dsf.dev/fhir/CodeSystem/bpmn-message").setCode("message-name"); + task.addInput().setValue(new StringType(testActivity)).getType().getCodingFirstRep() + .setSystem("http://dsf.dev/fhir/CodeSystem/test").setCode("test-activity"); + return task; + } + + private Predicate isBusinessKey() + { + return c -> "http://dsf.dev/fhir/CodeSystem/bpmn-message".equals(c.getType().getCodingFirstRep().getSystem()) + && "business-key".equals(c.getType().getCodingFirstRep().getCode()) + && c.getValue() instanceof StringType + && UUID_PATTERN.matcher(((StringType) c.getValue()).getValue()).matches(); + } + + private UUID getBusinessKey(Task t) + { + return UUID.fromString(t.getInput().stream().filter(isBusinessKey()).findFirst() + .map(ParameterComponent::getValue).map(v -> ((StringType) v).getValue()).get()); + } + + private Predicate isTestMethodSucceeded() + { + return c -> "http://dsf.dev/fhir/CodeSystem/test".equals(c.getType().getCodingFirstRep().getSystem()) + && "test-method-succeeded".equals(c.getType().getCodingFirstRep().getCode()) + && c.getValue() instanceof StringType; + } + + private List getTestMethodSucceeded(Task t) + { + return t.getOutput().stream().filter(isTestMethodSucceeded()).map(TaskOutputComponent::getValue) + .map(v -> ((StringType) v).getValue()).toList(); + } + + private Predicate isTestMethodFailed() + { + return c -> "http://dsf.dev/fhir/CodeSystem/test".equals(c.getType().getCodingFirstRep().getSystem()) + && "test-method-failed".equals(c.getType().getCodingFirstRep().getCode()) + && c.getValue() instanceof StringType; + } + + private List getTestMethodFailed(Task t) + { + return t.getOutput().stream().filter(isTestMethodFailed()).map(TaskOutputComponent::getValue) + .map(v -> ((StringType) v).getValue()).toList(); + } +} diff --git a/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/integration/PluginV1IntegrationTest.java b/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/integration/PluginV1IntegrationTest.java new file mode 100644 index 000000000..47372705e --- /dev/null +++ b/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/integration/PluginV1IntegrationTest.java @@ -0,0 +1,44 @@ +package dev.dsf.bpe.integration; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class PluginV1IntegrationTest extends AbstractPluginIntegrationTest +{ + private static final String PROCESS_VERSION = "1.0"; + + public PluginV1IntegrationTest() + { + super(PROCESS_VERSION); + } + + @BeforeClass + public static void verifyProcessPluginResourcesExist() throws Exception + { + verifyProcessPluginResourcesExistForVersion(PROCESS_VERSION); + } + + @Test + public void startApiTestProcess() throws Exception + { + executePluginTest(createTestTask("Api")); + } + + @Test + public void startProxyTestProcess() throws Exception + { + executePluginTest(createTestTask("Proxy")); + } + + @Test + public void startOrganizationProviderTestProcess() throws Exception + { + executePluginTest(createTestTask("OrganizationProvider")); + } + + @Test + public void startEndpointProviderTestProcess() throws Exception + { + executePluginTest(createTestTask("EndpointProvider")); + } +} \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/integration/PluginV2IntegrationTest.java b/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/integration/PluginV2IntegrationTest.java new file mode 100644 index 000000000..7bbdc6de9 --- /dev/null +++ b/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/integration/PluginV2IntegrationTest.java @@ -0,0 +1,44 @@ +package dev.dsf.bpe.integration; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class PluginV2IntegrationTest extends AbstractPluginIntegrationTest +{ + private static final String PROCESS_VERSION = "2.0"; + + public PluginV2IntegrationTest() + { + super(PROCESS_VERSION); + } + + @BeforeClass + public static void verifyProcessPluginResourcesExist() throws Exception + { + verifyProcessPluginResourcesExistForVersion(PROCESS_VERSION); + } + + @Test + public void startApiTestProcess() throws Exception + { + executePluginTest(createTestTask("Api")); + } + + @Test + public void startProxyTestProcess() throws Exception + { + executePluginTest(createTestTask("Proxy")); + } + + @Test + public void startOrganizationProviderTestProcess() throws Exception + { + executePluginTest(createTestTask("OrganizationProvider")); + } + + @Test + public void startEndpointProviderTestProcess() throws Exception + { + executePluginTest(createTestTask("EndpointProvider")); + } +} \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/integration/TestNameLoggerRule.java b/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/integration/TestNameLoggerRule.java new file mode 100644 index 000000000..04508e34a --- /dev/null +++ b/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/integration/TestNameLoggerRule.java @@ -0,0 +1,29 @@ +package dev.dsf.bpe.integration; + +import org.junit.rules.TestWatcher; +import org.junit.runner.Description; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TestNameLoggerRule extends TestWatcher +{ + private static final Logger logger = LoggerFactory.getLogger(TestNameLoggerRule.class); + + @Override + protected void starting(Description description) + { + logger.info("Starting {}.{} ...", description.getClassName(), description.getMethodName()); + } + + @Override + protected void succeeded(Description description) + { + logger.info("{}.{} [succeeded]", description.getClassName(), description.getMethodName()); + } + + @Override + protected void failed(Throwable e, Description description) + { + logger.info("{}.{} [failed]", description.getClassName(), description.getMethodName()); + } +} diff --git a/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/integration/X509Certificates.java b/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/integration/X509Certificates.java new file mode 100644 index 000000000..91d9c2911 --- /dev/null +++ b/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/integration/X509Certificates.java @@ -0,0 +1,433 @@ +package dev.dsf.bpe.integration; + +import static de.rwh.utils.crypto.CertificateHelper.DEFAULT_SIGNATURE_ALGORITHM; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; +import java.time.LocalDateTime; +import java.time.Period; +import java.util.List; +import java.util.UUID; + +import org.apache.commons.codec.binary.Hex; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest; +import org.junit.rules.ExternalResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import de.rwh.utils.crypto.CertificateAuthority; +import de.rwh.utils.crypto.CertificateHelper; +import de.rwh.utils.crypto.CertificationRequestBuilder; +import de.rwh.utils.crypto.io.CertificateWriter; +import de.rwh.utils.crypto.io.PemIo; + +public class X509Certificates extends ExternalResource +{ + public static final class ClientCertificate + { + private final X509Certificate certificate; + private final KeyStore trustStore; + private final KeyStore keyStore; + private final char[] keyStorePassword; + + ClientCertificate(X509Certificate certificate, KeyStore trustStore, KeyStore keyStore, char[] keyStorePassword) + { + this.certificate = certificate; + this.trustStore = trustStore; + this.keyStore = keyStore; + this.keyStorePassword = keyStorePassword; + } + + public X509Certificate getCertificate() + { + return certificate; + } + + public KeyStore getTrustStore() + { + return trustStore; + } + + public KeyStore getKeyStore() + { + return keyStore; + } + + public char[] getKeyStorePassword() + { + return keyStorePassword; + } + + public String getCertificateSha512ThumbprintHex() + { + try + { + return Hex.encodeHexString(MessageDigest.getInstance("SHA-512").digest(getCertificate().getEncoded())); + } + catch (CertificateEncodingException | NoSuchAlgorithmException e) + { + logger.error("Error while calculating SHA-512 certificate thumbprint", e); + throw new RuntimeException(e); + } + } + } + + private static final Logger logger = LoggerFactory.getLogger(X509Certificates.class); + private static final BouncyCastleProvider provider = new BouncyCastleProvider(); + private static final int KEY_SIZE = 2048; + public static final char[] PASSWORD = "password".toCharArray(); + + private boolean beforeRun; + + private final X509Certificates parent; + + private ClientCertificate clientCertificate; + private ClientCertificate practitionerClientCertificate; + private ClientCertificate externalClientCertificate; + + private Path caCertificateFile; + private Path bpeServerCertificateFile; + private Path bpeServerCertificatePrivateKeyFile; + private Path fhirServerCertificateFile; + private Path fhirServerCertificatePrivateKeyFile; + private Path clientCertificateFile; + private Path clientCertificatePrivateKeyFile; + private Path externalClientCertificateFile; + private Path externalClientCertificatePrivateKeyFile; + private Path practitionerClientCertificateFile; + private Path practitionerClientCertificatePrivateKeyFile; + + private List filesToDelete; + + public X509Certificates() + { + this(null); + } + + public X509Certificates(X509Certificates parent) + { + this.parent = parent; + } + + private boolean parentBeforeRan() + { + return parent != null && parent.beforeRun; + } + + @Override + protected void before() throws Throwable + { + if (parentBeforeRan()) + logger.debug("X509Certificates created by parent"); + else + createX509Certificates(); + + beforeRun = true; + } + + @Override + protected void after() + { + if (parentBeforeRan()) + logger.debug("X509Certificates will be deleted by parent"); + else + deleteX509Certificates(); + } + + public ClientCertificate getClientCertificate() + { + if (parentBeforeRan()) + return parent.getClientCertificate(); + else + return clientCertificate; + } + + public ClientCertificate getExternalClientCertificate() + { + if (parentBeforeRan()) + return parent.getExternalClientCertificate(); + else + return externalClientCertificate; + } + + public ClientCertificate getPractitionerClientCertificate() + { + if (parentBeforeRan()) + return parent.getPractitionerClientCertificate(); + else + return practitionerClientCertificate; + } + + public Path getCaCertificateFile() + { + if (parentBeforeRan()) + return parent.getCaCertificateFile(); + + return caCertificateFile; + } + + public Path getBpeServerCertificateFile() + { + if (parentBeforeRan()) + return parent.getBpeServerCertificateFile(); + + return bpeServerCertificateFile; + } + + public Path getBpeServerCertificatePrivateKeyFile() + { + if (parentBeforeRan()) + return parent.getBpeServerCertificatePrivateKeyFile(); + + return bpeServerCertificatePrivateKeyFile; + } + + public Path getFhirServerCertificateFile() + { + if (parentBeforeRan()) + return parent.getFhirServerCertificateFile(); + + return fhirServerCertificateFile; + } + + public Path getFhirServerCertificatePrivateKeyFile() + { + if (parentBeforeRan()) + return parent.getFhirServerCertificatePrivateKeyFile(); + + return fhirServerCertificatePrivateKeyFile; + } + + public Path getClientCertificateFile() + { + if (parentBeforeRan()) + return parent.getClientCertificateFile(); + + return clientCertificateFile; + } + + public Path getClientCertificatePrivateKeyFile() + { + if (parentBeforeRan()) + return parent.getClientCertificatePrivateKeyFile(); + + return clientCertificatePrivateKeyFile; + } + + public Path getExternalClientCertificateFile() + { + if (parentBeforeRan()) + return parent.getExternalClientCertificateFile(); + + return externalClientCertificateFile; + } + + public Path getExternalClientCertificatePrivateKeyFile() + { + if (parentBeforeRan()) + return parent.getExternalClientCertificatePrivateKeyFile(); + + return externalClientCertificatePrivateKeyFile; + } + + public Path getPractitionerClientCertificateFile() + { + if (parentBeforeRan()) + return parent.getPractitionerClientCertificateFile(); + + return practitionerClientCertificateFile; + } + + public Path getPractitionerClientCertificatePrivateKeyFile() + { + if (parentBeforeRan()) + return parent.getPractitionerClientCertificatePrivateKeyFile(); + + return practitionerClientCertificatePrivateKeyFile; + } + + private void createX509Certificates() throws InvalidKeyException, NoSuchAlgorithmException, KeyStoreException, + CertificateException, OperatorCreationException, IllegalStateException, IOException, InvalidKeySpecException + { + logger.info("Creating certificates ..."); + + Path caCertificateFile = Paths.get("target", UUID.randomUUID().toString() + ".pem"); + Path bpeServerCertificateFile = Paths.get("target", UUID.randomUUID().toString() + ".pem"); + Path bpeServerCertificatePrivateKeyFile = Paths.get("target", UUID.randomUUID().toString() + ".pem"); + Path fhirServerCertificateFile = Paths.get("target", UUID.randomUUID().toString() + ".pem"); + Path fhirServerCertificatePrivateKeyFile = Paths.get("target", UUID.randomUUID().toString() + ".pem"); + Path clientCertificateFile = Paths.get("target", UUID.randomUUID().toString() + ".pem"); + Path clientCertificatePrivateKeyFile = Paths.get("target", UUID.randomUUID().toString() + ".pem"); + Path externalClientCertificateFile = Paths.get("target", UUID.randomUUID().toString() + ".pem"); + Path externalClientCertificatePrivateKeyFile = Paths.get("target", UUID.randomUUID().toString() + ".pem"); + Path practitionerClientCertificateFile = Paths.get("target", UUID.randomUUID().toString() + ".pem"); + Path practitionerClientCertificatePrivateKeyFile = Paths.get("target", UUID.randomUUID().toString() + ".pem"); + + CertificateAuthority.registerBouncyCastleProvider(); + + CertificateAuthority ca = new CertificateAuthority("DE", null, null, null, null, "test-ca"); + LocalDateTime notBefore = LocalDateTime.now(); + LocalDateTime notAfter = notBefore.plusDays(1); + ca.initialize(notBefore, notAfter, KEY_SIZE, DEFAULT_SIGNATURE_ALGORITHM); + + X509Certificate caCertificate = ca.getCertificate(); + + PemIo.writeX509CertificateToPem(caCertificate, caCertificateFile); + + // -- bpe server + X500Name bpeServerSubject = CertificationRequestBuilder.createSubject("DE", null, null, null, null, + "bpe-server"); + KeyPair bpsServerRsaKeyPair = CertificateHelper.createKeyPair(CertificateHelper.DEFAULT_KEY_ALGORITHM, + KEY_SIZE); + JcaPKCS10CertificationRequest bpeServerRequest = CertificationRequestBuilder + .createServerCertificationRequest(bpeServerSubject, bpsServerRsaKeyPair, null, "localhost"); + + X509Certificate bpeServerCertificate = ca.signWebServerCertificate(bpeServerRequest, Period.ofDays(1)); + + CertificateWriter.toPkcs12(bpeServerCertificateFile, bpsServerRsaKeyPair.getPrivate(), PASSWORD, + bpeServerCertificate, caCertificate, "test-server"); + + PemIo.writeX509CertificateToPem(bpeServerCertificate, bpeServerCertificateFile); + PemIo.writeAes128EncryptedPrivateKeyToPkcs8(provider, bpeServerCertificatePrivateKeyFile, + bpsServerRsaKeyPair.getPrivate(), PASSWORD); + // bpe server -- + + // -- fhir server + X500Name fhirServerSubject = CertificationRequestBuilder.createSubject("DE", null, null, null, null, + "fhir-server"); + KeyPair fhirServerRsaKeyPair = CertificateHelper.createKeyPair(CertificateHelper.DEFAULT_KEY_ALGORITHM, + KEY_SIZE); + JcaPKCS10CertificationRequest fhirServerRequest = CertificationRequestBuilder + .createServerCertificationRequest(fhirServerSubject, fhirServerRsaKeyPair, null, "localhost"); + + X509Certificate fhirServerCertificate = ca.signWebServerCertificate(fhirServerRequest, Period.ofDays(1)); + + CertificateWriter.toPkcs12(fhirServerCertificateFile, fhirServerRsaKeyPair.getPrivate(), PASSWORD, + fhirServerCertificate, caCertificate, "test-server"); + + PemIo.writeX509CertificateToPem(fhirServerCertificate, fhirServerCertificateFile); + PemIo.writeAes128EncryptedPrivateKeyToPkcs8(provider, fhirServerCertificatePrivateKeyFile, + fhirServerRsaKeyPair.getPrivate(), PASSWORD); + // fhir server -- + + // -- client + X500Name clientSubject = CertificationRequestBuilder.createSubject("DE", null, null, null, null, "test-client"); + KeyPair clientRsaKeyPair = CertificateHelper.createKeyPair(CertificateHelper.DEFAULT_KEY_ALGORITHM, KEY_SIZE); + JcaPKCS10CertificationRequest clientRequest = CertificationRequestBuilder + .createClientCertificationRequest(clientSubject, clientRsaKeyPair); + + X509Certificate clientCertificate = ca.signWebClientCertificate(clientRequest, Period.ofDays(1)); + + KeyStore clientKeyStore = CertificateHelper.toPkcs12KeyStore(clientRsaKeyPair.getPrivate(), + new Certificate[] { clientCertificate, caCertificate }, "test-client", PASSWORD); + + PemIo.writeX509CertificateToPem(clientCertificate, clientCertificateFile); + PemIo.writeAes128EncryptedPrivateKeyToPkcs8(provider, clientCertificatePrivateKeyFile, + clientRsaKeyPair.getPrivate(), PASSWORD); + // client -- + + // -- external client + X500Name externalClientSubject = CertificationRequestBuilder.createSubject("DE", null, null, null, null, + "external-client"); + KeyPair externalClientRsaKeyPair = CertificateHelper.createKeyPair(CertificateHelper.DEFAULT_KEY_ALGORITHM, + KEY_SIZE); + JcaPKCS10CertificationRequest externalClientRequest = CertificationRequestBuilder + .createClientCertificationRequest(externalClientSubject, externalClientRsaKeyPair); + + X509Certificate externalClientCertificate = ca.signWebClientCertificate(externalClientRequest, + Period.ofDays(1)); + + KeyStore externalClientKeyStore = CertificateHelper.toPkcs12KeyStore(externalClientRsaKeyPair.getPrivate(), + new Certificate[] { externalClientCertificate, caCertificate }, "external-client", PASSWORD); + + CertificateWriter.toPkcs12(externalClientCertificateFile, externalClientRsaKeyPair.getPrivate(), PASSWORD, + externalClientCertificate, caCertificate, "client"); + + PemIo.writeX509CertificateToPem(externalClientCertificate, externalClientCertificateFile); + PemIo.writeAes128EncryptedPrivateKeyToPkcs8(provider, externalClientCertificatePrivateKeyFile, + externalClientRsaKeyPair.getPrivate(), PASSWORD); + // external client -- + + // -- practitioner client + X500Name practitionerClientSubject = CertificationRequestBuilder.createSubject("DE", null, null, null, null, + "practitioner-client"); + KeyPair practitionerClientRsaKeyPair = CertificateHelper.createKeyPair(CertificateHelper.DEFAULT_KEY_ALGORITHM, + KEY_SIZE); + JcaPKCS10CertificationRequest practitionerClientRequest = CertificationRequestBuilder + .createClientCertificationRequest(practitionerClientSubject, practitionerClientRsaKeyPair, + "practitioner@test.org"); + + X509Certificate practitionerClientCertificate = ca.signWebClientCertificate(practitionerClientRequest, + Period.ofDays(1)); + + KeyStore practitionerClientKeyStore = CertificateHelper.toPkcs12KeyStore( + practitionerClientRsaKeyPair.getPrivate(), + new Certificate[] { practitionerClientCertificate, caCertificate }, "practitioner-client", PASSWORD); + + CertificateWriter.toPkcs12(practitionerClientCertificateFile, practitionerClientRsaKeyPair.getPrivate(), + PASSWORD, practitionerClientCertificate, caCertificate, "client"); + + PemIo.writeX509CertificateToPem(practitionerClientCertificate, practitionerClientCertificateFile); + PemIo.writeAes128EncryptedPrivateKeyToPkcs8(provider, practitionerClientCertificatePrivateKeyFile, + practitionerClientRsaKeyPair.getPrivate(), PASSWORD); + // practitioner client -- + + this.clientCertificate = new ClientCertificate(clientCertificate, + CertificateHelper.extractTrust(clientKeyStore), clientKeyStore, PASSWORD); + this.externalClientCertificate = new ClientCertificate(externalClientCertificate, + CertificateHelper.extractTrust(externalClientKeyStore), externalClientKeyStore, PASSWORD); + this.practitionerClientCertificate = new ClientCertificate(practitionerClientCertificate, + CertificateHelper.extractTrust(practitionerClientKeyStore), practitionerClientKeyStore, PASSWORD); + + this.caCertificateFile = caCertificateFile; + this.bpeServerCertificateFile = bpeServerCertificateFile; + this.bpeServerCertificatePrivateKeyFile = bpeServerCertificatePrivateKeyFile; + this.fhirServerCertificateFile = fhirServerCertificateFile; + this.fhirServerCertificatePrivateKeyFile = fhirServerCertificatePrivateKeyFile; + this.clientCertificateFile = clientCertificateFile; + this.clientCertificatePrivateKeyFile = clientCertificatePrivateKeyFile; + this.externalClientCertificateFile = externalClientCertificateFile; + this.externalClientCertificatePrivateKeyFile = externalClientCertificatePrivateKeyFile; + this.practitionerClientCertificateFile = practitionerClientCertificateFile; + this.practitionerClientCertificatePrivateKeyFile = practitionerClientCertificatePrivateKeyFile; + + filesToDelete = List.of(caCertificateFile, bpeServerCertificateFile, bpeServerCertificatePrivateKeyFile, + fhirServerCertificateFile, fhirServerCertificatePrivateKeyFile, clientCertificateFile, + clientCertificatePrivateKeyFile, externalClientCertificateFile, externalClientCertificatePrivateKeyFile, + practitionerClientCertificateFile, practitionerClientCertificatePrivateKeyFile); + } + + private void deleteX509Certificates() + { + logger.info("Deleting certificate files {} ...", filesToDelete); + filesToDelete.forEach(this::deleteFile); + } + + private void deleteFile(Path file) + { + try + { + Files.delete(file); + } + catch (IOException e) + { + logger.error("Error while deleting certificate file {}, error: {}", file.toString(), e.toString()); + } + } +} diff --git a/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/mail/SmtpMailServiceTest.java b/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/mail/SmtpMailServiceTest.java index 5b6b1e0bb..8274bcecb 100644 --- a/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/mail/SmtpMailServiceTest.java +++ b/dsf-bpe/dsf-bpe-server/src/test/java/dev/dsf/bpe/mail/SmtpMailServiceTest.java @@ -2,7 +2,7 @@ import java.nio.file.Paths; import java.security.KeyStore; -import java.util.Arrays; +import java.util.List; import org.junit.Ignore; import org.junit.Test; @@ -15,25 +15,24 @@ public class SmtpMailServiceTest @Test public void testSend() throws Exception { - new SmtpMailService("from@localhost", Arrays.asList("to@localhost"), "localhost", 1025).send("test subject", + new SmtpMailService("from@localhost", List.of("to@localhost"), "localhost", 1025).send("test subject", "test message"); } @Test public void testSendTo() throws Exception { - new SmtpMailService("from@localhost", Arrays.asList("to@localhost"), "localhost", 1025).send("test subject", + new SmtpMailService("from@localhost", List.of("to@localhost"), "localhost", 1025).send("test subject", "test message", "to-test@localhost"); } @Test public void testSendReplyAndCc() throws Exception { - new SmtpMailService("from@localhost", Arrays.asList("to1@localhost", "to2@localhost"), - Arrays.asList("cc1@localhost", "cc2@localhost"), - Arrays.asList("replyTo1@localhost", "replyTo2@localhost"), false, "localhost", 1025, null, null, null, - null, null, null, null, false, 0, SmtpMailService.DEFAULT_DEBUG_LOG_LOCATION) - .send("test subject", "test message"); + new SmtpMailService("from@localhost", List.of("to1@localhost", "to2@localhost"), + List.of("cc1@localhost", "cc2@localhost"), List.of("replyTo1@localhost", "replyTo2@localhost"), false, + "localhost", 1025, null, null, null, null, null, null, null, false, 0, + SmtpMailService.DEFAULT_DEBUG_LOG_LOCATION).send("test subject", "test message"); } @Test @@ -42,17 +41,17 @@ public void testSendSigned() throws Exception char[] signStorePassword = "password".toCharArray(); KeyStore signStore = CertificateReader.fromPkcs12(Paths.get("cert.p12"), signStorePassword); - new SmtpMailService("from@localhost", Arrays.asList("to@localhost"), null, null, false, "localhost", 1025, null, - null, null, null, null, signStore, signStorePassword, false, 0, - SmtpMailService.DEFAULT_DEBUG_LOG_LOCATION).send("test subject", "test message"); + new SmtpMailService("from@localhost", List.of("to@localhost"), null, null, false, "localhost", 1025, null, null, + null, null, null, signStore, signStorePassword, false, 0, SmtpMailService.DEFAULT_DEBUG_LOG_LOCATION) + .send("test subject", "test message"); } @Test public void testSendViaSmtps() throws Exception { KeyStore trustStore = CertificateReader.allFromCer(Paths.get("cert.pem")); - new SmtpMailService("from@localhost", Arrays.asList("to@localhost"), null, null, true, "localhost", 465, null, - null, trustStore, null, null, null, null, false, 0, SmtpMailService.DEFAULT_DEBUG_LOG_LOCATION) + new SmtpMailService("from@localhost", List.of("to@localhost"), null, null, true, "localhost", 465, null, null, + trustStore, null, null, null, null, false, 0, SmtpMailService.DEFAULT_DEBUG_LOG_LOCATION) .send("test subject", "test message"); } @@ -60,8 +59,8 @@ public void testSendViaSmtps() throws Exception @Test public void testSendViaGmail() throws Exception { - new SmtpMailService("foo@gmail.com", Arrays.asList("foo@gmail.com"), null, null, true, "smtp.gmail.com", 465, - "foo", "password".toCharArray(), null, null, null, null, null, false, 0, + new SmtpMailService("foo@gmail.com", List.of("foo@gmail.com"), null, null, true, "smtp.gmail.com", 465, "foo", + "password".toCharArray(), null, null, null, null, null, false, 0, SmtpMailService.DEFAULT_DEBUG_LOG_LOCATION).send("test subject", "test message"); } diff --git a/dsf-bpe/dsf-bpe-server/src/test/resources/integration/test-bundle.xml b/dsf-bpe/dsf-bpe-server/src/test/resources/integration/test-bundle.xml new file mode 100644 index 000000000..d6e5b923f --- /dev/null +++ b/dsf-bpe/dsf-bpe-server/src/test/resources/integration/test-bundle.xml @@ -0,0 +1,282 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-test-plugin-v1/pom.xml b/dsf-bpe/dsf-bpe-test-plugin-v1/pom.xml new file mode 100644 index 000000000..4d25c2a7e --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v1/pom.xml @@ -0,0 +1,22 @@ + + 4.0.0 + + dsf-bpe-test-plugin-v1 + + + dev.dsf + dsf-bpe-pom + 2.0.0-SNAPSHOT + + + + + dev.dsf + dsf-bpe-test-plugin + + + dev.dsf + dsf-bpe-process-api-v1 + + + \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/TestProcessPluginDefinition.java b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/TestProcessPluginDefinition.java new file mode 100644 index 000000000..b733d60de --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/TestProcessPluginDefinition.java @@ -0,0 +1,55 @@ +package dev.dsf.bpe.test; + +import java.time.LocalDate; +import java.util.List; +import java.util.Map; + +import dev.dsf.bpe.test.spring.config.Config; +import dev.dsf.bpe.v1.ProcessPluginDefinition; + +public class TestProcessPluginDefinition implements ProcessPluginDefinition +{ + public static final String VERSION = "1.0.0.0"; + public static final LocalDate RELEASE_DATE = LocalDate.of(2025, 2, 8); + + @Override + public String getName() + { + return "dsf-process-test"; + } + + @Override + public String getVersion() + { + return VERSION; + } + + @Override + public LocalDate getReleaseDate() + { + return RELEASE_DATE; + } + + @Override + public List getProcessModels() + { + return List.of("bpe/test.bpmn"); + } + + @Override + public List> getSpringConfigurations() + { + return List.of(Config.class); + } + + @Override + public Map> getFhirResourcesByProcessId() + { + var aTest = "fhir/ActivityDefinition/dsf-test.xml"; + var cTest = "fhir/CodeSystem/dsf-test.xml"; + var sTest = "fhir/StructureDefinition/dsf-task-test.xml"; + var vTest = "fhir/ValueSet/dsf-test.xml"; + + return Map.of("dsfdev_test", List.of(aTest, cTest, sTest, vTest)); + } +} diff --git a/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/service/AbstractTest.java b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/service/AbstractTest.java new file mode 100644 index 000000000..2f10bfcea --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/service/AbstractTest.java @@ -0,0 +1,33 @@ +package dev.dsf.bpe.test.service; + +import java.util.function.Consumer; + +import org.camunda.bpm.engine.delegate.BpmnError; +import org.camunda.bpm.engine.delegate.DelegateExecution; +import org.hl7.fhir.r4.model.StringType; + +import dev.dsf.bpe.test.PluginTestExecutor; +import dev.dsf.bpe.v1.ProcessPluginApi; +import dev.dsf.bpe.v1.activity.AbstractServiceDelegate; +import dev.dsf.bpe.v1.variables.Variables; + +public abstract class AbstractTest extends AbstractServiceDelegate +{ + public AbstractTest(ProcessPluginApi api) + { + super(api); + } + + @Override + protected void doExecute(DelegateExecution execution, Variables variables) throws BpmnError, Exception + { + PluginTestExecutor.execute(this, output(variables, "test-method-succeeded"), + output(variables, "test-method-failed"), () -> variables.updateTask(variables.getStartTask())); + } + + private Consumer output(Variables variables, String code) + { + return t -> variables.getStartTask().addOutput( + api.getTaskHelper().createOutput(new StringType(t), "http://dsf.dev/fhir/CodeSystem/test", code)); + } +} diff --git a/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/service/ApiTest.java b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/service/ApiTest.java new file mode 100644 index 000000000..8fd904ce2 --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/service/ApiTest.java @@ -0,0 +1,102 @@ +package dev.dsf.bpe.test.service; + +import static dev.dsf.bpe.test.PluginTestExecutor.expectNotNull; + +import org.camunda.bpm.engine.delegate.BpmnError; +import org.camunda.bpm.engine.delegate.DelegateExecution; + +import dev.dsf.bpe.test.PluginTest; +import dev.dsf.bpe.v1.ProcessPluginApi; +import dev.dsf.bpe.v1.variables.Variables; + +public class ApiTest extends AbstractTest +{ + private DelegateExecution execution; + + public ApiTest(ProcessPluginApi api) + { + super(api); + } + + @Override + protected void doExecute(DelegateExecution execution, Variables variables) throws BpmnError, Exception + { + this.execution = execution; + + super.doExecute(execution, variables); + + this.execution = null; + } + + @PluginTest + public void apiNotNull() throws Exception + { + expectNotNull(api); + } + + @PluginTest + public void apiGetEndpointProviderNotNull() throws Exception + { + expectNotNull(api.getEndpointProvider()); + } + + @PluginTest + public void apiGetFhirContextNotNull() throws Exception + { + expectNotNull(api.getFhirContext()); + } + + @PluginTest + public void apiGetFhirWebserviceClientProviderNotNull() throws Exception + { + expectNotNull(api.getFhirWebserviceClientProvider()); + } + + @PluginTest + public void apiGetMailServiceNotNull() throws Exception + { + expectNotNull(api.getMailService()); + } + + @PluginTest + public void apiGetObjectMapperNotNull() throws Exception + { + expectNotNull(api.getObjectMapper()); + } + + @PluginTest + public void apiGetOrganizationProviderNotNull() throws Exception + { + expectNotNull(api.getOrganizationProvider()); + } + + @PluginTest + public void apiGetProcessAuthorizationHelperNotNull() throws Exception + { + expectNotNull(api.getProcessAuthorizationHelper()); + } + + @PluginTest + public void apiGetProxyConfigNotNull() throws Exception + { + expectNotNull(api.getProxyConfig()); + } + + @PluginTest + public void apiGetReadAccessHelperNotNull() throws Exception + { + expectNotNull(api.getReadAccessHelper()); + } + + @PluginTest + public void apiGetTaskHelperNotNull() throws Exception + { + expectNotNull(api.getTaskHelper()); + } + + @PluginTest + public void apiGetVariablesNotNull() throws Exception + { + expectNotNull(api.getVariables(execution)); + } +} diff --git a/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/service/EndpointProviderTest.java b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/service/EndpointProviderTest.java new file mode 100644 index 000000000..e206d885f --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/service/EndpointProviderTest.java @@ -0,0 +1,902 @@ +package dev.dsf.bpe.test.service; + +import static dev.dsf.bpe.test.PluginTestExecutor.expectNotNull; +import static dev.dsf.bpe.test.PluginTestExecutor.expectSame; +import static dev.dsf.bpe.test.PluginTestExecutor.expectTrue; + +import java.util.List; +import java.util.Optional; + +import org.hl7.fhir.r4.model.Coding; +import org.hl7.fhir.r4.model.Endpoint; +import org.hl7.fhir.r4.model.Identifier; + +import dev.dsf.bpe.test.PluginTest; +import dev.dsf.bpe.v1.ProcessPluginApi; +import dev.dsf.bpe.v1.constants.NamingSystems.EndpointIdentifier; +import dev.dsf.bpe.v1.constants.NamingSystems.OrganizationIdentifier; + +public class EndpointProviderTest extends AbstractTest +{ + private static final String ORGANIZATION_IDENTIFIER_LOCAL_VALUE = "Test_Organization"; + private static final Identifier ORGANIZATION_IDENTIFIER_LOCAL = OrganizationIdentifier + .withValue(ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + private static final String ORGANIZATION_IDENTIFIER_PARENT_VALUE = "Parent_Organization"; + private static final Identifier ORGANIZATION_IDENTIFIER_PARENT = OrganizationIdentifier + .withValue(ORGANIZATION_IDENTIFIER_PARENT_VALUE); + private static final String ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE = "External_Test_Organization"; + private static final Identifier ORGANIZATION_IDENTIFIER_EXTERNAL = OrganizationIdentifier + .withValue(ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE); + + private static final String ENDPOINT_IDENTIFIER_LOCAL_VALUE = "Test_Endpoint"; + private static final Identifier ENDPOINT_IDENTIFIER_LOCAL = EndpointIdentifier + .withValue(ENDPOINT_IDENTIFIER_LOCAL_VALUE); + private static final String ENDPOINT_IDENTIFIER_EXTERNAL_VALUE = "External_Test_Endpoint"; + private static final Identifier ENDPOINT_IDENTIFIER_EXTERNAL = EndpointIdentifier + .withValue(ENDPOINT_IDENTIFIER_EXTERNAL_VALUE); + + private static final String ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE = "not-existing-identifier-value"; + private static final Identifier ORGANIZATION_IDENTIFIER_NOT_EXISTING = OrganizationIdentifier + .withValue(ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE); + private static final String MEMBER_ROLE_NOT_EXISTING_CODE = "not-existing-role"; + private static final Coding MEMBER_ROLE_NOT_EXISTING = new Coding( + "http://dsf.dev/fhir/CodeSystem/organization-role", MEMBER_ROLE_NOT_EXISTING_CODE, null); + private static final Coding MEMBER_ROLE_TTP = new Coding("http://dsf.dev/fhir/CodeSystem/organization-role", "TTP", + null); + private static final Coding MEMBER_ROLE_DIC = new Coding("http://dsf.dev/fhir/CodeSystem/organization-role", "DIC", + null); + + public EndpointProviderTest(ProcessPluginApi api) + { + super(api); + } + + private void testEndpointLocal(Optional oE) + { + expectNotNull(oE); + expectTrue(oE.isPresent()); + + testEndpointLocal(oE.get()); + } + + private void testEndpointExternal(Optional oE) + { + expectNotNull(oE); + expectTrue(oE.isPresent()); + + testEndpointExternal(oE.get()); + } + + private void testEndpointLocal(Endpoint e) + { + testEndpoint(e, () -> expectTrue(e.getAddress().matches("https://localhost:[0-9]+/fhir")), + ENDPOINT_IDENTIFIER_LOCAL_VALUE); + } + + private void testEndpointExternal(Endpoint e) + { + testEndpoint(e, () -> expectSame("https://localhost:80010/fhir", e.getAddress()), + ENDPOINT_IDENTIFIER_EXTERNAL_VALUE); + } + + private void testEndpoint(Endpoint e, Runnable testAddress, String expectedIdentifierValue) + { + expectNotNull(e); + expectNotNull(e.getAddress()); + testAddress.run(); + + List ids = e.getIdentifier(); + expectNotNull(ids); + expectSame(1, ids.size()); + expectNotNull(ids.get(0)); + expectSame(EndpointIdentifier.SID, ids.get(0).getSystem()); + expectSame(expectedIdentifierValue, ids.get(0).getValue()); + } + + private void testEndpointAddressLocal(Optional a) + { + expectNotNull(a); + expectTrue(a.isPresent()); + expectNotNull(a.get()); + expectTrue(a.get().matches("https://localhost:[0-9]+/fhir")); + } + + private void testEndpointAddressExternal(Optional a) + { + expectNotNull(a); + expectTrue(a.isPresent()); + expectNotNull(a.get()); + expectSame("https://localhost:80010/fhir", a.get()); + } + + @PluginTest + public void getLocalEndpointAddress() throws Exception + { + String a = api.getEndpointProvider().getLocalEndpointAddress(); + expectNotNull(a); + expectTrue(a.matches("https://localhost:[0-9]+/fhir")); + } + + @PluginTest + public void getLocalEndpoint() throws Exception + { + Optional e = api.getEndpointProvider().getLocalEndpoint(); + expectNotNull(e); + expectTrue(e.isPresent()); + expectNotNull(e.get()); + expectNotNull(e.get().getAddress()); + expectTrue(e.get().getAddress().matches("https://localhost:[0-9]+/fhir")); + + List ids = e.get().getIdentifier(); + expectNotNull(ids); + expectSame(1, ids.size()); + expectNotNull(ids.get(0)); + expectSame(EndpointIdentifier.SID, ids.get(0).getSystem()); + expectSame(ENDPOINT_IDENTIFIER_LOCAL_VALUE, ids.get(0).getValue()); + } + + @PluginTest + public void getLocalEndpointIdentifier() throws Exception + { + Optional id = api.getEndpointProvider().getLocalEndpointIdentifier(); + expectNotNull(id); + expectTrue(id.isPresent()); + expectNotNull(id.get()); + expectSame(EndpointIdentifier.SID, id.get().getSystem()); + expectSame(ENDPOINT_IDENTIFIER_LOCAL_VALUE, id.get().getValue()); + } + + @PluginTest + public void getLocalEndpointIdentifierValue() throws Exception + { + Optional idV = api.getEndpointProvider().getLocalEndpointIdentifierValue(); + expectNotNull(idV); + expectTrue(idV.isPresent()); + expectNotNull(idV.get()); + expectSame(ENDPOINT_IDENTIFIER_LOCAL_VALUE, idV.get()); + } + + @PluginTest + public void getEndpointByEndpointIdentifierNull() throws Exception + { + Optional e = api.getEndpointProvider().getEndpoint((Identifier) null); + expectNotNull(e); + expectTrue(e.isEmpty()); + } + + @PluginTest + public void getEndpointByEndpointIdentifierNotExisting() throws Exception + { + Optional e = api.getEndpointProvider() + .getEndpoint(EndpointIdentifier.withValue("not-existing-identifier-value")); + expectNotNull(e); + expectTrue(e.isEmpty()); + } + + @PluginTest + public void getEndpointByEndpointIdentifierLocal() throws Exception + { + Optional e = api.getEndpointProvider().getEndpoint(ENDPOINT_IDENTIFIER_LOCAL); + testEndpointLocal(e); + } + + @PluginTest + public void getEndpointByEndpointIdentifierExternal() throws Exception + { + Optional e = api.getEndpointProvider().getEndpoint(ENDPOINT_IDENTIFIER_EXTERNAL); + testEndpointExternal(e); + } + + @PluginTest + public void getEndpointByEndpointIdentifierValueNull() throws Exception + { + Optional e = api.getEndpointProvider().getEndpoint((String) null); + expectNotNull(e); + expectTrue(e.isEmpty()); + } + + @PluginTest + public void getEndpointByEndpointIdentifierValueNotExisting() throws Exception + { + Optional e = api.getEndpointProvider().getEndpoint("not-existing-identifier-value"); + expectNotNull(e); + expectTrue(e.isEmpty()); + } + + @PluginTest + public void getEndpointByEndpointIdentifierValueLocal() throws Exception + { + testEndpointLocal(api.getEndpointProvider().getEndpoint(ENDPOINT_IDENTIFIER_LOCAL_VALUE)); + } + + @PluginTest + public void getEndpointByEndpointIdentifierValueExternal() throws Exception + { + testEndpointExternal(api.getEndpointProvider().getEndpoint(ENDPOINT_IDENTIFIER_EXTERNAL_VALUE)); + } + + @PluginTest + public void getEndpointAddressByEndpointIdentifierNull() throws Exception + { + Optional a = api.getEndpointProvider().getEndpointAddress((Identifier) null); + expectNotNull(a); + expectTrue(a.isEmpty()); + } + + @PluginTest + public void getEndpointAddressByEndpointIdentifierNotExisting() throws Exception + { + Optional a = api.getEndpointProvider() + .getEndpointAddress(EndpointIdentifier.withValue("not-existing-identifier-value")); + expectNotNull(a); + expectTrue(a.isEmpty()); + } + + @PluginTest + public void getEndpointAddressByEndpointIdentifierLocal() throws Exception + { + Optional a = api.getEndpointProvider().getEndpointAddress(ENDPOINT_IDENTIFIER_LOCAL); + testEndpointAddressLocal(a); + } + + @PluginTest + public void getEndpointAddressByEndpointIdentifierExternal() throws Exception + { + Optional a = api.getEndpointProvider().getEndpointAddress(ENDPOINT_IDENTIFIER_EXTERNAL); + testEndpointAddressExternal(a); + } + + @PluginTest + public void getEndpointAddressbyEndpointIdentifierValueNull() throws Exception + { + Optional a = api.getEndpointProvider().getEndpointAddress((String) null); + expectNotNull(a); + expectTrue(a.isEmpty()); + } + + @PluginTest + public void getEndpointAddressbyEndpointIdentifierValueNotExisting() throws Exception + { + Optional a = api.getEndpointProvider().getEndpointAddress("not-existing-identifier-value"); + expectNotNull(a); + expectTrue(a.isEmpty()); + } + + @PluginTest + public void getEndpointAddressbyEndpointIdentifierValueLocal() throws Exception + { + Optional a = api.getEndpointProvider().getEndpointAddress(ENDPOINT_IDENTIFIER_LOCAL_VALUE); + testEndpointAddressLocal(a); + } + + @PluginTest + public void getEndpointAddressbyEndpointIdentifierValueExternal() throws Exception + { + Optional a = api.getEndpointProvider().getEndpointAddress(ENDPOINT_IDENTIFIER_EXTERNAL_VALUE); + testEndpointAddressExternal(a); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNull1() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(null, ORGANIZATION_IDENTIFIER_LOCAL, + MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNull2() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, null, + MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNull3() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_LOCAL, null); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNull4() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty(null, null, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNull5() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, null, + null); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNull6() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(null, ORGANIZATION_IDENTIFIER_LOCAL, + null); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNull7() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty(null, null, null); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting1() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING, + ORGANIZATION_IDENTIFIER_LOCAL, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting2() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_NOT_EXISTING, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting3() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_LOCAL, MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting4() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING, + ORGANIZATION_IDENTIFIER_NOT_EXISTING, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting5() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_NOT_EXISTING, MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting6() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING, + ORGANIZATION_IDENTIFIER_LOCAL, MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting7() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING, + ORGANIZATION_IDENTIFIER_NOT_EXISTING, MEMBER_ROLE_NOT_EXISTING); + } + + private void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(Identifier parentIdentifier, + Identifier memberIdentifier, Coding memberRole) + { + Optional es = api.getEndpointProvider().getEndpoint(parentIdentifier, memberIdentifier, memberRole); + expectNotNull(es); + expectTrue(es.isEmpty()); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleDic() throws Exception + { + testEndpointLocal(api.getEndpointProvider().getEndpoint(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_LOCAL, MEMBER_ROLE_DIC)); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleTtp() throws Exception + { + testEndpointExternal(api.getEndpointProvider().getEndpoint(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_EXTERNAL, MEMBER_ROLE_TTP)); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull1() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty(null, + ORGANIZATION_IDENTIFIER_LOCAL_VALUE, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull2() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, null, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull3() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, ORGANIZATION_IDENTIFIER_LOCAL_VALUE, null); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull4() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty(null, null, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull5() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, null, null); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull6() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty(null, + ORGANIZATION_IDENTIFIER_LOCAL_VALUE, null); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull7() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty(null, null, null); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, ORGANIZATION_IDENTIFIER_LOCAL_VALUE, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting2() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting3() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, ORGANIZATION_IDENTIFIER_LOCAL_VALUE, MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting4() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting5() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting6() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, ORGANIZATION_IDENTIFIER_LOCAL_VALUE, + MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting7() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + MEMBER_ROLE_NOT_EXISTING); + } + + private void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + String parentIdentifierValue, String memberIdentifierValue, Coding memberRole) + { + Optional es = api.getEndpointProvider().getEndpoint(parentIdentifierValue, memberIdentifierValue, + memberRole); + expectNotNull(es); + expectTrue(es.isEmpty()); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleDic() throws Exception + { + testEndpointLocal(api.getEndpointProvider().getEndpoint(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + ORGANIZATION_IDENTIFIER_LOCAL_VALUE, MEMBER_ROLE_DIC)); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleTtp() throws Exception + { + testEndpointExternal(api.getEndpointProvider().getEndpoint(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE, MEMBER_ROLE_TTP)); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNull1() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(null, + ORGANIZATION_IDENTIFIER_LOCAL, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNull2() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + null, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNull3() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_LOCAL, null); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNull4() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(null, null, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNull5() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + null, null); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNull6() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(null, + ORGANIZATION_IDENTIFIER_LOCAL, null); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNull7() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(null, null, null); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting1() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING, ORGANIZATION_IDENTIFIER_LOCAL, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting2() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_NOT_EXISTING, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting3() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_LOCAL, MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting4() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING, ORGANIZATION_IDENTIFIER_NOT_EXISTING, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting5() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_NOT_EXISTING, MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting6() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING, ORGANIZATION_IDENTIFIER_LOCAL, MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting7() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING, ORGANIZATION_IDENTIFIER_NOT_EXISTING, MEMBER_ROLE_NOT_EXISTING); + } + + private void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty( + Identifier parentIdentifier, Identifier memberIdentifier, Coding memberRole) + { + Optional a = api.getEndpointProvider().getEndpointAddress(parentIdentifier, memberIdentifier, + memberRole); + expectNotNull(a); + expectTrue(a.isEmpty()); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleDic() throws Exception + { + testEndpointAddressLocal(api.getEndpointProvider().getEndpointAddress(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_LOCAL, MEMBER_ROLE_DIC)); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleTtp() throws Exception + { + testEndpointAddressExternal(api.getEndpointProvider().getEndpointAddress(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_EXTERNAL, MEMBER_ROLE_TTP)); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull1() throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty(null, + ORGANIZATION_IDENTIFIER_LOCAL_VALUE, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull2() throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, null, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull3() throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, ORGANIZATION_IDENTIFIER_LOCAL_VALUE, null); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull4() throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty(null, null, + MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull5() throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, null, null); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull6() throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty(null, + ORGANIZATION_IDENTIFIER_LOCAL_VALUE, null); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull7() throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty(null, null, null); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting1() + throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, ORGANIZATION_IDENTIFIER_LOCAL_VALUE, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting2() + throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting3() + throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, ORGANIZATION_IDENTIFIER_LOCAL_VALUE, MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting4() + throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting5() + throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting6() + throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, ORGANIZATION_IDENTIFIER_LOCAL_VALUE, + MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting7() + throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + MEMBER_ROLE_NOT_EXISTING); + } + + private void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + String parentIdentifierValue, String memberIdentifierValue, Coding memberRole) + { + Optional a = api.getEndpointProvider().getEndpointAddress(parentIdentifierValue, memberIdentifierValue, + memberRole); + expectNotNull(a); + expectTrue(a.isEmpty()); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleDic() throws Exception + { + testEndpointAddressLocal(api.getEndpointProvider().getEndpointAddress(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + ORGANIZATION_IDENTIFIER_LOCAL_VALUE, MEMBER_ROLE_DIC)); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleTtp() throws Exception + { + testEndpointAddressExternal(api.getEndpointProvider().getEndpointAddress(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE, MEMBER_ROLE_TTP)); + } + + @PluginTest + public void getEndpointsByParentIdentifierAndMemberRoleNull1() throws Exception + { + getEndpointsByParentIdentifierAndMemberRoleExpectEmpty(null, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointsByParentIdentifierAndMemberRoleNull2() throws Exception + { + getEndpointsByParentIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, null); + } + + @PluginTest + public void getEndpointsByParentIdentifierAndMemberRoleNull3() throws Exception + { + getEndpointsByParentIdentifierAndMemberRoleExpectEmpty(null, null); + } + + @PluginTest + public void getEndpointsByParentIdentifierAndMemberRoleNotExisting1() throws Exception + { + getEndpointsByParentIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointsByParentIdentifierAndMemberRoleNotExisting2() throws Exception + { + getEndpointsByParentIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointsByParentIdentifierAndMemberRoleNotExisting3() throws Exception + { + getEndpointsByParentIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING, + MEMBER_ROLE_NOT_EXISTING); + } + + private void getEndpointsByParentIdentifierAndMemberRoleExpectEmpty(Identifier parentOrganizationIdentifier, + Coding memberOrganizationRole) + { + List es = api.getEndpointProvider().getEndpoints(parentOrganizationIdentifier, + memberOrganizationRole); + expectNotNull(es); + expectTrue(es.isEmpty()); + } + + @PluginTest + public void getEndpointsByParentIdentifierAndMemberRoleDic() throws Exception + { + List es = api.getEndpointProvider().getEndpoints(ORGANIZATION_IDENTIFIER_PARENT, MEMBER_ROLE_DIC); + expectNotNull(es); + expectSame(1, es.size()); + testEndpointLocal(es.get(0)); + } + + @PluginTest + public void getEndpointsByParentIdentifierAndMemberRoleTtp() throws Exception + { + List es = api.getEndpointProvider().getEndpoints(ORGANIZATION_IDENTIFIER_PARENT, MEMBER_ROLE_TTP); + expectNotNull(es); + expectSame(1, es.size()); + testEndpointExternal(es.get(0)); + } + + @PluginTest + public void getEndpointsByParentIdentifierValueAndMemberRoleNull1() throws Exception + { + getEndpointsByParentIdentifierValueAndMemberRoleExpectEmpty(null, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointsByParentIdentifierValueAndMemberRoleNull2() throws Exception + { + getEndpointsByParentIdentifierValueAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT_VALUE, null); + } + + @PluginTest + public void getEndpointsByParentIdentifierValueAndMemberRoleNull3() throws Exception + { + getEndpointsByParentIdentifierValueAndMemberRoleExpectEmpty(null, null); + } + + @PluginTest + public void getEndpointsByParentIdentifierValueAndMemberRoleNotExisting1() throws Exception + { + getEndpointsByParentIdentifierValueAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + MEMBER_ROLE_DIC); + } + + @PluginTest + public void getEndpointsByParentIdentifierValueAndMemberRoleNotExisting2() throws Exception + { + getEndpointsByParentIdentifierValueAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointsByParentIdentifierValueAndMemberRoleNotExisting3() throws Exception + { + getEndpointsByParentIdentifierValueAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + MEMBER_ROLE_NOT_EXISTING); + } + + private void getEndpointsByParentIdentifierValueAndMemberRoleExpectEmpty(String parentOrganizationIdentifierValue, + Coding memberOrganizationRole) + { + List es = api.getEndpointProvider().getEndpoints(parentOrganizationIdentifierValue, + memberOrganizationRole); + expectNotNull(es); + expectTrue(es.isEmpty()); + } + + @PluginTest + public void getEndpointsByParentIdentifierValueAndMemberRoleDic() throws Exception + { + List es = api.getEndpointProvider().getEndpoints(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + MEMBER_ROLE_DIC); + expectNotNull(es); + expectSame(1, es.size()); + testEndpointLocal(es.get(0)); + } + + @PluginTest + public void getEndpointsByParentIdentifierValueAndMemberRoleTtp() throws Exception + { + List es = api.getEndpointProvider().getEndpoints(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + MEMBER_ROLE_TTP); + expectNotNull(es); + expectSame(1, es.size()); + testEndpointExternal(es.get(0)); + } +} diff --git a/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/service/OrganizationProviderTest.java b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/service/OrganizationProviderTest.java new file mode 100644 index 000000000..71acf57e1 --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/service/OrganizationProviderTest.java @@ -0,0 +1,375 @@ +package dev.dsf.bpe.test.service; + +import static dev.dsf.bpe.test.PluginTestExecutor.expectNotNull; +import static dev.dsf.bpe.test.PluginTestExecutor.expectSame; +import static dev.dsf.bpe.test.PluginTestExecutor.expectTrue; + +import java.util.List; +import java.util.Optional; + +import org.hl7.fhir.r4.model.Coding; +import org.hl7.fhir.r4.model.Identifier; +import org.hl7.fhir.r4.model.Organization; + +import dev.dsf.bpe.test.PluginTest; +import dev.dsf.bpe.v1.ProcessPluginApi; +import dev.dsf.bpe.v1.constants.NamingSystems.OrganizationIdentifier; + +public class OrganizationProviderTest extends AbstractTest +{ + private static final String ORGANIZATION_IDENTIFIER_LOCAL_VALUE = "Test_Organization"; + private static final Identifier ORGANIZATION_IDENTIFIER_LOCAL = OrganizationIdentifier + .withValue(ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + private static final String ORGANIZATION_IDENTIFIER_PARENT_VALUE = "Parent_Organization"; + private static final Identifier ORGANIZATION_IDENTIFIER_PARENT = OrganizationIdentifier + .withValue(ORGANIZATION_IDENTIFIER_PARENT_VALUE); + private static final String ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE = "External_Test_Organization"; + + private static final String ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE = "not-existing-identifier-value"; + private static final Identifier ORGANIZATION_IDENTIFIER_NOT_EXISTING = OrganizationIdentifier + .withValue(ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE); + private static final String MEMBER_ROLE_NOT_EXISTING_CODE = "not-existing-role"; + private static final Coding MEMBER_ROLE_NOT_EXISTING = new Coding( + "http://dsf.dev/fhir/CodeSystem/organization-role", MEMBER_ROLE_NOT_EXISTING_CODE, null); + private static final Coding MEMBER_ROLE_TTP = new Coding("http://dsf.dev/fhir/CodeSystem/organization-role", "TTP", + null); + private static final Coding MEMBER_ROLE_DIC = new Coding("http://dsf.dev/fhir/CodeSystem/organization-role", "DIC", + null); + + public OrganizationProviderTest(ProcessPluginApi api) + { + super(api); + } + + private void testOrganization(Optional oO, String identifierValue) + { + expectNotNull(oO); + expectTrue(oO.isPresent()); + expectNotNull(oO.get()); + + Optional identifier = OrganizationIdentifier.findFirst(oO); + expectNotNull(identifier); + expectTrue(identifier.isPresent()); + expectSame(identifierValue, identifier.get().getValue()); + } + + private void testOrganization(Organization o, String identifierValue) + { + expectNotNull(o); + + Optional identifier = OrganizationIdentifier.findFirst(o); + expectNotNull(identifier); + expectTrue(identifier.isPresent()); + expectSame(identifierValue, identifier.get().getValue()); + } + + @PluginTest + public void getLocalOrganization() throws Exception + { + Optional oO = api.getOrganizationProvider().getLocalOrganization(); + testOrganization(oO, ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + } + + @PluginTest + public void getLocalOrganizationIdentifier() throws Exception + { + expectNotNull(api.getOrganizationProvider().getLocalOrganizationIdentifier()); + expectTrue(api.getOrganizationProvider().getLocalOrganizationIdentifier().isPresent()); + expectNotNull(api.getOrganizationProvider().getLocalOrganizationIdentifier().get()); + expectSame(ORGANIZATION_IDENTIFIER_LOCAL_VALUE, + api.getOrganizationProvider().getLocalOrganizationIdentifier().get().getValue()); + } + + @PluginTest + public void getLocalOrganizationIdentifierValue() throws Exception + { + expectNotNull(api.getOrganizationProvider().getLocalOrganizationIdentifierValue()); + expectTrue(api.getOrganizationProvider().getLocalOrganizationIdentifierValue().isPresent()); + expectSame(ORGANIZATION_IDENTIFIER_LOCAL_VALUE, + api.getOrganizationProvider().getLocalOrganizationIdentifierValue().get()); + } + + @PluginTest + public void getOrganizationByIdentifierNull() throws Exception + { + Optional oO = api.getOrganizationProvider().getOrganization((Identifier) null); + expectNotNull(oO); + expectTrue(oO.isEmpty()); + } + + @PluginTest + public void getOrganizationByIdentifierNotExisting() throws Exception + { + Optional oO = api.getOrganizationProvider().getOrganization(ORGANIZATION_IDENTIFIER_NOT_EXISTING); + expectNotNull(oO); + expectTrue(oO.isEmpty()); + } + + @PluginTest + public void getOrganizationByIdentifier() throws Exception + { + Optional oO = api.getOrganizationProvider().getOrganization(ORGANIZATION_IDENTIFIER_LOCAL); + testOrganization(oO, ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + } + + @PluginTest + public void getOrganizationByIdentifierValueNull() throws Exception + { + Optional oO = api.getOrganizationProvider().getOrganization((String) null); + expectNotNull(oO); + expectTrue(oO.isEmpty()); + } + + @PluginTest + public void getOrganizationByIdentifierValueNotExisting() throws Exception + { + Optional oO = api.getOrganizationProvider() + .getOrganization(ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE); + expectNotNull(oO); + expectTrue(oO.isEmpty()); + } + + @PluginTest + public void getOrganizationByIdentifierValue() throws Exception + { + Optional oO = api.getOrganizationProvider().getOrganization(ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + testOrganization(oO, ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + } + + @PluginTest + public void getOrganizationsByParentIdentifierNull() throws Exception + { + getOrganizationsByParentIdentifierExpectEmpty(null); + } + + @PluginTest + public void getOrganizationsByParentIdentifierNotExisting() throws Exception + { + getOrganizationsByParentIdentifierExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING); + } + + private void getOrganizationsByParentIdentifierExpectEmpty(Identifier parentIdentifier) + { + List os = api.getOrganizationProvider().getOrganizations(parentIdentifier); + expectNotNull(os); + expectTrue(os.isEmpty()); + } + + @PluginTest + public void getOrganizationsByParentIdentifier() throws Exception + { + List os = api.getOrganizationProvider().getOrganizations(ORGANIZATION_IDENTIFIER_PARENT); + expectNotNull(os); + expectSame(2, os.size()); + + List memberIdentifiers = os.stream().filter(o -> o.getIdentifier().size() == 1) + .map(OrganizationIdentifier::findFirst).flatMap(Optional::stream).map(Identifier::getValue).toList(); + expectSame(2, memberIdentifiers.size()); + + int localOrgIndex = memberIdentifiers.indexOf(ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + expectTrue(localOrgIndex >= 0); + testOrganization(os.get(localOrgIndex), ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + + int externalOrgIndex = memberIdentifiers.indexOf(ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE); + expectTrue(externalOrgIndex >= 0); + testOrganization(os.get(externalOrgIndex), ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueNull() throws Exception + { + getOrganizationsByParentIdentifierValueExpectEmpty(null); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueNotExisting() throws Exception + { + getOrganizationsByParentIdentifierValueExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE); + } + + private void getOrganizationsByParentIdentifierValueExpectEmpty(String parentIdentifierValue) + { + List os = api.getOrganizationProvider().getOrganizations(parentIdentifierValue); + expectNotNull(os); + expectTrue(os.isEmpty()); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValue() throws Exception + { + List os = api.getOrganizationProvider().getOrganizations(ORGANIZATION_IDENTIFIER_PARENT_VALUE); + expectNotNull(os); + expectSame(2, os.size()); + + List memberIdentifiers = os.stream().filter(o -> o.getIdentifier().size() == 1) + .map(OrganizationIdentifier::findFirst).flatMap(Optional::stream).map(Identifier::getValue).toList(); + expectSame(2, memberIdentifiers.size()); + + int localOrgIndex = memberIdentifiers.indexOf(ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + expectTrue(localOrgIndex >= 0); + testOrganization(os.get(localOrgIndex), ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + + int externalOrgIndex = memberIdentifiers.indexOf(ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE); + expectTrue(externalOrgIndex >= 0); + testOrganization(os.get(externalOrgIndex), ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE); + } + + @PluginTest + public void getOrganizationsByParentIdentifierAndMemberRoleNull1() throws Exception + { + getOrganizationsByParentIdentifierAndMemberRoleExpectEmpty(null, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getOrganizationsByParentIdentifierAndMemberRoleNull2() throws Exception + { + getOrganizationsByParentIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, null); + } + + @PluginTest + public void getOrganizationsByParentIdentifierAndMemberRoleNull3() throws Exception + { + getOrganizationsByParentIdentifierAndMemberRoleExpectEmpty(null, null); + } + + @PluginTest + public void getOrganizationsByParentIdentifierAndMemberRoleNotExisting1() throws Exception + { + getOrganizationsByParentIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING, + MEMBER_ROLE_DIC); + } + + @PluginTest + public void getOrganizationsByParentIdentifierAndMemberRoleNotExisting2() throws Exception + { + getOrganizationsByParentIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getOrganizationsByParentIdentifierAndMemberRoleNotExisting3() throws Exception + { + getOrganizationsByParentIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING, + MEMBER_ROLE_NOT_EXISTING); + } + + private void getOrganizationsByParentIdentifierAndMemberRoleExpectEmpty(Identifier parentIdentifier, + Coding memberRole) + { + List os = api.getOrganizationProvider().getOrganizations(parentIdentifier, memberRole); + expectNotNull(os); + expectTrue(os.isEmpty()); + } + + @PluginTest + public void getOrganizationsByParentIdentifierAndMemberRoleDic() throws Exception + { + getOrganizationsByParentIdentifierAndMemberRoleExpectNotEmpty(ORGANIZATION_IDENTIFIER_PARENT, MEMBER_ROLE_DIC, + ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + } + + @PluginTest + public void getOrganizationsByParentIdentifierAndMemberRoleTtp() throws Exception + { + getOrganizationsByParentIdentifierAndMemberRoleExpectNotEmpty(ORGANIZATION_IDENTIFIER_PARENT, MEMBER_ROLE_TTP, + ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE); + } + + private void getOrganizationsByParentIdentifierAndMemberRoleExpectNotEmpty(Identifier parentIdentifier, + Coding memberRole, String expectedOrganizationIdentifierValue) + { + List os = api.getOrganizationProvider().getOrganizations(parentIdentifier, memberRole); + expectNotNull(os); + expectSame(1, os.size()); + testOrganization(os.get(0), expectedOrganizationIdentifierValue); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueAndMemberRoleNull1() throws Exception + { + getOrganizationsByParentIdentifierValueAndMemberRoleExpectEmpty(null, MEMBER_ROLE_DIC); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueAndMemberRoleNull2() throws Exception + { + getOrganizationsByParentIdentifierValueAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT_VALUE, null); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueAndMemberRoleNull3() throws Exception + { + getOrganizationsByParentIdentifierValueAndMemberRoleExpectEmpty(null, null); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueAndMemberRoleNotExisting1() throws Exception + { + getOrganizationsByParentIdentifierValueAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + MEMBER_ROLE_DIC); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueAndMemberRoleNotExisting2() throws Exception + { + getOrganizationsByParentIdentifierValueAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueAndMemberRoleNotExisting3() throws Exception + { + getOrganizationsByParentIdentifierValueAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + MEMBER_ROLE_NOT_EXISTING); + } + + private void getOrganizationsByParentIdentifierValueAndMemberRoleExpectEmpty(String parentIdentifierValue, + Coding memberRole) + { + List os = api.getOrganizationProvider().getOrganizations(parentIdentifierValue, memberRole); + expectNotNull(os); + expectTrue(os.isEmpty()); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueAndMemberRoleDic() throws Exception + { + getOrganizationsByParentIdentifierValueAndMemberRoleExpectNotEmpty(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + MEMBER_ROLE_DIC, ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueAndMemberRoleTtp() throws Exception + { + getOrganizationsByParentIdentifierValueAndMemberRoleExpectNotEmpty(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + MEMBER_ROLE_TTP, ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE); + } + + private void getOrganizationsByParentIdentifierValueAndMemberRoleExpectNotEmpty(String parentIdentifierValue, + Coding memberRole, String expectedOrganizationIdentifierValue) + { + List os = api.getOrganizationProvider().getOrganizations(parentIdentifierValue, memberRole); + expectNotNull(os); + expectSame(1, os.size()); + testOrganization(os.get(0), expectedOrganizationIdentifierValue); + } + + @PluginTest + public void getRemoteOrganizations() throws Exception + { + List os = api.getOrganizationProvider().getRemoteOrganizations(); + expectSame(2, os.size()); + + List oIdentifiers = os.stream().filter(o -> o.getIdentifier().size() == 1) + .map(OrganizationIdentifier::findFirst).flatMap(Optional::stream).map(Identifier::getValue).toList(); + expectSame(2, oIdentifiers.size()); + + int parentOrgIndex = oIdentifiers.indexOf(ORGANIZATION_IDENTIFIER_PARENT_VALUE); + expectTrue(parentOrgIndex >= 0); + testOrganization(os.get(parentOrgIndex), ORGANIZATION_IDENTIFIER_PARENT_VALUE); + + int externalOrgIndex = oIdentifiers.indexOf(ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE); + expectTrue(externalOrgIndex >= 0); + testOrganization(os.get(externalOrgIndex), ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE); + } +} diff --git a/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/service/ProxyTest.java b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/service/ProxyTest.java new file mode 100644 index 000000000..04aa72a10 --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/service/ProxyTest.java @@ -0,0 +1,70 @@ +package dev.dsf.bpe.test.service; + +import static dev.dsf.bpe.test.PluginTestExecutor.expectException; +import static dev.dsf.bpe.test.PluginTestExecutor.expectFalse; +import static dev.dsf.bpe.test.PluginTestExecutor.expectNotNull; +import static dev.dsf.bpe.test.PluginTestExecutor.expectSame; +import static dev.dsf.bpe.test.PluginTestExecutor.expectTrue; + +import dev.dsf.bpe.test.PluginTest; +import dev.dsf.bpe.v1.ProcessPluginApi; + +public class ProxyTest extends AbstractTest +{ + public ProxyTest(ProcessPluginApi api) + { + super(api); + } + + @PluginTest + public void isEnabled() throws Exception + { + expectTrue(api.getProxyConfig().isEnabled()); + } + + @PluginTest + public void getNoProxyUrls() throws Exception + { + expectNotNull(api.getProxyConfig().getNoProxyUrls()); + expectSame(2, api.getProxyConfig().getNoProxyUrls().size()); + expectTrue(api.getProxyConfig().getNoProxyUrls().contains("localhost")); + expectTrue(api.getProxyConfig().getNoProxyUrls().contains("noproxy:443")); + } + + @PluginTest + public void getPassword() throws Exception + { + expectNotNull(api.getProxyConfig().getPassword()); + expectSame("proxy_password".toCharArray(), api.getProxyConfig().getPassword()); + } + + @PluginTest + public void getUrl() throws Exception + { + expectNotNull(api.getProxyConfig().getUrl()); + expectSame("http://proxy:8080", api.getProxyConfig().getUrl()); + } + + @PluginTest + public void getUsername() throws Exception + { + expectNotNull(api.getProxyConfig().getUsername()); + expectSame("proxy_username", api.getProxyConfig().getUsername()); + } + + @PluginTest + public void isNotProxyUrl() throws Exception + { + expectTrue(api.getProxyConfig().isNoProxyUrl("https://localhost")); + expectTrue(api.getProxyConfig().isNoProxyUrl("http://localhost")); + expectTrue(api.getProxyConfig().isNoProxyUrl("http://localhost:8080")); + expectException(IllegalArgumentException.class, () -> api.getProxyConfig().isNoProxyUrl("localhost:1234")); + expectException(IllegalArgumentException.class, () -> api.getProxyConfig().isNoProxyUrl("ftp://localhost")); + + expectTrue(api.getProxyConfig().isNoProxyUrl("https://noproxy")); + expectFalse(api.getProxyConfig().isNoProxyUrl("http://noproxy")); + expectFalse(api.getProxyConfig().isNoProxyUrl("http://noproxy:8080")); + + expectFalse(api.getProxyConfig().isNoProxyUrl("foo")); + } +} diff --git a/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/service/TestActivitySelector.java b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/service/TestActivitySelector.java new file mode 100644 index 000000000..5aed4698d --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/service/TestActivitySelector.java @@ -0,0 +1,24 @@ +package dev.dsf.bpe.test.service; + +import org.camunda.bpm.engine.delegate.BpmnError; +import org.camunda.bpm.engine.delegate.DelegateExecution; + +import dev.dsf.bpe.v1.ProcessPluginApi; +import dev.dsf.bpe.v1.activity.AbstractServiceDelegate; +import dev.dsf.bpe.v1.variables.Variables; + +public class TestActivitySelector extends AbstractServiceDelegate +{ + public TestActivitySelector(ProcessPluginApi api) + { + super(api); + } + + @Override + protected void doExecute(DelegateExecution execution, Variables variables) throws BpmnError, Exception + { + String testActivity = api.getTaskHelper().getFirstInputParameterStringValue(variables.getStartTask(), + "http://dsf.dev/fhir/CodeSystem/test", "test-activity").get(); + variables.setString("testActivity", testActivity); + } +} diff --git a/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/spring/config/Config.java b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/spring/config/Config.java new file mode 100644 index 000000000..ddd43bf2a --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/java/dev/dsf/bpe/test/spring/config/Config.java @@ -0,0 +1,56 @@ +package dev.dsf.bpe.test.spring.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; + +import dev.dsf.bpe.test.service.ApiTest; +import dev.dsf.bpe.test.service.EndpointProviderTest; +import dev.dsf.bpe.test.service.OrganizationProviderTest; +import dev.dsf.bpe.test.service.ProxyTest; +import dev.dsf.bpe.test.service.TestActivitySelector; +import dev.dsf.bpe.v1.ProcessPluginApi; + +@Configuration +public class Config +{ + @Autowired + private ProcessPluginApi api; + + @Bean + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public TestActivitySelector testActivitySelector() + { + return new TestActivitySelector(api); + } + + @Bean + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public ProxyTest proxyTest() + { + return new ProxyTest(api); + } + + @Bean + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public ApiTest apiTest() + { + return new ApiTest(api); + } + + @Bean + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public OrganizationProviderTest organizationProviderTest() + { + return new OrganizationProviderTest(api); + } + + @Bean + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public EndpointProviderTest endpointProviderTest() + { + return new EndpointProviderTest(api); + } +} diff --git a/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/resources/META-INF/services/dev.dsf.bpe.v1.ProcessPluginDefinition b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/resources/META-INF/services/dev.dsf.bpe.v1.ProcessPluginDefinition new file mode 100644 index 000000000..7e9e3d00a --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/resources/META-INF/services/dev.dsf.bpe.v1.ProcessPluginDefinition @@ -0,0 +1 @@ +dev.dsf.bpe.test.TestProcessPluginDefinition \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/resources/bpe/test.bpmn b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/resources/bpe/test.bpmn new file mode 100644 index 000000000..2a4aae6fc --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/resources/bpe/test.bpmn @@ -0,0 +1,153 @@ + + + + + Flow_112zq99 + + + + Flow_0iy74da + Flow_1mkx5o3 + + + Flow_14rzc0j + Flow_08zzudo + + + Flow_0a1kwg9 + + + Flow_112zq99 + Flow_1bqddk1 + + + Flow_1bqddk1 + Flow_14rzc0j + Flow_0iy74da + Flow_1h0pa8u + Flow_1hhwby8 + + + + ${testActivity == 'Proxy'} + + + + ${testActivity == 'Api'} + + + Flow_08zzudo + Flow_1mkx5o3 + Flow_0usx9io + Flow_1bn9gvv + Flow_0a1kwg9 + + + + + + Flow_1h0pa8u + Flow_0usx9io + + + ${testActivity == 'OrganizationProvider'} + + + + Flow_1hhwby8 + Flow_1bn9gvv + + + ${testActivity == 'EndpointProvider'} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/resources/fhir/ActivityDefinition/dsf-test.xml b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/resources/fhir/ActivityDefinition/dsf-test.xml new file mode 100644 index 000000000..98139eeb8 --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/resources/fhir/ActivityDefinition/dsf-test.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <subtitle value="Test Process" /> + <!-- status managed by bpe --> + <status value="unknown" /> + <experimental value="false" /> + <!-- date managed by bpe --> + <date value="#{date}" /> + <publisher value="DSF" /> + <description value="Test process" /> + <kind value="Task" /> +</ActivityDefinition> \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/resources/fhir/CodeSystem/dsf-test.xml b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/resources/fhir/CodeSystem/dsf-test.xml new file mode 100644 index 000000000..ed9153da3 --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/resources/fhir/CodeSystem/dsf-test.xml @@ -0,0 +1,39 @@ +<CodeSystem xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <url value="http://dsf.dev/fhir/CodeSystem/test" /> + <!-- version managed by bpe --> + <version value="#{version}" /> + <name value="DSF_Test" /> + <title value="DSF Test" /> + <!-- status managed by bpe --> + <status value="unknown" /> + <experimental value="false" /> + <!-- date managed by bpe --> + <date value="#{date}" /> + <publisher value="DSF" /> + <description value="CodeSystem for process plugin integration testing" /> + <caseSensitive value="true" /> + <hierarchyMeaning value="grouped-by" /> + <versionNeeded value="false" /> + <content value="complete" /> + <concept> + <code value="test-activity" /> + <display value="Test Activity" /> + <definition value="Name of test activity to execute" /> + </concept> + <concept> + <code value="test-method-succeeded" /> + <display value="Test Method Succeeded" /> + <definition value="Name of succeeded test method" /> + </concept> + <concept> + <code value="test-method-failed" /> + <display value="Test Method Failed" /> + <definition value="Name of failed test method" /> + </concept> +</CodeSystem> \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/resources/fhir/StructureDefinition/dsf-task-test.xml b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/resources/fhir/StructureDefinition/dsf-task-test.xml new file mode 100644 index 000000000..3856429b5 --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/resources/fhir/StructureDefinition/dsf-task-test.xml @@ -0,0 +1,145 @@ +<StructureDefinition xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <url value="http://dsf.dev/fhir/StructureDefinition/task-test" /> + <!-- version managed by bpe --> + <version value="#{version}" /> + <name value="TaskTest" /> + <!-- status managed by bpe --> + <status value="unknown" /> + <experimental value="false" /> + <!-- date managed by bpe --> + <date value="#{date}" /> + <fhirVersion value="4.0.1" /> + <kind value="resource" /> + <abstract value="false" /> + <type value="Task" /> + <baseDefinition value="http://dsf.dev/fhir/StructureDefinition/task-base" /> + <derivation value="constraint" /> + <differential> + <element id="Task.instantiatesUri"> + <path value="Task.instantiatesUri" /> + <fixedUri value="http://dsf.dev/bpe/Process/test/#{version}" /> + </element> + <element id="Task.input"> + <path value="Task.input" /> + <min value="2" /> + <max value="3" /> + </element> + <element id="Task.input:message-name"> + <path value="Task.input" /> + <sliceName value="message-name" /> + </element> + <element id="Task.input:message-name.value[x]"> + <path value="Task.input.value[x]" /> + <fixedString value="start" /> + </element> + <element id="Task.input:correlation-key"> + <path value="Task.input" /> + <sliceName value="correlation-key" /> + <max value="0" /> + </element> + <element id="Task.input:test-activity"> + <path value="Task.input" /> + <sliceName value="test-activity" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Task.input:test-activity.type"> + <path value="Task.input.type" /> + <binding> + <strength value="required" /> + <valueSet value="http://dsf.dev/fhir/ValueSet/test|#{version}" /> + </binding> + </element> + <element id="Task.input:test-activity.type.coding"> + <path value="Task.input.type.coding" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Task.input:test-activity.type.coding.system"> + <path value="Task.input.type.coding.system" /> + <min value="1" /> + <fixedUri value="http://dsf.dev/fhir/CodeSystem/test" /> + </element> + <element id="Task.input:test-activity.type.coding.code"> + <path value="Task.input.type.coding.code" /> + <min value="1" /> + <fixedCode value="test-activity" /> + </element> + <element id="Task.input:test-activity.value[x]"> + <path value="Task.input.value[x]" /> + <type> + <code value="string" /> + </type> + </element> + <element id="Task.output:test-method-succeeded"> + <path value="Task.output" /> + <sliceName value="test-method-succeeded" /> + </element> + <element id="Task.output:test-method-succeeded.type"> + <path value="Task.output.type" /> + <binding> + <strength value="required" /> + <valueSet value="http://dsf.dev/fhir/ValueSet/test|#{version}" /> + </binding> + </element> + <element id="Task.output:test-method-succeeded.type.coding"> + <path value="Task.output.type.coding" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Task.output:test-method-succeeded.type.coding.system"> + <path value="Task.output.type.coding.system" /> + <min value="1" /> + <fixedUri value="http://dsf.dev/fhir/CodeSystem/test" /> + </element> + <element id="Task.output:test-method-succeeded.type.coding.code"> + <path value="Task.output.type.coding.code" /> + <min value="1" /> + <fixedCode value="test-method-succeeded" /> + </element> + <element id="Task.output:test-method-succeeded.value[x]"> + <path value="Task.output.value[x]" /> + <type> + <code value="string" /> + </type> + </element> + <element id="Task.output:test-method-failed"> + <path value="Task.output" /> + <sliceName value="test-method-failed" /> + </element> + <element id="Task.output:test-method-failed.type"> + <path value="Task.output.type" /> + <binding> + <strength value="required" /> + <valueSet value="http://dsf.dev/fhir/ValueSet/test|#{version}" /> + </binding> + </element> + <element id="Task.output:test-method-failed.type.coding"> + <path value="Task.output.type.coding" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Task.output:test-method-failed.type.coding.system"> + <path value="Task.output.type.coding.system" /> + <min value="1" /> + <fixedUri value="http://dsf.dev/fhir/CodeSystem/test" /> + </element> + <element id="Task.output:test-method-failed.type.coding.code"> + <path value="Task.output.type.coding.code" /> + <min value="1" /> + <fixedCode value="test-method-failed" /> + </element> + <element id="Task.output:test-method-failed.value[x]"> + <path value="Task.output.value[x]" /> + <type> + <code value="string" /> + </type> + </element> + </differential> +</StructureDefinition> \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/resources/fhir/ValueSet/dsf-test.xml b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/resources/fhir/ValueSet/dsf-test.xml new file mode 100644 index 000000000..fa9d0bba0 --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v1/src/main/resources/fhir/ValueSet/dsf-test.xml @@ -0,0 +1,27 @@ +<ValueSet xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <url value="http://dsf.dev/fhir/ValueSet/test" /> + <!-- version managed by bpe --> + <version value="#{version}" /> + <name value="DSF_Test" /> + <title value="DSF Test" /> + <!-- status managed by bpe --> + <status value="unknown" /> + <experimental value="false" /> + <!-- date managed by bpe --> + <date value="#{date}" /> + <publisher value="DSF" /> + <description value="ValueSet for process plugin integration testing" /> + <immutable value="true" /> + <compose> + <include> + <system value="http://dsf.dev/fhir/CodeSystem/test" /> + <version value="#{version}" /> + </include> + </compose> +</ValueSet> \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-test-plugin-v2/pom.xml b/dsf-bpe/dsf-bpe-test-plugin-v2/pom.xml new file mode 100644 index 000000000..7be25b718 --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v2/pom.xml @@ -0,0 +1,22 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <artifactId>dsf-bpe-test-plugin-v2</artifactId> + + <parent> + <groupId>dev.dsf</groupId> + <artifactId>dsf-bpe-pom</artifactId> + <version>2.0.0-SNAPSHOT</version> + </parent> + + <dependencies> + <dependency> + <groupId>dev.dsf</groupId> + <artifactId>dsf-bpe-test-plugin</artifactId> + </dependency> + <dependency> + <groupId>dev.dsf</groupId> + <artifactId>dsf-bpe-process-api-v2</artifactId> + </dependency> + </dependencies> +</project> \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/TestProcessPluginDefinition.java b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/TestProcessPluginDefinition.java new file mode 100644 index 000000000..ee82f5ed5 --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/TestProcessPluginDefinition.java @@ -0,0 +1,55 @@ +package dev.dsf.bpe.test; + +import java.time.LocalDate; +import java.util.List; +import java.util.Map; + +import dev.dsf.bpe.test.spring.config.Config; +import dev.dsf.bpe.v2.ProcessPluginDefinition; + +public class TestProcessPluginDefinition implements ProcessPluginDefinition +{ + public static final String VERSION = "2.0.0.0"; + public static final LocalDate RELEASE_DATE = LocalDate.of(2025, 2, 8); + + @Override + public String getName() + { + return "dsf-process-test"; + } + + @Override + public String getVersion() + { + return VERSION; + } + + @Override + public LocalDate getReleaseDate() + { + return RELEASE_DATE; + } + + @Override + public List<String> getProcessModels() + { + return List.of("bpe/test.bpmn"); + } + + @Override + public List<Class<?>> getSpringConfigurations() + { + return List.of(Config.class); + } + + @Override + public Map<String, List<String>> getFhirResourcesByProcessId() + { + var aTest = "fhir/ActivityDefinition/dsf-test.xml"; + var cTest = "fhir/CodeSystem/dsf-test.xml"; + var sTest = "fhir/StructureDefinition/dsf-task-test.xml"; + var vTest = "fhir/ValueSet/dsf-test.xml"; + + return Map.of("dsfdev_test", List.of(aTest, cTest, sTest, vTest)); + } +} diff --git a/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/service/AbstractTest.java b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/service/AbstractTest.java new file mode 100644 index 000000000..34570e2db --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/service/AbstractTest.java @@ -0,0 +1,33 @@ +package dev.dsf.bpe.test.service; + +import java.util.function.Consumer; + +import org.camunda.bpm.engine.delegate.BpmnError; +import org.camunda.bpm.engine.delegate.DelegateExecution; +import org.hl7.fhir.r4.model.StringType; + +import dev.dsf.bpe.test.PluginTestExecutor; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.AbstractServiceDelegate; +import dev.dsf.bpe.v2.variables.Variables; + +public abstract class AbstractTest extends AbstractServiceDelegate +{ + public AbstractTest(ProcessPluginApi api) + { + super(api); + } + + @Override + protected void doExecute(DelegateExecution execution, Variables variables) throws BpmnError, Exception + { + PluginTestExecutor.execute(this, output(variables, "test-method-succeeded"), + output(variables, "test-method-failed"), () -> variables.updateTask(variables.getStartTask())); + } + + private Consumer<String> output(Variables variables, String code) + { + return t -> variables.getStartTask().addOutput( + api.getTaskHelper().createOutput(new StringType(t), "http://dsf.dev/fhir/CodeSystem/test", code)); + } +} diff --git a/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/service/ApiTest.java b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/service/ApiTest.java new file mode 100644 index 000000000..2c41c6ae6 --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/service/ApiTest.java @@ -0,0 +1,102 @@ +package dev.dsf.bpe.test.service; + +import static dev.dsf.bpe.test.PluginTestExecutor.expectNotNull; + +import org.camunda.bpm.engine.delegate.BpmnError; +import org.camunda.bpm.engine.delegate.DelegateExecution; + +import dev.dsf.bpe.test.PluginTest; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.variables.Variables; + +public class ApiTest extends AbstractTest +{ + private DelegateExecution execution; + + public ApiTest(ProcessPluginApi api) + { + super(api); + } + + @Override + protected void doExecute(DelegateExecution execution, Variables variables) throws BpmnError, Exception + { + this.execution = execution; + + super.doExecute(execution, variables); + + this.execution = null; + } + + @PluginTest + public void apiNotNull() throws Exception + { + expectNotNull(api); + } + + @PluginTest + public void apiGetEndpointProviderNotNull() throws Exception + { + expectNotNull(api.getEndpointProvider()); + } + + @PluginTest + public void apiGetFhirContextNotNull() throws Exception + { + expectNotNull(api.getFhirContext()); + } + + @PluginTest + public void apiGetFhirWebserviceClientProviderNotNull() throws Exception + { + expectNotNull(api.getFhirWebserviceClientProvider()); + } + + @PluginTest + public void apiGetMailServiceNotNull() throws Exception + { + expectNotNull(api.getMailService()); + } + + @PluginTest + public void apiGetObjectMapperNotNull() throws Exception + { + expectNotNull(api.getObjectMapper()); + } + + @PluginTest + public void apiGetOrganizationProviderNotNull() throws Exception + { + expectNotNull(api.getOrganizationProvider()); + } + + @PluginTest + public void apiGetProcessAuthorizationHelperNotNull() throws Exception + { + expectNotNull(api.getProcessAuthorizationHelper()); + } + + @PluginTest + public void apiGetProxyConfigNotNull() throws Exception + { + expectNotNull(api.getProxyConfig()); + } + + @PluginTest + public void apiGetReadAccessHelperNotNull() throws Exception + { + expectNotNull(api.getReadAccessHelper()); + } + + @PluginTest + public void apiGetTaskHelperNotNull() throws Exception + { + expectNotNull(api.getTaskHelper()); + } + + @PluginTest + public void apiGetVariablesNotNull() throws Exception + { + expectNotNull(api.getVariables(execution)); + } +} diff --git a/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/service/EndpointProviderTest.java b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/service/EndpointProviderTest.java new file mode 100644 index 000000000..b51195dff --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/service/EndpointProviderTest.java @@ -0,0 +1,916 @@ +package dev.dsf.bpe.test.service; + +import static dev.dsf.bpe.test.PluginTestExecutor.expectNotNull; +import static dev.dsf.bpe.test.PluginTestExecutor.expectSame; +import static dev.dsf.bpe.test.PluginTestExecutor.expectTrue; + +import java.util.List; +import java.util.Optional; + +import org.hl7.fhir.r4.model.Coding; +import org.hl7.fhir.r4.model.Endpoint; +import org.hl7.fhir.r4.model.Identifier; + +import dev.dsf.bpe.test.PluginTest; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.constants.CodeSystems.OrganizationRole; +import dev.dsf.bpe.v2.constants.NamingSystems.EndpointIdentifier; +import dev.dsf.bpe.v2.constants.NamingSystems.OrganizationIdentifier; + +public class EndpointProviderTest extends AbstractTest +{ + private static final String ORGANIZATION_IDENTIFIER_LOCAL_VALUE = "Test_Organization"; + private static final Identifier ORGANIZATION_IDENTIFIER_LOCAL = OrganizationIdentifier + .withValue(ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + private static final String ORGANIZATION_IDENTIFIER_PARENT_VALUE = "Parent_Organization"; + private static final Identifier ORGANIZATION_IDENTIFIER_PARENT = OrganizationIdentifier + .withValue(ORGANIZATION_IDENTIFIER_PARENT_VALUE); + private static final String ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE = "External_Test_Organization"; + private static final Identifier ORGANIZATION_IDENTIFIER_EXTERNAL = OrganizationIdentifier + .withValue(ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE); + + private static final String ENDPOINT_IDENTIFIER_LOCAL_VALUE = "Test_Endpoint"; + private static final Identifier ENDPOINT_IDENTIFIER_LOCAL = EndpointIdentifier + .withValue(ENDPOINT_IDENTIFIER_LOCAL_VALUE); + private static final String ENDPOINT_IDENTIFIER_EXTERNAL_VALUE = "External_Test_Endpoint"; + private static final Identifier ENDPOINT_IDENTIFIER_EXTERNAL = EndpointIdentifier + .withValue(ENDPOINT_IDENTIFIER_EXTERNAL_VALUE); + + private static final String ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE = "not-existing-identifier-value"; + private static final Identifier ORGANIZATION_IDENTIFIER_NOT_EXISTING = OrganizationIdentifier + .withValue(ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE); + private static final String MEMBER_ROLE_NOT_EXISTING_CODE = "not-existing-role"; + private static final Coding MEMBER_ROLE_NOT_EXISTING = OrganizationRole.withCode(MEMBER_ROLE_NOT_EXISTING_CODE); + + public EndpointProviderTest(ProcessPluginApi api) + { + super(api); + } + + private void testEndpointLocal(Optional<Endpoint> oE) + { + expectNotNull(oE); + expectTrue(oE.isPresent()); + + testEndpointLocal(oE.get()); + } + + private void testEndpointExternal(Optional<Endpoint> oE) + { + expectNotNull(oE); + expectTrue(oE.isPresent()); + + testEndpointExternal(oE.get()); + } + + private void testEndpointLocal(Endpoint e) + { + testEndpoint(e, () -> expectTrue(e.getAddress().matches("https://localhost:[0-9]+/fhir")), + ENDPOINT_IDENTIFIER_LOCAL_VALUE); + } + + private void testEndpointExternal(Endpoint e) + { + testEndpoint(e, () -> expectSame("https://localhost:80010/fhir", e.getAddress()), + ENDPOINT_IDENTIFIER_EXTERNAL_VALUE); + } + + private void testEndpoint(Endpoint e, Runnable testAddress, String expectedIdentifierValue) + { + expectNotNull(e); + expectNotNull(e.getAddress()); + testAddress.run(); + + List<Identifier> ids = e.getIdentifier(); + expectNotNull(ids); + expectSame(1, ids.size()); + expectNotNull(ids.get(0)); + expectSame(EndpointIdentifier.SID, ids.get(0).getSystem()); + expectSame(expectedIdentifierValue, ids.get(0).getValue()); + } + + private void testEndpointAddressLocal(Optional<String> a) + { + expectNotNull(a); + expectTrue(a.isPresent()); + expectNotNull(a.get()); + expectTrue(a.get().matches("https://localhost:[0-9]+/fhir")); + } + + private void testEndpointAddressExternal(Optional<String> a) + { + expectNotNull(a); + expectTrue(a.isPresent()); + expectNotNull(a.get()); + expectSame("https://localhost:80010/fhir", a.get()); + } + + @PluginTest + public void getLocalEndpointAddress() throws Exception + { + String a = api.getEndpointProvider().getLocalEndpointAddress(); + expectNotNull(a); + expectTrue(a.matches("https://localhost:[0-9]+/fhir")); + } + + @PluginTest + public void getLocalEndpoint() throws Exception + { + Optional<Endpoint> e = api.getEndpointProvider().getLocalEndpoint(); + expectNotNull(e); + expectTrue(e.isPresent()); + expectNotNull(e.get()); + expectNotNull(e.get().getAddress()); + expectTrue(e.get().getAddress().matches("https://localhost:[0-9]+/fhir")); + + List<Identifier> ids = e.get().getIdentifier(); + expectNotNull(ids); + expectSame(1, ids.size()); + expectNotNull(ids.get(0)); + expectSame(EndpointIdentifier.SID, ids.get(0).getSystem()); + expectSame(ENDPOINT_IDENTIFIER_LOCAL_VALUE, ids.get(0).getValue()); + } + + @PluginTest + public void getLocalEndpointIdentifier() throws Exception + { + Optional<Identifier> id = api.getEndpointProvider().getLocalEndpointIdentifier(); + expectNotNull(id); + expectTrue(id.isPresent()); + expectNotNull(id.get()); + expectSame(EndpointIdentifier.SID, id.get().getSystem()); + expectSame(ENDPOINT_IDENTIFIER_LOCAL_VALUE, id.get().getValue()); + } + + @PluginTest + public void getLocalEndpointIdentifierValue() throws Exception + { + Optional<String> idV = api.getEndpointProvider().getLocalEndpointIdentifierValue(); + expectNotNull(idV); + expectTrue(idV.isPresent()); + expectNotNull(idV.get()); + expectSame(ENDPOINT_IDENTIFIER_LOCAL_VALUE, idV.get()); + } + + @PluginTest + public void getEndpointByEndpointIdentifierNull() throws Exception + { + Optional<Endpoint> e = api.getEndpointProvider().getEndpoint((Identifier) null); + expectNotNull(e); + expectTrue(e.isEmpty()); + } + + @PluginTest + public void getEndpointByEndpointIdentifierNotExisting() throws Exception + { + Optional<Endpoint> e = api.getEndpointProvider() + .getEndpoint(EndpointIdentifier.withValue("not-existing-identifier-value")); + expectNotNull(e); + expectTrue(e.isEmpty()); + } + + @PluginTest + public void getEndpointByEndpointIdentifierLocal() throws Exception + { + Optional<Endpoint> e = api.getEndpointProvider().getEndpoint(ENDPOINT_IDENTIFIER_LOCAL); + testEndpointLocal(e); + } + + @PluginTest + public void getEndpointByEndpointIdentifierExternal() throws Exception + { + Optional<Endpoint> e = api.getEndpointProvider().getEndpoint(ENDPOINT_IDENTIFIER_EXTERNAL); + testEndpointExternal(e); + } + + @PluginTest + public void getEndpointByEndpointIdentifierValueNull() throws Exception + { + Optional<Endpoint> e = api.getEndpointProvider().getEndpoint((String) null); + expectNotNull(e); + expectTrue(e.isEmpty()); + } + + @PluginTest + public void getEndpointByEndpointIdentifierValueNotExisting() throws Exception + { + Optional<Endpoint> e = api.getEndpointProvider().getEndpoint("not-existing-identifier-value"); + expectNotNull(e); + expectTrue(e.isEmpty()); + } + + @PluginTest + public void getEndpointByEndpointIdentifierValueLocal() throws Exception + { + testEndpointLocal(api.getEndpointProvider().getEndpoint(ENDPOINT_IDENTIFIER_LOCAL_VALUE)); + } + + @PluginTest + public void getEndpointByEndpointIdentifierValueExternal() throws Exception + { + testEndpointExternal(api.getEndpointProvider().getEndpoint(ENDPOINT_IDENTIFIER_EXTERNAL_VALUE)); + } + + @PluginTest + public void getEndpointAddressByEndpointIdentifierNull() throws Exception + { + Optional<String> a = api.getEndpointProvider().getEndpointAddress((Identifier) null); + expectNotNull(a); + expectTrue(a.isEmpty()); + } + + @PluginTest + public void getEndpointAddressByEndpointIdentifierNotExisting() throws Exception + { + Optional<String> a = api.getEndpointProvider() + .getEndpointAddress(EndpointIdentifier.withValue("not-existing-identifier-value")); + expectNotNull(a); + expectTrue(a.isEmpty()); + } + + @PluginTest + public void getEndpointAddressByEndpointIdentifierLocal() throws Exception + { + Optional<String> a = api.getEndpointProvider().getEndpointAddress(ENDPOINT_IDENTIFIER_LOCAL); + testEndpointAddressLocal(a); + } + + @PluginTest + public void getEndpointAddressByEndpointIdentifierExternal() throws Exception + { + Optional<String> a = api.getEndpointProvider().getEndpointAddress(ENDPOINT_IDENTIFIER_EXTERNAL); + testEndpointAddressExternal(a); + } + + @PluginTest + public void getEndpointAddressbyEndpointIdentifierValueNull() throws Exception + { + Optional<String> a = api.getEndpointProvider().getEndpointAddress((String) null); + expectNotNull(a); + expectTrue(a.isEmpty()); + } + + @PluginTest + public void getEndpointAddressbyEndpointIdentifierValueNotExisting() throws Exception + { + Optional<String> a = api.getEndpointProvider().getEndpointAddress("not-existing-identifier-value"); + expectNotNull(a); + expectTrue(a.isEmpty()); + } + + @PluginTest + public void getEndpointAddressbyEndpointIdentifierValueLocal() throws Exception + { + Optional<String> a = api.getEndpointProvider().getEndpointAddress(ENDPOINT_IDENTIFIER_LOCAL_VALUE); + testEndpointAddressLocal(a); + } + + @PluginTest + public void getEndpointAddressbyEndpointIdentifierValueExternal() throws Exception + { + Optional<String> a = api.getEndpointProvider().getEndpointAddress(ENDPOINT_IDENTIFIER_EXTERNAL_VALUE); + testEndpointAddressExternal(a); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNull1() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(null, ORGANIZATION_IDENTIFIER_LOCAL, + OrganizationRole.dic()); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNull2() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, null, + OrganizationRole.dic()); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNull3() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_LOCAL, null); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNull4() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(null, null, OrganizationRole.dic()); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNull5() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, null, + null); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNull6() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(null, ORGANIZATION_IDENTIFIER_LOCAL, + null); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNull7() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(null, null, null); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting1() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING, + ORGANIZATION_IDENTIFIER_LOCAL, OrganizationRole.dic()); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting2() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_NOT_EXISTING, OrganizationRole.dic()); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting3() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_LOCAL, MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting4() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING, + ORGANIZATION_IDENTIFIER_NOT_EXISTING, OrganizationRole.dic()); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting5() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_NOT_EXISTING, MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting6() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING, + ORGANIZATION_IDENTIFIER_LOCAL, MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting7() throws Exception + { + getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING, + ORGANIZATION_IDENTIFIER_NOT_EXISTING, MEMBER_ROLE_NOT_EXISTING); + } + + private void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(Identifier parentIdentifier, + Identifier memberIdentifier, Coding memberRole) + { + Optional<Endpoint> es = api.getEndpointProvider().getEndpoint(parentIdentifier, memberIdentifier, memberRole); + expectNotNull(es); + expectTrue(es.isEmpty()); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleDic() throws Exception + { + testEndpointLocal(api.getEndpointProvider().getEndpoint(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_LOCAL, OrganizationRole.dic())); + } + + @PluginTest + public void getEndpointByParentIdentifierAndMemberIdentifierAndMemberRoleTtp() throws Exception + { + testEndpointExternal(api.getEndpointProvider().getEndpoint(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_EXTERNAL, OrganizationRole.ttp())); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeNull1() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeExpectEmpty(null, + ORGANIZATION_IDENTIFIER_LOCAL_VALUE, OrganizationRole.Codes.DIC); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeNull2() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, null, OrganizationRole.Codes.DIC); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeNull3() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, ORGANIZATION_IDENTIFIER_LOCAL_VALUE, null); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeNull4() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeExpectEmpty(null, null, + OrganizationRole.Codes.DIC); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeNull5() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, null, null); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeNull6() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeExpectEmpty(null, + ORGANIZATION_IDENTIFIER_LOCAL_VALUE, null); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeNull7() throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeExpectEmpty(null, null, null); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeNotExisting() + throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, ORGANIZATION_IDENTIFIER_LOCAL_VALUE, + OrganizationRole.Codes.DIC); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeNotExisting2() + throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + OrganizationRole.Codes.DIC); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeNotExisting3() + throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, ORGANIZATION_IDENTIFIER_LOCAL_VALUE, + MEMBER_ROLE_NOT_EXISTING_CODE); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeNotExisting4() + throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + OrganizationRole.Codes.DIC); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeNotExisting5() + throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + MEMBER_ROLE_NOT_EXISTING_CODE); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeNotExisting6() + throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, ORGANIZATION_IDENTIFIER_LOCAL_VALUE, + MEMBER_ROLE_NOT_EXISTING_CODE); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeNotExisting7() + throws Exception + { + getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + MEMBER_ROLE_NOT_EXISTING_CODE); + } + + private void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeExpectEmpty( + String parentIdentifierValue, String memberIdentifierValue, String memberRoleCode) + { + Optional<Endpoint> es = api.getEndpointProvider().getEndpoint(parentIdentifierValue, memberIdentifierValue, + memberRoleCode); + expectNotNull(es); + expectTrue(es.isEmpty()); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeDic() throws Exception + { + testEndpointLocal(api.getEndpointProvider().getEndpoint(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + ORGANIZATION_IDENTIFIER_LOCAL_VALUE, OrganizationRole.Codes.DIC)); + } + + @PluginTest + public void getEndpointByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeTtp() throws Exception + { + testEndpointExternal(api.getEndpointProvider().getEndpoint(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE, OrganizationRole.Codes.TTP)); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNull1() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(null, + ORGANIZATION_IDENTIFIER_LOCAL, OrganizationRole.dic()); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNull2() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + null, OrganizationRole.dic()); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNull3() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_LOCAL, null); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNull4() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(null, null, + OrganizationRole.dic()); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNull5() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + null, null); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNull6() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(null, + ORGANIZATION_IDENTIFIER_LOCAL, null); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNull7() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(null, null, null); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting1() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING, ORGANIZATION_IDENTIFIER_LOCAL, OrganizationRole.dic()); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting2() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_NOT_EXISTING, OrganizationRole.dic()); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting3() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_LOCAL, MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting4() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING, ORGANIZATION_IDENTIFIER_NOT_EXISTING, OrganizationRole.dic()); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting5() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_NOT_EXISTING, MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting6() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING, ORGANIZATION_IDENTIFIER_LOCAL, MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleNotExisting7() throws Exception + { + getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING, ORGANIZATION_IDENTIFIER_NOT_EXISTING, MEMBER_ROLE_NOT_EXISTING); + } + + private void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleExpectEmpty( + Identifier parentIdentifier, Identifier memberIdentifier, Coding memberRole) + { + Optional<String> a = api.getEndpointProvider().getEndpointAddress(parentIdentifier, memberIdentifier, + memberRole); + expectNotNull(a); + expectTrue(a.isEmpty()); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleDic() throws Exception + { + testEndpointAddressLocal(api.getEndpointProvider().getEndpointAddress(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_LOCAL, OrganizationRole.dic())); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierAndMemberIdentifierAndMemberRoleTtp() throws Exception + { + testEndpointAddressExternal(api.getEndpointProvider().getEndpointAddress(ORGANIZATION_IDENTIFIER_PARENT, + ORGANIZATION_IDENTIFIER_EXTERNAL, OrganizationRole.ttp())); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull1() throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty(null, + ORGANIZATION_IDENTIFIER_LOCAL_VALUE, OrganizationRole.Codes.DIC); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull2() throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, null, OrganizationRole.Codes.DIC); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull3() throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, ORGANIZATION_IDENTIFIER_LOCAL_VALUE, null); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull4() throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty(null, null, + OrganizationRole.Codes.DIC); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull5() throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, null, null); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull6() throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty(null, + ORGANIZATION_IDENTIFIER_LOCAL_VALUE, null); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNull7() throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty(null, null, null); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting1() + throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, ORGANIZATION_IDENTIFIER_LOCAL_VALUE, + OrganizationRole.Codes.DIC); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting2() + throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + OrganizationRole.Codes.DIC); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting3() + throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, ORGANIZATION_IDENTIFIER_LOCAL_VALUE, + MEMBER_ROLE_NOT_EXISTING_CODE); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting4() + throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + OrganizationRole.Codes.DIC); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting5() + throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_PARENT_VALUE, ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + MEMBER_ROLE_NOT_EXISTING_CODE); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting6() + throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, ORGANIZATION_IDENTIFIER_LOCAL_VALUE, + MEMBER_ROLE_NOT_EXISTING_CODE); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleNotExisting7() + throws Exception + { + getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + MEMBER_ROLE_NOT_EXISTING_CODE); + } + + private void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleExpectEmpty( + String parentIdentifierValue, String memberIdentifierValue, String memberRole) + { + Optional<String> a = api.getEndpointProvider().getEndpointAddress(parentIdentifierValue, memberIdentifierValue, + memberRole); + expectNotNull(a); + expectTrue(a.isEmpty()); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeDic() throws Exception + { + testEndpointAddressLocal(api.getEndpointProvider().getEndpointAddress(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + ORGANIZATION_IDENTIFIER_LOCAL_VALUE, OrganizationRole.Codes.DIC)); + } + + @PluginTest + public void getEndpointAddressByParentIdentifierValueAndMemberIdentifierValueAndMemberRoleCodeTtp() throws Exception + { + testEndpointAddressExternal(api.getEndpointProvider().getEndpointAddress(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE, OrganizationRole.Codes.TTP)); + } + + @PluginTest + public void getEndpointsByParentIdentifierAndMemberRoleNull1() throws Exception + { + getEndpointsByParentIdentifierAndMemberRoleExpectEmpty(null, OrganizationRole.dic()); + } + + @PluginTest + public void getEndpointsByParentIdentifierAndMemberRoleNull2() throws Exception + { + getEndpointsByParentIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, null); + } + + @PluginTest + public void getEndpointsByParentIdentifierAndMemberRoleNull3() throws Exception + { + getEndpointsByParentIdentifierAndMemberRoleExpectEmpty(null, null); + } + + @PluginTest + public void getEndpointsByParentIdentifierAndMemberRoleNotExisting1() throws Exception + { + getEndpointsByParentIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING, + OrganizationRole.dic()); + } + + @PluginTest + public void getEndpointsByParentIdentifierAndMemberRoleNotExisting2() throws Exception + { + getEndpointsByParentIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getEndpointsByParentIdentifierAndMemberRoleNotExisting3() throws Exception + { + getEndpointsByParentIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING, + MEMBER_ROLE_NOT_EXISTING); + } + + private void getEndpointsByParentIdentifierAndMemberRoleExpectEmpty(Identifier parentOrganizationIdentifier, + Coding memberOrganizationRole) + { + List<Endpoint> es = api.getEndpointProvider().getEndpoints(parentOrganizationIdentifier, + memberOrganizationRole); + expectNotNull(es); + expectTrue(es.isEmpty()); + } + + @PluginTest + public void getEndpointsByParentIdentifierAndMemberRoleDic() throws Exception + { + List<Endpoint> es = api.getEndpointProvider().getEndpoints(ORGANIZATION_IDENTIFIER_PARENT, + OrganizationRole.dic()); + expectNotNull(es); + expectSame(1, es.size()); + testEndpointLocal(es.get(0)); + } + + @PluginTest + public void getEndpointsByParentIdentifierAndMemberRoleTtp() throws Exception + { + List<Endpoint> es = api.getEndpointProvider().getEndpoints(ORGANIZATION_IDENTIFIER_PARENT, + OrganizationRole.ttp()); + expectNotNull(es); + expectSame(1, es.size()); + testEndpointExternal(es.get(0)); + } + + @PluginTest + public void getEndpointsByParentIdentifierValueAndMemberRoleNull1() throws Exception + { + getEndpointsByParentIdentifierValueAndMemberRoleExpectEmpty(null, OrganizationRole.Codes.DIC); + } + + @PluginTest + public void getEndpointsByParentIdentifierValueAndMemberRoleNull2() throws Exception + { + getEndpointsByParentIdentifierValueAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT_VALUE, null); + } + + @PluginTest + public void getEndpointsByParentIdentifierValueAndMemberRoleNull3() throws Exception + { + getEndpointsByParentIdentifierValueAndMemberRoleExpectEmpty(null, null); + } + + @PluginTest + public void getEndpointsByParentIdentifierValueAndMemberRoleNotExisting1() throws Exception + { + getEndpointsByParentIdentifierValueAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + OrganizationRole.Codes.DIC); + } + + @PluginTest + public void getEndpointsByParentIdentifierValueAndMemberRoleNotExisting2() throws Exception + { + getEndpointsByParentIdentifierValueAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + MEMBER_ROLE_NOT_EXISTING_CODE); + } + + @PluginTest + public void getEndpointsByParentIdentifierValueAndMemberRoleNotExisting3() throws Exception + { + getEndpointsByParentIdentifierValueAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + MEMBER_ROLE_NOT_EXISTING_CODE); + } + + private void getEndpointsByParentIdentifierValueAndMemberRoleExpectEmpty(String parentOrganizationIdentifierValue, + String memberOrganizationRole) + { + List<Endpoint> es = api.getEndpointProvider().getEndpoints(parentOrganizationIdentifierValue, + memberOrganizationRole); + expectNotNull(es); + expectTrue(es.isEmpty()); + } + + @PluginTest + public void getEndpointsByParentIdentifierValueAndMemberRoleCodeDic() throws Exception + { + List<Endpoint> es = api.getEndpointProvider().getEndpoints(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + OrganizationRole.Codes.DIC); + expectNotNull(es); + expectSame(1, es.size()); + testEndpointLocal(es.get(0)); + } + + @PluginTest + public void getEndpointsByParentIdentifierValueAndMemberRoleCodeTtp() throws Exception + { + List<Endpoint> es = api.getEndpointProvider().getEndpoints(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + OrganizationRole.Codes.TTP); + expectNotNull(es); + expectSame(1, es.size()); + testEndpointExternal(es.get(0)); + } +} diff --git a/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/service/OrganizationProviderTest.java b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/service/OrganizationProviderTest.java new file mode 100644 index 000000000..7a3f8dd2c --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/service/OrganizationProviderTest.java @@ -0,0 +1,368 @@ +package dev.dsf.bpe.test.service; + +import static dev.dsf.bpe.test.PluginTestExecutor.expectNotNull; +import static dev.dsf.bpe.test.PluginTestExecutor.expectSame; +import static dev.dsf.bpe.test.PluginTestExecutor.expectTrue; + +import java.util.List; +import java.util.Optional; + +import org.hl7.fhir.r4.model.Coding; +import org.hl7.fhir.r4.model.Identifier; +import org.hl7.fhir.r4.model.Organization; + +import dev.dsf.bpe.test.PluginTest; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.constants.CodeSystems.OrganizationRole; +import dev.dsf.bpe.v2.constants.NamingSystems.OrganizationIdentifier; + +public class OrganizationProviderTest extends AbstractTest +{ + private static final String ORGANIZATION_IDENTIFIER_LOCAL_VALUE = "Test_Organization"; + private static final Identifier ORGANIZATION_IDENTIFIER_LOCAL = OrganizationIdentifier + .withValue(ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + private static final String ORGANIZATION_IDENTIFIER_PARENT_VALUE = "Parent_Organization"; + private static final Identifier ORGANIZATION_IDENTIFIER_PARENT = OrganizationIdentifier + .withValue(ORGANIZATION_IDENTIFIER_PARENT_VALUE); + private static final String ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE = "External_Test_Organization"; + + private static final String ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE = "not-existing-identifier-value"; + private static final Identifier ORGANIZATION_IDENTIFIER_NOT_EXISTING = OrganizationIdentifier + .withValue(ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE); + private static final String MEMBER_ROLE_NOT_EXISTING_CODE = "not-existing-role"; + private static final Coding MEMBER_ROLE_NOT_EXISTING = OrganizationRole.withCode(MEMBER_ROLE_NOT_EXISTING_CODE); + + public OrganizationProviderTest(ProcessPluginApi api) + { + super(api); + } + + private void testOrganization(Optional<Organization> oO, String identifierValue) + { + expectNotNull(oO); + expectTrue(oO.isPresent()); + expectNotNull(oO.get()); + + Optional<Identifier> identifier = OrganizationIdentifier.findFirst(oO); + expectNotNull(identifier); + expectTrue(identifier.isPresent()); + expectSame(identifierValue, identifier.get().getValue()); + } + + private void testOrganization(Organization o, String identifierValue) + { + expectNotNull(o); + + Optional<Identifier> identifier = OrganizationIdentifier.findFirst(o); + expectNotNull(identifier); + expectTrue(identifier.isPresent()); + expectSame(identifierValue, identifier.get().getValue()); + } + + @PluginTest + public void getLocalOrganization() throws Exception + { + Optional<Organization> oO = api.getOrganizationProvider().getLocalOrganization(); + testOrganization(oO, ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + } + + @PluginTest + public void getLocalOrganizationIdentifier() throws Exception + { + expectNotNull(api.getOrganizationProvider().getLocalOrganizationIdentifier()); + expectTrue(api.getOrganizationProvider().getLocalOrganizationIdentifier().isPresent()); + expectNotNull(api.getOrganizationProvider().getLocalOrganizationIdentifier().get()); + expectSame(ORGANIZATION_IDENTIFIER_LOCAL_VALUE, + api.getOrganizationProvider().getLocalOrganizationIdentifier().get().getValue()); + } + + @PluginTest + public void getLocalOrganizationIdentifierValue() throws Exception + { + expectNotNull(api.getOrganizationProvider().getLocalOrganizationIdentifierValue()); + expectTrue(api.getOrganizationProvider().getLocalOrganizationIdentifierValue().isPresent()); + expectSame(ORGANIZATION_IDENTIFIER_LOCAL_VALUE, + api.getOrganizationProvider().getLocalOrganizationIdentifierValue().get()); + } + + @PluginTest + public void getOrganizationByIdentifierNull() throws Exception + { + Optional<Organization> oO = api.getOrganizationProvider().getOrganization((Identifier) null); + expectNotNull(oO); + expectTrue(oO.isEmpty()); + } + + @PluginTest + public void getOrganizationByIdentifierNotExisting() throws Exception + { + Optional<Organization> oO = api.getOrganizationProvider().getOrganization(ORGANIZATION_IDENTIFIER_NOT_EXISTING); + expectNotNull(oO); + expectTrue(oO.isEmpty()); + } + + @PluginTest + public void getOrganizationByIdentifier() throws Exception + { + Optional<Organization> oO = api.getOrganizationProvider().getOrganization(ORGANIZATION_IDENTIFIER_LOCAL); + testOrganization(oO, ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + } + + @PluginTest + public void getOrganizationByIdentifierValueNull() throws Exception + { + Optional<Organization> oO = api.getOrganizationProvider().getOrganization((String) null); + expectNotNull(oO); + expectTrue(oO.isEmpty()); + } + + @PluginTest + public void getOrganizationByIdentifierValueNotExisting() throws Exception + { + Optional<Organization> oO = api.getOrganizationProvider() + .getOrganization(ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE); + expectNotNull(oO); + expectTrue(oO.isEmpty()); + } + + @PluginTest + public void getOrganizationByIdentifierValue() throws Exception + { + Optional<Organization> oO = api.getOrganizationProvider().getOrganization(ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + testOrganization(oO, ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + } + + @PluginTest + public void getOrganizationsByParentIdentifierNull() throws Exception + { + getOrganizationsByParentIdentifierExpectEmpty(null); + } + + @PluginTest + public void getOrganizationsByParentIdentifierNotExisting() throws Exception + { + getOrganizationsByParentIdentifierExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING); + } + + private void getOrganizationsByParentIdentifierExpectEmpty(Identifier parentIdentifier) + { + List<Organization> os = api.getOrganizationProvider().getOrganizations(parentIdentifier); + expectNotNull(os); + expectTrue(os.isEmpty()); + } + + @PluginTest + public void getOrganizationsByParentIdentifier() throws Exception + { + List<Organization> os = api.getOrganizationProvider().getOrganizations(ORGANIZATION_IDENTIFIER_PARENT); + expectNotNull(os); + expectSame(2, os.size()); + + List<String> memberIdentifiers = os.stream().filter(o -> o.getIdentifier().size() == 1) + .map(OrganizationIdentifier::findFirst).flatMap(Optional::stream).map(Identifier::getValue).toList(); + expectSame(2, memberIdentifiers.size()); + + int localOrgIndex = memberIdentifiers.indexOf(ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + expectTrue(localOrgIndex >= 0); + testOrganization(os.get(localOrgIndex), ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + + int externalOrgIndex = memberIdentifiers.indexOf(ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE); + expectTrue(externalOrgIndex >= 0); + testOrganization(os.get(externalOrgIndex), ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueNull() throws Exception + { + getOrganizationsByParentIdentifierValueExpectEmpty(null); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueNotExisting() throws Exception + { + getOrganizationsByParentIdentifierValueExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE); + } + + private void getOrganizationsByParentIdentifierValueExpectEmpty(String parentIdentifierValue) + { + List<Organization> os = api.getOrganizationProvider().getOrganizations(parentIdentifierValue); + expectNotNull(os); + expectTrue(os.isEmpty()); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValue() throws Exception + { + List<Organization> os = api.getOrganizationProvider().getOrganizations(ORGANIZATION_IDENTIFIER_PARENT_VALUE); + expectNotNull(os); + expectSame(2, os.size()); + + List<String> memberIdentifiers = os.stream().filter(o -> o.getIdentifier().size() == 1) + .map(OrganizationIdentifier::findFirst).flatMap(Optional::stream).map(Identifier::getValue).toList(); + expectSame(2, memberIdentifiers.size()); + + int localOrgIndex = memberIdentifiers.indexOf(ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + expectTrue(localOrgIndex >= 0); + testOrganization(os.get(localOrgIndex), ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + + int externalOrgIndex = memberIdentifiers.indexOf(ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE); + expectTrue(externalOrgIndex >= 0); + testOrganization(os.get(externalOrgIndex), ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE); + } + + @PluginTest + public void getOrganizationsByParentIdentifierAndMemberRoleNull1() throws Exception + { + getOrganizationsByParentIdentifierAndMemberRoleExpectEmpty(null, OrganizationRole.dic()); + } + + @PluginTest + public void getOrganizationsByParentIdentifierAndMemberRoleNull2() throws Exception + { + getOrganizationsByParentIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, null); + } + + @PluginTest + public void getOrganizationsByParentIdentifierAndMemberRoleNull3() throws Exception + { + getOrganizationsByParentIdentifierAndMemberRoleExpectEmpty(null, null); + } + + @PluginTest + public void getOrganizationsByParentIdentifierAndMemberRoleNotExisting1() throws Exception + { + getOrganizationsByParentIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING, + OrganizationRole.dic()); + } + + @PluginTest + public void getOrganizationsByParentIdentifierAndMemberRoleNotExisting2() throws Exception + { + getOrganizationsByParentIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT, + MEMBER_ROLE_NOT_EXISTING); + } + + @PluginTest + public void getOrganizationsByParentIdentifierAndMemberRoleNotExisting3() throws Exception + { + getOrganizationsByParentIdentifierAndMemberRoleExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING, + MEMBER_ROLE_NOT_EXISTING); + } + + private void getOrganizationsByParentIdentifierAndMemberRoleExpectEmpty(Identifier parentIdentifier, + Coding memberRole) + { + List<Organization> os = api.getOrganizationProvider().getOrganizations(parentIdentifier, memberRole); + expectNotNull(os); + expectTrue(os.isEmpty()); + } + + @PluginTest + public void getOrganizationsByParentIdentifierAndMemberRoleDic() throws Exception + { + getOrganizationsByParentIdentifierAndMemberRoleExpectNotEmpty(ORGANIZATION_IDENTIFIER_PARENT, + OrganizationRole.dic(), ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + } + + @PluginTest + public void getOrganizationsByParentIdentifierAndMemberRoleTtp() throws Exception + { + getOrganizationsByParentIdentifierAndMemberRoleExpectNotEmpty(ORGANIZATION_IDENTIFIER_PARENT, + OrganizationRole.ttp(), ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE); + } + + private void getOrganizationsByParentIdentifierAndMemberRoleExpectNotEmpty(Identifier parentIdentifier, + Coding memberRole, String expectedOrganizationIdentifierValue) + { + List<Organization> os = api.getOrganizationProvider().getOrganizations(parentIdentifier, memberRole); + expectNotNull(os); + expectSame(1, os.size()); + testOrganization(os.get(0), expectedOrganizationIdentifierValue); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueAndMemberRoleCodeNull1() throws Exception + { + getOrganizationsByParentIdentifierValueAndMemberRoleCodeExpectEmpty(null, OrganizationRole.Codes.DIC); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueAndMemberRoleCodeNull2() throws Exception + { + getOrganizationsByParentIdentifierValueAndMemberRoleCodeExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT_VALUE, null); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueAndMemberRoleCodeNull3() throws Exception + { + getOrganizationsByParentIdentifierValueAndMemberRoleCodeExpectEmpty(null, null); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueAndMemberRoleCodeNotExisting1() throws Exception + { + getOrganizationsByParentIdentifierValueAndMemberRoleCodeExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + OrganizationRole.Codes.DIC); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueAndMemberRoleCodeNotExisting2() throws Exception + { + getOrganizationsByParentIdentifierValueAndMemberRoleCodeExpectEmpty(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + MEMBER_ROLE_NOT_EXISTING_CODE); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueAndMemberRoleCodeNotExisting3() throws Exception + { + getOrganizationsByParentIdentifierValueAndMemberRoleCodeExpectEmpty(ORGANIZATION_IDENTIFIER_NOT_EXISTING_VALUE, + MEMBER_ROLE_NOT_EXISTING_CODE); + } + + private void getOrganizationsByParentIdentifierValueAndMemberRoleCodeExpectEmpty(String parentIdentifierValue, + String memberRoleCode) + { + List<Organization> os = api.getOrganizationProvider().getOrganizations(parentIdentifierValue, memberRoleCode); + expectNotNull(os); + expectTrue(os.isEmpty()); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueAndMemberRoleCodeDic() throws Exception + { + getOrganizationsByParentIdentifierValueAndMemberRoleExpectNotEmpty(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + OrganizationRole.Codes.DIC, ORGANIZATION_IDENTIFIER_LOCAL_VALUE); + } + + @PluginTest + public void getOrganizationsByParentIdentifierValueAndMemberRoleCodeTtp() throws Exception + { + getOrganizationsByParentIdentifierValueAndMemberRoleExpectNotEmpty(ORGANIZATION_IDENTIFIER_PARENT_VALUE, + OrganizationRole.Codes.TTP, ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE); + } + + private void getOrganizationsByParentIdentifierValueAndMemberRoleExpectNotEmpty(String parentIdentifierValue, + String memberRoleCode, String expectedOrganizationIdentifierValue) + { + List<Organization> os = api.getOrganizationProvider().getOrganizations(parentIdentifierValue, memberRoleCode); + expectNotNull(os); + expectSame(1, os.size()); + testOrganization(os.get(0), expectedOrganizationIdentifierValue); + } + + @PluginTest + public void getRemoteOrganizations() throws Exception + { + List<Organization> os = api.getOrganizationProvider().getRemoteOrganizations(); + expectSame(1, os.size()); + testOrganization(os.get(0), ORGANIZATION_IDENTIFIER_EXTERNAL_VALUE); + } + + @PluginTest + public void getParentOrganizations() throws Exception + { + List<Organization> os = api.getOrganizationProvider().getParentOrganizations(); + expectSame(1, os.size()); + testOrganization(os.get(0), ORGANIZATION_IDENTIFIER_PARENT_VALUE); + } +} diff --git a/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/service/ProxyTest.java b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/service/ProxyTest.java new file mode 100644 index 000000000..21125a3d5 --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/service/ProxyTest.java @@ -0,0 +1,70 @@ +package dev.dsf.bpe.test.service; + +import static dev.dsf.bpe.test.PluginTestExecutor.expectException; +import static dev.dsf.bpe.test.PluginTestExecutor.expectFalse; +import static dev.dsf.bpe.test.PluginTestExecutor.expectNotNull; +import static dev.dsf.bpe.test.PluginTestExecutor.expectSame; +import static dev.dsf.bpe.test.PluginTestExecutor.expectTrue; + +import dev.dsf.bpe.test.PluginTest; +import dev.dsf.bpe.v2.ProcessPluginApi; + +public class ProxyTest extends AbstractTest +{ + public ProxyTest(ProcessPluginApi api) + { + super(api); + } + + @PluginTest + public void isEnabled() throws Exception + { + expectTrue(api.getProxyConfig().isEnabled()); + } + + @PluginTest + public void getNoProxyUrls() throws Exception + { + expectNotNull(api.getProxyConfig().getNoProxyUrls()); + expectSame(2, api.getProxyConfig().getNoProxyUrls().size()); + expectTrue(api.getProxyConfig().getNoProxyUrls().contains("localhost")); + expectTrue(api.getProxyConfig().getNoProxyUrls().contains("noproxy:443")); + } + + @PluginTest + public void getPassword() throws Exception + { + expectNotNull(api.getProxyConfig().getPassword()); + expectSame("proxy_password".toCharArray(), api.getProxyConfig().getPassword()); + } + + @PluginTest + public void getUrl() throws Exception + { + expectNotNull(api.getProxyConfig().getUrl()); + expectSame("http://proxy:8080", api.getProxyConfig().getUrl()); + } + + @PluginTest + public void getUsername() throws Exception + { + expectNotNull(api.getProxyConfig().getUsername()); + expectSame("proxy_username", api.getProxyConfig().getUsername()); + } + + @PluginTest + public void isNotProxyUrl() throws Exception + { + expectTrue(api.getProxyConfig().isNoProxyUrl("https://localhost")); + expectTrue(api.getProxyConfig().isNoProxyUrl("http://localhost")); + expectTrue(api.getProxyConfig().isNoProxyUrl("http://localhost:8080")); + expectException(IllegalArgumentException.class, () -> api.getProxyConfig().isNoProxyUrl("localhost:1234")); + expectException(IllegalArgumentException.class, () -> api.getProxyConfig().isNoProxyUrl("ftp://localhost")); + + expectTrue(api.getProxyConfig().isNoProxyUrl("https://noproxy")); + expectFalse(api.getProxyConfig().isNoProxyUrl("http://noproxy")); + expectFalse(api.getProxyConfig().isNoProxyUrl("http://noproxy:8080")); + + expectFalse(api.getProxyConfig().isNoProxyUrl("foo")); + } +} diff --git a/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/service/TestActivitySelector.java b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/service/TestActivitySelector.java new file mode 100644 index 000000000..85ade6307 --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/service/TestActivitySelector.java @@ -0,0 +1,24 @@ +package dev.dsf.bpe.test.service; + +import org.camunda.bpm.engine.delegate.BpmnError; +import org.camunda.bpm.engine.delegate.DelegateExecution; + +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.AbstractServiceDelegate; +import dev.dsf.bpe.v2.variables.Variables; + +public class TestActivitySelector extends AbstractServiceDelegate +{ + public TestActivitySelector(ProcessPluginApi api) + { + super(api); + } + + @Override + protected void doExecute(DelegateExecution execution, Variables variables) throws BpmnError, Exception + { + String testActivity = api.getTaskHelper().getFirstInputParameterStringValue(variables.getStartTask(), + "http://dsf.dev/fhir/CodeSystem/test", "test-activity").get(); + variables.setString("testActivity", testActivity); + } +} diff --git a/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/spring/config/Config.java b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/spring/config/Config.java new file mode 100644 index 000000000..84a57d371 --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/java/dev/dsf/bpe/test/spring/config/Config.java @@ -0,0 +1,56 @@ +package dev.dsf.bpe.test.spring.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; + +import dev.dsf.bpe.test.service.ApiTest; +import dev.dsf.bpe.test.service.EndpointProviderTest; +import dev.dsf.bpe.test.service.OrganizationProviderTest; +import dev.dsf.bpe.test.service.ProxyTest; +import dev.dsf.bpe.test.service.TestActivitySelector; +import dev.dsf.bpe.v2.ProcessPluginApi; + +@Configuration +public class Config +{ + @Autowired + private ProcessPluginApi api; + + @Bean + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public TestActivitySelector testActivitySelector() + { + return new TestActivitySelector(api); + } + + @Bean + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public ProxyTest proxyTest() + { + return new ProxyTest(api); + } + + @Bean + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public ApiTest apiTest() + { + return new ApiTest(api); + } + + @Bean + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public OrganizationProviderTest organizationProviderTest() + { + return new OrganizationProviderTest(api); + } + + @Bean + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public EndpointProviderTest endpointProviderTest() + { + return new EndpointProviderTest(api); + } +} diff --git a/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/resources/META-INF/services/dev.dsf.bpe.v2.ProcessPluginDefinition b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/resources/META-INF/services/dev.dsf.bpe.v2.ProcessPluginDefinition new file mode 100644 index 000000000..7e9e3d00a --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/resources/META-INF/services/dev.dsf.bpe.v2.ProcessPluginDefinition @@ -0,0 +1 @@ +dev.dsf.bpe.test.TestProcessPluginDefinition \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/resources/bpe/test.bpmn b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/resources/bpe/test.bpmn new file mode 100644 index 000000000..2a4aae6fc --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/resources/bpe/test.bpmn @@ -0,0 +1,153 @@ +<?xml version="1.0" encoding="UTF-8"?> +<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1yb5vw3" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.31.0"> + <bpmn:process id="dsfdev_test" isExecutable="true" camunda:versionTag="#{version}"> + <bpmn:startEvent id="StartEvent"> + <bpmn:outgoing>Flow_112zq99</bpmn:outgoing> + <bpmn:messageEventDefinition messageRef="Message_1nn2wdw" /> + </bpmn:startEvent> + <bpmn:serviceTask id="ApiTest" name="ApiTest" camunda:class="dev.dsf.bpe.test.service.ApiTest"> + <bpmn:incoming>Flow_0iy74da</bpmn:incoming> + <bpmn:outgoing>Flow_1mkx5o3</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:serviceTask id="ProxyTest" name="ProxyTest" camunda:class="dev.dsf.bpe.test.service.ProxyTest"> + <bpmn:incoming>Flow_14rzc0j</bpmn:incoming> + <bpmn:outgoing>Flow_08zzudo</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:endEvent id="EndEvent"> + <bpmn:incoming>Flow_0a1kwg9</bpmn:incoming> + </bpmn:endEvent> + <bpmn:serviceTask id="TestActivitySelector" name="TestActivitySelector" camunda:class="dev.dsf.bpe.test.service.TestActivitySelector"> + <bpmn:incoming>Flow_112zq99</bpmn:incoming> + <bpmn:outgoing>Flow_1bqddk1</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:exclusiveGateway id="Gateway_0eszi2t"> + <bpmn:incoming>Flow_1bqddk1</bpmn:incoming> + <bpmn:outgoing>Flow_14rzc0j</bpmn:outgoing> + <bpmn:outgoing>Flow_0iy74da</bpmn:outgoing> + <bpmn:outgoing>Flow_1h0pa8u</bpmn:outgoing> + <bpmn:outgoing>Flow_1hhwby8</bpmn:outgoing> + </bpmn:exclusiveGateway> + <bpmn:sequenceFlow id="Flow_1bqddk1" sourceRef="TestActivitySelector" targetRef="Gateway_0eszi2t" /> + <bpmn:sequenceFlow id="Flow_14rzc0j" sourceRef="Gateway_0eszi2t" targetRef="ProxyTest"> + <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${testActivity == 'Proxy'}</bpmn:conditionExpression> + </bpmn:sequenceFlow> + <bpmn:sequenceFlow id="Flow_112zq99" sourceRef="StartEvent" targetRef="TestActivitySelector" /> + <bpmn:sequenceFlow id="Flow_0iy74da" sourceRef="Gateway_0eszi2t" targetRef="ApiTest"> + <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${testActivity == 'Api'}</bpmn:conditionExpression> + </bpmn:sequenceFlow> + <bpmn:exclusiveGateway id="Gateway_056f6tw"> + <bpmn:incoming>Flow_08zzudo</bpmn:incoming> + <bpmn:incoming>Flow_1mkx5o3</bpmn:incoming> + <bpmn:incoming>Flow_0usx9io</bpmn:incoming> + <bpmn:incoming>Flow_1bn9gvv</bpmn:incoming> + <bpmn:outgoing>Flow_0a1kwg9</bpmn:outgoing> + </bpmn:exclusiveGateway> + <bpmn:sequenceFlow id="Flow_08zzudo" sourceRef="ProxyTest" targetRef="Gateway_056f6tw" /> + <bpmn:sequenceFlow id="Flow_1mkx5o3" sourceRef="ApiTest" targetRef="Gateway_056f6tw" /> + <bpmn:sequenceFlow id="Flow_0a1kwg9" sourceRef="Gateway_056f6tw" targetRef="EndEvent" /> + <bpmn:serviceTask id="OrganizationProviderTest" name="OrganizationProviderTest" camunda:class="dev.dsf.bpe.test.service.OrganizationProviderTest"> + <bpmn:incoming>Flow_1h0pa8u</bpmn:incoming> + <bpmn:outgoing>Flow_0usx9io</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_1h0pa8u" sourceRef="Gateway_0eszi2t" targetRef="OrganizationProviderTest"> + <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${testActivity == 'OrganizationProvider'}</bpmn:conditionExpression> + </bpmn:sequenceFlow> + <bpmn:sequenceFlow id="Flow_0usx9io" sourceRef="OrganizationProviderTest" targetRef="Gateway_056f6tw" /> + <bpmn:serviceTask id="EndpointProviderTest" name="EndpointProviderTest" camunda:class="dev.dsf.bpe.test.service.EndpointProviderTest"> + <bpmn:incoming>Flow_1hhwby8</bpmn:incoming> + <bpmn:outgoing>Flow_1bn9gvv</bpmn:outgoing> + </bpmn:serviceTask> + <bpmn:sequenceFlow id="Flow_1hhwby8" sourceRef="Gateway_0eszi2t" targetRef="EndpointProviderTest"> + <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${testActivity == 'EndpointProvider'}</bpmn:conditionExpression> + </bpmn:sequenceFlow> + <bpmn:sequenceFlow id="Flow_1bn9gvv" sourceRef="EndpointProviderTest" targetRef="Gateway_056f6tw" /> + </bpmn:process> + <bpmn:message id="Message_1nn2wdw" name="start" /> + <bpmn:message id="Message_2iq6v5e" name="proxyTest" /> + <bpmndi:BPMNDiagram id="BPMNDiagram_1"> + <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="dsfdev_test"> + <bpmndi:BPMNShape id="StartEvent_0x5gijn_di" bpmnElement="StartEvent"> + <dc:Bounds x="152" y="102" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="ServiceTask_0um3ad2_di" bpmnElement="ApiTest"> + <dc:Bounds x="480" y="80" width="100" height="80" /> + <bpmndi:BPMNLabel /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="BPMNShape_161ssjb" bpmnElement="ProxyTest"> + <dc:Bounds x="480" y="190" width="100" height="80" /> + <bpmndi:BPMNLabel /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="EndEvent_0xd0x8k_di" bpmnElement="EndEvent"> + <dc:Bounds x="712" y="102" width="36" height="36" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Activity_1x0k0hn_di" bpmnElement="TestActivitySelector"> + <dc:Bounds x="230" y="80" width="100" height="80" /> + <bpmndi:BPMNLabel /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Gateway_0eszi2t_di" bpmnElement="Gateway_0eszi2t" isMarkerVisible="true"> + <dc:Bounds x="385" y="95" width="50" height="50" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="Gateway_056f6tw_di" bpmnElement="Gateway_056f6tw" isMarkerVisible="true"> + <dc:Bounds x="625" y="95" width="50" height="50" /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="BPMNShape_1n4vu6v" bpmnElement="OrganizationProviderTest"> + <dc:Bounds x="480" y="300" width="100" height="80" /> + <bpmndi:BPMNLabel /> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="BPMNShape_1xcwytq" bpmnElement="EndpointProviderTest"> + <dc:Bounds x="480" y="410" width="100" height="80" /> + <bpmndi:BPMNLabel /> + </bpmndi:BPMNShape> + <bpmndi:BPMNEdge id="Flow_1bqddk1_di" bpmnElement="Flow_1bqddk1"> + <di:waypoint x="330" y="120" /> + <di:waypoint x="385" y="120" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_14rzc0j_di" bpmnElement="Flow_14rzc0j"> + <di:waypoint x="410" y="145" /> + <di:waypoint x="410" y="230" /> + <di:waypoint x="480" y="230" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_112zq99_di" bpmnElement="Flow_112zq99"> + <di:waypoint x="188" y="120" /> + <di:waypoint x="230" y="120" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0iy74da_di" bpmnElement="Flow_0iy74da"> + <di:waypoint x="435" y="120" /> + <di:waypoint x="480" y="120" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_08zzudo_di" bpmnElement="Flow_08zzudo"> + <di:waypoint x="580" y="230" /> + <di:waypoint x="650" y="230" /> + <di:waypoint x="650" y="145" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1mkx5o3_di" bpmnElement="Flow_1mkx5o3"> + <di:waypoint x="580" y="120" /> + <di:waypoint x="625" y="120" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0a1kwg9_di" bpmnElement="Flow_0a1kwg9"> + <di:waypoint x="675" y="120" /> + <di:waypoint x="712" y="120" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1h0pa8u_di" bpmnElement="Flow_1h0pa8u"> + <di:waypoint x="410" y="145" /> + <di:waypoint x="410" y="340" /> + <di:waypoint x="480" y="340" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_0usx9io_di" bpmnElement="Flow_0usx9io"> + <di:waypoint x="580" y="340" /> + <di:waypoint x="650" y="340" /> + <di:waypoint x="650" y="145" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1hhwby8_di" bpmnElement="Flow_1hhwby8"> + <di:waypoint x="410" y="145" /> + <di:waypoint x="410" y="450" /> + <di:waypoint x="480" y="450" /> + </bpmndi:BPMNEdge> + <bpmndi:BPMNEdge id="Flow_1bn9gvv_di" bpmnElement="Flow_1bn9gvv"> + <di:waypoint x="580" y="450" /> + <di:waypoint x="650" y="450" /> + <di:waypoint x="650" y="145" /> + </bpmndi:BPMNEdge> + </bpmndi:BPMNPlane> + </bpmndi:BPMNDiagram> +</bpmn:definitions> diff --git a/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/resources/fhir/ActivityDefinition/dsf-test.xml b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/resources/fhir/ActivityDefinition/dsf-test.xml new file mode 100644 index 000000000..98139eeb8 --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/resources/fhir/ActivityDefinition/dsf-test.xml @@ -0,0 +1,42 @@ +<ActivityDefinition xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <extension url="http://dsf.dev/fhir/StructureDefinition/extension-process-authorization"> + <extension url="message-name"> + <valueString value="start" /> + </extension> + <extension url="task-profile"> + <valueCanonical value="http://dsf.dev/fhir/StructureDefinition/task-test|#{version}" /> + </extension> + <extension url="requester"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> + <code value="LOCAL_ALL" /> + </valueCoding> + </extension> + <extension url="recipient"> + <valueCoding> + <system value="http://dsf.dev/fhir/CodeSystem/process-authorization" /> + <code value="LOCAL_ALL" /> + </valueCoding> + </extension> + </extension> + <url value="http://dsf.dev/bpe/Process/test" /> + <!-- version managed by bpe --> + <version value="#{version}" /> + <name value="Test" /> + <title value="Test" /> + <subtitle value="Test Process" /> + <!-- status managed by bpe --> + <status value="unknown" /> + <experimental value="false" /> + <!-- date managed by bpe --> + <date value="#{date}" /> + <publisher value="DSF" /> + <description value="Test process" /> + <kind value="Task" /> +</ActivityDefinition> \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/resources/fhir/CodeSystem/dsf-test.xml b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/resources/fhir/CodeSystem/dsf-test.xml new file mode 100644 index 000000000..ed9153da3 --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/resources/fhir/CodeSystem/dsf-test.xml @@ -0,0 +1,39 @@ +<CodeSystem xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <url value="http://dsf.dev/fhir/CodeSystem/test" /> + <!-- version managed by bpe --> + <version value="#{version}" /> + <name value="DSF_Test" /> + <title value="DSF Test" /> + <!-- status managed by bpe --> + <status value="unknown" /> + <experimental value="false" /> + <!-- date managed by bpe --> + <date value="#{date}" /> + <publisher value="DSF" /> + <description value="CodeSystem for process plugin integration testing" /> + <caseSensitive value="true" /> + <hierarchyMeaning value="grouped-by" /> + <versionNeeded value="false" /> + <content value="complete" /> + <concept> + <code value="test-activity" /> + <display value="Test Activity" /> + <definition value="Name of test activity to execute" /> + </concept> + <concept> + <code value="test-method-succeeded" /> + <display value="Test Method Succeeded" /> + <definition value="Name of succeeded test method" /> + </concept> + <concept> + <code value="test-method-failed" /> + <display value="Test Method Failed" /> + <definition value="Name of failed test method" /> + </concept> +</CodeSystem> \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/resources/fhir/StructureDefinition/dsf-task-test.xml b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/resources/fhir/StructureDefinition/dsf-task-test.xml new file mode 100644 index 000000000..3856429b5 --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/resources/fhir/StructureDefinition/dsf-task-test.xml @@ -0,0 +1,145 @@ +<StructureDefinition xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <url value="http://dsf.dev/fhir/StructureDefinition/task-test" /> + <!-- version managed by bpe --> + <version value="#{version}" /> + <name value="TaskTest" /> + <!-- status managed by bpe --> + <status value="unknown" /> + <experimental value="false" /> + <!-- date managed by bpe --> + <date value="#{date}" /> + <fhirVersion value="4.0.1" /> + <kind value="resource" /> + <abstract value="false" /> + <type value="Task" /> + <baseDefinition value="http://dsf.dev/fhir/StructureDefinition/task-base" /> + <derivation value="constraint" /> + <differential> + <element id="Task.instantiatesUri"> + <path value="Task.instantiatesUri" /> + <fixedUri value="http://dsf.dev/bpe/Process/test/#{version}" /> + </element> + <element id="Task.input"> + <path value="Task.input" /> + <min value="2" /> + <max value="3" /> + </element> + <element id="Task.input:message-name"> + <path value="Task.input" /> + <sliceName value="message-name" /> + </element> + <element id="Task.input:message-name.value[x]"> + <path value="Task.input.value[x]" /> + <fixedString value="start" /> + </element> + <element id="Task.input:correlation-key"> + <path value="Task.input" /> + <sliceName value="correlation-key" /> + <max value="0" /> + </element> + <element id="Task.input:test-activity"> + <path value="Task.input" /> + <sliceName value="test-activity" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Task.input:test-activity.type"> + <path value="Task.input.type" /> + <binding> + <strength value="required" /> + <valueSet value="http://dsf.dev/fhir/ValueSet/test|#{version}" /> + </binding> + </element> + <element id="Task.input:test-activity.type.coding"> + <path value="Task.input.type.coding" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Task.input:test-activity.type.coding.system"> + <path value="Task.input.type.coding.system" /> + <min value="1" /> + <fixedUri value="http://dsf.dev/fhir/CodeSystem/test" /> + </element> + <element id="Task.input:test-activity.type.coding.code"> + <path value="Task.input.type.coding.code" /> + <min value="1" /> + <fixedCode value="test-activity" /> + </element> + <element id="Task.input:test-activity.value[x]"> + <path value="Task.input.value[x]" /> + <type> + <code value="string" /> + </type> + </element> + <element id="Task.output:test-method-succeeded"> + <path value="Task.output" /> + <sliceName value="test-method-succeeded" /> + </element> + <element id="Task.output:test-method-succeeded.type"> + <path value="Task.output.type" /> + <binding> + <strength value="required" /> + <valueSet value="http://dsf.dev/fhir/ValueSet/test|#{version}" /> + </binding> + </element> + <element id="Task.output:test-method-succeeded.type.coding"> + <path value="Task.output.type.coding" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Task.output:test-method-succeeded.type.coding.system"> + <path value="Task.output.type.coding.system" /> + <min value="1" /> + <fixedUri value="http://dsf.dev/fhir/CodeSystem/test" /> + </element> + <element id="Task.output:test-method-succeeded.type.coding.code"> + <path value="Task.output.type.coding.code" /> + <min value="1" /> + <fixedCode value="test-method-succeeded" /> + </element> + <element id="Task.output:test-method-succeeded.value[x]"> + <path value="Task.output.value[x]" /> + <type> + <code value="string" /> + </type> + </element> + <element id="Task.output:test-method-failed"> + <path value="Task.output" /> + <sliceName value="test-method-failed" /> + </element> + <element id="Task.output:test-method-failed.type"> + <path value="Task.output.type" /> + <binding> + <strength value="required" /> + <valueSet value="http://dsf.dev/fhir/ValueSet/test|#{version}" /> + </binding> + </element> + <element id="Task.output:test-method-failed.type.coding"> + <path value="Task.output.type.coding" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Task.output:test-method-failed.type.coding.system"> + <path value="Task.output.type.coding.system" /> + <min value="1" /> + <fixedUri value="http://dsf.dev/fhir/CodeSystem/test" /> + </element> + <element id="Task.output:test-method-failed.type.coding.code"> + <path value="Task.output.type.coding.code" /> + <min value="1" /> + <fixedCode value="test-method-failed" /> + </element> + <element id="Task.output:test-method-failed.value[x]"> + <path value="Task.output.value[x]" /> + <type> + <code value="string" /> + </type> + </element> + </differential> +</StructureDefinition> \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/resources/fhir/ValueSet/dsf-test.xml b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/resources/fhir/ValueSet/dsf-test.xml new file mode 100644 index 000000000..fa9d0bba0 --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin-v2/src/main/resources/fhir/ValueSet/dsf-test.xml @@ -0,0 +1,27 @@ +<ValueSet xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <url value="http://dsf.dev/fhir/ValueSet/test" /> + <!-- version managed by bpe --> + <version value="#{version}" /> + <name value="DSF_Test" /> + <title value="DSF Test" /> + <!-- status managed by bpe --> + <status value="unknown" /> + <experimental value="false" /> + <!-- date managed by bpe --> + <date value="#{date}" /> + <publisher value="DSF" /> + <description value="ValueSet for process plugin integration testing" /> + <immutable value="true" /> + <compose> + <include> + <system value="http://dsf.dev/fhir/CodeSystem/test" /> + <version value="#{version}" /> + </include> + </compose> +</ValueSet> \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-test-plugin/pom.xml b/dsf-bpe/dsf-bpe-test-plugin/pom.xml new file mode 100644 index 000000000..244af9651 --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin/pom.xml @@ -0,0 +1,9 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>dev.dsf</groupId> + <artifactId>dsf-bpe-pom</artifactId> + <version>2.0.0-SNAPSHOT</version> + </parent> + <artifactId>dsf-bpe-test-plugin</artifactId> +</project> \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-test-plugin/src/main/java/dev/dsf/bpe/test/PluginTest.java b/dsf-bpe/dsf-bpe-test-plugin/src/main/java/dev/dsf/bpe/test/PluginTest.java new file mode 100644 index 000000000..c5544a3c1 --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin/src/main/java/dev/dsf/bpe/test/PluginTest.java @@ -0,0 +1,12 @@ +package dev.dsf.bpe.test; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD }) +public @interface PluginTest +{ +} \ No newline at end of file diff --git a/dsf-bpe/dsf-bpe-test-plugin/src/main/java/dev/dsf/bpe/test/PluginTestExecutor.java b/dsf-bpe/dsf-bpe-test-plugin/src/main/java/dev/dsf/bpe/test/PluginTestExecutor.java new file mode 100644 index 000000000..3df3c8e9e --- /dev/null +++ b/dsf-bpe/dsf-bpe-test-plugin/src/main/java/dev/dsf/bpe/test/PluginTestExecutor.java @@ -0,0 +1,194 @@ +package dev.dsf.bpe.test; + +import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; +import java.util.Objects; +import java.util.function.Consumer; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class PluginTestExecutor +{ + private static final Logger logger = LoggerFactory.getLogger(PluginTestExecutor.class); + + private static final class TestAssertException extends RuntimeException + { + private static final long serialVersionUID = 1L; + + public TestAssertException(String message) + { + super(message); + } + } + + public static final void execute(Object testClass, Consumer<String> addTestSucceededToStartTask, + Consumer<String> addTestFailedToStartTask, Runnable updateStartTask) + { + Arrays.stream(testClass.getClass().getDeclaredMethods()) + .filter(m -> m.getAnnotationsByType(PluginTest.class).length == 1) + .filter(m -> m.getParameterCount() == 0).forEach(m -> + { + try + { + logger.info("Executing test method {}.{} ...", testClass.getClass().getName(), m.getName()); + m.invoke(testClass); + logger.info("Executing test method {}.{} [succeeded]", testClass.getClass().getName(), + m.getName()); + + addTestSucceededToStartTask.accept(testClass.getClass().getName() + "." + m.getName()); + } + catch (InvocationTargetException e) + { + if (e.getCause() instanceof TestAssertException t) + { + String location = t.getStackTrace() != null && t.getStackTrace().length > 1 + ? (t.getStackTrace()[1].getClassName() + ":" + t.getStackTrace()[1].getLineNumber()) + : "?"; + logger.warn("Executing test method {}.{} [failed] - {} at {}", + testClass.getClass().getName(), m.getName(), t.getMessage(), location); + } + else + logger.error("Executing test method {}.{} [error] - {}: {}", testClass.getClass().getName(), + m.getName(), e.getClass().getName(), e.getMessage(), e); + + addTestFailedToStartTask.accept(testClass.getClass().getName() + "." + m.getName()); + } + catch (Exception e) + { + logger.error("Executing test method {}.{} [error] - {}: {}", testClass.getClass().getName(), + m.getName(), e.getClass().getName(), e.getMessage(), e); + + addTestFailedToStartTask.accept(testClass.getClass().getName() + "." + m.getName()); + } + }); + + updateStartTask.run(); + } + + public static void expectNotNull(Object actual) + { + if (actual == null) + throw new TestAssertException("Object is null, expected not null"); + } + + public static void expectNull(Object actual) + { + if (actual != null) + throw new TestAssertException(actual.getClass().getSimpleName() + " is not null, expected null"); + } + + public static void expectTrue(boolean actual) + { + if (!actual) + throw new TestAssertException("Boolean value is false, expected true"); + } + + public static void expectFalse(boolean actual) + { + if (actual) + throw new TestAssertException("Boolean value is true, expected false"); + } + + public static void expectSame(Object expected, Object actual) + { + if (!Objects.equals(expected, actual)) + throw createTestAssertExceptionNotSame("Object", Objects.toString(expected), Objects.toString(actual)); + } + + public static void expectSame(byte expected, byte actual) + { + if (expected != actual) + throw createTestAssertExceptionNotSame("byte", Objects.toString(expected), Objects.toString(actual)); + } + + public static void expectSame(int expected, int actual) + { + if (expected != actual) + throw createTestAssertExceptionNotSame("int", Objects.toString(expected), Objects.toString(actual)); + } + + public static void expectSame(long expected, long actual) + { + if (expected != actual) + throw createTestAssertExceptionNotSame("long", Objects.toString(expected), Objects.toString(actual)); + } + + public static void expectSame(float expected, float actual) + { + if (expected != actual) + throw createTestAssertExceptionNotSame("float", Objects.toString(expected), Objects.toString(actual)); + } + + public static void expectSame(double expected, double actual) + { + if (expected != actual) + throw createTestAssertExceptionNotSame("double", Objects.toString(expected), Objects.toString(actual)); + } + + public static void expectSame(char expected, char actual) + { + if (expected != actual) + throw createTestAssertExceptionNotSame("char", Objects.toString(expected), Objects.toString(actual)); + } + + public static void expectSame(byte[] expected, byte[] actual) + { + if (!Arrays.equals(expected, actual)) + throw createTestAssertExceptionNotSame("byte[]", Arrays.toString(expected), Arrays.toString(actual)); + } + + public static void expectSame(int[] expected, int[] actual) + { + if (!Arrays.equals(expected, actual)) + throw createTestAssertExceptionNotSame("int[]", Arrays.toString(expected), Arrays.toString(actual)); + } + + public static void expectSame(long[] expected, long[] actual) + { + if (!Arrays.equals(expected, actual)) + throw createTestAssertExceptionNotSame("long[]", Arrays.toString(expected), Arrays.toString(actual)); + } + + public static void expectSame(float[] expected, float[] actual) + { + if (!Arrays.equals(expected, actual)) + throw createTestAssertExceptionNotSame("float[]", Arrays.toString(expected), Arrays.toString(actual)); + } + + public static void expectSame(double[] expected, double[] actual) + { + if (!Arrays.equals(expected, actual)) + throw createTestAssertExceptionNotSame("double[]", Arrays.toString(expected), Arrays.toString(actual)); + } + + public static void expectSame(char[] expected, char[] actual) + { + if (!Arrays.equals(expected, actual)) + throw createTestAssertExceptionNotSame("char[]", Arrays.toString(expected), Arrays.toString(actual)); + } + + private static TestAssertException createTestAssertExceptionNotSame(String type, String expected, String actual) + { + throw new TestAssertException( + "Tested " + type + " is not same as expected [expected: " + expected + ", actual: " + actual + "]"); + } + + public static void expectException(Class<?> expectedException, Runnable run) + { + Objects.requireNonNull(expectedException, "expectedException"); + Objects.requireNonNull(run, "run"); + + try + { + run.run(); + } + catch (Exception e) + { + if (!expectedException.isInstance(e)) + throw new TestAssertException("Expected " + expectedException.getName() + " but caught " + + e.getClass().getName() + + (e.getMessage() != null && !e.getMessage().isBlank() ? " (" + e.getMessage() + ")" : "")); + } + } +} diff --git a/dsf-bpe/pom.xml b/dsf-bpe/pom.xml index 80503d3fd..1606f1f31 100755 --- a/dsf-bpe/pom.xml +++ b/dsf-bpe/pom.xml @@ -18,6 +18,9 @@ <module>dsf-bpe-process-api-v2-impl</module> <module>dsf-bpe-server</module> <module>dsf-bpe-server-jetty</module> + <module>dsf-bpe-test-plugin</module> + <module>dsf-bpe-test-plugin-v1</module> + <module>dsf-bpe-test-plugin-v2</module> </modules> <properties> @@ -56,40 +59,60 @@ <dependencies> <dependency> <groupId>dev.dsf</groupId> - <artifactId>dsf-bpe-server</artifactId> + <artifactId>dsf-bpe-process-api</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>dev.dsf</groupId> - <artifactId>dsf-bpe-jetty</artifactId> + <artifactId>dsf-bpe-process-api-v1</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>dev.dsf</groupId> - <artifactId>dsf-bpe-process-api</artifactId> + <artifactId>dsf-bpe-process-api-v1-impl</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>dev.dsf</groupId> - <artifactId>dsf-bpe-process-api-v1</artifactId> + <artifactId>dsf-bpe-process-api-v2</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>dev.dsf</groupId> - <artifactId>dsf-bpe-process-api-v1-impl</artifactId> + <artifactId>dsf-bpe-process-api-v2-impl</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>dev.dsf</groupId> - <artifactId>dsf-bpe-process-api-v2</artifactId> + <artifactId>dsf-bpe-server</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>dev.dsf</groupId> - <artifactId>dsf-bpe-process-api-v2-impl</artifactId> + <artifactId>dsf-bpe-server-jetty</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>dev.dsf</groupId> + <artifactId>dsf-bpe-test-plugin</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>dev.dsf</groupId> + <artifactId>dsf-bpe-test-plugin-v1</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>dev.dsf</groupId> + <artifactId>dsf-bpe-test-plugin-v2</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>dev.dsf</groupId> + <artifactId>dsf-fhir-server</artifactId> + <version>${project.version}</version> + </dependency> <dependency> <groupId>dev.dsf</groupId> <artifactId>dsf-fhir-websocket-client</artifactId> 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 78dd77ff2..8c47f0cf3 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 @@ -7,7 +7,6 @@ import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; @@ -170,7 +169,7 @@ private Map<String, Object> getPropertyMap(Map<String, Object> map, String prope if (propertyValue != null && propertyValue instanceof Map m) return m; else - return Collections.emptyMap(); + return Map.of(); } private List<String> getPropertyArray(Map<String, Object> map, String property) @@ -179,7 +178,7 @@ private List<String> getPropertyArray(Map<String, Object> map, String property) if (propertyValue != null && propertyValue instanceof Object[] o) return Arrays.stream(o).filter(v -> v instanceof String).map(v -> (String) v).toList(); else - return Collections.emptyList(); + return List.of(); } // thumbprint from certificate, token roles and groups from jwt @@ -306,7 +305,7 @@ private Optional<Practitioner> toPractitioner(JcaX509CertificateHolder certifica List<String> email2 = getValues(subject, BCStyle.EmailAddress); Extension subjectAlternativeNames = certificate.getExtension(Extension.subjectAlternativeName); - List<String> rfc822Names = subjectAlternativeNames == null ? Collections.emptyList() + List<String> rfc822Names = subjectAlternativeNames == null ? List.of() : Stream.of(GeneralNames.getInstance(subjectAlternativeNames.getParsedValue()).getNames()) .filter(n -> n.getTagNo() == GeneralName.rfc822Name).map(GeneralName::getName) .map(IETFUtils::valueToString).toList(); diff --git a/dsf-common/dsf-common-auth/src/main/java/dev/dsf/common/auth/conf/RoleConfig.java b/dsf-common/dsf-common-auth/src/main/java/dev/dsf/common/auth/conf/RoleConfig.java index 19e74f06c..34cbf419e 100644 --- a/dsf-common/dsf-common-auth/src/main/java/dev/dsf/common/auth/conf/RoleConfig.java +++ b/dsf-common/dsf-common-auth/src/main/java/dev/dsf/common/auth/conf/RoleConfig.java @@ -1,7 +1,6 @@ package dev.dsf.common.auth.conf; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; @@ -26,8 +25,8 @@ public class RoleConfig private static final String PROPERTY_DSF_ROLE = "dsf-role"; private static final String PROPERTY_PRACTITIONER_ROLE = "practitioner-role"; - private static final List<String> PROPERTIES = Arrays.asList(PROPERTY_THUMBPRINT, PROPERTY_EMAIL, - PROPERTY_TOKEN_ROLE, PROPERTY_TOKEN_GROUP, PROPERTY_DSF_ROLE, PROPERTY_PRACTITIONER_ROLE); + private static final List<String> PROPERTIES = List.of(PROPERTY_THUMBPRINT, PROPERTY_EMAIL, PROPERTY_TOKEN_ROLE, + PROPERTY_TOKEN_GROUP, PROPERTY_DSF_ROLE, PROPERTY_PRACTITIONER_ROLE); private static final String THUMBPRINT_PATTERN_STRING = "^[a-f0-9]{128}$"; private static final Pattern THUMBPRINT_PATTERN = Pattern.compile(THUMBPRINT_PATTERN_STRING); @@ -290,9 +289,9 @@ private static List<String> getValues(Object o) { return switch (o) { - case String s -> Collections.singletonList(s); + case String s -> List.of(s); case @SuppressWarnings("rawtypes") List l -> l; - default -> Collections.emptyList(); + default -> List.of(); }; } diff --git a/dsf-common/dsf-common-auth/src/test/java/dev/dsf/common/auth/RoleConfigTest.java b/dsf-common/dsf-common-auth/src/test/java/dev/dsf/common/auth/RoleConfigTest.java index 70d22ee91..3e5018b08 100644 --- a/dsf-common/dsf-common-auth/src/test/java/dev/dsf/common/auth/RoleConfigTest.java +++ b/dsf-common/dsf-common-auth/src/test/java/dev/dsf/common/auth/RoleConfigTest.java @@ -4,8 +4,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.function.Function; import java.util.stream.Stream; @@ -97,30 +95,27 @@ public void testRead() throws Exception assertNotNull(roles.getEntries()); assertEquals(5, roles.getEntries().size()); - assertMapping("foo", Arrays.asList( + assertMapping("foo", List.of( "f7f9ef095c5c246d3e8149729221e668b6ffd9a117fe23e2687658f6a203d31a0e769fb20dc2af6361306717116c700c5905a895a7311057af461c5d78a257b5"), - Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), - Arrays.asList(TestRole.foo, TestRole.bar, TestRole.baz), Collections.emptyList(), + List.of(), List.of(), List.of(), List.of(TestRole.foo, TestRole.bar, TestRole.baz), List.of(), roles.getEntries().get(0)); - assertMapping("bar", Arrays.asList( + assertMapping("bar", List.of( "2d259cc15ee2fe57bc11e1322040ee9e045dd3efb83ed1cb0f393c3bdfecaf3f6506e5573fbc213a1025a7c3dfef101fc8d85ab069e5662d666ea970c7e0cbb6", "b52a8b63b030181b8b6bc9ca1e47279da4842ef7ab46c08de6c5713a4e8ecc2c1d7f8cd5c17fe4eb0fe43838ee4b020a88634ea47c520dcc7f5f966b66e69190"), - Arrays.asList("one@test.com", "two@test.com"), Collections.emptyList(), Collections.emptyList(), - Arrays.asList(TestRole.foo, TestRole.baz), Collections.emptyList(), roles.getEntries().get(1)); + List.of("one@test.com", "two@test.com"), List.of(), List.of(), List.of(TestRole.foo, TestRole.baz), + List.of(), roles.getEntries().get(1)); - assertMapping("test1", Collections.emptyList(), Arrays.asList("someone@test.com"), Collections.emptyList(), - Collections.emptyList(), Arrays.asList(TestRole.foo, TestRole.bar), - Collections.singletonList(new Coding().setSystem("http://test.org/fhir/CodeSystem/foo").setCode("bar")), + assertMapping("test1", List.of(), List.of("someone@test.com"), List.of(), List.of(), + List.of(TestRole.foo, TestRole.bar), + List.of(new Coding().setSystem("http://test.org/fhir/CodeSystem/foo").setCode("bar")), roles.getEntries().get(2)); - assertMapping("test2", Collections.emptyList(), Collections.emptyList(), Arrays.asList("claim_a", "claim_b"), - Collections.emptyList(), Arrays.asList(TestRole.foo), Collections.emptyList(), - roles.getEntries().get(3)); + assertMapping("test2", List.of(), List.of(), List.of("claim_a", "claim_b"), List.of(), List.of(TestRole.foo), + List.of(), roles.getEntries().get(3)); - assertMapping("test3", Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), - Collections.singletonList("group1"), Arrays.asList(TestRole.foo), - Arrays.asList(new Coding().setSystem("http://test.org/fhir/CodeSystem/foo").setCode("bar"), + assertMapping("test3", List.of(), List.of(), List.of(), List.of("group1"), List.of(TestRole.foo), + List.of(new Coding().setSystem("http://test.org/fhir/CodeSystem/foo").setCode("bar"), new Coding().setSystem("http://test.org/fhir/CodeSystem/foo").setCode("baz")), roles.getEntries().get(4)); } diff --git a/dsf-common/dsf-common-config/src/test/java/dev/dsf/common/config/ProxyConfigTest.java b/dsf-common/dsf-common-config/src/test/java/dev/dsf/common/config/ProxyConfigTest.java index b9357ea9b..24603f438 100644 --- a/dsf-common/dsf-common-config/src/test/java/dev/dsf/common/config/ProxyConfigTest.java +++ b/dsf-common/dsf-common-config/src/test/java/dev/dsf/common/config/ProxyConfigTest.java @@ -39,6 +39,7 @@ public void testGetMethods() throws Exception { String url = "http://proxy", username = "username"; char[] password = "password".toCharArray(); + // Arrays.asList as we need a null element, not allowed in List.of List<String> noProxy = Arrays.asList(null, " ", "no-proxy"); ProxyConfigImpl c = new ProxyConfigImpl(url, username, password, noProxy); @@ -54,16 +55,16 @@ public void testGetMethods() throws Exception public void testIsEnabled() throws Exception { assertTrue(new ProxyConfigImpl("http://proxy", null, null, null).isEnabled()); - assertTrue(new ProxyConfigImpl("http://proxy", null, null, Arrays.asList("foo")).isEnabled()); + assertTrue(new ProxyConfigImpl("http://proxy", null, null, List.of("foo")).isEnabled()); assertFalse(new ProxyConfigImpl(null, null, null, null).isEnabled()); - assertFalse(new ProxyConfigImpl("http://proxy", null, null, Arrays.asList("*")).isEnabled()); + assertFalse(new ProxyConfigImpl("http://proxy", null, null, List.of("*")).isEnabled()); } @Test public void testIsEndabled() throws Exception { ProxyConfig proxyConfig = new ProxyConfigImpl("http://proxy", null, null, - Arrays.asList("foo.bar", "foo.bar.baz:8080", "test:1234")); + List.of("foo.bar", "foo.bar.baz:8080", "test:1234")); assertFalse(proxyConfig.isEnabled("http://foo.bar")); assertFalse(proxyConfig.isEnabled("http://foo.bar:8080")); @@ -85,7 +86,7 @@ public void testIsEndabled() throws Exception @Test public void testIsEnabledAllNoProxy() throws Exception { - ProxyConfig proxyConfig = new ProxyConfigImpl(null, null, null, Arrays.asList("*")); + ProxyConfig proxyConfig = new ProxyConfigImpl(null, null, null, List.of("*")); assertFalse(proxyConfig.isEnabled("http://foo.bar")); assertFalse(proxyConfig.isEnabled("http://foo.bar:8080")); @@ -106,15 +107,15 @@ public void testIsEnabledAllNoProxy() throws Exception public void testIsEnabledNull() throws Exception { assertFalse(new ProxyConfigImpl("http://proxy", null, null, null).isEnabled(null)); - assertFalse(new ProxyConfigImpl("http://proxy", null, null, Arrays.asList("*")).isEnabled(null)); + assertFalse(new ProxyConfigImpl("http://proxy", null, null, List.of("*")).isEnabled(null)); assertFalse(new ProxyConfigImpl("http://proxy", null, null, null).isEnabled(null)); } @Test public void testIsEnabledBlank() throws Exception { - assertFalse(new ProxyConfigImpl("http://proxy", null, null, Arrays.asList("*")).isEnabled("")); - assertFalse(new ProxyConfigImpl("http://proxy", null, null, Arrays.asList("*")).isEnabled(" ")); + assertFalse(new ProxyConfigImpl("http://proxy", null, null, List.of("*")).isEnabled("")); + assertFalse(new ProxyConfigImpl("http://proxy", null, null, List.of("*")).isEnabled(" ")); assertFalse(new ProxyConfigImpl("http://proxy", null, null, null).isEnabled("")); assertFalse(new ProxyConfigImpl("http://proxy", null, null, null).isEnabled(" ")); } @@ -122,7 +123,7 @@ public void testIsEnabledBlank() throws Exception @Test public void testIsEnabledMalformedUrl() throws Exception { - assertFalse(new ProxyConfigImpl("http://proxy", null, null, Arrays.asList("*")).isEnabled("malformed")); + assertFalse(new ProxyConfigImpl("http://proxy", null, null, List.of("*")).isEnabled("malformed")); assertTrue(new ProxyConfigImpl("http://proxy", null, null, null).isEnabled(":malformed")); assertTrue(new ProxyConfigImpl("http://proxy", null, null, null).isEnabled("malformed")); } diff --git a/dsf-common/dsf-common-jetty/src/main/java/dev/dsf/common/auth/DsfOpenIdCredentialsImpl.java b/dsf-common/dsf-common-jetty/src/main/java/dev/dsf/common/auth/DsfOpenIdCredentialsImpl.java index c0d8c9a11..a1e40ca1e 100644 --- a/dsf-common/dsf-common-jetty/src/main/java/dev/dsf/common/auth/DsfOpenIdCredentialsImpl.java +++ b/dsf-common/dsf-common-jetty/src/main/java/dev/dsf/common/auth/DsfOpenIdCredentialsImpl.java @@ -22,7 +22,7 @@ public DsfOpenIdCredentialsImpl(OpenIdCredentials credentials) public DsfOpenIdCredentialsImpl(String accessToken) { - this.idToken = Collections.emptyMap(); + this.idToken = Map.of(); this.accessToken = JwtDecoder.decode(accessToken); } diff --git a/dsf-common/dsf-common-jetty/src/main/java/dev/dsf/common/auth/jwk/Jwks.java b/dsf-common/dsf-common-jetty/src/main/java/dev/dsf/common/auth/jwk/Jwks.java index 84e9c586f..e7875332e 100644 --- a/dsf-common/dsf-common-jetty/src/main/java/dev/dsf/common/auth/jwk/Jwks.java +++ b/dsf-common/dsf-common-jetty/src/main/java/dev/dsf/common/auth/jwk/Jwks.java @@ -2,7 +2,6 @@ import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -34,7 +33,7 @@ public static Jwks from(String json) if (jwksJson instanceof Map) return new Jwks((Map<String, Object>) jwksJson); else - return new Jwks(Collections.emptyMap()); + return new Jwks(Map.of()); } public Jwk getKey(String id) 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 8fd65ec3d..a1001444d 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 @@ -20,7 +20,6 @@ import java.time.Duration; import java.time.temporal.ChronoUnit; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Map; @@ -230,7 +229,7 @@ public JettyServer jettyServer(ConfigurableEnvironment environment) { org.springframework.core.env.PropertySource<?> jettyProperties = environment.getPropertySources() .get("URL [file:conf/jetty.properties]"); - Map<String, String> initParameters = jettyProperties == null ? Collections.emptyMap() + Map<String, String> initParameters = jettyProperties == null ? Map.of() : ((Properties) jettyProperties.getSource()).entrySet().stream().collect( Collectors.toMap(e -> Objects.toString(e.getKey()), e -> Objects.toString(e.getValue()))); diff --git a/dsf-common/dsf-common-jetty/src/main/java/dev/dsf/common/jetty/JettyServer.java b/dsf-common/dsf-common-jetty/src/main/java/dev/dsf/common/jetty/JettyServer.java index e3a82ab75..4f265874c 100644 --- a/dsf-common/dsf-common-jetty/src/main/java/dev/dsf/common/jetty/JettyServer.java +++ b/dsf-common/dsf-common-jetty/src/main/java/dev/dsf/common/jetty/JettyServer.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.net.InetSocketAddress; +import java.net.SocketAddress; import java.net.StandardSocketOptions; import java.nio.channels.ServerSocketChannel; import java.security.KeyStore; @@ -59,9 +60,10 @@ private static HttpConnectionFactory httpConnectionFactory(Customizer... customi return new HttpConnectionFactory(httpConfiguration); } - public static ServerSocketChannel serverSocketChannel() + public static ServerSocketChannel serverSocketChannel(String hostname) { - InetSocketAddress bindAddress = new InetSocketAddress(0); + InetSocketAddress bindAddress = hostname == null ? new InetSocketAddress(0) + : new InetSocketAddress(hostname, 0); ServerSocketChannel serverChannel = null; try @@ -108,6 +110,7 @@ public static Function<Server, ServerConnector> statusConnector(ServerSocketChan { ServerConnector connector = new ServerConnector(server, httpConnectionFactory()); connector.open(channel); + setHostAndPort(channel, connector); return connector; } @@ -147,6 +150,7 @@ public static Function<Server, ServerConnector> httpConnector(ServerSocketChanne httpConnectionFactory(new ForwardedRequestCustomizer(), new ForwardedSecureRequestCustomizer(clientCertificateHeaderName))); connector.open(channel); + setHostAndPort(channel, connector); return connector; } @@ -173,6 +177,7 @@ server, sslConnectionFactory(clientCertificateTrustStore, serverCertificateKeySt keyStorePassword, needClientAuth), httpConnectionFactory(new SecureRequestCustomizer())); connector.open(channel); + setHostAndPort(channel, connector); return connector; } @@ -202,6 +207,17 @@ public static Function<Server, ServerConnector> httpsConnector(String host, int }; } + private static void setHostAndPort(ServerSocketChannel channel, ServerConnector connector) throws IOException + { + SocketAddress address = channel.getLocalAddress(); + if (address != null && address instanceof InetSocketAddress i && i.getAddress() != null + && i.getAddress().getHostAddress() != null) + { + connector.setHost(i.getAddress().getHostAddress()); + connector.setPort(i.getPort()); + } + } + private static SslConnectionFactory sslConnectionFactory(KeyStore clientCertificateTrustStore, KeyStore keyStore, char[] keyStorePassword, boolean needClientAuth) { @@ -342,8 +358,6 @@ protected void generateResponse(Request request, Response response, int code, St public void start() { - Runtime.getRuntime().addShutdownHook(new Thread(this::stop)); - try { logger.info("Starting jetty server ..."); @@ -367,6 +381,11 @@ public void start() } } + public void addShutdownHook() + { + Runtime.getRuntime().addShutdownHook(new Thread(this::stop)); + } + public void stop() { logger.info("Stopping jetty server ..."); diff --git a/dsf-common/dsf-common-ui/src/main/java/dev/dsf/common/ui/webservice/StaticResourcesService.java b/dsf-common/dsf-common-ui/src/main/java/dev/dsf/common/ui/webservice/StaticResourcesService.java index 0971463ff..13252313b 100644 --- a/dsf-common/dsf-common-ui/src/main/java/dev/dsf/common/ui/webservice/StaticResourcesService.java +++ b/dsf-common/dsf-common-ui/src/main/java/dev/dsf/common/ui/webservice/StaticResourcesService.java @@ -10,6 +10,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.function.Function; import java.util.regex.Pattern; @@ -73,22 +74,31 @@ private static String mimeType(String fileName) private static abstract class AbstractCache { + final String baseFolder; + + AbstractCache(String baseFolder) + { + this.baseFolder = Objects.requireNonNull(baseFolder, "baseFolder"); + } + abstract Optional<CacheEntry> get(String fileName); - protected CacheEntry read(InputStream stream, String fileName) throws IOException + CacheEntry read(InputStream stream, String fileName) throws IOException { byte[] data = stream.readAllBytes(); return new CacheEntry(data, fileName); } - protected InputStream getStream(String fileName) throws IOException + InputStream getStream(String fileName) throws IOException { - java.nio.file.Path target = OVERRIDE_RESOURCE_FOLDER.resolve(fileName); - if (Files.isReadable(target)) + java.nio.file.Path target = OVERRIDE_RESOURCE_FOLDER.resolve(fileName).normalize(); + if (target.getParent() == null || !target.getParent().equals(OVERRIDE_RESOURCE_FOLDER)) + return null; + else if (Files.isReadable(target)) return Files.newInputStream(target); else - return StaticResourcesService.class.getResourceAsStream("/static/" + fileName); + return StaticResourcesService.class.getResourceAsStream(baseFolder + "/static/" + fileName); } } @@ -96,6 +106,11 @@ private static final class Cache extends AbstractCache { private final Map<String, SoftReference<CacheEntry>> entries = new HashMap<>(); + Cache(String baseFolder) + { + super(baseFolder); + } + @Override Optional<CacheEntry> get(String fileName) { @@ -128,6 +143,11 @@ Optional<CacheEntry> read(String fileName) private static final class NoCache extends AbstractCache { + NoCache(String baseFolder) + { + super(baseFolder); + } + @Override Optional<CacheEntry> get(String fileName) { @@ -155,9 +175,13 @@ Optional<CacheEntry> get(String fileName) private final AbstractCache cache; private final CacheControl cacheControl; - public StaticResourcesService(boolean cacheEnabled) + public StaticResourcesService(String baseFolder, boolean cacheEnabled) { - cache = cacheEnabled ? new Cache() : new NoCache(); + Objects.requireNonNull(baseFolder, "baseFolder"); + if (!baseFolder.startsWith("/") || baseFolder.endsWith("/")) + throw new IllegalArgumentException("baseFolder must start with '/' and not end with '/'"); + + cache = cacheEnabled ? new Cache(baseFolder) : new NoCache(baseFolder); cacheControl = cacheEnabled ? NO_TRANSFORM : NO_CACHE_NO_TRANSFORM; } diff --git a/dsf-docker/fhir_proxy/Dockerfile b/dsf-docker/fhir_proxy/Dockerfile index 115969fa1..a89a5c1e5 100755 --- a/dsf-docker/fhir_proxy/Dockerfile +++ b/dsf-docker/fhir_proxy/Dockerfile @@ -1,47 +1,47 @@ -FROM httpd:2.4-alpine -LABEL org.opencontainers.image.source=https://github.com/datasharingframework/dsf -LABEL org.opencontainers.image.description="DSF FHIR Reverse Proxy" -LABEL org.opencontainers.image.licenses="Apache License, Version 2.0" - -WORKDIR /usr/local/apache2 -COPY ./ ./ -RUN chown daemon:daemon ./ca/ && \ - chmod 750 ./ca/ ./start.sh && \ - chmod 440 ./ca/client_cert_ca_chains.pem ./ca/client_cert_issuing_cas.pem && \ - chmod 644 ./conf/httpd.conf ./conf/extra/host.conf ./conf/extra/host-ssl.conf ./conf/extra/httpd-ssl.conf && \ - apk update && apk upgrade && rm -vrf /var/cache/apk/* - -# setting non existing default values, see host-ssl.conf IfFile tests -ENV SSL_CERTIFICATE_CHAIN_FILE="/does/not/exist" - -# trusted client certificate issuing CAs, modifies the "Acceptable client certificate CA names" send to the client, uses all from SSLCACertificateFile if set to a non existing file e.g. /does/not/exist -ENV SSL_CA_DN_REQUEST_FILE="ca/client_cert_issuing_cas.pem" - -# trusted full CA chains for validating client certificates -ENV SSL_CA_CERTIFICATE_FILE="ca/client_cert_ca_chains.pem" - -# setting default value - client certificate required, use 'optional' when using OIDC -ENV SSL_VERIFY_CLIENT="require" - -# expected client certificate subject DN country (C) values -ENV SSL_EXPECTED_CLIENT_S_DN_C_VALUES="'DE'" - -# expected client certificate issuer DN common-name (CN) values -ENV SSL_EXPECTED_CLIENT_I_DN_CN_VALUES="'GEANT TLS ECC 1', 'HARICA OV TLS ECC', 'GEANT TLS RSA 1', 'HARICA OV TLS RSA', 'GEANT S/MIME ECC 1', 'HARICA S/MIME ECC', 'GEANT S/MIME RSA 1', 'HARICA S/MIME RSA', 'DFN-Verein Global Issuing CA', 'Fraunhofer User CA - G02', 'D-TRUST SSL Class 3 CA 1 2009', 'Sectigo RSA Organization Validation Secure Server CA', 'GEANT OV RSA CA 4', 'GEANT Personal CA 4', 'GEANT eScience Personal CA 4', 'Sectigo ECC Organization Validation Secure Server CA', 'GEANT OV ECC CA 4', 'GEANT Personal ECC CA 4', 'GEANT eScience Personal ECC CA 4', 'D-TRUST Limited Basic CA 1-2 2019', 'D-TRUST Limited Basic CA 1-3 2019'" - -# timeout (seconds) for reverse proxy to app server http connection, time the proxy waits for a reply -ENV PROXY_PASS_TIMEOUT_HTTP=60 - -# timeout (seconds) for reverse proxy to app server ws connection, time the proxy waits for a reply -ENV PROXY_PASS_TIMEOUT_WS=60 - -# connection timeout (seconds) for reverse proxy to app server http connection, time the proxy waits for a connection to be established -ENV PROXY_PASS_CONNECTION_TIMEOUT_HTTP=30 - -# connection timeout (seconds) for reverse proxy to app server ws connection, time the proxy waits for a connection to be established -ENV PROXY_PASS_CONNECTION_TIMEOUT_WS=30 - -# server context path: / character at start, no / character at end -ENV SERVER_CONTEXT_PATH="/fhir" - +FROM httpd:2.4-alpine +LABEL org.opencontainers.image.source=https://github.com/datasharingframework/dsf +LABEL org.opencontainers.image.description="DSF FHIR Reverse Proxy" +LABEL org.opencontainers.image.licenses="Apache License, Version 2.0" + +WORKDIR /usr/local/apache2 +COPY ./ ./ +RUN chown daemon:daemon ./ca/ && \ + chmod 750 ./ca/ ./start.sh && \ + chmod 440 ./ca/client_cert_ca_chains.pem ./ca/client_cert_issuing_cas.pem && \ + chmod 644 ./conf/httpd.conf ./conf/extra/host.conf ./conf/extra/host-ssl.conf ./conf/extra/httpd-ssl.conf && \ + apk update && apk upgrade && rm -vrf /var/cache/apk/* + +# setting non existing default values, see host-ssl.conf IfFile tests +ENV SSL_CERTIFICATE_CHAIN_FILE="/does/not/exist" + +# trusted client certificate issuing CAs, modifies the "Acceptable client certificate CA names" send to the client, uses all from SSLCACertificateFile if set to a non existing file e.g. /does/not/exist +ENV SSL_CA_DN_REQUEST_FILE="ca/client_cert_issuing_cas.pem" + +# trusted full CA chains for validating client certificates +ENV SSL_CA_CERTIFICATE_FILE="ca/client_cert_ca_chains.pem" + +# setting default value - client certificate required, use 'optional' when using OIDC +ENV SSL_VERIFY_CLIENT="require" + +# expected client certificate subject DN country (C) values +ENV SSL_EXPECTED_CLIENT_S_DN_C_VALUES="'DE'" + +# expected client certificate issuer DN common-name (CN) values +ENV SSL_EXPECTED_CLIENT_I_DN_CN_VALUES="'GEANT TLS ECC 1', 'HARICA OV TLS ECC', 'GEANT TLS RSA 1', 'HARICA OV TLS RSA', 'GEANT S/MIME ECC 1', 'HARICA S/MIME ECC', 'GEANT S/MIME RSA 1', 'HARICA S/MIME RSA', 'DFN-Verein Global Issuing CA', 'Fraunhofer User CA - G02', 'D-TRUST SSL Class 3 CA 1 2009', 'Sectigo RSA Organization Validation Secure Server CA', 'GEANT OV RSA CA 4', 'GEANT Personal CA 4', 'GEANT eScience Personal CA 4', 'Sectigo ECC Organization Validation Secure Server CA', 'GEANT OV ECC CA 4', 'GEANT Personal ECC CA 4', 'GEANT eScience Personal ECC CA 4', 'D-TRUST Limited Basic CA 1-2 2019', 'D-TRUST Limited Basic CA 1-3 2019'" + +# timeout (seconds) for reverse proxy to app server http connection, time the proxy waits for a reply +ENV PROXY_PASS_TIMEOUT_HTTP=60 + +# timeout (seconds) for reverse proxy to app server ws connection, time the proxy waits for a reply +ENV PROXY_PASS_TIMEOUT_WS=60 + +# connection timeout (seconds) for reverse proxy to app server http connection, time the proxy waits for a connection to be established +ENV PROXY_PASS_CONNECTION_TIMEOUT_HTTP=30 + +# connection timeout (seconds) for reverse proxy to app server ws connection, time the proxy waits for a connection to be established +ENV PROXY_PASS_CONNECTION_TIMEOUT_WS=30 + +# server context path: / character at start, no / character at end +ENV SERVER_CONTEXT_PATH="/fhir" + ENTRYPOINT [ "sh", "./start.sh" ] \ No newline at end of file diff --git a/dsf-docker/fhir_proxy/conf/extra/host.conf b/dsf-docker/fhir_proxy/conf/extra/host.conf index 2f75893d2..e7f135d1d 100755 --- a/dsf-docker/fhir_proxy/conf/extra/host.conf +++ b/dsf-docker/fhir_proxy/conf/extra/host.conf @@ -1,3 +1,3 @@ -<VirtualHost *:80> - Redirect permanent / https://${HTTPS_SERVER_NAME_PORT}/ +<VirtualHost *:80> + Redirect permanent / https://${HTTPS_SERVER_NAME_PORT}/ </VirtualHost> \ No newline at end of file diff --git a/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/process/All.java b/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/process/All.java index 05e65770c..8abc6e996 100644 --- a/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/process/All.java +++ b/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/process/All.java @@ -1,6 +1,5 @@ package dev.dsf.fhir.authorization.process; -import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.Set; @@ -61,7 +60,7 @@ private Set<Coding> getPractitionerRoles(Identity identity) if (identity instanceof PractitionerIdentity p) return p.getPractionerRoles(); else - return Collections.emptySet(); + return Set.of(); } private boolean hasPractitionerRole(Set<Coding> practitionerRoles) diff --git a/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/process/Organization.java b/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/process/Organization.java index 9cfed6494..1788df80a 100644 --- a/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/process/Organization.java +++ b/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/process/Organization.java @@ -1,6 +1,5 @@ package dev.dsf.fhir.authorization.process; -import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -79,7 +78,7 @@ private Set<Coding> getPractitionerRoles(Identity identity) if (identity instanceof PractitionerIdentity p) return p.getPractionerRoles(); else - return Collections.emptySet(); + return Set.of(); } private boolean hasPractitionerRole(Set<Coding> practitionerRoles) diff --git a/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/process/ProcessAuthorizationHelper.java b/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/process/ProcessAuthorizationHelper.java index 1745f0494..d61f79455 100644 --- a/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/process/ProcessAuthorizationHelper.java +++ b/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/process/ProcessAuthorizationHelper.java @@ -1,7 +1,7 @@ package dev.dsf.fhir.authorization.process; import java.util.Collection; -import java.util.Collections; +import java.util.List; import java.util.function.Predicate; import java.util.stream.Stream; @@ -62,8 +62,7 @@ boolean isValid(ActivityDefinition activityDefinition, Predicate<CanonicalType> default Stream<Requester> getRequesters(ActivityDefinition activityDefinition, String processUrl, String processVersion, String messageName, String taskProfile) { - return getRequesters(activityDefinition, processUrl, processVersion, messageName, - Collections.singleton(taskProfile)); + return getRequesters(activityDefinition, processUrl, processVersion, messageName, List.of(taskProfile)); } Stream<Requester> getRequesters(ActivityDefinition activityDefinition, String processUrl, String processVersion, @@ -72,8 +71,7 @@ Stream<Requester> getRequesters(ActivityDefinition activityDefinition, String pr default Stream<Recipient> getRecipients(ActivityDefinition activityDefinition, String processUrl, String processVersion, String messageName, String taskProfiles) { - return getRecipients(activityDefinition, processUrl, processVersion, messageName, - Collections.singleton(taskProfiles)); + return getRecipients(activityDefinition, processUrl, processVersion, messageName, List.of(taskProfiles)); } Stream<Recipient> getRecipients(ActivityDefinition activityDefinition, String processUrl, String processVersion, diff --git a/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/process/Role.java b/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/process/Role.java index a5d07be4d..e1b38184b 100644 --- a/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/process/Role.java +++ b/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/process/Role.java @@ -1,6 +1,5 @@ package dev.dsf.fhir.authorization.process; -import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -120,7 +119,7 @@ private Set<Coding> getPractitionerRoles(Identity identity) if (identity instanceof PractitionerIdentity p) return p.getPractionerRoles(); else - return Collections.emptySet(); + return Set.of(); } private boolean hasPractitionerRole(Set<Coding> practitionerRoles) diff --git a/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/read/ReadAccessHelperImpl.java b/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/read/ReadAccessHelperImpl.java index 5996978a5..8d758f312 100644 --- a/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/read/ReadAccessHelperImpl.java +++ b/dsf-fhir/dsf-fhir-auth/src/main/java/dev/dsf/fhir/authorization/read/ReadAccessHelperImpl.java @@ -1,6 +1,5 @@ package dev.dsf.fhir.authorization.read; -import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -19,7 +18,7 @@ public class ReadAccessHelperImpl implements ReadAccessHelper { - private static final List<String> READ_ACCESS_TAG_VALUES = Arrays.asList(READ_ACCESS_TAG_VALUE_LOCAL, + private static final List<String> READ_ACCESS_TAG_VALUES = List.of(READ_ACCESS_TAG_VALUE_LOCAL, READ_ACCESS_TAG_VALUE_ORGANIZATION, READ_ACCESS_TAG_VALUE_ROLE, READ_ACCESS_TAG_VALUE_ALL); private Predicate<Coding> matchesTagValue(String value) diff --git a/dsf-fhir/dsf-fhir-auth/src/test/java/dev/dsf/fhir/authorization/process/ProcessAuthorizationHelperTest.java b/dsf-fhir/dsf-fhir-auth/src/test/java/dev/dsf/fhir/authorization/process/ProcessAuthorizationHelperTest.java index 46df86e73..286bfc234 100644 --- a/dsf-fhir/dsf-fhir-auth/src/test/java/dev/dsf/fhir/authorization/process/ProcessAuthorizationHelperTest.java +++ b/dsf-fhir/dsf-fhir-auth/src/test/java/dev/dsf/fhir/authorization/process/ProcessAuthorizationHelperTest.java @@ -8,8 +8,6 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Paths; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -117,7 +115,7 @@ public void testGetRequesterRemoteAllRecipientLocalAllViaFile() throws Exception requestersList.get(0).getProcessAuthorizationCode().getCode()); assertTrue(requestersList.get(0).isRequesterAuthorized( TestOrganizationIdentity.remote(new org.hl7.fhir.r4.model.Organization().setActive(true)), - Collections.emptyList())); + List.of())); Stream<Recipient> recipients = helper.getRecipients(ad, "http://dsf.dev/bpe/Process/test", "1.0.0", "foo", "http://bar.org/fhir/StructureDefinition/baz"); @@ -129,7 +127,7 @@ public void testGetRequesterRemoteAllRecipientLocalAllViaFile() throws Exception recipientsList.get(0).getProcessAuthorizationCode().getCode()); assertTrue(recipientsList.get(0).isRecipientAuthorized( TestOrganizationIdentity.local(new org.hl7.fhir.r4.model.Organization().setActive(true)), - Collections.emptyList())); + List.of())); } } @@ -154,7 +152,7 @@ public void testGetRequesterRemoteOrganizationRecipientLocalParentOrganizationRo .addIdentifier(new Identifier() .setSystem(ProcessAuthorizationHelper.ORGANIZATION_IDENTIFIER_SYSTEM) .setValue("organization.com"))); - assertTrue(requestersList.get(0).isRequesterAuthorized(remoteUser, Collections.emptyList())); + assertTrue(requestersList.get(0).isRequesterAuthorized(remoteUser, List.of())); Stream<Recipient> recipients = helper.getRecipients(ad, "http://dsf.dev/bpe/Process/test", "1.0.0", "foo", "http://bar.org/fhir/StructureDefinition/baz"); @@ -175,7 +173,7 @@ public void testGetRequesterRemoteOrganizationRecipientLocalParentOrganizationRo .setSystem(ProcessAuthorizationHelper.ORGANIZATION_IDENTIFIER_SYSTEM).setValue("member.com"); affiliation.getCodeFirstRep().getCodingFirstRep() .setSystem("http://dsf.dev/fhir/CodeSystem/organization-role").setCode("DIC"); - assertTrue(recipientsList.get(0).isRecipientAuthorized(localUser, Collections.singleton(affiliation))); + assertTrue(recipientsList.get(0).isRecipientAuthorized(localUser, List.of(affiliation))); } } @@ -268,8 +266,8 @@ public void testAddRequesterLocalAllRemoteAllRecipientLocalAll() throws Exceptio var ad = createActivityDefinition(); - ad = helper.add(ad, messageName, taskProfile, Arrays.asList(requesterLocalAll, requesterRemoteAll), - Collections.singleton(recipientLocalAll)); + ad = helper.add(ad, messageName, taskProfile, List.of(requesterLocalAll, requesterRemoteAll), + List.of(recipientLocalAll)); assertNotNull(ad); assertTrue(ad.hasExtension()); @@ -370,8 +368,8 @@ public void testAddRequesterLocalOrgRemoteOrgRecipientLocalOrg() throws Exceptio var ad = createActivityDefinition(); - ad = helper.add(ad, messageName, taskProfile, Arrays.asList(requesterLocalOrg, requesterRemoteOrg), - Collections.singleton(recipientLocalOrg)); + ad = helper.add(ad, messageName, taskProfile, List.of(requesterLocalOrg, requesterRemoteOrg), + List.of(recipientLocalOrg)); assertNotNull(ad); assertTrue(ad.hasExtension()); @@ -528,8 +526,8 @@ public void testAddRequesterLocalRoleRemoteRoleRecipientLocalRole() throws Excep var ad = createActivityDefinition(); - ad = helper.add(ad, messageName, taskProfile, Arrays.asList(requesterLocalRole, requesterRemoteRole), - Collections.singleton(recipientLocalRole)); + ad = helper.add(ad, messageName, taskProfile, List.of(requesterLocalRole, requesterRemoteRole), + List.of(recipientLocalRole)); assertNotNull(ad); assertTrue(ad.hasExtension()); @@ -734,8 +732,8 @@ public void testAddRequesterLocalAllPractitioner() throws Exception var ad = createActivityDefinition(); - ad = helper.add(ad, messageName, taskProfile, Collections.singleton(requesterLocalAllPractitioner), - Collections.singleton(recipientLocalAll)); + ad = helper.add(ad, messageName, taskProfile, List.of(requesterLocalAllPractitioner), + List.of(recipientLocalAll)); assertNotNull(ad); assertTrue(ad.hasExtension()); @@ -835,8 +833,8 @@ public void testAddRequesterLocalOrganizationPractitioner() throws Exception var ad = createActivityDefinition(); - ad = helper.add(ad, messageName, taskProfile, Collections.singleton(requesterLocalOrganizationPractitioner), - Collections.singleton(recipientLocalAll)); + ad = helper.add(ad, messageName, taskProfile, List.of(requesterLocalOrganizationPractitioner), + List.of(recipientLocalAll)); assertNotNull(ad); assertTrue(ad.hasExtension()); @@ -956,8 +954,8 @@ public void testAddRequesterLocalRolePractitioner() throws Exception var ad = createActivityDefinition(); - ad = helper.add(ad, messageName, taskProfile, Collections.singleton(requesterLocalRolePractitioner), - Collections.singleton(recipientLocalAll)); + ad = helper.add(ad, messageName, taskProfile, List.of(requesterLocalRolePractitioner), + List.of(recipientLocalAll)); logger.debug(FhirContext.forR4().newXmlParser().setPrettyPrint(true).encodeResourceToString(ad)); diff --git a/dsf-fhir/dsf-fhir-auth/src/test/java/dev/dsf/fhir/authorization/process/TestPractitionerIdentity.java b/dsf-fhir/dsf-fhir-auth/src/test/java/dev/dsf/fhir/authorization/process/TestPractitionerIdentity.java index 2b333db00..2fb568251 100644 --- a/dsf-fhir/dsf-fhir-auth/src/test/java/dev/dsf/fhir/authorization/process/TestPractitionerIdentity.java +++ b/dsf-fhir/dsf-fhir-auth/src/test/java/dev/dsf/fhir/authorization/process/TestPractitionerIdentity.java @@ -1,9 +1,9 @@ package dev.dsf.fhir.authorization.process; import java.security.cert.X509Certificate; -import java.util.Arrays; import java.util.Collection; import java.util.HashSet; +import java.util.List; import java.util.Optional; import java.util.Set; @@ -30,7 +30,7 @@ private TestPractitionerIdentity(Organization organization, Collection<Coding> r public static TestPractitionerIdentity practitioner(Organization organization, Coding... roles) { - return new TestPractitionerIdentity(organization, Arrays.asList(roles)); + return new TestPractitionerIdentity(organization, List.of(roles)); } @Override diff --git a/dsf-fhir/dsf-fhir-rest-adapter/src/main/java/dev/dsf/fhir/service/ResourceReference.java b/dsf-fhir/dsf-fhir-rest-adapter/src/main/java/dev/dsf/fhir/service/ResourceReference.java index d4015defd..3b69687e6 100644 --- a/dsf-fhir/dsf-fhir-rest-adapter/src/main/java/dev/dsf/fhir/service/ResourceReference.java +++ b/dsf-fhir/dsf-fhir-rest-adapter/src/main/java/dev/dsf/fhir/service/ResourceReference.java @@ -165,12 +165,12 @@ public ResourceReference(String location, Reference reference, Class<? extends R public ResourceReference(String location, RelatedArtifact relatedArtifact) { - this(location, null, relatedArtifact, null, null, Collections.emptyList()); + this(location, null, relatedArtifact, null, null, List.of()); } public ResourceReference(String location, Attachment attachment) { - this(location, null, null, attachment, null, Collections.emptyList()); + this(location, null, null, attachment, null, List.of()); } @SafeVarargs diff --git a/dsf-fhir/dsf-fhir-server-jetty/conf/jetty.properties b/dsf-fhir/dsf-fhir-server-jetty/conf/jetty.properties index 7af2bbc07..504b17529 100755 --- a/dsf-fhir/dsf-fhir-server-jetty/conf/jetty.properties +++ b/dsf-fhir/dsf-fhir-server-jetty/conf/jetty.properties @@ -1,9 +1,9 @@ -dev.dsf.server.api.port=8001 -dev.dsf.server.status.port=10001 -dev.dsf.server.context.path=/fhir - -dev.dsf.server.certificate=target/localhost_certificate.pem -dev.dsf.server.certificate.key=target/localhost_private-key.pem -dev.dsf.server.certificate.key.password=password - +dev.dsf.server.api.port=8001 +dev.dsf.server.status.port=10001 +dev.dsf.server.context.path=/fhir + +dev.dsf.server.certificate=target/localhost_certificate.pem +dev.dsf.server.certificate.key=target/localhost_private-key.pem +dev.dsf.server.certificate.key.password=password + dev.dsf.server.auth.trust.client.certificate.cas=target/testca_certificate.pem \ No newline at end of file diff --git a/dsf-fhir/dsf-fhir-server-jetty/src/main/java/dev/dsf/fhir/FhirJettyServer.java b/dsf-fhir/dsf-fhir-server-jetty/src/main/java/dev/dsf/fhir/FhirJettyServer.java index 604dce0cb..23dd79aa5 100755 --- a/dsf-fhir/dsf-fhir-server-jetty/src/main/java/dev/dsf/fhir/FhirJettyServer.java +++ b/dsf-fhir/dsf-fhir-server-jetty/src/main/java/dev/dsf/fhir/FhirJettyServer.java @@ -36,6 +36,8 @@ public static void main(String[] args) FhirHttpJettyConfig.class)) { JettyServer server = context.getBean(JettyServer.class); + + server.addShutdownHook(); server.start(); } } diff --git a/dsf-fhir/dsf-fhir-server-jetty/src/main/java/dev/dsf/fhir/FhirJettyServerHttps.java b/dsf-fhir/dsf-fhir-server-jetty/src/main/java/dev/dsf/fhir/FhirJettyServerHttps.java index f49c1b02b..9fbaa3c5a 100755 --- a/dsf-fhir/dsf-fhir-server-jetty/src/main/java/dev/dsf/fhir/FhirJettyServerHttps.java +++ b/dsf-fhir/dsf-fhir-server-jetty/src/main/java/dev/dsf/fhir/FhirJettyServerHttps.java @@ -36,6 +36,8 @@ public static void main(String[] args) FhirHttpsJettyConfig.class)) { JettyServer server = context.getBean(JettyServer.class); + + server.addShutdownHook(); server.start(); } } diff --git a/dsf-fhir/dsf-fhir-server-jetty/src/main/java/dev/dsf/fhir/config/FhirDbMigratorConfig.java b/dsf-fhir/dsf-fhir-server-jetty/src/main/java/dev/dsf/fhir/config/FhirDbMigratorConfig.java index 34522d871..cdfad2f00 100644 --- a/dsf-fhir/dsf-fhir-server-jetty/src/main/java/dev/dsf/fhir/config/FhirDbMigratorConfig.java +++ b/dsf-fhir/dsf-fhir-server-jetty/src/main/java/dev/dsf/fhir/config/FhirDbMigratorConfig.java @@ -96,6 +96,12 @@ public char[] getDbLiquibasePassword() return dbLiquibasePassword; } + @Override + public String getChangelogFile() + { + return "fhir/db/db.changelog.xml"; + } + @Override public Map<String, String> getChangeLogParameters() { 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 46a0c6e9d..53dc566c0 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 @@ -115,7 +115,7 @@ public ThymeleafTemplateServiceImpl(String serverBaseUrl, Theme theme, FhirConte ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver(); resolver.setTemplateMode(TemplateMode.HTML); - resolver.setPrefix("/template/"); + resolver.setPrefix("/fhir/template/"); resolver.setSuffix(".html"); resolver.setCacheable(cacheEnabled); diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authentication/OrganizationProviderImpl.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authentication/OrganizationProviderImpl.java index 0edb1e42f..c708aead5 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authentication/OrganizationProviderImpl.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authentication/OrganizationProviderImpl.java @@ -4,7 +4,7 @@ import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; -import java.util.Collections; +import java.util.List; import java.util.Objects; import java.util.Optional; @@ -84,6 +84,6 @@ public String getLocalOrganizationIdentifierValue() @Override public Optional<Identity> getLocalOrganizationAsIdentity() { - return getLocalOrganization().map(o -> new OrganizationIdentityImpl(true, o, Collections.emptySet(), null)); + return getLocalOrganization().map(o -> new OrganizationIdentityImpl(true, o, List.of(), null)); } } diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/AbstractAuthorizationRule.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/AbstractAuthorizationRule.java index 4e978a6e3..d87c826f9 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/AbstractAuthorizationRule.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/AbstractAuthorizationRule.java @@ -3,7 +3,6 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.Collection; -import java.util.Collections; import java.util.EnumSet; import java.util.List; import java.util.Map; @@ -133,7 +132,7 @@ public final Optional<String> reasonReadAllowed(Identity identity, R existingRes protected List<OrganizationAffiliation> getAffiliations(Connection connection, String organizationIdentifierValue) { if (organizationIdentifierValue == null) - return Collections.emptyList(); + return List.of(); try { @@ -187,8 +186,7 @@ protected final boolean organizationWithIdentifierExists(Connection connection, String iSystem = organizationIdentifier.getSystem(); String iValue = organizationIdentifier.getValue(); - Map<String, List<String>> queryParameters = Map.of("identifier", - Collections.singletonList(iSystem + "|" + iValue)); + Map<String, List<String>> queryParameters = Map.of("identifier", List.of(iSystem + "|" + iValue)); OrganizationDao dao = daoProvider.getOrganizationDao(); SearchQuery<Organization> query = dao.createSearchQueryWithoutUserFilter(PageAndCount.exists()) .configureParameters(queryParameters); @@ -222,7 +220,7 @@ protected final boolean roleExists(Connection connection, Coding coding) String cCode = coding.getCode(); Map<String, List<String>> queryParameters = Map.of("url", - Collections.singletonList(cSystem + (coding.hasVersion() ? "|" + cVersion : ""))); + List.of(cSystem + (coding.hasVersion() ? "|" + cVersion : ""))); CodeSystemDao dao = daoProvider.getCodeSystemDao(); SearchQuery<CodeSystem> query = dao.createSearchQueryWithoutUserFilter(PageAndCount.single()) .configureParameters(queryParameters); diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/EndpointAuthorizationRule.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/EndpointAuthorizationRule.java index 9c663bea3..a5fc3de73 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/EndpointAuthorizationRule.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/EndpointAuthorizationRule.java @@ -3,7 +3,6 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; @@ -110,7 +109,7 @@ protected boolean resourceExists(Connection connection, Endpoint newResource) private boolean endpointWithAddressExists(Connection connection, String address) { - Map<String, List<String>> queryParameters = Map.of("address", Collections.singletonList(address)); + Map<String, List<String>> queryParameters = Map.of("address", List.of(address)); EndpointDao dao = getDao(); SearchQuery<Endpoint> query = dao.createSearchQueryWithoutUserFilter(PageAndCount.exists()) .configureParameters(queryParameters); @@ -140,7 +139,7 @@ private boolean endpointWithAddressExists(Connection connection, String address) private boolean endpointWithIdentifierExists(Connection connection, String identifierValue) { Map<String, List<String>> queryParameters = Map.of("identifier", - Collections.singletonList(ENDPOINT_IDENTIFIER_SYSTEM + "|" + identifierValue)); + List.of(ENDPOINT_IDENTIFIER_SYSTEM + "|" + identifierValue)); EndpointDao dao = getDao(); SearchQuery<Endpoint> query = dao.createSearchQueryWithoutUserFilter(PageAndCount.exists()) .configureParameters(queryParameters); diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/OrganizationAffiliationAuthorizationRule.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/OrganizationAffiliationAuthorizationRule.java index afa3fab62..562d594b1 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/OrganizationAffiliationAuthorizationRule.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/OrganizationAffiliationAuthorizationRule.java @@ -3,7 +3,6 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; @@ -146,10 +145,9 @@ private boolean organizationAffiliationWithParentAndMemberAndAnyRoleExists(Conne private Map<String, List<String>> queryParameters(OrganizationAffiliation newResource, String param, String value) { - return Map.of("primary-organization", Collections.singletonList(newResource.getOrganization().getReference()), - "participating-organization", - Collections.singletonList(newResource.getParticipatingOrganization().getReference()), param, - Collections.singletonList(value)); + return Map.of("primary-organization", List.of(newResource.getOrganization().getReference()), + "participating-organization", List.of(newResource.getParticipatingOrganization().getReference()), param, + List.of(value)); } private boolean organizationAffiliationExists(Connection connection, Map<String, List<String>> queryParameters) diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/OrganizationAuthorizationRule.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/OrganizationAuthorizationRule.java index 3933ea14e..fbe8eeda7 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/OrganizationAuthorizationRule.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/OrganizationAuthorizationRule.java @@ -3,7 +3,6 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.regex.Pattern; @@ -108,7 +107,7 @@ protected boolean resourceExists(Connection connection, Organization newResource .findFirst().orElseThrow(); return (newResource.getMeta().hasProfile(DSF_ORGANIZATION) - && resourceExistsWithThumbprint(connection, newResource, Collections.emptyList())) + && resourceExistsWithThumbprint(connection, newResource, List.of())) || organizationWithIdentifierExists(connection, organizationIdentifier); } diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/SubscriptionAuthorizationRule.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/SubscriptionAuthorizationRule.java index c1e1c978f..73b40c855 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/SubscriptionAuthorizationRule.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/authorization/SubscriptionAuthorizationRule.java @@ -3,9 +3,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; @@ -25,7 +23,6 @@ import dev.dsf.fhir.dao.provider.DaoProvider; import dev.dsf.fhir.help.ParameterConverter; import dev.dsf.fhir.search.PageAndCount; -import dev.dsf.fhir.search.PartialResult; import dev.dsf.fhir.search.SearchQuery; import dev.dsf.fhir.search.SearchQueryParameterError; import dev.dsf.fhir.service.ReferenceResolver; @@ -128,26 +125,10 @@ private Optional<String> newResourceOk(Connection connection, Subscription newRe @Override protected boolean resourceExists(Connection connection, Subscription newResource) { - Map<String, List<String>> queryParameters = Map.of("criteria", - Collections.singletonList(newResource.getCriteria()), "type", - Collections.singletonList(newResource.getChannel().getType().toCode()), "payload", - Collections.singletonList(newResource.getChannel().getPayload())); - SubscriptionDao dao = getDao(); - SearchQuery<Subscription> query = dao.createSearchQueryWithoutUserFilter(PageAndCount.exists()) - .configureParameters(queryParameters); - - List<SearchQueryParameterError> uQp = query.getUnsupportedQueryParameters(); - if (!uQp.isEmpty()) - { - logger.warn("Unable to search for Subscription: Unsupported query parameters: {}", uQp); - - throw new IllegalStateException("Unable to search for Subscription: Unsupported query parameters"); - } - try { - PartialResult<Subscription> result = dao.searchWithTransaction(connection, query); - return result.getTotal() >= 1; + return getDao().existsByCriteriaChannelTypeAndChannelPayload(newResource.getCriteria(), + newResource.getChannel().getType().toCode(), newResource.getChannel().getPayload()); } catch (SQLException e) { diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/SubscriptionDao.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/SubscriptionDao.java index 9bfa023f4..c7029299a 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/SubscriptionDao.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/SubscriptionDao.java @@ -9,4 +9,7 @@ public interface SubscriptionDao extends ResourceDao<Subscription> { List<Subscription> readByStatus(SubscriptionStatus status) throws SQLException; + + boolean existsByCriteriaChannelTypeAndChannelPayload(String criteria, String channelType, String channelPayload) + throws SQLException; } 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 d944d1695..ab6f31ada 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 @@ -198,7 +198,10 @@ public Bundle execute() throws WebApplicationException connection.rollback(); if (PSQLState.UNIQUE_VIOLATION.getState().equals(e.getSQLState())) - throw new WebApplicationException(responseGenerator.duplicateResourceExists()); + { + Response response = responseGenerator.duplicateResourceExists(); + throw new WebApplicationException(response); + } else throw e; } diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/jdbc/HistroyDaoJdbc.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/jdbc/HistroyDaoJdbc.java index b4be34a97..4b82a02c8 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/jdbc/HistroyDaoJdbc.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/jdbc/HistroyDaoJdbc.java @@ -6,7 +6,6 @@ import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.UUID; @@ -76,8 +75,7 @@ public History readHistory(HistoryIdentityFilter filter, PageAndCount pageAndCou Objects.requireNonNull(sinceParameter, "sinceParameter"); Objects.requireNonNull(resource, "resource"); - return readHistory(Collections.singletonList(filter), pageAndCount, atParameters, sinceParameter, resource, - null); + return readHistory(List.of(filter), pageAndCount, atParameters, sinceParameter, resource, null); } @Override @@ -91,7 +89,7 @@ public History readHistory(HistoryIdentityFilter filter, PageAndCount pageAndCou Objects.requireNonNull(resource, "resource"); Objects.requireNonNull(id, "id"); - return readHistory(Collections.singletonList(filter), pageAndCount, atParameters, sinceParameter, resource, id); + return readHistory(List.of(filter), pageAndCount, atParameters, sinceParameter, resource, id); } private History readHistory(List<HistoryIdentityFilter> filter, PageAndCount pageAndCount, diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/jdbc/OrganizationAffiliationDaoJdbc.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/jdbc/OrganizationAffiliationDaoJdbc.java index 930f3ccee..0bb936078 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/jdbc/OrganizationAffiliationDaoJdbc.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/jdbc/OrganizationAffiliationDaoJdbc.java @@ -5,7 +5,6 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.UUID; @@ -68,7 +67,7 @@ public List<OrganizationAffiliation> readActiveNotDeletedByMemberOrganizationIde { Objects.requireNonNull(connection, "connection"); if (identifierValue == null || identifierValue.isBlank()) - return Collections.emptyList(); + return List.of(); try (PreparedStatement statement = connection.prepareStatement("SELECT organization_affiliation" + ",(SELECT identifiers->>'value' FROM current_organizations, jsonb_array_elements(organization->'identifier') AS identifiers " diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/jdbc/SubscriptionDaoJdbc.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/jdbc/SubscriptionDaoJdbc.java index 641a872d0..789ae8117 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/jdbc/SubscriptionDaoJdbc.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/dao/jdbc/SubscriptionDaoJdbc.java @@ -5,7 +5,6 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import javax.sql.DataSource; @@ -47,7 +46,7 @@ protected Subscription copy(Subscription resource) public List<Subscription> readByStatus(Subscription.SubscriptionStatus status) throws SQLException { if (status == null) - return Collections.emptyList(); + return List.of(); try (Connection connection = getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement( @@ -66,4 +65,28 @@ public List<Subscription> readByStatus(Subscription.SubscriptionStatus status) t } } } + + @Override + public boolean existsByCriteriaChannelTypeAndChannelPayload(String criteria, String channelType, + String channelPayload) throws SQLException + { + try (Connection connection = getDataSource().getConnection(); + PreparedStatement statement = connection + .prepareStatement("SELECT count(*) FROM current_subscriptions WHERE " + + "subscription->>'criteria' = ? AND subscription->'channel'->>'type' = ? AND " + + (channelPayload == null ? "NOT subscription->'channel' ?? 'payload'" + : "subscription->'channel'->>'payload' = ?"))) + { + statement.setString(1, criteria); + statement.setString(2, channelType); + + if (channelPayload != null) + statement.setString(3, channelPayload); + + try (ResultSet result = statement.executeQuery()) + { + return result.next() && result.getInt(1) > 0; + } + } + } } diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/help/ParameterConverter.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/help/ParameterConverter.java index 907e9e2d0..3b13eee59 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/help/ParameterConverter.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/help/ParameterConverter.java @@ -2,7 +2,6 @@ import java.net.URLDecoder; import java.nio.charset.StandardCharsets; -import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -176,7 +175,7 @@ public PreferHandlingType getPreferHandling(HttpHeaders headers) public Integer getFirstInt(Map<String, List<String>> queryParameters, String key) { - List<String> listForKey = queryParameters.getOrDefault(key, Collections.emptyList()); + List<String> listForKey = queryParameters.getOrDefault(key, List.of()); if (listForKey.isEmpty()) return null; else 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 4d84eee63..14c312b46 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 @@ -1,7 +1,6 @@ package dev.dsf.fhir.history; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.stream.Stream; @@ -95,7 +94,7 @@ public Bundle getHistory(Identity identity, UriInfo uri, HttpHeaders headers, List<SearchQueryParameterError> errors = new ArrayList<>(); - List<String> atValues = queryParameters.getOrDefault(AtParameter.PARAMETER_NAME, Collections.emptyList()); + List<String> atValues = queryParameters.getOrDefault(AtParameter.PARAMETER_NAME, List.of()); atValues.stream().filter(v -> v != null && !v.isBlank()).forEach(atValue -> { AtParameter atParameter = new AtParameter(); diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/PageAndCount.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/PageAndCount.java index c1847b5ce..0c0672c0c 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/PageAndCount.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/PageAndCount.java @@ -1,6 +1,5 @@ package dev.dsf.fhir.search; -import java.util.Collections; import java.util.List; import java.util.Map; @@ -29,7 +28,7 @@ public static PageAndCount from(Map<String, List<String>> queryParameters, int d private static Integer getFirstInt(Map<String, List<String>> queryParameters, String key) { - List<String> values = queryParameters.getOrDefault(key, Collections.emptyList()); + List<String> values = queryParameters.getOrDefault(key, List.of()); if (values.isEmpty()) return null; else diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/SearchQuery.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/SearchQuery.java index 40669b5e6..d4f42de8d 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/SearchQuery.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/SearchQuery.java @@ -6,7 +6,6 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; @@ -89,7 +88,7 @@ public SearchQueryBuilder<R> with(SearchQueryParameterFactory<R> searchParameter public SearchQueryBuilder<R> with( @SuppressWarnings("unchecked") SearchQueryParameterFactory<R>... searchParameters) { - return with(Arrays.asList(searchParameters)); + return with(List.of(searchParameters)); } public SearchQueryBuilder<R> with(List<? extends SearchQueryParameterFactory<R>> searchParameters) @@ -106,7 +105,7 @@ public SearchQueryBuilder<R> withRevInclude(SearchQueryRevIncludeParameterFactor public SearchQueryBuilder<R> withRevInclude(SearchQueryRevIncludeParameterFactory... revIncludeParameters) { - return withRevInclude(Arrays.asList(revIncludeParameters)); + return withRevInclude(List.of(revIncludeParameters)); } public SearchQueryBuilder<R> withRevInclude(List<SearchQueryRevIncludeParameterFactory> revIncludeParameters) @@ -220,11 +219,10 @@ public SearchQuery<R> configureParameters(Map<String, List<String>> queryParamet filterQuery = createFilterQuery(queryParameters); - includeSql = createIncludeSql(queryParameters.getOrDefault(PARAMETER_INCLUDE, Collections.emptyList())); - revIncludeSql = createRevIncludeSql( - queryParameters.getOrDefault(PARAMETER_REVINCLUDE, Collections.emptyList())); + includeSql = createIncludeSql(queryParameters.getOrDefault(PARAMETER_INCLUDE, List.of())); + revIncludeSql = createRevIncludeSql(queryParameters.getOrDefault(PARAMETER_REVINCLUDE, List.of())); - sortSql = createSortSql(queryParameters.getOrDefault(PARAMETER_SORT, Collections.emptyList())); + sortSql = createSortSql(queryParameters.getOrDefault(PARAMETER_SORT, List.of())); return this; } @@ -457,7 +455,7 @@ public UriBuilder configureBundleUri(UriBuilder bundleUri) searchParameters.stream().filter(SearchQueryParameter::isDefined) .collect(Collectors.toMap(SearchQueryParameter::getBundleUriQueryParameterName, - p -> Collections.singletonList(p.getBundleUriQueryParameterValue()), (v1, v2) -> + p -> List.of(p.getBundleUriQueryParameterValue()), (v1, v2) -> { List<String> list = new ArrayList<>(v1); list.addAll(v2); @@ -528,8 +526,8 @@ public boolean matches(Resource resource) if (resource == null || !getResourceType().isInstance(resource)) return false; - return searchParameters.stream().filter(SearchQueryParameter::isDefined).map(p -> p.matches(resource)) - .allMatch(b -> b); + // returns true if no search parameters configured + return searchParameters.stream().filter(SearchQueryParameter::isDefined).allMatch(p -> p.matches(resource)); } @Override diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/basic/AbstractCanonicalUrlParameter.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/basic/AbstractCanonicalUrlParameter.java index 019cf6bd3..f84f4f477 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/basic/AbstractCanonicalUrlParameter.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/basic/AbstractCanonicalUrlParameter.java @@ -1,6 +1,5 @@ package dev.dsf.fhir.search.parameters.basic; -import java.util.Collections; import java.util.List; import org.hl7.fhir.r4.model.Resource; @@ -23,7 +22,7 @@ protected enum UriSearchType public static List<String> getNameModifiers() { - return Collections.singletonList(UriSearchType.BELOW.modifier); + return List.of(UriSearchType.BELOW.modifier); } protected static class CanonicalUrlAndSearchType diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/basic/AbstractReferenceParameter.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/basic/AbstractReferenceParameter.java index ce3794f2b..ffe5cd812 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/basic/AbstractReferenceParameter.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/basic/AbstractReferenceParameter.java @@ -2,8 +2,6 @@ import java.sql.Connection; import java.sql.SQLException; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Optional; @@ -25,7 +23,7 @@ public abstract class AbstractReferenceParameter<R extends DomainResource> exten public static List<String> getNameModifiers() { - return Collections.singletonList(PARAMETER_NAME_IDENTIFIER_MODIFIER); + return List.of(PARAMETER_NAME_IDENTIFIER_MODIFIER); } protected enum ReferenceSearchType @@ -181,7 +179,7 @@ public AbstractReferenceParameter(Class<R> resourceType, String parameterName, S { super(resourceType, parameterName); - this.targetResourceTypeNames = Arrays.asList(targetResourceTypeNames); + this.targetResourceTypeNames = List.of(targetResourceTypeNames); } @Override diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/EndpointOrganizationRevInclude.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/EndpointOrganizationRevInclude.java index 6a18c277a..8d22037b4 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/EndpointOrganizationRevInclude.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/EndpointOrganizationRevInclude.java @@ -1,7 +1,6 @@ package dev.dsf.fhir.search.parameters.rev.include; import java.sql.Connection; -import java.util.Arrays; import java.util.List; import org.hl7.fhir.r4.model.Endpoint; @@ -20,7 +19,7 @@ public class EndpointOrganizationRevInclude extends AbstractRevIncludeParameter public static List<String> getRevIncludeParameterValues() { - return Arrays.asList(RESOURCE_TYPE_NAME + ":" + PARAMETER_NAME, + return List.of(RESOURCE_TYPE_NAME + ":" + PARAMETER_NAME, RESOURCE_TYPE_NAME + ":" + PARAMETER_NAME + ":" + TARGET_RESOURCE_TYPE_NAME); } diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/OrganizationAffiliationParticipatingOrganizationRevInclude.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/OrganizationAffiliationParticipatingOrganizationRevInclude.java index bc279fa93..a0771ebdf 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/OrganizationAffiliationParticipatingOrganizationRevInclude.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/OrganizationAffiliationParticipatingOrganizationRevInclude.java @@ -1,7 +1,6 @@ package dev.dsf.fhir.search.parameters.rev.include; import java.sql.Connection; -import java.util.Arrays; import java.util.List; import org.hl7.fhir.r4.model.Organization; @@ -20,7 +19,7 @@ public class OrganizationAffiliationParticipatingOrganizationRevInclude extends public static List<String> getRevIncludeParameterValues() { - return Arrays.asList(RESOURCE_TYPE_NAME + ":" + PARAMETER_NAME, + return List.of(RESOURCE_TYPE_NAME + ":" + PARAMETER_NAME, RESOURCE_TYPE_NAME + ":" + PARAMETER_NAME + ":" + TARGET_RESOURCE_TYPE_NAME); } diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/OrganizationAffiliationPrimaryOrganizationRevInclude.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/OrganizationAffiliationPrimaryOrganizationRevInclude.java index 2c38742b5..0c936d0d4 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/OrganizationAffiliationPrimaryOrganizationRevInclude.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/OrganizationAffiliationPrimaryOrganizationRevInclude.java @@ -1,7 +1,6 @@ package dev.dsf.fhir.search.parameters.rev.include; import java.sql.Connection; -import java.util.Arrays; import java.util.List; import org.hl7.fhir.r4.model.Organization; @@ -20,7 +19,7 @@ public class OrganizationAffiliationPrimaryOrganizationRevInclude extends Abstra public static List<String> getRevIncludeParameterValues() { - return Arrays.asList(RESOURCE_TYPE_NAME + ":" + PARAMETER_NAME, + return List.of(RESOURCE_TYPE_NAME + ":" + PARAMETER_NAME, RESOURCE_TYPE_NAME + ":" + PARAMETER_NAME + ":" + TARGET_RESOURCE_TYPE_NAME); } diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/OrganizationEndpointRevInclude.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/OrganizationEndpointRevInclude.java index fe298c702..9b49810e0 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/OrganizationEndpointRevInclude.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/OrganizationEndpointRevInclude.java @@ -1,7 +1,6 @@ package dev.dsf.fhir.search.parameters.rev.include; import java.sql.Connection; -import java.util.Arrays; import java.util.List; import org.hl7.fhir.r4.model.Endpoint; @@ -20,7 +19,7 @@ public class OrganizationEndpointRevInclude extends AbstractRevIncludeParameter public static List<String> getRevIncludeParameterValues() { - return Arrays.asList(RESOURCE_TYPE_NAME + ":" + PARAMETER_NAME, + return List.of(RESOURCE_TYPE_NAME + ":" + PARAMETER_NAME, RESOURCE_TYPE_NAME + ":" + PARAMETER_NAME + ":" + TARGET_RESOURCE_TYPE_NAME); } diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/ResearchStudyEnrollmentRevInclude.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/ResearchStudyEnrollmentRevInclude.java index 2f07584a4..63cb718a6 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/ResearchStudyEnrollmentRevInclude.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/search/parameters/rev/include/ResearchStudyEnrollmentRevInclude.java @@ -1,7 +1,6 @@ package dev.dsf.fhir.search.parameters.rev.include; import java.sql.Connection; -import java.util.Arrays; import java.util.List; import org.hl7.fhir.r4.model.Group; @@ -20,7 +19,7 @@ public class ResearchStudyEnrollmentRevInclude extends AbstractRevIncludeParamet public static List<String> getRevIncludeParameterValues() { - return Arrays.asList(RESOURCE_TYPE_NAME + ":" + PARAMETER_NAME, + return List.of(RESOURCE_TYPE_NAME + ":" + PARAMETER_NAME, RESOURCE_TYPE_NAME + ":" + PARAMETER_NAME + ":" + TARGET_RESOURCE_TYPE_NAME); } diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/service/ReferenceResolverImpl.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/service/ReferenceResolverImpl.java index 3e5a64795..035a5c226 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/service/ReferenceResolverImpl.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/service/ReferenceResolverImpl.java @@ -121,11 +121,10 @@ private void throwIfReferenceTypeUnexpected(ReferenceType type, ReferenceType ex throw new IllegalArgumentException("ReferenceType " + expected + " expected, but was " + type); } - private void throwIfReferenceTypeUnexpected(ReferenceType type, ReferenceType... expected) + private void throwIfReferenceTypeUnexpected(ReferenceType type, EnumSet<ReferenceType> expected) { - if (!EnumSet.copyOf(Arrays.asList(expected)).contains(type)) - throw new IllegalArgumentException( - "ReferenceTypes " + Arrays.toString(expected) + " expected, but was " + type); + if (!expected.contains(type)) + throw new IllegalArgumentException("ReferenceTypes " + expected + " expected, but was " + type); } private Optional<Resource> resolveLiteralInternalReference(ResourceReference reference, Connection connection) @@ -176,8 +175,8 @@ private Optional<Resource> resolveLiteralInternalReference(ResourceReference ref private Optional<Resource> resolveLiteralExternalReference(ResourceReference reference) { Objects.requireNonNull(reference, "reference"); - throwIfReferenceTypeUnexpected(reference.getType(serverBase), ReferenceType.LITERAL_EXTERNAL, - ReferenceType.RELATED_ARTEFACT_LITERAL_EXTERNAL_URL, ReferenceType.ATTACHMENT_LITERAL_EXTERNAL_URL); + throwIfReferenceTypeUnexpected(reference.getType(serverBase), EnumSet.of(ReferenceType.LITERAL_EXTERNAL, + ReferenceType.RELATED_ARTEFACT_LITERAL_EXTERNAL_URL, ReferenceType.ATTACHMENT_LITERAL_EXTERNAL_URL)); String remoteServerBase = reference.getServerBase(serverBase); Optional<FhirWebserviceClient> client = clientProvider.getClient(remoteServerBase); @@ -222,8 +221,8 @@ private Optional<Resource> resolveConditionalReference(Identity identity, Resour Objects.requireNonNull(reference, "reference"); ReferenceType referenceType = reference.getType(serverBase); - throwIfReferenceTypeUnexpected(referenceType, ReferenceType.CONDITIONAL, - ReferenceType.RELATED_ARTEFACT_CONDITIONAL_URL, ReferenceType.ATTACHMENT_CONDITIONAL_URL); + throwIfReferenceTypeUnexpected(referenceType, EnumSet.of(ReferenceType.CONDITIONAL, + ReferenceType.RELATED_ARTEFACT_CONDITIONAL_URL, ReferenceType.ATTACHMENT_CONDITIONAL_URL)); String referenceValue = reference.getValue(); String referenceLocation = reference.getLocation(); @@ -375,8 +374,8 @@ public Optional<OperationOutcome> checkLiteralInternalReference(Resource resourc Objects.requireNonNull(resource, "resource"); Objects.requireNonNull(reference, "reference"); Objects.requireNonNull(connection, "connection"); - throwIfReferenceTypeUnexpected(reference.getType(serverBase), ReferenceType.LITERAL_INTERNAL, - ReferenceType.RELATED_ARTEFACT_LITERAL_INTERNAL_URL, ReferenceType.ATTACHMENT_LITERAL_INTERNAL_URL); + throwIfReferenceTypeUnexpected(reference.getType(serverBase), EnumSet.of(ReferenceType.LITERAL_INTERNAL, + ReferenceType.RELATED_ARTEFACT_LITERAL_INTERNAL_URL, ReferenceType.ATTACHMENT_LITERAL_INTERNAL_URL)); IdType id = new IdType(reference.getValue()); Optional<ResourceDao<?>> referenceDao = daoProvider.getDao(id.getResourceType()); @@ -413,8 +412,8 @@ public Optional<OperationOutcome> checkLiteralExternalReference(Resource resourc { Objects.requireNonNull(resource, "resource"); Objects.requireNonNull(reference, "reference"); - throwIfReferenceTypeUnexpected(reference.getType(serverBase), ReferenceType.LITERAL_EXTERNAL, - ReferenceType.RELATED_ARTEFACT_LITERAL_EXTERNAL_URL, ReferenceType.ATTACHMENT_LITERAL_EXTERNAL_URL); + throwIfReferenceTypeUnexpected(reference.getType(serverBase), EnumSet.of(ReferenceType.LITERAL_EXTERNAL, + ReferenceType.RELATED_ARTEFACT_LITERAL_EXTERNAL_URL, ReferenceType.ATTACHMENT_LITERAL_EXTERNAL_URL)); String remoteServerBase = reference.getServerBase(serverBase); String referenceValue = reference.getValue(); diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/service/ValidationSupportWithCache.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/service/ValidationSupportWithCache.java index f373cc2d2..88c7d3b8f 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/service/ValidationSupportWithCache.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/service/ValidationSupportWithCache.java @@ -267,7 +267,7 @@ public <T extends IBaseResource> List<T> fetchAllStructureDefinitions() @Override public IBaseResource fetchStructureDefinition(String url) { - logger.trace("Fetiching structure-definition '{}'", url); + logger.trace("Fetching structure-definition '{}'", url); if (url == null || url.isBlank()) return null; @@ -284,7 +284,7 @@ public boolean isCodeSystemSupported(ValidationSupportContext theRootValidationS @Override public IBaseResource fetchCodeSystem(String url) { - logger.trace("Fetiching code-system '{}'", url); + logger.trace("Fetching code-system '{}'", url); if (url == null || url.isBlank()) return null; @@ -301,7 +301,7 @@ public boolean isValueSetSupported(ValidationSupportContext theRootValidationSup @Override public IBaseResource fetchValueSet(String url) { - logger.trace("Fetiching value-set '{}'", url); + logger.trace("Fetching value-set '{}'", url); if (url == null || url.isBlank()) return null; diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/spring/config/InitialDataMigratorConfig.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/spring/config/InitialDataMigratorConfig.java index 83a6b3883..4fb1b68fa 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/spring/config/InitialDataMigratorConfig.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/spring/config/InitialDataMigratorConfig.java @@ -2,7 +2,6 @@ import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE; -import java.util.Collections; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; @@ -27,7 +26,7 @@ public List<MigrationJob> migrationJobs() { // currently no migration jobs // add future migration jobs here - return Collections.emptyList(); + return List.of(); } @Bean 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 7b6868f54..6c8a3bd07 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 @@ -4,7 +4,6 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; -import java.util.Arrays; import java.util.List; import java.util.Properties; @@ -182,7 +181,7 @@ private static void injectEndpointProperties(ConfigurableEnvironment environment public void afterPropertiesSet() throws Exception { URL url = new URI(serverBaseUrl).toURL(); - if (!Arrays.asList("http", "https").contains(url.getProtocol())) + if (!List.of("http", "https").contains(url.getProtocol())) { logger.warn("Invalid DSF FHIR server base URL: '{}', URL not starting with 'http://' or 'https://'", serverBaseUrl); diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/spring/config/WebserviceConfig.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/spring/config/WebserviceConfig.java index 730ed820f..a8995685e 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/spring/config/WebserviceConfig.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/spring/config/WebserviceConfig.java @@ -900,7 +900,7 @@ private ConformanceServiceImpl conformanceServiceImpl() @Bean public StaticResourcesService staticResourcesService() { - return new StaticResourcesService(propertiesConfig.getStaticResourceCacheEnabled()); + return new StaticResourcesService("/fhir", propertiesConfig.getStaticResourceCacheEnabled()); } @Bean diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/subscription/WebSocketSubscriptionManagerImpl.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/subscription/WebSocketSubscriptionManagerImpl.java index e7aac3fc7..9d9d29410 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/subscription/WebSocketSubscriptionManagerImpl.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/subscription/WebSocketSubscriptionManagerImpl.java @@ -3,7 +3,6 @@ import java.io.IOException; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -161,8 +160,8 @@ private void refreshMatchers() } else { - matchers.put(matcher.get().getResourceType(), new ArrayList<>( - Collections.singletonList(new SubscriptionAndMatcher(subscription, matcher.get())))); + matchers.put(matcher.get().getResourceType(), + new ArrayList<>(List.of(new SubscriptionAndMatcher(subscription, matcher.get())))); } } } 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 2bb5fd3ab..d94660cff 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 @@ -168,7 +168,10 @@ public Response create(R resource, UriInfo uri, HttpHeaders headers) connection.rollback(); if (PSQLState.UNIQUE_VIOLATION.getState().equals(e.getSQLState())) - throw new WebApplicationException(responseGenerator.duplicateResourceExists(resourceTypeName)); + { + Response response = responseGenerator.duplicateResourceExists(resourceTypeName); + throw new WebApplicationException(response); + } else throw e; } @@ -555,8 +558,10 @@ public Response update(String id, R resource, UriInfo uri, HttpHeaders headers) catch (SQLException e) { if (PSQLState.UNIQUE_VIOLATION.getState().equals(e.getSQLState())) - throw new WebApplicationException( - responseGenerator.duplicateResourceExists(resourceTypeName)); + { + Response response = responseGenerator.duplicateResourceExists(resourceTypeName); + throw new WebApplicationException(response); + } connection.rollback(); throw e; diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/webservice/impl/ConformanceServiceImpl.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/webservice/impl/ConformanceServiceImpl.java index df99fce31..53949871d 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/webservice/impl/ConformanceServiceImpl.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/webservice/impl/ConformanceServiceImpl.java @@ -1,7 +1,6 @@ package dev.dsf.fhir.webservice.impl; import java.util.Arrays; -import java.util.Collections; import java.util.Comparator; import java.util.EnumSet; import java.util.HashMap; @@ -305,7 +304,7 @@ private CapabilityStatement createCapabilityStatement() websocketExtension.setUrl("http://hl7.org/fhir/StructureDefinition/capabilitystatement-websocket"); websocketExtension.setValue(new UrlType(serverBase.replace("http", "ws") + ServerEndpoint.PATH)); - var resources = Arrays.asList(ActivityDefinition.class, Binary.class, Bundle.class, CodeSystem.class, + var resources = List.of(ActivityDefinition.class, Binary.class, Bundle.class, CodeSystem.class, DocumentReference.class, Endpoint.class, Group.class, HealthcareService.class, Library.class, Location.class, Measure.class, MeasureReport.class, NamingSystem.class, Organization.class, OrganizationAffiliation.class, Patient.class, PractitionerRole.class, Practitioner.class, @@ -316,95 +315,93 @@ private CapabilityStatement createCapabilityStatement() var revIncludeParameters = new HashMap<Class<? extends Resource>, List<Class<? extends AbstractRevIncludeParameter>>>(); searchParameters.put(ActivityDefinition.class, - Arrays.asList(ActivityDefinitionDate.class, ActivityDefinitionUrl.class, - ActivityDefinitionIdentifier.class, ActivityDefinitionVersion.class, - ActivityDefinitionName.class, ActivityDefinitionStatus.class)); + List.of(ActivityDefinitionDate.class, ActivityDefinitionUrl.class, ActivityDefinitionIdentifier.class, + ActivityDefinitionVersion.class, ActivityDefinitionName.class, ActivityDefinitionStatus.class)); - searchParameters.put(Binary.class, Arrays.asList(BinaryContentType.class)); + searchParameters.put(Binary.class, List.of(BinaryContentType.class)); - searchParameters.put(Bundle.class, Arrays.asList(BundleIdentifier.class)); + searchParameters.put(Bundle.class, List.of(BundleIdentifier.class)); - searchParameters.put(CodeSystem.class, Arrays.asList(CodeSystemDate.class, CodeSystemIdentifier.class, + searchParameters.put(CodeSystem.class, List.of(CodeSystemDate.class, CodeSystemIdentifier.class, CodeSystemName.class, CodeSystemUrl.class, CodeSystemVersion.class, CodeSystemStatus.class)); - searchParameters.put(DocumentReference.class, Arrays.asList(DocumentReferenceIdentifier.class)); + searchParameters.put(DocumentReference.class, List.of(DocumentReferenceIdentifier.class)); - searchParameters.put(Endpoint.class, Arrays.asList(EndpointAddress.class, EndpointIdentifier.class, + searchParameters.put(Endpoint.class, List.of(EndpointAddress.class, EndpointIdentifier.class, EndpointName.class, EndpointOrganization.class, EndpointStatus.class)); - revIncludeParameters.put(Endpoint.class, Arrays.asList(OrganizationEndpointRevInclude.class)); + revIncludeParameters.put(Endpoint.class, List.of(OrganizationEndpointRevInclude.class)); - searchParameters.put(Group.class, Arrays.asList(GroupIdentifier.class)); - revIncludeParameters.put(Group.class, Arrays.asList(ResearchStudyEnrollmentRevInclude.class)); + searchParameters.put(Group.class, List.of(GroupIdentifier.class)); + revIncludeParameters.put(Group.class, List.of(ResearchStudyEnrollmentRevInclude.class)); - searchParameters.put(HealthcareService.class, Arrays.asList(HealthcareServiceActive.class, - HealthcareServiceIdentifier.class, HealthcareServiceName.class)); + searchParameters.put(HealthcareService.class, + List.of(HealthcareServiceActive.class, HealthcareServiceIdentifier.class, HealthcareServiceName.class)); - searchParameters.put(Library.class, Arrays.asList(LibraryDate.class, LibraryIdentifier.class, LibraryName.class, + searchParameters.put(Library.class, List.of(LibraryDate.class, LibraryIdentifier.class, LibraryName.class, LibraryStatus.class, LibraryUrl.class, LibraryVersion.class)); - searchParameters.put(Location.class, Arrays.asList(LocationIdentifier.class, LocationName.class)); + searchParameters.put(Location.class, List.of(LocationIdentifier.class, LocationName.class)); - searchParameters.put(Measure.class, - Arrays.asList(MeasureDate.class, MeasureDependsOn.class, MeasureIdentifier.class, MeasureName.class, - MeasureStatus.class, MeasureUrl.class, MeasureVersion.class)); + searchParameters.put(Measure.class, List.of(MeasureDate.class, MeasureDependsOn.class, MeasureIdentifier.class, + MeasureName.class, MeasureStatus.class, MeasureUrl.class, MeasureVersion.class)); - searchParameters.put(MeasureReport.class, Arrays.asList(MeasureReportIdentifier.class)); + searchParameters.put(MeasureReport.class, List.of(MeasureReportIdentifier.class)); searchParameters.put(NamingSystem.class, - Arrays.asList(NamingSystemDate.class, NamingSystemName.class, NamingSystemStatus.class)); + List.of(NamingSystemDate.class, NamingSystemName.class, NamingSystemStatus.class)); - searchParameters.put(Organization.class, Arrays.asList(OrganizationActive.class, OrganizationEndpoint.class, + searchParameters.put(Organization.class, List.of(OrganizationActive.class, OrganizationEndpoint.class, OrganizationIdentifier.class, OrganizationName.class, OrganizationType.class)); revIncludeParameters.put(Organization.class, - Arrays.asList(EndpointOrganizationRevInclude.class, + List.of(EndpointOrganizationRevInclude.class, OrganizationAffiliationParticipatingOrganizationRevInclude.class, OrganizationAffiliationPrimaryOrganizationRevInclude.class)); searchParameters.put(OrganizationAffiliation.class, - Arrays.asList(OrganizationAffiliationActive.class, OrganizationAffiliationEndpoint.class, + List.of(OrganizationAffiliationActive.class, OrganizationAffiliationEndpoint.class, OrganizationAffiliationIdentifier.class, OrganizationAffiliationParticipatingOrganization.class, OrganizationAffiliationPrimaryOrganization.class, OrganizationAffiliationRole.class)); - searchParameters.put(Patient.class, Arrays.asList(PatientActive.class, PatientIdentifier.class)); + searchParameters.put(Patient.class, List.of(PatientActive.class, PatientIdentifier.class)); - searchParameters.put(Practitioner.class, Arrays.asList(PractitionerActive.class, PractitionerIdentifier.class)); + searchParameters.put(Practitioner.class, List.of(PractitionerActive.class, PractitionerIdentifier.class)); searchParameters.put(PractitionerRole.class, - Arrays.asList(PractitionerRoleActive.class, PractitionerRoleIdentifier.class, + List.of(PractitionerRoleActive.class, PractitionerRoleIdentifier.class, PractitionerRoleOrganization.class, PractitionerRolePractitioner.class)); searchParameters.put(Questionnaire.class, - Arrays.asList(QuestionnaireDate.class, QuestionnaireIdentifier.class, QuestionnaireName.class, + List.of(QuestionnaireDate.class, QuestionnaireIdentifier.class, QuestionnaireName.class, QuestionnaireStatus.class, QuestionnaireUrl.class, QuestionnaireVersion.class)); - searchParameters.put(QuestionnaireResponse.class, Arrays.asList(QuestionnaireResponseAuthored.class, + searchParameters.put(QuestionnaireResponse.class, List.of(QuestionnaireResponseAuthored.class, QuestionnaireResponseIdentifier.class, QuestionnaireResponseStatus.class)); - searchParameters.put(ResearchStudy.class, Arrays.asList(ResearchStudyIdentifier.class, - ResearchStudyEnrollment.class, ResearchStudyPrincipalInvestigator.class)); + searchParameters.put(ResearchStudy.class, List.of(ResearchStudyIdentifier.class, ResearchStudyEnrollment.class, + ResearchStudyPrincipalInvestigator.class)); searchParameters.put(StructureDefinition.class, - Arrays.asList(StructureDefinitionDate.class, StructureDefinitionIdentifier.class, + List.of(StructureDefinitionDate.class, StructureDefinitionIdentifier.class, StructureDefinitionName.class, StructureDefinitionStatus.class, StructureDefinitionUrl.class, StructureDefinitionVersion.class)); - searchParameters.put(Subscription.class, Arrays.asList(SubscriptionCriteria.class, SubscriptionPayload.class, + searchParameters.put(Subscription.class, List.of(SubscriptionCriteria.class, SubscriptionPayload.class, SubscriptionStatus.class, SubscriptionType.class)); - searchParameters.put(Task.class, Arrays.asList(TaskAuthoredOn.class, TaskIdentifier.class, TaskModified.class, + searchParameters.put(Task.class, List.of(TaskAuthoredOn.class, TaskIdentifier.class, TaskModified.class, TaskRequester.class, TaskStatus.class)); - searchParameters.put(ValueSet.class, Arrays.asList(ValueSetDate.class, ValueSetIdentifier.class, - ValueSetName.class, ValueSetUrl.class, ValueSetVersion.class, ValueSetStatus.class)); + searchParameters.put(ValueSet.class, List.of(ValueSetDate.class, ValueSetIdentifier.class, ValueSetName.class, + ValueSetUrl.class, ValueSetVersion.class, ValueSetStatus.class)); var operations = new HashMap<Class<? extends DomainResource>, List<CapabilityStatementRestResourceOperationComponent>>(); var snapshotOperation = createOperation("snapshot", "http://hl7.org/fhir/OperationDefinition/StructureDefinition-snapshot", "Generates a StructureDefinition instance with a snapshot, based on a differential in a specified StructureDefinition"); - operations.put(StructureDefinition.class, Arrays.asList(snapshotOperation)); + operations.put(StructureDefinition.class, List.of(snapshotOperation)); - var standardSortableSearchParameters = Arrays.asList(ResourceId.class, ResourceLastUpdated.class, + var standardSortableSearchParameters = List.of(ResourceId.class, ResourceLastUpdated.class, ResourceProfile.class); Map<String, List<CanonicalType>> profileUrlsByResource = validationSupport.fetchAllStructureDefinitions() @@ -439,7 +436,7 @@ private CapabilityStatement createCapabilityStatement() r.addInteraction().setCode(TypeRestfulInteraction.DELETE); r.addInteraction().setCode(TypeRestfulInteraction.SEARCHTYPE); - var resourceSearchParameters = searchParameters.getOrDefault(resource, Collections.emptyList()); + var resourceSearchParameters = searchParameters.getOrDefault(resource, List.of()); resourceSearchParameters.stream().map(this::createSearchParameter) .sorted(Comparator.comparing(CapabilityStatementRestResourceSearchParamComponent::getName)) .forEach(r::addSearchParam); @@ -465,7 +462,7 @@ private CapabilityStatement createCapabilityStatement() r.addSearchParam(createSinceParameter()); r.addSearchParam(createAtParameter()); - var resourceRevIncludeParameters = revIncludeParameters.getOrDefault(resource, Collections.emptyList()); + var resourceRevIncludeParameters = revIncludeParameters.getOrDefault(resource, List.of()); var revIncludes = resourceRevIncludeParameters.stream() .map(p -> p.getAnnotation(IncludeParameterDefinition.class)).filter(def -> def != null) .collect(Collectors.toList()); @@ -481,10 +478,9 @@ private CapabilityStatement createCapabilityStatement() r.getSearchParam().sort(Comparator.comparing(CapabilityStatementRestResourceSearchParamComponent::getName)); - operations.getOrDefault(resource, Collections.emptyList()).forEach(r::addOperation); + operations.getOrDefault(resource, List.of()).forEach(r::addOperation); - r.setSupportedProfile( - profileUrlsByResource.getOrDefault(resourceDefAnnotation.name(), Collections.emptyList())); + r.setSupportedProfile(profileUrlsByResource.getOrDefault(resourceDefAnnotation.name(), List.of())); } return statement; 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 bb72ab9f5..dec2d7751 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 @@ -1,6 +1,5 @@ package dev.dsf.fhir.webservice.impl; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -230,9 +229,8 @@ private Response getSnapshot(String url, UriInfo uri, HttpHeaders headers) SearchQuery<StructureDefinition> query = snapshotDao.createSearchQuery(getCurrentIdentity(), PageAndCount.single()); Map<String, List<String>> searchParameters = new HashMap<>(); - searchParameters.put(StructureDefinitionUrl.PARAMETER_NAME, Collections.singletonList(url)); - searchParameters.put(SearchQuery.PARAMETER_SORT, - Collections.singletonList("-" + ResourceLastUpdated.PARAMETER_NAME)); + searchParameters.put(StructureDefinitionUrl.PARAMETER_NAME, List.of(url)); + searchParameters.put(SearchQuery.PARAMETER_SORT, List.of("-" + ResourceLastUpdated.PARAMETER_NAME)); query.configureParameters(searchParameters); PartialResult<StructureDefinition> result = exceptionHandler diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.changelog.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.changelog.xml deleted file mode 100644 index d91572e60..000000000 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.changelog.xml +++ /dev/null @@ -1,46 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> - - <include file="db/db.create-db-users.changelog-1.0.0.xml" /> - - <include file="db/db.activity_definitions.changelog-1.0.0.xml" /> - <include file="db/db.binaries.changelog-1.0.0.xml" /> - <include file="db/db.bundles.changelog-1.0.0.xml" /> - <include file="db/db.code_systems.changelog-1.0.0.xml" /> - <include file="db/db.document_references.changelog-1.0.0.xml" /> - <include file="db/db.endpoints.changelog-1.0.0.xml"/> - <include file="db/db.groups.changelog-1.0.0.xml" /> - <include file="db/db.healthcare_services.changelog-1.0.0.xml" /> - <include file="db/db.libraries.changelog-1.0.0.xml" /> - <include file="db/db.locations.changelog-1.0.0.xml" /> - <include file="db/db.measure_reports.changelog-1.0.0.xml" /> - <include file="db/db.measures.changelog-1.0.0.xml" /> - <include file="db/db.naming_systems.changelog-1.0.0.xml" /> - <include file="db/db.organization_affiliations.changelog-1.0.0.xml" /> - <include file="db/db.organizations.changelog-1.0.0.xml" /> - <include file="db/db.patients.changelog-1.0.0.xml" /> - <include file="db/db.practitioner_roles.changelog-1.0.0.xml" /> - <include file="db/db.practitioners.changelog-1.0.0.xml" /> - <include file="db/db.provenances.changelog-1.0.0.xml" /> - <include file="db/db.questionnaire_responses.changelog-1.0.0.xml" /> - <include file="db/db.questionnaires.changelog-1.0.0.xml" /> - <include file="db/db.research_studies.changelog-1.0.0.xml" /> - <include file="db/db.structure_definition_snapshots.changelog-1.0.0.xml" /> - <include file="db/db.structure_definitions.changelog-1.0.0.xml" /> - <include file="db/db.subscriptions.changelog-1.0.0.xml" /> - <include file="db/db.tasks.changelog-1.0.0.xml" /> - <include file="db/db.value_sets.changelog-1.0.0.xml" /> - - <include file="db/db.history.changelog-1.0.0.xml" /> - <include file="db/db.read_access.changelog-1.0.0.xml" /> - - <include file="db/db.read_access.changelog-1.5.0.xml" /> - - <include file="db/db.read_access.changelog-1.6.0.xml" /> - - <include file="db/db.constraint_trigger.changelog-1.6.1.xml" /> - <include file="db/db.delete_duplicate_resources.changelog-1.6.1.xml" /> - -</databaseChangeLog> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.activity_definitions.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.activity_definitions.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.activity_definitions.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.activity_definitions.changelog-1.0.0.xml index 01c413c5c..ba117fdd8 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.activity_definitions.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.activity_definitions.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.activity_definitions.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.binaries.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.binaries.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.binaries.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.binaries.changelog-1.0.0.xml index 91d71feba..c68a5b18f 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.binaries.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.binaries.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.binaries.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.bundles.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.bundles.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.bundles.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.bundles.changelog-1.0.0.xml index dfa4dd94f..4a9f6ef6e 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.bundles.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.bundles.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.bundles.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.changelog.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.changelog.xml new file mode 100644 index 000000000..7d29ec746 --- /dev/null +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.changelog.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + + <include file="fhir/db/db.create-db-users.changelog-1.0.0.xml" /> + + <include file="fhir/db/db.activity_definitions.changelog-1.0.0.xml" /> + <include file="fhir/db/db.binaries.changelog-1.0.0.xml" /> + <include file="fhir/db/db.bundles.changelog-1.0.0.xml" /> + <include file="fhir/db/db.code_systems.changelog-1.0.0.xml" /> + <include file="fhir/db/db.document_references.changelog-1.0.0.xml" /> + <include file="fhir/db/db.endpoints.changelog-1.0.0.xml"/> + <include file="fhir/db/db.groups.changelog-1.0.0.xml" /> + <include file="fhir/db/db.healthcare_services.changelog-1.0.0.xml" /> + <include file="fhir/db/db.libraries.changelog-1.0.0.xml" /> + <include file="fhir/db/db.locations.changelog-1.0.0.xml" /> + <include file="fhir/db/db.measure_reports.changelog-1.0.0.xml" /> + <include file="fhir/db/db.measures.changelog-1.0.0.xml" /> + <include file="fhir/db/db.naming_systems.changelog-1.0.0.xml" /> + <include file="fhir/db/db.organization_affiliations.changelog-1.0.0.xml" /> + <include file="fhir/db/db.organizations.changelog-1.0.0.xml" /> + <include file="fhir/db/db.patients.changelog-1.0.0.xml" /> + <include file="fhir/db/db.practitioner_roles.changelog-1.0.0.xml" /> + <include file="fhir/db/db.practitioners.changelog-1.0.0.xml" /> + <include file="fhir/db/db.provenances.changelog-1.0.0.xml" /> + <include file="fhir/db/db.questionnaire_responses.changelog-1.0.0.xml" /> + <include file="fhir/db/db.questionnaires.changelog-1.0.0.xml" /> + <include file="fhir/db/db.research_studies.changelog-1.0.0.xml" /> + <include file="fhir/db/db.structure_definition_snapshots.changelog-1.0.0.xml" /> + <include file="fhir/db/db.structure_definitions.changelog-1.0.0.xml" /> + <include file="fhir/db/db.subscriptions.changelog-1.0.0.xml" /> + <include file="fhir/db/db.tasks.changelog-1.0.0.xml" /> + <include file="fhir/db/db.value_sets.changelog-1.0.0.xml" /> + + <include file="fhir/db/db.history.changelog-1.0.0.xml" /> + <include file="fhir/db/db.read_access.changelog-1.0.0.xml" /> + + <include file="fhir/db/db.read_access.changelog-1.5.0.xml" /> + + <include file="fhir/db/db.read_access.changelog-1.6.0.xml" /> + + <include file="fhir/db/db.constraint_trigger.changelog-1.6.1.xml" /> + <include file="fhir/db/db.delete_duplicate_resources.changelog-1.6.1.xml" /> + +</databaseChangeLog> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.code_systems.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.code_systems.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.code_systems.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.code_systems.changelog-1.0.0.xml index f93e1156a..66c19b8be 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.code_systems.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.code_systems.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.code_systems.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.constraint_trigger.changelog-1.6.1.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.constraint_trigger.changelog-1.6.1.xml similarity index 98% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.constraint_trigger.changelog-1.6.1.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.constraint_trigger.changelog-1.6.1.xml index 0ba9ae4eb..e4ab70a15 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.constraint_trigger.changelog-1.6.1.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.constraint_trigger.changelog-1.6.1.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd" + logicalFilePath="db/db.constraint_trigger.changelog-1.6.1.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.create-db-users.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.create-db-users.changelog-1.0.0.xml similarity index 95% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.create-db-users.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.create-db-users.changelog-1.0.0.xml index 05b641104..b8635620b 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.create-db-users.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.create-db-users.changelog-1.0.0.xml @@ -2,7 +2,8 @@ <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.create-db-users.changelog-1.0.0.xml"> <changeSet author="hhund" id="db.create-db-users.changelog-1.0.0" dbms="postgresql"> <preConditions onFail="MARK_RAN"> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.delete_duplicate_resources.changelog-1.6.1.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.delete_duplicate_resources.changelog-1.6.1.xml similarity index 99% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.delete_duplicate_resources.changelog-1.6.1.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.delete_duplicate_resources.changelog-1.6.1.xml index 6a15cf8a6..3933523ec 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.delete_duplicate_resources.changelog-1.6.1.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.delete_duplicate_resources.changelog-1.6.1.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd" + logicalFilePath="db/db.delete_duplicate_resources.changelog-1.6.1.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.document_references.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.document_references.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.document_references.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.document_references.changelog-1.0.0.xml index fe07b0c67..c28601399 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.document_references.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.document_references.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.document_references.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.endpoints.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.endpoints.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.endpoints.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.endpoints.changelog-1.0.0.xml index ce02521b0..f9804c7fc 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.endpoints.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.endpoints.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.endpoints.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.groups.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.groups.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.groups.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.groups.changelog-1.0.0.xml index 0e3cf0882..86414edd7 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.groups.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.groups.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.groups.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.healthcare_services.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.healthcare_services.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.healthcare_services.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.healthcare_services.changelog-1.0.0.xml index 5db8a4a60..80d1636ac 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.healthcare_services.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.healthcare_services.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.healthcare_services.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.history.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.history.changelog-1.0.0.xml similarity index 99% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.history.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.history.changelog-1.0.0.xml index 515dcc7e8..86edc532d 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.history.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.history.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.history.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.libraries.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.libraries.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.libraries.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.libraries.changelog-1.0.0.xml index 7bc209743..611871dbb 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.libraries.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.libraries.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.libraries.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.locations.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.locations.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.locations.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.locations.changelog-1.0.0.xml index 3173575c9..519a6d16c 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.locations.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.locations.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.locations.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.measure_reports.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.measure_reports.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.measure_reports.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.measure_reports.changelog-1.0.0.xml index 53f410828..60a3598ff 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.measure_reports.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.measure_reports.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.measure_reports.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.measures.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.measures.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.measures.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.measures.changelog-1.0.0.xml index fbda183e5..d263b39aa 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.measures.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.measures.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.measures.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.naming_systems.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.naming_systems.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.naming_systems.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.naming_systems.changelog-1.0.0.xml index 1aa971d8c..9415b3328 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.naming_systems.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.naming_systems.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.naming_systems.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.organization_affiliations.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.organization_affiliations.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.organization_affiliations.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.organization_affiliations.changelog-1.0.0.xml index f396bb34e..07c34abd7 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.organization_affiliations.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.organization_affiliations.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.organization_affiliations.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.organizations.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.organizations.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.organizations.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.organizations.changelog-1.0.0.xml index c54a37282..623736d10 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.organizations.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.organizations.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.organizations.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.patients.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.patients.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.patients.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.patients.changelog-1.0.0.xml index 4c28e8555..e5d3b1bec 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.patients.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.patients.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.patients.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.practitioner_roles.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.practitioner_roles.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.practitioner_roles.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.practitioner_roles.changelog-1.0.0.xml index 5442bf95b..0e081a113 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.practitioner_roles.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.practitioner_roles.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.practitioner_roles.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.practitioners.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.practitioners.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.practitioners.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.practitioners.changelog-1.0.0.xml index 4a4ee0f4b..c5ca11221 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.practitioners.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.practitioners.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.practitioners.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.provenances.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.provenances.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.provenances.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.provenances.changelog-1.0.0.xml index 3e27d65d1..999c5b7c5 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.provenances.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.provenances.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.provenances.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.questionnaire_responses.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.questionnaire_responses.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.questionnaire_responses.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.questionnaire_responses.changelog-1.0.0.xml index 477b6c430..7080ff9d9 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.questionnaire_responses.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.questionnaire_responses.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.questionnaire_responses.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.questionnaires.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.questionnaires.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.questionnaires.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.questionnaires.changelog-1.0.0.xml index 14e025fc5..33dfc9d21 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.questionnaires.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.questionnaires.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.questionnaires.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.read_access.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.read_access.changelog-1.0.0.xml similarity index 99% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.read_access.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.read_access.changelog-1.0.0.xml index dc8e3919c..0f96928fa 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.read_access.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.read_access.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd" + logicalFilePath="db/db.read_access.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.read_access.changelog-1.5.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.read_access.changelog-1.5.0.xml similarity index 99% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.read_access.changelog-1.5.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.read_access.changelog-1.5.0.xml index 34399376d..2df83a5d4 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.read_access.changelog-1.5.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.read_access.changelog-1.5.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd" + logicalFilePath="db/db.read_access.changelog-1.5.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.read_access.changelog-1.6.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.read_access.changelog-1.6.0.xml similarity index 98% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.read_access.changelog-1.6.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.read_access.changelog-1.6.0.xml index a63509673..ec9de6019 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.read_access.changelog-1.6.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.read_access.changelog-1.6.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd" + logicalFilePath="db/db.read_access.changelog-1.6.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.research_studies.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.research_studies.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.research_studies.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.research_studies.changelog-1.0.0.xml index af3f47eda..9fc54f310 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.research_studies.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.research_studies.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.research_studies.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.structure_definition_snapshots.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.structure_definition_snapshots.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.structure_definition_snapshots.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.structure_definition_snapshots.changelog-1.0.0.xml index 738b01351..bcf9b65f6 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.structure_definition_snapshots.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.structure_definition_snapshots.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.structure_definition_snapshots.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.structure_definitions.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.structure_definitions.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.structure_definitions.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.structure_definitions.changelog-1.0.0.xml index d65e10313..322a02b89 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.structure_definitions.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.structure_definitions.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.structure_definitions.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.subscriptions.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.subscriptions.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.subscriptions.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.subscriptions.changelog-1.0.0.xml index 29778a422..c40ded7a5 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.subscriptions.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.subscriptions.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.subscriptions.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.tasks.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.tasks.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.tasks.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.tasks.changelog-1.0.0.xml index b735cfde8..255a2c958 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.tasks.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.tasks.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.tasks.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.value_sets.changelog-1.0.0.xml b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.value_sets.changelog-1.0.0.xml similarity index 96% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/db.value_sets.changelog-1.0.0.xml rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.value_sets.changelog-1.0.0.xml index 2f7023b01..118b9de05 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/db.value_sets.changelog-1.0.0.xml +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/db.value_sets.changelog-1.0.0.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog - http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd" + logicalFilePath="db/db.value_sets.changelog-1.0.0.xml"> <property name="json" value="JSONB" dbms="postgresql" /> <property name="json" value="varchar(5000)" dbms="h2" /> diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_activity_definitions_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_activity_definitions_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_activity_definitions_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_activity_definitions_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_activity_definitions_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_activity_definitions_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_activity_definitions_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_activity_definitions_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_activity_definitions_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_activity_definitions_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_activity_definitions_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_activity_definitions_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_binaries_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_binaries_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_binaries_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_binaries_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_binaries_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_binaries_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_binaries_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_binaries_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_binaries_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_binaries_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_binaries_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_binaries_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_bundles_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_bundles_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_bundles_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_bundles_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_bundles_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_bundles_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_bundles_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_bundles_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_bundles_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_bundles_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_bundles_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_bundles_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_code_systems_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_code_systems_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_code_systems_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_code_systems_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_code_systems_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_code_systems_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_code_systems_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_code_systems_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_code_systems_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_code_systems_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_code_systems_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_code_systems_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_document_references_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_document_references_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_document_references_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_document_references_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_document_references_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_document_references_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_document_references_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_document_references_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_document_references_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_document_references_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_document_references_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_document_references_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_endpoints_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_endpoints_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_endpoints_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_endpoints_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_endpoints_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_endpoints_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_endpoints_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_endpoints_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_endpoints_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_endpoints_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_endpoints_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_endpoints_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_groups_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_groups_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_groups_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_groups_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_groups_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_groups_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_groups_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_groups_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_groups_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_groups_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_groups_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_groups_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_healthcare_services_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_healthcare_services_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_healthcare_services_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_healthcare_services_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_healthcare_services_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_healthcare_services_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_healthcare_services_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_healthcare_services_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_healthcare_services_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_healthcare_services_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_healthcare_services_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_healthcare_services_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_libraries_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_libraries_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_libraries_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_libraries_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_libraries_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_libraries_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_libraries_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_libraries_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_libraries_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_libraries_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_libraries_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_libraries_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_locations_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_locations_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_locations_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_locations_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_locations_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_locations_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_locations_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_locations_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_locations_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_locations_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_locations_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_locations_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_measure_reports_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_measure_reports_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_measure_reports_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_measure_reports_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_measure_reports_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_measure_reports_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_measure_reports_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_measure_reports_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_measure_reports_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_measure_reports_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_measure_reports_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_measure_reports_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_measures_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_measures_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_measures_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_measures_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_measures_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_measures_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_measures_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_measures_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_measures_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_measures_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_measures_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_measures_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_naming_systems_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_naming_systems_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_naming_systems_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_naming_systems_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_naming_systems_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_naming_systems_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_naming_systems_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_naming_systems_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_naming_systems_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_naming_systems_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_naming_systems_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_naming_systems_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_organization_affiliations_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_organization_affiliations_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_organization_affiliations_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_organization_affiliations_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_organization_affiliations_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_organization_affiliations_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_organization_affiliations_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_organization_affiliations_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_organization_affiliations_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_organization_affiliations_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_organization_affiliations_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_organization_affiliations_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_organizations_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_organizations_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_organizations_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_organizations_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_organizations_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_organizations_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_organizations_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_organizations_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_organizations_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_organizations_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_organizations_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_organizations_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_patients_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_patients_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_patients_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_patients_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_patients_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_patients_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_patients_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_patients_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_patients_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_patients_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_patients_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_patients_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_practitioner_roles_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_practitioner_roles_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_practitioner_roles_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_practitioner_roles_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_practitioner_roles_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_practitioner_roles_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_practitioner_roles_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_practitioner_roles_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_practitioner_roles_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_practitioner_roles_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_practitioner_roles_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_practitioner_roles_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_practitioners_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_practitioners_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_practitioners_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_practitioners_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_practitioners_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_practitioners_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_practitioners_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_practitioners_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_practitioners_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_practitioners_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_practitioners_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_practitioners_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_provenances_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_provenances_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_provenances_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_provenances_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_provenances_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_provenances_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_provenances_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_provenances_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_provenances_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_provenances_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_provenances_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_provenances_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_questionnaires_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_questionnaires_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_questionnaires_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_questionnaires_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_questionnaires_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_questionnaires_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_questionnaires_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_questionnaires_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_questionnaires_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_questionnaires_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_questionnaires_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_questionnaires_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_research_studies_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_research_studies_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_research_studies_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_research_studies_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_research_studies_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_research_studies_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_research_studies_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_research_studies_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_research_studies_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_research_studies_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_research_studies_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_research_studies_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_resources_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_resources_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_resources_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_resources_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_resources_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_resources_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_resources_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_resources_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_resources_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_resources_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_resources_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_resources_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_structure_definitions_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_structure_definitions_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_structure_definitions_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_structure_definitions_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_structure_definitions_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_structure_definitions_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_structure_definitions_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_structure_definitions_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_structure_definitions_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_structure_definitions_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_structure_definitions_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_structure_definitions_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_subscriptions_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_subscriptions_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_subscriptions_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_subscriptions_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_subscriptions_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_subscriptions_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_subscriptions_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_subscriptions_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_subscriptions_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_subscriptions_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_subscriptions_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_subscriptions_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_value_sets_delete.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_value_sets_delete.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_value_sets_delete.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_value_sets_delete.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_value_sets_insert.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_value_sets_insert.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_value_sets_insert.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_value_sets_insert.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_value_sets_update.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_value_sets_update.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/trigger_functions/on_value_sets_update.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/trigger_functions/on_value_sets_update.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/activity_definitions_unique.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/activity_definitions_unique.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/activity_definitions_unique.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/activity_definitions_unique.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/code_systems_unique.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/code_systems_unique.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/code_systems_unique.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/code_systems_unique.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/endpoints_unique.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/endpoints_unique.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/endpoints_unique.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/endpoints_unique.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/naming_systems_unique.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/naming_systems_unique.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/naming_systems_unique.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/naming_systems_unique.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/organization_affiliations_unique.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/organization_affiliations_unique.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/organization_affiliations_unique.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/organization_affiliations_unique.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/organizations_unique.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/organizations_unique.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/organizations_unique.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/organizations_unique.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/structure_definitions_unique.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/structure_definitions_unique.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/structure_definitions_unique.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/structure_definitions_unique.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/subscriptions_unique.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/subscriptions_unique.sql similarity index 75% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/subscriptions_unique.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/subscriptions_unique.sql index 95b391275..8f967bd56 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/subscriptions_unique.sql +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/subscriptions_unique.sql @@ -1,10 +1,11 @@ CREATE OR REPLACE FUNCTION subscriptions_unique() RETURNS TRIGGER AS $$ BEGIN - PERFORM pg_advisory_xact_lock(hashtext((NEW.subscription->>'criteria') || (NEW.subscription->'channel'->>'type') || (NEW.subscription->'channel'->>'payload'))); + PERFORM pg_advisory_xact_lock(hashtext((NEW.subscription->>'criteria') || (NEW.subscription->'channel'->>'type'))); IF EXISTS (SELECT 1 FROM current_subscriptions WHERE subscription_id <> NEW.subscription_id AND subscription->>'criteria' = NEW.subscription->>'criteria' AND subscription->'channel'->>'type' = NEW.subscription->'channel'->>'type' - AND subscription->'channel'->>'payload' = NEW.subscription->'channel'->>'payload') THEN + AND ((subscription->'channel'->>'payload' = NEW.subscription->'channel'->>'payload') + OR (NOT subscription->'channel' ? 'payload' AND NOT NEW.subscription->'channel' ? 'payload'))) THEN RAISE EXCEPTION 'Conflict: Not inserting Subscription with criteria %, channel.type % and channel.payload %, resource already exists with given criteria, channel type and channel payload', NEW.subscription->>'criteria', NEW.subscription->'channel'->>'type', NEW.subscription->'channel'->>'payload' USING ERRCODE = 'unique_violation'; ELSE diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/tasks_unique.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/tasks_unique.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/tasks_unique.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/tasks_unique.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/value_sets_unique.sql b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/value_sets_unique.sql similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/db/unique_trigger_functions/value_sets_unique.sql rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/db/unique_trigger_functions/value_sets_unique.sql diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/static/bookmarks.js b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/bookmarks.js similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/static/bookmarks.js rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/bookmarks.js diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/static/dsf.css b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/dsf.css similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/static/dsf.css rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/dsf.css diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/static/favicon.svg b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/favicon.svg similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/static/favicon.svg rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/favicon.svg diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/static/favicon_32x32.png b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/favicon_32x32.png similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/static/favicon_32x32.png rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/favicon_32x32.png diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/static/favicon_96x96.png b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/favicon_96x96.png similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/static/favicon_96x96.png rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/favicon_96x96.png diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/static/form.css b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/form.css similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/static/form.css rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/form.css diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/static/form.js b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/form.js similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/static/form.js rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/form.js diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/static/help.js b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/help.js similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/static/help.js rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/help.js diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/static/logo.svg b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/logo.svg similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/static/logo.svg rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/logo.svg diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/static/main.js b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/main.js similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/static/main.js rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/main.js diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/static/prettify.css b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/prettify.css similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/static/prettify.css rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/prettify.css diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/static/prettify.js b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/prettify.js similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/static/prettify.js rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/prettify.js diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/static/tabs.js b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/tabs.js similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/static/tabs.js rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/tabs.js diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/static/util.js b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/util.js similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/static/util.js rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/util.js diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/main.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/main.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/main.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/main.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/resource.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resource.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/resource.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resource.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceActivityDefinition.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceActivityDefinition.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceActivityDefinition.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceActivityDefinition.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceCodeSystem.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceCodeSystem.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceCodeSystem.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceCodeSystem.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceElements.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceElements.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceElements.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceElements.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceEndpoint.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceEndpoint.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceEndpoint.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceEndpoint.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceLibrary.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceLibrary.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceLibrary.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceLibrary.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceMeasure.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceMeasure.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceMeasure.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceMeasure.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceMeasureReport.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceMeasureReport.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceMeasureReport.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceMeasureReport.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceNamingSystem.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceNamingSystem.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceNamingSystem.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceNamingSystem.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceOrganization.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceOrganization.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceOrganization.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceOrganization.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceOrganizationAffiliation.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceOrganizationAffiliation.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceOrganizationAffiliation.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceOrganizationAffiliation.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceQuestionnaire.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceQuestionnaire.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceQuestionnaire.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceQuestionnaire.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceQuestionnaireResponse.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceQuestionnaireResponse.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceQuestionnaireResponse.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceQuestionnaireResponse.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceStructureDefinition.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceStructureDefinition.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceStructureDefinition.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceStructureDefinition.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceSubscription.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceSubscription.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceSubscription.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceSubscription.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceTask.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceTask.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceTask.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceTask.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceValueSet.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceValueSet.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/resourceValueSet.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceValueSet.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/searchset.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchset.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/searchset.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchset.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetActivityDefinition.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetActivityDefinition.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetActivityDefinition.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetActivityDefinition.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetEndpoint.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetEndpoint.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetEndpoint.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetEndpoint.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetMeasureReport.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetMeasureReport.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetMeasureReport.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetMeasureReport.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetMetadataResource.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetMetadataResource.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetMetadataResource.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetMetadataResource.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetNamingSystem.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetNamingSystem.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetNamingSystem.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetNamingSystem.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetOrganization.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetOrganization.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetOrganization.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetOrganization.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetOrganizationAffiliation.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetOrganizationAffiliation.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetOrganizationAffiliation.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetOrganizationAffiliation.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetQuestionnaireResponse.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetQuestionnaireResponse.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetQuestionnaireResponse.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetQuestionnaireResponse.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetSubscription.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetSubscription.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetSubscription.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetSubscription.html diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetTask.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetTask.html similarity index 100% rename from dsf-fhir/dsf-fhir-server/src/main/resources/template/searchsetTask.html rename to dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/searchsetTask.html diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/authentication/IdentityProviderTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/authentication/IdentityProviderTest.java index 0d9f25314..8b4bb1d36 100644 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/authentication/IdentityProviderTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/authentication/IdentityProviderTest.java @@ -20,7 +20,6 @@ import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; import java.time.LocalDateTime; -import java.util.Collections; import java.util.EnumSet; import java.util.List; import java.util.Map; @@ -274,14 +273,12 @@ public void testGetPractitionerIdentityByX509Certificate() throws Exception when(organizationProvider.getOrganization(LOCAL_ORGANIZATION_CERTIFICATE)).thenReturn(Optional.empty()); when(organizationProvider.getLocalOrganization()).thenReturn(Optional.of(LOCAL_ORGANIZATION)); - when(roleConfig.getDsfRolesForEmail(LOCAL_PRACTITIONER_MAIL)) - .thenReturn(Collections.singletonList(FhirServerRole.CREATE)); + when(roleConfig.getDsfRolesForEmail(LOCAL_PRACTITIONER_MAIL)).thenReturn(List.of(FhirServerRole.CREATE)); when(roleConfig.getDsfRolesForThumbprint(LOCAL_PRACTITIONER_CERTIFICATE_THUMBPRINT)) - .thenReturn(Collections.singletonList(FhirServerRole.DELETE)); - when(roleConfig.getPractitionerRolesForEmail(LOCAL_PRACTITIONER_MAIL)) - .thenReturn(Collections.singletonList(PRACTIONER_ROLE1)); + .thenReturn(List.of(FhirServerRole.DELETE)); + when(roleConfig.getPractitionerRolesForEmail(LOCAL_PRACTITIONER_MAIL)).thenReturn(List.of(PRACTIONER_ROLE1)); when(roleConfig.getPractitionerRolesForThumbprint(LOCAL_PRACTITIONER_CERTIFICATE_THUMBPRINT)) - .thenReturn(Collections.singletonList(PRACTIONER_ROLE2)); + .thenReturn(List.of(PRACTIONER_ROLE2)); Identity i = provider.getIdentity(new X509Certificate[] { LOCAL_PRACTITIONER_CERTIFICATE }); assertNotNull(i); @@ -366,23 +363,17 @@ public void testGetPractitionerIdentityByOpenIdCredentials() throws Exception Map.of("resource_access", Map.of(TOKEN_ROLE2_CLIENT, Map.of("roles", new String[] { TOKEN_ROLE2 })), "groups", new String[] { TOKEN_GROUP })); - when(roleConfig.getDsfRolesForEmail(LOCAL_PRACTITIONER_MAIL)) - .thenReturn(Collections.singletonList(FhirServerRole.CREATE)); - when(roleConfig.getDsfRolesForTokenRole(TOKEN_ROLE1)) - .thenReturn(Collections.singletonList(FhirServerRole.DELETE)); + when(roleConfig.getDsfRolesForEmail(LOCAL_PRACTITIONER_MAIL)).thenReturn(List.of(FhirServerRole.CREATE)); + when(roleConfig.getDsfRolesForTokenRole(TOKEN_ROLE1)).thenReturn(List.of(FhirServerRole.DELETE)); when(roleConfig.getDsfRolesForTokenRole(TOKEN_ROLE2_CLIENT + "." + TOKEN_ROLE2)) - .thenReturn(Collections.singletonList(FhirServerRole.HISTORY)); - when(roleConfig.getDsfRolesForTokenGroup(TOKEN_GROUP)) - .thenReturn(Collections.singletonList(FhirServerRole.PERMANENT_DELETE)); - - when(roleConfig.getPractitionerRolesForEmail(LOCAL_PRACTITIONER_MAIL)) - .thenReturn(Collections.singletonList(PRACTIONER_ROLE1)); - when(roleConfig.getPractitionerRolesForTokenRole(TOKEN_ROLE1)) - .thenReturn(Collections.singletonList(PRACTIONER_ROLE2)); + .thenReturn(List.of(FhirServerRole.HISTORY)); + when(roleConfig.getDsfRolesForTokenGroup(TOKEN_GROUP)).thenReturn(List.of(FhirServerRole.PERMANENT_DELETE)); + + when(roleConfig.getPractitionerRolesForEmail(LOCAL_PRACTITIONER_MAIL)).thenReturn(List.of(PRACTIONER_ROLE1)); + when(roleConfig.getPractitionerRolesForTokenRole(TOKEN_ROLE1)).thenReturn(List.of(PRACTIONER_ROLE2)); when(roleConfig.getPractitionerRolesForTokenRole(TOKEN_ROLE2_CLIENT + "." + TOKEN_ROLE2)) - .thenReturn(Collections.singletonList(PRACTIONER_ROLE3)); - when(roleConfig.getPractitionerRolesForTokenGroup(TOKEN_GROUP)) - .thenReturn(Collections.singletonList(PRACTIONER_ROLE4)); + .thenReturn(List.of(PRACTIONER_ROLE3)); + when(roleConfig.getPractitionerRolesForTokenGroup(TOKEN_GROUP)).thenReturn(List.of(PRACTIONER_ROLE4)); Identity i = provider.getIdentity(credentials); assertNotNull(i); diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/AbstractDbTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/AbstractDbTest.java index 8d79cc45a..a4c815b0a 100644 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/AbstractDbTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/AbstractDbTest.java @@ -8,8 +8,6 @@ import org.postgresql.Driver; import org.slf4j.bridge.SLF4JBridgeHandler; -import com.fasterxml.jackson.core.StreamReadConstraints; - import dev.dsf.common.db.DataSourceWithLogger; public abstract class AbstractDbTest @@ -18,15 +16,11 @@ public abstract class AbstractDbTest { SLF4JBridgeHandler.removeHandlersForRootLogger(); SLF4JBridgeHandler.install(); - - // TODO remove workaround after upgrading to HAPI 6.8+, see https://github.com/hapifhir/hapi-fhir/issues/5205 - StreamReadConstraints.overrideDefaultStreamReadConstraints( - StreamReadConstraints.builder().maxStringLength(Integer.MAX_VALUE).build()); } protected static final boolean LOG_DB_STATEMENTS = true; - protected static final String CHANGE_LOG_FILE = "db/db.changelog.xml"; + protected static final String CHANGE_LOG_FILE = "fhir/db/db.changelog.xml"; protected static final String DATABASE_USERS_GROUP = "server_users_group"; protected static final String DATABASE_USER = "server_user"; diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/AbstractReadAccessDaoTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/AbstractReadAccessDaoTest.java index 134f3ec3a..3686d42ee 100644 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/AbstractReadAccessDaoTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/AbstractReadAccessDaoTest.java @@ -13,7 +13,7 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; -import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.UUID; import java.util.function.Consumer; @@ -412,7 +412,7 @@ private void testReadAccessTriggerUpdate(String accessType, Consumer<D> readAcce assertReadAccessEntryCount(1, 1, v1, accessType); - v1.getMeta().setTag(Collections.emptyList()); + v1.getMeta().setTag(List.of()); D v2 = getDao().update(v1); assertEquals(2L, (long) v2.getIdElement().getVersionIdPartAsLong()); @@ -1086,7 +1086,7 @@ private void testSearchWithUserFilterAfterReadAccessTrigger(String accessType, C assertReadAccessEntryCount(1, 1, createdD, accessType); SearchQuery<D> query = getDao().createSearchQuery(userCreator.apply(createdOrg), PageAndCount.from(1, 20)) - .configureParameters(Map.of("id", Collections.singletonList(createdD.getIdElement().getIdPart()))); + .configureParameters(Map.of("id", List.of(createdD.getIdElement().getIdPart()))); PartialResult<D> searchResult = getDao().search(query); assertNotNull(searchResult); assertEquals(expectedCount, searchResult.getTotal()); diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/BinaryDaoTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/BinaryDaoTest.java index 8a2e6ad49..4798883aa 100755 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/BinaryDaoTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/BinaryDaoTest.java @@ -16,7 +16,8 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.Arrays; -import java.util.Collections; +import java.util.List; +import java.util.Map; import java.util.UUID; import java.util.function.Consumer; import java.util.function.Function; @@ -147,7 +148,7 @@ public void testSearch() throws Exception assertNotNull(createdB); SearchQuery<Binary> query = dao.createSearchQuery(TestOrganizationIdentity.local(org), PageAndCount.single()); - query.configureParameters(Collections.emptyMap()); + query.configureParameters(Map.of()); assertNotNull(query); PartialResult<Binary> result = dao.search(query); @@ -174,7 +175,7 @@ public void testSearchBinaryWithSecurityContext() throws Exception assertNotNull(createdB); SearchQuery<Binary> query = dao.createSearchQuery(TestOrganizationIdentity.local(org), PageAndCount.single()); - query.configureParameters(Collections.emptyMap()); + query.configureParameters(Map.of()); assertNotNull(query); PartialResult<Binary> result = dao.search(query); @@ -213,7 +214,7 @@ public void testSearchBinaryWithSecurityContextOrganization() throws Exception SearchQuery<Binary> query = dao.createSearchQuery(TestOrganizationIdentity.local(createdOrg), PageAndCount.single()); - query.configureParameters(Collections.emptyMap()); + query.configureParameters(Map.of()); assertNotNull(query); PartialResult<Binary> result = dao.search(query); @@ -272,7 +273,7 @@ public void testSearchBinaryWithSecurityContextRole() throws Exception SearchQuery<Binary> query = dao.createSearchQuery(TestOrganizationIdentity.local(createdMemberOrg), PageAndCount.single()); - query.configureParameters(Collections.emptyMap()); + query.configureParameters(Map.of()); assertNotNull(query); PartialResult<Binary> result = dao.search(query); @@ -630,7 +631,7 @@ private void testReadAccessTriggerSecurityContextUpdate(String accessType, assertReadAccessEntryCount(2, 1, v1, accessType); assertReadAccessEntryCount(2, 1, createdB, accessType); - v1.getMeta().setTag(Collections.emptyList()); + v1.getMeta().setTag(List.of()); ResearchStudy v2 = researchStudyDao.update(v1); assertEquals(2L, (long) v2.getIdElement().getVersionIdPartAsLong()); @@ -680,7 +681,7 @@ private void testReadAccessTriggerSecurityContextVersionSpecificUpdate(String ac assertReadAccessEntryCount(2, 1, v1, accessType); assertReadAccessEntryCount(2, 1, createdB, accessType); - v1.getMeta().setTag(Collections.emptyList()); + v1.getMeta().setTag(List.of()); ResearchStudy v2 = researchStudyDao.update(v1); assertEquals(2L, (long) v2.getIdElement().getVersionIdPartAsLong()); diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/HistoryDaoTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/HistoryDaoTest.java index 23b58d3fc..8b80c494d 100644 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/HistoryDaoTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/HistoryDaoTest.java @@ -3,7 +3,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import java.util.Collections; +import java.util.List; import java.util.UUID; import javax.sql.DataSource; @@ -80,7 +80,7 @@ public void testReadHistory() throws Exception History history = dao.readHistory( filterFactory.getIdentityFilters(TestOrganizationIdentity.local(createdOrganization)), - PageAndCount.from(1, 1000), Collections.singletonList(new AtParameter()), new SinceParameter()); + PageAndCount.from(1, 1000), List.of(new AtParameter()), new SinceParameter()); assertNotNull(history); assertEquals(1, history.getTotal()); assertNotNull(history.getEntries()); @@ -99,8 +99,7 @@ public void testReadHistoryOrganization() throws Exception History history = dao.readHistory( filterFactory.getIdentityFilter(TestOrganizationIdentity.local(createdOrganization), Organization.class), - PageAndCount.from(1, 1000), Collections.singletonList(new AtParameter()), new SinceParameter(), - Organization.class); + PageAndCount.from(1, 1000), List.of(new AtParameter()), new SinceParameter(), Organization.class); assertNotNull(history); assertEquals(1, history.getTotal()); assertNotNull(history.getEntries()); @@ -119,8 +118,8 @@ public void testReadHistoryOrganizationWithId() throws Exception History history = dao.readHistory( filterFactory.getIdentityFilter(TestOrganizationIdentity.local(createdOrganization), Organization.class), - PageAndCount.from(1, 1000), Collections.singletonList(new AtParameter()), new SinceParameter(), - Organization.class, UUID.fromString(createdOrganization.getIdElement().getIdPart())); + PageAndCount.from(1, 1000), List.of(new AtParameter()), new SinceParameter(), Organization.class, + UUID.fromString(createdOrganization.getIdElement().getIdPart())); assertNotNull(history); assertEquals(1, history.getTotal()); diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/ProvenanceDaoTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/ProvenanceDaoTest.java index 62c267b38..22029cfbb 100755 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/ProvenanceDaoTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/dao/ProvenanceDaoTest.java @@ -4,9 +4,9 @@ import static org.junit.Assert.assertTrue; import java.util.Arrays; -import java.util.Collections; import java.util.Date; import java.util.GregorianCalendar; +import java.util.List; import org.hl7.fhir.r4.model.Provenance; import org.hl7.fhir.r4.model.Signature; @@ -40,7 +40,7 @@ protected void checkCreated(Provenance resource) @Override protected Provenance updateResource(Provenance resource) { - resource.setSignature(Collections.singletonList(new Signature().setData(signatureData))); + resource.setSignature(List.of(new Signature().setData(signatureData))); return resource; } diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/AbstractIntegrationTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/AbstractIntegrationTest.java index a4376ee36..cf6f2e1b5 100644 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/AbstractIntegrationTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/AbstractIntegrationTest.java @@ -18,8 +18,6 @@ import java.security.PrivateKey; import java.security.cert.Certificate; import java.security.cert.X509Certificate; -import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -105,10 +103,9 @@ public abstract class AbstractIntegrationTest extends AbstractDbTest private static final Logger logger = LoggerFactory.getLogger(AbstractIntegrationTest.class); protected static final String CONTEXT_PATH = "/fhir"; - protected static final String WEBSOCKET_URL = "wss://localhost:8001" + CONTEXT_PATH + "/ws"; private static final Path FHIR_BUNDLE_FILE = Paths.get("target", UUID.randomUUID().toString() + ".xml"); - private static final List<Path> FILES_TO_DELETE = Arrays.asList(FHIR_BUNDLE_FILE); + private static final List<Path> FILES_TO_DELETE = List.of(FHIR_BUNDLE_FILE); protected static final FhirContext fhirContext = FhirContext.forR4(); protected static final ReadAccessHelper readAccessHelper = new ReadAccessHelperImpl(); @@ -132,8 +129,8 @@ public static void beforeClass() throws Exception logger.info("Creating Bundle ..."); createTestBundle(certificates.getClientCertificate(), certificates.getExternalClientCertificate()); - ServerSocketChannel statusConnectorChannel = JettyServer.serverSocketChannel(); - ServerSocketChannel apiConnectorChannel = JettyServer.serverSocketChannel(); + ServerSocketChannel statusConnectorChannel = JettyServer.serverSocketChannel("127.0.0.1"); + ServerSocketChannel apiConnectorChannel = JettyServer.serverSocketChannel("127.0.0.1"); baseUrl = "https://localhost:" + apiConnectorChannel.socket().getLocalPort() + CONTEXT_PATH; @@ -169,12 +166,12 @@ private static FhirWebserviceClient createWebserviceClient(int apiPort, KeyStore referenceCleaner); } - private static WebsocketClient createWebsocketClient(KeyStore trustStore, KeyStore keyStore, + private static WebsocketClient createWebsocketClient(int apiPort, KeyStore trustStore, KeyStore keyStore, char[] keyStorePassword, String subscriptionIdPart) { return new WebsocketClientTyrus(() -> - {}, URI.create(WEBSOCKET_URL), trustStore, keyStore, keyStorePassword, null, null, null, - "Integration Test Client", subscriptionIdPart); + {}, URI.create("wss://localhost:" + apiPort + CONTEXT_PATH + "/ws"), trustStore, keyStore, keyStorePassword, + null, null, null, "Integration Test Client", subscriptionIdPart); } private static JettyServer startFhirServer(ServerSocketChannel statusConnectorChannel, @@ -228,7 +225,7 @@ private static JettyServer startFhirServer(ServerSocketChannel statusConnectorCh Function<Server, ServerConnector> apiConnector = JettyServer.httpsConnector(apiConnectorChannel, caCertificate, serverCertificateKeyStore, keyStorePassword, false); Function<Server, ServerConnector> statusConnector = JettyServer.statusConnector(statusConnectorChannel); - List<Class<? extends ServletContainerInitializer>> servletContainerInitializers = Arrays.asList( + List<Class<? extends ServletContainerInitializer>> servletContainerInitializers = List.of( JakartaWebSocketServletContainerInitializer.class, JerseyServletContainerInitializer.class, SpringServletContainerInitializer.class); @@ -271,7 +268,7 @@ protected static Bundle readBundle(Path bundleTemplateFile, IParser parser) } } - protected static void writeBundle(Path bundleFile, Bundle bundle) + private static void writeBundle(Path bundleFile, Bundle bundle) { try (OutputStream out = Files.newOutputStream(bundleFile); OutputStreamWriter writer = new OutputStreamWriter(out)) @@ -330,13 +327,11 @@ private static void createTestBundle(ClientCertificate clientCertificate, @AfterClass public static void afterClass() throws Exception { - defaultDataSource.unwrap(BasicDataSource.class).close(); - try { if (fhirServer != null) { - logger.info("Stoping FHIR Server ..."); + logger.info("Stopping FHIR Server ..."); fhirServer.stop(); } } @@ -345,6 +340,8 @@ public static void afterClass() throws Exception logger.error("Error while stopping FHIR Server", e); } + defaultDataSource.unwrap(BasicDataSource.class).close(); + logger.info("Deleting files {} ...", FILES_TO_DELETE); FILES_TO_DELETE.forEach(AbstractIntegrationTest::deleteFile); } @@ -390,9 +387,8 @@ protected static FhirWebserviceClient getPractitionerWebserviceClient() protected static WebsocketClient getWebsocketClient() { Bundle bundle = getWebserviceClient().searchWithStrictHandling(Subscription.class, - Map.of("criteria", Collections.singletonList("Task?status=requested"), "status", - Collections.singletonList("active"), "type", Collections.singletonList("websocket"), "payload", - Collections.singletonList("application/fhir+json"))); + Map.of("criteria", List.of("Task?status=requested"), "status", List.of("active"), "type", + List.of("websocket"), "payload", List.of("application/fhir+json"))); assertNotNull(bundle); assertEquals(1, bundle.getTotal()); @@ -403,7 +399,7 @@ protected static WebsocketClient getWebsocketClient() assertNotNull(subscription.getIdElement()); assertNotNull(subscription.getIdElement().getIdPart()); - return createWebsocketClient(certificates.getClientCertificate().getTrustStore(), + return createWebsocketClient(fhirServer.getApiPort(), certificates.getClientCertificate().getTrustStore(), certificates.getClientCertificate().getKeyStore(), certificates.getClientCertificate().getKeyStorePassword(), subscription.getIdElement().getIdPart()); } diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/BinaryIntegrationTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/BinaryIntegrationTest.java index 8f22e6504..5568853f3 100755 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/BinaryIntegrationTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/BinaryIntegrationTest.java @@ -12,7 +12,6 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Arrays; -import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; @@ -225,7 +224,7 @@ public void testReadAllowedExternalUser() throws Exception OrganizationDao orgDao = getSpringWebApplicationContext().getBean(OrganizationDao.class); PartialResult<Organization> result = orgDao .search(orgDao.createSearchQueryWithoutUserFilter(PageAndCount.single()) - .configureParameters(Map.of("name", Arrays.asList("External Test Organization")))); + .configureParameters(Map.of("name", List.of("External Test Organization")))); assertNotNull(result); assertEquals(1, result.getTotal()); assertNotNull(result.getPartialResult()); @@ -268,7 +267,7 @@ public void testReadAllowedExternalUserViaSecurityContext() throws Exception OrganizationDao orgDao = getSpringWebApplicationContext().getBean(OrganizationDao.class); PartialResult<Organization> result = orgDao .search(orgDao.createSearchQueryWithoutUserFilter(PageAndCount.single()) - .configureParameters(Map.of("name", Arrays.asList("External Test Organization")))); + .configureParameters(Map.of("name", List.of("External Test Organization")))); assertNotNull(result); assertEquals(1, result.getTotal()); assertNotNull(result.getPartialResult()); @@ -305,7 +304,7 @@ public void testReadAllowedExternalUserViaSecurityContextDocumentReference() thr OrganizationDao orgDao = getSpringWebApplicationContext().getBean(OrganizationDao.class); PartialResult<Organization> result = orgDao .search(orgDao.createSearchQueryWithoutUserFilter(PageAndCount.single()) - .configureParameters(Map.of("name", Arrays.asList("External Test Organization")))); + .configureParameters(Map.of("name", List.of("External Test Organization")))); assertNotNull(result); assertEquals(1, result.getTotal()); assertNotNull(result.getPartialResult()); @@ -343,7 +342,7 @@ public void testReadNotAllowedExternalUser() throws Exception OrganizationDao orgDao = getSpringWebApplicationContext().getBean(OrganizationDao.class); PartialResult<Organization> result = orgDao .search(orgDao.createSearchQueryWithoutUserFilter(PageAndCount.single()) - .configureParameters(Map.of("name", Arrays.asList("Test Organization")))); + .configureParameters(Map.of("name", List.of("Test Organization")))); assertNotNull(result); assertEquals(1, result.getTotal()); assertNotNull(result.getPartialResult()); @@ -402,7 +401,7 @@ public void testReadAllowedExternalUserViaTransactionBundle() throws Exception OrganizationDao orgDao = getSpringWebApplicationContext().getBean(OrganizationDao.class); PartialResult<Organization> result = orgDao .search(orgDao.createSearchQueryWithoutUserFilter(PageAndCount.single()) - .configureParameters(Map.of("name", Arrays.asList("External Test Organization")))); + .configureParameters(Map.of("name", List.of("External Test Organization")))); assertNotNull(result); assertEquals(1, result.getTotal()); assertNotNull(result.getPartialResult()); @@ -494,7 +493,7 @@ public void testReadAllowedExternalUserViaBatchBundle() throws Exception OrganizationDao orgDao = getSpringWebApplicationContext().getBean(OrganizationDao.class); PartialResult<Organization> result = orgDao .search(orgDao.createSearchQueryWithoutUserFilter(PageAndCount.single()) - .configureParameters(Map.of("name", Arrays.asList("External Test Organization")))); + .configureParameters(Map.of("name", List.of("External Test Organization")))); assertNotNull(result); assertEquals(1, result.getTotal()); assertNotNull(result.getPartialResult()); @@ -723,7 +722,7 @@ public void testHeadAllowedLocalUserNotFoundViaBatchBundleWithVersion() throws E public void testSearchAllowedLocalUserNotFound() throws Exception { Bundle resultBundle = getWebserviceClient().search(Binary.class, - Map.of("_id", Collections.singletonList(UUID.randomUUID().toString()))); + Map.of("_id", List.of(UUID.randomUUID().toString()))); assertNotNull(resultBundle); assertEquals(0, resultBundle.getTotal()); @@ -1017,7 +1016,7 @@ public void testHeadAllowedExternalUserViaTransactionBundle() throws Exception OrganizationDao orgDao = getSpringWebApplicationContext().getBean(OrganizationDao.class); PartialResult<Organization> result = orgDao .search(orgDao.createSearchQueryWithoutUserFilter(PageAndCount.single()) - .configureParameters(Map.of("name", Arrays.asList("External Test Organization")))); + .configureParameters(Map.of("name", List.of("External Test Organization")))); assertNotNull(result); assertEquals(1, result.getTotal()); assertNotNull(result.getPartialResult()); @@ -1103,7 +1102,7 @@ public void testHeadAllowedExternalUserViaBatchBundle() throws Exception OrganizationDao orgDao = getSpringWebApplicationContext().getBean(OrganizationDao.class); PartialResult<Organization> result = orgDao .search(orgDao.createSearchQueryWithoutUserFilter(PageAndCount.single()) - .configureParameters(Map.of("name", Arrays.asList("External Test Organization")))); + .configureParameters(Map.of("name", List.of("External Test Organization")))); assertNotNull(result); assertEquals(1, result.getTotal()); assertNotNull(result.getPartialResult()); @@ -2359,7 +2358,7 @@ public void testSearchAll() throws Exception b3 = binaryDao.create(b3); b4 = binaryDao.create(b4); - Bundle searchBundle = getWebserviceClient().search(Binary.class, Collections.emptyMap()); + Bundle searchBundle = getWebserviceClient().search(Binary.class, Map.of()); assertNotNull(searchBundle); assertEquals(4, searchBundle.getTotal()); assertTrue(searchBundle.getEntry().stream() @@ -2368,8 +2367,8 @@ public void testSearchAll() throws Exception String actualIds = searchBundle.getEntry().stream().map(BundleEntryComponent::getResource) .map(r -> "Binary/" + r.getIdElement().getIdPart() + "/_history/" + r.getMeta().getVersionId()).sorted() .collect(Collectors.joining(", ")); - String expectedIds = Arrays.asList(b1, b2, b3, b4).stream().map(b -> b.getIdElement().getValueAsString()) - .sorted().collect(Collectors.joining(", ")); + String expectedIds = List.of(b1, b2, b3, b4).stream().map(b -> b.getIdElement().getValueAsString()).sorted() + .collect(Collectors.joining(", ")); assertEquals(expectedIds, actualIds); } @@ -2428,7 +2427,7 @@ public void testSearchAllExternalUser() throws Exception b4 = binaryDao.create(b4); b5 = binaryDao.create(b5); - Bundle searchBundle = getExternalWebserviceClient().search(Binary.class, Collections.emptyMap()); + Bundle searchBundle = getExternalWebserviceClient().search(Binary.class, Map.of()); assertNotNull(searchBundle); assertEquals(3, searchBundle.getTotal()); assertTrue(searchBundle.getEntry().stream() @@ -2437,7 +2436,7 @@ public void testSearchAllExternalUser() throws Exception String actualIds = searchBundle.getEntry().stream().map(BundleEntryComponent::getResource) .map(r -> "Binary/" + r.getIdElement().getIdPart() + "/_history/" + r.getMeta().getVersionId()).sorted() .collect(Collectors.joining(", ")); - String expectedIds = Arrays.asList(b2, b3, b5).stream().map(b -> b.getIdElement().getValueAsString()).sorted() + String expectedIds = List.of(b2, b3, b5).stream().map(b -> b.getIdElement().getValueAsString()).sorted() .collect(Collectors.joining(", ")); assertEquals(expectedIds, actualIds); } diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/BundleIntegrationTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/BundleIntegrationTest.java index f7d3607fc..ecf398ec1 100644 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/BundleIntegrationTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/BundleIntegrationTest.java @@ -9,8 +9,6 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; @@ -58,8 +56,8 @@ public void testCreateBundle() throws Exception logger.debug(fhirContext.newJsonParser().encodeResourceToString(allowList)); - Bundle updatedBundle = getWebserviceClient().updateConditionaly(allowList, Map.of("identifier", - Collections.singletonList("http://dsf.dev/fhir/CodeSystem/update-allow-list|allow_list"))); + Bundle updatedBundle = getWebserviceClient().updateConditionaly(allowList, + Map.of("identifier", List.of("http://dsf.dev/fhir/CodeSystem/update-allow-list|allow_list"))); assertNotNull(updatedBundle); } @@ -72,8 +70,8 @@ public void testCreateBundleReturnMinimal() throws Exception logger.debug(fhirContext.newJsonParser().encodeResourceToString(allowList)); - IdType id = getWebserviceClient().withMinimalReturn().updateConditionaly(allowList, Map.of("identifier", - Collections.singletonList("http://dsf.dev/fhir/CodeSystem/update-allow-list|allow_list"))); + IdType id = getWebserviceClient().withMinimalReturn().updateConditionaly(allowList, + Map.of("identifier", List.of("http://dsf.dev/fhir/CodeSystem/update-allow-list|allow_list"))); assertNotNull(id); } @@ -87,8 +85,7 @@ public void testCreateBundleReturnOperationOutcome() throws Exception logger.debug(fhirContext.newJsonParser().encodeResourceToString(allowList)); OperationOutcome outcome = getWebserviceClient().withOperationOutcomeReturn().updateConditionaly(allowList, - Map.of("identifier", - Collections.singletonList("http://dsf.dev/fhir/CodeSystem/update-allow-list|allow_list"))); + Map.of("identifier", List.of("http://dsf.dev/fhir/CodeSystem/update-allow-list|allow_list"))); assertNotNull(outcome); } @@ -182,8 +179,8 @@ public void testPostTransactionBundle() throws Exception Bundle rBundle = getWebserviceClient().postBundle(bundle); - checkReturnBundle(BundleType.TRANSACTIONRESPONSE, rBundle, bundle.getEntry().size(), Arrays.asList("200 OK", - "201 Created", "200 OK", "200 OK", "200 OK", "200 OK", "200 OK", "404 Not Found")); + checkReturnBundle(BundleType.TRANSACTIONRESPONSE, rBundle, bundle.getEntry().size(), + List.of("200 OK", "201 Created", "200 OK", "200 OK", "200 OK", "200 OK", "200 OK", "404 Not Found")); DataSource dataSource = getSpringWebApplicationContext().getBean("dataSource", DataSource.class); try (Connection connection = dataSource.getConnection(); @@ -206,8 +203,8 @@ public void testPostBatchBundle() throws Exception Bundle rBundle = getWebserviceClient().postBundle(bundle); - checkReturnBundle(BundleType.BATCHRESPONSE, rBundle, bundle.getEntry().size(), Arrays.asList("200 OK", - "201 Created", "200 OK", "200 OK", "200 OK", "200 OK", "200 OK", "404 Not Found")); + checkReturnBundle(BundleType.BATCHRESPONSE, rBundle, bundle.getEntry().size(), + List.of("200 OK", "201 Created", "200 OK", "200 OK", "200 OK", "200 OK", "200 OK", "404 Not Found")); DataSource dataSource = getSpringWebApplicationContext().getBean("dataSource", DataSource.class); try (Connection connection = dataSource.getConnection(); @@ -315,7 +312,7 @@ public void testPostPartialyFailingBatchBundle() throws Exception Bundle rBundle = getWebserviceClient().postBundle(bundle); checkReturnBundle(BundleType.BATCHRESPONSE, rBundle, bundle.getEntry().size(), - Arrays.asList("200 OK", "405 Method Not Allowed")); + List.of("200 OK", "405 Method Not Allowed")); DataSource dataSource = getSpringWebApplicationContext().getBean("dataSource", DataSource.class); try (Connection connection = dataSource.getConnection(); diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/DocumentReferenceIntegrationTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/DocumentReferenceIntegrationTest.java index 4359c191a..b9fe97362 100644 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/DocumentReferenceIntegrationTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/DocumentReferenceIntegrationTest.java @@ -5,8 +5,8 @@ import static org.junit.Assert.assertTrue; import java.nio.charset.StandardCharsets; -import java.util.Collections; import java.util.Date; +import java.util.List; import java.util.Map; import org.hl7.fhir.r4.model.Bundle; @@ -139,44 +139,42 @@ public void testSearchByIdentifier() throws Exception assertNotNull(created.getIdElement().getVersionIdPart()); Bundle bundle1 = getWebserviceClient().search(DocumentReference.class, - Map.of("identifier", Collections.singletonList(system + "|" + value1))); + Map.of("identifier", List.of(system + "|" + value1))); assertFound(bundle1, created); Bundle bundle1not = getWebserviceClient().search(DocumentReference.class, - Map.of("identifier:not", Collections.singletonList(system + "|" + value1))); + Map.of("identifier:not", List.of(system + "|" + value1))); assertNotFound(bundle1not); - Bundle bundle2 = getWebserviceClient().search(DocumentReference.class, - Map.of("identifier", Collections.singletonList(value1))); + Bundle bundle2 = getWebserviceClient().search(DocumentReference.class, Map.of("identifier", List.of(value1))); assertFound(bundle2, created); Bundle bundle2not = getWebserviceClient().search(DocumentReference.class, - Map.of("identifier:not", Collections.singletonList(value1))); + Map.of("identifier:not", List.of(value1))); assertNotFound(bundle2not); Bundle bundle3 = getWebserviceClient().search(DocumentReference.class, - Map.of("identifier:not", Collections.singletonList(system + "|Baz"))); + Map.of("identifier:not", List.of(system + "|Baz"))); assertFound(bundle3, created); Bundle bundle4 = getWebserviceClient().search(DocumentReference.class, - Map.of("identifier:not", Collections.singletonList("Something|Baz"))); + Map.of("identifier:not", List.of("Something|Baz"))); assertFound(bundle4, created); Bundle bundle5 = getWebserviceClient().search(DocumentReference.class, - Map.of("identifier:not", Collections.singletonList("Baz"))); + Map.of("identifier:not", List.of("Baz"))); assertFound(bundle5, created); Bundle bundle6 = getWebserviceClient().search(DocumentReference.class, - Map.of("identifier", Collections.singletonList(system + "|" + value2))); + Map.of("identifier", List.of(system + "|" + value2))); assertFound(bundle6, created); Bundle bundle6not = getWebserviceClient().search(DocumentReference.class, - Map.of("identifier:not", Collections.singletonList(system + "|" + value2))); + Map.of("identifier:not", List.of(system + "|" + value2))); assertNotFound(bundle6not); - Bundle bundle7 = getWebserviceClient().search(DocumentReference.class, - Map.of("identifier", Collections.singletonList(value2))); + Bundle bundle7 = getWebserviceClient().search(DocumentReference.class, Map.of("identifier", List.of(value2))); assertFound(bundle7, created); Bundle bundle7not = getWebserviceClient().search(DocumentReference.class, - Map.of("identifier:not", Collections.singletonList(value2))); + Map.of("identifier:not", List.of(value2))); assertNotFound(bundle7not); Bundle bundle8 = getWebserviceClient().search(DocumentReference.class, - Map.of("identifier", Collections.singletonList(system + "|"))); + Map.of("identifier", List.of(system + "|"))); assertFound(bundle8, created); Bundle bundle8not = getWebserviceClient().search(DocumentReference.class, - Map.of("identifier:not", Collections.singletonList(system + "|"))); + Map.of("identifier:not", List.of(system + "|"))); assertNotFound(bundle8not); } @@ -195,11 +193,10 @@ public void testSearchByIdentifierNoSystem() throws Exception assertNotNull(created.getIdElement().getIdPart()); assertNotNull(created.getIdElement().getVersionIdPart()); - Bundle bundle = getWebserviceClient().search(DocumentReference.class, - Map.of("identifier", Collections.singletonList("|Foo"))); + Bundle bundle = getWebserviceClient().search(DocumentReference.class, Map.of("identifier", List.of("|Foo"))); assertFound(bundle, created); Bundle bundleNot = getWebserviceClient().search(DocumentReference.class, - Map.of("identifier:not", Collections.singletonList("|Foo"))); + Map.of("identifier:not", List.of("|Foo"))); assertNotFound(bundleNot); } diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/EndpointIntegrationTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/EndpointIntegrationTest.java index 64c58dc01..4444aa565 100644 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/EndpointIntegrationTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/EndpointIntegrationTest.java @@ -5,7 +5,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; @@ -56,7 +56,7 @@ private Endpoint createEndpoint() @Test public void testSearchAll() throws Exception { - Bundle searchBundle = getWebserviceClient().search(Endpoint.class, Collections.emptyMap()); + Bundle searchBundle = getWebserviceClient().search(Endpoint.class, Map.of()); assertNotNull(searchBundle); assertEquals(2, searchBundle.getTotal()); @@ -79,14 +79,14 @@ public void testSearchAll() throws Exception public void testSearchWithUnsupportedQueryParameterStrictHandling() throws Exception { expectBadRequest(() -> getWebserviceClient().searchWithStrictHandling(Endpoint.class, - Map.of("not-supported-parameter", Collections.singletonList("not-supported-parameter-value")))); + Map.of("not-supported-parameter", List.of("not-supported-parameter-value")))); } @Test public void testSearchWithUnsupportedQueryParameterLenientHandling() throws Exception { Bundle searchBundle = getWebserviceClient().search(Endpoint.class, - Map.of("not-supported-parameter", Collections.singletonList("not-supported-parameter-value"))); + Map.of("not-supported-parameter", List.of("not-supported-parameter-value"))); assertNotNull(searchBundle.getEntry()); assertEquals(3, searchBundle.getEntry().size()); @@ -113,7 +113,7 @@ public void testSearchWithUnsupportedQueryParameterLenientHandling() throws Exce public void testSearchEndpointIncludeOrganization() throws Exception { Bundle searchBundle = getWebserviceClient().search(Endpoint.class, - Map.of("_include", Collections.singletonList("Endpoint:organization"))); + Map.of("_include", List.of("Endpoint:organization"))); assertNotNull(searchBundle); assertEquals(2, searchBundle.getTotal()); assertEquals(4, searchBundle.getEntry().size()); @@ -147,7 +147,7 @@ public void testSearchEndpointIncludeOrganization() throws Exception public void testSearchEndpointRevIncludeOrganization() throws Exception { Bundle searchBundle = getWebserviceClient().search(Endpoint.class, - Map.of("_revinclude", Collections.singletonList("Organization:endpoint"))); + Map.of("_revinclude", List.of("Organization:endpoint"))); assertNotNull(searchBundle); assertEquals(2, searchBundle.getTotal()); assertEquals(4, searchBundle.getEntry().size()); @@ -330,8 +330,8 @@ public void testUpdateWithRelativeLiteralReferenceNotExisting() throws Exception EndpointDao endpointDao = getSpringWebApplicationContext().getBean(EndpointDao.class); SearchQuery<Organization> query = organizationDao.createSearchQueryWithoutUserFilter(PageAndCount.single()) - .configureParameters(Map.of("identifier", - Collections.singletonList("http://dsf.dev/sid/organization-identifier|Test_Organization"))); + .configureParameters( + Map.of("identifier", List.of("http://dsf.dev/sid/organization-identifier|Test_Organization"))); PartialResult<Organization> organizationResult = organizationDao.search(query); assertNotNull(organizationResult); assertEquals(1, organizationResult.getTotal()); @@ -358,8 +358,8 @@ public void testUpdateViaBundleWithRelativeLiteralReferenceNotExisting() throws EndpointDao endpointDao = getSpringWebApplicationContext().getBean(EndpointDao.class); SearchQuery<Organization> query = organizationDao.createSearchQueryWithoutUserFilter(PageAndCount.single()) - .configureParameters(Map.of("identifier", - Collections.singletonList("http://dsf.dev/sid/organization-identifier|Test_Organization"))); + .configureParameters( + Map.of("identifier", List.of("http://dsf.dev/sid/organization-identifier|Test_Organization"))); PartialResult<Organization> organizationResult = organizationDao.search(query); assertNotNull(organizationResult); assertEquals(1, organizationResult.getTotal()); diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/GroupIntegrationTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/GroupIntegrationTest.java index 6e9f33a7f..fbb286456 100644 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/GroupIntegrationTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/GroupIntegrationTest.java @@ -4,8 +4,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import java.util.Arrays; -import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -48,8 +47,7 @@ public void testSearchGroupByIdentifier() throws Exception assertTrue(created.hasIdentifier()); assertEquals(identifier, created.getIdentifierFirstRep().getValue()); - Bundle bundle = getWebserviceClient().search(Group.class, - Map.of("identifier", Collections.singletonList(identifier))); + Bundle bundle = getWebserviceClient().search(Group.class, Map.of("identifier", List.of(identifier))); assertNotNull(bundle); assertEquals(1, bundle.getTotal()); assertTrue(bundle.hasEntry()); @@ -80,7 +78,7 @@ public void testSearchGroupByTwoIdentifiers() throws Exception assertTrue(created2.hasIdElement()); Bundle bundle = getWebserviceClient().search(Group.class, - Map.of("identifier", Arrays.asList(identifier1, identifier2))); + Map.of("identifier", List.of(identifier1, identifier2))); assertNotNull(bundle); assertEquals(1, bundle.getTotal()); assertTrue(bundle.hasEntry()); diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/MeasureIntegrationTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/MeasureIntegrationTest.java index 67f40100d..a52a40359 100644 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/MeasureIntegrationTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/MeasureIntegrationTest.java @@ -5,7 +5,6 @@ import static org.junit.Assert.assertTrue; import java.nio.charset.StandardCharsets; -import java.util.Collections; import java.util.List; import java.util.Map; @@ -64,8 +63,7 @@ public void testSearchIncludingLibrary() throws Exception Measure measure = measureDao.create(createMeasure()); Bundle searchBundle = getWebserviceClient().search(Measure.class, - Map.of("_id", Collections.singletonList(measure.getIdElement().getIdPart()), "_include", - Collections.singletonList("Measure:depends-on"))); + Map.of("_id", List.of(measure.getIdElement().getIdPart()), "_include", List.of("Measure:depends-on"))); assertNotNull(searchBundle.getEntry()); assertEquals(2, searchBundle.getEntry().size()); @@ -99,8 +97,8 @@ public void testSearchMeasureDependingOnLibrary() throws Exception MeasureDao measureDao = getSpringWebApplicationContext().getBean(MeasureDao.class); String measureId = measureDao.create(createMeasure()).getIdElement().getIdPart(); - Bundle resultBundle = getWebserviceClient().searchWithStrictHandling(Measure.class, Map.of("depends-on", - Collections.singletonList("https://foo.bar/fhir/Library/0a887526-2b9f-413a-8842-5e9252e2d7f7"))); + Bundle resultBundle = getWebserviceClient().searchWithStrictHandling(Measure.class, + Map.of("depends-on", List.of("https://foo.bar/fhir/Library/0a887526-2b9f-413a-8842-5e9252e2d7f7"))); assertNotNull(resultBundle); assertEquals(1, resultBundle.getTotal()); @@ -116,7 +114,7 @@ public void testSearchMeasureDependingOnLibraryNotSupportedById() throws Excepti measureDao.create(createMeasure()).getIdElement().getIdPart(); expectBadRequest(() -> getWebserviceClient().searchWithStrictHandling(Measure.class, - Map.of("depends-on", Collections.singletonList("0a887526-2b9f-413a-8842-5e9252e2d7f7")))); + Map.of("depends-on", List.of("0a887526-2b9f-413a-8842-5e9252e2d7f7")))); } @Test @@ -132,8 +130,8 @@ public void testSearchMeasureDependingOnRelatedArtifactLibrary() throws Exceptio MeasureDao measureDao = getSpringWebApplicationContext().getBean(MeasureDao.class); String measureId = measureDao.create(measure).getIdElement().getIdPart(); - Bundle resultBundle = getWebserviceClient().searchWithStrictHandling(Measure.class, Map.of("depends-on", - Collections.singletonList("https://foo.bar/fhir/Library/0a887526-2b9f-413a-8842-5e9252e2d7f7"))); + Bundle resultBundle = getWebserviceClient().searchWithStrictHandling(Measure.class, + Map.of("depends-on", List.of("https://foo.bar/fhir/Library/0a887526-2b9f-413a-8842-5e9252e2d7f7"))); assertNotNull(resultBundle); assertEquals(1, resultBundle.getTotal()); diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/OrganizationIntegrationTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/OrganizationIntegrationTest.java index a97ae1850..f4db38943 100755 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/OrganizationIntegrationTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/OrganizationIntegrationTest.java @@ -4,7 +4,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import java.util.Collections; import java.util.List; import java.util.Map; @@ -23,7 +22,7 @@ public class OrganizationIntegrationTest extends AbstractIntegrationTest @Test public void testSearchAll() throws Exception { - Bundle searchBundle = getWebserviceClient().search(Organization.class, Collections.emptyMap()); + Bundle searchBundle = getWebserviceClient().search(Organization.class, Map.of()); assertNotNull(searchBundle); assertEquals(3, searchBundle.getTotal()); assertTrue(searchBundle.getEntryFirstRep().getResource() instanceof Organization); @@ -33,7 +32,7 @@ public void testSearchAll() throws Exception public void testSearchOrganizationIncludeEndpoint() throws Exception { Bundle searchBundle = getWebserviceClient().search(Organization.class, - Map.of("_include", Collections.singletonList("Organization:endpoint"))); + Map.of("_include", List.of("Organization:endpoint"))); assertNotNull(searchBundle); assertEquals(3, searchBundle.getTotal()); assertEquals(5, searchBundle.getEntry().size()); @@ -73,7 +72,7 @@ public void testSearchOrganizationIncludeEndpoint() throws Exception public void testSearchOrganizationRevIncludeEndpoint() throws Exception { Bundle searchBundle = getWebserviceClient().search(Organization.class, - Map.of("_revinclude", Collections.singletonList("Endpoint:organization"))); + Map.of("_revinclude", List.of("Endpoint:organization"))); assertNotNull(searchBundle); assertEquals(3, searchBundle.getTotal()); assertEquals(5, searchBundle.getEntry().size()); @@ -112,8 +111,8 @@ public void testSearchOrganizationRevIncludeEndpoint() throws Exception @Test public void testUpdateOrganizationWithNewThumbprint() throws Exception { - Bundle bundle = getWebserviceClient().search(Organization.class, Map.of("identifier", - Collections.singletonList("http://dsf.dev/sid/organization-identifier|External_Test_Organization"))); + Bundle bundle = getWebserviceClient().search(Organization.class, + Map.of("identifier", List.of("http://dsf.dev/sid/organization-identifier|External_Test_Organization"))); assertNotNull(bundle); assertEquals(1, bundle.getTotal()); assertNotNull(bundle.getEntry()); @@ -138,8 +137,8 @@ public void testUpdateOrganizationWithNewThumbprint() throws Exception @Test public void testUpdateOrganizationWithExistingThumbprint() throws Exception { - Bundle bundle1 = getWebserviceClient().search(Organization.class, Map.of("identifier", - Collections.singletonList("http://dsf.dev/sid/organization-identifier|Test_Organization"))); + Bundle bundle1 = getWebserviceClient().search(Organization.class, + Map.of("identifier", List.of("http://dsf.dev/sid/organization-identifier|Test_Organization"))); assertNotNull(bundle1); assertEquals(1, bundle1.getTotal()); assertNotNull(bundle1.getEntry()); @@ -158,8 +157,8 @@ public void testUpdateOrganizationWithExistingThumbprint() throws Exception String existingThumbprint = ((StringType) thumbprints1.get(0).getValue()).getValue(); - Bundle bundle2 = getWebserviceClient().search(Organization.class, Map.of("identifier", - Collections.singletonList("http://dsf.dev/sid/organization-identifier|External_Test_Organization"))); + Bundle bundle2 = getWebserviceClient().search(Organization.class, + Map.of("identifier", List.of("http://dsf.dev/sid/organization-identifier|External_Test_Organization"))); assertNotNull(bundle2); assertEquals(1, bundle2.getTotal()); assertNotNull(bundle2.getEntry()); @@ -184,8 +183,8 @@ public void testUpdateOrganizationWithExistingThumbprint() throws Exception @Test public void testUpdateOrganizationWithExistingIdentifier() throws Exception { - Bundle bundle = getWebserviceClient().search(Organization.class, Map.of("identifier", - Collections.singletonList("http://dsf.dev/sid/organization-identifier|External_Test_Organization"))); + Bundle bundle = getWebserviceClient().search(Organization.class, + Map.of("identifier", List.of("http://dsf.dev/sid/organization-identifier|External_Test_Organization"))); assertNotNull(bundle); assertEquals(1, bundle.getTotal()); assertNotNull(bundle.getEntry()); @@ -205,8 +204,8 @@ public void testUpdateOrganizationWithExistingIdentifier() throws Exception @Test public void testUpdateOrganizationAddNewThumbprint() throws Exception { - Bundle bundle = getWebserviceClient().search(Organization.class, Map.of("identifier", - Collections.singletonList("http://dsf.dev/sid/organization-identifier|External_Test_Organization"))); + Bundle bundle = getWebserviceClient().search(Organization.class, + Map.of("identifier", List.of("http://dsf.dev/sid/organization-identifier|External_Test_Organization"))); assertNotNull(bundle); assertEquals(1, bundle.getTotal()); assertNotNull(bundle.getEntry()); @@ -232,14 +231,14 @@ public void testUpdateOrganizationAddNewThumbprint() throws Exception getWebserviceClient().update(org); // test if authentication still works - getExternalWebserviceClient().search(Organization.class, Collections.emptyMap()); + getExternalWebserviceClient().search(Organization.class, Map.of()); } @Test public void testSearchWithUnsupportedRevIncludeParameter() throws Exception { Bundle searchBundle = getWebserviceClient().search(Organization.class, - Map.of("_revinclude", Collections.singletonList("Endpoint:foo"))); + Map.of("_revinclude", List.of("Endpoint:foo"))); assertNotNull(searchBundle); assertEquals(3, searchBundle.getTotal()); assertEquals(4, searchBundle.getEntry().size()); @@ -255,6 +254,6 @@ public void testSearchWithUnsupportedRevIncludeParameter() throws Exception public void testStrictSearchWithUnsupportedRevIncludeParameter() throws Exception { expectBadRequest(() -> getWebserviceClient().searchWithStrictHandling(Organization.class, - Map.of("_revinclude", Collections.singletonList("Endpoint:foo")))); + Map.of("_revinclude", List.of("Endpoint:foo")))); } } diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/ParallelCreateIntegrationTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/ParallelCreateIntegrationTest.java index 0574bfedb..fa59828d1 100644 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/ParallelCreateIntegrationTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/ParallelCreateIntegrationTest.java @@ -311,17 +311,33 @@ public void testCreateDuplicateStructureDefinitionsViaBatchBundle() throws Excep } @Test - public void testCreateDuplicateSubscriptionsViaTransactionBundle() throws Exception + public void testCreateDuplicateSubscriptionsWithPayloadViaTransactionBundle() throws Exception { - Bundle bundle = createBundle(BundleType.TRANSACTION, createSubscription(), null, 2); + Bundle bundle = createBundle(BundleType.TRANSACTION, createSubscription(true), null, 2); expectForbidden(() -> getWebserviceClient().postBundle(bundle)); } @Test - public void testCreateDuplicateSubscriptionsViaBatchBundle() throws Exception + public void testCreateDuplicateSubscriptionsWithPayloadViaBatchBundle() throws Exception { - Bundle bundle = createBundle(BundleType.BATCH, createSubscription(), null, 2); + Bundle bundle = createBundle(BundleType.BATCH, createSubscription(true), null, 2); + + checkReturnBatchBundle(getWebserviceClient().postBundle(bundle)); + } + + @Test + public void testCreateDuplicateSubscriptionsWithoutPayloadViaTransactionBundle() throws Exception + { + Bundle bundle = createBundle(BundleType.TRANSACTION, createSubscription(false), null, 2); + + expectForbidden(() -> getWebserviceClient().postBundle(bundle)); + } + + @Test + public void testCreateDuplicateSubscriptionsWithoutPayloadViaBatchBundle() throws Exception + { + Bundle bundle = createBundle(BundleType.BATCH, createSubscription(false), null, 2); checkReturnBatchBundle(getWebserviceClient().postBundle(bundle)); } @@ -585,9 +601,9 @@ public void testCreateDuplicateStructureDefinitionsViaBatchBundleWithIfNoneExist } @Test - public void testCreateDuplicateSubscriptionsViaTransactionBundleWithIfNoneExists() throws Exception + public void testCreateDuplicateSubscriptionsWithPayloadViaTransactionBundleWithIfNoneExists() throws Exception { - Bundle bundle = createBundle(BundleType.TRANSACTION, createSubscription(), + Bundle bundle = createBundle(BundleType.TRANSACTION, createSubscription(true), (s, r) -> r .setIfNoneExist("criteria=" + s.getCriteria() + "&type=" + s.getChannel().getType().toCode()), 2); @@ -596,9 +612,31 @@ public void testCreateDuplicateSubscriptionsViaTransactionBundleWithIfNoneExists } @Test - public void testCreateDuplicateSubscriptionsViaBatchBundleWithIfNoneExists() throws Exception + public void testCreateDuplicateSubscriptionsWithPayloadViaBatchBundleWithIfNoneExists() throws Exception { - Bundle bundle = createBundle(BundleType.BATCH, createSubscription(), + Bundle bundle = createBundle(BundleType.BATCH, createSubscription(true), + (s, r) -> r + .setIfNoneExist("criteria=" + s.getCriteria() + "&type=" + s.getChannel().getType().toCode()), + 2); + + testCreateDuplicatesViaBundleWithIfNoneExists(bundle, BundleType.BATCHRESPONSE); + } + + @Test + public void testCreateDuplicateSubscriptionsWithoutPayloadViaTransactionBundleWithIfNoneExists() throws Exception + { + Bundle bundle = createBundle(BundleType.TRANSACTION, createSubscription(false), + (s, r) -> r + .setIfNoneExist("criteria=" + s.getCriteria() + "&type=" + s.getChannel().getType().toCode()), + 2); + + testCreateDuplicatesViaBundleWithIfNoneExists(bundle, BundleType.TRANSACTIONRESPONSE); + } + + @Test + public void testCreateDuplicateSubscriptionsWithoutPayloadViaBatchBundleWithIfNoneExists() throws Exception + { + Bundle bundle = createBundle(BundleType.BATCH, createSubscription(false), (s, r) -> r .setIfNoneExist("criteria=" + s.getCriteria() + "&type=" + s.getChannel().getType().toCode()), 2); @@ -825,11 +863,11 @@ public void testCreateDuplicateStructureDefinitionsParallelDirect() throws Excep } @Test - public void testCreateDuplicateSubscriptionsParallelDirect() throws Exception + public void testCreateDuplicateSubscriptionsWithPayloadParallelDirect() throws Exception { testCreateDuplicatesParallel(() -> { - Subscription returnS = getWebserviceClient().create(createSubscription()); + Subscription returnS = getWebserviceClient().create(createSubscription(true)); assertNotNull(returnS); }, SubscriptionDao.class, s -> SUBSCRIPTION_CRITERIA.equals(s.getCriteria()) @@ -837,6 +875,17 @@ public void testCreateDuplicateSubscriptionsParallelDirect() throws Exception && SUBSCRIPTION_CHANNEL_PAYLOAD.equals(s.getChannel().getPayload())); } + @Test + public void testCreateDuplicateSubscriptionsWithoutPayloadParallelDirect() throws Exception + { + testCreateDuplicatesParallel(() -> + { + Subscription returnS = getWebserviceClient().create(createSubscription(false)); + assertNotNull(returnS); + }, SubscriptionDao.class, s -> SUBSCRIPTION_CRITERIA.equals(s.getCriteria()) + && SUBSCRIPTION_CHANNEL_TYPE.equals(s.getChannel().getType()) && s.getChannel().getPayload() == null); + } + @Test public void testCreateDuplicateTasksParallelDirect() throws Exception { @@ -1235,12 +1284,12 @@ public void testCreateDuplicateStructureDefinitionsParallelBatchBundle() throws } @Test - public void testCreateDuplicateSubscriptionsParallelTransactionBundle() throws Exception + public void testCreateDuplicateSubscriptionsWithPayloadParallelTransactionBundle() throws Exception { testCreateDuplicatesParallel(() -> { Bundle returnBundle = getWebserviceClient() - .postBundle(createBundle(BundleType.TRANSACTION, createSubscription(), null, 1)); + .postBundle(createBundle(BundleType.TRANSACTION, createSubscription(true), null, 1)); assertNotNull(returnBundle); }, SubscriptionDao.class, s -> SUBSCRIPTION_CRITERIA.equals(s.getCriteria()) @@ -1249,12 +1298,12 @@ public void testCreateDuplicateSubscriptionsParallelTransactionBundle() throws E } @Test - public void testCreateDuplicateSubscriptionsParallelBatchBundle() throws Exception + public void testCreateDuplicateSubscriptionsWithPayloadParallelBatchBundle() throws Exception { testCreateDuplicatesParallel(() -> { Bundle returnBundle = getWebserviceClient() - .postBundle(createBundle(BundleType.BATCH, createSubscription(), null, 1)); + .postBundle(createBundle(BundleType.BATCH, createSubscription(true), null, 1)); assertNotNull(returnBundle); assertNotNull(returnBundle.getEntry()); @@ -1270,6 +1319,38 @@ public void testCreateDuplicateSubscriptionsParallelBatchBundle() throws Excepti && SUBSCRIPTION_CHANNEL_PAYLOAD.equals(s.getChannel().getPayload())); } + @Test + public void testCreateDuplicateSubscriptionsWithoutPayloadParallelTransactionBundle() throws Exception + { + testCreateDuplicatesParallel(() -> + { + Bundle returnBundle = getWebserviceClient() + .postBundle(createBundle(BundleType.TRANSACTION, createSubscription(false), null, 1)); + assertNotNull(returnBundle); + }, SubscriptionDao.class, s -> SUBSCRIPTION_CRITERIA.equals(s.getCriteria()) + && SUBSCRIPTION_CHANNEL_TYPE.equals(s.getChannel().getType()) && s.getChannel().getPayload() == null); + } + + @Test + public void testCreateDuplicateSubscriptionsWithoutPayloadParallelBatchBundle() throws Exception + { + testCreateDuplicatesParallel(() -> + { + Bundle returnBundle = getWebserviceClient() + .postBundle(createBundle(BundleType.BATCH, createSubscription(false), null, 1)); + assertNotNull(returnBundle); + + assertNotNull(returnBundle.getEntry()); + assertEquals(1, returnBundle.getEntry().size()); + assertNotNull(returnBundle.getEntry().get(0).getResponse()); + assertNotNull(returnBundle.getEntry().get(0).getResponse().getStatus()); + + if ("403 Forbidden".equals(returnBundle.getEntry().get(0).getResponse().getStatus())) + throw new WebApplicationException(403); + }, SubscriptionDao.class, s -> SUBSCRIPTION_CRITERIA.equals(s.getCriteria()) + && SUBSCRIPTION_CHANNEL_TYPE.equals(s.getChannel().getType()) && s.getChannel().getPayload() == null); + } + @Test public void testCreateDuplicateTasksParallelTransactionBundle() throws Exception { @@ -1574,11 +1655,14 @@ private StructureDefinition createStructureDefinition() return sD; } - private Subscription createSubscription() + private Subscription createSubscription(boolean withPayload) { Subscription s = new Subscription().setStatus(SubscriptionStatus.ACTIVE).setReason("some reason") - .setCriteria(SUBSCRIPTION_CRITERIA).setChannel(new SubscriptionChannelComponent() - .setType(SUBSCRIPTION_CHANNEL_TYPE).setPayload(SUBSCRIPTION_CHANNEL_PAYLOAD)); + .setCriteria(SUBSCRIPTION_CRITERIA) + .setChannel(new SubscriptionChannelComponent().setType(SUBSCRIPTION_CHANNEL_TYPE)); + + if (withPayload) + s.getChannel().setPayload(SUBSCRIPTION_CHANNEL_PAYLOAD); getReadAccessHelper().addAll(s); diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/QuestionnaireIntegrationTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/QuestionnaireIntegrationTest.java index ede768b4f..e30528ca2 100644 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/QuestionnaireIntegrationTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/QuestionnaireIntegrationTest.java @@ -4,7 +4,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import java.util.Collections; +import java.util.List; import java.util.Map; import org.hl7.fhir.r4.model.Bundle; @@ -34,7 +34,7 @@ public void testSearchByDate() throws Exception questionnaireDao.create(questionnaire); Bundle searchBundle = getWebserviceClient().search(Questionnaire.class, - Map.of("date", Collections.singletonList("le2022-02-01"))); + Map.of("date", List.of("le2022-02-01"))); assertNotNull(searchBundle.getEntry()); assertEquals(1, searchBundle.getEntry().size()); @@ -55,7 +55,7 @@ public void testSearchByIdentifier() throws Exception questionnaireDao.create(questionnaire); Bundle searchBundle = getWebserviceClient().search(Questionnaire.class, - Map.of("identifier", Collections.singletonList(TEST_IDENTIFIER_SYSTEM + "|" + TEST_IDENTIFIER_VALUE))); + Map.of("identifier", List.of(TEST_IDENTIFIER_SYSTEM + "|" + TEST_IDENTIFIER_VALUE))); assertNotNull(searchBundle.getEntry()); assertEquals(1, searchBundle.getEntry().size()); @@ -77,7 +77,7 @@ public void testSearchByStatus() throws Exception questionnaireDao.create(questionnaire); Bundle searchBundle = getWebserviceClient().search(Questionnaire.class, - Map.of("status", Collections.singletonList(QUESTIONNAIRE_STATUS.toCode()))); + Map.of("status", List.of(QUESTIONNAIRE_STATUS.toCode()))); assertNotNull(searchBundle.getEntry()); assertEquals(1, searchBundle.getEntry().size()); @@ -98,8 +98,7 @@ public void testSearchByUrlAndVersion() throws Exception questionnaireDao.create(questionnaire); Bundle searchBundle = getWebserviceClient().search(Questionnaire.class, - Map.of("url", Collections.singletonList(QUESTIONNAIRE_URL), "version", - Collections.singletonList(QUESTIONNAIRE_VERSION))); + Map.of("url", List.of(QUESTIONNAIRE_URL), "version", List.of(QUESTIONNAIRE_VERSION))); assertNotNull(searchBundle.getEntry()); assertEquals(1, searchBundle.getEntry().size()); diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/QuestionnaireResponseIntegrationTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/QuestionnaireResponseIntegrationTest.java index d93a490ed..dec034664 100644 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/QuestionnaireResponseIntegrationTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/QuestionnaireResponseIntegrationTest.java @@ -6,7 +6,6 @@ import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.UUID; @@ -164,7 +163,7 @@ public void testSearchByDate() throws Exception questionnaireResponseDao.create(questionnaireResponse); Bundle searchBundle = getWebserviceClient().search(QuestionnaireResponse.class, - Map.of("authored", Collections.singletonList("le2022-02-01"))); + Map.of("authored", List.of("le2022-02-01"))); assertNotNull(searchBundle.getEntry()); assertEquals(1, searchBundle.getEntry().size()); @@ -187,7 +186,7 @@ public void testSearchByIdentifier() throws Exception questionnaireResponseDao.create(questionnaireResponse); Bundle searchBundle = getWebserviceClient().search(QuestionnaireResponse.class, - Map.of("identifier", Collections.singletonList(TEST_IDENTIFIER_SYSTEM + "|" + TEST_IDENTIFIER_VALUE))); + Map.of("identifier", List.of(TEST_IDENTIFIER_SYSTEM + "|" + TEST_IDENTIFIER_VALUE))); assertNotNull(searchBundle.getEntry()); assertEquals(1, searchBundle.getEntry().size()); @@ -211,7 +210,7 @@ public void testSearchByIdentifierRemoteUser() throws Exception questionnaireResponseDao.create(questionnaireResponse); Bundle searchBundle = getExternalWebserviceClient().search(QuestionnaireResponse.class, - Map.of("identifier", Collections.singletonList(TEST_IDENTIFIER_SYSTEM + "|" + TEST_IDENTIFIER_VALUE))); + Map.of("identifier", List.of(TEST_IDENTIFIER_SYSTEM + "|" + TEST_IDENTIFIER_VALUE))); assertNotNull(searchBundle.getEntry()); assertEquals(0, searchBundle.getEntry().size()); @@ -240,9 +239,8 @@ private void testSearchByQuestionnaire(String questionnaireUrl) throws Exception .getBean(QuestionnaireResponseDao.class); questionnaireResponseDao.create(questionnaireResponse); - Bundle searchBundle = getWebserviceClient().search(QuestionnaireResponse.class, - Map.of("questionnaire", Collections.singletonList(questionnaireUrl), "_include", - Collections.singletonList("QuestionnaireResponse:questionnaire"))); + Bundle searchBundle = getWebserviceClient().search(QuestionnaireResponse.class, Map.of("questionnaire", + List.of(questionnaireUrl), "_include", List.of("QuestionnaireResponse:questionnaire"))); assertNotNull(searchBundle.getEntry()); assertEquals(2, searchBundle.getEntry().size()); @@ -278,9 +276,8 @@ public void testSearchByQuestionnaireNoVersion() throws Exception .getBean(QuestionnaireResponseDao.class); questionnaireResponseDao.create(questionnaireResponse); - Bundle searchBundle = getWebserviceClient().search(QuestionnaireResponse.class, - Map.of("questionnaire", Collections.singletonList(QUESTIONNAIRE_URL), "_include", - Collections.singletonList("QuestionnaireResponse:questionnaire"))); + Bundle searchBundle = getWebserviceClient().search(QuestionnaireResponse.class, Map.of("questionnaire", + List.of(QUESTIONNAIRE_URL), "_include", List.of("QuestionnaireResponse:questionnaire"))); assertNotNull(searchBundle.getEntry()); assertEquals(2, searchBundle.getEntry().size()); @@ -325,9 +322,8 @@ public void testSearchByQuestionnaireWithoutVersionButMultipleVersionExist() thr .getBean(QuestionnaireResponseDao.class); questionnaireResponseDao.create(questionnaireResponse); - Bundle searchBundle = getWebserviceClient().search(QuestionnaireResponse.class, - Map.of("questionnaire", Collections.singletonList(QUESTIONNAIRE_URL), "_include", - Collections.singletonList("QuestionnaireResponse:questionnaire"))); + Bundle searchBundle = getWebserviceClient().search(QuestionnaireResponse.class, Map.of("questionnaire", + List.of(QUESTIONNAIRE_URL), "_include", List.of("QuestionnaireResponse:questionnaire"))); assertNotNull(searchBundle.getEntry()); assertEquals(2, searchBundle.getEntry().size()); @@ -362,7 +358,7 @@ public void testSearchByStatus() throws Exception questionnaireResponseDao.create(questionnaireResponse); Bundle searchBundle = getWebserviceClient().search(QuestionnaireResponse.class, - Map.of("status", Collections.singletonList(QUESTIONNAIRE_RESPONSE_STATUS.toCode()))); + Map.of("status", List.of(QUESTIONNAIRE_RESPONSE_STATUS.toCode()))); assertNotNull(searchBundle.getEntry()); assertEquals(1, searchBundle.getEntry().size()); @@ -389,9 +385,8 @@ public void testSearchBySubjectReference() throws Exception Organization localOrganization = organizationProvider.getLocalOrganization().get(); String organizationReference = "Organization/" + localOrganization.getIdElement().getIdPart(); - Bundle searchBundle = getWebserviceClient().search(QuestionnaireResponse.class, - Map.of("subject", Collections.singletonList(organizationReference), "_include", - Collections.singletonList("QuestionnaireResponse:subject:Organization"))); + Bundle searchBundle = getWebserviceClient().search(QuestionnaireResponse.class, Map.of("subject", + List.of(organizationReference), "_include", List.of("QuestionnaireResponse:subject:Organization"))); assertNotNull(searchBundle.getEntry()); assertEquals(2, searchBundle.getEntry().size()); diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/ResearchStudyIntegrationTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/ResearchStudyIntegrationTest.java index 3470d6af3..0635e90d2 100644 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/ResearchStudyIntegrationTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/ResearchStudyIntegrationTest.java @@ -4,7 +4,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; @@ -45,7 +44,7 @@ public void testSearchByGroupId() throws Exception String researchStudyId = researchStudyDao.create(rs).getIdElement().getIdPart(); Bundle resultBundle = getWebserviceClient().searchWithStrictHandling(ResearchStudy.class, - Map.of("enrollment", Collections.singletonList(groupId))); + Map.of("enrollment", List.of(groupId))); assertNotNull(resultBundle); assertEquals(1, resultBundle.getTotal()); diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/SubscriptionIntegrationTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/SubscriptionIntegrationTest.java index 0bf6dc68f..85b541217 100644 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/SubscriptionIntegrationTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/SubscriptionIntegrationTest.java @@ -61,6 +61,35 @@ public void testCreateOkNoPayload() throws Exception assertEquals("1", created.getMeta().getVersionId()); } + @Test + public void testCreateOkNoPayloadAllreadyExistsWithPayload() throws Exception + { + Subscription t = newSubscription("Task?status=completed"); + + SubscriptionDao dao = getSpringWebApplicationContext().getBean(SubscriptionDao.class); + dao.create(t); + + t = newSubscription("Task?status=completed"); + t.getChannel().setPayload(null); + + Subscription created = getWebserviceClient().create(t); + assertNotNull(created); + assertTrue(created.getIdElement().hasValue()); + assertEquals("1", created.getMeta().getVersionId()); + } + + @Test + public void testCreateNotOkNoPayloadAllreadyExistsWithoutPayload() throws Exception + { + Subscription t = newSubscription("Task?status=completed"); + t.getChannel().setPayload(null); + + SubscriptionDao dao = getSpringWebApplicationContext().getBean(SubscriptionDao.class); + dao.create(t); + + expectForbidden(() -> getWebserviceClient().create(t)); + } + @Test public void testCreateInvalid() throws Exception { diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/TaskIntegrationTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/TaskIntegrationTest.java index 578f04677..eb94523e6 100755 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/TaskIntegrationTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/TaskIntegrationTest.java @@ -11,10 +11,9 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.sql.Connection; -import java.util.Arrays; -import java.util.Collections; import java.util.Date; import java.util.EnumSet; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; @@ -592,7 +591,7 @@ public void testSearchTaskByRequesterId() throws Exception String taskId = taskDao.create(t).getIdElement().getIdPart(); Bundle resultBundle = getWebserviceClient().searchWithStrictHandling(Task.class, - Map.of("requester", Collections.singletonList(orgId))); + Map.of("requester", List.of(orgId))); assertNotNull(resultBundle); assertEquals(1, resultBundle.getTotal()); @@ -1233,13 +1232,13 @@ public void testHistoryLiteralReferenceClean() throws Exception public void testDateTimeQueryParameter() throws Exception { Bundle r1 = getWebserviceClient().search(Task.class, - Map.of("_lastUpdated", Arrays.asList("gt2021-12-02T10:00:00", "lt2021-12-02T12:00:00"))); + Map.of("_lastUpdated", List.of("gt2021-12-02T10:00:00", "lt2021-12-02T12:00:00"))); assertNotNull(r1); assertEquals(0, r1.getTotal()); assertEquals(0, r1.getEntry().size()); Bundle r2 = getWebserviceClient().search(Task.class, - Map.of("_lastUpdated", Arrays.asList("lt2021-12-02T12:00:00", "gt2021-12-02T10:00:00"))); + Map.of("_lastUpdated", List.of("lt2021-12-02T12:00:00", "gt2021-12-02T10:00:00"))); assertNotNull(r2); assertEquals(0, r2.getTotal()); assertEquals(0, r2.getEntry().size()); @@ -1273,8 +1272,7 @@ public void testSearchByProfile() throws Exception Task createdTask2 = taskDao.create(task2); assertNotNull(createdTask2); - Bundle result1 = getWebserviceClient().search(Task.class, - Map.of("_profile", Collections.singletonList(profile))); + Bundle result1 = getWebserviceClient().search(Task.class, Map.of("_profile", List.of(profile))); assertNotNull(result1); assertEquals(2, result1.getTotal()); assertTrue(result1.hasEntry()); @@ -1282,8 +1280,7 @@ public void testSearchByProfile() throws Exception assertTrue(result1.getEntry().get(0).hasResource()); assertTrue(result1.getEntry().get(0).getResource() instanceof Task); - Bundle result2 = getWebserviceClient().search(Task.class, - Map.of("_profile", Collections.singletonList(profile + "|0.1.0"))); + Bundle result2 = getWebserviceClient().search(Task.class, Map.of("_profile", List.of(profile + "|0.1.0"))); assertNotNull(result2); assertEquals(1, result2.getTotal()); assertTrue(result2.hasEntry()); @@ -1296,17 +1293,16 @@ public void testSearchByProfile() throws Exception result2.getEntry().get(0).getResource().getMeta().getProfile().get(0).getValue()); Bundle result3 = getWebserviceClient().search(Task.class, - Map.of("_profile", Collections.singletonList("http://foo.bar/fhir/StructureDefinition/test"))); + Map.of("_profile", List.of("http://foo.bar/fhir/StructureDefinition/test"))); assertNotNull(result3); assertEquals(0, result3.getTotal()); - Bundle result4 = getWebserviceClient().search(Task.class, - Map.of("_profile", Collections.singletonList(profile + "|0.2.0"))); + Bundle result4 = getWebserviceClient().search(Task.class, Map.of("_profile", List.of(profile + "|0.2.0"))); assertNotNull(result4); assertEquals(0, result4.getTotal()); Bundle result5 = getWebserviceClient().search(Task.class, - Map.of("_profile:below", Collections.singletonList("http://foo.bar/fhir/StructureDefinition"))); + Map.of("_profile:below", List.of("http://foo.bar/fhir/StructureDefinition"))); assertNotNull(result5); assertEquals(2, result5.getTotal()); assertTrue(result5.hasEntry()); @@ -1315,7 +1311,7 @@ public void testSearchByProfile() throws Exception assertTrue(result5.getEntry().get(0).getResource() instanceof Task); Bundle result6 = getWebserviceClient().search(Task.class, - Map.of("_profile:below", Collections.singletonList("http://foo.bar/fhir/StructureDefinition|0.1.0"))); + Map.of("_profile:below", List.of("http://foo.bar/fhir/StructureDefinition|0.1.0"))); assertNotNull(result6); assertEquals(1, result6.getTotal()); assertTrue(result6.hasEntry()); diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/X509Certificates.java b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/X509Certificates.java index 1a2577c30..181e22996 100755 --- a/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/X509Certificates.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/dev/dsf/fhir/integration/X509Certificates.java @@ -1,5 +1,7 @@ package dev.dsf.fhir.integration; +import static de.rwh.utils.crypto.CertificateHelper.DEFAULT_SIGNATURE_ALGORITHM; + import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -15,7 +17,8 @@ import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; -import java.util.Arrays; +import java.time.LocalDateTime; +import java.time.Period; import java.util.List; import java.util.UUID; @@ -87,12 +90,9 @@ public String getCertificateSha512ThumbprintHex() private static final Logger logger = LoggerFactory.getLogger(X509Certificates.class); private static final BouncyCastleProvider provider = new BouncyCastleProvider(); + private static final int KEY_SIZE = 2048; public static final char[] PASSWORD = "password".toCharArray(); - private boolean beforeRun; - - private final X509Certificates parent; - private ClientCertificate clientCertificate; private ClientCertificate practitionerClientCertificate; private ClientCertificate externalClientCertificate; @@ -109,134 +109,75 @@ public String getCertificateSha512ThumbprintHex() private List<Path> filesToDelete; - public X509Certificates() - { - this(null); - } - - public X509Certificates(X509Certificates parent) - { - this.parent = parent; - } - - private boolean parentBeforeRan() - { - return parent != null && parent.beforeRun; - } - @Override protected void before() throws Throwable { - if (parentBeforeRan()) - logger.debug("X509Certificates created by parent"); - else - createX509Certificates(); - - beforeRun = true; + createX509Certificates(); } @Override protected void after() { - if (parentBeforeRan()) - logger.debug("X509Certificates will be deleted by parent"); - else - deleteX509Certificates(); + deleteX509Certificates(); } public ClientCertificate getClientCertificate() { - if (parentBeforeRan()) - return parent.getClientCertificate(); - else - return clientCertificate; + return clientCertificate; } public ClientCertificate getExternalClientCertificate() { - if (parentBeforeRan()) - return parent.getExternalClientCertificate(); - else - return externalClientCertificate; + return externalClientCertificate; } public ClientCertificate getPractitionerClientCertificate() { - if (parentBeforeRan()) - return parent.getPractitionerClientCertificate(); - else - return practitionerClientCertificate; + return practitionerClientCertificate; } public Path getCaCertificateFile() { - if (parentBeforeRan()) - return parent.getCaCertificateFile(); - return caCertificateFile; } public Path getServerCertificateFile() { - if (parentBeforeRan()) - return parent.getServerCertificateFile(); - return serverCertificateFile; } public Path getServerCertificatePrivateKeyFile() { - if (parentBeforeRan()) - return parent.getServerCertificatePrivateKeyFile(); - return serverCertificatePrivateKeyFile; } public Path getClientCertificateFile() { - if (parentBeforeRan()) - return parent.getClientCertificateFile(); - return clientCertificateFile; } public Path getClientCertificatePrivateKeyFile() { - if (parentBeforeRan()) - return parent.getClientCertificatePrivateKeyFile(); - return clientCertificatePrivateKeyFile; } public Path getExternalClientCertificateFile() { - if (parentBeforeRan()) - return parent.getExternalClientCertificateFile(); - return externalClientCertificateFile; } public Path getExternalClientCertificatePrivateKeyFile() { - if (parentBeforeRan()) - return parent.getExternalClientCertificatePrivateKeyFile(); - return externalClientCertificatePrivateKeyFile; } public Path getPractitionerClientCertificateFile() { - if (parentBeforeRan()) - return parent.getPractitionerClientCertificateFile(); - return practitionerClientCertificateFile; } public Path getPractitionerClientCertificatePrivateKeyFile() { - if (parentBeforeRan()) - return parent.getPractitionerClientCertificatePrivateKeyFile(); - return practitionerClientCertificatePrivateKeyFile; } @@ -258,18 +199,21 @@ private void createX509Certificates() throws InvalidKeyException, NoSuchAlgorith CertificateAuthority.registerBouncyCastleProvider(); CertificateAuthority ca = new CertificateAuthority("DE", null, null, null, null, "test-ca"); - ca.initialize(); + LocalDateTime notBefore = LocalDateTime.now(); + LocalDateTime notAfter = notBefore.plusDays(1); + ca.initialize(notBefore, notAfter, KEY_SIZE, DEFAULT_SIGNATURE_ALGORITHM); + X509Certificate caCertificate = ca.getCertificate(); PemIo.writeX509CertificateToPem(caCertificate, caCertificateFile); // -- server X500Name serverSubject = CertificationRequestBuilder.createSubject("DE", null, null, null, null, "test-server"); - KeyPair serverRsaKeyPair = CertificationRequestBuilder.createRsaKeyPair4096Bit(); + KeyPair serverRsaKeyPair = CertificateHelper.createKeyPair(CertificateHelper.DEFAULT_KEY_ALGORITHM, KEY_SIZE); JcaPKCS10CertificationRequest serverRequest = CertificationRequestBuilder .createServerCertificationRequest(serverSubject, serverRsaKeyPair, null, "localhost"); - X509Certificate serverCertificate = ca.signWebServerCertificate(serverRequest); + X509Certificate serverCertificate = ca.signWebServerCertificate(serverRequest, Period.ofDays(1)); CertificateWriter.toPkcs12(serverCertificateFile, serverRsaKeyPair.getPrivate(), PASSWORD, serverCertificate, caCertificate, "test-server"); @@ -277,16 +221,15 @@ private void createX509Certificates() throws InvalidKeyException, NoSuchAlgorith PemIo.writeX509CertificateToPem(serverCertificate, serverCertificateFile); PemIo.writeAes128EncryptedPrivateKeyToPkcs8(provider, serverCertificatePrivateKeyFile, serverRsaKeyPair.getPrivate(), PASSWORD); - // server -- // -- client X500Name clientSubject = CertificationRequestBuilder.createSubject("DE", null, null, null, null, "test-client"); - KeyPair clientRsaKeyPair = CertificationRequestBuilder.createRsaKeyPair4096Bit(); + KeyPair clientRsaKeyPair = CertificateHelper.createKeyPair(CertificateHelper.DEFAULT_KEY_ALGORITHM, KEY_SIZE); JcaPKCS10CertificationRequest clientRequest = CertificationRequestBuilder .createClientCertificationRequest(clientSubject, clientRsaKeyPair); - X509Certificate clientCertificate = ca.signWebClientCertificate(clientRequest); + X509Certificate clientCertificate = ca.signWebClientCertificate(clientRequest, Period.ofDays(1)); KeyStore clientKeyStore = CertificateHelper.toPkcs12KeyStore(clientRsaKeyPair.getPrivate(), new Certificate[] { clientCertificate, caCertificate }, "test-client", PASSWORD); @@ -299,11 +242,13 @@ private void createX509Certificates() throws InvalidKeyException, NoSuchAlgorith // -- external client X500Name externalClientSubject = CertificationRequestBuilder.createSubject("DE", null, null, null, null, "external-client"); - KeyPair externalClientRsaKeyPair = CertificationRequestBuilder.createRsaKeyPair4096Bit(); + KeyPair externalClientRsaKeyPair = CertificateHelper.createKeyPair(CertificateHelper.DEFAULT_KEY_ALGORITHM, + KEY_SIZE); JcaPKCS10CertificationRequest externalClientRequest = CertificationRequestBuilder .createClientCertificationRequest(externalClientSubject, externalClientRsaKeyPair); - X509Certificate externalClientCertificate = ca.signWebClientCertificate(externalClientRequest); + X509Certificate externalClientCertificate = ca.signWebClientCertificate(externalClientRequest, + Period.ofDays(1)); KeyStore externalClientKeyStore = CertificateHelper.toPkcs12KeyStore(externalClientRsaKeyPair.getPrivate(), new Certificate[] { externalClientCertificate, caCertificate }, "external-client", PASSWORD); @@ -319,7 +264,8 @@ private void createX509Certificates() throws InvalidKeyException, NoSuchAlgorith // -- practitioner client X500Name practitionerClientSubject = CertificationRequestBuilder.createSubject("DE", null, null, null, null, "practitioner-client"); - KeyPair practitionerClientRsaKeyPair = CertificationRequestBuilder.createRsaKeyPair4096Bit(); + KeyPair practitionerClientRsaKeyPair = CertificateHelper.createKeyPair(CertificateHelper.DEFAULT_KEY_ALGORITHM, + KEY_SIZE); JcaPKCS10CertificationRequest practitionerClientRequest = CertificationRequestBuilder .createClientCertificationRequest(practitionerClientSubject, practitionerClientRsaKeyPair, "practitioner@test.org"); @@ -355,7 +301,7 @@ private void createX509Certificates() throws InvalidKeyException, NoSuchAlgorith this.practitionerClientCertificateFile = practitionerClientCertificateFile; this.practitionerClientCertificatePrivateKeyFile = practitionerClientCertificatePrivateKeyFile; - this.filesToDelete = Arrays.asList(caCertificateFile, serverCertificateFile, serverCertificatePrivateKeyFile, + filesToDelete = List.of(caCertificateFile, serverCertificateFile, serverCertificatePrivateKeyFile, clientCertificateFile, clientCertificatePrivateKeyFile, externalClientCertificateFile, externalClientCertificatePrivateKeyFile, practitionerClientCertificateFile, practitionerClientCertificatePrivateKeyFile); diff --git a/dsf-fhir/dsf-fhir-validation/pom.xml b/dsf-fhir/dsf-fhir-validation/pom.xml index 2e604b6e0..0e268a8de 100644 --- a/dsf-fhir/dsf-fhir-validation/pom.xml +++ b/dsf-fhir/dsf-fhir-validation/pom.xml @@ -20,32 +20,22 @@ <artifactId>hapi-fhir-structures-r4</artifactId> <version>${hapi.fhir.version}</version> </dependency> - <dependency> - <groupId>ca.uhn.hapi.fhir</groupId> - <artifactId>hapi-fhir-structures-r5</artifactId> - <version>${hapi.fhir.version}</version> - </dependency> <dependency> <groupId>ca.uhn.hapi.fhir</groupId> <artifactId>hapi-fhir-validation</artifactId> + <version>${hapi.fhir.version}</version> <exclusions> <exclusion> <artifactId>commons-logging</artifactId> <groupId>commons-logging</groupId> </exclusion> </exclusions> - <version>${hapi.fhir.version}</version> </dependency> <dependency> <groupId>ca.uhn.hapi.fhir</groupId> <artifactId>hapi-fhir-validation-resources-r4</artifactId> <version>${hapi.fhir.version}</version> </dependency> - <dependency> - <groupId>ca.uhn.hapi.fhir</groupId> - <artifactId>hapi-fhir-validation-resources-r5</artifactId> - <version>${hapi.fhir.version}</version> - </dependency> <dependency> <groupId>commons-io</groupId> diff --git a/dsf-fhir/dsf-fhir-validation/src/main/java/dev/dsf/fhir/validation/ResourceValidatorImpl.java b/dsf-fhir/dsf-fhir-validation/src/main/java/dev/dsf/fhir/validation/ResourceValidatorImpl.java index 7a9c68b36..9c5cca35b 100755 --- a/dsf-fhir/dsf-fhir-validation/src/main/java/dev/dsf/fhir/validation/ResourceValidatorImpl.java +++ b/dsf-fhir/dsf-fhir-validation/src/main/java/dev/dsf/fhir/validation/ResourceValidatorImpl.java @@ -15,6 +15,8 @@ import org.hl7.fhir.r5.model.CanonicalResource; import org.hl7.fhir.r5.utils.validation.IResourceValidator; import org.hl7.fhir.r5.utils.validation.IValidatorResourceFetcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.support.IValidationSupport; @@ -24,13 +26,85 @@ public class ResourceValidatorImpl implements ResourceValidator { + private static final Logger logger = LoggerFactory.getLogger(ResourceValidatorImpl.class); + private static final Pattern AT_DEFAULT_SLICE_PATTERN = Pattern .compile(".*(Questionnaire|QuestionnaireResponse).item:@default.*"); + private static final String MISSING_NARRATIVE_MESSAGE_START = "Constraint failed: dom-6: 'A resource should have narrative for robust management'"; + + private static final class ValidatorResourceFetcher implements IValidatorResourceFetcher + { + @Override + public IValidatorResourceFetcher setLocale(Locale locale) + { + return this; + } + + @Override + public boolean resolveURL(IResourceValidator validator, Object appContext, String path, String url, String type, + boolean canonical) throws IOException, FHIRException + { + if (("urn:ietf:bcp:13".equals(url) || "urn:ietf:bcp:13|4.0.1".equals(url) + || "urn:ietf:rfc:3986".equals(url)) && "uri".equals(type) && !canonical) + return true; + else if (url != null && url.startsWith("urn:uuid:") && url.length() == 45 + && ("uri".equals(type) || "url".equals(type)) && !canonical) + return true; + else if (url != null && (url.startsWith("http://") || url.startsWith("https://")) + && ("uri".equals(type) || "canonical".equals(type))) + return true; + else if (path != null && (path.startsWith("ActivityDefinition") || path.startsWith("Binary") + || path.startsWith("Bundle") || path.startsWith("CodeSystem") + || path.startsWith("DocumentReference") || path.startsWith("Endpoint") || path.startsWith("Library") + || path.startsWith("Organization") || path.startsWith("QuestionnaireResponse") + || path.startsWith("ResearchStudy") || path.startsWith("StructureDefinition") + || path.startsWith("Task"))) + return true; + + logger.debug("Not resolving [path: {}, url: {}, type: {}, canonical: {}]", path, url, type, canonical); + return false; + } + + @Override + public boolean fetchesCanonicalResource(IResourceValidator validator, String url) + { + return false; + } + + @Override + public byte[] fetchRaw(IResourceValidator validator, String url) throws IOException + { + return null; + } + + @Override + public Set<String> fetchCanonicalResourceVersions(IResourceValidator validator, Object appContext, String url) + { + return Set.of(); + } + + @Override + public CanonicalResource fetchCanonicalResource(IResourceValidator validator, Object appContext, String url) + throws URISyntaxException + { + return null; + } + + @Override + public org.hl7.fhir.r5.elementmodel.Element fetch(IResourceValidator validator, Object appContext, String url) + throws FHIRException, IOException + { + return null; + } + } + + private final FhirContext context; private final FhirValidator validator; public ResourceValidatorImpl(FhirContext context, IValidationSupport validationSupport) { + this.context = context; this.validator = configureValidator(context, validationSupport); } @@ -41,75 +115,8 @@ protected FhirValidator configureValidator(FhirContext fhirContext, IValidationS IWorkerContext workerContext = FixedVersionSpecificWorkerContextWrapper .newVersionSpecificWorkerContextWrapper(validationSupport); - IValidatorResourceFetcher resourceFetcher = new IValidatorResourceFetcher() - { - @Override - public IValidatorResourceFetcher setLocale(Locale locale) - { - return this; - } - - @Override - public boolean resolveURL(IResourceValidator validator, Object appContext, String path, String url, - String type, boolean canonical) throws IOException, FHIRException - { - if (("urn:ietf:bcp:13".equals(url) || "urn:ietf:bcp:13|4.0.1".equals(url) - || "urn:ietf:rfc:3986".equals(url)) && "uri".equals(type) && !canonical) - return true; - else if (url != null && url.startsWith("urn:uuid:") && url.length() == 45 - && ("uri".equals(type) || "url".equals(type)) && !canonical) - return true; - else if (url != null && (url.startsWith("http://") || url.startsWith("https://")) - && ("uri".equals(type) || "canonical".equals(type))) - return true; - else if (path != null && (path.startsWith("ActivityDefinition") || path.startsWith("Binary") - || path.startsWith("Bundle") || path.startsWith("CodeSystem") - || path.startsWith("DocumentReference") || path.startsWith("Endpoint") - || path.startsWith("Library") || path.startsWith("Organization") - || path.startsWith("QuestionnaireResponse") || path.startsWith("ResearchStudy") - || path.startsWith("StructureDefinition") || path.startsWith("Task"))) - return true; - - System.err.println("!!!!!!! " + path + ", " + url + ", " + type + ", " + canonical); - return false; - } - - @Override - public boolean fetchesCanonicalResource(IResourceValidator validator, String url) - { - return false; - } - - @Override - public byte[] fetchRaw(IResourceValidator validator, String url) throws IOException - { - return null; - } - - @Override - public Set<String> fetchCanonicalResourceVersions(IResourceValidator validator, Object appContext, - String url) - { - return Set.of(); - } - - @Override - public CanonicalResource fetchCanonicalResource(IResourceValidator validator, Object appContext, String url) - throws URISyntaxException - { - return null; - } - - @Override - public org.hl7.fhir.r5.elementmodel.Element fetch(IResourceValidator validator, Object appContext, - String url) throws FHIRException, IOException - { - return null; - } - }; - - FhirInstanceValidator instanceValidator = new FhirInstanceValidatorExtension(validationSupport, resourceFetcher, - workerContext); + FhirInstanceValidator instanceValidator = new FhirInstanceValidatorExtension(validationSupport, + new ValidatorResourceFetcher(), workerContext); validator.registerValidatorModule(instanceValidator); return validator; @@ -123,12 +130,16 @@ public ValidationResult validate(Resource resource) // TODO: remove after HAPI validator is fixed: https://github.com/hapifhir/org.hl7.fhir.core/issues/193 adaptDefaultSliceValidationErrorToWarning(result); - return result; + return new ValidationResult(context, + result.getMessages().stream().filter(m -> !(ResultSeverityEnum.WARNING.equals(m.getSeverity()) + && m.getMessage().startsWith(MISSING_NARRATIVE_MESSAGE_START))).toList()); } private void adaptDefaultSliceValidationErrorToWarning(ValidationResult result) { - result.getMessages().stream().filter(m -> AT_DEFAULT_SLICE_PATTERN.matcher(m.getMessage()).matches()) + result.getMessages().stream() + .filter(m -> ResultSeverityEnum.ERROR.equals(m.getSeverity()) + && AT_DEFAULT_SLICE_PATTERN.matcher(m.getMessage()).matches()) .forEach(m -> m.setSeverity(ResultSeverityEnum.WARNING)); } } diff --git a/dsf-fhir/dsf-fhir-validation/src/main/java/dev/dsf/fhir/validation/StructureDefinitionReader.java b/dsf-fhir/dsf-fhir-validation/src/main/java/dev/dsf/fhir/validation/StructureDefinitionReader.java index ea85c3c15..c30af7a9f 100755 --- a/dsf-fhir/dsf-fhir-validation/src/main/java/dev/dsf/fhir/validation/StructureDefinitionReader.java +++ b/dsf-fhir/dsf-fhir-validation/src/main/java/dev/dsf/fhir/validation/StructureDefinitionReader.java @@ -7,7 +7,6 @@ import java.nio.file.Path; import java.time.LocalDate; import java.time.format.DateTimeFormatter; -import java.util.Arrays; import java.util.List; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -57,12 +56,12 @@ public StructureDefinitionReader(FhirContext context, String version, LocalDate public List<StructureDefinition> readXml(Path... xmlPaths) { - return readXml(Arrays.asList(xmlPaths)); + return readXml(List.of(xmlPaths)); } public List<StructureDefinition> readXml(String... xmlOnClassPaths) { - return readXmlFromClassPath(Arrays.asList(xmlOnClassPaths)); + return readXmlFromClassPath(List.of(xmlOnClassPaths)); } public List<StructureDefinition> readXml(List<Path> xmlPaths) diff --git a/dsf-fhir/dsf-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/FixedVersionSpecificWorkerContextWrapper.java b/dsf-fhir/dsf-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/FixedVersionSpecificWorkerContextWrapper.java index d13f8848b..60918dbd2 100644 --- a/dsf-fhir/dsf-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/FixedVersionSpecificWorkerContextWrapper.java +++ b/dsf-fhir/dsf-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/FixedVersionSpecificWorkerContextWrapper.java @@ -1,15 +1,22 @@ package org.hl7.fhir.common.hapi.validation.validator; +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.toSet; + +import static ca.uhn.fhir.context.support.IValidationSupport.CodeValidationIssueCoding.INVALID_DISPLAY; import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.EqualsBuilder; @@ -64,14 +71,16 @@ import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; -//copied and modified from hapi-fhir-validation version 7.4.0 +//copied and modified from https://github.com/hapifhir/hapi-fhir/blob/v7.6.1/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/VersionSpecificWorkerContextWrapper.java public class FixedVersionSpecificWorkerContextWrapper extends I18nBase implements IWorkerContext { private static final Logger ourLog = LoggerFactory.getLogger(FixedVersionSpecificWorkerContextWrapper.class); private final ValidationSupportContext myValidationSupportContext; private final VersionCanonicalizer myVersionCanonicalizer; private final LoadingCache<ResourceKey, IBaseResource> myFetchResourceCache; + private final Map<String, StructureDefinition> myStructureDefinitionNonExpiringCache; private volatile List<StructureDefinition> myAllStructures; + private volatile Set<String> myAllPrimitiveTypes; private Parameters myExpansionProfile; public FixedVersionSpecificWorkerContextWrapper(ValidationSupportContext theValidationSupportContext, @@ -79,6 +88,7 @@ public FixedVersionSpecificWorkerContextWrapper(ValidationSupportContext theVali { myValidationSupportContext = theValidationSupportContext; myVersionCanonicalizer = theVersionCanonicalizer; + myStructureDefinitionNonExpiringCache = new ConcurrentHashMap<>(); long timeoutMillis = HapiSystemProperties.getTestValidationResourceCachesMs(); @@ -108,24 +118,7 @@ public FixedVersionSpecificWorkerContextWrapper(ValidationSupportContext theVali IBaseResource fetched = myValidationSupportContext.getRootValidationSupport() .fetchResource(fetchResourceType, key.getUri()); - Resource canonical = myVersionCanonicalizer.resourceToValidatorCanonical(fetched); - - if (canonical instanceof StructureDefinition) - { - StructureDefinition canonicalSd = (StructureDefinition) canonical; - if (canonicalSd.getSnapshot().isEmpty()) - { - ourLog.info("Generating snapshot for StructureDefinition: {}", canonicalSd.getUrl()); - fetched = myValidationSupportContext.getRootValidationSupport() - .generateSnapshot(theValidationSupportContext, fetched, "", null, ""); - Validate.isTrue(fetched != null, - "StructureDefinition %s has no snapshot, and no snapshot generator is configured", - key.getUri()); - canonical = myVersionCanonicalizer.resourceToValidatorCanonical(fetched); - } - } - - return canonical; + return myVersionCanonicalizer.resourceToValidatorCanonical(fetched); }); setValidationMessageLanguage(getLocale()); @@ -324,8 +317,7 @@ else if (isNotBlank(message)) } retVal = new ValidationResult(issueSeverity, message, theSystem, theResult.getCodeSystemVersion(), - conceptDefinitionComponent, display, - getIssuesForCodeValidation(theResult.getCodeValidationIssues())); + conceptDefinitionComponent, display, getIssuesForCodeValidation(theResult.getIssues())); } if (retVal == null) @@ -337,78 +329,29 @@ else if (isNotBlank(message)) } private List<OperationOutcome.OperationOutcomeIssueComponent> getIssuesForCodeValidation( - List<IValidationSupport.CodeValidationIssue> codeValidationIssues) + List<IValidationSupport.CodeValidationIssue> theIssues) { - List<OperationOutcome.OperationOutcomeIssueComponent> issues = new ArrayList<>(); + List<OperationOutcome.OperationOutcomeIssueComponent> issueComponents = new ArrayList<>(); - for (IValidationSupport.CodeValidationIssue codeValidationIssue : codeValidationIssues) + for (IValidationSupport.CodeValidationIssue issue : theIssues) { - - CodeableConcept codeableConcept = new CodeableConcept().setText(codeValidationIssue.getMessage()); - codeableConcept.addCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", - getIssueCodingFromCodeValidationIssue(codeValidationIssue), null); - - OperationOutcome.OperationOutcomeIssueComponent issue = new OperationOutcome.OperationOutcomeIssueComponent() - .setSeverity(getIssueSeverityFromCodeValidationIssue(codeValidationIssue)) - .setCode(getIssueTypeFromCodeValidationIssue(codeValidationIssue)).setDetails(codeableConcept); - issue.getDetails().setText(codeValidationIssue.getMessage()); - issue.addExtension().setUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-message-id") + OperationOutcome.IssueSeverity severity = OperationOutcome.IssueSeverity + .fromCode(issue.getSeverity().getCode()); + OperationOutcome.IssueType issueType = OperationOutcome.IssueType.fromCode(issue.getType().getCode()); + String diagnostics = issue.getDiagnostics(); + + IValidationSupport.CodeValidationIssueDetails details = issue.getDetails(); + CodeableConcept codeableConcept = new CodeableConcept().setText(details.getText()); + details.getCodings().forEach(detailCoding -> codeableConcept.addCoding().setSystem(detailCoding.getSystem()) + .setCode(detailCoding.getCode())); + + OperationOutcome.OperationOutcomeIssueComponent issueComponent = new OperationOutcome.OperationOutcomeIssueComponent() + .setSeverity(severity).setCode(issueType).setDetails(codeableConcept).setDiagnostics(diagnostics); + issueComponent.addExtension().setUrl("http://hl7.org/fhir/StructureDefinition/operationoutcome-message-id") .setValue(new StringType("Terminology_PassThrough_TX_Message")); - issues.add(issue); - } - return issues; - } - - @SuppressWarnings("incomplete-switch") - private String getIssueCodingFromCodeValidationIssue(IValidationSupport.CodeValidationIssue codeValidationIssue) - { - switch (codeValidationIssue.getCoding()) - { - case VS_INVALID: - return "vs-invalid"; - case NOT_FOUND: - return "not-found"; - case NOT_IN_VS: - return "not-in-vs"; - case INVALID_CODE: - return "invalid-code"; - case INVALID_DISPLAY: - return "invalid-display"; - } - return null; - } - - @SuppressWarnings("incomplete-switch") - private OperationOutcome.IssueType getIssueTypeFromCodeValidationIssue( - IValidationSupport.CodeValidationIssue codeValidationIssue) - { - switch (codeValidationIssue.getCode()) - { - case NOT_FOUND: - return OperationOutcome.IssueType.NOTFOUND; - case CODE_INVALID: - return OperationOutcome.IssueType.CODEINVALID; - case INVALID: - return OperationOutcome.IssueType.INVALID; + issueComponents.add(issueComponent); } - return null; - } - - private OperationOutcome.IssueSeverity getIssueSeverityFromCodeValidationIssue( - IValidationSupport.CodeValidationIssue codeValidationIssue) - { - switch (codeValidationIssue.getSeverity()) - { - case FATAL: - return OperationOutcome.IssueSeverity.FATAL; - case ERROR: - return OperationOutcome.IssueSeverity.ERROR; - case WARNING: - return OperationOutcome.IssueSeverity.WARNING; - case INFORMATION: - return OperationOutcome.IssueSeverity.INFORMATION; - } - return null; + return issueComponents; } @Override @@ -493,7 +436,8 @@ public CodeSystem fetchCodeSystem(String system) @Override public CodeSystem fetchCodeSystem(String system, String verison) { - IBaseResource fetched = myValidationSupportContext.getRootValidationSupport().fetchCodeSystem(system); + IBaseResource fetched = myValidationSupportContext.getRootValidationSupport() + .fetchCodeSystem(system + "|" + verison); if (fetched == null) { return null; @@ -558,6 +502,14 @@ public <T extends Resource> T fetchResource(Class<T> class_, String theUri) return null; } + if (StructureDefinition.class.equals(class_)) + { + @SuppressWarnings("unchecked") + T structureDefinition = (T) myStructureDefinitionNonExpiringCache.computeIfAbsent(theUri, + k -> fetchStructureDefinition(theUri)); + return structureDefinition; + } + ResourceKey key = new ResourceKey(class_.getSimpleName(), theUri); @SuppressWarnings("unchecked") T retVal = (T) myFetchResourceCache.get(key); @@ -565,6 +517,35 @@ public <T extends Resource> T fetchResource(Class<T> class_, String theUri) return retVal; } + private StructureDefinition fetchStructureDefinition(String theUri) + { + // Fetch the resourceType + Class<? extends IBaseResource> resourceType = myValidationSupportContext.getRootValidationSupport() + .getFhirContext().getResourceDefinition(StructureDefinition.class.getSimpleName()) + .getImplementingClass(); + + // Fetch the resource + IBaseResource fetched = myValidationSupportContext.getRootValidationSupport().fetchResource(resourceType, + theUri); + + // Canonicalize the resource + Resource canonical = myVersionCanonicalizer.resourceToValidatorCanonical(fetched); + + // Ensure snapshot is present + StructureDefinition canonicalSd = (StructureDefinition) canonical; + if (canonicalSd != null && canonicalSd.getSnapshot().isEmpty()) + { + ourLog.info("Generating snapshot for StructureDefinition: {}", canonicalSd.getUrl()); + fetched = myValidationSupportContext.getRootValidationSupport().generateSnapshot(myValidationSupportContext, + fetched, "", null, ""); + Validate.isTrue(fetched != null, + "StructureDefinition %s has no snapshot, and no snapshot generator is configured", theUri); + canonicalSd = (StructureDefinition) myVersionCanonicalizer.resourceToValidatorCanonical(fetched); + } + + return canonicalSd; + } + @Override public Resource fetchResourceById(String type, String uri) { @@ -681,11 +662,24 @@ public List<StructureDefinition> fetchTypeDefinitions(String theTypeName, FhirPu @Override public boolean isPrimitiveType(String theType) { - List<StructureDefinition> allStructures = new ArrayList<>(allStructures()); - return allStructures.stream() - .filter(structureDefinition -> structureDefinition - .getKind() == StructureDefinition.StructureDefinitionKind.PRIMITIVETYPE) - .anyMatch(structureDefinition -> theType.equals(structureDefinition.getName())); + return allPrimitiveTypes().contains(theType); + } + + private Set<String> allPrimitiveTypes() + { + Set<String> retVal = myAllPrimitiveTypes; + if (retVal == null) + { + // Collector may be changed to Collectors.toUnmodifiableSet() when switching to Android API level >= 33 + retVal = allStructures().stream() + .filter(structureDefinition -> structureDefinition + .getKind() == StructureDefinition.StructureDefinitionKind.PRIMITIVETYPE) + .map(StructureDefinition::getName).filter(Objects::nonNull) + .collect(collectingAndThen(toSet(), Collections::unmodifiableSet)); + myAllPrimitiveTypes = retVal; + } + + return retVal; } @Override @@ -721,6 +715,14 @@ public <T extends Resource> boolean hasResource(Class<T> class_, String uri) return false; } + if (StructureDefinition.class.equals(class_)) + { + @SuppressWarnings("unchecked") + T structureDefinition = (T) myStructureDefinitionNonExpiringCache.computeIfAbsent(uri, + k -> fetchStructureDefinition(uri)); + return structureDefinition != null; + } + ResourceKey key = new ResourceKey(class_.getSimpleName(), uri); return myFetchResourceCache.get(key) != null; } @@ -919,7 +921,7 @@ private IValidationSupport.CodeValidationResult validateCodeInValueSet(IBaseReso IValidationSupport.CodeValidationResult result = myValidationSupportContext.getRootValidationSupport() .validateCodeInValueSet(myValidationSupportContext, theValidationOptions, theSystem, theCode, theDisplay, theValueSet); - if (result != null) + if (result != null && theSystem != null) { /* * We got a value set result, which could be successful, or could contain errors/warnings. The code might @@ -927,22 +929,19 @@ private IValidationSupport.CodeValidationResult validateCodeInValueSet(IBaseReso */ IValidationSupport.CodeValidationResult codeSystemResult = validateCodeInCodeSystem(theValidationOptions, theSystem, theCode, theDisplay); - final boolean valueSetResultContainsInvalidDisplay = result.getCodeValidationIssues().stream() - .anyMatch(codeValidationIssue -> codeValidationIssue - .getCoding() == IValidationSupport.CodeValidationIssueCoding.INVALID_DISPLAY); + final boolean valueSetResultContainsInvalidDisplay = result.getIssues().stream() + .anyMatch(FixedVersionSpecificWorkerContextWrapper::hasInvalidDisplayDetailCode); if (codeSystemResult != null) { - for (IValidationSupport.CodeValidationIssue codeValidationIssue : codeSystemResult - .getCodeValidationIssues()) + for (IValidationSupport.CodeValidationIssue codeValidationIssue : codeSystemResult.getIssues()) { /* * Value set validation should already have checked the display name. If we get INVALID_DISPLAY * issues from code system validation, they will only repeat what was already caught. */ - if (codeValidationIssue.getCoding() != IValidationSupport.CodeValidationIssueCoding.INVALID_DISPLAY - || !valueSetResultContainsInvalidDisplay) + if (!hasInvalidDisplayDetailCode(codeValidationIssue) || !valueSetResultContainsInvalidDisplay) { - result.addCodeValidationIssue(codeValidationIssue); + result.addIssue(codeValidationIssue); } } } @@ -950,6 +949,11 @@ private IValidationSupport.CodeValidationResult validateCodeInValueSet(IBaseReso return result; } + private static boolean hasInvalidDisplayDetailCode(IValidationSupport.CodeValidationIssue theIssue) + { + return theIssue.hasIssueDetailCode(INVALID_DISPLAY.getCode()); + } + private IValidationSupport.CodeValidationResult validateCodeInCodeSystem( ConceptValidationOptions theValidationOptions, String theSystem, String theCode, String theDisplay) { @@ -1013,6 +1017,7 @@ public ValidationResult validateCode(ValidationOptions theOptions, CodeableConce public void invalidateCaches() { myFetchResourceCache.invalidateAll(); + myStructureDefinitionNonExpiringCache.clear(); } @SuppressWarnings("unchecked") diff --git a/dsf-fhir/dsf-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/ValidationWrapperExtension.java b/dsf-fhir/dsf-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/ValidationWrapperExtension.java index b57c73f9a..10089eb3e 100644 --- a/dsf-fhir/dsf-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/ValidationWrapperExtension.java +++ b/dsf-fhir/dsf-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/ValidationWrapperExtension.java @@ -1,6 +1,6 @@ package org.hl7.fhir.common.hapi.validation.validator; -import java.util.Collections; +import java.util.List; import org.hl7.fhir.r5.utils.validation.IValidatorResourceFetcher; import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel; @@ -15,7 +15,7 @@ public static ValidatorWrapper create(IValidatorResourceFetcher validatorResourc { return new ValidationWrapperExtension().setAnyExtensionsAllowed(true) .setBestPracticeWarningLevel(BestPracticeWarningLevel.Ignore).setErrorForUnknownProfiles(true) - .setExtensionDomains(Collections.emptyList()).setValidationPolicyAdvisor(new FhirDefaultPolicyAdvisor()) + .setExtensionDomains(List.of()).setValidationPolicyAdvisor(new FhirDefaultPolicyAdvisor()) .setNoTerminologyChecks(false).setNoExtensibleWarnings(false).setNoBindingMsgSuppressed(false) .setValidatorResourceFetcher(validatorResourceFetcher).setAssumeValidRestReferences(false); } diff --git a/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/Subscription/dsf-bpmn-questionnaire-response-subscription.xml.post b/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/Subscription/dsf-bpmn-questionnaire-response-subscription.xml.post index e305c959b..5bd7dd61b 100644 --- a/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/Subscription/dsf-bpmn-questionnaire-response-subscription.xml.post +++ b/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/Subscription/dsf-bpmn-questionnaire-response-subscription.xml.post @@ -1 +1 @@ -criteria=QuestionnaireResponse%3Fstatus%3Dcompleted&status=active&type=websocket&payload=application/fhir%2Bjson \ No newline at end of file +criteria:exact=QuestionnaireResponse%3Fstatus%3Dcompleted&status=active&type=websocket&payload=application/fhir%2Bjson \ No newline at end of file diff --git a/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/Subscription/dsf-bpmn-task-subscription.xml.post b/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/Subscription/dsf-bpmn-task-subscription.xml.post index 44827415c..8102916d3 100644 --- a/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/Subscription/dsf-bpmn-task-subscription.xml.post +++ b/dsf-fhir/dsf-fhir-validation/src/main/resources/fhir/Subscription/dsf-bpmn-task-subscription.xml.post @@ -1 +1 @@ -criteria=Task%3Fstatus%3Drequested&status=active&type=websocket&payload=application/fhir%2Bjson \ No newline at end of file +criteria:exact=Task%3Fstatus%3Drequested&status=active&type=websocket&payload=application/fhir%2Bjson \ No newline at end of file diff --git a/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/ActivityDefinitionProfileTest.java b/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/ActivityDefinitionProfileTest.java index 6eeadb018..1c5866fb8 100644 --- a/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/ActivityDefinitionProfileTest.java +++ b/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/ActivityDefinitionProfileTest.java @@ -4,7 +4,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import java.util.Arrays; +import java.util.List; import org.hl7.fhir.r4.model.ActivityDefinition; import org.hl7.fhir.r4.model.ActivityDefinition.ActivityDefinitionKind; @@ -31,7 +31,7 @@ public class ActivityDefinitionProfileTest @ClassRule public static final ValidationSupportRule validationRule = new ValidationSupportRule( - Arrays.asList("dsf-activity-definition-1.0.0.xml", "dsf-extension-process-authorization-1.0.0.xml", + List.of("dsf-activity-definition-1.0.0.xml", "dsf-extension-process-authorization-1.0.0.xml", "dsf-extension-process-authorization-practitioner-1.0.0.xml", "dsf-extension-process-authorization-organization-1.0.0.xml", "dsf-extension-process-authorization-organization-practitioner-1.0.0.xml", @@ -46,9 +46,9 @@ public class ActivityDefinitionProfileTest "dsf-coding-process-authorization-remote-all-1.0.0.xml", "dsf-coding-process-authorization-remote-organization-1.0.0.xml", "dsf-coding-process-authorization-remote-parent-organization-role-1.0.0.xml"), - Arrays.asList("dsf-read-access-tag-1.0.0.xml", "dsf-organization-role-1.0.0.xml", + List.of("dsf-read-access-tag-1.0.0.xml", "dsf-organization-role-1.0.0.xml", "dsf-practitioner-role-1.0.0.xml", "dsf-process-authorization-1.0.0.xml"), - Arrays.asList("dsf-read-access-tag-1.0.0.xml", "dsf-organization-role-1.0.0.xml", + List.of("dsf-read-access-tag-1.0.0.xml", "dsf-organization-role-1.0.0.xml", "dsf-practitioner-role-1.0.0.xml", "dsf-process-authorization-recipient-1.0.0.xml", "dsf-process-authorization-requester-1.0.0.xml")); diff --git a/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/CodeSystemProfileTest.java b/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/CodeSystemProfileTest.java index 63b13fb41..5f4b63804 100644 --- a/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/CodeSystemProfileTest.java +++ b/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/CodeSystemProfileTest.java @@ -4,7 +4,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import java.util.Arrays; +import java.util.List; import org.hl7.fhir.r4.model.CodeSystem; import org.hl7.fhir.r4.model.CodeSystem.CodeSystemContentMode; @@ -29,10 +29,10 @@ public class CodeSystemProfileTest @ClassRule public static final ValidationSupportRule validationRule = new ValidationSupportRule( - Arrays.asList("dsf-code-system-1.0.0.xml", "dsf-extension-read-access-organization-1.0.0.xml", + List.of("dsf-code-system-1.0.0.xml", "dsf-extension-read-access-organization-1.0.0.xml", "dsf-extension-read-access-parent-organization-role-1.0.0.xml"), - Arrays.asList("dsf-read-access-tag-1.0.0.xml", "dsf-organization-role-1.0.0.xml"), - Arrays.asList("dsf-read-access-tag-1.0.0.xml", "dsf-organization-role-1.0.0.xml")); + List.of("dsf-read-access-tag-1.0.0.xml", "dsf-organization-role-1.0.0.xml"), + List.of("dsf-read-access-tag-1.0.0.xml", "dsf-organization-role-1.0.0.xml")); private final ResourceValidator resourceValidator = new ResourceValidatorImpl(validationRule.getFhirContext(), validationRule.getValidationSupport()); diff --git a/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/EndpointProfileTest.java b/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/EndpointProfileTest.java index e9bfc5439..a8c43b2f7 100644 --- a/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/EndpointProfileTest.java +++ b/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/EndpointProfileTest.java @@ -2,7 +2,7 @@ import static org.junit.Assert.assertEquals; -import java.util.Arrays; +import java.util.List; import java.util.UUID; import org.hl7.fhir.r4.model.Endpoint; @@ -25,9 +25,8 @@ public class EndpointProfileTest @ClassRule public static final ValidationSupportRule validationRule = new ValidationSupportRule( - Arrays.asList("dsf-endpoint-1.0.0.xml"), - Arrays.asList("dsf-read-access-tag-1.0.0.xml", "urn_ietf_bcp_13.xml"), - Arrays.asList("dsf-read-access-tag-1.0.0.xml", "valueset-mimetypes.xml")); + List.of("dsf-endpoint-1.0.0.xml"), List.of("dsf-read-access-tag-1.0.0.xml", "urn_ietf_bcp_13.xml"), + List.of("dsf-read-access-tag-1.0.0.xml", "valueset-mimetypes.xml")); private final ResourceValidator resourceValidator = new ResourceValidatorImpl(validationRule.getFhirContext(), validationRule.getValidationSupport()); diff --git a/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/OrganizationAffiliationProfileTest.java b/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/OrganizationAffiliationProfileTest.java index d0f4a0fd2..feab4349a 100644 --- a/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/OrganizationAffiliationProfileTest.java +++ b/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/OrganizationAffiliationProfileTest.java @@ -2,7 +2,7 @@ import static org.junit.Assert.assertEquals; -import java.util.Arrays; +import java.util.List; import java.util.UUID; import org.hl7.fhir.r4.model.OrganizationAffiliation; @@ -23,10 +23,10 @@ public class OrganizationAffiliationProfileTest @ClassRule public static final ValidationSupportRule validationRule = new ValidationSupportRule( - Arrays.asList("dsf-organization-affiliation-1.0.0.xml", "dsf-organization-1.0.0.xml", + List.of("dsf-organization-affiliation-1.0.0.xml", "dsf-organization-1.0.0.xml", "dsf-organization-parent-1.0.0.xml"), - Arrays.asList("dsf-read-access-tag-1.0.0.xml", "dsf-organization-role-1.0.0.xml"), - Arrays.asList("dsf-read-access-tag-1.0.0.xml", "dsf-organization-role-1.0.0.xml")); + List.of("dsf-read-access-tag-1.0.0.xml", "dsf-organization-role-1.0.0.xml"), + List.of("dsf-read-access-tag-1.0.0.xml", "dsf-organization-role-1.0.0.xml")); private final ResourceValidator resourceValidator = new ResourceValidatorImpl(validationRule.getFhirContext(), validationRule.getValidationSupport()); diff --git a/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/OrganizationProfileTest.java b/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/OrganizationProfileTest.java index de35f709c..a43bb1f14 100755 --- a/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/OrganizationProfileTest.java +++ b/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/OrganizationProfileTest.java @@ -2,7 +2,7 @@ import static org.junit.Assert.assertEquals; -import java.util.Arrays; +import java.util.List; import java.util.UUID; import org.hl7.fhir.r4.model.Coding; @@ -26,11 +26,11 @@ public class OrganizationProfileTest @ClassRule public static final ValidationSupportRule validationRule = new ValidationSupportRule( - Arrays.asList("dsf-organization-1.0.0.xml", "dsf-organization-parent-1.0.0.xml", + List.of("dsf-organization-1.0.0.xml", "dsf-organization-parent-1.0.0.xml", "dsf-extension-certificate-thumbprint-1.0.0.xml", "dsf-endpoint-1.0.0.xml", "dsf-extension-read-access-parent-organization-role-1.0.0.xml", "dsf-extension-read-access-organization-1.0.0.xml"), - Arrays.asList("dsf-read-access-tag-1.0.0.xml"), Arrays.asList("dsf-read-access-tag-1.0.0.xml")); + List.of("dsf-read-access-tag-1.0.0.xml"), List.of("dsf-read-access-tag-1.0.0.xml")); private final ResourceValidator resourceValidator = new ResourceValidatorImpl(validationRule.getFhirContext(), validationRule.getValidationSupport()); diff --git a/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/QuestionnaireProfileTest.java b/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/QuestionnaireProfileTest.java index 5d532cb55..ac91630ca 100644 --- a/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/QuestionnaireProfileTest.java +++ b/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/QuestionnaireProfileTest.java @@ -2,9 +2,8 @@ import static org.junit.Assert.assertEquals; -import java.util.Arrays; -import java.util.Collections; import java.util.Date; +import java.util.List; import org.hl7.fhir.r4.model.Enumerations; import org.hl7.fhir.r4.model.Questionnaire; @@ -28,8 +27,7 @@ public class QuestionnaireProfileTest @ClassRule public static final ValidationSupportRule validationRule = new ValidationSupportRule( - Arrays.asList("dsf-questionnaire-1.0.0.xml", "dsf-questionnaire-1.5.0.xml"), Collections.emptyList(), - Collections.emptyList()); + List.of("dsf-questionnaire-1.0.0.xml", "dsf-questionnaire-1.5.0.xml"), List.of(), List.of()); private final ResourceValidator resourceValidator = new ResourceValidatorImpl(validationRule.getFhirContext(), validationRule.getValidationSupport()); diff --git a/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/QuestionnaireResponseProfileTest.java b/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/QuestionnaireResponseProfileTest.java index 1f222177d..b1b580ab9 100644 --- a/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/QuestionnaireResponseProfileTest.java +++ b/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/QuestionnaireResponseProfileTest.java @@ -2,9 +2,8 @@ import static org.junit.Assert.assertEquals; -import java.util.Arrays; -import java.util.Collections; import java.util.Date; +import java.util.List; import java.util.UUID; import org.hl7.fhir.r4.model.BooleanType; @@ -36,7 +35,7 @@ public class QuestionnaireResponseProfileTest @ClassRule public static final ValidationSupportRule validationRule = new ValidationSupportRule( - Arrays.asList("dsf-questionnaire-response-1.0.0.xml"), Collections.emptyList(), Collections.emptyList()); + List.of("dsf-questionnaire-response-1.0.0.xml"), List.of(), List.of()); private final ResourceValidator resourceValidator = new ResourceValidatorImpl(validationRule.getFhirContext(), validationRule.getValidationSupport()); diff --git a/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/TaskProfileTest.java b/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/TaskProfileTest.java index 2848c42dc..25eeb4656 100755 --- a/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/TaskProfileTest.java +++ b/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/profiles/TaskProfileTest.java @@ -7,6 +7,7 @@ import java.util.Objects; import java.util.UUID; +import org.hl7.fhir.r4.model.IntegerType; import org.hl7.fhir.r4.model.ResourceType; import org.hl7.fhir.r4.model.StringType; import org.hl7.fhir.r4.model.Task; @@ -30,9 +31,9 @@ public class TaskProfileTest @ClassRule public static final ValidationSupportRule validationRule = new ValidationSupportRule( - List.of("dsf-task-base-1.0.0.xml", "dsf-task-test.xml"), - List.of("dsf-bpmn-message-1.0.0.xml", "dsf-test.xml"), - List.of("dsf-bpmn-message-1.0.0.xml", "dsf-test.xml")); + List.of("dsf-task-base-1.0.0.xml", "dsf-task-test.xml", "dsf-task-test-v2.xml"), + List.of("dsf-bpmn-message-1.0.0.xml", "dsf-test.xml", "dsf-test-v2.xml"), + List.of("dsf-bpmn-message-1.0.0.xml", "dsf-test.xml", "dsf-test-v2.xml")); private final ResourceValidator resourceValidator = new ResourceValidatorImpl(validationRule.getFhirContext(), validationRule.getValidationSupport()); @@ -151,10 +152,10 @@ private ValidationResult validate(Task task) } @Test - public void testTaskValidationWithAdditionalInputNotInDsfBaseTask() + public void testTaskValidationWithAdditionalInputNotInDsfBaseTaskVersion1_4() { Task task = new Task(); - task.getMeta().addProfile("http://dsf.dev/fhir/StructureDefinition/task-test"); + task.getMeta().addProfile("http://dsf.dev/fhir/StructureDefinition/task-test|1.4"); task.setInstantiatesCanonical("http://dsf.dev/bpe/Process/test|1.4"); task.setStatus(TaskStatus.REQUESTED); task.setIntent(TaskIntent.ORDER); @@ -167,7 +168,33 @@ public void testTaskValidationWithAdditionalInputNotInDsfBaseTask() task.addInput().setValue(new StringType("test")).getType().getCodingFirstRep() .setSystem("http://dsf.dev/fhir/CodeSystem/bpmn-message").setCode("message-name"); task.addInput().setValue(new StringType("some-test-string")).getType().getCodingFirstRep() - .setSystem("http://dsf.dev/fhir/CodeSystem/test").setCode("string-example"); + .setSystem("http://dsf.dev/fhir/CodeSystem/test|1.4").setCode("string-example"); + + ValidationResult result = resourceValidator.validate(task); + ValidationSupportRule.logValidationMessages(logger, result); + + assertEquals(0, result.getMessages().stream().filter(m -> ResultSeverityEnum.ERROR.equals(m.getSeverity()) + || ResultSeverityEnum.FATAL.equals(m.getSeverity())).count()); + } + + @Test + public void testTaskValidationWithAdditionalInputNotInDsfBaseTaskVersion2_0() + { + Task task = new Task(); + task.getMeta().addProfile("http://dsf.dev/fhir/StructureDefinition/task-test|2.0"); + task.setInstantiatesCanonical("http://dsf.dev/bpe/Process/test|2.0"); + task.setStatus(TaskStatus.REQUESTED); + task.setIntent(TaskIntent.ORDER); + task.setAuthoredOn(new Date()); + task.getRequester().setType(ResourceType.Organization.name()).getIdentifier() + .setSystem("http://dsf.dev/sid/organization-identifier").setValue("Test_DIC_1"); + task.getRestriction().addRecipient().setType(ResourceType.Organization.name()).getIdentifier() + .setSystem("http://dsf.dev/sid/organization-identifier").setValue("Test_DIC_1"); + + task.addInput().setValue(new StringType("test_v2")).getType().getCodingFirstRep() + .setSystem("http://dsf.dev/fhir/CodeSystem/bpmn-message").setCode("message-name"); + task.addInput().setValue(new IntegerType(42)).getType().getCodingFirstRep() + .setSystem("http://dsf.dev/fhir/CodeSystem/test|2.0").setCode("integer-example"); ValidationResult result = resourceValidator.validate(task); ValidationSupportRule.logValidationMessages(logger, result); diff --git a/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/validation/ValueSetExpanderTest.java b/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/validation/ValueSetExpanderTest.java index b839f2743..df3b91fb3 100755 --- a/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/validation/ValueSetExpanderTest.java +++ b/dsf-fhir/dsf-fhir-validation/src/test/java/dev/dsf/fhir/validation/ValueSetExpanderTest.java @@ -6,7 +6,6 @@ import java.io.IOException; import java.io.InputStream; -import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.stream.Collectors; @@ -43,8 +42,7 @@ public Locale getLocale() }); var validationSupport = new ValidationSupportChain(new InMemoryTerminologyServerValidationSupport(fhirContext), - new ValidationSupportWithCustomResources(fhirContext, Collections.emptyList(), readCodeSystems(), - Collections.emptyList()), + new ValidationSupportWithCustomResources(fhirContext, List.of(), readCodeSystems(), List.of()), new DefaultProfileValidationSupport(fhirContext)); valueSetExpander = new ValueSetExpanderImpl(fhirContext, validationSupport); diff --git a/dsf-fhir/dsf-fhir-validation/src/test/resources/fhir/CodeSystem/dsf-test-v2.xml b/dsf-fhir/dsf-fhir-validation/src/test/resources/fhir/CodeSystem/dsf-test-v2.xml new file mode 100644 index 000000000..b5b63d971 --- /dev/null +++ b/dsf-fhir/dsf-fhir-validation/src/test/resources/fhir/CodeSystem/dsf-test-v2.xml @@ -0,0 +1,31 @@ +<CodeSystem xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <url value="http://dsf.dev/fhir/CodeSystem/test" /> + <version value="2.0" /> + <name value="DSF_Test" /> + <title value="DSF Test" /> + <status value="active" /> + <experimental value="false" /> + <date value="2025-02-04" /> + <publisher value="DSF" /> + <description value="CodeSystem with standard values for a test process" /> + <caseSensitive value="true" /> + <hierarchyMeaning value="grouped-by" /> + <versionNeeded value="false" /> + <content value="complete" /> + <concept> + <code value="string-example" /> + <display value="String Example" /> + <definition value="Example string input value" /> + </concept> + <concept> + <code value="integer-example" /> + <display value="Integer Example" /> + <definition value="Example integer input value" /> + </concept> +</CodeSystem> \ No newline at end of file diff --git a/dsf-fhir/dsf-fhir-validation/src/test/resources/fhir/StructureDefinition/dsf-task-test-v2.xml b/dsf-fhir/dsf-fhir-validation/src/test/resources/fhir/StructureDefinition/dsf-task-test-v2.xml new file mode 100644 index 000000000..bd2c4084f --- /dev/null +++ b/dsf-fhir/dsf-fhir-validation/src/test/resources/fhir/StructureDefinition/dsf-task-test-v2.xml @@ -0,0 +1,86 @@ +<StructureDefinition xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <url value="http://dsf.dev/fhir/StructureDefinition/task-test" /> + <version value="2.0" /> + <name value="testProcess" /> + <status value="active" /> + <experimental value="false" /> + <date value="2025-02-04" /> + <fhirVersion value="4.0.1" /> + <kind value="resource" /> + <abstract value="false" /> + <type value="Task" /> + <baseDefinition value="http://dsf.dev/fhir/StructureDefinition/task-base" /> + <derivation value="constraint" /> + <differential> + <element id="Task.instantiatesUri"> + <path value="Task.instantiatesUri" /> + <fixedUri value="http://dsf.dev/bpe/Process/test/2.0" /> + </element> + <element id="Task.input"> + <extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-explicit-type-name"> + <valueString value="Parameter" /> + </extension> + <path value="Task.input" /> + </element> + <element id="Task.input:message-name"> + <extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-explicit-type-name"> + <valueString value="Parameter" /> + </extension> + <path value="Task.input" /> + <sliceName value="message-name" /> + </element> + <element id="Task.input:message-name.value[x]"> + <path value="Task.input.value[x]" /> + <fixedString value="test_v2" /> + </element> + <element id="Task.input:correlation-key"> + <extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-explicit-type-name"> + <valueString value="Parameter" /> + </extension> + <path value="Task.input" /> + <sliceName value="correlation-key" /> + <max value="0" /> + </element> + <element id="Task.input:integer-example"> + <path value="Task.input" /> + <sliceName value="integer-example" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Task.input:integer-example.type"> + <path value="Task.input.type" /> + <binding> + <strength value="required" /> + <valueSet value="http://dsf.dev/fhir/ValueSet/test|2.0" /> + </binding> + </element> + <element id="Task.input:string-example.type.coding"> + <path value="Task.input.type.coding" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Task.input:string-example.system"> + <path value="Task.input.type.coding.system" /> + <min value="1" /> + <fixedUri value="http://dsf.dev/fhir/CodeSystem/test|2.0" /> + </element> + <element id="Task.input:string-example.type.coding.code"> + <path value="Task.input.type.coding.code" /> + <min value="1" /> + <fixedCode value="integer-example" /> + </element> + <element id="Task.input:string-example.value[x]"> + <path value="Task.input.value[x]" /> + <type> + <code value="integer" /> + </type> + <min value="1" /> + </element> + </differential> +</StructureDefinition> \ No newline at end of file diff --git a/dsf-fhir/dsf-fhir-validation/src/test/resources/fhir/StructureDefinition/dsf-task-test.xml b/dsf-fhir/dsf-fhir-validation/src/test/resources/fhir/StructureDefinition/dsf-task-test.xml index 11d228862..b9d272efb 100644 --- a/dsf-fhir/dsf-fhir-validation/src/test/resources/fhir/StructureDefinition/dsf-task-test.xml +++ b/dsf-fhir/dsf-fhir-validation/src/test/resources/fhir/StructureDefinition/dsf-task-test.xml @@ -68,7 +68,7 @@ <element id="Task.input:string-example.system"> <path value="Task.input.type.coding.system" /> <min value="1" /> - <fixedUri value="http://dsf.dev/fhir/CodeSystem/test" /> + <fixedUri value="http://dsf.dev/fhir/CodeSystem/test|1.4" /> </element> <element id="Task.input:string-example.type.coding.code"> <path value="Task.input.type.coding.code" /> diff --git a/dsf-fhir/dsf-fhir-validation/src/test/resources/fhir/ValueSet/dsf-test-v2.xml b/dsf-fhir/dsf-fhir-validation/src/test/resources/fhir/ValueSet/dsf-test-v2.xml new file mode 100644 index 000000000..e4562a233 --- /dev/null +++ b/dsf-fhir/dsf-fhir-validation/src/test/resources/fhir/ValueSet/dsf-test-v2.xml @@ -0,0 +1,24 @@ +<ValueSet xmlns="http://hl7.org/fhir"> + <meta> + <tag> + <system value="http://dsf.dev/fhir/CodeSystem/read-access-tag" /> + <code value="ALL" /> + </tag> + </meta> + <url value="http://dsf.dev/fhir/ValueSet/test" /> + <version value="2.0" /> + <name value="DSF_Test" /> + <title value="DSF Test" /> + <status value="active" /> + <experimental value="false" /> + <date value="2025-02-04" /> + <publisher value="DSF" /> + <description value="ValueSet with standard values for a test process" /> + <immutable value="true" /> + <compose> + <include> + <system value="http://dsf.dev/fhir/CodeSystem/test" /> + <version value="2.0" /> + </include> + </compose> +</ValueSet> \ No newline at end of file diff --git a/dsf-fhir/dsf-fhir-webservice-client/src/main/java/dev/dsf/fhir/client/FhirWebserviceClientJersey.java b/dsf-fhir/dsf-fhir-webservice-client/src/main/java/dev/dsf/fhir/client/FhirWebserviceClientJersey.java index 8a1257ad8..b94236618 100755 --- a/dsf-fhir/dsf-fhir-webservice-client/src/main/java/dev/dsf/fhir/client/FhirWebserviceClientJersey.java +++ b/dsf-fhir/dsf-fhir-webservice-client/src/main/java/dev/dsf/fhir/client/FhirWebserviceClientJersey.java @@ -3,7 +3,6 @@ import java.io.InputStream; import java.security.KeyStore; import java.text.SimpleDateFormat; -import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Locale; @@ -80,8 +79,8 @@ public FhirWebserviceClientJersey(String baseUrl, KeyStore trustStore, KeyStore ReferenceCleaner referenceCleaner) { super(baseUrl, trustStore, keyStore, keyStorePassword, objectMapper, - Collections.singleton(new FhirAdapter(fhirContext, referenceCleaner)), proxySchemeHostPort, - proxyUserName, proxyPassword, connectTimeout, readTimeout, logRequests, userAgentValue); + List.of(new FhirAdapter(fhirContext, referenceCleaner)), proxySchemeHostPort, proxyUserName, + proxyPassword, connectTimeout, readTimeout, logRequests, userAgentValue); preferReturnMinimal = new PreferReturnMinimalWithRetryImpl(this); preferReturnOutcome = new PreferReturnOutcomeWithRetryImpl(this); diff --git a/dsf-fhir/dsf-fhir-websocket-client/src/main/java/dev/dsf/fhir/client/WebsocketClientTyrus.java b/dsf-fhir/dsf-fhir-websocket-client/src/main/java/dev/dsf/fhir/client/WebsocketClientTyrus.java index 40fe3f13f..bf93c512a 100755 --- a/dsf-fhir/dsf-fhir-websocket-client/src/main/java/dev/dsf/fhir/client/WebsocketClientTyrus.java +++ b/dsf-fhir/dsf-fhir-websocket-client/src/main/java/dev/dsf/fhir/client/WebsocketClientTyrus.java @@ -5,8 +5,8 @@ import java.nio.charset.StandardCharsets; import java.security.KeyStore; import java.util.Base64; -import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.function.Consumer; import java.util.function.Supplier; @@ -174,7 +174,7 @@ private ClientEndpointConfig createConfig(String userAgentValue) @Override public void beforeRequest(Map<String, java.util.List<String>> headers) { - headers.put(HttpHeaders.USER_AGENT, Collections.singletonList(userAgentValue)); + headers.put(HttpHeaders.USER_AGENT, List.of(userAgentValue)); } }; return ClientEndpointConfig.Builder.create().configurator(configurator).build(); @@ -189,8 +189,11 @@ public void disconnect() logger.debug("Closing websocket {}", wsUri); try { - connection.close(); - connection = null; + if (connection != null) + { + connection.close(); + connection = null; + } } catch (IOException e) { diff --git a/dsf-fhir/pom.xml b/dsf-fhir/pom.xml index 540e38ef9..bc849885f 100755 --- a/dsf-fhir/pom.xml +++ b/dsf-fhir/pom.xml @@ -41,6 +41,11 @@ <dependencyManagement> <dependencies> + <dependency> + <groupId>dev.dsf</groupId> + <artifactId>dsf-fhir-auth</artifactId> + <version>${project.version}</version> + </dependency> <dependency> <groupId>dev.dsf</groupId> <artifactId>dsf-fhir-rest-adapter</artifactId> @@ -58,7 +63,7 @@ </dependency> <dependency> <groupId>dev.dsf</groupId> - <artifactId>dsf-fhir-client</artifactId> + <artifactId>dsf-fhir-validation</artifactId> <version>${project.version}</version> </dependency> <dependency> @@ -71,16 +76,6 @@ <artifactId>dsf-fhir-websocket-client</artifactId> <version>${project.version}</version> </dependency> - <dependency> - <groupId>dev.dsf</groupId> - <artifactId>dsf-fhir-validation</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>dev.dsf</groupId> - <artifactId>dsf-fhir-auth</artifactId> - <version>${project.version}</version> - </dependency> <dependency> <groupId>dev.dsf</groupId> diff --git a/dsf-tools/dsf-tools-bundle-generator/pom.xml b/dsf-tools/dsf-tools-bundle-generator/pom.xml index 9c610dab0..30c7363b7 100755 --- a/dsf-tools/dsf-tools-bundle-generator/pom.xml +++ b/dsf-tools/dsf-tools-bundle-generator/pom.xml @@ -15,11 +15,6 @@ <artifactId>hapi-fhir-structures-r4</artifactId> <version>${hapi.fhir.version}</version> </dependency> - <dependency> - <groupId>ca.uhn.hapi.fhir</groupId> - <artifactId>hapi-fhir-structures-r5</artifactId> - <version>${hapi.fhir.version}</version> - </dependency> <dependency> <groupId>ca.uhn.hapi.fhir</groupId> <artifactId>hapi-fhir-validation</artifactId> @@ -36,12 +31,7 @@ <artifactId>hapi-fhir-validation-resources-r4</artifactId> <version>${hapi.fhir.version}</version> </dependency> - <dependency> - <groupId>ca.uhn.hapi.fhir</groupId> - <artifactId>hapi-fhir-validation-resources-r5</artifactId> - <version>${hapi.fhir.version}</version> - </dependency> - + <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> diff --git a/dsf-tools/dsf-tools-db-migration/src/main/java/dev/dsf/tools/db/DbMigrator.java b/dsf-tools/dsf-tools-db-migration/src/main/java/dev/dsf/tools/db/DbMigrator.java index f7f5c6ad9..007770b9a 100755 --- a/dsf-tools/dsf-tools-db-migration/src/main/java/dev/dsf/tools/db/DbMigrator.java +++ b/dsf-tools/dsf-tools-db-migration/src/main/java/dev/dsf/tools/db/DbMigrator.java @@ -126,7 +126,7 @@ public void migrate() ByteArrayOutputStream output = new ByteArrayOutputStream(); CommandScope updateCommand = new CommandScope(UpdateCommandStep.COMMAND_NAME); updateCommand.addArgumentValue(DbUrlConnectionArgumentsCommandStep.DATABASE_ARG, database); - updateCommand.addArgumentValue(UpdateCommandStep.CHANGELOG_FILE_ARG, "db/db.changelog.xml"); + updateCommand.addArgumentValue(UpdateCommandStep.CHANGELOG_FILE_ARG, config.getChangelogFile()); updateCommand.addArgumentValue(UpdateCommandStep.CONTEXTS_ARG, new Contexts().toString()); updateCommand.addArgumentValue(UpdateCommandStep.LABEL_FILTER_ARG, new LabelExpression().getOriginalString()); diff --git a/dsf-tools/dsf-tools-db-migration/src/main/java/dev/dsf/tools/db/DbMigratorConfig.java b/dsf-tools/dsf-tools-db-migration/src/main/java/dev/dsf/tools/db/DbMigratorConfig.java index 40e8651f2..d67177b6e 100644 --- a/dsf-tools/dsf-tools-db-migration/src/main/java/dev/dsf/tools/db/DbMigratorConfig.java +++ b/dsf-tools/dsf-tools-db-migration/src/main/java/dev/dsf/tools/db/DbMigratorConfig.java @@ -10,6 +10,8 @@ public interface DbMigratorConfig char[] getDbLiquibasePassword(); + String getChangelogFile(); + Map<String, String> getChangeLogParameters(); boolean forceLiquibaseUnlock(); diff --git a/dsf-tools/dsf-tools-default-ca-files-generator/pom.xml b/dsf-tools/dsf-tools-default-ca-files-generator/pom.xml index 62d562300..5074ce75f 100644 --- a/dsf-tools/dsf-tools-default-ca-files-generator/pom.xml +++ b/dsf-tools/dsf-tools-default-ca-files-generator/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>dev.dsf</groupId> <artifactId>dsf-tools-pom</artifactId> - <version>1.7.0</version> + <version>2.0.0-SNAPSHOT</version> </parent> <dependencies> diff --git a/dsf-tools/dsf-tools-documentation-generator/src/main/java/dev/dsf/tools/generator/DocumentationGenerator.java b/dsf-tools/dsf-tools-documentation-generator/src/main/java/dev/dsf/tools/generator/DocumentationGenerator.java index 8ebbe3a54..18472c6bf 100644 --- a/dsf-tools/dsf-tools-documentation-generator/src/main/java/dev/dsf/tools/generator/DocumentationGenerator.java +++ b/dsf-tools/dsf-tools-documentation-generator/src/main/java/dev/dsf/tools/generator/DocumentationGenerator.java @@ -17,7 +17,6 @@ import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Objects; @@ -136,7 +135,7 @@ private List<String> getPluginProcessNames(Reflections reflections, ClassLoader if (pluginDefinitionClasses.size() < 1) { logger.warn("No ProcessPluginDefinitions found in package {}", workingPackage); - return Collections.emptyList(); + return List.of(); } if (pluginDefinitionClasses.size() > 1) @@ -157,7 +156,7 @@ private List<String> getPluginProcessNames(Reflections reflections, ClassLoader logger.error("Could not read process names from package {} and ProcessPluginDefinition with name {}: {} {}", workingPackage, pluginDefinitionClasses.get(0).getName(), e.getClass().getSimpleName(), e.getMessage()); - return Collections.emptyList(); + return List.of(); } } diff --git a/dsf-tools/dsf-tools-test-data-generator/pom.xml b/dsf-tools/dsf-tools-test-data-generator/pom.xml index cf0ee0592..319d3f130 100755 --- a/dsf-tools/dsf-tools-test-data-generator/pom.xml +++ b/dsf-tools/dsf-tools-test-data-generator/pom.xml @@ -54,7 +54,7 @@ <goals> <goal>exec</goal> </goals> - <phase>prepare-package</phase> + <phase>install</phase> </execution> </executions> <configuration> diff --git a/dsf-tools/dsf-tools-test-data-generator/src/main/java/dev/dsf/tools/generator/CertificateGenerator.java b/dsf-tools/dsf-tools-test-data-generator/src/main/java/dev/dsf/tools/generator/CertificateGenerator.java index 833592127..b9d13cd7d 100755 --- a/dsf-tools/dsf-tools-test-data-generator/src/main/java/dev/dsf/tools/generator/CertificateGenerator.java +++ b/dsf-tools/dsf-tools-test-data-generator/src/main/java/dev/dsf/tools/generator/CertificateGenerator.java @@ -63,7 +63,7 @@ public class CertificateGenerator "test-client", "Webbrowser Test User" }; private static final Map<String, List<String>> DNS_NAMES = Map.of("localhost", - Arrays.asList("localhost", "host.docker.internal", "fhir", "bpe", "ttp", "dic1", "dic2", "dic3")); + List.of("localhost", "host.docker.internal", "fhir", "bpe", "ttp", "dic1", "dic2", "dic3")); private static final BouncyCastleProvider PROVIDER = new BouncyCastleProvider(); @@ -116,10 +116,10 @@ public void generateCertificates() serverCertificateFilesByCommonName = Arrays.stream(SERVER_COMMON_NAMES) .map(commonName -> createCert(CertificateType.SERVER, commonName, - DNS_NAMES.getOrDefault(commonName, Collections.singletonList(commonName)))) + DNS_NAMES.getOrDefault(commonName, List.of(commonName)))) .collect(Collectors.toMap(CertificateFiles::getCommonName, Function.identity())); clientCertificateFilesByCommonName = Arrays.stream(CLIENT_COMMON_NAMES) - .map(commonName -> createCert(CertificateType.CLIENT, commonName, Collections.emptyList())) + .map(commonName -> createCert(CertificateType.CLIENT, commonName, List.of())) .collect(Collectors.toMap(CertificateFiles::getCommonName, Function.identity())); writeThumbprints(); @@ -129,14 +129,14 @@ public Map<String, CertificateFiles> getServerCertificateFilesByCommonName() { return serverCertificateFilesByCommonName != null ? Collections.unmodifiableMap(serverCertificateFilesByCommonName) - : Collections.emptyMap(); + : Map.of(); } public Map<String, CertificateFiles> getClientCertificateFilesByCommonName() { return clientCertificateFilesByCommonName != null ? Collections.unmodifiableMap(clientCertificateFilesByCommonName) - : Collections.emptyMap(); + : Map.of(); } public CertificateAuthority initCA() @@ -177,7 +177,8 @@ private void writePrivateKeyEncrypted(Path privateKeyFile, PrivateKey privateKey } catch (IOException | OperatorCreationException e) { - logger.error("Error while writing encrypted private-key to {}", privateKeyFile.toString(), e); + logger.error("Error while writing encrypted private-key to {}", + privateKeyFile.toAbsolutePath().normalize().toString(), e); throw new RuntimeException(e); } } @@ -190,7 +191,8 @@ private void writePrivateKeyNotEncrypted(Path privateKeyFile, PrivateKey private } catch (IOException | OperatorCreationException e) { - logger.error("Error while writing not-encrypted private-key to {}", privateKeyFile.toString(), e); + logger.error("Error while writing not-encrypted private-key to {}", + privateKeyFile.toAbsolutePath().normalize().toString(), e); throw new RuntimeException(e); } } @@ -203,7 +205,8 @@ private void writeCertificate(Path certificateFile, X509Certificate certificate) } catch (CertificateEncodingException | IllegalStateException | IOException e) { - logger.error("Error while writing certificate to {}", certificateFile.toString(), e); + logger.error("Error while writing certificate to {}", + certificateFile.toAbsolutePath().normalize().toString(), e); throw new RuntimeException(e); } } @@ -216,7 +219,8 @@ private PrivateKey readPrivatekey(Path privateKeyFile) } catch (IOException | PKCSException e) { - logger.error("Error while reading private-key from {}", privateKeyFile.toString(), e); + logger.error("Error while reading private-key from {}", + privateKeyFile.toAbsolutePath().normalize().toString(), e); throw new RuntimeException(e); } } @@ -229,7 +233,8 @@ private X509Certificate readCertificate(Path certFile) } catch (CertificateException | IOException e) { - logger.error("Error while reading certificate from {}", certFile.toString(), e); + logger.error("Error while reading certificate from {}", certFile.toAbsolutePath().normalize().toString(), + e); throw new RuntimeException(e); } } @@ -251,7 +256,8 @@ public void writeThumbprints() } catch (IOException e) { - logger.error("Error while writing certificate thumbprints file to {}", thumbprintsFile.toString(), e); + logger.error("Error while writing certificate thumbprints file to {}", + thumbprintsFile.toAbsolutePath().normalize().toString(), e); throw new RuntimeException(e); } } @@ -364,7 +370,8 @@ private void writeCertificateRequest(Path certificateRequestFile, JcaPKCS10Certi } catch (IOException e) { - logger.error("Error while reading certificate-request from {}", certificateRequestFile.toString(), e); + logger.error("Error while reading certificate-request from {}", + certificateRequestFile.toAbsolutePath().normalize().toString(), e); throw new RuntimeException(e); } } @@ -377,7 +384,8 @@ private JcaPKCS10CertificationRequest readCertificateRequest(Path certificateReq } catch (NoSuchAlgorithmException | InvalidKeySpecException | IOException e) { - logger.error("Error while reading certificate-request from {}", certificateRequestFile.toString(), e); + logger.error("Error while reading certificate-request from {}", + certificateRequestFile.toAbsolutePath().normalize().toString(), e); throw new RuntimeException(e); } } @@ -450,7 +458,8 @@ private Path createFolderIfNotExists(Path file) } catch (IOException e) { - logger.error("Error while creating directories {}", file.getParent().toString(), e); + logger.error("Error while creating directories {}", + file.getParent().toAbsolutePath().normalize().toString(), e); throw new RuntimeException(e); } @@ -625,7 +634,7 @@ public void copyDockerTest3DicTtpCertificates() logger.info("Copying localhost private-key file to {}", localhostCertificatePrivateKey); writePrivateKeyNotEncrypted(localhostCertificatePrivateKey, localhost.keyPair.getPrivate()); - List<String> commonNames = Arrays.asList("dic1", "dic2", "dic3", "ttp"); + List<String> commonNames = List.of("dic1", "dic2", "dic3", "ttp"); commonNames.forEach(cn -> copyDockerTest3DicTtpClientCertFiles("../../dsf-docker-test-setup-3dic-ttp/secrets/", cn + "-client")); @@ -694,7 +703,8 @@ private void writeCertificates(Path certificateFile, X509Certificate... certific } catch (CertificateEncodingException | IllegalStateException | IOException e) { - logger.error("Error while writing certificate to {}", certificateFile.toString(), e); + logger.error("Error while writing certificate to {}", + certificateFile.toAbsolutePath().normalize().toString(), e); throw new RuntimeException(e); } } @@ -738,7 +748,7 @@ private void writeKeyStore(Path file, KeyStore keyStore) } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { - logger.error("Error while writing keystore file to {}", file.toString(), e); + logger.error("Error while writing keystore file to {}", file.toAbsolutePath().normalize().toString(), e); throw new RuntimeException(e); } } diff --git a/dsf-tools/dsf-tools-test-data-generator/src/main/java/dev/dsf/tools/generator/EnvGenerator.java b/dsf-tools/dsf-tools-test-data-generator/src/main/java/dev/dsf/tools/generator/EnvGenerator.java index 6bc8753bb..f0e3798af 100644 --- a/dsf-tools/dsf-tools-test-data-generator/src/main/java/dev/dsf/tools/generator/EnvGenerator.java +++ b/dsf-tools/dsf-tools-test-data-generator/src/main/java/dev/dsf/tools/generator/EnvGenerator.java @@ -4,7 +4,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Map; @@ -81,8 +80,8 @@ private Stream<String> filterAndMapToThumbprint(Map<String, CertificateFiles> cl String... commonNames) { return clientCertificateFilesByCommonName.entrySet().stream() - .filter(entry -> Arrays.asList(commonNames).contains(entry.getKey())) - .sorted(Comparator.comparing(e -> Arrays.asList(commonNames).indexOf(e.getKey()))).map(Entry::getValue) + .filter(entry -> List.of(commonNames).contains(entry.getKey())) + .sorted(Comparator.comparing(e -> List.of(commonNames).indexOf(e.getKey()))).map(Entry::getValue) .map(CertificateFiles::getCertificateSha512ThumbprintHex); } diff --git a/dsf-tools/dsf-tools-test-data-generator/src/main/resources/config-templates/java-test-bpe-config.properties b/dsf-tools/dsf-tools-test-data-generator/src/main/resources/config-templates/java-test-bpe-config.properties index ef8b9420f..59a9f7f17 100644 --- a/dsf-tools/dsf-tools-test-data-generator/src/main/resources/config-templates/java-test-bpe-config.properties +++ b/dsf-tools/dsf-tools-test-data-generator/src/main/resources/config-templates/java-test-bpe-config.properties @@ -1,13 +1,6 @@ dev.dsf.bpe.db.url=jdbc:postgresql://localhost/bpe -#dev.dsf.bpe.db.liquibase.username=liquibase_user dev.dsf.bpe.db.liquibase.password=fLp6ZSd5QrMAkGZMjxqXjmcWrTfa3Dn8fA57h92Y - -#dev.dsf.bpe.db.user.group=bpe_users -#dev.dsf.bpe.db.user.username=bpe_server_user dev.dsf.bpe.db.user.password=as2hm56BPcaJKtG25JEx - -#dev.dsf.bpe.db.user.camunda.group=camunda_users -#dev.dsf.bpe.db.user.camunda.username=camunda_server_user dev.dsf.bpe.db.user.camunda.password=arpJ2FgJuYvUJhbxeuh7 dev.dsf.bpe.fhir.server.organization.identifier.value=Test_Organization @@ -17,30 +10,9 @@ dev.dsf.bpe.fhir.client.certificate=target/test-client_certificate.pem dev.dsf.bpe.fhir.client.certificate.private.key=target/test-client_private-key.pem dev.dsf.bpe.fhir.client.certificate.private.key.password=password -#dev.dsf.bpe.fhir.client.remote.timeout.read=60000 -#dev.dsf.bpe.fhir.client.remote.timeout.connect=5000 - dev.dsf.bpe.fhir.server.base.url=https://localhost:8001/fhir - -#dev.dsf.bpe.fhir.client.local.timeout.read=60000 -#dev.dsf.bpe.fhir.client.local.timeout.connect=2000 - -#dev.dsf.bpe.fhir.task.subscription.search.parameter=?criteria=Task%3Fstatus%3Drequested&status=active&type=websocket&payload=application/fhir%2Bjson -#dev.dsf.bpe.fhir.task.subscription.retry.max=-1 -#dev.dsf.bpe.fhir.task.subscription.retry.sleep=5000 - -#dev.dsf.bpe.process.plugin.directroy=process -#dev.dsf.bpe.process.excluded= -#dev.dsf.bpe.process.retired= -#dev.dsf.bpe.process.fhir.server.retry.max=-1 -#dev.dsf.bpe.process.fhir.server.retry.sleep=5000 - -#dev.dsf.bpe.proxy.url= -#dev.dsf.bpe.proxy.username= -#dev.dsf.bpe.proxy.password= -#dev.dsf.bpe.proxy.noProxy= - dev.dsf.bpe.server.base.url=https://localhost:8002/bpe dev.dsf.bpe.server.static.resource.cache=false -dev.dsf.bpe.server.ui.theme=dev \ No newline at end of file +dev.dsf.bpe.server.ui.theme=dev +dev.dsf.bpe.process.api.directory=../dsf-bpe-server-jetty/docker/api \ No newline at end of file diff --git a/dsf-tools/dsf-tools-test-data-generator/src/main/resources/config-templates/java-test-fhir-config.properties b/dsf-tools/dsf-tools-test-data-generator/src/main/resources/config-templates/java-test-fhir-config.properties index 0818b09ed..ca3aa8665 100755 --- a/dsf-tools/dsf-tools-test-data-generator/src/main/resources/config-templates/java-test-fhir-config.properties +++ b/dsf-tools/dsf-tools-test-data-generator/src/main/resources/config-templates/java-test-fhir-config.properties @@ -1,34 +1,16 @@ dev.dsf.fhir.db.url=jdbc:postgresql://localhost/fhir -#dev.dsf.fhir.db.liquibase.username=liquibase_user dev.dsf.fhir.db.liquibase.password=fLp6ZSd5QrMAkGZMjxqXjmcWrTfa3Dn8fA57h92Y - -#dev.dsf.fhir.db.user.group=fhir_users -#dev.dsf.fhir.db.user.username=fhir_server_user dev.dsf.fhir.db.user.password=gv7UJQEPPx3Yq87TWzYj -#dev.dsf.fhir.db.user.permanent.delete.group=fhir_permanent_delete_users -#dev.dsf.fhir.db.user.permanent.delete.username=fhir_server_permanent_delete_user dev.dsf.fhir.db.user.permanent.delete.password=TcqAgZWrhqUqZJDk2PVyEjuX8QXe63jq dev.dsf.fhir.server.base.url=https://localhost:8001/fhir -#dev.dsf.fhir.server.page.count=20 - -dev.dsf.fhir.server.user.thumbprints= -dev.dsf.fhir.server.user.thumbprints.permanent.delete= dev.dsf.fhir.server.organization.identifier.value=Test_Organization -#dev.dsf.fhir.server.init.bundle=conf/bundle.xml dev.dsf.fhir.client.trust.server.certificate.cas=target/testca_certificate.pem dev.dsf.fhir.client.certificate=target/test-client_certificate.pem dev.dsf.fhir.client.certificate.private.key=target/test-client_private-key.pem dev.dsf.fhir.client.certificate.private.key.password=password -#dev.dsf.fhir.client.timeout.read=10000 -#dev.dsf.fhir.client.timeout.connect=2000 - -#dev.dsf.fhir.proxy.url= -#dev.dsf.fhir.proxy.username= -#dev.dsf.fhir.proxy.password= -#dev.dsf.fhir.proxy.noProxy= dev.dsf.fhir.server.static.resource.cache=false dev.dsf.fhir.server.ui.theme=dev \ No newline at end of file diff --git a/pom.xml b/pom.xml index ff4b3e2b1..0a1f250c5 100755 --- a/pom.xml +++ b/pom.xml @@ -30,8 +30,9 @@ <jackson.version>2.18.2</jackson.version> <camunda.version>7.22.0</camunda.version> <hapi.fhir.version.v1>5.1.0</hapi.fhir.version.v1> - <hapi.fhir.version.v2>7.4.3</hapi.fhir.version.v2> - <hapi.fhir.version>7.4.3</hapi.fhir.version> + <hapi.fhir.version.v2>7.6.1</hapi.fhir.version.v2> + <hapi.fhir.org.hl7.version.v2>6.4.0</hapi.fhir.org.hl7.version.v2> + <hapi.fhir.version>7.6.1</hapi.fhir.version> <bouncycastle.version>1.80</bouncycastle.version> </properties> @@ -267,6 +268,16 @@ <artifactId>jackson-annotations</artifactId> <version>${jackson.version}</version> </dependency> + <dependency> + <groupId>com.fasterxml.jackson.datatype</groupId> + <artifactId>jackson-datatype-jsr310</artifactId> + <version>${jackson.version}</version> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.module</groupId> + <artifactId>jackson-module-jakarta-xmlbind-annotations</artifactId> + <version>${jackson.version}</version> + </dependency> <!-- tyrus --> <dependency> @@ -379,6 +390,11 @@ <artifactId>httpclient</artifactId> <version>4.5.14</version> </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore</artifactId> + <version>4.4.16</version> + </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId>