LDAP-266: Initial effort for automatic repository support.

This commit is contained in:
Mattias Hellborg Arthursson
2013-10-10 13:32:45 +02:00
parent 41fc6306ae
commit c98110b8c2
22 changed files with 732 additions and 8 deletions

View File

@@ -12,7 +12,8 @@ dependencies {
compile "commons-logging:commons-logging:$commonsLoggingVersion",
"org.springframework:spring-core:$springVersion",
"org.springframework:spring-beans:$springVersion",
"org.springframework:spring-tx:$springVersion"
"org.springframework:spring-tx:$springVersion",
"org.springframework.data:spring-data-commons:$springDataVersion"
provided "commons-pool:commons-pool:$commonsPoolVersion",
"com.sun:ldapbp:1.0",

View File

@@ -24,6 +24,7 @@ public abstract class Elements {
public static final String POOLING = "pooling";
public static final String LDAP_TEMPLATE = "ldap-template";
public static final String TRANSACTION_MANAGER = "transaction-manager";
public static final String REPOSITORIES = "repositories";
public static final String DEFAULT_RENAMING_STRATEGY = "default-renaming-strategy";
public static final String DIFFERENT_SUBTREE_RENAMING_STRATEGY = "different-subtree-renaming-strategy";
}

View File

@@ -17,6 +17,8 @@
package org.springframework.ldap.config;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
import org.springframework.data.repository.config.RepositoryBeanDefinitionParser;
import org.springframework.ldap.repository.config.LdapRepositoryConfigurationExtension;
/**
* @author Mattias Hellborg Arthursson
@@ -24,8 +26,12 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
public class LdapNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
LdapRepositoryConfigurationExtension extension = new LdapRepositoryConfigurationExtension();
RepositoryBeanDefinitionParser repositoryParser = new RepositoryBeanDefinitionParser(extension);
registerBeanDefinitionParser(Elements.CONTEXT_SOURCE, new ContextSourceParser());
registerBeanDefinitionParser(Elements.LDAP_TEMPLATE, new LdapTemplateParser());
registerBeanDefinitionParser(Elements.TRANSACTION_MANAGER, new TransactionManagerParser());
registerBeanDefinitionParser(Elements.REPOSITORIES, repositoryParser);
}
}

View File

@@ -21,6 +21,7 @@ import org.springframework.ldap.ContextNotEmptyException;
import org.springframework.ldap.NamingException;
import org.springframework.ldap.core.support.AbstractContextSource;
import org.springframework.ldap.filter.Filter;
import org.springframework.ldap.odm.core.ObjectDirectoryMapper;
import org.springframework.ldap.query.LdapQuery;
import org.springframework.ldap.support.LdapUtils;
@@ -1620,6 +1621,22 @@ public interface LdapOperations {
*/
<T> T searchForObject(String base, String filter, ContextMapper<T> mapper);
/**
* Perform a search with parameters from the specified LdapQuery. All found objects will be supplied to the
* <code>NameClassPairCallbackHandler</code> for processing.
*
* @param query the LDAP query specification.
* @param callbackHandler the <code>NameClassPairCallbackHandler</code> to supply all found entries to.
* @return a <code>List</code> containing all entries received from the
* <code>ContextMapper</code>.
*
* @throws NamingException if any error occurs.
* @since 2.0
* @see org.springframework.ldap.query.LdapQueryBuilder
* @see org.springframework.ldap.core.support.CountNameClassPairCallbackHandler
*/
void search(LdapQuery query, NameClassPairCallbackHandler callbackHandler);
/**
* Perform a search with parameters from the specified LdapQuery. All found objects will be supplied to the
* <code>ContextMapper</code> for processing, and all returned objects will be collected in a list to be returned.
@@ -1699,7 +1716,7 @@ public interface LdapOperations {
* is set in the object, this will be used as the distinguished name of the new entry. If no explicit DN is specified,
* an attempt will be made to calculate the name from fields annotated with {@link org.springframework.ldap.odm.annotations.DnAttribute}.
*
* @param entry The entry to be create, it must <em>not</em> already exist in the directory.
* @param entry The entry to be create, it must <em>not</em> be null or already exist in the directory.
*
* @throws org.springframework.ldap.NamingException on error.
* @throws IllegalArgumentException if the entry is null or on failure to determine the distinguished name.
@@ -1825,4 +1842,12 @@ public interface LdapOperations {
* @throws IncorrectResultSizeDataAccessException if more than one matching entry is found
*/
<T> T findOne(LdapQuery query, Class<T> clazz);
/**
* Get the configured ObjectDirectoryMapper. For internal use.
*
* @return the configured ObjectDirectoryMapper.
* @since 2.0
*/
ObjectDirectoryMapper getObjectDirectoryMapper();
}

View File

@@ -114,6 +114,11 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
this.contextSource = contextSource;
}
@Override
public ObjectDirectoryMapper getObjectDirectoryMapper() {
return odm;
}
/**
* Set the ObjectDirectoryMapper instance to use.
*
@@ -1669,6 +1674,15 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
}
}
@Override
public void search(LdapQuery query, NameClassPairCallbackHandler callbackHandler) {
SearchControls searchControls = searchControlsForQuery(query, DONT_RETURN_OBJ_FLAG);
search(query.base(),
query.filter().encode(),
searchControls,
callbackHandler);
}
@Override
public <T> List<T> search(LdapQuery query, ContextMapper<T> mapper) {
SearchControls searchControls = searchControlsForQuery(query, RETURN_OBJ_FLAG);

View File

@@ -56,6 +56,15 @@ public interface ObjectDirectoryMapper {
*/
Name getId(Object entry);
/**
* Set the distinguished name for the specified object.
*
* @param entry the entry to set the name on
* @param id the name to set
* @throws org.springframework.ldap.NamingException on error.
*/
void setId(Object entry, Name id);
Name getCalculatedId(Object entry);
/**

View File

@@ -367,13 +367,27 @@ public class DefaultObjectDirectoryMapper implements ObjectDirectoryMapper {
@Override
public Name getId(Object entry) {
try {
return (Name)getEntityData(entry.getClass()).metaData.getIdAttribute().getField().get(entry);
return (Name) getIdField(entry).get(entry);
} catch (Exception e) {
throw new InvalidEntryException(String.format("Can't get Id field from Entry %1$s", entry),
e);
}
}
private Field getIdField(Object entry) {
return getEntityData(entry.getClass()).metaData.getIdAttribute().getField();
}
@Override
public void setId(Object entry, Name id) {
try {
getIdField(entry).set(entry, id);
} catch (Exception e) {
throw new InvalidEntryException(
String.format("Can't set Id field on Entry %s to %s", entry, id), e);
}
}
@Override
public Name getCalculatedId(Object entry) {
Assert.notNull(entry, "Entry must not be null");

View File

@@ -157,9 +157,13 @@ public class LdapQueryBuilder implements LdapQuery {
* @throws IllegalStateException if a filter has already been specified.
*/
public ConditionCriteria where(String attribute) {
initRootContainer();
return new DefaultConditionCriteria(rootContainer, attribute);
}
private void initRootContainer() {
assertFilterNotStarted();
rootContainer = new DefaultContainerCriteria(this);
return new DefaultConditionCriteria(rootContainer, attribute);
}
/**
@@ -174,12 +178,17 @@ public class LdapQueryBuilder implements LdapQuery {
* @throws IllegalStateException if a filter has already been specified.
*/
public LdapQuery filter(String hardcodedFilter) {
assertFilterNotStarted();
rootContainer = new DefaultContainerCriteria(this);
initRootContainer();
rootContainer.append(new HardcodedFilter(hardcodedFilter));
return this;
}
public LdapQuery filter(Filter filter) {
initRootContainer();
rootContainer.append(filter);
return this;
}
/**
* Specify a hardcoded filter using the specified parameters. The parameters will be properly encoded using
* {@link LdapEncoder#filterEncode(String)} to make sure no malicious data gets through. The <code>filterFormat</code>

View File

@@ -0,0 +1,55 @@
/*
* Copyright 2005-2013 the original author or authors.
*
* Licensed 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.springframework.ldap.repository;
import org.springframework.data.repository.core.EntityInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import org.springframework.ldap.core.LdapOperations;
import java.io.Serializable;
/**
* @author Mattias Hellborg Arthursson
* @since 2.0
*/
public class LdapRepositoryFactory extends RepositoryFactorySupport {
private final LdapOperations ldapOperations;
public LdapRepositoryFactory(LdapOperations ldapOperations) {
this.ldapOperations = ldapOperations;
}
@Override
public <T, ID extends Serializable> EntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
return null;
}
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
protected Object getTargetRepository(RepositoryMetadata metadata) {
return new SimpleLdapRepository(
ldapOperations,
ldapOperations.getObjectDirectoryMapper(),
metadata.getDomainType());
}
@Override
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
return SimpleLdapRepository.class;
}
}

View File

@@ -0,0 +1,32 @@
package org.springframework.ldap.repository;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import org.springframework.ldap.core.LdapOperations;
import org.springframework.util.Assert;
import javax.naming.Name;
/**
* @author Mattias Hellborg Arthursson
* @since 2.0
*/
public class LdapRepositoryFactoryBean<T extends Repository<S, Name>, S> extends RepositoryFactoryBeanSupport<T, S, Name> {
private LdapOperations ldapOperations;
public void setLdapOperations(LdapOperations ldapOperations) {
this.ldapOperations = ldapOperations;
}
@Override
protected RepositoryFactorySupport createRepositoryFactory() {
return new LdapRepositoryFactory(ldapOperations);
}
@Override
public void afterPropertiesSet() {
super.afterPropertiesSet();
Assert.notNull(ldapOperations, "LdapOperations must be set");
}
}

View File

@@ -0,0 +1,191 @@
/*
* Copyright 2005-2013 the original author or authors.
*
* Licensed 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.springframework.ldap.repository;
import org.springframework.data.domain.Persistable;
import org.springframework.data.repository.CrudRepository;
import org.springframework.ldap.NameNotFoundException;
import org.springframework.ldap.core.LdapOperations;
import org.springframework.ldap.core.support.CountNameClassPairCallbackHandler;
import org.springframework.ldap.filter.Filter;
import org.springframework.ldap.odm.core.ObjectDirectoryMapper;
import org.springframework.ldap.query.LdapQuery;
import org.springframework.util.Assert;
import javax.naming.Name;
import java.util.Iterator;
import static org.springframework.ldap.query.LdapQueryBuilder.query;
/**
* Base repository implementation for LDAP.
*
* @author Mattias Hellborg Arthursson
* @since 2.0
*/
public class SimpleLdapRepository<T> implements CrudRepository<T, Name> {
private static final String OBJECTCLASS_ATTRIBUTE = "objectclass";
private final LdapOperations ldapOperations;
private final ObjectDirectoryMapper odm;
private final Class<T> clazz;
public SimpleLdapRepository(LdapOperations ldapOperations, ObjectDirectoryMapper odm, Class<T> clazz) {
this.ldapOperations = ldapOperations;
this.odm = odm;
this.clazz = clazz;
}
@Override
public long count() {
Filter filter = odm.filterFor(clazz, null);
CountNameClassPairCallbackHandler callback = new CountNameClassPairCallbackHandler();
LdapQuery query = query().attributes(OBJECTCLASS_ATTRIBUTE).filter(filter);
ldapOperations.search(query, callback);
return callback.getNoOfRows();
}
private <S extends T> boolean isNew(S entity, Name id) {
if (entity instanceof Persistable) {
Persistable persistable = (Persistable) entity;
return persistable.isNew();
} else {
return id != null;
}
}
@Override
public <S extends T> S save(S entity) {
Assert.notNull(entity, "Entity must not be null");
Name declaredId = odm.getId(entity);
Name calculatedId = odm.getCalculatedId(entity);
if(isNew(entity, declaredId)) {
if(declaredId == null) {
odm.setId(entity, calculatedId);
}
ldapOperations.create(entity);
} else {
ldapOperations.update(entity);
if(declaredId != calculatedId) {
odm.setId(entity, calculatedId);
}
}
return entity;
}
@Override
public <S extends T> Iterable<S> save(Iterable<S> entities) {
return new DelegatingIterable<S, S>(entities, new Function<S, S>() {
@Override
public S transform(S entry) {
return save(entry);
}
});
}
@Override
public T findOne(Name name) {
Assert.notNull(name, "Id must not be null");
try {
return ldapOperations.findByDn(name, clazz);
} catch (NameNotFoundException e) {
return null;
}
}
@Override
public boolean exists(Name name) {
return findOne(name) != null;
}
@Override
public Iterable<T> findAll() {
return ldapOperations.findAll(clazz);
}
@Override
public Iterable<T> findAll(final Iterable<Name> names) {
return new DelegatingIterable<Name, T>(names, new Function<Name, T>() {
@Override
public T transform(Name name) {
return findOne(name);
}
});
}
@Override
public void delete(Name name) {
Assert.notNull(name, "Id must not be null");
ldapOperations.unbind(name);
}
@Override
public void delete(T entity) {
Assert.notNull(entity, "Entity must not be null");
ldapOperations.delete(entity);
}
@Override
public void delete(Iterable<? extends T> entities) {
for (T entity : entities) {
delete(entity);
}
}
@Override
public void deleteAll() {
delete(findAll());
}
private static class DelegatingIterable<F, T> implements Iterable<T> {
private final Iterable<F> target;
private final Function<F, T> function;
private DelegatingIterable(Iterable<F> target, Function<F, T> function) {
this.target = target;
this.function = function;
}
@Override
public Iterator<T> iterator() {
final Iterator<F> targetIterator = target.iterator();
return new Iterator<T>() {
@Override
public boolean hasNext() {
return targetIterator.hasNext();
}
@Override
public T next() {
return function.transform(targetIterator.next());
}
@Override
public void remove() {
throw new UnsupportedOperationException("Remove is not supported for this iterator");
}
};
}
}
private interface Function<F, T> {
T transform(F entry);
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2005-2013 the original author or authors.
*
* Licensed 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.springframework.ldap.repository.config;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
import org.springframework.data.repository.config.XmlRepositoryConfigurationSource;
import org.springframework.ldap.repository.LdapRepositoryFactoryBean;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* @author Mattias Hellborg Arthursson
*/
public class LdapRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport {
private static final String ATT_LDAP_TEMPLATE_REF = "ldap-template-ref";
@Override
protected String getModulePrefix() {
return "ldap";
}
@Override
public String getRepositoryFactoryClassName() {
return LdapRepositoryFactoryBean.class.getName();
}
@Override
public void postProcess(BeanDefinitionBuilder builder, XmlRepositoryConfigurationSource config) {
Element element = config.getElement();
String ldapTemplateRef = element.getAttribute(ATT_LDAP_TEMPLATE_REF);
if(!StringUtils.hasText(ldapTemplateRef)) {
ldapTemplateRef = "ldapTemplate";
}
builder.addPropertyReference("ldapOperations", ldapTemplateRef);
}
}

View File

@@ -1,9 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ldap="http://www.springframework.org/schema/ldap"
xmlns:repository="http://www.springframework.org/schema/data/repository"
elementFormDefault="qualified"
targetNamespace="http://www.springframework.org/schema/ldap">
<xs:import namespace="http://www.springframework.org/schema/data/repository"
schemaLocation="http://www.springframework.org/schema/data/repository/spring-repository.xsd" />
<xs:attributeGroup name="context-source.attlist">
<xs:attribute name="id" type="xs:token">
<xs:annotation>
@@ -445,4 +449,20 @@
<xs:attributeGroup ref="ldap:transaction-manager.attlist" />
</xs:complexType>
</xs:element>
<xs:element name="repositories">
<xs:complexType>
<xs:complexContent>
<xs:extension base="repository:repositories">
<xs:attribute name="ldap-template-ref">
<xs:annotation>
<xs:documentation>
The reference to an LdapTemplate. Will default to 'ldapTemplate'.
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@@ -0,0 +1,7 @@
package org.springframework.ldap.config;
/**
* @author Mattias Hellborg Arthursson
*/
public class DummyEntity {
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2005-2013 the original author or authors.
*
* Licensed 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.springframework.ldap.config;
import org.springframework.data.repository.CrudRepository;
import javax.naming.Name;
/**
* @author Mattias Hellborg Arthursson
*/
public interface DummyLdapRepository extends CrudRepository<DummyEntity, Name> {
}

View File

@@ -305,4 +305,12 @@ public class LdapTemplateNamespaceHandlerTest {
public void verifyParseWithPoolingAndNativePoolingWillFail() {
new ClassPathXmlApplicationContext("/ldap-namespace-config-pooling-with-native.xml");
}
@Test
public void verifyAutomaticRepositorySupport() {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/ldap-namespace-config-with-repositories.xml");
DummyLdapRepository repository = ctx.getBean(DummyLdapRepository.class);
assertNotNull(repository);
}
}

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ldap="http://www.springframework.org/schema/ldap"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/ldap http://www.springframework.org/schema/ldap/spring-ldap.xsd">
<ldap:context-source password="apassword" url="ldap://localhost:389" username="uid=admin"/>
<ldap:ldap-template />
<ldap:repositories base-package="org.springframework.ldap.config" />
</beans>

View File

@@ -5,6 +5,7 @@ sourceCompatibility = '1.6'
targetCompatibility = '1.6'
ext.springVersion = '3.2.4.RELEASE'
ext.springDataVersion = '1.6.1.RELEASE'
ext.springBatchVersion = '2.0.4.RELEASE'
ext.junitVersion = '4.10'
ext.commonsPoolVersion = '1.5.4'

View File

@@ -1,8 +1,10 @@
package org.springframework.ldap.itest.odm;
import org.springframework.data.domain.Persistable;
import org.springframework.ldap.odm.annotations.Attribute;
import org.springframework.ldap.odm.annotations.Entry;
import org.springframework.ldap.odm.annotations.Id;
import org.springframework.ldap.odm.annotations.Transient;
import javax.naming.Name;
import java.util.List;
@@ -11,7 +13,7 @@ import java.util.List;
* @author Mattias Hellborg Arthursson
*/
@Entry(objectClasses = { "inetOrgPerson", "organizationalPerson", "person", "top" })
public class Person {
public class Person implements Persistable<Name> {
@Id
private Name dn;
@@ -30,6 +32,19 @@ public class Person {
@Attribute(name = "telephoneNumber")
private String telephoneNumber;
@Transient
private boolean isNew;
@Override
public Name getId() {
return getDn();
}
@Override
public boolean isNew() {
return isNew;
}
public Name getDn() {
return dn;
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright 2005-2013 the original author or authors.
*
* Licensed 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.springframework.ldap.itest.repositories;
import org.springframework.data.repository.CrudRepository;
import org.springframework.ldap.itest.odm.Person;
import javax.naming.Name;
/**
* @author Mattias Hellborg Arthursson
*/
public interface PersonRepository extends CrudRepository<Person, Name> {
}

View File

@@ -0,0 +1,172 @@
/*
* Copyright 2005-2013 the original author or authors.
*
* Licensed 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.springframework.ldap.itest.repository;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.itest.AbstractLdapTemplateIntegrationTest;
import org.springframework.ldap.itest.odm.Person;
import org.springframework.ldap.itest.repositories.PersonRepository;
import org.springframework.ldap.odm.core.OdmException;
import org.springframework.ldap.support.LdapNameBuilder;
import org.springframework.ldap.support.LdapUtils;
import org.springframework.test.context.ContextConfiguration;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static org.springframework.ldap.query.LdapQueryBuilder.query;
/**
* Tests for Spring LDAP automatic repository scan functionality.
*
* @author Ulrik Sandberg
*/
@ContextConfiguration(locations = {"/conf/repositoryScanTestContext.xml"})
public class RepositoryScanITest extends AbstractLdapTemplateIntegrationTest {
@Autowired
private LdapTemplate ldapTemplate;
@Autowired
private PersonRepository tested;
@Test
public void testFindOne() {
Person person = tested.findOne(LdapUtils.newLdapName("cn=Some Person3, ou=Company1, c=Sweden"));
assertNotNull(person);
Assert.assertEquals("Some Person3", person.getCommonName());
Assert.assertEquals("Person3", person.getSurname());
Assert.assertEquals("Sweden, Company1, Some Person3", person.getDesc().get(0));
Assert.assertEquals("+46 555-123654", person.getTelephoneNumber());
}
// @Test
// public void testFindByDn() {
// Person person = tested.findByDn(LdapUtils.newLdapName("cn=Some Person3,ou=company1,c=Sweden"), Person.class);
//
// assertNotNull(person);
// Assert.assertEquals("Some Person3", person.getCommonName());
// Assert.assertEquals("Person3", person.getSurname());
// Assert.assertEquals("Sweden, Company1, Some Person3", person.getDesc().get(0));
// Assert.assertEquals("+46 555-123654", person.getTelephoneNumber());
// }
//
// @Test(expected = OdmException.class)
// public void testFindByDnThrowsExceptionOnInvalidEntry() {
// tested.findByDn(LdapUtils.newLdapName("ou=company1,c=Sweden"), Person.class);
// }
//
// @Test(expected = EmptyResultDataAccessException.class)
// public void testFindOneThrowsEmptyResultIfNotFound() {
// tested.findOne(query()
// .where("cn").is("This cn does not exist"), Person.class);
// }
//
// @Test
// public void testFind() {
// List<Person> persons = tested.find(query()
// .where("cn").is("Some Person3"), Person.class);
//
// Assert.assertEquals(1, persons.size());
// Person person = persons.get(0);
//
// assertNotNull(person);
// Assert.assertEquals("Some Person3", person.getCommonName());
// Assert.assertEquals("Person3", person.getSurname());
// Assert.assertEquals("Sweden, Company1, Some Person3", person.getDesc().get(0));
// Assert.assertEquals("+46 555-123654", person.getTelephoneNumber());
// }
//
// @Test
// public void testFindInCountry() {
// List<Person> persons = tested.find(query()
// .base("c=Sweden")
// .where("cn").isPresent(), Person.class);
//
// Assert.assertEquals(4, persons.size());
// Person person = persons.get(0);
//
// assertNotNull(person);
// }
//
// @Test
// public void testFindAll() {
// List<Person> result = tested.findAll(Person.class);
// Assert.assertEquals(5, result.size());
// }
//
// @Test
// public void testCreate() {
// Person person = new Person();
// person.setDn(LdapNameBuilder.newLdapName("ou=company1,c=Sweden")
// .add("cn", "New Person").build());
// person.setCommonName("New Person");
// person.setSurname("Person");
// person.setDesc(Arrays.asList("This is the description"));
// person.setTelephoneNumber("0123456");
//
// tested.create(person);
//
// Assert.assertEquals(6, tested.findAll(Person.class).size());
//
// person = tested.findOne(query()
// .where("cn").is("New Person"), Person.class);
//
// Assert.assertEquals("New Person", person.getCommonName());
// Assert.assertEquals("Person", person.getSurname());
// Assert.assertEquals("This is the description", person.getDesc().get(0));
// Assert.assertEquals("0123456", person.getTelephoneNumber());
// }
//
// @Test
// public void testUpdate() {
// Person person = tested.findOne(query()
// .where("cn").is("Some Person3"), Person.class);
//
// person.setDesc(Arrays.asList("New Description"));
// tested.update(person);
//
// person = tested.findOne(query()
// .where("cn").is("Some Person3"), Person.class);
//
// Assert.assertEquals("Some Person3", person.getCommonName());
// Assert.assertEquals("Person3", person.getSurname());
// Assert.assertEquals("New Description", person.getDesc().get(0));
// Assert.assertEquals("+46 555-123654", person.getTelephoneNumber());
// }
//
// @Test
// public void testDelete() {
// Person person = tested.findOne(query()
// .where("cn").is("Some Person3"), Person.class);
//
// tested.delete(person);
//
// try {
// tested.findOne(query().where("cn").is("Some Person3"), Person.class);
// fail("EmptyResultDataAccessException e");
// } catch (EmptyResultDataAccessException e) {
// Assert.assertTrue(true);
// }
// }
}

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ldap="http://www.springframework.org/schema/ldap"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/ldap http://www.springframework.org/schema/ldap/spring-ldap.xsd">
<import resource="classpath:/conf/commonTestContext.xml" />
<ldap:context-source
password="${password}"
url="ldap://localhost:1888"
username="${userDn}"
base="dc=jayway,dc=se" />
<ldap:ldap-template />
<ldap:repositories base-package="org.springframework.ldap.itest.repositories" />
<bean id="dummy" class="org.springframework.ldap.test.TestContextSourceFactoryBean">
<property name="defaultPartitionSuffix" value="dc=jayway,dc=se" />
<property name="defaultPartitionName" value="jayway" />
<property name="ldifFile" value="classpath:/setup_data.ldif" />
<property name="port" value="1888" />
<property name="contextSource" ref="contextSource" />
</bean>
</beans>