You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2017/07/06 14:56:18 UTC
[3/4] syncope git commit: [SYNCOPE-1145] Core and Common
implementation completed, Console still TODO
http://git-wip-us.apache.org/repos/asf/syncope/blob/7451efb6/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 63cb084..ba4d62d 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,8 @@ import java.net.URI;
import org.apache.syncope.core.provisioning.api.data.ConnInstanceDataBinder;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Date;
+import java.util.List;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.lang3.tuple.Pair;
@@ -31,8 +33,12 @@ import org.apache.syncope.common.lib.to.ConnPoolConfTO;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.ConnConfPropSchema;
import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.core.persistence.api.dao.ConfDAO;
import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
+import org.apache.syncope.core.persistence.api.dao.ConnInstanceHistoryConfDAO;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
import org.apache.syncope.core.persistence.api.entity.ConnInstance;
+import org.apache.syncope.core.persistence.api.entity.ConnInstanceHistoryConf;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
import org.apache.syncope.core.provisioning.api.utils.ConnPoolConfUtils;
@@ -40,6 +46,7 @@ import org.identityconnectors.framework.api.ConfigurationProperties;
import org.identityconnectors.framework.api.ConfigurationProperty;
import org.identityconnectors.framework.impl.api.ConfigurationPropertyImpl;
import org.apache.syncope.core.spring.BeanUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.identityconnectors.framework.api.ConnectorInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -56,6 +63,12 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
private ConnInstanceDAO connInstanceDAO;
@Autowired
+ private ConnInstanceHistoryConfDAO connInstanceHistoryConfDAO;
+
+ @Autowired
+ private ConfDAO confDAO;
+
+ @Autowired
private EntityFactory entityFactory;
@Override
@@ -102,14 +115,31 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
}
@Override
- public ConnInstance update(final String key, final ConnInstanceTO connInstanceTO) {
- SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing);
-
- if (key == null) {
- sce.getElements().add("connector key");
+ public ConnInstance update(final ConnInstanceTO connInstanceTO) {
+ ConnInstance connInstance = connInstanceDAO.find(connInstanceTO.getKey());
+ if (connInstance == null) {
+ 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", "10").getValues().get(0).getLongValue();
+ 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());
+ }
}
- ConnInstance connInstance = connInstanceDAO.find(key);
+ // 3. actual update
connInstance.getCapabilities().clear();
connInstance.getCapabilities().addAll(connInstanceTO.getCapabilities());
@@ -148,8 +178,12 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
ConnPoolConfUtils.getConnPoolConf(connInstanceTO.getPoolConf(), entityFactory.newConnPoolConf()));
}
- if (!sce.isEmpty()) {
- throw sce;
+ try {
+ connInstance = connInstanceDAO.save(connInstance);
+ } catch (Exception e) {
+ SyncopeClientException ex = SyncopeClientException.build(ClientExceptionType.InvalidConnInstance);
+ ex.getElements().add(e.getMessage());
+ throw ex;
}
return connInstance;
@@ -188,8 +222,7 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
BeanUtils.copyProperties(connInstance, connInstanceTO, IGNORE_PROPERTIES);
connInstanceTO.setLocation(info.getLeft().toASCIIString());
// refresh stored properties in the given connInstance with direct information from underlying connector
- ConfigurationProperties properties =
- connIdBundleManager.getConfigurationProperties(info.getRight());
+ ConfigurationProperties properties = connIdBundleManager.getConfigurationProperties(info.getRight());
for (final String propName : properties.getPropertyNames()) {
ConnConfPropSchema schema = build(properties.getProperty(propName));
http://git-wip-us.apache.org/repos/asf/syncope/blob/7451efb6/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 8e730b7..e6293cf 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,8 +18,10 @@
*/
package org.apache.syncope.core.provisioning.java.data;
+import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.IteratorUtils;
import org.apache.syncope.common.lib.SyncopeClientCompositeException;
@@ -46,6 +48,8 @@ import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
import org.apache.syncope.core.spring.BeanUtils;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.ConfDAO;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceHistoryConfDAO;
import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
@@ -53,12 +57,14 @@ import org.apache.syncope.core.persistence.api.entity.DerSchema;
import org.apache.syncope.core.persistence.api.entity.PlainSchema;
import org.apache.syncope.core.persistence.api.entity.VirSchema;
import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResourceHistoryConf;
import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
import org.apache.syncope.core.provisioning.java.IntAttrNameParser;
import org.apache.syncope.core.provisioning.api.IntAttrName;
import org.apache.syncope.core.provisioning.api.data.ResourceDataBinder;
import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.identityconnectors.framework.common.objects.ObjectClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -88,6 +94,12 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
private AnyTypeClassDAO anyTypeClassDAO;
@Autowired
+ private ExternalResourceHistoryConfDAO resourceHistoryConfDAO;
+
+ @Autowired
+ private ConfDAO confDAO;
+
+ @Autowired
private EntityFactory entityFactory;
@Autowired
@@ -100,8 +112,25 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
@Override
public ExternalResource update(final ExternalResource resource, final ResourceTO resourceTO) {
- if (resourceTO == null) {
- return null;
+ 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", "10").getValues().get(0).getLongValue();
+ 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());
+ }
+ }
}
resource.setKey(resourceTO.getKey());
http://git-wip-us.apache.org/repos/asf/syncope/blob/7451efb6/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
index f43e662..2635413 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
@@ -153,7 +153,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
protected TaskDataBinder taskDataBinder;
@Autowired
- private TaskUtilsFactory taskUtilsFactory;
+ protected TaskUtilsFactory taskUtilsFactory;
@Autowired
protected EntityFactory entityFactory;
@@ -365,6 +365,8 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
protected TaskExec execute(final PropagationTask task, final PropagationReporter reporter) {
List<PropagationActions> actions = getPropagationActions(task.getResource());
+ String resource = task.getResource().getKey();
+
Date start = new Date();
TaskExec execution = entityFactory.newEntity(TaskExec.class);
@@ -384,7 +386,6 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
Uid uid = null;
Connector connector = null;
Result result;
- String resource = task.getResource().getKey();
try {
provision = task.getResource().getProvision(new ObjectClass(task.getObjectClassName()));
orgUnit = task.getResource().getOrgUnit();
@@ -507,10 +508,9 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
for (PropagationActions action : actions) {
action.after(task, execution, afterObj);
}
-
+
String anyTypeKind = task.getAnyTypeKind() == null ? "realm" : task.getAnyTypeKind().name().toLowerCase();
String operation = task.getOperation().name().toLowerCase();
- // SYNCOPE-1139, check if notification or audit are requested and use TOs instead of persistence objects
boolean notificationsAvailable = notificationManager.notificationsAvailable(
AuditElements.EventCategoryType.PROPAGATION, anyTypeKind, resource, operation);
boolean auditRequested = auditManager.auditRequested(AuditElements.EventCategoryType.PROPAGATION, anyTypeKind,
http://git-wip-us.apache.org/repos/asf/syncope/blob/7451efb6/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorHistoryServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorHistoryServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorHistoryServiceImpl.java
new file mode 100644
index 0000000..3424c5e
--- /dev/null
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorHistoryServiceImpl.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.rest.cxf.service;
+
+import java.util.List;
+import org.apache.syncope.common.lib.to.ConnInstanceHistoryConfTO;
+import org.apache.syncope.common.rest.api.service.ConnectorHistoryService;
+import org.apache.syncope.core.logic.ConnectorHistoryLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class ConnectorHistoryServiceImpl extends AbstractServiceImpl implements ConnectorHistoryService {
+
+ @Autowired
+ private ConnectorHistoryLogic logic;
+
+ @Override
+ public List<ConnInstanceHistoryConfTO> list(final String connectorKey) {
+ return logic.list(connectorKey);
+ }
+
+ @Override
+ public void restore(final String key) {
+ logic.restore(key);
+ }
+
+ @Override
+ public void delete(final String key) {
+ logic.delete(key);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/7451efb6/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceHistoryServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceHistoryServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceHistoryServiceImpl.java
new file mode 100644
index 0000000..b69b5be
--- /dev/null
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceHistoryServiceImpl.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.rest.cxf.service;
+
+import java.util.List;
+import org.apache.syncope.common.lib.to.ResourceHistoryConfTO;
+import org.apache.syncope.common.rest.api.service.ResourceHistoryService;
+import org.apache.syncope.core.logic.ResourceHistoryLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class ResourceHistoryServiceImpl extends AbstractServiceImpl implements ResourceHistoryService {
+
+ @Autowired
+ private ResourceHistoryLogic logic;
+
+ @Override
+ public List<ResourceHistoryConfTO> list(final String resourceKey) {
+ return logic.list(resourceKey);
+ }
+
+ @Override
+ public void restore(final String key) {
+ logic.restore(key);
+ }
+
+ @Override
+ public void delete(final String key) {
+ logic.delete(key);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/7451efb6/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
index b584802..880ed66 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
@@ -25,7 +25,6 @@ import static org.junit.Assert.fail;
import java.io.InputStream;
import java.net.URI;
import java.util.Locale;
-import java.util.Map;
import java.util.Properties;
import java.util.UUID;
import javax.naming.Context;
@@ -61,7 +60,6 @@ import org.apache.syncope.common.lib.to.ReportTO;
import org.apache.syncope.common.lib.to.RoleTO;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.ConnConfProperty;
import org.apache.syncope.common.lib.types.PatchOperation;
import org.apache.syncope.common.lib.types.SchemaType;
import org.apache.syncope.common.lib.types.TraceLevel;
@@ -105,6 +103,9 @@ import org.junit.runners.MethodSorters;
import org.springframework.jdbc.core.JdbcTemplate;
import com.google.common.net.HttpHeaders;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.rest.api.service.ConnectorHistoryService;
+import org.apache.syncope.common.rest.api.service.ResourceHistoryService;
@FixMethodOrder(MethodSorters.JVM)
public abstract class AbstractITCase {
@@ -209,10 +210,14 @@ public abstract class AbstractITCase {
protected static ResourceService resourceService;
+ protected static ResourceHistoryService resourceHistoryService;
+
protected static ConfigurationService configurationService;
protected static ConnectorService connectorService;
+ protected static ConnectorHistoryService connectorHistoryService;
+
protected static LoggerService loggerService;
protected static ReportTemplateService reportTemplateService;
@@ -289,8 +294,10 @@ public abstract class AbstractITCase {
userWorkflowService = adminClient.getService(UserWorkflowService.class);
groupService = adminClient.getService(GroupService.class);
resourceService = adminClient.getService(ResourceService.class);
+ resourceHistoryService = adminClient.getService(ResourceHistoryService.class);
configurationService = adminClient.getService(ConfigurationService.class);
connectorService = adminClient.getService(ConnectorService.class);
+ connectorHistoryService = adminClient.getService(ConnectorHistoryService.class);
loggerService = adminClient.getService(LoggerService.class);
reportTemplateService = adminClient.getService(ReportTemplateService.class);
reportService = adminClient.getService(ReportService.class);
@@ -507,18 +514,17 @@ public abstract class AbstractITCase {
protected InitialDirContext getLdapResourceDirContext(final String bindDn, final String bindPwd)
throws NamingException {
ResourceTO ldapRes = resourceService.read(RESOURCE_NAME_LDAP);
- final Map<String, ConnConfProperty> ldapConnConf =
- connectorService.read(ldapRes.getConnector(), Locale.ENGLISH.getLanguage()).getConfMap();
+ ConnInstanceTO ldapConn = connectorService.read(ldapRes.getConnector(), Locale.ENGLISH.getLanguage());
Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
- env.put(Context.PROVIDER_URL, "ldap://" + ldapConnConf.get("host").getValues().get(0)
- + ":" + ldapConnConf.get("port").getValues().get(0) + "/");
+ env.put(Context.PROVIDER_URL, "ldap://" + ldapConn.getConf("host").getValues().get(0)
+ + ":" + ldapConn.getConf("port").getValues().get(0) + "/");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL,
- bindDn == null ? ldapConnConf.get("principal").getValues().get(0) : bindDn);
+ bindDn == null ? ldapConn.getConf("principal").getValues().get(0) : bindDn);
env.put(Context.SECURITY_CREDENTIALS,
- bindPwd == null ? ldapConnConf.get("credentials").getValues().get(0) : bindPwd);
+ bindPwd == null ? ldapConn.getConf("credentials").getValues().get(0) : bindPwd);
return new InitialDirContext(env);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/7451efb6/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 4cea200..c5190b3 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
@@ -20,6 +20,7 @@ package org.apache.syncope.fit.core;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -27,24 +28,25 @@ import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.InputStream;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
-import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;
import javax.ws.rs.core.Response;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.SerializationUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.ConnBundleTO;
import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
+import org.apache.syncope.common.lib.to.ConnInstanceHistoryConfTO;
import org.apache.syncope.common.lib.to.ConnInstanceTO;
import org.apache.syncope.common.lib.to.ConnPoolConfTO;
import org.apache.syncope.common.lib.to.MappingItemTO;
@@ -268,97 +270,9 @@ public class ConnectorITCase extends AbstractITCase {
assertEquals(Integer.valueOf(20), actual.getConnRequestTimeout());
}
- private List<ResourceTO> filter(final List<ResourceTO> input, final String connectorKey) {
- List<ResourceTO> result = new ArrayList<>();
-
- for (ResourceTO resource : input) {
- if (connectorKey.equals(resource.getConnector())) {
- result.add(resource);
- }
- }
-
- return result;
- }
-
@Test
- public void issueSYNCOPE10() {
- // ----------------------------------
- // Copy resource and connector in order to create new objects.
- // ----------------------------------
- // Retrieve a connector instance template.
- ConnInstanceTO connInstanceTO = connectorService.read(
- "fcf9f2b0-f7d6-42c9-84a6-61b28255a42b", Locale.ENGLISH.getLanguage());
- assertNotNull(connInstanceTO);
-
- // check for resource
- List<ResourceTO> resources =
- filter(resourceService.list(), "fcf9f2b0-f7d6-42c9-84a6-61b28255a42b");
- assertEquals(4, resources.size());
-
- // Retrieve a resource TO template.
- ResourceTO resourceTO = resources.get(0);
-
- // Make it new.
- resourceTO.setKey("newAbout103" + getUUIDString());
-
- // Make it new.
- connInstanceTO.setKey(null);
- connInstanceTO.setDisplayName("newDisplayName" + getUUIDString());
- // ----------------------------------
-
- // ----------------------------------
- // Create a new connector instance.
- // ----------------------------------
- Response response = connectorService.create(connInstanceTO);
- if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
- throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
- }
-
- connInstanceTO = getObject(response.getLocation(), ConnectorService.class, ConnInstanceTO.class);
- assertNotNull(connInstanceTO);
- assertFalse(connInstanceTO.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
-
- String connKey = connInstanceTO.getKey();
-
- // Link resourceTO to the new connector instance.
- resourceTO.setConnector(connKey);
- // ----------------------------------
-
- // ----------------------------------
- // Check for connector instance update after resource creation.
- // ----------------------------------
- response = resourceService.create(resourceTO);
- resourceTO = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
-
- assertNotNull(resourceTO);
-
- resources = filter(resourceService.list(), connKey);
- assertEquals(1, resources.size());
- // ----------------------------------
-
- // ----------------------------------
- // Check for spring bean.
- // ----------------------------------
- ConnInstanceTO connInstanceBean = connectorService.readByResource(
- resourceTO.getKey(), Locale.ENGLISH.getLanguage());
- assertNotNull(connInstanceBean);
- assertFalse(connInstanceBean.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
- // ----------------------------------
-
- // ----------------------------------
- // Check for spring bean update after connector instance update.
- // ----------------------------------
- connInstanceTO.getCapabilities().add(ConnectorCapability.AUTHENTICATE);
-
- connectorService.update(connInstanceTO);
- ConnInstanceTO actual = connectorService.read(connInstanceTO.getKey(), Locale.ENGLISH.getLanguage());
- assertNotNull(actual);
- assertTrue(connInstanceTO.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
-
- // check for spring bean update
- connInstanceBean = connectorService.readByResource(resourceTO.getKey(), Locale.ENGLISH.getLanguage());
- assertTrue(connInstanceBean.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
- // ----------------------------------
+ public void reload() {
+ connectorService.reload();
}
@Test
@@ -425,11 +339,9 @@ public class ConnectorITCase extends AbstractITCase {
// 1. Check Italian
List<ConnInstanceTO> connectorInstanceTOs = connectorService.list("it");
- Map<String, ConnConfProperty> instanceConfMap;
for (ConnInstanceTO instance : connectorInstanceTOs) {
if ("net.tirasa.connid.bundles.db.table".equals(instance.getBundleName())) {
- instanceConfMap = instance.getConfMap();
- assertEquals("Utente", instanceConfMap.get("user").getSchema().getDisplayName());
+ assertEquals("Utente", instance.getConf("user").getSchema().getDisplayName());
}
}
@@ -438,8 +350,7 @@ public class ConnectorITCase extends AbstractITCase {
for (ConnInstanceTO instance : connectorInstanceTOs) {
if ("net.tirasa.connid.bundles.db.table".equals(instance.getBundleName())) {
- instanceConfMap = instance.getConfMap();
- assertEquals("User", instanceConfMap.get("user").getSchema().getDisplayName());
+ assertEquals("User", instance.getConf("user").getSchema().getDisplayName());
}
}
}
@@ -574,6 +485,132 @@ public class ConnectorITCase extends AbstractITCase {
}
@Test
+ public void history() {
+ List<ConnInstanceHistoryConfTO> history = connectorHistoryService.list("74141a3b-0762-4720-a4aa-fc3e374ef3ef");
+ assertNotNull(history);
+ int pre = history.size();
+
+ ConnInstanceTO ldapConn = connectorService.read("74141a3b-0762-4720-a4aa-fc3e374ef3ef", null);
+ String originalDisplayName = ldapConn.getDisplayName();
+ Set<ConnectorCapability> originalCapabilities = new HashSet<>(ldapConn.getCapabilities());
+ ConnConfProperty originalConfProp = SerializationUtils.clone(ldapConn.getConf("maintainPosixGroupMembership"));
+ assertEquals(1, originalConfProp.getValues().size());
+ assertEquals("false", originalConfProp.getValues().get(0));
+
+ ldapConn.setDisplayName(originalDisplayName + " modified");
+ ldapConn.getCapabilities().clear();
+ ldapConn.getConf("maintainPosixGroupMembership").getValues().set(0, "true");
+ connectorService.update(ldapConn);
+
+ ldapConn = connectorService.read("74141a3b-0762-4720-a4aa-fc3e374ef3ef", null);
+ assertNotEquals(originalDisplayName, ldapConn.getDisplayName());
+ assertNotEquals(originalCapabilities, ldapConn.getCapabilities());
+ assertNotEquals(originalConfProp, ldapConn.getConf("maintainPosixGroupMembership"));
+
+ history = connectorHistoryService.list("74141a3b-0762-4720-a4aa-fc3e374ef3ef");
+ assertEquals(pre + 1, history.size());
+
+ connectorHistoryService.restore(history.get(0).getKey());
+
+ ldapConn = connectorService.read("74141a3b-0762-4720-a4aa-fc3e374ef3ef", null);
+ assertEquals(originalDisplayName, ldapConn.getDisplayName());
+ assertEquals(originalCapabilities, ldapConn.getCapabilities());
+ assertEquals(originalConfProp, ldapConn.getConf("maintainPosixGroupMembership"));
+ }
+
+ @Test
+ public void issueSYNCOPE10() {
+ // ----------------------------------
+ // Copy resource and connector in order to create new objects.
+ // ----------------------------------
+ // Retrieve a connector instance template.
+ ConnInstanceTO connInstanceTO = connectorService.read(
+ "fcf9f2b0-f7d6-42c9-84a6-61b28255a42b", Locale.ENGLISH.getLanguage());
+ assertNotNull(connInstanceTO);
+
+ // check for resource
+ Collection<ResourceTO> resources = CollectionUtils.select(resourceService.list(), new Predicate<ResourceTO>() {
+
+ @Override
+ public boolean evaluate(final ResourceTO object) {
+ return "fcf9f2b0-f7d6-42c9-84a6-61b28255a42b".equals(object.getConnector());
+ }
+ });
+ assertEquals(4, resources.size());
+
+ // Retrieve a resource TO template.
+ ResourceTO resourceTO = resources.iterator().next();
+
+ // Make it new.
+ resourceTO.setKey("newAbout103" + getUUIDString());
+
+ // Make it new.
+ connInstanceTO.setKey(null);
+ connInstanceTO.setDisplayName("newDisplayName" + getUUIDString());
+ // ----------------------------------
+
+ // ----------------------------------
+ // Create a new connector instance.
+ // ----------------------------------
+ Response response = connectorService.create(connInstanceTO);
+ if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+ throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
+ }
+
+ connInstanceTO = getObject(response.getLocation(), ConnectorService.class, ConnInstanceTO.class);
+ assertNotNull(connInstanceTO);
+ assertFalse(connInstanceTO.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
+
+ final String connKey = connInstanceTO.getKey();
+
+ // Link resourceTO to the new connector instance.
+ resourceTO.setConnector(connKey);
+ // ----------------------------------
+
+ // ----------------------------------
+ // Check for connector instance update after resource creation.
+ // ----------------------------------
+ response = resourceService.create(resourceTO);
+ resourceTO = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+
+ assertNotNull(resourceTO);
+
+ resources = CollectionUtils.select(resourceService.list(), new Predicate<ResourceTO>() {
+
+ @Override
+ public boolean evaluate(final ResourceTO object) {
+ return connKey.equals(object.getConnector());
+ }
+ });
+ assertEquals(1, resources.size());
+ // ----------------------------------
+
+ // ----------------------------------
+ // Check for spring bean.
+ // ----------------------------------
+ ConnInstanceTO connInstanceBean = connectorService.readByResource(
+ resourceTO.getKey(), Locale.ENGLISH.getLanguage());
+ assertNotNull(connInstanceBean);
+ assertFalse(connInstanceBean.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
+ // ----------------------------------
+
+ // ----------------------------------
+ // Check for spring bean update after connector instance update.
+ // ----------------------------------
+ connInstanceTO.getCapabilities().add(ConnectorCapability.AUTHENTICATE);
+
+ connectorService.update(connInstanceTO);
+ ConnInstanceTO actual = connectorService.read(connInstanceTO.getKey(), Locale.ENGLISH.getLanguage());
+ assertNotNull(actual);
+ assertTrue(connInstanceTO.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
+
+ // check for spring bean update
+ connInstanceBean = connectorService.readByResource(resourceTO.getKey(), Locale.ENGLISH.getLanguage());
+ assertTrue(connInstanceBean.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
+ // ----------------------------------
+ }
+
+ @Test
public void issueSYNCOPE112() {
// ----------------------------------------
// Create a new connector
@@ -686,11 +723,6 @@ public class ConnectorITCase extends AbstractITCase {
}
@Test
- public void reload() {
- connectorService.reload();
- }
-
- @Test
public void issueSYNCOPE605() {
ConnInstanceTO connectorInstanceTO = connectorService.read(
"fcf9f2b0-f7d6-42c9-84a6-61b28255a42b", Locale.ENGLISH.getLanguage());
http://git-wip-us.apache.org/repos/asf/syncope/blob/7451efb6/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
index 59e290e..d1d85f8 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
@@ -563,7 +563,7 @@ public class PullTaskITCase extends AbstractTaskITCase {
try {
connForTest.getCapabilities().add(ConnectorCapability.SYNC);
- ConnConfProperty changeLogColumn = connForTest.getConfMap().get("changeLogColumn");
+ ConnConfProperty changeLogColumn = connForTest.getConf("changeLogColumn");
assertNotNull(changeLogColumn);
assertTrue(changeLogColumn.getValues().isEmpty());
changeLogColumn.getValues().add("lastModification");
@@ -953,7 +953,7 @@ public class PullTaskITCase extends AbstractTaskITCase {
ResourceTO ldapResource = resourceService.read(RESOURCE_NAME_LDAP);
resourceConnector = connectorService.read(
ldapResource.getConnector(), Locale.ENGLISH.getLanguage());
- property = resourceConnector.getConfMap().get("retrievePasswordsWithSearch");
+ property = resourceConnector.getConf("retrievePasswordsWithSearch");
property.getValues().clear();
property.getValues().add(Boolean.TRUE);
connectorService.update(resourceConnector);
http://git-wip-us.apache.org/repos/asf/syncope/blob/7451efb6/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
index ebfb113..751ce0e 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
@@ -20,6 +20,7 @@ package org.apache.syncope.fit.core;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -35,6 +36,7 @@ import java.util.Set;
import javax.ws.rs.core.Response;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.SerializationUtils;
import org.apache.syncope.client.console.commons.ConnIdSpecialName;
import org.apache.syncope.client.lib.AnonymousAuthenticationHandler;
import org.apache.syncope.common.lib.SyncopeClientException;
@@ -46,6 +48,7 @@ import org.apache.syncope.common.lib.to.MappingTO;
import org.apache.syncope.common.lib.to.OrgUnitTO;
import org.apache.syncope.common.lib.to.PagedConnObjectTOResult;
import org.apache.syncope.common.lib.to.ProvisionTO;
+import org.apache.syncope.common.lib.to.ResourceHistoryConfTO;
import org.apache.syncope.common.lib.to.ResourceTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ClientExceptionType;
@@ -53,6 +56,7 @@ import org.apache.syncope.common.lib.types.ConnConfPropSchema;
import org.apache.syncope.common.lib.types.ConnConfProperty;
import org.apache.syncope.common.lib.types.EntityViolationType;
import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.common.lib.types.TraceLevel;
import org.apache.syncope.common.rest.api.beans.ConnObjectTOListQuery;
import org.apache.syncope.common.rest.api.service.ResourceService;
import org.identityconnectors.framework.common.objects.ObjectClass;
@@ -498,29 +502,6 @@ public class ResourceITCase extends AbstractITCase {
}
@Test
- public void issueSYNCOPE323() {
- ResourceTO actual = resourceService.read(RESOURCE_NAME_TESTDB);
- assertNotNull(actual);
-
- try {
- createResource(actual);
- fail();
- } catch (SyncopeClientException e) {
- assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
- assertEquals(ClientExceptionType.EntityExists, e.getType());
- }
-
- actual.setKey(null);
- try {
- createResource(actual);
- fail();
- } catch (SyncopeClientException e) {
- assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
- assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
- }
- }
-
- @Test
public void anonymous() {
ResourceService unauthenticated = clientFactory.create().getService(ResourceService.class);
try {
@@ -593,6 +574,65 @@ public class ResourceITCase extends AbstractITCase {
}
@Test
+ public void history() {
+ List<ResourceHistoryConfTO> history = resourceHistoryService.list(RESOURCE_NAME_LDAP);
+ assertNotNull(history);
+ int pre = history.size();
+
+ ResourceTO ldap = resourceService.read(RESOURCE_NAME_LDAP);
+ TraceLevel originalTraceLevel = SerializationUtils.clone(ldap.getUpdateTraceLevel());
+ assertEquals(TraceLevel.ALL, originalTraceLevel);
+ ProvisionTO originalProvision = SerializationUtils.clone(ldap.getProvision(AnyTypeKind.USER.name()));
+ assertEquals(ObjectClass.ACCOUNT_NAME, originalProvision.getObjectClass());
+ boolean originalFlag = ldap.isRandomPwdIfNotProvided();
+ assertTrue(originalFlag);
+
+ ldap.setUpdateTraceLevel(TraceLevel.FAILURES);
+ ldap.getProvision(AnyTypeKind.USER.name()).setObjectClass("ANOTHER");
+ ldap.setRandomPwdIfNotProvided(false);
+ resourceService.update(ldap);
+
+ ldap = resourceService.read(RESOURCE_NAME_LDAP);
+ assertNotEquals(originalTraceLevel, ldap.getUpdateTraceLevel());
+ assertNotEquals(
+ originalProvision.getObjectClass(), ldap.getProvision(AnyTypeKind.USER.name()).getObjectClass());
+ assertNotEquals(originalFlag, ldap.isRandomPwdIfNotProvided());
+
+ history = resourceHistoryService.list(RESOURCE_NAME_LDAP);
+ assertEquals(pre + 1, history.size());
+
+ resourceHistoryService.restore(history.get(0).getKey());
+
+ ldap = resourceService.read(RESOURCE_NAME_LDAP);
+ assertEquals(originalTraceLevel, ldap.getUpdateTraceLevel());
+ assertEquals(originalProvision.getObjectClass(), ldap.getProvision(AnyTypeKind.USER.name()).getObjectClass());
+ assertEquals(originalFlag, ldap.isRandomPwdIfNotProvided());
+ }
+
+ @Test
+ public void issueSYNCOPE323() {
+ ResourceTO actual = resourceService.read(RESOURCE_NAME_TESTDB);
+ assertNotNull(actual);
+
+ try {
+ createResource(actual);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
+ assertEquals(ClientExceptionType.EntityExists, e.getType());
+ }
+
+ actual.setKey(null);
+ try {
+ createResource(actual);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
+ assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+ }
+ }
+
+ @Test
public void issueSYNCOPE360() {
final String name = "SYNCOPE360-" + getUUIDString();
resourceService.create(buildResourceTO(name));