use of org.apache.syncope.core.provisioning.api.propagation.PropagationReporter in project syncope by apache.
the class DefaultGroupProvisioningManager method delete.
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Override
public List<PropagationStatus> delete(final String key, final Set<String> excludedResources, final boolean nullPriorityAsync) {
List<PropagationTaskTO> tasks = new ArrayList<>();
// Generate propagation tasks for deleting users and any objects from group resources,
// if they are on those resources only because of the reason being deleted (see SYNCOPE-357)
groupDataBinder.findUsersWithTransitiveResources(key).entrySet().forEach(entry -> {
tasks.addAll(propagationManager.getDeleteTasks(AnyTypeKind.USER, entry.getKey(), entry.getValue(), excludedResources));
});
groupDataBinder.findAnyObjectsWithTransitiveResources(key).entrySet().forEach(entry -> {
tasks.addAll(propagationManager.getDeleteTasks(AnyTypeKind.ANY_OBJECT, entry.getKey(), entry.getValue(), excludedResources));
});
// Generate propagation tasks for deleting this group from resources
tasks.addAll(propagationManager.getDeleteTasks(AnyTypeKind.GROUP, key, null, null));
PropagationReporter propagationReporter = taskExecutor.execute(tasks, nullPriorityAsync);
gwfAdapter.delete(key);
return propagationReporter.getStatuses();
}
use of org.apache.syncope.core.provisioning.api.propagation.PropagationReporter in project syncope by apache.
the class AbstractPropagationTaskExecutor method execute.
protected TaskExec execute(final PropagationTaskTO taskTO, final PropagationReporter reporter) {
PropagationTask task = entityFactory.newEntity(PropagationTask.class);
task.setResource(resourceDAO.find(taskTO.getResource()));
task.setObjectClassName(taskTO.getObjectClassName());
task.setAnyTypeKind(taskTO.getAnyTypeKind());
task.setAnyType(taskTO.getAnyType());
task.setEntityKey(taskTO.getEntityKey());
task.setOperation(taskTO.getOperation());
task.setConnObjectKey(taskTO.getConnObjectKey());
task.setOldConnObjectKey(taskTO.getOldConnObjectKey());
Set<Attribute> attributes = new HashSet<>();
if (StringUtils.isNotBlank(taskTO.getAttributes())) {
attributes.addAll(Arrays.asList(POJOHelper.deserialize(taskTO.getAttributes(), Attribute[].class)));
}
task.setAttributes(attributes);
List<PropagationActions> actions = getPropagationActions(task.getResource());
String resource = task.getResource().getKey();
Date start = new Date();
TaskExec execution = entityFactory.newEntity(TaskExec.class);
execution.setStatus(PropagationTaskExecStatus.CREATED.name());
String taskExecutionMessage = null;
String failureReason = null;
// Flag to state whether any propagation has been attempted
AtomicReference<Boolean> propagationAttempted = new AtomicReference<>(false);
ConnectorObject beforeObj = null;
ConnectorObject afterObj = null;
Provision provision = null;
OrgUnit orgUnit = null;
Uid uid = null;
Connector connector = null;
Result result;
try {
provision = task.getResource().getProvision(new ObjectClass(task.getObjectClassName())).orElse(null);
orgUnit = task.getResource().getOrgUnit();
connector = connFactory.getConnector(task.getResource());
// Try to read remote object BEFORE any actual operation
beforeObj = provision == null && orgUnit == null ? null : orgUnit == null ? getRemoteObject(task, connector, provision, false) : getRemoteObject(task, connector, orgUnit, false);
for (PropagationActions action : actions) {
action.before(task, beforeObj);
}
switch(task.getOperation()) {
case CREATE:
case UPDATE:
uid = createOrUpdate(task, beforeObj, connector, propagationAttempted);
break;
case DELETE:
uid = delete(task, beforeObj, connector, propagationAttempted);
break;
default:
}
execution.setStatus(propagationAttempted.get() ? PropagationTaskExecStatus.SUCCESS.name() : PropagationTaskExecStatus.NOT_ATTEMPTED.name());
LOG.debug("Successfully propagated to {}", task.getResource());
result = Result.SUCCESS;
} catch (Exception e) {
result = Result.FAILURE;
LOG.error("Exception during provision on resource " + resource, 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];
}
}
try {
execution.setStatus(PropagationTaskExecStatus.FAILURE.name());
} catch (Exception wft) {
LOG.error("While executing KO action on {}", execution, wft);
}
propagationAttempted.set(true);
actions.forEach(action -> {
action.onError(task, execution, e);
});
} finally {
// Try to read remote object AFTER any actual operation
if (connector != null) {
if (uid != null) {
task.setConnObjectKey(uid.getUidValue());
}
try {
afterObj = provision == null && orgUnit == null ? null : orgUnit == null ? getRemoteObject(task, connector, provision, true) : getRemoteObject(task, connector, orgUnit, true);
} catch (Exception ignore) {
// ignore exception
LOG.error("Error retrieving after object", ignore);
}
}
if (task.getOperation() != ResourceOperation.DELETE && afterObj == null && uid != null) {
afterObj = new ConnectorObjectBuilder().setObjectClass(new ObjectClass(task.getObjectClassName())).setUid(uid).setName(AttributeUtil.getNameFromAttributes(task.getAttributes())).build();
}
execution.setStart(start);
execution.setMessage(taskExecutionMessage);
execution.setEnd(new Date());
LOG.debug("Execution finished: {}", execution);
if (hasToBeregistered(task, execution)) {
LOG.debug("Execution to be stored: {}", execution);
execution.setTask(task);
task.add(execution);
taskDAO.save(task);
// needed to generate a value for the execution key
taskDAO.flush();
}
if (reporter != null) {
reporter.onSuccessOrNonPriorityResourceFailures(taskTO, PropagationTaskExecStatus.valueOf(execution.getStatus()), failureReason, beforeObj, afterObj);
}
}
for (PropagationActions action : actions) {
action.after(task, execution, afterObj);
}
// SYNCOPE-1136
String anyTypeKind = task.getAnyTypeKind() == null ? "realm" : task.getAnyTypeKind().name().toLowerCase();
String operation = task.getOperation().name().toLowerCase();
boolean notificationsAvailable = notificationManager.notificationsAvailable(AuditElements.EventCategoryType.PROPAGATION, anyTypeKind, resource, operation);
boolean auditRequested = auditManager.auditRequested(AuditElements.EventCategoryType.PROPAGATION, anyTypeKind, resource, operation);
if (notificationsAvailable || auditRequested) {
ExecTO execTO = taskDataBinder.getExecTO(execution);
notificationManager.createTasks(AuditElements.EventCategoryType.PROPAGATION, anyTypeKind, resource, operation, result, beforeObj, new Object[] { execTO, afterObj }, taskTO);
auditManager.audit(AuditElements.EventCategoryType.PROPAGATION, anyTypeKind, resource, operation, result, beforeObj, new Object[] { execTO, afterObj }, taskTO);
}
return execution;
}
use of org.apache.syncope.core.provisioning.api.propagation.PropagationReporter in project syncope by apache.
the class PriorityPropagationTaskExecutor method doExecute.
@Override
protected void doExecute(final Collection<PropagationTaskTO> tasks, final PropagationReporter reporter, final boolean nullPriorityAsync) {
Map<PropagationTaskTO, ExternalResource> taskToResource = tasks.stream().collect(Collectors.toMap(Function.identity(), task -> resourceDAO.find(task.getResource())));
List<PropagationTaskTO> prioritizedTasks = tasks.stream().filter(task -> taskToResource.get(task).getPropagationPriority() != null).collect(Collectors.toList());
Collections.sort(prioritizedTasks, new PriorityComparator(taskToResource));
LOG.debug("Propagation tasks sorted by priority, for serial execution: {}", prioritizedTasks);
Collection<PropagationTaskTO> concurrentTasks = tasks.stream().filter(task -> !prioritizedTasks.contains(task)).collect(Collectors.toSet());
LOG.debug("Propagation tasks for concurrent execution: {}", concurrentTasks);
// first process priority resources sequentially and fail as soon as any propagation failure is reported
prioritizedTasks.forEach(task -> {
TaskExec execution = null;
PropagationTaskExecStatus execStatus;
try {
execution = newPropagationTaskCallable(task, reporter).call();
execStatus = PropagationTaskExecStatus.valueOf(execution.getStatus());
} catch (Exception e) {
LOG.error("Unexpected exception", e);
execStatus = PropagationTaskExecStatus.FAILURE;
}
if (execStatus != PropagationTaskExecStatus.SUCCESS) {
throw new PropagationException(task.getResource(), execution == null ? null : execution.getMessage());
}
});
// then process non-priority resources concurrently...
CompletionService<TaskExec> completionService = new ExecutorCompletionService<>(executor);
Map<PropagationTaskTO, Future<TaskExec>> nullPriority = new HashMap<>(concurrentTasks.size());
concurrentTasks.forEach(task -> {
try {
nullPriority.put(task, completionService.submit(newPropagationTaskCallable(task, reporter)));
} catch (Exception e) {
LOG.error("Unexpected exception", e);
}
});
// ...waiting for all callables to complete, if async processing was not required
if (!nullPriority.isEmpty()) {
if (nullPriorityAsync) {
nullPriority.forEach((task, exec) -> {
reporter.onSuccessOrNonPriorityResourceFailures(task, PropagationTaskExecStatus.CREATED, null, null, null);
});
} else {
final Set<Future<TaskExec>> nullPriorityFutures = new HashSet<>(nullPriority.values());
try {
executor.submit(() -> {
while (!nullPriorityFutures.isEmpty()) {
try {
nullPriorityFutures.remove(completionService.take());
} catch (Exception e) {
LOG.error("Unexpected exception", e);
}
}
}).get(60, TimeUnit.SECONDS);
} catch (Exception e) {
LOG.error("Unexpected exception", e);
} finally {
nullPriorityFutures.forEach(future -> {
future.cancel(true);
});
nullPriorityFutures.clear();
nullPriority.clear();
}
}
}
}
use of org.apache.syncope.core.provisioning.api.propagation.PropagationReporter in project syncope by apache.
the class ProvisionProducer method process.
@SuppressWarnings("unchecked")
@Override
public void process(final Exchange exchange) throws Exception {
String key = exchange.getIn().getBody(String.class);
List<String> resources = exchange.getProperty("resources", List.class);
Boolean nullPriorityAsync = exchange.getProperty("nullPriorityAsync", Boolean.class);
if (getAnyTypeKind() == AnyTypeKind.USER) {
Boolean changePwd = exchange.getProperty("changePwd", Boolean.class);
String password = exchange.getProperty("password", String.class);
UserPatch userPatch = new UserPatch();
userPatch.setKey(key);
userPatch.getResources().addAll(resources.stream().map(resource -> new StringPatchItem.Builder().operation(PatchOperation.ADD_REPLACE).value(resource).build()).collect(Collectors.toList()));
if (changePwd) {
userPatch.setPassword(new PasswordPatch.Builder().onSyncope(true).value(password).resources(resources).build());
}
PropagationByResource propByRes = new PropagationByResource();
propByRes.addAll(ResourceOperation.UPDATE, resources);
WorkflowResult<Pair<UserPatch, Boolean>> wfResult = new WorkflowResult<>(ImmutablePair.of(userPatch, (Boolean) null), propByRes, "update");
List<PropagationTaskTO> tasks = getPropagationManager().getUserUpdateTasks(wfResult, changePwd, null);
PropagationReporter propagationReporter = getPropagationTaskExecutor().execute(tasks, nullPriorityAsync);
exchange.getOut().setBody(propagationReporter.getStatuses());
} else {
PropagationByResource propByRes = new PropagationByResource();
propByRes.addAll(ResourceOperation.UPDATE, resources);
AnyTypeKind anyTypeKind = AnyTypeKind.GROUP;
if (getAnyTypeKind() != null) {
anyTypeKind = getAnyTypeKind();
}
List<PropagationTaskTO> tasks = getPropagationManager().getUpdateTasks(anyTypeKind, key, false, null, propByRes, null, null);
PropagationReporter propagationReporter = getPropagationTaskExecutor().execute(tasks, nullPriorityAsync);
exchange.getOut().setBody(propagationReporter.getStatuses());
}
}
use of org.apache.syncope.core.provisioning.api.propagation.PropagationReporter in project syncope by apache.
the class DefaultRealmPushResultHandler method update.
private Realm update(final RealmTO realmTO, final ProvisioningReport result) {
Realm realm = realmDAO.findByFullPath(realmTO.getFullPath());
PropagationByResource propByRes = binder.update(realm, realmTO);
realm = realmDAO.save(realm);
PropagationReporter reporter = taskExecutor.execute(propagationManager.createTasks(realm, propByRes, null), false);
reportPropagation(result, reporter);
return realm;
}
Aggregations