keycloak-uncached

Merge pull request #2888 from mposolda/1.9.x Admin events

5/25/2016 6:50:47 PM

Changes

Details

diff --git a/core/src/main/java/org/keycloak/representations/idm/RequiredActionProviderSimpleRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RequiredActionProviderSimpleRepresentation.java
index 1e0a60d..492204d 100644
--- a/core/src/main/java/org/keycloak/representations/idm/RequiredActionProviderSimpleRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/RequiredActionProviderSimpleRepresentation.java
@@ -25,9 +25,18 @@ package org.keycloak.representations.idm;
  */
 public class RequiredActionProviderSimpleRepresentation {
 
+    private String id;
     private String name;
     private String providerId;
 
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
     public String getName() {
         return name;
     }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AttackDetectionResource.java b/services/src/main/java/org/keycloak/services/resources/admin/AttackDetectionResource.java
index 0ade972..6ffa12c 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AttackDetectionResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AttackDetectionResource.java
@@ -115,7 +115,7 @@ public class AttackDetectionResource {
         UsernameLoginFailureModel model = session.sessions().getUserLoginFailure(realm, username.toLowerCase());
         if (model != null) {
             session.sessions().removeUserLoginFailure(realm, username);
-            adminEvent.operation(OperationType.DELETE).success();
+            adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
         }
     }
 
@@ -131,7 +131,7 @@ public class AttackDetectionResource {
         auth.requireManage();
 
         session.sessions().removeAllUserLoginFailures(realm);
-        adminEvent.operation(OperationType.DELETE).success();
+        adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
     }
 
 
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java b/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java
index a720a32..b481a75 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java
@@ -28,6 +28,7 @@ import org.keycloak.authentication.FormAction;
 import org.keycloak.authentication.FormAuthenticator;
 import org.keycloak.authentication.RequiredActionFactory;
 import org.keycloak.authentication.RequiredActionProvider;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.models.AuthenticationExecutionModel;
 import org.keycloak.models.AuthenticationFlowModel;
 import org.keycloak.models.AuthenticatorConfigModel;
@@ -212,7 +213,10 @@ public class AuthenticationManagementResource {
             return ErrorResponse.exists("Flow " + flow.getAlias() + " already exists");
         }
 
-        realm.addAuthenticationFlow(RepresentationToModel.toModel(flow));
+        AuthenticationFlowModel createdModel = realm.addAuthenticationFlow(RepresentationToModel.toModel(flow));
+
+        flow.setId(createdModel.getId());
+        adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, createdModel.getId()).representation(flow).success();
         return Response.status(201).build();
     }
 
@@ -263,6 +267,9 @@ public class AuthenticationManagementResource {
         	realm.removeAuthenticatorExecution(execution);
         }
         realm.removeAuthenticationFlow(flow);
+
+        // Use just one event for top-level flow. Using separate events won't work properly for flows of depth 2 or bigger
+        adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
     }
 
     /**
@@ -299,6 +306,9 @@ public class AuthenticationManagementResource {
         copy = realm.addAuthenticationFlow(copy);
         copy(newName, flow, copy);
 
+        data.put("id", copy.getId());
+        adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(data).success();
+
         return Response.status(201).build();
 
     }
@@ -362,8 +372,10 @@ public class AuthenticationManagementResource {
         execution.setAuthenticatorFlow(true);
         execution.setAuthenticator(provider);
         execution.setPriority(getNextPriority(parentFlow));
+        execution = realm.addAuthenticatorExecution(execution);
 
-        realm.addAuthenticatorExecution(execution);
+        data.put("id", execution.getId());
+        adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(data).success();
     }
 
     private int getNextPriority(AuthenticationFlowModel parentFlow) {
@@ -413,7 +425,10 @@ public class AuthenticationManagementResource {
         execution.setAuthenticator(provider);
         execution.setPriority(getNextPriority(parentFlow));
 
-        realm.addAuthenticatorExecution(execution);
+        execution = realm.addAuthenticatorExecution(execution);
+
+        data.put("id", execution.getId());
+        adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(data).success();
     }
 
     /**
@@ -519,6 +534,7 @@ public class AuthenticationManagementResource {
         if (!model.getRequirement().name().equals(rep.getRequirement())) {
             model.setRequirement(AuthenticationExecutionModel.Requirement.valueOf(rep.getRequirement()));
             realm.updateAuthenticatorExecution(model);
+            adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success();
         }
     }
 
@@ -541,6 +557,8 @@ public class AuthenticationManagementResource {
         }
         model.setPriority(getNextPriority(parentFlow));
         model = realm.addAuthenticatorExecution(model);
+
+        adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, model.getId()).representation(execution).success();
         return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build();
     }
 
@@ -592,6 +610,8 @@ public class AuthenticationManagementResource {
         realm.updateAuthenticatorExecution(previous);
         model.setPriority(tmp);
         realm.updateAuthenticatorExecution(model);
+
+        adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).success();
     }
 
     public List<AuthenticationExecutionModel> getSortedExecutions(AuthenticationFlowModel parentFlow) {
@@ -635,6 +655,8 @@ public class AuthenticationManagementResource {
         realm.updateAuthenticatorExecution(model);
         next.setPriority(tmp);
         realm.updateAuthenticatorExecution(next);
+
+        adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).success();
     }
 
 
@@ -666,6 +688,8 @@ public class AuthenticationManagementResource {
         }
 
         realm.removeAuthenticatorExecution(model);
+
+        adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
     }
 
 
@@ -693,6 +717,9 @@ public class AuthenticationManagementResource {
         config = realm.addAuthenticatorConfig(config);
         model.setAuthenticatorConfig(config.getId());
         realm.updateAuthenticatorExecution(model);
+
+        json.setId(config.getId());
+        adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(json).success();
         return Response.created(uriInfo.getAbsolutePathBuilder().path(config.getId()).build()).build();
     }
 
@@ -772,7 +799,10 @@ public class AuthenticationManagementResource {
         requiredAction.setProviderId(providerId);
         requiredAction.setDefaultAction(false);
         requiredAction.setEnabled(true);
-        realm.addRequiredActionProvider(requiredAction);
+        requiredAction = realm.addRequiredActionProvider(requiredAction);
+
+        data.put("id", requiredAction.getId());
+        adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(data).success();
     }
 
 
@@ -850,6 +880,8 @@ public class AuthenticationManagementResource {
         update.setEnabled(rep.isEnabled());
         update.setConfig(rep.getConfig());
         realm.updateRequiredActionProvider(update);
+
+        adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success();
     }
 
     /**
@@ -866,6 +898,8 @@ public class AuthenticationManagementResource {
             throw new NotFoundException("Failed to find required action.");
         }
         realm.removeRequiredActionProvider(model);
+
+        adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
     }
 
     /**
@@ -947,6 +981,7 @@ public class AuthenticationManagementResource {
         auth.requireManage();
 
         AuthenticatorConfigModel config = realm.addAuthenticatorConfig(RepresentationToModel.toModel(rep));
+        adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, config.getId()).representation(rep).success();
         return Response.created(uriInfo.getAbsolutePathBuilder().path(config.getId()).build()).build();
     }
 
@@ -995,6 +1030,8 @@ public class AuthenticationManagementResource {
         }
 
         realm.removeAuthenticatorConfig(config);
+
+        adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
     }
 
     /**
@@ -1017,5 +1054,6 @@ public class AuthenticationManagementResource {
         exists.setAlias(rep.getAlias());
         exists.setConfig(rep.getConfig());
         realm.updateAuthenticatorConfig(exists);
+        adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success();
     }
 }
\ No newline at end of file
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientInitialAccessResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientInitialAccessResource.java
index ff766d6..a2c35d8 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientInitialAccessResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientInitialAccessResource.java
@@ -108,6 +108,7 @@ public class ClientInitialAccessResource {
         auth.requireManage();
 
         session.sessions().removeClientInitialAccessModel(realm, id);
+        adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
     }
 
     private ClientInitialAccessPresentation wrap(ClientInitialAccessModel model) {
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java
index 53045ba..08177b9 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java
@@ -485,7 +485,7 @@ public class ClientResource {
         }
         if (logger.isDebugEnabled()) logger.debug("Register node: " + node);
         client.registerNode(node, Time.currentTime());
-        adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
+        adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, node).success();
     }
 
     /**
@@ -532,9 +532,9 @@ public class ClientResource {
         }
 
         logger.debug("Test availability of cluster nodes");
-        adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
-        return new ResourceAdminManager(session).testNodesAvailability(uriInfo.getRequestUri(), realm, client);
-
+        GlobalRequestResult result = new ResourceAdminManager(session).testNodesAvailability(uriInfo.getRequestUri(), realm, client);
+        adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).representation(result).success();
+        return result;
     }
 
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java
index ff0745b..a1c0433 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java
@@ -43,6 +43,7 @@ import javax.ws.rs.core.UriInfo;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Properties;
 import java.util.Set;
@@ -196,12 +197,15 @@ public class ClientRoleMappingsResource {
 
         if (roles == null) {
             Set<RoleModel> roleModels = user.getClientRoleMappings(client);
+            roles = new LinkedList<>();
+
             for (RoleModel roleModel : roleModels) {
-                if (!(roleModel.getContainer() instanceof ClientModel)) {
+                if (roleModel.getContainer() instanceof ClientModel) {
                     ClientModel client = (ClientModel) roleModel.getContainer();
                     if (!client.getId().equals(this.client.getId())) continue;
                 }
                 user.deleteRoleMapping(roleModel);
+                roles.add(ModelToRepresentation.toRepresentation(roleModel));
             }
 
         } else {
@@ -220,6 +224,7 @@ public class ClientRoleMappingsResource {
                 }
             }
         }
+
         adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).representation(roles).success();
     }
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java b/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java
index 49b607b..a22002c 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java
@@ -144,7 +144,7 @@ public class GroupResource {
             if (child == null) {
                 throw new NotFoundException("Could not find child by id");
             }
-            adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(rep).success();
+            adminEvent.operation(OperationType.UPDATE);
         } else {
             child = realm.createGroup(rep.getName());
             updateGroup(rep, child);
@@ -152,10 +152,13 @@ public class GroupResource {
                                            .path(uriInfo.getMatchedURIs().get(2))
                                            .path(child.getId()).build();
             builder.status(201).location(uri);
-            adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success();
+            rep.setId(child.getId());
+            adminEvent.operation(OperationType.CREATE);
 
         }
         realm.moveGroup(child, group);
+        adminEvent.resourcePath(uriInfo).representation(rep).success();
+
         GroupRepresentation childRep = ModelToRepresentation.toGroupHierarchy(child, true);
         return builder.type(MediaType.APPLICATION_JSON_TYPE).entity(childRep).build();
     }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java
index 037235d..7b164a5 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java
@@ -108,16 +108,20 @@ public class GroupsResource {
             if (child == null) {
                 throw new NotFoundException("Could not find child by id");
             }
-            adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success();
+            adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo);
         } else {
             child = realm.createGroup(rep.getName());
             GroupResource.updateGroup(rep, child);
             URI uri = uriInfo.getAbsolutePathBuilder()
                     .path(child.getId()).build();
             builder.status(201).location(uri);
-            adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(rep).success();
+
+            rep.setId(child.getId());
+            adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, child.getId());
         }
         realm.moveGroup(child, null);
+
+        adminEvent.representation(rep).success();
         return builder.build();
     }
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java
index 4974a6b..953cb38 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java
@@ -189,7 +189,8 @@ public class IdentityProvidersResource {
             IdentityProviderModel identityProvider = RepresentationToModel.toModel(realm, representation);
             this.realm.addIdentityProvider(identityProvider);
 
-            adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, identityProvider.getInternalId())
+            representation.setInternalId(identityProvider.getInternalId());
+            adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, identityProvider.getAlias())
                     .representation(representation).success();
             
             return Response.created(uriInfo.getAbsolutePathBuilder().path(representation.getAlias()).build()).build();
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
index 24f3dc3..6c265bd 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
@@ -354,8 +354,9 @@ public class RealmAdminResource {
     public GlobalRequestResult pushRevocation() {
         auth.requireManage();
 
-        adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
-        return new ResourceAdminManager(session).pushRealmRevocationPolicy(uriInfo.getRequestUri(), realm);
+        GlobalRequestResult result = new ResourceAdminManager(session).pushRealmRevocationPolicy(uriInfo.getRequestUri(), realm);
+        adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).representation(result).success();
+        return result;
     }
 
     /**
@@ -369,8 +370,9 @@ public class RealmAdminResource {
         auth.init(RealmAuth.Resource.USER).requireManage();
 
         session.sessions().removeUserSessions(realm);
-        adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
-        return new ResourceAdminManager(session).logoutAll(uriInfo.getRequestUri(), realm);
+        GlobalRequestResult result = new ResourceAdminManager(session).logoutAll(uriInfo.getRequestUri(), realm);
+        adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).representation(result).success();
+        return result;
     }
 
     /**
@@ -730,6 +732,8 @@ public class RealmAdminResource {
             throw new NotFoundException("Group not found");
         }
         realm.addDefaultGroup(group);
+
+        adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).success();
     }
 
     @DELETE
@@ -743,6 +747,8 @@ public class RealmAdminResource {
             throw new NotFoundException("Group not found");
         }
         realm.removeDefaultGroup(group);
+
+        adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
     }
 
 
@@ -794,11 +800,12 @@ public class RealmAdminResource {
     public void clearRealmCache() {
         auth.requireManage();
 
-        adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
         CacheRealmProvider cache = session.getProvider(CacheRealmProvider.class);
         if (cache != null) {
             cache.clear();
         }
+
+        adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
     }
 
     /**
@@ -810,11 +817,12 @@ public class RealmAdminResource {
     public void clearUserCache() {
         auth.requireManage();
 
-        adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
         CacheUserProvider cache = session.getProvider(CacheUserProvider.class);
         if (cache != null) {
             cache.clear();
         }
+
+        adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
     }
 
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java
index 58ccb6a..99ec68a 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java
@@ -226,9 +226,7 @@ public class RoleByIdResource extends RoleResource {
         auth.requireManage();
 
         RoleModel role = getRoleModel(id);
-        deleteComposites(roles, role);
-
-        adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).representation(roles).success();
+        deleteComposites(adminEvent, uriInfo, roles, role);
     }
 
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
index 12dfc54..e116ca3 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
@@ -115,7 +115,8 @@ public class RoleContainerResource extends RoleResource {
             boolean scopeParamRequired = rep.isScopeParamRequired()==null ? false : rep.isScopeParamRequired();
             role.setScopeParamRequired(scopeParamRequired);
 
-            adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, role.getId()).representation(rep).success();
+            rep.setId(role.getId());
+            adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, role.getName()).representation(rep).success();
 
             return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getName()).build()).build();
         } catch (ModelDuplicateException e) {
@@ -332,8 +333,7 @@ public class RoleContainerResource extends RoleResource {
         if (role == null) {
             throw new NotFoundException("Could not find role");
         }
-        deleteComposites(roles, role);
-        adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
+        deleteComposites(adminEvent, uriInfo, roles, role);
     }
 
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java
index d8fe904..79ae4dc 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java
@@ -50,6 +50,7 @@ import javax.ws.rs.core.UriInfo;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
@@ -236,8 +237,9 @@ public class RoleMapperResource {
                 throw new NotFoundException("Role not found");
             }
             roleMapper.grantRole(roleModel);
-            adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, role.getId()).representation(roles).success();
         }
+
+        adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(roles).success();
     }
 
     /**
@@ -258,10 +260,13 @@ public class RoleMapperResource {
         logger.debug("deleteRealmRoleMappings");
         if (roles == null) {
             Set<RoleModel> roleModels = roleMapper.getRealmRoleMappings();
+            roles = new LinkedList<>();
+
             for (RoleModel roleModel : roleModels) {
                 roleMapper.deleteRoleMapping(roleModel);
+                roles.add(ModelToRepresentation.toRepresentation(roleModel));
             }
-            adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(roles).success();
+
         } else {
             for (RoleRepresentation role : roles) {
                 RoleModel roleModel = realm.getRole(role.getName());
@@ -276,11 +281,12 @@ public class RoleMapperResource {
                     throw new ErrorResponseException(me.getMessage(), MessageFormat.format(messages.getProperty(me.getMessage(), me.getMessage()), me.getParameters()),
                             Response.Status.BAD_REQUEST);
                 }
-
-                adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo, role.getId()).representation(roles).success();
             }
+
         }
 
+        adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).representation(roles).success();
+
     }
 
     @Path("clients/{client}")
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
index 34df0c6..f05572e 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
@@ -65,9 +65,9 @@ public abstract class RoleResource {
                 throw new NotFoundException("Could not find composite role");
             }
             role.addCompositeRole(composite);
-
-            adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, rep.getId()).representation(roles).success();
         }
+
+        adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(roles).success();
     }
 
     protected Set<RoleRepresentation> getRoleComposites(RoleModel role) {
@@ -102,7 +102,7 @@ public abstract class RoleResource {
         return composites;
     }
 
-    protected void deleteComposites(List<RoleRepresentation> roles, RoleModel role) {
+    protected void deleteComposites(AdminEventBuilder adminEvent, UriInfo uriInfo, List<RoleRepresentation> roles, RoleModel role) {
         for (RoleRepresentation rep : roles) {
             RoleModel composite = realm.getRoleById(rep.getId());
             if (composite == null) {
@@ -110,5 +110,7 @@ public abstract class RoleResource {
             }
             role.removeCompositeRole(composite);
         }
+
+        adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).representation(roles).success();
     }
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java
index 2ff4d2f..eb685e4 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java
@@ -38,6 +38,7 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 
 import java.util.ArrayList;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
 
@@ -151,8 +152,9 @@ public class ScopeMappedClientResource {
                 throw new NotFoundException("Role not found");
             }
             scopeContainer.addScopeMapping(roleModel);
-            adminEvent.operation(OperationType.CREATE).resourcePath(session.getContext().getUri(), roleModel.getId()).representation(roles).success();
         }
+
+        adminEvent.operation(OperationType.CREATE).resourcePath(session.getContext().getUri()).representation(roles).success();
     }
 
     /**
@@ -171,10 +173,13 @@ public class ScopeMappedClientResource {
 
         if (roles == null) {
             Set<RoleModel> roleModels = KeycloakModelUtils.getClientScopeMappings(scopedClient, scopeContainer);//scopedClient.getClientScopeMappings(client);
+            roles = new LinkedList<>();
+
             for (RoleModel roleModel : roleModels) {
                 scopeContainer.deleteScopeMapping(roleModel);
+                roles.add(ModelToRepresentation.toRepresentation(roleModel));
             }
-            adminEvent.operation(OperationType.DELETE).resourcePath(session.getContext().getUri()).representation(roles).success();
+
         } else {
             for (RoleRepresentation role : roles) {
                 RoleModel roleModel = scopedClient.getRole(role.getName());
@@ -182,8 +187,9 @@ public class ScopeMappedClientResource {
                     throw new NotFoundException("Role not found");
                 }
                 scopeContainer.deleteScopeMapping(roleModel);
-                adminEvent.operation(OperationType.DELETE).resourcePath(session.getContext().getUri(), roleModel.getId()).representation(roles).success();
             }
         }
+
+        adminEvent.operation(OperationType.DELETE).resourcePath(session.getContext().getUri()).representation(roles).success();
     }
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java
index 1f2fbe7..bf3cb88 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java
@@ -42,6 +42,7 @@ import javax.ws.rs.core.MediaType;
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -220,8 +221,9 @@ public class ScopeMappedResource {
                 throw new NotFoundException("Role not found");
             }
             scopeContainer.addScopeMapping(roleModel);
-            adminEvent.operation(OperationType.CREATE).resourcePath(session.getContext().getUri(), role.getId()).representation(roles).success();
         }
+
+        adminEvent.operation(OperationType.CREATE).resourcePath(session.getContext().getUri()).representation(roles).success();
     }
 
     /**
@@ -241,10 +243,13 @@ public class ScopeMappedResource {
 
         if (roles == null) {
             Set<RoleModel> roleModels = scopeContainer.getRealmScopeMappings();
+            roles = new LinkedList<>();
+
             for (RoleModel roleModel : roleModels) {
                 scopeContainer.deleteScopeMapping(roleModel);
+                roles.add(ModelToRepresentation.toRepresentation(roleModel));
             }
-            adminEvent.operation(OperationType.DELETE).resourcePath(session.getContext().getUri()).representation(roles).success();
+
        } else {
             for (RoleRepresentation role : roles) {
                 RoleModel roleModel = realm.getRoleById(role.getId());
@@ -252,10 +257,11 @@ public class ScopeMappedResource {
                     throw new NotFoundException("Client not found");
                 }
                 scopeContainer.deleteScopeMapping(roleModel);
-                adminEvent.operation(OperationType.DELETE).resourcePath(session.getContext().getUri(), roleModel.getId()).representation(roles).success();
             }
         }
 
+        adminEvent.operation(OperationType.DELETE).resourcePath(session.getContext().getUri()).representation(roles).success();
+
     }
 
     @Path("clients/{client}")
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java
index 0d15f9b..c8cf4fd 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java
@@ -190,7 +190,11 @@ public class UserFederationProviderResource {
             throw new NotFoundException("Unknown action: " + action);
         }
 
-        adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
+        Map<String, Object> eventRep = new HashMap<>();
+        eventRep.put("action", action);
+        eventRep.put("result", syncResult);
+        adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).representation(eventRep).success();
+
         return syncResult;
     }
 
@@ -422,7 +426,10 @@ public class UserFederationProviderResource {
             throw new NotFoundException("Unknown direction: " + direction);
         }
 
-        adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
+        Map<String, Object> eventRep = new HashMap<>();
+        eventRep.put("action", direction);
+        eventRep.put("result", syncResult);
+        adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).representation(eventRep).success();
         return syncResult;
     }
 
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java
index 7e0e7a2..eff1de7 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java
@@ -37,11 +37,9 @@ import org.keycloak.representations.idm.ConfigPropertyRepresentation;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.UserFederationProviderFactoryRepresentation;
 import org.keycloak.representations.idm.UserFederationProviderRepresentation;
-import org.keycloak.services.ErrorResponse;
 import org.keycloak.services.ErrorResponseException;
 import org.keycloak.services.ServicesLogger;
 import org.keycloak.services.managers.UsersSyncManager;
-import org.keycloak.timer.TimerProvider;
 import org.keycloak.utils.CredentialHelper;
 
 import javax.ws.rs.Consumes;
@@ -211,8 +209,8 @@ public class UserFederationProvidersResource {
             logger.addedKerberosToRealmCredentials();
         }
 
-
-        adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(rep).success();
+        rep.setId(model.getId());
+        adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, model.getId()).representation(rep).success();
 
         return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build();
     }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
index bbc6a96..82ca7dc 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
@@ -959,7 +959,7 @@ public class UsersResource {
         try {
             if (user.isMemberOf(group)){
                 user.leaveGroup(group);
-                adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
+                adminEvent.operation(OperationType.DELETE).representation(ModelToRepresentation.toRepresentation(group, true)).resourcePath(uriInfo).success();
             }
         } catch (ModelException me) {
             Properties messages = AdminRoot.getMessages(session, realm, auth.getAuth().getToken().getLocale());
@@ -984,9 +984,8 @@ public class UsersResource {
         }
         if (!user.isMemberOf(group)){
             user.joinGroup(group);
-            adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).success();
+            adminEvent.operation(OperationType.CREATE).representation(ModelToRepresentation.toRepresentation(group, true)).resourcePath(uriInfo).success();
         }
     }
 
-
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AttackDetectionResourceTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AttackDetectionResourceTest.java
index 40bc43e..d39f43c 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AttackDetectionResourceTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/AttackDetectionResourceTest.java
@@ -17,13 +17,12 @@
 
 package org.keycloak.testsuite.admin;
 
-import org.jboss.arquillian.graphene.page.Page;
 import org.jboss.arquillian.test.api.ArquillianResource;
 import org.junit.Test;
 import org.keycloak.admin.client.resource.AttackDetectionResource;
-import org.keycloak.common.util.Time;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.testsuite.pages.LoginPage;
+import org.keycloak.testsuite.util.AdminEventPaths;
 import org.keycloak.testsuite.util.OAuthClient;
 import org.keycloak.testsuite.util.UserBuilder;
 
@@ -33,7 +32,6 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
 /**
- * TODO adminEvents: Add adminEvents once resourcePath is added in AttackDetectionResource (server-side) events
  *
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
@@ -69,11 +67,13 @@ public class AttackDetectionResourceTest extends AbstractAdminTest {
         assertBruteForce(detection.bruteForceUserStatus("nosuchuser"), 0, false, false);
 
         detection.clearBruteForceForUser("test-user@localhost");
+        assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.attackDetectionClearBruteForceForUserPath("test-user@localhost"));
 
         assertBruteForce(detection.bruteForceUserStatus("test-user@localhost"), 0, false, false);
         assertBruteForce(detection.bruteForceUserStatus("test-user2"), 2, true, true);
 
         detection.clearAllBruteForce();
+        assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.attackDetectionClearAllBruteForcePath());
 
         assertBruteForce(detection.bruteForceUserStatus("test-user@localhost"), 0, false, false);
         assertBruteForce(detection.bruteForceUserStatus("test-user2"), 0, false, false);
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/AbstractAuthenticationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/AbstractAuthenticationTest.java
index 50b11ac..d77c76c 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/AbstractAuthenticationTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/AbstractAuthenticationTest.java
@@ -19,19 +19,26 @@ package org.keycloak.testsuite.admin.authentication;
 
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.Rule;
 import org.keycloak.admin.client.resource.AuthenticationManagementResource;
 import org.keycloak.admin.client.resource.RealmResource;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
 import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
 import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
 import org.keycloak.representations.idm.AuthenticatorConfigRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.testsuite.AbstractKeycloakTest;
+import org.keycloak.testsuite.util.AdminEventPaths;
+import org.keycloak.testsuite.util.AssertAdminEvents;
+import org.keycloak.testsuite.util.RealmBuilder;
 
 import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.List;
 
+import javax.ws.rs.core.Response;
+
 
 /**
  * @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
@@ -48,6 +55,9 @@ public abstract class AbstractAuthenticationTest extends AbstractKeycloakTest {
     RealmResource realmResource;
     AuthenticationManagementResource authMgmtResource;
 
+    @Rule
+    public AssertAdminEvents assertAdminEvents = new AssertAdminEvents(this);
+
     @Before
     public void before() {
         realmResource = adminClient.realms().realm(REALM_NAME);
@@ -56,9 +66,8 @@ public abstract class AbstractAuthenticationTest extends AbstractKeycloakTest {
 
     @Override
     public void addTestRealms(List<RealmRepresentation> testRealms) {
-        RealmRepresentation testRealmRep = new RealmRepresentation();
-        testRealmRep.setRealm(REALM_NAME);
-        testRealmRep.setEnabled(true);
+        RealmRepresentation testRealmRep = RealmBuilder.create().name(REALM_NAME).testEventListener().build();
+        testRealmRep.setId(REALM_NAME);
         testRealms.add(testRealmRep);
     }
 
@@ -182,4 +191,11 @@ public abstract class AbstractAuthenticationTest extends AbstractKeycloakTest {
         config.setConfig(params);
         return config;
     }
+
+    void createFlow(AuthenticationFlowRepresentation flowRep) {
+        Response response = authMgmtResource.createFlow(flowRep);
+        org.keycloak.testsuite.Assert.assertEquals(201, response.getStatus());
+        response.close();
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AssertAdminEvents.isExpectedPrefixFollowedByUuid(AdminEventPaths.authFlowsPath()), flowRep);
+    }
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/AuthenticatorConfigTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/AuthenticatorConfigTest.java
index c5f7ed1..eb1cda5 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/AuthenticatorConfigTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/AuthenticatorConfigTest.java
@@ -28,11 +28,14 @@ import org.junit.Before;
 import org.junit.Test;
 import org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticator;
 import org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticatorFactory;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
 import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
 import org.keycloak.representations.idm.AuthenticatorConfigRepresentation;
 import org.keycloak.testsuite.Assert;
 import org.keycloak.testsuite.admin.ApiUtil;
+import org.keycloak.testsuite.util.AdminEventPaths;
+import org.keycloak.testsuite.util.AssertAdminEvents;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@@ -43,13 +46,13 @@ public class AuthenticatorConfigTest extends AbstractAuthenticationTest {
 
     @Before
     public void beforeConfigTest() {
-        Response response = authMgmtResource.createFlow(newFlow("firstBrokerLogin2", "firstBrokerLogin2", "basic-flow", true, false));
-        Assert.assertEquals(201, response.getStatus());
-        response.close();
+        AuthenticationFlowRepresentation flowRep = newFlow("firstBrokerLogin2", "firstBrokerLogin2", "basic-flow", true, false);
+        createFlow(flowRep);
 
         HashMap<String, String> params = new HashMap<>();
         params.put("provider", IdpCreateUserIfUniqueAuthenticatorFactory.PROVIDER_ID);
         authMgmtResource.addExecution("firstBrokerLogin2", params);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("firstBrokerLogin2"), params);
 
         List<AuthenticationExecutionInfoRepresentation> executionReps = authMgmtResource.getExecutions("firstBrokerLogin2");
         AuthenticationExecutionInfoRepresentation exec = findExecutionByProvider(IdpCreateUserIfUniqueAuthenticatorFactory.PROVIDER_ID, executionReps);
@@ -57,12 +60,6 @@ public class AuthenticatorConfigTest extends AbstractAuthenticationTest {
         executionId = exec.getId();
     }
 
-    @Override
-    public void afterAbstractKeycloakTest() {
-        AuthenticationFlowRepresentation flowRep = findFlowByAlias("firstBrokerLogin2", authMgmtResource.getFlows());
-        authMgmtResource.deleteFlow(flowRep.getId());
-    }
-
 
     @Test
     public void testCreateConfig() {
@@ -82,6 +79,7 @@ public class AuthenticatorConfigTest extends AbstractAuthenticationTest {
 
         // Cleanup
         authMgmtResource.removeAuthenticatorConfig(cfgId);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionConfigPath(cfgId));
     }
 
 
@@ -107,6 +105,7 @@ public class AuthenticatorConfigTest extends AbstractAuthenticationTest {
         cfgRep.setAlias("foo2");
         cfgRep.getConfig().put("configKey2", "configValue2");
         authMgmtResource.updateAuthenticatorConfig(cfgRep.getId(), cfgRep);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authExecutionConfigPath(cfgId), cfgRep);
 
         // Assert updated
         cfgRep = authMgmtResource.getAuthenticatorConfig(cfgRep.getId());
@@ -137,7 +136,8 @@ public class AuthenticatorConfigTest extends AbstractAuthenticationTest {
         }
 
         // Test remove our config
-        authMgmtResource.removeAuthenticatorConfig(cfgRep.getId());
+        authMgmtResource.removeAuthenticatorConfig(cfgId);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionConfigPath(cfgId));
 
         // Assert config not found
         try {
@@ -159,6 +159,7 @@ public class AuthenticatorConfigTest extends AbstractAuthenticationTest {
         Assert.assertEquals(201, resp.getStatus());
         String cfgId = ApiUtil.getCreatedId(resp);
         Assert.assertNotNull(cfgId);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionConfigPath(executionId), cfg);
         return cfgId;
     }
 
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ExecutionTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ExecutionTest.java
index be0b9c4..ae19ff6 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ExecutionTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ExecutionTest.java
@@ -21,10 +21,12 @@ import org.junit.Assert;
 import org.junit.Test;
 import org.keycloak.authentication.AuthenticationFlow;
 import org.keycloak.authentication.authenticators.client.ClientIdAndSecretAuthenticator;
-import org.keycloak.models.AuthenticationExecutionModel;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
 import org.keycloak.representations.idm.AuthenticationExecutionRepresentation;
 import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
+import org.keycloak.testsuite.util.AdminEventPaths;
+import org.keycloak.testsuite.util.AssertAdminEvents;
 
 import javax.ws.rs.BadRequestException;
 import javax.ws.rs.NotFoundException;
@@ -60,8 +62,9 @@ public class ExecutionTest extends AbstractAuthenticationTest {
         }
 
         // copy built-in flow so we get a new editable flow
-        params.put("newName", "Copy of browser");
+        params.put("newName", "Copy-of-browser");
         Response response = authMgmtResource.copy("browser", params);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authCopyFlowPath("browser"), params);
         try {
             Assert.assertEquals("Copy flow", 201, response.getStatus());
         } finally {
@@ -71,17 +74,19 @@ public class ExecutionTest extends AbstractAuthenticationTest {
         // add execution using inexistent provider
         params.put("provider", "test-execution");
         try {
-            authMgmtResource.addExecution("Copy of browser", params);
+            authMgmtResource.addExecution("CopyOfBrowser", params);
             Assert.fail("add execution with inexistent provider should fail");
         } catch(BadRequestException expected) {
+            // Expected
         }
 
         // add execution - should succeed
         params.put("provider", "idp-review-profile");
-        authMgmtResource.addExecution("Copy of browser", params);
+        authMgmtResource.addExecution("Copy-of-browser", params);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("Copy-of-browser"), params);
 
         // check execution was added
-        List<AuthenticationExecutionInfoRepresentation> executionReps = authMgmtResource.getExecutions("Copy of browser");
+        List<AuthenticationExecutionInfoRepresentation> executionReps = authMgmtResource.getExecutions("Copy-of-browser");
         AuthenticationExecutionInfoRepresentation exec = findExecutionByProvider("idp-review-profile", executionReps);
         Assert.assertNotNull("idp-review-profile added", exec);
 
@@ -92,9 +97,10 @@ public class ExecutionTest extends AbstractAuthenticationTest {
 
         // remove execution
         authMgmtResource.removeExecution(exec.getId());
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionPath(exec.getId()));
 
         // check execution was removed
-        executionReps = authMgmtResource.getExecutions("Copy of browser");
+        executionReps = authMgmtResource.getExecutions("Copy-of-browser");
         exec = findExecutionByProvider("idp-review-profile", executionReps);
         Assert.assertNull("idp-review-profile removed", exec);
 
@@ -102,6 +108,7 @@ public class ExecutionTest extends AbstractAuthenticationTest {
 
         // delete auth-cookie
         authMgmtResource.removeExecution(authCookieExec.getId());
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionPath(authCookieExec.getId()));
 
         AuthenticationExecutionRepresentation rep = new AuthenticationExecutionRepresentation();
         rep.setPriority(10);
@@ -135,13 +142,14 @@ public class ExecutionTest extends AbstractAuthenticationTest {
             response.close();
         }
 
-        // get Copy of browser flow id, and set it on execution
+        // get Copy-of-browser flow id, and set it on execution
         List<AuthenticationFlowRepresentation> flows = authMgmtResource.getFlows();
-        AuthenticationFlowRepresentation flow = findFlowByAlias("Copy of browser", flows);
+        AuthenticationFlowRepresentation flow = findFlowByAlias("Copy-of-browser", flows);
         rep.setParentFlow(flow.getId());
 
         // add execution - should succeed
         response = authMgmtResource.addExecution(rep);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AssertAdminEvents.isExpectedPrefixFollowedByUuid(AdminEventPaths.authMgmtBasePath() + "/executions"), rep);
         try {
             Assert.assertEquals("added execution", 201, response.getStatus());
         } finally {
@@ -149,7 +157,7 @@ public class ExecutionTest extends AbstractAuthenticationTest {
         }
 
         // check execution was added
-        List<AuthenticationExecutionInfoRepresentation> executions = authMgmtResource.getExecutions("Copy of browser");
+        List<AuthenticationExecutionInfoRepresentation> executions = authMgmtResource.getExecutions("Copy-of-browser");
         exec = findExecutionByProvider("auth-cookie", executions);
         Assert.assertNotNull("auth-cookie added", exec);
 
@@ -170,6 +178,7 @@ public class ExecutionTest extends AbstractAuthenticationTest {
         // switch from DISABLED to ALTERNATIVE
         exec.setRequirement(DISABLED);
         authMgmtResource.updateExecutions("browser", exec);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("browser"), exec);
 
         // make sure the change is visible
         executionReps = authMgmtResource.getExecutions("browser");
@@ -183,14 +192,13 @@ public class ExecutionTest extends AbstractAuthenticationTest {
     public void testClientFlowExecutions() {
         // Create client flow
         AuthenticationFlowRepresentation clientFlow = newFlow("new-client-flow", "desc", AuthenticationFlow.CLIENT_FLOW, true, false);
-        Response response = authMgmtResource.createFlow(clientFlow);
-        Assert.assertEquals(201, response.getStatus());
-        response.close();
+        createFlow(clientFlow);
 
         // Add execution to it
         Map<String, String> executionData = new HashMap<>();
         executionData.put("provider", ClientIdAndSecretAuthenticator.PROVIDER_ID);
         authMgmtResource.addExecution("new-client-flow", executionData);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("new-client-flow"), executionData);
 
         // Check executions of not-existent flow - SHOULD FAIL
         try {
@@ -226,6 +234,7 @@ public class ExecutionTest extends AbstractAuthenticationTest {
         // Update success
         executionRep.setRequirement(ALTERNATIVE);
         authMgmtResource.updateExecutions("new-client-flow", executionRep);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("new-client-flow"), executionRep);
 
         // Check updated
         executionRep = findExecutionByProvider(ClientIdAndSecretAuthenticator.PROVIDER_ID, authMgmtResource.getExecutions("new-client-flow"));
@@ -241,7 +250,10 @@ public class ExecutionTest extends AbstractAuthenticationTest {
 
         // Successfuly remove execution and flow
         authMgmtResource.removeExecution(executionRep.getId());
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionPath(executionRep.getId()));
+
         AuthenticationFlowRepresentation rep = findFlowByAlias("new-client-flow", authMgmtResource.getFlows());
         authMgmtResource.deleteFlow(rep.getId());
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authFlowPath(rep.getId()));
     }
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/FlowTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/FlowTest.java
index 80d17bb..7e2f4a8 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/FlowTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/FlowTest.java
@@ -19,8 +19,10 @@ package org.keycloak.testsuite.admin.authentication;
 
 import org.junit.Assert;
 import org.junit.Test;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
 import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
+import org.keycloak.testsuite.util.AdminEventPaths;
 
 import javax.ws.rs.BadRequestException;
 import javax.ws.rs.NotFoundException;
@@ -67,12 +69,7 @@ public class FlowTest extends AbstractAuthenticationTest {
 
         // create new flow that should succeed
         AuthenticationFlowRepresentation newFlow = newFlow("browser-2", "Browser flow", "basic-flow", true, false);
-        response = authMgmtResource.createFlow(newFlow);
-        try {
-            Assert.assertEquals("createFlow success", 201, response.getStatus());
-        } finally {
-            response.close();
-        }
+        createFlow(newFlow);
 
         // check that new flow is returned in a children list
         flows = authMgmtResource.getFlows();
@@ -122,6 +119,7 @@ public class FlowTest extends AbstractAuthenticationTest {
         // Successfully add flow
         data.put("alias", "SomeFlow");
         authMgmtResource.addExecutionFlow("browser-2", data);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionFlowPath("browser-2"), data);
 
         // check that new flow is returned in a children list
         flows = authMgmtResource.getFlows();
@@ -143,6 +141,7 @@ public class FlowTest extends AbstractAuthenticationTest {
 
         // delete non-built-in flow
         authMgmtResource.deleteFlow(found.getId());
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authFlowPath(found.getId()));
 
         // check the deleted flow is no longer returned
         flows = authMgmtResource.getFlows();
@@ -185,6 +184,7 @@ public class FlowTest extends AbstractAuthenticationTest {
         // copy that should succeed
         params.put("newName", "Copy of browser");
         response = authMgmtResource.copy("browser", params);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authCopyFlowPath("browser"), params);
         try {
             Assert.assertEquals("Copy flow", 201, response.getStatus());
         } finally {
@@ -219,6 +219,7 @@ public class FlowTest extends AbstractAuthenticationTest {
         Response response = authMgmtResource.copy("browser", params);
         Assert.assertEquals(201, response.getStatus());
         response.close();
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authCopyFlowPath("browser"), params);
 
         params = new HashMap<>();
         params.put("alias", "child");
@@ -227,6 +228,7 @@ public class FlowTest extends AbstractAuthenticationTest {
         params.put("type", "basic-flow");
 
         authMgmtResource.addExecutionFlow("parent", params);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionFlowPath("parent"), params);
     }
 
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RegistrationFlowTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RegistrationFlowTest.java
index bf2babe..d7e25b6 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RegistrationFlowTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RegistrationFlowTest.java
@@ -25,6 +25,9 @@ import javax.ws.rs.core.Response;
 
 import org.junit.Assert;
 import org.junit.Test;
+import org.keycloak.events.admin.OperationType;
+import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
+import org.keycloak.testsuite.util.AdminEventPaths;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@@ -34,13 +37,8 @@ public class RegistrationFlowTest extends AbstractAuthenticationTest {
     @Test
     public void testAddExecution() {
         // Add registration flow 2
-        Response response = authMgmtResource.createFlow(newFlow("registration2", "RegistrationFlow2", "basic-flow", true, false));
-        try {
-            Assert.assertEquals("createFlow success", 201, response.getStatus());
-        } finally {
-            response.close();
-        }
-
+        AuthenticationFlowRepresentation flowRep = newFlow("registration2", "RegistrationFlow2", "basic-flow", true, false);
+        createFlow(flowRep);
 
         // add registration execution form flow
         Map<String, String> data = new HashMap<>();
@@ -49,6 +47,7 @@ public class RegistrationFlowTest extends AbstractAuthenticationTest {
         data.put("description", "registrationForm2 flow");
         data.put("provider", "registration-page-form");
         authMgmtResource.addExecutionFlow("registration2", data);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionFlowPath("registration2"), data);
 
         // Should fail to add execution under top level flow
         Map<String, String> data2 = new HashMap<>();
@@ -63,9 +62,9 @@ public class RegistrationFlowTest extends AbstractAuthenticationTest {
 
         // Should success to add execution under form flow
         authMgmtResource.addExecution("registrationForm2", data2);
-
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("registrationForm2"), data2);
     }
 
-    // TODO: More coverage... And hopefully more type-safety instead of passing generic maps
+    // TODO: More type-safety instead of passing generic maps
 
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RequiredActionsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RequiredActionsTest.java
index 7418cb1..8d45830 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RequiredActionsTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RequiredActionsTest.java
@@ -19,9 +19,11 @@ package org.keycloak.testsuite.admin.authentication;
 
 import org.junit.Assert;
 import org.junit.Test;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
 import org.keycloak.representations.idm.RequiredActionProviderSimpleRepresentation;
 import org.keycloak.testsuite.actions.DummyRequiredActionFactory;
+import org.keycloak.testsuite.util.AdminEventPaths;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -59,6 +61,7 @@ public class RequiredActionsTest extends AbstractAuthenticationTest {
 
         forUpdate.setConfig(Collections.<String, String>emptyMap());
         authMgmtResource.updateRequiredAction(forUpdate.getAlias(), forUpdate);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authRequiredActionPath(forUpdate.getAlias()));
 
         result = authMgmtResource.getRequiredActions();
         RequiredActionProviderRepresentation updated = findRequiredActionByAlias(forUpdate.getAlias(), result);
@@ -78,6 +81,7 @@ public class RequiredActionsTest extends AbstractAuthenticationTest {
 
         // Register it
         authMgmtResource.registerRequiredAction(action);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authMgmtBasePath() + "/register-required-action", action);
 
         // Try to find not-existent action - should fail
         try {
@@ -103,6 +107,7 @@ public class RequiredActionsTest extends AbstractAuthenticationTest {
         // Update (set it as defaultAction)
         rep.setDefaultAction(true);
         authMgmtResource.updateRequiredAction(DummyRequiredActionFactory.PROVIDER_ID, rep);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authRequiredActionPath(rep.getAlias()), rep);
         compareRequiredAction(rep, newRequiredAction(DummyRequiredActionFactory.PROVIDER_ID, "Dummy Action",
                 true, true, Collections.emptyMap()));
 
@@ -116,6 +121,7 @@ public class RequiredActionsTest extends AbstractAuthenticationTest {
 
         // Remove success
         authMgmtResource.removeRequiredAction(DummyRequiredActionFactory.PROVIDER_ID);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authRequiredActionPath(rep.getAlias()));
 
     }
 
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ShiftExecutionTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ShiftExecutionTest.java
index 9ce4f53..ba8ae09 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ShiftExecutionTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/ShiftExecutionTest.java
@@ -19,7 +19,9 @@ package org.keycloak.testsuite.admin.authentication;
 
 import org.junit.Assert;
 import org.junit.Test;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
+import org.keycloak.testsuite.util.AdminEventPaths;
 
 import javax.ws.rs.NotFoundException;
 import javax.ws.rs.BadRequestException;
@@ -39,6 +41,7 @@ public class ShiftExecutionTest extends AbstractAuthenticationTest {
         HashMap<String, String> params = new HashMap<>();
         params.put("newName", "Copy of browser");
         Response response = authMgmtResource.copy("browser", params);
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authCopyFlowPath("browser"), params);
         try {
             Assert.assertEquals("Copy flow", 201, response.getStatus());
         } finally {
@@ -61,6 +64,7 @@ public class ShiftExecutionTest extends AbstractAuthenticationTest {
 
         // shift last execution up
         authMgmtResource.raisePriority(last.getId());
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authRaiseExecutionPath(last.getId()));
 
         List<AuthenticationExecutionInfoRepresentation> executions2 = authMgmtResource.getExecutions("Copy of browser");
 
@@ -80,6 +84,7 @@ public class ShiftExecutionTest extends AbstractAuthenticationTest {
 
         // shift one before last down
         authMgmtResource.lowerPriority(oneButLast2.getId());
+        assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authLowerExecutionPath(oneButLast2.getId()));
 
         executions2 = authMgmtResource.getExecutions("Copy of browser");
 
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientRolesTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientRolesTest.java
index 19c9822..aed3461 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientRolesTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientRolesTest.java
@@ -17,7 +17,6 @@
 
 package org.keycloak.testsuite.admin.client;
 
-import org.hamcrest.Matchers;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -27,7 +26,6 @@ import org.keycloak.events.admin.OperationType;
 import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.testsuite.Assert;
 import org.keycloak.testsuite.util.AdminEventPaths;
-import org.keycloak.testsuite.util.RoleBuilder;
 
 import java.util.LinkedList;
 import java.util.List;
@@ -75,15 +73,17 @@ public class ClientRolesTest extends AbstractClientTest {
 
     @Test
     public void testAddRole() {
-        rolesRsc.create(makeRole("role1"));
-        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, Matchers.startsWith(AdminEventPaths.clientRolesResourcePath(clientDbId)));
+        RoleRepresentation role1 = makeRole("role1");
+        rolesRsc.create(role1);
+        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role1"), role1);
         assertTrue(hasRole(rolesRsc, "role1"));
     }
 
     @Test
     public void testRemoveRole() {
-        rolesRsc.create(makeRole("role2"));
-        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, Matchers.startsWith(AdminEventPaths.clientRolesResourcePath(clientDbId)));
+        RoleRepresentation role2 = makeRole("role2");
+        rolesRsc.create(role2);
+        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role2"), role2);
 
         rolesRsc.deleteRole("role2");
         assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role2"));
@@ -93,25 +93,26 @@ public class ClientRolesTest extends AbstractClientTest {
 
     @Test
     public void testComposites() {
-        rolesRsc.create(makeRole("role-a"));
-        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, Matchers.startsWith(AdminEventPaths.clientRolesResourcePath(clientDbId)));
+        RoleRepresentation roleA = makeRole("role-a");
+        rolesRsc.create(roleA);
+        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role-a"), roleA);
 
         assertFalse(rolesRsc.get("role-a").toRepresentation().isComposite());
         assertEquals(0, rolesRsc.get("role-a").getRoleComposites().size());
 
-        rolesRsc.create(makeRole("role-b"));
-        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, Matchers.startsWith(AdminEventPaths.clientRolesResourcePath(clientDbId)));
+        RoleRepresentation roleB = makeRole("role-b");
+        rolesRsc.create(roleB);
+        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role-b"), roleB);
 
-        testRealmResource().roles().create(makeRole("role-c"));
-        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, Matchers.startsWith(AdminEventPaths.rolesResourcePath()));
+        RoleRepresentation roleC = makeRole("role-c");
+        testRealmResource().roles().create(roleC);
+        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.roleResourcePath("role-c"), roleC);
 
         List<RoleRepresentation> l = new LinkedList<>();
         l.add(rolesRsc.get("role-b").toRepresentation());
         l.add(testRealmResource().roles().get("role-c").toRepresentation());
         rolesRsc.get("role-a").addComposites(l);
-        // TODO adminEvents: Fix once composite roles events will be fixed...
-        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, Matchers.startsWith(AdminEventPaths.clientRoleResourceCompositesPath(clientDbId, "role-a")));
-        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, Matchers.startsWith(AdminEventPaths.clientRoleResourceCompositesPath(clientDbId, "role-a")));
+        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourceCompositesPath(clientDbId, "role-a"), l);
 
         Set<RoleRepresentation> composites = rolesRsc.get("role-a").getRoleComposites();
 
@@ -125,7 +126,7 @@ public class ClientRolesTest extends AbstractClientTest {
         Assert.assertNames(clientComposites, "role-b");
 
         rolesRsc.get("role-a").deleteComposites(l);
-        assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientRoleResourceCompositesPath(clientDbId, "role-a"));
+        assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientRoleResourceCompositesPath(clientDbId, "role-a"), l);
 
         assertFalse(rolesRsc.get("role-a").toRepresentation().isComposite());
         assertEquals(0, rolesRsc.get("role-a").getRoleComposites().size());
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateProtocolMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateProtocolMapperTest.java
index 39fd220..1036005 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateProtocolMapperTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateProtocolMapperTest.java
@@ -26,7 +26,6 @@ import org.junit.Before;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
-import org.keycloak.admin.client.resource.ClientTemplateResource;
 import org.keycloak.admin.client.resource.ClientTemplatesResource;
 import org.keycloak.admin.client.resource.ProtocolMappersResource;
 import org.keycloak.events.admin.OperationType;
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateTest.java
index 86ab249..2b469a9 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientTemplateTest.java
@@ -27,7 +27,6 @@ import javax.ws.rs.BadRequestException;
 import javax.ws.rs.NotFoundException;
 import javax.ws.rs.core.Response;
 
-import org.hamcrest.Matchers;
 import org.junit.Assert;
 import org.junit.Test;
 import org.keycloak.admin.client.resource.ClientTemplatesResource;
@@ -162,7 +161,7 @@ public class ClientTemplateTest extends AbstractClientTest {
 
         // Add role2 as composite to role1
         testRealmResource().roles().get("role1").addComposites(Collections.singletonList(roleRep2));
-        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, Matchers.startsWith(AdminEventPaths.roleResourceCompositesPath("role1")));
+        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.roleResourceCompositesPath("role1"), Collections.singletonList(roleRep2));
 
         // create client template
         ClientTemplateRepresentation templateRep = new ClientTemplateRepresentation();
@@ -176,10 +175,10 @@ public class ClientTemplateTest extends AbstractClientTest {
         RoleMappingResource scopesResource = clientTemplates().get(templateId).getScopeMappings();
 
         scopesResource.realmLevel().add(Collections.singletonList(roleRep1));
-        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId) + "/" + roleRep1.getId());
+        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId), Collections.singletonList(roleRep1));
 
         scopesResource.clientLevel(accountMgmtId).add(Collections.singletonList(viewAccountRoleRep));
-        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsClientLevelPath(templateId, accountMgmtId) + "/" + viewAccountRoleRep.getId());
+        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsClientLevelPath(templateId, accountMgmtId), Collections.singletonList(viewAccountRoleRep));
 
         // test that scopes are available (also through composite role)
         List<RoleRepresentation> allRealm = scopesResource.realmLevel().listAll();
@@ -198,10 +197,10 @@ public class ClientTemplateTest extends AbstractClientTest {
 
         // remove scopes
         scopesResource.realmLevel().remove(Collections.singletonList(roleRep1));
-        assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId) + "/" + roleRep1.getId());
+        assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId), Collections.singletonList(roleRep1));
 
         scopesResource.clientLevel(accountMgmtId).remove(Collections.singletonList(viewAccountRoleRep));
-        assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateScopeMappingsClientLevelPath(templateId, accountMgmtId) + "/" + viewAccountRoleRep.getId());
+        assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateScopeMappingsClientLevelPath(templateId, accountMgmtId), Collections.singletonList(viewAccountRoleRep));
 
         // assert scopes are removed
         allRealm = scopesResource.realmLevel().listAll();
@@ -256,7 +255,7 @@ public class ClientTemplateTest extends AbstractClientTest {
 
         // Add realm role to scopes of clientTemplate
         clientTemplates().get(templateId).getScopeMappings().realmLevel().add(Collections.singletonList(roleRep));
-        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId) + "/" + roleRep.getId());
+        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId), Collections.singletonList(roleRep));
 
         List<RoleRepresentation> roleReps = clientTemplates().get(templateId).getScopeMappings().realmLevel().listAll();
         Assert.assertEquals(1, roleReps.size());
@@ -279,7 +278,7 @@ public class ClientTemplateTest extends AbstractClientTest {
         roleRep.setName(roleName);
         testRealmResource().roles().create(roleRep);
 
-        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, Matchers.startsWith(AdminEventPaths.rolesResourcePath()));
+        assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.roleResourcePath(roleName), roleRep);
 
         return testRealmResource().roles().get(roleName).toRepresentation();
     }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java
index 03f9cef..fc7a341 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java
@@ -17,7 +17,6 @@
 
 package org.keycloak.testsuite.admin;
 
-import org.hamcrest.Matchers;
 import org.junit.Test;
 import org.keycloak.OAuth2Constants;
 import org.keycloak.admin.client.resource.ClientResource;
@@ -43,10 +42,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.keycloak.services.resources.admin.ScopeMappedResource;
 import org.keycloak.testsuite.Assert;
 import org.keycloak.testsuite.util.AdminEventPaths;
-import org.keycloak.testsuite.util.AssertAdminEvents;
 import org.keycloak.testsuite.util.ClientBuilder;
 import org.keycloak.testsuite.util.CredentialBuilder;
 import org.keycloak.testsuite.util.OAuthClient;
@@ -154,7 +151,7 @@ public class ClientTest extends AbstractAdminTest {
         RoleRepresentation role = new RoleRepresentation("test", "test", false);
         realm.clients().get(id).roles().create(role);
 
-        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, Matchers.startsWith(AdminEventPaths.clientRolesResourcePath(id)), role);
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(id, "test"), role);
 
         ClientRepresentation foundClientRep = realm.clients().get(id).toRepresentation();
         foundClientRep.setDefaultRoles(new String[]{"test"});
@@ -258,18 +255,18 @@ public class ClientTest extends AbstractAdminTest {
         ClientRepresentation client = createAppClient();
         String id = client.getId();
 
-        realm.clients().get(id).registerNode(Collections.singletonMap("node", suiteContext.getAuthServerInfo().getContextRoot().getHost()));
+        String myhost = suiteContext.getAuthServerInfo().getContextRoot().getHost();
+        realm.clients().get(id).registerNode(Collections.singletonMap("node", myhost));
         realm.clients().get(id).registerNode(Collections.singletonMap("node", "invalid"));
 
-        // TODO adminEvents: should be rather CREATE and include nodePath like in DELETE event
-        assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.clientNodesPath(id));
-        assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.clientNodesPath(id));
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientNodePath(id, myhost));
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientNodePath(id, "invalid"));
 
         GlobalRequestResult result = realm.clients().get(id).testNodesAvailable();
         assertEquals(1, result.getSuccessRequests().size());
         assertEquals(1, result.getFailedRequests().size());
 
-        assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.clientTestNodesAvailablePath(id));
+        assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.clientTestNodesAvailablePath(id), result);
 
         TestAvailabilityAction testAvailable = testingClient.testApp().getTestAvailable();
         assertEquals("test-app", testAvailable.getResource());
@@ -327,28 +324,24 @@ public class ClientTest extends AbstractAdminTest {
         realm.roles().create(roleRep1);
         realm.roles().create(roleRep2);
 
-        AssertAdminEvents.ExpectedAdminEvent adminEvent = assertAdminEvents.expect()
-                .realmId(realmId)
-                .operationType(OperationType.CREATE)
-                .resourcePath(Matchers.startsWith(AdminEventPaths.rolesResourcePath()));
-        adminEvent.representation(roleRep1).assertEvent();
-        adminEvent.representation(roleRep2).assertEvent();
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role1"), roleRep1);
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role2"), roleRep2);
 
         roleRep1 = realm.roles().get("role1").toRepresentation();
         roleRep2 = realm.roles().get("role2").toRepresentation();
 
         realm.roles().get("role1").addComposites(Collections.singletonList(roleRep2));
 
-        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, Matchers.startsWith(AdminEventPaths.roleResourceCompositesPath("role1")));
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourceCompositesPath("role1"), Collections.singletonList(roleRep2));
 
         String accountMgmtId = realm.clients().findByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).get(0).getId();
         RoleRepresentation viewAccountRoleRep = realm.clients().get(accountMgmtId).roles().get(AccountRoles.VIEW_PROFILE).toRepresentation();
 
         scopesResource.realmLevel().add(Collections.singletonList(roleRep1));
-        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientScopeMappingsRealmLevelPath(id) + "/" + roleRep1.getId());
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientScopeMappingsRealmLevelPath(id), Collections.singletonList(roleRep1));
 
         scopesResource.clientLevel(accountMgmtId).add(Collections.singletonList(viewAccountRoleRep));
-        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientScopeMappingsClientLevelPath(id, accountMgmtId) + "/" + viewAccountRoleRep.getId());
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientScopeMappingsClientLevelPath(id, accountMgmtId), Collections.singletonList(viewAccountRoleRep));
 
         Assert.assertNames(scopesResource.realmLevel().listAll(), "role1");
         Assert.assertNames(scopesResource.realmLevel().listEffective(), "role1", "role2");
@@ -362,10 +355,10 @@ public class ClientTest extends AbstractAdminTest {
         Assert.assertNames(scopesResource.getAll().getClientMappings().get(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).getMappings(), AccountRoles.VIEW_PROFILE);
 
         scopesResource.realmLevel().remove(Collections.singletonList(roleRep1));
-        assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientScopeMappingsRealmLevelPath(id) + "/" + roleRep1.getId());
+        assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientScopeMappingsRealmLevelPath(id), Collections.singletonList(roleRep1));
 
         scopesResource.clientLevel(accountMgmtId).remove(Collections.singletonList(viewAccountRoleRep));
-        assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientScopeMappingsClientLevelPath(id, accountMgmtId) + "/" + viewAccountRoleRep.getId());
+        assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientScopeMappingsClientLevelPath(id, accountMgmtId), Collections.singletonList(viewAccountRoleRep));
 
         Assert.assertNames(scopesResource.realmLevel().listAll());
         Assert.assertNames(scopesResource.realmLevel().listEffective());
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java
index 7d24027..dcc70b1 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java
@@ -23,6 +23,7 @@ import org.junit.Test;
 import org.keycloak.admin.client.resource.RealmResource;
 import org.keycloak.admin.client.resource.RoleMappingResource;
 import org.keycloak.events.admin.OperationType;
+import org.keycloak.models.RoleModel;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.representations.idm.ClientRepresentation;
 import org.keycloak.representations.idm.CredentialRepresentation;
@@ -109,7 +110,7 @@ public class GroupTest extends AbstractGroupTest {
         RoleRepresentation role = new RoleRepresentation();
         role.setName("foo-role");
         realm.clients().get(client.getId()).roles().create(role);
-        assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.clientRolesResourcePath(clientUuid)), role);
+        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientUuid, "foo-role"), role);
         role = realm.clients().get(client.getId()).roles().get("foo-role").toRepresentation();
 
         GroupRepresentation group = new GroupRepresentation();
@@ -119,7 +120,7 @@ public class GroupTest extends AbstractGroupTest {
         List<RoleRepresentation> list = new LinkedList<>();
         list.add(role);
         realm.groups().group(group.getId()).roles().clientLevel(client.getId()).add(list);
-        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientUuid));
+        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientUuid), list);
 
         realm.clients().get(client.getId()).remove();
         assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.clientResourcePath(clientUuid));
@@ -130,8 +131,7 @@ public class GroupTest extends AbstractGroupTest {
         String groupId = ApiUtil.getCreatedId(response);
         response.close();
 
-        // TODO adminEvents: ID of group is missing in create event
-        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupsPath(), group);
+        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupPath(groupId), group);
 
         // Set ID to the original rep
         group.setId(groupId);
@@ -171,14 +171,13 @@ public class GroupTest extends AbstractGroupTest {
         List<RoleRepresentation> roles = new LinkedList<>();
         roles.add(topRole);
         realm.groups().group(topGroup.getId()).roles().realmLevel().add(roles);
-        assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.groupRolesRealmRolesPath(topGroup.getId())));
+        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(topGroup.getId()), roles);
 
         GroupRepresentation level2Group = new GroupRepresentation();
         level2Group.setName("level2");
         Response response = realm.groups().group(topGroup.getId()).subGroup(level2Group);
         response.close();
-        // TODO adminEvents: Should be CREATE
-        assertAdminEvents.assertEvent("test", OperationType.UPDATE, AdminEventPaths.groupSubgroupsPath(topGroup.getId()), level2Group);
+        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupSubgroupsPath(topGroup.getId()), level2Group);
 
         URI location = response.getLocation();
         final String level2Id = ApiUtil.getCreatedId(response);
@@ -199,21 +198,20 @@ public class GroupTest extends AbstractGroupTest {
         roles.clear();
         roles.add(level2Role);
         realm.groups().group(level2Group.getId()).roles().realmLevel().add(roles);
-        assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.groupRolesRealmRolesPath(level2Group.getId())));
+        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(level2Group.getId()), roles);
 
         GroupRepresentation level3Group = new GroupRepresentation();
         level3Group.setName("level3");
         response = realm.groups().group(level2Group.getId()).subGroup(level3Group);
         response.close();
-        // TODO adminEvents: Should be CREATE
-        assertAdminEvents.assertEvent("test", OperationType.UPDATE, AdminEventPaths.groupSubgroupsPath(level2Group.getId()), level3Group);
+        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupSubgroupsPath(level2Group.getId()), level3Group);
 
         level3Group = realm.getGroupByPath("/top/level2/level3");
         Assert.assertNotNull(level3Group);
         roles.clear();
         roles.add(level3Role);
         realm.groups().group(level3Group.getId()).roles().realmLevel().add(roles);
-        assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.groupRolesRealmRolesPath(level3Group.getId())));
+        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(level3Group.getId()), roles);
 
         topGroup = realm.getGroupByPath("/top");
         assertEquals(1, topGroup.getRealmRoles().size());
@@ -233,7 +231,7 @@ public class GroupTest extends AbstractGroupTest {
 
         UserRepresentation user = realm.users().search("direct-login", -1, -1).get(0);
         realm.users().get(user.getId()).joinGroup(level3Group.getId());
-        assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.userGroupPath(user.getId(), level3Group.getId())));
+        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userGroupPath(user.getId(), level3Group.getId()));
 
         List<GroupRepresentation> membership = realm.users().get(user.getId()).groups();
         assertEquals(1, membership.size());
@@ -245,6 +243,7 @@ public class GroupTest extends AbstractGroupTest {
         assertTrue(token.getRealmAccess().getRoles().contains("level3Role"));
 
         realm.addDefaultGroup(level3Group.getId());
+        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.defaultGroupPath(level3Group.getId()));
 
         List<GroupRepresentation> defaultGroups = realm.getDefaultGroups();
         assertEquals(1, defaultGroups.size());
@@ -263,6 +262,8 @@ public class GroupTest extends AbstractGroupTest {
         assertEquals("level3", membership.get(0).getName());
 
         realm.removeDefaultGroup(level3Group.getId());
+        assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.defaultGroupPath(level3Group.getId()));
+
         defaultGroups = realm.getDefaultGroups();
         assertEquals(0, defaultGroups.size());
 
@@ -348,19 +349,19 @@ public class GroupTest extends AbstractGroupTest {
         assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userResourcePath(userBId));
 
         realm.users().get(userAId).joinGroup(groupId);
-        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userGroupPath(userAId, groupId));
+        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userGroupPath(userAId, groupId), group);
 
         List<UserRepresentation> members = realm.groups().group(groupId).members(0, 10);
         assertNames(members, "user-a");
 
         realm.users().get(userBId).joinGroup(groupId);
-        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userGroupPath(userBId, groupId));
+        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userGroupPath(userBId, groupId), group);
 
         members = realm.groups().group(groupId).members(0, 10);
         assertNames(members, "user-a", "user-b");
 
         realm.users().get(userAId).leaveGroup(groupId);
-        assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.userGroupPath(userAId, groupId));
+        assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.userGroupPath(userAId, groupId), group);
 
         members = realm.groups().group(groupId).members(0, 10);
         assertNames(members, "user-b");
@@ -418,14 +419,15 @@ public class GroupTest extends AbstractGroupTest {
         l.add(realm.roles().get("realm-role").toRepresentation());
         l.add(realm.roles().get("realm-composite").toRepresentation());
         roles.realmLevel().add(l);
-        assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.groupRolesRealmRolesPath(group.getId())));
-        assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.groupRolesRealmRolesPath(group.getId())));
+        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(group.getId()), l);
 
         // Add client roles
-        roles.clientLevel(clientId).add(Collections.singletonList(realm.clients().get(clientId).roles().get("client-role").toRepresentation()));
-        roles.clientLevel(clientId).add(Collections.singletonList(realm.clients().get(clientId).roles().get("client-composite").toRepresentation()));
-        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId));
-        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId));
+        RoleRepresentation clientRole = realm.clients().get(clientId).roles().get("client-role").toRepresentation();
+        RoleRepresentation clientComposite = realm.clients().get(clientId).roles().get("client-composite").toRepresentation();
+        roles.clientLevel(clientId).add(Collections.singletonList(clientRole));
+        roles.clientLevel(clientId).add(Collections.singletonList(clientComposite));
+        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId), Collections.singletonList(clientRole));
+        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId), Collections.singletonList(clientComposite));
 
         // List realm roles
         assertNames(roles.realmLevel().listAll(), "realm-role", "realm-composite");
@@ -444,16 +446,15 @@ public class GroupTest extends AbstractGroupTest {
         assertNames(all.getClientMappings().get("myclient").getMappings(), "client-role", "client-composite");
 
         // Remove realm role
-        // TODO adminEvents: DEleting group realmRole mapping has ID in the end. For deleting clientRole not.
         RoleRepresentation realmRoleRep = realm.roles().get("realm-role").toRepresentation();
         roles.realmLevel().remove(Collections.singletonList(realmRoleRep));
-        assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.groupRolesRealmRolesPath(group.getId()) + "/" + realmRoleRep.getId());
+        assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.groupRolesRealmRolesPath(group.getId()), Collections.singletonList(realmRoleRep));
         assertNames(roles.realmLevel().listAll(), "realm-composite");
 
         // Remove client role
         RoleRepresentation clientRoleRep = realm.clients().get(clientId).roles().get("client-role").toRepresentation();
         roles.clientLevel(clientId).remove(Collections.singletonList(clientRoleRep));
-        assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId));
+        assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId), Collections.singletonList(clientRoleRep));
         assertNames(roles.clientLevel(clientId).listAll(), "client-composite");
     }
 
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java
index c346b68..a283cfc 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java
@@ -17,7 +17,6 @@
 
 package org.keycloak.testsuite.admin;
 
-import org.hamcrest.Matchers;
 import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput;
 import org.junit.Test;
 import org.keycloak.admin.client.resource.IdentityProviderResource;
@@ -166,8 +165,7 @@ public class IdentityProviderTest extends AbstractAdminTest {
         Assert.assertNotNull(ApiUtil.getCreatedId(response));
         response.close();
 
-        // TODO adminEvents: should rather use alias instead of internalId (same issue like for roles)
-        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, Matchers.startsWith(AdminEventPaths.identityProviderCreatePath()), idpRep);
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.identityProviderPath(idpRep.getAlias()), idpRep);
     }
 
     private IdentityProviderRepresentation createRep(String id, String providerId) {
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/InitialAccessTokenResourceTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/InitialAccessTokenResourceTest.java
index 2c56db8..9f9538d 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/InitialAccessTokenResourceTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/InitialAccessTokenResourceTest.java
@@ -69,13 +69,22 @@ public class InitialAccessTokenResourceTest extends AbstractAdminTest {
 
         rep.setCount(4);
         response = resource.create(rep);
-        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientInitialAccessPath(response.getId()), rep);
+        String lastId = response.getId();
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientInitialAccessPath(lastId), rep);
 
         List<ClientInitialAccessPresentation> list = resource.list();
         assertEquals(3, list.size());
 
         assertEquals(9, list.get(0).getCount() + list.get(1).getCount() + list.get(2).getCount());
         assertNull(list.get(0).getToken());
+
+        // Delete last and assert it was deleted
+        resource.delete(lastId);
+        assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientInitialAccessPath(lastId));
+
+        list = resource.list();
+        assertEquals(2, list.size());
+        assertEquals(5, list.get(0).getCount() + list.get(1).getCount());
     }
 
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmRolesTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmRolesTest.java
index ad54e4f..04221c0 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmRolesTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmRolesTest.java
@@ -17,10 +17,8 @@
 
 package org.keycloak.testsuite.admin.realm;
 
-import org.hamcrest.Matchers;
 import org.junit.Before;
 import org.junit.Test;
-import org.keycloak.admin.client.resource.RoleByIdResource;
 import org.keycloak.admin.client.resource.RolesResource;
 import org.keycloak.events.admin.OperationType;
 import org.keycloak.representations.idm.ClientRepresentation;
@@ -80,12 +78,11 @@ public class RealmRolesTest extends AbstractAdminTest {
 
         resource = adminClient.realm(REALM_NAME).roles();
 
-        // ResourcePath for event for creating role contains roleID instead of roleName (looks like a bug...)
-        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath(ids.get("role-a")), roleA);
-        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath(ids.get("role-b")), roleB);
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role-a"), roleA);
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role-b"), roleB);
 
         assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientResourcePath(clientUuid), clientRep);
-        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientUuid, ids.get("role-c")), roleC);
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientUuid, "role-c"), roleC);
     }
 
     @Test
@@ -138,9 +135,8 @@ public class RealmRolesTest extends AbstractAdminTest {
         l.add(RoleBuilder.create().id(ids.get("role-b")).build());
         l.add(RoleBuilder.create().id(ids.get("role-c")).build());
         resource.get("role-a").addComposites(l);
-        // TODO adminEvents: Fix once composite roles events will be fixed...
-        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, Matchers.startsWith(AdminEventPaths.roleResourceCompositesPath("role-a")));
-        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, Matchers.startsWith(AdminEventPaths.roleResourceCompositesPath("role-a")));
+
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourceCompositesPath("role-a"), l);
 
         Set<RoleRepresentation> composites = resource.get("role-a").getRoleComposites();
 
@@ -154,7 +150,7 @@ public class RealmRolesTest extends AbstractAdminTest {
         Assert.assertNames(clientComposites, "role-c");
 
         resource.get("role-a").deleteComposites(l);
-        assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleResourceCompositesPath("role-a"));
+        assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleResourceCompositesPath("role-a"), l);
 
         assertFalse(resource.get("role-a").toRepresentation().isComposite());
         assertEquals(0, resource.get("role-a").getRoleComposites().size());
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java
index ca5429c..2ba3c5c 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java
@@ -282,7 +282,7 @@ public class RealmTest extends AbstractAdminTest {
     public void deleteDefaultRole() {
         RoleRepresentation role = new RoleRepresentation("test", "test", false);
         realm.roles().create(role);
-        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, Matchers.startsWith(AdminEventPaths.rolesResourcePath()));
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("test"), role);
 
         assertNotNull(realm.roles().get("test").toRepresentation());
 
@@ -523,7 +523,7 @@ public class RealmTest extends AbstractAdminTest {
         assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep);
 
         GlobalRequestResult globalRequestResult = realm.pushRevocation();
-        assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "push-revocation");
+        assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "push-revocation", globalRequestResult);
 
         assertEquals(1, globalRequestResult.getSuccessRequests().size());
         assertEquals("http://localhost:8180/auth/realms/master/app/admin", globalRequestResult.getSuccessRequests().get(0));
@@ -548,7 +548,7 @@ public class RealmTest extends AbstractAdminTest {
         oauth.doLogin("user", "password");
 
         GlobalRequestResult globalRequestResult = realm.logoutAll();
-        assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "logout-all");
+        assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "logout-all", globalRequestResult);
 
         assertEquals(1, globalRequestResult.getSuccessRequests().size());
         assertEquals("http://localhost:8180/auth/realms/master/app/admin", globalRequestResult.getSuccessRequests().get(0));
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/RoleByIdResourceTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/RoleByIdResourceTest.java
index e26bcbc..6db07e1 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/RoleByIdResourceTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/RoleByIdResourceTest.java
@@ -17,7 +17,6 @@
 
 package org.keycloak.testsuite.admin;
 
-import org.hamcrest.Matchers;
 import org.junit.Before;
 import org.junit.Test;
 import org.keycloak.admin.client.resource.RoleByIdResource;
@@ -120,9 +119,7 @@ public class RoleByIdResourceTest extends AbstractAdminTest {
         l.add(RoleBuilder.create().id(ids.get("role-c")).build());
         resource.addComposites(ids.get("role-a"), l);
 
-        // TODO adminEvents: Fix once composite roles events will be fixed...
-        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, Matchers.startsWith(AdminEventPaths.roleByIdResourceCompositesPath(ids.get("role-a"))));
-        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, Matchers.startsWith(AdminEventPaths.roleByIdResourceCompositesPath(ids.get("role-a"))));
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleByIdResourceCompositesPath(ids.get("role-a")), l);
 
         Set<RoleRepresentation> composites = resource.getRoleComposites(ids.get("role-a"));
 
@@ -136,7 +133,7 @@ public class RoleByIdResourceTest extends AbstractAdminTest {
         Assert.assertNames(clientComposites, "role-c");
 
         resource.deleteComposites(ids.get("role-a"), l);
-        assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleByIdResourceCompositesPath(ids.get("role-a")));
+        assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleByIdResourceCompositesPath(ids.get("role-a")), l);
 
         assertFalse(resource.getRole(ids.get("role-a")).isComposite());
         assertEquals(0, resource.getRoleComposites(ids.get("role-a")).size());
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationMapperTest.java
index 0db5f7c..52e1699 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationMapperTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationMapperTest.java
@@ -65,7 +65,7 @@ public class UserFederationMapperTest extends AbstractAdminTest {
         Response resp = realm.userFederation().create(ldapRep);
         this.ldapProviderId = ApiUtil.getCreatedId(resp);
         resp.close();
-        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userFederationCreateResourcePath(), ldapRep);
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userFederationResourcePath(this.ldapProviderId), ldapRep);
 
         UserFederationProviderRepresentation dummyRep = UserFederationProviderBuilder.create()
                 .displayName("dummy-1")
@@ -75,7 +75,7 @@ public class UserFederationMapperTest extends AbstractAdminTest {
         resp = realm.userFederation().create(dummyRep);
         this.dummyProviderId = ApiUtil.getCreatedId(resp);
         resp.close();
-        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userFederationCreateResourcePath(), dummyRep);
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userFederationResourcePath(this.dummyProviderId), dummyRep);
     }
 
     @After
@@ -254,11 +254,16 @@ public class UserFederationMapperTest extends AbstractAdminTest {
         // Try fed To Keycloak sync
         UserFederationSyncResultRepresentation result = ldapProviderResource().syncMapperData(mapperId, "fedToKeycloak");
         Assert.assertEquals("dummyFedToKeycloakSuccess mapper=some-dummy", result.getStatus());
-        assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userFederationMapperResourcePath(ldapProviderId, mapperId) + "/sync");
+
+        Map<String, Object> eventRep = new HashMap<>();
+        eventRep.put("action", "fedToKeycloak");
+        assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userFederationMapperResourcePath(ldapProviderId, mapperId) + "/sync", eventRep);
 
         // Try keycloak to fed
         result = ldapProviderResource().syncMapperData(mapperId, "keycloakToFed");
         Assert.assertEquals("dummyKeycloakToFedSuccess mapper=some-dummy", result.getStatus());
+
+        eventRep.put("action", "keycloakToFed");
         assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userFederationMapperResourcePath(ldapProviderId, mapperId) + "/sync");
 
     }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationTest.java
index 82e4e68..90b14a2 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationTest.java
@@ -17,8 +17,10 @@
 
 package org.keycloak.testsuite.admin;
 
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 
 import javax.ws.rs.BadRequestException;
 import javax.ws.rs.NotFoundException;
@@ -251,6 +253,7 @@ public class UserFederationTest extends AbstractAdminTest {
         // Switch kerberos authenticator to DISABLED
         kerberosExecution.setRequirement(AuthenticationExecutionModel.Requirement.DISABLED.toString());
         realm.flows().updateExecutions("browser", kerberosExecution);
+        assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("browser"), kerberosExecution);
 
         // update LDAP provider with kerberos
         ldapRep = userFederation().get(id).toRepresentation();
@@ -264,6 +267,7 @@ public class UserFederationTest extends AbstractAdminTest {
         // Cleanup
         kerberosExecution.setRequirement(AuthenticationExecutionModel.Requirement.DISABLED.toString());
         realm.flows().updateExecutions("browser", kerberosExecution);
+        assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("browser"), kerberosExecution);
         removeUserFederationProvider(id);
     }
 
@@ -297,7 +301,10 @@ public class UserFederationTest extends AbstractAdminTest {
         // Sync and assert it happened
         UserFederationSyncResultRepresentation syncResult = userFederation().get(id1).syncUsers("triggerFullSync");
         Assert.assertEquals("0 imported users, 0 updated users", syncResult.getStatus());
-        assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userFederationResourcePath(id1) + "/sync");
+
+        Map<String, Object> eventRep = new HashMap<>();
+        eventRep.put("action", "triggerFullSync");
+        assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userFederationResourcePath(id1) + "/sync", eventRep);
 
         int fullSyncTime = userFederation().get(id1).toRepresentation().getLastSync();
         Assert.assertTrue(fullSyncTime > 0);
@@ -305,7 +312,9 @@ public class UserFederationTest extends AbstractAdminTest {
         // Changed sync
         setTimeOffset(50);
         syncResult = userFederation().get(id1).syncUsers("triggerChangedUsersSync");
-        assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userFederationResourcePath(id1) + "/sync");
+
+        eventRep.put("action", "triggerChangedUsersSync");
+        assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userFederationResourcePath(id1) + "/sync", eventRep);
 
         Assert.assertEquals("0 imported users, 0 updated users", syncResult.getStatus());
         int changedSyncTime = userFederation().get(id1).toRepresentation().getLastSync();
@@ -323,8 +332,7 @@ public class UserFederationTest extends AbstractAdminTest {
         resp.close();
         String federationProviderId = ApiUtil.getCreatedId(resp);
 
-        // TODO adminEvents: should be rather whole path include ID (consistency with UPDATE and DELETE)
-        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userFederationCreateResourcePath(), rep);
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userFederationResourcePath(federationProviderId), rep);
         return federationProviderId;
     }
 
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java
index 843bdec..19645a8 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java
@@ -353,7 +353,7 @@ public class UserTest extends AbstractAdminTest {
         rep.setProviderId("social-provider-type");
 
         realm.identityProviders().create(rep);
-        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, Matchers.startsWith(AdminEventPaths.identityProviderCreatePath()), rep);
+        assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.identityProviderPath(rep.getAlias()), rep);
     }
 
     private void removeSampleIdentityProvider() {
@@ -742,6 +742,7 @@ public class UserTest extends AbstractAdminTest {
         RequiredActionProviderRepresentation updatePasswordReqAction = realm.flows().getRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD.toString());
         updatePasswordReqAction.setDefaultAction(true);
         realm.flows().updateRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD.toString(), updatePasswordReqAction);
+        assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authRequiredActionPath(UserModel.RequiredAction.UPDATE_PASSWORD.toString()), updatePasswordReqAction);
 
         // Create user
         String userId = createUser("user1", "user1@localhost");
@@ -754,6 +755,7 @@ public class UserTest extends AbstractAdminTest {
         updatePasswordReqAction = realm.flows().getRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD.toString());
         updatePasswordReqAction.setDefaultAction(true);
         realm.flows().updateRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD.toString(), updatePasswordReqAction);
+        assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authRequiredActionPath(UserModel.RequiredAction.UPDATE_PASSWORD.toString()), updatePasswordReqAction);
     }
 
     @Test
@@ -794,14 +796,16 @@ public class UserTest extends AbstractAdminTest {
         l.add(realm.roles().get("realm-role").toRepresentation());
         l.add(realm.roles().get("realm-composite").toRepresentation());
         roles.realmLevel().add(l);
-        assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.userRealmRoleMappingsPath(userId)));
-        assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.userRealmRoleMappingsPath(userId)));
+        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userRealmRoleMappingsPath(userId), l);
 
         // Add client roles
-        roles.clientLevel(clientUuid).add(Collections.singletonList(realm.clients().get(clientUuid).roles().get("client-role").toRepresentation()));
-        roles.clientLevel(clientUuid).add(Collections.singletonList(realm.clients().get(clientUuid).roles().get("client-composite").toRepresentation()));
-        assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid)));
-        assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid)));
+        List<RoleRepresentation> list = Collections.singletonList(realm.clients().get(clientUuid).roles().get("client-role").toRepresentation());
+        roles.clientLevel(clientUuid).add(list);
+        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid), list);
+
+        list = Collections.singletonList(realm.clients().get(clientUuid).roles().get("client-composite").toRepresentation());
+        roles.clientLevel(clientUuid).add(list);
+        assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid), list);
 
         // List realm roles
         assertNames(roles.realmLevel().listAll(), "realm-role", "realm-composite", "user", "offline_access");
@@ -823,16 +827,14 @@ public class UserTest extends AbstractAdminTest {
         // Remove realm role
         RoleRepresentation realmRoleRep = realm.roles().get("realm-role").toRepresentation();
         roles.realmLevel().remove(Collections.singletonList(realmRoleRep));
-        assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.userRealmRoleMappingsPath(userId) + "/" + realmRoleRep.getId());
+        assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.userRealmRoleMappingsPath(userId), Collections.singletonList(realmRoleRep));
 
         assertNames(roles.realmLevel().listAll(), "realm-composite", "user", "offline_access");
 
         // Remove client role
         RoleRepresentation clientRoleRep = realm.clients().get(clientUuid).roles().get("client-role").toRepresentation();
         roles.clientLevel(clientUuid).remove(Collections.singletonList(clientRoleRep));
-
-        // TODO: Inconsistency between event for delete realm role mapping and client role mapping (the latter doesn't have roleRep.getId() in the path)
-        assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid));
+        assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid), Collections.singletonList(clientRoleRep));
 
         assertNames(roles.clientLevel(clientUuid).listAll(), "client-composite");
     }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/AdminEventPaths.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/AdminEventPaths.java
index 7ff548a..dddc621 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/AdminEventPaths.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/AdminEventPaths.java
@@ -21,6 +21,8 @@ import java.net.URI;
 
 import javax.ws.rs.core.UriBuilder;
 
+import org.keycloak.admin.client.resource.AttackDetectionResource;
+import org.keycloak.admin.client.resource.AuthenticationManagementResource;
 import org.keycloak.admin.client.resource.ClientAttributeCertificateResource;
 import org.keycloak.admin.client.resource.ClientInitialAccessResource;
 import org.keycloak.admin.client.resource.ClientResource;
@@ -54,6 +56,11 @@ public class AdminEventPaths {
         return uri.toString();
     }
 
+    public static String defaultGroupPath(String groupId) {
+        URI uri = UriBuilder.fromUri("").path(RealmResource.class, "addDefaultGroup").build(groupId);
+        return uri.toString();
+    }
+
 
     // CLIENT RESOURCE
 
@@ -353,4 +360,99 @@ public class AdminEventPaths {
     }
 
 
+    // AUTHENTICATION FLOWS
+
+    public static String authMgmtBasePath() {
+        URI uri = UriBuilder.fromUri("").path(RealmResource.class, "flows")
+                .build();
+        return uri.toString();
+    }
+
+    public static String authFlowsPath() {
+        URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "getFlows")
+                .build();
+        return uri.toString();
+    }
+
+    public static String authFlowPath(String flowId) {
+        URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "getFlow")
+                .build(flowId);
+        return uri.toString();
+    }
+
+    public static String authCopyFlowPath(String flowAlias) {
+        URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "copy")
+                .build(flowAlias);
+        return uri.toString();
+    }
+
+    public static String authAddExecutionFlowPath(String flowAlias) {
+        URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "addExecutionFlow")
+                .build(flowAlias);
+        return uri.toString();
+    }
+
+    public static String authAddExecutionPath(String flowAlias) {
+        return authFlowPath(flowAlias) + "/executions/execution";
+    }
+
+    public static String authUpdateExecutionPath(String flowAlias) {
+        URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "updateExecutions")
+                .build(flowAlias);
+        return uri.toString();
+    }
+
+    public static String authExecutionPath(String executionId) {
+        URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "removeExecution")
+                .build(executionId);
+        return uri.toString();
+    }
+
+    public static String authAddExecutionConfigPath(String executionId) {
+        URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "newExecutionConfig")
+                .build(executionId);
+        return uri.toString();
+    }
+
+    public static String authExecutionConfigPath(String configId) {
+        URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "getAuthenticatorConfig")
+                .build(configId);
+        return uri.toString();
+    }
+
+    public static String authRaiseExecutionPath(String executionId) {
+        URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "raisePriority")
+                .build(executionId);
+        return uri.toString();
+    }
+
+    public static String authLowerExecutionPath(String executionId) {
+        URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "lowerPriority")
+                .build(executionId);
+        return uri.toString();
+    }
+
+    public static String authRequiredActionPath(String requiredActionAlias) {
+        URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "getRequiredAction")
+                .build(requiredActionAlias);
+        return uri.toString();
+    }
+
+    // ATTACK DETECTION
+
+    public static String attackDetectionClearBruteForceForUserPath(String username) {
+        URI uri = UriBuilder.fromUri("").path(RealmResource.class, "attackDetection")
+                .path(AttackDetectionResource.class, "clearBruteForceForUser")
+                .build(username);
+        return uri.toString();
+    }
+
+    public static String attackDetectionClearAllBruteForcePath() {
+        URI uri = UriBuilder.fromUri("").path(RealmResource.class, "attackDetection")
+                .path(AttackDetectionResource.class, "clearAllBruteForce")
+                .build();
+        return uri.toString();
+    }
+
+
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/AssertAdminEvents.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/AssertAdminEvents.java
index 0383a45..58f8e9a 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/AssertAdminEvents.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/AssertAdminEvents.java
@@ -17,13 +17,22 @@
 
 package org.keycloak.testsuite.util;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 import javax.ws.rs.core.Response;
 
+import com.fasterxml.jackson.core.type.TypeReference;
+import org.hamcrest.Description;
 import org.hamcrest.Matcher;
 import org.hamcrest.Matchers;
+import org.hamcrest.TypeSafeMatcher;
 import org.junit.rules.TestRule;
 import org.junit.runners.model.Statement;
 import org.keycloak.common.util.ObjectUtil;
@@ -34,7 +43,9 @@ import org.keycloak.jose.jws.JWSInputException;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.representations.idm.AdminEventRepresentation;
 import org.keycloak.representations.idm.AuthDetailsRepresentation;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.testsuite.AbstractKeycloakTest;
 import org.keycloak.testsuite.Assert;
 import org.keycloak.util.JsonSerialization;
@@ -179,8 +190,8 @@ public class AssertAdminEvents implements TestRule {
 
         public AdminEventRepresentation assertEvent(AdminEventRepresentation actual) {
             Assert.assertEquals(expected.getRealmId(), actual.getRealmId());
-            Assert.assertEquals(expected.getOperationType(), actual.getOperationType());
             Assert.assertThat(actual.getResourcePath(), resourcePath);
+            Assert.assertEquals(expected.getOperationType(), actual.getOperationType());
 
             Assert.assertTrue(ObjectUtil.isEqualOrBothNull(expected.getError(), actual.getError()));
 
@@ -197,20 +208,55 @@ public class AssertAdminEvents implements TestRule {
                 Assert.assertEquals(expectedAuth.getClientId(), actualAuth.getClientId());
             }
 
-            // Representation - compare the non-null fields of "expected" representation with the actual representation
+            // Representation comparison
             if (expectedRep != null) {
                 if (actual.getRepresentation() == null) {
                     Assert.fail("Expected representation " + expectedRep + " but no representation was available on actual event");
                 } else {
                     try {
-                        Object actualRep = JsonSerialization.readValue(actual.getRepresentation(), expectedRep.getClass());
 
-                        for (Method method : Reflections.getAllDeclaredMethods(expectedRep.getClass())) {
-                            if (method.getName().startsWith("get") || method.getName().startsWith("is")) {
-                                Object expectedValue = Reflections.invokeMethod(method, expectedRep);
+                        if (expectedRep instanceof List) {
+                            // List of roles. All must be available in actual representation
+                            List<RoleRepresentation> expectedRoles = (List<RoleRepresentation>) expectedRep;
+                            List<RoleRepresentation> actualRoles = JsonSerialization.readValue(new ByteArrayInputStream(actual.getRepresentation().getBytes()), new TypeReference<List<RoleRepresentation>>() {
+                            });
+
+                            Map<String, String> expectedRolesMap = new HashMap<>();
+                            for (RoleRepresentation role : expectedRoles) {
+                                expectedRolesMap.put(role.getId(), role.getName());
+                            }
+
+                            Map<String, String> actualRolesMap = new HashMap<>();
+                            for (RoleRepresentation role : actualRoles) {
+                                actualRolesMap.put(role.getId(), role.getName());
+                            }
+                            Assert.assertEquals(expectedRolesMap, actualRolesMap);
+
+                        } else if (expectedRep instanceof Map) {
+                            Object actualRep = JsonSerialization.readValue(actual.getRepresentation(), Map.class);
+
+                            // Comparing of map representations. All of "expected" key-values must be available on "actual" map from the event
+                            Map<?, ?> expectedRepMap = (Map) expectedRep;
+                            Map<?, ?> actualRepMap = (Map) actualRep;
+
+                            for (Map.Entry entry : expectedRepMap.entrySet()) {
+                                Object expectedValue = entry.getValue();
                                 if (expectedValue != null) {
-                                    Object actualValue = Reflections.invokeMethod(method, actualRep);
-                                    Assert.assertEquals("Property " + method.getName() + " of representation not equal.", expectedValue, actualValue);
+                                    Object actualValue = actualRepMap.get(entry.getKey());
+                                    Assert.assertEquals("Map item with key '" + entry.getKey() + "' not equal.", expectedValue, actualValue);
+                                }
+                            }
+                        } else {
+                            Object actualRep = JsonSerialization.readValue(actual.getRepresentation(), expectedRep.getClass());
+
+                            // Reflection-based comparing for other types - compare the non-null fields of "expected" representation with the "actual" representation from the event
+                            for (Method method : Reflections.getAllDeclaredMethods(expectedRep.getClass())) {
+                                if (method.getName().startsWith("get") || method.getName().startsWith("is")) {
+                                    Object expectedValue = Reflections.invokeMethod(method, expectedRep);
+                                    if (expectedValue != null) {
+                                        Object actualValue = Reflections.invokeMethod(method, actualRep);
+                                        Assert.assertEquals("Property method '" + method.getName() + "' of representation not equal.", expectedValue, actualValue);
+                                    }
                                 }
                             }
                         }
@@ -241,5 +287,22 @@ public class AssertAdminEvents implements TestRule {
         }
     }
 
+    public static Matcher<String> isExpectedPrefixFollowedByUuid(final String prefix) {
+        return new TypeSafeMatcher<String>() {
+
+            @Override
+            protected boolean matchesSafely(String item) {
+                int expectedLength = prefix.length() + 1 + org.keycloak.models.utils.KeycloakModelUtils.generateId().length();
+                return item.startsWith(prefix) && expectedLength == item.length();
+            }
+
+            @Override
+            public void describeTo(Description description) {
+                description.appendText("resourcePath in the format like \"" + prefix + "/<UUID>\"");
+            }
+
+        };
+    }
+
 
 }