protected TaskExec doExecute()

in core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java [530:733]


    protected TaskExec<PropagationTask> doExecute(
            final PropagationTaskInfo taskInfo,
            final PropagationReporter reporter,
            final String executor) {

        Connector connector = taskInfo.getConnector() == null
                ? connectorManager.getConnector(taskInfo.getResource())
                : taskInfo.getConnector();

        List<PropagationActions> actions = getPropagationActions(taskInfo.getResource());

        OffsetDateTime start = OffsetDateTime.now();

        TaskExec<PropagationTask> exec = taskUtilsFactory.getInstance(TaskType.PROPAGATION).newTaskExec();
        exec.setStatus(ExecStatus.CREATED.name());
        exec.setExecutor(executor);

        String taskExecutionMessage = null;
        String failureReason = null;

        // Flag to state whether any propagation has been attempted
        Mutable<Boolean> propagationAttempted = new MutableObject<>(false);

        boolean fetchRemoteObj = isFetchRemoteObj(taskInfo);

        ConnectorObject beforeObj = null;
        ConnectorObject afterObj = null;

        Provision provision = null;
        OrgUnit orgUnit = null;
        Uid uid = null;
        OpEvent.Outcome result;
        try {
            provision = taskInfo.getResource().
                    getProvisionByObjectClass(taskInfo.getObjectClass().getObjectClassValue()).orElse(null);
            orgUnit = taskInfo.getResource().getOrgUnit();

            if (taskInfo.getBeforeObj().isEmpty()) {
                if (fetchRemoteObj) {
                    // Try to read remote object BEFORE any actual operation
                    beforeObj = provision == null && orgUnit == null
                            ? null
                            : orgUnit == null
                                    ? getRemoteObject(taskInfo, connector, provision, actions, false)
                                    : getRemoteObject(taskInfo, connector, orgUnit, actions, false);
                    taskInfo.setBeforeObj(Optional.ofNullable(beforeObj));
                }
            } else {
                beforeObj = taskInfo.getBeforeObj().get();
            }

            actions.forEach(action -> action.before(taskInfo));

            switch (taskInfo.getOperation()) {
                case CREATE:
                case UPDATE:
                    uid = createOrUpdate(taskInfo, fetchRemoteObj, beforeObj, connector, propagationAttempted);
                    break;

                case DELETE:
                    uid = delete(taskInfo, fetchRemoteObj, beforeObj, connector, propagationAttempted);
                    break;

                default:
            }

            exec.setStatus(propagationAttempted.getValue()
                    ? ExecStatus.SUCCESS.name()
                    : ExecStatus.NOT_ATTEMPTED.name());

            result = OpEvent.Outcome.SUCCESS;

            LOG.debug("Successfully propagated to {}", taskInfo.getResource());
        } catch (Exception e) {
            result = OpEvent.Outcome.FAILURE;

            exec.setStatus(ExecStatus.FAILURE.name());

            propagationAttempted.setValue(true);

            LOG.error("Exception during provision on resource {}", taskInfo.getResource().getKey(), e);

            if (e instanceof ConnectorException && e.getCause() != null) {
                taskExecutionMessage = e.getCause().getMessage();
                if (e.getCause().getMessage() == null) {
                    failureReason = e.getMessage();
                } else {
                    failureReason = e.getMessage() + "\n\n Cause: " + e.getCause().getMessage().split("\n")[0];
                }
            } else {
                taskExecutionMessage = ExceptionUtils2.getFullStackTrace(e);
                if (e.getCause() == null) {
                    failureReason = e.getMessage();
                } else {
                    failureReason = e.getMessage() + "\n\n Cause: " + e.getCause().getMessage().split("\n")[0];
                }
            }

            actions.forEach(action -> action.onError(taskInfo, exec, e));
        } finally {
            // Try to read remote object AFTER any actual operation
            if (uid != null) {
                taskInfo.setConnObjectKey(uid.getUidValue());
            }
            if (fetchRemoteObj) {
                try {
                    afterObj = provision == null && orgUnit == null
                            ? null
                            : orgUnit == null
                                    ? getRemoteObject(taskInfo, connector, provision, actions, true)
                                    : getRemoteObject(taskInfo, connector, orgUnit, actions, true);
                } catch (Exception ignore) {
                    // ignore exception
                    LOG.error("Error retrieving after object", ignore);
                }
            }

            if (!ExecStatus.FAILURE.name().equals(exec.getStatus())
                    && afterObj == null
                    && uid != null
                    && taskInfo.getOperation() != ResourceOperation.DELETE) {

                afterObj = new ConnectorObjectBuilder().
                        setObjectClass(taskInfo.getObjectClass()).
                        setUid(uid).
                        setName(Optional.ofNullable(
                                AttributeUtil.getNameFromAttributes(taskInfo.getPropagationData().getAttributes())).
                                orElseGet(() -> new Name(taskInfo.getConnObjectKey()))).
                        build();
            }

            exec.setStart(start);
            exec.setMessage(taskExecutionMessage);
            exec.setEnd(OffsetDateTime.now());

            LOG.debug("Execution finished: {}", exec);

            hasToBeregistered(taskInfo, exec).ifPresent(task -> {
                LOG.debug("Execution to be stored: {}", exec);

                exec.setTask(task);
                task.add(exec);

                taskInfo.setKey(taskDAO.save(task).getKey());
            });

            String fiql = provision == null
                    ? null
                    : afterObj != null
                            ? outboundMatcher.getFIQL(afterObj, taskInfo.getResource(), provision)
                            : beforeObj != null
                                    ? outboundMatcher.getFIQL(beforeObj, taskInfo.getResource(), provision)
                                    : null;
            reporter.onSuccessOrNonPriorityResourceFailures(
                    taskInfo,
                    ExecStatus.valueOf(exec.getStatus()),
                    failureReason,
                    fiql,
                    beforeObj,
                    afterObj);
        }

        for (PropagationActions action : actions) {
            action.after(taskInfo, exec, afterObj);
        }
        // SYNCOPE-1136
        String anyTypeKind = Optional.ofNullable(taskInfo.getAnyTypeKind()).map(Enum::name).orElse("realm");
        String operation = taskInfo.getOperation().name().toLowerCase();
        boolean notificationsAvailable = notificationManager.notificationsAvailable(
                AuthContextUtils.getDomain(),
                OpEvent.CategoryType.PROPAGATION,
                anyTypeKind,
                taskInfo.getResource().getKey(),
                operation);
        boolean auditRequested = auditManager.auditRequested(
                AuthContextUtils.getDomain(),
                AuthContextUtils.getUsername(),
                OpEvent.CategoryType.PROPAGATION,
                anyTypeKind,
                taskInfo.getResource().getKey(),
                operation);

        if (notificationsAvailable || auditRequested) {
            ExecTO execTO = taskDataBinder.getExecTO(exec);

            AfterHandlingEvent event = new AfterHandlingEvent(
                    AuthContextUtils.getDomain(),
                    AuthContextUtils.getWho(),
                    OpEvent.CategoryType.PROPAGATION,
                    anyTypeKind,
                    taskInfo.getResource().getKey(),
                    operation,
                    result,
                    beforeObj,
                    new Object[] { execTO, afterObj },
                    taskInfo);

            notificationManager.createTasks(event);

            auditManager.audit(event);
        }

        return exec;
    }