diff --git a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/bpe/ConstantsBase.java b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/bpe/ConstantsBase.java
index c3f473e34..4050578df 100755
--- a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/bpe/ConstantsBase.java
+++ b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/bpe/ConstantsBase.java
@@ -16,6 +16,8 @@ public interface ConstantsBase
String BPMN_EXECUTION_VARIABLE_TTP_IDENTIFIER = "ttpIdentifier";
String BPMN_EXECUTION_VARIABLE_LEADING_MEDIC_IDENTIFIER = "leadingMedicIdentifier";
String BPMN_EXECUTION_VARIABLE_ALTERNATIVE_BUSINESS_KEY = "alternativeBusinessKey";
+ String BPMN_EXECUTION_VARIABLE_QUESTIONNAIRE_RESPONSE_ID = "questionnaireResponseId";
+ String BPMN_EXECUTION_VARIABLE_QUESTIONNAIRE_RESPONSE_COMPLETED = "questionnaireResponseCompleted";
/**
* Used to distinguish if I am at the moment in a process called by another process by a CallActivity or not
@@ -38,6 +40,10 @@ public interface ConstantsBase
String CODESYSTEM_HIGHMED_BPMN_VALUE_CORRELATION_KEY = "correlation-key";
String CODESYSTEM_HIGHMED_BPMN_VALUE_ERROR = "error";
+ String CODESYSTEM_HIGHMED_BPMN_USER_TASK = "http://highmed.org/fhir/CodeSystem/bpmn-user-task";
+ String CODESYSTEM_HIGHMED_BPMN_USER_TASK_VALUE_BUSINESS_KEY = "business-key";
+ String CODESYSTEM_HIGHMED_BPMN_USER_TASK_VALUE_USER_TASK_ID = "user-task-id";
+
/**
* @deprecated as of release 0.6.0, use {@link #CODESYSTEM_HIGHMED_ORGANIZATION_ROLE} instead
*/
diff --git a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/bpe/delegate/AbstractServiceDelegate.java b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/bpe/delegate/AbstractServiceDelegate.java
index 6dd3016ce..3979c6602 100755
--- a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/bpe/delegate/AbstractServiceDelegate.java
+++ b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/bpe/delegate/AbstractServiceDelegate.java
@@ -1,7 +1,5 @@
package org.highmed.dsf.bpe.delegate;
-import static org.highmed.dsf.bpe.ConstantsBase.BPMN_EXECUTION_VARIABLE_LEADING_TASK;
-import static org.highmed.dsf.bpe.ConstantsBase.BPMN_EXECUTION_VARIABLE_TASK;
import static org.highmed.dsf.bpe.ConstantsBase.CODESYSTEM_HIGHMED_BPMN;
import static org.highmed.dsf.bpe.ConstantsBase.CODESYSTEM_HIGHMED_BPMN_VALUE_ERROR;
@@ -14,7 +12,6 @@
import org.highmed.dsf.fhir.authorization.read.ReadAccessHelper;
import org.highmed.dsf.fhir.client.FhirWebserviceClientProvider;
import org.highmed.dsf.fhir.task.TaskHelper;
-import org.highmed.dsf.fhir.variables.FhirResourceValues;
import org.hl7.fhir.r4.model.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -28,6 +25,10 @@ public abstract class AbstractServiceDelegate implements JavaDelegate, Initializ
private final TaskHelper taskHelper;
private final ReadAccessHelper readAccessHelper;
+ /**
+ * @deprecated as of release 0.8.0, use {@link #getExecution()} instead
+ */
+ @Deprecated
protected DelegateExecution execution;
public AbstractServiceDelegate(FhirWebserviceClientProvider clientProvider, TaskHelper taskHelper,
@@ -60,7 +61,7 @@ public final void execute(DelegateExecution execution) throws Exception
// Error boundary event, do not stop process execution
catch (BpmnError error)
{
- Task task = getTask(execution);
+ Task task = getTask();
logger.debug("Error while executing service delegate " + getClass().getName(), error);
logger.error(
@@ -73,7 +74,7 @@ public final void execute(DelegateExecution execution) throws Exception
// Not an error boundary event, stop process execution
catch (Exception exception)
{
- Task task = getTask(execution);
+ Task task = getTask();
logger.debug("Error while executing service delegate " + getClass().getName(), exception);
logger.error("Process {} has fatal error in step {} for task with id {}, reason: {}",
@@ -95,13 +96,6 @@ public final void execute(DelegateExecution execution) throws Exception
}
}
- private Task getTask(DelegateExecution execution)
- {
- return execution.getParentId() == null || execution.getParentId().equals(execution.getProcessInstanceId())
- ? getLeadingTaskFromExecutionVariables()
- : getCurrentTaskFromExecutionVariables();
- }
-
/**
* Method called by a BPMN service task
*
@@ -115,6 +109,11 @@ private Task getTask(DelegateExecution execution)
*/
protected abstract void doExecute(DelegateExecution execution) throws BpmnError, Exception;
+ protected final DelegateExecution getExecution()
+ {
+ return execution;
+ }
+
protected final TaskHelper getTaskHelper()
{
return taskHelper;
@@ -130,6 +129,18 @@ protected final ReadAccessHelper getReadAccessHelper()
return readAccessHelper;
}
+ /**
+ * @return the active task from execution variables, i.e. the leading task if the main process is running or the
+ * current task if a subprocess is running.
+ * @throws IllegalStateException
+ * if execution of this service delegate has not been started
+ * @see ConstantsBase#BPMN_EXECUTION_VARIABLE_TASK
+ */
+ protected final Task getTask()
+ {
+ return taskHelper.getTask(execution);
+ }
+
/**
* @return the current task from execution variables, the task resource that started the current process or
* subprocess
@@ -139,10 +150,7 @@ protected final ReadAccessHelper getReadAccessHelper()
*/
protected final Task getCurrentTaskFromExecutionVariables()
{
- if (execution == null)
- throw new IllegalStateException("execution not started");
-
- return (Task) execution.getVariable(BPMN_EXECUTION_VARIABLE_TASK);
+ return taskHelper.getCurrentTaskFromExecutionVariables(execution);
}
/**
@@ -153,15 +161,11 @@ protected final Task getCurrentTaskFromExecutionVariables()
*/
protected final Task getLeadingTaskFromExecutionVariables()
{
- if (execution == null)
- throw new IllegalStateException("execution not started");
-
- Task leadingTask = (Task) execution.getVariable(BPMN_EXECUTION_VARIABLE_LEADING_TASK);
- return leadingTask != null ? leadingTask : getCurrentTaskFromExecutionVariables();
+ return taskHelper.getLeadingTaskFromExecutionVariables(execution);
}
/**
- * Uses this method to update the process engine variable {@link ConstantsBase#BPMN_EXECUTION_VARIABLE_TASK},
+ * Use this method to update the process engine variable {@link ConstantsBase#BPMN_EXECUTION_VARIABLE_TASK},
* after modifying the {@link Task}.
*
* @param task
@@ -172,17 +176,13 @@ protected final Task getLeadingTaskFromExecutionVariables()
*/
protected final void updateCurrentTaskInExecutionVariables(Task task)
{
- if (execution == null)
- throw new IllegalStateException("execution not started");
-
- Objects.requireNonNull(task, "task");
- execution.setVariable(BPMN_EXECUTION_VARIABLE_TASK, FhirResourceValues.create(task));
+ taskHelper.updateCurrentTaskInExecutionVariables(execution, task);
}
/**
- * Uses this method to update the process engine variable
+ * Use this method to update the process engine variable
* {@link ConstantsBase#BPMN_EXECUTION_VARIABLE_LEADING_TASK}, after modifying the {@link Task}.
- *
+ *
* Updates the current task if no leading task is set.
*
* @param task
@@ -193,15 +193,6 @@ protected final void updateCurrentTaskInExecutionVariables(Task task)
*/
protected final void updateLeadingTaskInExecutionVariables(Task task)
{
- if (execution == null)
- throw new IllegalStateException("execution not started");
-
- Objects.requireNonNull(task, "task");
- Task leadingTask = (Task) execution.getVariable(BPMN_EXECUTION_VARIABLE_LEADING_TASK);
-
- if (leadingTask != null)
- execution.setVariable(BPMN_EXECUTION_VARIABLE_LEADING_TASK, FhirResourceValues.create(task));
- else
- updateCurrentTaskInExecutionVariables(task);
+ taskHelper.updateLeadingTaskInExecutionVariables(execution, task);
}
}
diff --git a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/bpe/listener/DefaultUserTaskListener.java b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/bpe/listener/DefaultUserTaskListener.java
new file mode 100644
index 000000000..86bc1bbae
--- /dev/null
+++ b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/bpe/listener/DefaultUserTaskListener.java
@@ -0,0 +1,302 @@
+package org.highmed.dsf.bpe.listener;
+
+import static org.highmed.dsf.bpe.ConstantsBase.BPMN_EXECUTION_VARIABLE_QUESTIONNAIRE_RESPONSE_ID;
+import static org.highmed.dsf.bpe.ConstantsBase.CODESYSTEM_HIGHMED_BPMN;
+import static org.highmed.dsf.bpe.ConstantsBase.CODESYSTEM_HIGHMED_BPMN_USER_TASK_VALUE_BUSINESS_KEY;
+import static org.highmed.dsf.bpe.ConstantsBase.CODESYSTEM_HIGHMED_BPMN_USER_TASK_VALUE_USER_TASK_ID;
+import static org.highmed.dsf.bpe.ConstantsBase.CODESYSTEM_HIGHMED_BPMN_VALUE_ERROR;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.engine.delegate.DelegateTask;
+import org.camunda.bpm.engine.delegate.TaskListener;
+import org.highmed.dsf.bpe.ConstantsBase;
+import org.highmed.dsf.fhir.authorization.read.ReadAccessHelper;
+import org.highmed.dsf.fhir.client.FhirWebserviceClientProvider;
+import org.highmed.dsf.fhir.organization.OrganizationProvider;
+import org.highmed.dsf.fhir.questionnaire.QuestionnaireResponseHelper;
+import org.highmed.dsf.fhir.task.TaskHelper;
+import org.hl7.fhir.r4.model.Bundle;
+import org.hl7.fhir.r4.model.IdType;
+import org.hl7.fhir.r4.model.Questionnaire;
+import org.hl7.fhir.r4.model.QuestionnaireResponse;
+import org.hl7.fhir.r4.model.Reference;
+import org.hl7.fhir.r4.model.ResourceType;
+import org.hl7.fhir.r4.model.StringType;
+import org.hl7.fhir.r4.model.Task;
+import org.hl7.fhir.r4.model.Type;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
+
+public class DefaultUserTaskListener implements TaskListener, InitializingBean
+{
+ private static final Logger logger = LoggerFactory.getLogger(DefaultUserTaskListener.class);
+
+ private final FhirWebserviceClientProvider clientProvider;
+ private final OrganizationProvider organizationProvider;
+ private final QuestionnaireResponseHelper questionnaireResponseHelper;
+ private final TaskHelper taskHelper;
+ private final ReadAccessHelper readAccessHelper;
+
+ /**
+ * @deprecated as of release 0.8.0, use {@link #getExecution()} instead
+ */
+ @Deprecated
+ protected DelegateExecution execution;
+
+ public DefaultUserTaskListener(FhirWebserviceClientProvider clientProvider,
+ OrganizationProvider organizationProvider, QuestionnaireResponseHelper questionnaireResponseHelper,
+ TaskHelper taskHelper, ReadAccessHelper readAccessHelper)
+ {
+ this.clientProvider = clientProvider;
+ this.organizationProvider = organizationProvider;
+ this.questionnaireResponseHelper = questionnaireResponseHelper;
+ this.taskHelper = taskHelper;
+ this.readAccessHelper = readAccessHelper;
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception
+ {
+ Objects.requireNonNull(clientProvider, "clientProvider");
+ Objects.requireNonNull(organizationProvider, "organizationProvider");
+ Objects.requireNonNull(questionnaireResponseHelper, "questionnaireResponseHelper");
+ Objects.requireNonNull(taskHelper, "taskHelper");
+ Objects.requireNonNull(readAccessHelper, "readAccessHelper");
+ }
+
+ @Override
+ public final void notify(DelegateTask userTask)
+ {
+ this.execution = userTask.getExecution();
+
+ try
+ {
+ logger.trace("Execution of user task with id='{}'", execution.getCurrentActivityId());
+
+ String questionnaireUrlWithVersion = userTask.getBpmnModelElementInstance().getCamundaFormKey();
+ Questionnaire questionnaire = readQuestionnaire(questionnaireUrlWithVersion);
+
+ String businessKey = execution.getBusinessKey();
+ String userTaskId = userTask.getId();
+
+ QuestionnaireResponse questionnaireResponse = createDefaultQuestionnaireResponse(
+ questionnaireUrlWithVersion, businessKey, userTaskId);
+ addPlaceholderAnswersToQuestionnaireResponse(questionnaireResponse, questionnaire);
+
+ modifyQuestionnaireResponse(userTask, questionnaireResponse);
+
+ checkQuestionnaireResponse(questionnaireResponse);
+
+ IdType created = clientProvider.getLocalWebserviceClient().withRetryForever(60000)
+ .create(questionnaireResponse).getIdElement();
+ execution.setVariable(BPMN_EXECUTION_VARIABLE_QUESTIONNAIRE_RESPONSE_ID, created.getIdPart());
+
+ logger.info("Created user task with id={}, process waiting for it's completion", created.getValue());
+ }
+ catch (Exception exception)
+ {
+ Task task = getTask();
+
+ logger.debug("Error while executing user task listener " + getClass().getName(), exception);
+ logger.error("Process {} has fatal error in step {} for task with id {}, reason: {}",
+ execution.getProcessDefinitionId(), execution.getActivityInstanceId(), task.getId(),
+ exception.getMessage());
+
+ String errorMessage = "Process " + execution.getProcessDefinitionId() + " has fatal error in step "
+ + execution.getActivityInstanceId() + ", reason: " + exception.getMessage();
+
+ task.addOutput(taskHelper.createOutput(CODESYSTEM_HIGHMED_BPMN, CODESYSTEM_HIGHMED_BPMN_VALUE_ERROR,
+ errorMessage));
+ task.setStatus(Task.TaskStatus.FAILED);
+
+ clientProvider.getLocalWebserviceClient().withMinimalReturn().update(task);
+
+ // TODO evaluate throwing exception as alternative to stopping the process instance
+ execution.getProcessEngine().getRuntimeService().deleteProcessInstance(execution.getProcessInstanceId(),
+ exception.getMessage());
+ }
+ }
+
+ private Questionnaire readQuestionnaire(String urlWithVersion)
+ {
+ Bundle search = clientProvider.getLocalWebserviceClient().search(Questionnaire.class,
+ Map.of("url", Collections.singletonList(urlWithVersion)));
+
+ List questionnaires = search.getEntry().stream().filter(Bundle.BundleEntryComponent::hasResource)
+ .map(Bundle.BundleEntryComponent::getResource).filter(r -> r instanceof Questionnaire)
+ .map(r -> (Questionnaire) r).collect(Collectors.toList());
+
+ if (questionnaires.size() < 1)
+ throw new RuntimeException("Could not find Questionnaire resource with url|version=" + urlWithVersion);
+
+ if (questionnaires.size() > 1)
+ logger.info("Found {} Questionnaire resources with url|version={}, using the first", questionnaires.size(),
+ urlWithVersion);
+
+ return questionnaires.get(0);
+ }
+
+ private QuestionnaireResponse createDefaultQuestionnaireResponse(String questionnaireUrlWithVersion,
+ String businessKey, String userTaskId)
+ {
+ QuestionnaireResponse questionnaireResponse = new QuestionnaireResponse();
+ questionnaireResponse.setQuestionnaire(questionnaireUrlWithVersion);
+ questionnaireResponse.setStatus(QuestionnaireResponse.QuestionnaireResponseStatus.INPROGRESS);
+
+ questionnaireResponse.setAuthor(new Reference().setType(ResourceType.Organization.name())
+ .setIdentifier(organizationProvider.getLocalIdentifier()));
+
+ questionnaireResponseHelper.addItemLeave(questionnaireResponse,
+ CODESYSTEM_HIGHMED_BPMN_USER_TASK_VALUE_BUSINESS_KEY, "The business-key of the process execution",
+ new StringType(businessKey));
+ questionnaireResponseHelper.addItemLeave(questionnaireResponse,
+ CODESYSTEM_HIGHMED_BPMN_USER_TASK_VALUE_USER_TASK_ID, "The user-task-id of the process execution",
+ new StringType(userTaskId));
+
+ readAccessHelper.addLocal(questionnaireResponse);
+
+ return questionnaireResponse;
+ }
+
+ private void addPlaceholderAnswersToQuestionnaireResponse(QuestionnaireResponse questionnaireResponse,
+ Questionnaire questionnaire)
+ {
+ questionnaire.getItem().stream()
+ .filter(i -> !CODESYSTEM_HIGHMED_BPMN_USER_TASK_VALUE_BUSINESS_KEY.equals(i.getLinkId()))
+ .filter(i -> !CODESYSTEM_HIGHMED_BPMN_USER_TASK_VALUE_USER_TASK_ID.equals(i.getLinkId()))
+ .forEach(i -> createAndAddAnswerPlaceholder(questionnaireResponse, i));
+ }
+
+ private void createAndAddAnswerPlaceholder(QuestionnaireResponse questionnaireResponse,
+ Questionnaire.QuestionnaireItemComponent question)
+ {
+ Type answer = questionnaireResponseHelper.transformQuestionTypeToAnswerType(question);
+ questionnaireResponseHelper.addItemLeave(questionnaireResponse, question.getLinkId(), question.getText(),
+ answer);
+ }
+
+ private void checkQuestionnaireResponse(QuestionnaireResponse questionnaireResponse)
+ {
+ questionnaireResponse.getItem().stream()
+ .filter(i -> CODESYSTEM_HIGHMED_BPMN_USER_TASK_VALUE_BUSINESS_KEY.equals(i.getLinkId())).findFirst()
+ .orElseThrow(() -> new RuntimeException("QuestionnaireResponse does not contain an item with linkId='"
+ + CODESYSTEM_HIGHMED_BPMN_USER_TASK_VALUE_BUSINESS_KEY + "'"));
+
+ questionnaireResponse.getItem().stream()
+ .filter(i -> CODESYSTEM_HIGHMED_BPMN_USER_TASK_VALUE_USER_TASK_ID.equals(i.getLinkId())).findFirst()
+ .orElseThrow(() -> new RuntimeException("QuestionnaireResponse does not contain an item with linkId='"
+ + CODESYSTEM_HIGHMED_BPMN_USER_TASK_VALUE_USER_TASK_ID + "'"));
+
+ if (!QuestionnaireResponse.QuestionnaireResponseStatus.INPROGRESS.equals(questionnaireResponse.getStatus()))
+ throw new RuntimeException("QuestionnaireResponse must be in status 'in-progress'");
+ }
+
+ /**
+ * Use this method to modify the {@link QuestionnaireResponse} before it will be created in state
+ * {@link QuestionnaireResponse.QuestionnaireResponseStatus#INPROGRESS}
+ *
+ * @param userTask
+ * not null
, user task on which this {@link QuestionnaireResponse} is based
+ * @param questionnaireResponse
+ * not null
, containing an answer placeholder for every item in the corresponding
+ * {@link Questionnaire}
+ */
+ protected void modifyQuestionnaireResponse(DelegateTask userTask, QuestionnaireResponse questionnaireResponse)
+ {
+ // Nothing to do in default behaviour
+ }
+
+ protected final DelegateExecution getExecution()
+ {
+ return execution;
+ }
+
+ protected final TaskHelper getTaskHelper()
+ {
+ return taskHelper;
+ }
+
+ protected final FhirWebserviceClientProvider getFhirWebserviceClientProvider()
+ {
+ return clientProvider;
+ }
+
+ protected final ReadAccessHelper getReadAccessHelper()
+ {
+ return readAccessHelper;
+ }
+
+ /**
+ * @return the active task from execution variables, i.e. the leading task if the main process is running or the
+ * current task if a subprocess is running.
+ * @throws IllegalStateException
+ * if execution of this service delegate has not been started
+ * @see ConstantsBase#BPMN_EXECUTION_VARIABLE_TASK
+ */
+ protected final Task getTask()
+ {
+ return taskHelper.getTask(execution);
+ }
+
+ /**
+ * @return the current task from execution variables, the task resource that started the current process or
+ * subprocess
+ * @throws IllegalStateException
+ * if execution of this service delegate has not been started
+ * @see ConstantsBase#BPMN_EXECUTION_VARIABLE_TASK
+ */
+ protected final Task getCurrentTaskFromExecutionVariables()
+ {
+ return taskHelper.getCurrentTaskFromExecutionVariables(execution);
+ }
+
+ /**
+ * @return the leading task from execution variables, same as current task if not in a subprocess
+ * @throws IllegalStateException
+ * if execution of this service delegate has not been started
+ * @see ConstantsBase#BPMN_EXECUTION_VARIABLE_LEADING_TASK
+ */
+ protected final Task getLeadingTaskFromExecutionVariables()
+ {
+ return taskHelper.getLeadingTaskFromExecutionVariables(execution);
+ }
+
+ /**
+ * Use this method to update the process engine variable {@link ConstantsBase#BPMN_EXECUTION_VARIABLE_TASK},
+ * after modifying the {@link Task}.
+ *
+ * @param task
+ * not null
+ * @throws IllegalStateException
+ * if execution of this service delegate has not been started
+ * @see ConstantsBase#BPMN_EXECUTION_VARIABLE_TASK
+ */
+ protected final void updateCurrentTaskInExecutionVariables(Task task)
+ {
+ taskHelper.updateCurrentTaskInExecutionVariables(execution, task);
+ }
+
+ /**
+ * Use this method to update the process engine variable
+ * {@link ConstantsBase#BPMN_EXECUTION_VARIABLE_LEADING_TASK}, after modifying the {@link Task}.
+ *
+ * Updates the current task if no leading task is set.
+ *
+ * @param task
+ * not null
+ * @throws IllegalStateException
+ * if execution of this service delegate has not been started
+ * @see ConstantsBase#BPMN_EXECUTION_VARIABLE_LEADING_TASK
+ */
+ protected final void updateLeadingTaskInExecutionVariables(Task task)
+ {
+ taskHelper.updateLeadingTaskInExecutionVariables(execution, task);
+ }
+}
diff --git a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/bpe/service/MailService.java b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/bpe/service/MailService.java
new file mode 100644
index 000000000..2560e2849
--- /dev/null
+++ b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/bpe/service/MailService.java
@@ -0,0 +1,155 @@
+package org.highmed.dsf.bpe.service;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.function.Consumer;
+
+import javax.mail.Message.RecipientType;
+import javax.mail.MessagingException;
+import javax.mail.internet.AddressException;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+
+public interface MailService
+{
+ /**
+ * Sends a plain text mail to the BPE wide configured recipients.
+ *
+ * @param subject
+ * not null
+ * @param message
+ * not null
+ */
+ default void send(String subject, String message)
+ {
+ send(subject, message, (String) null);
+ }
+
+ /**
+ * Sends a plain text mail to the given address (to) if not null
or the BPE wide configured
+ * recipients.
+ *
+ * @param subject
+ * not null
+ * @param message
+ * not null
+ * @param to
+ * BPE wide configured recipients if parameter is null
+ */
+ default void send(String subject, String message, String to)
+ {
+ send(subject, message, to == null ? null : Collections.singleton(to));
+ }
+
+ /**
+ * Sends a plain text mail to the given addresses (to) if not null
and not empty or the BPE wide
+ * configured recipients.
+ *
+ * @param subject
+ * not null
+ * @param message
+ * not null
+ * @param to
+ * BPE wide configured recipients if parameter is null
or empty
+ */
+ default void send(String subject, String message, Collection to)
+ {
+ try
+ {
+ MimeBodyPart body = new MimeBodyPart();
+ body.setText(message, StandardCharsets.UTF_8.displayName());
+
+ send(subject, body, to);
+ }
+ catch (MessagingException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Sends the given {@link MimeBodyPart} as content of a mail to the BPE wide configured recipients.
+ *
+ * @param subject
+ * not null
+ * @param body
+ * not null
+ */
+ default void send(String subject, MimeBodyPart body)
+ {
+ send(subject, body, (String) null);
+ }
+
+ /**
+ * Sends the given {@link MimeBodyPart} as content of a mail to the given address (to) if not
+ * null
or the BPE wide configured recipients.
+ *
+ * @param subject
+ * not null
+ * @param body
+ * not null
+ * @param to
+ * BPE wide configured recipients if parameter is null
+ */
+ default void send(String subject, MimeBodyPart body, String to)
+ {
+ send(subject, body, to == null ? null : Collections.singleton(to));
+ }
+
+ /**
+ * Sends the given {@link MimeBodyPart} as content of a mail to the given addresses (to) if not
+ * null
and not empty or the BPE wide configured recipients.
+ *
+ * @param subject
+ * not null
+ * @param body
+ * not null
+ * @param to
+ * BPE wide configured recipients if parameter is null
or empty
+ */
+ default void send(String subject, MimeBodyPart body, Collection to)
+ {
+ if (to == null || to.isEmpty())
+ send(subject, body, (Consumer) null);
+ else
+ send(subject, body, m ->
+ {
+ try
+ {
+ m.setRecipients(RecipientType.TO, to.stream().map(t ->
+ {
+ try
+ {
+ return new InternetAddress(t);
+ }
+ catch (AddressException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }).toArray(InternetAddress[]::new));
+
+ m.saveChanges();
+ }
+ catch (MessagingException e)
+ {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
+ /**
+ * Sends the given {@link MimeBodyPart} as content of a mail to the BPE wide configured recipients, the
+ * messageModifier can be used to modify elements of the generated {@link MimeMessage} before it is send to
+ * the SMTP server.
+ *
+ * @param subject
+ * not null
+ * @param body
+ * not null
+ * @param messageModifier
+ * may be null
+ */
+ void send(String subject, MimeBodyPart body, Consumer messageModifier);
+}
diff --git a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/questionnaire/QuestionnaireResponseHelper.java b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/questionnaire/QuestionnaireResponseHelper.java
new file mode 100644
index 000000000..e0fcf307a
--- /dev/null
+++ b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/questionnaire/QuestionnaireResponseHelper.java
@@ -0,0 +1,41 @@
+package org.highmed.dsf.fhir.questionnaire;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.hl7.fhir.r4.model.Questionnaire;
+import org.hl7.fhir.r4.model.QuestionnaireResponse;
+import org.hl7.fhir.r4.model.Type;
+
+public interface QuestionnaireResponseHelper
+{
+ default Optional getFirstItemLeaveMatchingLinkId(
+ QuestionnaireResponse questionnaireResponse, String linkId)
+ {
+ return getItemLeavesMatchingLinkIdAsStream(questionnaireResponse, linkId).findFirst();
+ }
+
+ default List getItemLeavesMatchingLinkIdAsList(
+ QuestionnaireResponse questionnaireResponse, String linkId)
+ {
+ return getItemLeavesMatchingLinkIdAsStream(questionnaireResponse, linkId).collect(Collectors.toList());
+ }
+
+ Stream getItemLeavesMatchingLinkIdAsStream(
+ QuestionnaireResponse questionnaireResponse, String linkId);
+
+ default List getItemLeavesAsList(
+ QuestionnaireResponse questionnaireResponse)
+ {
+ return getItemLeavesAsStream(questionnaireResponse).collect(Collectors.toList());
+ }
+
+ Stream getItemLeavesAsStream(
+ QuestionnaireResponse questionnaireResponse);
+
+ Type transformQuestionTypeToAnswerType(Questionnaire.QuestionnaireItemComponent question);
+
+ void addItemLeave(QuestionnaireResponse questionnaireResponse, String linkId, String text, Type answer);
+}
diff --git a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/ActivityDefinitionResource.java b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/ActivityDefinitionResource.java
index 7f87af589..a0e4900cb 100644
--- a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/ActivityDefinitionResource.java
+++ b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/ActivityDefinitionResource.java
@@ -3,26 +3,23 @@
import java.util.Objects;
import org.hl7.fhir.r4.model.ActivityDefinition;
-import org.hl7.fhir.r4.model.MetadataResource;
public class ActivityDefinitionResource extends AbstractResource
{
- private ActivityDefinitionResource(Class extends MetadataResource> type, String dependecyJarName, String url,
- String version, String name, String fileName)
+ private ActivityDefinitionResource(String dependecyJarName, String url, String version, String name,
+ String fileName)
{
- super(type, dependecyJarName, url, version, name, fileName);
+ super(ActivityDefinition.class, dependecyJarName, url, version, name, fileName);
}
public static ActivityDefinitionResource file(String fileName)
{
- return new ActivityDefinitionResource(ActivityDefinition.class, null, null, null, null,
- Objects.requireNonNull(fileName, "fileName"));
+ return new ActivityDefinitionResource(null, null, null, null, Objects.requireNonNull(fileName, "fileName"));
}
public static ActivityDefinitionResource dependency(String dependecyJarName, String url, String version)
{
- return new ActivityDefinitionResource(ActivityDefinition.class,
- Objects.requireNonNull(dependecyJarName, "dependecyJarName"), Objects.requireNonNull(url, "url"),
- Objects.requireNonNull(version, "version"), null, null);
+ return new ActivityDefinitionResource(Objects.requireNonNull(dependecyJarName, "dependecyJarName"),
+ Objects.requireNonNull(url, "url"), Objects.requireNonNull(version, "version"), null, null);
}
}
diff --git a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/CodeSystemResource.java b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/CodeSystemResource.java
index ae8404677..b9038387a 100644
--- a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/CodeSystemResource.java
+++ b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/CodeSystemResource.java
@@ -3,27 +3,25 @@
import java.util.Objects;
import org.hl7.fhir.r4.model.CodeSystem;
-import org.hl7.fhir.r4.model.MetadataResource;
public class CodeSystemResource extends AbstractResource
{
- private CodeSystemResource(Class extends MetadataResource> type, String dependencyNameAndVersion,
- String codeSystemUrl, String codeSystemVersion, String codeSystemFileName)
+ private CodeSystemResource(String dependencyNameAndVersion, String codeSystemUrl, String codeSystemVersion,
+ String codeSystemFileName)
{
- super(type, dependencyNameAndVersion, codeSystemUrl, codeSystemVersion, null, codeSystemFileName);
+ super(CodeSystem.class, dependencyNameAndVersion, codeSystemUrl, codeSystemVersion, null, codeSystemFileName);
}
public static CodeSystemResource file(String codeSystemFileName)
{
- return new CodeSystemResource(CodeSystem.class, null, null, null,
+ return new CodeSystemResource(null, null, null,
Objects.requireNonNull(codeSystemFileName, "codeSystemFileName"));
}
public static CodeSystemResource dependency(String dependencyNameAndVersion, String codeSystemUrl,
String codeSystemVersion)
{
- return new CodeSystemResource(CodeSystem.class,
- Objects.requireNonNull(dependencyNameAndVersion, "dependencyNameAndVersion"),
+ return new CodeSystemResource(Objects.requireNonNull(dependencyNameAndVersion, "dependencyNameAndVersion"),
Objects.requireNonNull(codeSystemUrl, "codeSystemUrl"),
Objects.requireNonNull(codeSystemVersion, "codeSystemVersion"), null);
}
diff --git a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/NamingSystemResource.java b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/NamingSystemResource.java
index 81694150d..fa69d78dd 100644
--- a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/NamingSystemResource.java
+++ b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/NamingSystemResource.java
@@ -2,27 +2,24 @@
import java.util.Objects;
-import org.hl7.fhir.r4.model.MetadataResource;
import org.hl7.fhir.r4.model.NamingSystem;
public class NamingSystemResource extends AbstractResource
{
- private NamingSystemResource(Class extends MetadataResource> type, String dependencyNameAndVersion,
- String namingSystemName, String namingSystemFileName)
+ private NamingSystemResource(String dependencyNameAndVersion, String namingSystemName, String namingSystemFileName)
{
- super(type, dependencyNameAndVersion, null, null, namingSystemName, namingSystemFileName);
+ super(NamingSystem.class, dependencyNameAndVersion, null, null, namingSystemName, namingSystemFileName);
}
public static NamingSystemResource file(String namingSystemFileName)
{
- return new NamingSystemResource(NamingSystem.class, null, null,
+ return new NamingSystemResource(null, null,
Objects.requireNonNull(namingSystemFileName, "namingSystemFileName"));
}
public static NamingSystemResource dependency(String dependencyNameAndVersion, String namingSystemName)
{
- return new NamingSystemResource(NamingSystem.class,
- Objects.requireNonNull(dependencyNameAndVersion, "dependencyNameAndVersion"),
+ return new NamingSystemResource(Objects.requireNonNull(dependencyNameAndVersion, "dependencyNameAndVersion"),
Objects.requireNonNull(namingSystemName, "namingSystemName"), null);
}
}
diff --git a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/QuestionnaireResource.java b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/QuestionnaireResource.java
new file mode 100644
index 000000000..89dbe075d
--- /dev/null
+++ b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/QuestionnaireResource.java
@@ -0,0 +1,29 @@
+package org.highmed.dsf.fhir.resources;
+
+import java.util.Objects;
+
+import org.hl7.fhir.r4.model.Questionnaire;
+
+public class QuestionnaireResource extends AbstractResource
+{
+ private QuestionnaireResource(String dependencyNameAndVersion, String questionnaireUrl, String questionnaireVersion,
+ String questionnaireFileName)
+ {
+ super(Questionnaire.class, dependencyNameAndVersion, questionnaireUrl, questionnaireVersion, null,
+ questionnaireFileName);
+ }
+
+ public static QuestionnaireResource file(String questionnaireFileName)
+ {
+ return new QuestionnaireResource(null, null, null,
+ Objects.requireNonNull(questionnaireFileName, "questionnaireFileName"));
+ }
+
+ public static QuestionnaireResource dependency(String dependencyNameAndVersion, String questionnaireUrl,
+ String questionnaireVersion)
+ {
+ return new QuestionnaireResource(Objects.requireNonNull(dependencyNameAndVersion, "dependencyNameAndVersion"),
+ Objects.requireNonNull(questionnaireUrl, "questionnaireUrl"),
+ Objects.requireNonNull(questionnaireVersion, "questionnaireVersion"), null);
+ }
+}
diff --git a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/ResourceProvider.java b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/ResourceProvider.java
index 673427ebc..7c1dec88e 100644
--- a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/ResourceProvider.java
+++ b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/ResourceProvider.java
@@ -12,6 +12,7 @@
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.MetadataResource;
import org.hl7.fhir.r4.model.NamingSystem;
+import org.hl7.fhir.r4.model.Questionnaire;
import org.hl7.fhir.r4.model.StructureDefinition;
import org.hl7.fhir.r4.model.ValueSet;
import org.springframework.core.env.PropertyResolver;
@@ -26,6 +27,8 @@ public interface ResourceProvider
Optional getNamingSystem(String name);
+ Optional getQuestionnaire(String url, String version);
+
Optional getStructureDefinition(String url, String version);
Optional getValueSet(String url, String version);
@@ -57,6 +60,12 @@ public Optional getNamingSystem(String name)
return Optional.empty();
}
+ @Override
+ public Optional getQuestionnaire(String url, String version)
+ {
+ return Optional.empty();
+ }
+
@Override
public Optional getStructureDefinition(String url, String version)
{
diff --git a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/ResourceProviderImpl.java b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/ResourceProviderImpl.java
index febc6bf2e..5a1332f35 100644
--- a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/ResourceProviderImpl.java
+++ b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/ResourceProviderImpl.java
@@ -25,6 +25,7 @@
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.MetadataResource;
import org.hl7.fhir.r4.model.NamingSystem;
+import org.hl7.fhir.r4.model.Questionnaire;
import org.hl7.fhir.r4.model.StructureDefinition;
import org.hl7.fhir.r4.model.ValueSet;
import org.slf4j.Logger;
@@ -54,10 +55,10 @@ class ResourceProviderImpl implements ResourceProvider
private static final String PLACEHOLDER_PREFIX = "#{";
private static final Pattern PLACEHOLDER_PREFIX_PATTERN = Pattern.compile(Pattern.quote(PLACEHOLDER_PREFIX));
-
private final Map> activityDefinitionsByProcessKeyAndVersion = new HashMap<>();
private final Map> codeSystemsByProcessKeyAndVersion = new HashMap<>();
private final Map> namingSystemsByProcessKeyAndVersion = new HashMap<>();
+ private final Map> questionnairesByProcessKeyAndVersion = new HashMap<>();
private final Map> structureDefinitionsByProcessKeyAndVersion = new HashMap<>();
private final Map> valueSetsByProcessKeyAndVersion = new HashMap<>();
@@ -66,6 +67,7 @@ class ResourceProviderImpl implements ResourceProvider
ResourceProviderImpl(Map> activityDefinitionsByProcessKeyAndVersion,
Map> codeSystemsByProcessKeyAndVersion,
Map> namingSystemsByProcessKeyAndVersion,
+ Map> questionnairesByProcessKeyAndVersion,
Map> structureDefinitionsByProcessKeyAndVersion,
Map> valueSetsByProcessKeyAndVersion,
Map> dependencyResourcesByProcessKeyAndVersion)
@@ -76,6 +78,8 @@ class ResourceProviderImpl implements ResourceProvider
this.codeSystemsByProcessKeyAndVersion.putAll(codeSystemsByProcessKeyAndVersion);
if (namingSystemsByProcessKeyAndVersion != null)
this.namingSystemsByProcessKeyAndVersion.putAll(namingSystemsByProcessKeyAndVersion);
+ if (questionnairesByProcessKeyAndVersion != null)
+ this.questionnairesByProcessKeyAndVersion.putAll(questionnairesByProcessKeyAndVersion);
if (structureDefinitionsByProcessKeyAndVersion != null)
this.structureDefinitionsByProcessKeyAndVersion.putAll(structureDefinitionsByProcessKeyAndVersion);
if (valueSetsByProcessKeyAndVersion != null)
@@ -111,6 +115,12 @@ public Optional getNamingSystem(String name)
return opt;
}
+ @Override
+ public Optional getQuestionnaire(String url, String version)
+ {
+ return getMetadataResource(url, version, questionnairesByProcessKeyAndVersion, Questionnaire.class);
+ }
+
@Override
public Optional getStructureDefinition(String url, String version)
{
@@ -155,6 +165,8 @@ else if (CodeSystem.class.equals(resource.getType()))
return getCodeSystem(resource.getUrl(), resource.getVersion()).map(r -> (MetadataResource) r);
else if (NamingSystem.class.equals(resource.getType()))
return getNamingSystem(resource.getName()).map(r -> (MetadataResource) r);
+ else if (Questionnaire.class.equals(resource.getType()))
+ return getQuestionnaire(resource.getUrl(), resource.getVersion()).map(r -> (MetadataResource) r);
else if (StructureDefinition.class.equals(resource.getType()))
return getStructureDefinition(resource.getUrl(), resource.getVersion()).map(r -> (MetadataResource) r);
else if (ValueSet.class.equals(resource.getType()))
@@ -177,15 +189,14 @@ public Stream getResources(String processKeyAndVersion,
.map(r -> providerByNameAndVersion.apply(r.getDependencyNameAndVersion()).getMetadataResouce(r))
.filter(Optional::isPresent).map(Optional::get);
- Stream resources = Arrays
- .asList(activityDefinitionsByProcessKeyAndVersion.getOrDefault(processKeyAndVersion,
- Collections.emptyList()),
- codeSystemsByProcessKeyAndVersion.getOrDefault(processKeyAndVersion, Collections.emptyList()),
- namingSystemsByProcessKeyAndVersion.getOrDefault(processKeyAndVersion, Collections.emptyList()),
- structureDefinitionsByProcessKeyAndVersion.getOrDefault(processKeyAndVersion,
- Collections.emptyList()),
- valueSetsByProcessKeyAndVersion.getOrDefault(processKeyAndVersion, Collections.emptyList()))
- .stream().flatMap(List::stream);
+ Stream resources = Arrays.asList(
+ activityDefinitionsByProcessKeyAndVersion.getOrDefault(processKeyAndVersion, Collections.emptyList()),
+ codeSystemsByProcessKeyAndVersion.getOrDefault(processKeyAndVersion, Collections.emptyList()),
+ namingSystemsByProcessKeyAndVersion.getOrDefault(processKeyAndVersion, Collections.emptyList()),
+ questionnairesByProcessKeyAndVersion.getOrDefault(processKeyAndVersion, Collections.emptyList()),
+ structureDefinitionsByProcessKeyAndVersion.getOrDefault(processKeyAndVersion, Collections.emptyList()),
+ valueSetsByProcessKeyAndVersion.getOrDefault(processKeyAndVersion, Collections.emptyList())).stream()
+ .flatMap(List::stream);
return Stream.concat(resources, dependencyResources);
}
@@ -201,6 +212,7 @@ static ResourceProvider of(Map> resourcesByProces
Map> activityDefinitionsByProcessKeyAndVersion = new HashMap<>();
Map> codeSystemsByProcessKeyAndVersion = new HashMap<>();
Map> namingSystemsByProcessKeyAndVersion = new HashMap<>();
+ Map> questionnairesByProcessKeyAndVersion = new HashMap<>();
Map> structureDefinitionsByProcessKeyAndVersion = new HashMap<>();
Map> valueSetsByProcessKeyAndVersion = new HashMap<>();
@@ -214,6 +226,8 @@ else if (r instanceof CodeSystem)
addOrInsert(codeSystemsByProcessKeyAndVersion, e.getKey(), (CodeSystem) r);
else if (r instanceof NamingSystem)
addOrInsert(namingSystemsByProcessKeyAndVersion, e.getKey(), (NamingSystem) r);
+ else if (r instanceof Questionnaire)
+ addOrInsert(questionnairesByProcessKeyAndVersion, e.getKey(), (Questionnaire) r);
else if (r instanceof StructureDefinition)
addOrInsert(structureDefinitionsByProcessKeyAndVersion, e.getKey(), (StructureDefinition) r);
else if (r instanceof ValueSet)
@@ -225,8 +239,9 @@ else if (r instanceof ValueSet)
});
return new ResourceProviderImpl(activityDefinitionsByProcessKeyAndVersion, codeSystemsByProcessKeyAndVersion,
- namingSystemsByProcessKeyAndVersion, structureDefinitionsByProcessKeyAndVersion,
- valueSetsByProcessKeyAndVersion, dependencyResourcesByProcessKeyAndVersion);
+ namingSystemsByProcessKeyAndVersion, questionnairesByProcessKeyAndVersion,
+ structureDefinitionsByProcessKeyAndVersion, valueSetsByProcessKeyAndVersion,
+ dependencyResourcesByProcessKeyAndVersion);
}
private static void addOrInsert(Map> map, String processKeyAndVersion,
diff --git a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/StructureDefinitionResource.java b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/StructureDefinitionResource.java
index c9479e11a..75b9fbf74 100644
--- a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/StructureDefinitionResource.java
+++ b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/StructureDefinitionResource.java
@@ -2,28 +2,27 @@
import java.util.Objects;
-import org.hl7.fhir.r4.model.MetadataResource;
import org.hl7.fhir.r4.model.StructureDefinition;
public class StructureDefinitionResource extends AbstractResource
{
- private StructureDefinitionResource(Class extends MetadataResource> type, String dependecyNameAndVersion,
- String structureDefinitionUrl, String structureDefinitionVersion, String structureDefinitionFileName)
+ private StructureDefinitionResource(String dependecyNameAndVersion, String structureDefinitionUrl,
+ String structureDefinitionVersion, String structureDefinitionFileName)
{
- super(type, dependecyNameAndVersion, structureDefinitionUrl, structureDefinitionVersion, null,
- structureDefinitionFileName);
+ super(StructureDefinition.class, dependecyNameAndVersion, structureDefinitionUrl, structureDefinitionVersion,
+ null, structureDefinitionFileName);
}
public static StructureDefinitionResource file(String structureDefinitionFileName)
{
- return new StructureDefinitionResource(StructureDefinition.class, null, null, null,
+ return new StructureDefinitionResource(null, null, null,
Objects.requireNonNull(structureDefinitionFileName, "structureDefinitionFileName"));
}
public static StructureDefinitionResource dependency(String dependencyNameAndVersion, String structureDefinitionUrl,
String structureDefinitionVersion)
{
- return new StructureDefinitionResource(StructureDefinition.class,
+ return new StructureDefinitionResource(
Objects.requireNonNull(dependencyNameAndVersion, "dependencyNameAndVersion"),
Objects.requireNonNull(structureDefinitionUrl, "structureDefinitionUrl"),
Objects.requireNonNull(structureDefinitionVersion, "structureDefinitionVersion"), null);
diff --git a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/ValueSetResource.java b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/ValueSetResource.java
index 2fe8d6c1c..7a68ff6b8 100644
--- a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/ValueSetResource.java
+++ b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/resources/ValueSetResource.java
@@ -2,28 +2,25 @@
import java.util.Objects;
-import org.hl7.fhir.r4.model.MetadataResource;
import org.hl7.fhir.r4.model.ValueSet;
public class ValueSetResource extends AbstractResource
{
- private ValueSetResource(Class extends MetadataResource> type, String dependencyNameAndVersion,
- String valueSetUrl, String valueSetVersion, String valueSetFileName)
+ private ValueSetResource(String dependencyNameAndVersion, String valueSetUrl, String valueSetVersion,
+ String valueSetFileName)
{
- super(type, dependencyNameAndVersion, valueSetUrl, valueSetVersion, null, valueSetFileName);
+ super(ValueSet.class, dependencyNameAndVersion, valueSetUrl, valueSetVersion, null, valueSetFileName);
}
public static ValueSetResource file(String valueSetFileName)
{
- return new ValueSetResource(ValueSet.class, null, null, null,
- Objects.requireNonNull(valueSetFileName, "valueSetFileName"));
+ return new ValueSetResource(null, null, null, Objects.requireNonNull(valueSetFileName, "valueSetFileName"));
}
public static ValueSetResource dependency(String dependencyNameAndVersion, String valueSetUrl,
String valueSetVersion)
{
- return new ValueSetResource(ValueSet.class,
- Objects.requireNonNull(dependencyNameAndVersion, "dependencyNameAndVersion"),
+ return new ValueSetResource(Objects.requireNonNull(dependencyNameAndVersion, "dependencyNameAndVersion"),
Objects.requireNonNull(valueSetUrl, "valueSetUrl"),
Objects.requireNonNull(valueSetVersion, "valueSetVersion"), null);
}
diff --git a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/task/AbstractTaskMessageSend.java b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/task/AbstractTaskMessageSend.java
index 0d76eff6c..36053a38d 100755
--- a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/task/AbstractTaskMessageSend.java
+++ b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/task/AbstractTaskMessageSend.java
@@ -125,7 +125,7 @@ protected void handleIntermediateThrowEventError(Exception exception, String err
logger.debug("Error while executing Task message send " + getClass().getName(), exception);
logger.error("Process {} has fatal error in step {} for task with id {}, reason: {}",
- execution.getProcessDefinitionId(), execution.getActivityInstanceId(),
+ getExecution().getProcessDefinitionId(), getExecution().getActivityInstanceId(),
task == null ? "?" : task.getId(), exception.getMessage());
try
@@ -141,8 +141,8 @@ protected void handleIntermediateThrowEventError(Exception exception, String err
}
finally
{
- execution.getProcessEngine().getRuntimeService().deleteProcessInstance(execution.getProcessInstanceId(),
- exception.getMessage());
+ getExecution().getProcessEngine().getRuntimeService()
+ .deleteProcessInstance(getExecution().getProcessInstanceId(), exception.getMessage());
}
}
@@ -152,7 +152,7 @@ protected void handleEndEventError(Exception exception, String errorMessage)
logger.debug("Error while executing Task message send " + getClass().getName(), exception);
logger.error("Process {} has fatal error in step {} for task with id {}, reason: {}",
- execution.getProcessDefinitionId(), execution.getActivityInstanceId(),
+ getExecution().getProcessDefinitionId(), getExecution().getActivityInstanceId(),
task == null ? "?" : task.getId(), exception.getMessage());
if (task != null)
@@ -189,7 +189,7 @@ protected void handleSendTaskError(Exception exception, String errorMessage)
{
logger.debug("Error while executing Task message send " + getClass().getName(), exception);
logger.error("Process {} has fatal error in step {} for task with id {}, last reason: {}",
- execution.getProcessDefinitionId(), execution.getActivityInstanceId(),
+ getExecution().getProcessDefinitionId(), getExecution().getActivityInstanceId(),
task == null ? "?" : task.getId(), exception.getMessage());
try
@@ -204,8 +204,8 @@ protected void handleSendTaskError(Exception exception, String errorMessage)
}
finally
{
- execution.getProcessEngine().getRuntimeService()
- .deleteProcessInstance(execution.getProcessInstanceId(), exception.getMessage());
+ getExecution().getProcessEngine().getRuntimeService()
+ .deleteProcessInstance(getExecution().getProcessInstanceId(), exception.getMessage());
}
}
}
@@ -234,10 +234,10 @@ protected Target getTarget(DelegateExecution execution)
*/
protected Target getTarget()
{
- if (execution == null)
+ if (getExecution() == null)
throw new IllegalStateException("execution not started");
- return (Target) execution.getVariable(BPMN_EXECUTION_VARIABLE_TARGET);
+ return (Target) getExecution().getVariable(BPMN_EXECUTION_VARIABLE_TARGET);
}
/**
@@ -248,10 +248,10 @@ protected Target getTarget()
*/
protected Targets getTargets()
{
- if (execution == null)
+ if (getExecution() == null)
throw new IllegalStateException("execution not started");
- return (Targets) execution.getVariable(BPMN_EXECUTION_VARIABLE_TARGETS);
+ return (Targets) getExecution().getVariable(BPMN_EXECUTION_VARIABLE_TARGETS);
}
/**
@@ -263,10 +263,10 @@ protected Targets getTargets()
*/
protected void updateTargets(Targets targets)
{
- if (execution == null)
+ if (getExecution() == null)
throw new IllegalStateException("execution not started");
- execution.setVariable(BPMN_EXECUTION_VARIABLE_TARGETS, TargetsValues.create(targets));
+ getExecution().setVariable(BPMN_EXECUTION_VARIABLE_TARGETS, TargetsValues.create(targets));
}
/**
@@ -306,7 +306,8 @@ protected Stream getAdditionalInputParameters(DelegateExecut
protected final String createAndSaveAlternativeBusinessKey()
{
String alternativeBusinessKey = UUID.randomUUID().toString();
- execution.setVariable(BPMN_EXECUTION_VARIABLE_ALTERNATIVE_BUSINESS_KEY, alternativeBusinessKey);
+ getExecution().setVariable(BPMN_EXECUTION_VARIABLE_ALTERNATIVE_BUSINESS_KEY, alternativeBusinessKey);
+
return alternativeBusinessKey;
}
diff --git a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/task/TaskHelper.java b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/task/TaskHelper.java
index 5ac0c0a2d..0e25de098 100755
--- a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/task/TaskHelper.java
+++ b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/task/TaskHelper.java
@@ -3,6 +3,7 @@
import java.util.Optional;
import java.util.stream.Stream;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.Task;
import org.hl7.fhir.r4.model.Task.ParameterComponent;
@@ -48,4 +49,14 @@ public interface TaskHelper
TaskOutputComponent createOutputUnsignedInt(String system, String code, int value);
TaskOutputComponent createOutput(String system, String code, Reference reference);
+
+ Task getTask(DelegateExecution execution);
+
+ Task getCurrentTaskFromExecutionVariables(DelegateExecution execution);
+
+ Task getLeadingTaskFromExecutionVariables(DelegateExecution execution);
+
+ void updateCurrentTaskInExecutionVariables(DelegateExecution execution, Task task);
+
+ void updateLeadingTaskInExecutionVariables(DelegateExecution execution, Task task);
}
diff --git a/dsf-bpe/dsf-bpe-server-jetty/pom.xml b/dsf-bpe/dsf-bpe-server-jetty/pom.xml
index 346a9ec47..9d1ea2ce0 100755
--- a/dsf-bpe/dsf-bpe-server-jetty/pom.xml
+++ b/dsf-bpe/dsf-bpe-server-jetty/pom.xml
@@ -7,7 +7,7 @@
org.highmed.dsf
dsf-bpe-pom
- 0.7.0
+ 0.8.0
@@ -50,11 +50,6 @@
compile
-
- javax.mail
- mail
-
-
org.slf4j
jul-to-slf4j
diff --git a/dsf-bpe/dsf-bpe-server/pom.xml b/dsf-bpe/dsf-bpe-server/pom.xml
index 2f3fce2cb..08f531e0d 100755
--- a/dsf-bpe/dsf-bpe-server/pom.xml
+++ b/dsf-bpe/dsf-bpe-server/pom.xml
@@ -7,7 +7,7 @@
org.highmed.dsf
dsf-bpe-pom
- 0.7.0
+ 0.8.0
@@ -139,13 +139,21 @@
- de.hs-heilbronn.mi
- db-test-utils
- test
+ com.sun.mail
+ jakarta.mail
+
+
+ org.bouncycastle
+ bcmail-jdk15on
de.hs-heilbronn.mi
log4j2-utils
+
+
+
+ de.hs-heilbronn.mi
+ db-test-utils
test
@@ -167,5 +175,85 @@
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ log4j2-maven-surefire-config.xml
+
+
+ **/*DaoTest
+ **/*IntegrationTest
+
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+
+
+ log4j2-maven-surefire-config.xml
+
+
+ **/*DaoTest
+ **/*IntegrationTest
+
+
+
+
+
+ integration-test
+ verify
+
+
+
+
+
+ io.fabric8
+ docker-maven-plugin
+ true
+
+
+ start-postgres
+ pre-integration-test
+
+ start
+
+
+
+
+ postgres:13
+
+
+ 127.0.0.1:54321:5432
+
+
+ Europe/Berlin
+ postgres
+ password
+ db
+
+
+
+
+
+
+
+
+
+
+
+ stop-postgres
+ post-integration-test
+
+ stop
+
+
+
+
+
\ No newline at end of file
diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/bpe/camunda/MultiVersionBpmnParse.java b/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/bpe/camunda/MultiVersionBpmnParse.java
index 5fd514d46..fc9f40893 100644
--- a/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/bpe/camunda/MultiVersionBpmnParse.java
+++ b/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/bpe/camunda/MultiVersionBpmnParse.java
@@ -1,15 +1,21 @@
package org.highmed.dsf.bpe.camunda;
+import java.util.ArrayList;
import java.util.List;
+import org.camunda.bpm.engine.delegate.ExecutionListener;
+import org.camunda.bpm.engine.delegate.TaskListener;
import org.camunda.bpm.engine.impl.bpmn.behavior.ClassDelegateActivityBehavior;
import org.camunda.bpm.engine.impl.bpmn.parser.BpmnParse;
import org.camunda.bpm.engine.impl.bpmn.parser.BpmnParser;
import org.camunda.bpm.engine.impl.bpmn.parser.FieldDeclaration;
import org.camunda.bpm.engine.impl.pvm.process.ActivityImpl;
import org.camunda.bpm.engine.impl.pvm.process.ScopeImpl;
+import org.camunda.bpm.engine.impl.task.TaskDefinition;
import org.camunda.bpm.engine.impl.util.xml.Element;
import org.highmed.dsf.bpe.delegate.DelegateProvider;
+import org.highmed.dsf.bpe.listener.DefaultUserTaskListener;
+import org.highmed.dsf.bpe.process.ProcessKeyAndVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -17,6 +23,10 @@ public class MultiVersionBpmnParse extends BpmnParse
{
private static final Logger logger = LoggerFactory.getLogger(MultiVersionBpmnParse.class);
+ protected static final String TAGNAME_PROCESS = "process";
+ protected static final String PROPERTYNAME_ID = "id";
+ protected static final String PROPERTYNAME_VERSION = "http://camunda.org/schema/1.0/bpmn:versionTag";
+
private final DelegateProvider delegateProvider;
public MultiVersionBpmnParse(BpmnParser parser, DelegateProvider delegateProvider)
@@ -37,11 +47,123 @@ public void parseServiceTaskLike(ActivityImpl activity, String elementName, Elem
String className = serviceTaskElement.attributeNS(CAMUNDA_BPMN_EXTENSIONS_NS, PROPERTYNAME_CLASS);
List