From 861aa3c69a294af13765af617b460c60d1b15d28 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 7 Mar 2017 15:35:01 +0100 Subject: [PATCH] Cleaned-up workflow notifications (API and SimpleWorktlowNotifier). --- .../ns/public/common/common-workflows-3.xsd | 15 +- .../api/events/WorkItemAllocationEvent.java | 17 ++- .../api/events/WorkItemCustomEvent.java | 12 +- .../api/events/WorkItemEvent.java | 41 +++--- .../api/events/WorkItemLifecycleEvent.java | 13 +- .../notifications/impl/WorkflowListener.java | 96 ++++++------ .../notifiers/SimpleWorkflowNotifier.java | 139 ++++++++++++------ ...WorkItemAllocationChangeOperationInfo.java | 53 +++++++ .../midpoint/wf/api/WorkItemListener.java | 46 +++--- .../wf/api/WorkItemOperationInfo.java | 37 +++++ .../wf/api/WorkItemOperationSourceInfo.java | 54 +++++++ .../wf/impl/activiti/dao/WorkItemManager.java | 19 ++- .../common/WfTimedActionTriggerHandler.java | 12 +- .../wf/impl/processors/BaseAuditHelper.java | 7 +- .../wf/impl/processors/ChangeProcessor.java | 8 +- .../general/GeneralChangeProcessor.java | 4 +- .../scenarios/BaseGcpScenarioBean.java | 8 +- .../general/scenarios/GcpScenarioBean.java | 6 +- .../primary/PrimaryChangeProcessor.java | 8 +- .../wf/impl/tasks/WfTaskController.java | 81 +++++----- .../wf/impl/policy/other/TestEscalation.java | 2 +- .../midpoint/testing/story/TestStrings.java | 32 +--- 22 files changed, 437 insertions(+), 273 deletions(-) create mode 100644 model/workflow-api/src/main/java/com/evolveum/midpoint/wf/api/WorkItemAllocationChangeOperationInfo.java create mode 100644 model/workflow-api/src/main/java/com/evolveum/midpoint/wf/api/WorkItemOperationInfo.java create mode 100644 model/workflow-api/src/main/java/com/evolveum/midpoint/wf/api/WorkItemOperationSourceInfo.java diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd index 24403dbd48c..9fd772eaf10 100644 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd @@ -2159,8 +2159,7 @@ - Kind of (explicit) operation. Implicit operations like "work item deletion when process instance finishes" - are not covered here. + Kind of operation. 3.6 @@ -2218,6 +2217,18 @@ + + + + Cancel operation. Work item was cancelled as a result of other action. (E.g. another work item + was completed, resulting in process or stage completion. Or the process was cancelled/deleted + externally.) + + + + + + diff --git a/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/WorkItemAllocationEvent.java b/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/WorkItemAllocationEvent.java index cdb95be14f0..098936d010f 100644 --- a/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/WorkItemAllocationEvent.java +++ b/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/WorkItemAllocationEvent.java @@ -19,6 +19,8 @@ import com.evolveum.midpoint.prism.delta.ChangeType; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.LightweightIdentifierGenerator; +import com.evolveum.midpoint.wf.api.WorkItemOperationInfo; +import com.evolveum.midpoint.wf.api.WorkItemOperationSourceInfo; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -32,14 +34,13 @@ */ public class WorkItemAllocationEvent extends WorkItemEvent { - public WorkItemAllocationEvent(LightweightIdentifierGenerator lightweightIdentifierGenerator, ChangeType changeType, - @NotNull WorkItemType workItem, @Nullable SimpleObjectRef assignee, WorkItemOperationKindType operationKind, - SimpleObjectRef initiator, WorkItemResultType workItemResult, AbstractWorkItemActionType source, - WorkItemEventCauseInformationType cause, - WfContextType workflowContext, - Duration timeBefore) { - super(lightweightIdentifierGenerator, changeType, workItem, assignee, initiator, operationKind, - workItemResult, source, cause, workflowContext,null, timeBefore); + public WorkItemAllocationEvent(@NotNull LightweightIdentifierGenerator lightweightIdentifierGenerator, + @NotNull ChangeType changeType, + @NotNull WorkItemType workItem, @Nullable SimpleObjectRef assignee, @Nullable SimpleObjectRef initiator, + @Nullable WorkItemOperationInfo operationInfo, @Nullable WorkItemOperationSourceInfo sourceInfo, + @NotNull WfContextType workflowContext, @Nullable Duration timeBefore) { + super(lightweightIdentifierGenerator, changeType, workItem, assignee, initiator, operationInfo, sourceInfo, + workflowContext,null, timeBefore); } @Override diff --git a/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/WorkItemCustomEvent.java b/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/WorkItemCustomEvent.java index c4844cd14f8..7ba6dd4b183 100644 --- a/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/WorkItemCustomEvent.java +++ b/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/WorkItemCustomEvent.java @@ -19,6 +19,7 @@ import com.evolveum.midpoint.prism.delta.ChangeType; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.LightweightIdentifierGenerator; +import com.evolveum.midpoint.wf.api.WorkItemOperationSourceInfo; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -31,11 +32,12 @@ */ public class WorkItemCustomEvent extends WorkItemEvent { - public WorkItemCustomEvent(LightweightIdentifierGenerator lightweightIdentifierGenerator, ChangeType changeType, - @NotNull WorkItemType workItem, @Nullable SimpleObjectRef assignee, @NotNull WorkItemNotificationActionType source, - WorkItemEventCauseInformationType cause, WfContextType workflowContext) { - super(lightweightIdentifierGenerator, changeType, workItem, assignee, null, null, null, source, - cause, workflowContext, source.getHandler(), null); + public WorkItemCustomEvent(@NotNull LightweightIdentifierGenerator lightweightIdentifierGenerator, @NotNull ChangeType changeType, + @NotNull WorkItemType workItem, + @Nullable SimpleObjectRef assignee, @Nullable WorkItemOperationSourceInfo sourceInfo, + @NotNull WfContextType workflowContext, @Nullable EventHandlerType handler) { + super(lightweightIdentifierGenerator, changeType, workItem, assignee, null, null, + sourceInfo, workflowContext, handler, null); } @Override diff --git a/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/WorkItemEvent.java b/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/WorkItemEvent.java index d8584801e55..57b8651b8d0 100644 --- a/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/WorkItemEvent.java +++ b/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/WorkItemEvent.java @@ -20,6 +20,8 @@ import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.LightweightIdentifierGenerator; +import com.evolveum.midpoint.wf.api.WorkItemOperationInfo; +import com.evolveum.midpoint.wf.api.WorkItemOperationSourceInfo; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.lang.Validate; import org.jetbrains.annotations.NotNull; @@ -44,28 +46,23 @@ public class WorkItemEvent extends WorkflowEvent { * In case of automated actions (completion, delegation/escalation) this is not filled-in. */ protected final SimpleObjectRef initiator; - protected final WorkItemOperationKindType operationKind; - protected final AbstractWorkItemActionType source; - protected final WorkItemEventCauseInformationType cause; + protected final WorkItemOperationInfo operationInfo; + protected final WorkItemOperationSourceInfo sourceInfo; protected final Duration timeBefore; - protected final WorkItemResultType workItemResult; - WorkItemEvent(LightweightIdentifierGenerator lightweightIdentifierGenerator, ChangeType changeType, + WorkItemEvent(@NotNull LightweightIdentifierGenerator lightweightIdentifierGenerator, @NotNull ChangeType changeType, @NotNull WorkItemType workItem, - @Nullable SimpleObjectRef assignee, SimpleObjectRef initiator, WorkItemOperationKindType operationKind, - WorkItemResultType workItemResult, @Nullable AbstractWorkItemActionType source, - @Nullable WorkItemEventCauseInformationType cause, - WfContextType workflowContext, - EventHandlerType handler, Duration timeBefore) { + @Nullable SimpleObjectRef assignee, @Nullable SimpleObjectRef initiator, + @Nullable WorkItemOperationInfo operationInfo, @Nullable WorkItemOperationSourceInfo sourceInfo, + @NotNull WfContextType workflowContext, + @Nullable EventHandlerType handler, @Nullable Duration timeBefore) { super(lightweightIdentifierGenerator, changeType, workflowContext, handler); Validate.notNull(workItem); this.workItem = workItem; this.assignee = assignee; this.initiator = initiator; - this.operationKind = operationKind; - this.workItemResult = workItemResult; - this.source = source; - this.cause = cause; + this.operationInfo = operationInfo; + this.sourceInfo = sourceInfo; this.timeBefore = timeBefore; } @@ -92,21 +89,29 @@ public SimpleObjectRef getInitiator() { } public WorkItemOperationKindType getOperationKind() { - return operationKind; + return operationInfo != null ? operationInfo.getOperationKind() : null; } public AbstractWorkItemActionType getSource() { - return source; + return sourceInfo != null ? sourceInfo.getSource() : null; } public WorkItemEventCauseInformationType getCause() { - return cause; + return sourceInfo != null ? sourceInfo.getCause() : null; } public Duration getTimeBefore() { return timeBefore; } + public WorkItemOperationInfo getOperationInfo() { + return operationInfo; + } + + public WorkItemOperationSourceInfo getSourceInfo() { + return sourceInfo; + } + @Override public void createExpressionVariables(Map variables, OperationResult result) { super.createExpressionVariables(variables, result); @@ -115,7 +120,7 @@ public void createExpressionVariables(Map variables, OperationRes } public WorkItemResultType getWorkItemResult() { - return workItemResult != null ? workItemResult : workItem.getResult(); + return workItem.getResult(); } @Override diff --git a/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/WorkItemLifecycleEvent.java b/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/WorkItemLifecycleEvent.java index d2cfc20f63e..7e5a37930a0 100644 --- a/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/WorkItemLifecycleEvent.java +++ b/model/notifications-api/src/main/java/com/evolveum/midpoint/notifications/api/events/WorkItemLifecycleEvent.java @@ -19,6 +19,8 @@ import com.evolveum.midpoint.prism.delta.ChangeType; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.LightweightIdentifierGenerator; +import com.evolveum.midpoint.wf.api.WorkItemOperationInfo; +import com.evolveum.midpoint.wf.api.WorkItemOperationSourceInfo; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -31,14 +33,13 @@ */ public class WorkItemLifecycleEvent extends WorkItemEvent { - public WorkItemLifecycleEvent(LightweightIdentifierGenerator lightweightIdentifierGenerator, ChangeType changeType, + public WorkItemLifecycleEvent(@NotNull LightweightIdentifierGenerator lightweightIdentifierGenerator, @NotNull ChangeType changeType, @NotNull WorkItemType workItem, @Nullable SimpleObjectRef assignee, @Nullable SimpleObjectRef initiator, - WorkItemOperationKindType operationKind, - WorkItemResultType workItemResult, AbstractWorkItemActionType source, WorkItemEventCauseInformationType cause, - WfContextType workflowContext) { - super(lightweightIdentifierGenerator, changeType, workItem, assignee, initiator, operationKind, - workItemResult, source, cause, workflowContext, null, null); + @Nullable WorkItemOperationInfo operationInfo, @Nullable WorkItemOperationSourceInfo sourceInfo, + @NotNull WfContextType workflowContext) { + super(lightweightIdentifierGenerator, changeType, workItem, assignee, initiator, + operationInfo, sourceInfo, workflowContext, null, null); } @Override diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/WorkflowListener.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/WorkflowListener.java index 8569491abf9..8bddc7d1b0b 100644 --- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/WorkflowListener.java +++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/WorkflowListener.java @@ -25,12 +25,11 @@ import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.wf.api.ProcessListener; -import com.evolveum.midpoint.wf.api.WorkItemListener; -import com.evolveum.midpoint.wf.api.WorkflowManager; +import com.evolveum.midpoint.wf.api.*; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.lang.Validate; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -89,60 +88,59 @@ public void onProcessInstanceEnd(Task wfTask, OperationResult result) { //region WorkItem-level notifications @Override - public void onWorkItemCreation(WorkItemType workItem, ObjectReferenceType originalAssigneeRef, Task wfTask, - OperationResult result) { + public void onWorkItemCreation(ObjectReferenceType assignee, @NotNull WorkItemType workItem, + Task wfTask, OperationResult result) { WorkItemEvent event = new WorkItemLifecycleEvent(identifierGenerator, ChangeType.ADD, workItem, - SimpleObjectRefImpl.create(functions, originalAssigneeRef), null, null, null, null, null, wfTask.getWorkflowContext()); + SimpleObjectRefImpl.create(functions, assignee), null, null, null, wfTask.getWorkflowContext()); initializeWorkflowEvent(event, wfTask); processEvent(event, result); } @Override - public void onWorkItemDeletion(WorkItemType workItem, ObjectReferenceType assignee, ObjectReferenceType initiator, - WorkItemOperationKindType operationKind, - WorkItemResultType workItemResult, AbstractWorkItemActionType source, WorkItemEventCauseInformationType cause, + public void onWorkItemDeletion(ObjectReferenceType assignee, @NotNull WorkItemType workItem, + WorkItemOperationInfo operationInfo, WorkItemOperationSourceInfo sourceInfo, Task wfTask, OperationResult result) { WorkItemEvent event = new WorkItemLifecycleEvent(identifierGenerator, ChangeType.DELETE, workItem, SimpleObjectRefImpl.create(functions, assignee), - SimpleObjectRefImpl.create(functions, initiator), - operationKind, workItemResult, source, cause, wfTask.getWorkflowContext()); + getInitiator(sourceInfo), operationInfo, sourceInfo, wfTask.getWorkflowContext()); initializeWorkflowEvent(event, wfTask); processEvent(event, result); } @Override - public void onWorkItemCustomEvent(WorkItemType workItem, ObjectReferenceType assignee, + public void onWorkItemCustomEvent(ObjectReferenceType assignee, @NotNull WorkItemType workItem, @NotNull WorkItemNotificationActionType notificationAction, WorkItemEventCauseInformationType cause, Task wfTask, OperationResult result) { WorkItemEvent event = new WorkItemCustomEvent(identifierGenerator, ChangeType.ADD, workItem, - SimpleObjectRefImpl.create(functions, assignee), notificationAction, cause, wfTask.getWorkflowContext()); + SimpleObjectRefImpl.create(functions, assignee), + new WorkItemOperationSourceInfo(null, cause, notificationAction), + wfTask.getWorkflowContext(), notificationAction.getHandler()); initializeWorkflowEvent(event, wfTask); processEvent(event, result); } - @Override - public void onWorkItemAllocationChangeCurrentActors(WorkItemType workItem, List currentActors, - Duration timeBefore, WorkItemOperationKindType operationKind, ObjectReferenceType initiator, - WorkItemResultType workItemResult, AbstractWorkItemActionType source, - WorkItemEventCauseInformationType cause, Task task, OperationResult result) { - checkOids(currentActors); - for (ObjectReferenceType currentActor : currentActors) { - onWorkItemAllocationModifyDelete(currentActor, workItem, timeBefore, operationKind, initiator, workItemResult, source, cause, task, result); + @Override + public void onWorkItemAllocationChangeCurrentActors(@NotNull WorkItemType workItem, + @NotNull WorkItemAllocationChangeOperationInfo operationInfo, + @Nullable WorkItemOperationSourceInfo sourceInfo, + Duration timeBefore, Task task, OperationResult result) { + checkOids(operationInfo.getCurrentActors()); + for (ObjectReferenceType currentActor : operationInfo.getCurrentActors()) { + onWorkItemAllocationModifyDelete(currentActor, workItem, operationInfo, sourceInfo, timeBefore, task, result); } } @Override - public void onWorkItemAllocationChangeNewActors(WorkItemType workItem, List currentActors, - List newActors, WorkItemOperationKindType operationKind, ObjectReferenceType initiator, - AbstractWorkItemActionType source, - WorkItemEventCauseInformationType cause, Task task, OperationResult result) { - - checkOids(currentActors); - checkOids(newActors); - for (ObjectReferenceType newActor : newActors) { -// if (!ObjectTypeUtil.containsOid(currentActors, newActor.getOid())) { - onWorkItemAllocationAdd(newActor, workItem, operationKind, initiator, source, cause, task, result); -// } + public void onWorkItemAllocationChangeNewActors(@NotNull WorkItemType workItem, + @NotNull WorkItemAllocationChangeOperationInfo operationInfo, + @Nullable WorkItemOperationSourceInfo sourceInfo, + Task task, OperationResult result) { + Validate.notNull(operationInfo.getNewActors()); + + checkOids(operationInfo.getCurrentActors()); + checkOids(operationInfo.getNewActors()); + for (ObjectReferenceType newActor : operationInfo.getNewActors()) { + onWorkItemAllocationAdd(newActor, workItem, operationInfo, sourceInfo, task, result); } } @@ -150,27 +148,29 @@ private void checkOids(List refs) { refs.forEach(r -> Validate.notNull(r.getOid(), "No OID in actor object reference " + r)); } - private void onWorkItemAllocationAdd(ObjectReferenceType newActor, WorkItemType workItem, - WorkItemOperationKindType operationKind, ObjectReferenceType initiator, AbstractWorkItemActionType source, - WorkItemEventCauseInformationType cause, Task task, OperationResult result) { + private void onWorkItemAllocationAdd(ObjectReferenceType newActor, @NotNull WorkItemType workItem, + @Nullable WorkItemOperationInfo operationInfo, @Nullable WorkItemOperationSourceInfo sourceInfo, + Task task, OperationResult result) { WorkItemAllocationEvent event = new WorkItemAllocationEvent(identifierGenerator, ChangeType.ADD, workItem, SimpleObjectRefImpl.create(functions, newActor), - operationKind, SimpleObjectRefImpl.create(functions, initiator), - null, source, cause, + getInitiator(sourceInfo), operationInfo, sourceInfo, task.getWorkflowContext(), null); initializeWorkflowEvent(event, task); processEvent(event, result); } - private void onWorkItemAllocationModifyDelete(ObjectReferenceType currentActor, WorkItemType workItem, Duration timeBefore, - WorkItemOperationKindType operationKind, ObjectReferenceType initiator, WorkItemResultType workItemResult, - AbstractWorkItemActionType source, - WorkItemEventCauseInformationType cause, - Task task, OperationResult result) { + private SimpleObjectRef getInitiator(WorkItemOperationSourceInfo sourceInfo) { + return sourceInfo != null ? + SimpleObjectRefImpl.create(functions, sourceInfo.getInitiatorRef()) : null; + } + + private void onWorkItemAllocationModifyDelete(ObjectReferenceType currentActor, @NotNull WorkItemType workItem, + @Nullable WorkItemOperationInfo operationInfo, @Nullable WorkItemOperationSourceInfo sourceInfo, + Duration timeBefore, Task task, OperationResult result) { WorkItemAllocationEvent event = new WorkItemAllocationEvent(identifierGenerator, timeBefore != null ? ChangeType.MODIFY : ChangeType.DELETE, workItem, - SimpleObjectRefImpl.create(functions, currentActor), operationKind, SimpleObjectRefImpl.create(functions, initiator), - workItemResult, source, cause, + SimpleObjectRefImpl.create(functions, currentActor), + getInitiator(sourceInfo), operationInfo, sourceInfo, task.getWorkflowContext(), timeBefore); initializeWorkflowEvent(event, task); processEvent(event, result); @@ -192,14 +192,6 @@ private void processEvent(WorkflowEvent event, OperationResult result) { result.recordSuccessIfUnknown(); } - private void processEvent(WorkflowEvent event) { - try { - notificationManager.processEvent(event); - } catch (RuntimeException e) { - LoggingUtils.logUnexpectedException(LOGGER, "An unexpected exception occurred when preparing and sending notifications: " + e.getMessage(), e); - } - } - private void initializeWorkflowEvent(WorkflowEvent event, Task wfTask) { WfContextType wfc = wfTask.getWorkflowContext(); event.setRequester(SimpleObjectRefImpl.create(functions, wfc.getRequesterRef())); diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/SimpleWorkflowNotifier.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/SimpleWorkflowNotifier.java index 29e3d24cfdd..dc4ed733427 100644 --- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/SimpleWorkflowNotifier.java +++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/SimpleWorkflowNotifier.java @@ -140,22 +140,25 @@ protected String getBody(Event event, GeneralNotifierType generalNotifierType, S body.append(getSubject(event, generalNotifierType, transport, task, result)); body.append("\n\n"); - body.append("Process instance name: ").append(workflowEvent.getProcessInstanceName()).append("\n"); - if (workflowEvent instanceof WorkItemEvent) { - appendWorkItemInformation(body, (WorkItemEvent) workflowEvent, result); + appendGeneralInformation(body, workflowEvent); // process instance name, work item name, stage, escalation level + + if (workflowEvent instanceof WorkItemEvent) { + WorkItemEvent workItemEvent = (WorkItemEvent) workflowEvent; + appendAssigneeInformation(body, workItemEvent, result); + appendResultAndOriginInformation(body, workItemEvent, result); + appendDeadlineInformation(body, workItemEvent); } else { - appendStageInformation(body, workflowEvent); - body.append("\n"); - appendResultInformation(body, workflowEvent); + appendResultInformation(body, workflowEvent, true); } - body.append("Notification created on: ").append(new Date()).append("\n\n"); + body.append("\nNotification created on: ").append(new Date()).append("\n\n"); if (techInfo) { body.append("----------------------------------------\n"); body.append("Technical information:\n\n"); if (workflowEvent instanceof WorkItemEvent) { + WorkItemEvent workItemEvent = (WorkItemEvent) workflowEvent; body.append("WorkItem:\n") - .append(PrismUtil.serializeQuietly(prismContext, ((WorkItemEvent) workflowEvent).getWorkItem())) + .append(PrismUtil.serializeQuietly(prismContext, workItemEvent.getWorkItem())) .append("\n"); } body.append("Workflow context:\n") @@ -164,25 +167,87 @@ protected String getBody(Event event, GeneralNotifierType generalNotifierType, S return body.toString(); } - private void appendResultInformation(StringBuilder body, WorkflowEvent workflowEvent) { + private void appendGeneralInformation(StringBuilder sb, WorkflowEvent workflowEvent) { + sb.append("Process instance name: ").append(workflowEvent.getProcessInstanceName()).append("\n"); + if (workflowEvent instanceof WorkItemEvent) { + WorkItemEvent event = (WorkItemEvent) workflowEvent; + sb.append("Work item: ").append(event.getWorkItemName()).append("\n"); + appendStageInformation(sb, event); + appendEscalationInformation(sb, event); + } else { + appendStageInformation(sb, workflowEvent); + } + sb.append("\n"); + } + + private boolean appendResultInformation(StringBuilder body, WorkflowEvent workflowEvent, boolean emptyLineAfter) { if (workflowEvent.isDelete() && workflowEvent.isResultKnown()) { - body.append("Result: ").append(workflowEvent.isApproved() ? "APPROVED" : "REJECTED").append("\n\n"); + body.append("Result: ").append(workflowEvent.isApproved() ? "APPROVED" : "REJECTED").append("\n"); + if (emptyLineAfter) { + body.append("\n"); + } + return true; + } else { + return false; } } - private void appendWorkItemInformation(StringBuilder sb, WorkItemEvent event, OperationResult result) { + private void appendDeadlineInformation(StringBuilder sb, WorkItemEvent event) { WorkItemType workItem = event.getWorkItem(); + if (!isDone(event) && workItem.getDeadline() != null) { + XMLGregorianCalendar deadline = workItem.getDeadline(); + long before = XmlTypeConverter.toMillis(deadline) - System.currentTimeMillis(); + long beforeRounded = Math.round((double) before / 60000.0) * 60000L; + String beforeWords = DurationFormatUtils.formatDurationWords(Math.abs(beforeRounded), true, true); + String beforePhrase; + if (beforeRounded > 0) { + beforePhrase = " (in " + beforeWords + ")"; + } else if (beforeRounded < 0) { + beforePhrase = " (" + beforeWords + " ago)"; + } else { + beforePhrase = ""; + } + sb.append("Deadline: ").append(formatDateTime(deadline)).append(beforePhrase).append("\n"); + sb.append("\n"); + } + } - sb.append("Work item: ").append(event.getWorkItemName()).append("\n"); - appendStageInformation(sb, event); - appendEscalationInformation(sb, event); - sb.append("\n"); + private void appendResultAndOriginInformation(StringBuilder sb, WorkItemEvent event, OperationResult result) { + boolean atLeastOne = appendResultInformation(sb, event, false); + WorkItemEventCauseInformationType cause = event.getCause(); + if (cause != null && cause.getType() == WorkItemEventCauseTypeType.TIMED_ACTION) { + sb.append("Reason: "); + if (cause.getDisplayName() != null) { + sb.append(cause.getDisplayName()).append(" (timed action)"); + } else if (cause.getName() != null) { + sb.append(cause.getName()).append(" (timed action)"); + } else { + sb.append("Timed action"); + } + sb.append("\n"); + atLeastOne = true; + } else { + SimpleObjectRef initiator = event.getInitiator(); + if (initiator != null && !isCancelled(event)) { + UserType initiatorFull = (UserType) functions.getObjectType(initiator, true, result); + sb.append("Carried out by: ").append(formatUserName(initiatorFull, initiator.getOid())).append("\n"); + atLeastOne = true; + } + } + if (atLeastOne) { + sb.append("\n"); + } + } + private void appendAssigneeInformation(StringBuilder sb, WorkItemEvent event, OperationResult result) { + WorkItemType workItem = event.getWorkItem(); ObjectReferenceType originalAssignee = workItem.getOriginalAssigneeRef(); List currentAssignees = workItem.getAssigneeRef(); + boolean atLeastOne = false; if (currentAssignees.size() != 1 || !java.util.Objects.equals(originalAssignee.getOid(), currentAssignees.get(0).getOid())) { UserType originalAssigneeObject = (UserType) functions.getObjectType(originalAssignee, true, result); sb.append("Originally allocated to: ").append(formatUserName(originalAssigneeObject, originalAssignee.getOid())).append("\n"); + atLeastOne = true; } if (!workItem.getAssigneeRef().isEmpty()) { sb.append("Allocated to"); @@ -196,41 +261,11 @@ private void appendWorkItemInformation(StringBuilder sb, WorkItemEvent event, Op .map(ref -> formatUserName(ref, result)) .collect(Collectors.joining(", "))); sb.append("\n"); + atLeastOne = true; } - SimpleObjectRef initiator = event.getInitiator(); - if (initiator != null) { - UserType initiatorFull = (UserType) functions.getObjectType(initiator, true, result); - sb.append("Carried out by: ").append(formatUserName(initiatorFull, initiator.getOid())); - WorkItemEventCauseInformationType cause = event.getCause(); - if (cause != null && cause.getType() == WorkItemEventCauseTypeType.TIMED_ACTION) { - sb.append(" (timed action"); - if (cause.getDisplayName() != null) { - sb.append(" '").append(cause.getDisplayName()).append("'"); - } else if (cause.getName() != null) { - sb.append(" '").append(cause.getName()).append("'"); - } - sb.append(")"); - } + if (atLeastOne) { sb.append("\n"); } - - appendResultInformation(sb, event); - if (!isDone(event) && workItem.getDeadline() != null) { - XMLGregorianCalendar deadline = workItem.getDeadline(); - long before = XmlTypeConverter.toMillis(deadline) - System.currentTimeMillis(); - long beforeRounded = Math.round((double) before / 60000.0) * 60000L; - String beforeWords = DurationFormatUtils.formatDurationWords(Math.abs(beforeRounded), true, true); - String beforePhrase; - if (beforeRounded > 0) { - beforePhrase = " (in " + beforeWords + ")"; - } else if (beforeRounded < 0) { - beforePhrase = " (" + beforeWords + " ago)"; - } else { - beforePhrase = ""; - } - sb.append("Deadline: ").append(formatDateTime(deadline)).append(beforePhrase).append("\n"); - } - sb.append("\n"); } // a bit of heuristics... @@ -239,12 +274,19 @@ private boolean isDone(WorkItemEvent event) { return event.isDelete(); } else if (event instanceof WorkItemAllocationEvent) { return event.isDelete() && - (event.getOperationKind() == null || event.getOperationKind() == WorkItemOperationKindType.COMPLETE); + (event.getOperationKind() == null || event.getOperationKind() == WorkItemOperationKindType.CANCEL + || event.getOperationKind() == WorkItemOperationKindType.COMPLETE); } else { return false; } } + private boolean isCancelled(WorkItemEvent event) { + return (event instanceof WorkItemLifecycleEvent || event instanceof WorkItemAllocationEvent) + && event.isDelete() + && (event.getOperationKind() == null || event.getOperationKind() == WorkItemOperationKindType.CANCEL); + } + private String formatUserName(ObjectReferenceType ref, OperationResult result) { UserType user = (UserType) functions.getObjectType(ref, true, result); return formatUserName(user, ref.getOid()); @@ -296,6 +338,7 @@ private String getOperationPastTenseVerb(WorkItemOperationKindType operationKind case COMPLETE: return "completed"; case DELEGATE: return "delegated"; case ESCALATE: return "escalated"; + case CANCEL: return "cancelled"; default: throw new IllegalArgumentException("operation kind: " + operationKind); } } diff --git a/model/workflow-api/src/main/java/com/evolveum/midpoint/wf/api/WorkItemAllocationChangeOperationInfo.java b/model/workflow-api/src/main/java/com/evolveum/midpoint/wf/api/WorkItemAllocationChangeOperationInfo.java new file mode 100644 index 00000000000..7b8fe955945 --- /dev/null +++ b/model/workflow-api/src/main/java/com/evolveum/midpoint/wf/api/WorkItemAllocationChangeOperationInfo.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * 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 com.evolveum.midpoint.wf.api; + +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemOperationKindType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * Primarily used to simplify passing parameters to WorkflowListener. + * + * @author mederly + */ +public class WorkItemAllocationChangeOperationInfo extends WorkItemOperationInfo { + + @NotNull private final List currentActors; + @Nullable private final List newActors; + + public WorkItemAllocationChangeOperationInfo( + WorkItemOperationKindType operationKind, + @NotNull List currentActors, @Nullable List newActors) { + super(operationKind); + this.currentActors = currentActors; + this.newActors = newActors; + } + + @NotNull + public List getCurrentActors() { + return currentActors; + } + + @Nullable + public List getNewActors() { + return newActors; + } +} diff --git a/model/workflow-api/src/main/java/com/evolveum/midpoint/wf/api/WorkItemListener.java b/model/workflow-api/src/main/java/com/evolveum/midpoint/wf/api/WorkItemListener.java index f43bedab9c9..bc7115b7efb 100644 --- a/model/workflow-api/src/main/java/com/evolveum/midpoint/wf/api/WorkItemListener.java +++ b/model/workflow-api/src/main/java/com/evolveum/midpoint/wf/api/WorkItemListener.java @@ -18,10 +18,14 @@ import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.Task; -import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemEventCauseInformationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemNotificationActionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.xml.datatype.Duration; -import java.util.List; /** * An interface through which external observers can be notified about work item related events. @@ -40,43 +44,29 @@ public interface WorkItemListener { /** * This method is called by wf module when a work item is created. - * - * @param workItem the work item - * @param originalAssigneeRef */ - void onWorkItemCreation(WorkItemType workItem, ObjectReferenceType originalAssigneeRef, Task wfTask, OperationResult result); + void onWorkItemCreation(ObjectReferenceType assignee, @NotNull WorkItemType workItem, + Task wfTask, OperationResult result); /** * This method is called by wf module when a work item is completed. - * @param workItem the work item - * @param assignee - * @param initiator - * @param operationKind - * @param workItemResult - * @param source - * @param cause */ - void onWorkItemDeletion(WorkItemType workItem, ObjectReferenceType assignee, ObjectReferenceType initiator, - WorkItemOperationKindType operationKind, WorkItemResultType workItemResult, AbstractWorkItemActionType source, - WorkItemEventCauseInformationType cause, + void onWorkItemDeletion(ObjectReferenceType assignee, @NotNull WorkItemType workItem, + @Nullable WorkItemOperationInfo operationInfo, @Nullable WorkItemOperationSourceInfo sourceInfo, Task wfTask, OperationResult result); - void onWorkItemCustomEvent(WorkItemType workItem, ObjectReferenceType assignee, - WorkItemNotificationActionType notificationAction, WorkItemEventCauseInformationType cause, Task wfTask, + void onWorkItemCustomEvent(ObjectReferenceType assignee, @NotNull WorkItemType workItem, + @NotNull WorkItemNotificationActionType notificationAction, @Nullable WorkItemEventCauseInformationType cause, Task wfTask, OperationResult result); /** * EXPERIMENTAL */ - void onWorkItemAllocationChangeCurrentActors(WorkItemType workItem, List currentActors, - Duration timeBefore, WorkItemOperationKindType operationKind, ObjectReferenceType initiator, - WorkItemResultType workItemResult, AbstractWorkItemActionType source, - WorkItemEventCauseInformationType reason, - Task task, OperationResult result); + void onWorkItemAllocationChangeCurrentActors(@NotNull WorkItemType workItem, + @NotNull WorkItemAllocationChangeOperationInfo operationInfo, + @Nullable WorkItemOperationSourceInfo sourceInfo, + Duration timeBefore, Task task, OperationResult result); - void onWorkItemAllocationChangeNewActors(WorkItemType workItem, List currentActors, - List newActors, WorkItemOperationKindType operationKind, ObjectReferenceType initiator, - AbstractWorkItemActionType source, - WorkItemEventCauseInformationType reason, - Task task, OperationResult result); + void onWorkItemAllocationChangeNewActors(@NotNull WorkItemType workItem, @NotNull WorkItemAllocationChangeOperationInfo operationInfo, + @Nullable WorkItemOperationSourceInfo sourceInfo, Task task, OperationResult result); } diff --git a/model/workflow-api/src/main/java/com/evolveum/midpoint/wf/api/WorkItemOperationInfo.java b/model/workflow-api/src/main/java/com/evolveum/midpoint/wf/api/WorkItemOperationInfo.java new file mode 100644 index 00000000000..c7c09be1733 --- /dev/null +++ b/model/workflow-api/src/main/java/com/evolveum/midpoint/wf/api/WorkItemOperationInfo.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * 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 com.evolveum.midpoint.wf.api; + +import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemOperationKindType; + +/** + * Primarily used to simplify passing parameters to WorkflowListener. + * + * @author mederly + */ +public class WorkItemOperationInfo { + + private final WorkItemOperationKindType operationKind; + + public WorkItemOperationInfo(WorkItemOperationKindType operationKind) { + this.operationKind = operationKind; + } + + public WorkItemOperationKindType getOperationKind() { + return operationKind; + } +} diff --git a/model/workflow-api/src/main/java/com/evolveum/midpoint/wf/api/WorkItemOperationSourceInfo.java b/model/workflow-api/src/main/java/com/evolveum/midpoint/wf/api/WorkItemOperationSourceInfo.java new file mode 100644 index 00000000000..71989f78d0c --- /dev/null +++ b/model/workflow-api/src/main/java/com/evolveum/midpoint/wf/api/WorkItemOperationSourceInfo.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * 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 com.evolveum.midpoint.wf.api; + +import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractWorkItemActionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemEventCauseInformationType; + +/** + * What caused the operation. + * Primarily used to simplify passing parameters to WorkflowListener. + * + * @author mederly + */ +public class WorkItemOperationSourceInfo { + + private final ObjectReferenceType initiatorRef; + private final WorkItemEventCauseInformationType cause; + private final AbstractWorkItemActionType source; + + public WorkItemOperationSourceInfo(ObjectReferenceType initiatorRef, + WorkItemEventCauseInformationType cause, + AbstractWorkItemActionType source) { + this.initiatorRef = initiatorRef; + this.cause = cause; + this.source = source; + } + + public ObjectReferenceType getInitiatorRef() { + return initiatorRef; + } + + public WorkItemEventCauseInformationType getCause() { + return cause; + } + + public AbstractWorkItemActionType getSource() { + return source; + } +} diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemManager.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemManager.java index 18de496ef4f..87c7c363a49 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemManager.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemManager.java @@ -16,7 +16,6 @@ package com.evolveum.midpoint.wf.impl.activiti.dao; -import com.evolveum.midpoint.model.common.SystemObjectCache; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.util.CloneUtil; @@ -36,6 +35,8 @@ import com.evolveum.midpoint.util.exception.SystemException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.wf.api.WorkItemAllocationChangeOperationInfo; +import com.evolveum.midpoint.wf.api.WorkItemOperationSourceInfo; import com.evolveum.midpoint.wf.api.WorkflowManager; import com.evolveum.midpoint.wf.impl.activiti.ActivitiEngine; import com.evolveum.midpoint.wf.impl.processes.common.ActivitiUtil; @@ -79,7 +80,6 @@ public class WorkItemManager { @Autowired private ActivitiEngine activitiEngine; @Autowired private MiscDataUtil miscDataUtil; @Autowired private SecurityEnforcer securityEnforcer; - @Autowired private SystemObjectCache systemObjectCache; @Autowired private PrismContext prismContext; @Autowired private WorkItemProvider workItemProvider; @Autowired private WfTaskController wfTaskController; @@ -123,7 +123,9 @@ public void completeWorkItem(String workItemId, String decision, String comment, propertiesToSubmit.put(CommonProcessVariableNames.FORM_FIELD_DECISION, decision); propertiesToSubmit.put(CommonProcessVariableNames.FORM_FIELD_COMMENT, comment); if (additionalDelta != null) { - ObjectDeltaType objectDeltaType = DeltaConvertor.toObjectDeltaType(additionalDelta); + @SuppressWarnings({ "unchecked", "raw" }) + ObjectDelta additionalDeltaCasted = ((ObjectDelta) additionalDelta); + ObjectDeltaType objectDeltaType = DeltaConvertor.toObjectDeltaType(additionalDeltaCasted); String xmlDelta = prismContext.xmlSerializer() .serializeRealValue(objectDeltaType, SchemaConstants.T_OBJECT_DELTA); propertiesToSubmit.put(CommonProcessVariableNames.FORM_FIELD_ADDITIONAL_DELTA, xmlDelta); @@ -256,8 +258,10 @@ public void delegateWorkItem(String workItemId, List delega WorkItemOperationKindType operationKind = escalate ? ESCALATE : DELEGATE; com.evolveum.midpoint.task.api.Task wfTask = taskManager.getTask(workItem.getTaskRef().getOid(), result); - wfTaskController.notifyWorkItemAllocationChangeCurrentActors(workItem, assigneesBefore, null, operationKind, - initiator, null, null, causeInformation, wfTask, result); + WorkItemAllocationChangeOperationInfo operationInfoBefore = + new WorkItemAllocationChangeOperationInfo(operationKind, assigneesBefore, null); + WorkItemOperationSourceInfo sourceInfo = new WorkItemOperationSourceInfo(initiator, causeInformation, null); + wfTaskController.notifyWorkItemAllocationChangeCurrentActors(workItem, operationInfoBefore, sourceInfo, null, wfTask, result); List newAssignees; if (method == null) { @@ -322,8 +326,9 @@ public void delegateWorkItem(String workItemId, List delega WorkItemType workItemAfter = workItemProvider.getWorkItem(workItemId, result); com.evolveum.midpoint.task.api.Task wfTaskAfter = taskManager.getTask(wfTask.getOid(), result); - wfTaskController.notifyWorkItemAllocationChangeNewActors(workItemAfter, assigneesBefore, - workItemAfter.getAssigneeRef(), operationKind, initiator, null, causeInformation, wfTaskAfter, result); + WorkItemAllocationChangeOperationInfo operationInfoAfter = + new WorkItemAllocationChangeOperationInfo(operationKind, assigneesBefore, workItemAfter.getAssigneeRef()); + wfTaskController.notifyWorkItemAllocationChangeNewActors(workItemAfter, operationInfoAfter, sourceInfo, wfTaskAfter, result); } catch (SecurityViolationException|RuntimeException|ObjectNotFoundException|SchemaException e) { result.recordFatalError("Couldn't delegate/escalate work item " + workItemId + ": " + e.getMessage(), e); throw e; diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/common/WfTimedActionTriggerHandler.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/common/WfTimedActionTriggerHandler.java index c2b14fb4f1e..340e4a714ef 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/common/WfTimedActionTriggerHandler.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/common/WfTimedActionTriggerHandler.java @@ -29,6 +29,8 @@ import com.evolveum.midpoint.util.exception.*; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.wf.api.WorkItemAllocationChangeOperationInfo; +import com.evolveum.midpoint.wf.api.WorkItemOperationSourceInfo; import com.evolveum.midpoint.wf.api.WorkflowConstants; import com.evolveum.midpoint.wf.impl.activiti.dao.WorkItemManager; import com.evolveum.midpoint.wf.impl.activiti.dao.WorkItemProvider; @@ -134,8 +136,10 @@ private void executeNotifications(Duration timeBeforeAction, AbstractWorkItemAct cause.setName(action.getName()); cause.setDisplayName(action.getDisplayName()); } - wfTaskController.notifyWorkItemAllocationChangeCurrentActors(workItem, workItem.getAssigneeRef(), timeBeforeAction, - operationKind, null, null, action, cause, wfTask, result); + WorkItemAllocationChangeOperationInfo operationInfo = + new WorkItemAllocationChangeOperationInfo(operationKind, workItem.getAssigneeRef(), null); + WorkItemOperationSourceInfo sourceInfo = new WorkItemOperationSourceInfo(null, cause, action); + wfTaskController.notifyWorkItemAllocationChangeCurrentActors(workItem, operationInfo, sourceInfo, timeBeforeAction, wfTask, result); } private void executeActions(WorkItemActionsType actions, WorkItemType workItem, Task wfTask, Task triggerScannerTask, @@ -205,10 +209,10 @@ private void executeNotificationAction(WorkItemType workItem, @NotNull WorkItemN WorkItemEventCauseInformationType cause = createCauseInformation(notificationAction); if (BooleanUtils.isNotFalse(notificationAction.isPerAssignee())) { for (ObjectReferenceType assignee : workItem.getAssigneeRef()) { - wfTaskController.notifyWorkItemCustom(workItem, assignee, cause, wfTask, notificationAction, result); + wfTaskController.notifyWorkItemCustom(assignee, workItem, cause, wfTask, notificationAction, result); } } else { - wfTaskController.notifyWorkItemCustom(workItem, null, cause, wfTask, notificationAction, result); + wfTaskController.notifyWorkItemCustom(null, workItem, cause, wfTask, notificationAction, result); } } diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseAuditHelper.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseAuditHelper.java index 443137b9d65..ddf601ce5d1 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseAuditHelper.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseAuditHelper.java @@ -36,7 +36,6 @@ import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.wf.api.WorkflowConstants; import com.evolveum.midpoint.wf.api.WorkflowException; -import com.evolveum.midpoint.wf.impl.messages.TaskEvent; import com.evolveum.midpoint.wf.impl.tasks.WfTask; import com.evolveum.midpoint.wf.util.ApprovalUtils; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; @@ -165,9 +164,8 @@ public AuditEventRecord prepareWorkItemCreatedAuditRecord(WorkItemType workItem, } // workItem contains taskRef, assignee, candidates resolved (if possible) - public AuditEventRecord prepareWorkItemDeletedAuditRecord(WorkItemType workItem, TaskEvent taskEvent, - WorkItemEventCauseInformationType cause, WorkItemResultType workItemResult, WfTask wfTask, - OperationResult result) throws WorkflowException { + public AuditEventRecord prepareWorkItemDeletedAuditRecord(WorkItemType workItem, WorkItemEventCauseInformationType cause, + WfTask wfTask, OperationResult result) throws WorkflowException { AuditEventRecord record = prepareWorkItemAuditReportCommon(workItem, wfTask, AuditEventStage.EXECUTION, result); setCurrentUserAsInitiator(record); @@ -190,6 +188,7 @@ public AuditEventRecord prepareWorkItemDeletedAuditRecord(WorkItemType workItem, if (stageInfo != null) { message.append(stageInfo).append(" : "); } + WorkItemResultType workItemResult = workItem.getResult(); if (workItemResult != null) { String answer = ApprovalUtils.makeNice(workItemResult.getOutcomeAsString()); record.setResult(answer); diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/ChangeProcessor.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/ChangeProcessor.java index f9c522a804b..76d34e4180e 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/ChangeProcessor.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/ChangeProcessor.java @@ -33,7 +33,6 @@ import com.evolveum.midpoint.wf.impl.util.MiscDataUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.WfConfigurationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemEventCauseInformationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemResultType; import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemType; import org.jetbrains.annotations.NotNull; @@ -108,12 +107,11 @@ public interface ChangeProcessor { * Prepares a work item-related audit record. */ // workItem contains taskRef, assignee, candidates resolved (if possible) - AuditEventRecord prepareWorkItemCreatedAuditRecord(WorkItemType workItem, TaskEvent taskEvent, WfTask wfTask, - OperationResult result) throws WorkflowException; + AuditEventRecord prepareWorkItemCreatedAuditRecord(WorkItemType workItem, + TaskEvent taskEvent, WfTask wfTask, OperationResult result) throws WorkflowException; AuditEventRecord prepareWorkItemDeletedAuditRecord(WorkItemType workItem, WorkItemEventCauseInformationType cause, - WorkItemResultType workItemResult, TaskEvent taskEvent, WfTask wfTask, - OperationResult result) throws WorkflowException; + TaskEvent taskEvent, WfTask wfTask, OperationResult result) throws WorkflowException; /** * Auxiliary method to access autowired Spring beans from within non-spring java objects. diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/GeneralChangeProcessor.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/GeneralChangeProcessor.java index 782909bf84e..415358f9d20 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/GeneralChangeProcessor.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/GeneralChangeProcessor.java @@ -206,10 +206,10 @@ public AuditEventRecord prepareWorkItemCreatedAuditRecord(WorkItemType workItem, @Override public AuditEventRecord prepareWorkItemDeletedAuditRecord(WorkItemType workItem, WorkItemEventCauseInformationType cause, - WorkItemResultType workItemResult, TaskEvent taskEvent, WfTask wfTask, + TaskEvent taskEvent, WfTask wfTask, OperationResult result) throws WorkflowException { return getScenarioBean(taskEvent.getVariables()) - .prepareWorkItemDeletedAuditRecord(workItem, taskEvent, cause, workItemResult, wfTask, result); + .prepareWorkItemDeletedAuditRecord(workItem, cause, taskEvent, wfTask, result); } //endregion } diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/scenarios/BaseGcpScenarioBean.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/scenarios/BaseGcpScenarioBean.java index 0209409f823..4a61d69f12b 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/scenarios/BaseGcpScenarioBean.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/scenarios/BaseGcpScenarioBean.java @@ -34,7 +34,6 @@ import com.evolveum.midpoint.wf.impl.processors.general.GeneralChangeProcessorSpecificContent; import com.evolveum.midpoint.xml.ns._public.common.common_3.GeneralChangeProcessorScenarioType; import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemEventCauseInformationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemResultType; import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -100,10 +99,9 @@ public AuditEventRecord prepareWorkItemCreatedAuditRecord(WorkItemType workItem, } @Override - public AuditEventRecord prepareWorkItemDeletedAuditRecord(WorkItemType workItem, TaskEvent taskEvent, - WorkItemEventCauseInformationType cause, WorkItemResultType workItemResult, WfTask wfTask, - OperationResult result) throws WorkflowException { - return baseAuditHelper.prepareWorkItemDeletedAuditRecord(workItem, taskEvent, cause, workItemResult, wfTask, result); + public AuditEventRecord prepareWorkItemDeletedAuditRecord(WorkItemType workItem, WorkItemEventCauseInformationType cause, + TaskEvent taskEvent, WfTask wfTask, OperationResult result) throws WorkflowException { + return baseAuditHelper.prepareWorkItemDeletedAuditRecord(workItem, cause, wfTask, result); // TODO fill-in missing delta somehow } diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/scenarios/GcpScenarioBean.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/scenarios/GcpScenarioBean.java index 901b0274eab..2014dd0ecc6 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/scenarios/GcpScenarioBean.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/general/scenarios/GcpScenarioBean.java @@ -29,7 +29,6 @@ import com.evolveum.midpoint.wf.impl.messages.TaskEvent; import com.evolveum.midpoint.xml.ns._public.common.common_3.GeneralChangeProcessorScenarioType; import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemEventCauseInformationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemResultType; import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemType; import java.util.Map; @@ -55,9 +54,8 @@ public interface GcpScenarioBean { AuditEventRecord prepareWorkItemCreatedAuditRecord(WorkItemType workItem, WfTask wfTask, TaskEvent taskEvent, OperationResult result) throws WorkflowException; - AuditEventRecord prepareWorkItemDeletedAuditRecord(WorkItemType workItem, TaskEvent taskEvent, - WorkItemEventCauseInformationType cause, WorkItemResultType workItemResult, WfTask wfTask, - OperationResult result) throws WorkflowException; + AuditEventRecord prepareWorkItemDeletedAuditRecord(WorkItemType workItem, WorkItemEventCauseInformationType cause, + TaskEvent taskEvent, WfTask wfTask, OperationResult result) throws WorkflowException; WfTaskCreationInstruction prepareJobCreationInstruction(GeneralChangeProcessorScenarioType scenarioType, LensContext context, WfTask rootWfTask, Task taskFromModel, OperationResult result) throws SchemaException; } diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PrimaryChangeProcessor.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PrimaryChangeProcessor.java index 2712d7b101d..f4e08532d8c 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PrimaryChangeProcessor.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PrimaryChangeProcessor.java @@ -376,11 +376,11 @@ public AuditEventRecord prepareWorkItemCreatedAuditRecord(WorkItemType workItem, @Override public AuditEventRecord prepareWorkItemDeletedAuditRecord(WorkItemType workItem, WorkItemEventCauseInformationType cause, - WorkItemResultType workItemResult, TaskEvent taskEvent, WfTask wfTask, - OperationResult result) throws WorkflowException { - AuditEventRecord auditEventRecord = baseAuditHelper.prepareWorkItemDeletedAuditRecord(workItem, taskEvent, - cause, workItemResult, wfTask, result); + TaskEvent taskEvent, WfTask wfTask, OperationResult result) throws WorkflowException { + AuditEventRecord auditEventRecord = baseAuditHelper.prepareWorkItemDeletedAuditRecord(workItem, cause, + wfTask, result); try { + WorkItemResultType workItemResult = workItem.getResult(); // TODO - or merge with original deltas? if (workItemResult != null && workItemResult.getOutcome() == WorkItemOutcomeType.APPROVE && workItemResult.getAdditionalDeltas() != null) { diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskController.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskController.java index f3fa0f053b7..eb21bbd307e 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskController.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskController.java @@ -33,9 +33,7 @@ import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.wf.api.ProcessListener; -import com.evolveum.midpoint.wf.api.WorkItemListener; -import com.evolveum.midpoint.wf.api.WorkflowException; +import com.evolveum.midpoint.wf.api.*; import com.evolveum.midpoint.wf.impl.WfConfiguration; import com.evolveum.midpoint.wf.impl.activiti.ActivitiInterface; import com.evolveum.midpoint.wf.impl.messages.*; @@ -63,7 +61,6 @@ import java.util.*; import static com.evolveum.midpoint.task.api.TaskExecutionStatus.WAITING; -import static com.evolveum.midpoint.wf.impl.processes.common.SpringApplicationContextHolder.getItemApprovalProcessInterface; /** * Manages everything related to a activiti process instance, including the task that monitors that process instance. @@ -309,6 +306,7 @@ private ChangeProcessor getChangeProcessor(TaskEvent taskEvent) { //region Processing work item (task) events // workItem contains taskRef, assignee, candidates resolved (if possible) + // workItem can be freely modified (e.g. by overriding result, etc.) @SuppressWarnings("unchecked") public void onTaskEvent(WorkItemType workItem, TaskEvent taskEvent, OperationResult result) throws WorkflowException, SchemaException { @@ -326,10 +324,11 @@ public void onTaskEvent(WorkItemType workItem, TaskEvent taskEvent, OperationRes taskEvent, wfTask, result); auditService.audit(auditEventRecord, wfTask.getTask()); try { - notifyWorkItemCreated(workItem, workItem.getOriginalAssigneeRef(), wfTask, result); + notifyWorkItemCreated(workItem.getOriginalAssigneeRef(), workItem, wfTask, result); if (workItem.getAssigneeRef() != null) { - notifyWorkItemAllocationChangeNewActors(workItem, Collections.emptyList(), workItem.getAssigneeRef(), - null, null, null, null, wfTask.getTask(), result); + WorkItemAllocationChangeOperationInfo operationInfo = + new WorkItemAllocationChangeOperationInfo(null, Collections.emptyList(), workItem.getAssigneeRef()); + notifyWorkItemAllocationChangeNewActors(workItem, operationInfo, null, wfTask.getTask(), result); } } catch (SchemaException e) { LoggingUtils.logUnexpectedException(LOGGER, "Couldn't send notification about work item create event", e); @@ -346,14 +345,12 @@ public void onTaskEvent(WorkItemType workItem, TaskEvent taskEvent, OperationRes // would be closed for the same reason. For a user it would be misleading if we would simply view this task // as 'cancelled', while, in fact, it is e.g. approved/rejected because of a timed action. - LOGGER.error("###### processing {}", taskEvent, new IllegalStateException()); WorkItemOperationKindType operationKind = BooleanUtils.isTrue(ActivitiUtil.getVariable(taskEvent.getVariables(), CommonProcessVariableNames.VARIABLE_WORK_ITEM_WAS_COMPLETED, Boolean.class, prismContext)) ? - WorkItemOperationKindType.COMPLETE : null; + WorkItemOperationKindType.COMPLETE : WorkItemOperationKindType.CANCEL; WorkItemEventCauseInformationType cause = ActivitiUtil.getVariable(taskEvent.getVariables(), CommonProcessVariableNames.VARIABLE_CAUSE, WorkItemEventCauseInformationType.class, prismContext); - WorkItemResultType workItemResult = getItemApprovalProcessInterface().extractWorkItemResult(taskEvent.getVariables()); - boolean genuinelyCompleted = operationKind != null; + boolean genuinelyCompleted = operationKind == WorkItemOperationKindType.COMPLETE; MidPointPrincipal user; try { @@ -394,9 +391,10 @@ public void onTaskEvent(WorkItemType workItem, TaskEvent taskEvent, OperationRes cause.setName(completeAction.getName()); cause.setDisplayName(completeAction.getDisplayName()); foundTimedActions++; - workItemResult = new WorkItemResultType(); + WorkItemResultType workItemResult = new WorkItemResultType(); workItemResult.setOutcome(completeAction.getOutcome() != null ? completeAction.getOutcome() : WorkItemOutcomeType.REJECT); workItemResult.setOutcomeAsString(ApprovalUtils.approvalStringValue(completeAction.getOutcome())); + workItem.setResult(workItemResult); } if (foundTimedActions > 1) { LOGGER.warn("Multiple 'work item complete' timed actions ({}) for {}: {}", foundTimedActions, @@ -404,27 +402,29 @@ public void onTaskEvent(WorkItemType workItem, TaskEvent taskEvent, OperationRes } } - AuditEventRecord auditEventRecord = getChangeProcessor(taskEvent).prepareWorkItemDeletedAuditRecord(workItem, - cause, workItemResult, taskEvent, wfTask, result); + // We don't pass userRef (initiator) to the audit method. It does need the whole object (not only the reference), + // so it fetches it directly from the security enforcer (logged-in user). This could change in the future. + AuditEventRecord auditEventRecord = getChangeProcessor(taskEvent) + .prepareWorkItemDeletedAuditRecord(workItem, cause, taskEvent, wfTask, result); auditService.audit(auditEventRecord, wfTask.getTask()); try { + WorkItemAllocationChangeOperationInfo operationInfo = + new WorkItemAllocationChangeOperationInfo(operationKind, workItem.getAssigneeRef(), null); + WorkItemOperationSourceInfo sourceInfo = new WorkItemOperationSourceInfo(userRef, cause, null); if (workItem.getAssigneeRef().isEmpty()) { - notifyWorkItemDeleted(workItem, null, userRef, operationKind, workItemResult, - null, cause, wfTask, result); + notifyWorkItemDeleted(null, workItem, operationInfo, sourceInfo, wfTask, result); } else { for (ObjectReferenceType assignee : workItem.getAssigneeRef()) { - notifyWorkItemDeleted(workItem, assignee, userRef, operationKind, workItemResult, - null, cause, wfTask, result); + notifyWorkItemDeleted(assignee, workItem, operationInfo, sourceInfo, wfTask, result); } } - notifyWorkItemAllocationChangeCurrentActors(workItem, workItem.getAssigneeRef(), - null, operationKind, userRef, workItemResult,null, cause, - wfTask.getTask(), result); + notifyWorkItemAllocationChangeCurrentActors(workItem, operationInfo, sourceInfo, null, wfTask.getTask(), result); } catch (SchemaException e) { LoggingUtils.logUnexpectedException(LOGGER, "Couldn't audit work item complete event", e); } - if (genuinelyCompleted || workItemResult != null) { + WorkItemResultType workItemResult = workItem.getResult(); + if (genuinelyCompleted || workItemResult != null) { WorkItemCompletionEventType event = new WorkItemCompletionEventType(); ActivitiUtil.fillInWorkItemEvent(event, user, taskEvent.getTaskId(), taskEvent.getVariables(), prismContext); event.setCause(cause); @@ -465,52 +465,45 @@ private void notifyProcessEnd(WfTask wfTask, OperationResult result) throws Sche } } - private void notifyWorkItemCreated(WorkItemType workItem, ObjectReferenceType originalAssigneeRef, WfTask wfTask, - OperationResult result) throws SchemaException { + private void notifyWorkItemCreated(ObjectReferenceType originalAssigneeRef, WorkItemType workItem, + WfTask wfTask, OperationResult result) throws SchemaException { for (WorkItemListener workItemListener : workItemListeners) { - workItemListener.onWorkItemCreation(workItem, originalAssigneeRef, wfTask.getTask(), result); + workItemListener.onWorkItemCreation(originalAssigneeRef, workItem, wfTask.getTask(), result); } } - private void notifyWorkItemDeleted(WorkItemType workItem, ObjectReferenceType assignee, - ObjectReferenceType initiator, WorkItemOperationKindType operationKind, - WorkItemResultType workItemResult, @Nullable AbstractWorkItemActionType source, - @Nullable WorkItemEventCauseInformationType cause, + private void notifyWorkItemDeleted(ObjectReferenceType assignee, WorkItemType workItem, + WorkItemOperationInfo operationInfo, WorkItemOperationSourceInfo sourceInfo, WfTask wfTask, OperationResult result) throws SchemaException { for (WorkItemListener workItemListener : workItemListeners) { - workItemListener.onWorkItemDeletion(workItem, assignee, initiator, operationKind, workItemResult, source, cause, wfTask.getTask(), result); + workItemListener.onWorkItemDeletion(assignee, workItem, operationInfo, sourceInfo, wfTask.getTask(), result); } } public void notifyWorkItemAllocationChangeCurrentActors(WorkItemType workItem, - @NotNull List originalActors, - Duration timeBefore, WorkItemOperationKindType operationKind, ObjectReferenceType initiator, - WorkItemResultType workItemResult, @Nullable AbstractWorkItemActionType source, - @Nullable WorkItemEventCauseInformationType cause, + @NotNull WorkItemAllocationChangeOperationInfo operationInfo, + WorkItemOperationSourceInfo sourceInfo, Duration timeBefore, Task wfTask, OperationResult result) throws SchemaException { for (WorkItemListener workItemListener : workItemListeners) { - workItemListener.onWorkItemAllocationChangeCurrentActors(workItem, originalActors, timeBefore, operationKind, - initiator, workItemResult, source, cause, wfTask, result); + workItemListener.onWorkItemAllocationChangeCurrentActors(workItem, operationInfo, sourceInfo, timeBefore, wfTask, result); } } - public void notifyWorkItemAllocationChangeNewActors(WorkItemType workItem, @NotNull List originalActors, - @NotNull List newActors, WorkItemOperationKindType operationKind, - ObjectReferenceType initiator, @Nullable AbstractWorkItemActionType source, - @Nullable WorkItemEventCauseInformationType cause, + public void notifyWorkItemAllocationChangeNewActors(WorkItemType workItem, + @NotNull WorkItemAllocationChangeOperationInfo operationInfo, + @Nullable WorkItemOperationSourceInfo sourceInfo, Task wfTask, OperationResult result) throws SchemaException { for (WorkItemListener workItemListener : workItemListeners) { - workItemListener.onWorkItemAllocationChangeNewActors(workItem, originalActors, newActors, operationKind, - initiator, source, cause, wfTask, result); + workItemListener.onWorkItemAllocationChangeNewActors(workItem, operationInfo, sourceInfo, wfTask, result); } } - public void notifyWorkItemCustom(WorkItemType workItem, @Nullable ObjectReferenceType assignee, + public void notifyWorkItemCustom(@Nullable ObjectReferenceType assignee, WorkItemType workItem, WorkItemEventCauseInformationType cause, Task wfTask, @NotNull WorkItemNotificationActionType notificationAction, OperationResult result) throws SchemaException { for (WorkItemListener workItemListener : workItemListeners) { - workItemListener.onWorkItemCustomEvent(workItem, assignee, notificationAction, cause, wfTask, result); + workItemListener.onWorkItemCustomEvent(assignee, workItem, notificationAction, cause, wfTask, result); } } diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestEscalation.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestEscalation.java index 57aaba8db28..5464398373d 100644 --- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestEscalation.java +++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestEscalation.java @@ -320,7 +320,7 @@ public void test220Reject() throws Exception { List notifications = dummyTransport.getMessages("dummy:simpleWorkflowNotifier-WorkItems"); displayCollection("notifications - work items", notifications); for (Message notification : notifications) { - assertContains(notification, "Carried out by: midPoint Administrator (administrator) (timed action 'Automatic rejection at deadline')"); + assertContains(notification, "Reason: Automatic rejection at deadline (timed action)"); assertContains(notification, "Result: REJECTED"); } } diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestStrings.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestStrings.java index 8d86262eb67..f633a519d77 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestStrings.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestStrings.java @@ -393,7 +393,7 @@ public void test104SimpleAssignmentApproveByAdministrator() throws Exception { "Carried out by: midPoint Administrator (administrator)", "Result: APPROVED", "^Deadline:"); assertMessage(sorted.get("barkeeper@evolveum.com"), "barkeeper@evolveum.com", "Work item has been cancelled", "Work item: Approve assigning a-test-1 to bob", "Stage: Security (2/3)", - "Allocated to: Horridly Scarred Barkeep (barkeeper)", "^Result:", "^Deadline:"); + "Allocated to: Horridly Scarred Barkeep (barkeeper)", "^Result:", "^Deadline:", "^Carried out by:"); assertMessage(sorted.get("cheese@evolveum.com"), "cheese@evolveum.com", "A new work item has been created", "Work item: Approve assigning a-test-1 to bob", "Role approvers (all) (3/3)", "Allocated to: Ignatius Cheese (cheese)", "^Result:", "(in 5 days)"); @@ -407,7 +407,7 @@ public void test104SimpleAssignmentApproveByAdministrator() throws Exception { "Carried out by: midPoint Administrator (administrator)", "Result: APPROVED", "^Deadline:"); assertMessage(sorted2.get("barkeeper@evolveum.com"), "barkeeper@evolveum.com", "Work item has been cancelled", "Work item: Approve assigning a-test-1 to bob", "Stage: Security (2/3)", - "Allocated to: Horridly Scarred Barkeep (barkeeper)", "^Result:", "^Deadline:"); + "Allocated to: Horridly Scarred Barkeep (barkeeper)", "^Result:", "^Deadline:", "^Carried out by:"); assertMessage(sorted2.get("cheese@evolveum.com"), "cheese@evolveum.com", "Work item has been allocated to you", "Work item: Approve assigning a-test-1 to bob", "Role approvers (all) (3/3)", "Allocated to: Ignatius Cheese (cheese)", "^Result:", "(in 5 days)"); @@ -924,29 +924,6 @@ public void test209EightDaysLater() throws Exception { display("audit", dummyAuditService); } - private void checkOneCompletedOneCancelled(List lifecycleMessages) { - Map sorted = sortByRecipientsSingle(lifecycleMessages); - - assertMessage(sorted.get("elaine@evolveum.com"), "elaine@evolveum.com", - null, - "Security (2/3)", "Allocated to: Elaine Marley (elaine)"); - assertMessage(sorted.get("barkeeper@evolveum.com"), "barkeeper@evolveum.com", - null, - "Security (2/3)", "Allocated to: Horridly Scarred Barkeep (barkeeper)"); - int completed; - if (lifecycleMessages.get(0).getSubject().contains("completed")) { - completed = 0; - } else { - completed = 1; - } - assertMessage(lifecycleMessages.get(completed), null, "Work item has been completed", - "Carried out by: midPoint Administrator (administrator)", // TODO remove later - "Result: REJECTED"); - assertMessage(lifecycleMessages.get(1-completed), null, "Work item has been cancelled", - "^Carried out by:", - "^Result:"); - } - private void checkTwoCompleted(List lifecycleMessages) { Map sorted = sortByRecipientsSingle(lifecycleMessages); @@ -958,9 +935,12 @@ private void checkTwoCompleted(List lifecycleMessages) { "Security (2/3)", "Allocated to: Horridly Scarred Barkeep (barkeeper)"); int completed; assertMessage(lifecycleMessages.get(0), null, "Work item has been completed", - "Carried out by: midPoint Administrator (administrator)", // TODO remove later + "^Carried out by:", + "Reason: Timed action", "Result: REJECTED"); assertMessage(lifecycleMessages.get(1), null, "Work item has been completed", + "^Carried out by:", + "Reason: Timed action", "Result: REJECTED"); }