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);
}
}
}
}