use of org.apache.syncope.common.lib.to.PropagationTaskTO in project syncope by apache.
the class TaskDataBinderImpl method getTaskTO.
@Override
public <T extends TaskTO> T getTaskTO(final Task task, final TaskUtils taskUtils, final boolean details) {
T taskTO = taskUtils.newTaskTO();
BeanUtils.copyProperties(task, taskTO, IGNORE_TASK_PROPERTIES);
TaskExec latestExec = taskExecDAO.findLatestStarted(task);
if (latestExec == null) {
taskTO.setLatestExecStatus(StringUtils.EMPTY);
} else {
taskTO.setLatestExecStatus(latestExec.getStatus());
taskTO.setStart(latestExec.getStart());
taskTO.setEnd(latestExec.getEnd());
}
if (details) {
task.getExecs().stream().filter(execution -> execution != null).forEachOrdered(execution -> taskTO.getExecutions().add(getExecTO(execution)));
}
switch(taskUtils.getType()) {
case PROPAGATION:
PropagationTask propagationTask = (PropagationTask) task;
PropagationTaskTO propagationTaskTO = (PropagationTaskTO) taskTO;
propagationTaskTO.setAnyTypeKind(propagationTask.getAnyTypeKind());
propagationTaskTO.setEntityKey(propagationTask.getEntityKey());
propagationTaskTO.setResource(propagationTask.getResource().getKey());
propagationTaskTO.setAttributes(propagationTask.getSerializedAttributes());
break;
case SCHEDULED:
SchedTask schedTask = (SchedTask) task;
SchedTaskTO schedTaskTO = (SchedTaskTO) taskTO;
setExecTime(schedTaskTO, task);
if (schedTask.getJobDelegate() != null) {
schedTaskTO.setJobDelegate(schedTask.getJobDelegate().getKey());
}
break;
case PULL:
PullTask pullTask = (PullTask) task;
PullTaskTO pullTaskTO = (PullTaskTO) taskTO;
setExecTime(pullTaskTO, task);
pullTaskTO.setDestinationRealm(pullTask.getDestinatioRealm().getFullPath());
pullTaskTO.setResource(pullTask.getResource().getKey());
pullTaskTO.setMatchingRule(pullTask.getMatchingRule() == null ? MatchingRule.UPDATE : pullTask.getMatchingRule());
pullTaskTO.setUnmatchingRule(pullTask.getUnmatchingRule() == null ? UnmatchingRule.PROVISION : pullTask.getUnmatchingRule());
if (pullTask.getReconFilterBuilder() != null) {
pullTaskTO.setReconFilterBuilder(pullTask.getReconFilterBuilder().getKey());
}
pullTaskTO.getActions().addAll(pullTask.getActions().stream().map(Entity::getKey).collect(Collectors.toList()));
pullTask.getTemplates().forEach(template -> {
pullTaskTO.getTemplates().put(template.getAnyType().getKey(), template.get());
});
pullTaskTO.setRemediation(pullTask.isRemediation());
break;
case PUSH:
PushTask pushTask = (PushTask) task;
PushTaskTO pushTaskTO = (PushTaskTO) taskTO;
setExecTime(pushTaskTO, task);
pushTaskTO.setSourceRealm(pushTask.getSourceRealm().getFullPath());
pushTaskTO.setResource(pushTask.getResource().getKey());
pushTaskTO.setMatchingRule(pushTask.getMatchingRule() == null ? MatchingRule.LINK : pushTask.getMatchingRule());
pushTaskTO.setUnmatchingRule(pushTask.getUnmatchingRule() == null ? UnmatchingRule.ASSIGN : pushTask.getUnmatchingRule());
pushTaskTO.getActions().addAll(pushTask.getActions().stream().map(Entity::getKey).collect(Collectors.toList()));
pushTask.getFilters().forEach(filter -> {
pushTaskTO.getFilters().put(filter.getAnyType().getKey(), filter.getFIQLCond());
});
break;
case NOTIFICATION:
NotificationTask notificationTask = (NotificationTask) task;
NotificationTaskTO notificationTaskTO = (NotificationTaskTO) taskTO;
notificationTaskTO.setNotification(notificationTask.getNotification().getKey());
notificationTaskTO.setAnyTypeKind(notificationTask.getAnyTypeKind());
notificationTaskTO.setEntityKey(notificationTask.getEntityKey());
if (notificationTask.isExecuted() && StringUtils.isBlank(taskTO.getLatestExecStatus())) {
taskTO.setLatestExecStatus("[EXECUTED]");
}
break;
default:
}
return taskTO;
}
use of org.apache.syncope.common.lib.to.PropagationTaskTO 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.common.lib.to.PropagationTaskTO 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.common.lib.to.PropagationTaskTO in project syncope by apache.
the class UserWorkflowLogic method executeWorkflowTask.
@PreAuthorize("hasRole('" + StandardEntitlement.USER_UPDATE + "')")
public UserTO executeWorkflowTask(final UserTO userTO, final String taskId) {
WorkflowResult<String> updated = uwfAdapter.execute(userTO, taskId);
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
List<PropagationTaskTO> tasks = propagationManager.getUserUpdateTasks(new WorkflowResult<>(Pair.<UserPatch, Boolean>of(userPatch, null), updated.getPropByRes(), updated.getPerformedTasks()));
taskExecutor.execute(tasks, false);
return binder.getUserTO(updated.getResult());
}
use of org.apache.syncope.common.lib.to.PropagationTaskTO in project syncope by apache.
the class DefaultRealmPullResultHandler method create.
private void create(final RealmTO realmTO, final SyncDelta delta, final String operation, final ProvisioningReport result) throws JobExecutionException {
Object output;
Result resultStatus;
try {
Realm realm = realmDAO.save(binder.create(profile.getTask().getDestinatioRealm(), realmTO));
PropagationByResource propByRes = new PropagationByResource();
for (String resource : realm.getResourceKeys()) {
propByRes.add(ResourceOperation.CREATE, resource);
}
List<PropagationTaskTO> tasks = propagationManager.createTasks(realm, propByRes, null);
taskExecutor.execute(tasks, false);
RealmTO actual = binder.getRealmTO(realm, true);
result.setKey(actual.getKey());
result.setName(profile.getTask().getDestinatioRealm().getFullPath() + "/" + actual.getName());
output = actual;
resultStatus = Result.SUCCESS;
for (PullActions action : profile.getActions()) {
action.after(profile, delta, actual, result);
}
LOG.debug("Realm {} successfully created", actual.getKey());
} catch (PropagationException e) {
// A propagation failure doesn't imply a pull failure.
// The propagation exception status will be reported into the propagation task execution.
LOG.error("Could not propagate Realm {}", delta.getUid().getUidValue(), e);
output = e;
resultStatus = Result.FAILURE;
} catch (Exception e) {
throwIgnoreProvisionException(delta, e);
result.setStatus(ProvisioningReport.Status.FAILURE);
result.setMessage(ExceptionUtils.getRootCauseMessage(e));
LOG.error("Could not create Realm {} ", delta.getUid().getUidValue(), e);
output = e;
resultStatus = Result.FAILURE;
}
finalize(operation, resultStatus, null, output, delta);
}
Aggregations