diff --git a/.github/workflows/maven-build.yml b/.github/workflows/maven-build.yml index 881ed900..ff6e78a4 100644 --- a/.github/workflows/maven-build.yml +++ b/.github/workflows/maven-build.yml @@ -12,10 +12,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up JDK 17 + - name: Set up JDK 25 uses: actions/setup-java@v1 with: - java-version: 17 + java-version: 25 - name: Build with Maven env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/maven-publish.yml b/.github/workflows/maven-publish.yml index 91d39400..96718608 100644 --- a/.github/workflows/maven-publish.yml +++ b/.github/workflows/maven-publish.yml @@ -21,10 +21,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up JDK 17 + - name: Set up JDK 25 uses: actions/setup-java@v1 with: - java-version: 17 + java-version: 25 - name: Publish with Maven env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/pom.xml b/pom.xml index 64a30eb0..8c1e18d0 100644 --- a/pom.xml +++ b/pom.xml @@ -9,18 +9,24 @@ jar + 2026-07-05T12:00:00+02:00 + UTF-8 - 17 - 17 + 25 + 25 - 1.9.0 - 6.2.12 + 2.1.0 + 7.0.8 ../dsf dsf-process-ping-pong DSF ping-pong process for connection tests between DSF instances https://github.com/datasharingframework/dsf-process-ping-pong + + Data Sharing Framework + dsf.dev + scm:git:git://github.com/datasharingframework/dsf-process-ping-pong.git @@ -39,7 +45,7 @@ dev.dsf - dsf-bpe-process-api-v1 + dsf-bpe-process-api-v2 ${dsf.version} provided @@ -47,37 +53,9 @@ org.springframework spring-web ${spring.version} - provided - - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - 2.20.0 - - - com.fasterxml.jackson.core - jackson-core - - - com.fasterxml.jackson.core - jackson-databind - - - com.fasterxml.jackson.core - jackson-annotations - - - - dev.dsf - dsf-bpe-process-api-v1 - ${dsf.version} - test - test-jar - dev.dsf dsf-fhir-validation @@ -93,6 +71,30 @@ + + + src/main/resources + false + + plugin.properties + + + + src/main/resources + true + + plugin.properties + + + + src/main/resources/doc + true + + *.md + + doc + + org.apache.maven.plugins @@ -108,6 +110,24 @@ maven-surefire-plugin 3.5.4 + + com.coderplus.maven.plugins + copy-rename-maven-plugin + 1.0.1 + + + copy-plugin-documentation + prepare-package + + rename + + + target/ConfigDoc_dev.dsf.bpe.spring.config.md + target/classes/doc/configuration.md + + + + org.apache.maven.plugins maven-jar-plugin @@ -128,7 +148,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.6.1 + 3.6.2 package @@ -136,15 +156,27 @@ shade - false - com.fasterxml.jackson.datatype:jackson-datatype-jsr310 - - ** - + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + META-INF/*.MF + META-INF/NOTICE + META-INF/versions/9/module-info.class + META-INF/notice.txt + META-INF/spring/aot.factories + + false + true + + + + @@ -188,28 +220,29 @@ net.revelc.code impsort-maven-plugin - 1.12.0 + 1.13.0 - 17 + 24 + true java.,javax.,org.,com. java,* dev.dsf - dsf-tools-documentation-generator + dsf-maven-plugin ${dsf.version} - generate + generate-config-doc - - dev.dsf.bpe - + + dev.dsf.bpe.spring.config + diff --git a/src/main/java/dev/dsf/bpe/CodeSystem.java b/src/main/java/dev/dsf/bpe/CodeSystem.java index 12b891ae..01870f13 100644 --- a/src/main/java/dev/dsf/bpe/CodeSystem.java +++ b/src/main/java/dev/dsf/bpe/CodeSystem.java @@ -57,10 +57,9 @@ private DsfPing() { } - public static Coding fromCode(Code code) + public static Coding fromCode(Code code, String resourceVersion) { - return new Coding().setSystem(URL).setCode(code.getValue()) - .setVersion(PingProcessPluginDefinition.RESOURCE_VERSION); + return new Coding().setSystem(URL).setCode(code.getValue()).setVersion(resourceVersion); } public enum Code implements SingleStringValueEnum @@ -104,10 +103,9 @@ private DsfPingStatus() { } - public static Coding fromCode(Code code) + public static Coding fromCode(Code code, String resourceVersion) { - return new Coding().setSystem(URL).setCode(code.getValue()) - .setVersion(PingProcessPluginDefinition.RESOURCE_VERSION); + return new Coding().setSystem(URL).setCode(code.getValue()).setVersion(resourceVersion); } public enum Code implements SingleStringValueEnum @@ -146,10 +144,9 @@ private DsfPingUnits() { } - public static Coding fromCode(Code code) + public static Coding fromCode(Code code, String resourceVersion) { - return new Coding().setSystem(URL).setCode(code.toUcum()) - .setVersion(PingProcessPluginDefinition.RESOURCE_VERSION); + return new Coding().setSystem(URL).setCode(code.toUcum()).setVersion(resourceVersion); } public enum Code @@ -359,10 +356,10 @@ private DsfPingError() { } - public static Coding fromConcept(Concept concept) + public static Coding fromConcept(Concept concept, String resourceVersion) { return new Coding().setSystem(URL).setCode(concept.getCode()).setDisplay(concept.getDisplay()) - .setVersion(PingProcessPluginDefinition.RESOURCE_VERSION); + .setVersion(resourceVersion); } public enum Concept diff --git a/src/main/java/dev/dsf/bpe/ConstantsPing.java b/src/main/java/dev/dsf/bpe/ConstantsPing.java index cca333b8..905e8b82 100644 --- a/src/main/java/dev/dsf/bpe/ConstantsPing.java +++ b/src/main/java/dev/dsf/bpe/ConstantsPing.java @@ -64,6 +64,10 @@ private ConstantsPing() public static final String PONG_TIMEOUT_DURATION_DEFAULT_VALUE = "PT30S"; public static final String BPMN_ERROR_CODE_UNEXPECTED_ERROR = "unexpected-error"; + public static final String BPMN_ERROR_MESSAGE_UNEXPECTED_ERROR = "An unexpected error has occurred"; + + public static final String BPMN_ERROR_CODE_TARGET_NOT_ALLOWED = "target_not_allowed"; + public static final String BPMN_ERROR_MESSAGE_TARGET_NOT_ALLOWED = "target_not_allowed"; public static final String POTENTIAL_FIX_URL_BASE = "https://dsf.dev/s"; public static final String POTENTIAL_FIX_URL_ERROR_HTTP = POTENTIAL_FIX_URL_BASE + "/error-http"; diff --git a/src/main/java/dev/dsf/bpe/ExecutionVariables.java b/src/main/java/dev/dsf/bpe/ExecutionVariables.java index a606a5f7..766ee71d 100644 --- a/src/main/java/dev/dsf/bpe/ExecutionVariables.java +++ b/src/main/java/dev/dsf/bpe/ExecutionVariables.java @@ -9,6 +9,7 @@ public enum ExecutionVariables downloadResource, downloadResourceReference, statusCode, + statusCodeString, error, errorLocal, errorRemote, diff --git a/src/main/java/dev/dsf/bpe/PingProcessPluginDefinition.java b/src/main/java/dev/dsf/bpe/PingProcessPluginDefinition.java index 517a0ffa..fdbe7073 100644 --- a/src/main/java/dev/dsf/bpe/PingProcessPluginDefinition.java +++ b/src/main/java/dev/dsf/bpe/PingProcessPluginDefinition.java @@ -1,44 +1,14 @@ package dev.dsf.bpe; -import java.time.LocalDate; import java.util.Arrays; import java.util.List; import java.util.Map; import dev.dsf.bpe.spring.config.PingConfig; -import dev.dsf.bpe.v1.ProcessPluginDefinition; +import dev.dsf.bpe.v2.AbstractProcessPluginDefinition; -public class PingProcessPluginDefinition implements ProcessPluginDefinition +public class PingProcessPluginDefinition extends AbstractProcessPluginDefinition { - public static final String RESOURCE_VERSION = "2.1"; - public static final String NON_RESOURCE_VERSION = "0.0"; - public static final String VERSION = RESOURCE_VERSION + "." + NON_RESOURCE_VERSION; - public static final LocalDate RELEASE_DATE = LocalDate.of(2025, 11, 25); - - @Override - public String getName() - { - return "dsf-process-ping-pong"; - } - - @Override - public String getVersion() - { - return VERSION; - } - - @Override - public String getResourceVersion() - { - return RESOURCE_VERSION; - } - - @Override - public LocalDate getReleaseDate() - { - return RELEASE_DATE; - } - @Override public List getProcessModels() { diff --git a/src/main/java/dev/dsf/bpe/ProcessError.java b/src/main/java/dev/dsf/bpe/ProcessError.java index 17a5a8c7..434b9974 100644 --- a/src/main/java/dev/dsf/bpe/ProcessError.java +++ b/src/main/java/dev/dsf/bpe/ProcessError.java @@ -12,10 +12,13 @@ import org.hl7.fhir.r4.model.Task; import org.hl7.fhir.r4.model.UrlType; +import com.fasterxml.jackson.annotation.JsonAutoDetect; + +@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) public record ProcessError(String process, CodeSystem.DsfPingError.Concept concept, String potentialFixUrl) implements Serializable { - public static Extension toExtension(ProcessError error) + public static Extension toExtension(ProcessError error, String resourceVersion) { Objects.requireNonNull(error); Objects.requireNonNull(error.concept()); @@ -25,7 +28,7 @@ public static Extension toExtension(ProcessError error) extension.setUrl(ConstantsPing.STRUCTURE_DEFINITION_URL_EXTENSION_ERROR); extension.addExtension().setUrl(ConstantsPing.EXTENSION_URL_ERROR) - .setValue(CodeSystem.DsfPingError.fromConcept(error.concept())); + .setValue(CodeSystem.DsfPingError.fromConcept(error.concept(), resourceVersion)); if (Objects.nonNull(error.potentialFixUrl)) { extension.addExtension().setUrl(ConstantsPing.EXTENSION_URL_POTENTIAL_FIX) @@ -50,19 +53,19 @@ public static ProcessError toError(Extension extension, String process) return new ProcessError(process, error, potentialFixUrl); } - public static List toTaskOutput(List errors) + public static List toTaskOutput(List errors, String resourceVersion) { if (errors == null || errors.isEmpty()) return List.of(); - return errors.stream().map(ProcessError::toTaskOutput).collect(Collectors.toList()); + return errors.stream().map(e -> toTaskOutput(e, resourceVersion)).collect(Collectors.toList()); } - public static Task.TaskOutputComponent toTaskOutput(ProcessError error) + public static Task.TaskOutputComponent toTaskOutput(ProcessError error, String resourceVersion) { Task.TaskOutputComponent param = new Task.TaskOutputComponent(); - param.getType().addCoding(CodeSystem.DsfPing.fromCode(CodeSystem.DsfPing.Code.ERROR)); - param.addExtension(ProcessError.toExtension(error)); + param.getType().addCoding(CodeSystem.DsfPing.fromCode(CodeSystem.DsfPing.Code.ERROR, resourceVersion)); + param.addExtension(ProcessError.toExtension(error, resourceVersion)); Extension dataAbsentReason = new Extension() .setUrl("http://hl7.org/fhir/StructureDefinition/data-absent-reason") .setValue(new CodeType("not-applicable")); diff --git a/src/main/java/dev/dsf/bpe/ProcessErrors.java b/src/main/java/dev/dsf/bpe/ProcessErrors.java index 5c2891d7..6bd0f6a4 100644 --- a/src/main/java/dev/dsf/bpe/ProcessErrors.java +++ b/src/main/java/dev/dsf/bpe/ProcessErrors.java @@ -1,8 +1,8 @@ package dev.dsf.bpe; -import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Objects; import java.util.Vector; import com.fasterxml.jackson.annotation.JsonCreator; @@ -21,7 +21,14 @@ public ProcessErrors() @JsonCreator public ProcessErrors(@JsonProperty("entries") Collection entries) { - this.entries = new ArrayList<>(entries); + if (Objects.nonNull(entries)) + { + this.entries = new Vector<>(entries); + } + else + { + this.entries = new Vector<>(); + } } @JsonProperty("entries") diff --git a/src/main/java/dev/dsf/bpe/listener/PingPongProcessPluginDeploymentStateListener.java b/src/main/java/dev/dsf/bpe/listener/PingPongProcessPluginDeploymentStateListener.java index fa22f28d..247959b1 100644 --- a/src/main/java/dev/dsf/bpe/listener/PingPongProcessPluginDeploymentStateListener.java +++ b/src/main/java/dev/dsf/bpe/listener/PingPongProcessPluginDeploymentStateListener.java @@ -1,7 +1,5 @@ package dev.dsf.bpe.listener; -import static dev.dsf.bpe.PingProcessPluginDefinition.RESOURCE_VERSION; - import java.util.List; import java.util.Map; import java.util.Objects; @@ -22,18 +20,19 @@ import org.springframework.beans.factory.InitializingBean; import dev.dsf.bpe.ConstantsPing; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.ProcessPluginDeploymentStateListener; -import dev.dsf.fhir.client.FhirWebserviceClient; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.ProcessPluginDeploymentListener; +import dev.dsf.bpe.v2.client.dsf.DsfClient; -public class PingPongProcessPluginDeploymentStateListener - implements ProcessPluginDeploymentStateListener, InitializingBean +public class PingPongProcessPluginDeploymentStateListener implements ProcessPluginDeploymentListener, InitializingBean { private final ProcessPluginApi api; + private final String resourceVersion; public PingPongProcessPluginDeploymentStateListener(ProcessPluginApi api) { this.api = api; + this.resourceVersion = api.getProcessPluginDefinition().getResourceVersion(); } @Override @@ -65,10 +64,10 @@ public void onProcessesDeployed(List activeProcesses) private void updateDraftTaskResources() { - FhirWebserviceClient client = api.getFhirWebserviceClientProvider().getLocalWebserviceClient(); + DsfClient client = api.getDsfClientProvider().getLocal(); - String pingProcessPrefix = "http://dsf.dev/bpe/Process/ping/" + RESOURCE_VERSION; - String pingAutostartProcessPrefix = "http://dsf.dev/bpe/Process/pingAutostart/" + RESOURCE_VERSION; + String pingProcessPrefix = "http://dsf.dev/bpe/Process/ping/" + resourceVersion; + String pingAutostartProcessPrefix = "http://dsf.dev/bpe/Process/pingAutostart/" + resourceVersion; List draftTaskResourceIdentifiers = List.of(pingProcessPrefix + "/task-start-ping", pingAutostartProcessPrefix + "/task-start-ping-autostart"); @@ -91,7 +90,7 @@ private void adaptDraftTask(Task task) Coding downloadResourceSizeBytesCoding = new Coding(); downloadResourceSizeBytesCoding.setSystem(dev.dsf.bpe.CodeSystem.DsfPing.URL) .setCode(dev.dsf.bpe.CodeSystem.DsfPing.Code.DOWNLOAD_RESOURCE_SIZE_BYTES.getValue()) - .setVersion(RESOURCE_VERSION); + .setVersion(resourceVersion); Optional optInput = api.getTaskHelper().getFirstInputParameter(task, downloadResourceSizeBytesCoding, DecimalType.class); @@ -106,7 +105,7 @@ private void adaptDraftTask(Task task) Coding pongTimeoutDurationCoding = new Coding(); pongTimeoutDurationCoding.setSystem(dev.dsf.bpe.CodeSystem.DsfPing.URL) .setCode(dev.dsf.bpe.CodeSystem.DsfPing.Code.PONG_TIMEOUT_DURATION_ISO_8601.getValue()) - .setVersion(RESOURCE_VERSION); + .setVersion(resourceVersion); optInput = api.getTaskHelper().getFirstInputParameter(task, pongTimeoutDurationCoding, StringType.class); if (optInput.isEmpty()) @@ -134,13 +133,12 @@ private void updateOlderResourcesIfCurrentIsNewestR private Bundle search(Class type, String url) { - return api.getFhirWebserviceClientProvider().getLocalWebserviceClient().search(type, - Map.of("url", List.of(url))); + return api.getDsfClientProvider().getLocal().search(type, Map.of("url", List.of(url))); } private Bundle searchTask(String identifier) { - return api.getFhirWebserviceClientProvider().getLocalWebserviceClient().search(Task.class, + return api.getDsfClientProvider().getLocal().search(Task.class, Map.of("identifier", List.of(identifier), "status", List.of("draft"))); } @@ -170,7 +168,7 @@ else if (version1.major < version2.major) private boolean currentIsNewestResource(List resources) { - return !resources.isEmpty() && RESOURCE_VERSION.equals(resources.get(resources.size() - 1).getVersion()); + return !resources.isEmpty() && resourceVersion.equals(resources.get(resources.size() - 1).getVersion()); } private MinorMajorVersion getMajorMinorVersion(String version) @@ -230,7 +228,7 @@ private void overrideDifferentialForOlderExtensionStructureDefinitions( private void updateResources(List resources) { - resources.forEach(m -> api.getFhirWebserviceClientProvider().getLocalWebserviceClient().update(m)); + resources.forEach(m -> api.getDsfClientProvider().getLocal().update(m)); } private record MinorMajorVersion(int major, int minor) diff --git a/src/main/java/dev/dsf/bpe/listener/PingStatusGatewayListener.java b/src/main/java/dev/dsf/bpe/listener/PingStatusGatewayListener.java new file mode 100644 index 00000000..923ac20f --- /dev/null +++ b/src/main/java/dev/dsf/bpe/listener/PingStatusGatewayListener.java @@ -0,0 +1,27 @@ +package dev.dsf.bpe.listener; + +import java.util.Objects; + +import dev.dsf.bpe.CodeSystem; +import dev.dsf.bpe.ExecutionVariables; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ExecutionListener; +import dev.dsf.bpe.v2.variables.Variables; + +public class PingStatusGatewayListener implements ExecutionListener +{ + @Override + public void notify(ProcessPluginApi api, Variables variables) throws Exception + { + setPingStatusAsString(variables); + } + + private void setPingStatusAsString(Variables variables) + { + CodeSystem.DsfPingStatus.Code statusCode = variables.getVariableLocal(ExecutionVariables.statusCode.name()); + if (Objects.nonNull(statusCode)) + { + variables.setStringLocal(ExecutionVariables.statusCodeString.name(), statusCode.getValue()); + } + } +} diff --git a/src/main/java/dev/dsf/bpe/listener/PongStatusGatewayListener.java b/src/main/java/dev/dsf/bpe/listener/PongStatusGatewayListener.java new file mode 100644 index 00000000..d852feca --- /dev/null +++ b/src/main/java/dev/dsf/bpe/listener/PongStatusGatewayListener.java @@ -0,0 +1,27 @@ +package dev.dsf.bpe.listener; + +import java.util.Objects; + +import dev.dsf.bpe.CodeSystem; +import dev.dsf.bpe.ExecutionVariables; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ExecutionListener; +import dev.dsf.bpe.v2.variables.Variables; + +public class PongStatusGatewayListener implements ExecutionListener +{ + @Override + public void notify(ProcessPluginApi api, Variables variables) throws Exception + { + setPongStatusAsString(variables); + } + + private void setPongStatusAsString(Variables variables) + { + CodeSystem.DsfPingStatus.Code statusCode = variables.getVariableLocal(ExecutionVariables.statusCode.name()); + if (Objects.nonNull(statusCode)) + { + variables.setStringLocal(ExecutionVariables.statusCodeString.name(), statusCode.getValue()); + } + } +} diff --git a/src/main/java/dev/dsf/bpe/listener/SetCorrelationKeyListener.java b/src/main/java/dev/dsf/bpe/listener/SetCorrelationKeyListener.java index 3672cb3d..4bff3d4b 100644 --- a/src/main/java/dev/dsf/bpe/listener/SetCorrelationKeyListener.java +++ b/src/main/java/dev/dsf/bpe/listener/SetCorrelationKeyListener.java @@ -1,41 +1,24 @@ package dev.dsf.bpe.listener; -import java.util.Objects; - -import org.camunda.bpm.engine.delegate.DelegateExecution; -import org.camunda.bpm.engine.delegate.ExecutionListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.InitializingBean; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.constants.BpmnExecutionVariables; -import dev.dsf.bpe.v1.variables.Target; -import dev.dsf.bpe.v1.variables.Variables; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ExecutionListener; +import dev.dsf.bpe.v2.constants.BpmnExecutionVariables; +import dev.dsf.bpe.v2.variables.Target; +import dev.dsf.bpe.v2.variables.Variables; -public class SetCorrelationKeyListener implements ExecutionListener, InitializingBean +public class SetCorrelationKeyListener implements ExecutionListener { private static final Logger logger = LoggerFactory.getLogger(SetCorrelationKeyListener.class); - private final ProcessPluginApi api; - - public SetCorrelationKeyListener(ProcessPluginApi api) - { - this.api = api; - } - - @Override - public void afterPropertiesSet() throws Exception - { - Objects.requireNonNull(api, "api"); - } @Override - public void notify(DelegateExecution execution) throws Exception + public void notify(ProcessPluginApi processPluginApi, Variables variables) throws Exception { - logger.debug("Setting correlation key for subprocess instance {}", execution.getProcessInstanceId()); - Variables variables = api.getVariables(execution); + logger.debug("Setting correlation key for subprocess instance {}", variables.getActivityInstanceId()); Target target = variables.getTarget(); - execution.setVariableLocal(BpmnExecutionVariables.CORRELATION_KEY, target.getCorrelationKey()); + variables.setStringLocal(BpmnExecutionVariables.CORRELATION_KEY, target.getCorrelationKey()); } } diff --git a/src/main/java/dev/dsf/bpe/mail/AggregateErrorMailService.java b/src/main/java/dev/dsf/bpe/mail/AggregateErrorMailService.java index 57d380cf..b47bb942 100644 --- a/src/main/java/dev/dsf/bpe/mail/AggregateErrorMailService.java +++ b/src/main/java/dev/dsf/bpe/mail/AggregateErrorMailService.java @@ -10,8 +10,8 @@ import org.springframework.beans.factory.InitializingBean; import dev.dsf.bpe.ProcessError; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Target; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.variables.Target; public class AggregateErrorMailService implements InitializingBean { diff --git a/src/main/java/dev/dsf/bpe/message/CleanupPongMessage.java b/src/main/java/dev/dsf/bpe/message/CleanupPongMessage.java index eb148c12..57bcffac 100644 --- a/src/main/java/dev/dsf/bpe/message/CleanupPongMessage.java +++ b/src/main/java/dev/dsf/bpe/message/CleanupPongMessage.java @@ -1,9 +1,9 @@ package dev.dsf.bpe.message; import java.time.Duration; -import java.util.stream.Stream; +import java.util.ArrayList; +import java.util.List; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.hl7.fhir.r4.model.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,89 +14,110 @@ import dev.dsf.bpe.util.task.SendTaskErrorConverter; import dev.dsf.bpe.util.task.input.generator.DownloadedBytesGenerator; import dev.dsf.bpe.util.task.input.generator.DownloadedDurationGenerator; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.activity.AbstractTaskMessageSend; -import dev.dsf.bpe.v1.variables.Target; -import dev.dsf.bpe.v1.variables.Variables; -import dev.dsf.bpe.variables.process_error.ProcessErrorValueImpl; - -public class CleanupPongMessage extends AbstractTaskMessageSend +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.MessageSendTask; +import dev.dsf.bpe.v2.activity.task.DefaultTaskSender; +import dev.dsf.bpe.v2.activity.task.TaskSender; +import dev.dsf.bpe.v2.activity.values.SendTaskValues; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.error.MessageSendTaskErrorHandler; +import dev.dsf.bpe.v2.variables.Target; +import dev.dsf.bpe.v2.variables.Variables; + +public class CleanupPongMessage implements MessageSendTask { private static final Logger logger = LoggerFactory.getLogger(CleanupPongMessage.class); - public CleanupPongMessage(ProcessPluginApi api) - { - super(api); - } - @Override - protected Stream getAdditionalInputParameters(DelegateExecution execution, - Variables variables) + public List getAdditionalInputParameters(ProcessPluginApi api, Variables variables, + SendTaskValues sendTaskValues, Target target) { - Target target = variables.getTarget(); String correlationKey = target.getCorrelationKey(); Long downloadedBytes = variables.getLong(ExecutionVariables.downloadedBytes.correlatedValue(correlationKey)); - Duration downloadedDuration = (Duration) variables + Duration downloadedDuration = variables .getVariable(ExecutionVariables.downloadedDuration.correlatedValue(correlationKey)); - Stream downloadedBytesParameter = downloadedBytes != null - ? Stream.of(DownloadedBytesGenerator.create(downloadedBytes)) - : Stream.empty(); - Stream downloadedDurationParameter = downloadedDuration != null - ? Stream.of(DownloadedDurationGenerator.create(downloadedDuration)) - : Stream.empty(); + List additionalInputParameters = new ArrayList<>(); - return Stream.of(downloadedBytesParameter, downloadedDurationParameter).flatMap(s -> s); - } + String resourceVersion = api.getProcessPluginDefinition().getResourceVersion(); - @Override - protected void handleSendTaskError(DelegateExecution execution, Variables variables, Exception exception, - String errorMessage) - { - Target target = variables.getTarget(); - SendTaskErrorConverter.ProcessErrorWithStatusCode errorAndStatus = SendTaskErrorConverter - .convertLocal(exception, false, ConstantsPing.PROCESS_NAME_PING); + if (downloadedBytes != null) + additionalInputParameters.add(DownloadedBytesGenerator.create(downloadedBytes, resourceVersion)); - execution.setVariableLocal(ExecutionVariables.error.name(), new ProcessErrorValueImpl(errorAndStatus.error())); - execution.setVariableLocal(ExecutionVariables.statusCode.name(), CodeSystem.DsfPing.Code.ERROR.getValue()); + if (downloadedDuration != null) + additionalInputParameters.add(DownloadedDurationGenerator.create(downloadedDuration, resourceVersion)); - logger.info("Request to {} resulted in error: {}", target.getEndpointUrl(), - errorAndStatus.error().concept().getDisplay()); + return additionalInputParameters; } @Override - protected void sendTask(DelegateExecution execution, Variables variables, Target target, - String instantiatesCanonical, String messageName, String businessKey, String profile, - Stream additionalInputParameters) + public MessageSendTaskErrorHandler getErrorHandler() { - Target newTarget = new Target() + return new MessageSendTaskErrorHandler() { @Override - public String getOrganizationIdentifierValue() + public ErrorBoundaryEvent handleErrorBoundaryEvent(ProcessPluginApi processPluginApi, Variables variables, + ErrorBoundaryEvent errorBoundaryEvent) { - return target.getOrganizationIdentifierValue(); + return errorBoundaryEvent; } @Override - public String getEndpointIdentifierValue() + public Exception handleException(ProcessPluginApi processPluginApi, Variables variables, + SendTaskValues sendTaskValues, Exception e) { - return target.getEndpointIdentifierValue(); - } + Target target = variables.getTarget(); + SendTaskErrorConverter.ProcessErrorWithStatusCode errorAndStatus = SendTaskErrorConverter + .convertLocal(e, false, ConstantsPing.PROCESS_NAME_PING); - @Override - public String getEndpointUrl() - { - return target.getEndpointUrl(); + variables.setJsonVariableLocal(ExecutionVariables.error.name(), errorAndStatus.error()); + variables.setStringLocal(ExecutionVariables.statusCode.name(), + CodeSystem.DsfPing.Code.ERROR.getValue()); + + logger.info("Request to {} resulted in error: {}", target.getEndpointUrl(), + errorAndStatus.error().concept().getDisplay()); + + return null; } + }; + } + @Override + public TaskSender getTaskSender(ProcessPluginApi api, Variables variables, SendTaskValues sendTaskValues) + { + return new DefaultTaskSender(api, variables, sendTaskValues, this.getBusinessKeyStrategy()) + { @Override - public String getCorrelationKey() + protected Target getTarget() { - return null; + Target oldTarget = super.getTarget(); + return new Target() + { + @Override + public String getOrganizationIdentifierValue() + { + return oldTarget.getOrganizationIdentifierValue(); + } + + @Override + public String getEndpointIdentifierValue() + { + return oldTarget.getEndpointIdentifierValue(); + } + + @Override + public String getEndpointUrl() + { + return oldTarget.getEndpointUrl(); + } + + @Override + public String getCorrelationKey() + { + return null; + } + }; } }; - - super.sendTask(execution, variables, newTarget, instantiatesCanonical, messageName, businessKey, profile, - additionalInputParameters); } } diff --git a/src/main/java/dev/dsf/bpe/message/SendPingMessage.java b/src/main/java/dev/dsf/bpe/message/SendPingMessage.java index df30bce4..268543b4 100644 --- a/src/main/java/dev/dsf/bpe/message/SendPingMessage.java +++ b/src/main/java/dev/dsf/bpe/message/SendPingMessage.java @@ -1,106 +1,114 @@ package dev.dsf.bpe.message; -import java.util.stream.Stream; +import java.util.ArrayList; +import java.util.List; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.hl7.fhir.r4.model.IdType; import org.hl7.fhir.r4.model.Identifier; import org.hl7.fhir.r4.model.Reference; import org.hl7.fhir.r4.model.ResourceType; import org.hl7.fhir.r4.model.Task; -import org.hl7.fhir.r4.model.Task.ParameterComponent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import dev.dsf.bpe.CodeSystem; import dev.dsf.bpe.ConstantsPing; import dev.dsf.bpe.ExecutionVariables; -import dev.dsf.bpe.PingProcessPluginDefinition; import dev.dsf.bpe.util.task.SendTaskErrorConverter; import dev.dsf.bpe.util.task.input.generator.DownloadResourceReferenceGenerator; import dev.dsf.bpe.util.task.input.generator.DownloadResourceSizeGenerator; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.activity.AbstractTaskMessageSend; -import dev.dsf.bpe.v1.variables.Target; -import dev.dsf.bpe.v1.variables.Variables; -import dev.dsf.bpe.variables.codesystem.dsfpingstatus.CodeValueImpl; -import dev.dsf.bpe.variables.process_error.ProcessErrorValueImpl; -import dev.dsf.fhir.client.FhirWebserviceClient; - -public class SendPingMessage extends AbstractTaskMessageSend +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.MessageSendTask; +import dev.dsf.bpe.v2.activity.task.DefaultTaskSender; +import dev.dsf.bpe.v2.activity.task.TaskSender; +import dev.dsf.bpe.v2.activity.values.SendTaskValues; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.error.MessageSendTaskErrorHandler; +import dev.dsf.bpe.v2.variables.Target; +import dev.dsf.bpe.v2.variables.Variables; + +public class SendPingMessage implements MessageSendTask { private static final Logger logger = LoggerFactory.getLogger(SendPingMessage.class); - private IdType taskId; - - public SendPingMessage(ProcessPluginApi api) - { - super(api); - } @Override - protected Stream getAdditionalInputParameters(DelegateExecution execution, Variables variables) + public List getAdditionalInputParameters(ProcessPluginApi api, Variables variables, + SendTaskValues sendTaskValues, Target target) { String downloadResourceReference = variables.getString(ExecutionVariables.downloadResourceReference.name()); long downloadResourceSizeBytes = variables.getLong(ExecutionVariables.downloadResourceSizeBytes.name()); - Stream downloadResourceReferenceStream = downloadResourceReference == null ? Stream.empty() - : Stream.of(DownloadResourceReferenceGenerator.create(downloadResourceReference)); - Stream downloadResourceSizeBytesStream = Stream - .of(DownloadResourceSizeGenerator.create(downloadResourceSizeBytes)); - ParameterComponent endpointIdentifierComponent = api.getTaskHelper().createInput( - new Reference().setIdentifier(getLocalEndpointIdentifier()).setType(ResourceType.Endpoint.name()), - CodeSystem.DsfPing.URL, CodeSystem.DsfPing.Code.ENDPOINT_IDENTIFIER.getValue()); - endpointIdentifierComponent.getType().getCodingFirstRep() - .setVersion(PingProcessPluginDefinition.RESOURCE_VERSION); - Stream endpointIdentifierStream = Stream.of(endpointIdentifierComponent); - - return Stream.concat(endpointIdentifierStream, - Stream.concat(downloadResourceReferenceStream, downloadResourceSizeBytesStream)); + List additionalInputParameters = new ArrayList<>(); + + String resourceVersion = api.getProcessPluginDefinition().getResourceVersion(); + + if (downloadResourceReference != null) + additionalInputParameters + .add(DownloadResourceReferenceGenerator.create(downloadResourceReference, resourceVersion)); + + additionalInputParameters.add(DownloadResourceSizeGenerator.create(downloadResourceSizeBytes, resourceVersion)); + + Task.ParameterComponent endpointIdentifierComponent = api.getTaskHelper().createInput( + new Reference().setIdentifier(getLocalEndpointIdentifier(api)).setType(ResourceType.Endpoint.name()), + CodeSystem.DsfPing.URL, CodeSystem.DsfPing.Code.ENDPOINT_IDENTIFIER.getValue(), resourceVersion); + endpointIdentifierComponent.getType().getCodingFirstRep().setVersion(resourceVersion); + + additionalInputParameters.add(endpointIdentifierComponent); + + return additionalInputParameters; } @Override - protected void sendTask(DelegateExecution execution, Variables variables, Target target, - String instantiatesCanonical, String messageName, String businessKey, String profile, - Stream additionalInputParameters) + public TaskSender getTaskSender(ProcessPluginApi api, Variables variables, SendTaskValues sendTaskValues) { - super.sendTask(execution, variables, target, instantiatesCanonical, messageName, businessKey, profile, - additionalInputParameters); - if (taskId != null) + return new DefaultTaskSender(api, variables, sendTaskValues, getBusinessKeyStrategy(), + target -> getAdditionalInputParameters(api, variables, sendTaskValues, target)) { - execution.setVariableLocal(ExecutionVariables.pingTaskId.name(), taskId.getIdPart()); - } + @Override + protected IdType doSend(Task task, String targetEndpointUrl) + { + IdType taskId = super.doSend(task, targetEndpointUrl); + if (taskId != null) + { + variables.setStringLocal(ExecutionVariables.pingTaskId.name(), taskId.getIdPart()); + } + return taskId; + } + }; } @Override - protected IdType doSend(FhirWebserviceClient client, Task task) + public MessageSendTaskErrorHandler getErrorHandler() { - taskId = super.doSend(client, task); - return taskId; - } + return new MessageSendTaskErrorHandler() + { + @Override + public ErrorBoundaryEvent handleErrorBoundaryEvent(ProcessPluginApi processPluginApi, Variables variables, + ErrorBoundaryEvent errorBoundaryEvent) + { + return errorBoundaryEvent; + } - @Override - protected void handleSendTaskError(DelegateExecution execution, Variables variables, Exception exception, - String errorMessage) - { - Target target = variables.getTarget(); - SendTaskErrorConverter.ProcessErrorWithStatusCode errorAndStatus = SendTaskErrorConverter - .convertLocal(exception, true, ConstantsPing.PROCESS_NAME_PING); + @Override + public Exception handleException(ProcessPluginApi processPluginApi, Variables variables, + SendTaskValues sendTaskValues, Exception e) + { + Target target = variables.getTarget(); + SendTaskErrorConverter.ProcessErrorWithStatusCode errorAndStatus = SendTaskErrorConverter + .convertLocal(e, true, ConstantsPing.PROCESS_NAME_PING); - execution.setVariableLocal(ExecutionVariables.error.name(), new ProcessErrorValueImpl(errorAndStatus.error())); - execution.setVariableLocal(ExecutionVariables.statusCode.name(), - new CodeValueImpl(errorAndStatus.statusCode())); + variables.setJsonVariableLocal(ExecutionVariables.error.name(), errorAndStatus.error()); + variables.setJsonVariableLocal(ExecutionVariables.statusCode.name(), errorAndStatus.statusCode()); - logger.info("Request to {} resulted in error: {}", target.getEndpointUrl(), - errorAndStatus.error().concept().getDisplay()); - } + logger.info("Request to {} resulted in error: {}", target.getEndpointUrl(), + errorAndStatus.error().concept().getDisplay()); - @Override - protected void addErrorMessage(Task task, String errorMessage) - { - // error message part of status extension + return null; + } + }; } - private Identifier getLocalEndpointIdentifier() + private Identifier getLocalEndpointIdentifier(ProcessPluginApi api) { return api.getEndpointProvider().getLocalEndpointIdentifier() .orElseThrow(() -> new IllegalStateException("Local endpoint identifier unknown")); diff --git a/src/main/java/dev/dsf/bpe/message/SendPongMessage.java b/src/main/java/dev/dsf/bpe/message/SendPongMessage.java index 7aed532e..11ca21e9 100644 --- a/src/main/java/dev/dsf/bpe/message/SendPongMessage.java +++ b/src/main/java/dev/dsf/bpe/message/SendPongMessage.java @@ -1,9 +1,9 @@ package dev.dsf.bpe.message; import java.time.Duration; -import java.util.stream.Stream; +import java.util.ArrayList; +import java.util.List; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.hl7.fhir.r4.model.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,82 +19,103 @@ import dev.dsf.bpe.util.task.input.generator.DownloadedDurationGenerator; import dev.dsf.bpe.util.task.input.generator.ErrorInputComponentGenerator; import dev.dsf.bpe.util.task.output.generator.PingStatusGenerator; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.activity.AbstractTaskMessageSend; -import dev.dsf.bpe.v1.variables.Target; -import dev.dsf.bpe.v1.variables.Variables; -import dev.dsf.bpe.variables.codesystem.dsfpingstatus.CodeValueImpl; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.MessageSendTask; +import dev.dsf.bpe.v2.activity.values.SendTaskValues; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.error.MessageSendTaskErrorHandler; +import dev.dsf.bpe.v2.variables.Target; +import dev.dsf.bpe.v2.variables.Variables; -public class SendPongMessage extends AbstractTaskMessageSend +public class SendPongMessage implements MessageSendTask { private static final Logger logger = LoggerFactory.getLogger(SendPongMessage.class); + private final PingStatusGenerator pingStatusGenerator; - public SendPongMessage(ProcessPluginApi api) + public SendPongMessage(PingStatusGenerator pingStatusGenerator) { - super(api); + this.pingStatusGenerator = pingStatusGenerator; } @Override - protected Stream getAdditionalInputParameters(DelegateExecution execution, - Variables variables) + public List getAdditionalInputParameters(ProcessPluginApi api, Variables variables, + SendTaskValues sendTaskValues, Target target) { - ProcessErrors errorListRemote = ErrorListUtils.getErrorListRemote(execution); + ProcessErrors errorListRemote = ErrorListUtils.getErrorListRemote(variables); long downloadResourceSizeBytes = variables.getLong(ExecutionVariables.downloadResourceSizeBytes.name()); + String resourceVersion = api.getProcessPluginDefinition().getResourceVersion(); if (downloadResourceSizeBytes >= 0) { Long downloadedBytes = variables.getLong(ExecutionVariables.downloadedBytes.name()); - Duration downloadedDuration = (Duration) variables - .getVariable(ExecutionVariables.downloadedDuration.name()); + Duration downloadedDuration = variables.getVariable(ExecutionVariables.downloadedDuration.name()); String downloadResourceReference = variables.getString(ExecutionVariables.downloadResourceReference.name()); - Stream downloadedBytesParameter = downloadedBytes != null - ? Stream.of(DownloadedBytesGenerator.create(downloadedBytes)) - : Stream.empty(); - Stream downloadedDurationParameter = downloadedDuration != null - ? Stream.of(DownloadedDurationGenerator.create(downloadedDuration)) - : Stream.empty(); - Stream downloadedResourceReferenceParameter = downloadResourceReference != null - ? Stream.of(DownloadResourceReferenceGenerator.create(downloadResourceReference)) - : Stream.empty(); - - return Stream - .of(downloadedBytesParameter, downloadedDurationParameter, downloadedResourceReferenceParameter, - ErrorInputComponentGenerator.create(errorListRemote.getEntries()).stream()) - .flatMap(stream -> stream); + ArrayList additionalInputParameters = new ArrayList<>(); + + if (downloadedBytes != null) + additionalInputParameters.add(DownloadedBytesGenerator.create(downloadedBytes, resourceVersion)); + + if (downloadedDuration != null) + additionalInputParameters.add(DownloadedDurationGenerator.create(downloadedDuration, resourceVersion)); + + if (downloadResourceReference != null) + additionalInputParameters + .add(DownloadResourceReferenceGenerator.create(downloadResourceReference, resourceVersion)); + + additionalInputParameters + .addAll(ErrorInputComponentGenerator.create(errorListRemote.getEntries(), resourceVersion)); + + return additionalInputParameters; } else { - return ErrorInputComponentGenerator.create(errorListRemote.getEntries()).stream(); + return ErrorInputComponentGenerator.create(errorListRemote.getEntries(), resourceVersion); } } @Override - protected void doExecute(DelegateExecution execution, Variables variables) throws Exception + public void execute(ProcessPluginApi api, Variables variables, SendTaskValues sendTaskValues) + throws ErrorBoundaryEvent, Exception { Target target = variables.getTarget(); Task mainTask = variables.getStartTask(); - variables.setVariable(ExecutionVariables.statusCode.name(), - new CodeValueImpl(CodeSystem.DsfPingStatus.Code.PONG_SENT)); - PingStatusGenerator.updatePongStatusOutput(mainTask, target); + variables.setJsonVariable(ExecutionVariables.statusCode.name(), CodeSystem.DsfPingStatus.Code.PONG_SENT); + pingStatusGenerator.updatePongStatusOutput(mainTask, target); variables.updateTask(mainTask); - super.doExecute(execution, variables); + MessageSendTask.super.execute(api, variables, sendTaskValues); } @Override - protected void handleSendTaskError(DelegateExecution execution, Variables variables, Exception exception, - String errorMessage) + public MessageSendTaskErrorHandler getErrorHandler() { - Target target = variables.getTarget(); - Task startTask = variables.getStartTask(); + return new MessageSendTaskErrorHandler() + { + @Override + public ErrorBoundaryEvent handleErrorBoundaryEvent(ProcessPluginApi processPluginApi, Variables variables, + ErrorBoundaryEvent errorBoundaryEvent) + { + return errorBoundaryEvent; + } + + @Override + public Exception handleException(ProcessPluginApi processPluginApi, Variables variables, + SendTaskValues sendTaskValues, Exception e) + { + Target target = variables.getTarget(); + Task startTask = variables.getStartTask(); + + SendTaskErrorConverter.ProcessErrorWithStatusCode errorAndStatus = SendTaskErrorConverter + .convertLocal(e, true, ConstantsPing.PROCESS_NAME_PONG); - SendTaskErrorConverter.ProcessErrorWithStatusCode errorAndStatus = SendTaskErrorConverter - .convertLocal(exception, true, ConstantsPing.PROCESS_NAME_PONG); + ErrorListUtils.add(errorAndStatus.error(), variables); + variables.setJsonVariable(ExecutionVariables.statusCode.name(), errorAndStatus.statusCode()); + variables.updateTask(startTask); - ErrorListUtils.add(errorAndStatus.error(), execution); - variables.setVariable(ExecutionVariables.statusCode.name(), new CodeValueImpl(errorAndStatus.statusCode())); - variables.updateTask(startTask); + logger.info("Request to {} resulted in error: {}", target.getEndpointUrl(), + errorAndStatus.error().concept().getDisplay()); - logger.info("Request to {} resulted in error: {}", target.getEndpointUrl(), - errorAndStatus.error().concept().getDisplay()); + return null; + } + }; } } diff --git a/src/main/java/dev/dsf/bpe/message/SendStartPing.java b/src/main/java/dev/dsf/bpe/message/SendStartPing.java index 9640c1cc..4fa4f68c 100644 --- a/src/main/java/dev/dsf/bpe/message/SendStartPing.java +++ b/src/main/java/dev/dsf/bpe/message/SendStartPing.java @@ -1,34 +1,38 @@ package dev.dsf.bpe.message; -import java.util.UUID; -import java.util.stream.Stream; +import java.util.ArrayList; +import java.util.List; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.hl7.fhir.r4.model.Task; import org.hl7.fhir.r4.model.Task.ParameterComponent; import dev.dsf.bpe.CodeSystem; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.activity.AbstractTaskMessageSend; -import dev.dsf.bpe.v1.variables.Target; -import dev.dsf.bpe.v1.variables.Variables; - -public class SendStartPing extends AbstractTaskMessageSend +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.MessageIntermediateThrowEvent; +import dev.dsf.bpe.v2.activity.task.BusinessKeyStrategies; +import dev.dsf.bpe.v2.activity.task.BusinessKeyStrategy; +import dev.dsf.bpe.v2.activity.values.SendTaskValues; +import dev.dsf.bpe.v2.variables.Target; +import dev.dsf.bpe.v2.variables.Variables; + +public class SendStartPing implements MessageIntermediateThrowEvent { - public SendStartPing(ProcessPluginApi api) - { - super(api); - } - @Override - protected Stream getAdditionalInputParameters(DelegateExecution execution, Variables variables) + public List getAdditionalInputParameters(ProcessPluginApi api, Variables variables, + SendTaskValues sendTaskValues, Target target) { - return Stream.concat( - variables.getStartTask().getInput().stream().filter(Task.ParameterComponent::hasType) - .filter(i -> i.getType().getCoding().stream() - .anyMatch(c -> CodeSystem.DsfPing.URL.equals(c.getSystem()) - && CodeSystem.DsfPing.Code.TARGET_ENDPOINTS.getValue().equals(c.getCode()))), - variables.getStartTask().getInput().stream().filter(this::isDownloadResourceSizeParameter)); + List additionalInputParameters = new ArrayList<>(); + + variables.getStartTask().getInput().stream().filter(Task.ParameterComponent::hasType) + .filter(i -> i.getType().getCoding().stream() + .anyMatch(c -> CodeSystem.DsfPing.URL.equals(c.getSystem()) + && CodeSystem.DsfPing.Code.TARGET_ENDPOINTS.getValue().equals(c.getCode()))) + .forEach(additionalInputParameters::add); + + variables.getStartTask().getInput().stream().filter(this::isDownloadResourceSizeParameter) + .forEach(additionalInputParameters::add); + + return additionalInputParameters; } private boolean isDownloadResourceSizeParameter(ParameterComponent parameterComponent) @@ -39,14 +43,8 @@ private boolean isDownloadResourceSizeParameter(ParameterComponent parameterComp } @Override - protected void sendTask(DelegateExecution execution, Variables variables, Target target, - String instantiatesCanonical, String messageName, String businessKey, String profile, - Stream additionalInputParameters) + public BusinessKeyStrategy getBusinessKeyStrategy() { - // different business-key for every start-ping execution - businessKey = UUID.randomUUID().toString(); - - super.sendTask(execution, variables, target, instantiatesCanonical, messageName, businessKey, profile, - additionalInputParameters); + return BusinessKeyStrategies.NEW; } } diff --git a/src/main/java/dev/dsf/bpe/service/AbstractService.java b/src/main/java/dev/dsf/bpe/service/AbstractService.java deleted file mode 100644 index 1afeb6d3..00000000 --- a/src/main/java/dev/dsf/bpe/service/AbstractService.java +++ /dev/null @@ -1,42 +0,0 @@ -package dev.dsf.bpe.service; - -import org.camunda.bpm.engine.delegate.DelegateExecution; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.activity.AbstractServiceDelegate; -import dev.dsf.bpe.v1.variables.Variables; - -public abstract class AbstractService extends AbstractServiceDelegate -{ - private static final Logger logger = LoggerFactory.getLogger(AbstractService.class); - - public AbstractService(ProcessPluginApi api) - { - super(api); - } - - @Override - protected void doExecute(DelegateExecution execution, Variables variables) throws Exception - { - try - { - doExecuteWithErrorHandling(execution, variables); - } - catch (Exception e) - { - handleException(execution, variables, e); - } - } - - abstract protected void doExecuteWithErrorHandling(DelegateExecution execution, Variables variables) - throws Exception; - - protected void handleException(DelegateExecution execution, Variables variables, Exception exception) - throws Exception - { - logger.error("Unexpected error while executing service", exception); - throw exception; - } -} diff --git a/src/main/java/dev/dsf/bpe/service/Cleanup.java b/src/main/java/dev/dsf/bpe/service/Cleanup.java index 424b7eb7..70c93e8c 100644 --- a/src/main/java/dev/dsf/bpe/service/Cleanup.java +++ b/src/main/java/dev/dsf/bpe/service/Cleanup.java @@ -5,51 +5,41 @@ import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.HttpHostConnectException; -import org.camunda.bpm.engine.delegate.DelegateExecution; -import org.camunda.bpm.engine.delegate.Expression; import org.hl7.fhir.r4.model.Binary; import org.hl7.fhir.r4.model.IdType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.InitializingBean; import dev.dsf.bpe.CodeSystem; import dev.dsf.bpe.ConstantsPing; import dev.dsf.bpe.ExecutionVariables; import dev.dsf.bpe.ProcessError; import dev.dsf.bpe.util.ErrorListUtils; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.activity.AbstractServiceDelegate; -import dev.dsf.bpe.v1.variables.Variables; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Variables; import jakarta.ws.rs.ProcessingException; import jakarta.ws.rs.WebApplicationException; -public class Cleanup extends AbstractServiceDelegate implements InitializingBean +public class Cleanup implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(Cleanup.class); - private Expression process; + private String process; - public Cleanup(ProcessPluginApi api) - { - super(api); - } - - public void doExecute(DelegateExecution delegateExecution, Variables variables) + @Override + public void execute(ProcessPluginApi api, Variables variables) throws ErrorBoundaryEvent, Exception { logger.debug("Cleaning up..."); - String process = (String) this.process.getValue(delegateExecution); - String downloadResourceId = new IdType(variables.getString(ExecutionVariables.downloadResourceReference.name())) .getIdPart(); if (downloadResourceId != null) { try { - api.getFhirWebserviceClientProvider().getLocalWebserviceClient().delete(Binary.class, - downloadResourceId); - api.getFhirWebserviceClientProvider().getLocalWebserviceClient().deletePermanently(Binary.class, - downloadResourceId); + api.getDsfClientProvider().getLocal().delete(Binary.class, downloadResourceId); + api.getDsfClientProvider().getLocal().deletePermanently(Binary.class, downloadResourceId); logger.debug("Deleted Binary resource with ID {}", downloadResourceId); } catch (ProcessingException e) @@ -57,32 +47,32 @@ public void doExecute(DelegateExecution delegateExecution, Variables variables) if (e.getCause() instanceof SocketTimeoutException timeoutException) { ProcessError error = toProcessError(timeoutException, process); - ErrorListUtils.add(error, delegateExecution); + ErrorListUtils.add(error, variables); logger.error(e.getCause().getMessage()); } else if (e.getCause() instanceof ConnectTimeoutException) { ProcessError error = toProcessErrorConnectTimeout(process); - ErrorListUtils.add(error, delegateExecution); + ErrorListUtils.add(error, variables); logger.error(e.getCause().getMessage()); } else if (e.getCause() instanceof HttpHostConnectException) { ProcessError error = toProcessErrorLocalHttpHostConnect(process); - ErrorListUtils.add(error, delegateExecution); + ErrorListUtils.add(error, variables); logger.error(e.getCause().getMessage()); } else { ProcessError error = new ProcessError(process, CodeSystem.DsfPingError.Concept.LOCAL_UNKNOWN, null); - ErrorListUtils.add(error, delegateExecution); + ErrorListUtils.add(error, variables); logger.error("Unexpected error: {}", e.getCause().getMessage()); } } catch (WebApplicationException e) { ProcessError error = toProcessError(e, process); - ErrorListUtils.add(error, delegateExecution); + ErrorListUtils.add(error, variables); } } else @@ -153,7 +143,7 @@ private ProcessError toProcessError(WebApplicationException e, String process) }; } - public void setProcess(Expression process) + public void setProcess(String process) { this.process = process; } diff --git a/src/main/java/dev/dsf/bpe/service/GenerateAndStoreResource.java b/src/main/java/dev/dsf/bpe/service/GenerateAndStoreResource.java index 0b7429bd..6f881e0e 100644 --- a/src/main/java/dev/dsf/bpe/service/GenerateAndStoreResource.java +++ b/src/main/java/dev/dsf/bpe/service/GenerateAndStoreResource.java @@ -5,47 +5,37 @@ import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.HttpHostConnectException; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; -import org.camunda.bpm.engine.delegate.Expression; import org.hl7.fhir.r4.model.IdType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.InitializingBean; import dev.dsf.bpe.CodeSystem; import dev.dsf.bpe.ConstantsPing; import dev.dsf.bpe.ExecutionVariables; import dev.dsf.bpe.ProcessError; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Variables; -import dev.dsf.bpe.variables.process_error.ProcessErrorValueImpl; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Variables; import jakarta.ws.rs.ProcessingException; import jakarta.ws.rs.WebApplicationException; -public class GenerateAndStoreResource extends AbstractService implements InitializingBean +public class GenerateAndStoreResource implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(GenerateAndStoreResource.class); private final long maxUploadSizeBytes; - private Expression process; + private String process; - public GenerateAndStoreResource(ProcessPluginApi api, long maxUploadSizeBytes) + public GenerateAndStoreResource(long maxUploadSizeBytes) { - super(api); this.maxUploadSizeBytes = maxUploadSizeBytes; } @Override - public void afterPropertiesSet() throws Exception - { - super.afterPropertiesSet(); - } - - public void doExecuteWithErrorHandling(DelegateExecution delegateExecution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi api, Variables variables) throws ErrorBoundaryEvent, Exception { logger.debug("Generating resource..."); long downloadResourceSizeBytes = getDownloadResourceSize(variables); - String process = (String) this.process.getValue(delegateExecution); RandomByteInputStream resourceContent; if (downloadResourceSizeBytes > maxUploadSizeBytes) { @@ -65,7 +55,7 @@ public void doExecuteWithErrorHandling(DelegateExecution delegateExecution, Vari try { - IdType downloadResource = storeBinary(resourceContent); + IdType downloadResource = storeBinary(api, resourceContent); String reference = downloadResource.toVersionless().getValueAsString(); @@ -138,11 +128,10 @@ public void doExecuteWithErrorHandling(DelegateExecution delegateExecution, Vari break; } - variables.setVariable(ExecutionVariables.resourceUploadError.name(), new ProcessErrorValueImpl(error)); + variables.setJsonVariable(ExecutionVariables.resourceUploadError.name(), error); if (ConstantsPing.PROCESS_NAME_PONG.equals(process)) { - variables.setVariable(ExecutionVariables.resourceUploadErrorRemote.name(), - new ProcessErrorValueImpl(errorRemote)); + variables.setJsonVariable(ExecutionVariables.resourceUploadErrorRemote.name(), errorRemote); } } catch (ProcessingException e) @@ -152,11 +141,10 @@ public void doExecuteWithErrorHandling(DelegateExecution delegateExecution, Vari ProcessError error = toProcessErrorLocal(socketTimeoutException, process); ProcessError errorRemote = toProcessErrorRemote(socketTimeoutException, process); - variables.setVariable(ExecutionVariables.resourceUploadError.name(), new ProcessErrorValueImpl(error)); + variables.setJsonVariable(ExecutionVariables.resourceUploadError.name(), error); if (ConstantsPing.PROCESS_NAME_PONG.equals(process)) { - variables.setVariable(ExecutionVariables.resourceUploadErrorRemote.name(), - new ProcessErrorValueImpl(errorRemote)); + variables.setJsonVariable(ExecutionVariables.resourceUploadErrorRemote.name(), errorRemote); } } else if (e.getCause() instanceof ConnectTimeoutException) @@ -164,11 +152,10 @@ else if (e.getCause() instanceof ConnectTimeoutException) ProcessError error = toProcessErrorLocalConnectTimeout(process); ProcessError errorRemote = toProcessErrorRemoteConnectTimeout(process); - variables.setVariable(ExecutionVariables.resourceUploadError.name(), new ProcessErrorValueImpl(error)); + variables.setJsonVariable(ExecutionVariables.resourceUploadError.name(), error); if (ConstantsPing.PROCESS_NAME_PONG.equals(process)) { - variables.setVariable(ExecutionVariables.resourceUploadErrorRemote.name(), - new ProcessErrorValueImpl(errorRemote)); + variables.setJsonVariable(ExecutionVariables.resourceUploadErrorRemote.name(), errorRemote); } } else if (e.getCause() instanceof HttpHostConnectException) @@ -176,11 +163,10 @@ else if (e.getCause() instanceof HttpHostConnectException) ProcessError error = toProcessErrorLocalHttpHostConnect(process); ProcessError errorRemote = toProcessErrorRemoteHttpHostConnect(process); - variables.setVariable(ExecutionVariables.resourceUploadError.name(), new ProcessErrorValueImpl(error)); + variables.setJsonVariable(ExecutionVariables.resourceUploadError.name(), error); if (ConstantsPing.PROCESS_NAME_PONG.equals(process)) { - variables.setVariable(ExecutionVariables.resourceUploadErrorRemote.name(), - new ProcessErrorValueImpl(errorRemote)); + variables.setJsonVariable(ExecutionVariables.resourceUploadErrorRemote.name(), errorRemote); } } else @@ -188,11 +174,10 @@ else if (e.getCause() instanceof HttpHostConnectException) ProcessError error = new ProcessError(process, CodeSystem.DsfPingError.Concept.LOCAL_UNKNOWN, null); ProcessError errorRemote = new ProcessError(process, CodeSystem.DsfPingError.Concept.REMOTE_UNKNOWN, null); - variables.setVariable(ExecutionVariables.resourceUploadError.name(), new ProcessErrorValueImpl(error)); + variables.setJsonVariable(ExecutionVariables.resourceUploadError.name(), error); if (ConstantsPing.PROCESS_NAME_PONG.equals(process)) { - variables.setVariable(ExecutionVariables.resourceUploadErrorRemote.name(), - new ProcessErrorValueImpl(errorRemote)); + variables.setJsonVariable(ExecutionVariables.resourceUploadErrorRemote.name(), errorRemote); } logger.error("Unexpected error: {}", e.getMessage()); } @@ -277,14 +262,14 @@ private void setDownloadResourceSizeBytes(Variables variables, long resourceSize variables.setLong(ExecutionVariables.downloadResourceSizeBytes.name(), resourceSizeBytes); } - private IdType storeBinary(RandomByteInputStream downloadResourceContent) + private IdType storeBinary(ProcessPluginApi api, RandomByteInputStream downloadResourceContent) { - return api.getFhirWebserviceClientProvider().getLocalWebserviceClient().withMinimalReturn().createBinary( - downloadResourceContent, ConstantsPing.DOWNLOAD_RESOURCE_MIME_TYPE, + return api.getDsfClientProvider().getLocal().withMinimalReturn().createBinary(downloadResourceContent, + ConstantsPing.DOWNLOAD_RESOURCE_MIME_TYPE, api.getOrganizationProvider().getLocalOrganization().get().getIdElement().getValue()); } - public void setProcess(Expression process) + public void setProcess(String process) { this.process = process; } diff --git a/src/main/java/dev/dsf/bpe/service/SetDownloadResourceSize.java b/src/main/java/dev/dsf/bpe/service/SetDownloadResourceSize.java index e3bc7fe7..49a6797b 100644 --- a/src/main/java/dev/dsf/bpe/service/SetDownloadResourceSize.java +++ b/src/main/java/dev/dsf/bpe/service/SetDownloadResourceSize.java @@ -2,8 +2,6 @@ import java.util.Optional; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.hl7.fhir.r4.model.DecimalType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,17 +9,18 @@ import dev.dsf.bpe.CodeSystem; import dev.dsf.bpe.ConstantsPing; import dev.dsf.bpe.ExecutionVariables; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Variables; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Variables; -public class SetDownloadResourceSize extends AbstractService +public class SetDownloadResourceSize implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(SetDownloadResourceSize.class); private final long maxDownloadResourceSizeBytes; - public SetDownloadResourceSize(ProcessPluginApi api, long maxDownloadResourceSizeBytes) + public SetDownloadResourceSize(long maxDownloadResourceSizeBytes) { - super(api); if (maxDownloadResourceSizeBytes < 0) { this.maxDownloadResourceSizeBytes = 0L; @@ -33,11 +32,11 @@ public SetDownloadResourceSize(ProcessPluginApi api, long maxDownloadResourceSiz } @Override - protected void doExecuteWithErrorHandling(DelegateExecution delegateExecution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi api, Variables variables) throws ErrorBoundaryEvent, Exception { logger.debug("Setting download resource size..."); - long downloadResourceSizeBytes = getDownloadResourceSizeBytes(variables); + long downloadResourceSizeBytes = getDownloadResourceSizeBytes(api, variables); variables.setLong(ExecutionVariables.downloadResourceSizeBytes.name(), downloadResourceSizeBytes); logger.debug("Set download resource size to " + downloadResourceSizeBytes); @@ -47,7 +46,7 @@ protected void doExecuteWithErrorHandling(DelegateExecution delegateExecution, V logger.debug("Set maximum download resource size to " + maxDownloadResourceSizeBytes); } - private long getDownloadResourceSizeBytes(Variables variables) + private long getDownloadResourceSizeBytes(ProcessPluginApi api, Variables variables) { Optional downloadResourceSizeType = api.getTaskHelper().getFirstInputParameterValue( variables.getStartTask(), CodeSystem.DsfPing.URL, diff --git a/src/main/java/dev/dsf/bpe/service/autostart/SetTargetAndConfigureTimer.java b/src/main/java/dev/dsf/bpe/service/autostart/SetTargetAndConfigureTimer.java index 7e6a27a4..3db01064 100644 --- a/src/main/java/dev/dsf/bpe/service/autostart/SetTargetAndConfigureTimer.java +++ b/src/main/java/dev/dsf/bpe/service/autostart/SetTargetAndConfigureTimer.java @@ -1,30 +1,24 @@ package dev.dsf.bpe.service.autostart; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import dev.dsf.bpe.CodeSystem; import dev.dsf.bpe.ConstantsPing; import dev.dsf.bpe.ExecutionVariables; -import dev.dsf.bpe.service.AbstractService; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Variables; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Variables; -public class SetTargetAndConfigureTimer extends AbstractService +public class SetTargetAndConfigureTimer implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(SetTargetAndConfigureTimer.class); - public SetTargetAndConfigureTimer(ProcessPluginApi api) - { - super(api); - } - @Override - protected void doExecuteWithErrorHandling(DelegateExecution execution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi api, Variables variables) throws ErrorBoundaryEvent, Exception { - String timerInterval = getTimerInterval(variables); + String timerInterval = getTimerInterval(api, variables); logger.debug("Setting variable '{}' to {}", ExecutionVariables.timerInterval.name(), timerInterval); variables.setString(ExecutionVariables.timerInterval.name(), timerInterval); @@ -34,7 +28,7 @@ protected void doExecuteWithErrorHandling(DelegateExecution execution, Variables api.getEndpointProvider().getLocalEndpointAddress())); } - private String getTimerInterval(Variables variables) + private String getTimerInterval(ProcessPluginApi api, Variables variables) { return api.getTaskHelper() .getFirstInputParameterStringValue(variables.getStartTask(), CodeSystem.DsfPing.URL, diff --git a/src/main/java/dev/dsf/bpe/service/ping/CheckPingTaskStatus.java b/src/main/java/dev/dsf/bpe/service/ping/CheckPingTaskStatus.java index 36ed301e..625d8c88 100644 --- a/src/main/java/dev/dsf/bpe/service/ping/CheckPingTaskStatus.java +++ b/src/main/java/dev/dsf/bpe/service/ping/CheckPingTaskStatus.java @@ -1,7 +1,7 @@ package dev.dsf.bpe.service.ping; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; +import java.time.Duration; + import org.hl7.fhir.r4.model.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -10,26 +10,24 @@ import dev.dsf.bpe.ConstantsPing; import dev.dsf.bpe.ExecutionVariables; import dev.dsf.bpe.ProcessError; -import dev.dsf.bpe.service.AbstractService; import dev.dsf.bpe.util.ErrorListUtils; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Target; -import dev.dsf.bpe.v1.variables.Variables; -import dev.dsf.bpe.variables.codesystem.dsfpingstatus.CodeValueImpl; -import dev.dsf.fhir.client.FhirWebserviceClient; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.client.dsf.DelayStrategy; +import dev.dsf.bpe.v2.client.dsf.DsfClient; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.error.ServiceTaskErrorHandler; +import dev.dsf.bpe.v2.error.impl.DefaultServiceTaskErrorHandler; +import dev.dsf.bpe.v2.variables.Target; +import dev.dsf.bpe.v2.variables.Variables; import jakarta.ws.rs.WebApplicationException; -public class CheckPingTaskStatus extends AbstractService +public class CheckPingTaskStatus implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(CheckPingTaskStatus.class); - public CheckPingTaskStatus(ProcessPluginApi api) - { - super(api); - } - @Override - protected void doExecuteWithErrorHandling(DelegateExecution delegateExecution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi api, Variables variables) throws ErrorBoundaryEvent, Exception { logger.debug("Checking status of ping task..."); @@ -45,10 +43,10 @@ protected void doExecuteWithErrorHandling(DelegateExecution delegateExecution, V { if (taskId != null) { - FhirWebserviceClient fhirWebserviceClient = api.getFhirWebserviceClientProvider() - .getWebserviceClient(target.getEndpointUrl()); + DsfClient dsfClient = api.getDsfClientProvider().getByEndpointUrl(target.getEndpointUrl()); - Task pingTask = fhirWebserviceClient.withRetry(3, 1000).read(Task.class, taskId); + Task pingTask = dsfClient.withRetry(3, DelayStrategy.constant(Duration.ofSeconds(1))).read(Task.class, + taskId); ProcessError error = switch (pingTask.getStatus()) { case COMPLETED -> new ProcessError(ConstantsPing.PROCESS_NAME_PING, @@ -62,18 +60,18 @@ protected void doExecuteWithErrorHandling(DelegateExecution delegateExecution, V default -> new ProcessError(ConstantsPing.PROCESS_NAME_PING, CodeSystem.DsfPingError.Concept.RESPONSE_MESSAGE_TIMEOUT_STATUS_UNEXPECTED, null); }; - ErrorListUtils.add(error, delegateExecution, correlationKey); + ErrorListUtils.add(error, variables, correlationKey); } } catch (WebApplicationException e) { ProcessError error = getProcessError(e); - ErrorListUtils.add(error, delegateExecution, correlationKey); + ErrorListUtils.add(error, variables, correlationKey); } finally { - variables.setVariable(ExecutionVariables.statusCode.correlatedValue(correlationKey), - new CodeValueImpl(CodeSystem.DsfPingStatus.Code.PONG_MISSING)); + variables.setJsonVariable(ExecutionVariables.statusCode.correlatedValue(correlationKey), + CodeSystem.DsfPingStatus.Code.PONG_MISSING); } logger.debug("Saved '{}' to process execution for correlation key '{}'", @@ -113,14 +111,20 @@ private static ProcessError getProcessError(WebApplicationException e) } @Override - protected void handleException(DelegateExecution execution, Variables variables, Exception exception) - throws Exception + public ServiceTaskErrorHandler getErrorHandler() { - logger.error("Unexpected error while checking status of ping task.", exception); - String correlationKey = variables.getTarget().getCorrelationKey(); - ErrorListUtils.add( - new ProcessError(ConstantsPing.PROCESS_NAME_PING, CodeSystem.DsfPingError.Concept.LOCAL_UNKNOWN, null), - execution, correlationKey); - throw new BpmnError(ConstantsPing.BPMN_ERROR_CODE_UNEXPECTED_ERROR); + return new DefaultServiceTaskErrorHandler() + { + @Override + public Exception handleException(ProcessPluginApi processPluginApi, Variables variables, Exception e) + { + logger.error("Unexpected error while checking status of ping task.", e); + String correlationKey = variables.getTarget().getCorrelationKey(); + ErrorListUtils.add(new ProcessError(ConstantsPing.PROCESS_NAME_PING, + CodeSystem.DsfPingError.Concept.LOCAL_UNKNOWN, null), variables, correlationKey); + return new ErrorBoundaryEvent(ConstantsPing.BPMN_ERROR_CODE_UNEXPECTED_ERROR, + ConstantsPing.BPMN_ERROR_MESSAGE_UNEXPECTED_ERROR); + } + }; } } diff --git a/src/main/java/dev/dsf/bpe/service/ping/DownloadResourceAndMeasureSpeedInSubProcess.java b/src/main/java/dev/dsf/bpe/service/ping/DownloadResourceAndMeasureSpeedInSubProcess.java index dbcde996..bfb28103 100644 --- a/src/main/java/dev/dsf/bpe/service/ping/DownloadResourceAndMeasureSpeedInSubProcess.java +++ b/src/main/java/dev/dsf/bpe/service/ping/DownloadResourceAndMeasureSpeedInSubProcess.java @@ -1,7 +1,5 @@ package dev.dsf.bpe.service.ping; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.hl7.fhir.r4.model.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -10,25 +8,22 @@ import dev.dsf.bpe.ConstantsPing; import dev.dsf.bpe.ExecutionVariables; import dev.dsf.bpe.ProcessError; -import dev.dsf.bpe.service.AbstractService; import dev.dsf.bpe.util.BinaryResourceDownloader; import dev.dsf.bpe.util.ErrorListUtils; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Target; -import dev.dsf.bpe.v1.variables.Variables; -import dev.dsf.bpe.variables.duration.DurationValueImpl; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.error.ServiceTaskErrorHandler; +import dev.dsf.bpe.v2.error.impl.DefaultServiceTaskErrorHandler; +import dev.dsf.bpe.v2.variables.Target; +import dev.dsf.bpe.v2.variables.Variables; -public class DownloadResourceAndMeasureSpeedInSubProcess extends AbstractService +public class DownloadResourceAndMeasureSpeedInSubProcess implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(DownloadResourceAndMeasureSpeedInSubProcess.class); - public DownloadResourceAndMeasureSpeedInSubProcess(ProcessPluginApi api) - { - super(api); - } - @Override - protected void doExecuteWithErrorHandling(DelegateExecution delegateExecution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi api, Variables variables) throws ErrorBoundaryEvent, Exception { logger.debug("Starting resource download to measure speed..."); @@ -44,12 +39,12 @@ protected void doExecuteWithErrorHandling(DelegateExecution delegateExecution, V { variables.setLong(ExecutionVariables.downloadedBytes.correlatedValue(correlationKey), downloadResult.getDownloadedBytes()); - variables.setVariable(ExecutionVariables.downloadedDuration.correlatedValue(correlationKey), - new DurationValueImpl(downloadResult.getDownloadedDuration())); + variables.setJsonVariable(ExecutionVariables.downloadedDuration.correlatedValue(correlationKey), + downloadResult.getDownloadedDuration()); } else { - delegateExecution.setVariableLocal(ExecutionVariables.resourceDownloadError.name(), + variables.setJsonVariableLocal(ExecutionVariables.resourceDownloadError.name(), downloadResult.getErrorTuple().errorLocal()); } @@ -57,14 +52,20 @@ protected void doExecuteWithErrorHandling(DelegateExecution delegateExecution, V } @Override - protected void handleException(DelegateExecution execution, Variables variables, Exception exception) - throws Exception + public ServiceTaskErrorHandler getErrorHandler() { - logger.error("Unexpected error while downloading resource and measuring speed.", exception); - String correlationKey = variables.getTarget().getCorrelationKey(); - ErrorListUtils.add( - new ProcessError(ConstantsPing.PROCESS_NAME_PING, CodeSystem.DsfPingError.Concept.LOCAL_UNKNOWN, null), - execution, correlationKey); - throw new BpmnError(ConstantsPing.BPMN_ERROR_CODE_UNEXPECTED_ERROR); + return new DefaultServiceTaskErrorHandler() + { + @Override + public Exception handleException(ProcessPluginApi api, Variables variables, Exception exception) + { + logger.error("Unexpected error while downloading resource and measuring speed.", exception); + String correlationKey = variables.getTarget().getCorrelationKey(); + ErrorListUtils.add(new ProcessError(ConstantsPing.PROCESS_NAME_PING, + CodeSystem.DsfPingError.Concept.LOCAL_UNKNOWN, null), variables, correlationKey); + return new ErrorBoundaryEvent(ConstantsPing.BPMN_ERROR_CODE_UNEXPECTED_ERROR, + ConstantsPing.BPMN_ERROR_MESSAGE_UNEXPECTED_ERROR); + } + }; } } diff --git a/src/main/java/dev/dsf/bpe/service/ping/LogAndSaveError.java b/src/main/java/dev/dsf/bpe/service/ping/LogAndSaveError.java index 71571b87..a4bac513 100644 --- a/src/main/java/dev/dsf/bpe/service/ping/LogAndSaveError.java +++ b/src/main/java/dev/dsf/bpe/service/ping/LogAndSaveError.java @@ -1,36 +1,29 @@ package dev.dsf.bpe.service.ping; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import dev.dsf.bpe.ExecutionVariables; import dev.dsf.bpe.ProcessError; -import dev.dsf.bpe.service.AbstractService; import dev.dsf.bpe.util.ErrorListUtils; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Target; -import dev.dsf.bpe.v1.variables.Variables; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Target; +import dev.dsf.bpe.v2.variables.Variables; -public class LogAndSaveError extends AbstractService +public class LogAndSaveError implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(LogAndSaveError.class); - public LogAndSaveError(ProcessPluginApi api) - { - super(api); - } - @Override - protected void doExecuteWithErrorHandling(DelegateExecution delegateExecution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi processPluginApi, Variables variables) throws ErrorBoundaryEvent, Exception { Target target = variables.getTarget(); - ProcessError error = (ProcessError) delegateExecution - .getVariableLocal(ExecutionVariables.resourceDownloadError.name()); + ProcessError error = variables.getVariableLocal(ExecutionVariables.resourceDownloadError.name()); - ErrorListUtils.add(error, delegateExecution, target.getCorrelationKey()); + ErrorListUtils.add(error, variables, target.getCorrelationKey()); logger.info("Error while trying to download resource from {}: {}", target.getEndpointUrl(), error.concept().getDisplay()); diff --git a/src/main/java/dev/dsf/bpe/service/ping/LogAndSaveSendError.java b/src/main/java/dev/dsf/bpe/service/ping/LogAndSaveSendError.java index d6235223..7fae1245 100644 --- a/src/main/java/dev/dsf/bpe/service/ping/LogAndSaveSendError.java +++ b/src/main/java/dev/dsf/bpe/service/ping/LogAndSaveSendError.java @@ -2,40 +2,32 @@ import java.util.Objects; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import dev.dsf.bpe.CodeSystem; import dev.dsf.bpe.ExecutionVariables; import dev.dsf.bpe.ProcessError; -import dev.dsf.bpe.service.AbstractService; import dev.dsf.bpe.util.ErrorListUtils; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Variables; -import dev.dsf.bpe.variables.codesystem.dsfpingstatus.CodeValueImpl; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Variables; -public class LogAndSaveSendError extends AbstractService +public class LogAndSaveSendError implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(LogAndSaveSendError.class); - public LogAndSaveSendError(ProcessPluginApi api) - { - super(api); - } - @Override - protected void doExecuteWithErrorHandling(DelegateExecution execution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi processPluginApi, Variables variables) throws ErrorBoundaryEvent, Exception { String correlationKey = variables.getTarget().getCorrelationKey(); - ProcessError error = (ProcessError) execution.getVariableLocal(ExecutionVariables.error.name()); - CodeSystem.DsfPingStatus.Code status = (CodeSystem.DsfPingStatus.Code) execution - .getVariableLocal(ExecutionVariables.statusCode.name()); + ProcessError error = variables.getVariableLocal(ExecutionVariables.error.name()); + CodeSystem.DsfPingStatus.Code status = variables.getVariableLocal(ExecutionVariables.statusCode.name()); Objects.requireNonNull(status, "status"); - ErrorListUtils.add(error, execution, correlationKey); - variables.setVariable(ExecutionVariables.statusCode.correlatedValue(correlationKey), new CodeValueImpl(status)); + ErrorListUtils.add(error, variables, correlationKey); + variables.setJsonVariable(ExecutionVariables.statusCode.correlatedValue(correlationKey), status); logger.debug("Saved error when trying to send ping message. Error message: {}", error.concept().getDisplay()); } } diff --git a/src/main/java/dev/dsf/bpe/service/ping/LogAndSaveUploadErrorPing.java b/src/main/java/dev/dsf/bpe/service/ping/LogAndSaveUploadErrorPing.java index c4177ef2..c31c4259 100644 --- a/src/main/java/dev/dsf/bpe/service/ping/LogAndSaveUploadErrorPing.java +++ b/src/main/java/dev/dsf/bpe/service/ping/LogAndSaveUploadErrorPing.java @@ -1,41 +1,42 @@ package dev.dsf.bpe.service.ping; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import dev.dsf.bpe.ExecutionVariables; import dev.dsf.bpe.ProcessError; -import dev.dsf.bpe.service.AbstractService; import dev.dsf.bpe.util.ErrorListUtils; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Variables; - -public class LogAndSaveUploadErrorPing extends AbstractService +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.error.ServiceTaskErrorHandler; +import dev.dsf.bpe.v2.error.impl.DefaultServiceTaskErrorHandler; +import dev.dsf.bpe.v2.variables.Variables; + +public class LogAndSaveUploadErrorPing implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(LogAndSaveUploadErrorPing.class); - public LogAndSaveUploadErrorPing(ProcessPluginApi api) - { - super(api); - } - @Override - protected void doExecuteWithErrorHandling(DelegateExecution execution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi processPluginApi, Variables variables) throws ErrorBoundaryEvent, Exception { - ProcessError error = (ProcessError) variables.getVariable(ExecutionVariables.resourceUploadError.name()); + ProcessError error = variables.getVariable(ExecutionVariables.resourceUploadError.name()); - ErrorListUtils.add(error, execution); + ErrorListUtils.add(error, variables); logger.info("Error while storing binary resource for download: {}", error.concept().getDisplay()); } @Override - protected void handleException(DelegateExecution execution, Variables variables, Exception exception) - throws Exception + public ServiceTaskErrorHandler getErrorHandler() { - logger.error("Unexpected error while storing binary resource for download.", exception); - throw exception; + return new DefaultServiceTaskErrorHandler() + { + @Override + public Exception handleException(ProcessPluginApi api, Variables variables, Exception exception) + { + return super.handleException(api, variables, exception); + } + }; } } diff --git a/src/main/java/dev/dsf/bpe/service/ping/SavePong.java b/src/main/java/dev/dsf/bpe/service/ping/SavePong.java index d2a70eb3..9128a682 100644 --- a/src/main/java/dev/dsf/bpe/service/ping/SavePong.java +++ b/src/main/java/dev/dsf/bpe/service/ping/SavePong.java @@ -4,8 +4,6 @@ import java.util.List; import java.util.Optional; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.hl7.fhir.r4.model.DecimalType; import org.hl7.fhir.r4.model.Task; import org.slf4j.Logger; @@ -16,30 +14,23 @@ import dev.dsf.bpe.ExecutionVariables; import dev.dsf.bpe.ProcessError; import dev.dsf.bpe.ProcessErrors; -import dev.dsf.bpe.service.AbstractService; import dev.dsf.bpe.util.ErrorListUtils; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Target; -import dev.dsf.bpe.v1.variables.Variables; -import dev.dsf.bpe.variables.codesystem.dsfpingstatus.CodeValueImpl; -import dev.dsf.bpe.variables.duration.DurationValueImpl; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Target; +import dev.dsf.bpe.v2.variables.Variables; -public class SavePong extends AbstractService +public class SavePong implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(SavePong.class); - public SavePong(ProcessPluginApi api) - { - super(api); - } - @Override - protected void doExecuteWithErrorHandling(DelegateExecution delegateExecution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi api, Variables variables) throws ErrorBoundaryEvent, Exception { Target target = variables.getTarget(); logger.debug("Pong received from {}. Saving pong information...", target.getEndpointUrl()); String correlationKey = target.getCorrelationKey(); - delegateExecution.removeVariable("statusCode"); Task pong = variables.getLatestTask(); @@ -47,9 +38,9 @@ protected void doExecuteWithErrorHandling(DelegateExecution delegateExecution, V .getFirstInputParameterValue(pong, CodeSystem.DsfPing.URL, CodeSystem.DsfPing.Code.DOWNLOADED_DURATION_MILLIS.getValue(), org.hl7.fhir.r4.model.Duration.class); - optDownloadedDuration.ifPresent( - duration -> variables.setVariable(ExecutionVariables.uploadedDuration.correlatedValue(correlationKey), - new DurationValueImpl(Duration.ofMillis(duration.getValue().longValue())))); + optDownloadedDuration.ifPresent(duration -> variables.setJsonVariable( + ExecutionVariables.uploadedDuration.correlatedValue(correlationKey), + Duration.ofMillis(duration.getValue().longValue()))); Optional optDownloadedBytes = api.getTaskHelper().getFirstInputParameterValue(pong, CodeSystem.DsfPing.URL, CodeSystem.DsfPing.Code.DOWNLOADED_BYTES.getValue(), DecimalType.class); @@ -59,9 +50,9 @@ protected void doExecuteWithErrorHandling(DelegateExecution delegateExecution, V ProcessErrors errorList = new ProcessErrors(parseInputs(pong)); - ErrorListUtils.addAll(errorList, delegateExecution, correlationKey); - variables.setVariable(ExecutionVariables.statusCode.correlatedValue(correlationKey), - new CodeValueImpl(CodeSystem.DsfPingStatus.Code.PONG_RECEIVED)); + ErrorListUtils.addAll(errorList, variables, correlationKey); + variables.setJsonVariable(ExecutionVariables.statusCode.correlatedValue(correlationKey), + CodeSystem.DsfPingStatus.Code.PONG_RECEIVED); logger.debug("Saved pong information."); } diff --git a/src/main/java/dev/dsf/bpe/service/ping/SelectPingTargets.java b/src/main/java/dev/dsf/bpe/service/ping/SelectPingTargets.java index 50ea5a2b..137747bb 100644 --- a/src/main/java/dev/dsf/bpe/service/ping/SelectPingTargets.java +++ b/src/main/java/dev/dsf/bpe/service/ping/SelectPingTargets.java @@ -12,8 +12,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent; import org.hl7.fhir.r4.model.Endpoint; @@ -24,38 +22,35 @@ import org.hl7.fhir.r4.model.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.InitializingBean; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; import dev.dsf.bpe.CodeSystem; import dev.dsf.bpe.ConstantsPing; import dev.dsf.bpe.ProcessError; -import dev.dsf.bpe.service.AbstractService; import dev.dsf.bpe.util.ErrorListUtils; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.constants.NamingSystems.EndpointIdentifier; -import dev.dsf.bpe.v1.constants.NamingSystems.OrganizationIdentifier; -import dev.dsf.bpe.v1.variables.Target; -import dev.dsf.bpe.v1.variables.Variables; - -public class SelectPingTargets extends AbstractService implements InitializingBean +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.constants.NamingSystems.EndpointIdentifier; +import dev.dsf.bpe.v2.constants.NamingSystems.OrganizationIdentifier; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.error.ServiceTaskErrorHandler; +import dev.dsf.bpe.v2.error.impl.DefaultServiceTaskErrorHandler; +import dev.dsf.bpe.v2.variables.Target; +import dev.dsf.bpe.v2.variables.Variables; + +public class SelectPingTargets implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(SelectPingTargets.class); private static final Pattern endpointResouceTypes = Pattern.compile( "Endpoint|HealthcareService|ImagingStudy|InsurancePlan|Location|Organization|OrganizationAffiliation|PractitionerRole"); - public SelectPingTargets(ProcessPluginApi api) - { - super(api); - } - @Override - protected void doExecuteWithErrorHandling(DelegateExecution execution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi api, Variables variables) throws ErrorBoundaryEvent, Exception { - Stream targetEndpoints = getTargetEndpointsSearchParameter(variables) - .map(uriComponents -> searchForEndpoints(uriComponents)).orElse(allEndpoints()) - .filter(isLocalEndpoint().negate()); + Stream targetEndpoints = getTargetEndpointsSearchParameter(api, variables) + .map(uriComponents -> searchForEndpoints(api, uriComponents)).orElse(allEndpoints(api)) + .filter(isLocalEndpoint(api).negate()); List remoteOrganizations = api.getOrganizationProvider().getRemoteOrganizations(); Map organizationIdentifierByOrganizationId = remoteOrganizations.stream().collect( @@ -78,17 +73,23 @@ protected void doExecuteWithErrorHandling(DelegateExecution execution, Variables } @Override - protected void handleException(DelegateExecution execution, Variables variables, Exception exception) - throws Exception + public ServiceTaskErrorHandler getErrorHandler() { - logger.error("Unexpected error while selecting ping targets.", exception); - ErrorListUtils.add( - new ProcessError(ConstantsPing.PROCESS_NAME_PING, CodeSystem.DsfPingError.Concept.LOCAL_UNKNOWN, null), - execution); - throw new BpmnError(ConstantsPing.BPMN_ERROR_CODE_UNEXPECTED_ERROR); + return new DefaultServiceTaskErrorHandler() + { + @Override + public Exception handleException(ProcessPluginApi api, Variables variables, Exception exception) + { + logger.error("Unexpected error while selecting ping targets.", exception); + ErrorListUtils.add(new ProcessError(ConstantsPing.PROCESS_NAME_PING, + CodeSystem.DsfPingError.Concept.LOCAL_UNKNOWN, null), variables); + return new ErrorBoundaryEvent(ConstantsPing.BPMN_ERROR_CODE_UNEXPECTED_ERROR, + ConstantsPing.BPMN_ERROR_MESSAGE_UNEXPECTED_ERROR); + } + }; } - private Optional getTargetEndpointsSearchParameter(Variables variables) + private Optional getTargetEndpointsSearchParameter(ProcessPluginApi api, Variables variables) { Task mainTask = variables.getStartTask(); return api.getTaskHelper() @@ -97,12 +98,13 @@ private Optional getTargetEndpointsSearchParameter(Variables vari .map(requestUrl -> UriComponentsBuilder.fromUriString(requestUrl).build()); } - private Stream searchForEndpoints(UriComponents searchParameters) + private Stream searchForEndpoints(ProcessPluginApi api, UriComponents searchParameters) { - return searchForEndpoints(searchParameters, 1, 0); + return searchForEndpoints(api, searchParameters, 1, 0); } - private Stream searchForEndpoints(UriComponents searchParameters, int page, int currentTotal) + private Stream searchForEndpoints(ProcessPluginApi api, UriComponents searchParameters, int page, + int currentTotal) { if (searchParameters.getPathSegments().isEmpty()) return Stream.empty(); @@ -115,12 +117,12 @@ private Stream searchForEndpoints(UriComponents searchParameters, int queryParameters.putAll(searchParameters.getQueryParams()); queryParameters.put("_page", Collections.singletonList(String.valueOf(page))); - Bundle searchResult = api.getFhirWebserviceClientProvider().getLocalWebserviceClient() - .searchWithStrictHandling(resourceType.get(), queryParameters); + Bundle searchResult = api.getDsfClientProvider().getLocal().searchWithStrictHandling(resourceType.get(), + queryParameters); if (searchResult.getTotal() > currentTotal + searchResult.getEntry().size()) return Stream.concat(toEndpoints(searchResult), - searchForEndpoints(searchParameters, page + 1, currentTotal + searchResult.getEntry().size())); + searchForEndpoints(api, searchParameters, page + 1, currentTotal + searchResult.getEntry().size())); else return toEndpoints(searchResult); } @@ -146,27 +148,26 @@ private Optional> getResourceType(UriComponents search } } - private Stream allEndpoints() + private Stream allEndpoints(ProcessPluginApi api) { - return allEndpoints(1, 0); + return allEndpoints(api, 1, 0); } - private Predicate isLocalEndpoint() + private Predicate isLocalEndpoint(ProcessPluginApi api) { return e -> Objects.equals(api.getEndpointProvider().getLocalEndpointAddress(), e.getAddress()); } - private Stream allEndpoints(int page, int currentTotal) + private Stream allEndpoints(ProcessPluginApi api, int page, int currentTotal) { - Bundle searchResult = api.getFhirWebserviceClientProvider().getLocalWebserviceClient().searchWithStrictHandling( - Endpoint.class, + Bundle searchResult = api.getDsfClientProvider().getLocal().searchWithStrictHandling(Endpoint.class, Map.of("status", Collections.singletonList("active"), "identifier", Collections.singletonList("http://dsf.dev/sid/endpoint-identifier|"), "_page", Collections.singletonList(String.valueOf(page)))); if (searchResult.getTotal() > currentTotal + searchResult.getEntry().size()) return Stream.concat(toEndpoints(searchResult), - allEndpoints(page + 1, currentTotal + searchResult.getEntry().size())); + allEndpoints(api, page + 1, currentTotal + searchResult.getEntry().size())); else return toEndpoints(searchResult); } diff --git a/src/main/java/dev/dsf/bpe/service/ping/SetPongTimeoutDuration.java b/src/main/java/dev/dsf/bpe/service/ping/SetPongTimeoutDuration.java index 05e2951c..f672478d 100644 --- a/src/main/java/dev/dsf/bpe/service/ping/SetPongTimeoutDuration.java +++ b/src/main/java/dev/dsf/bpe/service/ping/SetPongTimeoutDuration.java @@ -4,28 +4,23 @@ import java.time.format.DateTimeParseException; import java.util.Optional; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.hl7.fhir.r4.model.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import dev.dsf.bpe.CodeSystem; import dev.dsf.bpe.ExecutionVariables; -import dev.dsf.bpe.service.AbstractService; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Variables; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Variables; -public class SetPongTimeoutDuration extends AbstractService +public class SetPongTimeoutDuration implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(SetPongTimeoutDuration.class); - public SetPongTimeoutDuration(ProcessPluginApi api) - { - super(api); - } - @Override - protected void doExecuteWithErrorHandling(DelegateExecution execution, Variables variables) throws Exception + public void execute(ProcessPluginApi api, Variables variables) throws ErrorBoundaryEvent, Exception { logger.debug("Setting pong timer duration..."); Task startTask = variables.getStartTask(); diff --git a/src/main/java/dev/dsf/bpe/service/ping/StoreResults.java b/src/main/java/dev/dsf/bpe/service/ping/StoreResults.java index d49ee395..8e0056dd 100644 --- a/src/main/java/dev/dsf/bpe/service/ping/StoreResults.java +++ b/src/main/java/dev/dsf/bpe/service/ping/StoreResults.java @@ -9,8 +9,6 @@ import java.util.Objects; import java.util.Optional; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.hl7.fhir.r4.model.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,50 +21,52 @@ import dev.dsf.bpe.mail.AggregateErrorMailService; import dev.dsf.bpe.util.ErrorListUtils; import dev.dsf.bpe.util.task.output.generator.PingStatusGenerator; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.activity.AbstractServiceDelegate; -import dev.dsf.bpe.v1.variables.Target; -import dev.dsf.bpe.v1.variables.Targets; -import dev.dsf.bpe.v1.variables.Variables; - -public class StoreResults extends AbstractServiceDelegate implements InitializingBean +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Target; +import dev.dsf.bpe.v2.variables.Targets; +import dev.dsf.bpe.v2.variables.Variables; + +public class StoreResults implements ServiceTask, InitializingBean { private static final Logger logger = LoggerFactory.getLogger(StoreResults.class); private final AggregateErrorMailService errorMailService; - private CodeSystem.DsfPingUnits.Code networkSpeedUnit; + private final CodeSystem.DsfPingUnits.Code networkSpeedUnit; + private final PingStatusGenerator pingStatusGenerator; - public StoreResults(ProcessPluginApi api, AggregateErrorMailService errorMailService, - CodeSystem.DsfPingUnits.Code networkSpeedUnit) + public StoreResults(AggregateErrorMailService errorMailService, CodeSystem.DsfPingUnits.Code networkSpeedUnit, + PingStatusGenerator pingStatusGenerator) { - super(api); this.networkSpeedUnit = networkSpeedUnit; this.errorMailService = errorMailService; + this.pingStatusGenerator = pingStatusGenerator; } @Override public void afterPropertiesSet() throws Exception { - super.afterPropertiesSet(); - Objects.requireNonNull(errorMailService, "errorMailService"); } @Override - protected void doExecute(DelegateExecution execution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi api, Variables variables) throws ErrorBoundaryEvent, Exception { logger.debug("Storing results for process started with Task {}", variables.getStartTask().getIdElement().getValue()); Task task = variables.getStartTask(); Targets targets = variables.getTargets(); Map> errorsPerTarget = new HashMap<>(); + String resourceVersion = api.getProcessPluginDefinition().getResourceVersion(); - ProcessError.toTaskOutput(ErrorListUtils.getErrorList(execution).getEntries()).forEach(task::addOutput); + ProcessError.toTaskOutput(ErrorListUtils.getErrorList(variables).getEntries(), resourceVersion) + .forEach(task::addOutput); targets.getEntries().stream().sorted(Comparator.comparing(Target::getEndpointIdentifierValue)).forEach(target -> { String correlationKey = target.getCorrelationKey(); - ProcessErrors errors = ErrorListUtils.getErrorList(execution, correlationKey); + ProcessErrors errors = ErrorListUtils.getErrorList(variables, correlationKey); CodeSystem.DsfPingStatus.Code statusCode = (CodeSystem.DsfPingStatus.Code) variables .getVariable(ExecutionVariables.statusCode.correlatedValue(correlationKey)); long downloadResourceSizeBytes = variables.getLong(ExecutionVariables.downloadResourceSizeBytes.name()); @@ -97,12 +97,12 @@ protected void doExecute(DelegateExecution execution, Variables variables) throw .map(CodeSystem.DsfPingUnits.Code.SpeedAndUnit::unit).orElse(null); - PingStatusGenerator.createPingStatusOutput(target, statusCode, errors.getEntries(), downloadSpeed, + pingStatusGenerator.createPingStatusOutput(target, statusCode, errors.getEntries(), downloadSpeed, downloadSpeedUnit, uploadSpeed, uploadSpeedUnit).ifPresent(task::addOutput); } else // if slim-ping { - PingStatusGenerator.createPingStatusOutput(target, statusCode, errors.getEntries()) + pingStatusGenerator.createPingStatusOutput(target, statusCode, errors.getEntries()) .ifPresent(task::addOutput); } errorsPerTarget.put(target, errors.getEntries()); diff --git a/src/main/java/dev/dsf/bpe/service/pong/DownloadResourceAndMeasureSpeed.java b/src/main/java/dev/dsf/bpe/service/pong/DownloadResourceAndMeasureSpeed.java index a8670f99..3ee0ed61 100644 --- a/src/main/java/dev/dsf/bpe/service/pong/DownloadResourceAndMeasureSpeed.java +++ b/src/main/java/dev/dsf/bpe/service/pong/DownloadResourceAndMeasureSpeed.java @@ -1,30 +1,23 @@ package dev.dsf.bpe.service.pong; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.hl7.fhir.r4.model.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import dev.dsf.bpe.ConstantsPing; import dev.dsf.bpe.ExecutionVariables; -import dev.dsf.bpe.service.AbstractService; import dev.dsf.bpe.util.BinaryResourceDownloader; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Variables; -import dev.dsf.bpe.variables.duration.DurationValueImpl; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Variables; -public class DownloadResourceAndMeasureSpeed extends AbstractService +public class DownloadResourceAndMeasureSpeed implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(DownloadResourceAndMeasureSpeed.class); - public DownloadResourceAndMeasureSpeed(ProcessPluginApi api) - { - super(api); - } - @Override - protected void doExecuteWithErrorHandling(DelegateExecution delegateExecution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi api, Variables variables) throws ErrorBoundaryEvent, Exception { logger.debug("Starting resource download to measure speed..."); @@ -36,14 +29,14 @@ protected void doExecuteWithErrorHandling(DelegateExecution delegateExecution, V if (downloadResult.getErrorTuple() == null) { variables.setLong(ExecutionVariables.downloadedBytes.name(), downloadResult.getDownloadedBytes()); - variables.setVariable(ExecutionVariables.downloadedDuration.name(), - new DurationValueImpl(downloadResult.getDownloadedDuration())); + variables.setJsonVariable(ExecutionVariables.downloadedDuration.name(), + downloadResult.getDownloadedDuration()); } else { - delegateExecution.setVariable(ExecutionVariables.resourceDownloadError.name(), + variables.setJsonVariable(ExecutionVariables.resourceDownloadError.name(), downloadResult.getErrorTuple().errorLocal()); - delegateExecution.setVariable(ExecutionVariables.resourceDownloadErrorRemote.name(), + variables.setJsonVariable(ExecutionVariables.resourceDownloadErrorRemote.name(), downloadResult.getErrorTuple().errorRemote()); } logger.debug("Completed resource download and measured speed."); diff --git a/src/main/java/dev/dsf/bpe/service/pong/EstimateCleanupTimerDuration.java b/src/main/java/dev/dsf/bpe/service/pong/EstimateCleanupTimerDuration.java index b89b198a..de6a343d 100644 --- a/src/main/java/dev/dsf/bpe/service/pong/EstimateCleanupTimerDuration.java +++ b/src/main/java/dev/dsf/bpe/service/pong/EstimateCleanupTimerDuration.java @@ -3,27 +3,21 @@ import java.time.Duration; import java.util.Optional; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import dev.dsf.bpe.ExecutionVariables; -import dev.dsf.bpe.service.AbstractService; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Variables; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Variables; -public class EstimateCleanupTimerDuration extends AbstractService +public class EstimateCleanupTimerDuration implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(EstimateCleanupTimerDuration.class); - public EstimateCleanupTimerDuration(ProcessPluginApi api) - { - super(api); - } - @Override - protected void doExecuteWithErrorHandling(DelegateExecution delegateExecution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi processPluginApi, Variables variables) throws ErrorBoundaryEvent, Exception { logger.debug("Estimating cleanup timer duration..."); final long minTimerDurationMillis = 20000; diff --git a/src/main/java/dev/dsf/bpe/service/pong/LogAndSaveAndStoreError.java b/src/main/java/dev/dsf/bpe/service/pong/LogAndSaveAndStoreError.java index 263aad20..4d5ca858 100644 --- a/src/main/java/dev/dsf/bpe/service/pong/LogAndSaveAndStoreError.java +++ b/src/main/java/dev/dsf/bpe/service/pong/LogAndSaveAndStoreError.java @@ -1,45 +1,42 @@ package dev.dsf.bpe.service.pong; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.hl7.fhir.r4.model.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import dev.dsf.bpe.ExecutionVariables; import dev.dsf.bpe.ProcessError; -import dev.dsf.bpe.service.AbstractService; import dev.dsf.bpe.util.ErrorListUtils; import dev.dsf.bpe.util.task.output.generator.PingStatusGenerator; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Target; -import dev.dsf.bpe.v1.variables.Variables; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Target; +import dev.dsf.bpe.v2.variables.Variables; -public class LogAndSaveAndStoreError extends AbstractService +public class LogAndSaveAndStoreError implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(LogAndSaveAndStoreError.class); + private final PingStatusGenerator pingStatusGenerator; - public LogAndSaveAndStoreError(ProcessPluginApi api) + public LogAndSaveAndStoreError(PingStatusGenerator pingStatusGenerator) { - super(api); + this.pingStatusGenerator = pingStatusGenerator; } @Override - protected void doExecuteWithErrorHandling(DelegateExecution delegateExecution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi processPluginApi, Variables variables) throws ErrorBoundaryEvent, Exception { Target target = variables.getTarget(); Task startTask = variables.getStartTask(); - ProcessError error = (ProcessError) delegateExecution - .getVariable(ExecutionVariables.resourceDownloadError.name()); - ErrorListUtils.add(error, delegateExecution); + ProcessError error = variables.getVariable(ExecutionVariables.resourceDownloadError.name()); + ErrorListUtils.add(error, variables); - ProcessError errorRemote = (ProcessError) delegateExecution - .getVariable(ExecutionVariables.resourceDownloadErrorRemote.name()); - ErrorListUtils.addRemote(errorRemote, delegateExecution); + ProcessError errorRemote = variables.getVariable(ExecutionVariables.resourceDownloadErrorRemote.name()); + ErrorListUtils.addRemote(errorRemote, variables); - PingStatusGenerator.updatePongStatusOutput(startTask, - ErrorListUtils.getErrorList(delegateExecution).getEntries()); + pingStatusGenerator.updatePongStatusOutput(startTask, ErrorListUtils.getErrorList(variables).getEntries()); variables.updateTask(startTask); logger.info("Error while trying to download resource from {}: {}", target.getEndpointUrl(), diff --git a/src/main/java/dev/dsf/bpe/service/pong/LogAndSaveUploadErrorPong.java b/src/main/java/dev/dsf/bpe/service/pong/LogAndSaveUploadErrorPong.java index 60484a97..8e857191 100644 --- a/src/main/java/dev/dsf/bpe/service/pong/LogAndSaveUploadErrorPong.java +++ b/src/main/java/dev/dsf/bpe/service/pong/LogAndSaveUploadErrorPong.java @@ -1,35 +1,28 @@ package dev.dsf.bpe.service.pong; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import dev.dsf.bpe.ExecutionVariables; import dev.dsf.bpe.ProcessError; -import dev.dsf.bpe.service.AbstractService; import dev.dsf.bpe.util.ErrorListUtils; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Variables; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Variables; -public class LogAndSaveUploadErrorPong extends AbstractService +public class LogAndSaveUploadErrorPong implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(LogAndSaveUploadErrorPong.class); - public LogAndSaveUploadErrorPong(ProcessPluginApi api) - { - super(api); - } - @Override - protected void doExecuteWithErrorHandling(DelegateExecution execution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi processPluginApi, Variables variables) throws ErrorBoundaryEvent, Exception { - ProcessError error = (ProcessError) variables.getVariable(ExecutionVariables.resourceUploadError.name()); - ErrorListUtils.add(error, execution); + ProcessError error = variables.getVariable(ExecutionVariables.resourceUploadError.name()); + ErrorListUtils.add(error, variables); - ProcessError errorRemote = (ProcessError) variables - .getVariable(ExecutionVariables.resourceUploadErrorRemote.name()); - ErrorListUtils.addRemote(errorRemote, execution); + ProcessError errorRemote = variables.getVariable(ExecutionVariables.resourceUploadErrorRemote.name()); + ErrorListUtils.addRemote(errorRemote, variables); logger.info("Error while storing binary resource for download: {}", error.concept().getDisplay()); } diff --git a/src/main/java/dev/dsf/bpe/service/pong/LogPing.java b/src/main/java/dev/dsf/bpe/service/pong/LogPing.java index 0e18158c..72e93ea5 100644 --- a/src/main/java/dev/dsf/bpe/service/pong/LogPing.java +++ b/src/main/java/dev/dsf/bpe/service/pong/LogPing.java @@ -1,7 +1,5 @@ package dev.dsf.bpe.service.pong; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.hl7.fhir.r4.model.Identifier; import org.hl7.fhir.r4.model.Reference; import org.hl7.fhir.r4.model.Task; @@ -9,29 +7,25 @@ import org.slf4j.LoggerFactory; import dev.dsf.bpe.CodeSystem; -import dev.dsf.bpe.service.AbstractService; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Variables; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Variables; -public class LogPing extends AbstractService +public class LogPing implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(LogPing.class); - public LogPing(ProcessPluginApi api) - { - super(api); - } - @Override - protected void doExecuteWithErrorHandling(DelegateExecution execution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi api, Variables variables) throws ErrorBoundaryEvent, Exception { Task task = variables.getLatestTask(); logger.info("PING from {} (endpoint: {})", task.getRequester().getIdentifier().getValue(), - getEndpointIdentifierValue(task)); + getEndpointIdentifierValue(api, task)); } - private String getEndpointIdentifierValue(Task task) + private String getEndpointIdentifierValue(ProcessPluginApi api, Task task) { return api.getTaskHelper() .getFirstInputParameterValue(task, CodeSystem.DsfPing.URL, diff --git a/src/main/java/dev/dsf/bpe/service/pong/SaveTimeoutError.java b/src/main/java/dev/dsf/bpe/service/pong/SaveTimeoutError.java index 3a8d0731..b65aa92f 100644 --- a/src/main/java/dev/dsf/bpe/service/pong/SaveTimeoutError.java +++ b/src/main/java/dev/dsf/bpe/service/pong/SaveTimeoutError.java @@ -1,36 +1,30 @@ package dev.dsf.bpe.service.pong; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import dev.dsf.bpe.CodeSystem; import dev.dsf.bpe.ConstantsPing; import dev.dsf.bpe.ProcessError; -import dev.dsf.bpe.service.AbstractService; import dev.dsf.bpe.util.ErrorListUtils; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Variables; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Variables; -public class SaveTimeoutError extends AbstractService +public class SaveTimeoutError implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(SaveTimeoutError.class); - public SaveTimeoutError(ProcessPluginApi api) - { - super(api); - } - @Override - protected void doExecuteWithErrorHandling(DelegateExecution execution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi processPluginApi, Variables variables) throws ErrorBoundaryEvent, Exception { logger.debug("Storing timeout error..."); ProcessError error = new ProcessError(ConstantsPing.PROCESS_NAME_PONG, CodeSystem.DsfPingError.Concept.CLEANUP_MESSAGE_TIMEOUT, null); - ErrorListUtils.add(error, execution); + ErrorListUtils.add(error, variables); logger.debug("Stored timeout error: {}", error.concept().getDisplay()); } diff --git a/src/main/java/dev/dsf/bpe/service/pong/SelectPongTarget.java b/src/main/java/dev/dsf/bpe/service/pong/SelectPongTarget.java index fa45ac62..76aa306e 100644 --- a/src/main/java/dev/dsf/bpe/service/pong/SelectPongTarget.java +++ b/src/main/java/dev/dsf/bpe/service/pong/SelectPongTarget.java @@ -1,36 +1,32 @@ package dev.dsf.bpe.service.pong; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; +import static dev.dsf.bpe.ConstantsPing.BPMN_ERROR_CODE_TARGET_NOT_ALLOWED; +import static dev.dsf.bpe.ConstantsPing.BPMN_ERROR_MESSAGE_TARGET_NOT_ALLOWED; + import org.hl7.fhir.r4.model.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.InitializingBean; import dev.dsf.bpe.ExecutionVariables; -import dev.dsf.bpe.service.AbstractService; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.constants.CodeSystems.BpmnMessage; -import dev.dsf.bpe.v1.variables.Variables; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.constants.CodeSystems.BpmnMessage; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Variables; -public class SelectPongTarget extends AbstractService implements InitializingBean +public class SelectPongTarget implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(SelectPongTarget.class); - public SelectPongTarget(ProcessPluginApi api) - { - super(api); - } - @Override - protected void doExecuteWithErrorHandling(DelegateExecution execution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi api, Variables variables) throws ErrorBoundaryEvent, Exception { logger.debug("Selecting pong targets..."); Task task = variables.getStartTask(); String correlationKey = api.getTaskHelper() - .getFirstInputParameterStringValue(task, BpmnMessage.URL, BpmnMessage.Codes.CORRELATION_KEY).get(); + .getFirstInputParameterStringValue(task, BpmnMessage.SYSTEM, BpmnMessage.Codes.CORRELATION_KEY).get(); String targetOrganizationIdentifierValue = task.getRequester().getIdentifier().getValue(); String targetEndpointIdentifierValue = variables.getString(ExecutionVariables.targetEndpointIdentifier.name()); @@ -40,7 +36,8 @@ protected void doExecuteWithErrorHandling(DelegateExecution execution, Variables logger.warn( "Pong response target (organization {}, endpoint {}) not found locally or not active, not sending pong", targetOrganizationIdentifierValue, targetEndpointIdentifierValue); - return new BpmnError("target_not_allowed"); + return new ErrorBoundaryEvent(BPMN_ERROR_CODE_TARGET_NOT_ALLOWED, + BPMN_ERROR_MESSAGE_TARGET_NOT_ALLOWED); }); variables.setTarget(variables.createTarget(targetOrganizationIdentifierValue, targetEndpointIdentifierValue, diff --git a/src/main/java/dev/dsf/bpe/service/pong/SetEndpointIdentifier.java b/src/main/java/dev/dsf/bpe/service/pong/SetEndpointIdentifier.java index de6956b6..02ed0f68 100644 --- a/src/main/java/dev/dsf/bpe/service/pong/SetEndpointIdentifier.java +++ b/src/main/java/dev/dsf/bpe/service/pong/SetEndpointIdentifier.java @@ -1,7 +1,5 @@ package dev.dsf.bpe.service.pong; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.hl7.fhir.r4.model.Identifier; import org.hl7.fhir.r4.model.Reference; import org.hl7.fhir.r4.model.Task; @@ -10,32 +8,28 @@ import dev.dsf.bpe.CodeSystem; import dev.dsf.bpe.ExecutionVariables; -import dev.dsf.bpe.service.AbstractService; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Variables; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Variables; -public class SetEndpointIdentifier extends AbstractService +public class SetEndpointIdentifier implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(SetEndpointIdentifier.class); - public SetEndpointIdentifier(ProcessPluginApi api) - { - super(api); - } - @Override - protected void doExecuteWithErrorHandling(DelegateExecution execution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi api, Variables variables) throws ErrorBoundaryEvent, Exception { logger.debug("Setting endpoint identifier..."); Task task = variables.getStartTask(); - String endpointIdentifierValue = getEndpointIdentifierValue(task); + String endpointIdentifierValue = getEndpointIdentifierValue(api, task); variables.setString(ExecutionVariables.targetEndpointIdentifier.name(), endpointIdentifierValue); logger.debug("Set endpoint identifier to " + endpointIdentifierValue); } - private String getEndpointIdentifierValue(Task task) + private String getEndpointIdentifierValue(ProcessPluginApi api, Task task) { return api.getTaskHelper() .getFirstInputParameterValue(task, CodeSystem.DsfPing.URL, diff --git a/src/main/java/dev/dsf/bpe/service/pong/StoreDownloadSpeed.java b/src/main/java/dev/dsf/bpe/service/pong/StoreDownloadSpeed.java index 303cbeaa..8cb5a3c4 100644 --- a/src/main/java/dev/dsf/bpe/service/pong/StoreDownloadSpeed.java +++ b/src/main/java/dev/dsf/bpe/service/pong/StoreDownloadSpeed.java @@ -4,38 +4,38 @@ import java.time.Duration; import java.util.Objects; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.hl7.fhir.r4.model.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import dev.dsf.bpe.CodeSystem; import dev.dsf.bpe.ExecutionVariables; -import dev.dsf.bpe.service.AbstractService; import dev.dsf.bpe.util.task.output.generator.PingStatusGenerator; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Variables; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Variables; -public class StoreDownloadSpeed extends AbstractService +public class StoreDownloadSpeed implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(StoreDownloadSpeed.class); + private final PingStatusGenerator pingStatusGenerator; private CodeSystem.DsfPingUnits.Code networkSpeedUnit; - public StoreDownloadSpeed(ProcessPluginApi api, CodeSystem.DsfPingUnits.Code networkSpeedUnit) + public StoreDownloadSpeed(CodeSystem.DsfPingUnits.Code networkSpeedUnit, PingStatusGenerator pingStatusGenerator) { - super(api); this.networkSpeedUnit = networkSpeedUnit; + this.pingStatusGenerator = pingStatusGenerator; } @Override - protected void doExecuteWithErrorHandling(DelegateExecution execution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi processPluginApi, Variables variables) throws ErrorBoundaryEvent, Exception { Task startTask = variables.getStartTask(); logger.debug("Storing download speed..."); long downloadedBytes = variables.getLong(ExecutionVariables.downloadedBytes.name()); - Duration downloadedDuration = (Duration) variables.getVariable(ExecutionVariables.downloadedDuration.name()); + Duration downloadedDuration = variables.getVariable(ExecutionVariables.downloadedDuration.name()); BigDecimal downloadSpeed = null; if (downloadedDuration != null) @@ -53,7 +53,7 @@ protected void doExecuteWithErrorHandling(DelegateExecution execution, Variables } } - PingStatusGenerator.updatePongStatusOutputDownloadSpeed(startTask, downloadSpeed, networkSpeedUnit); + pingStatusGenerator.updatePongStatusOutputDownloadSpeed(startTask, downloadSpeed, networkSpeedUnit); variables.updateTask(startTask); logger.debug("Stored download speed: " + downloadSpeed + " " + networkSpeedUnit); diff --git a/src/main/java/dev/dsf/bpe/service/pong/StoreErrors.java b/src/main/java/dev/dsf/bpe/service/pong/StoreErrors.java index 571c6881..de9b2027 100644 --- a/src/main/java/dev/dsf/bpe/service/pong/StoreErrors.java +++ b/src/main/java/dev/dsf/bpe/service/pong/StoreErrors.java @@ -3,56 +3,53 @@ import java.util.Map; import java.util.Objects; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.hl7.fhir.r4.model.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; import dev.dsf.bpe.CodeSystem; import dev.dsf.bpe.ExecutionVariables; import dev.dsf.bpe.ProcessErrors; import dev.dsf.bpe.mail.AggregateErrorMailService; -import dev.dsf.bpe.service.AbstractService; import dev.dsf.bpe.util.ErrorListUtils; import dev.dsf.bpe.util.task.output.generator.PingStatusGenerator; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Target; -import dev.dsf.bpe.v1.variables.Variables; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Target; +import dev.dsf.bpe.v2.variables.Variables; -public class StoreErrors extends AbstractService +public class StoreErrors implements ServiceTask, InitializingBean { private static final Logger logger = LoggerFactory.getLogger(StoreErrors.class); private final AggregateErrorMailService errorMailService; + private final PingStatusGenerator pingStatusGenerator; - public StoreErrors(ProcessPluginApi api, AggregateErrorMailService errorMailService) + public StoreErrors(AggregateErrorMailService errorMailService, PingStatusGenerator pingStatusGenerator) { - super(api); - this.errorMailService = errorMailService; + this.pingStatusGenerator = pingStatusGenerator; } @Override public void afterPropertiesSet() throws Exception { - super.afterPropertiesSet(); - Objects.requireNonNull(errorMailService, "errorMailService"); } @Override - protected void doExecuteWithErrorHandling(DelegateExecution execution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi processPluginApi, Variables variables) throws ErrorBoundaryEvent, Exception { Task startTask = variables.getStartTask(); logger.debug("Storing errors..."); - ProcessErrors errors = ErrorListUtils.getErrorList(execution); - PingStatusGenerator.updatePongStatusOutput(startTask, errors.getEntries()); + ProcessErrors errors = ErrorListUtils.getErrorList(variables); + pingStatusGenerator.updatePongStatusOutput(startTask, errors.getEntries()); - CodeSystem.DsfPingStatus.Code status = (CodeSystem.DsfPingStatus.Code) variables - .getVariable(ExecutionVariables.statusCode.name()); - PingStatusGenerator.updatePongStatusOutput(startTask, status); + CodeSystem.DsfPingStatus.Code status = variables.getVariable(ExecutionVariables.statusCode.name()); + pingStatusGenerator.updatePongStatusOutput(startTask, status); variables.updateTask(startTask); diff --git a/src/main/java/dev/dsf/bpe/service/pong/StoreUploadSpeed.java b/src/main/java/dev/dsf/bpe/service/pong/StoreUploadSpeed.java index 6eb70acb..7494ecac 100644 --- a/src/main/java/dev/dsf/bpe/service/pong/StoreUploadSpeed.java +++ b/src/main/java/dev/dsf/bpe/service/pong/StoreUploadSpeed.java @@ -5,8 +5,6 @@ import java.util.Objects; import java.util.Optional; -import org.camunda.bpm.engine.delegate.BpmnError; -import org.camunda.bpm.engine.delegate.DelegateExecution; import org.hl7.fhir.r4.model.DecimalType; import org.hl7.fhir.r4.model.PrimitiveType; import org.hl7.fhir.r4.model.Task; @@ -14,31 +12,33 @@ import org.slf4j.LoggerFactory; import dev.dsf.bpe.CodeSystem; -import dev.dsf.bpe.service.AbstractService; import dev.dsf.bpe.util.task.output.generator.PingStatusGenerator; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Variables; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.activity.ServiceTask; +import dev.dsf.bpe.v2.error.ErrorBoundaryEvent; +import dev.dsf.bpe.v2.variables.Variables; -public class StoreUploadSpeed extends AbstractService +public class StoreUploadSpeed implements ServiceTask { private static final Logger logger = LoggerFactory.getLogger(StoreUploadSpeed.class); + private final PingStatusGenerator pingStatusGenerator; private CodeSystem.DsfPingUnits.Code networkSpeedUnit; - public StoreUploadSpeed(ProcessPluginApi api, CodeSystem.DsfPingUnits.Code networkSpeedUnit) + public StoreUploadSpeed(CodeSystem.DsfPingUnits.Code networkSpeedUnit, PingStatusGenerator pingStatusGenerator) { - super(api); this.networkSpeedUnit = networkSpeedUnit; + this.pingStatusGenerator = pingStatusGenerator; } @Override - protected void doExecuteWithErrorHandling(DelegateExecution delegateExecution, Variables variables) throws BpmnError + public void execute(ProcessPluginApi api, Variables variables) throws ErrorBoundaryEvent, Exception { Task startTask = variables.getStartTask(); Task cleanup = variables.getLatestTask(); logger.debug("Storing upload speed..."); - Optional uploadedBytesTaskInput = getUploadedBytes(cleanup); - Optional uploadedDurationTaskInput = getUploadedDuration(cleanup); + Optional uploadedBytesTaskInput = getUploadedBytes(api, cleanup); + Optional uploadedDurationTaskInput = getUploadedDuration(api, cleanup); long uploadedBytes = uploadedBytesTaskInput.map(PrimitiveType::getValue).orElse(BigDecimal.valueOf(0)) .longValue(); Duration uploadedDuration = uploadedDurationTaskInput @@ -60,19 +60,19 @@ protected void doExecuteWithErrorHandling(DelegateExecution delegateExecution, V } } - PingStatusGenerator.updatePongStatusOutputUploadSpeed(startTask, uploadSpeed, networkSpeedUnit); + pingStatusGenerator.updatePongStatusOutputUploadSpeed(startTask, uploadSpeed, networkSpeedUnit); variables.updateTask(startTask); logger.debug("Stored upload speed: " + uploadSpeed + " " + networkSpeedUnit); } - private Optional getUploadedBytes(Task task) + private Optional getUploadedBytes(ProcessPluginApi api, Task task) { return api.getTaskHelper().getFirstInputParameterValue(task, CodeSystem.DsfPing.URL, CodeSystem.DsfPing.Code.DOWNLOADED_BYTES.getValue(), DecimalType.class); } - private Optional getUploadedDuration(Task task) + private Optional getUploadedDuration(ProcessPluginApi api, Task task) { return api.getTaskHelper().getFirstInputParameterValue(task, CodeSystem.DsfPing.URL, CodeSystem.DsfPing.Code.DOWNLOADED_DURATION_MILLIS.getValue(), org.hl7.fhir.r4.model.Duration.class); diff --git a/src/main/java/dev/dsf/bpe/spring/config/PingConfig.java b/src/main/java/dev/dsf/bpe/spring/config/PingConfig.java index facf729a..d22d2008 100644 --- a/src/main/java/dev/dsf/bpe/spring/config/PingConfig.java +++ b/src/main/java/dev/dsf/bpe/spring/config/PingConfig.java @@ -2,18 +2,16 @@ import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; 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 com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; - import dev.dsf.bpe.CodeSystem; import dev.dsf.bpe.listener.PingPongProcessPluginDeploymentStateListener; +import dev.dsf.bpe.listener.PingStatusGatewayListener; +import dev.dsf.bpe.listener.PongStatusGatewayListener; import dev.dsf.bpe.listener.SetCorrelationKeyListener; import dev.dsf.bpe.mail.AggregateErrorMailService; import dev.dsf.bpe.message.CleanupPongMessage; @@ -44,12 +42,10 @@ import dev.dsf.bpe.service.pong.StoreDownloadSpeed; import dev.dsf.bpe.service.pong.StoreErrors; import dev.dsf.bpe.service.pong.StoreUploadSpeed; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.documentation.ProcessDocumentation; -import dev.dsf.bpe.variables.codesystem.dsfpingstatus.CodeValueSerializer; -import dev.dsf.bpe.variables.duration.DurationValueSerializer; -import dev.dsf.bpe.variables.process_error.ProcessErrorValueSerializer; -import dev.dsf.bpe.variables.process_errors.ProcessErrorsValueSerializer; +import dev.dsf.bpe.util.task.output.generator.PingStatusGenerator; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.documentation.ProcessDocumentation; +import dev.dsf.bpe.v2.spring.ActivityPrototypeBeanCreator; @Configuration public class PingConfig implements InitializingBean @@ -116,6 +112,19 @@ public void afterPropertiesSet() throws Exception fixMaxResourceSizes(); } + @Bean + public static ActivityPrototypeBeanCreator activityPrototypeBeanCreator() + { + return new ActivityPrototypeBeanCreator(SetTargetAndConfigureTimer.class, SendStartPing.class, + SetPongTimeoutDuration.class, SelectPingTargets.class, SendPingMessage.class, + SetCorrelationKeyListener.class, LogPing.class, SelectPongTarget.class, CheckPingTaskStatus.class, + CleanupPongMessage.class, DownloadResourceAndMeasureSpeed.class, + DownloadResourceAndMeasureSpeedInSubProcess.class, Cleanup.class, LogAndSaveAndStoreError.class, + LogAndSaveError.class, EstimateCleanupTimerDuration.class, SavePong.class, SetEndpointIdentifier.class, + LogAndSaveSendError.class, SaveTimeoutError.class, LogAndSaveUploadErrorPing.class, + LogAndSaveUploadErrorPong.class, PingStatusGatewayListener.class, PongStatusGatewayListener.class); + } + @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public PingPongProcessPluginDeploymentStateListener pingPongProcessPluginDeploymentStateListener() @@ -124,17 +133,16 @@ public PingPongProcessPluginDeploymentStateListener pingPongProcessPluginDeploym } @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public SetTargetAndConfigureTimer setTargetAndConfigureTimer() + public PingStatusGenerator pingStatusGenerator() { - return new SetTargetAndConfigureTimer(api); + return new PingStatusGenerator(api.getProcessPluginDefinition().getResourceVersion()); } @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public SendStartPing sendStartPing() + public SendPongMessage sendPongMessage(PingStatusGenerator pingStatusGenerator) { - return new SendStartPing(api); + return new SendPongMessage(pingStatusGenerator); } @Bean @@ -151,231 +159,49 @@ public AggregateErrorMailService aggregateErrorMailServicePong() AggregateErrorMailService.PONG_PROCESS_HAS_ERRORS); } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public SetPongTimeoutDuration setPongTimeoutDuration() - { - return new SetPongTimeoutDuration(api); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public SelectPingTargets selectPingTargets() - { - return new SelectPingTargets(api); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public SendPingMessage sendPing() - { - return new SendPingMessage(api); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public SetCorrelationKeyListener setCorrelationKeyListener() - { - return new SetCorrelationKeyListener(api); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public StoreResults savePingResults() - { - return new StoreResults(api, aggregateErrorMailServicePing(), networkSpeedUnit); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public LogPing logPing() - { - return new LogPing(api); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public SelectPongTarget selectPongTarget() - { - return new SelectPongTarget(api); - } - @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public SendPongMessage sendPong() + public StoreResults savePingResults(PingStatusGenerator pingStatusGenerator) { - return new SendPongMessage(api); + return new StoreResults(aggregateErrorMailServicePing(), networkSpeedUnit, pingStatusGenerator); } @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public CheckPingTaskStatus logAndSaveNoResponse() + public StoreUploadSpeed storeUploadSpeed(PingStatusGenerator pingStatusGenerator) { - return new CheckPingTaskStatus(api); + return new StoreUploadSpeed(networkSpeedUnit, pingStatusGenerator); } - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public CleanupPongMessage cleanupPongMessage() - { - return new CleanupPongMessage(api); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public DownloadResourceAndMeasureSpeed downloadResourceAndMeasureSpeed() - { - return new DownloadResourceAndMeasureSpeed(api); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public DownloadResourceAndMeasureSpeedInSubProcess downloadResourceAndMeasureSpeedInSubProcess() - { - return new DownloadResourceAndMeasureSpeedInSubProcess(api); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public Cleanup cleanup() - { - return new Cleanup(api); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public LogAndSaveAndStoreError logAndSaveAndStoreError() - { - return new LogAndSaveAndStoreError(api); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public LogAndSaveError logAndSaveError() - { - return new LogAndSaveError(api); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public StoreUploadSpeed storeDownloadSpeeds() - { - return new StoreUploadSpeed(api, networkSpeedUnit); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public EstimateCleanupTimerDuration estimateCleanupTimerDuration() - { - return new EstimateCleanupTimerDuration(api); - } @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public SetDownloadResourceSize setDownloadResourceSize() { - return new SetDownloadResourceSize(api, maxDownloadSizeBytes); + return new SetDownloadResourceSize(maxDownloadSizeBytes); } @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public SavePong savePong() + public StoreDownloadSpeed storeDownloadSpeed(PingStatusGenerator pingStatusGenerator) { - return new SavePong(api); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public SetEndpointIdentifier setEndpointIdentifier() - { - return new SetEndpointIdentifier(api); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public StoreDownloadSpeed storeDownloadSpeed() - { - return new StoreDownloadSpeed(api, networkSpeedUnit); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public LogAndSaveSendError logAndSaveSendError() - { - return new LogAndSaveSendError(api); + return new StoreDownloadSpeed(networkSpeedUnit, pingStatusGenerator); } @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public GenerateAndStoreResource generateAndStoreResource() { - return new GenerateAndStoreResource(api, maxUploadSizeBytes); + return new GenerateAndStoreResource(maxUploadSizeBytes); } @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public SaveTimeoutError saveTimeoutError() + public StoreErrors storeErrors(PingStatusGenerator pingStatusGenerator) { - return new SaveTimeoutError(api); + return new StoreErrors(aggregateErrorMailServicePong(), pingStatusGenerator); } - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public StoreErrors storeErrors() - { - return new StoreErrors(api, aggregateErrorMailServicePong()); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public LogAndSaveUploadErrorPing logAndSaveUploadErrorPing() - { - return new LogAndSaveUploadErrorPing(api); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public LogAndSaveUploadErrorPong logAndSaveUploadErrorPong() - { - return new LogAndSaveUploadErrorPong(api); - } - - @Bean - public CodeValueSerializer pingStatusCodeSerializer() - { - return new CodeValueSerializer(); - } - - @Bean - public DurationValueSerializer durationValueSerializer( - @Qualifier(OBJECT_MAPPER_WITH_TIME_MODULE) ObjectMapper objectMapper) - { - return new DurationValueSerializer(objectMapper); - } - - @Bean - public ProcessErrorValueSerializer processErrorValueSerializer() - { - return new ProcessErrorValueSerializer(); - } - - @Bean - public ProcessErrorsValueSerializer processErrorsValueSerializer() - { - return new ProcessErrorsValueSerializer(); - } - - @Bean(name = OBJECT_MAPPER_WITH_TIME_MODULE) - public ObjectMapper objectMapperWithJavaTimeModule() - { - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.registerModule(new JavaTimeModule()); - return objectMapper; - } - - private static final String OBJECT_MAPPER_WITH_TIME_MODULE = "objectMapperWithJavaTimeModule"; - private void fixMaxResourceSizes() { if (getMaxDownloadSizeBytes() < 0) diff --git a/src/main/java/dev/dsf/bpe/util/BinaryResourceDownloader.java b/src/main/java/dev/dsf/bpe/util/BinaryResourceDownloader.java index 01a82a1b..0506bdeb 100644 --- a/src/main/java/dev/dsf/bpe/util/BinaryResourceDownloader.java +++ b/src/main/java/dev/dsf/bpe/util/BinaryResourceDownloader.java @@ -19,8 +19,8 @@ import dev.dsf.bpe.ConstantsPing; import dev.dsf.bpe.ExecutionVariables; import dev.dsf.bpe.ProcessError; -import dev.dsf.bpe.v1.ProcessPluginApi; -import dev.dsf.bpe.v1.variables.Variables; +import dev.dsf.bpe.v2.ProcessPluginApi; +import dev.dsf.bpe.v2.variables.Variables; import jakarta.ws.rs.ProcessingException; import jakarta.ws.rs.WebApplicationException; @@ -63,8 +63,7 @@ public DownloadResult download(Variables variables, ProcessPluginApi api, Task t String webserviceUrl = downloadResourceReferenceIdType.getBaseUrl(); try { - InputStream binaryResourceInputStream = api.getFhirWebserviceClientProvider() - .getWebserviceClient(webserviceUrl) + InputStream binaryResourceInputStream = api.getDsfClientProvider().getByEndpointUrl(webserviceUrl) .readBinary(downloadResourceReferenceId, ConstantsPing.DOWNLOAD_RESOURCE_MIME_TYPE); try (binaryResourceInputStream) diff --git a/src/main/java/dev/dsf/bpe/util/ErrorListUtils.java b/src/main/java/dev/dsf/bpe/util/ErrorListUtils.java index 0df63dc7..edc47a8e 100644 --- a/src/main/java/dev/dsf/bpe/util/ErrorListUtils.java +++ b/src/main/java/dev/dsf/bpe/util/ErrorListUtils.java @@ -1,168 +1,166 @@ package dev.dsf.bpe.util; -import org.camunda.bpm.engine.delegate.DelegateExecution; - import dev.dsf.bpe.ExecutionVariables; import dev.dsf.bpe.ProcessError; import dev.dsf.bpe.ProcessErrors; -import dev.dsf.bpe.variables.process_errors.ProcessErrorsValueImpl; +import dev.dsf.bpe.v2.variables.Variables; public class ErrorListUtils { - public static void addAll(ProcessErrors errors, DelegateExecution execution) + public static void addAll(ProcessErrors errors, Variables variables) { - ProcessErrors errorList = getErrorList(execution); + ProcessErrors errorList = getErrorList(variables); if (errors != null) { errorList.addAll(errors); - saveErrorList(errorList, execution, null); + saveErrorList(errorList, variables, null); } } - public static void addAll(ProcessErrors errors, DelegateExecution execution, String correlationKey) + public static void addAll(ProcessErrors errors, Variables variables, String correlationKey) { - ProcessErrors errorList = correlationKey != null ? getErrorList(execution, correlationKey) - : getErrorList(execution); + ProcessErrors errorList = correlationKey != null ? getErrorList(variables, correlationKey) + : getErrorList(variables); if (errors != null) { errorList.addAll(errors); - saveErrorList(errorList, execution, correlationKey); + saveErrorList(errorList, variables, correlationKey); } } - public static void addAllRemote(ProcessErrors errors, DelegateExecution execution) + public static void addAllRemote(ProcessErrors errors, Variables variables) { - ProcessErrors errorList = getErrorListRemote(execution); + ProcessErrors errorList = getErrorListRemote(variables); if (errors != null) { errorList.addAll(errors); - saveErrorListRemote(errorList, execution, null); + saveErrorListRemote(errorList, variables, null); } } - public static void addAllRemote(ProcessErrors errors, DelegateExecution execution, String correlationKey) + public static void addAllRemote(ProcessErrors errors, Variables variables, String correlationKey) { - ProcessErrors errorList = correlationKey != null ? getErrorListRemote(execution, correlationKey) - : getErrorListRemote(execution); + ProcessErrors errorList = correlationKey != null ? getErrorListRemote(variables, correlationKey) + : getErrorListRemote(variables); if (errors != null) { errorList.addAll(errors); - saveErrorListRemote(errorList, execution, correlationKey); + saveErrorListRemote(errorList, variables, correlationKey); } } - public static void add(ProcessError error, DelegateExecution execution) + public static void add(ProcessError error, Variables variables) { - add(error, execution, null); + add(error, variables, null); } - public static void add(ProcessError error, DelegateExecution execution, String correlationKey) + public static void add(ProcessError error, Variables variables, String correlationKey) { if (correlationKey != null) { - add(error, ExecutionVariables.errors.correlatedValue(correlationKey), execution); + add(error, ExecutionVariables.errors.correlatedValue(correlationKey), variables); } else { - add(error, ExecutionVariables.errors.name(), execution); + add(error, ExecutionVariables.errors.name(), variables); } } - public static void addRemote(ProcessError error, DelegateExecution execution) + public static void addRemote(ProcessError error, Variables variables) { - addRemote(error, execution, null); + addRemote(error, variables, null); } - public static void addRemote(ProcessError error, DelegateExecution execution, String correlationKey) + public static void addRemote(ProcessError error, Variables variables, String correlationKey) { if (correlationKey != null) { - add(error, ExecutionVariables.errorsRemote.correlatedValue(correlationKey), execution); + add(error, ExecutionVariables.errorsRemote.correlatedValue(correlationKey), variables); } else { - add(error, ExecutionVariables.errorsRemote.name(), execution); + add(error, ExecutionVariables.errorsRemote.name(), variables); } } - public static ProcessErrors getErrorList(DelegateExecution execution) + public static ProcessErrors getErrorList(Variables variables) { - return getErrorList(execution, null); + return getErrorList(variables, null); } - public static ProcessErrors getErrorList(DelegateExecution execution, String correlationKey) + public static ProcessErrors getErrorList(Variables variables, String correlationKey) { if (correlationKey != null) { - return getErrorList(ExecutionVariables.errors.correlatedValue(correlationKey), execution); + return getErrorList(ExecutionVariables.errors.correlatedValue(correlationKey), variables); } else { - return getErrorList(ExecutionVariables.errors.name(), execution); + return getErrorList(ExecutionVariables.errors.name(), variables); } } - public static ProcessErrors getErrorListRemote(DelegateExecution execution) + public static ProcessErrors getErrorListRemote(Variables variables) { - return getErrorListRemote(execution, null); + return getErrorListRemote(variables, null); } - public static ProcessErrors getErrorListRemote(DelegateExecution execution, String correlationKey) + public static ProcessErrors getErrorListRemote(Variables variables, String correlationKey) { if (correlationKey != null) { - return getErrorList(ExecutionVariables.errorsRemote.correlatedValue(correlationKey), execution); + return getErrorList(ExecutionVariables.errorsRemote.correlatedValue(correlationKey), variables); } else { - return getErrorList(ExecutionVariables.errorsRemote.name(), execution); + return getErrorList(ExecutionVariables.errorsRemote.name(), variables); } } - public static ProcessErrors getErrorList(String variableName, DelegateExecution execution) + public static ProcessErrors getErrorList(String variableName, Variables variables) { - ProcessErrors errors = (ProcessErrors) execution.getVariable(variableName); + ProcessErrors errors = variables.getVariable(variableName); if (errors == null) { errors = new ProcessErrors(); - saveErrorList(errors, variableName, execution); + saveErrorList(errors, variableName, variables); } return errors; } - public static void add(ProcessError error, String variableName, DelegateExecution execution) + public static void add(ProcessError error, String variableName, Variables variables) { - ProcessErrors errors = getErrorList(variableName, execution); + ProcessErrors errors = getErrorList(variableName, variables); errors.add(error); - saveErrorList(errors, variableName, execution); + saveErrorList(errors, variableName, variables); } - private static void saveErrorList(ProcessErrors errors, DelegateExecution execution, String correlationKey) + private static void saveErrorList(ProcessErrors errors, Variables variables, String correlationKey) { if (correlationKey != null) { - saveErrorList(errors, ExecutionVariables.errors.correlatedValue(correlationKey), execution); + saveErrorList(errors, ExecutionVariables.errors.correlatedValue(correlationKey), variables); } else { - saveErrorList(errors, ExecutionVariables.errors.name(), execution); + saveErrorList(errors, ExecutionVariables.errors.name(), variables); } } - private static void saveErrorListRemote(ProcessErrors errors, DelegateExecution execution, String correlationKey) + private static void saveErrorListRemote(ProcessErrors errors, Variables variables, String correlationKey) { if (correlationKey != null) { - saveErrorList(errors, ExecutionVariables.errorsRemote.correlatedValue(correlationKey), execution); + saveErrorList(errors, ExecutionVariables.errorsRemote.correlatedValue(correlationKey), variables); } else { - saveErrorList(errors, ExecutionVariables.errorsRemote.name(), execution); + saveErrorList(errors, ExecutionVariables.errorsRemote.name(), variables); } } - private static void saveErrorList(ProcessErrors errors, String variableName, DelegateExecution execution) + private static void saveErrorList(ProcessErrors errors, String variableName, Variables variables) { - execution.setVariable(variableName, new ProcessErrorsValueImpl(errors)); + variables.setJsonVariable(variableName, errors); } } diff --git a/src/main/java/dev/dsf/bpe/util/task/input/generator/DownloadResourceReferenceGenerator.java b/src/main/java/dev/dsf/bpe/util/task/input/generator/DownloadResourceReferenceGenerator.java index a8e2a09f..ee2ab3a1 100644 --- a/src/main/java/dev/dsf/bpe/util/task/input/generator/DownloadResourceReferenceGenerator.java +++ b/src/main/java/dev/dsf/bpe/util/task/input/generator/DownloadResourceReferenceGenerator.java @@ -11,13 +11,13 @@ private DownloadResourceReferenceGenerator() { } - public static Task.ParameterComponent create(String uri) + public static Task.ParameterComponent create(String uri, String resourceVersion) { Reference reference = new Reference(uri); reference.setType("Binary"); Task.ParameterComponent param = new Task.ParameterComponent(); - param.setValue(reference).getType() - .addCoding(CodeSystem.DsfPing.fromCode(CodeSystem.DsfPing.Code.DOWNLOAD_RESOURCE_REFERENCE)); + param.setValue(reference).getType().addCoding( + CodeSystem.DsfPing.fromCode(CodeSystem.DsfPing.Code.DOWNLOAD_RESOURCE_REFERENCE, resourceVersion)); return param; } } diff --git a/src/main/java/dev/dsf/bpe/util/task/input/generator/DownloadResourceSizeGenerator.java b/src/main/java/dev/dsf/bpe/util/task/input/generator/DownloadResourceSizeGenerator.java index 53429582..1825d346 100644 --- a/src/main/java/dev/dsf/bpe/util/task/input/generator/DownloadResourceSizeGenerator.java +++ b/src/main/java/dev/dsf/bpe/util/task/input/generator/DownloadResourceSizeGenerator.java @@ -11,11 +11,11 @@ private DownloadResourceSizeGenerator() { } - public static Task.ParameterComponent create(long sizeBytes) + public static Task.ParameterComponent create(long sizeBytes, String resourceVersion) { Task.ParameterComponent param = new Task.ParameterComponent(); - param.setValue(new DecimalType(sizeBytes)).getType() - .addCoding(CodeSystem.DsfPing.fromCode(CodeSystem.DsfPing.Code.DOWNLOAD_RESOURCE_SIZE_BYTES)); + param.setValue(new DecimalType(sizeBytes)).getType().addCoding( + CodeSystem.DsfPing.fromCode(CodeSystem.DsfPing.Code.DOWNLOAD_RESOURCE_SIZE_BYTES, resourceVersion)); return param; } } diff --git a/src/main/java/dev/dsf/bpe/util/task/input/generator/DownloadedBytesGenerator.java b/src/main/java/dev/dsf/bpe/util/task/input/generator/DownloadedBytesGenerator.java index e8f22422..c20ce9ce 100644 --- a/src/main/java/dev/dsf/bpe/util/task/input/generator/DownloadedBytesGenerator.java +++ b/src/main/java/dev/dsf/bpe/util/task/input/generator/DownloadedBytesGenerator.java @@ -4,7 +4,6 @@ import org.hl7.fhir.r4.model.Task; import dev.dsf.bpe.CodeSystem; -import dev.dsf.bpe.PingProcessPluginDefinition; public final class DownloadedBytesGenerator { @@ -12,12 +11,11 @@ private DownloadedBytesGenerator() { } - public static Task.ParameterComponent create(long bytes) + public static Task.ParameterComponent create(long bytes, String resourceVersion) { Task.ParameterComponent param = new Task.ParameterComponent(); param.setValue(new DecimalType(bytes)).getType().addCoding().setSystem(CodeSystem.DsfPing.URL) - .setCode(CodeSystem.DsfPing.Code.DOWNLOADED_BYTES.getValue()) - .setVersion(PingProcessPluginDefinition.RESOURCE_VERSION); + .setCode(CodeSystem.DsfPing.Code.DOWNLOADED_BYTES.getValue()).setVersion(resourceVersion); return param; } } diff --git a/src/main/java/dev/dsf/bpe/util/task/input/generator/DownloadedDurationGenerator.java b/src/main/java/dev/dsf/bpe/util/task/input/generator/DownloadedDurationGenerator.java index b24288f5..c9bf2e7e 100644 --- a/src/main/java/dev/dsf/bpe/util/task/input/generator/DownloadedDurationGenerator.java +++ b/src/main/java/dev/dsf/bpe/util/task/input/generator/DownloadedDurationGenerator.java @@ -5,7 +5,6 @@ import org.hl7.fhir.r4.model.Task; import dev.dsf.bpe.CodeSystem; -import dev.dsf.bpe.PingProcessPluginDefinition; public final class DownloadedDurationGenerator { @@ -16,13 +15,12 @@ private DownloadedDurationGenerator() { } - public static Task.ParameterComponent create(Duration duration) + public static Task.ParameterComponent create(Duration duration, String resourceVersion) { Task.ParameterComponent param = new Task.ParameterComponent(); param.setValue(new org.hl7.fhir.r4.model.Duration().setValue(duration.toMillis()).setSystem(CODESYSTEM_UCUM) .setCode(CODESYSTEM_UCUM_CODE_MILLISECONDS)).getType().addCoding().setSystem(CodeSystem.DsfPing.URL) - .setCode(CodeSystem.DsfPing.Code.DOWNLOADED_DURATION_MILLIS.getValue()) - .setVersion(PingProcessPluginDefinition.RESOURCE_VERSION); + .setCode(CodeSystem.DsfPing.Code.DOWNLOADED_DURATION_MILLIS.getValue()).setVersion(resourceVersion); return param; } } diff --git a/src/main/java/dev/dsf/bpe/util/task/input/generator/ErrorInputComponentGenerator.java b/src/main/java/dev/dsf/bpe/util/task/input/generator/ErrorInputComponentGenerator.java index eb821935..8954f517 100644 --- a/src/main/java/dev/dsf/bpe/util/task/input/generator/ErrorInputComponentGenerator.java +++ b/src/main/java/dev/dsf/bpe/util/task/input/generator/ErrorInputComponentGenerator.java @@ -17,19 +17,20 @@ private ErrorInputComponentGenerator() { } - public static List create(List errors) + public static List create(List errors, String resourceVersion) { if (errors == null || errors.isEmpty()) return List.of(); - return errors.stream().map(ErrorInputComponentGenerator::create).collect(Collectors.toList()); + return errors.stream().map(e -> ErrorInputComponentGenerator.create(e, resourceVersion)) + .collect(Collectors.toList()); } - public static Task.ParameterComponent create(ProcessError error) + public static Task.ParameterComponent create(ProcessError error, String resourceVersion) { Task.ParameterComponent param = new Task.ParameterComponent(); - param.getType().addCoding(CodeSystem.DsfPing.fromCode(CodeSystem.DsfPing.Code.ERROR)); - param.addExtension(ProcessError.toExtension(error)); + param.getType().addCoding(CodeSystem.DsfPing.fromCode(CodeSystem.DsfPing.Code.ERROR, resourceVersion)); + param.addExtension(ProcessError.toExtension(error, resourceVersion)); Extension dataAbsentReason = new Extension() .setUrl("http://hl7.org/fhir/StructureDefinition/data-absent-reason") .setValue(new CodeType("not-applicable")); diff --git a/src/main/java/dev/dsf/bpe/util/task/output/generator/PingStatusGenerator.java b/src/main/java/dev/dsf/bpe/util/task/output/generator/PingStatusGenerator.java index 46395923..3a42a045 100644 --- a/src/main/java/dev/dsf/bpe/util/task/output/generator/PingStatusGenerator.java +++ b/src/main/java/dev/dsf/bpe/util/task/output/generator/PingStatusGenerator.java @@ -17,21 +17,22 @@ import dev.dsf.bpe.CodeSystem; import dev.dsf.bpe.ConstantsPing; -import dev.dsf.bpe.PingProcessPluginDefinition; import dev.dsf.bpe.ProcessError; -import dev.dsf.bpe.v1.constants.NamingSystems.EndpointIdentifier; -import dev.dsf.bpe.v1.constants.NamingSystems.OrganizationIdentifier; -import dev.dsf.bpe.v1.variables.Target; +import dev.dsf.bpe.v2.constants.NamingSystems.EndpointIdentifier; +import dev.dsf.bpe.v2.constants.NamingSystems.OrganizationIdentifier; +import dev.dsf.bpe.v2.variables.Target; public final class PingStatusGenerator { - private static final String CODESYSTEM_UCUM = "http://unitsofmeasure.org"; + private final String CODESYSTEM_UCUM = "http://unitsofmeasure.org"; + private final String resourceVersion; - private PingStatusGenerator() + public PingStatusGenerator(String resourceVersion) { + this.resourceVersion = resourceVersion; } - public static Task updatePongStatusOutput(Task task, List errors) + public Task updatePongStatusOutput(Task task, List errors) { List pongStatusOutputs = getOutputsByExtensionUrlAndCodes(task, CodeSystem.DsfPing.Code.PONG_STATUS.getValue()); @@ -54,7 +55,7 @@ public static Task updatePongStatusOutput(Task task, List errors) return task; } - public static TaskOutputComponent updateStatusOutput(TaskOutputComponent output, List errors) + public TaskOutputComponent updateStatusOutput(TaskOutputComponent output, List errors) { if (output != null) { @@ -74,7 +75,7 @@ public static TaskOutputComponent updateStatusOutput(TaskOutputComponent output, return output; } - public static Task updatePongStatusOutput(Task task, CodeSystem.DsfPingStatus.Code statusCode) + public Task updatePongStatusOutput(Task task, CodeSystem.DsfPingStatus.Code statusCode) { List pongStatusOutputs = getOutputsByExtensionUrlAndCodes(task, CodeSystem.DsfPing.Code.PONG_STATUS.getValue()); @@ -97,7 +98,7 @@ public static Task updatePongStatusOutput(Task task, CodeSystem.DsfPingStatus.Co return task; } - private static TaskOutputComponent updatePongStatusOutput(TaskOutputComponent outputComponent, + private TaskOutputComponent updatePongStatusOutput(TaskOutputComponent outputComponent, CodeSystem.DsfPingStatus.Code statusCode) { if (hasStatusCodeSet(outputComponent)) @@ -112,7 +113,7 @@ private static TaskOutputComponent updatePongStatusOutput(TaskOutputComponent ou return outputComponent; } - public static Task updatePongStatusOutput(Task task, Target target) + public Task updatePongStatusOutput(Task task, Target target) { List outputs = getOutputsByExtensionUrlAndCodes(task, CodeSystem.DsfPing.Code.PONG_STATUS.getValue()); @@ -135,7 +136,7 @@ public static Task updatePongStatusOutput(Task task, Target target) return task; } - private static TaskOutputComponent updateStatusOutput(TaskOutputComponent outputComponent, Target target) + private TaskOutputComponent updateStatusOutput(TaskOutputComponent outputComponent, Target target) { if (hasTargetSet(outputComponent)) { @@ -148,7 +149,7 @@ private static TaskOutputComponent updateStatusOutput(TaskOutputComponent output return outputComponent; } - public static Task updatePongStatusOutputDownloadSpeed(Task task, BigDecimal downloadSpeed, + public Task updatePongStatusOutputDownloadSpeed(Task task, BigDecimal downloadSpeed, CodeSystem.DsfPingUnits.Code networkSpeedUnit) { List outputs = getOutputsByExtensionUrlAndCodes(task, @@ -172,7 +173,7 @@ public static Task updatePongStatusOutputDownloadSpeed(Task task, BigDecimal dow return task; } - private static TaskOutputComponent updateStatusOutputDownloadSpeed(TaskOutputComponent outputComponent, + private TaskOutputComponent updateStatusOutputDownloadSpeed(TaskOutputComponent outputComponent, BigDecimal downloadSpeed, CodeSystem.DsfPingUnits.Code networkSpeedUnit) { if (hasDownloadSpeedSet(outputComponent)) @@ -190,7 +191,7 @@ private static TaskOutputComponent updateStatusOutputDownloadSpeed(TaskOutputCom return outputComponent; } - public static Task updatePongStatusOutputUploadSpeed(Task task, BigDecimal uploadSpeed, + public Task updatePongStatusOutputUploadSpeed(Task task, BigDecimal uploadSpeed, CodeSystem.DsfPingUnits.Code networkSpeedUnit) { List outputs = getOutputsByExtensionUrlAndCodes(task, @@ -214,7 +215,7 @@ public static Task updatePongStatusOutputUploadSpeed(Task task, BigDecimal uploa return task; } - private static TaskOutputComponent updateStatusOutputUploadSpeed(TaskOutputComponent outputComponent, + private TaskOutputComponent updateStatusOutputUploadSpeed(TaskOutputComponent outputComponent, BigDecimal uploadSpeed, CodeSystem.DsfPingUnits.Code networkSpeedUnit) { if (hasDownloadSpeedSet(outputComponent)) @@ -231,7 +232,7 @@ private static TaskOutputComponent updateStatusOutputUploadSpeed(TaskOutputCompo return outputComponent; } - private static boolean hasTargetSet(TaskOutputComponent outputComponent) + private boolean hasTargetSet(TaskOutputComponent outputComponent) { List correlationKeyExtensions = outputComponent .getExtensionsByUrl(ConstantsPing.EXTENSION_URL_CORRELATION_KEY); @@ -243,7 +244,7 @@ private static boolean hasTargetSet(TaskOutputComponent outputComponent) || !endpointIdentifierExtensions.isEmpty(); } - private static boolean hasStatusCodeSet(TaskOutputComponent outputComponent) + private boolean hasStatusCodeSet(TaskOutputComponent outputComponent) { Type valueType = outputComponent.getValue(); List outputTypeCodings = outputComponent.getType().getCoding(); @@ -252,7 +253,7 @@ private static boolean hasStatusCodeSet(TaskOutputComponent outputComponent) || outputTypeCodings.stream().anyMatch(coding -> CodeSystem.DsfPing.URL.equals(coding.getSystem())); } - private static boolean hasDownloadSpeedSet(TaskOutputComponent outputComponent) + private boolean hasDownloadSpeedSet(TaskOutputComponent outputComponent) { Extension extension = getOrCreatePingStatusExtension(outputComponent); Extension downloadSpeedExtension = extension.getExtensionByUrl(ConstantsPing.EXTENSION_URL_DOWNLOAD_SPEED); @@ -260,16 +261,16 @@ private static boolean hasDownloadSpeedSet(TaskOutputComponent outputComponent) return downloadSpeedExtension != null; } - public static Optional createPingStatusOutput(Target target, - CodeSystem.DsfPingStatus.Code statusCode, List errors) + public Optional createPingStatusOutput(Target target, CodeSystem.DsfPingStatus.Code statusCode, + List errors) { return createStatusOutput(target, CodeSystem.DsfPing.Code.PING_STATUS, statusCode, errors, null, null, null, null, null, null, null, null); } - public static Optional createPingStatusOutput(Target target, - CodeSystem.DsfPingStatus.Code statusCode, List errors, BigDecimal downloadSpeed, - CodeSystem.DsfPingUnits.Code downloadUnit, BigDecimal uploadSpeed, CodeSystem.DsfPingUnits.Code uploadUnit) + public Optional createPingStatusOutput(Target target, CodeSystem.DsfPingStatus.Code statusCode, + List errors, BigDecimal downloadSpeed, CodeSystem.DsfPingUnits.Code downloadUnit, + BigDecimal uploadSpeed, CodeSystem.DsfPingUnits.Code uploadUnit) { return createStatusOutput(target, CodeSystem.DsfPing.Code.PING_STATUS, statusCode, errors, downloadSpeed, @@ -279,18 +280,17 @@ public static Optional createPingStatusOutput(Target target uploadUnit != null ? uploadUnit.toUcum() : null); } - public static Optional createPongStatusOutput(Target target, - CodeSystem.DsfPingStatus.Code statusCode, List errors) + public Optional createPongStatusOutput(Target target, CodeSystem.DsfPingStatus.Code statusCode, + List errors) { return createStatusOutput(target, CodeSystem.DsfPing.Code.PONG_STATUS, statusCode, errors, null, null, null, null, null, null, null, null); } - private static Optional createStatusOutput(Target target, - CodeSystem.DsfPing.Code outputParameter, CodeSystem.DsfPingStatus.Code statusCode, - List errors, BigDecimal downloadSpeed, String downloadUnit, String downloadUnitSystem, - String downloadUnitCode, BigDecimal uploadSpeed, String uploadUnit, String uploadUnitSystem, - String uploadUnitCode) + private Optional createStatusOutput(Target target, CodeSystem.DsfPing.Code outputParameter, + CodeSystem.DsfPingStatus.Code statusCode, List errors, BigDecimal downloadSpeed, + String downloadUnit, String downloadUnitSystem, String downloadUnitCode, BigDecimal uploadSpeed, + String uploadUnit, String uploadUnitSystem, String uploadUnitCode) { if (statusCode == null) return Optional.empty(); @@ -305,31 +305,30 @@ private static Optional createStatusOutput(Target target, return Optional.of(output); } - private static TaskOutputComponent addStatus(TaskOutputComponent outputComponent, - CodeSystem.DsfPing.Code outputParameter, CodeSystem.DsfPingStatus.Code statusCode) + private TaskOutputComponent addStatus(TaskOutputComponent outputComponent, CodeSystem.DsfPing.Code outputParameter, + CodeSystem.DsfPingStatus.Code statusCode) { if (outputParameter != null && statusCode != null) { - outputComponent.setValue(CodeSystem.DsfPingStatus.fromCode(statusCode)); - outputComponent.getType().addCoding(CodeSystem.DsfPing.fromCode(outputParameter)); + outputComponent.setValue(CodeSystem.DsfPingStatus.fromCode(statusCode, resourceVersion)); + outputComponent.getType().addCoding(CodeSystem.DsfPing.fromCode(outputParameter, resourceVersion)); sortStatusOutputExtensions(outputComponent); } return outputComponent; } - private static TaskOutputComponent updateStatus(TaskOutputComponent outputComponent, String outputParameter, + private TaskOutputComponent updateStatus(TaskOutputComponent outputComponent, String outputParameter, CodeSystem.DsfPingStatus.Code statusCode) { Type valueType = outputComponent.getValue(); if (valueType instanceof Coding coding) { - coding.setSystem(CodeSystem.DsfPingStatus.URL).setCode(statusCode.getValue()) - .setVersion(PingProcessPluginDefinition.RESOURCE_VERSION); + coding.setSystem(CodeSystem.DsfPingStatus.URL).setCode(statusCode.getValue()).setVersion(resourceVersion); } else { - outputComponent.setValue(CodeSystem.DsfPingStatus.fromCode(statusCode)); + outputComponent.setValue(CodeSystem.DsfPingStatus.fromCode(statusCode, resourceVersion)); } List outputTypeCodings = outputComponent.getType().getCoding(); @@ -355,7 +354,7 @@ private static TaskOutputComponent updateStatus(TaskOutputComponent outputCompon return outputComponent; } - private static TaskOutputComponent addTarget(TaskOutputComponent outputComponent, Target target) + private TaskOutputComponent addTarget(TaskOutputComponent outputComponent, Target target) { if (target != null) { @@ -373,7 +372,7 @@ private static TaskOutputComponent addTarget(TaskOutputComponent outputComponent return outputComponent; } - private static TaskOutputComponent updateTarget(TaskOutputComponent outputComponent, Target target) + private TaskOutputComponent updateTarget(TaskOutputComponent outputComponent, Target target) { Extension extension = getOrCreatePingStatusExtension(outputComponent); @@ -415,7 +414,7 @@ private static TaskOutputComponent updateTarget(TaskOutputComponent outputCompon return outputComponent; } - private static TaskOutputComponent addErrors(TaskOutputComponent outputComponent, List errors) + private TaskOutputComponent addErrors(TaskOutputComponent outputComponent, List errors) { if (errors != null && !errors.isEmpty()) { @@ -423,21 +422,21 @@ private static TaskOutputComponent addErrors(TaskOutputComponent outputComponent Extension errorsExtension = getOrCreateErrorsExtension(extension); for (ProcessError error : errors) { - errorsExtension.addExtension(ProcessError.toExtension(error)); + errorsExtension.addExtension(ProcessError.toExtension(error, resourceVersion)); } } sortStatusOutputExtensions(outputComponent); return outputComponent; } - private static TaskOutputComponent updateErrors(TaskOutputComponent outputComponent, List errors) + private TaskOutputComponent updateErrors(TaskOutputComponent outputComponent, List errors) { Extension extension = getOrCreatePingStatusExtension(outputComponent); Extension errorsExtension = getOrCreateErrorsExtension(extension); if (errors != null) { - List newErrorExtensions = errors.stream().map(ProcessError::toExtension) + List newErrorExtensions = errors.stream().map(e -> ProcessError.toExtension(e, resourceVersion)) .collect(Collectors.toCollection(ArrayList::new)); errorsExtension.setExtension(newErrorExtensions); } @@ -446,7 +445,7 @@ private static TaskOutputComponent updateErrors(TaskOutputComponent outputCompon return outputComponent; } - private static TaskOutputComponent addNetworkSpeed(TaskOutputComponent outputComponent, BigDecimal downloadSpeed, + private TaskOutputComponent addNetworkSpeed(TaskOutputComponent outputComponent, BigDecimal downloadSpeed, String downloadUnit, String downloadUnitSystem, String downloadUnitCode, BigDecimal uploadSpeed, String uploadUnit, String uploadUnitSystem, String uploadUnitCode) { @@ -456,7 +455,7 @@ private static TaskOutputComponent addNetworkSpeed(TaskOutputComponent outputCom return outputComponent; } - private static TaskOutputComponent addDownloadSpeed(TaskOutputComponent outputComponent, BigDecimal downloadSpeed, + private TaskOutputComponent addDownloadSpeed(TaskOutputComponent outputComponent, BigDecimal downloadSpeed, String unit, String unitSystem, String unitCode) { if (downloadSpeed != null && unit != null && unitSystem != null && unitCode != null) @@ -476,8 +475,8 @@ private static TaskOutputComponent addDownloadSpeed(TaskOutputComponent outputCo return outputComponent; } - private static TaskOutputComponent updateDownloadSpeed(TaskOutputComponent outputComponent, - BigDecimal downloadSpeed, String unit, String unitSystem, String unitCode) + private TaskOutputComponent updateDownloadSpeed(TaskOutputComponent outputComponent, BigDecimal downloadSpeed, + String unit, String unitSystem, String unitCode) { if (downloadSpeed != null && unit != null && unitSystem != null && unitCode != null) { @@ -508,8 +507,8 @@ private static TaskOutputComponent updateDownloadSpeed(TaskOutputComponent outpu return outputComponent; } - private static TaskOutputComponent addUploadSpeed(TaskOutputComponent outputComponent, BigDecimal uploadSpeed, - String unit, String unitSystem, String unitCode) + private TaskOutputComponent addUploadSpeed(TaskOutputComponent outputComponent, BigDecimal uploadSpeed, String unit, + String unitSystem, String unitCode) { if (uploadSpeed != null && unit != null && unitSystem != null && unitCode != null) { @@ -527,7 +526,7 @@ private static TaskOutputComponent addUploadSpeed(TaskOutputComponent outputComp return outputComponent; } - private static TaskOutputComponent updateUploadSpeed(TaskOutputComponent outputComponent, BigDecimal uploadSpeed, + private TaskOutputComponent updateUploadSpeed(TaskOutputComponent outputComponent, BigDecimal uploadSpeed, String unit, String unitSystem, String unitCode) { if (uploadSpeed != null && unit != null && unitSystem != null && unitCode != null) @@ -561,7 +560,7 @@ private static TaskOutputComponent updateUploadSpeed(TaskOutputComponent outputC return outputComponent; } - private static Extension getOrCreatePingStatusExtension(TaskOutputComponent outputComponent) + private Extension getOrCreatePingStatusExtension(TaskOutputComponent outputComponent) { Optional optionalExtension = getPingStatusExtension(outputComponent); if (optionalExtension.isPresent()) @@ -576,7 +575,7 @@ private static Extension getOrCreatePingStatusExtension(TaskOutputComponent outp } } - private static Optional getPingStatusExtension(TaskOutputComponent outputComponent) + private Optional getPingStatusExtension(TaskOutputComponent outputComponent) { List pingStatusExtensions = outputComponent.getExtension().stream().filter( extension -> ConstantsPing.STRUCTURE_DEFINITION_URL_EXTENSION_PING_STATUS.equals(extension.getUrl())) @@ -599,7 +598,7 @@ private static Optional getPingStatusExtension(TaskOutputComponent ou } } - private static Extension getOrCreateErrorsExtension(Extension extension) + private Extension getOrCreateErrorsExtension(Extension extension) { Optional optionalExtension = getErrorsExtension(extension); if (optionalExtension.isPresent()) @@ -614,7 +613,7 @@ private static Extension getOrCreateErrorsExtension(Extension extension) } } - private static Optional getErrorsExtension(Extension extension) + private Optional getErrorsExtension(Extension extension) { List errorsExtensions = extension.getExtension().stream() .filter(ex -> ConstantsPing.EXTENSION_URL_ERRORS.equals(ex.getUrl())).toList(); @@ -635,7 +634,7 @@ private static Optional getErrorsExtension(Extension extension) } } - private static List getOutputsByExtensionUrlAndCodes(Task task, String... codes) + private List getOutputsByExtensionUrlAndCodes(Task task, String... codes) { return task.getOutput().stream() .filter(outputComponent -> outputComponent.getType().getCoding().stream() @@ -647,7 +646,7 @@ private static List getOutputsByExtensionUrlAndCodes(T .collect(Collectors.toCollection(ArrayList::new)); } - private static void sortStatusOutputExtensions(TaskOutputComponent outputComponent) + private void sortStatusOutputExtensions(TaskOutputComponent outputComponent) { Optional optPingStatusExtension = getPingStatusExtension(outputComponent); if (optPingStatusExtension.isPresent()) diff --git a/src/main/java/dev/dsf/bpe/variables/GenericPrimitiveTypeSerializer.java b/src/main/java/dev/dsf/bpe/variables/GenericPrimitiveTypeSerializer.java deleted file mode 100644 index 9702968b..00000000 --- a/src/main/java/dev/dsf/bpe/variables/GenericPrimitiveTypeSerializer.java +++ /dev/null @@ -1,100 +0,0 @@ -package dev.dsf.bpe.variables; - -import java.lang.reflect.InvocationTargetException; -import java.util.Objects; - -import org.camunda.bpm.engine.impl.variable.serializer.PrimitiveValueSerializer; -import org.camunda.bpm.engine.impl.variable.serializer.ValueFields; -import org.camunda.bpm.engine.variable.impl.value.PrimitiveTypeValueImpl; -import org.camunda.bpm.engine.variable.impl.value.UntypedValueImpl; -import org.camunda.bpm.engine.variable.type.PrimitiveValueType; -import org.camunda.bpm.engine.variable.value.PrimitiveValue; -import org.springframework.beans.factory.InitializingBean; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - -public abstract class GenericPrimitiveTypeSerializer & PrimitiveValue> - extends PrimitiveValueSerializer implements InitializingBean -{ - private final ObjectMapper objectMapper; - private final Class typeClass; - private final Class valueClass; - private final PrimitiveValueType primitiveValueType; - - public GenericPrimitiveTypeSerializer(PrimitiveValueType variableType, ObjectMapper objectMapper, - Class typeClass, Class valueClass) - { - super(variableType); - this.objectMapper = objectMapper; - this.typeClass = typeClass; - this.valueClass = valueClass; - this.primitiveValueType = variableType; - } - - @Override - public void afterPropertiesSet() - { - Objects.requireNonNull(objectMapper); - } - - @Override - public T readValue(ValueFields valueFields, boolean asTransientValue) - { - try - { - byte[] bytes = valueFields.getByteArrayValue(); - return (bytes == null || bytes.length == 0) ? null - : typeClass.getConstructor(valueClass, PrimitiveValueType.class) - .newInstance(objectMapper.readValue(bytes, valueClass), primitiveValueType); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - - @Override - public void writeValue(T value, ValueFields valueFields) - { - try - { - valueFields.setByteArrayValue(objectMapper.writeValueAsBytes(value.getValue())); - } - catch (JsonProcessingException e) - { - throw new RuntimeException(e); - } - } - - @Override - public T convertToTypedValue(UntypedValueImpl untypedValue) - { - try - { - if (untypedValue != null && typeClass.isAssignableFrom(untypedValue.getValue().getClass())) - { - T typedValue = typeClass.cast(untypedValue.getValue()); - - return typeClass.getConstructor(typeClass, primitiveValueType.getClass()).newInstance(typedValue, - primitiveValueType); - - } - else if (untypedValue != null) - { - throw new IllegalArgumentException("Cannot convert " - + untypedValue.getValue().getClass().getSimpleName() + " to " + typeClass.getSimpleName()); - } - throw new IllegalArgumentException("Cannot convert " + null + " to " + typeClass.getSimpleName()); - } - catch (NoSuchMethodException e) - { - throw new IllegalArgumentException("Cannot convert " + untypedValue.getValue().getClass().getSimpleName() - + " to " + typeClass.getSimpleName()); - } - catch (InvocationTargetException | IllegalAccessException | InstantiationException e) - { - throw new RuntimeException(e); - } - } -} diff --git a/src/main/java/dev/dsf/bpe/variables/codesystem/dsfpingstatus/CodeValue.java b/src/main/java/dev/dsf/bpe/variables/codesystem/dsfpingstatus/CodeValue.java deleted file mode 100644 index 7614746e..00000000 --- a/src/main/java/dev/dsf/bpe/variables/codesystem/dsfpingstatus/CodeValue.java +++ /dev/null @@ -1,9 +0,0 @@ -package dev.dsf.bpe.variables.codesystem.dsfpingstatus; - -import org.camunda.bpm.engine.variable.value.PrimitiveValue; - -import dev.dsf.bpe.CodeSystem; - -public interface CodeValue extends PrimitiveValue -{ -} diff --git a/src/main/java/dev/dsf/bpe/variables/codesystem/dsfpingstatus/CodeValueImpl.java b/src/main/java/dev/dsf/bpe/variables/codesystem/dsfpingstatus/CodeValueImpl.java deleted file mode 100644 index ecf084cf..00000000 --- a/src/main/java/dev/dsf/bpe/variables/codesystem/dsfpingstatus/CodeValueImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -package dev.dsf.bpe.variables.codesystem.dsfpingstatus; - -import java.io.Serial; - -import org.camunda.bpm.engine.variable.impl.value.PrimitiveTypeValueImpl; -import org.camunda.bpm.engine.variable.type.PrimitiveValueType; - -import dev.dsf.bpe.CodeSystem; - -public class CodeValueImpl extends PrimitiveTypeValueImpl implements CodeValue -{ - @Serial - private static final long serialVersionUID = 1L; - - private static final PrimitiveValueType DURATION_VALUE_TYPE = new CodeValueTypeImpl(); - - public CodeValueImpl(CodeSystem.DsfPingStatus.Code value) - { - super(value, DURATION_VALUE_TYPE); - } - - public CodeValueImpl(CodeSystem.DsfPingStatus.Code value, PrimitiveValueType type) - { - super(value, type); - } -} diff --git a/src/main/java/dev/dsf/bpe/variables/codesystem/dsfpingstatus/CodeValueSerializer.java b/src/main/java/dev/dsf/bpe/variables/codesystem/dsfpingstatus/CodeValueSerializer.java deleted file mode 100644 index 462f66f1..00000000 --- a/src/main/java/dev/dsf/bpe/variables/codesystem/dsfpingstatus/CodeValueSerializer.java +++ /dev/null @@ -1,18 +0,0 @@ -package dev.dsf.bpe.variables.codesystem.dsfpingstatus; - -import org.camunda.bpm.engine.variable.type.PrimitiveValueType; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import dev.dsf.bpe.CodeSystem; -import dev.dsf.bpe.variables.GenericPrimitiveTypeSerializer; - -public class CodeValueSerializer extends GenericPrimitiveTypeSerializer -{ - private static final PrimitiveValueType DURATION_VALUE_TYPE = new CodeValueTypeImpl(); - - public CodeValueSerializer() - { - super(DURATION_VALUE_TYPE, new ObjectMapper(), CodeValueImpl.class, CodeSystem.DsfPingStatus.Code.class); - } -} diff --git a/src/main/java/dev/dsf/bpe/variables/codesystem/dsfpingstatus/CodeValueTypeImpl.java b/src/main/java/dev/dsf/bpe/variables/codesystem/dsfpingstatus/CodeValueTypeImpl.java deleted file mode 100644 index 0e90f6a0..00000000 --- a/src/main/java/dev/dsf/bpe/variables/codesystem/dsfpingstatus/CodeValueTypeImpl.java +++ /dev/null @@ -1,35 +0,0 @@ -package dev.dsf.bpe.variables.codesystem.dsfpingstatus; - -import java.io.Serial; -import java.util.Map; - -import org.camunda.bpm.engine.variable.impl.type.PrimitiveValueTypeImpl; - -import dev.dsf.bpe.CodeSystem; - -public class CodeValueTypeImpl extends PrimitiveValueTypeImpl -{ - @Serial - private static final long serialVersionUID = 1L; - - private static final Class CODE_CLASS = CodeSystem.DsfPingStatus.Code.class; - - public CodeValueTypeImpl() - { - super(CODE_CLASS); - } - - @Override - public CodeValueImpl createValue(Object o, Map map) - { - if (o instanceof CodeSystem.DsfPingStatus.Code code) - { - return new CodeValueImpl(code); - } - else - { - throw new IllegalArgumentException("Cannot create value of type " + CODE_CLASS.getSimpleName() - + " from type " + o.getClass().getSimpleName()); - } - } -} diff --git a/src/main/java/dev/dsf/bpe/variables/duration/DurationValue.java b/src/main/java/dev/dsf/bpe/variables/duration/DurationValue.java deleted file mode 100644 index 531ed68d..00000000 --- a/src/main/java/dev/dsf/bpe/variables/duration/DurationValue.java +++ /dev/null @@ -1,9 +0,0 @@ -package dev.dsf.bpe.variables.duration; - -import java.time.Duration; - -import org.camunda.bpm.engine.variable.value.PrimitiveValue; - -public interface DurationValue extends PrimitiveValue -{ -} diff --git a/src/main/java/dev/dsf/bpe/variables/duration/DurationValueImpl.java b/src/main/java/dev/dsf/bpe/variables/duration/DurationValueImpl.java deleted file mode 100644 index 645a9862..00000000 --- a/src/main/java/dev/dsf/bpe/variables/duration/DurationValueImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package dev.dsf.bpe.variables.duration; - -import java.io.Serial; -import java.time.Duration; - -import org.camunda.bpm.engine.variable.impl.value.PrimitiveTypeValueImpl; -import org.camunda.bpm.engine.variable.type.PrimitiveValueType; - -public class DurationValueImpl extends PrimitiveTypeValueImpl implements DurationValue -{ - @Serial - private static final long serialVersionUID = 1L; - - private static final PrimitiveValueType DURATION_VALUE_TYPE = new DurationValueTypeImpl(); - - public DurationValueImpl(Duration value) - { - super(value, DURATION_VALUE_TYPE); - } - - public DurationValueImpl(Duration value, PrimitiveValueType type) - { - super(value, type); - } -} diff --git a/src/main/java/dev/dsf/bpe/variables/duration/DurationValueSerializer.java b/src/main/java/dev/dsf/bpe/variables/duration/DurationValueSerializer.java deleted file mode 100644 index 5e50fb41..00000000 --- a/src/main/java/dev/dsf/bpe/variables/duration/DurationValueSerializer.java +++ /dev/null @@ -1,19 +0,0 @@ -package dev.dsf.bpe.variables.duration; - -import java.time.Duration; - -import org.camunda.bpm.engine.variable.type.PrimitiveValueType; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import dev.dsf.bpe.variables.GenericPrimitiveTypeSerializer; - -public class DurationValueSerializer extends GenericPrimitiveTypeSerializer -{ - private static final PrimitiveValueType DURATION_VALUE_TYPE = new DurationValueTypeImpl(); - - public DurationValueSerializer(ObjectMapper objectMapperWithJavaTimeModule) - { - super(DURATION_VALUE_TYPE, objectMapperWithJavaTimeModule, DurationValueImpl.class, Duration.class); - } -} diff --git a/src/main/java/dev/dsf/bpe/variables/duration/DurationValueTypeImpl.java b/src/main/java/dev/dsf/bpe/variables/duration/DurationValueTypeImpl.java deleted file mode 100644 index 5a51e8e5..00000000 --- a/src/main/java/dev/dsf/bpe/variables/duration/DurationValueTypeImpl.java +++ /dev/null @@ -1,34 +0,0 @@ -package dev.dsf.bpe.variables.duration; - -import java.io.Serial; -import java.time.Duration; -import java.util.Map; - -import org.camunda.bpm.engine.variable.impl.type.PrimitiveValueTypeImpl; - -public class DurationValueTypeImpl extends PrimitiveValueTypeImpl -{ - @Serial - private static final long serialVersionUID = 1L; - - private static final Class DURATION_CLASS = Duration.class; - - public DurationValueTypeImpl() - { - super(DURATION_CLASS); - } - - @Override - public DurationValueImpl createValue(Object o, Map map) - { - if (o instanceof Duration duration) - { - return new DurationValueImpl(duration); - } - else - { - throw new IllegalArgumentException("Cannot create value of type " + DURATION_CLASS.getSimpleName() - + " from type " + o.getClass().getSimpleName()); - } - } -} diff --git a/src/main/java/dev/dsf/bpe/variables/process_error/ProcessErrorValue.java b/src/main/java/dev/dsf/bpe/variables/process_error/ProcessErrorValue.java deleted file mode 100644 index ffe1451e..00000000 --- a/src/main/java/dev/dsf/bpe/variables/process_error/ProcessErrorValue.java +++ /dev/null @@ -1,9 +0,0 @@ -package dev.dsf.bpe.variables.process_error; - -import org.camunda.bpm.engine.variable.value.PrimitiveValue; - -import dev.dsf.bpe.ProcessError; - -public interface ProcessErrorValue extends PrimitiveValue -{ -} diff --git a/src/main/java/dev/dsf/bpe/variables/process_error/ProcessErrorValueImpl.java b/src/main/java/dev/dsf/bpe/variables/process_error/ProcessErrorValueImpl.java deleted file mode 100644 index ad9827cd..00000000 --- a/src/main/java/dev/dsf/bpe/variables/process_error/ProcessErrorValueImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -package dev.dsf.bpe.variables.process_error; - -import java.io.Serial; - -import org.camunda.bpm.engine.variable.impl.value.PrimitiveTypeValueImpl; -import org.camunda.bpm.engine.variable.type.PrimitiveValueType; - -import dev.dsf.bpe.ProcessError; - -public class ProcessErrorValueImpl extends PrimitiveTypeValueImpl implements ProcessErrorValue -{ - @Serial - private static final long serialVersionUID = 1L; - - private static final ProcessErrorValueTypeImpl PROCESS_ERROR_VALUE_TYPE = new ProcessErrorValueTypeImpl(); - - public ProcessErrorValueImpl(ProcessError value) - { - super(value, PROCESS_ERROR_VALUE_TYPE); - } - - public ProcessErrorValueImpl(ProcessError value, PrimitiveValueType type) - { - super(value, type); - } -} diff --git a/src/main/java/dev/dsf/bpe/variables/process_error/ProcessErrorValueSerializer.java b/src/main/java/dev/dsf/bpe/variables/process_error/ProcessErrorValueSerializer.java deleted file mode 100644 index 079990ba..00000000 --- a/src/main/java/dev/dsf/bpe/variables/process_error/ProcessErrorValueSerializer.java +++ /dev/null @@ -1,16 +0,0 @@ -package dev.dsf.bpe.variables.process_error; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import dev.dsf.bpe.ProcessError; -import dev.dsf.bpe.variables.GenericPrimitiveTypeSerializer; - -public class ProcessErrorValueSerializer extends GenericPrimitiveTypeSerializer -{ - private static final ProcessErrorValueTypeImpl PROCESS_ERROR_VALUE_TYPE = new ProcessErrorValueTypeImpl(); - - public ProcessErrorValueSerializer() - { - super(PROCESS_ERROR_VALUE_TYPE, new ObjectMapper(), ProcessErrorValueImpl.class, ProcessError.class); - } -} diff --git a/src/main/java/dev/dsf/bpe/variables/process_error/ProcessErrorValueTypeImpl.java b/src/main/java/dev/dsf/bpe/variables/process_error/ProcessErrorValueTypeImpl.java deleted file mode 100644 index a18e795d..00000000 --- a/src/main/java/dev/dsf/bpe/variables/process_error/ProcessErrorValueTypeImpl.java +++ /dev/null @@ -1,36 +0,0 @@ -package dev.dsf.bpe.variables.process_error; - -import java.io.Serial; -import java.util.Map; - -import org.camunda.bpm.engine.variable.impl.type.PrimitiveValueTypeImpl; -import org.camunda.bpm.engine.variable.value.TypedValue; - -import dev.dsf.bpe.ProcessError; - -public class ProcessErrorValueTypeImpl extends PrimitiveValueTypeImpl -{ - @Serial - private static final long serialVersionUID = 1L; - - private static final Class PROCESS_ERROR_CLASS = ProcessError.class; - - public ProcessErrorValueTypeImpl() - { - super(PROCESS_ERROR_CLASS); - } - - @Override - public TypedValue createValue(Object value, Map valueInfo) - { - if (value instanceof ProcessError error) - { - return new ProcessErrorValueImpl(error); - } - else - { - throw new IllegalArgumentException("Cannot create value of type " + PROCESS_ERROR_CLASS.getSimpleName() - + " from type " + value.getClass().getSimpleName()); - } - } -} diff --git a/src/main/java/dev/dsf/bpe/variables/process_errors/ProcessErrorsValue.java b/src/main/java/dev/dsf/bpe/variables/process_errors/ProcessErrorsValue.java deleted file mode 100644 index 75c99472..00000000 --- a/src/main/java/dev/dsf/bpe/variables/process_errors/ProcessErrorsValue.java +++ /dev/null @@ -1,9 +0,0 @@ -package dev.dsf.bpe.variables.process_errors; - -import org.camunda.bpm.engine.variable.value.PrimitiveValue; - -import dev.dsf.bpe.ProcessErrors; - -public interface ProcessErrorsValue extends PrimitiveValue -{ -} diff --git a/src/main/java/dev/dsf/bpe/variables/process_errors/ProcessErrorsValueImpl.java b/src/main/java/dev/dsf/bpe/variables/process_errors/ProcessErrorsValueImpl.java deleted file mode 100644 index 8e79fc2b..00000000 --- a/src/main/java/dev/dsf/bpe/variables/process_errors/ProcessErrorsValueImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -package dev.dsf.bpe.variables.process_errors; - -import java.io.Serial; - -import org.camunda.bpm.engine.variable.impl.value.PrimitiveTypeValueImpl; -import org.camunda.bpm.engine.variable.type.PrimitiveValueType; - -import dev.dsf.bpe.ProcessErrors; - -public class ProcessErrorsValueImpl extends PrimitiveTypeValueImpl implements ProcessErrorsValue -{ - @Serial - private static final long serialVersionUID = 1L; - - private static final ProcessErrorsValueTypeImpl PROCESS_ERRORS_VALUE_TYPE = new ProcessErrorsValueTypeImpl(); - - public ProcessErrorsValueImpl(ProcessErrors value) - { - super(value, PROCESS_ERRORS_VALUE_TYPE); - } - - public ProcessErrorsValueImpl(ProcessErrors value, PrimitiveValueType type) - { - super(value, type); - } -} diff --git a/src/main/java/dev/dsf/bpe/variables/process_errors/ProcessErrorsValueSerializer.java b/src/main/java/dev/dsf/bpe/variables/process_errors/ProcessErrorsValueSerializer.java deleted file mode 100644 index 54dfb15b..00000000 --- a/src/main/java/dev/dsf/bpe/variables/process_errors/ProcessErrorsValueSerializer.java +++ /dev/null @@ -1,16 +0,0 @@ -package dev.dsf.bpe.variables.process_errors; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import dev.dsf.bpe.ProcessErrors; -import dev.dsf.bpe.variables.GenericPrimitiveTypeSerializer; - -public class ProcessErrorsValueSerializer extends GenericPrimitiveTypeSerializer -{ - private static final ProcessErrorsValueTypeImpl TYPE = new ProcessErrorsValueTypeImpl(); - - public ProcessErrorsValueSerializer() - { - super(TYPE, new ObjectMapper(), ProcessErrorsValueImpl.class, ProcessErrors.class); - } -} diff --git a/src/main/java/dev/dsf/bpe/variables/process_errors/ProcessErrorsValueTypeImpl.java b/src/main/java/dev/dsf/bpe/variables/process_errors/ProcessErrorsValueTypeImpl.java deleted file mode 100644 index c7fc5727..00000000 --- a/src/main/java/dev/dsf/bpe/variables/process_errors/ProcessErrorsValueTypeImpl.java +++ /dev/null @@ -1,36 +0,0 @@ -package dev.dsf.bpe.variables.process_errors; - -import java.io.Serial; -import java.util.Map; - -import org.camunda.bpm.engine.variable.impl.type.PrimitiveValueTypeImpl; -import org.camunda.bpm.engine.variable.value.TypedValue; - -import dev.dsf.bpe.ProcessErrors; - -public class ProcessErrorsValueTypeImpl extends PrimitiveValueTypeImpl -{ - @Serial - private static final long serialVersionUID = 1L; - - private static final Class PROCESS_ERRORS_CLASS = ProcessErrors.class; - - public ProcessErrorsValueTypeImpl() - { - super(PROCESS_ERRORS_CLASS); - } - - @Override - public TypedValue createValue(Object value, Map valueInfo) - { - if (value instanceof ProcessErrors errors) - { - return new ProcessErrorsValueImpl(errors); - } - else - { - throw new IllegalArgumentException("Cannot create value of type " + PROCESS_ERRORS_CLASS.getSimpleName() - + " from type " + value.getClass().getSimpleName()); - } - } -} diff --git a/src/main/resources/META-INF/services/dev.dsf.bpe.v1.ProcessPluginDefinition b/src/main/resources/META-INF/services/dev.dsf.bpe.v2.ProcessPluginDefinition similarity index 100% rename from src/main/resources/META-INF/services/dev.dsf.bpe.v1.ProcessPluginDefinition rename to src/main/resources/META-INF/services/dev.dsf.bpe.v2.ProcessPluginDefinition diff --git a/src/main/resources/bpe/ping.bpmn b/src/main/resources/bpe/ping.bpmn index 9cc5e928..388beb43 100644 --- a/src/main/resources/bpe/ping.bpmn +++ b/src/main/resources/bpe/ping.bpmn @@ -38,11 +38,14 @@ Flow_0y9usku Flow_1lghrxh - + Flow_1fjeq2h Flow_136htek - + + + + Flow_08vgmf6 Flow_1j54c2s Flow_101sqed @@ -58,7 +61,7 @@ Flow_1ho1hys - + http://dsf.dev/bpe/Process/pong|#{version} @@ -78,11 +81,11 @@ Flow_13u1nzy Flow_1yt9547 - + Flow_1yt9547 Flow_1ncztgo - + http://dsf.dev/fhir/StructureDefinition/task-cleanup-pong|#{version} @@ -98,7 +101,7 @@ Flow_18wxsor Flow_0klalf8 - + Flow_0qif01p Flow_0jcfur3 @@ -114,32 +117,32 @@ Flow_03nx6rk Flow_0c6l9ff - + - + - - - - ${execution.hasVariable('statusCode') && (statusCode.getValue() == 'not-allowed' || statusCode.getValue() == 'not-reachable')} + + + + ${execution.hasVariable('statusCodeString') && (statusCodeString == 'not-allowed' || statusCodeString == 'not-reachable')} ${downloadResourceSizeBytes < 0} - - - - - + + + + + Flow_1ewmc79 Flow_1jwekqw - + - - + + Flow_101sqed Flow_0upu487 @@ -148,12 +151,12 @@ Flow_0qif01p Flow_18wxsor - - + + ${execution.hasVariable('resourceDownloadError')} - - + + Flow_1m5uggy @@ -161,13 +164,13 @@ Flow_1m5uggy - + Flow_0c6l9ff - + ping @@ -176,7 +179,7 @@ Flow_152nb9r Flow_1op4sei - + ping @@ -186,7 +189,7 @@ Flow_1mer14f Flow_0gubpgz - + Flow_0gubpgz Flow_1du5wys @@ -199,7 +202,7 @@ Flow_1qyomuj Flow_1c15ef2 - + Flow_1c15ef2 Flow_0j92st0 @@ -212,22 +215,22 @@ Flow_1hor4v7 - - - - - + + + + + ${downloadResourceSizeBytes < 0} - - - + + + Flow_0xy3953 Flow_0fxlsv3 - - + + Flow_0z3dgxw Flow_0ejw9k5 @@ -236,22 +239,22 @@ Flow_0z3dgxw Flow_1qyomuj - - + + ${execution.hasVariable('resourceUploadError')} - - - + + + Flow_1hor4v7 Flow_0xy3953 - + Flow_1mer14f - + Log = logger Save = save as execution variable @@ -284,32 +287,38 @@ Store = store on DSF FHIR server either as separate resource or output parameter - + + + + - + + + + - + - + - + @@ -319,28 +328,25 @@ Store = store on DSF FHIR server either as separate resource or output parameter - + + + + - - - - - + + - - - @@ -444,14 +450,14 @@ Store = store on DSF FHIR server either as separate resource or output parameter - + - + - + @@ -461,7 +467,7 @@ Store = store on DSF FHIR server either as separate resource or output parameter - + @@ -474,17 +480,17 @@ Store = store on DSF FHIR server either as separate resource or output parameter - + - + - + diff --git a/src/main/resources/bpe/pong.bpmn b/src/main/resources/bpe/pong.bpmn index 97574644..5f13e123 100644 --- a/src/main/resources/bpe/pong.bpmn +++ b/src/main/resources/bpe/pong.bpmn @@ -10,7 +10,7 @@ Flow_10z0d4x Flow_08gidyv - + Flow_10z0d4x Flow_0vqsjzn @@ -20,7 +20,7 @@ Flow_0dp8f59 Flow_1o3n9u6 - + http://dsf.dev/bpe/Process/ping|#{version} @@ -35,7 +35,10 @@ Flow_1o3n9u6 Flow_0fzmjzb - + + + + Flow_0fzmjzb Flow_0h8flp6 Flow_1bzjspe @@ -63,11 +66,11 @@ Flow_0yujsot Flow_0x7t1ii - + Flow_1w3kcjh Flow_1jehvly - + pong @@ -78,7 +81,7 @@ Flow_0h8flp6 Flow_0zib7wr - + pong @@ -87,114 +90,114 @@ Flow_0x7t1ii Flow_033lqly - + Flow_17wqhp8 Flow_0gvrnxd - + ${downloadResourceSizeBytes < 0} - - - - - ${execution.hasVariable('statusCode') && (statusCode.getValue() == 'not-reachable' || statusCode.getValue() == 'not-allowed')} + + + + + ${execution.hasVariable('statusCodeString') && (statusCodeString == 'not-reachable' || statusCodeString == 'not-allowed')} - + ${downloadResourceSizeBytes < 0} - - - + + + Flow_1j5lf0u Flow_1oo1n55 - + Flow_1oo1n55 Flow_1fzloso - + Flow_1bgedez - - + + Flow_1eh8lho Flow_1n4fb8d Flow_1lfcycx - - - + + + Flow_1ttsk1o Flow_1eh8lho - - - + + + Flow_0pp3r2w Flow_0yujsot - - - + + + Flow_1xfk4ds Flow_1n4fb8d - - + + Flow_0zib7wr Flow_1bgedez - + Flow_19b3cp4 Flow_1j5lf0u - - + + Flow_1fzloso Flow_1gap0hi Flow_0qxt5zo - + Flow_0qxt5zo - - + + Flow_0vqsjzn Flow_0pp3r2w Flow_1w3kcjh - - - + + + ${execution.hasVariable('resourceDownloadError')} - + Flow_033lqly Flow_17wqhp8 Flow_15xatzp - - + + ${execution.hasVariable('resourceUploadError')} - + Flow_15xatzp Flow_0dp8f59 - + Log = logger Save = save as execution variable @@ -218,19 +221,22 @@ Store = store on DSF FHIR server either as separate resource or output parameter - + - + + + + @@ -241,29 +247,60 @@ Store = store on DSF FHIR server either as separate resource or output parameter + + + - + + + + + + + + - + + + + - + - + + + + + + + + + + + - + + + + + + + + + - + @@ -276,38 +313,7 @@ Store = store on DSF FHIR server either as separate resource or output parameter - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/src/main/resources/doc/description.md b/src/main/resources/doc/description.md new file mode 100644 index 00000000..8e814588 --- /dev/null +++ b/src/main/resources/doc/description.md @@ -0,0 +1,42 @@ +# Ping Pong Process ${project.version} Description + +The Ping Pong process allows testing connections to other (remote) DSF FHIR Endpoints. The following connections are tested: +- local DSF FHIR Server -> local BPE +- local BPE -> remote DSF FHIR Server +- remote DSF FHIR Server -> local DSF FHIR Server +- remote DSF FHIR Server -> remote BPE +- remote BPE -> local DSF FHIR Server +- local DSF FHIR Server -> remote DSF FHIR Server + +The Ping Pong process's output paremters will link to a page which contains troubleshooting tips if any connection fails for known reasons. In order to test connections between DSF FHIR Servers, the process creates a Binary resource containing random data. Sending a reference to this resource to another DSF FHIR Server causes the server to verify the existence of the referenced resource on the requesting DSF FHIR Server, thus testing the connection. This allows the process to also be used to measure connection speeds as the Binary resource gets downloaded during execution and deleted before the process finishes. This means the process also tests the ability to transfer data, which can be helpful to make sure the DSF installation is properly set up in preparation for other process plugins involving data transfers. + +Troubleshooting tips and network speeds can be found in the outputs of the completed process. They are named `potential-fix`, `download-speed-from-remote` and `upload-speed-to-remote` respectively. + + + + + Ping Pong Process Collaboration Diagram + + + +### Autostart Process +The ping pong process plugin includes an autostart process which allows automatically starting the ping process on an interval. + +# Ping-Pong: Ping +The **ping** process is used to ping other DSF FHIR Endpoints. It contains the following steps: +1. If requested, generate a Binary resource and store it on the local DSF FHIR Server +2. Send a ping message to all requested endpoints, containing a reference to the generated Binary resource +3. Wait for responses via pong messages +4. Download the Binary resource referenced in the pong message and measure network speed +5. Send a cleanup message to all endpoints +6. Delete the Binary resource generated in 1. +7. Store results and errors in the start task as output parameters + +# Ping-Pong: Pong +The **pong** process is used to respond to incoming ping requests. It contains the following steps: +1. Download the Binary resource referenced in the ping message and measure network speed +2. If requested, generate a Binary resource and store it on the local DSF FHIR Server +3. Send a pong message to the requesting endpoint, containing a reference to the generated Binary resource, network speed and all errors that occured during execution so far +4. Wait for cleanup message +5. Delete the Binary resource generated in 2. +6. Store results and errors in the ping task as output parameters \ No newline at end of file diff --git a/src/main/resources/doc/license.md b/src/main/resources/doc/license.md new file mode 100644 index 00000000..dc8b2392 --- /dev/null +++ b/src/main/resources/doc/license.md @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/src/main/resources/fhir/ActivityDefinition/dsf-ping-autostart.xml b/src/main/resources/fhir/ActivityDefinition/dsf-ping-autostart.xml index 1ac37a1e..764006a2 100644 --- a/src/main/resources/fhir/ActivityDefinition/dsf-ping-autostart.xml +++ b/src/main/resources/fhir/ActivityDefinition/dsf-ping-autostart.xml @@ -1,5 +1,6 @@ + diff --git a/src/main/resources/fhir/ActivityDefinition/dsf-ping.xml b/src/main/resources/fhir/ActivityDefinition/dsf-ping.xml index 367348ad..2a66448d 100644 --- a/src/main/resources/fhir/ActivityDefinition/dsf-ping.xml +++ b/src/main/resources/fhir/ActivityDefinition/dsf-ping.xml @@ -1,5 +1,6 @@ + diff --git a/src/main/resources/fhir/ActivityDefinition/dsf-pong.xml b/src/main/resources/fhir/ActivityDefinition/dsf-pong.xml index efde8372..6737cc91 100644 --- a/src/main/resources/fhir/ActivityDefinition/dsf-pong.xml +++ b/src/main/resources/fhir/ActivityDefinition/dsf-pong.xml @@ -1,5 +1,6 @@ + diff --git a/src/main/resources/fhir/CodeSystem/dsf-ping-error.xml b/src/main/resources/fhir/CodeSystem/dsf-ping-error.xml index fc7862be..4da0fb83 100644 --- a/src/main/resources/fhir/CodeSystem/dsf-ping-error.xml +++ b/src/main/resources/fhir/CodeSystem/dsf-ping-error.xml @@ -1,5 +1,6 @@ + diff --git a/src/main/resources/fhir/CodeSystem/dsf-ping-status.xml b/src/main/resources/fhir/CodeSystem/dsf-ping-status.xml index 8dfaf7e5..a40b872d 100644 --- a/src/main/resources/fhir/CodeSystem/dsf-ping-status.xml +++ b/src/main/resources/fhir/CodeSystem/dsf-ping-status.xml @@ -1,5 +1,6 @@ + diff --git a/src/main/resources/fhir/CodeSystem/dsf-ping.xml b/src/main/resources/fhir/CodeSystem/dsf-ping.xml index 100877d6..ec29715c 100644 --- a/src/main/resources/fhir/CodeSystem/dsf-ping.xml +++ b/src/main/resources/fhir/CodeSystem/dsf-ping.xml @@ -1,5 +1,6 @@ + diff --git a/src/main/resources/fhir/StructureDefinition/dsf-extension-error.xml b/src/main/resources/fhir/StructureDefinition/dsf-extension-error.xml index 6476c0fa..28cc2cec 100644 --- a/src/main/resources/fhir/StructureDefinition/dsf-extension-error.xml +++ b/src/main/resources/fhir/StructureDefinition/dsf-extension-error.xml @@ -1,5 +1,6 @@ + diff --git a/src/main/resources/fhir/StructureDefinition/dsf-extension-ping-status.xml b/src/main/resources/fhir/StructureDefinition/dsf-extension-ping-status.xml index 5d42cc76..e6a9a12c 100644 --- a/src/main/resources/fhir/StructureDefinition/dsf-extension-ping-status.xml +++ b/src/main/resources/fhir/StructureDefinition/dsf-extension-ping-status.xml @@ -1,5 +1,6 @@ + diff --git a/src/main/resources/fhir/StructureDefinition/dsf-task-cleanup-pong.xml b/src/main/resources/fhir/StructureDefinition/dsf-task-cleanup-pong.xml index aa0dbfda..188af93d 100644 --- a/src/main/resources/fhir/StructureDefinition/dsf-task-cleanup-pong.xml +++ b/src/main/resources/fhir/StructureDefinition/dsf-task-cleanup-pong.xml @@ -1,5 +1,6 @@ + @@ -18,7 +19,7 @@ - + diff --git a/src/main/resources/fhir/StructureDefinition/dsf-task-ping.xml b/src/main/resources/fhir/StructureDefinition/dsf-task-ping.xml index 245253da..7795a118 100644 --- a/src/main/resources/fhir/StructureDefinition/dsf-task-ping.xml +++ b/src/main/resources/fhir/StructureDefinition/dsf-task-ping.xml @@ -1,5 +1,6 @@ + @@ -18,7 +19,7 @@ - + diff --git a/src/main/resources/fhir/StructureDefinition/dsf-task-pong.xml b/src/main/resources/fhir/StructureDefinition/dsf-task-pong.xml index e57266cb..f0544f2c 100644 --- a/src/main/resources/fhir/StructureDefinition/dsf-task-pong.xml +++ b/src/main/resources/fhir/StructureDefinition/dsf-task-pong.xml @@ -1,5 +1,6 @@ + @@ -18,7 +19,7 @@ - + diff --git a/src/main/resources/fhir/StructureDefinition/dsf-task-start-ping-autostart.xml b/src/main/resources/fhir/StructureDefinition/dsf-task-start-ping-autostart.xml index 0666b67d..df8c364d 100644 --- a/src/main/resources/fhir/StructureDefinition/dsf-task-start-ping-autostart.xml +++ b/src/main/resources/fhir/StructureDefinition/dsf-task-start-ping-autostart.xml @@ -1,5 +1,6 @@ + @@ -18,7 +19,7 @@ - + diff --git a/src/main/resources/fhir/StructureDefinition/dsf-task-start-ping.xml b/src/main/resources/fhir/StructureDefinition/dsf-task-start-ping.xml index a04e9815..684e622d 100644 --- a/src/main/resources/fhir/StructureDefinition/dsf-task-start-ping.xml +++ b/src/main/resources/fhir/StructureDefinition/dsf-task-start-ping.xml @@ -1,5 +1,6 @@ + @@ -18,7 +19,7 @@ - + diff --git a/src/main/resources/fhir/StructureDefinition/dsf-task-stop-ping-autostart.xml b/src/main/resources/fhir/StructureDefinition/dsf-task-stop-ping-autostart.xml index bc6a7b1b..1f995ea5 100644 --- a/src/main/resources/fhir/StructureDefinition/dsf-task-stop-ping-autostart.xml +++ b/src/main/resources/fhir/StructureDefinition/dsf-task-stop-ping-autostart.xml @@ -1,5 +1,6 @@ + @@ -18,7 +19,7 @@ - + diff --git a/src/main/resources/fhir/ValueSet/dsf-network-speed-units.xml b/src/main/resources/fhir/ValueSet/dsf-network-speed-units.xml index 647e36fe..682d8705 100644 --- a/src/main/resources/fhir/ValueSet/dsf-network-speed-units.xml +++ b/src/main/resources/fhir/ValueSet/dsf-network-speed-units.xml @@ -1,5 +1,6 @@ + diff --git a/src/main/resources/fhir/ValueSet/dsf-ping-status.xml b/src/main/resources/fhir/ValueSet/dsf-ping-status.xml index 0729a89a..a7103782 100644 --- a/src/main/resources/fhir/ValueSet/dsf-ping-status.xml +++ b/src/main/resources/fhir/ValueSet/dsf-ping-status.xml @@ -1,5 +1,6 @@ + diff --git a/src/main/resources/fhir/ValueSet/dsf-ping.xml b/src/main/resources/fhir/ValueSet/dsf-ping.xml index 0fef6dbf..da239c81 100644 --- a/src/main/resources/fhir/ValueSet/dsf-ping.xml +++ b/src/main/resources/fhir/ValueSet/dsf-ping.xml @@ -1,5 +1,6 @@ + diff --git a/src/main/resources/fhir/ValueSet/dsf-pong-status.xml b/src/main/resources/fhir/ValueSet/dsf-pong-status.xml index 09860584..8adc166d 100644 --- a/src/main/resources/fhir/ValueSet/dsf-pong-status.xml +++ b/src/main/resources/fhir/ValueSet/dsf-pong-status.xml @@ -1,5 +1,6 @@ + diff --git a/src/main/resources/plugin.properties b/src/main/resources/plugin.properties new file mode 100644 index 00000000..5ef8b65a --- /dev/null +++ b/src/main/resources/plugin.properties @@ -0,0 +1,6 @@ +release-date=${project.build.outputTimestamp} +version=${project.version} +name=${project.artifactId} +title=${project.description} +publisher=${project.organization.name} +publisher-email=mail@test.com \ No newline at end of file diff --git a/src/test/java/dev/dsf/bpe/PingProcessPluginDefinitionTest.java b/src/test/java/dev/dsf/bpe/PingProcessPluginDefinitionTest.java index 55e289ab..69e74619 100644 --- a/src/test/java/dev/dsf/bpe/PingProcessPluginDefinitionTest.java +++ b/src/test/java/dev/dsf/bpe/PingProcessPluginDefinitionTest.java @@ -8,7 +8,7 @@ import org.junit.Test; -import dev.dsf.bpe.v1.ProcessPluginDefinition; +import dev.dsf.bpe.v2.ProcessPluginDefinition; public class PingProcessPluginDefinitionTest { diff --git a/src/test/java/dev/dsf/bpe/start/Ping3DicFromTtpExampleStarter.java b/src/test/java/dev/dsf/bpe/start/Ping3DicFromTtpExampleStarter.java deleted file mode 100644 index 3778876b..00000000 --- a/src/test/java/dev/dsf/bpe/start/Ping3DicFromTtpExampleStarter.java +++ /dev/null @@ -1,46 +0,0 @@ -package dev.dsf.bpe.start; - -import java.util.Date; - -import org.hl7.fhir.r4.model.ResourceType; -import org.hl7.fhir.r4.model.StringType; -import org.hl7.fhir.r4.model.Task; - -import dev.dsf.bpe.ConstantsPing; -import dev.dsf.bpe.PingProcessPluginDefinition; -import dev.dsf.bpe.v1.constants.CodeSystems.BpmnMessage; -import dev.dsf.bpe.v1.constants.NamingSystems.OrganizationIdentifier; - -public class Ping3DicFromTtpExampleStarter -{ - // Environment variable "DSF_CLIENT_CERTIFICATE_PATH" or args[0]: the path to the client-certificate - // dsf/dsf-tools/dsf-tools-test-data-generator/cert/Webbrowser_Test_User/Webbrowser_Test_User_certificate.p12 - // Environment variable "DSF_CLIENT_CERTIFICATE_PASSWORD" or args[1]: the password of the client-certificate - // password - public static void main(String[] args) throws Exception - { - ExampleStarter.forServer(args, ConstantsExampleStarters.TTP_FHIR_BASE_URL).startWith(task()); - } - - private static Task task() - { - var def = new PingProcessPluginDefinition(); - - Task task = new Task(); - task.getMeta().addProfile(ConstantsPing.PROFILE_DSF_TASK_START_PING + "|" + def.getResourceVersion()); - task.setInstantiatesCanonical(ConstantsPing.PROFILE_DSF_TASK_PING_PROCESS_URI + "|" + def.getResourceVersion()); - task.setStatus(Task.TaskStatus.REQUESTED); - task.setIntent(Task.TaskIntent.ORDER); - task.setAuthoredOn(new Date()); - task.getRequester().setType(ResourceType.Organization.name()).setIdentifier(OrganizationIdentifier - .withValue(ConstantsExampleStarters.NAMINGSYSTEM_DSF_ORGANIZATION_IDENTIFIER_VALUE_TTP)); - task.getRestriction().addRecipient().setType(ResourceType.Organization.name()) - .setIdentifier(OrganizationIdentifier - .withValue(ConstantsExampleStarters.NAMINGSYSTEM_DSF_ORGANIZATION_IDENTIFIER_VALUE_TTP)); - - task.addInput().setValue(new StringType(ConstantsPing.PROFILE_DSF_TASK_START_PING_MESSAGE_NAME)).getType() - .addCoding(BpmnMessage.messageName()); - - return task; - } -} diff --git a/src/test/java/dev/dsf/bpe/start/PingTtpsFromDic1ExampleStarter.java b/src/test/java/dev/dsf/bpe/start/PingTtpsFromDic1ExampleStarter.java deleted file mode 100644 index ceec3006..00000000 --- a/src/test/java/dev/dsf/bpe/start/PingTtpsFromDic1ExampleStarter.java +++ /dev/null @@ -1,54 +0,0 @@ -package dev.dsf.bpe.start; - -import java.util.Date; - -import org.hl7.fhir.r4.model.ResourceType; -import org.hl7.fhir.r4.model.StringType; -import org.hl7.fhir.r4.model.Task; - -import dev.dsf.bpe.CodeSystem; -import dev.dsf.bpe.ConstantsPing; -import dev.dsf.bpe.PingProcessPluginDefinition; -import dev.dsf.bpe.v1.constants.CodeSystems.BpmnMessage; -import dev.dsf.bpe.v1.constants.NamingSystems.OrganizationIdentifier; - -public class PingTtpsFromDic1ExampleStarter -{ - // Environment variable "DSF_CLIENT_CERTIFICATE_PATH" or args[0]: the path to the client-certificate - // dsf/dsf-tools/dsf-tools-test-data-generator/cert/Webbrowser_Test_User/Webbrowser_Test_User_certificate.p12 - // Environment variable "DSF_CLIENT_CERTIFICATE_PASSWORD" or args[1]: the password of the client-certificate - // password - public static void main(String[] args) throws Exception - { - ExampleStarter.forServer(args, ConstantsExampleStarters.DIC_1_FHIR_BASE_URL).startWith(task()); - } - - private static Task task() - { - var def = new PingProcessPluginDefinition(); - - Task task = new Task(); - task.getMeta().addProfile(ConstantsPing.PROFILE_DSF_TASK_START_PING + "|" + def.getResourceVersion()); - task.setInstantiatesCanonical(ConstantsPing.PROFILE_DSF_TASK_PING_PROCESS_URI + "|" + def.getResourceVersion()); - task.setStatus(Task.TaskStatus.REQUESTED); - task.setIntent(Task.TaskIntent.ORDER); - task.setAuthoredOn(new Date()); - task.getRequester().setType(ResourceType.Organization.name()).setIdentifier(OrganizationIdentifier - .withValue(ConstantsExampleStarters.NAMINGSYSTEM_DSF_ORGANIZATION_IDENTIFIER_VALUE_DIC_1)); - task.getRestriction().addRecipient().setType(ResourceType.Organization.name()) - .setIdentifier(OrganizationIdentifier - .withValue(ConstantsExampleStarters.NAMINGSYSTEM_DSF_ORGANIZATION_IDENTIFIER_VALUE_DIC_1)); - - task.addInput().setValue(new StringType(ConstantsPing.PROFILE_DSF_TASK_START_PING_MESSAGE_NAME)).getType() - .addCoding(BpmnMessage.messageName()); - - task.addInput().setValue(new StringType( - "OrganizationAffiliation?primary-organization:identifier=http://dsf.dev/sid/organization-identifier|highmed.org" - + "&role=http://dsf.dev/fhir/CodeSystem/organization-role|TTP" - + "&_include=OrganizationAffiliation:endpoint")) - .getType().addCoding().setSystem(CodeSystem.DsfPing.URL) - .setCode(CodeSystem.DsfPing.Code.TARGET_ENDPOINTS.getValue()); - - return task; - } -} diff --git a/src/test/java/dev/dsf/bpe/start/StartAutostartPing3DicFromTtpExampleStarter.java b/src/test/java/dev/dsf/bpe/start/StartAutostartPing3DicFromTtpExampleStarter.java deleted file mode 100644 index 396f424e..00000000 --- a/src/test/java/dev/dsf/bpe/start/StartAutostartPing3DicFromTtpExampleStarter.java +++ /dev/null @@ -1,53 +0,0 @@ -package dev.dsf.bpe.start; - -import java.util.Date; - -import org.hl7.fhir.r4.model.ResourceType; -import org.hl7.fhir.r4.model.StringType; -import org.hl7.fhir.r4.model.Task; - -import dev.dsf.bpe.CodeSystem; -import dev.dsf.bpe.ConstantsPing; -import dev.dsf.bpe.PingProcessPluginDefinition; -import dev.dsf.bpe.v1.constants.CodeSystems.BpmnMessage; -import dev.dsf.bpe.v1.constants.NamingSystems.OrganizationIdentifier; - -public class StartAutostartPing3DicFromTtpExampleStarter -{ - // Environment variable "DSF_CLIENT_CERTIFICATE_PATH" or args[0]: the path to the client-certificate - // dsf/dsf-tools/dsf-tools-test-data-generator/cert/Webbrowser_Test_User/Webbrowser_Test_User_certificate.p12 - // Environment variable "DSF_CLIENT_CERTIFICATE_PASSWORD" or args[1]: the password of the client-certificate - // password - public static void main(String[] args) throws Exception - { - ExampleStarter.forServer(args, ConstantsExampleStarters.TTP_FHIR_BASE_URL).startWith(task()); - } - - private static Task task() - { - var def = new PingProcessPluginDefinition(); - - Task task = new Task(); - task.getMeta().addProfile(ConstantsPing.PROFILE_DSF_TASK_START_PING_AUTOSTART + "|" + def.getResourceVersion()); - task.setInstantiatesCanonical( - ConstantsPing.PROFILE_DSF_TASK_START_PING_AUTOSTART_PROCESS_URI + "|" + def.getResourceVersion()); - task.setStatus(Task.TaskStatus.REQUESTED); - task.setIntent(Task.TaskIntent.ORDER); - task.setAuthoredOn(new Date()); - task.getRequester().setType(ResourceType.Organization.name()).setIdentifier(OrganizationIdentifier - .withValue(ConstantsExampleStarters.NAMINGSYSTEM_DSF_ORGANIZATION_IDENTIFIER_VALUE_TTP)); - task.getRestriction().addRecipient().setType(ResourceType.Organization.name()) - .setIdentifier(OrganizationIdentifier - .withValue(ConstantsExampleStarters.NAMINGSYSTEM_DSF_ORGANIZATION_IDENTIFIER_VALUE_TTP)); - - task.addInput().setValue(new StringType(ConstantsPing.PROFILE_DSF_TASK_START_PING_AUTOSTART_MESSAGE_NAME)) - .getType().addCoding(BpmnMessage.messageName()); - task.addInput().setValue(new StringType("Endpoint?identifier=http://dsf.dev/sid/endpoint-identifier|")) - .getType().addCoding().setSystem(CodeSystem.DsfPing.URL) - .setCode(CodeSystem.DsfPing.Code.TARGET_ENDPOINTS.getValue()); - task.addInput().setValue(new StringType("PT7M")).getType().addCoding().setSystem(CodeSystem.DsfPing.URL) - .setCode(CodeSystem.DsfPing.Code.TIMER_INTERVAL.getValue()); - - return task; - } -} diff --git a/src/test/java/dev/dsf/bpe/start/StopAutostartPing3DicFromTtpExampleStarter.java b/src/test/java/dev/dsf/bpe/start/StopAutostartPing3DicFromTtpExampleStarter.java deleted file mode 100644 index 94bc4d35..00000000 --- a/src/test/java/dev/dsf/bpe/start/StopAutostartPing3DicFromTtpExampleStarter.java +++ /dev/null @@ -1,47 +0,0 @@ -package dev.dsf.bpe.start; - -import java.util.Date; - -import org.hl7.fhir.r4.model.ResourceType; -import org.hl7.fhir.r4.model.StringType; -import org.hl7.fhir.r4.model.Task; - -import dev.dsf.bpe.ConstantsPing; -import dev.dsf.bpe.PingProcessPluginDefinition; -import dev.dsf.bpe.v1.constants.CodeSystems.BpmnMessage; -import dev.dsf.bpe.v1.constants.NamingSystems.OrganizationIdentifier; - -public class StopAutostartPing3DicFromTtpExampleStarter -{ - // Environment variable "DSF_CLIENT_CERTIFICATE_PATH" or args[0]: the path to the client-certificate - // dsf/dsf-tools/dsf-tools-test-data-generator/cert/Webbrowser_Test_User/Webbrowser_Test_User_certificate.p12 - // Environment variable "DSF_CLIENT_CERTIFICATE_PASSWORD" or args[1]: the password of the client-certificate - // password - public static void main(String[] args) throws Exception - { - ExampleStarter.forServer(args, ConstantsExampleStarters.TTP_FHIR_BASE_URL).startWith(task()); - } - - private static Task task() - { - var def = new PingProcessPluginDefinition(); - - Task task = new Task(); - task.getMeta().addProfile(ConstantsPing.PROFILE_DSF_TASK_STOP_PING_AUTOSTART + "|" + def.getResourceVersion()); - task.setInstantiatesCanonical( - ConstantsPing.PROFILE_DSF_TASK_STOP_PING_AUTOSTART_PROCESS_URI + "|" + def.getResourceVersion()); - task.setStatus(Task.TaskStatus.REQUESTED); - task.setIntent(Task.TaskIntent.ORDER); - task.setAuthoredOn(new Date()); - task.getRequester().setType(ResourceType.Organization.name()).setIdentifier(OrganizationIdentifier - .withValue(ConstantsExampleStarters.NAMINGSYSTEM_DSF_ORGANIZATION_IDENTIFIER_VALUE_TTP)); - task.getRestriction().addRecipient().setType(ResourceType.Organization.name()) - .setIdentifier(OrganizationIdentifier - .withValue(ConstantsExampleStarters.NAMINGSYSTEM_DSF_ORGANIZATION_IDENTIFIER_VALUE_TTP)); - - task.addInput().setValue(new StringType(ConstantsPing.PROFILE_DSF_TASK_STOP_PING_AUTOSTART_MESSAGE_NAME)) - .getType().addCoding(BpmnMessage.messageName()); - - return task; - } -} diff --git a/src/test/java/dev/dsf/bpe/util/PingStatusGeneratorTest.java b/src/test/java/dev/dsf/bpe/util/PingStatusGeneratorTest.java index 04d32224..879f9f3b 100644 --- a/src/test/java/dev/dsf/bpe/util/PingStatusGeneratorTest.java +++ b/src/test/java/dev/dsf/bpe/util/PingStatusGeneratorTest.java @@ -13,12 +13,16 @@ import dev.dsf.bpe.CodeSystem; import dev.dsf.bpe.ConstantsPing; +import dev.dsf.bpe.PingProcessPluginDefinition; import dev.dsf.bpe.ProcessError; import dev.dsf.bpe.util.task.output.generator.PingStatusGenerator; import dev.dsf.fhir.profiles.TaskProfileTest; public class PingStatusGeneratorTest { + private static final PingProcessPluginDefinition def = new PingProcessPluginDefinition(); + private static final PingStatusGenerator pingStatusGenerator = new PingStatusGenerator(def.getResourceVersion()); + @Test public void updatingPongErrorsResultsInOneErrorsExtensionTest() { @@ -28,11 +32,11 @@ public void updatingPongErrorsResultsInOneErrorsExtensionTest() Task pongTask = TaskProfileTest.createValidTaskStartPingProcess(); - PingStatusGenerator.updatePongStatusOutput(pongTask, errors); + pingStatusGenerator.updatePongStatusOutput(pongTask, errors); errors.add(new ProcessError(process, CodeSystem.DsfPingError.Concept.LOCAL_BINARY_POST_HTTP_UNEXPECTED, null)); - PingStatusGenerator.updatePongStatusOutput(pongTask, errors); + pingStatusGenerator.updatePongStatusOutput(pongTask, errors); List errorsExtensions = pongTask.getOutput().stream().map(Element::getExtension) .map(extensions -> extensions.stream() diff --git a/src/test/java/dev/dsf/fhir/profiles/ActivityDefinitionProfileTest.java b/src/test/java/dev/dsf/fhir/profiles/ActivityDefinitionProfileTest.java index 23e82bb4..5f010d8e 100644 --- a/src/test/java/dev/dsf/fhir/profiles/ActivityDefinitionProfileTest.java +++ b/src/test/java/dev/dsf/fhir/profiles/ActivityDefinitionProfileTest.java @@ -15,8 +15,7 @@ import ca.uhn.fhir.validation.ResultSeverityEnum; import ca.uhn.fhir.validation.ValidationResult; import dev.dsf.bpe.PingProcessPluginDefinition; -import dev.dsf.fhir.authorization.process.ProcessAuthorizationHelper; -import dev.dsf.fhir.authorization.process.ProcessAuthorizationHelperImpl; +import dev.dsf.bpe.v2.service.process.ProcessAuthorizationHelper; import dev.dsf.fhir.validation.ResourceValidator; import dev.dsf.fhir.validation.ResourceValidatorImpl; import dev.dsf.fhir.validation.ValidationSupportRule; @@ -24,30 +23,32 @@ public class ActivityDefinitionProfileTest { private static final Logger logger = LoggerFactory.getLogger(ActivityDefinitionProfileTest.class); + private static final PingProcessPluginDefinition def = new PingProcessPluginDefinition(); @ClassRule - public static final ValidationSupportRule validationRule = new ValidationSupportRule( - PingProcessPluginDefinition.VERSION, PingProcessPluginDefinition.RELEASE_DATE, - Arrays.asList("dsf-activity-definition-1.0.0.xml", "dsf-extension-process-authorization-1.0.0.xml", - "dsf-extension-process-authorization-organization-1.0.0.xml", - "dsf-extension-process-authorization-organization-practitioner-1.0.0.xml", - "dsf-extension-process-authorization-parent-organization-role-1.0.0.xml", - "dsf-extension-process-authorization-parent-organization-role-practitioner-1.0.0.xml", - "dsf-extension-process-authorization-practitioner-1.0.0.xml", - "dsf-coding-process-authorization-local-all-1.0.0.xml", - "dsf-coding-process-authorization-local-all-practitioner-1.0.0.xml", - "dsf-coding-process-authorization-local-organization-1.0.0.xml", - "dsf-coding-process-authorization-local-organization-practitioner-1.0.0.xml", - "dsf-coding-process-authorization-local-parent-organization-role-1.0.0.xml", - "dsf-coding-process-authorization-local-parent-organization-role-practitioner-1.0.0.xml", - "dsf-coding-process-authorization-remote-all-1.0.0.xml", - "dsf-coding-process-authorization-remote-parent-organization-role-1.0.0.xml", - "dsf-coding-process-authorization-remote-organization-1.0.0.xml"), - Arrays.asList("dsf-organization-role-1.0.0.xml", "dsf-practitioner-role-1.0.0.xml", - "dsf-process-authorization-1.0.0.xml", "dsf-read-access-tag-1.0.0.xml"), - Arrays.asList("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", - "dsf-read-access-tag-1.0.0.xml")); + public static final ValidationSupportRule validationRule = new ValidationSupportRule(def.getVersion(), + def.getReleaseDate(), + Arrays.asList("dsf-meta-2.0.0.xml", "dsf-activity-definition-2.0.0.xml", + "dsf-extension-process-authorization-2.0.0.xml", + "dsf-extension-process-authorization-organization-2.0.0.xml", + "dsf-extension-process-authorization-organization-practitioner-2.0.0.xml", + "dsf-extension-process-authorization-parent-organization-role-2.0.0.xml", + "dsf-extension-process-authorization-parent-organization-role-practitioner-2.0.0.xml", + "dsf-extension-process-authorization-practitioner-2.0.0.xml", + "dsf-coding-process-authorization-local-all-2.0.0.xml", + "dsf-coding-process-authorization-local-all-practitioner-2.0.0.xml", + "dsf-coding-process-authorization-local-organization-2.0.0.xml", + "dsf-coding-process-authorization-local-organization-practitioner-2.0.0.xml", + "dsf-coding-process-authorization-local-parent-organization-role-2.0.0.xml", + "dsf-coding-process-authorization-local-parent-organization-role-practitioner-2.0.0.xml", + "dsf-coding-process-authorization-remote-all-2.0.0.xml", + "dsf-coding-process-authorization-remote-parent-organization-role-2.0.0.xml", + "dsf-coding-process-authorization-remote-organization-2.0.0.xml"), + Arrays.asList("dsf-organization-role-2.0.0.xml", "dsf-practitioner-role-2.0.0.xml", + "dsf-process-authorization-2.0.0.xml", "dsf-read-access-tag-2.0.0.xml"), + Arrays.asList("dsf-organization-role-2.0.0.xml", "dsf-practitioner-role-2.0.0.xml", + "dsf-process-authorization-recipient-2.0.0.xml", "dsf-process-authorization-requester-2.0.0.xml", + "dsf-read-access-tag-2.0.0.xml")); private final ResourceValidator resourceValidator = new ResourceValidatorImpl(validationRule.getFhirContext(), validationRule.getValidationSupport()); @@ -66,8 +67,7 @@ public void testAutostartValid() throws Exception assertEquals(0, result.getMessages().stream().filter(m -> ResultSeverityEnum.ERROR.equals(m.getSeverity()) || ResultSeverityEnum.FATAL.equals(m.getSeverity())).count()); - assertTrue(processAuthorizationHelper.isValid(ad, taskProfile -> true, practitionerRole -> true, - orgIdentifier -> true, organizationRole -> true)); + assertTrue(processAuthorizationHelper.isValid(ad, _ -> true, _ -> true, _ -> true, _ -> true)); } @Test @@ -82,8 +82,7 @@ public void testPingValid() throws Exception assertEquals(0, result.getMessages().stream().filter(m -> ResultSeverityEnum.ERROR.equals(m.getSeverity()) || ResultSeverityEnum.FATAL.equals(m.getSeverity())).count()); - assertTrue(processAuthorizationHelper.isValid(ad, taskProfile -> true, practitionerRole -> true, - orgIdentifier -> true, organizationRole -> true)); + assertTrue(processAuthorizationHelper.isValid(ad, _ -> true, _ -> true, _ -> true, _ -> true)); } @Test @@ -98,7 +97,6 @@ public void testPongValid() throws Exception assertEquals(0, result.getMessages().stream().filter(m -> ResultSeverityEnum.ERROR.equals(m.getSeverity()) || ResultSeverityEnum.FATAL.equals(m.getSeverity())).count()); - assertTrue(processAuthorizationHelper.isValid(ad, taskProfile -> true, practitionerRole -> true, - orgIdentifier -> true, organizationRole -> true)); + assertTrue(processAuthorizationHelper.isValid(ad, _ -> true, _ -> true, _ -> true, _ -> true)); } } diff --git a/src/test/java/dev/dsf/fhir/profiles/All.java b/src/test/java/dev/dsf/fhir/profiles/All.java new file mode 100644 index 00000000..cc466142 --- /dev/null +++ b/src/test/java/dev/dsf/fhir/profiles/All.java @@ -0,0 +1,224 @@ +/* + * Copyright 2018-2025 Heilbronn University of Applied Sciences + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package dev.dsf.fhir.profiles; + +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.hl7.fhir.r4.model.Coding; +import org.hl7.fhir.r4.model.Extension; +import org.hl7.fhir.r4.model.OrganizationAffiliation; + +import dev.dsf.bpe.v2.constants.CodeSystems.ProcessAuthorization; +import dev.dsf.bpe.v2.service.process.Identity; +import dev.dsf.bpe.v2.service.process.OrganizationIdentity; +import dev.dsf.bpe.v2.service.process.PractitionerIdentity; +import dev.dsf.bpe.v2.service.process.Recipient; +import dev.dsf.bpe.v2.service.process.Requester; + +public class All implements Recipient, Requester +{ + private static final String EXTENSION_PROCESS_AUTHORIZATION_REQUESTER = "requester"; + private static final String EXTENSION_PROCESS_AUTHORIZATION_RECIPIENT = "recipient"; + + private static final String EXTENSION_PROCESS_AUTHORIZATION_PRACTITIONER = "http://dsf.dev/fhir/StructureDefinition/extension-process-authorization-practitioner"; + + private final boolean localIdentity; + + private final String practitionerRoleSystem; + private final String practitionerRoleCode; + + public All(boolean localIdentity, String practitionerRoleSystem, String practitionerRoleCode) + { + this.localIdentity = localIdentity; + + this.practitionerRoleSystem = practitionerRoleSystem; + this.practitionerRoleCode = practitionerRoleCode; + } + + private boolean needsPractitionerRole() + { + return practitionerRoleSystem != null && practitionerRoleCode != null; + } + + @Override + public boolean isRequesterAuthorized(Identity requester, Stream requesterAffiliations) + { + return isAuthorized(requester); + } + + @Override + public boolean isRecipientAuthorized(Identity recipient, Stream recipientAffiliations) + { + return isAuthorized(recipient); + } + + private boolean isAuthorized(Identity identity) + { + return identity != null && identity.getOrganization() != null && identity.getOrganization().getActive() + && identity.isLocalIdentity() == localIdentity + && ((needsPractitionerRole() && hasPractitionerRole(getPractitionerRoles(identity))) + || (!needsPractitionerRole() && identity instanceof OrganizationIdentity)); + } + + private Set getPractitionerRoles(Identity identity) + { + if (identity instanceof PractitionerIdentity p) + return p.getPractionerRoles(); + else + return Set.of(); + } + + private boolean hasPractitionerRole(Set practitionerRoles) + { + return practitionerRoles.stream().anyMatch( + c -> practitionerRoleSystem.equals(c.getSystem()) && practitionerRoleCode.equals(c.getCode())); + } + + @Override + public Extension toRecipientExtension() + { + return new Extension().setUrl(EXTENSION_PROCESS_AUTHORIZATION_RECIPIENT).setValue(toCoding(false)); + } + + @Override + public Extension toRequesterExtension() + { + return new Extension().setUrl(EXTENSION_PROCESS_AUTHORIZATION_REQUESTER) + .setValue(toCoding(needsPractitionerRole())); + } + + private Coding toCoding(boolean needsPractitionerRole) + { + Coding coding = getProcessAuthorizationCode(); + + if (needsPractitionerRole) + coding.addExtension().setUrl(EXTENSION_PROCESS_AUTHORIZATION_PRACTITIONER) + .setValue(new Coding(practitionerRoleSystem, practitionerRoleCode, null)); + + return coding; + } + + @Override + public Coding getProcessAuthorizationCode() + { + if (localIdentity) + { + if (needsPractitionerRole()) + return ProcessAuthorization.localAllPractitioner(); + else + return ProcessAuthorization.localAll(); + } + else + return ProcessAuthorization.remoteAll(); + } + + @Override + public boolean requesterMatches(Extension requesterExtension) + { + return matches(requesterExtension, EXTENSION_PROCESS_AUTHORIZATION_REQUESTER) + && hasMatchingPractitionerExtension(requesterExtension.getValue().getExtension()); + } + + @Override + public boolean recipientMatches(Extension recipientExtension) + { + return matches(recipientExtension, EXTENSION_PROCESS_AUTHORIZATION_RECIPIENT); + } + + private boolean matches(Extension extension, String url) + { + return extension != null && url.equals(extension.getUrl()) && extension.hasValue() + && extension.getValue() instanceof Coding value && matches(value); + } + + private boolean hasMatchingPractitionerExtension(List extensions) + { + return needsPractitionerRole() ? extensions.stream().anyMatch(this::practitionerExtensionMatches) + : extensions.stream().noneMatch(this::practitionerExtensionMatches); + } + + private boolean practitionerExtensionMatches(Extension extension) + { + return EXTENSION_PROCESS_AUTHORIZATION_PRACTITIONER.equals(extension.getUrl()) && extension.hasValue() + && extension.getValue() instanceof Coding value && practitionerRoleMatches(value); + } + + private boolean practitionerRoleMatches(Coding coding) + { + return coding != null && coding.hasSystem() && coding.hasCode() + && practitionerRoleSystem.equals(coding.getSystem()) && practitionerRoleCode.equals(coding.getCode()); + } + + @Override + public boolean matches(Coding processAuthorizationCode) + { + if (localIdentity) + if (needsPractitionerRole()) + return ProcessAuthorization.isLocalAllPractitioner(processAuthorizationCode); + else + return ProcessAuthorization.isLocalAll(processAuthorizationCode); + else + return ProcessAuthorization.isRemoteAll(processAuthorizationCode); + } + + public static Optional fromRequester(Coding coding, Predicate practitionerRoleExists) + { + if (ProcessAuthorization.isLocalAll(coding)) + return Optional.of(new All(true, null, null)); + else if (ProcessAuthorization.isRemoteAll(coding)) + return Optional.of(new All(false, null, null)); + else if (ProcessAuthorization.isLocalAllPractitioner(coding)) + return fromPractitionerRequester(coding, practitionerRoleExists); + else + return Optional.empty(); + } + + private static Optional fromPractitionerRequester(Coding coding, + Predicate practitionerRoleExists) + { + if (coding != null && coding.hasExtension()) + { + List practitionerRoles = coding.getExtension().stream().filter(Extension::hasUrl) + .filter(e -> EXTENSION_PROCESS_AUTHORIZATION_PRACTITIONER.equals(e.getUrl())) + .collect(Collectors.toList()); + if (practitionerRoles.size() == 1) + { + Extension practitionerRole = practitionerRoles.get(0); + if (practitionerRole.hasValue() && practitionerRole.getValue() instanceof Coding value + && value.hasSystem() && value.hasCode() && practitionerRoleExists.test(coding)) + { + return Optional.of(new All(true, value.getSystem(), value.getCode())); + } + } + } + + return Optional.empty(); + } + + public static Optional fromRecipient(Coding coding) + { + if (ProcessAuthorization.isLocalAll(coding)) + return Optional.of(new All(true, null, null)); + else + // remote not allowed for recipient + return Optional.empty(); + } +} \ No newline at end of file diff --git a/src/test/java/dev/dsf/fhir/profiles/Organization.java b/src/test/java/dev/dsf/fhir/profiles/Organization.java new file mode 100644 index 00000000..f6cac40b --- /dev/null +++ b/src/test/java/dev/dsf/fhir/profiles/Organization.java @@ -0,0 +1,340 @@ +/* + * Copyright 2018-2025 Heilbronn University of Applied Sciences + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package dev.dsf.fhir.profiles; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.hl7.fhir.r4.model.Coding; +import org.hl7.fhir.r4.model.Extension; +import org.hl7.fhir.r4.model.Identifier; +import org.hl7.fhir.r4.model.OrganizationAffiliation; + +import dev.dsf.bpe.v2.constants.CodeSystems.ProcessAuthorization; +import dev.dsf.bpe.v2.constants.NamingSystems.OrganizationIdentifier; +import dev.dsf.bpe.v2.service.process.Identity; +import dev.dsf.bpe.v2.service.process.OrganizationIdentity; +import dev.dsf.bpe.v2.service.process.PractitionerIdentity; +import dev.dsf.bpe.v2.service.process.ProcessAuthorizationHelper; +import dev.dsf.bpe.v2.service.process.Recipient; +import dev.dsf.bpe.v2.service.process.Requester; + +public class Organization implements Recipient, Requester +{ + private final String organizationIdentifier; + private final boolean localIdentity; + + private final String practitionerRoleSystem; + private final String practitionerRoleCode; + + public Organization(boolean localIdentity, String organizationIdentifier, String practitionerRoleSystem, + String practitionerRoleCode) + { + Objects.requireNonNull(organizationIdentifier, "organizationIdentifier"); + if (organizationIdentifier.isBlank()) + throw new IllegalArgumentException("organizationIdentifier blank"); + + this.localIdentity = localIdentity; + this.organizationIdentifier = organizationIdentifier; + + this.practitionerRoleSystem = practitionerRoleSystem; + this.practitionerRoleCode = practitionerRoleCode; + } + + private boolean needsPractitionerRole() + { + return practitionerRoleSystem != null && practitionerRoleCode != null; + } + + @Override + public boolean isRequesterAuthorized(Identity requester, Stream requesterAffiliations) + { + return isAuthorized(requester); + } + + @Override + public boolean isRecipientAuthorized(Identity recipient, Stream recipientAffiliations) + { + return isAuthorized(recipient); + } + + private boolean isAuthorized(Identity identity) + { + return identity != null && identity.getOrganization() != null && identity.getOrganization().getActive() + && identity.isLocalIdentity() == localIdentity && hasOrganizationIdentifier(identity.getOrganization()) + && ((needsPractitionerRole() && hasPractitionerRole(getPractitionerRoles(identity))) + || (!needsPractitionerRole() && identity instanceof OrganizationIdentity)); + } + + private boolean hasOrganizationIdentifier(org.hl7.fhir.r4.model.Organization organization) + { + return organization.getIdentifier().stream().filter(Identifier::hasSystem).filter(Identifier::hasValue) + .filter(i -> OrganizationIdentifier.SID.equals(i.getSystem())) + .anyMatch(i -> organizationIdentifier.equals(i.getValue())); + } + + private Set getPractitionerRoles(Identity identity) + { + if (identity instanceof PractitionerIdentity p) + return p.getPractionerRoles(); + else + return Set.of(); + } + + private boolean hasPractitionerRole(Set practitionerRoles) + { + return practitionerRoles.stream().anyMatch( + c -> practitionerRoleSystem.equals(c.getSystem()) && practitionerRoleCode.equals(c.getCode())); + } + + @Override + public Extension toRecipientExtension() + { + return new Extension().setUrl(ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_RECIPIENT) + .setValue(toCoding(false)); + } + + @Override + public Extension toRequesterExtension() + { + return new Extension().setUrl(ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_REQUESTER) + .setValue(toCoding(needsPractitionerRole())); + } + + private Coding toCoding(boolean needsPractitionerRole) + { + Identifier organization = OrganizationIdentifier.withValue(organizationIdentifier); + Coding coding = getProcessAuthorizationCode(); + + if (needsPractitionerRole) + { + Extension extension = coding.addExtension() + .setUrl(ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_ORGANIZATION_PRACTITIONER); + extension.addExtension( + ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_ORGANIZATION_PRACTITIONER_ORGANIZATION, + organization); + extension.addExtension( + ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_ORGANIZATION_PRACTITIONER_PRACTITIONER_ROLE, + new Coding(practitionerRoleSystem, practitionerRoleCode, null)); + } + else + { + coding.addExtension().setUrl(ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_ORGANIZATION) + .setValue(organization); + } + + return coding; + } + + @Override + public Coding getProcessAuthorizationCode() + { + if (localIdentity) + { + if (needsPractitionerRole()) + return ProcessAuthorization.localOrganizationPractitioner(); + else + return ProcessAuthorization.localOrganization(); + } + else + return ProcessAuthorization.remoteOrganization(); + } + + @Override + public boolean requesterMatches(Extension requesterExtension) + { + return matches(requesterExtension, ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_REQUESTER, + needsPractitionerRole()); + } + + @Override + public boolean recipientMatches(Extension recipientExtension) + { + return matches(recipientExtension, ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_RECIPIENT, false); + } + + private boolean matches(Extension extension, String url, boolean needsPractitionerRole) + { + return extension != null && url.equals(extension.getUrl()) && extension.hasValue() + && extension.getValue() instanceof Coding value && matches(value) && value.hasExtension() + && hasMatchingOrganizationExtension(value.getExtension(), needsPractitionerRole); + } + + private boolean hasMatchingOrganizationExtension(List extensions, boolean needsPractitionerRole) + { + return extensions.stream().anyMatch(organizationExtensionMatches(needsPractitionerRole)); + } + + private Predicate organizationExtensionMatches(boolean needsPractitionerRole) + { + if (needsPractitionerRole) + { + return extension -> ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_ORGANIZATION_PRACTITIONER + .equals(extension.getUrl()) && !extension.hasValue() + && hasMatchingSubOrganizationExtension(extension.getExtension()) + && hasMatchingPractitionerExtension(extension.getExtension()); + } + else + { + return extension -> ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_ORGANIZATION + .equals(extension.getUrl()) && extension.hasValue() + && extension.getValue() instanceof Identifier value && organizationIdentifierMatches(value); + } + } + + private boolean organizationIdentifierMatches(Identifier identifier) + { + return identifier != null && identifier.hasSystem() && identifier.hasValue() + && OrganizationIdentifier.SID.equals(identifier.getSystem()) + && organizationIdentifier.equals(identifier.getValue()); + } + + private boolean hasMatchingSubOrganizationExtension(List extensions) + { + return extensions.stream().anyMatch(this::subOrganizationExtensionMatches); + } + + private boolean subOrganizationExtensionMatches(Extension extension) + { + return ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_ORGANIZATION_PRACTITIONER_ORGANIZATION + .equals(extension.getUrl()) && extension.hasValue() && extension.getValue() instanceof Identifier value + && organizationIdentifierMatches(value); + } + + private boolean hasMatchingPractitionerExtension(List extensions) + { + return extensions.stream().anyMatch(this::practitionerExtensionMatches); + } + + private boolean practitionerExtensionMatches(Extension extension) + { + return ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_ORGANIZATION_PRACTITIONER_PRACTITIONER_ROLE + .equals(extension.getUrl()) && extension.hasValue() && extension.getValue() instanceof Coding value + && practitionerRoleMatches(value); + } + + private boolean practitionerRoleMatches(Coding coding) + { + return coding != null && coding.hasSystem() && coding.hasCode() + && practitionerRoleSystem.equals(coding.getSystem()) && practitionerRoleCode.equals(coding.getCode()); + } + + @Override + public boolean matches(Coding processAuthorizationCode) + { + if (localIdentity) + if (needsPractitionerRole()) + return ProcessAuthorization.isLocalOrganizationPractitioner(processAuthorizationCode); + else + return ProcessAuthorization.isLocalOrganization(processAuthorizationCode); + else + return ProcessAuthorization.isRemoteOrganization(processAuthorizationCode); + } + + public static Optional fromRequester(Coding coding, Predicate practitionerRoleExists, + Predicate organizationWithIdentifierExists) + { + if (ProcessAuthorization.isLocalOrganization(coding)) + return Optional.ofNullable(from(true, coding, organizationWithIdentifierExists)); + else if (ProcessAuthorization.isRemoteOrganization(coding)) + return Optional.ofNullable(from(false, coding, organizationWithIdentifierExists)); + else if (ProcessAuthorization.isLocalOrganizationPractitioner(coding)) + return fromPractitionerRequester(coding, practitionerRoleExists, organizationWithIdentifierExists); + else + return Optional.empty(); + } + + public static Optional fromRecipient(Coding coding, + Predicate organizationWithIdentifierExists) + { + if (ProcessAuthorization.isLocalOrganization(coding)) + return Optional.ofNullable(from(true, coding, organizationWithIdentifierExists)); + else + return Optional.empty(); + } + + private static Organization from(boolean localIdentity, Coding coding, + Predicate organizationWithIdentifierExists) + { + if (coding != null && coding.hasExtension()) + { + List organizations = coding.getExtension().stream().filter(Extension::hasUrl).filter( + e -> ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_ORGANIZATION.equals(e.getUrl())) + .collect(Collectors.toList()); + if (organizations.size() == 1) + { + Extension organization = organizations.get(0); + if (organization.hasValue() && organization.getValue() instanceof Identifier identifier + && OrganizationIdentifier.SID.equals(identifier.getSystem()) + && organizationWithIdentifierExists.test(identifier)) + { + return new Organization(localIdentity, identifier.getValue(), null, null); + } + } + } + + return null; + } + + private static Optional fromPractitionerRequester(Coding coding, + Predicate practitionerRoleExists, Predicate organizationWithIdentifierExists) + { + if (coding != null && coding.hasExtension()) + { + List organizationPractitioners = coding.getExtension().stream().filter(Extension::hasUrl) + .filter(e -> ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_ORGANIZATION_PRACTITIONER + .equals(e.getUrl())) + .collect(Collectors.toList()); + if (organizationPractitioners.size() == 1) + { + Extension organizationPractitioner = organizationPractitioners.get(0); + List organizations = organizationPractitioner.getExtension().stream() + .filter(Extension::hasUrl) + .filter(e -> ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_ORGANIZATION_PRACTITIONER_ORGANIZATION + .equals(e.getUrl())) + .collect(Collectors.toList()); + List practitionerRoles = organizationPractitioner.getExtension().stream() + .filter(Extension::hasUrl) + .filter(e -> ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_ORGANIZATION_PRACTITIONER_PRACTITIONER_ROLE + .equals(e.getUrl())) + .collect(Collectors.toList()); + if (organizations.size() == 1 && practitionerRoles.size() == 1) + { + Extension organization = organizations.get(0); + Extension practitionerRole = practitionerRoles.get(0); + + if (organization.hasValue() && organization.getValue() instanceof Identifier organizationIdentifier + && practitionerRole.hasValue() + && practitionerRole.getValue() instanceof Coding practitionerRoleCoding + && OrganizationIdentifier.SID.equals(organizationIdentifier.getSystem()) + && organizationWithIdentifierExists.test(organizationIdentifier) + && practitionerRoleExists.test(practitionerRoleCoding)) + { + return Optional.of(new Organization(true, organizationIdentifier.getValue(), + practitionerRoleCoding.getSystem(), practitionerRoleCoding.getCode())); + } + } + } + } + + return Optional.empty(); + } +} \ No newline at end of file diff --git a/src/test/java/dev/dsf/fhir/profiles/ProcessAuthorizationHelperImpl.java b/src/test/java/dev/dsf/fhir/profiles/ProcessAuthorizationHelperImpl.java new file mode 100644 index 00000000..56630eb6 --- /dev/null +++ b/src/test/java/dev/dsf/fhir/profiles/ProcessAuthorizationHelperImpl.java @@ -0,0 +1,520 @@ +/* + * Copyright 2018-2025 Heilbronn University of Applied Sciences + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package dev.dsf.fhir.profiles; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.hl7.fhir.r4.model.ActivityDefinition; +import org.hl7.fhir.r4.model.CanonicalType; +import org.hl7.fhir.r4.model.Coding; +import org.hl7.fhir.r4.model.Extension; +import org.hl7.fhir.r4.model.Identifier; +import org.hl7.fhir.r4.model.StringType; + +import dev.dsf.bpe.v2.constants.CodeSystems.ProcessAuthorization; +import dev.dsf.bpe.v2.service.process.ProcessAuthorizationHelper; +import dev.dsf.bpe.v2.service.process.Recipient; +import dev.dsf.bpe.v2.service.process.Requester; + +public class ProcessAuthorizationHelperImpl implements ProcessAuthorizationHelper +{ + private static final class RecipientFactoryImpl implements RecipientFactory + { + @Override + public Recipient localAll() + { + return new All(true, null, null); + } + + @Override + public Recipient localOrganization(String organizationIdentifier) + { + return new Organization(true, organizationIdentifier, null, null); + } + + @Override + public Recipient localRole(String parentOrganizationIdentifier, String roleSystem, String roleCode) + { + return new Role(true, parentOrganizationIdentifier, roleSystem, roleCode, null, null); + } + } + + private static final class RequesterFactoryImpl implements RequesterFactory + { + @Override + public Requester localAll() + { + return all(true, null, null); + } + + @Override + public Requester localAllPractitioner(String practitionerRoleSystem, String practitionerRoleCode) + { + return all(true, practitionerRoleSystem, practitionerRoleCode); + } + + @Override + public Requester remoteAll() + { + return all(false, null, null); + } + + private Requester all(boolean localIdentity, String userRoleSystem, String userRoleCode) + { + return new All(localIdentity, userRoleSystem, userRoleCode); + } + + @Override + public Requester localOrganization(String organizationIdentifier) + { + return organization(true, organizationIdentifier, null, null); + } + + @Override + public Requester localOrganizationPractitioner(String organizationIdentifier, String practitionerRoleSystem, + String practitionerRoleCode) + { + return organization(true, organizationIdentifier, practitionerRoleSystem, practitionerRoleCode); + } + + @Override + public Requester remoteOrganization(String organizationIdentifier) + { + return organization(false, organizationIdentifier, null, null); + } + + private Requester organization(boolean localIdentity, String organizationIdentifier, + String practitionerRoleSystem, String practitionerRoleCode) + { + return new Organization(localIdentity, organizationIdentifier, practitionerRoleSystem, + practitionerRoleCode); + } + + @Override + public Requester localRole(String parentOrganizationIdentifier, String organizatioRoleSystem, + String organizatioRoleCode) + { + return role(true, parentOrganizationIdentifier, organizatioRoleSystem, organizatioRoleCode, null, null); + } + + @Override + public Requester localRolePractitioner(String parentOrganizationIdentifier, String organizatioRoleSystem, + String organizatioRoleCode, String practitionerRoleSystem, String practitionerRoleCode) + { + return role(true, parentOrganizationIdentifier, organizatioRoleSystem, organizatioRoleCode, + practitionerRoleSystem, practitionerRoleCode); + } + + @Override + public Requester remoteRole(String parentOrganizationIdentifier, String organizatioRoleSystem, + String organizatioRoleCode) + { + return role(false, parentOrganizationIdentifier, organizatioRoleSystem, organizatioRoleCode, null, null); + } + + private Requester role(boolean localIdentity, String parentOrganizationIdentifier, String organizatioRoleSystem, + String organizatioRoleCode, String practitionerRoleSystem, String practitionerRoleCode) + { + return new Role(localIdentity, parentOrganizationIdentifier, organizatioRoleSystem, organizatioRoleCode, + practitionerRoleSystem, practitionerRoleCode); + } + } + + private static final RecipientFactory RECIPIENT_FACTORY = new RecipientFactoryImpl(); + private static final RequesterFactory REQUESTER_FACTORY = new RequesterFactoryImpl(); + + @Override + public RecipientFactory getRecipientFactory() + { + return RECIPIENT_FACTORY; + } + + @Override + public RequesterFactory getRequesterFactory() + { + return REQUESTER_FACTORY; + } + + @Override + public ActivityDefinition add(ActivityDefinition activityDefinition, String messageName, String taskProfile, + Requester requester, Recipient recipient) + { + Objects.requireNonNull(activityDefinition, "activityDefinition"); + Objects.requireNonNull(messageName, "messageName"); + if (messageName.isBlank()) + throw new IllegalArgumentException("messageName blank"); + Objects.requireNonNull(taskProfile, "taskProfile"); + if (taskProfile.isBlank()) + throw new IllegalArgumentException("taskProfile blank"); + Objects.requireNonNull(requester, "requester"); + Objects.requireNonNull(recipient, "recipient"); + + Extension extension = getExtensionByMessageNameAndTaskProfile(activityDefinition, messageName, taskProfile); + if (!hasAuthorization(extension, requester)) + extension.addExtension(requester.toRequesterExtension()); + if (!hasAuthorization(extension, recipient)) + extension.addExtension(recipient.toRecipientExtension()); + + return activityDefinition; + } + + @Override + public ActivityDefinition add(ActivityDefinition activityDefinition, String messageName, String taskProfile, + Collection requesters, Collection recipients) + { + Objects.requireNonNull(activityDefinition, "activityDefinition"); + Objects.requireNonNull(messageName, "messageName"); + if (messageName.isBlank()) + throw new IllegalArgumentException("messageName blank"); + Objects.requireNonNull(taskProfile, "taskProfile"); + if (taskProfile.isBlank()) + throw new IllegalArgumentException("taskProfile blank"); + Objects.requireNonNull(requesters, "requesters"); + if (requesters.isEmpty()) + throw new IllegalArgumentException("requesters empty"); + Objects.requireNonNull(recipients, "recipients"); + if (recipients.isEmpty()) + throw new IllegalArgumentException("recipients empty"); + + Extension extension = getExtensionByMessageNameAndTaskProfile(activityDefinition, messageName, taskProfile); + requesters.stream().filter(r -> !hasAuthorization(extension, r)) + .forEach(r -> extension.addExtension(r.toRequesterExtension())); + recipients.stream().filter(r -> !hasAuthorization(extension, r)) + .forEach(r -> extension.addExtension(r.toRecipientExtension())); + + return activityDefinition; + } + + private Extension getExtensionByMessageNameAndTaskProfile(ActivityDefinition a, String messageName, + String taskProfile) + { + return a.getExtension().stream().filter(Extension::hasUrl) + .filter(e -> EXTENSION_PROCESS_AUTHORIZATION.equals(e.getUrl())).filter(Extension::hasExtension) + .filter(e -> hasMessageName(e, messageName) && hasTaskProfileExact(e, taskProfile)).findFirst() + .orElseGet(() -> + { + Extension e = newExtension(messageName, taskProfile); + a.addExtension(e); + return e; + }); + } + + private boolean hasMessageName(Extension processAuthorization, String messageName) + { + return processAuthorization.getExtension().stream().filter(Extension::hasUrl) + .filter(e -> EXTENSION_PROCESS_AUTHORIZATION_MESSAGE_NAME.equals(e.getUrl())) + .filter(Extension::hasValue).filter(e -> e.getValue() instanceof StringType) + .map(e -> (StringType) e.getValue()).anyMatch(s -> messageName.equals(s.getValueAsString())); + } + + private boolean hasTaskProfileExact(Extension processAuthorization, String taskProfile) + { + return processAuthorization.getExtension().stream().filter(Extension::hasUrl) + .filter(e -> EXTENSION_PROCESS_AUTHORIZATION_TASK_PROFILE.equals(e.getUrl())) + .filter(Extension::hasValue).filter(e -> e.getValue() instanceof CanonicalType) + .map(e -> (CanonicalType) e.getValue()).anyMatch(c -> taskProfile.equals(c.getValueAsString())); + } + + private Extension newExtension(String messageName, String taskProfile) + { + Extension e = new Extension(EXTENSION_PROCESS_AUTHORIZATION); + e.addExtension(newMessageName(messageName)); + e.addExtension(newTaskProfile(taskProfile)); + + return e; + } + + private Extension newMessageName(String messageName) + { + return new Extension(EXTENSION_PROCESS_AUTHORIZATION_MESSAGE_NAME).setValue(new StringType(messageName)); + } + + private Extension newTaskProfile(String taskProfile) + { + return new Extension(EXTENSION_PROCESS_AUTHORIZATION_TASK_PROFILE).setValue(new CanonicalType(taskProfile)); + } + + private boolean hasAuthorization(Extension processAuthorization, Requester authorization) + { + return processAuthorization.getExtension().stream().anyMatch(authorization::requesterMatches); + } + + private boolean hasAuthorization(Extension processAuthorization, Recipient authorization) + { + return processAuthorization.getExtension().stream().anyMatch(authorization::recipientMatches); + } + + @Override + public boolean isValid(ActivityDefinition activityDefinition, Predicate profileExists, + Predicate practitionerRoleExists, Predicate organizationWithIdentifierExists, + Predicate organizationRoleExists) + { + if (activityDefinition == null) + return false; + + List processAuthorizations = activityDefinition.getExtension().stream().filter(Extension::hasUrl) + .filter(e -> EXTENSION_PROCESS_AUTHORIZATION.equals(e.getUrl())).collect(Collectors.toList()); + + if (processAuthorizations.isEmpty()) + return false; + + return processAuthorizations.stream() + .map(e -> isProcessAuthorizationValid(e, profileExists, practitionerRoleExists, + organizationWithIdentifierExists, organizationRoleExists)) + .allMatch(v -> v) && messageNamesUnique(processAuthorizations); + } + + private boolean messageNamesUnique(List processAuthorizations) + { + return processAuthorizations.size() == processAuthorizations.stream().flatMap(e -> e.getExtension().stream() + .filter(mn -> EXTENSION_PROCESS_AUTHORIZATION_MESSAGE_NAME.equals(mn.getUrl())).map(Extension::getValue) + .map(v -> (StringType) v).map(StringType::getValueAsString).findFirst().stream()).distinct().count(); + } + + private boolean isProcessAuthorizationValid(Extension processAuthorization, Predicate profileExists, + Predicate practitionerRoleExists, Predicate organizationWithIdentifierExists, + Predicate organizationRoleExists) + { + if (processAuthorization == null || !EXTENSION_PROCESS_AUTHORIZATION.equals(processAuthorization.getUrl()) + || !processAuthorization.hasExtension()) + return false; + + List messageNames = new ArrayList<>(), taskProfiles = new ArrayList<>(), + requesters = new ArrayList<>(), recipients = new ArrayList<>(); + for (Extension extension : processAuthorization.getExtension()) + { + if (extension.hasUrl()) + { + switch (extension.getUrl()) + { + case EXTENSION_PROCESS_AUTHORIZATION_MESSAGE_NAME: + messageNames.add(extension); + break; + case EXTENSION_PROCESS_AUTHORIZATION_TASK_PROFILE: + taskProfiles.add(extension); + break; + case EXTENSION_PROCESS_AUTHORIZATION_REQUESTER: + requesters.add(extension); + break; + case EXTENSION_PROCESS_AUTHORIZATION_RECIPIENT: + recipients.add(extension); + break; + } + } + } + + if (messageNames.size() != 1 || taskProfiles.size() != 1 || requesters.isEmpty() || recipients.isEmpty()) + return false; + + return isMessageNameValid(messageNames.get(0)) && isTaskProfileValid(taskProfiles.get(0), profileExists) + && isRequestersValid(requesters, practitionerRoleExists, organizationWithIdentifierExists, + organizationRoleExists) + && isRecipientsValid(recipients, organizationWithIdentifierExists, organizationRoleExists); + } + + private boolean isMessageNameValid(Extension messageName) + { + if (messageName == null || !EXTENSION_PROCESS_AUTHORIZATION_MESSAGE_NAME.equals(messageName.getUrl())) + return false; + + return messageName.hasValue() && messageName.getValue() instanceof StringType value + && !value.getValueAsString().isBlank(); + } + + private boolean isTaskProfileValid(Extension taskProfile, Predicate profileExists) + { + if (taskProfile == null || !EXTENSION_PROCESS_AUTHORIZATION_TASK_PROFILE.equals(taskProfile.getUrl())) + return false; + + return taskProfile.hasValue() && taskProfile.getValue() instanceof CanonicalType value + && profileExists.test(value); + } + + private boolean isRequestersValid(List requesters, Predicate practitionerRoleExists, + Predicate organizationWithIdentifierExists, Predicate organizationRoleExists) + { + return requesters.stream().allMatch(r -> isRequesterValid(r, practitionerRoleExists, + organizationWithIdentifierExists, organizationRoleExists)); + } + + private boolean isRequesterValid(Extension requester, Predicate practitionerRoleExists, + Predicate organizationWithIdentifierExists, Predicate organizationRoleExists) + { + if (requester == null || !EXTENSION_PROCESS_AUTHORIZATION_REQUESTER.equals(requester.getUrl())) + return false; + + if (requester.hasValue() && requester.getValue() instanceof Coding value) + { + return requesterFrom(value, practitionerRoleExists, organizationWithIdentifierExists, + organizationRoleExists).isPresent(); + } + + return false; + } + + private Optional requesterFrom(Coding coding, Predicate practitionerRoleExists, + Predicate organizationWithIdentifierExists, Predicate organizatioRoleExists) + { + switch (coding.getCode()) + { + case ProcessAuthorization.Codes.LOCAL_ALL: + case ProcessAuthorization.Codes.LOCAL_ALL_PRACTITIONER: + case ProcessAuthorization.Codes.REMOTE_ALL: + return All.fromRequester(coding, practitionerRoleExists); + + case ProcessAuthorization.Codes.LOCAL_ORGANIZATION: + case ProcessAuthorization.Codes.LOCAL_ORGANIZATION_PRACTITIONER: + case ProcessAuthorization.Codes.REMOTE_ORGANIZATION: + return Organization.fromRequester(coding, practitionerRoleExists, organizationWithIdentifierExists); + + case ProcessAuthorization.Codes.LOCAL_ROLE: + case ProcessAuthorization.Codes.LOCAL_ROLE_PRACTITIONER: + case ProcessAuthorization.Codes.REMOTE_ROLE: + return Role.fromRequester(coding, practitionerRoleExists, organizationWithIdentifierExists, + organizatioRoleExists); + } + + return Optional.empty(); + } + + private boolean isRecipientsValid(List recipients, + Predicate organizationWithIdentifierExists, Predicate organizationRoleExists) + { + return recipients.stream() + .allMatch(r -> isRecipientValid(r, organizationWithIdentifierExists, organizationRoleExists)); + } + + private boolean isRecipientValid(Extension recipient, Predicate organizationWithIdentifierExists, + Predicate organizationRoleExists) + { + if (recipient == null || !EXTENSION_PROCESS_AUTHORIZATION_RECIPIENT.equals(recipient.getUrl())) + return false; + + if (recipient.hasValue() && recipient.getValue() instanceof Coding value) + { + return recipientFrom(value, organizationWithIdentifierExists, organizationRoleExists).isPresent(); + } + + return false; + } + + private Optional recipientFrom(Coding coding, Predicate organizationWithIdentifierExists, + Predicate organizationRoleExists) + { + return switch (coding.getCode()) + { + case ProcessAuthorization.Codes.LOCAL_ALL -> All.fromRecipient(coding); + + case ProcessAuthorization.Codes.LOCAL_ORGANIZATION -> Organization.fromRecipient(coding, + organizationWithIdentifierExists); + + case ProcessAuthorization.Codes.LOCAL_ROLE -> Role.fromRecipient(coding, organizationWithIdentifierExists, + organizationRoleExists); + + default -> Optional.empty(); + }; + } + + @Override + public Stream getRequesters(ActivityDefinition activityDefinition, String processUrl, + String processVersion, String messageName, Collection taskProfiles) + { + Optional authorizationExtension = getAuthorizationExtension(activityDefinition, processUrl, + processVersion, messageName, taskProfiles); + + if (authorizationExtension.isEmpty()) + return Stream.empty(); + else + return authorizationExtension.get().getExtension().stream().filter(Extension::hasUrl) + .filter(e -> EXTENSION_PROCESS_AUTHORIZATION_REQUESTER.equals(e.getUrl())) + .filter(Extension::hasValue).filter(e -> e.getValue() instanceof Coding) + .map(e -> (Coding) e.getValue()) + .flatMap(coding -> requesterFrom(coding, _ -> true, _ -> true, _ -> true).stream()); + } + + @Override + public Stream getRecipients(ActivityDefinition activityDefinition, String processUrl, + String processVersion, String messageName, Collection taskProfiles) + { + Optional authorizationExtension = getAuthorizationExtension(activityDefinition, processUrl, + processVersion, messageName, taskProfiles); + + if (authorizationExtension.isEmpty()) + return Stream.empty(); + else + return authorizationExtension.get().getExtension().stream().filter(Extension::hasUrl) + .filter(e -> EXTENSION_PROCESS_AUTHORIZATION_RECIPIENT.equals(e.getUrl())) + .filter(Extension::hasValue).filter(e -> e.getValue() instanceof Coding) + .map(e -> (Coding) e.getValue()) + .flatMap(coding -> recipientFrom(coding, _ -> true, _ -> true).stream()); + } + + private Optional getAuthorizationExtension(ActivityDefinition activityDefinition, String processUrl, + String processVersion, String messageName, Collection taskProfiles) + { + if (activityDefinition == null || processUrl == null || processUrl.isBlank() || processVersion == null + || processVersion.isBlank() || messageName == null || messageName.isBlank() || taskProfiles == null) + return Optional.empty(); + + if (!processUrl.equals(activityDefinition.getUrl()) || !processVersion.equals(activityDefinition.getVersion())) + return Optional.empty(); + + Optional authorizationExtension = activityDefinition.getExtension().stream() + .filter(Extension::hasUrl).filter(e -> EXTENSION_PROCESS_AUTHORIZATION.equals(e.getUrl())) + .filter(Extension::hasExtension) + .filter(e -> hasMessageName(e, messageName) && hasTaskProfile(e, taskProfiles)).findFirst(); + return authorizationExtension; + } + + private boolean hasTaskProfile(Extension processAuthorization, Collection taskProfiles) + { + return taskProfiles.stream() + .anyMatch(taskProfile -> hasTaskProfileNotVersionSpecific(processAuthorization, taskProfile)); + } + + private boolean hasTaskProfileNotVersionSpecific(Extension processAuthorization, String taskProfile) + { + return processAuthorization.getExtension().stream().filter(Extension::hasUrl) + .filter(e -> EXTENSION_PROCESS_AUTHORIZATION_TASK_PROFILE.equals(e.getUrl())) + .filter(Extension::hasValue).filter(e -> e.getValue() instanceof CanonicalType) + .map(e -> (CanonicalType) e.getValue()) + + // match if task profile is equal to value in activity definition + // or match if task profile is not version specific but value in activity definition is and non version + // specific profiles are same -> client does not care about version of task resource, may result in + // validation errors + .anyMatch(c -> taskProfile.equals(c.getValueAsString()) + || taskProfile.equals(getBase(c.getValueAsString()))); + } + + private static String getBase(String canonicalUrl) + { + if (canonicalUrl.contains("|")) + { + String[] split = canonicalUrl.split("\\|"); + return split[0]; + } + else + return canonicalUrl; + } +} diff --git a/src/test/java/dev/dsf/fhir/profiles/RequesterFactoryImpl.java b/src/test/java/dev/dsf/fhir/profiles/RequesterFactoryImpl.java new file mode 100644 index 00000000..72889314 --- /dev/null +++ b/src/test/java/dev/dsf/fhir/profiles/RequesterFactoryImpl.java @@ -0,0 +1,99 @@ +/* + * Copyright 2018-2025 Heilbronn University of Applied Sciences + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package dev.dsf.fhir.profiles; + +import dev.dsf.bpe.v2.service.process.ProcessAuthorizationHelper.RequesterFactory; +import dev.dsf.bpe.v2.service.process.Requester; + +public class RequesterFactoryImpl implements RequesterFactory +{ + @Override + public Requester localAll() + { + return all(true, null, null); + } + + @Override + public Requester localAllPractitioner(String practitionerRoleSystem, String practitionerRoleCode) + { + return all(true, practitionerRoleSystem, practitionerRoleCode); + } + + @Override + public Requester remoteAll() + { + return all(false, null, null); + } + + private Requester all(boolean localIdentity, String userRoleSystem, String userRoleCode) + { + return new All(localIdentity, userRoleSystem, userRoleCode); + } + + @Override + public Requester localOrganization(String organizationIdentifier) + { + return organization(true, organizationIdentifier, null, null); + } + + @Override + public Requester localOrganizationPractitioner(String organizationIdentifier, String practitionerRoleSystem, + String practitionerRoleCode) + { + return organization(true, organizationIdentifier, practitionerRoleSystem, practitionerRoleCode); + } + + @Override + public Requester remoteOrganization(String organizationIdentifier) + { + return organization(false, organizationIdentifier, null, null); + } + + private Requester organization(boolean localIdentity, String organizationIdentifier, String practitionerRoleSystem, + String practitionerRoleCode) + { + return new Organization(localIdentity, organizationIdentifier, practitionerRoleSystem, practitionerRoleCode); + } + + @Override + public Requester localRole(String parentOrganizationIdentifier, String organizatioRoleSystem, + String organizatioRoleCode) + { + return role(true, parentOrganizationIdentifier, organizatioRoleSystem, organizatioRoleCode, null, null); + } + + @Override + public Requester localRolePractitioner(String parentOrganizationIdentifier, String organizatioRoleSystem, + String organizatioRoleCode, String practitionerRoleSystem, String practitionerRoleCode) + { + return role(true, parentOrganizationIdentifier, organizatioRoleSystem, organizatioRoleCode, + practitionerRoleSystem, practitionerRoleCode); + } + + @Override + public Requester remoteRole(String parentOrganizationIdentifier, String organizatioRoleSystem, + String organizatioRoleCode) + { + return role(false, parentOrganizationIdentifier, organizatioRoleSystem, organizatioRoleCode, null, null); + } + + private Requester role(boolean localIdentity, String parentOrganizationIdentifier, String organizatioRoleSystem, + String organizatioRoleCode, String practitionerRoleSystem, String practitionerRoleCode) + { + return new Role(localIdentity, parentOrganizationIdentifier, organizatioRoleSystem, organizatioRoleCode, + practitionerRoleSystem, practitionerRoleCode); + } +} diff --git a/src/test/java/dev/dsf/fhir/profiles/Role.java b/src/test/java/dev/dsf/fhir/profiles/Role.java new file mode 100644 index 00000000..ef5c44c3 --- /dev/null +++ b/src/test/java/dev/dsf/fhir/profiles/Role.java @@ -0,0 +1,450 @@ +/* + * Copyright 2018-2025 Heilbronn University of Applied Sciences + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package dev.dsf.fhir.profiles; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.hl7.fhir.r4.model.CodeableConcept; +import org.hl7.fhir.r4.model.Coding; +import org.hl7.fhir.r4.model.Extension; +import org.hl7.fhir.r4.model.Identifier; +import org.hl7.fhir.r4.model.OrganizationAffiliation; + +import dev.dsf.bpe.v2.constants.CodeSystems.ProcessAuthorization; +import dev.dsf.bpe.v2.constants.NamingSystems.OrganizationIdentifier; +import dev.dsf.bpe.v2.service.process.Identity; +import dev.dsf.bpe.v2.service.process.OrganizationIdentity; +import dev.dsf.bpe.v2.service.process.PractitionerIdentity; +import dev.dsf.bpe.v2.service.process.ProcessAuthorizationHelper; +import dev.dsf.bpe.v2.service.process.Recipient; +import dev.dsf.bpe.v2.service.process.Requester; + +public class Role implements Recipient, Requester +{ + private final boolean localIdentity; + private final String parentOrganizationIdentifier; + private final String organizationRoleSystem; + private final String organizationRoleCode; + + private final String practitionerRoleSystem; + private final String practitionerRoleCode; + + public Role(boolean localIdentity, String parentOrganizationIdentifier, String organizatioRoleSystem, + String organizationRoleCode, String practitionerRoleSystem, String practitionerRoleCode) + { + Objects.requireNonNull(parentOrganizationIdentifier, "parentOrganizationIdentifier"); + if (parentOrganizationIdentifier.isBlank()) + throw new IllegalArgumentException("parentOrganizationIdentifier blank"); + Objects.requireNonNull(organizatioRoleSystem, "organizatioRoleSystem"); + if (organizatioRoleSystem.isBlank()) + throw new IllegalArgumentException("organizatioRoleSystem blank"); + Objects.requireNonNull(organizationRoleCode, "organizationRoleCode"); + if (organizationRoleCode.isBlank()) + throw new IllegalArgumentException("organizationRoleCode blank"); + + this.localIdentity = localIdentity; + this.parentOrganizationIdentifier = parentOrganizationIdentifier; + this.organizationRoleSystem = organizatioRoleSystem; + this.organizationRoleCode = organizationRoleCode; + + this.practitionerRoleSystem = practitionerRoleSystem; + this.practitionerRoleCode = practitionerRoleCode; + } + + private boolean needsPractitionerRole() + { + return practitionerRoleSystem != null && practitionerRoleCode != null; + } + + @Override + public boolean isRequesterAuthorized(Identity requester, Stream requesterAffiliations) + { + return isAuthorized(requester, requesterAffiliations); + } + + @Override + public boolean isRecipientAuthorized(Identity recipient, Stream recipientAffiliations) + { + return isAuthorized(recipient, recipientAffiliations); + } + + private boolean isAuthorized(Identity identity, Stream affiliations) + { + return identity != null && identity.getOrganization() != null && identity.getOrganization().getActive() + && identity.isLocalIdentity() == localIdentity && affiliations != null + && hasParentOrganizationMemberRole(identity.getOrganization(), affiliations) + && ((needsPractitionerRole() && hasPractitionerRole(getPractitionerRoles(identity))) + || (!needsPractitionerRole() && identity instanceof OrganizationIdentity)); + } + + private boolean hasParentOrganizationMemberRole(org.hl7.fhir.r4.model.Organization recipientOrganization, + Stream affiliations) + { + return affiliations + + // check affiliation active + .filter(OrganizationAffiliation::getActive) + + // check parent-organization identifier + .filter(OrganizationAffiliation::hasOrganization).filter(a -> a.getOrganization().hasIdentifier()) + .filter(a -> a.getOrganization().getIdentifier().hasSystem()) + .filter(a -> a.getOrganization().getIdentifier().hasValue()) + .filter(a -> OrganizationIdentifier.SID.equals(a.getOrganization().getIdentifier().getSystem())) + .filter(a -> parentOrganizationIdentifier.equals(a.getOrganization().getIdentifier().getValue())) + + // check member identifier + .filter(OrganizationAffiliation::hasParticipatingOrganization) + .filter(a -> a.getParticipatingOrganization().hasIdentifier()) + .filter(a -> a.getParticipatingOrganization().getIdentifier().hasSystem()) + .filter(a -> a.getParticipatingOrganization().getIdentifier().hasValue()).filter(a -> + { + final Identifier memberIdentifier = a.getParticipatingOrganization().getIdentifier(); + return recipientOrganization.getIdentifier().stream().filter(Identifier::hasSystem) + .filter(Identifier::hasValue) + .anyMatch(i -> i.getSystem().equals(memberIdentifier.getSystem()) + && i.getValue().equals(memberIdentifier.getValue())); + }) + + // check role + .filter(OrganizationAffiliation::hasCode).flatMap(a -> a.getCode().stream()) + .filter(CodeableConcept::hasCoding).flatMap(c -> c.getCoding().stream()).filter(Coding::hasSystem) + .filter(Coding::hasCode).anyMatch( + c -> c.getSystem().equals(organizationRoleSystem) && c.getCode().equals(organizationRoleCode)); + } + + private Set getPractitionerRoles(Identity identity) + { + if (identity instanceof PractitionerIdentity p) + return p.getPractionerRoles(); + else + return Set.of(); + } + + private boolean hasPractitionerRole(Set practitionerRoles) + { + return practitionerRoles.stream().anyMatch( + c -> practitionerRoleSystem.equals(c.getSystem()) && practitionerRoleCode.equals(c.getCode())); + } + + @Override + public Extension toRecipientExtension() + { + return new Extension().setUrl(ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_RECIPIENT) + .setValue(toCoding(false)); + } + + @Override + public Extension toRequesterExtension() + { + return new Extension().setUrl(ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_REQUESTER) + .setValue(toCoding(needsPractitionerRole())); + } + + private Coding toCoding(boolean needsPractitionerRole) + { + Identifier parentOrganization = OrganizationIdentifier.withValue(parentOrganizationIdentifier); + Extension parentOrganizationExt = new Extension( + ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_PARENT_ORGANIZATION_ROLE_PARENT_ORGANIZATION, + parentOrganization); + + Coding organizationRole = new Coding(organizationRoleSystem, organizationRoleCode, null); + Extension organizationRoleExt = new Extension( + ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_PARENT_ORGANIZATION_ROLE_ORGANIZATION_ROLE, + organizationRole); + + Coding coding = getProcessAuthorizationCode(); + + if (needsPractitionerRole) + { + Extension practitionerRoleExt = new Extension( + ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_PARENT_ORGANIZATION_ROLE_PRACTITIONER_PRACTITIONER_ROLE, + new Coding(practitionerRoleSystem, practitionerRoleCode, null)); + + coding.addExtension().setUrl( + ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_PARENT_ORGANIZATION_ROLE_PRACTITIONER) + .addExtension(parentOrganizationExt).addExtension(organizationRoleExt) + .addExtension(practitionerRoleExt); + } + else + { + coding.addExtension() + .setUrl(ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_PARENT_ORGANIZATION_ROLE) + .addExtension(parentOrganizationExt).addExtension(organizationRoleExt); + } + + return coding; + } + + @Override + public Coding getProcessAuthorizationCode() + { + if (localIdentity) + { + if (needsPractitionerRole()) + return ProcessAuthorization.localRolePractitioner(); + else + return ProcessAuthorization.localRole(); + } + else + return ProcessAuthorization.remoteRole(); + } + + @Override + public boolean requesterMatches(Extension requesterExtension) + { + return matches(requesterExtension, ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_REQUESTER, + needsPractitionerRole()); + } + + @Override + public boolean recipientMatches(Extension recipientExtension) + { + return matches(recipientExtension, ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_RECIPIENT, false); + } + + private boolean matches(Extension extension, String url, boolean needsPractitionerRole) + { + return extension != null && url.equals(extension.getUrl()) && extension.hasValue() + && extension.getValue() instanceof Coding value && matches(value) && value.hasExtension() + && hasMatchingParentOrganizationRoleExtension(value.getExtension(), needsPractitionerRole); + } + + private boolean hasMatchingParentOrganizationRoleExtension(List extension, boolean needsPractitionerRole) + { + return extension.stream().anyMatch(parentOrganizationRoleExtensionMatches(needsPractitionerRole)); + } + + private Predicate parentOrganizationRoleExtensionMatches(boolean needsPractitionerRole) + { + if (needsPractitionerRole) + { + return extension -> ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_PARENT_ORGANIZATION_ROLE_PRACTITIONER + .equals(extension.getUrl()) && extension.hasExtension() + && hasMatchingParentOrganizationExtension(extension.getExtension()) + && hasMatchingOrganizationRoleExtension(extension.getExtension()) + && hasMatchingPractitionerRoleExtension(extension.getExtension()); + } + else + { + return extension -> ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_PARENT_ORGANIZATION_ROLE + .equals(extension.getUrl()) && extension.hasExtension() + && hasMatchingParentOrganizationExtension(extension.getExtension()) + && hasMatchingOrganizationRoleExtension(extension.getExtension()); + } + } + + private boolean hasMatchingParentOrganizationExtension(List extensions) + { + return extensions.stream().anyMatch(this::parentOrganizationExtensionMatches); + } + + private boolean parentOrganizationExtensionMatches(Extension extension) + { + return ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_PARENT_ORGANIZATION_ROLE_PARENT_ORGANIZATION + .equals(extension.getUrl()) && extension.hasValue() && extension.getValue() instanceof Identifier value + && parentOrganizationIdentifierMatches(value); + } + + private boolean parentOrganizationIdentifierMatches(Identifier identifier) + { + return identifier != null && identifier.hasSystem() && identifier.hasValue() + && OrganizationIdentifier.SID.equals(identifier.getSystem()) + && parentOrganizationIdentifier.equals(identifier.getValue()); + } + + private boolean hasMatchingOrganizationRoleExtension(List extensions) + { + return extensions.stream().anyMatch(this::organizationRoleExtensionMatches); + } + + private boolean organizationRoleExtensionMatches(Extension extension) + { + return ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_PARENT_ORGANIZATION_ROLE_ORGANIZATION_ROLE + .equals(extension.getUrl()) && extension.hasValue() && extension.getValue() instanceof Coding value + && organizationRoleMatches(value); + } + + private boolean organizationRoleMatches(Coding coding) + { + return coding != null && coding.hasSystem() && coding.hasCode() + && organizationRoleSystem.equals(coding.getSystem()) && organizationRoleCode.equals(coding.getCode()); + } + + private boolean hasMatchingPractitionerRoleExtension(List extensions) + { + return extensions.stream().anyMatch(this::practitionerRoleExtensionMatches); + } + + private boolean practitionerRoleExtensionMatches(Extension extension) + { + return ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_PARENT_ORGANIZATION_ROLE_PRACTITIONER_PRACTITIONER_ROLE + .equals(extension.getUrl()) && extension.hasValue() && extension.getValue() instanceof Coding value + && practitionerRoleMatches(value); + } + + private boolean practitionerRoleMatches(Coding coding) + { + return coding != null && coding.hasSystem() && coding.hasCode() + && practitionerRoleSystem.equals(coding.getSystem()) && practitionerRoleCode.equals(coding.getCode()); + } + + @Override + public boolean matches(Coding processAuthorizationCode) + { + if (localIdentity) + if (needsPractitionerRole()) + return ProcessAuthorization.isLocalRolePractitioner(processAuthorizationCode); + else + return ProcessAuthorization.isLocalRole(processAuthorizationCode); + else + return ProcessAuthorization.isRemoteRole(processAuthorizationCode); + } + + public static Optional fromRequester(Coding coding, Predicate practitionerRoleExists, + Predicate organizationWithIdentifierExists, Predicate organizationRoleExists) + { + if (ProcessAuthorization.isLocalRole(coding)) + return Optional.ofNullable(from(true, coding, organizationWithIdentifierExists, organizationRoleExists)); + else if (ProcessAuthorization.isRemoteRole(coding)) + return Optional.ofNullable(from(false, coding, organizationWithIdentifierExists, organizationRoleExists)); + else if (ProcessAuthorization.isLocalRolePractitioner(coding)) + return fromPractitionerRequester(coding, practitionerRoleExists, organizationWithIdentifierExists, + organizationRoleExists); + else + return Optional.empty(); + } + + public static Optional fromRecipient(Coding coding, + Predicate organizationWithIdentifierExists, Predicate organizationRoleExists) + { + if (ProcessAuthorization.isLocalRole(coding)) + return Optional.ofNullable(from(true, coding, organizationWithIdentifierExists, organizationRoleExists)); + else + return Optional.empty(); + } + + private static Role from(boolean localIdentity, Coding coding, + Predicate organizationWithIdentifierExists, Predicate organizationRoleExists) + { + if (coding != null && coding.hasExtension()) + { + List parentOrganizationRoles = coding.getExtension().stream().filter(Extension::hasUrl) + .filter(e -> ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_PARENT_ORGANIZATION_ROLE + .equals(e.getUrl())) + .collect(Collectors.toList()); + + if (parentOrganizationRoles.size() == 1) + { + Extension parentOrganizationRole = parentOrganizationRoles.get(0); + List parentOrganizations = parentOrganizationRole.getExtension().stream() + .filter(Extension::hasUrl) + .filter(e -> ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_PARENT_ORGANIZATION_ROLE_PARENT_ORGANIZATION + .equals(e.getUrl())) + .collect(Collectors.toList()); + List organizationRoles = parentOrganizationRole.getExtension().stream() + .filter(Extension::hasUrl) + .filter(e -> ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_PARENT_ORGANIZATION_ROLE_ORGANIZATION_ROLE + .equals(e.getUrl())) + .collect(Collectors.toList()); + + if (parentOrganizations.size() == 1 && organizationRoles.size() == 1) + { + Extension parentOrganization = parentOrganizations.get(0); + Extension organizationRole = organizationRoles.get(0); + + if (parentOrganization.hasValue() + && parentOrganization.getValue() instanceof Identifier parentOrganizationIdentifier + && organizationRole.hasValue() + && organizationRole.getValue() instanceof Coding organizationRoleCoding + && OrganizationIdentifier.SID.equals(parentOrganizationIdentifier.getSystem()) + && organizationWithIdentifierExists.test(parentOrganizationIdentifier) + && organizationRoleExists.test(organizationRoleCoding)) + { + return new Role(localIdentity, parentOrganizationIdentifier.getValue(), + organizationRoleCoding.getSystem(), organizationRoleCoding.getCode(), null, null); + } + } + } + } + + return null; + } + + private static Optional fromPractitionerRequester(Coding coding, + Predicate practitionerRoleExists, Predicate organizationWithIdentifierExists, + Predicate organizationRoleExists) + { + if (coding != null && coding.hasExtension()) + { + List parentOrganizationRolePractitioners = coding.getExtension().stream() + .filter(Extension::hasUrl) + .filter(e -> ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_PARENT_ORGANIZATION_ROLE_PRACTITIONER + .equals(e.getUrl())) + .collect(Collectors.toList()); + + if (parentOrganizationRolePractitioners.size() == 1) + { + Extension parentOrganizationRolePractitioner = parentOrganizationRolePractitioners.get(0); + List parentOrganizations = parentOrganizationRolePractitioner.getExtension().stream() + .filter(Extension::hasUrl) + .filter(e -> ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_PARENT_ORGANIZATION_ROLE_PARENT_ORGANIZATION + .equals(e.getUrl())) + .collect(Collectors.toList()); + List organizationRoles = parentOrganizationRolePractitioner.getExtension().stream() + .filter(Extension::hasUrl) + .filter(e -> ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_PARENT_ORGANIZATION_ROLE_ORGANIZATION_ROLE + .equals(e.getUrl())) + .collect(Collectors.toList()); + List practitionerRoles = parentOrganizationRolePractitioner.getExtension().stream() + .filter(Extension::hasUrl) + .filter(e -> ProcessAuthorizationHelper.EXTENSION_PROCESS_AUTHORIZATION_PARENT_ORGANIZATION_ROLE_PRACTITIONER_PRACTITIONER_ROLE + .equals(e.getUrl())) + .collect(Collectors.toList()); + + if (parentOrganizations.size() == 1 && organizationRoles.size() == 1 && practitionerRoles.size() == 1) + { + Extension parentOrganization = parentOrganizations.get(0); + Extension organizationRole = organizationRoles.get(0); + Extension practitionerRole = practitionerRoles.get(0); + + if (parentOrganization.hasValue() + && parentOrganization.getValue() instanceof Identifier parentOrganizationIdentifier + && organizationRole.hasValue() + && organizationRole.getValue() instanceof Coding organizationRoleCoding + && practitionerRole.hasValue() + && practitionerRole.getValue() instanceof Coding practitionerRoleCoding + && OrganizationIdentifier.SID.equals(parentOrganizationIdentifier.getSystem()) + && organizationWithIdentifierExists.test(parentOrganizationIdentifier) + && organizationRoleExists.test(organizationRoleCoding) + && practitionerRoleExists.test(practitionerRoleCoding)) + { + return Optional.of(new Role(true, parentOrganizationIdentifier.getValue(), + organizationRoleCoding.getSystem(), organizationRoleCoding.getCode(), + practitionerRoleCoding.getSystem(), practitionerRoleCoding.getCode())); + } + } + } + } + + return Optional.empty(); + } +} \ No newline at end of file diff --git a/src/test/java/dev/dsf/fhir/profiles/TaskProfileTest.java b/src/test/java/dev/dsf/fhir/profiles/TaskProfileTest.java index 5266ff79..1bfea638 100644 --- a/src/test/java/dev/dsf/fhir/profiles/TaskProfileTest.java +++ b/src/test/java/dev/dsf/fhir/profiles/TaskProfileTest.java @@ -44,10 +44,10 @@ import dev.dsf.bpe.util.task.input.generator.DownloadedDurationGenerator; import dev.dsf.bpe.util.task.input.generator.ErrorInputComponentGenerator; import dev.dsf.bpe.util.task.output.generator.PingStatusGenerator; -import dev.dsf.bpe.v1.constants.CodeSystems.BpmnMessage; -import dev.dsf.bpe.v1.constants.NamingSystems.EndpointIdentifier; -import dev.dsf.bpe.v1.constants.NamingSystems.OrganizationIdentifier; -import dev.dsf.bpe.v1.variables.Target; +import dev.dsf.bpe.v2.constants.CodeSystems.BpmnMessage; +import dev.dsf.bpe.v2.constants.NamingSystems.EndpointIdentifier; +import dev.dsf.bpe.v2.constants.NamingSystems.OrganizationIdentifier; +import dev.dsf.bpe.v2.variables.Target; import dev.dsf.fhir.validation.ResourceValidator; import dev.dsf.fhir.validation.ResourceValidatorImpl; import dev.dsf.fhir.validation.ValidationSupportRule; @@ -57,17 +57,18 @@ public class TaskProfileTest private static final Logger logger = LoggerFactory.getLogger(TaskProfileTest.class); private static final PingProcessPluginDefinition def = new PingProcessPluginDefinition(); + private static final PingStatusGenerator pingStatusGenerator = new PingStatusGenerator(def.getResourceVersion()); @ClassRule public static final ValidationSupportRule validationRule = new ValidationSupportRule(def.getResourceVersion(), def.getResourceReleaseDate(), - Arrays.asList("dsf-task-base-1.0.0.xml", "dsf-extension-error.xml", "dsf-extension-ping-status.xml", + Arrays.asList("dsf-task-2.0.0.xml", "dsf-extension-error.xml", "dsf-extension-ping-status.xml", "dsf-task-ping.xml", "dsf-task-pong.xml", "dsf-task-start-ping.xml", "dsf-task-start-ping-autostart.xml", "dsf-task-stop-ping-autostart.xml", "dsf-task-cleanup-pong.xml"), - Arrays.asList("dsf-read-access-tag-1.0.0.xml", "dsf-bpmn-message-1.0.0.xml", "dsf-ping-1_0.xml", + Arrays.asList("dsf-read-access-tag-2.0.0.xml", "dsf-bpmn-message-2.0.0.xml", "dsf-ping-1_0.xml", "dsf-ping.xml", "dsf-ping-status-1_0.xml", "dsf-ping-status.xml"), - Arrays.asList("dsf-read-access-tag-1.0.0.xml", "dsf-bpmn-message-1.0.0.xml", "dsf-ping-1_0.xml", + Arrays.asList("dsf-read-access-tag-2.0.0.xml", "dsf-bpmn-message-2.0.0.xml", "dsf-ping-1_0.xml", "dsf-ping.xml", "dsf-ping-status-1_0.xml", "dsf-ping-status.xml", "dsf-pong-status-1_0.xml", "dsf-pong-status.xml", "dsf-network-speed-units.xml")); @@ -94,8 +95,7 @@ public void testTaskStartAutostartProcessProfileValidWithTargetEndpoints() .setValue(new StringType( "Endpoint?identifier=http://dsf.dev/sid/endpoint-identifier|endpoint.target.org")) .getType().addCoding().setSystem(CodeSystem.DsfPing.URL) - .setCode(CodeSystem.DsfPing.Code.TARGET_ENDPOINTS.getValue()) - .setVersion(PingProcessPluginDefinition.RESOURCE_VERSION); + .setCode(CodeSystem.DsfPing.Code.TARGET_ENDPOINTS.getValue()).setVersion(def.getResourceVersion()); ValidationResult result = resourceValidator.validate(task); ValidationSupportRule.logValidationMessages(logger, result); @@ -109,8 +109,7 @@ public void testTaskStartAutostartProcessProfileValidTimerInterval() { Task task = createValidTaskStartAutostartProcess(); task.addInput().setValue(new StringType("PT24H")).getType().addCoding().setSystem(CodeSystem.DsfPing.URL) - .setCode(CodeSystem.DsfPing.Code.TIMER_INTERVAL.getValue()) - .setVersion(PingProcessPluginDefinition.RESOURCE_VERSION); + .setCode(CodeSystem.DsfPing.Code.TIMER_INTERVAL.getValue()).setVersion(def.getResourceVersion()); ValidationResult result = resourceValidator.validate(task); ValidationSupportRule.logValidationMessages(logger, result); @@ -125,7 +124,7 @@ public void testTaskStartAutostartProcessProfileNotValidTimerInterval() Task task = createValidTaskStartAutostartProcess(); task.addInput().setValue(new StringType("invalid_duration")).getType().addCoding() .setSystem(CodeSystem.DsfPing.URL).setCode(CodeSystem.DsfPing.Code.TIMER_INTERVAL.getValue()) - .setVersion(PingProcessPluginDefinition.RESOURCE_VERSION); + .setVersion(def.getResourceVersion()); ValidationResult result = resourceValidator.validate(task); ValidationSupportRule.logValidationMessages(logger, result); @@ -151,7 +150,7 @@ private Task createValidTaskStartAutostartProcess() task.addInput().setValue(new StringType(ConstantsPing.PROFILE_DSF_TASK_START_PING_AUTOSTART_MESSAGE_NAME)) .getType().addCoding(BpmnMessage.messageName()); - task.addInput(DownloadResourceSizeGenerator.create(0)); + task.addInput(DownloadResourceSizeGenerator.create(0, def.getResourceVersion())); return task; } @@ -205,7 +204,7 @@ public void testTaskStartPingProcessProfileValidWithErrorMessages() { Task task = createValidTaskStartPingProcess(); - ProcessError.toTaskOutput(processErrors(4)).forEach(task::addOutput); + ProcessError.toTaskOutput(processErrors(4), def.getResourceVersion()).forEach(task::addOutput); ValidationResult result = resourceValidator.validate(task); ValidationSupportRule.logValidationMessages(logger, result); @@ -233,8 +232,7 @@ public void testTaskStartPingProcessProfileValidWithTargetEndpoints() .setValue(new StringType( "Endpoint?identifier=http://dsf.dev/sid/endpoint-identifier|endpoint.target.org")) .getType().addCoding().setSystem(CodeSystem.DsfPing.URL) - .setCode(CodeSystem.DsfPing.Code.TARGET_ENDPOINTS.getValue()) - .setVersion(PingProcessPluginDefinition.RESOURCE_VERSION); + .setCode(CodeSystem.DsfPing.Code.TARGET_ENDPOINTS.getValue()).setVersion(def.getResourceVersion()); ValidationResult result = resourceValidator.validate(task); ValidationSupportRule.logValidationMessages(logger, result); @@ -290,7 +288,7 @@ public String getCorrelationKey() Task task = createValidTaskStartPingProcess(); task.addInput().setValue(new StringType(UUID.randomUUID().toString())).getType() .addCoding(BpmnMessage.businessKey()); - task.addOutput(PingStatusGenerator + task.addOutput(pingStatusGenerator .createPingStatusOutput(target, CodeSystem.DsfPingStatus.Code.PONG_MISSING, processErrors(5)).get()); ValidationResult result = resourceValidator.validate(task); @@ -458,7 +456,7 @@ public static Task createValidTaskStartPingProcess() .addCoding(BpmnMessage.messageName()); task.addInput().setValue(new DecimalType(1)).getType().addCoding().setSystem(CodeSystem.DsfPing.URL) .setCode(CodeSystem.DsfPing.Code.DOWNLOAD_RESOURCE_SIZE_BYTES.getValue()) - .setVersion(PingProcessPluginDefinition.RESOURCE_VERSION); + .setVersion(def.getResourceVersion()); return task; } @@ -547,8 +545,9 @@ public String getCorrelationKey() Task task = createValidTaskPing(); task.addOutput(createPongStatusOutput(target, CodeSystem.DsfPingStatus.Code.PONG_SENT)); - task.addInput(DownloadResourceSizeGenerator.create(1000)); - task.addInput(DownloadResourceReferenceGenerator.create("https://test.endpoint.org/fhir/Binary")); + task.addInput(DownloadResourceSizeGenerator.create(1000, def.getResourceVersion())); + task.addInput(DownloadResourceReferenceGenerator.create("https://test.endpoint.org/fhir/Binary", + def.getResourceVersion())); ValidationResult result = resourceValidator.validate(task); ValidationSupportRule.logValidationMessages(logger, result); @@ -580,8 +579,7 @@ public static Task createValidTaskPing() .setValue(new Reference().setType(ResourceType.Endpoint.name()) .setIdentifier(EndpointIdentifier.withValue("endpoint.target.org"))) .getType().addCoding().setSystem(CodeSystem.DsfPing.URL) - .setCode(CodeSystem.DsfPing.Code.ENDPOINT_IDENTIFIER.getValue()) - .setVersion(PingProcessPluginDefinition.RESOURCE_VERSION); + .setCode(CodeSystem.DsfPing.Code.ENDPOINT_IDENTIFIER.getValue()).setVersion(def.getResourceVersion()); return task; } @@ -603,9 +601,10 @@ public void testTaskPongValidWithReferenceAndDownloadedDurationMillisAndDownload { Task task = createValidTaskPong(); - task.addInput(DownloadResourceReferenceGenerator.create("https://test.endpoint.org/fhir/Binary")); - task.addInput(DownloadedBytesGenerator.create(1000)); - task.addInput(DownloadedDurationGenerator.create(Duration.ofMillis(1000))); + task.addInput(DownloadResourceReferenceGenerator.create("https://test.endpoint.org/fhir/Binary", + def.getResourceVersion())); + task.addInput(DownloadedBytesGenerator.create(1000, def.getResourceVersion())); + task.addInput(DownloadedDurationGenerator.create(Duration.ofMillis(1000), def.getResourceVersion())); ValidationResult result = resourceValidator.validate(task); ValidationSupportRule.logValidationMessages(logger, result); @@ -619,11 +618,12 @@ public void testTaskPongValidWithMultipleErrorMessages() { Task task = createValidTaskPong(); - task.addInput(DownloadResourceReferenceGenerator.create("https://test.endpoint.org/fhir/Binary")); - task.addInput(DownloadedBytesGenerator.create(1000)); - task.addInput(DownloadedDurationGenerator.create(Duration.ofMillis(1000))); - task.addInput(ErrorInputComponentGenerator.create(processErrors(1).get(0))); - task.addInput(ErrorInputComponentGenerator.create(processErrors(1).get(0))); + task.addInput(DownloadResourceReferenceGenerator.create("https://test.endpoint.org/fhir/Binary", + def.getResourceVersion())); + task.addInput(DownloadedBytesGenerator.create(1000, def.getResourceVersion())); + task.addInput(DownloadedDurationGenerator.create(Duration.ofMillis(1000), def.getResourceVersion())); + task.addInput(ErrorInputComponentGenerator.create(processErrors(1).get(0), def.getResourceVersion())); + task.addInput(ErrorInputComponentGenerator.create(processErrors(1).get(0), def.getResourceVersion())); ValidationResult result = resourceValidator.validate(task); ValidationSupportRule.logValidationMessages(logger, result); @@ -686,8 +686,8 @@ private Task createValidTaskCleanupPong() task.addInput().setValue(new StringType(UUID.randomUUID().toString())).getType() .addCoding(BpmnMessage.businessKey()); - task.addInput(DownloadedBytesGenerator.create(1000)); - task.addInput(DownloadedDurationGenerator.create(Duration.ofMillis(1000))); + task.addInput(DownloadedBytesGenerator.create(1000, def.getResourceVersion())); + task.addInput(DownloadedDurationGenerator.create(Duration.ofMillis(1000), def.getResourceVersion())); return task; } @@ -763,17 +763,17 @@ private String fillPlaceholders(String xml) private Task.TaskOutputComponent createPingStatusOutput(Target target, CodeSystem.DsfPingStatus.Code statusCode, BigDecimal downloadSpeed, BigDecimal uploadSpeed, CodeSystem.DsfPingUnits.Code unit) { - return PingStatusGenerator + return pingStatusGenerator .createPingStatusOutput(target, statusCode, null, downloadSpeed, unit, uploadSpeed, unit).get(); } private Task.TaskOutputComponent createPongStatusOutput(Target target, CodeSystem.DsfPingStatus.Code statusCode) { - return PingStatusGenerator.createPongStatusOutput(target, statusCode, null).get(); + return pingStatusGenerator.createPongStatusOutput(target, statusCode, null).get(); } private Task.TaskOutputComponent createPingErrorOutput(ProcessError processError) { - return ProcessError.toTaskOutput(processError); + return ProcessError.toTaskOutput(processError, def.getResourceVersion()); } }