private void doHandle()

in core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java [253:496]


    private void doHandle(final Realm realm) throws JobExecutionException {
        ProvisioningReport result = new ProvisioningReport();
        profile.getResults().add(result);

        result.setKey(realm.getKey());
        result.setAnyType(SyncopeConstants.REALM_ANYTYPE);
        result.setName(realm.getFullPath());

        LOG.debug("Propagating Realm with key {} towards {}", realm.getKey(), profile.getTask().getResource());

        Object output = null;
        OpEvent.Outcome resultStatus = null;

        // Try to read remote object BEFORE any actual operation
        OrgUnit orgUnit = profile.getTask().getResource().getOrgUnit();
        Optional<Item> connObjectKey = orgUnit.getConnObjectKeyItem();
        Optional<String> connObjecKeyValue = mappingManager.getConnObjectKeyValue(
                realm, profile.getTask().getResource());

        ConnectorObject beforeObj = null;
        if (connObjectKey.isPresent() && connObjecKeyValue.isPresent()) {
            beforeObj = getRemoteObject(
                    new ObjectClass(orgUnit.getObjectClass()),
                    connObjectKey.get().getExtAttrName(),
                    connObjecKeyValue.get(),
                    orgUnit.isIgnoreCaseMatch(),
                    orgUnit.getItems().stream());
        } else {
            LOG.debug("OrgUnitItem {} or its value {} are null", connObjectKey, connObjecKeyValue);
        }

        if (profile.isDryRun()) {
            if (beforeObj == null) {
                result.setOperation(toResourceOperation(profile.getTask().getUnmatchingRule()));
            } else {
                result.setOperation(toResourceOperation(profile.getTask().getMatchingRule()));
            }
            result.setStatus(ProvisioningReport.Status.SUCCESS);
        } else {
            String operation = beforeObj == null
                    ? UnmatchingRule.toOp(profile.getTask().getUnmatchingRule())
                    : MatchingRule.toOp(profile.getTask().getMatchingRule());

            boolean notificationsAvailable = notificationManager.notificationsAvailable(
                    AuthContextUtils.getDomain(),
                    OpEvent.CategoryType.PUSH,
                    SyncopeConstants.REALM_ANYTYPE.toLowerCase(),
                    profile.getTask().getResource().getKey(),
                    operation);
            boolean auditRequested = auditManager.auditRequested(
                    AuthContextUtils.getDomain(),
                    AuthContextUtils.getUsername(),
                    OpEvent.CategoryType.PUSH,
                    SyncopeConstants.REALM_ANYTYPE.toLowerCase(),
                    profile.getTask().getResource().getKey(),
                    operation);
            try {
                if (beforeObj == null) {
                    result.setOperation(toResourceOperation(profile.getTask().getUnmatchingRule()));

                    switch (profile.getTask().getUnmatchingRule()) {
                        case ASSIGN -> {
                            for (PushActions action : profile.getActions()) {
                                action.beforeAssign(profile, realm);
                            }

                            if (!profile.getTask().isPerformCreate()) {
                                LOG.debug("PushTask not configured for create");
                                result.setStatus(ProvisioningReport.Status.IGNORE);
                            } else {
                                assign(realm, result);
                            }
                        }

                        case PROVISION -> {
                            for (PushActions action : profile.getActions()) {
                                action.beforeProvision(profile, realm);
                            }

                            if (!profile.getTask().isPerformCreate()) {
                                LOG.debug("PushTask not configured for create");
                                result.setStatus(ProvisioningReport.Status.IGNORE);
                            } else {
                                provision(realm, result);
                            }
                        }

                        case UNLINK -> {
                            for (PushActions action : profile.getActions()) {
                                action.beforeUnlink(profile, realm);
                            }

                            if (!profile.getTask().isPerformUpdate()) {
                                LOG.debug("PushTask not configured for update");
                                result.setStatus(ProvisioningReport.Status.IGNORE);
                            } else {
                                link(realm, true, result);
                            }
                        }

                        case IGNORE -> {
                            LOG.debug("Ignored any: {}", realm);
                            result.setStatus(ProvisioningReport.Status.IGNORE);
                        }

                        default -> {
                        }
                    }
                    // do nothing
                } else {
                    result.setOperation(toResourceOperation(profile.getTask().getMatchingRule()));

                    switch (profile.getTask().getMatchingRule()) {
                        case UPDATE -> {
                            for (PushActions action : profile.getActions()) {
                                action.beforeUpdate(profile, realm);
                            }
                            if (!profile.getTask().isPerformUpdate()) {
                                LOG.debug("PushTask not configured for update");
                                result.setStatus(ProvisioningReport.Status.IGNORE);
                            } else {
                                update(binder.getRealmTO(realm, true), beforeObj, result);
                            }
                        }

                        case DEPROVISION -> {
                            for (PushActions action : profile.getActions()) {
                                action.beforeDeprovision(profile, realm);
                            }

                            if (!profile.getTask().isPerformDelete()) {
                                LOG.debug("PushTask not configured for delete");
                                result.setStatus(ProvisioningReport.Status.IGNORE);
                            } else {
                                deprovision(realm, beforeObj, result);
                            }
                        }

                        case UNASSIGN -> {
                            for (PushActions action : profile.getActions()) {
                                action.beforeUnassign(profile, realm);
                            }

                            if (!profile.getTask().isPerformDelete()) {
                                LOG.debug("PushTask not configured for delete");
                                result.setStatus(ProvisioningReport.Status.IGNORE);
                            } else {
                                unassign(realm, beforeObj, result);
                            }
                        }

                        case LINK -> {
                            for (PushActions action : profile.getActions()) {
                                action.beforeLink(profile, realm);
                            }

                            if (!profile.getTask().isPerformUpdate()) {
                                LOG.debug("PushTask not configured for update");
                                result.setStatus(ProvisioningReport.Status.IGNORE);
                            } else {
                                link(realm, false, result);
                            }
                        }

                        case UNLINK -> {
                            for (PushActions action : profile.getActions()) {
                                action.beforeUnlink(profile, realm);
                            }

                            if (!profile.getTask().isPerformUpdate()) {
                                LOG.debug("PushTask not configured for update");
                                result.setStatus(ProvisioningReport.Status.IGNORE);
                            } else {
                                link(realm, true, result);
                            }
                        }

                        case IGNORE -> {
                            LOG.debug("Ignored any: {}", realm);
                            result.setStatus(ProvisioningReport.Status.IGNORE);
                        }

                        default -> {
                        }
                    }
                    // do nothing
                }

                for (PushActions action : profile.getActions()) {
                    action.after(profile, realm, result);
                }

                if (result.getStatus() == null) {
                    result.setStatus(ProvisioningReport.Status.SUCCESS);
                }

                if (notificationsAvailable || auditRequested) {
                    resultStatus = OpEvent.Outcome.SUCCESS;
                    if (connObjectKey.isPresent() && connObjecKeyValue.isPresent()) {
                        output = getRemoteObject(
                                new ObjectClass(orgUnit.getObjectClass()),
                                connObjectKey.get().getExtAttrName(),
                                connObjecKeyValue.get(),
                                orgUnit.isIgnoreCaseMatch(),
                                orgUnit.getItems().stream());
                    }
                }
            } catch (IgnoreProvisionException e) {
                throw e;
            } catch (Exception e) {
                result.setStatus(ProvisioningReport.Status.FAILURE);
                result.setMessage(ExceptionUtils.getRootCauseMessage(e));

                if (notificationsAvailable || auditRequested) {
                    resultStatus = OpEvent.Outcome.FAILURE;
                    output = e;
                }

                LOG.warn("Error pushing {} towards {}", realm, profile.getTask().getResource(), e);

                for (PushActions action : profile.getActions()) {
                    action.onError(profile, realm, result, e);
                }

                throw new JobExecutionException(e);
            } finally {
                if (notificationsAvailable || auditRequested) {
                    Map<String, Object> jobMap = new HashMap<>();
                    jobMap.put(AfterHandlingEvent.JOBMAP_KEY, new AfterHandlingEvent(
                            AuthContextUtils.getDomain(),
                            AuthContextUtils.getWho(),
                            OpEvent.CategoryType.PUSH,
                            SyncopeConstants.REALM_ANYTYPE.toLowerCase(),
                            profile.getTask().getResource().getKey(),
                            operation,
                            resultStatus,
                            beforeObj,
                            output,
                            realm));
                    AfterHandlingJob.schedule(scheduler, jobMap);
                }
            }
        }
    }