This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/master by this push:
     new 77d1e9f2e8 [SYNCOPE-1674] Optimizing User, Group and Any Object 
lifecycle event publishing
77d1e9f2e8 is described below

commit 77d1e9f2e84cadbec0173f9a2bc23dc59159aa40
Author: Francesco Chicchiriccò <[email protected]>
AuthorDate: Sat May 7 17:21:14 2022 +0200

    [SYNCOPE-1674] Optimizing User, Group and Any Object lifecycle event 
publishing
---
 .../persistence/jpa/JPAJSONPersistenceContext.java |  6 +-
 .../persistence/jpa/dao/JPAJSONAnyObjectDAO.java   |  8 +--
 .../core/persistence/jpa/dao/JPAJSONUserDAO.java   |  7 ---
 .../core/persistence/jpa/PersistenceContext.java   |  4 --
 .../core/persistence/jpa/dao/AbstractAnyDAO.java   |  5 --
 .../core/persistence/jpa/dao/JPAAnyObjectDAO.java  |  9 +--
 .../core/persistence/jpa/dao/JPADynRealmDAO.java   |  9 ++-
 .../core/persistence/jpa/dao/JPAGroupDAO.java      | 42 ++++++++------
 .../core/persistence/jpa/dao/JPARoleDAO.java       | 11 ++--
 .../core/persistence/jpa/dao/JPAUserDAO.java       | 10 +---
 .../provisioning/api/event/AnyDeletedEvent.java    | 65 ----------------------
 ...tedUpdatedEvent.java => AnyLifecycleEvent.java} | 14 ++++-
 .../java/DefaultAnyObjectWorkflowAdapter.java      | 21 ++++++-
 .../workflow/java/DefaultGroupWorkflowAdapter.java | 21 ++++++-
 .../workflow/java/DefaultUserWorkflowAdapter.java  | 34 ++++++++++-
 .../core/workflow/java/WorkflowContext.java        | 16 ++++--
 .../client/ElasticsearchIndexManager.java          | 52 +++++++++--------
 .../core/flowable/FlowableWorkflowContext.java     | 21 ++++---
 .../core/flowable/api/UserRequestHandler.java      |  5 +-
 .../flowable/impl/FlowableUserRequestHandler.java  | 18 +++---
 .../flowable/impl/FlowableUserWorkflowAdapter.java | 48 ++++++++++++++--
 fit/core-reference/pom.xml                         |  1 +
 22 files changed, 228 insertions(+), 199 deletions(-)

diff --git 
a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/JPAJSONPersistenceContext.java
 
b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/JPAJSONPersistenceContext.java
index 8a3312a8c6..3e1c072536 100644
--- 
a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/JPAJSONPersistenceContext.java
+++ 
b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/JPAJSONPersistenceContext.java
@@ -51,9 +51,6 @@ import org.springframework.context.annotation.Lazy;
 @Configuration(proxyBeanMethods = false)
 public abstract class JPAJSONPersistenceContext {
 
-    @Autowired
-    protected ApplicationEventPublisher publisher;
-
     @Autowired
     protected SecurityProperties securityProperties;
 
@@ -70,7 +67,6 @@ public abstract class JPAJSONPersistenceContext {
 
         return new JPAJSONAnyObjectDAO(
                 anyUtilsFactory,
-                publisher,
                 plainSchemaDAO,
                 derSchemaDAO,
                 dynRealmDAO,
@@ -83,6 +79,7 @@ public abstract class JPAJSONPersistenceContext {
     @Bean
     public GroupDAO groupDAO(
             final AnyUtilsFactory anyUtilsFactory,
+            final ApplicationEventPublisher publisher,
             final @Lazy PlainSchemaDAO plainSchemaDAO,
             final @Lazy DerSchemaDAO derSchemaDAO,
             final @Lazy DynRealmDAO dynRealmDAO,
@@ -137,7 +134,6 @@ public abstract class JPAJSONPersistenceContext {
 
         return new JPAJSONUserDAO(
                 anyUtilsFactory,
-                publisher,
                 plainSchemaDAO,
                 derSchemaDAO,
                 dynRealmDAO,
diff --git 
a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONAnyObjectDAO.java
 
b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONAnyObjectDAO.java
index 3850731365..f4397ded86 100644
--- 
a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONAnyObjectDAO.java
+++ 
b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONAnyObjectDAO.java
@@ -35,9 +35,6 @@ import 
org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.apache.syncope.core.provisioning.api.event.AnyCreatedUpdatedEvent;
-import org.apache.syncope.core.spring.security.AuthContextUtils;
-import org.springframework.context.ApplicationEventPublisher;
 
 public class JPAJSONAnyObjectDAO extends JPAAnyObjectDAO {
 
@@ -45,7 +42,6 @@ public class JPAJSONAnyObjectDAO extends JPAAnyObjectDAO {
 
     public JPAJSONAnyObjectDAO(
             final AnyUtilsFactory anyUtilsFactory,
-            final ApplicationEventPublisher publisher,
             final PlainSchemaDAO plainSchemaDAO,
             final DerSchemaDAO derSchemaDAO,
             final DynRealmDAO dynRealmDAO,
@@ -53,7 +49,7 @@ public class JPAJSONAnyObjectDAO extends JPAAnyObjectDAO {
             final GroupDAO groupDAO,
             final JPAJSONAnyDAO anyDAO) {
 
-        super(anyUtilsFactory, publisher, plainSchemaDAO, derSchemaDAO, 
dynRealmDAO, userDAO, groupDAO);
+        super(anyUtilsFactory, plainSchemaDAO, derSchemaDAO, dynRealmDAO, 
userDAO, groupDAO);
         this.anyDAO = anyDAO;
     }
 
@@ -93,8 +89,6 @@ public class JPAJSONAnyObjectDAO extends JPAAnyObjectDAO {
         // ensure that entity listeners are invoked at this point
         entityManager().flush();
 
-        publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, merged, 
AuthContextUtils.getDomain()));
-
         Pair<Set<String>, Set<String>> dynGroupMembs = 
groupDAO.refreshDynMemberships(merged);
         dynRealmDAO.refreshDynMemberships(merged);
 
diff --git 
a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONUserDAO.java
 
b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONUserDAO.java
index 09c4e8e51e..91b7a511b8 100644
--- 
a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONUserDAO.java
+++ 
b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONUserDAO.java
@@ -40,10 +40,7 @@ import 
org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
-import org.apache.syncope.core.provisioning.api.event.AnyCreatedUpdatedEvent;
-import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.spring.security.SecurityProperties;
-import org.springframework.context.ApplicationEventPublisher;
 
 public class JPAJSONUserDAO extends JPAUserDAO {
 
@@ -51,7 +48,6 @@ public class JPAJSONUserDAO extends JPAUserDAO {
 
     public JPAJSONUserDAO(
             final AnyUtilsFactory anyUtilsFactory,
-            final ApplicationEventPublisher publisher,
             final PlainSchemaDAO plainSchemaDAO,
             final DerSchemaDAO derSchemaDAO,
             final DynRealmDAO dynRealmDAO,
@@ -64,7 +60,6 @@ public class JPAJSONUserDAO extends JPAUserDAO {
             final JPAJSONAnyDAO anyDAO) {
 
         super(anyUtilsFactory,
-                publisher,
                 plainSchemaDAO,
                 derSchemaDAO,
                 dynRealmDAO,
@@ -129,8 +124,6 @@ public class JPAJSONUserDAO extends JPAUserDAO {
         // ensure that entity listeners are invoked at this point
         entityManager().flush();
 
-        publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, merged, 
AuthContextUtils.getDomain()));
-
         roleDAO.refreshDynMemberships(merged);
         Pair<Set<String>, Set<String>> dynGroupMembs = 
groupDAO.refreshDynMemberships(merged);
         dynRealmDAO.refreshDynMemberships(merged);
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java
index c38af10a13..204f954c44 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java
@@ -325,7 +325,6 @@ public class PersistenceContext {
     @ConditionalOnMissingBean
     @Bean
     public AnyObjectDAO anyObjectDAO(
-            final ApplicationEventPublisher publisher,
             final AnyUtilsFactory anyUtilsFactory,
             final @Lazy PlainSchemaDAO plainSchemaDAO,
             final @Lazy DerSchemaDAO derSchemaDAO,
@@ -335,7 +334,6 @@ public class PersistenceContext {
 
         return new JPAAnyObjectDAO(
                 anyUtilsFactory,
-                publisher,
                 plainSchemaDAO,
                 derSchemaDAO,
                 dynRealmDAO,
@@ -651,7 +649,6 @@ public class PersistenceContext {
     @ConditionalOnMissingBean
     @Bean
     public UserDAO userDAO(
-            final ApplicationEventPublisher publisher,
             final SecurityProperties securityProperties,
             final AnyUtilsFactory anyUtilsFactory,
             final @Lazy PlainSchemaDAO plainSchemaDAO,
@@ -665,7 +662,6 @@ public class PersistenceContext {
 
         return new JPAUserDAO(
                 anyUtilsFactory,
-                publisher,
                 plainSchemaDAO,
                 derSchemaDAO,
                 dynRealmDAO,
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
index e706221ec3..564c6fe5f5 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
@@ -64,7 +64,6 @@ import 
org.apache.syncope.core.persistence.api.entity.group.Group;
 import 
org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
-import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -72,8 +71,6 @@ public abstract class AbstractAnyDAO<A extends Any<?>> 
extends AbstractDAO<A> im
 
     protected final AnyUtilsFactory anyUtilsFactory;
 
-    protected final ApplicationEventPublisher publisher;
-
     protected final PlainSchemaDAO plainSchemaDAO;
 
     protected final DerSchemaDAO derSchemaDAO;
@@ -84,13 +81,11 @@ public abstract class AbstractAnyDAO<A extends Any<?>> 
extends AbstractDAO<A> im
 
     public AbstractAnyDAO(
             final AnyUtilsFactory anyUtilsFactory,
-            final ApplicationEventPublisher publisher,
             final PlainSchemaDAO plainSchemaDAO,
             final DerSchemaDAO derSchemaDAO,
             final DynRealmDAO dynRealmDAO) {
 
         this.anyUtilsFactory = anyUtilsFactory;
-        this.publisher = publisher;
         this.plainSchemaDAO = plainSchemaDAO;
         this.derSchemaDAO = derSchemaDAO;
         this.dynRealmDAO = dynRealmDAO;
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
index 1992493740..a49bd837d1 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -61,10 +61,7 @@ import 
org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAMembership;
 import 
org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAARelationship;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAURelationship;
-import org.apache.syncope.core.provisioning.api.event.AnyCreatedUpdatedEvent;
-import org.apache.syncope.core.provisioning.api.event.AnyDeletedEvent;
 import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
-import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -76,14 +73,13 @@ public class JPAAnyObjectDAO extends 
AbstractAnyDAO<AnyObject> implements AnyObj
 
     public JPAAnyObjectDAO(
             final AnyUtilsFactory anyUtilsFactory,
-            final ApplicationEventPublisher publisher,
             final PlainSchemaDAO plainSchemaDAO,
             final DerSchemaDAO derSchemaDAO,
             final DynRealmDAO dynRealmDAO,
             final UserDAO userDAO,
             final GroupDAO groupDAO) {
 
-        super(anyUtilsFactory, publisher, plainSchemaDAO, derSchemaDAO, 
dynRealmDAO);
+        super(anyUtilsFactory, plainSchemaDAO, derSchemaDAO, dynRealmDAO);
         this.userDAO = userDAO;
         this.groupDAO = groupDAO;
     }
@@ -236,7 +232,6 @@ public class JPAAnyObjectDAO extends 
AbstractAnyDAO<AnyObject> implements AnyObj
 
     protected Pair<AnyObject, Pair<Set<String>, Set<String>>> doSave(final 
AnyObject anyObject) {
         AnyObject merged = super.save(anyObject);
-        publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, merged, 
AuthContextUtils.getDomain()));
 
         Pair<Set<String>, Set<String>> dynGroupMembs = 
groupDAO.refreshDynMemberships(merged);
         dynRealmDAO.refreshDynMemberships(merged);
@@ -291,8 +286,6 @@ public class JPAAnyObjectDAO extends 
AbstractAnyDAO<AnyObject> implements AnyObj
         });
 
         entityManager().remove(anyObject);
-        publisher.publishEvent(new AnyDeletedEvent(
-                this, AnyTypeKind.ANY_OBJECT, anyObject.getKey(), 
anyObject.getName(), AuthContextUtils.getDomain()));
     }
 
     @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADynRealmDAO.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADynRealmDAO.java
index 9978d52045..411711ad54 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADynRealmDAO.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADynRealmDAO.java
@@ -28,7 +28,6 @@ import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.DynRealm;
 import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
 import org.apache.syncope.core.persistence.jpa.entity.JPADynRealm;
-import org.apache.syncope.core.provisioning.api.event.AnyCreatedUpdatedEvent;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.transaction.annotation.Transactional;
@@ -37,6 +36,8 @@ import 
org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
+import org.apache.syncope.core.provisioning.api.event.AnyLifecycleEvent;
+import org.identityconnectors.framework.common.objects.SyncDeltaType;
 
 public class JPADynRealmDAO extends AbstractDAO<DynRealm> implements 
DynRealmDAO {
 
@@ -120,7 +121,8 @@ public class JPADynRealmDAO extends AbstractDAO<DynRealm> 
implements DynRealmDAO
                 any = anyObjectDAO.find(key);
             }
             if (any != null) {
-                publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, any, 
AuthContextUtils.getDomain()));
+                publisher.publishEvent(
+                        new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, 
any, AuthContextUtils.getDomain()));
             }
         });
     }
@@ -141,7 +143,8 @@ public class JPADynRealmDAO extends AbstractDAO<DynRealm> 
implements DynRealmDAO
             insert.setParameter(2, merged.getKey());
             insert.executeUpdate();
 
-            publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, any, 
AuthContextUtils.getDomain()));
+            publisher.publishEvent(
+                    new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, any, 
AuthContextUtils.getDomain()));
             cleared.remove(any.getKey());
         }));
 
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
index b55ba20d81..df071e5a70 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
@@ -66,11 +66,11 @@ import 
org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
 import org.apache.syncope.core.persistence.jpa.entity.group.JPATypeExtension;
 import 
org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMembership;
-import org.apache.syncope.core.provisioning.api.event.AnyCreatedUpdatedEvent;
-import org.apache.syncope.core.provisioning.api.event.AnyDeletedEvent;
+import org.apache.syncope.core.provisioning.api.event.AnyLifecycleEvent;
 import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import 
org.apache.syncope.core.spring.security.DelegatedAdministrationException;
+import org.identityconnectors.framework.common.objects.SyncDeltaType;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -80,6 +80,8 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> 
implements GroupDAO {
 
     public static final String ADYNMEMB_TABLE = "ADynGroupMembers";
 
+    protected final ApplicationEventPublisher publisher;
+
     protected final AnyMatchDAO anyMatchDAO;
 
     protected final PlainAttrDAO plainAttrDAO;
@@ -105,7 +107,8 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> 
implements GroupDAO {
             final AnySearchDAO searchDAO,
             final SearchCondVisitor searchCondVisitor) {
 
-        super(anyUtilsFactory, publisher, plainSchemaDAO, derSchemaDAO, 
dynRealmDAO);
+        super(anyUtilsFactory, plainSchemaDAO, derSchemaDAO, dynRealmDAO);
+        this.publisher = publisher;
         this.anyMatchDAO = anyMatchDAO;
         this.plainAttrDAO = plainAttrDAO;
         this.userDAO = userDAO;
@@ -289,7 +292,6 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> 
implements GroupDAO {
     @Override
     public Group saveAndRefreshDynMemberships(final Group group) {
         Group merged = save(group);
-        publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, merged, 
AuthContextUtils.getDomain()));
 
         // refresh dynamic memberships
         clearUDynMembers(merged);
@@ -311,7 +313,8 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> 
implements GroupDAO {
                     insert.setParameter(2, merged.getKey());
                     insert.executeUpdate();
 
-                    publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, 
user, AuthContextUtils.getDomain()));
+                    publisher.publishEvent(
+                            new AnyLifecycleEvent<>(this, 
SyncDeltaType.UPDATE, user, AuthContextUtils.getDomain()));
                 });
             }
         }
@@ -328,15 +331,16 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> 
implements GroupDAO {
                         List.of(),
                         AnyTypeKind.ANY_OBJECT);
 
-                matching.forEach(anyObject -> {
+                matching.forEach(any -> {
                     Query insert = entityManager().createNativeQuery(
                             "INSERT INTO " + ADYNMEMB_TABLE + " VALUES(?, ?, 
?)");
-                    insert.setParameter(1, anyObject.getType().getKey());
-                    insert.setParameter(2, anyObject.getKey());
+                    insert.setParameter(1, any.getType().getKey());
+                    insert.setParameter(2, any.getKey());
                     insert.setParameter(3, merged.getKey());
                     insert.executeUpdate();
 
-                    publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, 
anyObject, AuthContextUtils.getDomain()));
+                    publisher.publishEvent(
+                            new AnyLifecycleEvent<>(this, 
SyncDeltaType.UPDATE, any, AuthContextUtils.getDomain()));
                 });
             }
         });
@@ -362,7 +366,8 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> 
implements GroupDAO {
             });
 
             anyObjectDAO.save(leftEnd);
-            publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, leftEnd, 
AuthContextUtils.getDomain()));
+            publisher.publishEvent(
+                    new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, 
leftEnd, AuthContextUtils.getDomain()));
         });
 
         findUMemberships(group).forEach(membership -> {
@@ -378,15 +383,14 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> 
implements GroupDAO {
             });
 
             userDAO.save(leftEnd);
-            publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, leftEnd, 
AuthContextUtils.getDomain()));
+            publisher.publishEvent(
+                    new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, 
leftEnd, AuthContextUtils.getDomain()));
         });
 
         clearUDynMembers(group);
         clearADynMembers(group);
 
         entityManager().remove(group);
-        publisher.publishEvent(new AnyDeletedEvent(
-                this, AnyTypeKind.GROUP, group.getKey(), group.getName(), 
AuthContextUtils.getDomain()));
     }
 
     @Override
@@ -516,7 +520,8 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> 
implements GroupDAO {
                 delete.executeUpdate();
             }
 
-            publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, 
memb.getGroup(), AuthContextUtils.getDomain()));
+            publisher.publishEvent(
+                    new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, 
memb.getGroup(), AuthContextUtils.getDomain()));
         });
 
         return Pair.of(before, after);
@@ -534,7 +539,8 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> 
implements GroupDAO {
         dynGroups.forEach(group -> {
             before.add(group.getKey());
 
-            publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, group, 
AuthContextUtils.getDomain()));
+            publisher.publishEvent(
+                    new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, group, 
AuthContextUtils.getDomain()));
         });
 
         return before;
@@ -614,7 +620,8 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> 
implements GroupDAO {
                 delete.executeUpdate();
             }
 
-            publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, 
memb.getGroup(), AuthContextUtils.getDomain()));
+            publisher.publishEvent(
+                    new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, 
memb.getGroup(), AuthContextUtils.getDomain()));
         });
 
         return Pair.of(before, after);
@@ -632,7 +639,8 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> 
implements GroupDAO {
         dynGroups.forEach(group -> {
             before.add(group.getKey());
 
-            publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, group, 
AuthContextUtils.getDomain()));
+            publisher.publishEvent(
+                    new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, group, 
AuthContextUtils.getDomain()));
         });
 
         return before;
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
index 941929076f..e2e2f11875 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
@@ -35,8 +35,9 @@ import 
org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
 import org.apache.syncope.core.persistence.jpa.entity.JPARole;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
-import org.apache.syncope.core.provisioning.api.event.AnyCreatedUpdatedEvent;
+import org.apache.syncope.core.provisioning.api.event.AnyLifecycleEvent;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.identityconnectors.framework.common.objects.SyncDeltaType;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -120,13 +121,14 @@ public class JPARoleDAO extends AbstractDAO<Role> 
implements RoleDAO {
                     SearchCondConverter.convert(searchCondVisitor, 
merged.getDynMembership().getFIQLCond()),
                     AnyTypeKind.USER);
 
-            matching.forEach((user) -> {
+            matching.forEach(user -> {
                 Query insert = entityManager().createNativeQuery("INSERT INTO 
" + DYNMEMB_TABLE + " VALUES(?, ?)");
                 insert.setParameter(1, user.getKey());
                 insert.setParameter(2, merged.getKey());
                 insert.executeUpdate();
 
-                publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, 
user, AuthContextUtils.getDomain()));
+                publisher.publishEvent(
+                        new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, 
user, AuthContextUtils.getDomain()));
             });
         }
 
@@ -141,7 +143,8 @@ public class JPARoleDAO extends AbstractDAO<Role> 
implements RoleDAO {
 
         query.getResultList().forEach(user -> {
             user.getRoles().remove(role);
-            publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, user, 
AuthContextUtils.getDomain()));
+            publisher.publishEvent(
+                    new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, user, 
AuthContextUtils.getDomain()));
         });
 
         clearDynMembers(role);
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
index 244cc3fcb0..615d6ef051 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
@@ -69,15 +69,12 @@ import 
org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPALinkedAccount;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMembership;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
-import org.apache.syncope.core.provisioning.api.event.AnyCreatedUpdatedEvent;
-import org.apache.syncope.core.provisioning.api.event.AnyDeletedEvent;
 import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
 import org.apache.syncope.core.spring.ImplementationManager;
 import org.apache.syncope.core.spring.policy.AccountPolicyException;
 import org.apache.syncope.core.spring.policy.PasswordPolicyException;
 import org.apache.syncope.core.spring.security.Encryptor;
 import org.apache.syncope.core.spring.security.SecurityProperties;
-import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -97,7 +94,6 @@ public class JPAUserDAO extends AbstractAnyDAO<User> 
implements UserDAO {
 
     public JPAUserDAO(
             final AnyUtilsFactory anyUtilsFactory,
-            final ApplicationEventPublisher publisher,
             final PlainSchemaDAO plainSchemaDAO,
             final DerSchemaDAO derSchemaDAO,
             final DynRealmDAO dynRealmDAO,
@@ -108,7 +104,7 @@ public class JPAUserDAO extends AbstractAnyDAO<User> 
implements UserDAO {
             final DelegationDAO delegationDAO,
             final SecurityProperties securityProperties) {
 
-        super(anyUtilsFactory, publisher, plainSchemaDAO, derSchemaDAO, 
dynRealmDAO);
+        super(anyUtilsFactory, plainSchemaDAO, derSchemaDAO, dynRealmDAO);
         this.roleDAO = roleDAO;
         this.accessTokenDAO = accessTokenDAO;
         this.realmDAO = realmDAO;
@@ -463,8 +459,6 @@ public class JPAUserDAO extends AbstractAnyDAO<User> 
implements UserDAO {
             throw e;
         }
 
-        publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, merged, 
AuthContextUtils.getDomain()));
-
         roleDAO.refreshDynMemberships(merged);
         Pair<Set<String>, Set<String>> dynGroupMembs = 
groupDAO.refreshDynMemberships(merged);
         dynRealmDAO.refreshDynMemberships(merged);
@@ -501,8 +495,6 @@ public class JPAUserDAO extends AbstractAnyDAO<User> 
implements UserDAO {
         }
 
         entityManager().remove(user);
-        publisher.publishEvent(new AnyDeletedEvent(
-                this, AnyTypeKind.USER, user.getKey(), user.getUsername(), 
AuthContextUtils.getDomain()));
     }
 
     @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
diff --git 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/event/AnyDeletedEvent.java
 
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/event/AnyDeletedEvent.java
deleted file mode 100644
index d9f503598a..0000000000
--- 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/event/AnyDeletedEvent.java
+++ /dev/null
@@ -1,65 +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.api.event;
-
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.springframework.context.ApplicationEvent;
-
-public class AnyDeletedEvent extends ApplicationEvent {
-
-    private static final long serialVersionUID = 6389886937942135639L;
-
-    private final AnyTypeKind anyTypeKind;
-
-    private final String anyKey;
-
-    private final String anyName;
-
-    private final String domain;
-
-    public AnyDeletedEvent(
-            final Object source,
-            final AnyTypeKind anyTypeKind,
-            final String anyKey,
-            final String anyName,
-            final String domain) {
-
-        super(source);
-        this.anyTypeKind = anyTypeKind;
-        this.anyKey = anyKey;
-        this.anyName = anyName;
-        this.domain = domain;
-    }
-
-    public AnyTypeKind getAnyTypeKind() {
-        return anyTypeKind;
-    }
-
-    public String getAnyKey() {
-        return anyKey;
-    }
-
-    public String getAnyName() {
-        return anyName;
-    }
-
-    public String getDomain() {
-        return domain;
-    }
-}
diff --git 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/event/AnyCreatedUpdatedEvent.java
 
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/event/AnyLifecycleEvent.java
similarity index 77%
rename from 
core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/event/AnyCreatedUpdatedEvent.java
rename to 
core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/event/AnyLifecycleEvent.java
index 4a2f9a177c..8fbc75f1c3 100644
--- 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/event/AnyCreatedUpdatedEvent.java
+++ 
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/event/AnyLifecycleEvent.java
@@ -19,22 +19,31 @@
 package org.apache.syncope.core.provisioning.api.event;
 
 import org.apache.syncope.core.persistence.api.entity.Any;
+import org.identityconnectors.framework.common.objects.SyncDeltaType;
 import org.springframework.context.ApplicationEvent;
 
-public class AnyCreatedUpdatedEvent<A extends Any<?>> extends ApplicationEvent 
{
+public class AnyLifecycleEvent<A extends Any<?>> extends ApplicationEvent {
 
     private static final long serialVersionUID = -781747175059834365L;
 
+    private final SyncDeltaType type;
+
     private final A any;
 
     private final String domain;
 
-    public AnyCreatedUpdatedEvent(final Object source, final A any, final 
String domain) {
+    public AnyLifecycleEvent(final Object source, final SyncDeltaType type, 
final A any, final String domain) {
         super(source);
+
+        this.type = type;
         this.any = any;
         this.domain = domain;
     }
 
+    public SyncDeltaType getType() {
+        return type;
+    }
+
     public A getAny() {
         return any;
     }
@@ -42,5 +51,4 @@ public class AnyCreatedUpdatedEvent<A extends Any<?>> extends 
ApplicationEvent {
     public String getDomain() {
         return domain;
     }
-
 }
diff --git 
a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultAnyObjectWorkflowAdapter.java
 
b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultAnyObjectWorkflowAdapter.java
index ecb3305c34..dcdba391be 100644
--- 
a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultAnyObjectWorkflowAdapter.java
+++ 
b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultAnyObjectWorkflowAdapter.java
@@ -27,18 +27,26 @@ import 
org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
+import org.apache.syncope.core.provisioning.api.event.AnyLifecycleEvent;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.identityconnectors.framework.common.objects.SyncDeltaType;
+import org.springframework.context.ApplicationEventPublisher;
 
 /**
  * Simple implementation basically not involving any workflow engine.
  */
 public class DefaultAnyObjectWorkflowAdapter extends 
AbstractAnyObjectWorkflowAdapter {
 
+    protected final ApplicationEventPublisher publisher;
+
     public DefaultAnyObjectWorkflowAdapter(
             final AnyObjectDataBinder dataBinder,
             final AnyObjectDAO anyObjectDAO,
-            final EntityFactory entityFactory) {
+            final EntityFactory entityFactory,
+            final ApplicationEventPublisher publisher) {
 
         super(dataBinder, anyObjectDAO, entityFactory);
+        this.publisher = publisher;
     }
 
     @Override
@@ -50,6 +58,9 @@ public class DefaultAnyObjectWorkflowAdapter extends 
AbstractAnyObjectWorkflowAd
         metadata(anyObject, creator, context);
         anyObject = anyObjectDAO.save(anyObject);
 
+        publisher.publishEvent(
+                new AnyLifecycleEvent<>(this, SyncDeltaType.CREATE, anyObject, 
AuthContextUtils.getDomain()));
+
         PropagationByResource<String> propByRes = new 
PropagationByResource<>();
         propByRes.set(ResourceOperation.CREATE, 
anyObjectDAO.findAllResourceKeys(anyObject.getKey()));
 
@@ -62,7 +73,10 @@ public class DefaultAnyObjectWorkflowAdapter extends 
AbstractAnyObjectWorkflowAd
 
         PropagationByResource<String> propByRes = dataBinder.update(anyObject, 
anyObjectUR);
         metadata(anyObject, updater, context);
-        anyObjectDAO.save(anyObject);
+        AnyObject updated = anyObjectDAO.save(anyObject);
+
+        publisher.publishEvent(new AnyLifecycleEvent<>(
+                this, SyncDeltaType.UPDATE, updated, 
AuthContextUtils.getDomain()));
 
         return new WorkflowResult<>(anyObjectUR, propByRes, "update");
     }
@@ -70,5 +84,8 @@ public class DefaultAnyObjectWorkflowAdapter extends 
AbstractAnyObjectWorkflowAd
     @Override
     protected void doDelete(final AnyObject anyObject, final String eraser, 
final String context) {
         anyObjectDAO.delete(anyObject);
+
+        publisher.publishEvent(
+                new AnyLifecycleEvent<>(this, SyncDeltaType.DELETE, anyObject, 
AuthContextUtils.getDomain()));
     }
 }
diff --git 
a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultGroupWorkflowAdapter.java
 
b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultGroupWorkflowAdapter.java
index 1ec0c8b4d5..f35a7ee911 100644
--- 
a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultGroupWorkflowAdapter.java
+++ 
b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultGroupWorkflowAdapter.java
@@ -27,18 +27,26 @@ import 
org.apache.syncope.core.persistence.api.entity.EntityFactory;
 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.data.GroupDataBinder;
+import org.apache.syncope.core.provisioning.api.event.AnyLifecycleEvent;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.identityconnectors.framework.common.objects.SyncDeltaType;
+import org.springframework.context.ApplicationEventPublisher;
 
 /**
  * Simple implementation basically not involving any workflow engine.
  */
 public class DefaultGroupWorkflowAdapter extends AbstractGroupWorkflowAdapter {
 
+    protected final ApplicationEventPublisher publisher;
+
     public DefaultGroupWorkflowAdapter(
             final GroupDataBinder dataBinder,
             final GroupDAO groupDAO,
-            final EntityFactory entityFactory) {
+            final EntityFactory entityFactory,
+            final ApplicationEventPublisher publisher) {
 
         super(dataBinder, groupDAO, entityFactory);
+        this.publisher = publisher;
     }
 
     @Override
@@ -48,6 +56,9 @@ public class DefaultGroupWorkflowAdapter extends 
AbstractGroupWorkflowAdapter {
         metadata(group, creator, context);
         group = groupDAO.saveAndRefreshDynMemberships(group);
 
+        publisher.publishEvent(
+                new AnyLifecycleEvent<>(this, SyncDeltaType.CREATE, group, 
AuthContextUtils.getDomain()));
+
         PropagationByResource<String> propByRes = new 
PropagationByResource<>();
         propByRes.set(ResourceOperation.CREATE, 
groupDAO.findAllResourceKeys(group.getKey()));
 
@@ -60,7 +71,10 @@ public class DefaultGroupWorkflowAdapter extends 
AbstractGroupWorkflowAdapter {
 
         PropagationByResource<String> propByRes = dataBinder.update(group, 
groupUR);
         metadata(group, updater, context);
-        groupDAO.save(group);
+        Group updated = groupDAO.save(group);
+
+        publisher.publishEvent(new AnyLifecycleEvent<>(
+                this, SyncDeltaType.UPDATE, updated, 
AuthContextUtils.getDomain()));
 
         return new WorkflowResult<>(groupUR, propByRes, "update");
     }
@@ -68,5 +82,8 @@ public class DefaultGroupWorkflowAdapter extends 
AbstractGroupWorkflowAdapter {
     @Override
     protected void doDelete(final Group group, final String eraser, final 
String context) {
         groupDAO.delete(group);
+
+        publisher.publishEvent(
+                new AnyLifecycleEvent<>(this, SyncDeltaType.DELETE, group, 
AuthContextUtils.getDomain()));
     }
 }
diff --git 
a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java
 
b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java
index 07e0674953..ebeed5a65c 100644
--- 
a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java
+++ 
b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java
@@ -30,8 +30,11 @@ import 
org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.UserWorkflowResult;
 import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
+import org.springframework.context.ApplicationEventPublisher;
+import org.apache.syncope.core.provisioning.api.event.AnyLifecycleEvent;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.workflow.api.WorkflowException;
+import org.identityconnectors.framework.common.objects.SyncDeltaType;
 
 /**
  * Simple implementation basically not involving any workflow engine.
@@ -40,14 +43,18 @@ public class DefaultUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter {
 
     protected final ConfParamOps confParamOps;
 
+    protected final ApplicationEventPublisher publisher;
+
     public DefaultUserWorkflowAdapter(
             final UserDataBinder dataBinder,
             final UserDAO userDAO,
             final EntityFactory entityFactory,
-            final ConfParamOps confParamOps) {
+            final ConfParamOps confParamOps,
+            final ApplicationEventPublisher publisher) {
 
         super(dataBinder, userDAO, entityFactory);
         this.confParamOps = confParamOps;
+        this.publisher = publisher;
     }
 
     @Override
@@ -83,6 +90,9 @@ public class DefaultUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter {
         user.setStatus(status);
         user = userDAO.save(user);
 
+        publisher.publishEvent(
+                new AnyLifecycleEvent<>(this, SyncDeltaType.CREATE, user, 
AuthContextUtils.getDomain()));
+
         PropagationByResource<String> propByRes = new 
PropagationByResource<>();
         propByRes.set(ResourceOperation.CREATE, 
userDAO.findAllResourceKeys(user.getKey()));
 
@@ -111,6 +121,9 @@ public class DefaultUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter {
         user.setStatus("active");
         User updated = userDAO.save(user);
 
+        publisher.publishEvent(
+                new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, updated, 
AuthContextUtils.getDomain()));
+
         return new UserWorkflowResult<>(updated.getKey(), null, null, 
"activate");
     }
 
@@ -122,7 +135,10 @@ public class DefaultUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter {
                 dataBinder.update(user, userUR);
 
         metadata(user, updater, context);
-        userDAO.save(user);
+        User updated = userDAO.save(user);
+
+        publisher.publishEvent(new AnyLifecycleEvent<>(
+                this, SyncDeltaType.UPDATE, updated, 
AuthContextUtils.getDomain()));
 
         return new UserWorkflowResult<>(
                 Pair.of(userUR, !user.isSuspended()),
@@ -137,6 +153,9 @@ public class DefaultUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter {
         user.setStatus("suspended");
         User updated = userDAO.save(user);
 
+        publisher.publishEvent(
+                new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, updated, 
AuthContextUtils.getDomain()));
+
         return new UserWorkflowResult<>(updated.getKey(), null, null, 
"suspend");
     }
 
@@ -146,6 +165,9 @@ public class DefaultUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter {
         user.setStatus("active");
         User updated = userDAO.save(user);
 
+        publisher.publishEvent(
+                new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, updated, 
AuthContextUtils.getDomain()));
+
         return new UserWorkflowResult<>(updated.getKey(), null, null, 
"reactivate");
     }
 
@@ -155,7 +177,10 @@ public class DefaultUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter {
                 confParamOps.get(AuthContextUtils.getDomain(), "token.length", 
256, Integer.class),
                 confParamOps.get(AuthContextUtils.getDomain(), 
"token.expireTime", 60, Integer.class));
         metadata(user, updater, context);
-        userDAO.save(user);
+        User updated = userDAO.save(user);
+
+        publisher.publishEvent(
+                new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, updated, 
AuthContextUtils.getDomain()));
     }
 
     @Override
@@ -181,5 +206,8 @@ public class DefaultUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter {
     @Override
     protected void doDelete(final User user, final String eraser, final String 
context) {
         userDAO.delete(user);
+
+        publisher.publishEvent(
+                new AnyLifecycleEvent<>(this, SyncDeltaType.DELETE, user, 
AuthContextUtils.getDomain()));
     }
 }
diff --git 
a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/WorkflowContext.java
 
b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/WorkflowContext.java
index f51a0f2578..3ce0018668 100644
--- 
a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/WorkflowContext.java
+++ 
b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/WorkflowContext.java
@@ -30,6 +30,7 @@ import 
org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
 import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
 import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
 import 
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
@@ -42,9 +43,10 @@ public class WorkflowContext {
             final UserDataBinder userDataBinder,
             final UserDAO userDAO,
             final EntityFactory entityFactory,
-            final ConfParamOps confParamOps) {
+            final ConfParamOps confParamOps,
+            final ApplicationEventPublisher publisher) {
 
-        return new DefaultUserWorkflowAdapter(userDataBinder, userDAO, 
entityFactory, confParamOps);
+        return new DefaultUserWorkflowAdapter(userDataBinder, userDAO, 
entityFactory, confParamOps, publisher);
     }
 
     @ConditionalOnMissingBean
@@ -52,9 +54,10 @@ public class WorkflowContext {
     public GroupWorkflowAdapter gwfAdapter(
             final GroupDataBinder groupDataBinder,
             final GroupDAO groupDAO,
-            final EntityFactory entityFactory) {
+            final EntityFactory entityFactory,
+            final ApplicationEventPublisher publisher) {
 
-        return new DefaultGroupWorkflowAdapter(groupDataBinder, groupDAO, 
entityFactory);
+        return new DefaultGroupWorkflowAdapter(groupDataBinder, groupDAO, 
entityFactory, publisher);
     }
 
     @ConditionalOnMissingBean
@@ -62,8 +65,9 @@ public class WorkflowContext {
     public AnyObjectWorkflowAdapter awfAdapter(
             final AnyObjectDataBinder anyObjectDataBinder,
             final AnyObjectDAO anyObjectDAO,
-            final EntityFactory entityFactory) {
+            final EntityFactory entityFactory,
+            final ApplicationEventPublisher publisher) {
 
-        return new DefaultAnyObjectWorkflowAdapter(anyObjectDataBinder, 
anyObjectDAO, entityFactory);
+        return new DefaultAnyObjectWorkflowAdapter(anyObjectDataBinder, 
anyObjectDAO, entityFactory, publisher);
     }
 }
diff --git 
a/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchIndexManager.java
 
b/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchIndexManager.java
index 6aaef95279..8822a2ab91 100644
--- 
a/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchIndexManager.java
+++ 
b/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchIndexManager.java
@@ -41,9 +41,8 @@ import java.util.List;
 import java.util.Map;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.provisioning.api.event.AnyCreatedUpdatedEvent;
-import org.apache.syncope.core.provisioning.api.event.AnyDeletedEvent;
-import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.provisioning.api.event.AnyLifecycleEvent;
+import org.identityconnectors.framework.common.objects.SyncDeltaType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.transaction.event.TransactionalEventListener;
@@ -145,29 +144,28 @@ public class ElasticsearchIndexManager {
     }
 
     @TransactionalEventListener
-    public void after(final AnyCreatedUpdatedEvent<Any<?>> event) throws 
IOException {
-        String index = ElasticsearchUtils.getContextDomainName(
-                AuthContextUtils.getDomain(), 
event.getAny().getType().getKind());
-
-        IndexRequest<Map<String, Object>> request = new 
IndexRequest.Builder<Map<String, Object>>().
-                index(index).
-                id(event.getAny().getKey()).
-                document(elasticsearchUtils.document(event.getAny(), 
event.getDomain())).
-                build();
-        IndexResponse response = client.index(request);
-        LOG.debug("Index successfully created or updated for {}: {}", 
event.getAny(), response);
-    }
-
-    @TransactionalEventListener
-    public void after(final AnyDeletedEvent event) throws IOException {
-        LOG.debug("About to delete index for {}[{}]", event.getAnyTypeKind(), 
event.getAnyKey());
-
-        DeleteRequest request = new DeleteRequest.Builder().index(
-                
ElasticsearchUtils.getContextDomainName(AuthContextUtils.getDomain(), 
event.getAnyTypeKind())).
-                id(event.getAnyKey()).
-                build();
-        DeleteResponse response = client.delete(request);
-        LOG.debug("Index successfully deleted for {}[{}]: {}",
-                event.getAnyTypeKind(), event.getAnyKey(), response);
+    public void after(final AnyLifecycleEvent<Any<?>> event) throws 
IOException {
+        LOG.debug("About to {} index for {}", event.getType().name(), 
event.getAny());
+
+        if (event.getType() == SyncDeltaType.DELETE) {
+            DeleteRequest request = new DeleteRequest.Builder().index(
+                    ElasticsearchUtils.getContextDomainName(event.getDomain(), 
event.getAny().getType().getKind())).
+                    id(event.getAny().getKey()).
+                    build();
+            DeleteResponse response = client.delete(request);
+            LOG.debug("Index successfully deleted for {}[{}]: {}",
+                    event.getAny().getType().getKind(), 
event.getAny().getKey(), response);
+        } else {
+            String index = ElasticsearchUtils.getContextDomainName(
+                    event.getDomain(), event.getAny().getType().getKind());
+
+            IndexRequest<Map<String, Object>> request = new 
IndexRequest.Builder<Map<String, Object>>().
+                    index(index).
+                    id(event.getAny().getKey()).
+                    document(elasticsearchUtils.document(event.getAny(), 
event.getDomain())).
+                    build();
+            IndexResponse response = client.index(request);
+            LOG.debug("Index successfully created or updated for {}: {}", 
event.getAny(), response);
+        }
     }
 }
diff --git 
a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/FlowableWorkflowContext.java
 
b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/FlowableWorkflowContext.java
index e23ac764b6..78de315243 100644
--- 
a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/FlowableWorkflowContext.java
+++ 
b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/FlowableWorkflowContext.java
@@ -54,6 +54,7 @@ import 
org.flowable.idm.spring.configurator.SpringIdmEngineConfigurator;
 import org.flowable.spring.SpringProcessEngineConfiguration;
 import 
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import 
org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -76,7 +77,7 @@ public class FlowableWorkflowContext {
     @ConditionalOnMissingBean
     @Bean
     public SpringIdmEngineConfigurator syncopeIdmEngineConfigurator(
-        final SpringIdmEngineConfiguration syncopeIdmEngineConfiguration) {
+            final SpringIdmEngineConfiguration syncopeIdmEngineConfiguration) {
         SpringIdmEngineConfigurator configurator = new 
SpringIdmEngineConfigurator();
         configurator.setIdmEngineConfiguration(syncopeIdmEngineConfiguration);
         return configurator;
@@ -133,11 +134,11 @@ public class FlowableWorkflowContext {
     @Bean
     @Scope("prototype")
     public SpringProcessEngineConfiguration processEngineConfiguration(
-        final WorkflowFlowableProperties props,
-        final SpringIdmEngineConfigurator syncopeIdmEngineConfigurator,
-        final IdGenerator idGenerator,
-        final SyncopeEntitiesVariableType syncopeEntitiesVariableType,
-        final SyncopeFormHandlerHelper syncopeFormHandlerHelper) {
+            final WorkflowFlowableProperties props,
+            final SpringIdmEngineConfigurator syncopeIdmEngineConfigurator,
+            final IdGenerator idGenerator,
+            final SyncopeEntitiesVariableType syncopeEntitiesVariableType,
+            final SyncopeFormHandlerHelper syncopeFormHandlerHelper) {
         SpringProcessEngineConfiguration conf = new 
SpringProcessEngineConfiguration();
         
conf.setDatabaseSchemaUpdate(AbstractEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
         conf.setJpaHandleTransaction(true);
@@ -159,7 +160,7 @@ public class FlowableWorkflowContext {
 
     @Bean
     public Resource userWorkflowDef(final WorkflowFlowableProperties props,
-                                    final ResourceLoader resourceLoader) {
+            final ResourceLoader resourceLoader) {
         return resourceLoader.getResource(props.getUserWorkflowDef());
     }
 
@@ -170,14 +171,16 @@ public class FlowableWorkflowContext {
             final UserDAO userDAO,
             final EntityFactory entityFactory,
             final DomainProcessEngine engine,
-            final UserRequestHandler userRequestHandler) {
+            final UserRequestHandler userRequestHandler,
+            final ApplicationEventPublisher publisher) {
 
         return new FlowableUserWorkflowAdapter(
                 userDataBinder,
                 userDAO,
                 entityFactory,
                 engine,
-                userRequestHandler);
+                userRequestHandler,
+                publisher);
     }
 
     @ConditionalOnMissingBean
diff --git 
a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/UserRequestHandler.java
 
b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/UserRequestHandler.java
index 105278ed59..94a80a0717 100644
--- 
a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/UserRequestHandler.java
+++ 
b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/UserRequestHandler.java
@@ -25,9 +25,10 @@ import org.apache.syncope.common.lib.to.UserRequest;
 import org.apache.syncope.common.lib.to.UserRequestForm;
 import org.apache.syncope.common.lib.to.WorkflowTaskExecInput;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.UserWorkflowResult;
-import org.apache.syncope.core.provisioning.api.event.AnyDeletedEvent;
+import org.apache.syncope.core.provisioning.api.event.AnyLifecycleEvent;
 import org.flowable.engine.runtime.ProcessInstance;
 import org.springframework.transaction.event.TransactionalEventListener;
 
@@ -84,7 +85,7 @@ public interface UserRequestHandler {
      * @param event delete event
      */
     @TransactionalEventListener
-    void cancelByUser(AnyDeletedEvent event);
+    void cancelByUser(AnyLifecycleEvent<Any<?>> event);
 
     /**
      * Get the form matching the provided task id.
diff --git 
a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserRequestHandler.java
 
b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserRequestHandler.java
index 9ddae5d0af..efb237ba2a 100644
--- 
a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserRequestHandler.java
+++ 
b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserRequestHandler.java
@@ -37,7 +37,6 @@ import 
org.apache.syncope.common.lib.to.UserRequestFormProperty;
 import org.apache.syncope.common.lib.to.UserRequestForm;
 import org.apache.syncope.common.lib.to.UserRequestFormPropertyValue;
 import org.apache.syncope.common.lib.to.WorkflowTaskExecInput;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.UserRequestFormPropertyType;
 import org.apache.syncope.core.flowable.api.DropdownValueProvider;
@@ -46,12 +45,13 @@ import 
org.apache.syncope.core.flowable.support.DomainProcessEngine;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.PropagationByResource;
 import org.apache.syncope.core.provisioning.api.UserWorkflowResult;
 import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
-import org.apache.syncope.core.provisioning.api.event.AnyDeletedEvent;
+import org.apache.syncope.core.provisioning.api.event.AnyLifecycleEvent;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.workflow.api.WorkflowException;
@@ -69,6 +69,7 @@ import org.flowable.task.api.Task;
 import org.flowable.task.api.TaskQuery;
 import org.flowable.task.api.history.HistoricTaskInstance;
 import org.flowable.variable.api.history.HistoricVariableInstance;
+import org.identityconnectors.framework.common.objects.SyncDeltaType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
@@ -265,13 +266,16 @@ public class FlowableUserRequestHandler implements 
UserRequestHandler {
     }
 
     @Override
-    public void cancelByUser(final AnyDeletedEvent event) {
-        if (AuthContextUtils.getDomain().equals(event.getDomain()) && 
event.getAnyTypeKind() == AnyTypeKind.USER) {
-            String username = event.getAnyName();
+    public void cancelByUser(final AnyLifecycleEvent<Any<?>> event) {
+        if (AuthContextUtils.getDomain().equals(event.getDomain())
+                && event.getType() == SyncDeltaType.DELETE
+                && event.getAny() instanceof User) {
+
+            User user = (User) event.getAny();
             engine.getRuntimeService().createNativeProcessInstanceQuery().
-                    
sql(createProcessInstanceQuery(event.getAnyKey()).toString()).
+                    sql(createProcessInstanceQuery(user.getKey()).toString()).
                     list().forEach(procInst -> 
engine.getRuntimeService().deleteProcessInstance(
-                    procInst.getId(), "Cascade Delete user " + username));
+                    procInst.getId(), "Cascade Delete user " + 
user.getUsername()));
         }
     }
 
diff --git 
a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserWorkflowAdapter.java
 
b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserWorkflowAdapter.java
index 347588c71a..3453f49394 100644
--- 
a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserWorkflowAdapter.java
+++ 
b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserWorkflowAdapter.java
@@ -42,6 +42,7 @@ import 
org.apache.syncope.core.flowable.support.DomainProcessEngine;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
+import org.apache.syncope.core.provisioning.api.event.AnyLifecycleEvent;
 import org.apache.syncope.core.workflow.api.WorkflowException;
 import org.apache.syncope.core.workflow.java.AbstractUserWorkflowAdapter;
 import org.flowable.bpmn.model.FlowElement;
@@ -51,7 +52,9 @@ import org.flowable.bpmn.model.Process;
 import org.flowable.common.engine.api.FlowableException;
 import org.flowable.engine.runtime.ProcessInstance;
 import org.flowable.task.api.Task;
+import org.identityconnectors.framework.common.objects.SyncDeltaType;
 import org.springframework.beans.BeanUtils;
+import org.springframework.context.ApplicationEventPublisher;
 
 public class FlowableUserWorkflowAdapter extends AbstractUserWorkflowAdapter 
implements WorkflowTaskManager {
 
@@ -59,16 +62,20 @@ public class FlowableUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter imp
 
     protected final UserRequestHandler userRequestHandler;
 
+    protected final ApplicationEventPublisher publisher;
+
     public FlowableUserWorkflowAdapter(
             final UserDataBinder dataBinder,
             final UserDAO userDAO,
             final EntityFactory entityFactory,
             final DomainProcessEngine engine,
-            final UserRequestHandler userRequestHandler) {
+            final UserRequestHandler userRequestHandler,
+            final ApplicationEventPublisher publisher) {
 
         super(dataBinder, userDAO, entityFactory);
         this.engine = engine;
         this.userRequestHandler = userRequestHandler;
+        this.publisher = publisher;
     }
 
     @Override
@@ -144,6 +151,9 @@ public class FlowableUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter imp
         FlowableRuntimeUtils.updateStatus(engine, 
procInst.getProcessInstanceId(), user);
         User created = userDAO.save(user);
 
+        publisher.publishEvent(
+                new AnyLifecycleEvent<>(this, SyncDeltaType.CREATE, created, 
AuthContextUtils.getDomain()));
+
         engine.getRuntimeService().updateBusinessKey(
                 procInst.getProcessInstanceId(), 
FlowableRuntimeUtils.getWFProcBusinessKey(created.getKey()));
 
@@ -235,6 +245,9 @@ public class FlowableUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter imp
         FlowableRuntimeUtils.updateStatus(engine, procInstID, user);
         User updated = userDAO.save(user);
 
+        publisher.publishEvent(
+                new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, updated, 
AuthContextUtils.getDomain()));
+
         variables.keySet().forEach(key -> 
engine.getRuntimeService().removeVariable(procInstID, key));
         engine.getRuntimeService().removeVariable(procInstID, 
FlowableRuntimeUtils.USER);
         engine.getRuntimeService().removeVariable(procInstID, 
FlowableRuntimeUtils.WF_EXECUTOR);
@@ -271,6 +284,9 @@ public class FlowableUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter imp
         FlowableRuntimeUtils.updateStatus(engine, procInstID, user);
         User updated = userDAO.save(user);
 
+        publisher.publishEvent(
+                new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, updated, 
AuthContextUtils.getDomain()));
+
         engine.getRuntimeService().removeVariable(procInstID, 
FlowableRuntimeUtils.USER);
         engine.getRuntimeService().removeVariable(procInstID, 
FlowableRuntimeUtils.WF_EXECUTOR);
         engine.getRuntimeService().removeVariable(procInstID, 
FlowableRuntimeUtils.TASK);
@@ -327,6 +343,9 @@ public class FlowableUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter imp
         FlowableRuntimeUtils.updateStatus(engine, procInstID, user);
         User updated = userDAO.save(user);
 
+        publisher.publishEvent(
+                new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, updated, 
AuthContextUtils.getDomain()));
+
         @SuppressWarnings("unchecked")
         PropagationByResource<String> propByRes = 
engine.getRuntimeService().getVariable(
                 procInstID, FlowableRuntimeUtils.PROP_BY_RESOURCE, 
PropagationByResource.class);
@@ -357,6 +376,9 @@ public class FlowableUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter imp
         FlowableRuntimeUtils.updateStatus(engine, procInstID, user);
         User updated = userDAO.save(user);
 
+        publisher.publishEvent(
+                new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, updated, 
AuthContextUtils.getDomain()));
+
         @SuppressWarnings("unchecked")
         PropagationByResource<String> propByRes = 
engine.getRuntimeService().getVariable(
                 procInstID, FlowableRuntimeUtils.PROP_BY_RESOURCE, 
PropagationByResource.class);
@@ -388,7 +410,10 @@ public class FlowableUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter imp
         doExecuteNextTask(procInstID, user, variables);
 
         metadata(user, updater, context);
-        userDAO.save(user);
+        User updated = userDAO.save(user);
+
+        publisher.publishEvent(
+                new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, updated, 
AuthContextUtils.getDomain()));
 
         variables.keySet().forEach(key -> 
engine.getRuntimeService().removeVariable(procInstID, key));
         engine.getRuntimeService().removeVariable(procInstID, 
FlowableRuntimeUtils.USER);
@@ -411,7 +436,10 @@ public class FlowableUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter imp
         Set<String> tasks = doExecuteNextTask(procInstID, user, variables);
 
         metadata(user, updater, context);
-        userDAO.save(user);
+        User updated = userDAO.save(user);
+
+        publisher.publishEvent(
+                new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, updated, 
AuthContextUtils.getDomain()));
 
         variables.keySet().forEach(key -> 
engine.getRuntimeService().removeVariable(procInstID, key));
         engine.getRuntimeService().removeVariable(procInstID, 
FlowableRuntimeUtils.USER);
@@ -454,6 +482,9 @@ public class FlowableUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter imp
 
             userDAO.delete(user.getKey());
 
+            publisher.publishEvent(
+                    new AnyLifecycleEvent<>(this, SyncDeltaType.DELETE, user, 
AuthContextUtils.getDomain()));
+
             if 
(!engine.getHistoryService().createHistoricProcessInstanceQuery().
                     processInstanceId(procInstID).list().isEmpty()) {
 
@@ -471,7 +502,10 @@ public class FlowableUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter imp
 
             FlowableRuntimeUtils.updateStatus(engine, procInstID, user);
             metadata(user, eraser, context);
-            userDAO.save(user);
+            User updated = userDAO.save(user);
+
+            publisher.publishEvent(
+                    new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, 
updated, AuthContextUtils.getDomain()));
 
             engine.getRuntimeService().removeVariable(procInstID, 
FlowableRuntimeUtils.TASK);
             engine.getRuntimeService().removeVariable(procInstID, 
FlowableRuntimeUtils.USER);
@@ -493,6 +527,9 @@ public class FlowableUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter imp
         FlowableRuntimeUtils.updateStatus(engine, procInstID, user);
         user = userDAO.save(user);
 
+        publisher.publishEvent(
+                new AnyLifecycleEvent<>(this, SyncDeltaType.UPDATE, user, 
AuthContextUtils.getDomain()));
+
         engine.getRuntimeService().setVariable(
                 procInstID, FlowableRuntimeUtils.USER_TO, 
dataBinder.getUserTO(user, true));
 
@@ -501,6 +538,9 @@ public class FlowableUserWorkflowAdapter extends 
AbstractUserWorkflowAdapter imp
 
             userDAO.delete(user.getKey());
 
+            publisher.publishEvent(
+                    new AnyLifecycleEvent<>(this, SyncDeltaType.DELETE, user, 
AuthContextUtils.getDomain()));
+
             if 
(!engine.getHistoryService().createHistoricProcessInstanceQuery().
                     processInstanceId(procInstID).list().isEmpty()) {
 
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index 5228f3576b..065b994781 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -544,6 +544,7 @@ under the License.
                       <discovery.type>single-node</discovery.type>
                       <cluster.name>elasticsearch</cluster.name>
                       <xpack.security.enabled>false</xpack.security.enabled>
+                      
<ingest.geoip.downloader.enabled>false</ingest.geoip.downloader.enabled>
                     </env>
                     <ports>
                       <port>9200:9200</port>

Reply via email to