You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@directory.apache.org by Trustin Lee <tr...@gmail.com> on 2005/06/15 05:00:28 UTC

[apacheds] The summary of Recent Changes; A Must-Read

Recently I merged massive changes in the branch 'direve-158' into trunk. 
'direve-158' was named after the issue I wanted to resolve: 
http://issues.apache.org/jira/browse/DIREVE-158

We've been relying on JNDI environment hashtable heavily to configure 
ApacheDS, but it had significant problems. The biggest problem was that 
hashtable is not strongly typed. We had to include all validation, 
conversion, parse code into everywhere. It increased LOC of core without any 
good effect.

So I thought over and over. What if we configure ApacheDS using POJOs? It 
will free us from hashtables mostly, and we will be able to remove all 
EnvKeys properties and XxxxConfigBuilders, and then separate configuration 
file parser from core. We could even use existing frameworks like Spring and 
Pico to configure ApacheDS. That's why and what I've changed ApacheDS.

Here's the list of changes:

1. 'configuration' package
==========================
I added a package called 'configuration' to core, and replaced all 
configuration related with it. Configuration is the base class for all 
sub-configurations; StartupConfiguration, ShutdownConfiguration, and 
ShutdownConfiguration. Configuration has two conversion methods; 
toConfiguration() and toJndiEnvironment(). toJndiEnvironment() is used by 
ApacheDS users who want to pass Configuration to JNDI provider. 
toConfiguration() is used by ApacheDS core which wants to convert back JNDI 
properties to Configuration. Here's some example:

/////////////////
// 1. Start up //
/////////////////
MutableStartupConfiguration cfg = new MutablsStartupConfiguration();
// call your setters here
// ...

Hashtable env = cfg.toJndiEnvironment();
env.put( Context.INITIAL_CONTEXT_FACTORY, CoreContextFactory.class.getName() 
);
// put some mandatory JNDI properties here
// ...
Context ctx = new InitialContext( env );

/////////////////
// 2. Shutdown //
/////////////////
Hashtable env = new ShutdownConfiguration().toJndiEnvironment();
env.put( Context.INITIAL_CONTEXT_FACTORY, CoreContextFactory.class.getName() 
);
// put some mandatory JNDI properties here
// ...
Context ctx = new InitialContext( env );

/////////////
// 3. Sync //
/////////////
Hashtable env = new SyncConfiguration().toJndiEnvironment();
env.put( Context.INITIAL_CONTEXT_FACTORY, CoreContextFactory.class.getName() 
);
// put some mandatory JNDI properties here
// ...
Context ctx = new InitialContext( env );


And.. here's the resulting example Spring XML bean code that will excite 
you:

http://svn.apache.org/viewcvs.cgi/directory/apacheds/trunk/main/server.xml?rev=190555&view=markup

2. 'authn' package has been refactored.
=======================================
I removed AuthenticatorConfig which provides weak-typed configuration 
framework. Users will have to use setter or constructor injection to 
configure any implementation-specific properties now. Authenticator.init( 
AuthenticatorConfig ) has been replaced with init( AuthenticatorContext ) 
with more information such StartupConfiguration.

3. ContextPartition is not instantiated using reflection API anymore.
=====================================================================
We had been instantiating ContextPartition using reflection API. 
Implementations of ContextPastitions must had have a constructor with two 
parameters. Now users can instantiate ContextPartition by themselves with 
any constructor thanks to addition of 'configuration' package. ApacheDS core 
will call init( Name upDN, Name normalizedDN ) at initialization phase, so 
users will be able to initialize their ContextPartition then.

4. Resolved possible resource leakage in JNDI provider and 
ServerSystemPreferences
==================================================================================
JNDI SPI instantiates ContextFactories whenever a user calls new 
InitialContext(env), but we didn't take account for it. CoreContextFactory 
had a member variable that contains handles required for most LDAP 
operations while trying to be make that member a singleton. So resources 
started to leak and database files had not being closed.

To resolve this problem, I moved all codes in CoreContextFactory to 
JndiProvider and renamed it to DefaultContextFactoryContext (which 
implements ContextFactoryContext), and made it a singleton.

And, I added ServerSystemPreferences.close() which executes 
ShutdownConfiguration so that users can release all resources without 
knowing JNDI providers.

Now I found no resource leakage. :)

5. CoreContextFactory is now easily extensible.
===============================================
We had to extend CoreContextFactory and override getInitialContext(). It 
caused a lot of duplicate code in super class because we does three tasks in 
one method; startup, shutdown, and sync.

I created a class AbstractContextFactory and made getInitialContext() final. 
Instead, these hook methods has been added:

* beforeStartup( ContextFactoryContext )
* aftereStartup( ContextFactoryContext )
* beforeShutdown( ContextFactoryContext )
* aftereShutdown( ContextFactoryContext )
* beforeSync( ContextFactoryContext )
* aftereSync( ContextFactoryContext )

So now you can extend AbstractContextFactory and implement those 6 hooks to 
extend core. CoreContextFactory extends AbstractContextFactory and 
implements empty hooks.

6. More strict authentication parameter
=======================================

Whatever operation you do, you must specify these properties related with 
authentication:

* Context.SECURITY_AUTHENTICATION - 'none' or 'simple'

If it is 'simple' these properties are also mandatory:

* Context.SECURITY_PRINCIPAL
* Context.SECURITY_CREDENTIAL

I think it is more explicit and clear.

7. AbstractCoreTest has been splitted into three classes
========================================================
The three classes are AbstractTestCase, AbstractAdminTestCase, and 
AbstractNonAdminTestCase. AbstractAdminTestCase instantiates sysRoot as an 
admin, and AbstractNonAdminTestCase as non-admin. These classes replaces 
AbstractMultiUserTest.

Trustin
-- 
what we call human nature is actually human habit
--
http://gleamynode.net/