Repository: syncope
Updated Branches:
  refs/heads/2_0_X de63a75a2 -> 36f2537e7
  refs/heads/master 1afd1a705 -> 05ada83cc


[SYNCOPE-1143] Some fixes and refinements


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

Branch: refs/heads/2_0_X
Commit: 36f2537e7e4cd46bf7c2cd4761eeb24b857409b4
Parents: de63a75
Author: Francesco Chicchiriccò <ilgro...@apache.org>
Authored: Thu Aug 17 08:53:21 2017 +0200
Committer: Francesco Chicchiriccò <ilgro...@apache.org>
Committed: Thu Aug 17 08:53:21 2017 +0200

----------------------------------------------------------------------
 .../cli/commands/CommonsResultManager.java      |  4 +-
 .../connector/ConnectorResultManager.java       |  3 +-
 .../ConnInstanceHistoryConfDirectoryPanel.java  |  5 +-
 .../client/console/panels/DirectoryPanel.java   | 16 +++++--
 .../console/panels/HistoryConfDetails.java      | 38 +++++++--------
 .../ResourceHistoryConfDirectoryPanel.java      |  5 +-
 .../client/console/panels/VirSchemaDetails.java | 34 +++++++++++---
 .../console/rest/ConnectorRestClient.java       | 13 +++---
 .../client/console/rest/ResourceRestClient.java | 22 +++++----
 .../client/console/topology/Topology.java       |  6 +--
 .../console/topology/TopologyTogglePanel.java   | 42 +++++++++++------
 .../markup/html/bootstrap/dialog/BaseModal.java | 18 +++++++
 .../resources/ResourceConnConfPanel.java        |  5 +-
 .../resources/ResourceProvisionPanel.java       | 13 +++---
 .../syncope/common/lib/to/ConnInstanceTO.java   |  7 +--
 .../syncope/common/lib/to/ResourceTO.java       |  5 +-
 .../common/lib/types/ConnConfPropSchema.java    | 44 +++++++++++++++++-
 .../api/service/ConnectorHistoryService.java    |  4 +-
 .../persistence/api/entity/ConnInstance.java    |  3 +-
 .../persistence/jpa/entity/JPAConnInstance.java |  5 +-
 .../core/provisioning/api/ConnectorFactory.java |  6 +--
 .../provisioning/java/ConnectorManager.java     |  5 +-
 .../java/data/ConnInstanceDataBinderImpl.java   | 49 +++++++++++++-------
 .../java/data/ResourceDataBinderImpl.java       | 37 ++++++++-------
 .../syncope/fit/core/ConnectorITCase.java       |  2 +-
 25 files changed, 257 insertions(+), 134 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/client/cli/src/main/java/org/apache/syncope/client/cli/commands/CommonsResultManager.java
----------------------------------------------------------------------
diff --git 
a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/CommonsResultManager.java
 
b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/CommonsResultManager.java
index 6631dea..8098e20 100644
--- 
a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/CommonsResultManager.java
+++ 
b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/CommonsResultManager.java
@@ -19,9 +19,9 @@
 package org.apache.syncope.client.cli.commands;
 
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import org.apache.syncope.client.cli.Command;
 import org.apache.syncope.client.cli.view.Messages;
 import org.apache.syncope.client.cli.view.Table;
@@ -73,7 +73,7 @@ public abstract class CommonsResultManager {
         return 
Messages.commandHelpMessage(name.getAnnotation(Command.class).name());
     }
 
-    protected void printConfiguration(final Set<ConnConfProperty> 
configurationPropertys) {
+    protected void printConfiguration(final Collection<ConnConfProperty> 
configurationPropertys) {
         for (final ConnConfProperty configuration : configurationPropertys) {
             System.out.println("       name: " + 
configuration.getSchema().getName());
             System.out.println("       values: " + configuration.getValues());

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/client/cli/src/main/java/org/apache/syncope/client/cli/commands/connector/ConnectorResultManager.java
----------------------------------------------------------------------
diff --git 
a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/connector/ConnectorResultManager.java
 
b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/connector/ConnectorResultManager.java
index 157500f..69d2c58 100644
--- 
a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/connector/ConnectorResultManager.java
+++ 
b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/connector/ConnectorResultManager.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.cli.commands.connector;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -91,7 +92,7 @@ public class ConnectorResultManager extends 
CommonsResultManager {
         }
     }
 
-    public void printConfigurationProperties(final Set<ConnConfProperty> 
connConfPropertys) {
+    public void printConfigurationProperties(final 
Collection<ConnConfProperty> connConfPropertys) {
         printConfiguration(connConfPropertys);
 
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnInstanceHistoryConfDirectoryPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnInstanceHistoryConfDirectoryPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnInstanceHistoryConfDirectoryPanel.java
index 66f821d..836c12b 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnInstanceHistoryConfDirectoryPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnInstanceHistoryConfDirectoryPanel.java
@@ -65,18 +65,19 @@ public abstract class ConnInstanceHistoryConfDirectoryPanel 
extends DirectoryPan
 
     private final String entityKey;
 
-    protected ConnInstanceHistoryConfDirectoryPanel(
+    public ConnInstanceHistoryConfDirectoryPanel(
             final BaseModal<?> baseModal,
             final MultilevelPanel multiLevelPanelRef,
             final String entityKey,
             final PageReference pageRef) {
 
-        super(MultilevelPanel.FIRST_LEVEL_ID, pageRef, false);
+        super(MultilevelPanel.FIRST_LEVEL_ID, pageRef, false, false);
 
         this.baseModal = baseModal;
         this.multiLevelPanelRef = multiLevelPanelRef;
         restClient = new ConnectorHistoryRestClient();
         setShowResultPage(false);
+        disableCheckBoxes();
 
         this.entityKey = entityKey;
         initResultTable();

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java
index 55cca0f..9bc33d6 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java
@@ -109,7 +109,7 @@ public abstract class DirectoryPanel<
 
     /**
      * Create simple unfiltered search result panel.
-     * Use the available builder for powerfull configuration options.
+     * Use the available builder for powerful configuration options.
      *
      * @param id panel id.
      * @param pageRef page reference.
@@ -119,6 +119,12 @@ public abstract class DirectoryPanel<
     }
 
     public DirectoryPanel(final String id, final PageReference pageRef, final 
boolean wizardInModal) {
+        this(id, pageRef, true, wizardInModal);
+    }
+
+    public DirectoryPanel(
+            final String id, final PageReference pageRef, final boolean 
showPaginator, final boolean wizardInModal) {
+
         this(id, new Builder<T, W, E>(null, pageRef) {
 
             private static final long serialVersionUID = -8424727765826509309L;
@@ -129,6 +135,7 @@ public abstract class DirectoryPanel<
             }
         }.setFiltered(false), wizardInModal);
         setPageRef(pageRef);
+        this.showPaginator = showPaginator;
     }
 
     protected DirectoryPanel(final String id, final Builder<T, W, E> builder) {
@@ -202,14 +209,13 @@ public abstract class DirectoryPanel<
         // ---------------------------
         // Rows-per-page selector
         // ---------------------------
-        final Form<?> paginatorForm = new Form<>("paginator");
+        Form<?> paginatorForm = new Form<>("paginator");
         paginatorForm.setOutputMarkupPlaceholderTag(true);
         paginatorForm.setVisible(showPaginator);
         container.add(paginatorForm);
 
-        final DropDownChoice<Integer> rowsChooser = new DropDownChoice<>(
+        DropDownChoice<Integer> rowsChooser = new DropDownChoice<>(
                 "rowsChooser", new PropertyModel<Integer>(this, "rows"), 
prefMan.getPaginatorChoices());
-
         rowsChooser.add(new 
IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
 
             private static final long serialVersionUID = -1107858522700306810L;
@@ -218,7 +224,7 @@ public abstract class DirectoryPanel<
             protected void onUpdate(final AjaxRequestTarget target) {
                 prefMan.set(getRequest(), getResponse(), paginatorRowsKey(), 
String.valueOf(rows));
 
-                final EventDataWrapper data = new EventDataWrapper();
+                EventDataWrapper data = new EventDataWrapper();
                 data.setTarget(target);
                 data.setRows(rows);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/client/console/src/main/java/org/apache/syncope/client/console/panels/HistoryConfDetails.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/HistoryConfDetails.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/HistoryConfDetails.java
index aeb088b..00d95b3 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/HistoryConfDetails.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/HistoryConfDetails.java
@@ -21,7 +21,7 @@ package org.apache.syncope.client.console.panels;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import org.apache.commons.collections4.CollectionUtils;
@@ -150,25 +150,23 @@ public class HistoryConfDetails<T extends 
AbstractHistoryConf> extends Multileve
         return Pair.of(key, json);
     }
 
-    private Map<String, String> getDropdownNamesMap(final List<T> 
historyConfTOs) {
-        Map<String, String> historyConfMap = new HashMap<>();
-        if (selectedHistoryConfTO instanceof ConnInstanceHistoryConfTO) {
-            for (T historyConfValue : historyConfTOs) {
-                ConnInstanceHistoryConfTO historyConf = 
ConnInstanceHistoryConfTO.class.cast(historyConfValue);
-                historyConfMap.put(historyConf.getKey(),
-                        historyConf.getCreation() != null ? 
historyConf.getCreator() + " - " + SyncopeConsoleSession.
-                        get().getDateFormat().format(
-                                historyConf.getCreation()) + " - " + 
historyConf.getKey() : getString("current"));
-            }
-        } else if (selectedHistoryConfTO instanceof ResourceHistoryConfTO) {
-            for (T historyConfValue : historyConfTOs) {
-                ResourceHistoryConfTO historyConf = 
ResourceHistoryConfTO.class.cast(historyConfValue);
-                historyConfMap.put(historyConf.getKey(),
-                        historyConf.getCreation() != null ? 
historyConf.getCreator() + " - " + SyncopeConsoleSession.
-                        get().getDateFormat().format(
-                                historyConf.getCreation()) + " - " + 
historyConf.getKey() : getString("current"));
+    private <T extends AbstractHistoryConf> Map<String, String> 
getDropdownNamesMap(final List<T> historyConfTOs) {
+        Map<String, String> historyConfMap = new LinkedHashMap<>();
+
+        String current = null;
+        for (T historyConf : historyConfTOs) {
+            if (historyConf.getCreation() == null) {
+                current = historyConf.getKey();
+            } else {
+                historyConfMap.put(historyConf.getKey(), 
historyConf.getCreator() + " - "
+                        + SyncopeConsoleSession.get().getDateFormat().format(
+                                historyConf.getCreation()) + " - " + 
historyConf.getKey());
             }
         }
+        if (current != null) {
+            historyConfMap.put(current, getString("current"));
+        }
+
         return historyConfMap;
     }
 
@@ -250,10 +248,10 @@ public class HistoryConfDetails<T extends 
AbstractHistoryConf> extends Multileve
             conf = (T) new ConnInstanceHistoryConfTO();
             ((ConnInstanceHistoryConfTO) conf).setConnInstanceTO(current);
         } else if (selectedHistoryConfTO instanceof ResourceHistoryConfTO) {
-            ResourceTO currentRes = new ResourceRestClient().read(
+            ResourceTO current = new ResourceRestClient().read(
                     
ResourceHistoryConfTO.class.cast(selectedHistoryConfTO).getResourceTO().getKey());
             conf = (T) new ResourceHistoryConfTO();
-            ((ResourceHistoryConfTO) conf).setResourceTO(currentRes);
+            ((ResourceHistoryConfTO) conf).setResourceTO(current);
         }
 
         if (conf != null) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceHistoryConfDirectoryPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceHistoryConfDirectoryPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceHistoryConfDirectoryPanel.java
index ab95676..d212d9d 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceHistoryConfDirectoryPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceHistoryConfDirectoryPanel.java
@@ -68,18 +68,19 @@ public abstract class ResourceHistoryConfDirectoryPanel 
extends DirectoryPanel<
 
     private final String entityKey;
 
-    protected ResourceHistoryConfDirectoryPanel(
+    public ResourceHistoryConfDirectoryPanel(
             final BaseModal<?> baseModal,
             final MultilevelPanel multiLevelPanelRef,
             final String entityKey,
             final PageReference pageRef) {
 
-        super(MultilevelPanel.FIRST_LEVEL_ID, pageRef, false);
+        super(MultilevelPanel.FIRST_LEVEL_ID, pageRef, false, false);
 
         this.baseModal = baseModal;
         this.multiLevelPanelRef = multiLevelPanelRef;
         restClient = new ResourceHistoryRestClient();
         setShowResultPage(false);
+        disableCheckBoxes();
 
         this.entityKey = entityKey;
         initResultTable();

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/client/console/src/main/java/org/apache/syncope/client/console/panels/VirSchemaDetails.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/VirSchemaDetails.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/VirSchemaDetails.java
index 34cc61c..ceb51be 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/VirSchemaDetails.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/VirSchemaDetails.java
@@ -127,20 +127,40 @@ public class VirSchemaDetails extends 
AbstractSchemaDetailsPanel {
 
             @Override
             protected void onUpdate(final AjaxRequestTarget target) {
-                if (selectedResource != null && 
SyncopeConsoleSession.get().owns(StandardEntitlement.CONNECTOR_READ)) {
-                    extAttrName.setChoices(getExtAttrNames());
-                    target.add(extAttrName);
+                if (selectedResource != null) {
+                    String adminRealm = 
getAdminRealm(selectedResource.getKey());
+
+                    if 
(SyncopeConsoleSession.get().owns(StandardEntitlement.CONNECTOR_READ, 
adminRealm)) {
+                        extAttrName.setChoices(getExtAttrNames());
+                        target.add(extAttrName);
+                    }
                 }
             }
         });
     }
 
+    private String getAdminRealm(final String connectorKey) {
+        String adminRealm = null;
+        try {
+            adminRealm = new 
ConnectorRestClient().read(connectorKey).getAdminRealm();
+        } catch (Exception e) {
+            LOG.error("Could not read Admin Realm for External Resource {}", 
selectedResource.getKey());
+        }
+
+        return adminRealm;
+    }
+
     private void populateAnyTypes(final String resourceKey) {
         anyTypes.clear();
-        if (resourceKey != null && 
SyncopeConsoleSession.get().owns(StandardEntitlement.RESOURCE_READ)) {
-            selectedResource = resourceRestClient.read(resourceKey);
-            for (ProvisionTO provisionTO : selectedResource.getProvisions()) {
-                anyTypes.put(provisionTO.getAnyType(), 
provisionTO.getObjectClass());
+        if (resourceKey != null) {
+            ResourceTO resource = resourceRestClient.read(resourceKey);
+            String adminRealm = getAdminRealm(resource.getConnector());
+
+            if 
(SyncopeConsoleSession.get().owns(StandardEntitlement.RESOURCE_READ, 
adminRealm)) {
+                selectedResource = resource;
+                for (ProvisionTO provisionTO : 
selectedResource.getProvisions()) {
+                    anyTypes.put(provisionTO.getAnyType(), 
provisionTO.getObjectClass());
+                }
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
index 7c5c982..5f1d41b 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
@@ -19,10 +19,9 @@
 package org.apache.syncope.client.console.rest;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 import javax.ws.rs.core.Response;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.IterableUtils;
@@ -56,7 +55,7 @@ public class ConnectorRestClient extends BaseRestClient {
     }
 
     public ConnInstanceTO create(final ConnInstanceTO connectorTO) {
-        Set<ConnConfProperty> filteredConf = 
filterProperties(connectorTO.getConf());
+        List<ConnConfProperty> filteredConf = 
filterProperties(connectorTO.getConf());
         connectorTO.getConf().clear();
         connectorTO.getConf().addAll(filteredConf);
 
@@ -86,7 +85,7 @@ public class ConnectorRestClient extends BaseRestClient {
     }
 
     public List<String> getExtAttrNames(
-            final String objectClass, final String connectorKey, final 
Set<ConnConfProperty> conf) {
+            final String objectClass, final String connectorKey, final 
Collection<ConnConfProperty> conf) {
 
         ConnInstanceTO connInstanceTO = new ConnInstanceTO();
         connInstanceTO.setKey(connectorKey);
@@ -125,7 +124,7 @@ public class ConnectorRestClient extends BaseRestClient {
     }
 
     public void update(final ConnInstanceTO connectorTO) {
-        Set<ConnConfProperty> filteredConf = 
filterProperties(connectorTO.getConf());
+        List<ConnConfProperty> filteredConf = 
filterProperties(connectorTO.getConf());
         connectorTO.getConf().clear();
         connectorTO.getConf().addAll(filteredConf);
         getService(ConnectorService.class).update(connectorTO);
@@ -150,8 +149,8 @@ public class ConnectorRestClient extends BaseRestClient {
         return bundles;
     }
 
-    private Set<ConnConfProperty> filterProperties(final Set<ConnConfProperty> 
properties) {
-        Set<ConnConfProperty> newProperties = new HashSet<>();
+    private List<ConnConfProperty> filterProperties(final 
Collection<ConnConfProperty> properties) {
+        List<ConnConfProperty> newProperties = new ArrayList<>();
 
         for (ConnConfProperty property : properties) {
             ConnConfProperty prop = new ConnConfProperty();

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
index 6e2c271..d3b6903 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
@@ -92,14 +92,20 @@ public class ResourceRestClient extends BaseRestClient {
     }
 
     public List<ResourceTO> list() {
-        List<ResourceTO> resources = getService(ResourceService.class).list();
-        Collections.sort(resources, new Comparator<ResourceTO>() {
-
-            @Override
-            public int compare(final ResourceTO o1, final ResourceTO o2) {
-                return 
ComparatorUtils.<String>naturalComparator().compare(o1.getKey(), o2.getKey());
-            }
-        });
+        List<ResourceTO> resources = Collections.emptyList();
+        try {
+            resources = getService(ResourceService.class).list();
+            Collections.sort(resources, new Comparator<ResourceTO>() {
+
+                @Override
+                public int compare(final ResourceTO o1, final ResourceTO o2) {
+                    return 
ComparatorUtils.<String>naturalComparator().compare(o1.getKey(), o2.getKey());
+                }
+            });
+        } catch (Exception e) {
+            LOG.error("Could not fetch the Resource list", e);
+        }
+
         return resources;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
index 606a32d..071da87 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
@@ -409,7 +409,7 @@ public class Topology extends BasePage {
                 final ListView<TopologyNode> innerListView = new 
ListView<TopologyNode>("resources",
                         new 
ArrayList<>(connections.get(connectorKey).values())) {
 
-                    private static final long serialVersionUID = 1L;
+                    private static final long serialVersionUID = 
-3447760771863754342L;
 
                     private final int size = getModelObject().size() + 1;
 
@@ -505,7 +505,7 @@ public class Topology extends BasePage {
 
         newlyCreated = new ListView<TopologyNode>("newlyCreated", new 
ArrayList<TopologyNode>()) {
 
-            private static final long serialVersionUID = 1L;
+            private static final long serialVersionUID = 4949588177564901031L;
 
             @Override
             protected void populateItem(final ListItem<TopologyNode> item) {
@@ -542,7 +542,7 @@ public class Topology extends BasePage {
 
         behaviors.add(new Behavior() {
 
-            private static final long serialVersionUID = 1L;
+            private static final long serialVersionUID = 2661717818979056044L;
 
             @Override
             public void renderHead(final Component component, final 
IHeaderResponse response) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/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 8b6b1a5..8ffa39a 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
@@ -106,9 +106,7 @@ public class TopologyTogglePanel extends 
TogglePanel<Serializable> {
 
         provisionModal = new BaseModal<>("outer");
         provisionModal.size(Modal.Size.Large);
-        if 
(SyncopeConsoleSession.get().owns(StandardEntitlement.RESOURCE_UPDATE)) {
-            provisionModal.addSubmitButton();
-        }
+        provisionModal.addSubmitButton();
         addOuterObject(provisionModal);
 
         historyModal = new BaseModal<>("outer");
@@ -304,19 +302,20 @@ public class TopologyTogglePanel extends 
TogglePanel<Serializable> {
 
             @Override
             public void onClick(final AjaxRequestTarget target) {
-                final ConnInstanceTO modelObject = 
connectorRestClient.read(String.class.cast(node.getKey()));
+                ConnInstanceTO connInstance = 
connectorRestClient.read(String.class.cast(node.getKey()));
 
-                final IModel<ConnInstanceTO> model = new 
CompoundPropertyModel<>(modelObject);
+                final IModel<ConnInstanceTO> model = new 
CompoundPropertyModel<>(connInstance);
                 modal.setFormModel(model);
 
-                target.add(modal.setContent(new 
ConnectorWizardBuilder(modelObject, pageRef).
+                target.add(modal.setContent(new 
ConnectorWizardBuilder(connInstance, pageRef).
                         build(BaseModal.CONTENT_ID,
-                                
SyncopeConsoleSession.get().owns(StandardEntitlement.CONNECTOR_UPDATE)
+                                SyncopeConsoleSession.get().
+                                        
owns(StandardEntitlement.CONNECTOR_UPDATE, connInstance.getAdminRealm())
                                 ? AjaxWizard.Mode.EDIT
                                 : AjaxWizard.Mode.READONLY)));
 
                 modal.header(
-                        new 
Model<>(MessageFormat.format(getString("connector.edit"), 
modelObject.getDisplayName())));
+                        new 
Model<>(MessageFormat.format(getString("connector.edit"), 
connInstance.getDisplayName())));
                 modal.show(true);
             }
 
@@ -336,9 +335,10 @@ public class TopologyTogglePanel extends 
TogglePanel<Serializable> {
             @Override
             public void onClick(final AjaxRequestTarget target) {
                 String connKey = String.class.cast(node.getKey());
-                final ConnInstanceTO modelObject = 
connectorRestClient.read(String.class.cast(node.getKey()));
+                ConnInstanceTO connInstance = 
connectorRestClient.read(connKey);
 
-                target.add(historyModal.setContent(new 
HistoryConfList<>(historyModal, connKey, pageRef, modelObject)));
+                target.add(historyModal.setContent(
+                        new HistoryConfList<>(historyModal, connKey, pageRef, 
connInstance)));
 
                 historyModal.header(
                         new 
Model<>(MessageFormat.format(getString("connector.menu.history"), 
node.getDisplayName())));
@@ -389,14 +389,16 @@ public class TopologyTogglePanel extends 
TogglePanel<Serializable> {
 
             @Override
             public void onClick(final AjaxRequestTarget target) {
-                ResourceTO modelObject = 
resourceRestClient.read(node.getKey());
+                ResourceTO resource = resourceRestClient.read(node.getKey());
+                ConnInstanceTO connInstance = 
connectorRestClient.read(resource.getConnector());
 
-                IModel<ResourceTO> model = new 
CompoundPropertyModel<>(modelObject);
+                IModel<ResourceTO> model = new 
CompoundPropertyModel<>(resource);
                 modal.setFormModel(model);
 
-                target.add(modal.setContent(new 
ResourceWizardBuilder(modelObject, pageRef).
+                target.add(modal.setContent(new 
ResourceWizardBuilder(resource, pageRef).
                         build(BaseModal.CONTENT_ID,
-                                
SyncopeConsoleSession.get().owns(StandardEntitlement.RESOURCE_UPDATE)
+                                SyncopeConsoleSession.get().
+                                        
owns(StandardEntitlement.RESOURCE_UPDATE, connInstance.getAdminRealm())
                                 ? AjaxWizard.Mode.EDIT
                                 : AjaxWizard.Mode.READONLY)));
 
@@ -443,11 +445,21 @@ public class TopologyTogglePanel extends 
TogglePanel<Serializable> {
             @Override
             public void onClick(final AjaxRequestTarget target) {
                 ResourceTO resource = resourceRestClient.read(node.getKey());
+                ConnInstanceTO connInstance = 
connectorRestClient.read(resource.getConnector());
+
+                if (SyncopeConsoleSession.get().
+                        owns(StandardEntitlement.RESOURCE_UPDATE, 
connInstance.getAdminRealm())) {
+
+                    provisionModal.addSubmitButton();
+                } else {
+                    provisionModal.removeSubmitButton();
+                }
 
                 IModel<ResourceTO> model = new 
CompoundPropertyModel<>(resource);
                 provisionModal.setFormModel(model);
 
-                target.add(provisionModal.setContent(new 
ResourceProvisionPanel(provisionModal, resource, pageRef)));
+                target.add(provisionModal.setContent(
+                        new ResourceProvisionPanel(provisionModal, resource, 
connInstance.getAdminRealm(), pageRef)));
 
                 provisionModal.header(new 
Model<>(MessageFormat.format(getString("resource.edit"), node.getKey())));
                 provisionModal.show(true);

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
index 1df1e6c..968cb57 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
@@ -24,6 +24,8 @@ import 
de.agilecoders.wicket.extensions.markup.html.bootstrap.behavior.Draggable
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.client.console.panels.AbstractModalPanel;
 import org.apache.syncope.client.console.panels.ModalPanel;
 import org.apache.syncope.client.console.panels.NotificationPanel;
@@ -223,6 +225,22 @@ public class BaseModal<T extends Serializable> extends 
Modal<T> {
         return submit;
     }
 
+    public void removeSubmitButton() {
+        if (!(BaseModal.this.getContent() instanceof SubmitableModalPanel)) {
+            throw new IllegalStateException();
+        }
+
+        CollectionUtils.filterInverse(this.components, new 
Predicate<Component>() {
+
+            @Override
+            public boolean evaluate(final Component component) {
+                return SUBMIT.equals(component.getId());
+            }
+        });
+
+        submitButton = null;
+    }
+
     @Override
     protected void onInitialize() {
         super.onInitialize();

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceConnConfPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceConnConfPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceConnConfPanel.java
index 0869da9..a5e397a 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceConnConfPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceConnConfPanel.java
@@ -24,7 +24,6 @@ import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import org.apache.syncope.client.console.rest.ConnectorRestClient;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
@@ -49,7 +48,7 @@ public abstract class ResourceConnConfPanel extends 
AbstractConnConfPanel<Resour
 
             @Override
             protected List<ConnConfProperty> load() {
-                final List<ConnConfProperty> confOverride = 
getConnProperties(resourceTO);
+                List<ConnConfProperty> confOverride = 
getConnProperties(resourceTO);
                 resourceTO.getConfOverride().clear();
                 resourceTO.getConfOverride().addAll(confOverride);
 
@@ -59,7 +58,7 @@ public abstract class ResourceConnConfPanel extends 
AbstractConnConfPanel<Resour
 
                     @Override
                     public List<ConnConfProperty> getObject() {
-                        final List<ConnConfProperty> res = new 
ArrayList<>((Set<ConnConfProperty>) super.getObject());
+                        List<ConnConfProperty> res = new 
ArrayList<>(super.getObject());
 
                         // re-order properties
                         Collections.sort(res, new 
Comparator<ConnConfProperty>() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java
index ceab536..be20666 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java
@@ -79,6 +79,7 @@ public class ResourceProvisionPanel extends 
AbstractModalPanel<Serializable> {
     public ResourceProvisionPanel(
             final BaseModal<Serializable> modal,
             final ResourceTO resourceTO,
+            final String adminRealm,
             final PageReference pageRef) {
 
         super(modal, pageRef);
@@ -125,7 +126,7 @@ public class ResourceProvisionPanel extends 
AbstractModalPanel<Serializable> {
 
             @Override
             protected void customActionOnFinishCallback(final 
AjaxRequestTarget target) {
-                checkAddButton();
+                checkAddButton(adminRealm);
 
                 // keep list ordered - SYNCOPE-1154
                 sortProvisions();
@@ -217,7 +218,7 @@ public class ResourceProvisionPanel extends 
AbstractModalPanel<Serializable> {
                             
resourceTO.getProvisions().remove(provision.getProvisionTO());
                         }
                         provisions.remove(provision);
-                        checkAddButton();
+                        checkAddButton(adminRealm);
                         send(ResourceProvisionPanel.this, Broadcast.DEPTH, new 
ListViewReload<>(target));
                     }
                 }, ActionLink.ActionType.DELETE, 
StandardEntitlement.RESOURCE_UPDATE, true);
@@ -225,7 +226,7 @@ public class ResourceProvisionPanel extends 
AbstractModalPanel<Serializable> {
         builder.addNewItemPanelBuilder(wizard);
 
         list = builder.build("provision");
-        
list.setReadOnly(!SyncopeConsoleSession.get().owns(StandardEntitlement.RESOURCE_UPDATE));
+        
list.setReadOnly(!SyncopeConsoleSession.get().owns(StandardEntitlement.RESOURCE_UPDATE,
 adminRealm));
 
         addAjaxLink = new AjaxLink<ResourceProvision>("add") {
 
@@ -261,7 +262,7 @@ public class ResourceProvisionPanel extends 
AbstractModalPanel<Serializable> {
             }
 
         };
-        checkAddButton();
+        checkAddButton(adminRealm);
         add(objectTypeTogglePanel);
     }
 
@@ -346,9 +347,9 @@ public class ResourceProvisionPanel extends 
AbstractModalPanel<Serializable> {
         };
     }
 
-    private void checkAddButton() {
+    private void checkAddButton(final String adminRealm) {
         boolean enabled =
-                
SyncopeConsoleSession.get().owns(StandardEntitlement.RESOURCE_UPDATE)
+                
SyncopeConsoleSession.get().owns(StandardEntitlement.RESOURCE_UPDATE, 
adminRealm)
                 && !getAnyTypes().getObject().isEmpty();
         addAjaxLink.setVisible(enabled);
         objectTypeTogglePanel.setEnabled(enabled);

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
----------------------------------------------------------------------
diff --git 
a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java 
b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
index 9440972..23fb590 100644
--- 
a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
+++ 
b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
@@ -20,8 +20,9 @@ package org.apache.syncope.common.lib.to;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
 import java.util.EnumSet;
-import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import javax.ws.rs.PathParam;
 import javax.xml.bind.annotation.XmlElement;
@@ -52,7 +53,7 @@ public class ConnInstanceTO extends AbstractBaseBean 
implements EntityTO {
 
     private String version;
 
-    private final Set<ConnConfProperty> conf = new HashSet<>();
+    private final List<ConnConfProperty> conf = new ArrayList<>();
 
     private final Set<ConnectorCapability> capabilities = 
EnumSet.noneOf(ConnectorCapability.class);
 
@@ -116,7 +117,7 @@ public class ConnInstanceTO extends AbstractBaseBean 
implements EntityTO {
     @XmlElementWrapper(name = "conf")
     @XmlElement(name = "property")
     @JsonProperty("conf")
-    public Set<ConnConfProperty> getConf() {
+    public List<ConnConfProperty> getConf() {
         return this.conf;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
----------------------------------------------------------------------
diff --git 
a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java 
b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
index 9ea0029..4bc9c0d 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
@@ -22,7 +22,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.ArrayList;
 import java.util.EnumSet;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import javax.ws.rs.PathParam;
@@ -79,7 +78,7 @@ public class ResourceTO extends AbstractBaseBean implements 
EntityTO {
 
     private String pullPolicy;
 
-    private final Set<ConnConfProperty> confOverride = new HashSet<>();
+    private final List<ConnConfProperty> confOverride = new ArrayList<>();
 
     private boolean overrideCapabilities = false;
 
@@ -215,7 +214,7 @@ public class ResourceTO extends AbstractBaseBean implements 
EntityTO {
     @XmlElementWrapper(name = "confOverride")
     @XmlElement(name = "property")
     @JsonProperty("confOverride")
-    public Set<ConnConfProperty> getConfOverride() {
+    public List<ConnConfProperty> getConfOverride() {
         return confOverride;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/common/lib/src/main/java/org/apache/syncope/common/lib/types/ConnConfPropSchema.java
----------------------------------------------------------------------
diff --git 
a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ConnConfPropSchema.java
 
b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ConnConfPropSchema.java
index 8b0dbe6..1958dc6 100644
--- 
a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ConnConfPropSchema.java
+++ 
b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ConnConfPropSchema.java
@@ -21,6 +21,7 @@ package org.apache.syncope.common.lib.types;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -117,7 +118,46 @@ public class ConnConfPropSchema extends AbstractBaseBean 
implements Comparable<C
         return this.getOrder() > other.getOrder()
                 ? 1
                 : this.getOrder() < other.getOrder()
-                        ? -1
-                        : 0;
+                ? -1
+                : 0;
     }
+
+    @Override
+    public int hashCode() {
+        int hash = 5;
+        hash = 53 * hash + Objects.hashCode(this.name);
+        hash = 53 * hash + Objects.hashCode(this.type);
+        hash = 53 * hash + (this.required ? 1 : 0);
+        hash = 53 * hash + this.order;
+        hash = 53 * hash + (this.confidential ? 1 : 0);
+        return hash;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final ConnConfPropSchema other = (ConnConfPropSchema) obj;
+        if (this.required != other.required) {
+            return false;
+        }
+        if (this.order != other.order) {
+            return false;
+        }
+        if (this.confidential != other.confidential) {
+            return false;
+        }
+        if (!Objects.equals(this.name, other.name)) {
+            return false;
+        }
+        return Objects.equals(this.type, other.type);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorHistoryService.java
----------------------------------------------------------------------
diff --git 
a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorHistoryService.java
 
b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorHistoryService.java
index 28a0b3c..1825d08 100644
--- 
a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorHistoryService.java
+++ 
b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorHistoryService.java
@@ -30,7 +30,7 @@ import javax.ws.rs.core.MediaType;
 import org.apache.syncope.common.lib.to.ConnInstanceHistoryConfTO;
 
 /**
- * REST operations for connector instance configuration versioning.
+ * REST operations for connector configuration versioning.
  */
 @Path("connectorsHistory")
 public interface ConnectorHistoryService extends JAXRSService {
@@ -48,7 +48,7 @@ public interface ConnectorHistoryService extends JAXRSService 
{
 
     /**
      * Restores the connector configuration history instance matching the 
provided key.
-     * 
+     *
      * @param key connector configuration history instance key to be restored
      */
     @POST

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
index 908bb39..258ea31 100644
--- 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.persistence.api.entity;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
@@ -60,7 +61,7 @@ public interface ConnInstance extends Entity {
 
     List<? extends ExternalResource> getResources();
 
-    void setConf(Set<ConnConfProperty> conf);
+    void setConf(Collection<ConnConfProperty> conf);
 
     Set<ConnConfProperty> getConf();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
index 7678fc2..fb5b88e 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.core.persistence.jpa.entity;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -191,7 +192,7 @@ public class JPAConnInstance extends 
AbstractGeneratedKeyEntity implements ConnI
     }
 
     @Override
-    public void setConf(final Set<ConnConfProperty> conf) {
+    public void setConf(final Collection<ConnConfProperty> conf) {
         jsonConf = POJOHelper.serialize(new HashSet<>(conf));
     }
 
@@ -227,7 +228,7 @@ public class JPAConnInstance extends 
AbstractGeneratedKeyEntity implements ConnI
         // DEFAULT_TIMEOUT will be returned in case of null timeout:
         // * instances created by the content loader
         // * or with a timeout nullified explicitely
-        return connRequestTimeout == null ? Integer.valueOf(DEFAULT_TIMEOUT) : 
connRequestTimeout;
+        return connRequestTimeout == null ? DEFAULT_TIMEOUT : 
connRequestTimeout;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorFactory.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorFactory.java
 
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorFactory.java
index 4c6dd82..0b0beb9 100644
--- 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorFactory.java
+++ 
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorFactory.java
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.core.provisioning.api;
 
-import java.util.Set;
+import java.util.Collection;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.ConnectorCapability;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
@@ -41,8 +41,8 @@ public interface ConnectorFactory {
      */
     ConnInstance buildConnInstanceOverride(
             ConnInstance connInstance,
-            Set<ConnConfProperty> confOverride,
-            Set<ConnectorCapability> capabilitiesOverride);
+            Collection<ConnConfProperty> confOverride,
+            Collection<ConnectorCapability> capabilitiesOverride);
 
     /**
      * Create connector from given connector instance.

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
index 901acc2..f3c6e73 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.provisioning.java;
 
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Locale;
@@ -80,8 +81,8 @@ public class ConnectorManager implements ConnectorRegistry, 
ConnectorFactory, Sy
     @Override
     public ConnInstance buildConnInstanceOverride(
             final ConnInstance connInstance,
-            final Set<ConnConfProperty> confOverride,
-            final Set<ConnectorCapability> capabilitiesOverride) {
+            final Collection<ConnConfProperty> confOverride,
+            final Collection<ConnectorCapability> capabilitiesOverride) {
 
         synchronized (this) {
             if (entityFactory == null) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
index 0fc31f7..7dfb721 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
@@ -22,6 +22,7 @@ import java.net.URI;
 import org.apache.syncope.core.provisioning.api.data.ConnInstanceDataBinder;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import org.apache.commons.lang3.tuple.Pair;
@@ -54,7 +55,7 @@ import org.springframework.stereotype.Component;
 @Component
 public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
 
-    private static final String[] IGNORE_PROPERTIES = { "poolConf", 
"location", "adminRealm" };
+    private static final String[] IGNORE_PROPERTIES = { "poolConf", 
"location", "adminRealm", "conf" };
 
     @Autowired
     private ConnIdBundleManager connIdBundleManager;
@@ -110,6 +111,7 @@ public class ConnInstanceDataBinderImpl implements 
ConnInstanceDataBinder {
         if (connInstanceTO.getLocation() != null) {
             connInstance.setLocation(connInstanceTO.getLocation());
         }
+        connInstance.setConf(connInstanceTO.getConf());
         if (connInstanceTO.getPoolConf() != null) {
             connInstance.setPoolConf(
                     
ConnPoolConfUtils.getConnPoolConf(connInstanceTO.getPoolConf(), 
entityFactory.newConnPoolConf()));
@@ -130,21 +132,24 @@ public class ConnInstanceDataBinderImpl implements 
ConnInstanceDataBinder {
             throw new NotFoundException("Connector '" + 
connInstanceTO.getKey() + "'");
         }
 
-        // 1. save the current configuration, before update
-        ConnInstanceHistoryConf connInstanceHistoryConf = 
entityFactory.newEntity(ConnInstanceHistoryConf.class);
-        connInstanceHistoryConf.setCreator(AuthContextUtils.getUsername());
-        connInstanceHistoryConf.setCreation(new Date());
-        connInstanceHistoryConf.setEntity(connInstance);
-        connInstanceHistoryConf.setConf(getConnInstanceTO(connInstance));
-        connInstanceHistoryConfDAO.save(connInstanceHistoryConf);
-
-        // 2. ensure the maximum history size is not exceeded
-        List<ConnInstanceHistoryConf> history = 
connInstanceHistoryConfDAO.findByEntity(connInstance);
-        long maxHistorySize = confDAO.find("connector.conf.history.size", 10L);
-        if (maxHistorySize < history.size()) {
-            // always remove the last item since history was obtained  by a 
query with ORDER BY creation DESC
-            for (int i = 0; i < history.size() - maxHistorySize; i++) {
-                connInstanceHistoryConfDAO.delete(history.get(history.size() - 
1).getKey());
+        ConnInstanceTO current = getConnInstanceTO(connInstance);
+        if (!current.equals(connInstanceTO)) {
+            // 1. save the current configuration, before update
+            ConnInstanceHistoryConf connInstanceHistoryConf = 
entityFactory.newEntity(ConnInstanceHistoryConf.class);
+            connInstanceHistoryConf.setCreator(AuthContextUtils.getUsername());
+            connInstanceHistoryConf.setCreation(new Date());
+            connInstanceHistoryConf.setEntity(connInstance);
+            connInstanceHistoryConf.setConf(current);
+            connInstanceHistoryConfDAO.save(connInstanceHistoryConf);
+
+            // 2. ensure the maximum history size is not exceeded
+            List<ConnInstanceHistoryConf> history = 
connInstanceHistoryConfDAO.findByEntity(connInstance);
+            long maxHistorySize = confDAO.find("connector.conf.history.size", 
10L);
+            if (maxHistorySize < history.size()) {
+                // always remove the last item since history was obtained  by 
a query with ORDER BY creation DESC
+                for (int i = 0; i < history.size() - maxHistorySize; i++) {
+                    
connInstanceHistoryConfDAO.delete(history.get(history.size() - 1).getKey());
+                }
             }
         }
 
@@ -241,9 +246,10 @@ public class ConnInstanceDataBinderImpl implements 
ConnInstanceDataBinder {
         BeanUtils.copyProperties(connInstance, connInstanceTO, 
IGNORE_PROPERTIES);
         
connInstanceTO.setAdminRealm(connInstance.getAdminRealm().getFullPath());
         connInstanceTO.setLocation(info.getLeft().toASCIIString());
+        connInstanceTO.getConf().addAll(connInstance.getConf());
         // refresh stored properties in the given connInstance with direct 
information from underlying connector
         ConfigurationProperties properties = 
connIdBundleManager.getConfigurationProperties(info.getRight());
-        for (final String propName : properties.getPropertyNames()) {
+        for (String propName : properties.getPropertyNames()) {
             ConnConfPropSchema schema = 
build(properties.getProperty(propName));
 
             ConnConfProperty property = connInstanceTO.getConf(propName);
@@ -253,9 +259,16 @@ public class ConnInstanceDataBinderImpl implements 
ConnInstanceDataBinder {
             }
             property.setSchema(schema);
         }
+        Collections.sort(connInstanceTO.getConf());
 
         // pool configuration
-        if (connInstance.getPoolConf() != null) {
+        if (connInstance.getPoolConf() != null
+                && (connInstance.getPoolConf().getMaxIdle() != null
+                || connInstance.getPoolConf().getMaxObjects() != null
+                || connInstance.getPoolConf().getMaxWait() != null
+                || connInstance.getPoolConf().getMinEvictableIdleTimeMillis() 
!= null
+                || connInstance.getPoolConf().getMinIdle() != null)) {
+
             ConnPoolConfTO poolConf = new ConnPoolConfTO();
             BeanUtils.copyProperties(connInstance.getPoolConf(), poolConf);
             connInstanceTO.setPoolConf(poolConf);

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
index b21a605..9f8e75d 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.provisioning.java.data;
 
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -116,22 +117,25 @@ public class ResourceDataBinderImpl implements 
ResourceDataBinder {
     @Override
     public ExternalResource update(final ExternalResource resource, final 
ResourceTO resourceTO) {
         if (resource.getKey() != null) {
-            // 1. save the current configuration, before update
-            ExternalResourceHistoryConf resourceHistoryConf =
-                    entityFactory.newEntity(ExternalResourceHistoryConf.class);
-            resourceHistoryConf.setCreator(AuthContextUtils.getUsername());
-            resourceHistoryConf.setCreation(new Date());
-            resourceHistoryConf.setEntity(resource);
-            resourceHistoryConf.setConf(getResourceTO(resource));
-            resourceHistoryConfDAO.save(resourceHistoryConf);
-
-            // 2. ensure the maximum history size is not exceeded
-            List<ExternalResourceHistoryConf> history = 
resourceHistoryConfDAO.findByEntity(resource);
-            long maxHistorySize = confDAO.find("resource.conf.history.size", 
10L);
-            if (maxHistorySize < history.size()) {
-                // always remove the last item since history was obtained  by 
a query with ORDER BY creation DESC
-                for (int i = 0; i < history.size() - maxHistorySize; i++) {
-                    resourceHistoryConfDAO.delete(history.get(history.size() - 
1).getKey());
+            ResourceTO current = getResourceTO(resource);
+            if (!current.equals(resourceTO)) {
+                // 1. save the current configuration, before update
+                ExternalResourceHistoryConf resourceHistoryConf =
+                        
entityFactory.newEntity(ExternalResourceHistoryConf.class);
+                resourceHistoryConf.setCreator(AuthContextUtils.getUsername());
+                resourceHistoryConf.setCreation(new Date());
+                resourceHistoryConf.setEntity(resource);
+                resourceHistoryConf.setConf(current);
+                resourceHistoryConfDAO.save(resourceHistoryConf);
+
+                // 2. ensure the maximum history size is not exceeded
+                List<ExternalResourceHistoryConf> history = 
resourceHistoryConfDAO.findByEntity(resource);
+                long maxHistorySize = 
confDAO.find("resource.conf.history.size", 10L);
+                if (maxHistorySize < history.size()) {
+                    // always remove the last item since history was obtained  
by a query with ORDER BY creation DESC
+                    for (int i = 0; i < history.size() - maxHistorySize; i++) {
+                        
resourceHistoryConfDAO.delete(history.get(history.size() - 1).getKey());
+                    }
                 }
             }
         }
@@ -579,6 +583,7 @@ public class ResourceDataBinderImpl implements 
ResourceDataBinder {
                 ? null : resource.getPullPolicy().getKey());
 
         resourceTO.getConfOverride().addAll(resource.getConfOverride());
+        Collections.sort(resourceTO.getConfOverride());
 
         resourceTO.setOverrideCapabilities(resource.isOverrideCapabilities());
         
resourceTO.getCapabilitiesOverride().addAll(resource.getCapabilitiesOverride());

http://git-wip-us.apache.org/repos/asf/syncope/blob/36f2537e/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
index 02e744f..09a2653 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
@@ -319,7 +319,7 @@ public class ConnectorITCase extends AbstractITCase {
 
     @Test
     public void getConnectorConfiguration() {
-        Set<ConnConfProperty> props = connectorService.read(
+        List<ConnConfProperty> props = connectorService.read(
                 "6c2acf1b-b052-46f0-8c56-7a8ad6905edf", 
Locale.ENGLISH.getLanguage()).getConf();
         assertNotNull(props);
         assertFalse(props.isEmpty());

Reply via email to