@Transactional(propagation = Propagation.REQUIRES_NEW) @Override public boolean handle(final long anyKey) { Any<?> any = null; try { any = getAny(anyKey); doHandle(any); return true; } catch (IgnoreProvisionException e) { ProvisioningReport result = new ProvisioningReport(); result.setOperation(ResourceOperation.NONE); result.setAnyType(any == null ? null : any.getType().getKey()); result.setStatus(ProvisioningReport.Status.IGNORE); result.setKey(anyKey); profile.getResults().add(result); LOG.warn("Ignoring during push", e); return true; } catch (JobExecutionException e) { LOG.error("Push failed", e); return false; } }
protected final void doHandle(final Any<?> any) throws JobExecutionException { AnyUtils anyUtils = anyUtilsFactory.getInstance(any); ProvisioningReport result = new ProvisioningReport(); profile.getResults().add(result); result.setKey(any.getKey()); result.setAnyType(any.getType().getKey()); result.setName(getName(any)); Boolean enabled = any instanceof User && profile.getTask().isSyncStatus() ? ((User) any).isSuspended() ? Boolean.FALSE : Boolean.TRUE : null; LOG.debug( "Propagating {} with key {} towards {}", anyUtils.getAnyTypeKind(), any.getKey(), profile.getTask().getResource()); Object output = null; Result resultStatus = null; String operation = null; // Try to read remote object BEFORE any actual operation Provision provision = profile.getTask().getResource().getProvision(any.getType()); String connObjecKey = mappingUtils.getConnObjectKeyValue(any, provision); ConnectorObject beforeObj = getRemoteObject(connObjecKey, provision.getObjectClass()); Boolean status = profile.getTask().isSyncStatus() ? enabled : null; if (profile.isDryRun()) { if (beforeObj == null) { result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule())); } else { result.setOperation(getResourceOperation(profile.getTask().getMatchingRule())); } result.setStatus(ProvisioningReport.Status.SUCCESS); } else { try { if (beforeObj == null) { operation = UnmatchingRule.toEventName(profile.getTask().getUnmatchingRule()); result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule())); switch (profile.getTask().getUnmatchingRule()) { case ASSIGN: for (PushActions action : profile.getActions()) { action.beforeAssign(this.getProfile(), any); } if (!profile.getTask().isPerformCreate()) { LOG.debug("PushTask not configured for create"); } else { assign(any, status); } break; case PROVISION: for (PushActions action : profile.getActions()) { action.beforeProvision(this.getProfile(), any); } if (!profile.getTask().isPerformCreate()) { LOG.debug("PushTask not configured for create"); } else { provision(any, status); } break; case UNLINK: for (PushActions action : profile.getActions()) { action.beforeUnlink(this.getProfile(), any); } if (!profile.getTask().isPerformUpdate()) { LOG.debug("PushTask not configured for update"); } else { link(any, true); } break; case IGNORE: LOG.debug("Ignored any: {}", any); break; default: // do nothing } } else { operation = MatchingRule.toEventName(profile.getTask().getMatchingRule()); result.setOperation(getResourceOperation(profile.getTask().getMatchingRule())); switch (profile.getTask().getMatchingRule()) { case UPDATE: for (PushActions action : profile.getActions()) { action.beforeUpdate(this.getProfile(), any); } if (!profile.getTask().isPerformUpdate()) { LOG.debug("PushTask not configured for update"); } else { update(any, status); } break; case DEPROVISION: for (PushActions action : profile.getActions()) { action.beforeDeprovision(this.getProfile(), any); } if (!profile.getTask().isPerformDelete()) { LOG.debug("PushTask not configured for delete"); } else { deprovision(any); } break; case UNASSIGN: for (PushActions action : profile.getActions()) { action.beforeUnassign(this.getProfile(), any); } if (!profile.getTask().isPerformDelete()) { LOG.debug("PushTask not configured for delete"); } else { unassign(any); } break; case LINK: for (PushActions action : profile.getActions()) { action.beforeLink(this.getProfile(), any); } if (!profile.getTask().isPerformUpdate()) { LOG.debug("PushTask not configured for update"); } else { link(any, false); } break; case UNLINK: for (PushActions action : profile.getActions()) { action.beforeUnlink(this.getProfile(), any); } if (!profile.getTask().isPerformUpdate()) { LOG.debug("PushTask not configured for update"); } else { link(any, true); } break; case IGNORE: LOG.debug("Ignored any: {}", any); break; default: // do nothing } } for (PushActions action : profile.getActions()) { action.after(this.getProfile(), any, result); } result.setStatus(ProvisioningReport.Status.SUCCESS); resultStatus = AuditElements.Result.SUCCESS; output = getRemoteObject(connObjecKey, provision.getObjectClass()); } catch (IgnoreProvisionException e) { throw e; } catch (Exception e) { result.setStatus(ProvisioningReport.Status.FAILURE); result.setMessage(ExceptionUtils.getRootCauseMessage(e)); resultStatus = AuditElements.Result.FAILURE; output = e; LOG.warn("Error pushing {} towards {}", any, profile.getTask().getResource(), e); for (PushActions action : profile.getActions()) { action.onError(this.getProfile(), any, result, e); } throw new JobExecutionException(e); } finally { notificationManager.createTasks( AuditElements.EventCategoryType.PUSH, any.getType().getKind().name().toLowerCase(), profile.getTask().getResource().getKey(), operation, resultStatus, beforeObj, output, any); auditManager.audit( AuditElements.EventCategoryType.PUSH, any.getType().getKind().name().toLowerCase(), profile.getTask().getResource().getKey(), operation, resultStatus, connObjectUtils.getConnObjectTO(beforeObj), output instanceof ConnectorObject ? connObjectUtils.getConnObjectTO((ConnectorObject) output) : output, any); } } }