Skip to content

Commit

Permalink
Primitive escalation implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Feb 2, 2017
1 parent 7e0db86 commit cb2fcde
Show file tree
Hide file tree
Showing 19 changed files with 470 additions and 85 deletions.
Expand Up @@ -520,4 +520,13 @@ public static ObjectType toObjectable(PrismObject object) {
public static boolean containsOid(Collection<ObjectReferenceType> values, @NotNull String oid) {
return values.stream().anyMatch(v -> oid.equals(v.getOid()));
}

@SuppressWarnings("unchecked")
public static <T> T getExtensionItemRealValue(@Nullable ExtensionType extension, @NotNull QName itemName) {
if (extension == null) {
return null;
}
Item item = extension.asPrismContainerValue().findItem(itemName);
return item != null ? (T) item.getRealValue() : null;
}
}
Expand Up @@ -207,6 +207,8 @@
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="name" type="xsd:string" minOccurs="0"/>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
<xsd:element name="time" type="xsd:duration" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Expand Down Expand Up @@ -237,7 +239,7 @@
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="complete" type="tns:WorkItemOutcomeType" minOccurs="0" maxOccurs="1">
<xsd:element name="complete" type="tns:CompleteWorkItemActionType" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
Complete this work item with a given result.
Expand All @@ -246,8 +248,8 @@
</xsd:annotation>
</xsd:element>
<!-- TODO maybe also completeLevel -->
<!-- TODO something like notify -->
<xsd:element name="delegate" type="tns:WorkItemDelegationType" minOccurs="0">
<xsd:element name="notify" type="tns:WorkItemNotificationActionType" minOccurs="0"/>
<xsd:element name="delegate" type="tns:DelegateWorkItemActionType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Delegate (escalate) this work item.
Expand All @@ -257,10 +259,26 @@
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="workItemActions" type="tns:WorkItemActionsType" />
<xsd:element name="workItemId" type="xsd:string" />

<xsd:complexType name="WorkItemDelegationType">
<!-- TODO is this ok? -->
<xsd:element name="workItemActions" type="tns:WorkItemActionsType">
<xsd:annotation>
<xsd:appinfo>
<a:minOccurs>0</a:minOccurs>
<a:maxOccurs>1</a:maxOccurs>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="workItemId" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<a:minOccurs>0</a:minOccurs>
<a:maxOccurs>1</a:maxOccurs>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>

<xsd:complexType name="AbstractWorkItemActionType">
<xsd:annotation>
<xsd:documentation>
TODO
Expand All @@ -272,55 +290,115 @@
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="approverRef" type="c:ObjectReferenceType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Specific approver to replace the current one.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="approverExpression" type="c:ExpressionType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Expression giving an approver to replace the current one.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="approverRelation" type="xsd:QName" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
<p>
What relation(s) to use when determining approvers? E.g. "approver", "owner",
"securityApprover", and so on.
</p>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="outcomeIfNoApprovers" type="c:WorkItemOutcomeType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
What is the outcome (of this work item) if there is no approver to delegate/escalate to?
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="duration" type="xsd:duration" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Duration of the work item after delegation. If not specified, the deadline of the work item
is not changed (this is meaningful only if the delegation occurred before the original deadline).
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!--<xsd:element name="timedActions" type="tns:WorkItemTimedActionsType" minOccurs="0" maxOccurs="unbounded">-->
<!--<xsd:annotation>-->
<xsd:element name="name" type="xsd:string" minOccurs="0"/>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>

<xsd:complexType name="CompleteWorkItemActionType">
<xsd:annotation>
<xsd:documentation>
TODO
EXPERIMENTAL
</xsd:documentation>
<xsd:appinfo>
<a:since>3.6</a:since>
<a:container/>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="tns:AbstractWorkItemActionType">
<xsd:sequence>
<xsd:element name="outcome" type="tns:WorkItemOutcomeType" minOccurs="0" />
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="WorkItemNotificationActionType">
<xsd:annotation>
<xsd:documentation>
TODO
EXPERIMENTAL
</xsd:documentation>
<xsd:appinfo>
<a:since>3.6</a:since>
<a:container/>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="tns:AbstractWorkItemActionType">
<!-- TODO some parameters could come here, like which notification to invoke. -->
<!-- Currently standard WorkItemEvent is produced -->
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="DelegateWorkItemActionType">
<xsd:annotation>
<xsd:documentation>
TODO
EXPERIMENTAL
</xsd:documentation>
<xsd:appinfo>
<a:since>3.6</a:since>
<a:container/>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="tns:AbstractWorkItemActionType">
<xsd:sequence>
<xsd:element name="approverRef" type="c:ObjectReferenceType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Specific approver to replace the current one.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="approverExpression" type="c:ExpressionType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Expression giving an approver to replace the current one.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="approverRelation" type="xsd:QName" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
<p>
What relation(s) to use when determining approvers? E.g. "approver", "owner",
"securityApprover", and so on.
</p>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="outcomeIfNoApprovers" type="c:WorkItemOutcomeType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
What is the outcome (of this work item) if there is no approver to delegate/escalate to?
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="duration" type="xsd:duration" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Duration of the work item after delegation. If not specified, the deadline of the work item
is not changed (this is meaningful only if the delegation occurred before the original deadline).
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!--<xsd:element name="timedActions" type="tns:WorkItemTimedActionsType" minOccurs="0" maxOccurs="unbounded">-->
<!--<xsd:annotation>-->
<!--<xsd:documentation>-->
<!--What actions are to be applied to work items when given timer(s) occur; they are relative-->
<!--to the moment of delegation (positive ones) and to the new deadline (zero or negative ones).-->
<!--EXPERIMENTAL-->
<!--What actions are to be applied to work items when given timer(s) occur; they are relative-->
<!--to the moment of delegation (positive ones) and to the new deadline (zero or negative ones).-->
<!--EXPERIMENTAL-->
<!--</xsd:documentation>-->
<!--</xsd:annotation>-->
<!--</xsd:element>-->
</xsd:sequence>
<!--</xsd:annotation>-->
<!--</xsd:element>-->
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>

<xsd:simpleType name="WorkItemDelegationMethodType">
Expand Down
Expand Up @@ -2420,19 +2420,30 @@ protected OperationResult waitForTaskNextRunAssertSuccess(Task origTask, final b
}

protected OperationResult waitForTaskNextRun(final String taskOid, final boolean checkSubresult, final int timeout) throws Exception {
return waitForTaskNextRun(taskOid, checkSubresult, timeout, false);
}

protected OperationResult waitForTaskNextRun(final String taskOid, final boolean checkSubresult, final int timeout, boolean kickTheTask) throws Exception {
final OperationResult waitResult = new OperationResult(AbstractIntegrationTest.class+".waitForTaskNextRun");
Task origTask = taskManager.getTask(taskOid, waitResult);
return waitForTaskNextRun(origTask, checkSubresult, timeout, waitResult);
return waitForTaskNextRun(origTask, checkSubresult, timeout, waitResult, kickTheTask);
}

protected OperationResult waitForTaskNextRun(final Task origTask, final boolean checkSubresult, final int timeout) throws Exception {
return waitForTaskNextRun(origTask, checkSubresult, timeout, false);
}

protected OperationResult waitForTaskNextRun(final Task origTask, final boolean checkSubresult, final int timeout, boolean kickTheTask) throws Exception {
final OperationResult waitResult = new OperationResult(AbstractIntegrationTest.class+".waitForTaskNextRun");
return waitForTaskNextRun(origTask, checkSubresult, timeout, waitResult);
return waitForTaskNextRun(origTask, checkSubresult, timeout, waitResult, kickTheTask);
}

protected OperationResult waitForTaskNextRun(final Task origTask, final boolean checkSubresult, final int timeout, final OperationResult waitResult) throws Exception {
protected OperationResult waitForTaskNextRun(final Task origTask, final boolean checkSubresult, final int timeout, final OperationResult waitResult, boolean kickTheTask) throws Exception {
final Long origLastRunStartTimestamp = origTask.getLastRunStartTimestamp();
final Long origLastRunFinishTimestamp = origTask.getLastRunFinishTimestamp();
if (kickTheTask) {
taskManager.scheduleTaskNow(origTask, waitResult);
}
final Holder<OperationResult> taskResultHolder = new Holder<>();
Checker checker = new Checker() {
@Override
Expand Down
Expand Up @@ -20,10 +20,7 @@
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.xml.ns._public.common.common_3.DecisionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.EventCategoryType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.WfContextType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemType;
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;
Expand All @@ -39,6 +36,7 @@ public class WorkItemEvent extends WorkflowEvent {

@NotNull private final WorkItemType workItem;
private final SimpleObjectRef assignee;
private WorkItemNotificationActionType notificationAction; // temporary implementation

public WorkItemEvent(LightweightIdentifierGenerator lightweightIdentifierGenerator, ChangeType changeType, @NotNull WorkItemType workItem,
@Nullable SimpleObjectRef assignee, WfContextType workflowContext) {
Expand Down Expand Up @@ -66,7 +64,16 @@ public SimpleObjectRef getAssignee() {
return assignee;
}

@Override
public WorkItemNotificationActionType getNotificationAction() {
return notificationAction;
}

public void setNotificationAction(
WorkItemNotificationActionType notificationAction) {
this.notificationAction = notificationAction;
}

@Override
public void createExpressionVariables(Map<QName, Object> variables, OperationResult result) {
super.createExpressionVariables(variables, result);
variables.put(SchemaConstants.C_ASSIGNEE, assignee != null ? assignee.resolveObjectType(result, false) : null);
Expand Down
Expand Up @@ -18,6 +18,7 @@

import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemNotificationActionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemType;

/**
Expand All @@ -42,4 +43,7 @@ public interface WorkflowEventCreator {
WorkItemEvent createWorkItemCreateEvent(WorkItemType workItem, Task wfTask, OperationResult result);

WorkItemEvent createWorkItemCompleteEvent(WorkItemType workItem, Task wfTask, OperationResult result);

WorkItemEvent createWorkItemEventForNotificationAction(WorkItemType workItem, WorkItemNotificationActionType notificationAction,
Task wfTask, OperationResult result);
}
Expand Up @@ -29,6 +29,7 @@
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.xml.ns._public.common.common_3.WorkItemNotificationActionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
Expand Down Expand Up @@ -94,7 +95,15 @@ public void onWorkItemCompletion(WorkItemType workItem, Task wfTask, OperationRe
processEvent(event);
}

private void processEvent(WorkflowEvent event, OperationResult result) {
@Override
public void onWorkItemNotificationAction(WorkItemType workItem, WorkItemNotificationActionType notificationAction,
Task wfTask, OperationResult result) {
WorkflowEventCreator workflowEventCreator = notificationManager.getWorkflowEventCreator(wfTask);
WorkItemEvent event = workflowEventCreator.createWorkItemEventForNotificationAction(workItem, notificationAction, wfTask, result);
processEvent(event);
}

private void processEvent(WorkflowEvent event, OperationResult result) {
try {
notificationManager.processEvent(event);
} catch (RuntimeException e) {
Expand Down
Expand Up @@ -28,6 +28,7 @@
import com.evolveum.midpoint.task.api.LightweightIdentifierGenerator;
import com.evolveum.midpoint.task.api.Task;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
Expand Down Expand Up @@ -82,7 +83,15 @@ public WorkItemEvent createWorkItemCompleteEvent(WorkItemType workItem, Task wfT
return createWorkItemEvent(workItem, wfTask, ChangeType.DELETE);
}

private WorkItemEvent createWorkItemEvent(WorkItemType workItemType, Task wfTask, ChangeType changeType) {
@Override
public WorkItemEvent createWorkItemEventForNotificationAction(WorkItemType workItem,
WorkItemNotificationActionType notificationAction, Task wfTask, OperationResult result) {
WorkItemEvent event = createWorkItemEvent(workItem, wfTask, ChangeType.MODIFY);
event.setNotificationAction(notificationAction);
return event;
}

private WorkItemEvent createWorkItemEvent(WorkItemType workItemType, Task wfTask, ChangeType changeType) {
// TODO!!!
SimpleObjectRefImpl assignee = workItemType.getOriginalAssigneeRef() != null ?
new SimpleObjectRefImpl(notificationsUtil, workItemType.getOriginalAssigneeRef()) : null;
Expand Down

0 comments on commit cb2fcde

Please sign in to comment.