use of com.evolveum.midpoint.model.api.hooks.HookOperationMode in project midpoint by Evolveum.
the class Clockwork method processFinal.
private <F extends ObjectType> HookOperationMode processFinal(LensContext<F> context, Task task, OperationResult result) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException, PolicyViolationException {
auditFinalExecution(context, task, result);
logFinalReadable(context, task, result);
recordOperationExecution(context, null, task, result);
HookOperationMode opmode = personaProcessor.processPersonaChanges(context, task, result);
if (opmode == HookOperationMode.BACKGROUND) {
return opmode;
}
return triggerReconcileAffected(context, task, result);
}
use of com.evolveum.midpoint.model.api.hooks.HookOperationMode in project midpoint by Evolveum.
the class AbstractWfTestPolicy method executeTest.
protected <F extends FocusType> void executeTest(String testName, TestDetails testDetails, int expectedSubTaskCount) throws Exception {
// GIVEN
prepareNotifications();
dummyAuditService.clear();
Task modelTask = taskManager.createTaskInstance(AbstractWfTestPolicy.class.getName() + "." + testName);
modelTask.setOwner(userAdministrator);
OperationResult result = new OperationResult("execution");
LensContext<F> modelContext = testDetails.createModelContext(result);
display("Model context at test start", modelContext);
// this has problems with deleting assignments by ID
//assertFocusModificationSanity(modelContext);
// WHEN
HookOperationMode mode = clockwork.run(modelContext, modelTask, result);
// THEN
display("Model context after first clockwork.run", modelContext);
assertEquals("Unexpected state of the context", ModelState.PRIMARY, modelContext.getState());
assertEquals("Wrong mode after clockwork.run in " + modelContext.getState(), HookOperationMode.BACKGROUND, mode);
modelTask.refresh(result);
display("Model task after first clockwork.run", modelTask);
String rootTaskOid = wfTaskUtil.getRootTaskOid(modelTask);
assertNotNull("Root task OID is not set in model task", rootTaskOid);
Task rootTask = taskManager.getTask(rootTaskOid, result);
assertTrue("Root task is not persistent", rootTask.isPersistent());
UriStack uriStack = rootTask.getOtherHandlersUriStack();
if (!testDetails.executeImmediately()) {
assertEquals("Invalid handler at stack position 0", ModelOperationTaskHandler.MODEL_OPERATION_TASK_URI, uriStack.getUriStackEntry().get(0).getHandlerUri());
} else {
assertTrue("There should be no handlers for root tasks with immediate execution mode", uriStack == null || uriStack.getUriStackEntry().isEmpty());
}
ModelContext rootModelContext = testDetails.executeImmediately() ? null : wfTaskUtil.getModelContext(rootTask, result);
if (!testDetails.executeImmediately()) {
assertNotNull("Model context is not present in root task", rootModelContext);
} else {
assertNull("Model context is present in root task (execution mode = immediate)", rootModelContext);
}
List<Task> subtasks = rootTask.listSubtasks(result);
Task task0 = findAndRemoveTask0(subtasks, testDetails);
assertEquals("Incorrect number of subtasks", expectedSubTaskCount, subtasks.size());
final Collection<SelectorOptions<GetOperationOptions>> options1 = resolveItemsNamed(new ItemPath(T_PARENT, F_OBJECT_REF), new ItemPath(T_PARENT, F_TARGET_REF), F_ASSIGNEE_REF, F_ORIGINAL_ASSIGNEE_REF, new ItemPath(T_PARENT, F_REQUESTER_REF));
List<WorkItemType> workItems = modelService.searchContainers(WorkItemType.class, null, options1, modelTask, result);
testDetails.afterFirstClockworkRun(rootTask, subtasks, workItems, result);
if (testDetails.executeImmediately()) {
if (task0 != null) {
waitForTaskClose(task0, 20000);
}
testDetails.afterTask0Finishes(rootTask, result);
}
for (int i = 0; i < subtasks.size(); i++) {
Task subtask = subtasks.get(i);
PrismProperty<ObjectTreeDeltasType> deltas = subtask.getTaskPrismObject().findProperty(new ItemPath(F_WORKFLOW_CONTEXT, F_PROCESSOR_SPECIFIC_STATE, F_DELTAS_TO_PROCESS));
assertNotNull("There are no modifications in subtask #" + i + ": " + subtask, deltas);
assertEquals("Incorrect number of modifications in subtask #" + i + ": " + subtask, 1, deltas.getRealValues().size());
// todo check correctness of the modification?
// now check the workflow state
String pid = wfTaskUtil.getProcessId(subtask);
assertNotNull("Workflow process instance id not present in subtask " + subtask, pid);
List<org.activiti.engine.task.Task> tasks = activitiEngine.getTaskService().createTaskQuery().processInstanceId(pid).list();
assertFalse("activiti task not found", tasks.isEmpty());
for (org.activiti.engine.task.Task task : tasks) {
String executionId = task.getExecutionId();
display("Execution id = " + executionId);
Boolean approve = testDetails.decideOnApproval(executionId, task);
if (approve != null) {
workflowManager.completeWorkItem(task.getId(), approve, null, null, null, result);
login(userAdministrator);
break;
}
}
}
// alternative way of approvals executions
if (CollectionUtils.isNotEmpty(testDetails.getApprovalSequence())) {
List<ApprovalInstruction> instructions = new ArrayList<>(testDetails.getApprovalSequence());
while (!instructions.isEmpty()) {
List<WorkItemType> currentWorkItems = modelService.searchContainers(WorkItemType.class, null, options1, modelTask, result);
boolean matched = false;
main: for (ApprovalInstruction approvalInstruction : instructions) {
for (WorkItemType workItem : currentWorkItems) {
if (approvalInstruction.matches(workItem)) {
if (approvalInstruction.beforeApproval != null) {
approvalInstruction.beforeApproval.run();
}
login(getUserFromRepo(approvalInstruction.approverOid));
workflowManager.completeWorkItem(workItem.getExternalId(), approvalInstruction.approval, null, null, null, result);
if (approvalInstruction.afterApproval != null) {
approvalInstruction.afterApproval.run();
}
login(userAdministrator);
matched = true;
instructions.remove(approvalInstruction);
break main;
}
}
}
if (!matched) {
fail("None of approval instructions " + instructions + " matched any of current work items: " + currentWorkItems);
}
}
}
waitForTaskClose(rootTask, 60000);
subtasks = rootTask.listSubtasks(result);
findAndRemoveTask0(subtasks, testDetails);
testDetails.afterRootTaskFinishes(rootTask, subtasks, result);
notificationManager.setDisabled(true);
// Check audit
display("Audit", dummyAuditService);
display("Output context", modelContext);
}
use of com.evolveum.midpoint.model.api.hooks.HookOperationMode in project midpoint by Evolveum.
the class TestGeneralChangeProcessor method executeTest.
private void executeTest(String testName, String oid, int subtaskCount, boolean immediate, boolean checkObjectOnSubtasks, ContextCreator contextCreator) throws Exception {
int workflowSubtaskCount = immediate ? subtaskCount - 1 : subtaskCount;
// GIVEN
prepareNotifications();
dummyAuditService.clear();
OperationResult result = new OperationResult("execution");
Task modelTask = taskManager.createTaskInstance(TestGeneralChangeProcessor.class.getName() + "." + testName);
display("Model task after creation", modelTask);
LensContext<UserType> context = (LensContext<UserType>) contextCreator.createModelContext(result);
modelTask.setOwner(repositoryService.getObject(UserType.class, USER_ADMINISTRATOR_OID, null, result));
display("Input context", context);
assertFocusModificationSanity(context);
// WHEN
HookOperationMode mode = clockwork.run(context, modelTask, result);
// THEN
contextCreator.assertsAfterClockworkRun(context, modelTask, result);
assertEquals("Wrong mode after clockwork.run in " + context.getState(), HookOperationMode.BACKGROUND, mode);
modelTask.refresh(result);
display("Model task after clockwork runs", modelTask);
Task rootTask = taskManager.getTask(wfTaskUtil.getRootTaskOid(modelTask), result);
display("Workflow root task created by clockwork run", rootTask);
assertTrue("Workflow root task is not persistent", rootTask.isPersistent());
assertEquals("Invalid current handler", ModelOperationTaskHandler.MODEL_OPERATION_TASK_URI, rootTask.getHandlerUri());
ModelContext taskModelContext = immediate ? null : wfTaskUtil.getModelContext(rootTask, result);
assertNotNull("Model context is not present in root task", taskModelContext);
List<Task> subtasks = rootTask.listSubtasks(result);
assertEquals("Incorrect number of subtasks", subtaskCount, subtasks.size());
for (int subtaskIndex = 0; subtaskIndex < subtasks.size(); subtaskIndex++) {
Task subtask = subtasks.get(subtaskIndex);
// now check the workflow state
String pid = wfTaskUtil.getProcessId(subtask);
assertNotNull("Workflow process instance id not present in subtask " + subtask, pid);
/*
WfProcessInstanceType processInstance = null; //workflowServiceImpl.getProcessInstanceById(pid, false, true, result);
assertNotNull("Process instance information cannot be retrieved", processInstance);
assertEquals("Incorrect number of work items", 1, processInstance.getWorkItems().size());
String taskId = processInstance.getWorkItems().get(0).getWorkItemId();
//WorkItemNewType workItem = workflowServiceImpl.getWorkItemDetailsById(taskId, result);
WorkItemNewType workItem = null; // TODO
org.activiti.engine.task.Task t = activitiEngine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
assertNotNull("activiti task not found", t);
String executionId = t.getExecutionId();
LOGGER.trace("Task id = " + taskId + ", execution id = " + executionId);
contextCreator.completeWorkItem(workItem, taskId, result);
*/
}
waitForTaskClose(rootTask, 60000);
contextCreator.assertsRootTaskFinishes(rootTask, result);
}
use of com.evolveum.midpoint.model.api.hooks.HookOperationMode in project midpoint by Evolveum.
the class TestAddAssociationLegacy method test100AddJackToGuests.
/**
* Add entitlement for 'guests' to user jack - should be created without starting wf process
*/
@Test
public void test100AddJackToGuests() throws Exception {
final String TEST_NAME = "test100AddJackToGuests";
TestUtil.displayTestTile(this, TEST_NAME);
Task modelTask = taskManager.createTaskInstance(TEST_NAME);
OperationResult result = new OperationResult(TEST_NAME);
modelTask.setOwner(repositoryService.getObject(UserType.class, USER_ADMINISTRATOR_OID, null, result));
LensContext<UserType> context = createUserLensContext();
fillContextWithUser(context, USER_JACK_OID, result);
UserType jack = context.getFocusContext().getObjectCurrent().asObjectable();
AssertJUnit.assertEquals("Jack has wrong number of accounts", 1, jack.getLinkRef().size());
jackAccountShadowOid = jack.getLinkRef().get(0).getOid();
ShadowType accountBefore = getObject(ShadowType.class, jackAccountShadowOid).asObjectable();
assertEquals("Wrong # of jack's account associations", 1, accountBefore.getAssociation().size());
assertHasAssociation(accountBefore, new QName("group"), GROUP_TESTERS_OID);
LensProjectionContext accountContext = fillContextWithAccount(context, jackAccountShadowOid, modelTask, result);
ObjectModificationType modElement = PrismTestUtil.parseAtomicValue(REQ_SHADOW_MODIFY_ADD_ENTITLEMENT_GUESTS, ObjectModificationType.COMPLEX_TYPE);
ObjectDelta shadowDelta = DeltaConvertor.createObjectDelta(modElement, ShadowType.class, prismContext);
shadowDelta.setOid(jackAccountShadowOid);
accountContext.setPrimaryDelta(shadowDelta);
HookOperationMode mode = clockwork.run(context, modelTask, result);
assertEquals("Unexpected state of the context - workflow was started even if it should not", ModelState.FINAL, context.getState());
assertEquals("Wrong mode after clockwork.run in " + context.getState(), HookOperationMode.FOREGROUND, mode);
ShadowType accountAfter = getObject(ShadowType.class, jackAccountShadowOid).asObjectable();
assertEquals("Wrong # of jack's account associations", 2, accountAfter.getAssociation().size());
assertHasAssociation(accountAfter, new QName("group"), GROUP_TESTERS_OID);
assertHasAssociation(accountAfter, new QName("group"), GROUP_GUESTS_OID);
}
use of com.evolveum.midpoint.model.api.hooks.HookOperationMode in project midpoint by Evolveum.
the class WfHook method invoke.
@Override
public <O extends ObjectType> HookOperationMode invoke(@NotNull ModelContext<O> context, @NotNull Task task, @NotNull OperationResult parentResult) {
// Generally this cannot be minor as we need the "task switched to background" flag.
// But if the hook does nothing (returns FOREGROUND flag), we mark the result
// as minor afterwards.
OperationResult result = parentResult.createSubresult(OP_INVOKE);
result.addParam("task", task.toString());
result.addArbitraryObjectAsContext("model state", context.getState());
try {
WfConfigurationType wfConfigurationType = configurationHelper.getWorkflowConfiguration(context, result);
if (wfConfigurationType != null && Boolean.FALSE.equals(wfConfigurationType.isModelHookEnabled())) {
LOGGER.info("Workflow model hook is disabled. Proceeding with operation execution as if everything is approved.");
result.recordSuccess();
return HookOperationMode.FOREGROUND;
}
if (context.getPartialProcessingOptions().getApprovals() == PartialProcessingTypeType.SKIP) {
LOGGER.debug("Skipping workflow processing because of the partial processing option set to SKIP");
result.recordSuccess();
return HookOperationMode.FOREGROUND;
}
// e.g. for tests, initialization is scattered through many places, so that would be too much work.
if (SchemaConstants.CHANNEL_INIT_URI.equals(context.getChannel())) {
LOGGER.debug("Skipping workflow processing because the channel is '" + SchemaConstants.CHANNEL_INIT_URI + "'.");
result.recordSuccess();
return HookOperationMode.FOREGROUND;
}
logOperationInformation(context);
HookOperationMode retval = processModelInvocation(context, wfConfigurationType, task, result);
result.computeStatus();
if (retval == HookOperationMode.FOREGROUND) {
result.setMinor();
}
return retval;
} catch (RuntimeException e) {
result.recordFatalError("Couldn't process model invocation in workflow module: " + e.getMessage(), e);
throw e;
}
}
Aggregations