blob: a26e156af84f954089bc9e09b7fbf349ee0ec1c5 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.syncope.core.provisioning.java.pushpull;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.OrgUnit;
import org.apache.syncope.common.lib.to.ProvisioningReport;
import org.apache.syncope.common.lib.to.RealmTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.AuditElements;
import org.apache.syncope.common.lib.types.AuditElements.Result;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.MatchingRule;
import org.apache.syncope.common.lib.types.PullMode;
import org.apache.syncope.common.lib.types.ResourceOperation;
import org.apache.syncope.common.lib.types.UnmatchingRule;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.dao.CASSPClientAppDAO;
import org.apache.syncope.core.persistence.api.dao.OIDCRPClientAppDAO;
import org.apache.syncope.core.persistence.api.dao.SAML2SPClientAppDAO;
import org.apache.syncope.core.persistence.api.dao.TaskDAO;
import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
import org.apache.syncope.core.persistence.api.dao.search.AttrCond;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.api.entity.task.PullTask;
import org.apache.syncope.core.provisioning.api.PropagationByResource;
import org.apache.syncope.core.provisioning.api.job.JobExecutionException;
import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskInfo;
import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
import org.apache.syncope.core.provisioning.api.pushpull.RealmPullResultHandler;
import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.SyncDelta;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
@Transactional(rollbackFor = Throwable.class)
public class DefaultRealmPullResultHandler
extends AbstractRealmResultHandler<PullTask, PullActions>
implements RealmPullResultHandler {
protected static Result and(final Result left, final Result right) {
return left == Result.SUCCESS && right == Result.SUCCESS
? Result.SUCCESS
: Result.FAILURE;
}
@Autowired
protected InboundMatcher inboundMatcher;
@Autowired
protected ConnObjectUtils connObjectUtils;
@Autowired
protected AnySearchDAO searchDAO;
@Autowired
protected TaskDAO taskDAO;
@Autowired
protected CASSPClientAppDAO casSPClientAppDAO;
@Autowired
protected OIDCRPClientAppDAO oidcRPClientAppDAO;
@Autowired
protected SAML2SPClientAppDAO saml2SPClientAppDAO;
@Override
public boolean handle(final SyncDelta delta) {
try {
OrgUnit orgUnit = Optional.ofNullable(profile.getTask().getResource().getOrgUnit()).
orElseThrow(() -> new JobExecutionException(
"No orgUnit found on " + profile.getTask().getResource() + " for "
+ delta.getObject().getObjectClass()));
Result latestResult = doHandle(delta, orgUnit);
LOG.debug("Successfully handled {}", delta);
if (profile.getTask().getPullMode() != PullMode.INCREMENTAL) {
return true;
}
return latestResult == Result.SUCCESS;
} catch (IgnoreProvisionException e) {
ProvisioningReport ignoreResult = new ProvisioningReport();
ignoreResult.setOperation(ResourceOperation.NONE);
ignoreResult.setStatus(ProvisioningReport.Status.IGNORE);
ignoreResult.setAnyType(SyncopeConstants.REALM_ANYTYPE);
ignoreResult.setKey(null);
ignoreResult.setName(delta.getObject().getName().getNameValue());
profile.getResults().add(ignoreResult);
LOG.warn("Ignoring during pull", e);
return true;
} catch (JobExecutionException e) {
LOG.error("Pull failed", e);
return false;
}
}
protected void throwIgnoreProvisionException(final SyncDelta delta, final Exception exception)
throws JobExecutionException {
if (exception instanceof IgnoreProvisionException) {
throw IgnoreProvisionException.class.cast(exception);
}
IgnoreProvisionException ipe = null;
for (PullActions action : profile.getActions()) {
if (ipe == null) {
ipe = action.onError(profile, delta, exception);
}
}
if (ipe != null) {
throw ipe;
}
}
protected Result assign(final SyncDelta delta, final OrgUnit orgUnit)
throws JobExecutionException {
if (!profile.getTask().isPerformCreate()) {
LOG.debug("PullTask not configured for create");
end(UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), Result.SUCCESS, null, null, delta);
return Result.SUCCESS;
}
RealmTO realmTO = connObjectUtils.getRealmTO(delta.getObject(), orgUnit);
if (realmTO.getFullPath() == null) {
if (realmTO.getParent() == null) {
realmTO.setParent(profile.getTask().getDestinationRealm().getFullPath());
}
realmTO.setFullPath(realmTO.getParent() + '/' + realmTO.getName());
}
realmTO.getResources().add(profile.getTask().getResource().getKey());
ProvisioningReport result = new ProvisioningReport();
result.setOperation(ResourceOperation.CREATE);
result.setAnyType(SyncopeConstants.REALM_ANYTYPE);
result.setStatus(ProvisioningReport.Status.SUCCESS);
result.setName(realmTO.getFullPath());
if (profile.isDryRun()) {
result.setKey(null);
end(UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), Result.SUCCESS, null, null, delta);
return Result.SUCCESS;
}
for (PullActions action : profile.getActions()) {
action.beforeAssign(profile, delta, realmTO);
}
profile.getResults().add(result);
return create(realmTO, delta, UnmatchingRule.ASSIGN, result);
}
protected Result provision(final SyncDelta delta, final OrgUnit orgUnit)
throws JobExecutionException {
if (!profile.getTask().isPerformCreate()) {
LOG.debug("PullTask not configured for create");
end(UnmatchingRule.toEventName(UnmatchingRule.PROVISION), Result.SUCCESS, null, null, delta);
return Result.SUCCESS;
}
RealmTO realmTO = connObjectUtils.getRealmTO(delta.getObject(), orgUnit);
if (realmTO.getFullPath() == null) {
if (realmTO.getParent() == null) {
realmTO.setParent(profile.getTask().getDestinationRealm().getFullPath());
}
realmTO.setFullPath(realmTO.getParent() + '/' + realmTO.getName());
}
ProvisioningReport result = new ProvisioningReport();
result.setOperation(ResourceOperation.CREATE);
result.setAnyType(SyncopeConstants.REALM_ANYTYPE);
result.setStatus(ProvisioningReport.Status.SUCCESS);
result.setName(realmTO.getFullPath());
if (profile.isDryRun()) {
result.setKey(null);
end(UnmatchingRule.toEventName(UnmatchingRule.PROVISION), Result.SUCCESS, null, null, delta);
return Result.SUCCESS;
}
for (PullActions action : profile.getActions()) {
action.beforeProvision(profile, delta, realmTO);
}
profile.getResults().add(result);
return create(realmTO, delta, UnmatchingRule.PROVISION, result);
}
protected Result create(
final RealmTO realmTO,
final SyncDelta delta,
final UnmatchingRule unmatchingRule,
final ProvisioningReport result)
throws JobExecutionException {
Object output;
Result resultStatus;
try {
Realm realm = realmDAO.save(binder.create(profile.getTask().getDestinationRealm(), realmTO));
PropagationByResource<String> propByRes = new PropagationByResource<>();
propByRes.addAll(ResourceOperation.CREATE, realm.getResourceKeys());
if (unmatchingRule == UnmatchingRule.ASSIGN) {
List<PropagationTaskInfo> taskInfos = propagationManager.createTasks(realm, propByRes, null);
taskExecutor.execute(taskInfos, false, securityProperties.getAdminUser());
}
RealmTO actual = binder.getRealmTO(realm, true);
result.setKey(actual.getKey());
result.setName(profile.getTask().getDestinationRealm().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;
}
end(UnmatchingRule.toEventName(unmatchingRule), resultStatus, null, output, delta);
return resultStatus;
}
protected Result update(final SyncDelta delta, final List<Realm> realms, final boolean inLink)
throws JobExecutionException {
if (!profile.getTask().isPerformUpdate()) {
LOG.debug("PullTask not configured for update");
end(MatchingRule.toEventName(MatchingRule.UPDATE), Result.SUCCESS, null, null, delta);
return Result.SUCCESS;
}
LOG.debug("About to update {}", realms);
Result global = Result.SUCCESS;
for (Realm realm : realms) {
LOG.debug("About to update {}", realm);
ProvisioningReport result = new ProvisioningReport();
result.setOperation(ResourceOperation.UPDATE);
result.setAnyType(SyncopeConstants.REALM_ANYTYPE);
result.setStatus(ProvisioningReport.Status.SUCCESS);
result.setKey(realm.getKey());
result.setName(realm.getFullPath());
if (!profile.isDryRun()) {
Result resultStatus;
Object output;
RealmTO before = binder.getRealmTO(realm, true);
try {
if (!inLink) {
for (PullActions action : profile.getActions()) {
action.beforeUpdate(profile, delta, before, null);
}
}
Map<Pair<String, String>, Set<Attribute>> beforeAttrs = propagationManager.prepareAttrs(realm);
PropagationByResource<String> propByRes = binder.update(realm, before);
realm = realmDAO.save(realm);
RealmTO updated = binder.getRealmTO(realm, true);
List<PropagationTaskInfo> taskInfos = propagationManager.setAttributeDeltas(
propagationManager.createTasks(realm, propByRes, null),
beforeAttrs,
null);
taskExecutor.execute(taskInfos, false, securityProperties.getAdminUser());
for (PullActions action : profile.getActions()) {
action.after(profile, delta, updated, result);
}
output = updated;
resultStatus = Result.SUCCESS;
result.setName(updated.getFullPath());
LOG.debug("{} successfully updated", updated);
} 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 update Realm {}", delta.getUid().getUidValue(), e);
output = e;
resultStatus = Result.FAILURE;
}
end(MatchingRule.toEventName(MatchingRule.UPDATE), resultStatus, before, output, delta);
global = and(global, resultStatus);
}
profile.getResults().add(result);
}
return global;
}
protected Result deprovision(final SyncDelta delta, final List<Realm> realms, final boolean unlink)
throws JobExecutionException {
if (!profile.getTask().isPerformUpdate()) {
LOG.debug("PullTask not configured for update");
end(unlink
? MatchingRule.toEventName(MatchingRule.UNASSIGN)
: MatchingRule.toEventName(MatchingRule.DEPROVISION), Result.SUCCESS, null, null, delta);
return Result.SUCCESS;
}
LOG.debug("About to deprovision {}", realms);
Result global = Result.SUCCESS;
for (Realm realm : realms) {
LOG.debug("About to unassign resource {}", realm);
ProvisioningReport result = new ProvisioningReport();
result.setOperation(ResourceOperation.DELETE);
result.setAnyType(SyncopeConstants.REALM_ANYTYPE);
result.setStatus(ProvisioningReport.Status.SUCCESS);
result.setKey(realm.getKey());
result.setName(realm.getFullPath());
if (!profile.isDryRun()) {
Object output;
Result resultStatus;
RealmTO before = binder.getRealmTO(realm, true);
try {
if (unlink) {
for (PullActions action : profile.getActions()) {
action.beforeUnassign(profile, delta, before);
}
} else {
for (PullActions action : profile.getActions()) {
action.beforeDeprovision(profile, delta, before);
}
}
PropagationByResource<String> propByRes = new PropagationByResource<>();
propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
taskExecutor.execute(
propagationManager.createTasks(realm, propByRes, null),
false, securityProperties.getAdminUser());
RealmTO realmTO;
if (unlink) {
realm.getResources().remove(profile.getTask().getResource());
realmTO = binder.getRealmTO(realmDAO.save(realm), true);
} else {
realmTO = binder.getRealmTO(realm, true);
}
output = realmTO;
for (PullActions action : profile.getActions()) {
action.after(profile, delta, realmTO, result);
}
resultStatus = Result.SUCCESS;
LOG.debug("{} successfully updated", realm);
} 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 update Realm {}", delta.getUid().getUidValue(), e);
output = e;
resultStatus = Result.FAILURE;
}
end(unlink
? MatchingRule.toEventName(MatchingRule.UNASSIGN)
: MatchingRule.toEventName(MatchingRule.DEPROVISION),
resultStatus, before, output, delta);
global = and(global, resultStatus);
}
profile.getResults().add(result);
}
return global;
}
protected Result link(final SyncDelta delta, final List<Realm> realms, final boolean unlink)
throws JobExecutionException {
if (!profile.getTask().isPerformUpdate()) {
LOG.debug("PullTask not configured for update");
end(unlink
? MatchingRule.toEventName(MatchingRule.UNLINK)
: MatchingRule.toEventName(MatchingRule.LINK), Result.SUCCESS, null, null, delta);
return Result.SUCCESS;
}
LOG.debug("About to link {}", realms);
Result global = Result.SUCCESS;
for (Realm realm : realms) {
LOG.debug("About to unassign resource {}", realm);
ProvisioningReport result = new ProvisioningReport();
result.setOperation(ResourceOperation.NONE);
result.setAnyType(SyncopeConstants.REALM_ANYTYPE);
result.setStatus(ProvisioningReport.Status.SUCCESS);
result.setKey(realm.getKey());
result.setName(realm.getFullPath());
if (!profile.isDryRun()) {
Object output;
Result resultStatus;
RealmTO before = binder.getRealmTO(realm, true);
try {
if (unlink) {
for (PullActions action : profile.getActions()) {
action.beforeUnlink(profile, delta, before);
}
} else {
for (PullActions action : profile.getActions()) {
action.beforeLink(profile, delta, before);
}
}
if (unlink) {
realm.getResources().remove(profile.getTask().getResource());
} else {
realm.add(profile.getTask().getResource());
}
output = update(delta, List.of(realm), true);
resultStatus = Result.SUCCESS;
LOG.debug("{} successfully updated", realm);
} 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 update Realm {}", delta.getUid().getUidValue(), e);
output = e;
resultStatus = Result.FAILURE;
}
end(unlink
? MatchingRule.toEventName(MatchingRule.UNLINK)
: MatchingRule.toEventName(MatchingRule.LINK),
resultStatus, before, output, delta);
global = and(global, resultStatus);
}
profile.getResults().add(result);
}
return global;
}
protected Result delete(final SyncDelta delta, final List<Realm> realms)
throws JobExecutionException {
if (!profile.getTask().isPerformDelete()) {
LOG.debug("PullTask not configured for delete");
end(ResourceOperation.DELETE.name().toLowerCase(), Result.SUCCESS, null, null, delta);
return Result.SUCCESS;
}
LOG.debug("About to delete {}", realms);
Result global = Result.SUCCESS;
for (Realm realm : realms) {
Object output;
Result resultStatus = Result.FAILURE;
ProvisioningReport result = new ProvisioningReport();
RealmTO before = binder.getRealmTO(realm, true);
try {
result.setKey(realm.getKey());
result.setName(realm.getFullPath());
result.setOperation(ResourceOperation.DELETE);
result.setAnyType(SyncopeConstants.REALM_ANYTYPE);
result.setStatus(ProvisioningReport.Status.SUCCESS);
if (!profile.isDryRun()) {
for (PullActions action : profile.getActions()) {
action.beforeDelete(profile, delta, before);
}
try {
if (!realmSearchDAO.findChildren(realm).isEmpty()) {
throw SyncopeClientException.build(ClientExceptionType.RealmContains);
}
Set<String> adminRealms = Set.of(realm.getFullPath());
AnyCond keyCond = new AnyCond(AttrCond.Type.ISNOTNULL);
keyCond.setSchema("key");
SearchCond allMatchingCond = SearchCond.getLeaf(keyCond);
long users = searchDAO.count(
realmDAO.getRoot(), true, adminRealms, allMatchingCond, AnyTypeKind.USER);
long groups = searchDAO.count(
realmDAO.getRoot(), true, adminRealms, allMatchingCond, AnyTypeKind.GROUP);
long anyObjects = searchDAO.count(
realmDAO.getRoot(), true, adminRealms, allMatchingCond, AnyTypeKind.ANY_OBJECT);
long macroTasks = taskDAO.findByRealm(realm).size();
long clientApps = casSPClientAppDAO.findAllByRealm(realm).size()
+ saml2SPClientAppDAO.findAllByRealm(realm).size()
+ oidcRPClientAppDAO.findAllByRealm(realm).size();
if (users + groups + anyObjects + macroTasks + clientApps > 0) {
SyncopeClientException realmContains =
SyncopeClientException.build(ClientExceptionType.RealmContains);
realmContains.getElements().add(users + " user(s)");
realmContains.getElements().add(groups + " group(s)");
realmContains.getElements().add(anyObjects + " anyObject(s)");
realmContains.getElements().add(macroTasks + " command task(s)");
realmContains.getElements().add(clientApps + " client app(s)");
throw realmContains;
}
PropagationByResource<String> propByRes = new PropagationByResource<>();
propByRes.addAll(ResourceOperation.DELETE, realm.getResourceKeys());
List<PropagationTaskInfo> taskInfos = propagationManager.createTasks(realm, propByRes, null);
taskExecutor.execute(taskInfos, false, securityProperties.getAdminUser());
realmDAO.delete(realm);
output = null;
resultStatus = Result.SUCCESS;
for (PullActions action : profile.getActions()) {
action.after(profile, delta, before, result);
}
} catch (Exception e) {
throwIgnoreProvisionException(delta, e);
result.setStatus(ProvisioningReport.Status.FAILURE);
result.setMessage(ExceptionUtils.getRootCauseMessage(e));
LOG.error("Could not delete {}", realm, e);
output = e;
}
end(ResourceOperation.DELETE.name().toLowerCase(), resultStatus, before, output, delta);
global = and(global, resultStatus);
}
profile.getResults().add(result);
} catch (DelegatedAdministrationException e) {
LOG.error("Not allowed to read Realm {}", realm, e);
} catch (Exception e) {
LOG.error("Could not delete Realm {}", realm, e);
}
}
return global;
}
protected Result ignore(final SyncDelta delta, final boolean matching) throws JobExecutionException {
LOG.debug("Any to ignore {}", delta.getObject().getUid().getUidValue());
ProvisioningReport report = new ProvisioningReport();
report.setKey(null);
report.setName(delta.getObject().getUid().getUidValue());
report.setOperation(ResourceOperation.NONE);
report.setAnyType(SyncopeConstants.REALM_ANYTYPE);
report.setStatus(ProvisioningReport.Status.SUCCESS);
profile.getResults().add(report);
if (!profile.isDryRun()) {
end(matching
? MatchingRule.toEventName(MatchingRule.IGNORE)
: UnmatchingRule.toEventName(UnmatchingRule.IGNORE), Result.SUCCESS, null, null, delta);
return Result.SUCCESS;
}
return Result.SUCCESS;
}
protected Result doHandle(final SyncDelta delta, final OrgUnit orgUnit) throws JobExecutionException {
LOG.debug("Process {} for {} as {}",
delta.getDeltaType(), delta.getUid().getUidValue(), delta.getObject().getObjectClass());
SyncDelta finalDelta = delta;
for (PullActions action : profile.getActions()) {
finalDelta = action.preprocess(profile, finalDelta);
}
LOG.debug("Transformed {} for {} as {}",
finalDelta.getDeltaType(), finalDelta.getUid().getUidValue(), finalDelta.getObject().getObjectClass());
List<Realm> realms = inboundMatcher.match(finalDelta, orgUnit);
LOG.debug("Match found for {} as {}: {}",
finalDelta.getUid().getUidValue(), finalDelta.getObject().getObjectClass(), realms);
if (realms.size() > 1) {
switch (profile.getConflictResolutionAction()) {
case IGNORE:
throw new IgnoreProvisionException("More than one match found for "
+ finalDelta.getObject().getUid().getUidValue() + ": " + realms);
case FIRSTMATCH:
realms = realms.subList(0, 1);
break;
case LASTMATCH:
realms = realms.subList(realms.size() - 1, realms.size());
break;
default:
// keep keys unmodified
}
}
Result result = Result.SUCCESS;
try {
switch (delta.getDeltaType()) {
case CREATE:
case UPDATE:
case CREATE_OR_UPDATE:
if (realms.isEmpty()) {
switch (profile.getTask().getUnmatchingRule()) {
case ASSIGN:
result = assign(finalDelta, orgUnit);
break;
case PROVISION:
result = provision(finalDelta, orgUnit);
break;
case IGNORE:
result = ignore(finalDelta, false);
break;
default:
// do nothing
}
} else {
switch (profile.getTask().getMatchingRule()) {
case UPDATE:
result = update(finalDelta, realms, false);
break;
case DEPROVISION:
result = deprovision(finalDelta, realms, false);
break;
case UNASSIGN:
result = deprovision(finalDelta, realms, true);
break;
case LINK:
result = link(finalDelta, realms, false);
break;
case UNLINK:
result = link(finalDelta, realms, true);
break;
case IGNORE:
result = ignore(finalDelta, true);
break;
default:
// do nothing
}
}
break;
case DELETE:
if (realms.isEmpty()) {
end(ResourceOperation.DELETE.name().toLowerCase(), Result.SUCCESS, null, null, finalDelta);
LOG.debug("No match found for deletion");
} else {
result = delete(finalDelta, realms);
}
break;
default:
}
} catch (IllegalStateException | IllegalArgumentException e) {
LOG.warn(e.getMessage());
}
return result;
}
protected void end(
final String event,
final Result result,
final Object before,
final Object output,
final SyncDelta delta) {
notificationManager.createTasks(
AuthContextUtils.getWho(),
AuditElements.EventCategoryType.PULL,
SyncopeConstants.REALM_ANYTYPE.toLowerCase(),
profile.getTask().getResource().getKey(),
event,
result,
before,
output,
delta);
auditManager.audit(
AuthContextUtils.getWho(),
AuditElements.EventCategoryType.PULL,
SyncopeConstants.REALM_ANYTYPE.toLowerCase(),
profile.getTask().getResource().getKey(),
event,
result,
before,
output,
delta);
}
}