You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by fm...@apache.org on 2016/07/01 15:34:09 UTC

syncope git commit: [SYNCOPE-886] fix including integration test improving

Repository: syncope
Updated Branches:
  refs/heads/master fa1ea266e -> c54adf5ce


[SYNCOPE-886] fix including integration test improving


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

Branch: refs/heads/master
Commit: c54adf5ce25d7a4de93a0805b639b25ba83eb34b
Parents: fa1ea26
Author: fmartelli <fa...@gmail.com>
Authored: Fri Jul 1 17:33:55 2016 +0200
Committer: fmartelli <fa...@gmail.com>
Committed: Fri Jul 1 17:33:55 2016 +0200

----------------------------------------------------------------------
 .../client/console/bulk/BulkContent.java        | 88 ++++++++++++--------
 .../console/commons/status/StatusUtils.java     |  2 +-
 .../console/panels/AnyObjectDirectoryPanel.java |  6 +-
 .../console/panels/GroupDirectoryPanel.java     |  6 +-
 .../console/panels/UserDirectoryPanel.java      | 29 +++++--
 .../client/console/rest/UserRestClient.java     | 51 +++++++++++-
 .../console/status/AnyStatusDirectoryPanel.java | 12 +--
 .../client/console/status/AnyStatusModal.java   | 11 ++-
 .../console/status/ResourceStatusModal.java     |  6 +-
 .../client/console/status/StatusModal.java      |  5 +-
 .../console/topology/TopologyTogglePanel.java   |  2 +-
 .../rest/cxf/service/AbstractAnyService.java    |  4 +
 .../syncope/fit/console/BulkActionITCase.java   | 57 ++++++++++++-
 13 files changed, 211 insertions(+), 68 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/c54adf5c/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java b/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java
index 11891e5..bdfe2d5 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java
@@ -26,6 +26,7 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.status.StatusBean;
@@ -33,6 +34,7 @@ import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.panels.MultilevelPanel;
 import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
 import org.apache.syncope.client.console.rest.RestClient;
+import org.apache.syncope.client.console.rest.UserRestClient;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.BulkActionResultColumn;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
@@ -40,8 +42,6 @@ import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink.Acti
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
-import org.apache.syncope.common.lib.types.ResourceAssociationAction;
-import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
@@ -123,10 +123,25 @@ public class BulkContent<T extends Serializable, S> extends MultilevelPanel.Seco
                 private static final long serialVersionUID = -3722207913631435501L;
 
                 @Override
+                protected boolean statusCondition(final Serializable modelObject) {
+                    return CollectionUtils.isNotEmpty(items);
+                }
+
+                @Override
                 public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
                     try {
+                        if (CollectionUtils.isEmpty(items)) {
+                            throw new IllegalArgumentException("Invalid items");
+                        }
+
+                        String fieldName = keyFieldName;
+
                         BulkActionResult res = null;
                         try {
+                            if (items.iterator().next() instanceof StatusBean) {
+                                throw new IllegalArgumentException("Invalid items");
+                            }
+
                             final BulkAction bulkAction = new BulkAction();
                             bulkAction.setType(BulkAction.Type.valueOf(actionToBeAddresed.name()));
                             for (T item : items) {
@@ -140,6 +155,10 @@ public class BulkContent<T extends Serializable, S> extends MultilevelPanel.Seco
                                     bulkActionExecutor.getClass().getMethod("bulkAction", BulkAction.class).invoke(
                                     bulkActionExecutor, bulkAction));
                         } catch (IllegalArgumentException biae) {
+                            if (!(items.iterator().next() instanceof StatusBean)) {
+                                throw new IllegalArgumentException("Invalid items");
+                            }
+
                             if (!(bulkActionExecutor instanceof AbstractAnyRestClient)) {
                                 throw new IllegalArgumentException("Invalid bulk action executor");
                             }
@@ -147,10 +166,6 @@ public class BulkContent<T extends Serializable, S> extends MultilevelPanel.Seco
                             final AbstractAnyRestClient<?, ?> anyRestClient = AbstractAnyRestClient.class.cast(
                                     bulkActionExecutor);
 
-                            if (items.isEmpty() || !(items.iterator().next() instanceof StatusBean)) {
-                                throw new IllegalArgumentException("Invalid items");
-                            }
-
                             // Group bean information by anyKey
                             final Map<String, List<StatusBean>> beans = new HashMap<>();
                             for (T bean : items) {
@@ -167,34 +182,37 @@ public class BulkContent<T extends Serializable, S> extends MultilevelPanel.Seco
 
                             for (Map.Entry<String, List<StatusBean>> entry : beans.entrySet()) {
                                 final String etag = anyRestClient.read(entry.getKey()).getETagValue();
-                                try {
-                                    switch (ResourceDeassociationAction.valueOf(actionToBeAddresed.name())) {
-                                        case DEPROVISION:
-                                            res = anyRestClient.deprovision(etag, entry.getKey(), entry.getValue());
-                                            break;
-                                        case UNASSIGN:
-                                            res = anyRestClient.unassign(etag, entry.getKey(), entry.getValue());
-                                            break;
-                                        case UNLINK:
-                                            res = anyRestClient.unlink(etag, entry.getKey(), entry.getValue());
-                                            break;
-                                        default:
-                                            break;
-                                    }
-                                } catch (IllegalArgumentException diae) {
-                                    switch (ResourceAssociationAction.valueOf(actionToBeAddresed.name())) {
-                                        case ASSIGN:
-                                            res = anyRestClient.assign(etag, entry.getKey(), entry.getValue());
-                                            break;
-                                        case LINK:
-                                            res = anyRestClient.link(etag, entry.getKey(), entry.getValue());
-                                            break;
-                                        case PROVISION:
-                                            res = anyRestClient.provision(etag, entry.getKey(), entry.getValue());
-                                            break;
-                                        default:
-                                            break;
-                                    }
+                                switch (actionToBeAddresed.name()) {
+                                    case "DEPROVISION":
+                                        res = anyRestClient.deprovision(etag, entry.getKey(), entry.getValue());
+                                        break;
+                                    case "UNASSIGN":
+                                        res = anyRestClient.unassign(etag, entry.getKey(), entry.getValue());
+                                        break;
+                                    case "UNLINK":
+                                        res = anyRestClient.unlink(etag, entry.getKey(), entry.getValue());
+                                        break;
+                                    case "ASSIGN":
+                                        res = anyRestClient.assign(etag, entry.getKey(), entry.getValue());
+                                        break;
+                                    case "LINK":
+                                        res = anyRestClient.link(etag, entry.getKey(), entry.getValue());
+                                        break;
+                                    case "PROVISION":
+                                        res = anyRestClient.provision(etag, entry.getKey(), entry.getValue());
+                                        break;
+                                    case "REACTIVATE":
+                                        res = ((UserRestClient) anyRestClient).
+                                                reactivate(etag, entry.getKey(), entry.getValue());
+                                        fieldName = "resourceName";
+                                        break;
+                                    case "SUSPEND":
+                                        res = ((UserRestClient) anyRestClient).
+                                                suspend(etag, entry.getKey(), entry.getValue());
+                                        fieldName = "resourceName";
+                                        break;
+                                    default:
+                                        break;
                                 }
                             }
                         }
@@ -204,7 +222,7 @@ public class BulkContent<T extends Serializable, S> extends MultilevelPanel.Seco
                         }
 
                         final List<IColumn<T, S>> newColumnList = new ArrayList<>(columns);
-                        newColumnList.add(newColumnList.size(), new BulkActionResultColumn<T, S>(res, keyFieldName));
+                        newColumnList.add(newColumnList.size(), new BulkActionResultColumn<T, S>(res, fieldName));
 
                         container.addOrReplace(new AjaxFallbackDefaultDataTable<>(
                                 "selectedObjects",

http://git-wip-us.apache.org/repos/asf/syncope/blob/c54adf5c/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
index cfbf065..665870a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
@@ -139,7 +139,7 @@ public class StatusUtils implements Serializable {
         builder.value(password);
 
         for (StatusBean status : statuses) {
-            if ("syncope".equalsIgnoreCase(status.getResourceName())) {
+            if (Constants.SYNCOPE.equalsIgnoreCase(status.getResourceName())) {
                 builder.onSyncope(true);
             } else {
                 builder.resource(status.getResourceName());

http://git-wip-us.apache.org/repos/asf/syncope/blob/c54adf5c/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
index 749bdca..16c5675 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
@@ -174,7 +174,11 @@ public class AnyObjectDirectoryPanel extends AnyDirectoryPanel<AnyObjectTO, AnyO
                             altDefaultModal.setFormModel(formModel);
 
                             target.add(altDefaultModal.setContent(new AnyStatusModal<>(
-                                    altDefaultModal, pageRef, formModel.getObject().getInnerObject(), false)));
+                                    altDefaultModal,
+                                    pageRef,
+                                    formModel.getObject().getInnerObject(),
+                                    "resourceName",
+                                    false)));
 
                             altDefaultModal.header(new Model<>(
                                     getString("any.edit", new Model<>(new AnyWrapper<>(model.getObject())))));

http://git-wip-us.apache.org/repos/asf/syncope/blob/c54adf5c/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
index facbd0a..0374117 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
@@ -247,7 +247,11 @@ public class GroupDirectoryPanel extends AnyDirectoryPanel<GroupTO, GroupRestCli
                         altDefaultModal.setFormModel(formModel);
 
                         target.add(altDefaultModal.setContent(new AnyStatusModal<>(
-                                altDefaultModal, pageRef, formModel.getObject().getInnerObject(), false)));
+                                altDefaultModal,
+                                pageRef,
+                                formModel.getObject().getInnerObject(),
+                                "resourceName",
+                                false)));
 
                         altDefaultModal.header(new Model<>(
                                 getString("any.edit", new Model<>(new AnyWrapper<>(model.getObject())))));

http://git-wip-us.apache.org/repos/asf/syncope/blob/c54adf5c/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
index db1d0a3..1683766 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
@@ -41,7 +41,6 @@ import org.apache.syncope.client.console.wizards.AjaxWizard;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
 import org.apache.syncope.client.console.wizards.any.AnyWrapper;
 import org.apache.syncope.client.console.wizards.any.UserWrapper;
-import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
@@ -50,6 +49,7 @@ import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
 import org.apache.wicket.model.CompoundPropertyModel;
 import org.apache.wicket.model.IModel;
@@ -68,6 +68,17 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient
 
     protected UserDirectoryPanel(final String id, final Builder builder, final boolean wizardInModal) {
         super(id, builder, wizardInModal);
+
+        altDefaultModal.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
+
+            private static final long serialVersionUID = 8804221891699487139L;
+
+            @Override
+            public void onClose(final AjaxRequestTarget target) {
+                updateResultTable(target);
+                modal.show(false);
+            }
+        });
     }
 
     @Override
@@ -138,7 +149,7 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient
                                     model.getObject().getKey());
                             SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
                             target.add(container);
-                        } catch (SyncopeClientException e) {
+                        } catch (Exception e) {
                             LOG.error("While deleting object {}", model.getObject().getKey(), e);
                             SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage()) ? e.getClass().
                                     getName() : e.getMessage());
@@ -184,7 +195,7 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient
                             restClient.delete(model.getObject().getETagValue(), model.getObject().getKey());
                             SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
                             target.add(container);
-                        } catch (SyncopeClientException e) {
+                        } catch (Exception e) {
                             LOG.error("While deleting object {}", model.getObject().getKey(), e);
                             SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage()) ? e.getClass().
                                     getName() : e.getMessage());
@@ -205,7 +216,11 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient
                             altDefaultModal.setFormModel(formModel);
 
                             target.add(altDefaultModal.setContent(new AnyStatusModal<>(
-                                    altDefaultModal, pageRef, formModel.getObject().getInnerObject(), false)));
+                                    altDefaultModal,
+                                    pageRef,
+                                    formModel.getObject().getInnerObject(),
+                                    "resourceName",
+                                    false)));
 
                             altDefaultModal.header(new Model<>(
                                     getString("any.edit", new Model<>(new AnyWrapper<>(model.getObject())))));
@@ -223,7 +238,11 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient
                             altDefaultModal.setFormModel(formModel);
 
                             target.add(altDefaultModal.setContent(new AnyStatusModal<>(
-                                    altDefaultModal, pageRef, formModel.getObject().getInnerObject(), true)));
+                                    altDefaultModal,
+                                    pageRef,
+                                    formModel.getObject().getInnerObject(),
+                                    "resourceName",
+                                    true)));
 
                             altDefaultModal.header(new Model<>(
                                     getString("any.edit", new Model<>(new AnyWrapper<>(model.getObject())))));

http://git-wip-us.apache.org/repos/asf/syncope/blob/c54adf5c/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
index 7a4e559..68e3a01 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
@@ -19,13 +19,18 @@
 package org.apache.syncope.client.console.rest;
 
 import java.util.List;
+import java.util.Map;
 import javax.ws.rs.core.GenericType;
 import javax.ws.rs.core.Response;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.status.StatusBean;
 import org.apache.syncope.client.console.commons.status.StatusUtils;
 import org.apache.syncope.common.lib.patch.BooleanReplacePatchItem;
 import org.apache.syncope.common.lib.patch.StatusPatch;
 import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.StatusPatchType;
@@ -76,25 +81,63 @@ public class UserRestClient extends AbstractAnyRestClient<UserTO, UserPatch> {
         return update(etag, userPatch);
     }
 
-    public void suspend(final String etag, final String userKey, final List<StatusBean> statuses) {
+    public BulkActionResult suspend(final String etag, final String userKey, final List<StatusBean> statuses) {
         StatusPatch statusPatch = StatusUtils.buildStatusPatch(statuses, false);
         statusPatch.setKey(userKey);
         statusPatch.setType(StatusPatchType.SUSPEND);
+
+        BulkActionResult result;
         synchronized (this) {
+            result = new BulkActionResult();
+            Map<String, BulkActionResult.Status> res = result.getResults();
             UserService service = getService(etag, UserService.class);
-            service.status(statusPatch);
+
+            @SuppressWarnings("unchecked")
+            ProvisioningResult<UserTO> provisions = (ProvisioningResult<UserTO>) service.status(statusPatch).
+                    readEntity(ProvisioningResult.class);
+
+            if (statusPatch.isOnSyncope()) {
+                res.put(StringUtils.capitalize(Constants.SYNCOPE),
+                        "suspended".equalsIgnoreCase(provisions.getEntity().getStatus())
+                        ? BulkActionResult.Status.SUCCESS
+                        : BulkActionResult.Status.FAILURE);
+            }
+
+            for (PropagationStatus status : provisions.getPropagationStatuses()) {
+                res.put(status.getResource(), BulkActionResult.Status.valueOf(status.getStatus().name()));
+            }
             resetClient(UserService.class);
         }
+        return result;
     }
 
-    public void reactivate(final String etag, final String userKey, final List<StatusBean> statuses) {
+    public BulkActionResult reactivate(final String etag, final String userKey, final List<StatusBean> statuses) {
         StatusPatch statusPatch = StatusUtils.buildStatusPatch(statuses, true);
         statusPatch.setKey(userKey);
         statusPatch.setType(StatusPatchType.REACTIVATE);
+
+        BulkActionResult result;
         synchronized (this) {
+            result = new BulkActionResult();
+            Map<String, BulkActionResult.Status> res = result.getResults();
             UserService service = getService(etag, UserService.class);
-            service.status(statusPatch);
+
+            @SuppressWarnings("unchecked")
+            ProvisioningResult<UserTO> provisions = (ProvisioningResult<UserTO>) service.status(statusPatch).
+                    readEntity(ProvisioningResult.class);
+
+            if (statusPatch.isOnSyncope()) {
+                res.put(StringUtils.capitalize(Constants.SYNCOPE),
+                        "active".equalsIgnoreCase(provisions.getEntity().getStatus())
+                        ? BulkActionResult.Status.SUCCESS
+                        : BulkActionResult.Status.FAILURE);
+            }
+
+            for (PropagationStatus status : provisions.getPropagationStatuses()) {
+                res.put(status.getResource(), BulkActionResult.Status.valueOf(status.getStatus().name()));
+            }
             resetClient(UserService.class);
         }
+        return result;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/c54adf5c/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
index 89a9d65..8699a42 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
@@ -73,16 +73,8 @@ public class AnyStatusDirectoryPanel
             final BaseModal<?> baseModal,
             final MultilevelPanel multiLevelPanelRef,
             final PageReference pageRef,
-            final AnyTO anyTO) {
-
-        this(baseModal, multiLevelPanelRef, pageRef, anyTO, false);
-    }
-
-    public AnyStatusDirectoryPanel(
-            final BaseModal<?> baseModal,
-            final MultilevelPanel multiLevelPanelRef,
-            final PageReference pageRef,
             final AnyTO anyTO,
+            final String itemKeyFieldName,
             final boolean statusOnly) {
 
         super(MultilevelPanel.FIRST_LEVEL_ID, pageRef);
@@ -90,7 +82,7 @@ public class AnyStatusDirectoryPanel
         this.multiLevelPanelRef = multiLevelPanelRef;
         this.statusOnly = statusOnly;
         this.anyTO = anyTO;
-        this.itemKeyFieldName = statusOnly ? "anyKey" : "resourceName";
+        this.itemKeyFieldName = itemKeyFieldName;
 
         if (anyTO instanceof UserTO) {
             this.restClient = new UserRestClient();

http://git-wip-us.apache.org/repos/asf/syncope/blob/c54adf5c/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusModal.java b/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusModal.java
index 3af3bae..3d069f0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusModal.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusModal.java
@@ -32,8 +32,12 @@ public class AnyStatusModal<T extends AnyTO> extends StatusModal<T> {
     private static final long serialVersionUID = 1066124171682570080L;
 
     public AnyStatusModal(
-            final BaseModal<?> baseModal, final PageReference pageReference, final T anyTO, final boolean statusOnly) {
-        super(baseModal, pageReference, anyTO, statusOnly);
+            final BaseModal<?> baseModal,
+            final PageReference pageReference,
+            final T anyTO,
+            final String itemKeyFieldName,
+            final boolean statusOnly) {
+        super(baseModal, pageReference, anyTO, itemKeyFieldName, statusOnly);
     }
 
     @Override
@@ -43,7 +47,8 @@ public class AnyStatusModal<T extends AnyTO> extends StatusModal<T> {
             final BaseModal<?> baseModal,
             final PageReference pageReference,
             final T entity,
+            final String itemKeyFieldName,
             final boolean statusOnly) {
-        return new AnyStatusDirectoryPanel(baseModal, mlp, pageReference, entity, statusOnly);
+        return new AnyStatusDirectoryPanel(baseModal, mlp, pageReference, entity, itemKeyFieldName, statusOnly);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/c54adf5c/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java b/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java
index 5180f2e..ea07105 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java
@@ -47,10 +47,9 @@ public class ResourceStatusModal extends StatusModal<ResourceTO> {
     public ResourceStatusModal(
             final BaseModal<?> baseModal,
             final PageReference pageReference,
-            final ResourceTO resourceTO,
-            final boolean statusOnly) {
+            final ResourceTO resourceTO) {
 
-        super(baseModal, pageReference, resourceTO, statusOnly);
+        super(baseModal, pageReference, resourceTO, null, false);
 
         final LoadableDetachableModel<List<String>> types = new LoadableDetachableModel<List<String>>() {
 
@@ -87,6 +86,7 @@ public class ResourceStatusModal extends StatusModal<ResourceTO> {
             final BaseModal<?> baseModal,
             final PageReference pageReference,
             final ResourceTO entity,
+            final String itemKeyFieldName,
             final boolean statusOnly) {
 
         return new ResourceStatusDirectoryPanel(baseModal, mlp, pageReference, null, entity);

http://git-wip-us.apache.org/repos/asf/syncope/blob/c54adf5c/client/console/src/main/java/org/apache/syncope/client/console/status/StatusModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/status/StatusModal.java b/client/console/src/main/java/org/apache/syncope/client/console/status/StatusModal.java
index 6854420..9e04151 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/status/StatusModal.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/status/StatusModal.java
@@ -39,12 +39,14 @@ public abstract class StatusModal<T extends Serializable> extends Panel implemen
             final BaseModal<?> baseModal,
             final PageReference pageReference,
             final T entity,
+            final String itemKeyFieldName,
             final boolean statusOnly) {
 
         super(BaseModal.CONTENT_ID);
 
         final MultilevelPanel mlp = new MultilevelPanel("status");
-        this.directoryPanel = getStatusDirectoryPanel(mlp, baseModal, pageReference, entity, statusOnly);
+        this.directoryPanel = getStatusDirectoryPanel(
+                mlp, baseModal, pageReference, entity, itemKeyFieldName, statusOnly);
         add(mlp.setFirstLevel(this.directoryPanel));
     }
 
@@ -54,5 +56,6 @@ public abstract class StatusModal<T extends Serializable> extends Panel implemen
             final BaseModal<?> baseModal,
             final PageReference pageReference,
             final T entity,
+            final String itemKeyFieldName,
             final boolean statusOnly);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/c54adf5c/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
index d1ef0d2..8f58b45 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
@@ -351,7 +351,7 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
             public void onClick(final AjaxRequestTarget target) {
                 ResourceTO modelObject = resourceRestClient.read(node.getKey().toString());
                 target.add(propTaskModal.setContent(
-                        new ResourceStatusModal(propTaskModal, pageRef, modelObject, false)));
+                        new ResourceStatusModal(propTaskModal, pageRef, modelObject)));
                 propTaskModal.header(new ResourceModel("resource.provisioning.status", "Provisioning Status"));
                 propTaskModal.show(true);
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/c54adf5c/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
index 8548fbb..7a19af1 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
@@ -366,6 +366,8 @@ public abstract class AbstractAnyService<TO extends AnyTO, P extends AnyPatch>
                         StatusPatch statusPatch = new StatusPatch();
                         statusPatch.setKey(key);
                         statusPatch.setType(StatusPatchType.SUSPEND);
+                        statusPatch.setOnSyncope(true);
+
                         try {
                             result.getResults().put(
                                     ((UserLogic) logic).
@@ -387,6 +389,8 @@ public abstract class AbstractAnyService<TO extends AnyTO, P extends AnyPatch>
                         StatusPatch statusPatch = new StatusPatch();
                         statusPatch.setKey(key);
                         statusPatch.setType(StatusPatchType.REACTIVATE);
+                        statusPatch.setOnSyncope(true);
+
                         try {
                             result.getResults().put(
                                     ((UserLogic) logic).

http://git-wip-us.apache.org/repos/asf/syncope/blob/c54adf5c/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java
index 7334bb4..392443a 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java
@@ -18,9 +18,13 @@
  */
 package org.apache.syncope.fit.console;
 
+import static org.apache.syncope.fit.console.AbstractConsoleITCase.TESTER;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
 import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.status.Status;
+import org.apache.syncope.client.console.commons.status.StatusBean;
 import org.apache.wicket.Component;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
@@ -109,8 +113,16 @@ public class BulkActionITCase extends AbstractConsoleITCase {
 
     @Test
     public void userStatusBulkAction() {
-        // suspend 
+        userStatusBulkAction(1, "resource-testdb2");
+    }
 
+    @Test
+    public void userStatusOnSyncopeOnlyBulkAction() {
+        userStatusBulkAction(0, "Syncope");
+    }
+
+    private void userStatusBulkAction(final int index, final String resourceName) {
+        // suspend 
         TESTER.clickLink("body:realmsLI:realms");
         TESTER.clickLink("body:content:body:container:content:tabbedPanel:tabs-container:tabs:1:link");
 
@@ -124,12 +136,20 @@ public class BulkActionITCase extends AbstractConsoleITCase {
                 + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:groupForm:"
                 + "checkgroup:dataTable", WebMarkupContainer.class);
 
+        component = findComponentByProp("resourceName",
+                tabPanel + "outerObjectsRepeater:1:outer:form:content:status:firstLevelContainer:first:container:"
+                + "content:searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", resourceName);
+
+        component = TESTER.getComponentFromLastRenderedPage(component.getPageRelativePath() + ":cells:1:cell:check");
+        assertEquals(Status.ACTIVE, StatusBean.class.cast(component.getDefaultModelObject()).getStatus());
+        assertEquals(resourceName, StatusBean.class.cast(component.getDefaultModelObject()).getResourceName());
+
         FormTester formTester = TESTER.newFormTester(
                 tabPanel + "outerObjectsRepeater:1:outer:form:content:status:firstLevelContainer:"
                 + "first:container:content:searchContainer:resultTable:tablePanel:groupForm");
         assertNotNull(formTester);
 
-        formTester.select("checkgroup", 2);
+        formTester.select("checkgroup", index);
 
         TESTER.executeAjaxEvent(tabPanel + "outerObjectsRepeater:1:outer:form:content:status:"
                 + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:bulkActionLink",
@@ -142,9 +162,23 @@ public class BulkActionITCase extends AbstractConsoleITCase {
                 + "status:secondLevelContainer:second:container:actions:panelSuspend:suspendLink",
                 Constants.ON_CLICK);
 
+        TESTER.assertInfoMessages("Operation executed successfully");
+        TESTER.cleanupFeedbackMessages();
+
         TESTER.assertLabel(tabPanel + "outerObjectsRepeater:1:outer:form:content:status:"
                 + "secondLevelContainer:second:container:selectedObjects:body:rows:1:cells:3:cell", "SUCCESS");
 
+        TESTER.executeAjaxEvent(tabPanel + "outerObjectsRepeater:1:outer:form:content:status:secondLevelContainer:back",
+                Constants.ON_CLICK);
+
+        component = findComponentByProp("resourceName",
+                tabPanel + "outerObjectsRepeater:1:outer:form:content:status:firstLevelContainer:first:container:"
+                + "content:searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", resourceName);
+
+        component = TESTER.getComponentFromLastRenderedPage(component.getPageRelativePath() + ":cells:1:cell:check");
+        assertEquals(Status.SUSPENDED, StatusBean.class.cast(component.getDefaultModelObject()).getStatus());
+        assertEquals(resourceName, StatusBean.class.cast(component.getDefaultModelObject()).getResourceName());
+
         // re-activate
         TESTER.clickLink("body:realmsLI:realms");
         TESTER.clickLink("body:content:body:container:content:tabbedPanel:tabs-container:tabs:1:link");
@@ -164,7 +198,7 @@ public class BulkActionITCase extends AbstractConsoleITCase {
                 + "first:container:content:searchContainer:resultTable:tablePanel:groupForm");
         assertNotNull(formTester);
 
-        formTester.select("checkgroup", 2);
+        formTester.select("checkgroup", index);
 
         TESTER.executeAjaxEvent(tabPanel + "outerObjectsRepeater:1:outer:form:content:status:"
                 + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:bulkActionLink",
@@ -177,8 +211,25 @@ public class BulkActionITCase extends AbstractConsoleITCase {
                 + "status:secondLevelContainer:second:container:actions:panelReactivate:reactivateLink",
                 Constants.ON_CLICK);
 
+        TESTER.assertInfoMessages("Operation executed successfully");
+        TESTER.cleanupFeedbackMessages();
+
         TESTER.assertLabel(tabPanel + "outerObjectsRepeater:1:outer:form:content:status:"
                 + "secondLevelContainer:second:container:selectedObjects:body:rows:1:cells:3:cell", "SUCCESS");
+
+        TESTER.executeAjaxEvent(tabPanel + "outerObjectsRepeater:1:outer:form:content:status:secondLevelContainer:back",
+                Constants.ON_CLICK);
+
+        component = findComponentByProp("resourceName",
+                tabPanel + "outerObjectsRepeater:1:outer:form:content:status:firstLevelContainer:first:container:"
+                + "content:searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", resourceName);
+
+        component = TESTER.getComponentFromLastRenderedPage(component.getPageRelativePath() + ":cells:1:cell:check");
+        assertEquals(Status.ACTIVE, StatusBean.class.cast(component.getDefaultModelObject()).getStatus());
+        assertEquals(resourceName, StatusBean.class.cast(component.getDefaultModelObject()).getResourceName());
+
+        TESTER.executeAjaxEvent(tabPanel + "outerObjectsRepeater:1:outer:dialog:footer:buttons:0:button",
+                Constants.ON_CLICK);
     }
 
     @Test