Hallo all,

I'm working on the Acegi Security project for the Spring Framework and we're keen to use ApacheDS for testing our LDAP security provider. I've written a pile of code for this and have a set of JUnit tests which I now have running successfully against OpenLDAP and also against an ApacheDS server instance which is started from the unit test base class (using the Sun provider as the client).

Ideally we would prefer to run with an in-memory embedded server (similar to using HSQLDB in this fashion) because it is a lot faster and avoids issues like having to shut down the server (our Maven build in particular gets very upset about the embedded server). It seems that this may be possible by just by having the client use CoreContextFactory to obtain contexts directly rather than the Sun provider. I've managed to get some way to achieving this but the behaviour isn't consistent with the full stack version and I'm not sure whether this is expected or if I'm doing something wrong.

My setup is like this:

I have a simple DIT with a root "dc=acegisecurity,dc=org". This has two subcontexts "ou=people" and "ou=groups" for my users and roles respectively. When the test base class instantiated, I create a MutableStartupConfiguration and add a partition to it with the suffix "dc=acegisecurity,dc=org". I then create a context with this configuration as follows:

    env.setProperty( Context.PROVIDER_URL, "dc=acegisecurity,dc=org" );
    env.setProperty( Context.INITIAL_CONTEXT_FACTORY,
             CoreContextFactory.class.getName());
    env.putAll( cfg.toJndiEnvironment() );

    serverContext = new InitialDirContext( env );

When I need a context in my tests it is created the same way.

Bind authentication works fine in both scenarios. I have problems with two things when trying to use CoreContextFactory :

1. The name returned by a search. When I do a search for a user in the directory, I get back the full DN rather than the name relative to the context I search in. So if I call

   ctx.search("ou=people", "(uid={0})", new String[] {"bob"}, ctls);

on a context obtained as above, I get back a SearchResult with name

"uid=bob,ou=people,dc=acegisecurity,dc=org"

whereas with the full server (or OpenLDAP) I get

"uid=bob"

as expected. This then unfortunately leads to an attempt to bind with an an unknown DN which causes the infinite recursion problem.

2. Performing "compare" operations. I had problems with this before, as reported in

http://issues.apache.org/jira/browse/DIRLDAP-77

but this now works with the full server, thanks to Emmanuel's speedy response. Running the same search code against a context obtained from CoreContextFactory fails however. A compare is never performed and the search returns an empty enumeration. Is there some way I can get my client code (as posted in JIRA):

     SearchControls ctls = new SearchControls();
     ctls.setReturningAttributes(new String[0]);
     ctls.setSearchScope(SearchControls.OBJECT_SCOPE);

     String filter = "(userPassword={0})";
     NamingEnumeration results = ctx.search(dn, filter, new
           Object[]{password.getBytes()}, ctls);

to trigger a compare call on the context? The compare/search also fails for non-binary attributes.

I was also wondering if there was any way of running fully in-memory without any persistent storage as it isn't needed for this kind of usage and it would avoid the need for clearing up the data files during the build.

Any help would be greatly appreciated as we're looking to include LDAP support in the forthcoming 1.0 release and ApacheDS seems like our best option for an integrated server both for testing and sample applications.

cheers,

Luke.



--
 Luke Taylor.                      Monkey Machine Ltd.
 PGP Key ID: 0x57E9523C            http://www.monkeymachine.ltd.uk

Reply via email to