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 2015/04/30 12:54:33 UTC

[2/8] syncope git commit: [SYNCOPE-663] Throwing new IgnoreException from SyncActions' or PushActions's methods will make the related user / role to get ignored by the sync / push process

[SYNCOPE-663] Throwing new IgnoreException from SyncActions' or PushActions's methods will make the related user / role to get ignored by the sync / push process


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/857f02a0
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/857f02a0
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/857f02a0

Branch: refs/heads/master
Commit: 857f02a0cbc0d6662ac98bcf3e7934557a761212
Parents: fa3223f
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Thu Apr 30 12:11:50 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Apr 30 12:11:50 2015 +0200

----------------------------------------------------------------------
 .../pages/SecurityQuestionModalPage.java        |  2 -
 .../syncope/console/EditProfileTestITCase.java  | 13 ++--
 .../core/rest/controller/RoleController.java    |  2 -
 .../core/sync/IgnoreProvisionException.java     | 29 +++++++++
 .../apache/syncope/core/sync/PushActions.java   |  5 +-
 .../apache/syncope/core/sync/SyncActions.java   | 64 +++++++++++---------
 .../apache/syncope/core/sync/SyncResult.java    |  8 ++-
 .../impl/AbstractSubjectPushResultHandler.java  | 33 +++++-----
 .../impl/AbstractSubjectSyncResultHandler.java  | 45 ++++++++------
 .../syncope/core/sync/impl/AbstractSyncJob.java | 57 +++++++++++------
 .../sync/impl/AbstractSyncopeResultHandler.java |  9 ++-
 .../core/sync/impl/RoleSyncResultHandler.java   | 11 ++--
 .../core/sync/impl/UserSyncResultHandler.java   | 12 ++--
 .../core/rest/AuthenticationTestITCase.java     |  1 -
 .../syncope/core/rest/ResourceTestITCase.java   |  5 +-
 .../syncope/core/rest/TaskTestITCase.java       | 13 +++-
 .../syncope/core/sync/TestSyncActions.java      | 16 ++++-
 17 files changed, 206 insertions(+), 119 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/857f02a0/console/src/main/java/org/apache/syncope/console/pages/SecurityQuestionModalPage.java
----------------------------------------------------------------------
diff --git a/console/src/main/java/org/apache/syncope/console/pages/SecurityQuestionModalPage.java b/console/src/main/java/org/apache/syncope/console/pages/SecurityQuestionModalPage.java
index c9cd4c7..a6e5442 100644
--- a/console/src/main/java/org/apache/syncope/console/pages/SecurityQuestionModalPage.java
+++ b/console/src/main/java/org/apache/syncope/console/pages/SecurityQuestionModalPage.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.console.pages;
 
-import static org.apache.syncope.console.pages.AbstractBasePage.FORM;
-
 import org.apache.syncope.common.SyncopeClientException;
 import org.apache.syncope.common.to.SecurityQuestionTO;
 import org.apache.syncope.console.commons.Constants;

http://git-wip-us.apache.org/repos/asf/syncope/blob/857f02a0/console/src/test/java/org/apache/syncope/console/EditProfileTestITCase.java
----------------------------------------------------------------------
diff --git a/console/src/test/java/org/apache/syncope/console/EditProfileTestITCase.java b/console/src/test/java/org/apache/syncope/console/EditProfileTestITCase.java
index 484a2a1..4752162 100644
--- a/console/src/test/java/org/apache/syncope/console/EditProfileTestITCase.java
+++ b/console/src/test/java/org/apache/syncope/console/EditProfileTestITCase.java
@@ -19,7 +19,6 @@
 package org.apache.syncope.console;
 
 import java.util.concurrent.TimeUnit;
-import static org.apache.syncope.console.AbstractTest.ADMIN;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -36,21 +35,21 @@ public class EditProfileTestITCase extends AbstractTest {
     public void setUp() throws Exception {
         seleniumDriver = new FirefoxDriver();
         //selenium = new WebDriverBackedSelenium(seleniumDriver, BASE_URL);
-        seleniumDriver.get(BASE_URL);        
+        seleniumDriver.get(BASE_URL);
         wait = new WebDriverWait(seleniumDriver, 6);
-        
+
     }
 
     @Test
     public void selfRegistration() {
         seleniumDriver.findElement(By.xpath("//div/div[2]/div[1]/span/a/span")).click();
-        
+
         wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//iframe")));
         seleniumDriver.switchTo().frame(0);
 
         wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//span[contains(text(),'Attributes')]")));
         seleniumDriver.switchTo().defaultContent();
-        seleniumDriver.findElement(By.xpath("//a[@class='w_close']")).click();               
+        seleniumDriver.findElement(By.xpath("//a[@class='w_close']")).click();
 
         // only to have some "Logout" available for @After
         seleniumDriver.get(BASE_URL);
@@ -62,7 +61,7 @@ public class EditProfileTestITCase extends AbstractTest {
         seleniumDriver.findElement(By.name("p::submit")).click();
         seleniumDriver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
     }
-    
+
     @Test
     public void editUserProfile() {
         WebElement element = seleniumDriver.findElement(By.name("userId"));
@@ -75,7 +74,7 @@ public class EditProfileTestITCase extends AbstractTest {
         seleniumDriver.findElement(By.xpath("//div[@id='username']/a")).click();
 
         wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//iframe")));
-        seleniumDriver.switchTo().frame(0);        
+        seleniumDriver.switchTo().frame(0);
         wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//span[contains(text(),'Attributes')]")));
         wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//input[@value='rossini']")));
         seleniumDriver.switchTo().defaultContent();

http://git-wip-us.apache.org/repos/asf/syncope/blob/857f02a0/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java b/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java
index 22001e5..a64bdb5 100644
--- a/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java
+++ b/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.core.rest.controller;
 
-import static org.apache.syncope.core.rest.controller.AbstractController.LOG;
-
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collection;

http://git-wip-us.apache.org/repos/asf/syncope/blob/857f02a0/core/src/main/java/org/apache/syncope/core/sync/IgnoreProvisionException.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/sync/IgnoreProvisionException.java b/core/src/main/java/org/apache/syncope/core/sync/IgnoreProvisionException.java
new file mode 100644
index 0000000..893c35f
--- /dev/null
+++ b/core/src/main/java/org/apache/syncope/core/sync/IgnoreProvisionException.java
@@ -0,0 +1,29 @@
+/*
+ * 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.sync;
+
+/**
+ * Raised by {@link SyncActions} or {@link PushActions} methods when the given subject is to be ignored for
+ * synchronization / push.
+ */
+public class IgnoreProvisionException extends RuntimeException {
+
+    private static final long serialVersionUID = -8803817097998786364L;
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/857f02a0/core/src/main/java/org/apache/syncope/core/sync/PushActions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/sync/PushActions.java b/core/src/main/java/org/apache/syncope/core/sync/PushActions.java
index 4ab45ad..a020aac 100644
--- a/core/src/main/java/org/apache/syncope/core/sync/PushActions.java
+++ b/core/src/main/java/org/apache/syncope/core/sync/PushActions.java
@@ -18,15 +18,14 @@
  */
 package org.apache.syncope.core.sync;
 
-import java.util.Map;
-import java.util.Set;
 import org.apache.syncope.core.persistence.beans.AbstractAttributable;
 import org.apache.syncope.core.sync.impl.AbstractSyncopeResultHandler;
-import org.identityconnectors.framework.common.objects.Attribute;
 import org.quartz.JobExecutionException;
 
 /**
  * Interface for actions to be performed during PushJob execution.
+ * <br/>
+ * All methods can throw {@link IgnoreProvisionException} to make the current subject ignored by the push process.
  */
 public interface PushActions extends AbstractSyncActions<AbstractSyncopeResultHandler<?, ?>> {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/857f02a0/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java b/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java
index 42548d1..c169f8c 100644
--- a/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java
+++ b/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java
@@ -26,6 +26,9 @@ import org.quartz.JobExecutionException;
 
 /**
  * Interface for actions to be performed during SyncJob execution.
+ * <br/>
+ * All methods can throw {@link IgnoreProvisionException} to make the current subject ignored by the synchronization
+ * process.
  */
 public interface SyncActions extends AbstractSyncActions<AbstractSyncopeResultHandler<?, ?>> {
 
@@ -41,9 +44,9 @@ public interface SyncActions extends AbstractSyncActions<AbstractSyncopeResultHa
      * @throws JobExecutionException in case of generic failure
      */
     <T extends AbstractAttributableTO> SyncDelta beforeProvision(
-            final SyncProfile<?, ?> profile,
-            final SyncDelta delta,
-            final T subject) throws JobExecutionException;
+            SyncProfile<?, ?> profile,
+            SyncDelta delta,
+            T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before creating (and linking to the resource) a synchronized user / role locally.
@@ -57,9 +60,9 @@ public interface SyncActions extends AbstractSyncActions<AbstractSyncopeResultHa
      * @throws JobExecutionException in case of generic failure
      */
     <T extends AbstractAttributableTO> SyncDelta beforeAssign(
-            final SyncProfile<?, ?> profile,
-            final SyncDelta delta,
-            final T subject) throws JobExecutionException;
+            SyncProfile<?, ?> profile,
+            SyncDelta delta,
+            T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before unlinking resource from the synchronized user / role and de-provisioning.
@@ -73,9 +76,9 @@ public interface SyncActions extends AbstractSyncActions<AbstractSyncopeResultHa
      * @throws JobExecutionException in case of generic failure
      */
     <T extends AbstractAttributableTO> SyncDelta beforeUnassign(
-            final SyncProfile<?, ?> profile,
-            final SyncDelta delta,
-            final T subject) throws JobExecutionException;
+            SyncProfile<?, ?> profile,
+            SyncDelta delta,
+            T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before de-provisioning action only.
@@ -89,9 +92,9 @@ public interface SyncActions extends AbstractSyncActions<AbstractSyncopeResultHa
      * @throws JobExecutionException in case of generic failure
      */
     <T extends AbstractAttributableTO> SyncDelta beforeDeprovision(
-            final SyncProfile<?, ?> profile,
-            final SyncDelta delta,
-            final T subject) throws JobExecutionException;
+            SyncProfile<?, ?> profile,
+            SyncDelta delta,
+            T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before unlinking resource from the synchronized user / role.
@@ -105,9 +108,9 @@ public interface SyncActions extends AbstractSyncActions<AbstractSyncopeResultHa
      * @throws JobExecutionException in case of generic failure
      */
     <T extends AbstractAttributableTO> SyncDelta beforeUnlink(
-            final SyncProfile<?, ?> profile,
-            final SyncDelta delta,
-            final T subject) throws JobExecutionException;
+            SyncProfile<?, ?> profile,
+            SyncDelta delta,
+            T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before linking resource to the synchronized user / role.
@@ -121,9 +124,9 @@ public interface SyncActions extends AbstractSyncActions<AbstractSyncopeResultHa
      * @throws JobExecutionException in case of generic failure
      */
     <T extends AbstractAttributableTO> SyncDelta beforeLink(
-            final SyncProfile<?, ?> profile,
-            final SyncDelta delta,
-            final T subject) throws JobExecutionException;
+            SyncProfile<?, ?> profile,
+            SyncDelta delta,
+            T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before to update a synchronized user / role locally.
@@ -138,10 +141,10 @@ public interface SyncActions extends AbstractSyncActions<AbstractSyncopeResultHa
      * @throws JobExecutionException in case of generic failure.
      */
     <T extends AbstractAttributableTO, K extends AbstractAttributableMod> SyncDelta beforeUpdate(
-            final SyncProfile<?, ?> profile,
-            final SyncDelta delta,
-            final T subject,
-            final K subjectMod)
+            SyncProfile<?, ?> profile,
+            SyncDelta delta,
+            T subject,
+            K subjectMod)
             throws JobExecutionException;
 
     /**
@@ -154,22 +157,23 @@ public interface SyncActions extends AbstractSyncActions<AbstractSyncopeResultHa
      * @throws JobExecutionException in case of generic failure
      */
     <T extends AbstractAttributableTO> SyncDelta beforeDelete(
-            final SyncProfile<?, ?> profile,
-            final SyncDelta delta,
-            final T subject) throws JobExecutionException;
+            SyncProfile<?, ?> profile,
+            SyncDelta delta,
+            T subject) throws JobExecutionException;
 
     /**
      * Action to be executed after each local user / role synchronization.
      *
      * @param profile profile of the synchronization being executed.
-     * @param delta retrieved synchronization information (may be modified by 'beforeProvision/beforeUpdate/beforeDelete')
+     * @param delta retrieved synchronization information (may be modified by
+     * 'beforeProvision/beforeUpdate/beforeDelete')
      * @param subject synchronized local user / role
      * @param result global synchronization results at the current synchronization step
      * @throws JobExecutionException in case of generic failure
      */
     <T extends AbstractAttributableTO> void after(
-            final SyncProfile<?, ?> profile,
-            final SyncDelta delta,
-            final T subject,
-            final SyncResult result) throws JobExecutionException;
+            SyncProfile<?, ?> profile,
+            SyncDelta delta,
+            T subject,
+            SyncResult result) throws JobExecutionException;
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/857f02a0/core/src/main/java/org/apache/syncope/core/sync/SyncResult.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/sync/SyncResult.java b/core/src/main/java/org/apache/syncope/core/sync/SyncResult.java
index 5ebca8a..d95cad9 100644
--- a/core/src/main/java/org/apache/syncope/core/sync/SyncResult.java
+++ b/core/src/main/java/org/apache/syncope/core/sync/SyncResult.java
@@ -28,9 +28,13 @@ import org.apache.syncope.common.types.ResourceOperation;
 import org.apache.syncope.common.types.TraceLevel;
 
 public class SyncResult {
+
     public enum Status {
+
         SUCCESS,
+        IGNORE,
         FAILURE
+
     }
 
     private String message;
@@ -115,8 +119,8 @@ public class SyncResult {
             // All
             return String.format("%s %s (id/name): %d/%s %s", operation, status, id, name,
                     StringUtils.isBlank(message)
-                    ? ""
-                    : "with message: " + message);
+                            ? ""
+                            : "with message: " + message);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/857f02a0/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectPushResultHandler.java b/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectPushResultHandler.java
index 9ea22fd..e360f43 100644
--- a/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectPushResultHandler.java
+++ b/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectPushResultHandler.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.core.sync.impl;
 
 import static org.apache.syncope.core.sync.impl.AbstractSyncopeResultHandler.LOG;
+
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -26,8 +27,6 @@ import java.util.Set;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.syncope.common.mod.AttributeMod;
 import org.apache.syncope.common.mod.MembershipMod;
-import org.apache.syncope.common.to.AbstractSubjectTO;
-import org.apache.syncope.common.types.AttributableType;
 import org.apache.syncope.common.types.AuditElements;
 import org.apache.syncope.common.types.AuditElements.Result;
 import org.apache.syncope.common.types.IntMappingType;
@@ -42,6 +41,7 @@ import org.apache.syncope.core.persistence.beans.PushTask;
 import org.apache.syncope.core.persistence.beans.membership.Membership;
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
 import org.apache.syncope.core.propagation.PropagationByResource;
+import org.apache.syncope.core.sync.IgnoreProvisionException;
 import org.apache.syncope.core.sync.PushActions;
 import org.apache.syncope.core.sync.SyncResult;
 import org.apache.syncope.core.util.AttributableUtil;
@@ -52,33 +52,38 @@ import org.springframework.transaction.annotation.Transactional;
 
 public abstract class AbstractSubjectPushResultHandler extends AbstractSyncopeResultHandler<PushTask, PushActions> {
 
-    protected abstract AttributableUtil getAttributableUtil();
-
-    protected abstract String getName(final AbstractSubject subject);
+    protected abstract String getName(AbstractSubject subject);
 
     protected abstract AbstractMapping getMapping();
 
-    protected abstract AbstractSubjectTO getSubjectTO(final long id);
+    protected abstract AbstractSubject getSubject(long id);
 
-    protected abstract AbstractSubject getSubject(final long id);
+    protected abstract AbstractSubject deprovision(AbstractSubject sbj);
 
-    protected abstract AbstractSubject deprovision(final AbstractSubject sbj);
+    protected abstract AbstractSubject provision(AbstractSubject sbj, Boolean enabled);
 
-    protected abstract AbstractSubject provision(final AbstractSubject sbj, final Boolean enabled);
+    protected abstract AbstractSubject link(AbstractSubject sbj, Boolean unlink);
 
-    protected abstract AbstractSubject link(final AbstractSubject sbj, final Boolean unlink);
+    protected abstract AbstractSubject unassign(AbstractSubject sbj);
 
-    protected abstract AbstractSubject unassign(final AbstractSubject sbj);
+    protected abstract AbstractSubject assign(AbstractSubject sbj, Boolean enabled);
 
-    protected abstract AbstractSubject assign(final AbstractSubject sbj, Boolean enabled);
-
-    protected abstract ConnectorObject getRemoteObject(final String accountId);
+    protected abstract ConnectorObject getRemoteObject(String accountId);
 
     @Transactional
     public boolean handle(final long subjectId) {
         try {
             doHandle(subjectId);
             return true;
+        } catch (IgnoreProvisionException e) {
+            SyncResult result = new SyncResult();
+            result.setOperation(ResourceOperation.NONE);
+            result.setSubjectType(getAttributableUtil().getType());
+            result.setStatus(SyncResult.Status.IGNORE);
+            result.setId(subjectId);
+
+            LOG.warn("Ignoring during synchronization", e);
+            return true;
         } catch (JobExecutionException e) {
             LOG.error("Synchronization failed", e);
             return false;

http://git-wip-us.apache.org/repos/asf/syncope/blob/857f02a0/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectSyncResultHandler.java b/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectSyncResultHandler.java
index 9a51ebe..6b6c647 100644
--- a/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectSyncResultHandler.java
+++ b/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSubjectSyncResultHandler.java
@@ -20,8 +20,6 @@ package org.apache.syncope.core.sync.impl;
 
 import org.apache.syncope.core.sync.SyncUtilities;
 
-import static org.apache.syncope.core.sync.impl.AbstractSyncopeResultHandler.LOG;
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -40,6 +38,7 @@ import org.apache.syncope.core.persistence.dao.UserDAO;
 import org.apache.syncope.core.propagation.PropagationException;
 import org.apache.syncope.core.rest.controller.UnauthorizedRoleException;
 import org.apache.syncope.core.rest.data.AttributableTransformer;
+import org.apache.syncope.core.sync.IgnoreProvisionException;
 import org.apache.syncope.core.sync.SyncActions;
 import org.apache.syncope.core.sync.SyncResult;
 import org.apache.syncope.core.util.AttributableUtil;
@@ -61,26 +60,22 @@ public abstract class AbstractSubjectSyncResultHandler extends AbstractSyncopeRe
     @Autowired
     protected UserDAO userDAO;
 
-    protected abstract AttributableUtil getAttributableUtil();
-
     protected abstract String getName(AbstractSubjectTO subjectTO);
 
-    protected abstract AbstractSubjectTO getSubjectTO(long id);
-
     protected abstract AbstractSubjectMod getSubjectMod(AbstractSubjectTO subjectTO, SyncDelta delta);
 
-    protected abstract AbstractSubjectTO create(AbstractSubjectTO subjectTO, SyncDelta _delta, SyncResult result);
+    protected abstract AbstractSubjectTO doCreate(AbstractSubjectTO subjectTO, SyncDelta _delta, SyncResult result);
 
-    protected abstract AbstractSubjectTO link(AbstractSubjectTO before, SyncResult result, boolean unlink)
+    protected abstract AbstractSubjectTO doLink(AbstractSubjectTO before, SyncResult result, boolean unlink)
             throws Exception;
 
-    protected abstract AbstractSubjectTO update(AbstractSubjectTO before, AbstractSubjectMod subjectMod,
+    protected abstract AbstractSubjectTO doUpdate(AbstractSubjectTO before, AbstractSubjectMod subjectMod,
             SyncDelta delta, SyncResult result)
             throws Exception;
 
-    protected abstract void deprovision(Long id, boolean unlink) throws Exception;
+    protected abstract void doDeprovision(Long id, boolean unlink) throws Exception;
 
-    protected abstract void delete(Long id);
+    protected abstract void doDelete(Long id);
 
     @Override
     public boolean handle(final SyncDelta delta) {
@@ -91,6 +86,16 @@ public abstract class AbstractSubjectSyncResultHandler extends AbstractSyncopeRe
 
             doHandle(delta, profile.getResults());
             return true;
+        } catch (IgnoreProvisionException e) {
+            SyncResult result = new SyncResult();
+            result.setOperation(ResourceOperation.NONE);
+            result.setSubjectType(getAttributableUtil().getType());
+            result.setStatus(SyncResult.Status.IGNORE);
+            result.setId(0L);
+            result.setName(delta.getObject().getName().getNameValue());
+
+            LOG.warn("Ignoring during synchronization", e);
+            return true;
         } catch (JobExecutionException e) {
             LOG.error("Synchronization failed", e);
             return false;
@@ -99,6 +104,7 @@ public abstract class AbstractSubjectSyncResultHandler extends AbstractSyncopeRe
 
     protected List<SyncResult> assign(final SyncDelta delta, final AttributableUtil attrUtil)
             throws JobExecutionException {
+
         if (!profile.getSyncTask().isPerformCreate()) {
             LOG.debug("SyncTask not configured for create");
             return Collections.<SyncResult>emptyList();
@@ -134,8 +140,9 @@ public abstract class AbstractSubjectSyncResultHandler extends AbstractSyncopeRe
         return Collections.singletonList(result);
     }
 
-    protected List<SyncResult> create(final SyncDelta delta, final AttributableUtil attrUtil)
+    protected List<SyncResult> provision(final SyncDelta delta, final AttributableUtil attrUtil)
             throws JobExecutionException {
+
         if (!profile.getSyncTask().isPerformCreate()) {
             LOG.debug("SyncTask not configured for create");
             return Collections.<SyncResult>emptyList();
@@ -181,7 +188,7 @@ public abstract class AbstractSubjectSyncResultHandler extends AbstractSyncopeRe
         Result resultStatus;
 
         try {
-            AbstractSubjectTO actual = create(subjectTO, delta, result);
+            AbstractSubjectTO actual = doCreate(subjectTO, delta, result);
             result.setName(getName(actual));
             output = actual;
             resultStatus = Result.SUCCESS;
@@ -256,7 +263,7 @@ public abstract class AbstractSubjectSyncResultHandler extends AbstractSyncopeRe
                             delta = action.beforeUpdate(this.getProfile(), delta, before, attributableMod);
                         }
 
-                        final AbstractSubjectTO updated = update(before, attributableMod, delta, result);
+                        final AbstractSubjectTO updated = doUpdate(before, attributableMod, delta, result);
 
                         for (SyncActions action : profile.getActions()) {
                             action.after(this.getProfile(), delta, updated, result);
@@ -340,7 +347,7 @@ public abstract class AbstractSubjectSyncResultHandler extends AbstractSyncopeRe
                             }
                         }
 
-                        deprovision(id, unlink);
+                        doDeprovision(id, unlink);
                         output = getSubjectTO(id);
 
                         for (SyncActions action : profile.getActions()) {
@@ -426,7 +433,7 @@ public abstract class AbstractSubjectSyncResultHandler extends AbstractSyncopeRe
                             }
                         }
 
-                        output = link(before, result, unlink);
+                        output = doLink(before, result, unlink);
 
                         for (SyncActions action : profile.getActions()) {
                             action.after(this.getProfile(), delta, AbstractSubjectTO.class.cast(output), result);
@@ -491,7 +498,7 @@ public abstract class AbstractSubjectSyncResultHandler extends AbstractSyncopeRe
                     }
 
                     try {
-                        delete(id);
+                        doDelete(id);
                         output = null;
                         resultStatus = Result.SUCCESS;
                     } catch (Exception e) {
@@ -552,7 +559,7 @@ public abstract class AbstractSubjectSyncResultHandler extends AbstractSyncopeRe
      * @param delta returned by the underlying profile.getConnector()
      * @throws JobExecutionException in case of synchronization failure.
      */
-    protected final void doHandle(final SyncDelta delta, final Collection<SyncResult> syncResults)
+    protected void doHandle(final SyncDelta delta, final Collection<SyncResult> syncResults)
             throws JobExecutionException {
 
         final AttributableUtil attrUtil = getAttributableUtil();
@@ -593,7 +600,7 @@ public abstract class AbstractSubjectSyncResultHandler extends AbstractSyncopeRe
                             profile.getResults().addAll(assign(delta, attrUtil));
                             break;
                         case PROVISION:
-                            profile.getResults().addAll(create(delta, attrUtil));
+                            profile.getResults().addAll(provision(delta, attrUtil));
                             break;
                         case IGNORE:
                             profile.getResults().addAll(ignore(delta, attrUtil, false));

http://git-wip-us.apache.org/repos/asf/syncope/blob/857f02a0/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncJob.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncJob.java b/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncJob.java
index 0124082..e174971 100644
--- a/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncJob.java
+++ b/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncJob.java
@@ -117,6 +117,7 @@ public abstract class AbstractSyncJob<T extends AbstractSyncTask, A extends Abst
         List<SyncResult> uSuccDelete = new ArrayList<SyncResult>();
         List<SyncResult> uFailDelete = new ArrayList<SyncResult>();
         List<SyncResult> uSuccNone = new ArrayList<SyncResult>();
+        List<SyncResult> uIgnore = new ArrayList<SyncResult>();
         List<SyncResult> rSuccCreate = new ArrayList<SyncResult>();
         List<SyncResult> rFailCreate = new ArrayList<SyncResult>();
         List<SyncResult> rSuccUpdate = new ArrayList<SyncResult>();
@@ -124,6 +125,7 @@ public abstract class AbstractSyncJob<T extends AbstractSyncTask, A extends Abst
         List<SyncResult> rSuccDelete = new ArrayList<SyncResult>();
         List<SyncResult> rFailDelete = new ArrayList<SyncResult>();
         List<SyncResult> rSuccNone = new ArrayList<SyncResult>();
+        List<SyncResult> rIgnore = new ArrayList<SyncResult>();
 
         for (SyncResult syncResult : syncResults) {
             switch (syncResult.getStatus()) {
@@ -237,6 +239,20 @@ public abstract class AbstractSyncJob<T extends AbstractSyncTask, A extends Abst
                     }
                     break;
 
+                case IGNORE:
+                    switch (syncResult.getSubjectType()) {
+                        case USER:
+                            uIgnore.add(syncResult);
+                            break;
+
+                        case ROLE:
+                            rIgnore.add(syncResult);
+                            break;
+
+                        default:
+                    }
+                    break;
+
                 default:
             }
         }
@@ -249,7 +265,8 @@ public abstract class AbstractSyncJob<T extends AbstractSyncTask, A extends Abst
                 append(' ').
                 append("[deleted/failures]: ").append(uSuccDelete.size()).append('/').append(uFailDelete.size()).
                 append(' ').
-                append("[ignored]: ").append(uSuccNone.size()).append('\n');
+                append("[no operation/ignored]: ").append(uSuccNone.size()).append('/').append(uIgnore.size()).
+                append('\n');
         report.append("Roles ").
                 append("[created/failures]: ").append(rSuccCreate.size()).append('/').append(rFailCreate.size()).
                 append(' ').
@@ -257,7 +274,7 @@ public abstract class AbstractSyncJob<T extends AbstractSyncTask, A extends Abst
                 append(' ').
                 append("[deleted/failures]: ").append(rSuccDelete.size()).append('/').append(rFailDelete.size()).
                 append(' ').
-                append("[ignored]: ").append(rSuccNone.size());
+                append("[no operation/ignored]: ").append(rSuccNone.size()).append('/').append(rIgnore.size());
 
         // Failures
         if (syncTraceLevel == TraceLevel.FAILURES || syncTraceLevel == TraceLevel.ALL) {
@@ -290,22 +307,26 @@ public abstract class AbstractSyncJob<T extends AbstractSyncTask, A extends Abst
 
         // Succeeded, only if on 'ALL' level
         if (syncTraceLevel == TraceLevel.ALL) {
-            report.append("\n\nUsers created:\n")
-                    .append(SyncResult.produceReport(uSuccCreate, syncTraceLevel))
-                    .append("\nUsers updated:\n")
-                    .append(SyncResult.produceReport(uSuccUpdate, syncTraceLevel))
-                    .append("\nUsers deleted:\n")
-                    .append(SyncResult.produceReport(uSuccDelete, syncTraceLevel))
-                    .append("\nUsers ignored:\n")
-                    .append(SyncResult.produceReport(uSuccNone, syncTraceLevel));
-            report.append("\n\nRoles created:\n")
-                    .append(SyncResult.produceReport(rSuccCreate, syncTraceLevel))
-                    .append("\nRoles updated:\n")
-                    .append(SyncResult.produceReport(rSuccUpdate, syncTraceLevel))
-                    .append("\nRoles deleted:\n")
-                    .append(SyncResult.produceReport(rSuccDelete, syncTraceLevel))
-                    .append("\nRoles ignored:\n")
-                    .append(SyncResult.produceReport(rSuccNone, syncTraceLevel));
+            report.append("\n\nUsers created:\n").
+                    append(SyncResult.produceReport(uSuccCreate, syncTraceLevel)).
+                    append("\nUsers updated:\n").
+                    append(SyncResult.produceReport(uSuccUpdate, syncTraceLevel)).
+                    append("\nUsers deleted:\n").
+                    append(SyncResult.produceReport(uSuccDelete, syncTraceLevel)).
+                    append("\nUsers no CRUD:\n").
+                    append(SyncResult.produceReport(uSuccNone, syncTraceLevel)).
+                    append("\nUsers no operation:\n").
+                    append(SyncResult.produceReport(uIgnore, syncTraceLevel));
+            report.append("\n\nRoles created:\n").
+                    append(SyncResult.produceReport(rSuccCreate, syncTraceLevel)).
+                    append("\nRoles updated:\n").
+                    append(SyncResult.produceReport(rSuccUpdate, syncTraceLevel)).
+                    append("\nRoles deleted:\n").
+                    append(SyncResult.produceReport(rSuccDelete, syncTraceLevel)).
+                    append("\nRoles no operation:\n").
+                    append(SyncResult.produceReport(rSuccNone, syncTraceLevel)).
+                    append("\nRoles ignored:\n").
+                    append(SyncResult.produceReport(rIgnore, syncTraceLevel));
         }
 
         return report.toString();

http://git-wip-us.apache.org/repos/asf/syncope/blob/857f02a0/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java b/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java
index adf7c8d..3ac390f 100644
--- a/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java
+++ b/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.sync.impl;
 
+import org.apache.syncope.common.to.AbstractSubjectTO;
 import org.apache.syncope.core.sync.SyncProfile;
 import org.apache.syncope.core.audit.AuditManager;
 import org.apache.syncope.core.connid.ConnObjectUtil;
@@ -28,6 +29,7 @@ import org.apache.syncope.core.propagation.impl.PropagationManager;
 import org.apache.syncope.core.rest.data.RoleDataBinder;
 import org.apache.syncope.core.rest.data.UserDataBinder;
 import org.apache.syncope.core.sync.AbstractSyncActions;
+import org.apache.syncope.core.util.AttributableUtil;
 import org.apache.syncope.core.workflow.role.RoleWorkflowAdapter;
 import org.apache.syncope.core.workflow.user.UserWorkflowAdapter;
 import org.slf4j.Logger;
@@ -40,7 +42,7 @@ public abstract class AbstractSyncopeResultHandler<T extends AbstractSyncTask, A
      * Logger.
      */
     protected static final Logger LOG = LoggerFactory.getLogger(AbstractSyncopeResultHandler.class);
-    
+
     /**
      * User data binder.
      */
@@ -100,6 +102,10 @@ public abstract class AbstractSyncopeResultHandler<T extends AbstractSyncTask, A
      */
     protected SyncProfile<T, A> profile;
 
+    protected abstract AttributableUtil getAttributableUtil();
+
+    protected abstract AbstractSubjectTO getSubjectTO(long id);
+
     public void setProfile(final SyncProfile<T, A> profile) {
         this.profile = profile;
     }
@@ -107,4 +113,5 @@ public abstract class AbstractSyncopeResultHandler<T extends AbstractSyncTask, A
     public SyncProfile<T, A> getProfile() {
         return profile;
     }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/857f02a0/core/src/main/java/org/apache/syncope/core/sync/impl/RoleSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/sync/impl/RoleSyncResultHandler.java b/core/src/main/java/org/apache/syncope/core/sync/impl/RoleSyncResultHandler.java
index 8eb3960..72ab83d 100644
--- a/core/src/main/java/org/apache/syncope/core/sync/impl/RoleSyncResultHandler.java
+++ b/core/src/main/java/org/apache/syncope/core/sync/impl/RoleSyncResultHandler.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.core.sync.impl;
 
-import static org.apache.syncope.core.sync.impl.AbstractSyncopeResultHandler.LOG;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -80,7 +79,7 @@ public class RoleSyncResultHandler extends AbstractSubjectSyncResultHandler {
     }
 
     @Override
-    protected AbstractSubjectTO create(
+    protected AbstractSubjectTO doCreate(
             final AbstractSubjectTO subjectTO, final SyncDelta _delta, final SyncResult result) {
 
         RoleTO roleTO = RoleTO.class.cast(subjectTO);
@@ -107,7 +106,7 @@ public class RoleSyncResultHandler extends AbstractSubjectSyncResultHandler {
     }
 
     @Override
-    protected AbstractSubjectTO link(
+    protected AbstractSubjectTO doLink(
             final AbstractSubjectTO before,
             final SyncResult result,
             final boolean unlink)
@@ -126,7 +125,7 @@ public class RoleSyncResultHandler extends AbstractSubjectSyncResultHandler {
     }
 
     @Override
-    protected AbstractSubjectTO update(
+    protected AbstractSubjectTO doUpdate(
             final AbstractSubjectTO before,
             final AbstractSubjectMod subjectMod,
             final SyncDelta delta,
@@ -160,7 +159,7 @@ public class RoleSyncResultHandler extends AbstractSubjectSyncResultHandler {
     }
 
     @Override
-    protected void deprovision(final Long id, final boolean unlink) {
+    protected void doDeprovision(final Long id, final boolean unlink) {
 
         taskExecutor.execute(
                 propagationManager.getRoleDeleteTaskIds(id, profile.getSyncTask().getResource().getName()));
@@ -173,7 +172,7 @@ public class RoleSyncResultHandler extends AbstractSubjectSyncResultHandler {
     }
 
     @Override
-    protected void delete(final Long id) {
+    protected void doDelete(final Long id) {
         try {
             taskExecutor.execute(
                     propagationManager.getRoleDeleteTaskIds(id, profile.getSyncTask().getResource().getName()));

http://git-wip-us.apache.org/repos/asf/syncope/blob/857f02a0/core/src/main/java/org/apache/syncope/core/sync/impl/UserSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/sync/impl/UserSyncResultHandler.java b/core/src/main/java/org/apache/syncope/core/sync/impl/UserSyncResultHandler.java
index a8cc00b..979feb3 100644
--- a/core/src/main/java/org/apache/syncope/core/sync/impl/UserSyncResultHandler.java
+++ b/core/src/main/java/org/apache/syncope/core/sync/impl/UserSyncResultHandler.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.core.sync.impl;
 
-import static org.apache.syncope.core.sync.impl.AbstractSyncopeResultHandler.LOG;
-
 import java.util.AbstractMap;
 import java.util.Collections;
 import java.util.HashSet;
@@ -74,7 +72,7 @@ public class UserSyncResultHandler extends AbstractSubjectSyncResultHandler {
     }
 
     @Override
-    protected AbstractSubjectTO create(
+    protected AbstractSubjectTO doCreate(
             final AbstractSubjectTO subjectTO, final SyncDelta delta, final SyncResult result) {
 
         UserTO userTO = UserTO.class.cast(subjectTO);
@@ -98,7 +96,7 @@ public class UserSyncResultHandler extends AbstractSubjectSyncResultHandler {
     }
 
     @Override
-    protected AbstractSubjectTO link(
+    protected AbstractSubjectTO doLink(
             final AbstractSubjectTO before,
             final SyncResult result,
             final boolean unlink)
@@ -117,7 +115,7 @@ public class UserSyncResultHandler extends AbstractSubjectSyncResultHandler {
     }
 
     @Override
-    protected AbstractSubjectTO update(
+    protected AbstractSubjectTO doUpdate(
             final AbstractSubjectTO before,
             final AbstractSubjectMod subjectMod,
             final SyncDelta delta,
@@ -174,7 +172,7 @@ public class UserSyncResultHandler extends AbstractSubjectSyncResultHandler {
     }
 
     @Override
-    protected void deprovision(
+    protected void doDeprovision(
             final Long id,
             final boolean unlink) {
 
@@ -189,7 +187,7 @@ public class UserSyncResultHandler extends AbstractSubjectSyncResultHandler {
     }
 
     @Override
-    protected void delete(final Long id) {
+    protected void doDelete(final Long id) {
         try {
             taskExecutor.execute(
                     propagationManager.getUserDeleteTaskIds(id, profile.getSyncTask().getResource().getName()));

http://git-wip-us.apache.org/repos/asf/syncope/blob/857f02a0/core/src/test/java/org/apache/syncope/core/rest/AuthenticationTestITCase.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/syncope/core/rest/AuthenticationTestITCase.java b/core/src/test/java/org/apache/syncope/core/rest/AuthenticationTestITCase.java
index c24fa69..01e5520 100644
--- a/core/src/test/java/org/apache/syncope/core/rest/AuthenticationTestITCase.java
+++ b/core/src/test/java/org/apache/syncope/core/rest/AuthenticationTestITCase.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.core.rest;
 
-import static org.apache.syncope.core.rest.AbstractTest.userService;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;

http://git-wip-us.apache.org/repos/asf/syncope/blob/857f02a0/core/src/test/java/org/apache/syncope/core/rest/ResourceTestITCase.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/syncope/core/rest/ResourceTestITCase.java b/core/src/test/java/org/apache/syncope/core/rest/ResourceTestITCase.java
index de4435b..afc05e4 100644
--- a/core/src/test/java/org/apache/syncope/core/rest/ResourceTestITCase.java
+++ b/core/src/test/java/org/apache/syncope/core/rest/ResourceTestITCase.java
@@ -299,8 +299,9 @@ public class ResourceTestITCase extends AbstractTest {
         try {
             ResourceTO resourceTO = new ResourceTO();
             resourceTO.setName("resourcenotfound");
-
             resourceService.update(resourceTO.getName(), resourceTO);
+
+            fail();
         } catch (SyncopeClientException e) {
             assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
         }
@@ -357,6 +358,7 @@ public class ResourceTestITCase extends AbstractTest {
     public void deleteWithException() {
         try {
             resourceService.delete("resourcenotfound");
+            fail();
         } catch (SyncopeClientException e) {
             assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
         }
@@ -390,6 +392,7 @@ public class ResourceTestITCase extends AbstractTest {
 
         try {
             resourceService.read(resourceName);
+            fail();
         } catch (SyncopeClientException e) {
             assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/857f02a0/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java b/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java
index ecbebd9..5823f9b 100644
--- a/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java
+++ b/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java
@@ -382,8 +382,7 @@ public class TaskTestITCase extends AbstractTest {
             assertEquals(1, userTO.getMemberships().size());
             assertTrue(userTO.getMemberships().get(0).getAttrMap().containsKey("subscriptionDate"));
 
-            // Unmatching --> Assign (link)
-            // SYNCOPE-658
+            // Unmatching --> Assign (link) - SYNCOPE-658
             assertTrue(userTO.getResources().contains(RESOURCE_NAME_CSV));
             int counter = 0;
             for (AttributeTO attributeTO : userTO.getDerAttrs()) {
@@ -397,10 +396,18 @@ public class TaskTestITCase extends AbstractTest {
             assertNotNull(userTO);
             assertEquals("TYPE_8", userTO.getAttrMap().get("type").getValues().get(0));
 
+            // Check for ignored user - SYNCOPE-663
+            try {
+                readUser("test2");
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+            }
+
             // check for sync results
             int usersPost = userService.list(1, 1).getTotalCount();
             assertNotNull(usersPost);
-            assertEquals(usersPre + 9, usersPost);
+            assertEquals(usersPre + 8, usersPost);
 
             // Check for issue 215:
             // * expected disabled user test1

http://git-wip-us.apache.org/repos/asf/syncope/blob/857f02a0/core/src/test/java/org/apache/syncope/core/sync/TestSyncActions.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/syncope/core/sync/TestSyncActions.java b/core/src/test/java/org/apache/syncope/core/sync/TestSyncActions.java
index 75ea2a4..610d9e9 100644
--- a/core/src/test/java/org/apache/syncope/core/sync/TestSyncActions.java
+++ b/core/src/test/java/org/apache/syncope/core/sync/TestSyncActions.java
@@ -22,6 +22,7 @@ import org.apache.syncope.common.mod.AbstractAttributableMod;
 import org.apache.syncope.common.mod.AttributeMod;
 import org.apache.syncope.common.to.AbstractAttributableTO;
 import org.apache.syncope.common.to.AttributeTO;
+import org.apache.syncope.common.to.UserTO;
 import org.identityconnectors.framework.common.objects.SyncDelta;
 import org.quartz.JobExecutionException;
 
@@ -31,9 +32,7 @@ public class TestSyncActions extends DefaultSyncActions {
 
     @Override
     public <T extends AbstractAttributableTO> SyncDelta beforeProvision(
-            final SyncProfile<?, ?> profile,
-            final SyncDelta delta,
-            final T subject) throws JobExecutionException {
+            final SyncProfile<?, ?> profile, final SyncDelta delta, final T subject) throws JobExecutionException {
 
         AttributeTO attrTO = null;
         for (int i = 0; i < subject.getAttrs().size(); i++) {
@@ -53,6 +52,17 @@ public class TestSyncActions extends DefaultSyncActions {
     }
 
     @Override
+    public <T extends AbstractAttributableTO> SyncDelta beforeAssign(
+            final SyncProfile<?, ?> profile, final SyncDelta delta, final T subject) throws JobExecutionException {
+
+        if (subject instanceof UserTO && "test2".equals(UserTO.class.cast(subject).getUsername())) {
+            throw new IgnoreProvisionException();
+        }
+
+        return delta;
+    }
+
+    @Override
     public <T extends AbstractAttributableTO, K extends AbstractAttributableMod> SyncDelta beforeUpdate(
             final SyncProfile<?, ?> profile,
             final SyncDelta delta,