Skip to content

Commit

Permalink
work item complete event merged to work item delegate event
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Feb 8, 2017
1 parent 18761c3 commit 521e65a
Show file tree
Hide file tree
Showing 14 changed files with 96 additions and 83 deletions.
Expand Up @@ -1958,7 +1958,7 @@
<xsd:element name="result" type="tns:WorkItemResultType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Result of this work item.
Result of this work item (null if it was not completed).
</xsd:documentation>
<xsd:appinfo>
<a:since>3.6</a:since>
Expand Down
Expand Up @@ -18,6 +18,7 @@

import com.evolveum.midpoint.notifications.api.NotificationManager;
import com.evolveum.midpoint.notifications.api.events.WorkItemEvent;
import com.evolveum.midpoint.notifications.api.events.WorkItemLifecycleEvent;
import com.evolveum.midpoint.notifications.api.events.WorkflowEvent;
import com.evolveum.midpoint.notifications.api.events.WorkflowProcessEvent;
import com.evolveum.midpoint.prism.delta.ChangeType;
Expand All @@ -33,6 +34,7 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.WfContextType;
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.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

Expand All @@ -41,6 +43,8 @@
/**
* Listener that accepts events generated by workflow module. These events are related to processes and work items.
*
* TODO what about tasks? Should the task (wfTask) be passed to the notification module?
*
* @author mederly
*/
@Component
Expand Down Expand Up @@ -69,6 +73,7 @@ public void init() {
}
}

//region Process-level notifications
@Override
public void onProcessInstanceStart(Task wfTask, OperationResult result) {
WorkflowProcessEvent event = new WorkflowProcessEvent(identifierGenerator, ChangeType.ADD, wfTask);
Expand All @@ -82,36 +87,31 @@ public void onProcessInstanceEnd(Task wfTask, OperationResult result) {
initializeWorkflowEvent(event, wfTask);
processEvent(event, result);
}
//endregion

private void initializeWorkflowEvent(WorkflowEvent event, Task wfTask) {
WfContextType wfc = wfTask.getWorkflowContext();
event.setRequester(new SimpleObjectRefImpl(functions, wfc.getRequesterRef()));
if (wfc.getObjectRef() != null) {
event.setRequestee(new SimpleObjectRefImpl(functions, wfc.getObjectRef()));
}
// TODO what if requestee is yet to be created?
}



//region WorkItem-level notifications
@Override
public void onWorkItemCreation(WorkItemType workItem, Task wfTask, OperationResult result) {
SimpleObjectRefImpl assignee = workItem.getOriginalAssigneeRef() != null ?
new SimpleObjectRefImpl(functions, workItem.getOriginalAssigneeRef()) : null;
WorkItemEvent event = new WorkItemEvent(identifierGenerator, ChangeType.ADD, workItem, assignee, wfTask.getWorkflowContext());
SimpleObjectRefImpl assignee = getAssignee(workItem);
WorkItemEvent event = new WorkItemLifecycleEvent(identifierGenerator, ChangeType.ADD, workItem, assignee, wfTask.getWorkflowContext());
initializeWorkflowEvent(event, wfTask);
processEvent(event, result);
}

@Override
public void onWorkItemCompletion(WorkItemType workItem, Task wfTask, OperationResult result) {
SimpleObjectRefImpl assignee = workItem.getOriginalAssigneeRef() != null ?
new SimpleObjectRefImpl(functions, workItem.getOriginalAssigneeRef()) : null;
WorkItemEvent event = new WorkItemEvent(identifierGenerator, ChangeType.DELETE, workItem, assignee, wfTask.getWorkflowContext());
public void onWorkItemDeletion(WorkItemType workItem, Task wfTask, OperationResult result) {
SimpleObjectRefImpl assignee = getAssignee(workItem);
WorkItemEvent event = new WorkItemLifecycleEvent(identifierGenerator, ChangeType.DELETE, workItem, assignee, wfTask.getWorkflowContext());
initializeWorkflowEvent(event, wfTask);
processEvent(event, result);
}

@Nullable
private SimpleObjectRefImpl getAssignee(WorkItemType workItem) {
return workItem.getOriginalAssigneeRef() != null ?
new SimpleObjectRefImpl(functions, workItem.getOriginalAssigneeRef()) : null;
}

@Override
public void onWorkItemNotificationAction(WorkItemType workItem, WorkItemNotificationActionType notificationAction,
Task wfTask, OperationResult result) {
Expand All @@ -120,6 +120,7 @@ public void onWorkItemNotificationAction(WorkItemType workItem, WorkItemNotifica
// processEvent(event);
throw new UnsupportedOperationException();
}
//endregion

private void processEvent(WorkflowEvent event, OperationResult result) {
try {
Expand All @@ -143,4 +144,14 @@ private void processEvent(WorkflowEvent event) {
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(new SimpleObjectRefImpl(functions, wfc.getRequesterRef()));
if (wfc.getObjectRef() != null) {
event.setRequestee(new SimpleObjectRefImpl(functions, wfc.getObjectRef()));
}
// TODO what if requestee is yet to be created?
}

}
Expand Up @@ -48,7 +48,7 @@ public interface WorkItemListener {
*
* @param workItem the work item
*/
void onWorkItemCompletion(WorkItemType workItem, Task wfTask, OperationResult result);
void onWorkItemDeletion(WorkItemType workItem, Task wfTask, OperationResult result);

/**
* EXPERIMENTAL
Expand Down
Expand Up @@ -28,17 +28,9 @@
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.wf.impl.activiti.dao.WorkItemProvider;
import com.evolveum.midpoint.wf.impl.messages.*;
import com.evolveum.midpoint.wf.impl.processes.common.ActivitiUtil;
import com.evolveum.midpoint.wf.impl.tasks.WfTaskController;
import com.evolveum.midpoint.wf.impl.messages.ProcessEvent;
import com.evolveum.midpoint.wf.impl.messages.ProcessFinishedEvent;
import com.evolveum.midpoint.wf.impl.messages.ProcessStartedEvent;
import com.evolveum.midpoint.wf.impl.messages.QueryProcessCommand;
import com.evolveum.midpoint.wf.impl.messages.QueryProcessResponse;
import com.evolveum.midpoint.wf.impl.messages.StartProcessCommand;
import com.evolveum.midpoint.wf.impl.messages.TaskCompletedEvent;
import com.evolveum.midpoint.wf.impl.messages.TaskCreatedEvent;
import com.evolveum.midpoint.wf.impl.messages.TaskEvent;
import com.evolveum.midpoint.wf.impl.processes.ProcessInterfaceFinder;
import com.evolveum.midpoint.wf.impl.processes.common.CommonProcessVariableNames;

Expand Down Expand Up @@ -195,9 +187,11 @@ public void notifyMidpointAboutTaskEvent(DelegateTask delegateTask) {

TaskEvent taskEvent;
if (TaskListener.EVENTNAME_CREATE.equals(delegateTask.getEventName())) {
taskEvent = new TaskCreatedEvent();
taskEvent = new TaskCreatedEvent(); // TODO distinguish created vs. assigned event
} else if (TaskListener.EVENTNAME_COMPLETE.equals(delegateTask.getEventName())) {
taskEvent = new TaskCompletedEvent();
} else if (TaskListener.EVENTNAME_DELETE.equals(delegateTask.getEventName())) {
taskEvent = new TaskDeletedEvent();
} else {
return; // ignoring other events
}
Expand Down
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2010-2014 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.impl.messages;

/**
* @author mederly
*/
public class TaskDeletedEvent extends TaskEvent {
}
Expand Up @@ -135,4 +135,8 @@ public class CommonProcessVariableNames {
public static final String VARIABLE_ORIGINAL_ASSIGNEE = "originalAssignee";

public static final String TYPE_NAME_SEPARATOR = ":";

// Whether this work item was completed (instead of simply deleted)
// [Boolean]
public static final String VARIABLE_WORK_ITEM_WAS_COMPLETED = "workItemWasCompleted";
}
Expand Up @@ -28,12 +28,14 @@
import com.evolveum.midpoint.wf.impl.messages.ProcessEvent;
import com.evolveum.midpoint.wf.impl.processes.BaseProcessMidPointInterface;
import com.evolveum.midpoint.wf.impl.processes.common.ActivitiUtil;
import com.evolveum.midpoint.wf.impl.processes.common.CommonProcessVariableNames;
import com.evolveum.midpoint.wf.impl.processors.primary.PcpChildWfTaskCreationInstruction;
import com.evolveum.midpoint.wf.impl.processors.primary.PcpWfTask;
import com.evolveum.midpoint.wf.impl.tasks.WfTaskCreationInstruction;
import com.evolveum.midpoint.wf.util.ApprovalUtils;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

Expand Down Expand Up @@ -72,6 +74,10 @@ public void prepareStartInstruction(WfTaskCreationInstruction instruction) {

@Override
public WorkItemResultType extractWorkItemResult(Map<String, Object> variables) {
Boolean wasCompleted = ActivitiUtil.getVariable(variables, VARIABLE_WORK_ITEM_WAS_COMPLETED, Boolean.class, prismContext);
if (BooleanUtils.isNotTrue(wasCompleted)) {
return null;
}
WorkItemResultType result = new WorkItemResultType();
result.setOutcomeAsString(ActivitiUtil.getVariable(variables, FORM_FIELD_DECISION, String.class, prismContext));
result.setOutcome(ApprovalUtils.approvalOutcomeValue(result.getOutcomeAsString()));
Expand Down
Expand Up @@ -61,8 +61,6 @@ public void notify(DelegateTask delegateTask) {
// System.out.println("%%% Task " + delegateTask + " has been completed.");
// LOGGER.info("%%% Task {} has been completed", delegateTask);

new MidPointTaskListener().notify(delegateTask);

MidPointPrincipal user;
try {
user = SecurityUtil.getPrincipal();
Expand Down Expand Up @@ -98,6 +96,8 @@ public void notify(DelegateTask delegateTask) {
execution.setVariable(
CommonProcessVariableNames.VARIABLE_WF_STATE, "User " + (user!=null?user.getName():null) + " decided to " + (isApproved ? "approve" : "reject") + " the request.");

delegateTask.setVariableLocal(CommonProcessVariableNames.VARIABLE_WORK_ITEM_WAS_COMPLETED, Boolean.TRUE);

if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Approval process instance {} (id {}), level {}: recording decision {}; level stops now: {}",
execution.getVariable(CommonProcessVariableNames.VARIABLE_PROCESS_INSTANCE_NAME),
Expand All @@ -109,6 +109,7 @@ public void notify(DelegateTask delegateTask) {
result.getAdditionalDeltas().getFocusPrimaryDelta() : null;
MidpointUtil.recordEventInTask(event, additionalDelta, wfTask.getOid(), opResult);

getActivitiInterface().notifyMidpointAboutTaskEvent(delegateTask);
getActivitiInterface().notifyMidpointAboutProcessEvent(execution);
}

Expand Down
Expand Up @@ -26,6 +26,8 @@
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;

import static com.evolveum.midpoint.wf.impl.processes.common.SpringApplicationContextHolder.getActivitiInterface;

/**
* @author mederly
*/
Expand Down Expand Up @@ -54,6 +56,6 @@ public void notify(DelegateTask delegateTask) {
delegateTask.setVariableLocal(CommonProcessVariableNames.VARIABLE_ORIGINAL_ASSIGNEE, assignee);
}

new MidPointTaskListener().notify(delegateTask);
getActivitiInterface().notifyMidpointAboutTaskEvent(delegateTask);
}
}
Expand Up @@ -26,6 +26,7 @@
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;

import static com.evolveum.midpoint.wf.impl.processes.common.SpringApplicationContextHolder.getActivitiInterface;
import static com.evolveum.midpoint.wf.impl.processes.common.SpringApplicationContextHolder.getPrismContext;

/**
Expand All @@ -47,25 +48,6 @@ public void notify(DelegateTask delegateTask) {
//ApprovalLevelType level = ActivitiUtil.getAndVerifyCurrentStage(execution, wfTask, true, prismContext);

MidpointUtil.removeTriggersForWorkItem(wfTask, delegateTask.getId(), opResult);

// We could send a "task deleted" notification, if needed.
// In order to do this, task completion listener could create "wasCompleted" task variable (so we could know which
// tasks were completed and which simply deleted - the former ones should not get 'delete' notification twice!).
// And we would call new MidPointTaskListener().notify(delegateTask), and amend it to send a notification for
// deleted non-completed tasks.


// DelegateExecution execution = delegateTask.getExecution();
// PrismContext prismContext = getPrismContext();
// OperationResult opResult = new OperationResult(TaskDeleteListener.class.getName() + ".notify");
// Task wfTask = ActivitiUtil.getTask(execution, opResult);
// //ApprovalLevelType level = ActivitiUtil.getAndVerifyCurrentStage(execution, wfTask, true, prismContext);
//
// System.out.println("%%% Task " + delegateTask + " is being deleted.");
// LOGGER.info("%%% Task {} is being deleted", delegateTask);
//
// System.out.println("%%% Variables: " + delegateTask.getVariables());

getActivitiInterface().notifyMidpointAboutTaskEvent(delegateTask);
}

}
Expand Up @@ -20,7 +20,6 @@
import com.evolveum.midpoint.audit.api.AuditEventStage;
import com.evolveum.midpoint.audit.api.AuditEventType;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.repo.api.RepositoryService;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.result.OperationResultStatus;
import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
Expand All @@ -29,19 +28,16 @@
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.wf.api.WorkflowException;
import com.evolveum.midpoint.wf.impl.activiti.dao.WorkItemProvider;
import com.evolveum.midpoint.wf.impl.tasks.WfTask;
import com.evolveum.midpoint.wf.impl.messages.TaskEvent;
import com.evolveum.midpoint.wf.impl.util.MiscDataUtil;
import com.evolveum.midpoint.wf.util.ApprovalUtils;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import com.evolveum.midpoint.xml.ns._public.common.common_3.GenericObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemResultType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemType;
import com.evolveum.prism.xml.ns._public.types_3.PolyStringType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.util.Map;

import static com.evolveum.midpoint.audit.api.AuditEventStage.EXECUTION;
import static com.evolveum.midpoint.audit.api.AuditEventType.WORKFLOW_PROCESS_INSTANCE;

Expand All @@ -53,20 +49,10 @@ public class BaseAuditHelper {

private static final Trace LOGGER = TraceManager.getTrace(BaseAuditHelper.class);

@Autowired
private MiscDataUtil miscDataUtil;

@Autowired
private WorkItemProvider workItemProvider;

@Autowired
private SecurityEnforcer securityEnforcer;

@Autowired
@Qualifier("cacheRepositoryService")
private RepositoryService repositoryService;

public AuditEventRecord prepareProcessInstanceAuditRecord(WfTask wfTask, AuditEventStage stage, Map<String, Object> variables, OperationResult result) {
public AuditEventRecord prepareProcessInstanceAuditRecord(WfTask wfTask, AuditEventStage stage, OperationResult result) {

AuditEventRecord auditEventRecord = new AuditEventRecord();
auditEventRecord.setEventType(WORKFLOW_PROCESS_INSTANCE);
Expand All @@ -88,16 +74,18 @@ public AuditEventRecord prepareProcessInstanceAuditRecord(WfTask wfTask, AuditEv
}

// workItem contains taskRef, assignee, candidates resolved (if possible)
public AuditEventRecord prepareWorkItemAuditRecord(WorkItemType workItem, WfTask wfTask, TaskEvent taskEvent, AuditEventStage stage,
OperationResult result) throws WorkflowException {
public AuditEventRecord prepareWorkItemAuditRecord(WorkItemType workItem, WfTask wfTask, AuditEventStage stage,
OperationResult result) throws WorkflowException {

AuditEventRecord auditEventRecord = new AuditEventRecord();
auditEventRecord.setEventType(AuditEventType.WORK_ITEM);
auditEventRecord.setEventStage(stage);

if (stage == AuditEventStage.REQUEST) {
auditEventRecord.setInitiator(wfTask.getRequesterIfExists(result));
auditEventRecord.setTargetOwner((PrismObject<UserType>) ObjectTypeUtil.getPrismObjectFromReference(workItem.getOriginalAssigneeRef()));
@SuppressWarnings("unchecked")
PrismObject<UserType> targetOwner = (PrismObject<UserType>) ObjectTypeUtil.getPrismObjectFromReference(workItem.getOriginalAssigneeRef());
auditEventRecord.setTargetOwner(targetOwner);
} else {
try {
@SuppressWarnings("unchecked")
Expand Down
Expand Up @@ -86,14 +86,14 @@ public boolean determineActivation(GeneralChangeProcessorScenarioType scenarioTy

@Override
public AuditEventRecord prepareProcessInstanceAuditRecord(Map<String, Object> variables, WfTask wfTask, AuditEventStage stage, OperationResult result) {
return baseAuditHelper.prepareProcessInstanceAuditRecord(wfTask, stage, variables, result);
return baseAuditHelper.prepareProcessInstanceAuditRecord(wfTask, stage, result);
// TODO what with missing data (delta, result)? We could at least attempt to determine them ...
}

@Override
public AuditEventRecord prepareWorkItemAuditRecord(WorkItemType workItem, WfTask wfTask, TaskEvent taskEvent, AuditEventStage stage,
OperationResult result) throws WorkflowException {
return baseAuditHelper.prepareWorkItemAuditRecord(workItem, wfTask, taskEvent, stage, result);
return baseAuditHelper.prepareWorkItemAuditRecord(workItem, wfTask, stage, result);
// TODO fill-in missing delta somehow
}

Expand Down

0 comments on commit 521e65a

Please sign in to comment.