You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2017/09/22 08:15:52 UTC
[1/6] syncope git commit: [SYNCOPE-1212] Clearing and refactoring for
easier extensions
Repository: syncope
Updated Branches:
refs/heads/2_0_X 8ae705731 -> 4661b8cc0
refs/heads/master 9e24b8eeb -> 9c289134b
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
deleted file mode 100644
index c4be4e2..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
+++ /dev/null
@@ -1,795 +0,0 @@
-/*
- * 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.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.syncope.common.lib.SyncopeClientException;
-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.core.provisioning.api.PropagationByResource;
-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.search.AnyCond;
-import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
-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.resource.OrgUnit;
-import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
-import org.apache.syncope.core.persistence.api.entity.task.PullTask;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
-import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
-import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
-import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullExecutor;
-import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullResultHandler;
-import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
-import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.identityconnectors.framework.common.objects.SyncDeltaType;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional(rollbackFor = Throwable.class)
-public class RealmPullResultHandlerImpl
- extends AbstractRealmResultHandler<PullTask, PullActions>
- implements SyncopePullResultHandler {
-
- @Autowired
- private PullUtils pullUtils;
-
- @Autowired
- private ConnObjectUtils connObjectUtils;
-
- @Autowired
- private AnySearchDAO searchDAO;
-
- private SyncopePullExecutor executor;
-
- private Result latestResult;
-
- @Override
- public void setPullExecutor(final SyncopePullExecutor executor) {
- this.executor = executor;
- }
-
- @Override
- public boolean handle(final SyncDelta delta) {
- try {
- OrgUnit orgUnit = profile.getTask().getResource().getOrgUnit();
- if (orgUnit == null) {
- throw new JobExecutionException("No orgUnit found on " + profile.getTask().getResource() + " for "
- + delta.getObject().getObjectClass());
- }
-
- doHandle(delta, orgUnit);
-
- LOG.debug("Successfully handled {}", delta);
-
- if (profile.getTask().getPullMode() != PullMode.INCREMENTAL) {
- return true;
- }
-
- boolean shouldContinue;
- synchronized (this) {
- shouldContinue = latestResult == Result.SUCCESS;
- this.latestResult = null;
- }
- if (shouldContinue) {
- executor.setLatestSyncToken(delta.getObjectClass(), delta.getToken());
- }
- return shouldContinue;
- } catch (IgnoreProvisionException e) {
- ProvisioningReport ignoreResult = new ProvisioningReport();
- ignoreResult.setOperation(ResourceOperation.NONE);
- ignoreResult.setStatus(ProvisioningReport.Status.IGNORE);
- ignoreResult.setAnyType(REALM_TYPE);
- ignoreResult.setKey(null);
- ignoreResult.setName(delta.getObject().getName().getNameValue());
- profile.getResults().add(ignoreResult);
-
- LOG.warn("Ignoring during pull", e);
-
- executor.setLatestSyncToken(delta.getObjectClass(), delta.getToken());
-
- return true;
- } catch (JobExecutionException e) {
- LOG.error("Pull failed", e);
-
- return false;
- }
- }
-
- private List<ProvisioningReport> assign(final SyncDelta delta, final OrgUnit orgUnit) throws JobExecutionException {
- if (!profile.getTask().isPerformCreate()) {
- LOG.debug("PullTask not configured for create");
- finalize(UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), Result.SUCCESS, null, null, delta);
- return Collections.<ProvisioningReport>emptyList();
- }
-
- RealmTO realmTO = connObjectUtils.getRealmTO(delta.getObject(), profile.getTask(), orgUnit);
- if (realmTO.getFullPath() == null) {
- if (realmTO.getParent() == null) {
- realmTO.setParent(profile.getTask().getDestinatioRealm().getFullPath());
- }
-
- realmTO.setFullPath(realmTO.getParent() + "/" + realmTO.getName());
- }
- realmTO.getResources().add(profile.getTask().getResource().getKey());
-
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.CREATE);
- result.setAnyType(REALM_TYPE);
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- result.setName(realmTO.getFullPath());
-
- if (profile.isDryRun()) {
- result.setKey(null);
- finalize(UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), Result.SUCCESS, null, null, delta);
- } else {
- SyncDelta actionedDelta = delta;
- for (PullActions action : profile.getActions()) {
- actionedDelta = action.beforeAssign(profile, actionedDelta, realmTO);
- }
-
- create(realmTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), result);
- }
-
- return Collections.singletonList(result);
- }
-
- private List<ProvisioningReport> provision(final SyncDelta delta, final OrgUnit orgUnit)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformCreate()) {
- LOG.debug("PullTask not configured for create");
- finalize(UnmatchingRule.toEventName(UnmatchingRule.PROVISION), Result.SUCCESS, null, null, delta);
- return Collections.<ProvisioningReport>emptyList();
- }
-
- RealmTO realmTO = connObjectUtils.getRealmTO(delta.getObject(), profile.getTask(), orgUnit);
- if (realmTO.getFullPath() == null) {
- if (realmTO.getParent() == null) {
- realmTO.setParent(profile.getTask().getDestinatioRealm().getFullPath());
- }
-
- realmTO.setFullPath(realmTO.getParent() + "/" + realmTO.getName());
- }
-
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.CREATE);
- result.setAnyType(REALM_TYPE);
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- result.setName(realmTO.getFullPath());
-
- if (profile.isDryRun()) {
- result.setKey(null);
- finalize(UnmatchingRule.toEventName(UnmatchingRule.PROVISION), Result.SUCCESS, null, null, delta);
- } else {
- SyncDelta actionedDelta = delta;
- for (PullActions action : profile.getActions()) {
- actionedDelta = action.beforeProvision(profile, actionedDelta, realmTO);
- }
-
- create(realmTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.PROVISION), result);
- }
-
- return Collections.singletonList(result);
- }
-
- private 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;
- }
- }
-
- 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().getFullPath(), realmTO));
-
- PropagationByResource propByRes = new PropagationByResource();
- for (String resource : realm.getResourceKeys()) {
- propByRes.add(ResourceOperation.CREATE, resource);
- }
- List<PropagationTask> 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);
- }
-
- private List<ProvisioningReport> update(final SyncDelta delta, final List<String> keys)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("PullTask not configured for update");
- finalize(MatchingRule.toEventName(MatchingRule.UPDATE), Result.SUCCESS, null, null, delta);
- return Collections.<ProvisioningReport>emptyList();
- }
-
- LOG.debug("About to update {}", keys);
-
- List<ProvisioningReport> results = new ArrayList<>();
-
- SyncDelta workingDelta = delta;
- for (String key : keys) {
- LOG.debug("About to update {}", key);
-
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.UPDATE);
- result.setAnyType(REALM_TYPE);
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- result.setKey(key);
-
- Realm realm = realmDAO.find(key);
- RealmTO before = binder.getRealmTO(realm, true);
- if (before == null) {
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(String.format("Realm '%s' not found", key));
- } else {
- result.setName(before.getFullPath());
- }
-
- if (!profile.isDryRun()) {
- Result resultStatus;
- Object output;
-
- if (before == null) {
- resultStatus = Result.FAILURE;
- output = null;
- } else {
- try {
- for (PullActions action : profile.getActions()) {
- workingDelta = action.beforeUpdate(profile, workingDelta, before, null);
- }
-
- PropagationByResource propByRes = binder.update(realm, before);
- realm = realmDAO.save(realm);
- RealmTO updated = binder.getRealmTO(realm, true);
-
- List<PropagationTask> tasks = propagationManager.createTasks(realm, propByRes, null);
- taskExecutor.execute(tasks, false);
-
- for (PullActions action : profile.getActions()) {
- action.after(profile, workingDelta, 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 {}", workingDelta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- } catch (Exception e) {
- throwIgnoreProvisionException(workingDelta, e);
-
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(ExceptionUtils.getRootCauseMessage(e));
- LOG.error("Could not update Realm {}", workingDelta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- }
- }
- finalize(MatchingRule.toEventName(MatchingRule.UPDATE), resultStatus, before, output, workingDelta);
- }
- results.add(result);
- }
-
- return results;
- }
-
- private List<ProvisioningReport> deprovision(final SyncDelta delta, final List<String> keys, final boolean unlink)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("PullTask not configured for update");
- finalize(unlink
- ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
- : MatchingRule.toEventName(MatchingRule.DEPROVISION), Result.SUCCESS, null, null, delta);
- return Collections.<ProvisioningReport>emptyList();
- }
-
- LOG.debug("About to deprovision {}", keys);
-
- final List<ProvisioningReport> results = new ArrayList<>();
-
- SyncDelta workingDelta = delta;
- for (String key : keys) {
- LOG.debug("About to unassign resource {}", key);
-
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.DELETE);
- result.setAnyType(REALM_TYPE);
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- result.setKey(key);
-
- Realm realm = realmDAO.find(key);
- RealmTO before = binder.getRealmTO(realm, true);
- if (before == null) {
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(String.format("Realm '%s' not found", key));
- } else {
- result.setName(before.getFullPath());
- }
-
- if (!profile.isDryRun()) {
- Object output;
- Result resultStatus;
-
- if (before == null) {
- resultStatus = Result.FAILURE;
- output = null;
- } else {
- try {
- if (unlink) {
- for (PullActions action : profile.getActions()) {
- workingDelta = action.beforeUnassign(profile, workingDelta, before);
- }
- } else {
- for (PullActions action : profile.getActions()) {
- workingDelta = action.beforeDeprovision(profile, workingDelta, before);
- }
- }
-
- PropagationByResource propByRes = new PropagationByResource();
- propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
- taskExecutor.execute(propagationManager.createTasks(realm, propByRes, null), false);
-
- if (unlink) {
- realm.getResources().remove(profile.getTask().getResource());
- output = binder.getRealmTO(realmDAO.save(realm), true);
- } else {
- output = binder.getRealmTO(realm, true);
- }
-
- for (PullActions action : profile.getActions()) {
- action.after(profile, workingDelta, RealmTO.class.cast(output), 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 {}", workingDelta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- } catch (Exception e) {
- throwIgnoreProvisionException(workingDelta, 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;
- }
- }
- finalize(unlink
- ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
- : MatchingRule.toEventName(MatchingRule.DEPROVISION), resultStatus, before, output, delta);
- }
- results.add(result);
- }
-
- return results;
- }
-
- private List<ProvisioningReport> link(final SyncDelta delta, final List<String> keys, final boolean unlink)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("PullTask not configured for update");
- finalize(unlink
- ? MatchingRule.toEventName(MatchingRule.UNLINK)
- : MatchingRule.toEventName(MatchingRule.LINK), Result.SUCCESS, null, null, delta);
- return Collections.<ProvisioningReport>emptyList();
- }
-
- LOG.debug("About to link {}", keys);
-
- final List<ProvisioningReport> results = new ArrayList<>();
-
- SyncDelta workingDelta = delta;
- for (String key : keys) {
- LOG.debug("About to unassign resource {}", key);
-
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.NONE);
- result.setAnyType(REALM_TYPE);
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- result.setKey(key);
-
- Realm realm = realmDAO.find(key);
- RealmTO before = binder.getRealmTO(realm, true);
- if (before == null) {
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(String.format("Realm '%s' not found", key));
- } else {
- result.setName(before.getFullPath());
- }
-
- Object output;
- Result resultStatus;
- if (!profile.isDryRun()) {
- if (before == null) {
- resultStatus = Result.FAILURE;
- output = null;
- } else {
- try {
- if (unlink) {
- for (PullActions action : profile.getActions()) {
- workingDelta = action.beforeUnlink(profile, workingDelta, before);
- }
- } else {
- for (PullActions action : profile.getActions()) {
- workingDelta = action.beforeLink(profile, workingDelta, before);
- }
- }
-
- if (unlink) {
- realm.getResources().remove(profile.getTask().getResource());
- } else {
- realm.add(profile.getTask().getResource());
- }
- output = update(workingDelta, Collections.singletonList(key));
-
- for (PullActions action : profile.getActions()) {
- action.after(profile, workingDelta, RealmTO.class.cast(output), 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 {}", workingDelta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- } catch (Exception e) {
- throwIgnoreProvisionException(workingDelta, e);
-
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(ExceptionUtils.getRootCauseMessage(e));
- LOG.error("Could not update Realm {}", workingDelta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- }
- }
- finalize(unlink
- ? MatchingRule.toEventName(MatchingRule.UNLINK)
- : MatchingRule.toEventName(MatchingRule.LINK), resultStatus, before, output, workingDelta);
- }
- results.add(result);
- }
-
- return results;
- }
-
- private List<ProvisioningReport> delete(final SyncDelta delta, final List<String> keys)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformDelete()) {
- LOG.debug("PullTask not configured for delete");
- finalize(ResourceOperation.DELETE.name().toLowerCase(), Result.SUCCESS, null, null, delta);
- return Collections.<ProvisioningReport>emptyList();
- }
-
- LOG.debug("About to delete {}", keys);
-
- List<ProvisioningReport> results = new ArrayList<>();
-
- SyncDelta workingDelta = delta;
- for (String key : keys) {
- Object output;
- Result resultStatus = Result.FAILURE;
-
- ProvisioningReport result = new ProvisioningReport();
-
- try {
- result.setKey(key);
- result.setOperation(ResourceOperation.DELETE);
- result.setAnyType(REALM_TYPE);
- result.setStatus(ProvisioningReport.Status.SUCCESS);
-
- Realm realm = realmDAO.find(key);
- RealmTO before = binder.getRealmTO(realm, true);
- if (before == null) {
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(String.format("Realm '%s' not found", key));
- } else {
- result.setName(before.getFullPath());
- }
-
- if (!profile.isDryRun()) {
- for (PullActions action : profile.getActions()) {
- workingDelta = action.beforeDelete(profile, workingDelta, before);
- }
-
- try {
- if (!realmDAO.findChildren(realm).isEmpty()) {
- throw SyncopeClientException.build(ClientExceptionType.HasChildren);
- }
-
- Set<String> adminRealms = Collections.singleton(realm.getFullPath());
- AnyCond keyCond = new AnyCond(AttributeCond.Type.ISNOTNULL);
- keyCond.setSchema("key");
- SearchCond allMatchingCond = SearchCond.getLeafCond(keyCond);
- int users = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.USER);
- int groups = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.GROUP);
- int anyObjects = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.ANY_OBJECT);
-
- if (users + groups + anyObjects > 0) {
- SyncopeClientException containedAnys = SyncopeClientException.build(
- ClientExceptionType.AssociatedAnys);
- containedAnys.getElements().add(users + " user(s)");
- containedAnys.getElements().add(groups + " group(s)");
- containedAnys.getElements().add(anyObjects + " anyObject(s)");
- throw containedAnys;
- }
-
- PropagationByResource propByRes = new PropagationByResource();
- for (String resource : realm.getResourceKeys()) {
- propByRes.add(ResourceOperation.DELETE, resource);
- }
- List<PropagationTask> tasks = propagationManager.createTasks(realm, propByRes, null);
- taskExecutor.execute(tasks, false);
-
- realmDAO.delete(realm);
-
- output = null;
- resultStatus = Result.SUCCESS;
-
- for (PullActions action : profile.getActions()) {
- action.after(profile, workingDelta, before, result);
- }
- } catch (Exception e) {
- throwIgnoreProvisionException(workingDelta, e);
-
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(ExceptionUtils.getRootCauseMessage(e));
- LOG.error("Could not delete {}", realm, e);
- output = e;
- }
-
- finalize(ResourceOperation.DELETE.name().toLowerCase(), resultStatus, before, output, workingDelta);
- }
-
- results.add(result);
- } catch (DelegatedAdministrationException e) {
- LOG.error("Not allowed to read Realm {}", key, e);
- } catch (Exception e) {
- LOG.error("Could not delete Realm {}", key, e);
- }
- }
-
- return results;
- }
-
- private ProvisioningReport ignore(
- final SyncDelta delta,
- final boolean matching)
- throws JobExecutionException {
-
- LOG.debug("Any to ignore {}", delta.getObject().getUid().getUidValue());
-
- ProvisioningReport result = new ProvisioningReport();
-
- result.setKey(null);
- result.setName(delta.getObject().getUid().getUidValue());
- result.setOperation(ResourceOperation.NONE);
- result.setAnyType(REALM_TYPE);
- result.setStatus(ProvisioningReport.Status.SUCCESS);
-
- if (!profile.isDryRun()) {
- finalize(matching
- ? MatchingRule.toEventName(MatchingRule.IGNORE)
- : UnmatchingRule.toEventName(UnmatchingRule.IGNORE), Result.SUCCESS, null, null, delta);
- }
-
- return result;
- }
-
- private void doHandle(final SyncDelta delta, final OrgUnit orgUnit) throws JobExecutionException {
- LOG.debug("Process {} for {} as {}",
- delta.getDeltaType(), delta.getUid().getUidValue(), delta.getObject().getObjectClass());
-
- String uid = delta.getPreviousUid() == null
- ? delta.getUid().getUidValue()
- : delta.getPreviousUid().getUidValue();
-
- List<String> keys = pullUtils.findExisting(uid, delta.getObject(), orgUnit);
- LOG.debug("Match found for {} as {}: {}",
- delta.getUid().getUidValue(), delta.getObject().getObjectClass(), keys);
-
- if (keys.size() > 1) {
- switch (profile.getResAct()) {
- case IGNORE:
- throw new IllegalStateException("More than one match " + keys);
-
- case FIRSTMATCH:
- keys = keys.subList(0, 1);
- break;
-
- case LASTMATCH:
- keys = keys.subList(keys.size() - 1, keys.size());
- break;
-
- default:
- // keep keys unmodified
- }
- }
-
- try {
- if (SyncDeltaType.CREATE_OR_UPDATE == delta.getDeltaType()) {
- if (keys.isEmpty()) {
- switch (profile.getTask().getUnmatchingRule()) {
- case ASSIGN:
- profile.getResults().addAll(assign(delta, orgUnit));
- break;
-
- case PROVISION:
- profile.getResults().addAll(provision(delta, orgUnit));
- break;
-
- case IGNORE:
- profile.getResults().add(ignore(delta, false));
- break;
-
- default:
- // do nothing
- }
- } else {
- switch (profile.getTask().getMatchingRule()) {
- case UPDATE:
- profile.getResults().addAll(update(delta, keys));
- break;
-
- case DEPROVISION:
- profile.getResults().addAll(deprovision(delta, keys, false));
- break;
-
- case UNASSIGN:
- profile.getResults().addAll(deprovision(delta, keys, true));
- break;
-
- case LINK:
- profile.getResults().addAll(link(delta, keys, false));
- break;
-
- case UNLINK:
- profile.getResults().addAll(link(delta, keys, true));
- break;
-
- case IGNORE:
- profile.getResults().add(ignore(delta, true));
- break;
-
- default:
- // do nothing
- }
- }
- } else if (SyncDeltaType.DELETE == delta.getDeltaType()) {
- if (keys.isEmpty()) {
- finalize(ResourceOperation.DELETE.name().toLowerCase(), Result.SUCCESS, null, null, delta);
- LOG.debug("No match found for deletion");
- } else {
- profile.getResults().addAll(delete(delta, keys));
- }
- }
- } catch (IllegalStateException | IllegalArgumentException e) {
- LOG.warn(e.getMessage());
- }
- }
-
- private void finalize(
- final String event,
- final Result result,
- final Object before,
- final Object output,
- final SyncDelta delta) {
-
- synchronized (this) {
- this.latestResult = result;
- }
-
- notificationManager.createTasks(AuditElements.EventCategoryType.PULL,
- REALM_TYPE.toLowerCase(),
- profile.getTask().getResource().getKey(),
- event,
- result,
- before,
- output,
- delta);
-
- auditManager.audit(AuditElements.EventCategoryType.PULL,
- REALM_TYPE.toLowerCase(),
- profile.getTask().getResource().getKey(),
- event,
- result,
- before,
- output,
- delta);
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
deleted file mode 100644
index 4becdad..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * 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.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.syncope.common.lib.to.RealmTO;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.Result;
-import org.apache.syncope.common.lib.types.MatchingRule;
-import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
-import org.apache.syncope.core.provisioning.api.PropagationByResource;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.common.lib.types.UnmatchingRule;
-import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.apache.syncope.core.persistence.api.entity.resource.Item;
-import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
-import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
-import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.provisioning.api.MappingManager;
-import org.apache.syncope.core.provisioning.api.TimeoutException;
-import org.apache.syncope.core.provisioning.api.event.AfterHandlingEvent;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
-import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
-import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
-import org.apache.syncope.core.provisioning.api.pushpull.SyncopePushResultHandler;
-import org.apache.syncope.core.provisioning.java.job.AfterHandlingJob;
-import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
-import org.identityconnectors.framework.common.objects.AttributeBuilder;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.quartz.SchedulerFactoryBean;
-import org.springframework.transaction.annotation.Propagation;
-import org.springframework.transaction.annotation.Transactional;
-
-public class RealmPushResultHandlerImpl
- extends AbstractRealmResultHandler<PushTask, PushActions>
- implements SyncopePushResultHandler {
-
- @Autowired
- private MappingManager mappingManager;
-
- @Autowired
- private SchedulerFactoryBean scheduler;
-
- @Transactional(propagation = Propagation.REQUIRES_NEW)
- @Override
- public boolean handle(final String realmKey) {
- Realm realm = null;
- try {
- realm = realmDAO.find(realmKey);
- doHandle(realm);
- return true;
- } catch (IgnoreProvisionException e) {
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.NONE);
- result.setAnyType(realm == null ? null : REALM_TYPE);
- result.setStatus(ProvisioningReport.Status.IGNORE);
- result.setKey(realmKey);
- profile.getResults().add(result);
-
- LOG.warn("Ignoring during push", e);
- return true;
- } catch (JobExecutionException e) {
- LOG.error("Push failed", e);
- return false;
- }
- }
-
- private void reportPropagation(final ProvisioningReport result, final PropagationReporter reporter) {
- if (!reporter.getStatuses().isEmpty()) {
- result.setStatus(toProvisioningReportStatus(reporter.getStatuses().get(0).getStatus()));
- result.setMessage(reporter.getStatuses().get(0).getFailureReason());
- }
- }
-
- 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;
- }
-
- private void deprovision(final Realm realm, final ProvisioningReport result) {
- List<String> noPropResources = new ArrayList<>(realm.getResourceKeys());
- noPropResources.remove(profile.getTask().getResource().getKey());
-
- PropagationByResource propByRes = new PropagationByResource();
- propByRes.addAll(ResourceOperation.DELETE, realm.getResourceKeys());
-
- PropagationReporter reporter = taskExecutor.execute(
- propagationManager.createTasks(realm, propByRes, noPropResources), false);
- reportPropagation(result, reporter);
- }
-
- private void provision(final Realm realm, final ProvisioningReport result) {
- List<String> noPropResources = new ArrayList<>(realm.getResourceKeys());
- noPropResources.remove(profile.getTask().getResource().getKey());
-
- PropagationByResource propByRes = new PropagationByResource();
- propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
-
- PropagationReporter reporter = taskExecutor.execute(
- propagationManager.createTasks(realm, propByRes, noPropResources), false);
- reportPropagation(result, reporter);
- }
-
- private void link(final Realm realm, final boolean unlink, final ProvisioningReport result) {
- RealmTO realmTO = binder.getRealmTO(realm, true);
- if (unlink) {
- realmTO.getResources().remove(profile.getTask().getResource().getKey());
- } else {
- realmTO.getResources().add(profile.getTask().getResource().getKey());
- }
-
- update(realmTO, result);
- }
-
- private void unassign(final Realm realm, final ProvisioningReport result) {
- RealmTO realmTO = binder.getRealmTO(realm, true);
- realmTO.getResources().remove(profile.getTask().getResource().getKey());
-
- deprovision(update(realmTO, result), result);
- }
-
- private void assign(final Realm realm, final ProvisioningReport result) {
- RealmTO realmTO = binder.getRealmTO(realm, true);
- realmTO.getResources().add(profile.getTask().getResource().getKey());
-
- provision(update(realmTO, result), result);
- }
-
- protected ConnectorObject getRemoteObject(
- final ObjectClass objectClass,
- final String connObjectKey,
- final String connObjectKeyValue,
- final Iterator<? extends Item> iterator) {
-
- ConnectorObject obj = null;
- try {
- obj = profile.getConnector().getObject(
- objectClass,
- AttributeBuilder.build(connObjectKey, connObjectKeyValue),
- MappingUtils.buildOperationOptions(iterator));
- } catch (TimeoutException toe) {
- LOG.debug("Request timeout", toe);
- throw toe;
- } catch (RuntimeException ignore) {
- LOG.debug("While resolving {}", connObjectKeyValue, ignore);
- }
-
- return obj;
- }
-
- private void doHandle(final Realm realm) throws JobExecutionException {
- ProvisioningReport result = new ProvisioningReport();
- profile.getResults().add(result);
-
- result.setKey(realm.getKey());
- result.setAnyType(REALM_TYPE);
- result.setName(realm.getFullPath());
-
- LOG.debug("Propagating Realm with key {} towards {}", realm.getKey(), profile.getTask().getResource());
-
- Object output = null;
- Result resultStatus = null;
-
- // Try to read remote object BEFORE any actual operation
- OrgUnit orgUnit = profile.getTask().getResource().getOrgUnit();
- OrgUnitItem connObjectKey = orgUnit.getConnObjectKeyItem();
- String connObjecKeyValue = mappingManager.getConnObjectKeyValue(realm, orgUnit);
-
- ConnectorObject beforeObj = getRemoteObject(
- orgUnit.getObjectClass(),
- connObjectKey.getExtAttrName(),
- connObjecKeyValue,
- orgUnit.getItems().iterator());
-
- 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.toEventName(profile.getTask().getUnmatchingRule())
- : MatchingRule.toEventName(profile.getTask().getMatchingRule());
-
- boolean notificationsAvailable = notificationManager.notificationsAvailable(
- AuditElements.EventCategoryType.PUSH,
- REALM_TYPE.toLowerCase(),
- profile.getTask().getResource().getKey(),
- operation);
- boolean auditRequested = auditManager.auditRequested(
- AuditElements.EventCategoryType.PUSH,
- REALM_TYPE.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);
- }
-
- break;
-
- 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);
- }
-
- break;
-
- 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);
- }
-
- break;
-
- case IGNORE:
- LOG.debug("Ignored any: {}", realm);
- result.setStatus(ProvisioningReport.Status.IGNORE);
- break;
-
- 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), result);
- }
-
- break;
-
- 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, result);
- }
-
- break;
-
- 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, result);
- }
-
- break;
-
- 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);
- }
-
- break;
-
- 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);
- }
-
- break;
-
- case IGNORE:
- LOG.debug("Ignored any: {}", realm);
- result.setStatus(ProvisioningReport.Status.IGNORE);
- break;
-
- default:
- // do nothing
- }
- }
-
- for (PushActions action : profile.getActions()) {
- action.after(profile, realm, result);
- }
-
- if (result.getStatus() == null) {
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- }
- resultStatus = AuditElements.Result.SUCCESS;
- output = getRemoteObject(
- orgUnit.getObjectClass(),
- connObjectKey.getExtAttrName(),
- connObjecKeyValue,
- orgUnit.getItems().iterator());
- } 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 {}", 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(
- AuditElements.EventCategoryType.PUSH,
- REALM_TYPE.toLowerCase(),
- profile.getTask().getResource().getKey(),
- operation,
- resultStatus,
- beforeObj,
- output,
- realm));
- AfterHandlingJob.schedule(scheduler, jobMap);
- }
- }
- }
- }
-
- private ResourceOperation toResourceOperation(final UnmatchingRule rule) {
- switch (rule) {
- case ASSIGN:
- case PROVISION:
- return ResourceOperation.CREATE;
- default:
- return ResourceOperation.NONE;
- }
- }
-
- private ResourceOperation toResourceOperation(final MatchingRule rule) {
- switch (rule) {
- case UPDATE:
- return ResourceOperation.UPDATE;
- case DEPROVISION:
- case UNASSIGN:
- return ResourceOperation.DELETE;
- default:
- return ResourceOperation.NONE;
- }
- }
-
- private ProvisioningReport.Status toProvisioningReportStatus(final PropagationTaskExecStatus status) {
- switch (status) {
- case FAILURE:
- return ProvisioningReport.Status.FAILURE;
-
- case SUCCESS:
- return ProvisioningReport.Status.SUCCESS;
-
- case CREATED:
- case NOT_ATTEMPTED:
- default:
- return ProvisioningReport.Status.IGNORE;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPullResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPullResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPullResultHandlerImpl.java
deleted file mode 100644
index fa299a0..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPullResultHandlerImpl.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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.Collections;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.PropagationStatus;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.provisioning.api.ProvisioningManager;
-import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.apache.syncope.core.provisioning.api.pushpull.UserPullResultHandler;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class UserPullResultHandlerImpl extends AbstractPullResultHandler implements UserPullResultHandler {
-
- @Autowired
- private UserProvisioningManager userProvisioningManager;
-
- @Override
- protected AnyUtils getAnyUtils() {
- return anyUtilsFactory.getInstance(AnyTypeKind.USER);
- }
-
- @Override
- protected String getName(final AnyTO anyTO) {
- return UserTO.class.cast(anyTO).getUsername();
- }
-
- @Override
- protected ProvisioningManager<?, ?> getProvisioningManager() {
- return userProvisioningManager;
- }
-
- @Override
- protected Any<?> getAny(final String key) {
- try {
- return userDAO.authFind(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving user {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AnyTO getAnyTO(final String key) {
- return userDataBinder.getUserTO(key);
- }
-
- @Override
- protected AnyPatch newPatch(final String key) {
- UserPatch patch = new UserPatch();
- patch.setKey(key);
- return patch;
- }
-
- @Override
- protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
- WorkflowResult<Pair<UserPatch, Boolean>> update = uwfAdapter.update((UserPatch) patch);
- return new WorkflowResult<>(update.getResult().getLeft(), update.getPropByRes(), update.getPerformedTasks());
- }
-
- @Override
- protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta) {
- UserTO userTO = UserTO.class.cast(anyTO);
-
- Boolean enabled = pullUtils.readEnabled(delta.getObject(), profile.getTask());
- Map.Entry<String, List<PropagationStatus>> created =
- userProvisioningManager.create(userTO, true, true, enabled,
- Collections.singleton(profile.getTask().getResource().getKey()), true);
-
- return getAnyTO(created.getKey());
- }
-
- @Override
- protected AnyPatch doUpdate(
- final AnyTO before,
- final AnyPatch anyPatch,
- final SyncDelta delta,
- final ProvisioningReport result) {
-
- UserPatch userPatch = UserPatch.class.cast(anyPatch);
- Boolean enabled = pullUtils.readEnabled(delta.getObject(), profile.getTask());
-
- Pair<UserPatch, List<PropagationStatus>> updated = userProvisioningManager.update(
- userPatch,
- result,
- enabled,
- Collections.singleton(profile.getTask().getResource().getKey()),
- true);
-
- return updated.getLeft();
- }
-
- @Override
- protected void doDelete(final AnyTypeKind kind, final String key) {
- try {
- userProvisioningManager.delete(
- key, Collections.<String>singleton(profile.getTask().getResource().getKey()), true);
- } catch (Exception 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 user " + key, e);
- }
-
- uwfAdapter.delete(key);
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java
deleted file mode 100644
index b89850f..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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.ArrayList;
-import java.util.List;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.provisioning.api.PropagationByResource;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
-import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.pushpull.UserPushResultHandler;
-
-public class UserPushResultHandlerImpl extends AbstractPushResultHandler implements UserPushResultHandler {
-
- @Override
- protected AnyUtils getAnyUtils() {
- return anyUtilsFactory.getInstance(AnyTypeKind.USER);
- }
-
- @Override
- protected void provision(final Any<?> any, final Boolean enabled, final ProvisioningReport result) {
- AnyTO before = getAnyTO(any.getKey());
-
- List<String> noPropResources = new ArrayList<>(before.getResources());
- noPropResources.remove(profile.getTask().getResource().getKey());
-
- PropagationByResource propByRes = new PropagationByResource();
- propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
-
- PropagationReporter reporter = taskExecutor.execute(propagationManager.getUserCreateTasks(
- before.getKey(),
- null,
- enabled,
- propByRes,
- before.getVirAttrs(),
- noPropResources),
- false);
- reportPropagation(result, reporter);
- }
-
- @Override
- protected String getName(final Any<?> any) {
- return User.class.cast(any).getUsername();
- }
-
- @Override
- protected Any<?> getAny(final String key) {
- try {
- return userDAO.authFind(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving user {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AnyTO getAnyTO(final String key) {
- return userDataBinder.getUserTO(key);
- }
-
- @Override
- protected AnyPatch newPatch(final String key) {
- UserPatch patch = new UserPatch();
- patch.setKey(key);
- return patch;
- }
-
- @Override
- protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
- WorkflowResult<Pair<UserPatch, Boolean>> update = uwfAdapter.update((UserPatch) patch);
- return new WorkflowResult<>(update.getResult().getLeft(), update.getPropByRes(), update.getPerformedTasks());
- }
-
-}
[2/6] syncope git commit: [SYNCOPE-1212] Clearing and refactoring for
easier extensions
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java
new file mode 100644
index 0000000..03fea98
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java
@@ -0,0 +1,449 @@
+/*
+ * 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.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.syncope.common.lib.to.RealmTO;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.AuditElements.Result;
+import org.apache.syncope.common.lib.types.MatchingRule;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.core.provisioning.api.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.common.lib.types.UnmatchingRule;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
+import org.apache.syncope.core.persistence.api.entity.task.PushTask;
+import org.apache.syncope.core.provisioning.api.MappingManager;
+import org.apache.syncope.core.provisioning.api.TimeoutException;
+import org.apache.syncope.core.provisioning.api.event.AfterHandlingEvent;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
+import org.apache.syncope.core.provisioning.api.pushpull.RealmPushResultHandler;
+import org.apache.syncope.core.provisioning.java.job.AfterHandlingJob;
+import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
+import org.identityconnectors.framework.common.objects.AttributeBuilder;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+public class DefaultRealmPushResultHandler
+ extends AbstractRealmResultHandler<PushTask, PushActions>
+ implements RealmPushResultHandler {
+
+ @Autowired
+ private MappingManager mappingManager;
+
+ @Autowired
+ private SchedulerFactoryBean scheduler;
+
+ @Transactional(propagation = Propagation.REQUIRES_NEW)
+ @Override
+ public boolean handle(final String realmKey) {
+ Realm realm = null;
+ try {
+ realm = realmDAO.find(realmKey);
+ doHandle(realm);
+ return true;
+ } catch (IgnoreProvisionException e) {
+ ProvisioningReport result = new ProvisioningReport();
+ result.setOperation(ResourceOperation.NONE);
+ result.setAnyType(realm == null ? null : REALM_TYPE);
+ result.setStatus(ProvisioningReport.Status.IGNORE);
+ result.setKey(realmKey);
+ profile.getResults().add(result);
+
+ LOG.warn("Ignoring during push", e);
+ return true;
+ } catch (JobExecutionException e) {
+ LOG.error("Push failed", e);
+ return false;
+ }
+ }
+
+ private void reportPropagation(final ProvisioningReport result, final PropagationReporter reporter) {
+ if (!reporter.getStatuses().isEmpty()) {
+ result.setStatus(toProvisioningReportStatus(reporter.getStatuses().get(0).getStatus()));
+ result.setMessage(reporter.getStatuses().get(0).getFailureReason());
+ }
+ }
+
+ 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;
+ }
+
+ private void deprovision(final Realm realm, final ProvisioningReport result) {
+ List<String> noPropResources = new ArrayList<>(realm.getResourceKeys());
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ PropagationByResource propByRes = new PropagationByResource();
+ propByRes.addAll(ResourceOperation.DELETE, realm.getResourceKeys());
+
+ PropagationReporter reporter = taskExecutor.execute(
+ propagationManager.createTasks(realm, propByRes, noPropResources), false);
+ reportPropagation(result, reporter);
+ }
+
+ private void provision(final Realm realm, final ProvisioningReport result) {
+ List<String> noPropResources = new ArrayList<>(realm.getResourceKeys());
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ PropagationByResource propByRes = new PropagationByResource();
+ propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
+
+ PropagationReporter reporter = taskExecutor.execute(
+ propagationManager.createTasks(realm, propByRes, noPropResources), false);
+ reportPropagation(result, reporter);
+ }
+
+ private void link(final Realm realm, final boolean unlink, final ProvisioningReport result) {
+ RealmTO realmTO = binder.getRealmTO(realm, true);
+ if (unlink) {
+ realmTO.getResources().remove(profile.getTask().getResource().getKey());
+ } else {
+ realmTO.getResources().add(profile.getTask().getResource().getKey());
+ }
+
+ update(realmTO, result);
+ }
+
+ private void unassign(final Realm realm, final ProvisioningReport result) {
+ RealmTO realmTO = binder.getRealmTO(realm, true);
+ realmTO.getResources().remove(profile.getTask().getResource().getKey());
+
+ deprovision(update(realmTO, result), result);
+ }
+
+ private void assign(final Realm realm, final ProvisioningReport result) {
+ RealmTO realmTO = binder.getRealmTO(realm, true);
+ realmTO.getResources().add(profile.getTask().getResource().getKey());
+
+ provision(update(realmTO, result), result);
+ }
+
+ protected ConnectorObject getRemoteObject(
+ final ObjectClass objectClass,
+ final String connObjectKey,
+ final String connObjectKeyValue,
+ final Iterator<? extends Item> iterator) {
+
+ ConnectorObject obj = null;
+ try {
+ obj = profile.getConnector().getObject(
+ objectClass,
+ AttributeBuilder.build(connObjectKey, connObjectKeyValue),
+ MappingUtils.buildOperationOptions(iterator));
+ } catch (TimeoutException toe) {
+ LOG.debug("Request timeout", toe);
+ throw toe;
+ } catch (RuntimeException ignore) {
+ LOG.debug("While resolving {}", connObjectKeyValue, ignore);
+ }
+
+ return obj;
+ }
+
+ private void doHandle(final Realm realm) throws JobExecutionException {
+ ProvisioningReport result = new ProvisioningReport();
+ profile.getResults().add(result);
+
+ result.setKey(realm.getKey());
+ result.setAnyType(REALM_TYPE);
+ result.setName(realm.getFullPath());
+
+ LOG.debug("Propagating Realm with key {} towards {}", realm.getKey(), profile.getTask().getResource());
+
+ Object output = null;
+ Result resultStatus = null;
+
+ // Try to read remote object BEFORE any actual operation
+ OrgUnit orgUnit = profile.getTask().getResource().getOrgUnit();
+ OrgUnitItem connObjectKey = orgUnit.getConnObjectKeyItem();
+ String connObjecKeyValue = mappingManager.getConnObjectKeyValue(realm, orgUnit);
+
+ ConnectorObject beforeObj = getRemoteObject(
+ orgUnit.getObjectClass(),
+ connObjectKey.getExtAttrName(),
+ connObjecKeyValue,
+ orgUnit.getItems().iterator());
+
+ 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.toEventName(profile.getTask().getUnmatchingRule())
+ : MatchingRule.toEventName(profile.getTask().getMatchingRule());
+
+ boolean notificationsAvailable = notificationManager.notificationsAvailable(
+ AuditElements.EventCategoryType.PUSH,
+ REALM_TYPE.toLowerCase(),
+ profile.getTask().getResource().getKey(),
+ operation);
+ boolean auditRequested = auditManager.auditRequested(
+ AuditElements.EventCategoryType.PUSH,
+ REALM_TYPE.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);
+ }
+
+ break;
+
+ 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);
+ }
+
+ break;
+
+ 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);
+ }
+
+ break;
+
+ case IGNORE:
+ LOG.debug("Ignored any: {}", realm);
+ result.setStatus(ProvisioningReport.Status.IGNORE);
+ break;
+
+ 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), result);
+ }
+
+ break;
+
+ 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, result);
+ }
+
+ break;
+
+ 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, result);
+ }
+
+ break;
+
+ 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);
+ }
+
+ break;
+
+ 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);
+ }
+
+ break;
+
+ case IGNORE:
+ LOG.debug("Ignored any: {}", realm);
+ result.setStatus(ProvisioningReport.Status.IGNORE);
+ break;
+
+ default:
+ // do nothing
+ }
+ }
+
+ for (PushActions action : profile.getActions()) {
+ action.after(profile, realm, result);
+ }
+
+ if (result.getStatus() == null) {
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ }
+ resultStatus = AuditElements.Result.SUCCESS;
+ output = getRemoteObject(
+ orgUnit.getObjectClass(),
+ connObjectKey.getExtAttrName(),
+ connObjecKeyValue,
+ orgUnit.getItems().iterator());
+ } 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 {}", 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(
+ AuditElements.EventCategoryType.PUSH,
+ REALM_TYPE.toLowerCase(),
+ profile.getTask().getResource().getKey(),
+ operation,
+ resultStatus,
+ beforeObj,
+ output,
+ realm));
+ AfterHandlingJob.schedule(scheduler, jobMap);
+ }
+ }
+ }
+ }
+
+ private ResourceOperation toResourceOperation(final UnmatchingRule rule) {
+ switch (rule) {
+ case ASSIGN:
+ case PROVISION:
+ return ResourceOperation.CREATE;
+ default:
+ return ResourceOperation.NONE;
+ }
+ }
+
+ private ResourceOperation toResourceOperation(final MatchingRule rule) {
+ switch (rule) {
+ case UPDATE:
+ return ResourceOperation.UPDATE;
+ case DEPROVISION:
+ case UNASSIGN:
+ return ResourceOperation.DELETE;
+ default:
+ return ResourceOperation.NONE;
+ }
+ }
+
+ private ProvisioningReport.Status toProvisioningReportStatus(final PropagationTaskExecStatus status) {
+ switch (status) {
+ case FAILURE:
+ return ProvisioningReport.Status.FAILURE;
+
+ case SUCCESS:
+ return ProvisioningReport.Status.SUCCESS;
+
+ case CREATED:
+ case NOT_ATTEMPTED:
+ default:
+ return ProvisioningReport.Status.IGNORE;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPullResultHandler.java
new file mode 100644
index 0000000..83a5401
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPullResultHandler.java
@@ -0,0 +1,134 @@
+/*
+ * 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.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.provisioning.api.ProvisioningManager;
+import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.apache.syncope.core.provisioning.api.pushpull.UserPullResultHandler;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DefaultUserPullResultHandler extends AbstractPullResultHandler implements UserPullResultHandler {
+
+ @Autowired
+ private UserProvisioningManager userProvisioningManager;
+
+ @Override
+ protected AnyUtils getAnyUtils() {
+ return anyUtilsFactory.getInstance(AnyTypeKind.USER);
+ }
+
+ @Override
+ protected String getName(final AnyTO anyTO) {
+ return UserTO.class.cast(anyTO).getUsername();
+ }
+
+ @Override
+ protected ProvisioningManager<?, ?> getProvisioningManager() {
+ return userProvisioningManager;
+ }
+
+ @Override
+ protected Any<?> getAny(final String key) {
+ try {
+ return userDAO.authFind(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving user {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AnyTO getAnyTO(final String key) {
+ return userDataBinder.getUserTO(key);
+ }
+
+ @Override
+ protected AnyPatch newPatch(final String key) {
+ UserPatch patch = new UserPatch();
+ patch.setKey(key);
+ return patch;
+ }
+
+ @Override
+ protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
+ WorkflowResult<Pair<UserPatch, Boolean>> update = uwfAdapter.update((UserPatch) patch);
+ return new WorkflowResult<>(update.getResult().getLeft(), update.getPropByRes(), update.getPerformedTasks());
+ }
+
+ @Override
+ protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta) {
+ UserTO userTO = UserTO.class.cast(anyTO);
+
+ Boolean enabled = pullUtils.readEnabled(delta.getObject(), profile.getTask());
+ Map.Entry<String, List<PropagationStatus>> created =
+ userProvisioningManager.create(userTO, true, true, enabled,
+ Collections.singleton(profile.getTask().getResource().getKey()), true);
+
+ return getAnyTO(created.getKey());
+ }
+
+ @Override
+ protected AnyPatch doUpdate(
+ final AnyTO before,
+ final AnyPatch anyPatch,
+ final SyncDelta delta,
+ final ProvisioningReport result) {
+
+ UserPatch userPatch = UserPatch.class.cast(anyPatch);
+ Boolean enabled = pullUtils.readEnabled(delta.getObject(), profile.getTask());
+
+ Pair<UserPatch, List<PropagationStatus>> updated = userProvisioningManager.update(
+ userPatch,
+ result,
+ enabled,
+ Collections.singleton(profile.getTask().getResource().getKey()),
+ true);
+
+ return updated.getLeft();
+ }
+
+ @Override
+ protected void doDelete(final AnyTypeKind kind, final String key) {
+ try {
+ userProvisioningManager.delete(
+ key, Collections.<String>singleton(profile.getTask().getResource().getKey()), true);
+ } catch (Exception 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 user " + key, e);
+ }
+
+ uwfAdapter.delete(key);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java
new file mode 100644
index 0000000..70f3a00
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java
@@ -0,0 +1,99 @@
+/*
+ * 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.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.provisioning.api.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.pushpull.UserPushResultHandler;
+
+public class DefaultUserPushResultHandler extends AbstractPushResultHandler implements UserPushResultHandler {
+
+ @Override
+ protected AnyUtils getAnyUtils() {
+ return anyUtilsFactory.getInstance(AnyTypeKind.USER);
+ }
+
+ @Override
+ protected void provision(final Any<?> any, final Boolean enabled, final ProvisioningReport result) {
+ AnyTO before = getAnyTO(any.getKey());
+
+ List<String> noPropResources = new ArrayList<>(before.getResources());
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ PropagationByResource propByRes = new PropagationByResource();
+ propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
+
+ PropagationReporter reporter = taskExecutor.execute(propagationManager.getUserCreateTasks(
+ before.getKey(),
+ null,
+ enabled,
+ propByRes,
+ before.getVirAttrs(),
+ noPropResources),
+ false);
+ reportPropagation(result, reporter);
+ }
+
+ @Override
+ protected String getName(final Any<?> any) {
+ return User.class.cast(any).getUsername();
+ }
+
+ @Override
+ protected Any<?> getAny(final String key) {
+ try {
+ return userDAO.authFind(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving user {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AnyTO getAnyTO(final String key) {
+ return userDataBinder.getUserTO(key);
+ }
+
+ @Override
+ protected AnyPatch newPatch(final String key) {
+ UserPatch patch = new UserPatch();
+ patch.setKey(key);
+ return patch;
+ }
+
+ @Override
+ protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
+ WorkflowResult<Pair<UserPatch, Boolean>> update = uwfAdapter.update((UserPatch) patch);
+ return new WorkflowResult<>(update.getResult().getLeft(), update.getPropByRes(), update.getPerformedTasks());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPullResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPullResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPullResultHandlerImpl.java
deleted file mode 100644
index 3e2b5bd..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPullResultHandlerImpl.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.AttrPatch;
-import org.apache.syncope.common.lib.patch.GroupPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.PropagationStatus;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
-import org.apache.syncope.core.provisioning.api.ProvisioningManager;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.apache.syncope.core.provisioning.api.pushpull.GroupPullResultHandler;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class GroupPullResultHandlerImpl extends AbstractPullResultHandler implements GroupPullResultHandler {
-
- @Autowired
- private GroupProvisioningManager groupProvisioningManager;
-
- private final Map<String, String> groupOwnerMap = new HashMap<>();
-
- @Override
- public Map<String, String> getGroupOwnerMap() {
- return this.groupOwnerMap;
- }
-
- @Override
- protected AnyUtils getAnyUtils() {
- return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
- }
-
- @Override
- protected String getName(final AnyTO anyTO) {
- return GroupTO.class.cast(anyTO).getName();
- }
-
- @Override
- protected ProvisioningManager<?, ?> getProvisioningManager() {
- return groupProvisioningManager;
- }
-
- @Override
- protected Any<?> getAny(final String key) {
- try {
- return groupDAO.authFind(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving group {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AnyTO getAnyTO(final String key) {
- return groupDataBinder.getGroupTO(key);
- }
-
- @Override
- protected AnyPatch newPatch(final String key) {
- GroupPatch patch = new GroupPatch();
- patch.setKey(key);
- return patch;
- }
-
- @Override
- protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
- return gwfAdapter.update((GroupPatch) patch);
- }
-
- @Override
- protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta) {
- GroupTO groupTO = GroupTO.class.cast(anyTO);
-
- Map.Entry<String, List<PropagationStatus>> created = groupProvisioningManager.create(
- groupTO,
- groupOwnerMap,
- Collections.singleton(profile.getTask().getResource().getKey()),
- true);
-
- return getAnyTO(created.getKey());
- }
-
- @Override
- protected AnyPatch doUpdate(
- final AnyTO before,
- final AnyPatch anyPatch,
- final SyncDelta delta,
- final ProvisioningReport result) {
-
- GroupPatch groupPatch = GroupPatch.class.cast(anyPatch);
-
- Pair<GroupPatch, List<PropagationStatus>> updated = groupProvisioningManager.update(
- groupPatch, Collections.singleton(profile.getTask().getResource().getKey()), true);
-
- String groupOwner = null;
- for (AttrPatch attrPatch : groupPatch.getPlainAttrs()) {
- if (attrPatch.getOperation() == PatchOperation.ADD_REPLACE && attrPatch.getAttrTO() != null
- && attrPatch.getAttrTO().getSchema().isEmpty() && !attrPatch.getAttrTO().getValues().isEmpty()) {
-
- groupOwner = attrPatch.getAttrTO().getValues().get(0);
- }
- }
- if (groupOwner != null) {
- groupOwnerMap.put(updated.getLeft().getKey(), groupOwner);
- }
-
- return anyPatch;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPushResultHandlerImpl.java
deleted file mode 100644
index 01a112d..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPushResultHandlerImpl.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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 org.apache.syncope.common.lib.patch.GroupPatch;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.pushpull.GroupPushResultHandler;
-
-public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implements GroupPushResultHandler {
-
- @Override
- protected AnyUtils getAnyUtils() {
- return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
- }
-
- @Override
- protected String getName(final Any<?> any) {
- return Group.class.cast(any).getName();
- }
-
- @Override
- protected Any<?> getAny(final String key) {
- try {
- return groupDAO.authFind(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving group {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AnyTO getAnyTO(final String key) {
- return groupDataBinder.getGroupTO(key);
- }
-
- @Override
- protected AnyPatch newPatch(final String key) {
- GroupPatch patch = new GroupPatch();
- patch.setKey(key);
- return patch;
- }
-
- @Override
- protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
- return gwfAdapter.update((GroupPatch) patch);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
index b0c2370..b8c1fa2 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
@@ -49,6 +49,7 @@ import org.apache.syncope.core.persistence.api.entity.task.PullTask;
import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPullResultHandler;
import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
import org.apache.syncope.core.provisioning.api.pushpull.GroupPullResultHandler;
+import org.apache.syncope.core.provisioning.api.pushpull.RealmPullResultHandler;
import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullExecutor;
import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullResultHandler;
import org.apache.syncope.core.provisioning.api.pushpull.UserPullResultHandler;
@@ -60,25 +61,35 @@ import org.identityconnectors.framework.common.objects.SyncToken;
public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> implements SyncopePullExecutor {
@Autowired
- private UserDAO userDAO;
+ protected UserDAO userDAO;
@Autowired
- private GroupDAO groupDAO;
+ protected GroupDAO groupDAO;
@Autowired
- private VirSchemaDAO virSchemaDAO;
+ protected VirSchemaDAO virSchemaDAO;
@Autowired
- private PullUtils pullUtils;
+ protected PullUtils pullUtils;
- private final Map<ObjectClass, SyncToken> latestSyncTokens = new HashMap<>();
+ protected final Map<ObjectClass, SyncToken> latestSyncTokens = new HashMap<>();
+
+ protected ProvisioningProfile<PullTask, PullActions> profile;
+
+ protected RealmPullResultHandler rhandler;
+
+ protected AnyObjectPullResultHandler ahandler;
+
+ protected UserPullResultHandler uhandler;
+
+ protected GroupPullResultHandler ghandler;
@Override
public void setLatestSyncToken(final ObjectClass objectClass, final SyncToken latestSyncToken) {
latestSyncTokens.put(objectClass, latestSyncToken);
}
- private void setGroupOwners(final GroupPullResultHandler ghandler) {
+ protected void setGroupOwners(final GroupPullResultHandler ghandler) {
for (Map.Entry<String, String> entry : ghandler.getGroupOwnerMap().entrySet()) {
Group group = groupDAO.find(entry.getKey());
if (group == null) {
@@ -114,6 +125,42 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i
}
}
+ protected RealmPullResultHandler buildRealmHandler() {
+ RealmPullResultHandler handler = (RealmPullResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(DefaultRealmPullResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ handler.setProfile(profile);
+ handler.setPullExecutor(this);
+
+ return handler;
+ }
+
+ protected AnyObjectPullResultHandler buildAnyObjectHandler() {
+ AnyObjectPullResultHandler handler = (AnyObjectPullResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(DefaultAnyObjectPullResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ handler.setProfile(profile);
+ handler.setPullExecutor(this);
+
+ return handler;
+ }
+
+ protected UserPullResultHandler buildUserHandler() {
+ UserPullResultHandler handler = (UserPullResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(DefaultUserPullResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ handler.setProfile(profile);
+ handler.setPullExecutor(this);
+
+ return handler;
+ }
+
+ protected GroupPullResultHandler buildGroupHandler() {
+ GroupPullResultHandler handler = (GroupPullResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(DefaultGroupPullResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ handler.setProfile(profile);
+ handler.setPullExecutor(this);
+
+ return handler;
+ }
+
@Override
protected String doExecuteProvisioning(
final PullTask pullTask,
@@ -135,7 +182,7 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i
}
}
- ProvisioningProfile<PullTask, PullActions> profile = new ProvisioningProfile<>(connector, pullTask);
+ profile = new ProvisioningProfile<>(connector, pullTask);
profile.getActions().addAll(actions);
profile.setDryRun(dryRun);
profile.setResAct(getPullPolicySpec(pullTask).getConflictResolutionAction());
@@ -148,16 +195,13 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i
}
}
- // First OrgUnits...
+ // First realms...
if (pullTask.getResource().getOrgUnit() != null) {
OrgUnit orgUnit = pullTask.getResource().getOrgUnit();
OperationOptions options = MappingUtils.buildOperationOptions(
MappingUtils.getPullItems(orgUnit.getItems()).iterator());
- SyncopePullResultHandler rhandler = (SyncopePullResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(RealmPullResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- rhandler.setProfile(profile);
- rhandler.setPullExecutor(this);
+ rhandler = buildRealmHandler();
try {
switch (pullTask.getPullMode()) {
@@ -202,20 +246,9 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i
}
// ...then provisions for any types
- AnyObjectPullResultHandler ahandler = (AnyObjectPullResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(AnyObjectPullResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- ahandler.setProfile(profile);
- ahandler.setPullExecutor(this);
-
- UserPullResultHandler uhandler = (UserPullResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(UserPullResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- uhandler.setProfile(profile);
- uhandler.setPullExecutor(this);
-
- GroupPullResultHandler ghandler = (GroupPullResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(GroupPullResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- ghandler.setProfile(profile);
- ghandler.setPullExecutor(this);
+ ahandler = buildAnyObjectHandler();
+ uhandler = buildUserHandler();
+ ghandler = buildGroupHandler();
for (Provision provision : pullTask.getResource().getProvisions()) {
if (provision.getMapping() != null) {
@@ -303,7 +336,7 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i
return result;
}
- private PullPolicySpec getPullPolicySpec(final ProvisioningTask task) {
+ protected PullPolicySpec getPullPolicySpec(final ProvisioningTask task) {
PullPolicySpec pullPolicySpec;
if (task instanceof PullTask) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java
index 8a4a036..5c8e788 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java
@@ -43,6 +43,7 @@ import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPushResultHand
import org.apache.syncope.core.provisioning.api.pushpull.GroupPushResultHandler;
import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile;
import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
+import org.apache.syncope.core.provisioning.api.pushpull.RealmPushResultHandler;
import org.apache.syncope.core.provisioning.api.pushpull.SyncopePushResultHandler;
import org.apache.syncope.core.provisioning.api.pushpull.UserPushResultHandler;
import org.quartz.JobExecutionException;
@@ -55,27 +56,37 @@ public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> {
* User DAO.
*/
@Autowired
- private UserDAO userDAO;
+ protected UserDAO userDAO;
/**
* Search DAO.
*/
@Autowired
- private AnySearchDAO searchDAO;
+ protected AnySearchDAO searchDAO;
/**
* Group DAO.
*/
@Autowired
- private GroupDAO groupDAO;
+ protected GroupDAO groupDAO;
@Autowired
- private AnyObjectDAO anyObjectDAO;
+ protected AnyObjectDAO anyObjectDAO;
@Autowired
- private RealmDAO realmDAO;
+ protected RealmDAO realmDAO;
- private AnyDAO<?> getAnyDAO(final AnyTypeKind anyTypeKind) {
+ protected ProvisioningProfile<PushTask, PushActions> profile;
+
+ protected RealmPushResultHandler rhandler;
+
+ protected AnyObjectPushResultHandler ahandler;
+
+ protected UserPushResultHandler uhandler;
+
+ protected GroupPushResultHandler ghandler;
+
+ protected AnyDAO<?> getAnyDAO(final AnyTypeKind anyTypeKind) {
AnyDAO<?> result;
switch (anyTypeKind) {
case USER:
@@ -94,7 +105,7 @@ public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> {
return result;
}
- private void doHandle(
+ protected void doHandle(
final List<? extends Any<?>> anys,
final SyncopePushResultHandler handler,
final ExternalResource resource)
@@ -110,6 +121,38 @@ public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> {
}
}
+ protected RealmPushResultHandler buildRealmHandler() {
+ RealmPushResultHandler handler = (RealmPushResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(DefaultRealmPushResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ handler.setProfile(profile);
+
+ return handler;
+ }
+
+ protected AnyObjectPushResultHandler buildAnyObjectHandler() {
+ AnyObjectPushResultHandler handler = (AnyObjectPushResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(DefaultAnyObjectPushResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ handler.setProfile(profile);
+
+ return handler;
+ }
+
+ protected UserPushResultHandler buildUserHandler() {
+ UserPushResultHandler handler = (UserPushResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(DefaultUserPushResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ handler.setProfile(profile);
+
+ return handler;
+ }
+
+ protected GroupPushResultHandler buildGroupHandler() {
+ GroupPushResultHandler handler = (GroupPushResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(DefaultGroupPushResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ handler.setProfile(profile);
+
+ return handler;
+ }
+
@Override
protected String doExecuteProvisioning(
final PushTask pushTask,
@@ -131,7 +174,7 @@ public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> {
}
}
- ProvisioningProfile<PushTask, PushActions> profile = new ProvisioningProfile<>(connector, pushTask);
+ profile = new ProvisioningProfile<>(connector, pushTask);
profile.getActions().addAll(actions);
profile.setDryRun(dryRun);
profile.setResAct(null);
@@ -142,11 +185,9 @@ public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> {
}
}
- // First OrgUnits...
+ // First realms...
if (pushTask.getResource().getOrgUnit() != null) {
- SyncopePushResultHandler rhandler = (SyncopePushResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(RealmPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- rhandler.setProfile(profile);
+ rhandler = buildRealmHandler();
for (Realm realm : realmDAO.findDescendants(profile.getTask().getSourceRealm())) {
// Never push the root realm
@@ -162,19 +203,9 @@ public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> {
}
// ...then provisions for any types
- AnyObjectPushResultHandler ahandler = (AnyObjectPushResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(AnyObjectPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- ahandler.setProfile(profile);
-
- UserPushResultHandler uhandler =
- (UserPushResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(UserPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- uhandler.setProfile(profile);
-
- GroupPushResultHandler ghandler =
- (GroupPushResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(GroupPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- ghandler.setProfile(profile);
+ ahandler = buildAnyObjectHandler();
+ uhandler = buildUserHandler();
+ ghandler = buildGroupHandler();
for (Provision provision : pushTask.getResource().getProvisions()) {
if (provision.getMapping() != null) {
[4/6] syncope git commit: [SYNCOPE-1212] Clearing and refactoring for
easier extensions
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
deleted file mode 100644
index c4be4e2..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
+++ /dev/null
@@ -1,795 +0,0 @@
-/*
- * 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.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.syncope.common.lib.SyncopeClientException;
-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.core.provisioning.api.PropagationByResource;
-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.search.AnyCond;
-import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
-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.resource.OrgUnit;
-import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
-import org.apache.syncope.core.persistence.api.entity.task.PullTask;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
-import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
-import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
-import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullExecutor;
-import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullResultHandler;
-import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
-import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.identityconnectors.framework.common.objects.SyncDeltaType;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional(rollbackFor = Throwable.class)
-public class RealmPullResultHandlerImpl
- extends AbstractRealmResultHandler<PullTask, PullActions>
- implements SyncopePullResultHandler {
-
- @Autowired
- private PullUtils pullUtils;
-
- @Autowired
- private ConnObjectUtils connObjectUtils;
-
- @Autowired
- private AnySearchDAO searchDAO;
-
- private SyncopePullExecutor executor;
-
- private Result latestResult;
-
- @Override
- public void setPullExecutor(final SyncopePullExecutor executor) {
- this.executor = executor;
- }
-
- @Override
- public boolean handle(final SyncDelta delta) {
- try {
- OrgUnit orgUnit = profile.getTask().getResource().getOrgUnit();
- if (orgUnit == null) {
- throw new JobExecutionException("No orgUnit found on " + profile.getTask().getResource() + " for "
- + delta.getObject().getObjectClass());
- }
-
- doHandle(delta, orgUnit);
-
- LOG.debug("Successfully handled {}", delta);
-
- if (profile.getTask().getPullMode() != PullMode.INCREMENTAL) {
- return true;
- }
-
- boolean shouldContinue;
- synchronized (this) {
- shouldContinue = latestResult == Result.SUCCESS;
- this.latestResult = null;
- }
- if (shouldContinue) {
- executor.setLatestSyncToken(delta.getObjectClass(), delta.getToken());
- }
- return shouldContinue;
- } catch (IgnoreProvisionException e) {
- ProvisioningReport ignoreResult = new ProvisioningReport();
- ignoreResult.setOperation(ResourceOperation.NONE);
- ignoreResult.setStatus(ProvisioningReport.Status.IGNORE);
- ignoreResult.setAnyType(REALM_TYPE);
- ignoreResult.setKey(null);
- ignoreResult.setName(delta.getObject().getName().getNameValue());
- profile.getResults().add(ignoreResult);
-
- LOG.warn("Ignoring during pull", e);
-
- executor.setLatestSyncToken(delta.getObjectClass(), delta.getToken());
-
- return true;
- } catch (JobExecutionException e) {
- LOG.error("Pull failed", e);
-
- return false;
- }
- }
-
- private List<ProvisioningReport> assign(final SyncDelta delta, final OrgUnit orgUnit) throws JobExecutionException {
- if (!profile.getTask().isPerformCreate()) {
- LOG.debug("PullTask not configured for create");
- finalize(UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), Result.SUCCESS, null, null, delta);
- return Collections.<ProvisioningReport>emptyList();
- }
-
- RealmTO realmTO = connObjectUtils.getRealmTO(delta.getObject(), profile.getTask(), orgUnit);
- if (realmTO.getFullPath() == null) {
- if (realmTO.getParent() == null) {
- realmTO.setParent(profile.getTask().getDestinatioRealm().getFullPath());
- }
-
- realmTO.setFullPath(realmTO.getParent() + "/" + realmTO.getName());
- }
- realmTO.getResources().add(profile.getTask().getResource().getKey());
-
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.CREATE);
- result.setAnyType(REALM_TYPE);
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- result.setName(realmTO.getFullPath());
-
- if (profile.isDryRun()) {
- result.setKey(null);
- finalize(UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), Result.SUCCESS, null, null, delta);
- } else {
- SyncDelta actionedDelta = delta;
- for (PullActions action : profile.getActions()) {
- actionedDelta = action.beforeAssign(profile, actionedDelta, realmTO);
- }
-
- create(realmTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), result);
- }
-
- return Collections.singletonList(result);
- }
-
- private List<ProvisioningReport> provision(final SyncDelta delta, final OrgUnit orgUnit)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformCreate()) {
- LOG.debug("PullTask not configured for create");
- finalize(UnmatchingRule.toEventName(UnmatchingRule.PROVISION), Result.SUCCESS, null, null, delta);
- return Collections.<ProvisioningReport>emptyList();
- }
-
- RealmTO realmTO = connObjectUtils.getRealmTO(delta.getObject(), profile.getTask(), orgUnit);
- if (realmTO.getFullPath() == null) {
- if (realmTO.getParent() == null) {
- realmTO.setParent(profile.getTask().getDestinatioRealm().getFullPath());
- }
-
- realmTO.setFullPath(realmTO.getParent() + "/" + realmTO.getName());
- }
-
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.CREATE);
- result.setAnyType(REALM_TYPE);
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- result.setName(realmTO.getFullPath());
-
- if (profile.isDryRun()) {
- result.setKey(null);
- finalize(UnmatchingRule.toEventName(UnmatchingRule.PROVISION), Result.SUCCESS, null, null, delta);
- } else {
- SyncDelta actionedDelta = delta;
- for (PullActions action : profile.getActions()) {
- actionedDelta = action.beforeProvision(profile, actionedDelta, realmTO);
- }
-
- create(realmTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.PROVISION), result);
- }
-
- return Collections.singletonList(result);
- }
-
- private 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;
- }
- }
-
- 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().getFullPath(), realmTO));
-
- PropagationByResource propByRes = new PropagationByResource();
- for (String resource : realm.getResourceKeys()) {
- propByRes.add(ResourceOperation.CREATE, resource);
- }
- List<PropagationTask> 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);
- }
-
- private List<ProvisioningReport> update(final SyncDelta delta, final List<String> keys)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("PullTask not configured for update");
- finalize(MatchingRule.toEventName(MatchingRule.UPDATE), Result.SUCCESS, null, null, delta);
- return Collections.<ProvisioningReport>emptyList();
- }
-
- LOG.debug("About to update {}", keys);
-
- List<ProvisioningReport> results = new ArrayList<>();
-
- SyncDelta workingDelta = delta;
- for (String key : keys) {
- LOG.debug("About to update {}", key);
-
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.UPDATE);
- result.setAnyType(REALM_TYPE);
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- result.setKey(key);
-
- Realm realm = realmDAO.find(key);
- RealmTO before = binder.getRealmTO(realm, true);
- if (before == null) {
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(String.format("Realm '%s' not found", key));
- } else {
- result.setName(before.getFullPath());
- }
-
- if (!profile.isDryRun()) {
- Result resultStatus;
- Object output;
-
- if (before == null) {
- resultStatus = Result.FAILURE;
- output = null;
- } else {
- try {
- for (PullActions action : profile.getActions()) {
- workingDelta = action.beforeUpdate(profile, workingDelta, before, null);
- }
-
- PropagationByResource propByRes = binder.update(realm, before);
- realm = realmDAO.save(realm);
- RealmTO updated = binder.getRealmTO(realm, true);
-
- List<PropagationTask> tasks = propagationManager.createTasks(realm, propByRes, null);
- taskExecutor.execute(tasks, false);
-
- for (PullActions action : profile.getActions()) {
- action.after(profile, workingDelta, 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 {}", workingDelta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- } catch (Exception e) {
- throwIgnoreProvisionException(workingDelta, e);
-
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(ExceptionUtils.getRootCauseMessage(e));
- LOG.error("Could not update Realm {}", workingDelta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- }
- }
- finalize(MatchingRule.toEventName(MatchingRule.UPDATE), resultStatus, before, output, workingDelta);
- }
- results.add(result);
- }
-
- return results;
- }
-
- private List<ProvisioningReport> deprovision(final SyncDelta delta, final List<String> keys, final boolean unlink)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("PullTask not configured for update");
- finalize(unlink
- ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
- : MatchingRule.toEventName(MatchingRule.DEPROVISION), Result.SUCCESS, null, null, delta);
- return Collections.<ProvisioningReport>emptyList();
- }
-
- LOG.debug("About to deprovision {}", keys);
-
- final List<ProvisioningReport> results = new ArrayList<>();
-
- SyncDelta workingDelta = delta;
- for (String key : keys) {
- LOG.debug("About to unassign resource {}", key);
-
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.DELETE);
- result.setAnyType(REALM_TYPE);
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- result.setKey(key);
-
- Realm realm = realmDAO.find(key);
- RealmTO before = binder.getRealmTO(realm, true);
- if (before == null) {
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(String.format("Realm '%s' not found", key));
- } else {
- result.setName(before.getFullPath());
- }
-
- if (!profile.isDryRun()) {
- Object output;
- Result resultStatus;
-
- if (before == null) {
- resultStatus = Result.FAILURE;
- output = null;
- } else {
- try {
- if (unlink) {
- for (PullActions action : profile.getActions()) {
- workingDelta = action.beforeUnassign(profile, workingDelta, before);
- }
- } else {
- for (PullActions action : profile.getActions()) {
- workingDelta = action.beforeDeprovision(profile, workingDelta, before);
- }
- }
-
- PropagationByResource propByRes = new PropagationByResource();
- propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
- taskExecutor.execute(propagationManager.createTasks(realm, propByRes, null), false);
-
- if (unlink) {
- realm.getResources().remove(profile.getTask().getResource());
- output = binder.getRealmTO(realmDAO.save(realm), true);
- } else {
- output = binder.getRealmTO(realm, true);
- }
-
- for (PullActions action : profile.getActions()) {
- action.after(profile, workingDelta, RealmTO.class.cast(output), 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 {}", workingDelta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- } catch (Exception e) {
- throwIgnoreProvisionException(workingDelta, 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;
- }
- }
- finalize(unlink
- ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
- : MatchingRule.toEventName(MatchingRule.DEPROVISION), resultStatus, before, output, delta);
- }
- results.add(result);
- }
-
- return results;
- }
-
- private List<ProvisioningReport> link(final SyncDelta delta, final List<String> keys, final boolean unlink)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("PullTask not configured for update");
- finalize(unlink
- ? MatchingRule.toEventName(MatchingRule.UNLINK)
- : MatchingRule.toEventName(MatchingRule.LINK), Result.SUCCESS, null, null, delta);
- return Collections.<ProvisioningReport>emptyList();
- }
-
- LOG.debug("About to link {}", keys);
-
- final List<ProvisioningReport> results = new ArrayList<>();
-
- SyncDelta workingDelta = delta;
- for (String key : keys) {
- LOG.debug("About to unassign resource {}", key);
-
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.NONE);
- result.setAnyType(REALM_TYPE);
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- result.setKey(key);
-
- Realm realm = realmDAO.find(key);
- RealmTO before = binder.getRealmTO(realm, true);
- if (before == null) {
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(String.format("Realm '%s' not found", key));
- } else {
- result.setName(before.getFullPath());
- }
-
- Object output;
- Result resultStatus;
- if (!profile.isDryRun()) {
- if (before == null) {
- resultStatus = Result.FAILURE;
- output = null;
- } else {
- try {
- if (unlink) {
- for (PullActions action : profile.getActions()) {
- workingDelta = action.beforeUnlink(profile, workingDelta, before);
- }
- } else {
- for (PullActions action : profile.getActions()) {
- workingDelta = action.beforeLink(profile, workingDelta, before);
- }
- }
-
- if (unlink) {
- realm.getResources().remove(profile.getTask().getResource());
- } else {
- realm.add(profile.getTask().getResource());
- }
- output = update(workingDelta, Collections.singletonList(key));
-
- for (PullActions action : profile.getActions()) {
- action.after(profile, workingDelta, RealmTO.class.cast(output), 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 {}", workingDelta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- } catch (Exception e) {
- throwIgnoreProvisionException(workingDelta, e);
-
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(ExceptionUtils.getRootCauseMessage(e));
- LOG.error("Could not update Realm {}", workingDelta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- }
- }
- finalize(unlink
- ? MatchingRule.toEventName(MatchingRule.UNLINK)
- : MatchingRule.toEventName(MatchingRule.LINK), resultStatus, before, output, workingDelta);
- }
- results.add(result);
- }
-
- return results;
- }
-
- private List<ProvisioningReport> delete(final SyncDelta delta, final List<String> keys)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformDelete()) {
- LOG.debug("PullTask not configured for delete");
- finalize(ResourceOperation.DELETE.name().toLowerCase(), Result.SUCCESS, null, null, delta);
- return Collections.<ProvisioningReport>emptyList();
- }
-
- LOG.debug("About to delete {}", keys);
-
- List<ProvisioningReport> results = new ArrayList<>();
-
- SyncDelta workingDelta = delta;
- for (String key : keys) {
- Object output;
- Result resultStatus = Result.FAILURE;
-
- ProvisioningReport result = new ProvisioningReport();
-
- try {
- result.setKey(key);
- result.setOperation(ResourceOperation.DELETE);
- result.setAnyType(REALM_TYPE);
- result.setStatus(ProvisioningReport.Status.SUCCESS);
-
- Realm realm = realmDAO.find(key);
- RealmTO before = binder.getRealmTO(realm, true);
- if (before == null) {
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(String.format("Realm '%s' not found", key));
- } else {
- result.setName(before.getFullPath());
- }
-
- if (!profile.isDryRun()) {
- for (PullActions action : profile.getActions()) {
- workingDelta = action.beforeDelete(profile, workingDelta, before);
- }
-
- try {
- if (!realmDAO.findChildren(realm).isEmpty()) {
- throw SyncopeClientException.build(ClientExceptionType.HasChildren);
- }
-
- Set<String> adminRealms = Collections.singleton(realm.getFullPath());
- AnyCond keyCond = new AnyCond(AttributeCond.Type.ISNOTNULL);
- keyCond.setSchema("key");
- SearchCond allMatchingCond = SearchCond.getLeafCond(keyCond);
- int users = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.USER);
- int groups = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.GROUP);
- int anyObjects = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.ANY_OBJECT);
-
- if (users + groups + anyObjects > 0) {
- SyncopeClientException containedAnys = SyncopeClientException.build(
- ClientExceptionType.AssociatedAnys);
- containedAnys.getElements().add(users + " user(s)");
- containedAnys.getElements().add(groups + " group(s)");
- containedAnys.getElements().add(anyObjects + " anyObject(s)");
- throw containedAnys;
- }
-
- PropagationByResource propByRes = new PropagationByResource();
- for (String resource : realm.getResourceKeys()) {
- propByRes.add(ResourceOperation.DELETE, resource);
- }
- List<PropagationTask> tasks = propagationManager.createTasks(realm, propByRes, null);
- taskExecutor.execute(tasks, false);
-
- realmDAO.delete(realm);
-
- output = null;
- resultStatus = Result.SUCCESS;
-
- for (PullActions action : profile.getActions()) {
- action.after(profile, workingDelta, before, result);
- }
- } catch (Exception e) {
- throwIgnoreProvisionException(workingDelta, e);
-
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(ExceptionUtils.getRootCauseMessage(e));
- LOG.error("Could not delete {}", realm, e);
- output = e;
- }
-
- finalize(ResourceOperation.DELETE.name().toLowerCase(), resultStatus, before, output, workingDelta);
- }
-
- results.add(result);
- } catch (DelegatedAdministrationException e) {
- LOG.error("Not allowed to read Realm {}", key, e);
- } catch (Exception e) {
- LOG.error("Could not delete Realm {}", key, e);
- }
- }
-
- return results;
- }
-
- private ProvisioningReport ignore(
- final SyncDelta delta,
- final boolean matching)
- throws JobExecutionException {
-
- LOG.debug("Any to ignore {}", delta.getObject().getUid().getUidValue());
-
- ProvisioningReport result = new ProvisioningReport();
-
- result.setKey(null);
- result.setName(delta.getObject().getUid().getUidValue());
- result.setOperation(ResourceOperation.NONE);
- result.setAnyType(REALM_TYPE);
- result.setStatus(ProvisioningReport.Status.SUCCESS);
-
- if (!profile.isDryRun()) {
- finalize(matching
- ? MatchingRule.toEventName(MatchingRule.IGNORE)
- : UnmatchingRule.toEventName(UnmatchingRule.IGNORE), Result.SUCCESS, null, null, delta);
- }
-
- return result;
- }
-
- private void doHandle(final SyncDelta delta, final OrgUnit orgUnit) throws JobExecutionException {
- LOG.debug("Process {} for {} as {}",
- delta.getDeltaType(), delta.getUid().getUidValue(), delta.getObject().getObjectClass());
-
- String uid = delta.getPreviousUid() == null
- ? delta.getUid().getUidValue()
- : delta.getPreviousUid().getUidValue();
-
- List<String> keys = pullUtils.findExisting(uid, delta.getObject(), orgUnit);
- LOG.debug("Match found for {} as {}: {}",
- delta.getUid().getUidValue(), delta.getObject().getObjectClass(), keys);
-
- if (keys.size() > 1) {
- switch (profile.getResAct()) {
- case IGNORE:
- throw new IllegalStateException("More than one match " + keys);
-
- case FIRSTMATCH:
- keys = keys.subList(0, 1);
- break;
-
- case LASTMATCH:
- keys = keys.subList(keys.size() - 1, keys.size());
- break;
-
- default:
- // keep keys unmodified
- }
- }
-
- try {
- if (SyncDeltaType.CREATE_OR_UPDATE == delta.getDeltaType()) {
- if (keys.isEmpty()) {
- switch (profile.getTask().getUnmatchingRule()) {
- case ASSIGN:
- profile.getResults().addAll(assign(delta, orgUnit));
- break;
-
- case PROVISION:
- profile.getResults().addAll(provision(delta, orgUnit));
- break;
-
- case IGNORE:
- profile.getResults().add(ignore(delta, false));
- break;
-
- default:
- // do nothing
- }
- } else {
- switch (profile.getTask().getMatchingRule()) {
- case UPDATE:
- profile.getResults().addAll(update(delta, keys));
- break;
-
- case DEPROVISION:
- profile.getResults().addAll(deprovision(delta, keys, false));
- break;
-
- case UNASSIGN:
- profile.getResults().addAll(deprovision(delta, keys, true));
- break;
-
- case LINK:
- profile.getResults().addAll(link(delta, keys, false));
- break;
-
- case UNLINK:
- profile.getResults().addAll(link(delta, keys, true));
- break;
-
- case IGNORE:
- profile.getResults().add(ignore(delta, true));
- break;
-
- default:
- // do nothing
- }
- }
- } else if (SyncDeltaType.DELETE == delta.getDeltaType()) {
- if (keys.isEmpty()) {
- finalize(ResourceOperation.DELETE.name().toLowerCase(), Result.SUCCESS, null, null, delta);
- LOG.debug("No match found for deletion");
- } else {
- profile.getResults().addAll(delete(delta, keys));
- }
- }
- } catch (IllegalStateException | IllegalArgumentException e) {
- LOG.warn(e.getMessage());
- }
- }
-
- private void finalize(
- final String event,
- final Result result,
- final Object before,
- final Object output,
- final SyncDelta delta) {
-
- synchronized (this) {
- this.latestResult = result;
- }
-
- notificationManager.createTasks(AuditElements.EventCategoryType.PULL,
- REALM_TYPE.toLowerCase(),
- profile.getTask().getResource().getKey(),
- event,
- result,
- before,
- output,
- delta);
-
- auditManager.audit(AuditElements.EventCategoryType.PULL,
- REALM_TYPE.toLowerCase(),
- profile.getTask().getResource().getKey(),
- event,
- result,
- before,
- output,
- delta);
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
deleted file mode 100644
index 655f0c5..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * 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.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.syncope.common.lib.to.RealmTO;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.Result;
-import org.apache.syncope.common.lib.types.MatchingRule;
-import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
-import org.apache.syncope.core.provisioning.api.PropagationByResource;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.common.lib.types.UnmatchingRule;
-import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.apache.syncope.core.persistence.api.entity.resource.Item;
-import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
-import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
-import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.provisioning.api.MappingManager;
-import org.apache.syncope.core.provisioning.api.TimeoutException;
-import org.apache.syncope.core.provisioning.api.event.AfterHandlingEvent;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
-import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
-import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
-import org.apache.syncope.core.provisioning.api.pushpull.SyncopePushResultHandler;
-import org.apache.syncope.core.provisioning.java.job.AfterHandlingJob;
-import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
-import org.identityconnectors.framework.common.objects.AttributeBuilder;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.quartz.SchedulerFactoryBean;
-import org.springframework.transaction.annotation.Propagation;
-import org.springframework.transaction.annotation.Transactional;
-
-public class RealmPushResultHandlerImpl
- extends AbstractRealmResultHandler<PushTask, PushActions>
- implements SyncopePushResultHandler {
-
- @Autowired
- private MappingManager mappingManager;
-
- @Autowired
- private SchedulerFactoryBean scheduler;
-
- @Transactional(propagation = Propagation.REQUIRES_NEW)
- @Override
- public boolean handle(final String realmKey) {
- Realm realm = null;
- try {
- realm = realmDAO.find(realmKey);
- doHandle(realm);
- return true;
- } catch (IgnoreProvisionException e) {
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.NONE);
- result.setAnyType(realm == null ? null : REALM_TYPE);
- result.setStatus(ProvisioningReport.Status.IGNORE);
- result.setKey(realmKey);
- profile.getResults().add(result);
-
- LOG.warn("Ignoring during push", e);
- return true;
- } catch (JobExecutionException e) {
- LOG.error("Push failed", e);
- return false;
- }
- }
-
- private void reportPropagation(final ProvisioningReport result, final PropagationReporter reporter) {
- if (!reporter.getStatuses().isEmpty()) {
- result.setStatus(toProvisioningReportStatus(reporter.getStatuses().get(0).getStatus()));
- result.setMessage(reporter.getStatuses().get(0).getFailureReason());
- }
- }
-
- 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;
- }
-
- private void deprovision(final Realm realm, final ProvisioningReport result) {
- List<String> noPropResources = new ArrayList<>(realm.getResourceKeys());
- noPropResources.remove(profile.getTask().getResource().getKey());
-
- PropagationByResource propByRes = new PropagationByResource();
- propByRes.addAll(ResourceOperation.DELETE, realm.getResourceKeys());
-
- PropagationReporter reporter = taskExecutor.execute(
- propagationManager.createTasks(realm, propByRes, noPropResources), false);
- reportPropagation(result, reporter);
- }
-
- private void provision(final Realm realm, final ProvisioningReport result) {
- List<String> noPropResources = new ArrayList<>(realm.getResourceKeys());
- noPropResources.remove(profile.getTask().getResource().getKey());
-
- PropagationByResource propByRes = new PropagationByResource();
- propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
-
- PropagationReporter reporter = taskExecutor.execute(
- propagationManager.createTasks(realm, propByRes, noPropResources), false);
- reportPropagation(result, reporter);
- }
-
- private void link(final Realm realm, final boolean unlink, final ProvisioningReport result) {
- RealmTO realmTO = binder.getRealmTO(realm, true);
- if (unlink) {
- realmTO.getResources().remove(profile.getTask().getResource().getKey());
- } else {
- realmTO.getResources().add(profile.getTask().getResource().getKey());
- }
-
- update(realmTO, result);
- }
-
- private void unassign(final Realm realm, final ProvisioningReport result) {
- RealmTO realmTO = binder.getRealmTO(realm, true);
- realmTO.getResources().remove(profile.getTask().getResource().getKey());
-
- deprovision(update(realmTO, result), result);
- }
-
- private void assign(final Realm realm, final ProvisioningReport result) {
- RealmTO realmTO = binder.getRealmTO(realm, true);
- realmTO.getResources().add(profile.getTask().getResource().getKey());
-
- provision(update(realmTO, result), result);
- }
-
- protected ConnectorObject getRemoteObject(
- final ObjectClass objectClass,
- final String connObjectKey,
- final String connObjectKeyValue,
- final Iterator<? extends Item> iterator) {
-
- ConnectorObject obj = null;
- try {
- obj = profile.getConnector().getObject(
- objectClass,
- AttributeBuilder.build(connObjectKey, connObjectKeyValue),
- MappingUtils.buildOperationOptions(iterator));
- } catch (TimeoutException toe) {
- LOG.debug("Request timeout", toe);
- throw toe;
- } catch (RuntimeException ignore) {
- LOG.debug("While resolving {}", connObjectKeyValue, ignore);
- }
-
- return obj;
- }
-
- private void doHandle(final Realm realm) throws JobExecutionException {
- ProvisioningReport result = new ProvisioningReport();
- profile.getResults().add(result);
-
- result.setKey(realm.getKey());
- result.setAnyType(REALM_TYPE);
- result.setName(realm.getFullPath());
-
- LOG.debug("Propagating Realm with key {} towards {}", realm.getKey(), profile.getTask().getResource());
-
- Object output = null;
- Result resultStatus = null;
-
- // Try to read remote object BEFORE any actual operation
- OrgUnit orgUnit = profile.getTask().getResource().getOrgUnit();
- Optional<? extends OrgUnitItem> connObjectKey = orgUnit.getConnObjectKeyItem();
- String connObjecKeyValue = mappingManager.getConnObjectKeyValue(realm, orgUnit);
-
- ConnectorObject beforeObj = getRemoteObject(
- orgUnit.getObjectClass(),
- connObjectKey.get().getExtAttrName(),
- connObjecKeyValue,
- orgUnit.getItems().iterator());
-
- 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.toEventName(profile.getTask().getUnmatchingRule())
- : MatchingRule.toEventName(profile.getTask().getMatchingRule());
-
- boolean notificationsAvailable = notificationManager.notificationsAvailable(
- AuditElements.EventCategoryType.PUSH,
- REALM_TYPE.toLowerCase(),
- profile.getTask().getResource().getKey(),
- operation);
- boolean auditRequested = auditManager.auditRequested(
- AuditElements.EventCategoryType.PUSH,
- REALM_TYPE.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);
- }
-
- break;
-
- 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);
- }
-
- break;
-
- 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);
- }
-
- break;
-
- case IGNORE:
- LOG.debug("Ignored any: {}", realm);
- result.setStatus(ProvisioningReport.Status.IGNORE);
- break;
-
- 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), result);
- }
-
- break;
-
- 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, result);
- }
-
- break;
-
- 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, result);
- }
-
- break;
-
- 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);
- }
-
- break;
-
- 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);
- }
-
- break;
-
- case IGNORE:
- LOG.debug("Ignored any: {}", realm);
- result.setStatus(ProvisioningReport.Status.IGNORE);
- break;
-
- default:
- // do nothing
- }
- }
-
- for (PushActions action : profile.getActions()) {
- action.after(profile, realm, result);
- }
-
- if (result.getStatus() == null) {
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- }
- resultStatus = AuditElements.Result.SUCCESS;
- output = getRemoteObject(
- orgUnit.getObjectClass(),
- connObjectKey.get().getExtAttrName(),
- connObjecKeyValue,
- orgUnit.getItems().iterator());
- } 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 {}", 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(
- AuditElements.EventCategoryType.PUSH,
- REALM_TYPE.toLowerCase(),
- profile.getTask().getResource().getKey(),
- operation,
- resultStatus,
- beforeObj,
- output,
- realm));
- AfterHandlingJob.schedule(scheduler, jobMap);
- }
- }
- }
- }
-
- private ResourceOperation toResourceOperation(final UnmatchingRule rule) {
- switch (rule) {
- case ASSIGN:
- case PROVISION:
- return ResourceOperation.CREATE;
- default:
- return ResourceOperation.NONE;
- }
- }
-
- private ResourceOperation toResourceOperation(final MatchingRule rule) {
- switch (rule) {
- case UPDATE:
- return ResourceOperation.UPDATE;
- case DEPROVISION:
- case UNASSIGN:
- return ResourceOperation.DELETE;
- default:
- return ResourceOperation.NONE;
- }
- }
-
- private ProvisioningReport.Status toProvisioningReportStatus(final PropagationTaskExecStatus status) {
- switch (status) {
- case FAILURE:
- return ProvisioningReport.Status.FAILURE;
-
- case SUCCESS:
- return ProvisioningReport.Status.SUCCESS;
-
- case CREATED:
- case NOT_ATTEMPTED:
- default:
- return ProvisioningReport.Status.IGNORE;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPullResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPullResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPullResultHandlerImpl.java
deleted file mode 100644
index fa299a0..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPullResultHandlerImpl.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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.Collections;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.PropagationStatus;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.provisioning.api.ProvisioningManager;
-import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.apache.syncope.core.provisioning.api.pushpull.UserPullResultHandler;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class UserPullResultHandlerImpl extends AbstractPullResultHandler implements UserPullResultHandler {
-
- @Autowired
- private UserProvisioningManager userProvisioningManager;
-
- @Override
- protected AnyUtils getAnyUtils() {
- return anyUtilsFactory.getInstance(AnyTypeKind.USER);
- }
-
- @Override
- protected String getName(final AnyTO anyTO) {
- return UserTO.class.cast(anyTO).getUsername();
- }
-
- @Override
- protected ProvisioningManager<?, ?> getProvisioningManager() {
- return userProvisioningManager;
- }
-
- @Override
- protected Any<?> getAny(final String key) {
- try {
- return userDAO.authFind(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving user {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AnyTO getAnyTO(final String key) {
- return userDataBinder.getUserTO(key);
- }
-
- @Override
- protected AnyPatch newPatch(final String key) {
- UserPatch patch = new UserPatch();
- patch.setKey(key);
- return patch;
- }
-
- @Override
- protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
- WorkflowResult<Pair<UserPatch, Boolean>> update = uwfAdapter.update((UserPatch) patch);
- return new WorkflowResult<>(update.getResult().getLeft(), update.getPropByRes(), update.getPerformedTasks());
- }
-
- @Override
- protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta) {
- UserTO userTO = UserTO.class.cast(anyTO);
-
- Boolean enabled = pullUtils.readEnabled(delta.getObject(), profile.getTask());
- Map.Entry<String, List<PropagationStatus>> created =
- userProvisioningManager.create(userTO, true, true, enabled,
- Collections.singleton(profile.getTask().getResource().getKey()), true);
-
- return getAnyTO(created.getKey());
- }
-
- @Override
- protected AnyPatch doUpdate(
- final AnyTO before,
- final AnyPatch anyPatch,
- final SyncDelta delta,
- final ProvisioningReport result) {
-
- UserPatch userPatch = UserPatch.class.cast(anyPatch);
- Boolean enabled = pullUtils.readEnabled(delta.getObject(), profile.getTask());
-
- Pair<UserPatch, List<PropagationStatus>> updated = userProvisioningManager.update(
- userPatch,
- result,
- enabled,
- Collections.singleton(profile.getTask().getResource().getKey()),
- true);
-
- return updated.getLeft();
- }
-
- @Override
- protected void doDelete(final AnyTypeKind kind, final String key) {
- try {
- userProvisioningManager.delete(
- key, Collections.<String>singleton(profile.getTask().getResource().getKey()), true);
- } catch (Exception 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 user " + key, e);
- }
-
- uwfAdapter.delete(key);
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java
deleted file mode 100644
index b89850f..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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.ArrayList;
-import java.util.List;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.provisioning.api.PropagationByResource;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
-import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.pushpull.UserPushResultHandler;
-
-public class UserPushResultHandlerImpl extends AbstractPushResultHandler implements UserPushResultHandler {
-
- @Override
- protected AnyUtils getAnyUtils() {
- return anyUtilsFactory.getInstance(AnyTypeKind.USER);
- }
-
- @Override
- protected void provision(final Any<?> any, final Boolean enabled, final ProvisioningReport result) {
- AnyTO before = getAnyTO(any.getKey());
-
- List<String> noPropResources = new ArrayList<>(before.getResources());
- noPropResources.remove(profile.getTask().getResource().getKey());
-
- PropagationByResource propByRes = new PropagationByResource();
- propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
-
- PropagationReporter reporter = taskExecutor.execute(propagationManager.getUserCreateTasks(
- before.getKey(),
- null,
- enabled,
- propByRes,
- before.getVirAttrs(),
- noPropResources),
- false);
- reportPropagation(result, reporter);
- }
-
- @Override
- protected String getName(final Any<?> any) {
- return User.class.cast(any).getUsername();
- }
-
- @Override
- protected Any<?> getAny(final String key) {
- try {
- return userDAO.authFind(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving user {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AnyTO getAnyTO(final String key) {
- return userDataBinder.getUserTO(key);
- }
-
- @Override
- protected AnyPatch newPatch(final String key) {
- UserPatch patch = new UserPatch();
- patch.setKey(key);
- return patch;
- }
-
- @Override
- protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
- WorkflowResult<Pair<UserPatch, Boolean>> update = uwfAdapter.update((UserPatch) patch);
- return new WorkflowResult<>(update.getResult().getLeft(), update.getPropByRes(), update.getPerformedTasks());
- }
-
-}
[6/6] syncope git commit: [SYNCOPE-1212] Clearing and refactoring for
easier extensions
Posted by il...@apache.org.
[SYNCOPE-1212] Clearing and refactoring for easier extensions
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/9c289134
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/9c289134
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/9c289134
Branch: refs/heads/master
Commit: 9c289134b3452874d279e83ef300dc8c313d44f9
Parents: 9e24b8e
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Sep 22 10:12:45 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Sep 22 10:15:38 2017 +0200
----------------------------------------------------------------------
.../jpa/content/ContentLoaderHandler.java | 2 +-
.../entity/task/AbstractProvisioningTask.java | 10 -
.../api/pushpull/RealmPullResultHandler.java | 23 +
.../api/pushpull/RealmPushResultHandler.java | 23 +
.../java/data/TaskDataBinderImpl.java | 8 +-
.../provisioning/java/job/JobManagerImpl.java | 21 +-
.../pushpull/AbstractPullResultHandler.java | 14 +-
.../pushpull/AbstractPushResultHandler.java | 10 +-
.../AnyObjectPullResultHandlerImpl.java | 112 ---
.../AnyObjectPushResultHandlerImpl.java | 70 --
.../DefaultAnyObjectPullResultHandler.java | 112 +++
.../DefaultAnyObjectPushResultHandler.java | 70 ++
.../pushpull/DefaultGroupPullResultHandler.java | 138 ++++
.../pushpull/DefaultGroupPushResultHandler.java | 70 ++
.../pushpull/DefaultRealmPullResultHandler.java | 795 +++++++++++++++++++
.../pushpull/DefaultRealmPushResultHandler.java | 450 +++++++++++
.../pushpull/DefaultUserPullResultHandler.java | 134 ++++
.../pushpull/DefaultUserPushResultHandler.java | 99 +++
.../pushpull/GroupPullResultHandlerImpl.java | 138 ----
.../pushpull/GroupPushResultHandlerImpl.java | 70 --
.../java/pushpull/PullJobDelegate.java | 87 +-
.../java/pushpull/PushJobDelegate.java | 81 +-
.../pushpull/RealmPullResultHandlerImpl.java | 795 -------------------
.../pushpull/RealmPushResultHandlerImpl.java | 450 -----------
.../pushpull/UserPullResultHandlerImpl.java | 134 ----
.../pushpull/UserPushResultHandlerImpl.java | 99 ---
26 files changed, 2063 insertions(+), 1952 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
index 72f5967..713fee0 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
@@ -189,7 +189,7 @@ public class ContentLoaderHandler extends DefaultHandler {
try {
jdbcTemplate.update(query.toString(), getParameters(qName, atts));
} catch (DataAccessException e) {
- LOG.error("While trying to perform {}", query, e);
+ LOG.error("While trying to perform {} with params {}", query, getParameters(qName, atts), e);
if (!continueOnError) {
throw e;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
index 0441eb3..dc35f9d 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
@@ -80,16 +80,6 @@ public abstract class AbstractProvisioningTask extends JPASchedTask implements P
protected MatchingRule matchingRule;
@Override
- public String getJobDelegateClassName() {
- return null;
- }
-
- @Override
- public void setJobDelegateClassName(final String jobDelegateClassName) {
- // fixed, cannot be changed
- }
-
- @Override
public ExternalResource getResource() {
return resource;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/RealmPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/RealmPullResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/RealmPullResultHandler.java
new file mode 100644
index 0000000..6f38692
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/RealmPullResultHandler.java
@@ -0,0 +1,23 @@
+/*
+ * 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.api.pushpull;
+
+public interface RealmPullResultHandler extends SyncopePullResultHandler {
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/RealmPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/RealmPushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/RealmPushResultHandler.java
new file mode 100644
index 0000000..e994213
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/RealmPushResultHandler.java
@@ -0,0 +1,23 @@
+/*
+ * 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.api.pushpull;
+
+public interface RealmPushResultHandler extends SyncopePushResultHandler {
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
index 646e950..2066cb2 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
@@ -110,7 +110,9 @@ public class TaskDataBinderImpl implements TaskDataBinder {
PushTask pushTask = (PushTask) task;
final PushTaskTO pushTaskTO = (PushTaskTO) taskTO;
- pushTask.setJobDelegateClassName(PushJobDelegate.class.getName());
+ pushTask.setJobDelegateClassName(pushTaskTO.getJobDelegateClassName() == null
+ ? PushJobDelegate.class.getName()
+ : pushTaskTO.getJobDelegateClassName());
pushTask.setSourceRealm(realmDAO.findByFullPath(pushTaskTO.getSourceRealm()));
@@ -148,7 +150,9 @@ public class TaskDataBinderImpl implements TaskDataBinder {
pullTask.setDestinationRealm(realmDAO.findByFullPath(pullTaskTO.getDestinationRealm()));
- pullTask.setJobDelegateClassName(PullJobDelegate.class.getName());
+ pullTask.setJobDelegateClassName(pullTaskTO.getJobDelegateClassName() == null
+ ? PullJobDelegate.class.getName()
+ : pullTaskTO.getJobDelegateClassName());
pullTask.setMatchingRule(pullTaskTO.getMatchingRule() == null
? MatchingRule.UPDATE : pullTaskTO.getMatchingRule());
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
index f82c243..42daca5 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
@@ -46,8 +46,6 @@ import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.SyncopeLoader;
import org.apache.syncope.core.persistence.api.DomainsHolder;
-import org.apache.syncope.core.provisioning.java.pushpull.PushJobDelegate;
-import org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate;
import org.quartz.CronScheduleBuilder;
import org.quartz.Job;
import org.quartz.JobBuilder;
@@ -69,8 +67,11 @@ import org.identityconnectors.common.IOUtil;
import org.quartz.impl.jdbcjobstore.Constants;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.apache.syncope.core.persistence.api.entity.task.PullTask;
+import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
import org.apache.syncope.core.provisioning.java.job.notification.NotificationJob;
import org.apache.syncope.core.provisioning.java.job.report.ReportJob;
+import org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate;
+import org.apache.syncope.core.provisioning.java.pushpull.PushJobDelegate;
public class JobManagerImpl implements JobManager, SyncopeLoader {
@@ -214,11 +215,17 @@ public class JobManagerImpl implements JobManager, SyncopeLoader {
TaskJob job = createSpringBean(TaskJob.class);
job.setTaskKey(task.getKey());
- String jobDelegateClassName = task instanceof PullTask
- ? PullJobDelegate.class.getName()
- : task instanceof PushTask
- ? PushJobDelegate.class.getName()
- : task.getJobDelegateClassName();
+ String jobDelegateClassName = task.getJobDelegateClassName() == null
+ ? task instanceof PullTask
+ ? PullJobDelegate.class.getName()
+ : task instanceof PushTask
+ ? PushJobDelegate.class.getName()
+ : null
+ : task.getJobDelegateClassName();
+ if (jobDelegateClassName == null) {
+ throw new IllegalArgumentException("Task " + task
+ + " does not provide any " + SchedTaskJobDelegate.class.getSimpleName());
+ }
Map<String, Object> jobMap = new HashMap<>();
jobMap.put(JobManager.DOMAIN_KEY, AuthContextUtils.getDomain());
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
index b6fe9ac..d545994 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
@@ -69,23 +69,23 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
protected PullUtils pullUtils;
@Autowired
- private NotificationManager notificationManager;
+ protected NotificationManager notificationManager;
@Autowired
- private AuditManager auditManager;
+ protected AuditManager auditManager;
@Autowired
- private ConnObjectUtils connObjectUtils;
+ protected ConnObjectUtils connObjectUtils;
@Autowired
- private VirSchemaDAO virSchemaDAO;
+ protected VirSchemaDAO virSchemaDAO;
@Autowired
- private VirAttrCache virAttrCache;
+ protected VirAttrCache virAttrCache;
- private SyncopePullExecutor executor;
+ protected SyncopePullExecutor executor;
- private Result latestResult;
+ protected Result latestResult;
protected abstract String getName(AnyTO anyTO);
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
index 395ec3e..cfbd325 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
@@ -96,7 +96,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
}
}
- private void update(final Any<?> any, final ProvisioningReport result) {
+ protected void update(final Any<?> any, final ProvisioningReport result) {
boolean changepwd;
Collection<String> resourceKeys;
if (any instanceof User) {
@@ -241,7 +241,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
}
}
- private void doHandle(final Any<?> any) throws JobExecutionException {
+ protected void doHandle(final Any<?> any) throws JobExecutionException {
AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
ProvisioningReport result = new ProvisioningReport();
@@ -473,7 +473,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
}
}
- private ResourceOperation toResourceOperation(final UnmatchingRule rule) {
+ protected ResourceOperation toResourceOperation(final UnmatchingRule rule) {
switch (rule) {
case ASSIGN:
case PROVISION:
@@ -483,7 +483,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
}
}
- private ResourceOperation toResourceOperation(final MatchingRule rule) {
+ protected ResourceOperation toResourceOperation(final MatchingRule rule) {
switch (rule) {
case UPDATE:
return ResourceOperation.UPDATE;
@@ -495,7 +495,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
}
}
- private ProvisioningReport.Status toProvisioningReportStatus(final PropagationTaskExecStatus status) {
+ protected ProvisioningReport.Status toProvisioningReportStatus(final PropagationTaskExecStatus status) {
switch (status) {
case FAILURE:
return ProvisioningReport.Status.FAILURE;
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPullResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPullResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPullResultHandlerImpl.java
deleted file mode 100644
index 3e652ee..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPullResultHandlerImpl.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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.Collections;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.patch.AnyObjectPatch;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.PropagationStatus;
-import org.apache.syncope.common.lib.to.AnyObjectTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
-import org.apache.syncope.core.provisioning.api.ProvisioningManager;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPullResultHandler;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class AnyObjectPullResultHandlerImpl extends AbstractPullResultHandler implements AnyObjectPullResultHandler {
-
- @Autowired
- private AnyObjectProvisioningManager anyObjectProvisioningManager;
-
- @Override
- protected AnyUtils getAnyUtils() {
- return anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT);
- }
-
- @Override
- protected String getName(final AnyTO anyTO) {
- return AnyObjectTO.class.cast(anyTO).getName();
- }
-
- @Override
- protected ProvisioningManager<?, ?> getProvisioningManager() {
- return anyObjectProvisioningManager;
- }
-
- @Override
- protected Any<?> getAny(final String key) {
- try {
- return anyObjectDAO.authFind(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving anyObject {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AnyTO getAnyTO(final String key) {
- return anyObjectDataBinder.getAnyObjectTO(key);
- }
-
- @Override
- protected AnyPatch newPatch(final String key) {
- AnyObjectPatch patch = new AnyObjectPatch();
- patch.setKey(key);
- return patch;
- }
-
- @Override
- protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
- return awfAdapter.update((AnyObjectPatch) patch);
- }
-
- @Override
- protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta) {
- AnyObjectTO anyObjectTO = AnyObjectTO.class.cast(anyTO);
-
- Map.Entry<String, List<PropagationStatus>> created = anyObjectProvisioningManager.create(
- anyObjectTO, Collections.singleton(profile.getTask().getResource().getKey()), true);
-
- return getAnyTO(created.getKey());
- }
-
- @Override
- protected AnyPatch doUpdate(
- final AnyTO before,
- final AnyPatch anyPatch,
- final SyncDelta delta,
- final ProvisioningReport result) {
-
- AnyObjectPatch anyObjectPatch = AnyObjectPatch.class.cast(anyPatch);
-
- Pair<AnyObjectPatch, List<PropagationStatus>> updated = anyObjectProvisioningManager.update(
- anyObjectPatch, Collections.singleton(profile.getTask().getResource().getKey()), true);
-
- return anyPatch;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPushResultHandlerImpl.java
deleted file mode 100644
index 48f464a..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPushResultHandlerImpl.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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 org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.patch.AnyObjectPatch;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPushResultHandler;
-
-public class AnyObjectPushResultHandlerImpl extends AbstractPushResultHandler implements AnyObjectPushResultHandler {
-
- @Override
- protected AnyUtils getAnyUtils() {
- return anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT);
- }
-
- @Override
- protected String getName(final Any<?> any) {
- return StringUtils.EMPTY;
- }
-
- @Override
- protected Any<?> getAny(final String key) {
- try {
- return anyObjectDAO.authFind(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving anyObject {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AnyTO getAnyTO(final String key) {
- return anyObjectDataBinder.getAnyObjectTO(key);
- }
-
- @Override
- protected AnyPatch newPatch(final String key) {
- AnyObjectPatch patch = new AnyObjectPatch();
- patch.setKey(key);
- return patch;
- }
-
- @Override
- protected WorkflowResult<? extends AnyObjectPatch> update(final AnyPatch patch) {
- return awfAdapter.update((AnyObjectPatch) patch);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultAnyObjectPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultAnyObjectPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultAnyObjectPullResultHandler.java
new file mode 100644
index 0000000..8d71a2d
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultAnyObjectPullResultHandler.java
@@ -0,0 +1,112 @@
+/*
+ * 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.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.patch.AnyObjectPatch;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
+import org.apache.syncope.core.provisioning.api.ProvisioningManager;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPullResultHandler;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DefaultAnyObjectPullResultHandler extends AbstractPullResultHandler implements AnyObjectPullResultHandler {
+
+ @Autowired
+ private AnyObjectProvisioningManager anyObjectProvisioningManager;
+
+ @Override
+ protected AnyUtils getAnyUtils() {
+ return anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT);
+ }
+
+ @Override
+ protected String getName(final AnyTO anyTO) {
+ return AnyObjectTO.class.cast(anyTO).getName();
+ }
+
+ @Override
+ protected ProvisioningManager<?, ?> getProvisioningManager() {
+ return anyObjectProvisioningManager;
+ }
+
+ @Override
+ protected Any<?> getAny(final String key) {
+ try {
+ return anyObjectDAO.authFind(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving anyObject {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AnyTO getAnyTO(final String key) {
+ return anyObjectDataBinder.getAnyObjectTO(key);
+ }
+
+ @Override
+ protected AnyPatch newPatch(final String key) {
+ AnyObjectPatch patch = new AnyObjectPatch();
+ patch.setKey(key);
+ return patch;
+ }
+
+ @Override
+ protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
+ return awfAdapter.update((AnyObjectPatch) patch);
+ }
+
+ @Override
+ protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta) {
+ AnyObjectTO anyObjectTO = AnyObjectTO.class.cast(anyTO);
+
+ Map.Entry<String, List<PropagationStatus>> created = anyObjectProvisioningManager.create(
+ anyObjectTO, Collections.singleton(profile.getTask().getResource().getKey()), true);
+
+ return getAnyTO(created.getKey());
+ }
+
+ @Override
+ protected AnyPatch doUpdate(
+ final AnyTO before,
+ final AnyPatch anyPatch,
+ final SyncDelta delta,
+ final ProvisioningReport result) {
+
+ AnyObjectPatch anyObjectPatch = AnyObjectPatch.class.cast(anyPatch);
+
+ Pair<AnyObjectPatch, List<PropagationStatus>> updated = anyObjectProvisioningManager.update(
+ anyObjectPatch, Collections.singleton(profile.getTask().getResource().getKey()), true);
+
+ return anyPatch;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultAnyObjectPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultAnyObjectPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultAnyObjectPushResultHandler.java
new file mode 100644
index 0000000..3c401ae
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultAnyObjectPushResultHandler.java
@@ -0,0 +1,70 @@
+/*
+ * 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 org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.patch.AnyObjectPatch;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPushResultHandler;
+
+public class DefaultAnyObjectPushResultHandler extends AbstractPushResultHandler implements AnyObjectPushResultHandler {
+
+ @Override
+ protected AnyUtils getAnyUtils() {
+ return anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT);
+ }
+
+ @Override
+ protected String getName(final Any<?> any) {
+ return StringUtils.EMPTY;
+ }
+
+ @Override
+ protected Any<?> getAny(final String key) {
+ try {
+ return anyObjectDAO.authFind(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving anyObject {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AnyTO getAnyTO(final String key) {
+ return anyObjectDataBinder.getAnyObjectTO(key);
+ }
+
+ @Override
+ protected AnyPatch newPatch(final String key) {
+ AnyObjectPatch patch = new AnyObjectPatch();
+ patch.setKey(key);
+ return patch;
+ }
+
+ @Override
+ protected WorkflowResult<? extends AnyObjectPatch> update(final AnyPatch patch) {
+ return awfAdapter.update((AnyObjectPatch) patch);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultGroupPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultGroupPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultGroupPullResultHandler.java
new file mode 100644
index 0000000..451659b
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultGroupPullResultHandler.java
@@ -0,0 +1,138 @@
+/*
+ * 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.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.AttrPatch;
+import org.apache.syncope.common.lib.patch.GroupPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
+import org.apache.syncope.core.provisioning.api.ProvisioningManager;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.apache.syncope.core.provisioning.api.pushpull.GroupPullResultHandler;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DefaultGroupPullResultHandler extends AbstractPullResultHandler implements GroupPullResultHandler {
+
+ @Autowired
+ private GroupProvisioningManager groupProvisioningManager;
+
+ private final Map<String, String> groupOwnerMap = new HashMap<>();
+
+ @Override
+ public Map<String, String> getGroupOwnerMap() {
+ return this.groupOwnerMap;
+ }
+
+ @Override
+ protected AnyUtils getAnyUtils() {
+ return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
+ }
+
+ @Override
+ protected String getName(final AnyTO anyTO) {
+ return GroupTO.class.cast(anyTO).getName();
+ }
+
+ @Override
+ protected ProvisioningManager<?, ?> getProvisioningManager() {
+ return groupProvisioningManager;
+ }
+
+ @Override
+ protected Any<?> getAny(final String key) {
+ try {
+ return groupDAO.authFind(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving group {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AnyTO getAnyTO(final String key) {
+ return groupDataBinder.getGroupTO(key);
+ }
+
+ @Override
+ protected AnyPatch newPatch(final String key) {
+ GroupPatch patch = new GroupPatch();
+ patch.setKey(key);
+ return patch;
+ }
+
+ @Override
+ protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
+ return gwfAdapter.update((GroupPatch) patch);
+ }
+
+ @Override
+ protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta) {
+ GroupTO groupTO = GroupTO.class.cast(anyTO);
+
+ Map.Entry<String, List<PropagationStatus>> created = groupProvisioningManager.create(
+ groupTO,
+ groupOwnerMap,
+ Collections.singleton(profile.getTask().getResource().getKey()),
+ true);
+
+ return getAnyTO(created.getKey());
+ }
+
+ @Override
+ protected AnyPatch doUpdate(
+ final AnyTO before,
+ final AnyPatch anyPatch,
+ final SyncDelta delta,
+ final ProvisioningReport result) {
+
+ GroupPatch groupPatch = GroupPatch.class.cast(anyPatch);
+
+ Pair<GroupPatch, List<PropagationStatus>> updated = groupProvisioningManager.update(
+ groupPatch, Collections.singleton(profile.getTask().getResource().getKey()), true);
+
+ String groupOwner = null;
+ for (AttrPatch attrPatch : groupPatch.getPlainAttrs()) {
+ if (attrPatch.getOperation() == PatchOperation.ADD_REPLACE && attrPatch.getAttrTO() != null
+ && attrPatch.getAttrTO().getSchema().isEmpty() && !attrPatch.getAttrTO().getValues().isEmpty()) {
+
+ groupOwner = attrPatch.getAttrTO().getValues().get(0);
+ }
+ }
+ if (groupOwner != null) {
+ groupOwnerMap.put(updated.getLeft().getKey(), groupOwner);
+ }
+
+ return anyPatch;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultGroupPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultGroupPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultGroupPushResultHandler.java
new file mode 100644
index 0000000..993f747
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultGroupPushResultHandler.java
@@ -0,0 +1,70 @@
+/*
+ * 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 org.apache.syncope.common.lib.patch.GroupPatch;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.pushpull.GroupPushResultHandler;
+
+public class DefaultGroupPushResultHandler extends AbstractPushResultHandler implements GroupPushResultHandler {
+
+ @Override
+ protected AnyUtils getAnyUtils() {
+ return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
+ }
+
+ @Override
+ protected String getName(final Any<?> any) {
+ return Group.class.cast(any).getName();
+ }
+
+ @Override
+ protected Any<?> getAny(final String key) {
+ try {
+ return groupDAO.authFind(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving group {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AnyTO getAnyTO(final String key) {
+ return groupDataBinder.getGroupTO(key);
+ }
+
+ @Override
+ protected AnyPatch newPatch(final String key) {
+ GroupPatch patch = new GroupPatch();
+ patch.setKey(key);
+ return patch;
+ }
+
+ @Override
+ protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
+ return gwfAdapter.update((GroupPatch) patch);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java
new file mode 100644
index 0000000..69c0604
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java
@@ -0,0 +1,795 @@
+/*
+ * 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.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+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.core.provisioning.api.PropagationByResource;
+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.search.AnyCond;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+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.resource.OrgUnit;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.persistence.api.entity.task.PullTask;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
+import org.apache.syncope.core.provisioning.api.pushpull.RealmPullResultHandler;
+import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullExecutor;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.identityconnectors.framework.common.objects.SyncDeltaType;
+import org.quartz.JobExecutionException;
+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 {
+
+ @Autowired
+ private PullUtils pullUtils;
+
+ @Autowired
+ private ConnObjectUtils connObjectUtils;
+
+ @Autowired
+ private AnySearchDAO searchDAO;
+
+ private SyncopePullExecutor executor;
+
+ private Result latestResult;
+
+ @Override
+ public void setPullExecutor(final SyncopePullExecutor executor) {
+ this.executor = executor;
+ }
+
+ @Override
+ public boolean handle(final SyncDelta delta) {
+ try {
+ OrgUnit orgUnit = profile.getTask().getResource().getOrgUnit();
+ if (orgUnit == null) {
+ throw new JobExecutionException("No orgUnit found on " + profile.getTask().getResource() + " for "
+ + delta.getObject().getObjectClass());
+ }
+
+ doHandle(delta, orgUnit);
+
+ LOG.debug("Successfully handled {}", delta);
+
+ if (profile.getTask().getPullMode() != PullMode.INCREMENTAL) {
+ return true;
+ }
+
+ boolean shouldContinue;
+ synchronized (this) {
+ shouldContinue = latestResult == Result.SUCCESS;
+ this.latestResult = null;
+ }
+ if (shouldContinue) {
+ executor.setLatestSyncToken(delta.getObjectClass(), delta.getToken());
+ }
+ return shouldContinue;
+ } catch (IgnoreProvisionException e) {
+ ProvisioningReport ignoreResult = new ProvisioningReport();
+ ignoreResult.setOperation(ResourceOperation.NONE);
+ ignoreResult.setStatus(ProvisioningReport.Status.IGNORE);
+ ignoreResult.setAnyType(REALM_TYPE);
+ ignoreResult.setKey(null);
+ ignoreResult.setName(delta.getObject().getName().getNameValue());
+ profile.getResults().add(ignoreResult);
+
+ LOG.warn("Ignoring during pull", e);
+
+ executor.setLatestSyncToken(delta.getObjectClass(), delta.getToken());
+
+ return true;
+ } catch (JobExecutionException e) {
+ LOG.error("Pull failed", e);
+
+ return false;
+ }
+ }
+
+ private List<ProvisioningReport> assign(final SyncDelta delta, final OrgUnit orgUnit) throws JobExecutionException {
+ if (!profile.getTask().isPerformCreate()) {
+ LOG.debug("PullTask not configured for create");
+ finalize(UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), Result.SUCCESS, null, null, delta);
+ return Collections.<ProvisioningReport>emptyList();
+ }
+
+ RealmTO realmTO = connObjectUtils.getRealmTO(delta.getObject(), profile.getTask(), orgUnit);
+ if (realmTO.getFullPath() == null) {
+ if (realmTO.getParent() == null) {
+ realmTO.setParent(profile.getTask().getDestinatioRealm().getFullPath());
+ }
+
+ realmTO.setFullPath(realmTO.getParent() + "/" + realmTO.getName());
+ }
+ realmTO.getResources().add(profile.getTask().getResource().getKey());
+
+ ProvisioningReport result = new ProvisioningReport();
+ result.setOperation(ResourceOperation.CREATE);
+ result.setAnyType(REALM_TYPE);
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ result.setName(realmTO.getFullPath());
+
+ if (profile.isDryRun()) {
+ result.setKey(null);
+ finalize(UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), Result.SUCCESS, null, null, delta);
+ } else {
+ SyncDelta actionedDelta = delta;
+ for (PullActions action : profile.getActions()) {
+ actionedDelta = action.beforeAssign(profile, actionedDelta, realmTO);
+ }
+
+ create(realmTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), result);
+ }
+
+ return Collections.singletonList(result);
+ }
+
+ private List<ProvisioningReport> provision(final SyncDelta delta, final OrgUnit orgUnit)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformCreate()) {
+ LOG.debug("PullTask not configured for create");
+ finalize(UnmatchingRule.toEventName(UnmatchingRule.PROVISION), Result.SUCCESS, null, null, delta);
+ return Collections.<ProvisioningReport>emptyList();
+ }
+
+ RealmTO realmTO = connObjectUtils.getRealmTO(delta.getObject(), profile.getTask(), orgUnit);
+ if (realmTO.getFullPath() == null) {
+ if (realmTO.getParent() == null) {
+ realmTO.setParent(profile.getTask().getDestinatioRealm().getFullPath());
+ }
+
+ realmTO.setFullPath(realmTO.getParent() + "/" + realmTO.getName());
+ }
+
+ ProvisioningReport result = new ProvisioningReport();
+ result.setOperation(ResourceOperation.CREATE);
+ result.setAnyType(REALM_TYPE);
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ result.setName(realmTO.getFullPath());
+
+ if (profile.isDryRun()) {
+ result.setKey(null);
+ finalize(UnmatchingRule.toEventName(UnmatchingRule.PROVISION), Result.SUCCESS, null, null, delta);
+ } else {
+ SyncDelta actionedDelta = delta;
+ for (PullActions action : profile.getActions()) {
+ actionedDelta = action.beforeProvision(profile, actionedDelta, realmTO);
+ }
+
+ create(realmTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.PROVISION), result);
+ }
+
+ return Collections.singletonList(result);
+ }
+
+ private 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;
+ }
+ }
+
+ 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().getFullPath(), realmTO));
+
+ PropagationByResource propByRes = new PropagationByResource();
+ for (String resource : realm.getResourceKeys()) {
+ propByRes.add(ResourceOperation.CREATE, resource);
+ }
+ List<PropagationTask> 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);
+ }
+
+ private List<ProvisioningReport> update(final SyncDelta delta, final List<String> keys)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("PullTask not configured for update");
+ finalize(MatchingRule.toEventName(MatchingRule.UPDATE), Result.SUCCESS, null, null, delta);
+ return Collections.<ProvisioningReport>emptyList();
+ }
+
+ LOG.debug("About to update {}", keys);
+
+ List<ProvisioningReport> results = new ArrayList<>();
+
+ SyncDelta workingDelta = delta;
+ for (String key : keys) {
+ LOG.debug("About to update {}", key);
+
+ ProvisioningReport result = new ProvisioningReport();
+ result.setOperation(ResourceOperation.UPDATE);
+ result.setAnyType(REALM_TYPE);
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ result.setKey(key);
+
+ Realm realm = realmDAO.find(key);
+ RealmTO before = binder.getRealmTO(realm, true);
+ if (before == null) {
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(String.format("Realm '%s' not found", key));
+ } else {
+ result.setName(before.getFullPath());
+ }
+
+ if (!profile.isDryRun()) {
+ Result resultStatus;
+ Object output;
+
+ if (before == null) {
+ resultStatus = Result.FAILURE;
+ output = null;
+ } else {
+ try {
+ for (PullActions action : profile.getActions()) {
+ workingDelta = action.beforeUpdate(profile, workingDelta, before, null);
+ }
+
+ PropagationByResource propByRes = binder.update(realm, before);
+ realm = realmDAO.save(realm);
+ RealmTO updated = binder.getRealmTO(realm, true);
+
+ List<PropagationTask> tasks = propagationManager.createTasks(realm, propByRes, null);
+ taskExecutor.execute(tasks, false);
+
+ for (PullActions action : profile.getActions()) {
+ action.after(profile, workingDelta, 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 {}", workingDelta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+ } catch (Exception e) {
+ throwIgnoreProvisionException(workingDelta, e);
+
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+ LOG.error("Could not update Realm {}", workingDelta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+ }
+ }
+ finalize(MatchingRule.toEventName(MatchingRule.UPDATE), resultStatus, before, output, workingDelta);
+ }
+ results.add(result);
+ }
+
+ return results;
+ }
+
+ private List<ProvisioningReport> deprovision(final SyncDelta delta, final List<String> keys, final boolean unlink)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("PullTask not configured for update");
+ finalize(unlink
+ ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
+ : MatchingRule.toEventName(MatchingRule.DEPROVISION), Result.SUCCESS, null, null, delta);
+ return Collections.<ProvisioningReport>emptyList();
+ }
+
+ LOG.debug("About to deprovision {}", keys);
+
+ final List<ProvisioningReport> results = new ArrayList<>();
+
+ SyncDelta workingDelta = delta;
+ for (String key : keys) {
+ LOG.debug("About to unassign resource {}", key);
+
+ ProvisioningReport result = new ProvisioningReport();
+ result.setOperation(ResourceOperation.DELETE);
+ result.setAnyType(REALM_TYPE);
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ result.setKey(key);
+
+ Realm realm = realmDAO.find(key);
+ RealmTO before = binder.getRealmTO(realm, true);
+ if (before == null) {
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(String.format("Realm '%s' not found", key));
+ } else {
+ result.setName(before.getFullPath());
+ }
+
+ if (!profile.isDryRun()) {
+ Object output;
+ Result resultStatus;
+
+ if (before == null) {
+ resultStatus = Result.FAILURE;
+ output = null;
+ } else {
+ try {
+ if (unlink) {
+ for (PullActions action : profile.getActions()) {
+ workingDelta = action.beforeUnassign(profile, workingDelta, before);
+ }
+ } else {
+ for (PullActions action : profile.getActions()) {
+ workingDelta = action.beforeDeprovision(profile, workingDelta, before);
+ }
+ }
+
+ PropagationByResource propByRes = new PropagationByResource();
+ propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
+ taskExecutor.execute(propagationManager.createTasks(realm, propByRes, null), false);
+
+ if (unlink) {
+ realm.getResources().remove(profile.getTask().getResource());
+ output = binder.getRealmTO(realmDAO.save(realm), true);
+ } else {
+ output = binder.getRealmTO(realm, true);
+ }
+
+ for (PullActions action : profile.getActions()) {
+ action.after(profile, workingDelta, RealmTO.class.cast(output), 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 {}", workingDelta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+ } catch (Exception e) {
+ throwIgnoreProvisionException(workingDelta, 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;
+ }
+ }
+ finalize(unlink
+ ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
+ : MatchingRule.toEventName(MatchingRule.DEPROVISION), resultStatus, before, output, delta);
+ }
+ results.add(result);
+ }
+
+ return results;
+ }
+
+ private List<ProvisioningReport> link(final SyncDelta delta, final List<String> keys, final boolean unlink)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("PullTask not configured for update");
+ finalize(unlink
+ ? MatchingRule.toEventName(MatchingRule.UNLINK)
+ : MatchingRule.toEventName(MatchingRule.LINK), Result.SUCCESS, null, null, delta);
+ return Collections.<ProvisioningReport>emptyList();
+ }
+
+ LOG.debug("About to link {}", keys);
+
+ final List<ProvisioningReport> results = new ArrayList<>();
+
+ SyncDelta workingDelta = delta;
+ for (String key : keys) {
+ LOG.debug("About to unassign resource {}", key);
+
+ ProvisioningReport result = new ProvisioningReport();
+ result.setOperation(ResourceOperation.NONE);
+ result.setAnyType(REALM_TYPE);
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ result.setKey(key);
+
+ Realm realm = realmDAO.find(key);
+ RealmTO before = binder.getRealmTO(realm, true);
+ if (before == null) {
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(String.format("Realm '%s' not found", key));
+ } else {
+ result.setName(before.getFullPath());
+ }
+
+ Object output;
+ Result resultStatus;
+ if (!profile.isDryRun()) {
+ if (before == null) {
+ resultStatus = Result.FAILURE;
+ output = null;
+ } else {
+ try {
+ if (unlink) {
+ for (PullActions action : profile.getActions()) {
+ workingDelta = action.beforeUnlink(profile, workingDelta, before);
+ }
+ } else {
+ for (PullActions action : profile.getActions()) {
+ workingDelta = action.beforeLink(profile, workingDelta, before);
+ }
+ }
+
+ if (unlink) {
+ realm.getResources().remove(profile.getTask().getResource());
+ } else {
+ realm.add(profile.getTask().getResource());
+ }
+ output = update(workingDelta, Collections.singletonList(key));
+
+ for (PullActions action : profile.getActions()) {
+ action.after(profile, workingDelta, RealmTO.class.cast(output), 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 {}", workingDelta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+ } catch (Exception e) {
+ throwIgnoreProvisionException(workingDelta, e);
+
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+ LOG.error("Could not update Realm {}", workingDelta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+ }
+ }
+ finalize(unlink
+ ? MatchingRule.toEventName(MatchingRule.UNLINK)
+ : MatchingRule.toEventName(MatchingRule.LINK), resultStatus, before, output, workingDelta);
+ }
+ results.add(result);
+ }
+
+ return results;
+ }
+
+ private List<ProvisioningReport> delete(final SyncDelta delta, final List<String> keys)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformDelete()) {
+ LOG.debug("PullTask not configured for delete");
+ finalize(ResourceOperation.DELETE.name().toLowerCase(), Result.SUCCESS, null, null, delta);
+ return Collections.<ProvisioningReport>emptyList();
+ }
+
+ LOG.debug("About to delete {}", keys);
+
+ List<ProvisioningReport> results = new ArrayList<>();
+
+ SyncDelta workingDelta = delta;
+ for (String key : keys) {
+ Object output;
+ Result resultStatus = Result.FAILURE;
+
+ ProvisioningReport result = new ProvisioningReport();
+
+ try {
+ result.setKey(key);
+ result.setOperation(ResourceOperation.DELETE);
+ result.setAnyType(REALM_TYPE);
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+
+ Realm realm = realmDAO.find(key);
+ RealmTO before = binder.getRealmTO(realm, true);
+ if (before == null) {
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(String.format("Realm '%s' not found", key));
+ } else {
+ result.setName(before.getFullPath());
+ }
+
+ if (!profile.isDryRun()) {
+ for (PullActions action : profile.getActions()) {
+ workingDelta = action.beforeDelete(profile, workingDelta, before);
+ }
+
+ try {
+ if (!realmDAO.findChildren(realm).isEmpty()) {
+ throw SyncopeClientException.build(ClientExceptionType.HasChildren);
+ }
+
+ Set<String> adminRealms = Collections.singleton(realm.getFullPath());
+ AnyCond keyCond = new AnyCond(AttributeCond.Type.ISNOTNULL);
+ keyCond.setSchema("key");
+ SearchCond allMatchingCond = SearchCond.getLeafCond(keyCond);
+ int users = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.USER);
+ int groups = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.GROUP);
+ int anyObjects = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.ANY_OBJECT);
+
+ if (users + groups + anyObjects > 0) {
+ SyncopeClientException containedAnys = SyncopeClientException.build(
+ ClientExceptionType.AssociatedAnys);
+ containedAnys.getElements().add(users + " user(s)");
+ containedAnys.getElements().add(groups + " group(s)");
+ containedAnys.getElements().add(anyObjects + " anyObject(s)");
+ throw containedAnys;
+ }
+
+ PropagationByResource propByRes = new PropagationByResource();
+ for (String resource : realm.getResourceKeys()) {
+ propByRes.add(ResourceOperation.DELETE, resource);
+ }
+ List<PropagationTask> tasks = propagationManager.createTasks(realm, propByRes, null);
+ taskExecutor.execute(tasks, false);
+
+ realmDAO.delete(realm);
+
+ output = null;
+ resultStatus = Result.SUCCESS;
+
+ for (PullActions action : profile.getActions()) {
+ action.after(profile, workingDelta, before, result);
+ }
+ } catch (Exception e) {
+ throwIgnoreProvisionException(workingDelta, e);
+
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+ LOG.error("Could not delete {}", realm, e);
+ output = e;
+ }
+
+ finalize(ResourceOperation.DELETE.name().toLowerCase(), resultStatus, before, output, workingDelta);
+ }
+
+ results.add(result);
+ } catch (DelegatedAdministrationException e) {
+ LOG.error("Not allowed to read Realm {}", key, e);
+ } catch (Exception e) {
+ LOG.error("Could not delete Realm {}", key, e);
+ }
+ }
+
+ return results;
+ }
+
+ private ProvisioningReport ignore(
+ final SyncDelta delta,
+ final boolean matching)
+ throws JobExecutionException {
+
+ LOG.debug("Any to ignore {}", delta.getObject().getUid().getUidValue());
+
+ ProvisioningReport result = new ProvisioningReport();
+
+ result.setKey(null);
+ result.setName(delta.getObject().getUid().getUidValue());
+ result.setOperation(ResourceOperation.NONE);
+ result.setAnyType(REALM_TYPE);
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+
+ if (!profile.isDryRun()) {
+ finalize(matching
+ ? MatchingRule.toEventName(MatchingRule.IGNORE)
+ : UnmatchingRule.toEventName(UnmatchingRule.IGNORE), Result.SUCCESS, null, null, delta);
+ }
+
+ return result;
+ }
+
+ private void doHandle(final SyncDelta delta, final OrgUnit orgUnit) throws JobExecutionException {
+ LOG.debug("Process {} for {} as {}",
+ delta.getDeltaType(), delta.getUid().getUidValue(), delta.getObject().getObjectClass());
+
+ String uid = delta.getPreviousUid() == null
+ ? delta.getUid().getUidValue()
+ : delta.getPreviousUid().getUidValue();
+
+ List<String> keys = pullUtils.findExisting(uid, delta.getObject(), orgUnit);
+ LOG.debug("Match found for {} as {}: {}",
+ delta.getUid().getUidValue(), delta.getObject().getObjectClass(), keys);
+
+ if (keys.size() > 1) {
+ switch (profile.getResAct()) {
+ case IGNORE:
+ throw new IllegalStateException("More than one match " + keys);
+
+ case FIRSTMATCH:
+ keys = keys.subList(0, 1);
+ break;
+
+ case LASTMATCH:
+ keys = keys.subList(keys.size() - 1, keys.size());
+ break;
+
+ default:
+ // keep keys unmodified
+ }
+ }
+
+ try {
+ if (SyncDeltaType.CREATE_OR_UPDATE == delta.getDeltaType()) {
+ if (keys.isEmpty()) {
+ switch (profile.getTask().getUnmatchingRule()) {
+ case ASSIGN:
+ profile.getResults().addAll(assign(delta, orgUnit));
+ break;
+
+ case PROVISION:
+ profile.getResults().addAll(provision(delta, orgUnit));
+ break;
+
+ case IGNORE:
+ profile.getResults().add(ignore(delta, false));
+ break;
+
+ default:
+ // do nothing
+ }
+ } else {
+ switch (profile.getTask().getMatchingRule()) {
+ case UPDATE:
+ profile.getResults().addAll(update(delta, keys));
+ break;
+
+ case DEPROVISION:
+ profile.getResults().addAll(deprovision(delta, keys, false));
+ break;
+
+ case UNASSIGN:
+ profile.getResults().addAll(deprovision(delta, keys, true));
+ break;
+
+ case LINK:
+ profile.getResults().addAll(link(delta, keys, false));
+ break;
+
+ case UNLINK:
+ profile.getResults().addAll(link(delta, keys, true));
+ break;
+
+ case IGNORE:
+ profile.getResults().add(ignore(delta, true));
+ break;
+
+ default:
+ // do nothing
+ }
+ }
+ } else if (SyncDeltaType.DELETE == delta.getDeltaType()) {
+ if (keys.isEmpty()) {
+ finalize(ResourceOperation.DELETE.name().toLowerCase(), Result.SUCCESS, null, null, delta);
+ LOG.debug("No match found for deletion");
+ } else {
+ profile.getResults().addAll(delete(delta, keys));
+ }
+ }
+ } catch (IllegalStateException | IllegalArgumentException e) {
+ LOG.warn(e.getMessage());
+ }
+ }
+
+ private void finalize(
+ final String event,
+ final Result result,
+ final Object before,
+ final Object output,
+ final SyncDelta delta) {
+
+ synchronized (this) {
+ this.latestResult = result;
+ }
+
+ notificationManager.createTasks(AuditElements.EventCategoryType.PULL,
+ REALM_TYPE.toLowerCase(),
+ profile.getTask().getResource().getKey(),
+ event,
+ result,
+ before,
+ output,
+ delta);
+
+ auditManager.audit(AuditElements.EventCategoryType.PULL,
+ REALM_TYPE.toLowerCase(),
+ profile.getTask().getResource().getKey(),
+ event,
+ result,
+ before,
+ output,
+ delta);
+ }
+}
[5/6] syncope git commit: [SYNCOPE-1212] Clearing and refactoring for
easier extensions
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java
new file mode 100644
index 0000000..1040461
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java
@@ -0,0 +1,450 @@
+/*
+ * 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.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.syncope.common.lib.to.RealmTO;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.AuditElements.Result;
+import org.apache.syncope.common.lib.types.MatchingRule;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.core.provisioning.api.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.common.lib.types.UnmatchingRule;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
+import org.apache.syncope.core.persistence.api.entity.task.PushTask;
+import org.apache.syncope.core.provisioning.api.MappingManager;
+import org.apache.syncope.core.provisioning.api.TimeoutException;
+import org.apache.syncope.core.provisioning.api.event.AfterHandlingEvent;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
+import org.apache.syncope.core.provisioning.api.pushpull.RealmPushResultHandler;
+import org.apache.syncope.core.provisioning.java.job.AfterHandlingJob;
+import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
+import org.identityconnectors.framework.common.objects.AttributeBuilder;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+public class DefaultRealmPushResultHandler
+ extends AbstractRealmResultHandler<PushTask, PushActions>
+ implements RealmPushResultHandler {
+
+ @Autowired
+ private MappingManager mappingManager;
+
+ @Autowired
+ private SchedulerFactoryBean scheduler;
+
+ @Transactional(propagation = Propagation.REQUIRES_NEW)
+ @Override
+ public boolean handle(final String realmKey) {
+ Realm realm = null;
+ try {
+ realm = realmDAO.find(realmKey);
+ doHandle(realm);
+ return true;
+ } catch (IgnoreProvisionException e) {
+ ProvisioningReport result = new ProvisioningReport();
+ result.setOperation(ResourceOperation.NONE);
+ result.setAnyType(realm == null ? null : REALM_TYPE);
+ result.setStatus(ProvisioningReport.Status.IGNORE);
+ result.setKey(realmKey);
+ profile.getResults().add(result);
+
+ LOG.warn("Ignoring during push", e);
+ return true;
+ } catch (JobExecutionException e) {
+ LOG.error("Push failed", e);
+ return false;
+ }
+ }
+
+ private void reportPropagation(final ProvisioningReport result, final PropagationReporter reporter) {
+ if (!reporter.getStatuses().isEmpty()) {
+ result.setStatus(toProvisioningReportStatus(reporter.getStatuses().get(0).getStatus()));
+ result.setMessage(reporter.getStatuses().get(0).getFailureReason());
+ }
+ }
+
+ 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;
+ }
+
+ private void deprovision(final Realm realm, final ProvisioningReport result) {
+ List<String> noPropResources = new ArrayList<>(realm.getResourceKeys());
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ PropagationByResource propByRes = new PropagationByResource();
+ propByRes.addAll(ResourceOperation.DELETE, realm.getResourceKeys());
+
+ PropagationReporter reporter = taskExecutor.execute(
+ propagationManager.createTasks(realm, propByRes, noPropResources), false);
+ reportPropagation(result, reporter);
+ }
+
+ private void provision(final Realm realm, final ProvisioningReport result) {
+ List<String> noPropResources = new ArrayList<>(realm.getResourceKeys());
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ PropagationByResource propByRes = new PropagationByResource();
+ propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
+
+ PropagationReporter reporter = taskExecutor.execute(
+ propagationManager.createTasks(realm, propByRes, noPropResources), false);
+ reportPropagation(result, reporter);
+ }
+
+ private void link(final Realm realm, final boolean unlink, final ProvisioningReport result) {
+ RealmTO realmTO = binder.getRealmTO(realm, true);
+ if (unlink) {
+ realmTO.getResources().remove(profile.getTask().getResource().getKey());
+ } else {
+ realmTO.getResources().add(profile.getTask().getResource().getKey());
+ }
+
+ update(realmTO, result);
+ }
+
+ private void unassign(final Realm realm, final ProvisioningReport result) {
+ RealmTO realmTO = binder.getRealmTO(realm, true);
+ realmTO.getResources().remove(profile.getTask().getResource().getKey());
+
+ deprovision(update(realmTO, result), result);
+ }
+
+ private void assign(final Realm realm, final ProvisioningReport result) {
+ RealmTO realmTO = binder.getRealmTO(realm, true);
+ realmTO.getResources().add(profile.getTask().getResource().getKey());
+
+ provision(update(realmTO, result), result);
+ }
+
+ protected ConnectorObject getRemoteObject(
+ final ObjectClass objectClass,
+ final String connObjectKey,
+ final String connObjectKeyValue,
+ final Iterator<? extends Item> iterator) {
+
+ ConnectorObject obj = null;
+ try {
+ obj = profile.getConnector().getObject(
+ objectClass,
+ AttributeBuilder.build(connObjectKey, connObjectKeyValue),
+ MappingUtils.buildOperationOptions(iterator));
+ } catch (TimeoutException toe) {
+ LOG.debug("Request timeout", toe);
+ throw toe;
+ } catch (RuntimeException ignore) {
+ LOG.debug("While resolving {}", connObjectKeyValue, ignore);
+ }
+
+ return obj;
+ }
+
+ private void doHandle(final Realm realm) throws JobExecutionException {
+ ProvisioningReport result = new ProvisioningReport();
+ profile.getResults().add(result);
+
+ result.setKey(realm.getKey());
+ result.setAnyType(REALM_TYPE);
+ result.setName(realm.getFullPath());
+
+ LOG.debug("Propagating Realm with key {} towards {}", realm.getKey(), profile.getTask().getResource());
+
+ Object output = null;
+ Result resultStatus = null;
+
+ // Try to read remote object BEFORE any actual operation
+ OrgUnit orgUnit = profile.getTask().getResource().getOrgUnit();
+ Optional<? extends OrgUnitItem> connObjectKey = orgUnit.getConnObjectKeyItem();
+ String connObjecKeyValue = mappingManager.getConnObjectKeyValue(realm, orgUnit);
+
+ ConnectorObject beforeObj = getRemoteObject(
+ orgUnit.getObjectClass(),
+ connObjectKey.get().getExtAttrName(),
+ connObjecKeyValue,
+ orgUnit.getItems().iterator());
+
+ 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.toEventName(profile.getTask().getUnmatchingRule())
+ : MatchingRule.toEventName(profile.getTask().getMatchingRule());
+
+ boolean notificationsAvailable = notificationManager.notificationsAvailable(
+ AuditElements.EventCategoryType.PUSH,
+ REALM_TYPE.toLowerCase(),
+ profile.getTask().getResource().getKey(),
+ operation);
+ boolean auditRequested = auditManager.auditRequested(
+ AuditElements.EventCategoryType.PUSH,
+ REALM_TYPE.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);
+ }
+
+ break;
+
+ 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);
+ }
+
+ break;
+
+ 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);
+ }
+
+ break;
+
+ case IGNORE:
+ LOG.debug("Ignored any: {}", realm);
+ result.setStatus(ProvisioningReport.Status.IGNORE);
+ break;
+
+ 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), result);
+ }
+
+ break;
+
+ 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, result);
+ }
+
+ break;
+
+ 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, result);
+ }
+
+ break;
+
+ 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);
+ }
+
+ break;
+
+ 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);
+ }
+
+ break;
+
+ case IGNORE:
+ LOG.debug("Ignored any: {}", realm);
+ result.setStatus(ProvisioningReport.Status.IGNORE);
+ break;
+
+ default:
+ // do nothing
+ }
+ }
+
+ for (PushActions action : profile.getActions()) {
+ action.after(profile, realm, result);
+ }
+
+ if (result.getStatus() == null) {
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ }
+ resultStatus = AuditElements.Result.SUCCESS;
+ output = getRemoteObject(
+ orgUnit.getObjectClass(),
+ connObjectKey.get().getExtAttrName(),
+ connObjecKeyValue,
+ orgUnit.getItems().iterator());
+ } 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 {}", 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(
+ AuditElements.EventCategoryType.PUSH,
+ REALM_TYPE.toLowerCase(),
+ profile.getTask().getResource().getKey(),
+ operation,
+ resultStatus,
+ beforeObj,
+ output,
+ realm));
+ AfterHandlingJob.schedule(scheduler, jobMap);
+ }
+ }
+ }
+ }
+
+ private ResourceOperation toResourceOperation(final UnmatchingRule rule) {
+ switch (rule) {
+ case ASSIGN:
+ case PROVISION:
+ return ResourceOperation.CREATE;
+ default:
+ return ResourceOperation.NONE;
+ }
+ }
+
+ private ResourceOperation toResourceOperation(final MatchingRule rule) {
+ switch (rule) {
+ case UPDATE:
+ return ResourceOperation.UPDATE;
+ case DEPROVISION:
+ case UNASSIGN:
+ return ResourceOperation.DELETE;
+ default:
+ return ResourceOperation.NONE;
+ }
+ }
+
+ private ProvisioningReport.Status toProvisioningReportStatus(final PropagationTaskExecStatus status) {
+ switch (status) {
+ case FAILURE:
+ return ProvisioningReport.Status.FAILURE;
+
+ case SUCCESS:
+ return ProvisioningReport.Status.SUCCESS;
+
+ case CREATED:
+ case NOT_ATTEMPTED:
+ default:
+ return ProvisioningReport.Status.IGNORE;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPullResultHandler.java
new file mode 100644
index 0000000..83a5401
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPullResultHandler.java
@@ -0,0 +1,134 @@
+/*
+ * 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.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.provisioning.api.ProvisioningManager;
+import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.apache.syncope.core.provisioning.api.pushpull.UserPullResultHandler;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DefaultUserPullResultHandler extends AbstractPullResultHandler implements UserPullResultHandler {
+
+ @Autowired
+ private UserProvisioningManager userProvisioningManager;
+
+ @Override
+ protected AnyUtils getAnyUtils() {
+ return anyUtilsFactory.getInstance(AnyTypeKind.USER);
+ }
+
+ @Override
+ protected String getName(final AnyTO anyTO) {
+ return UserTO.class.cast(anyTO).getUsername();
+ }
+
+ @Override
+ protected ProvisioningManager<?, ?> getProvisioningManager() {
+ return userProvisioningManager;
+ }
+
+ @Override
+ protected Any<?> getAny(final String key) {
+ try {
+ return userDAO.authFind(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving user {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AnyTO getAnyTO(final String key) {
+ return userDataBinder.getUserTO(key);
+ }
+
+ @Override
+ protected AnyPatch newPatch(final String key) {
+ UserPatch patch = new UserPatch();
+ patch.setKey(key);
+ return patch;
+ }
+
+ @Override
+ protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
+ WorkflowResult<Pair<UserPatch, Boolean>> update = uwfAdapter.update((UserPatch) patch);
+ return new WorkflowResult<>(update.getResult().getLeft(), update.getPropByRes(), update.getPerformedTasks());
+ }
+
+ @Override
+ protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta) {
+ UserTO userTO = UserTO.class.cast(anyTO);
+
+ Boolean enabled = pullUtils.readEnabled(delta.getObject(), profile.getTask());
+ Map.Entry<String, List<PropagationStatus>> created =
+ userProvisioningManager.create(userTO, true, true, enabled,
+ Collections.singleton(profile.getTask().getResource().getKey()), true);
+
+ return getAnyTO(created.getKey());
+ }
+
+ @Override
+ protected AnyPatch doUpdate(
+ final AnyTO before,
+ final AnyPatch anyPatch,
+ final SyncDelta delta,
+ final ProvisioningReport result) {
+
+ UserPatch userPatch = UserPatch.class.cast(anyPatch);
+ Boolean enabled = pullUtils.readEnabled(delta.getObject(), profile.getTask());
+
+ Pair<UserPatch, List<PropagationStatus>> updated = userProvisioningManager.update(
+ userPatch,
+ result,
+ enabled,
+ Collections.singleton(profile.getTask().getResource().getKey()),
+ true);
+
+ return updated.getLeft();
+ }
+
+ @Override
+ protected void doDelete(final AnyTypeKind kind, final String key) {
+ try {
+ userProvisioningManager.delete(
+ key, Collections.<String>singleton(profile.getTask().getResource().getKey()), true);
+ } catch (Exception 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 user " + key, e);
+ }
+
+ uwfAdapter.delete(key);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java
new file mode 100644
index 0000000..70f3a00
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java
@@ -0,0 +1,99 @@
+/*
+ * 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.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.provisioning.api.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.pushpull.UserPushResultHandler;
+
+public class DefaultUserPushResultHandler extends AbstractPushResultHandler implements UserPushResultHandler {
+
+ @Override
+ protected AnyUtils getAnyUtils() {
+ return anyUtilsFactory.getInstance(AnyTypeKind.USER);
+ }
+
+ @Override
+ protected void provision(final Any<?> any, final Boolean enabled, final ProvisioningReport result) {
+ AnyTO before = getAnyTO(any.getKey());
+
+ List<String> noPropResources = new ArrayList<>(before.getResources());
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ PropagationByResource propByRes = new PropagationByResource();
+ propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
+
+ PropagationReporter reporter = taskExecutor.execute(propagationManager.getUserCreateTasks(
+ before.getKey(),
+ null,
+ enabled,
+ propByRes,
+ before.getVirAttrs(),
+ noPropResources),
+ false);
+ reportPropagation(result, reporter);
+ }
+
+ @Override
+ protected String getName(final Any<?> any) {
+ return User.class.cast(any).getUsername();
+ }
+
+ @Override
+ protected Any<?> getAny(final String key) {
+ try {
+ return userDAO.authFind(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving user {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AnyTO getAnyTO(final String key) {
+ return userDataBinder.getUserTO(key);
+ }
+
+ @Override
+ protected AnyPatch newPatch(final String key) {
+ UserPatch patch = new UserPatch();
+ patch.setKey(key);
+ return patch;
+ }
+
+ @Override
+ protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
+ WorkflowResult<Pair<UserPatch, Boolean>> update = uwfAdapter.update((UserPatch) patch);
+ return new WorkflowResult<>(update.getResult().getLeft(), update.getPropByRes(), update.getPerformedTasks());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPullResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPullResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPullResultHandlerImpl.java
deleted file mode 100644
index 3e2b5bd..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPullResultHandlerImpl.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.AttrPatch;
-import org.apache.syncope.common.lib.patch.GroupPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.PropagationStatus;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
-import org.apache.syncope.core.provisioning.api.ProvisioningManager;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.apache.syncope.core.provisioning.api.pushpull.GroupPullResultHandler;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class GroupPullResultHandlerImpl extends AbstractPullResultHandler implements GroupPullResultHandler {
-
- @Autowired
- private GroupProvisioningManager groupProvisioningManager;
-
- private final Map<String, String> groupOwnerMap = new HashMap<>();
-
- @Override
- public Map<String, String> getGroupOwnerMap() {
- return this.groupOwnerMap;
- }
-
- @Override
- protected AnyUtils getAnyUtils() {
- return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
- }
-
- @Override
- protected String getName(final AnyTO anyTO) {
- return GroupTO.class.cast(anyTO).getName();
- }
-
- @Override
- protected ProvisioningManager<?, ?> getProvisioningManager() {
- return groupProvisioningManager;
- }
-
- @Override
- protected Any<?> getAny(final String key) {
- try {
- return groupDAO.authFind(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving group {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AnyTO getAnyTO(final String key) {
- return groupDataBinder.getGroupTO(key);
- }
-
- @Override
- protected AnyPatch newPatch(final String key) {
- GroupPatch patch = new GroupPatch();
- patch.setKey(key);
- return patch;
- }
-
- @Override
- protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
- return gwfAdapter.update((GroupPatch) patch);
- }
-
- @Override
- protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta) {
- GroupTO groupTO = GroupTO.class.cast(anyTO);
-
- Map.Entry<String, List<PropagationStatus>> created = groupProvisioningManager.create(
- groupTO,
- groupOwnerMap,
- Collections.singleton(profile.getTask().getResource().getKey()),
- true);
-
- return getAnyTO(created.getKey());
- }
-
- @Override
- protected AnyPatch doUpdate(
- final AnyTO before,
- final AnyPatch anyPatch,
- final SyncDelta delta,
- final ProvisioningReport result) {
-
- GroupPatch groupPatch = GroupPatch.class.cast(anyPatch);
-
- Pair<GroupPatch, List<PropagationStatus>> updated = groupProvisioningManager.update(
- groupPatch, Collections.singleton(profile.getTask().getResource().getKey()), true);
-
- String groupOwner = null;
- for (AttrPatch attrPatch : groupPatch.getPlainAttrs()) {
- if (attrPatch.getOperation() == PatchOperation.ADD_REPLACE && attrPatch.getAttrTO() != null
- && attrPatch.getAttrTO().getSchema().isEmpty() && !attrPatch.getAttrTO().getValues().isEmpty()) {
-
- groupOwner = attrPatch.getAttrTO().getValues().get(0);
- }
- }
- if (groupOwner != null) {
- groupOwnerMap.put(updated.getLeft().getKey(), groupOwner);
- }
-
- return anyPatch;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPushResultHandlerImpl.java
deleted file mode 100644
index 01a112d..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPushResultHandlerImpl.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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 org.apache.syncope.common.lib.patch.GroupPatch;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.pushpull.GroupPushResultHandler;
-
-public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implements GroupPushResultHandler {
-
- @Override
- protected AnyUtils getAnyUtils() {
- return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
- }
-
- @Override
- protected String getName(final Any<?> any) {
- return Group.class.cast(any).getName();
- }
-
- @Override
- protected Any<?> getAny(final String key) {
- try {
- return groupDAO.authFind(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving group {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AnyTO getAnyTO(final String key) {
- return groupDataBinder.getGroupTO(key);
- }
-
- @Override
- protected AnyPatch newPatch(final String key) {
- GroupPatch patch = new GroupPatch();
- patch.setKey(key);
- return patch;
- }
-
- @Override
- protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
- return gwfAdapter.update((GroupPatch) patch);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
index 9c6f486..8bfe089 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
@@ -49,6 +49,7 @@ import org.apache.syncope.core.persistence.api.entity.task.PullTask;
import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPullResultHandler;
import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
import org.apache.syncope.core.provisioning.api.pushpull.GroupPullResultHandler;
+import org.apache.syncope.core.provisioning.api.pushpull.RealmPullResultHandler;
import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullExecutor;
import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullResultHandler;
import org.apache.syncope.core.provisioning.api.pushpull.UserPullResultHandler;
@@ -60,25 +61,35 @@ import org.identityconnectors.framework.common.objects.SyncToken;
public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> implements SyncopePullExecutor {
@Autowired
- private UserDAO userDAO;
+ protected UserDAO userDAO;
@Autowired
- private GroupDAO groupDAO;
+ protected GroupDAO groupDAO;
@Autowired
- private VirSchemaDAO virSchemaDAO;
+ protected VirSchemaDAO virSchemaDAO;
@Autowired
- private PullUtils pullUtils;
+ protected PullUtils pullUtils;
- private final Map<ObjectClass, SyncToken> latestSyncTokens = new HashMap<>();
+ protected final Map<ObjectClass, SyncToken> latestSyncTokens = new HashMap<>();
+
+ protected ProvisioningProfile<PullTask, PullActions> profile;
+
+ protected RealmPullResultHandler rhandler;
+
+ protected AnyObjectPullResultHandler ahandler;
+
+ protected UserPullResultHandler uhandler;
+
+ protected GroupPullResultHandler ghandler;
@Override
public void setLatestSyncToken(final ObjectClass objectClass, final SyncToken latestSyncToken) {
latestSyncTokens.put(objectClass, latestSyncToken);
}
- private void setGroupOwners(final GroupPullResultHandler ghandler) {
+ protected void setGroupOwners(final GroupPullResultHandler ghandler) {
ghandler.getGroupOwnerMap().entrySet().stream().map(entry -> {
Group group = groupDAO.find(entry.getKey());
if (group == null) {
@@ -114,6 +125,42 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i
});
}
+ protected RealmPullResultHandler buildRealmHandler() {
+ RealmPullResultHandler handler = (RealmPullResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(DefaultRealmPullResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ handler.setProfile(profile);
+ handler.setPullExecutor(this);
+
+ return handler;
+ }
+
+ protected AnyObjectPullResultHandler buildAnyObjectHandler() {
+ AnyObjectPullResultHandler handler = (AnyObjectPullResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(DefaultAnyObjectPullResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ handler.setProfile(profile);
+ handler.setPullExecutor(this);
+
+ return handler;
+ }
+
+ protected UserPullResultHandler buildUserHandler() {
+ UserPullResultHandler handler = (UserPullResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(DefaultUserPullResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ handler.setProfile(profile);
+ handler.setPullExecutor(this);
+
+ return handler;
+ }
+
+ protected GroupPullResultHandler buildGroupHandler() {
+ GroupPullResultHandler handler = (GroupPullResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(DefaultGroupPullResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ handler.setProfile(profile);
+ handler.setPullExecutor(this);
+
+ return handler;
+ }
+
@Override
protected String doExecuteProvisioning(
final PullTask pullTask,
@@ -135,7 +182,7 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i
}
});
- ProvisioningProfile<PullTask, PullActions> profile = new ProvisioningProfile<>(connector, pullTask);
+ profile = new ProvisioningProfile<>(connector, pullTask);
profile.getActions().addAll(actions);
profile.setDryRun(dryRun);
profile.setResAct(getPullPolicySpec(pullTask).getConflictResolutionAction());
@@ -148,16 +195,13 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i
}
}
- // First OrgUnits...
+ // First realms...
if (pullTask.getResource().getOrgUnit() != null) {
OrgUnit orgUnit = pullTask.getResource().getOrgUnit();
OperationOptions options = MappingUtils.buildOperationOptions(
MappingUtils.getPullItems(orgUnit.getItems()).iterator());
- SyncopePullResultHandler rhandler = (SyncopePullResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(RealmPullResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- rhandler.setProfile(profile);
- rhandler.setPullExecutor(this);
+ rhandler = buildRealmHandler();
try {
switch (pullTask.getPullMode()) {
@@ -202,20 +246,9 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i
}
// ...then provisions for any types
- AnyObjectPullResultHandler ahandler = (AnyObjectPullResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(AnyObjectPullResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- ahandler.setProfile(profile);
- ahandler.setPullExecutor(this);
-
- UserPullResultHandler uhandler = (UserPullResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(UserPullResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- uhandler.setProfile(profile);
- uhandler.setPullExecutor(this);
-
- GroupPullResultHandler ghandler = (GroupPullResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(GroupPullResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- ghandler.setProfile(profile);
- ghandler.setPullExecutor(this);
+ ahandler = buildAnyObjectHandler();
+ uhandler = buildUserHandler();
+ ghandler = buildGroupHandler();
for (Provision provision : pullTask.getResource().getProvisions()) {
if (provision.getMapping() != null) {
@@ -303,7 +336,7 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i
return result;
}
- private PullPolicySpec getPullPolicySpec(final ProvisioningTask task) {
+ protected PullPolicySpec getPullPolicySpec(final ProvisioningTask task) {
PullPolicySpec pullPolicySpec;
if (task instanceof PullTask) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/9c289134/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java
index 996ccad..ad3ccfd 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java
@@ -45,6 +45,7 @@ import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPushResultHand
import org.apache.syncope.core.provisioning.api.pushpull.GroupPushResultHandler;
import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile;
import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
+import org.apache.syncope.core.provisioning.api.pushpull.RealmPushResultHandler;
import org.apache.syncope.core.provisioning.api.pushpull.SyncopePushResultHandler;
import org.apache.syncope.core.provisioning.api.pushpull.UserPushResultHandler;
import org.quartz.JobExecutionException;
@@ -57,27 +58,37 @@ public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> {
* User DAO.
*/
@Autowired
- private UserDAO userDAO;
+ protected UserDAO userDAO;
/**
* Search DAO.
*/
@Autowired
- private AnySearchDAO searchDAO;
+ protected AnySearchDAO searchDAO;
/**
* Group DAO.
*/
@Autowired
- private GroupDAO groupDAO;
+ protected GroupDAO groupDAO;
@Autowired
- private AnyObjectDAO anyObjectDAO;
+ protected AnyObjectDAO anyObjectDAO;
@Autowired
- private RealmDAO realmDAO;
+ protected RealmDAO realmDAO;
- private AnyDAO<?> getAnyDAO(final AnyTypeKind anyTypeKind) {
+ protected ProvisioningProfile<PushTask, PushActions> profile;
+
+ protected RealmPushResultHandler rhandler;
+
+ protected AnyObjectPushResultHandler ahandler;
+
+ protected UserPushResultHandler uhandler;
+
+ protected GroupPushResultHandler ghandler;
+
+ protected AnyDAO<?> getAnyDAO(final AnyTypeKind anyTypeKind) {
AnyDAO<?> result;
switch (anyTypeKind) {
case USER:
@@ -96,7 +107,7 @@ public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> {
return result;
}
- private void doHandle(
+ protected void doHandle(
final List<? extends Any<?>> anys,
final SyncopePushResultHandler handler,
final ExternalResource resource)
@@ -112,6 +123,38 @@ public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> {
}
}
+ protected RealmPushResultHandler buildRealmHandler() {
+ RealmPushResultHandler handler = (RealmPushResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(DefaultRealmPushResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ handler.setProfile(profile);
+
+ return handler;
+ }
+
+ protected AnyObjectPushResultHandler buildAnyObjectHandler() {
+ AnyObjectPushResultHandler handler = (AnyObjectPushResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(DefaultAnyObjectPushResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ handler.setProfile(profile);
+
+ return handler;
+ }
+
+ protected UserPushResultHandler buildUserHandler() {
+ UserPushResultHandler handler = (UserPushResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(DefaultUserPushResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ handler.setProfile(profile);
+
+ return handler;
+ }
+
+ protected GroupPushResultHandler buildGroupHandler() {
+ GroupPushResultHandler handler = (GroupPushResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(DefaultGroupPushResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ handler.setProfile(profile);
+
+ return handler;
+ }
+
@Override
protected String doExecuteProvisioning(
final PushTask pushTask,
@@ -133,7 +176,7 @@ public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> {
}
});
- ProvisioningProfile<PushTask, PushActions> profile = new ProvisioningProfile<>(connector, pushTask);
+ profile = new ProvisioningProfile<>(connector, pushTask);
profile.getActions().addAll(actions);
profile.setDryRun(dryRun);
profile.setResAct(null);
@@ -144,11 +187,9 @@ public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> {
}
}
- // First OrgUnits...
+ // First realms...
if (pushTask.getResource().getOrgUnit() != null) {
- SyncopePushResultHandler rhandler = (SyncopePushResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(RealmPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- rhandler.setProfile(profile);
+ rhandler = buildRealmHandler();
for (Realm realm : realmDAO.findDescendants(profile.getTask().getSourceRealm())) {
// Never push the root realm
@@ -164,19 +205,9 @@ public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> {
}
// ...then provisions for any types
- AnyObjectPushResultHandler ahandler = (AnyObjectPushResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(AnyObjectPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- ahandler.setProfile(profile);
-
- UserPushResultHandler uhandler =
- (UserPushResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(UserPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- uhandler.setProfile(profile);
-
- GroupPushResultHandler ghandler =
- (GroupPushResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(GroupPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- ghandler.setProfile(profile);
+ ahandler = buildAnyObjectHandler();
+ uhandler = buildUserHandler();
+ ghandler = buildGroupHandler();
for (Provision provision : pushTask.getResource().getProvisions()) {
if (provision.getMapping() != null) {
[3/6] syncope git commit: [SYNCOPE-1212] Clearing and refactoring for
easier extensions
Posted by il...@apache.org.
[SYNCOPE-1212] Clearing and refactoring for easier extensions
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/4661b8cc
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/4661b8cc
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/4661b8cc
Branch: refs/heads/2_0_X
Commit: 4661b8cc085d7b920848d67bf246b706223cb545
Parents: 8ae7057
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Sep 22 10:12:45 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Sep 22 10:12:45 2017 +0200
----------------------------------------------------------------------
.../jpa/content/ContentLoaderHandler.java | 2 +-
.../entity/task/AbstractProvisioningTask.java | 10 -
.../api/pushpull/RealmPullResultHandler.java | 23 +
.../api/pushpull/RealmPushResultHandler.java | 23 +
.../java/data/TaskDataBinderImpl.java | 8 +-
.../provisioning/java/job/JobManagerImpl.java | 21 +-
.../pushpull/AbstractPullResultHandler.java | 14 +-
.../pushpull/AbstractPushResultHandler.java | 10 +-
.../AnyObjectPullResultHandlerImpl.java | 112 ---
.../AnyObjectPushResultHandlerImpl.java | 70 --
.../DefaultAnyObjectPullResultHandler.java | 112 +++
.../DefaultAnyObjectPushResultHandler.java | 70 ++
.../pushpull/DefaultGroupPullResultHandler.java | 138 ++++
.../pushpull/DefaultGroupPushResultHandler.java | 70 ++
.../pushpull/DefaultRealmPullResultHandler.java | 795 +++++++++++++++++++
.../pushpull/DefaultRealmPushResultHandler.java | 449 +++++++++++
.../pushpull/DefaultUserPullResultHandler.java | 134 ++++
.../pushpull/DefaultUserPushResultHandler.java | 99 +++
.../pushpull/GroupPullResultHandlerImpl.java | 138 ----
.../pushpull/GroupPushResultHandlerImpl.java | 70 --
.../java/pushpull/PullJobDelegate.java | 87 +-
.../java/pushpull/PushJobDelegate.java | 81 +-
.../pushpull/RealmPullResultHandlerImpl.java | 795 -------------------
.../pushpull/RealmPushResultHandlerImpl.java | 449 -----------
.../pushpull/UserPullResultHandlerImpl.java | 134 ----
.../pushpull/UserPushResultHandlerImpl.java | 99 ---
26 files changed, 2062 insertions(+), 1951 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
index c287ca1..9bc30f7 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
@@ -196,7 +196,7 @@ public class ContentLoaderHandler extends DefaultHandler {
try {
jdbcTemplate.update(query.toString(), getParameters(qName, atts));
} catch (DataAccessException e) {
- LOG.error("While trying to perform {}", query, e);
+ LOG.error("While trying to perform {} with params {}", query, getParameters(qName, atts), e);
if (!continueOnError) {
throw e;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
index 0441eb3..dc35f9d 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
@@ -80,16 +80,6 @@ public abstract class AbstractProvisioningTask extends JPASchedTask implements P
protected MatchingRule matchingRule;
@Override
- public String getJobDelegateClassName() {
- return null;
- }
-
- @Override
- public void setJobDelegateClassName(final String jobDelegateClassName) {
- // fixed, cannot be changed
- }
-
- @Override
public ExternalResource getResource() {
return resource;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/RealmPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/RealmPullResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/RealmPullResultHandler.java
new file mode 100644
index 0000000..6f38692
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/RealmPullResultHandler.java
@@ -0,0 +1,23 @@
+/*
+ * 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.api.pushpull;
+
+public interface RealmPullResultHandler extends SyncopePullResultHandler {
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/RealmPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/RealmPushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/RealmPushResultHandler.java
new file mode 100644
index 0000000..e994213
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/RealmPushResultHandler.java
@@ -0,0 +1,23 @@
+/*
+ * 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.api.pushpull;
+
+public interface RealmPushResultHandler extends SyncopePushResultHandler {
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
index 09b5d12..a22db75 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
@@ -114,7 +114,9 @@ public class TaskDataBinderImpl implements TaskDataBinder {
PushTask pushTask = (PushTask) task;
final PushTaskTO pushTaskTO = (PushTaskTO) taskTO;
- pushTask.setJobDelegateClassName(PushJobDelegate.class.getName());
+ pushTask.setJobDelegateClassName(pushTaskTO.getJobDelegateClassName() == null
+ ? PushJobDelegate.class.getName()
+ : pushTaskTO.getJobDelegateClassName());
pushTask.setSourceRealm(realmDAO.findByFullPath(pushTaskTO.getSourceRealm()));
@@ -155,7 +157,9 @@ public class TaskDataBinderImpl implements TaskDataBinder {
pullTask.setDestinationRealm(realmDAO.findByFullPath(pullTaskTO.getDestinationRealm()));
- pullTask.setJobDelegateClassName(PullJobDelegate.class.getName());
+ pullTask.setJobDelegateClassName(pullTaskTO.getJobDelegateClassName() == null
+ ? PullJobDelegate.class.getName()
+ : pullTaskTO.getJobDelegateClassName());
pullTask.setMatchingRule(pullTaskTO.getMatchingRule() == null
? MatchingRule.UPDATE : pullTaskTO.getMatchingRule());
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
index 1af62c5..b48f80c 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
@@ -47,8 +47,6 @@ import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.SyncopeLoader;
import org.apache.syncope.core.persistence.api.DomainsHolder;
-import org.apache.syncope.core.provisioning.java.pushpull.PushJobDelegate;
-import org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate;
import org.quartz.CronScheduleBuilder;
import org.quartz.Job;
import org.quartz.JobBuilder;
@@ -71,8 +69,11 @@ import org.identityconnectors.common.IOUtil;
import org.quartz.impl.jdbcjobstore.Constants;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.apache.syncope.core.persistence.api.entity.task.PullTask;
+import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
import org.apache.syncope.core.provisioning.java.job.notification.NotificationJob;
import org.apache.syncope.core.provisioning.java.job.report.ReportJob;
+import org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate;
+import org.apache.syncope.core.provisioning.java.pushpull.PushJobDelegate;
public class JobManagerImpl implements JobManager, SyncopeLoader {
@@ -222,11 +223,17 @@ public class JobManagerImpl implements JobManager, SyncopeLoader {
TaskJob job = createSpringBean(TaskJob.class);
job.setTaskKey(task.getKey());
- String jobDelegateClassName = task instanceof PullTask
- ? PullJobDelegate.class.getName()
- : task instanceof PushTask
- ? PushJobDelegate.class.getName()
- : task.getJobDelegateClassName();
+ String jobDelegateClassName = task.getJobDelegateClassName() == null
+ ? task instanceof PullTask
+ ? PullJobDelegate.class.getName()
+ : task instanceof PushTask
+ ? PushJobDelegate.class.getName()
+ : null
+ : task.getJobDelegateClassName();
+ if (jobDelegateClassName == null) {
+ throw new IllegalArgumentException("Task " + task
+ + " does not provide any " + SchedTaskJobDelegate.class.getSimpleName());
+ }
Map<String, Object> jobMap = new HashMap<>();
jobMap.put(JobManager.DOMAIN_KEY, AuthContextUtils.getDomain());
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
index 6b6f922..6c54260 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
@@ -69,23 +69,23 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
protected PullUtils pullUtils;
@Autowired
- private NotificationManager notificationManager;
+ protected NotificationManager notificationManager;
@Autowired
- private AuditManager auditManager;
+ protected AuditManager auditManager;
@Autowired
- private ConnObjectUtils connObjectUtils;
+ protected ConnObjectUtils connObjectUtils;
@Autowired
- private VirSchemaDAO virSchemaDAO;
+ protected VirSchemaDAO virSchemaDAO;
@Autowired
- private VirAttrCache virAttrCache;
+ protected VirAttrCache virAttrCache;
- private SyncopePullExecutor executor;
+ protected SyncopePullExecutor executor;
- private Result latestResult;
+ protected Result latestResult;
protected abstract String getName(AnyTO anyTO);
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
index 7095739..6b03c1d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
@@ -95,7 +95,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
}
}
- private void update(final Any<?> any, final ProvisioningReport result) {
+ protected void update(final Any<?> any, final ProvisioningReport result) {
boolean changepwd;
Collection<String> resourceKeys;
if (any instanceof User) {
@@ -240,7 +240,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
}
}
- private void doHandle(final Any<?> any) throws JobExecutionException {
+ protected void doHandle(final Any<?> any) throws JobExecutionException {
AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
ProvisioningReport result = new ProvisioningReport();
@@ -472,7 +472,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
}
}
- private ResourceOperation toResourceOperation(final UnmatchingRule rule) {
+ protected ResourceOperation toResourceOperation(final UnmatchingRule rule) {
switch (rule) {
case ASSIGN:
case PROVISION:
@@ -482,7 +482,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
}
}
- private ResourceOperation toResourceOperation(final MatchingRule rule) {
+ protected ResourceOperation toResourceOperation(final MatchingRule rule) {
switch (rule) {
case UPDATE:
return ResourceOperation.UPDATE;
@@ -494,7 +494,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
}
}
- private ProvisioningReport.Status toProvisioningReportStatus(final PropagationTaskExecStatus status) {
+ protected ProvisioningReport.Status toProvisioningReportStatus(final PropagationTaskExecStatus status) {
switch (status) {
case FAILURE:
return ProvisioningReport.Status.FAILURE;
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPullResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPullResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPullResultHandlerImpl.java
deleted file mode 100644
index 3e652ee..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPullResultHandlerImpl.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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.Collections;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.patch.AnyObjectPatch;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.PropagationStatus;
-import org.apache.syncope.common.lib.to.AnyObjectTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
-import org.apache.syncope.core.provisioning.api.ProvisioningManager;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPullResultHandler;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class AnyObjectPullResultHandlerImpl extends AbstractPullResultHandler implements AnyObjectPullResultHandler {
-
- @Autowired
- private AnyObjectProvisioningManager anyObjectProvisioningManager;
-
- @Override
- protected AnyUtils getAnyUtils() {
- return anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT);
- }
-
- @Override
- protected String getName(final AnyTO anyTO) {
- return AnyObjectTO.class.cast(anyTO).getName();
- }
-
- @Override
- protected ProvisioningManager<?, ?> getProvisioningManager() {
- return anyObjectProvisioningManager;
- }
-
- @Override
- protected Any<?> getAny(final String key) {
- try {
- return anyObjectDAO.authFind(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving anyObject {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AnyTO getAnyTO(final String key) {
- return anyObjectDataBinder.getAnyObjectTO(key);
- }
-
- @Override
- protected AnyPatch newPatch(final String key) {
- AnyObjectPatch patch = new AnyObjectPatch();
- patch.setKey(key);
- return patch;
- }
-
- @Override
- protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
- return awfAdapter.update((AnyObjectPatch) patch);
- }
-
- @Override
- protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta) {
- AnyObjectTO anyObjectTO = AnyObjectTO.class.cast(anyTO);
-
- Map.Entry<String, List<PropagationStatus>> created = anyObjectProvisioningManager.create(
- anyObjectTO, Collections.singleton(profile.getTask().getResource().getKey()), true);
-
- return getAnyTO(created.getKey());
- }
-
- @Override
- protected AnyPatch doUpdate(
- final AnyTO before,
- final AnyPatch anyPatch,
- final SyncDelta delta,
- final ProvisioningReport result) {
-
- AnyObjectPatch anyObjectPatch = AnyObjectPatch.class.cast(anyPatch);
-
- Pair<AnyObjectPatch, List<PropagationStatus>> updated = anyObjectProvisioningManager.update(
- anyObjectPatch, Collections.singleton(profile.getTask().getResource().getKey()), true);
-
- return anyPatch;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPushResultHandlerImpl.java
deleted file mode 100644
index 48f464a..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPushResultHandlerImpl.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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 org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.patch.AnyObjectPatch;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPushResultHandler;
-
-public class AnyObjectPushResultHandlerImpl extends AbstractPushResultHandler implements AnyObjectPushResultHandler {
-
- @Override
- protected AnyUtils getAnyUtils() {
- return anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT);
- }
-
- @Override
- protected String getName(final Any<?> any) {
- return StringUtils.EMPTY;
- }
-
- @Override
- protected Any<?> getAny(final String key) {
- try {
- return anyObjectDAO.authFind(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving anyObject {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AnyTO getAnyTO(final String key) {
- return anyObjectDataBinder.getAnyObjectTO(key);
- }
-
- @Override
- protected AnyPatch newPatch(final String key) {
- AnyObjectPatch patch = new AnyObjectPatch();
- patch.setKey(key);
- return patch;
- }
-
- @Override
- protected WorkflowResult<? extends AnyObjectPatch> update(final AnyPatch patch) {
- return awfAdapter.update((AnyObjectPatch) patch);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultAnyObjectPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultAnyObjectPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultAnyObjectPullResultHandler.java
new file mode 100644
index 0000000..8d71a2d
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultAnyObjectPullResultHandler.java
@@ -0,0 +1,112 @@
+/*
+ * 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.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.patch.AnyObjectPatch;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
+import org.apache.syncope.core.provisioning.api.ProvisioningManager;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPullResultHandler;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DefaultAnyObjectPullResultHandler extends AbstractPullResultHandler implements AnyObjectPullResultHandler {
+
+ @Autowired
+ private AnyObjectProvisioningManager anyObjectProvisioningManager;
+
+ @Override
+ protected AnyUtils getAnyUtils() {
+ return anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT);
+ }
+
+ @Override
+ protected String getName(final AnyTO anyTO) {
+ return AnyObjectTO.class.cast(anyTO).getName();
+ }
+
+ @Override
+ protected ProvisioningManager<?, ?> getProvisioningManager() {
+ return anyObjectProvisioningManager;
+ }
+
+ @Override
+ protected Any<?> getAny(final String key) {
+ try {
+ return anyObjectDAO.authFind(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving anyObject {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AnyTO getAnyTO(final String key) {
+ return anyObjectDataBinder.getAnyObjectTO(key);
+ }
+
+ @Override
+ protected AnyPatch newPatch(final String key) {
+ AnyObjectPatch patch = new AnyObjectPatch();
+ patch.setKey(key);
+ return patch;
+ }
+
+ @Override
+ protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
+ return awfAdapter.update((AnyObjectPatch) patch);
+ }
+
+ @Override
+ protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta) {
+ AnyObjectTO anyObjectTO = AnyObjectTO.class.cast(anyTO);
+
+ Map.Entry<String, List<PropagationStatus>> created = anyObjectProvisioningManager.create(
+ anyObjectTO, Collections.singleton(profile.getTask().getResource().getKey()), true);
+
+ return getAnyTO(created.getKey());
+ }
+
+ @Override
+ protected AnyPatch doUpdate(
+ final AnyTO before,
+ final AnyPatch anyPatch,
+ final SyncDelta delta,
+ final ProvisioningReport result) {
+
+ AnyObjectPatch anyObjectPatch = AnyObjectPatch.class.cast(anyPatch);
+
+ Pair<AnyObjectPatch, List<PropagationStatus>> updated = anyObjectProvisioningManager.update(
+ anyObjectPatch, Collections.singleton(profile.getTask().getResource().getKey()), true);
+
+ return anyPatch;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultAnyObjectPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultAnyObjectPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultAnyObjectPushResultHandler.java
new file mode 100644
index 0000000..3c401ae
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultAnyObjectPushResultHandler.java
@@ -0,0 +1,70 @@
+/*
+ * 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 org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.patch.AnyObjectPatch;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPushResultHandler;
+
+public class DefaultAnyObjectPushResultHandler extends AbstractPushResultHandler implements AnyObjectPushResultHandler {
+
+ @Override
+ protected AnyUtils getAnyUtils() {
+ return anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT);
+ }
+
+ @Override
+ protected String getName(final Any<?> any) {
+ return StringUtils.EMPTY;
+ }
+
+ @Override
+ protected Any<?> getAny(final String key) {
+ try {
+ return anyObjectDAO.authFind(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving anyObject {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AnyTO getAnyTO(final String key) {
+ return anyObjectDataBinder.getAnyObjectTO(key);
+ }
+
+ @Override
+ protected AnyPatch newPatch(final String key) {
+ AnyObjectPatch patch = new AnyObjectPatch();
+ patch.setKey(key);
+ return patch;
+ }
+
+ @Override
+ protected WorkflowResult<? extends AnyObjectPatch> update(final AnyPatch patch) {
+ return awfAdapter.update((AnyObjectPatch) patch);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultGroupPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultGroupPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultGroupPullResultHandler.java
new file mode 100644
index 0000000..451659b
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultGroupPullResultHandler.java
@@ -0,0 +1,138 @@
+/*
+ * 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.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.AttrPatch;
+import org.apache.syncope.common.lib.patch.GroupPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
+import org.apache.syncope.core.provisioning.api.ProvisioningManager;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.apache.syncope.core.provisioning.api.pushpull.GroupPullResultHandler;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DefaultGroupPullResultHandler extends AbstractPullResultHandler implements GroupPullResultHandler {
+
+ @Autowired
+ private GroupProvisioningManager groupProvisioningManager;
+
+ private final Map<String, String> groupOwnerMap = new HashMap<>();
+
+ @Override
+ public Map<String, String> getGroupOwnerMap() {
+ return this.groupOwnerMap;
+ }
+
+ @Override
+ protected AnyUtils getAnyUtils() {
+ return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
+ }
+
+ @Override
+ protected String getName(final AnyTO anyTO) {
+ return GroupTO.class.cast(anyTO).getName();
+ }
+
+ @Override
+ protected ProvisioningManager<?, ?> getProvisioningManager() {
+ return groupProvisioningManager;
+ }
+
+ @Override
+ protected Any<?> getAny(final String key) {
+ try {
+ return groupDAO.authFind(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving group {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AnyTO getAnyTO(final String key) {
+ return groupDataBinder.getGroupTO(key);
+ }
+
+ @Override
+ protected AnyPatch newPatch(final String key) {
+ GroupPatch patch = new GroupPatch();
+ patch.setKey(key);
+ return patch;
+ }
+
+ @Override
+ protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
+ return gwfAdapter.update((GroupPatch) patch);
+ }
+
+ @Override
+ protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta) {
+ GroupTO groupTO = GroupTO.class.cast(anyTO);
+
+ Map.Entry<String, List<PropagationStatus>> created = groupProvisioningManager.create(
+ groupTO,
+ groupOwnerMap,
+ Collections.singleton(profile.getTask().getResource().getKey()),
+ true);
+
+ return getAnyTO(created.getKey());
+ }
+
+ @Override
+ protected AnyPatch doUpdate(
+ final AnyTO before,
+ final AnyPatch anyPatch,
+ final SyncDelta delta,
+ final ProvisioningReport result) {
+
+ GroupPatch groupPatch = GroupPatch.class.cast(anyPatch);
+
+ Pair<GroupPatch, List<PropagationStatus>> updated = groupProvisioningManager.update(
+ groupPatch, Collections.singleton(profile.getTask().getResource().getKey()), true);
+
+ String groupOwner = null;
+ for (AttrPatch attrPatch : groupPatch.getPlainAttrs()) {
+ if (attrPatch.getOperation() == PatchOperation.ADD_REPLACE && attrPatch.getAttrTO() != null
+ && attrPatch.getAttrTO().getSchema().isEmpty() && !attrPatch.getAttrTO().getValues().isEmpty()) {
+
+ groupOwner = attrPatch.getAttrTO().getValues().get(0);
+ }
+ }
+ if (groupOwner != null) {
+ groupOwnerMap.put(updated.getLeft().getKey(), groupOwner);
+ }
+
+ return anyPatch;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultGroupPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultGroupPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultGroupPushResultHandler.java
new file mode 100644
index 0000000..993f747
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultGroupPushResultHandler.java
@@ -0,0 +1,70 @@
+/*
+ * 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 org.apache.syncope.common.lib.patch.GroupPatch;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.pushpull.GroupPushResultHandler;
+
+public class DefaultGroupPushResultHandler extends AbstractPushResultHandler implements GroupPushResultHandler {
+
+ @Override
+ protected AnyUtils getAnyUtils() {
+ return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
+ }
+
+ @Override
+ protected String getName(final Any<?> any) {
+ return Group.class.cast(any).getName();
+ }
+
+ @Override
+ protected Any<?> getAny(final String key) {
+ try {
+ return groupDAO.authFind(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving group {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AnyTO getAnyTO(final String key) {
+ return groupDataBinder.getGroupTO(key);
+ }
+
+ @Override
+ protected AnyPatch newPatch(final String key) {
+ GroupPatch patch = new GroupPatch();
+ patch.setKey(key);
+ return patch;
+ }
+
+ @Override
+ protected WorkflowResult<? extends AnyPatch> update(final AnyPatch patch) {
+ return gwfAdapter.update((GroupPatch) patch);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/4661b8cc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java
new file mode 100644
index 0000000..69c0604
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java
@@ -0,0 +1,795 @@
+/*
+ * 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.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+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.core.provisioning.api.PropagationByResource;
+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.search.AnyCond;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+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.resource.OrgUnit;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.persistence.api.entity.task.PullTask;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
+import org.apache.syncope.core.provisioning.api.pushpull.RealmPullResultHandler;
+import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullExecutor;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.identityconnectors.framework.common.objects.SyncDeltaType;
+import org.quartz.JobExecutionException;
+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 {
+
+ @Autowired
+ private PullUtils pullUtils;
+
+ @Autowired
+ private ConnObjectUtils connObjectUtils;
+
+ @Autowired
+ private AnySearchDAO searchDAO;
+
+ private SyncopePullExecutor executor;
+
+ private Result latestResult;
+
+ @Override
+ public void setPullExecutor(final SyncopePullExecutor executor) {
+ this.executor = executor;
+ }
+
+ @Override
+ public boolean handle(final SyncDelta delta) {
+ try {
+ OrgUnit orgUnit = profile.getTask().getResource().getOrgUnit();
+ if (orgUnit == null) {
+ throw new JobExecutionException("No orgUnit found on " + profile.getTask().getResource() + " for "
+ + delta.getObject().getObjectClass());
+ }
+
+ doHandle(delta, orgUnit);
+
+ LOG.debug("Successfully handled {}", delta);
+
+ if (profile.getTask().getPullMode() != PullMode.INCREMENTAL) {
+ return true;
+ }
+
+ boolean shouldContinue;
+ synchronized (this) {
+ shouldContinue = latestResult == Result.SUCCESS;
+ this.latestResult = null;
+ }
+ if (shouldContinue) {
+ executor.setLatestSyncToken(delta.getObjectClass(), delta.getToken());
+ }
+ return shouldContinue;
+ } catch (IgnoreProvisionException e) {
+ ProvisioningReport ignoreResult = new ProvisioningReport();
+ ignoreResult.setOperation(ResourceOperation.NONE);
+ ignoreResult.setStatus(ProvisioningReport.Status.IGNORE);
+ ignoreResult.setAnyType(REALM_TYPE);
+ ignoreResult.setKey(null);
+ ignoreResult.setName(delta.getObject().getName().getNameValue());
+ profile.getResults().add(ignoreResult);
+
+ LOG.warn("Ignoring during pull", e);
+
+ executor.setLatestSyncToken(delta.getObjectClass(), delta.getToken());
+
+ return true;
+ } catch (JobExecutionException e) {
+ LOG.error("Pull failed", e);
+
+ return false;
+ }
+ }
+
+ private List<ProvisioningReport> assign(final SyncDelta delta, final OrgUnit orgUnit) throws JobExecutionException {
+ if (!profile.getTask().isPerformCreate()) {
+ LOG.debug("PullTask not configured for create");
+ finalize(UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), Result.SUCCESS, null, null, delta);
+ return Collections.<ProvisioningReport>emptyList();
+ }
+
+ RealmTO realmTO = connObjectUtils.getRealmTO(delta.getObject(), profile.getTask(), orgUnit);
+ if (realmTO.getFullPath() == null) {
+ if (realmTO.getParent() == null) {
+ realmTO.setParent(profile.getTask().getDestinatioRealm().getFullPath());
+ }
+
+ realmTO.setFullPath(realmTO.getParent() + "/" + realmTO.getName());
+ }
+ realmTO.getResources().add(profile.getTask().getResource().getKey());
+
+ ProvisioningReport result = new ProvisioningReport();
+ result.setOperation(ResourceOperation.CREATE);
+ result.setAnyType(REALM_TYPE);
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ result.setName(realmTO.getFullPath());
+
+ if (profile.isDryRun()) {
+ result.setKey(null);
+ finalize(UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), Result.SUCCESS, null, null, delta);
+ } else {
+ SyncDelta actionedDelta = delta;
+ for (PullActions action : profile.getActions()) {
+ actionedDelta = action.beforeAssign(profile, actionedDelta, realmTO);
+ }
+
+ create(realmTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), result);
+ }
+
+ return Collections.singletonList(result);
+ }
+
+ private List<ProvisioningReport> provision(final SyncDelta delta, final OrgUnit orgUnit)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformCreate()) {
+ LOG.debug("PullTask not configured for create");
+ finalize(UnmatchingRule.toEventName(UnmatchingRule.PROVISION), Result.SUCCESS, null, null, delta);
+ return Collections.<ProvisioningReport>emptyList();
+ }
+
+ RealmTO realmTO = connObjectUtils.getRealmTO(delta.getObject(), profile.getTask(), orgUnit);
+ if (realmTO.getFullPath() == null) {
+ if (realmTO.getParent() == null) {
+ realmTO.setParent(profile.getTask().getDestinatioRealm().getFullPath());
+ }
+
+ realmTO.setFullPath(realmTO.getParent() + "/" + realmTO.getName());
+ }
+
+ ProvisioningReport result = new ProvisioningReport();
+ result.setOperation(ResourceOperation.CREATE);
+ result.setAnyType(REALM_TYPE);
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ result.setName(realmTO.getFullPath());
+
+ if (profile.isDryRun()) {
+ result.setKey(null);
+ finalize(UnmatchingRule.toEventName(UnmatchingRule.PROVISION), Result.SUCCESS, null, null, delta);
+ } else {
+ SyncDelta actionedDelta = delta;
+ for (PullActions action : profile.getActions()) {
+ actionedDelta = action.beforeProvision(profile, actionedDelta, realmTO);
+ }
+
+ create(realmTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.PROVISION), result);
+ }
+
+ return Collections.singletonList(result);
+ }
+
+ private 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;
+ }
+ }
+
+ 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().getFullPath(), realmTO));
+
+ PropagationByResource propByRes = new PropagationByResource();
+ for (String resource : realm.getResourceKeys()) {
+ propByRes.add(ResourceOperation.CREATE, resource);
+ }
+ List<PropagationTask> 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);
+ }
+
+ private List<ProvisioningReport> update(final SyncDelta delta, final List<String> keys)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("PullTask not configured for update");
+ finalize(MatchingRule.toEventName(MatchingRule.UPDATE), Result.SUCCESS, null, null, delta);
+ return Collections.<ProvisioningReport>emptyList();
+ }
+
+ LOG.debug("About to update {}", keys);
+
+ List<ProvisioningReport> results = new ArrayList<>();
+
+ SyncDelta workingDelta = delta;
+ for (String key : keys) {
+ LOG.debug("About to update {}", key);
+
+ ProvisioningReport result = new ProvisioningReport();
+ result.setOperation(ResourceOperation.UPDATE);
+ result.setAnyType(REALM_TYPE);
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ result.setKey(key);
+
+ Realm realm = realmDAO.find(key);
+ RealmTO before = binder.getRealmTO(realm, true);
+ if (before == null) {
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(String.format("Realm '%s' not found", key));
+ } else {
+ result.setName(before.getFullPath());
+ }
+
+ if (!profile.isDryRun()) {
+ Result resultStatus;
+ Object output;
+
+ if (before == null) {
+ resultStatus = Result.FAILURE;
+ output = null;
+ } else {
+ try {
+ for (PullActions action : profile.getActions()) {
+ workingDelta = action.beforeUpdate(profile, workingDelta, before, null);
+ }
+
+ PropagationByResource propByRes = binder.update(realm, before);
+ realm = realmDAO.save(realm);
+ RealmTO updated = binder.getRealmTO(realm, true);
+
+ List<PropagationTask> tasks = propagationManager.createTasks(realm, propByRes, null);
+ taskExecutor.execute(tasks, false);
+
+ for (PullActions action : profile.getActions()) {
+ action.after(profile, workingDelta, 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 {}", workingDelta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+ } catch (Exception e) {
+ throwIgnoreProvisionException(workingDelta, e);
+
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+ LOG.error("Could not update Realm {}", workingDelta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+ }
+ }
+ finalize(MatchingRule.toEventName(MatchingRule.UPDATE), resultStatus, before, output, workingDelta);
+ }
+ results.add(result);
+ }
+
+ return results;
+ }
+
+ private List<ProvisioningReport> deprovision(final SyncDelta delta, final List<String> keys, final boolean unlink)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("PullTask not configured for update");
+ finalize(unlink
+ ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
+ : MatchingRule.toEventName(MatchingRule.DEPROVISION), Result.SUCCESS, null, null, delta);
+ return Collections.<ProvisioningReport>emptyList();
+ }
+
+ LOG.debug("About to deprovision {}", keys);
+
+ final List<ProvisioningReport> results = new ArrayList<>();
+
+ SyncDelta workingDelta = delta;
+ for (String key : keys) {
+ LOG.debug("About to unassign resource {}", key);
+
+ ProvisioningReport result = new ProvisioningReport();
+ result.setOperation(ResourceOperation.DELETE);
+ result.setAnyType(REALM_TYPE);
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ result.setKey(key);
+
+ Realm realm = realmDAO.find(key);
+ RealmTO before = binder.getRealmTO(realm, true);
+ if (before == null) {
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(String.format("Realm '%s' not found", key));
+ } else {
+ result.setName(before.getFullPath());
+ }
+
+ if (!profile.isDryRun()) {
+ Object output;
+ Result resultStatus;
+
+ if (before == null) {
+ resultStatus = Result.FAILURE;
+ output = null;
+ } else {
+ try {
+ if (unlink) {
+ for (PullActions action : profile.getActions()) {
+ workingDelta = action.beforeUnassign(profile, workingDelta, before);
+ }
+ } else {
+ for (PullActions action : profile.getActions()) {
+ workingDelta = action.beforeDeprovision(profile, workingDelta, before);
+ }
+ }
+
+ PropagationByResource propByRes = new PropagationByResource();
+ propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
+ taskExecutor.execute(propagationManager.createTasks(realm, propByRes, null), false);
+
+ if (unlink) {
+ realm.getResources().remove(profile.getTask().getResource());
+ output = binder.getRealmTO(realmDAO.save(realm), true);
+ } else {
+ output = binder.getRealmTO(realm, true);
+ }
+
+ for (PullActions action : profile.getActions()) {
+ action.after(profile, workingDelta, RealmTO.class.cast(output), 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 {}", workingDelta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+ } catch (Exception e) {
+ throwIgnoreProvisionException(workingDelta, 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;
+ }
+ }
+ finalize(unlink
+ ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
+ : MatchingRule.toEventName(MatchingRule.DEPROVISION), resultStatus, before, output, delta);
+ }
+ results.add(result);
+ }
+
+ return results;
+ }
+
+ private List<ProvisioningReport> link(final SyncDelta delta, final List<String> keys, final boolean unlink)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("PullTask not configured for update");
+ finalize(unlink
+ ? MatchingRule.toEventName(MatchingRule.UNLINK)
+ : MatchingRule.toEventName(MatchingRule.LINK), Result.SUCCESS, null, null, delta);
+ return Collections.<ProvisioningReport>emptyList();
+ }
+
+ LOG.debug("About to link {}", keys);
+
+ final List<ProvisioningReport> results = new ArrayList<>();
+
+ SyncDelta workingDelta = delta;
+ for (String key : keys) {
+ LOG.debug("About to unassign resource {}", key);
+
+ ProvisioningReport result = new ProvisioningReport();
+ result.setOperation(ResourceOperation.NONE);
+ result.setAnyType(REALM_TYPE);
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ result.setKey(key);
+
+ Realm realm = realmDAO.find(key);
+ RealmTO before = binder.getRealmTO(realm, true);
+ if (before == null) {
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(String.format("Realm '%s' not found", key));
+ } else {
+ result.setName(before.getFullPath());
+ }
+
+ Object output;
+ Result resultStatus;
+ if (!profile.isDryRun()) {
+ if (before == null) {
+ resultStatus = Result.FAILURE;
+ output = null;
+ } else {
+ try {
+ if (unlink) {
+ for (PullActions action : profile.getActions()) {
+ workingDelta = action.beforeUnlink(profile, workingDelta, before);
+ }
+ } else {
+ for (PullActions action : profile.getActions()) {
+ workingDelta = action.beforeLink(profile, workingDelta, before);
+ }
+ }
+
+ if (unlink) {
+ realm.getResources().remove(profile.getTask().getResource());
+ } else {
+ realm.add(profile.getTask().getResource());
+ }
+ output = update(workingDelta, Collections.singletonList(key));
+
+ for (PullActions action : profile.getActions()) {
+ action.after(profile, workingDelta, RealmTO.class.cast(output), 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 {}", workingDelta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+ } catch (Exception e) {
+ throwIgnoreProvisionException(workingDelta, e);
+
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+ LOG.error("Could not update Realm {}", workingDelta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+ }
+ }
+ finalize(unlink
+ ? MatchingRule.toEventName(MatchingRule.UNLINK)
+ : MatchingRule.toEventName(MatchingRule.LINK), resultStatus, before, output, workingDelta);
+ }
+ results.add(result);
+ }
+
+ return results;
+ }
+
+ private List<ProvisioningReport> delete(final SyncDelta delta, final List<String> keys)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformDelete()) {
+ LOG.debug("PullTask not configured for delete");
+ finalize(ResourceOperation.DELETE.name().toLowerCase(), Result.SUCCESS, null, null, delta);
+ return Collections.<ProvisioningReport>emptyList();
+ }
+
+ LOG.debug("About to delete {}", keys);
+
+ List<ProvisioningReport> results = new ArrayList<>();
+
+ SyncDelta workingDelta = delta;
+ for (String key : keys) {
+ Object output;
+ Result resultStatus = Result.FAILURE;
+
+ ProvisioningReport result = new ProvisioningReport();
+
+ try {
+ result.setKey(key);
+ result.setOperation(ResourceOperation.DELETE);
+ result.setAnyType(REALM_TYPE);
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+
+ Realm realm = realmDAO.find(key);
+ RealmTO before = binder.getRealmTO(realm, true);
+ if (before == null) {
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(String.format("Realm '%s' not found", key));
+ } else {
+ result.setName(before.getFullPath());
+ }
+
+ if (!profile.isDryRun()) {
+ for (PullActions action : profile.getActions()) {
+ workingDelta = action.beforeDelete(profile, workingDelta, before);
+ }
+
+ try {
+ if (!realmDAO.findChildren(realm).isEmpty()) {
+ throw SyncopeClientException.build(ClientExceptionType.HasChildren);
+ }
+
+ Set<String> adminRealms = Collections.singleton(realm.getFullPath());
+ AnyCond keyCond = new AnyCond(AttributeCond.Type.ISNOTNULL);
+ keyCond.setSchema("key");
+ SearchCond allMatchingCond = SearchCond.getLeafCond(keyCond);
+ int users = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.USER);
+ int groups = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.GROUP);
+ int anyObjects = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.ANY_OBJECT);
+
+ if (users + groups + anyObjects > 0) {
+ SyncopeClientException containedAnys = SyncopeClientException.build(
+ ClientExceptionType.AssociatedAnys);
+ containedAnys.getElements().add(users + " user(s)");
+ containedAnys.getElements().add(groups + " group(s)");
+ containedAnys.getElements().add(anyObjects + " anyObject(s)");
+ throw containedAnys;
+ }
+
+ PropagationByResource propByRes = new PropagationByResource();
+ for (String resource : realm.getResourceKeys()) {
+ propByRes.add(ResourceOperation.DELETE, resource);
+ }
+ List<PropagationTask> tasks = propagationManager.createTasks(realm, propByRes, null);
+ taskExecutor.execute(tasks, false);
+
+ realmDAO.delete(realm);
+
+ output = null;
+ resultStatus = Result.SUCCESS;
+
+ for (PullActions action : profile.getActions()) {
+ action.after(profile, workingDelta, before, result);
+ }
+ } catch (Exception e) {
+ throwIgnoreProvisionException(workingDelta, e);
+
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+ LOG.error("Could not delete {}", realm, e);
+ output = e;
+ }
+
+ finalize(ResourceOperation.DELETE.name().toLowerCase(), resultStatus, before, output, workingDelta);
+ }
+
+ results.add(result);
+ } catch (DelegatedAdministrationException e) {
+ LOG.error("Not allowed to read Realm {}", key, e);
+ } catch (Exception e) {
+ LOG.error("Could not delete Realm {}", key, e);
+ }
+ }
+
+ return results;
+ }
+
+ private ProvisioningReport ignore(
+ final SyncDelta delta,
+ final boolean matching)
+ throws JobExecutionException {
+
+ LOG.debug("Any to ignore {}", delta.getObject().getUid().getUidValue());
+
+ ProvisioningReport result = new ProvisioningReport();
+
+ result.setKey(null);
+ result.setName(delta.getObject().getUid().getUidValue());
+ result.setOperation(ResourceOperation.NONE);
+ result.setAnyType(REALM_TYPE);
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+
+ if (!profile.isDryRun()) {
+ finalize(matching
+ ? MatchingRule.toEventName(MatchingRule.IGNORE)
+ : UnmatchingRule.toEventName(UnmatchingRule.IGNORE), Result.SUCCESS, null, null, delta);
+ }
+
+ return result;
+ }
+
+ private void doHandle(final SyncDelta delta, final OrgUnit orgUnit) throws JobExecutionException {
+ LOG.debug("Process {} for {} as {}",
+ delta.getDeltaType(), delta.getUid().getUidValue(), delta.getObject().getObjectClass());
+
+ String uid = delta.getPreviousUid() == null
+ ? delta.getUid().getUidValue()
+ : delta.getPreviousUid().getUidValue();
+
+ List<String> keys = pullUtils.findExisting(uid, delta.getObject(), orgUnit);
+ LOG.debug("Match found for {} as {}: {}",
+ delta.getUid().getUidValue(), delta.getObject().getObjectClass(), keys);
+
+ if (keys.size() > 1) {
+ switch (profile.getResAct()) {
+ case IGNORE:
+ throw new IllegalStateException("More than one match " + keys);
+
+ case FIRSTMATCH:
+ keys = keys.subList(0, 1);
+ break;
+
+ case LASTMATCH:
+ keys = keys.subList(keys.size() - 1, keys.size());
+ break;
+
+ default:
+ // keep keys unmodified
+ }
+ }
+
+ try {
+ if (SyncDeltaType.CREATE_OR_UPDATE == delta.getDeltaType()) {
+ if (keys.isEmpty()) {
+ switch (profile.getTask().getUnmatchingRule()) {
+ case ASSIGN:
+ profile.getResults().addAll(assign(delta, orgUnit));
+ break;
+
+ case PROVISION:
+ profile.getResults().addAll(provision(delta, orgUnit));
+ break;
+
+ case IGNORE:
+ profile.getResults().add(ignore(delta, false));
+ break;
+
+ default:
+ // do nothing
+ }
+ } else {
+ switch (profile.getTask().getMatchingRule()) {
+ case UPDATE:
+ profile.getResults().addAll(update(delta, keys));
+ break;
+
+ case DEPROVISION:
+ profile.getResults().addAll(deprovision(delta, keys, false));
+ break;
+
+ case UNASSIGN:
+ profile.getResults().addAll(deprovision(delta, keys, true));
+ break;
+
+ case LINK:
+ profile.getResults().addAll(link(delta, keys, false));
+ break;
+
+ case UNLINK:
+ profile.getResults().addAll(link(delta, keys, true));
+ break;
+
+ case IGNORE:
+ profile.getResults().add(ignore(delta, true));
+ break;
+
+ default:
+ // do nothing
+ }
+ }
+ } else if (SyncDeltaType.DELETE == delta.getDeltaType()) {
+ if (keys.isEmpty()) {
+ finalize(ResourceOperation.DELETE.name().toLowerCase(), Result.SUCCESS, null, null, delta);
+ LOG.debug("No match found for deletion");
+ } else {
+ profile.getResults().addAll(delete(delta, keys));
+ }
+ }
+ } catch (IllegalStateException | IllegalArgumentException e) {
+ LOG.warn(e.getMessage());
+ }
+ }
+
+ private void finalize(
+ final String event,
+ final Result result,
+ final Object before,
+ final Object output,
+ final SyncDelta delta) {
+
+ synchronized (this) {
+ this.latestResult = result;
+ }
+
+ notificationManager.createTasks(AuditElements.EventCategoryType.PULL,
+ REALM_TYPE.toLowerCase(),
+ profile.getTask().getResource().getKey(),
+ event,
+ result,
+ before,
+ output,
+ delta);
+
+ auditManager.audit(AuditElements.EventCategoryType.PULL,
+ REALM_TYPE.toLowerCase(),
+ profile.getTask().getResource().getKey(),
+ event,
+ result,
+ before,
+ output,
+ delta);
+ }
+}