Search in sources :

Example 11 with HookOperationMode

use of com.evolveum.midpoint.model.api.hooks.HookOperationMode in project midpoint by Evolveum.

the class Clockwork method click.

public <F extends ObjectType> HookOperationMode click(LensContext<F> context, Task task, OperationResult result) throws SchemaException, PolicyViolationException, ExpressionEvaluationException, ObjectNotFoundException, ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException {
    if (context.getDebugListener() == null) {
        context.setDebugListener(debugListener);
    }
    try {
        XMLGregorianCalendar now = clock.currentTimeXMLGregorianCalendar();
        // We need to determine focus before auditing. Otherwise we will not know user
        // for the accounts (unless there is a specific delta for it).
        // This is ugly, but it is the easiest way now (TODO: cleanup).
        contextLoader.determineFocusContext((LensContext<? extends FocusType>) context, result);
        ModelState state = context.getState();
        if (state == ModelState.INITIAL) {
            if (debugListener != null) {
                debugListener.beforeSync(context);
            }
            metadataManager.applyRequestMetadata(context, now, task, result);
            context.getStats().setRequestTimestamp(now);
            // We need to do this BEFORE projection. If we would do that after projection
            // there will be secondary changes that are not part of the request.
            audit(context, AuditEventStage.REQUEST, task, result);
        }
        boolean recompute = false;
        if (!context.isFresh()) {
            LOGGER.trace("Context is not fresh -- forcing cleanup and recomputation");
            recompute = true;
        } else if (context.getExecutionWave() > context.getProjectionWave()) {
            // should not occur
            LOGGER.warn("Execution wave is greater than projection wave -- forcing cleanup and recomputation");
            recompute = true;
        }
        if (recompute) {
            context.cleanup();
            projector.project(context, "PROJECTOR (" + state + ")", task, result);
        } else if (context.getExecutionWave() == context.getProjectionWave()) {
            LOGGER.trace("Running projector for current execution wave");
            projector.resume(context, "PROJECTOR (" + state + ")", task, result);
        } else {
            LOGGER.trace("Skipping projection because the context is fresh and projection for current wave has already run");
        }
        if (!context.isRequestAuthorized()) {
            authorizeContextRequest(context, task, result);
        }
        LensUtil.traceContext(LOGGER, "CLOCKWORK (" + state + ")", "before processing", true, context, false);
        if (InternalsConfig.consistencyChecks) {
            try {
                context.checkConsistence();
            } catch (IllegalStateException e) {
                throw new IllegalStateException(e.getMessage() + " in clockwork, state=" + state, e);
            }
        }
        if (InternalsConfig.encryptionChecks && !ModelExecuteOptions.isNoCrypt(context.getOptions())) {
            context.checkEncrypted();
        }
        switch(state) {
            case INITIAL:
                processInitialToPrimary(context, task, result);
                break;
            case PRIMARY:
                processPrimaryToSecondary(context, task, result);
                break;
            case SECONDARY:
                processSecondary(context, task, result);
                break;
            case FINAL:
                HookOperationMode mode = processFinal(context, task, result);
                if (debugListener != null) {
                    debugListener.afterSync(context);
                }
                return mode;
        }
        result.recomputeStatus();
        result.cleanupResult();
        return invokeHooks(context, task, result);
    } catch (CommunicationException | ConfigurationException | ExpressionEvaluationException | ObjectNotFoundException | PolicyViolationException | SchemaException | SecurityViolationException | RuntimeException | ObjectAlreadyExistsException e) {
        processClockworkException(context, e, task, result);
        throw e;
    }
}
Also used : SchemaException(com.evolveum.midpoint.util.exception.SchemaException) ExpressionEvaluationException(com.evolveum.midpoint.util.exception.ExpressionEvaluationException) CommunicationException(com.evolveum.midpoint.util.exception.CommunicationException) SecurityViolationException(com.evolveum.midpoint.util.exception.SecurityViolationException) ModelState(com.evolveum.midpoint.model.api.context.ModelState) XMLGregorianCalendar(javax.xml.datatype.XMLGregorianCalendar) HookOperationMode(com.evolveum.midpoint.model.api.hooks.HookOperationMode) ConfigurationException(com.evolveum.midpoint.util.exception.ConfigurationException) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException) PolicyViolationException(com.evolveum.midpoint.util.exception.PolicyViolationException) ObjectAlreadyExistsException(com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException)

Example 12 with HookOperationMode

use of com.evolveum.midpoint.model.api.hooks.HookOperationMode in project midpoint by Evolveum.

the class Clockwork method invokeHooks.

/**
     * Invokes hooks, if there are any.
     *
     * @return
     *  - ERROR, if any hook reported error; otherwise returns
     *  - BACKGROUND, if any hook reported switching to background; otherwise
     *  - FOREGROUND (if all hooks reported finishing on foreground) 
     */
private HookOperationMode invokeHooks(LensContext context, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, PolicyViolationException {
    // TODO: following two parts should be merged together in later versions
    // Execute configured scripting hooks
    PrismObject<SystemConfigurationType> systemConfiguration = systemObjectCache.getSystemConfiguration(result);
    // systemConfiguration may be null in some tests
    if (systemConfiguration != null) {
        ModelHooksType modelHooks = systemConfiguration.asObjectable().getModelHooks();
        if (modelHooks != null) {
            HookListType changeHooks = modelHooks.getChange();
            if (changeHooks != null) {
                for (HookType hookType : changeHooks.getHook()) {
                    String shortDesc;
                    if (hookType.getName() != null) {
                        shortDesc = "hook '" + hookType.getName() + "'";
                    } else {
                        shortDesc = "scripting hook in system configuration";
                    }
                    if (hookType.isEnabled() != null && !hookType.isEnabled()) {
                        // Disabled hook, skip
                        continue;
                    }
                    if (hookType.getState() != null) {
                        if (!context.getState().toModelStateType().equals(hookType.getState())) {
                            continue;
                        }
                    }
                    if (hookType.getFocusType() != null) {
                        if (context.getFocusContext() == null) {
                            continue;
                        }
                        QName hookFocusTypeQname = hookType.getFocusType();
                        ObjectTypes hookFocusType = ObjectTypes.getObjectTypeFromTypeQName(hookFocusTypeQname);
                        if (hookFocusType == null) {
                            throw new SchemaException("Unknown focus type QName " + hookFocusTypeQname + " in " + shortDesc);
                        }
                        Class focusClass = context.getFocusClass();
                        Class<? extends ObjectType> hookFocusClass = hookFocusType.getClassDefinition();
                        if (!hookFocusClass.isAssignableFrom(focusClass)) {
                            continue;
                        }
                    }
                    ScriptExpressionEvaluatorType scriptExpressionEvaluatorType = hookType.getScript();
                    if (scriptExpressionEvaluatorType == null) {
                        continue;
                    }
                    try {
                        evaluateScriptingHook(context, hookType, scriptExpressionEvaluatorType, shortDesc, task, result);
                    } catch (ExpressionEvaluationException e) {
                        LOGGER.error("Evaluation of {} failed: {}", new Object[] { shortDesc, e.getMessage(), e });
                        throw new ExpressionEvaluationException("Evaluation of " + shortDesc + " failed: " + e.getMessage(), e);
                    } catch (ObjectNotFoundException e) {
                        LOGGER.error("Evaluation of {} failed: {}", new Object[] { shortDesc, e.getMessage(), e });
                        throw new ObjectNotFoundException("Evaluation of " + shortDesc + " failed: " + e.getMessage(), e);
                    } catch (SchemaException e) {
                        LOGGER.error("Evaluation of {} failed: {}", new Object[] { shortDesc, e.getMessage(), e });
                        throw new SchemaException("Evaluation of " + shortDesc + " failed: " + e.getMessage(), e);
                    }
                }
            }
        }
    }
    // Execute registered Java hooks
    HookOperationMode resultMode = HookOperationMode.FOREGROUND;
    if (hookRegistry != null) {
        for (ChangeHook hook : hookRegistry.getAllChangeHooks()) {
            HookOperationMode mode = hook.invoke(context, task, result);
            if (mode == HookOperationMode.ERROR) {
                resultMode = HookOperationMode.ERROR;
            } else if (mode == HookOperationMode.BACKGROUND) {
                if (resultMode != HookOperationMode.ERROR) {
                    resultMode = HookOperationMode.BACKGROUND;
                }
            }
        }
    }
    return resultMode;
}
Also used : SchemaException(com.evolveum.midpoint.util.exception.SchemaException) ExpressionEvaluationException(com.evolveum.midpoint.util.exception.ExpressionEvaluationException) QName(javax.xml.namespace.QName) ChangeHook(com.evolveum.midpoint.model.api.hooks.ChangeHook) ObjectTypes(com.evolveum.midpoint.schema.constants.ObjectTypes) HookOperationMode(com.evolveum.midpoint.model.api.hooks.HookOperationMode) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException)

Example 13 with HookOperationMode

use of com.evolveum.midpoint.model.api.hooks.HookOperationMode in project midpoint by Evolveum.

the class AbstractWfTestLegacy method executeTest.

protected void executeTest(String testName, String oid, TestDetails testDetails) throws Exception {
    // GIVEN
    prepareNotifications();
    dummyAuditService.clear();
    Task modelTask = taskManager.createTaskInstance(AbstractWfTestLegacy.class.getName() + "." + testName);
    OperationResult result = new OperationResult("execution");
    modelTask.setOwner(repositoryService.getObject(UserType.class, USER_ADMINISTRATOR_OID, null, result));
    if (oid != null && testDetails.removeAssignmentsBeforeTest()) {
        removeAllAssignments(oid, result);
    }
    LensContext<UserType> context = (LensContext<UserType>) testDetails.createModelContext(modelTask, result);
    display("Input context", context);
    assertFocusModificationSanity(context);
    // WHEN
    HookOperationMode mode = clockwork.run(context, modelTask, result);
    // THEN
    assertEquals("Unexpected state of the context", ModelState.PRIMARY, context.getState());
    assertEquals("Wrong mode after clockwork.run in " + context.getState(), HookOperationMode.BACKGROUND, mode);
    modelTask.refresh(result);
    String rootTaskOid = wfTaskUtil.getRootTaskOid(modelTask);
    assertNotNull("Root task OID is not set in model task", rootTaskOid);
    Task rootTask = taskManager.getTask(rootTaskOid, result);
    // trivial ;)
    assertTrue("Root task is not persistent", rootTask.isPersistent());
    if (!testDetails.approvedAutomatically()) {
        UriStack uriStack = rootTask.getOtherHandlersUriStack();
        if (!testDetails.immediate()) {
            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 taskModelContext = testDetails.immediate() ? null : wfTaskUtil.getModelContext(rootTask, result);
        if (!testDetails.immediate()) {
            assertNotNull("Model context is not present in root task", taskModelContext);
        } else {
            assertFalse("Model context is present in root task (execution mode = immediate)", wfTaskUtil.hasModelContext(rootTask));
        }
        List<Task> subtasks = rootTask.listSubtasks(result);
        assertEquals("Incorrect number of subtasks", testDetails.subtaskCount(), subtasks.size());
        Task task0 = extractTask0(subtasks, testDetails);
        testDetails.assertsAfterClockworkRun(rootTask, subtasks, result);
        if (testDetails.immediate()) {
            waitForTaskClose(task0, 20000);
            //TestUtil.assertSuccess(task0.getResult());            // todo enable this
            testDetails.assertsAfterImmediateExecutionFinished(rootTask, result);
        }
        for (int i = 0; i < subtasks.size(); i++) {
            Task subtask = subtasks.get(i);
            //assertEquals("Subtask #" + i + " is not recurring: " + subtask, TaskRecurrence.RECURRING, subtask.getRecurrenceStatus());
            //assertEquals("Incorrect execution status of subtask #" + i + ": " + subtask, TaskExecutionStatus.RUNNABLE, subtask.getExecutionStatus());
            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);
            //                WfProcessInstanceType processInstance = 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();
            //WorkItemDetailed workItemDetailed = wfDataAccessor.getWorkItemDetailsById(taskId, result);
            org.activiti.engine.task.Task t = activitiEngine.getTaskService().createTaskQuery().processInstanceId(pid).singleResult();
            assertNotNull("activiti task not found", t);
            String executionId = t.getExecutionId();
            LOGGER.trace("Execution id = {}", executionId);
            boolean approve = testDetails.decideOnApproval(executionId);
            workflowManager.completeWorkItem(t.getId(), approve, null, null, null, result);
            login(userAdministrator);
        }
    }
    waitForTaskClose(rootTask, 60000);
    List<Task> subtasks = rootTask.listSubtasks(result);
    extractTask0(subtasks, testDetails);
    //TestUtil.assertSuccess(rootTask.getResult());
    testDetails.assertsRootTaskFinishes(rootTask, subtasks, result);
    if (oid == null) {
        oid = testDetails.getObjectOid(rootTask, result);
    }
    assertNotNull("object oid is null after operation", oid);
    if (!oid.equals(DONT_CHECK)) {
        assertObjectInTaskTree(rootTask, oid, testDetails.checkObjectOnSubtasks(), result);
    }
    if (!testDetails.approvedAutomatically()) {
    // ZZZ temporarily disabled
    //            checkDummyTransportMessages("simpleWorkflowNotifier-Processes", workflowSubtaskCount * 2);
    //            checkDummyTransportMessages("simpleWorkflowNotifier-WorkItems", workflowSubtaskCount * 2);
    }
    notificationManager.setDisabled(true);
    // Check audit
    display("Audit", dummyAuditService);
    display("Output context", context);
}
Also used : Task(com.evolveum.midpoint.task.api.Task) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) LensContext(com.evolveum.midpoint.model.impl.lens.LensContext) ModelContext(com.evolveum.midpoint.model.api.context.ModelContext) HookOperationMode(com.evolveum.midpoint.model.api.hooks.HookOperationMode) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Example 14 with HookOperationMode

use of com.evolveum.midpoint.model.api.hooks.HookOperationMode in project midpoint by Evolveum.

the class TestClockwork method assignAccountToJackAsync.

private void assignAccountToJackAsync(String testName, boolean serialize) throws Exception {
    displayTestTile(testName);
    // GIVEN
    Task task = createTask(testName);
    OperationResult result = task.getResult();
    assertNoDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME);
    LensContext<UserType> context = createJackAssignAccountContext(result);
    //        display("Input context", context);
    assertFocusModificationSanity(context);
    mockClockworkHook.reset();
    mockClockworkHook.setRecord(true);
    mockClockworkHook.setAsynchronous(true);
    rememberShadowFetchOperationCount();
    // WHEN
    displayWhen(testName);
    while (context.getState() != ModelState.FINAL) {
        display("CLICK START: " + context.getState());
        HookOperationMode mode = clockwork.click(context, task, result);
        display("CLICK END: " + context.getState());
        assertTrue("Unexpected INITIAL state of the context", context.getState() != ModelState.INITIAL);
        assertEquals("Wrong mode after click in " + context.getState(), HookOperationMode.BACKGROUND, mode);
        assertShadowFetchOperationCountIncrement(0);
        if (serialize) {
            display("Context before serialization", context);
            PrismContainer<LensContextType> lensContextType = context.toPrismContainer();
            String xml = prismContext.xmlSerializer().serialize(lensContextType.getValue(), lensContextType.getElementName());
            display("Serialized form", xml);
            LensContextType unmarshalledContainer = prismContext.parserFor(xml).xml().parseRealValue(LensContextType.class);
            context = LensContext.fromLensContextType(unmarshalledContainer, context.getPrismContext(), provisioningService, task, result);
            display("Context after deserialization", context.debugDump());
            context.checkConsistence();
        }
    }
    // THEN
    displayThen(testName);
    mockClockworkHook.setRecord(false);
    //        display("Output context", context);
    //        display("Hook contexts", mockClockworkHook);
    assertShadowFetchOperationCountIncrement(0);
    assertJackAssignAccountContext(context);
    assertJackAccountShadow(context);
}
Also used : Task(com.evolveum.midpoint.task.api.Task) HookOperationMode(com.evolveum.midpoint.model.api.hooks.HookOperationMode) OperationResult(com.evolveum.midpoint.schema.result.OperationResult)

Example 15 with HookOperationMode

use of com.evolveum.midpoint.model.api.hooks.HookOperationMode in project midpoint by Evolveum.

the class WfHook method processModelInvocation.

private HookOperationMode processModelInvocation(@NotNull ModelContext<? extends ObjectType> modelContext, WfConfigurationType wfConfigurationType, @NotNull Task taskFromModel, @NotNull OperationResult result) {
    try {
        modelContext.reportProgress(new ProgressInformation(WORKFLOWS, ENTERING));
        for (ChangeProcessor changeProcessor : wfConfiguration.getChangeProcessors()) {
            LOGGER.trace("Trying change processor: {}", changeProcessor.getClass().getName());
            try {
                HookOperationMode hookOperationMode = changeProcessor.processModelInvocation(modelContext, wfConfigurationType, taskFromModel, result);
                if (hookOperationMode != null) {
                    return hookOperationMode;
                }
            } catch (ObjectNotFoundException | SchemaException | RuntimeException e) {
                LoggingUtils.logUnexpectedException(LOGGER, "Exception while running change processor {}", e, changeProcessor.getClass().getName());
                result.recordFatalError("Exception while running change processor " + changeProcessor.getClass(), e);
                return HookOperationMode.ERROR;
            }
        }
    } finally {
        if (result.isInProgress()) {
            // a bit of hack: IN_PROGRESS for workflows actually means "success"
            OperationResult r = result.clone();
            r.recordSuccess();
            modelContext.reportProgress(new ProgressInformation(WORKFLOWS, r));
        } else {
            modelContext.reportProgress(new ProgressInformation(WORKFLOWS, result));
        }
    }
    LOGGER.trace("No change processor caught this request, returning the FOREGROUND flag.");
    return HookOperationMode.FOREGROUND;
}
Also used : SchemaException(com.evolveum.midpoint.util.exception.SchemaException) ChangeProcessor(com.evolveum.midpoint.wf.impl.processors.ChangeProcessor) ProgressInformation(com.evolveum.midpoint.model.api.ProgressInformation) HookOperationMode(com.evolveum.midpoint.model.api.hooks.HookOperationMode) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException) OperationResult(com.evolveum.midpoint.schema.result.OperationResult)

Aggregations

HookOperationMode (com.evolveum.midpoint.model.api.hooks.HookOperationMode)21 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)14 Task (com.evolveum.midpoint.task.api.Task)9 ObjectNotFoundException (com.evolveum.midpoint.util.exception.ObjectNotFoundException)4 SchemaException (com.evolveum.midpoint.util.exception.SchemaException)4 QName (javax.xml.namespace.QName)4 ProgressInformation (com.evolveum.midpoint.model.api.ProgressInformation)3 ModelContext (com.evolveum.midpoint.model.api.context.ModelContext)3 LensContext (com.evolveum.midpoint.model.impl.lens.LensContext)3 ExpressionEvaluationException (com.evolveum.midpoint.util.exception.ExpressionEvaluationException)3 ChangeHook (com.evolveum.midpoint.model.api.hooks.ChangeHook)2 LensProjectionContext (com.evolveum.midpoint.model.impl.lens.LensProjectionContext)2 PrismContext (com.evolveum.midpoint.prism.PrismContext)2 ObjectDelta (com.evolveum.midpoint.prism.delta.ObjectDelta)2 ItemPath (com.evolveum.midpoint.prism.path.ItemPath)2 SelectorOptions (com.evolveum.midpoint.schema.SelectorOptions)2 ObjectTypes (com.evolveum.midpoint.schema.constants.ObjectTypes)2 CommunicationException (com.evolveum.midpoint.util.exception.CommunicationException)2 ConfigurationException (com.evolveum.midpoint.util.exception.ConfigurationException)2 SecurityViolationException (com.evolveum.midpoint.util.exception.SecurityViolationException)2