Skip to content

Latest commit

 

History

History
231 lines (173 loc) · 8.26 KB

ldap-repositories.adoc

File metadata and controls

231 lines (173 loc) · 8.26 KB

LDAP repositories

Introduction

This chapter will point out the specialties for repository support for LDAP. This builds on the core repository support explained in [repositories]. So make sure you’ve got a sound understanding of the basic concepts explained there.

  • Spring LDAP repositories can be enabled using an <data-ldap:repositories> tag in your XML configuration or using an @EnableLdapRepositories annotation on a configuration class.

  • To include support for LdapQuery parameters in automatically generated repositories, have your interface extend LdapRepository rather than CrudRepository.

  • All Spring LDAP repositories must work with entities annotated with the ODM annotations, as described in Object-Directory Mapping.

  • Since all ODM managed classes must have a Distinguished Name as ID, all Spring LDAP repositories must have the ID type parameter set to javax.naming.Name. Indeed, the built-in LdapRepository only takes one type parameter; the managed entity class, defaulting ID to javax.naming.Name.

  • Due to specifics of the LDAP protocol, paging and sorting is not supported for Spring LDAP repositories.

Note
Make sure to use ODM annotations like org.springframework.ldap.odm.annotations.Id. Using Spring Data’s annotation does not work as Spring LDAP uses its own mapping layer.

Usage

To access domain entities stored in a LDAP-compliant directory you can leverage our sophisticated repository support that eases implementing those quite significantly. To do so, simply create an interface for your repository:

Example 1. Sample Person entity
@Entry(objectClasses = { "person", "top" }, base="ou=someOu")
public class Person {

   @Id
   private Name dn;

   @Attribute(name="cn")
   @DnAttribute(value="cn", index=1)
   private String fullName;

   @Attribute(name="firstName")
   private String firstName;

   // No @Attribute annotation means this will be bound to the LDAP attribute
   // with the same value
   private String firstName;

   @DnAttribute(value="ou", index=0)
   @Transient
   private String company;

   @Transient
   private String someUnmappedField;
   // ...more attributes below
}

We have a quite simple domain object here. Note that it has a property named dn of type Name.

Example 2. Basic repository interface to persist Person entities
public interface PersonRepository extends CrudRepository<Person, Long> {

  // additional custom finder methods go here
}

Right now this interface simply serves typing purposes but we will add additional methods to it later. In your Spring configuration simply add

Example 3. General LDAP repository Spring configuration
<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"
  xmlns:data-ldap="http://www.springframework.org/schema/data/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
    http://www.springframework.org/schema/data/ldap
    http://www.springframework.org/schema/data/ldap/spring-ldap.xsd">

  <ldap:context-source url="ldap://127.0.0.1:389"
                     username="cn=Admin"
                     password="secret" />

  <ldap:ldap-template />

  <data-ldap:repositories base-package="com.acme.*.repositories" />

</beans>

This namespace element will cause the base packages to be scanned for interfaces extending LdapRepository and create Spring beans for each of them found. By default the repositories will get a LdapTemplate Spring bean wired that is called ldapTemplate, so you only need to configure ldap-template-ref explicitly if you deviate from this convention.

If you’d rather like to go with JavaConfig use the @EnableLdapRepositories annotation. The annotation carries the very same attributes like the namespace element. If no base package is configured the infrastructure will scan the package of the annotated configuration class.

Example 4. JavaConfig for repositories
@Configuration
@EnableLdapRepositories
class ApplicationConfig {

    @Bean
    ContextSource contextSource() {

        LdapContextSource ldapContextSource = new LdapContextSource();
        ldapContextSource.setUrl("ldap://127.0.0.1:389");

        return ldapContextSource;
    }

    @Bean
    LdapTemplate ldapTemplate(ContextSource contextSource) {
        return new LdapTemplate(contextSource);
    }
}

As our domain repository extends CrudRepository it provides you with CRUD operations as well as methods for access to the entities. Working with the repository instance is just a matter of dependency injecting it into a client.

Example 5. Paging access to Person entities
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class PersonRepositoryTests {

    @Autowired PersonRepository repository;

    @Test
    public void readAll() {

      List<Person> persons = repository.findAll();
      assertThat(persons.isEmpty(), is(false));
    }
}

The sample creates an application context with Spring’s unit test support which will perform annotation based dependency injection into test cases. Inside the test method we simply use the repository to query the datastore.

Query methods

Most of the data access operations you usually trigger on a repository result a query being executed against the LDAP directory. Defining such a query is just a matter of declaring a method on the repository interface

Example 6. PersonRepository with query methods
public interface PersonRepository extends PagingAndSortingRepository<Person, String> {

    List<Person> findByLastname(String lastname);                            (1)

    List<Person> findByLastnameFirstname(String lastname, String firstname); (2)
}
  1. The method shows a query for all people with the given lastname. The query will be derived parsing the method name for constraints which can be concatenated with And and Or. Thus the method name will result in a query expression of (&(objectclass=person)(lastname=lastname)).

  2. The method shows a query for all people with the given lastname and firstname. The query will be derived parsing the method name.Thus the method name will result in a query expression of (&(objectclass=person)(lastname=lastname)(firstname=firstname)).

Table 1. Supported keywords for query methods
Keyword Sample Logical result

LessThanEqual

findByAgeLessThanEqual(int age)

(attribute⇐age)

GreaterThanEqual

findByAgeGreaterThanEqual(int age)

(attribute>=age)

IsNotNull, NotNull

findByFirstnameNotNull()

(firstname=*)

IsNull, Null

findByFirstnameNull()

(!(firstname=*))

Like

findByFirstnameLike(String name)

(firstname=name)

NotLike, IsNotLike

findByFirstnameNotLike(String name)

(!(firstname=name*))

StartingWith

findByStartingWith(String name)

(firstname=name*)

EndingWith

findByFirstnameLike(String name)

(firstname=*name)

Containing

findByFirstnameLike(String name)

(firstname=*name*)

(No keyword)

findByFirstname(String name)

(Firstname=name)

Not

findByFirstnameNot(String name)

(!(Firstname=name))

QueryDSL support

Basic QueryDSL support is included in Spring LDAP. This support includes the following:

  • An Annotation Processor, LdapAnnotationProcessor, for generating QueryDSL classes based on Spring LDAP ODM annotations. See Object-Directory Mapping for more information on the ODM annotations.

  • A Query implementation, QueryDslLdapQuery, for building and executing QueryDSL queries in code.

  • Spring Data repository support for QueryDSL predicates. QueryDslPredicateExecutor includes a number of additional methods with appropriate parameters; extend this interface along with LdapRepository to include this support in your repository.