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/05/06 12:04:21 UTC

syncope git commit: [SYNCOPE-650] onError() methods added

Repository: syncope
Updated Branches:
  refs/heads/master 62193429f -> e080c7306


[SYNCOPE-650] onError() methods added


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

Branch: refs/heads/master
Commit: e080c73064c69c3e04240f2eed3efdde5ac17ecd
Parents: 6219342
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed May 6 12:04:14 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed May 6 12:04:14 2015 +0200

----------------------------------------------------------------------
 .../api/propagation/PropagationActions.java     |  2 +
 .../core/provisioning/api/sync/PushActions.java | 73 ++++++++++++--------
 .../core/provisioning/api/sync/SyncActions.java | 16 +++++
 .../AbstractPropagationTaskExecutor.java        | 12 ++--
 .../propagation/DefaultPropagationActions.java  |  7 ++
 .../java/sync/AbstractPushResultHandler.java    |  5 ++
 .../java/sync/AbstractSyncResultHandler.java    | 63 +++++++++++++----
 .../java/sync/DefaultPushActions.java           | 12 ++++
 .../java/sync/DefaultSyncActions.java           |  6 ++
 9 files changed, 149 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/e080c730/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationActions.java
index 864ec4b..cb6d643 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationActions.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationActions.java
@@ -26,5 +26,7 @@ public interface PropagationActions {
 
     void before(PropagationTask task, ConnectorObject beforeObj);
 
+    void onError(PropagationTask task, TaskExec execution, Exception error);
+
     void after(PropagationTask task, TaskExec execution, ConnectorObject afterObj);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e080c730/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
index 6dacc76..f66acde 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
@@ -31,109 +31,124 @@ public interface PushActions extends ProvisioningActions {
     /**
      * Action to be executed before to assign (link & provision) a synchronized user / group to the resource.
      *
-     * @param profile profile of the synchronization being executed.
+     * @param profile profile of the push being executed.
      * @param subject user / group to be created.
      * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
     <T extends Subject<?, ?, ?>> T beforeAssign(
-            final ProvisioningProfile<?, ?> profile,
-            final T subject) throws JobExecutionException;
+            ProvisioningProfile<?, ?> profile,
+            T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before to provision a synchronized user / group to the resource.
      *
-     * @param profile profile of the synchronization being executed.
+     * @param profile profile of the push being executed.
      * @param subject user / group to be created.
      * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
     <T extends Subject<?, ?, ?>> T beforeProvision(
-            final ProvisioningProfile<?, ?> profile,
-            final T subject) throws JobExecutionException;
+            ProvisioningProfile<?, ?> profile,
+            T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before to update a synchronized user / group on the resource.
      *
-     * @param profile profile of the synchronization being executed.
+     * @param profile profile of the push being executed.
      * @param subject user / group to be updated.
      * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
     <T extends Subject<?, ?, ?>> T beforeUpdate(
-            final ProvisioningProfile<?, ?> profile,
-            final T subject) throws JobExecutionException;
+            ProvisioningProfile<?, ?> profile,
+            T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before to link a synchronized user / group to the resource.
      *
-     * @param profile profile of the synchronization being executed.
+     * @param profile profile of the push being executed.
      * @param subject user / group to be created.
      * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
     <T extends Subject<?, ?, ?>> T beforeLink(
-            final ProvisioningProfile<?, ?> profile,
-            final T subject) throws JobExecutionException;
+            ProvisioningProfile<?, ?> profile,
+            T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before to unlink a synchronized user / group from the resource.
      *
-     * @param profile profile of the synchronization being executed.
+     * @param profile profile of the push being executed.
      * @param subject user / group to be created.
      * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
     <T extends Subject<?, ?, ?>> T beforeUnlink(
-            final ProvisioningProfile<?, ?> profile,
-            final T subject) throws JobExecutionException;
+            ProvisioningProfile<?, ?> profile,
+            T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before to unassign a synchronized user / group from the resource.
      *
-     * @param profile profile of the synchronization being executed.
+     * @param profile profile of the push being executed.
      * @param subject user / group to be created.
      * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
     <T extends Subject<?, ?, ?>> T beforeUnassign(
-            final ProvisioningProfile<?, ?> profile,
-            final T subject) throws JobExecutionException;
+            ProvisioningProfile<?, ?> profile,
+            T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before to unassign a synchronized user / group from the resource.
      *
-     * @param profile profile of the synchronization being executed.
+     * @param profile profile of the push being executed.
      * @param subject user / group to be created.
      * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
     <T extends Subject<?, ?, ?>> T beforeDeprovision(
-            final ProvisioningProfile<?, ?> profile,
-            final T subject) throws JobExecutionException;
+            ProvisioningProfile<?, ?> profile,
+            T subject) throws JobExecutionException;
 
     /**
      * Action to be executed before delete a synchronized user / group locally and from the resource.
      *
-     * @param profile profile of the synchronization being executed.
+     * @param profile profile of the push being executed.
      * @param subject user / group to be created.
      * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
     <T extends Subject<?, ?, ?>> T beforeDelete(
-            final ProvisioningProfile<?, ?> profile,
-            final T subject) throws JobExecutionException;
+            ProvisioningProfile<?, ?> profile,
+            T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed after each local user / group synchronization.
+     * Action to be executed after user / group push goes on error.
      *
-     * @param profile profile of the synchronization being executed.
+     * @param profile profile of the push being executed.
+     * @param subject synchronized user / group.
+     * @param result operation result.
+     * @param error error being reported
+     * @throws JobExecutionException in case of generic failure
+     */
+    <T extends Subject<?, ?, ?>> void onError(
+            ProvisioningProfile<?, ?> profile,
+            T subject,
+            ProvisioningResult result,
+            Exception error) throws JobExecutionException;
+
+    /**
+     * Action to be executed after each local user / group push.
+     *
+     * @param profile profile of the push being executed.
      * @param subject synchronized user / group.
      * @param result operation result.
      * @throws JobExecutionException in case of generic failure
      */
     <T extends Subject<?, ?, ?>> void after(
-            final ProvisioningProfile<?, ?> profile,
-            final T subject,
-            final ProvisioningResult result) throws JobExecutionException;
+            ProvisioningProfile<?, ?> profile,
+            T subject,
+            ProvisioningResult result) throws JobExecutionException;
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e080c730/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
index b62a9a9..ba577de 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
@@ -161,6 +161,22 @@ public interface SyncActions extends ProvisioningActions {
             T subject) throws JobExecutionException;
 
     /**
+     * Action to be executed when user / group synchronization goes on error.
+     *
+     * @param profile profile of the synchronization being executed.
+     * @param delta retrieved synchronization information (may be modified by
+     * 'beforeProvision/beforeUpdate/beforeDelete')
+     * @param result global synchronization results at the current synchronization step
+     * @param error error being reported
+     * @throws JobExecutionException in case of generic failure
+     */
+    void onError(
+            ProvisioningProfile<?, ?> profile,
+            SyncDelta delta,
+            ProvisioningResult result,
+            Exception error) throws JobExecutionException;
+
+    /**
      * Action to be executed after each local user / group synchronization.
      *
      * @param profile profile of the synchronization being executed.

http://git-wip-us.apache.org/repos/asf/syncope/blob/e080c730/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
index 73c0572..3856324 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
@@ -342,6 +342,10 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
                     ? PropagationTaskExecStatus.SUCCESS.name()
                     : PropagationTaskExecStatus.SUBMITTED.name());
 
+            for (PropagationActions action : actions) {
+                action.after(task, execution, afterObj);
+            }
+
             LOG.debug("Successfully propagated to {}", task.getResource());
             result = Result.SUCCESS;
         } catch (Exception e) {
@@ -373,6 +377,10 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
             }
 
             propagationAttempted.add(task.getPropagationOperation().name().toLowerCase());
+
+            for (PropagationActions action : actions) {
+                action.onError(task, execution, e);
+            }
         } finally {
             // Try to read remote object (user / group) AFTER any actual operation
             if (connector != null) {
@@ -416,10 +424,6 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
             }
         }
 
-        for (PropagationActions action : actions) {
-            action.after(task, execution, afterObj);
-        }
-
         notificationManager.createTasks(
                 AuditElements.EventCategoryType.PROPAGATION,
                 task.getSubjectType().name().toLowerCase(),

http://git-wip-us.apache.org/repos/asf/syncope/blob/e080c730/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationActions.java
index 379326d..23726ed 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationActions.java
@@ -30,9 +30,16 @@ public abstract class DefaultPropagationActions implements PropagationActions {
 
     @Override
     public void before(final PropagationTask task, final ConnectorObject beforeObj) {
+        // do nothing
+    }
+
+    @Override
+    public void onError(final PropagationTask task, final TaskExec execution, final Exception error) {
+        // do nothing
     }
 
     @Override
     public void after(final PropagationTask task, final TaskExec execution, final ConnectorObject afterObj) {
+        // do nothing
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e080c730/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
index 226cedf..5a63f8e 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
@@ -271,6 +271,11 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
                 output = e;
 
                 LOG.warn("Error pushing {} towards {}", subject, profile.getTask().getResource(), e);
+
+                for (PushActions action : profile.getActions()) {
+                    action.onError(this.getProfile(), subject, result, e);
+                }
+
                 throw new JobExecutionException(e);
             } finally {
                 notificationManager.createTasks(AuditElements.EventCategoryType.PUSH,

http://git-wip-us.apache.org/repos/asf/syncope/blob/e080c730/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
index d57f9ac..b3a73df 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
@@ -185,20 +185,28 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
             for (SyncActions action : profile.getActions()) {
                 action.after(this.getProfile(), delta, actual, result);
             }
+        } catch (IgnoreProvisionException e) {
+            throw e;
         } catch (PropagationException e) {
             // A propagation failure doesn't imply a synchronization failure.
             // The propagation exception status will be reported into the propagation task execution.
             LOG.error("Could not propagate {} {}", attrUtils.getType(), delta.getUid().getUidValue(), e);
             output = e;
             resultStatus = Result.FAILURE;
-        } catch (IgnoreProvisionException e) {
-            throw e;
+
+            for (SyncActions action : profile.getActions()) {
+                action.onError(this.getProfile(), delta, result, e);
+            }
         } catch (Exception e) {
             result.setStatus(ProvisioningResult.Status.FAILURE);
             result.setMessage(ExceptionUtils.getRootCauseMessage(e));
             LOG.error("Could not create {} {} ", attrUtils.getType(), delta.getUid().getUidValue(), e);
             output = e;
             resultStatus = Result.FAILURE;
+
+            for (SyncActions action : profile.getActions()) {
+                action.onError(this.getProfile(), delta, result, e);
+            }
         }
 
         audit(operation, resultStatus, null, output, delta);
@@ -262,22 +270,30 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                         resultStatus = Result.SUCCESS;
                         result.setName(getName(updated));
                         LOG.debug("{} {} successfully updated", attrUtils.getType(), key);
+                    } catch (IgnoreProvisionException e) {
+                        throw e;
                     } catch (PropagationException e) {
                         // A propagation failure doesn't imply a synchronization failure.
                         // The propagation exception status will be reported into the propagation task execution.
-                        LOG.error("Could not propagate {} {}", 
+                        LOG.error("Could not propagate {} {}",
                                 attrUtils.getType(), workingDelta.getUid().getUidValue(), e);
                         output = e;
                         resultStatus = Result.FAILURE;
-                    } catch (IgnoreProvisionException e) {
-                        throw e;
+
+                        for (SyncActions action : profile.getActions()) {
+                            action.onError(this.getProfile(), workingDelta, result, e);
+                        }
                     } catch (Exception e) {
                         result.setStatus(ProvisioningResult.Status.FAILURE);
                         result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                        LOG.error("Could not update {} {}", 
+                        LOG.error("Could not update {} {}",
                                 attrUtils.getType(), workingDelta.getUid().getUidValue(), e);
                         output = e;
                         resultStatus = Result.FAILURE;
+
+                        for (SyncActions action : profile.getActions()) {
+                            action.onError(this.getProfile(), workingDelta, result, e);
+                        }
                     }
                 }
                 audit(MatchingRule.toEventName(MatchingRule.UPDATE), resultStatus, before, output, workingDelta);
@@ -349,20 +365,28 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
 
                         resultStatus = Result.SUCCESS;
                         LOG.debug("{} {} successfully updated", attrUtils.getType(), id);
+                    } catch (IgnoreProvisionException e) {
+                        throw e;
                     } catch (PropagationException e) {
                         // A propagation failure doesn't imply a synchronization failure.
                         // The propagation exception status will be reported into the propagation task execution.
                         LOG.error("Could not propagate {} {}", attrUtils.getType(), delta.getUid().getUidValue(), e);
                         output = e;
                         resultStatus = Result.FAILURE;
-                    } catch (IgnoreProvisionException e) {
-                        throw e;
+
+                        for (SyncActions action : profile.getActions()) {
+                            action.onError(this.getProfile(), delta, result, e);
+                        }
                     } catch (Exception e) {
                         result.setStatus(ProvisioningResult.Status.FAILURE);
                         result.setMessage(ExceptionUtils.getRootCauseMessage(e));
                         LOG.error("Could not update {} {}", attrUtils.getType(), delta.getUid().getUidValue(), e);
                         output = e;
                         resultStatus = Result.FAILURE;
+
+                        for (SyncActions action : profile.getActions()) {
+                            action.onError(this.getProfile(), delta, result, e);
+                        }
                     }
                 }
                 audit(unlink
@@ -436,20 +460,28 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
 
                         resultStatus = Result.SUCCESS;
                         LOG.debug("{} {} successfully updated", attrUtils.getType(), id);
+                    } catch (IgnoreProvisionException e) {
+                        throw e;
                     } catch (PropagationException e) {
                         // A propagation failure doesn't imply a synchronization failure.
                         // The propagation exception status will be reported into the propagation task execution.
                         LOG.error("Could not propagate {} {}", attrUtils.getType(), delta.getUid().getUidValue(), e);
                         output = e;
                         resultStatus = Result.FAILURE;
-                    } catch (IgnoreProvisionException e) {
-                        throw e;
+
+                        for (SyncActions action : profile.getActions()) {
+                            action.onError(this.getProfile(), delta, result, e);
+                        }
                     } catch (Exception e) {
                         result.setStatus(ProvisioningResult.Status.FAILURE);
                         result.setMessage(ExceptionUtils.getRootCauseMessage(e));
                         LOG.error("Could not update {} {}", attrUtils.getType(), delta.getUid().getUidValue(), e);
                         output = e;
                         resultStatus = Result.FAILURE;
+
+                        for (SyncActions action : profile.getActions()) {
+                            action.onError(this.getProfile(), delta, result, e);
+                        }
                     }
                 }
                 audit(unlink ? MatchingRule.toEventName(MatchingRule.UNLINK)
@@ -500,6 +532,10 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                         doDelete(id);
                         output = null;
                         resultStatus = Result.SUCCESS;
+
+                        for (SyncActions action : profile.getActions()) {
+                            action.after(this.getProfile(), workingDelta, before, result);
+                        }
                     } catch (IgnoreProvisionException e) {
                         throw e;
                     } catch (Exception e) {
@@ -507,17 +543,16 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                         result.setMessage(ExceptionUtils.getRootCauseMessage(e));
                         LOG.error("Could not delete {} {}", attrUtils.getType(), id, e);
                         output = e;
-                    }
 
-                    for (SyncActions action : profile.getActions()) {
-                        action.after(this.getProfile(), workingDelta, before, result);
+                        for (SyncActions action : profile.getActions()) {
+                            action.onError(this.getProfile(), workingDelta, result, e);
+                        }
                     }
 
                     audit(ResourceOperation.DELETE.name().toLowerCase(), resultStatus, before, output, workingDelta);
                 }
 
                 delResults.add(result);
-
             } catch (NotFoundException e) {
                 LOG.error("Could not find {} {}", attrUtils.getType(), id, e);
             } catch (UnauthorizedException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/e080c730/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java
index 4517f78..fa5f843 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java
@@ -76,13 +76,25 @@ public abstract class DefaultPushActions implements PushActions {
     }
 
     @Override
+    public <T extends Subject<?, ?, ?>> void onError(
+            final ProvisioningProfile<?, ?> profile, final T subject, final ProvisioningResult result,
+            final Exception error) throws JobExecutionException {
+
+        // do nothing
+    }
+
+    @Override
     public <T extends Subject<?, ?, ?>> void after(
             final ProvisioningProfile<?, ?> profile, final T subject, final ProvisioningResult result)
             throws JobExecutionException {
+
+        // do nothing
     }
 
     @Override
     public void afterAll(final ProvisioningProfile<?, ?> profile)
             throws JobExecutionException {
+
+        // do nothing
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e080c730/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java
index e29847d..8f3432a 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java
@@ -102,6 +102,12 @@ public abstract class DefaultSyncActions implements SyncActions {
     }
 
     @Override
+    public void onError(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final ProvisioningResult result,
+            final Exception error) throws JobExecutionException {
+    }
+
+    @Override
     public <T extends AbstractSubjectTO> void after(
             final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject,
             final ProvisioningResult result)