From commits-return-15742-apmail-directory-commits-archive=directory.apache.org@directory.apache.org Sat Oct 06 06:50:39 2007 Return-Path: Delivered-To: apmail-directory-commits-archive@www.apache.org Received: (qmail 25265 invoked from network); 6 Oct 2007 06:50:38 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 6 Oct 2007 06:50:38 -0000 Received: (qmail 37554 invoked by uid 500); 6 Oct 2007 06:50:26 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 37498 invoked by uid 500); 6 Oct 2007 06:50:26 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 37487 invoked by uid 99); 6 Oct 2007 06:50:26 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 05 Oct 2007 23:50:26 -0700 X-ASF-Spam-Status: No, hits=-100.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 06 Oct 2007 06:50:27 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 79EEF1A9856; Fri, 5 Oct 2007 23:49:07 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r582462 [8/10] - in /directory: apacheds/branches/bigbang/ apacheds/branches/bigbang/core-unit/src/main/java/org/apache/directory/server/core/unit/ apacheds/branches/bigbang/core-unit/src/test/java/org/apache/directory/server/core/ apacheds... Date: Sat, 06 Oct 2007 06:48:45 -0000 To: commits@directory.apache.org From: akarasulu@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20071006064907.79EEF1A9856@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Modified: directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/bind/GssapiMechanismHandler.java URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/bind/GssapiMechanismHandler.java?rev=582462&r1=582461&r2=582462&view=diff ============================================================================== --- directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/bind/GssapiMechanismHandler.java (original) +++ directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/bind/GssapiMechanismHandler.java Fri Oct 5 23:48:35 2007 @@ -20,15 +20,15 @@ package org.apache.directory.server.ldap.support.bind; -import java.security.PrivilegedExceptionAction; -import java.util.Map; +import org.apache.directory.server.core.DirectoryService; +import org.apache.mina.common.IoSession; import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.Sasl; import javax.security.sasl.SaslServer; - -import org.apache.mina.common.IoSession; +import java.security.PrivilegedExceptionAction; +import java.util.Map; /** @@ -37,6 +37,14 @@ */ public class GssapiMechanismHandler implements MechanismHandler { + private final DirectoryService directoryService; + + + public GssapiMechanismHandler( DirectoryService directoryService ) + { + this.directoryService = directoryService; + } + public SaslServer handleMechanism( IoSession session, Object message ) throws Exception { SaslServer ss; @@ -52,12 +60,14 @@ final Map saslProps = ( Map ) session.getAttribute( "saslProps" ); final String saslHost = ( String ) session.getAttribute( "saslHost" ); - final CallbackHandler callbackHandler = new GssapiCallbackHandler( session, message ); + final CallbackHandler callbackHandler = new GssapiCallbackHandler( directoryService, session, message ); + //noinspection unchecked ss = ( SaslServer ) Subject.doAs( subject, new PrivilegedExceptionAction() { public Object run() throws Exception { + //noinspection unchecked return Sasl.createSaslServer( "GSSAPI", "ldap", saslHost, saslProps, callbackHandler ); } } ); Modified: directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/bind/HandleSasl.java URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/bind/HandleSasl.java?rev=582462&r1=582461&r2=582462&view=diff ============================================================================== --- directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/bind/HandleSasl.java (original) +++ directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/bind/HandleSasl.java Fri Oct 5 23:48:35 2007 @@ -20,13 +20,7 @@ package org.apache.directory.server.ldap.support.bind; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import javax.security.sasl.SaslException; -import javax.security.sasl.SaslServer; - +import org.apache.directory.server.core.DirectoryService; import org.apache.directory.shared.ldap.message.BindRequest; import org.apache.directory.shared.ldap.message.BindResponse; import org.apache.directory.shared.ldap.message.LdapResult; @@ -36,6 +30,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.security.sasl.SaslException; +import javax.security.sasl.SaslServer; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + /** * @author Apache Directory Project @@ -43,29 +43,30 @@ */ public class HandleSasl implements IoHandlerCommand { - private static final Logger log = LoggerFactory.getLogger( HandleSasl.class ); + private static final Logger LOG = LoggerFactory.getLogger( HandleSasl.class ); /** * A Hashed Adapter mapping SASL mechanisms to their handlers. */ - private static final Map DEFAULT_HANDLERS; + private final Map handlers; + - static + public HandleSasl( DirectoryService directoryService ) { Map map = new HashMap(); - map.put( "CRAM-MD5", new CramMd5MechanismHandler() ); - map.put( "DIGEST-MD5", new DigestMd5MechanismHandler() ); - map.put( "GSSAPI", new GssapiMechanismHandler() ); - - DEFAULT_HANDLERS = Collections.unmodifiableMap( map ); + map.put( "CRAM-MD5", new CramMd5MechanismHandler( directoryService ) ); + map.put( "DIGEST-MD5", new DigestMd5MechanismHandler( directoryService ) ); + map.put( "GSSAPI", new GssapiMechanismHandler( directoryService ) ); + handlers = Collections.unmodifiableMap( map ); } + public void execute( NextCommand next, IoSession session, Object message ) throws Exception { String sessionMechanism = ( String ) session.getAttribute( "sessionMechanism" ); - if ( DEFAULT_HANDLERS.containsKey( sessionMechanism ) ) + if ( handlers.containsKey( sessionMechanism ) ) { SaslServer ss = handleMechanism( sessionMechanism, session, message ); handleMechanism( ss, next, session, message ); @@ -79,7 +80,7 @@ private SaslServer handleMechanism( String mechanism, IoSession session, Object message ) throws Exception { - MechanismHandler mechanismHandler = ( MechanismHandler ) DEFAULT_HANDLERS.get( mechanism ); + MechanismHandler mechanismHandler = ( MechanismHandler ) handlers.get( mechanism ); if ( mechanismHandler == null ) { @@ -125,17 +126,17 @@ } else { - log.info( "Continuation token had length " + tokenBytes.length ); + LOG.info( "Continuation token had length " + tokenBytes.length ); result.setResultCode( ResultCodeEnum.SASL_BIND_IN_PROGRESS ); BindResponse resp = ( BindResponse ) request.getResultResponse(); resp.setServerSaslCreds( tokenBytes ); session.write( resp ); - log.debug( "Returning final authentication data to client to complete context." ); + LOG.debug( "Returning final authentication data to client to complete context." ); } } catch ( SaslException se ) { - log.error( se.getMessage() ); + LOG.error( se.getMessage() ); result.setResultCode( ResultCodeEnum.INVALID_CREDENTIALS ); result.setErrorMessage( se.getMessage() ); session.write( request.getResultResponse() ); Modified: directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/extended/GracefulShutdownHandler.java URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/extended/GracefulShutdownHandler.java?rev=582462&r1=582461&r2=582462&view=diff ============================================================================== --- directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/extended/GracefulShutdownHandler.java (original) +++ directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/extended/GracefulShutdownHandler.java Fri Oct 5 23:48:35 2007 @@ -20,18 +20,7 @@ package org.apache.directory.server.ldap.support.extended; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import javax.naming.NamingException; -import javax.naming.ldap.LdapContext; - import org.apache.directory.server.core.DirectoryService; -import org.apache.directory.server.core.configuration.StartupConfiguration; import org.apache.directory.server.core.jndi.ServerLdapContext; import org.apache.directory.server.core.partition.PartitionNexus; import org.apache.directory.server.ldap.ExtendedOperationHandler; @@ -49,6 +38,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.naming.NamingException; +import javax.naming.ldap.LdapContext; +import java.util.*; + /** * @org.apache.xbean.XBean @@ -56,8 +49,8 @@ */ public class GracefulShutdownHandler implements ExtendedOperationHandler { - private static final Logger log = LoggerFactory.getLogger( GracefulShutdownHandler.class ); - public static final Set EXTENSION_OIDS; + private static final Logger LOG = LoggerFactory.getLogger( GracefulShutdownHandler.class ); + public static final Set EXTENSION_OIDS; static { @@ -78,8 +71,8 @@ public void handleExtendedOperation( IoSession requestor, SessionRegistry registry, ExtendedRequest req ) throws NamingException { - DirectoryService service = null; - ServerLdapContext slc = null; + DirectoryService service; + ServerLdapContext slc; LdapContext ctx = registry.getLdapContext( requestor, null, false ); ctx = ( LdapContext ) ctx.lookup( "" ); @@ -92,7 +85,7 @@ } else { - log.error( "Encountered session context which was not a ServerLdapContext" ); + LOG.error( "Encountered session context which was not a ServerLdapContext" ); GracefulShutdownResponse msg = new GracefulShutdownResponse( req.getMessageId(), ResultCodeEnum.OPERATIONS_ERROR ); msg.getLdapResult().setErrorMessage( "The session context was not a ServerLdapContext" ); @@ -104,9 +97,9 @@ // not we respond to the requestor with with insufficientAccessRights(50) if ( !slc.getPrincipal().getName().equalsIgnoreCase( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) ) { - if ( log.isInfoEnabled() ) + if ( LOG.isInfoEnabled() ) { - log.info( "Rejected with insufficientAccessRights to attempt for server shutdown by " + LOG.info( "Rejected with insufficientAccessRights to attempt for server shutdown by " + slc.getPrincipal().getName() ); } @@ -120,13 +113,12 @@ // ------------------------------------------------------------------- IoAcceptor acceptor = ( IoAcceptor ) requestor.getService(); - List sessions = new ArrayList( acceptor.getManagedSessions( requestor.getServiceAddress() ) ); - StartupConfiguration cfg = service.getConfiguration().getStartupConfiguration(); + List sessions = new ArrayList( + acceptor.getManagedSessions( requestor.getServiceAddress() ) ); GracefulShutdownRequest gsreq = ( GracefulShutdownRequest ) req; // build the graceful disconnect message with replicationContexts - PartitionNexus nexus = service.getConfiguration().getPartitionNexus(); - GracefulDisconnect notice = getGracefulDisconnect( gsreq.getTimeOffline(), gsreq.getDelay(), nexus ); + GracefulDisconnect notice = getGracefulDisconnect( gsreq.getTimeOffline(), gsreq.getDelay() ); // send (synch) the GracefulDisconnect to each client before unbinding sendGracefulDisconnect( sessions, notice, requestor ); @@ -161,20 +153,19 @@ // ------------------------------------------------------------------- sendShutdownResponse( requestor, req.getMessageId() ); - if ( cfg.isExitVmOnShutdown() ) + if ( service.isExitVmOnShutdown() ) { System.exit( 0 ); } - return; } /** * Sends a successful response. * - * @param requestor - * @param messageId + * @param requestor the session of the requestor + * @param messageId the message id associaed with this shutdown request */ public static void sendShutdownResponse( IoSession requestor, int messageId ) { @@ -183,14 +174,14 @@ future.join(); if ( future.isWritten() ) { - if ( log.isInfoEnabled() ) + if ( LOG.isInfoEnabled() ) { - log.info( "Sent GracefulShutdownResponse to client: " + requestor.getRemoteAddress() ); + LOG.info( "Sent GracefulShutdownResponse to client: " + requestor.getRemoteAddress() ); } } else { - log.error( "Failed to write GracefulShutdownResponse to client: " + requestor.getRemoteAddress() ); + LOG.error( "Failed to write GracefulShutdownResponse to client: " + requestor.getRemoteAddress() ); } requestor.close(); } @@ -202,10 +193,11 @@ * * @param msg the graceful disconnec extended request to send * @param requestor the session of the graceful shutdown requestor + * @param sessions the IoSessions to send disconnect message to */ - public static void sendGracefulDisconnect( List sessions, GracefulDisconnect msg, IoSession requestor ) + public static void sendGracefulDisconnect( List sessions, GracefulDisconnect msg, IoSession requestor ) { - List writeFutures = new ArrayList(); + List writeFutures = new ArrayList(); // asynchronously send GracefulDisconnection messages to all connected // clients giving time for the message to arrive before we block @@ -213,11 +205,9 @@ if ( sessions != null ) { - for ( Iterator i = sessions.iterator(); i.hasNext(); ) + for ( IoSession session : sessions ) { - IoSession session = ( IoSession ) i.next(); - - // make sure we do not send the disconnect mesasge to the + // make sure we do not send the disconnect mesasge to the // client which sent the initiating GracefulShutdown request if ( session.equals( requestor ) ) { @@ -230,22 +220,21 @@ } catch ( Exception e ) { - log.warn( "Failed to write GracefulDisconnect to client session: " + session, e ); + LOG.warn( "Failed to write GracefulDisconnect to client session: " + session, e ); } } } // wait for GracefulDisconnect messages to be sent before returning - for ( Iterator i = writeFutures.iterator(); i.hasNext(); ) + for ( WriteFuture future : writeFutures ) { - WriteFuture future = ( WriteFuture ) i.next(); try { future.join( 1000 ); } catch ( Exception e ) { - log.warn( "Failed to sent GracefulDisconnect", e ); + LOG.warn( "Failed to sent GracefulDisconnect", e ); } } } @@ -257,19 +246,18 @@ * for the requestor of the GracefulShutdown. * * @param requestor the session of the graceful shutdown requestor + * @param sessions the sessions from mina */ - public static void sendNoticeOfDisconnect( List sessions, IoSession requestor ) + public static void sendNoticeOfDisconnect( List sessions, IoSession requestor ) { - List writeFutures = new ArrayList(); + List writeFutures = new ArrayList(); // Send Notification of Disconnection messages to all connected clients. if ( sessions != null ) { - for ( Iterator i = sessions.iterator(); i.hasNext(); ) + for ( IoSession session : sessions ) { - IoSession session = ( IoSession ) i.next(); - - // make sure we do not send the disconnect mesasge to the + // make sure we do not send the disconnect mesasge to the // client which sent the initiating GracefulShutdown request if ( session.equals( requestor ) ) { @@ -282,16 +270,15 @@ } catch ( Exception e ) { - log.warn( "Failed to sent NoD for client: " + session, e ); + LOG.warn( "Failed to sent NoD for client: " + session, e ); } } } // And close the connections when the NoDs are sent. Iterator sessionIt = sessions.iterator(); - for ( Iterator i = writeFutures.iterator(); i.hasNext(); ) + for ( WriteFuture future : writeFutures ) { - WriteFuture future = ( WriteFuture ) i.next(); try { future.join( 1000 ); @@ -299,16 +286,15 @@ } catch ( Exception e ) { - log.warn( "Failed to sent NoD.", e ); + LOG.warn( "Failed to sent NoD.", e ); } } } - public static GracefulDisconnect getGracefulDisconnect( int timeOffline, int delay, PartitionNexus nexus ) + public static GracefulDisconnect getGracefulDisconnect( int timeOffline, int delay ) { // build the graceful disconnect message with replicationContexts - GracefulDisconnect notice = new GracefulDisconnect( timeOffline, delay ); // @todo add the referral objects for replication contexts using setup code below // Iterator list = nexus.listSuffixes( true ); // while ( list.hasNext() ) @@ -316,7 +302,7 @@ // LdapName dn = new LdapName( ( String ) list.next() ); // DirectoryPartition partition = nexus.getPartition( dn ); // } - return notice; + return new GracefulDisconnect( timeOffline, delay ); } @@ -336,14 +322,14 @@ } catch ( InterruptedException e ) { - log.warn( "Got interrupted while waiting for delay before shutdown", e ); + LOG.warn( "Got interrupted while waiting for delay before shutdown", e ); } } } } - public Set getExtensionOids() + public Set getExtensionOids() { return EXTENSION_OIDS; } Modified: directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/extended/LaunchDiagnosticUiHandler.java URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/extended/LaunchDiagnosticUiHandler.java?rev=582462&r1=582461&r2=582462&view=diff ============================================================================== --- directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/extended/LaunchDiagnosticUiHandler.java (original) +++ directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/extended/LaunchDiagnosticUiHandler.java Fri Oct 5 23:48:35 2007 @@ -56,7 +56,7 @@ */ public class LaunchDiagnosticUiHandler implements ExtendedOperationHandler { - public static final Set EXTENSION_OIDS; + public static final Set EXTENSION_OIDS; static { @@ -95,7 +95,7 @@ requestor.write( new LaunchDiagnosticUiResponse( req.getMessageId() ) ); - PartitionNexus nexus = service.getConfiguration().getPartitionNexus(); + PartitionNexus nexus = service.getPartitionNexus(); Iterator list = nexus.listSuffixes( new ListSuffixOperationContext() ); int launchedWindowCount = 0; @@ -152,7 +152,7 @@ } - public Set getExtensionOids() + public Set getExtensionOids() { return EXTENSION_OIDS; } Modified: directory/apacheds/branches/bigbang/protocol-ldap/src/test/java/org/apache/directory/server/ldap/LdapProtocolProviderTest.java URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-ldap/src/test/java/org/apache/directory/server/ldap/LdapProtocolProviderTest.java?rev=582462&r1=582461&r2=582462&view=diff ============================================================================== --- directory/apacheds/branches/bigbang/protocol-ldap/src/test/java/org/apache/directory/server/ldap/LdapProtocolProviderTest.java (original) +++ directory/apacheds/branches/bigbang/protocol-ldap/src/test/java/org/apache/directory/server/ldap/LdapProtocolProviderTest.java Fri Oct 5 23:48:35 2007 @@ -20,36 +20,18 @@ package org.apache.directory.server.ldap; -import java.util.Properties; - import junit.framework.TestCase; - +import org.apache.directory.server.core.DefaultDirectoryService; +import org.apache.directory.server.core.DirectoryService; import org.apache.directory.server.ldap.support.ExtendedHandler; import org.apache.directory.shared.ldap.NotImplementedException; import org.apache.directory.shared.ldap.exception.LdapNamingException; -import org.apache.directory.shared.ldap.message.AbandonRequest; -import org.apache.directory.shared.ldap.message.AbandonRequestImpl; -import org.apache.directory.shared.ldap.message.AddRequest; -import org.apache.directory.shared.ldap.message.AddRequestImpl; -import org.apache.directory.shared.ldap.message.BindRequest; -import org.apache.directory.shared.ldap.message.BindRequestImpl; -import org.apache.directory.shared.ldap.message.CompareRequest; -import org.apache.directory.shared.ldap.message.CompareRequestImpl; -import org.apache.directory.shared.ldap.message.DeleteRequest; -import org.apache.directory.shared.ldap.message.DeleteRequestImpl; -import org.apache.directory.shared.ldap.message.ExtendedRequest; -import org.apache.directory.shared.ldap.message.ExtendedRequestImpl; -import org.apache.directory.shared.ldap.message.ModifyDnRequest; -import org.apache.directory.shared.ldap.message.ModifyDnRequestImpl; -import org.apache.directory.shared.ldap.message.ModifyRequest; -import org.apache.directory.shared.ldap.message.ModifyRequestImpl; -import org.apache.directory.shared.ldap.message.SearchRequest; -import org.apache.directory.shared.ldap.message.SearchRequestImpl; -import org.apache.directory.shared.ldap.message.UnbindRequest; -import org.apache.directory.shared.ldap.message.UnbindRequestImpl; +import org.apache.directory.shared.ldap.message.*; import org.apache.mina.common.IoSession; import org.apache.mina.handler.demux.MessageHandler; +import java.util.Properties; + /** * Tests the . @@ -69,7 +51,9 @@ */ public void testDefaultOperation() throws LdapNamingException { - LdapProtocolProvider provider = new LdapProtocolProvider( new LdapConfiguration(), new Properties() ); + DirectoryService directoryService = new DefaultDirectoryService(); + LdapProtocolProvider provider = new LdapProtocolProvider( directoryService, + new LdapConfiguration(), new Properties() ); assertNotNull( provider.getCodecFactory() ); assertTrue( provider.getName() == LdapProtocolProvider.SERVICE_NAME ); } @@ -116,7 +100,8 @@ props.setProperty( UnbindRequest.class.getName(), BogusUnbindHandler.class.getName() ); props.setProperty( UnbindRequestImpl.class.getName(), BogusUnbindHandler.class.getName() ); - LdapProtocolProvider provider = new LdapProtocolProvider( new LdapConfiguration(), props ); + DirectoryService directoryService = new DefaultDirectoryService(); + LdapProtocolProvider provider = new LdapProtocolProvider( directoryService, new LdapConfiguration(), props ); assertNotNull( provider.getCodecFactory() ); assertTrue( provider.getName() == LdapProtocolProvider.SERVICE_NAME ); } Modified: directory/apacheds/branches/bigbang/protocol-shared/src/main/java/org/apache/directory/server/protocol/shared/ServiceConfiguration.java URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-shared/src/main/java/org/apache/directory/server/protocol/shared/ServiceConfiguration.java?rev=582462&r1=582461&r2=582462&view=diff ============================================================================== --- directory/apacheds/branches/bigbang/protocol-shared/src/main/java/org/apache/directory/server/protocol/shared/ServiceConfiguration.java (original) +++ directory/apacheds/branches/bigbang/protocol-shared/src/main/java/org/apache/directory/server/protocol/shared/ServiceConfiguration.java Fri Oct 5 23:48:35 2007 @@ -87,7 +87,7 @@ private String servicePid; /** Whether this service is enabled. */ - private boolean isEnabled = false; + private boolean isEnabled; /** @@ -160,19 +160,13 @@ * Compares whether a Dictionary of configuration is * different from the current instance of configuration. * - * @param config + * @param config the configuration * @return Whether the configuration is different. */ public boolean isDifferent( Dictionary config ) { int port = getIpPort(); - - if ( port == Integer.parseInt( ( String ) config.get( IP_PORT_KEY ) ) ) - { - return false; - } - - return true; + return port != Integer.parseInt( ( String ) config.get( IP_PORT_KEY ) ); } @@ -358,6 +352,8 @@ /** * Throws a {@link ServiceConfigurationException} if the specified port number * is out of range. + * + * @param port the port number to validate */ protected void validatePortNumber( int port ) { Added: directory/apacheds/branches/bigbang/server-jndi/src/main/java/org/apache/directory/server/configuration/ApacheDS.java URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-jndi/src/main/java/org/apache/directory/server/configuration/ApacheDS.java?rev=582462&view=auto ============================================================================== --- directory/apacheds/branches/bigbang/server-jndi/src/main/java/org/apache/directory/server/configuration/ApacheDS.java (added) +++ directory/apacheds/branches/bigbang/server-jndi/src/main/java/org/apache/directory/server/configuration/ApacheDS.java Fri Oct 5 23:48:35 2007 @@ -0,0 +1,928 @@ +/* + * 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.directory.server.configuration; + + +import org.apache.commons.lang.StringUtils; +import org.apache.directory.server.changepw.ChangePasswordConfiguration; +import org.apache.directory.server.changepw.ChangePasswordServer; +import org.apache.directory.server.constants.ApacheSchemaConstants; +import org.apache.directory.server.core.DefaultDirectoryService; +import org.apache.directory.server.core.DirectoryService; +import org.apache.directory.server.core.partition.PartitionNexus; +import org.apache.directory.server.dns.DnsConfiguration; +import org.apache.directory.server.dns.DnsServer; +import org.apache.directory.server.dns.store.RecordStore; +import org.apache.directory.server.dns.store.jndi.JndiRecordStoreImpl; +import org.apache.directory.server.jndi.ServerContextFactory; +import org.apache.directory.server.kerberos.kdc.KdcConfiguration; +import org.apache.directory.server.kerberos.kdc.KerberosServer; +import org.apache.directory.server.kerberos.shared.store.JndiPrincipalStoreImpl; +import org.apache.directory.server.kerberos.shared.store.PrincipalStore; +import org.apache.directory.server.ldap.ExtendedOperationHandler; +import org.apache.directory.server.ldap.LdapConfiguration; +import org.apache.directory.server.ldap.LdapProtocolProvider; +import org.apache.directory.server.ldap.support.ssl.LdapsInitializer; +import org.apache.directory.server.ntp.NtpConfiguration; +import org.apache.directory.server.ntp.NtpServer; +import org.apache.directory.server.protocol.shared.store.LdifFileLoader; +import org.apache.directory.server.protocol.shared.store.LdifLoadFilter; +import org.apache.directory.shared.ldap.constants.SchemaConstants; +import org.apache.directory.shared.ldap.exception.LdapConfigurationException; +import org.apache.directory.shared.ldap.exception.LdapNamingException; +import org.apache.directory.shared.ldap.message.AttributesImpl; +import org.apache.directory.shared.ldap.message.extended.NoticeOfDisconnect; +import org.apache.directory.shared.ldap.util.StringTools; +import org.apache.mina.common.*; +import org.apache.mina.filter.executor.ExecutorFilter; +import org.apache.mina.transport.socket.nio.DatagramAcceptor; +import org.apache.mina.transport.socket.nio.DatagramAcceptorConfig; +import org.apache.mina.transport.socket.nio.SocketAcceptor; +import org.apache.mina.transport.socket.nio.SocketAcceptorConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.directory.Attributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + + +/** + * Apache Directory Server top level. + * + * @author Apache Directory Project + * @version $Rev$ + */ +public class ApacheDS +{ + public static final String JNDI_KEY = ApacheDS.class.toString(); + public static final int MAX_THREADS_DEFAULT = 32; + + private static final String WINDOWSFILE_ATTR = "windowsFilePath"; + private static final String UNIXFILE_ATTR = "unixFilePath"; + private static final Logger LOG = LoggerFactory.getLogger( ApacheDS.class.getName() ); + private static final String LDIF_FILES_DN = "ou=loadedLdifFiles,ou=configuration,ou=system"; + private static final long DEFAULT_SYNC_PERIOD_MILLIS = 20000; + + private int maxThreads = MAX_THREADS_DEFAULT; + private long synchPeriodMillis = DEFAULT_SYNC_PERIOD_MILLIS; + private boolean enableNetworking = true; + private Hashtable environment = new Hashtable(); + + private File ldifDirectory; + private final List ldifFilters = new ArrayList(); + + private KdcConfiguration kdcConfiguration = new KdcConfiguration(); + private NtpConfiguration ntpConfiguration = new NtpConfiguration(); + private ChangePasswordConfiguration changePasswordConfiguration = new ChangePasswordConfiguration(); + private LdapConfiguration ldapConfiguration = new LdapConfiguration(); + private LdapConfiguration ldapsConfiguration = new LdapConfiguration(); + private DnsConfiguration dnsConfiguration = new DnsConfiguration(); + private DirectoryService directoryService = new DefaultDirectoryService(); + + private IoAcceptor tcpAcceptor; + protected IoAcceptor udpAcceptor; + protected ExecutorService ioExecutor; + protected ExecutorService logicExecutor; + private boolean ldapsStarted; + private boolean ldapStarted; + private KerberosServer tcpKdcServer; + private KerberosServer udpKdcServer; + private ChangePasswordServer tcpChangePasswordServer; + private ChangePasswordServer udpChangePasswordServer; + private NtpServer tcpNtpServer; + private NtpServer udpNtpServer; + private DnsServer tcpDnsServer; + private DnsServer udpDnsServer; + + + public ApacheDS() + { + environment.put( JNDI_KEY, this ); + environment.put( Context.INITIAL_CONTEXT_FACTORY, ServerContextFactory.class.toString() ); + environment.put( Context.SECURITY_AUTHENTICATION, "simple" ); + ldapConfiguration.setEnabled( true ); + + ByteBuffer.setAllocator( new SimpleByteBufferAllocator() ); + ByteBuffer.setUseDirectBuffers( false ); + + ioExecutor = Executors.newCachedThreadPool(); + logicExecutor = Executors.newFixedThreadPool( maxThreads ); + udpAcceptor = new DatagramAcceptor(); + udpAcceptor.getFilterChain().addLast( "executor", new ExecutorFilter( logicExecutor ) ); + tcpAcceptor = new SocketAcceptor( Runtime.getRuntime().availableProcessors(), ioExecutor ); + tcpAcceptor.getFilterChain().addLast( "executor", new ExecutorFilter( logicExecutor ) ); + } + + + public void startup() throws NamingException + { + loadLdifs(); + + if ( ! directoryService.isStarted() ) + { + directoryService.startup(); + } + + if ( enableNetworking ) + { + startLDAP( environment ); + startLDAPS( environment ); + startKerberos(); + startChangePassword(); + startNTP(); + startDNS(); + } + } + + + public boolean isStarted() + { + return ldapStarted || ldapsStarted; + } + + + public void shutdown() throws NamingException + { + if ( ldapStarted ) + { + stopLDAP0( ldapConfiguration.getIpPort() ); + ldapStarted = false; + } + + if ( ldapsStarted ) + { + stopLDAP0( ldapsConfiguration.getIpPort() ); + ldapsStarted = false; + } + + if ( tcpKdcServer != null ) + { + tcpKdcServer.destroy(); + if ( LOG.isInfoEnabled() ) + { + LOG.info( "Unbind of KRB5 Service (TCP) complete: " + tcpKdcServer ); + } + tcpKdcServer = null; + } + + if ( udpKdcServer != null ) + { + udpKdcServer.destroy(); + if ( LOG.isInfoEnabled() ) + { + LOG.info( "Unbind of KRB5 Service (UDP) complete: " + udpKdcServer ); + } + udpKdcServer = null; + } + + if ( tcpChangePasswordServer != null ) + { + tcpChangePasswordServer.destroy(); + if ( LOG.isInfoEnabled() ) + { + LOG.info( "Unbind of Change Password Service (TCP) complete: " + tcpChangePasswordServer ); + } + tcpChangePasswordServer = null; + } + + if ( udpChangePasswordServer != null ) + { + udpChangePasswordServer.destroy(); + if ( LOG.isInfoEnabled() ) + { + LOG.info( "Unbind of Change Password Service (UDP) complete: " + udpChangePasswordServer ); + } + udpChangePasswordServer = null; + } + + if ( tcpNtpServer != null ) + { + tcpNtpServer.destroy(); + if ( LOG.isInfoEnabled() ) + { + LOG.info( "Unbind of NTP Service (TCP) complete: " + tcpNtpServer ); + } + tcpNtpServer = null; + } + + if ( udpNtpServer != null ) + { + udpNtpServer.destroy(); + if ( LOG.isInfoEnabled() ) + { + LOG.info( "Unbind of NTP Service (UDP) complete: " + udpNtpServer ); + } + udpNtpServer = null; + } + + if ( tcpDnsServer != null ) + { + tcpDnsServer.destroy(); + if ( LOG.isInfoEnabled() ) + { + LOG.info( "Unbind of DNS Service (TCP) complete: " + tcpDnsServer ); + } + tcpDnsServer = null; + } + + if ( udpDnsServer != null ) + { + udpDnsServer.destroy(); + if ( LOG.isInfoEnabled() ) + { + LOG.info( "Unbind of DNS Service (UDP) complete: " + udpDnsServer ); + } + udpDnsServer = null; + } + + logicExecutor.shutdown(); + for (;;) { + try { + if ( logicExecutor.awaitTermination( Integer.MAX_VALUE, TimeUnit.SECONDS ) ) + { + break; + } + } + catch ( InterruptedException e ) + { + LOG.error( "Failed to terminate logic executor", e ); + } + } + + ioExecutor.shutdown(); + for (;;) { + try { + if ( ioExecutor.awaitTermination( Integer.MAX_VALUE, TimeUnit.SECONDS ) ) + { + break; + } + } + catch ( InterruptedException e ) + { + LOG.error( "Failed to terminate io executor", e ); + } + } + + directoryService.shutdown(); + } + + + public KdcConfiguration getKdcConfiguration() + { + return kdcConfiguration; + } + + + public void setKdcConfiguration( KdcConfiguration kdcConfiguration ) + { + this.kdcConfiguration = kdcConfiguration; + } + + + public NtpConfiguration getNtpConfiguration() + { + return ntpConfiguration; + } + + + public void setNtpConfiguration( NtpConfiguration ntpConfiguration ) + { + this.ntpConfiguration = ntpConfiguration; + } + + + public ChangePasswordConfiguration getChangePasswordConfiguration() + { + return changePasswordConfiguration; + } + + + public void setChangePasswordConfiguration( ChangePasswordConfiguration changePasswordConfiguration ) + { + this.changePasswordConfiguration = changePasswordConfiguration; + } + + + public LdapConfiguration getLdapConfiguration() + { + return ldapConfiguration; + } + + + public void setLdapConfiguration( LdapConfiguration ldapConfiguration ) + { + this.ldapConfiguration = ldapConfiguration; + } + + + public LdapConfiguration getLdapsConfiguration() + { + return ldapsConfiguration; + } + + + public void setLdapsConfiguration( LdapConfiguration ldapsConfiguration ) + { + this.ldapsConfiguration = ldapsConfiguration; + } + + + public DnsConfiguration getDnsConfiguration() + { + return dnsConfiguration; + } + + + public void setDnsConfiguration( DnsConfiguration dnsConfiguration ) + { + this.dnsConfiguration = dnsConfiguration; + } + + + public DirectoryService getDirectoryService() + { + return directoryService; + } + + + public void setDirectoryService( DirectoryService directoryService ) + { + this.directoryService = directoryService; + } + + + public int getMaxThreads() + { + return maxThreads; + } + + + public void setMaxThreads( int maxThreads ) + { + this.maxThreads = maxThreads; + if ( maxThreads < 1 ) + { + throw new IllegalArgumentException( "Number of max threads should be greater than 0" ); + } + } + + + public long getSynchPeriodMillis() + { + return synchPeriodMillis; + } + + + public void setSynchPeriodMillis( long synchPeriodMillis ) + { + this.synchPeriodMillis = synchPeriodMillis; + } + + + public boolean isEnableNetworking() + { + return enableNetworking; + } + + + public void setEnableNetworking( boolean enableNetworking ) + { + this.enableNetworking = enableNetworking; + } + + + public File getLdifDirectory() + { + if ( ldifDirectory == null ) + { + return null; + } + else if ( ldifDirectory.isAbsolute() ) + { + return this.ldifDirectory; + } + else + { + return new File( directoryService.getWorkingDirectory().getParent() , ldifDirectory.toString() ); + } + } + + + public void setAllowAnonymousAccess( boolean allowAnonymousAccess ) + { + this.directoryService.setAllowAnonymousAccess( allowAnonymousAccess ); + this.ldapConfiguration.setAllowAnonymousAccess( allowAnonymousAccess ); + this.ldapsConfiguration.setAllowAnonymousAccess( allowAnonymousAccess ); + } + + + public void setLdifDirectory( File ldifDirectory ) + { + this.ldifDirectory = ldifDirectory; + } + + + public List getLdifFilters() + { + return new ArrayList( ldifFilters ); + } + + + protected void setLdifFilters( List filters ) + { + this.ldifFilters.clear(); + this.ldifFilters.addAll( filters ); + } + + + // ---------------------------------------------------------------------- + // From ServerContextFactory: presently in intermediate step but these + // methods will be moved to the appropriate protocol service eventually. + // This is here simply to start to remove the JNDI dependency then further + // refactoring will be needed to place these where they belong. + // ---------------------------------------------------------------------- + + private void ensureLdifFileBase( DirContext root ) + { + Attributes entry = new AttributesImpl( SchemaConstants.OU_AT, "loadedLdifFiles", true ); + entry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC ); + entry.get( SchemaConstants.OBJECT_CLASS_AT ).add( SchemaConstants.ORGANIZATIONAL_UNIT_OC ); + + try + { + root.createSubcontext( LDIF_FILES_DN, entry ); + LOG.info( "Creating " + LDIF_FILES_DN ); + } + catch ( NamingException e ) + { + LOG.info( LDIF_FILES_DN + " exists" ); + } + } + + + private String buildProtectedFileEntry( File ldif ) + { + StringBuffer buf = new StringBuffer(); + + buf.append( File.separatorChar == '\\' ? WINDOWSFILE_ATTR : UNIXFILE_ATTR ); + buf.append( "=" ); + + buf.append( StringTools.dumpHexPairs( StringTools.getBytesUtf8( getCanonical( ldif ) ) ) ); + + buf.append( "," ); + buf.append( LDIF_FILES_DN ); + + return buf.toString(); + } + + private void addFileEntry( DirContext root, File ldif ) throws NamingException + { + String rdnAttr = File.separatorChar == '\\' ? WINDOWSFILE_ATTR : UNIXFILE_ATTR; + String oc = File.separatorChar == '\\' ? ApacheSchemaConstants.WINDOWS_FILE_OC : ApacheSchemaConstants.UNIX_FILE_OC; + + Attributes entry = new AttributesImpl( rdnAttr, getCanonical( ldif ), true ); + entry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC ); + entry.get( SchemaConstants.OBJECT_CLASS_AT ).add( oc ); + root.createSubcontext( buildProtectedFileEntry( ldif ), entry ); + } + + + private Attributes getLdifFileEntry( DirContext root, File ldif ) + { + try + { + return root.getAttributes( buildProtectedFileEntry( ldif ), new String[] + { SchemaConstants.CREATE_TIMESTAMP_AT } ); + } + catch ( NamingException e ) + { + return null; + } + } + + + private String getCanonical( File file ) + { + String canonical; + + try + { + canonical = file.getCanonicalPath(); + } + catch ( IOException e ) + { + LOG.error( "could not get canonical path", e ); + return null; + } + + return StringUtils.replace( canonical, "\\", "\\\\" ); + } + + + private void loadLdifs() throws NamingException + { + // LOG and bail if property not set + if ( ldifDirectory == null ) + { + LOG.info( "LDIF load directory not specified. No LDIF files will be loaded." ); + return; + } + + // LOG and bail if LDIF directory does not exists + if ( ! ldifDirectory.exists() ) + { + LOG.warn( "LDIF load directory '" + getCanonical( ldifDirectory ) + + "' does not exist. No LDIF files will be loaded." ); + return; + } + + // get an initial context to the rootDSE for creating the LDIF entries + //noinspection unchecked + Hashtable env = ( Hashtable ) environment.clone(); + env.put( Context.PROVIDER_URL, "" ); + env.put( ApacheDS.JNDI_KEY, this ); + env.put( Context.INITIAL_CONTEXT_FACTORY, ServerContextFactory.class.getName() ); + DirContext root = new InitialDirContext( env ); + + // make sure the configuration area for loaded ldif files is present + ensureLdifFileBase( root ); + + // if ldif directory is a file try to load it + if ( ! ldifDirectory.isDirectory() ) + { + if ( LOG.isInfoEnabled() ) + { + LOG.info( "LDIF load directory '" + getCanonical( ldifDirectory ) + + "' is a file. Will attempt to load as LDIF." ); + } + + Attributes fileEntry = getLdifFileEntry( root, ldifDirectory ); + + if ( fileEntry != null ) + { + String time = ( String ) fileEntry.get( SchemaConstants.CREATE_TIMESTAMP_AT ).get(); + + if ( LOG.isInfoEnabled() ) + { + LOG.info( "Load of LDIF file '" + getCanonical( ldifDirectory ) + + "' skipped. It has already been loaded on " + time + "." ); + } + + return; + } + + LdifFileLoader loader = new LdifFileLoader( root, ldifDirectory, ldifFilters ); + loader.execute(); + + addFileEntry( root, ldifDirectory ); + return; + } + + // get all the ldif files within the directory (should be sorted alphabetically) + File[] ldifFiles = ldifDirectory.listFiles( new FileFilter() + { + public boolean accept( File pathname ) + { + boolean isLdif = pathname.getName().toLowerCase().endsWith( ".ldif" ); + return pathname.isFile() && pathname.canRead() && isLdif; + } + } ); + + // LOG and bail if we could not find any LDIF files + if ( ldifFiles == null || ldifFiles.length == 0 ) + { + LOG.warn( "LDIF load directory '" + getCanonical( ldifDirectory ) + + "' does not contain any LDIF files. No LDIF files will be loaded." ); + return; + } + + // load all the ldif files and load each one that is loaded + for ( File ldifFile : ldifFiles ) + { + Attributes fileEntry = getLdifFileEntry( root, ldifFile ); + + if ( fileEntry != null ) + { + String time = ( String ) fileEntry.get( SchemaConstants.CREATE_TIMESTAMP_AT ).get(); + LOG.info( "Load of LDIF file '" + getCanonical( ldifFile ) + + "' skipped. It has already been loaded on " + time + "." ); + continue; + } + + LdifFileLoader loader = new LdifFileLoader( root, ldifFile, ldifFilters ); + int count = loader.execute(); + LOG.info( "Loaded " + count + " entries from LDIF file '" + getCanonical( ldifFile ) + "'" ); + addFileEntry( root, ldifFile ); + } + } + + + /** + * Starts up the LDAP protocol provider to service LDAP requests + * + * @throws NamingException if there are problems starting the LDAP provider + * @param env the environment + */ + private void startLDAP( Hashtable env ) throws NamingException + { + // Skip if disabled + if ( ! ldapConfiguration.isEnabled() ) + { + return; + } + + DefaultIoFilterChainBuilder chain = new DefaultIoFilterChainBuilder(); + startLDAP0( ldapConfiguration, env, ldapConfiguration.getIpPort(), chain ); + } + + + /** + * Starts up the LDAPS protocol provider to service LDAPS requests + * + * @throws NamingException if there are problems starting the LDAPS provider + * @param env the JNDI environment + */ + private void startLDAPS( Hashtable env ) throws NamingException + { + // Skip if disabled + if ( !( ldapsConfiguration.isEnabled() && ldapsConfiguration.isEnableLdaps() ) ) + { + return; + } + + char[] certPasswordChars = ldapsConfiguration.getLdapsCertificatePassword().toCharArray(); + String storePath = ldapsConfiguration.getLdapsCertificateFile().getPath(); + + IoFilterChainBuilder chain = LdapsInitializer.init( certPasswordChars, storePath ); + ldapsStarted = true; + + startLDAP0( ldapsConfiguration, env, ldapsConfiguration.getIpPort(), chain ); + } + + + private void startLDAP0( LdapConfiguration ldapConfig, Hashtable env, int port, IoFilterChainBuilder chainBuilder ) + throws LdapNamingException, LdapConfigurationException + { + // Register all extended operation handlers. + LdapProtocolProvider protocolProvider = new LdapProtocolProvider( directoryService, ldapConfig, + ( Hashtable ) env.clone() ); + + for ( ExtendedOperationHandler h : ldapConfig.getExtendedOperationHandlers() ) + { + protocolProvider.addExtendedOperationHandler( h ); + LOG.info( "Added Extended Request Handler: " + h.getOid() ); + h.setLdapProvider( protocolProvider ); + PartitionNexus nexus = directoryService.getPartitionNexus(); + nexus.registerSupportedExtensions( h.getExtensionOids() ); + } + + try + { + SocketAcceptorConfig acceptorCfg = new SocketAcceptorConfig(); + + // Disable the disconnection of the clients on unbind + acceptorCfg.setDisconnectOnUnbind( false ); + acceptorCfg.setReuseAddress( true ); + acceptorCfg.setFilterChainBuilder( chainBuilder ); + acceptorCfg.setThreadModel( ThreadModel.MANUAL ); + + acceptorCfg.getSessionConfig().setTcpNoDelay( true ); + + tcpAcceptor.bind( new InetSocketAddress( port ), protocolProvider.getHandler(), acceptorCfg ); + ldapStarted = true; + + if ( LOG.isInfoEnabled() ) + { + LOG.info( "Successful bind of an LDAP Service (" + port + ") is complete." ); + } + } + catch ( IOException e ) + { + String msg = "Failed to bind an LDAP service (" + port + ") to the service registry."; + LdapConfigurationException lce = new LdapConfigurationException( msg ); + lce.setRootCause( e ); + LOG.error( msg, e ); + throw lce; + } + } + + + private void startKerberos() + { + // Skip if disabled + if ( ! kdcConfiguration.isEnabled() ) + { + return; + } + + try + { + PrincipalStore kdcStore = new JndiPrincipalStoreImpl( kdcConfiguration, directoryService ); + + DatagramAcceptorConfig udpConfig = new DatagramAcceptorConfig(); + udpConfig.setThreadModel( ThreadModel.MANUAL ); + + SocketAcceptorConfig tcpConfig = new SocketAcceptorConfig(); + tcpConfig.setDisconnectOnUnbind( false ); + tcpConfig.setReuseAddress( true ); + tcpConfig.setThreadModel( ThreadModel.MANUAL ); + + tcpKdcServer = new KerberosServer( kdcConfiguration, tcpAcceptor, tcpConfig, kdcStore ); + udpKdcServer = new KerberosServer( kdcConfiguration, udpAcceptor, udpConfig, kdcStore ); + } + catch ( Throwable t ) + { + LOG.error( "Failed to start the Kerberos service", t ); + } + } + + + private void startChangePassword() + { + // Skip if disabled + if ( ! changePasswordConfiguration.isEnabled() ) + { + return; + } + + try + { + PrincipalStore store = new JndiPrincipalStoreImpl( changePasswordConfiguration, directoryService ); + + DatagramAcceptorConfig udpConfig = new DatagramAcceptorConfig(); + udpConfig.setThreadModel( ThreadModel.MANUAL ); + + SocketAcceptorConfig tcpConfig = new SocketAcceptorConfig(); + tcpConfig.setDisconnectOnUnbind( false ); + tcpConfig.setReuseAddress( true ); + tcpConfig.setThreadModel( ThreadModel.MANUAL ); + + tcpChangePasswordServer = new ChangePasswordServer( changePasswordConfiguration, + tcpAcceptor, tcpConfig, store ); + udpChangePasswordServer = new ChangePasswordServer( changePasswordConfiguration, + udpAcceptor, udpConfig, store ); + } + catch ( Throwable t ) + { + LOG.error( "Failed to start the Change Password service", t ); + } + } + + + private void startNTP() + { + // Skip if disabled + if ( ! ntpConfiguration.isEnabled() ) + { + return; + } + + try + { + DatagramAcceptorConfig udpConfig = new DatagramAcceptorConfig(); + udpConfig.setThreadModel( ThreadModel.MANUAL ); + + SocketAcceptorConfig tcpConfig = new SocketAcceptorConfig(); + tcpConfig.setDisconnectOnUnbind( false ); + tcpConfig.setReuseAddress( true ); + tcpConfig.setThreadModel( ThreadModel.MANUAL ); + + tcpNtpServer = new NtpServer( ntpConfiguration, tcpAcceptor, tcpConfig ); + udpNtpServer = new NtpServer( ntpConfiguration, udpAcceptor, udpConfig ); + } + catch ( Throwable t ) + { + LOG.error( "Failed to start the NTP service", t ); + } + } + + + private void startDNS() + { + // Skip if disabled + if ( ! dnsConfiguration.isEnabled() ) + { + return; + } + + try + { + RecordStore store = new JndiRecordStoreImpl( dnsConfiguration, directoryService ); + + DatagramAcceptorConfig udpConfig = new DatagramAcceptorConfig(); + udpConfig.setThreadModel( ThreadModel.MANUAL ); + + SocketAcceptorConfig tcpConfig = new SocketAcceptorConfig(); + tcpConfig.setDisconnectOnUnbind( false ); + tcpConfig.setReuseAddress( true ); + tcpConfig.setThreadModel( ThreadModel.MANUAL ); + + tcpDnsServer = new DnsServer( dnsConfiguration, tcpAcceptor, tcpConfig, store ); + udpDnsServer = new DnsServer( dnsConfiguration, udpAcceptor, udpConfig, store ); + } + catch ( Throwable t ) + { + LOG.error( "Failed to start the DNS service", t ); + } + } + + + private void stopLDAP0( int port ) + { + try + { + // we should unbind the service before we begin sending the notice + // of disconnect so new connections are not formed while we process + List writeFutures = new ArrayList(); + + // If the socket has already been unbound as with a successful + // GracefulShutdownRequest then this will complain that the service + // is not bound - this is ok because the GracefulShutdown has already + // sent notices to to the existing active sessions + List sessions; + + try + { + sessions = new ArrayList( tcpAcceptor.getManagedSessions( new InetSocketAddress( port ) ) ); + } + catch ( IllegalArgumentException e ) + { + LOG.warn( "Seems like the LDAP service (" + port + ") has already been unbound." ); + return; + } + + tcpAcceptor.unbind( new InetSocketAddress( port ) ); + + if ( LOG.isInfoEnabled() ) + { + LOG.info( "Unbind of an LDAP service (" + port + ") is complete." ); + LOG.info( "Sending notice of disconnect to existing clients sessions." ); + } + + // Send Notification of Disconnection messages to all connected clients. + if ( sessions != null ) + { + for ( IoSession session:sessions ) + { + writeFutures.add( session.write( NoticeOfDisconnect.UNAVAILABLE ) ); + } + } + + // And close the connections when the NoDs are sent. + Iterator sessionIt = sessions.iterator(); + + for ( WriteFuture future:writeFutures ) + { + future.join( 1000 ); + sessionIt.next().close(); + } + } + catch ( Exception e ) + { + LOG.warn( "Failed to sent NoD.", e ); + } + } + + + public Hashtable getEnvironment() + { + return environment; + } + + + public void setEnvironment( Hashtable environment ) + { + this.environment = environment; + } +} Modified: directory/apacheds/branches/bigbang/server-jndi/src/main/java/org/apache/directory/server/jndi/ServerContextFactory.java URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-jndi/src/main/java/org/apache/directory/server/jndi/ServerContextFactory.java?rev=582462&r1=582461&r2=582462&view=diff ============================================================================== --- directory/apacheds/branches/bigbang/server-jndi/src/main/java/org/apache/directory/server/jndi/ServerContextFactory.java (original) +++ directory/apacheds/branches/bigbang/server-jndi/src/main/java/org/apache/directory/server/jndi/ServerContextFactory.java Fri Oct 5 23:48:35 2007 @@ -20,70 +20,15 @@ package org.apache.directory.server.jndi; -import java.io.File; -import java.io.FileFilter; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Hashtable; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; +import org.apache.directory.server.configuration.ApacheDS; +import org.apache.directory.server.core.DirectoryService; +import org.apache.directory.server.core.jndi.CoreContextFactory; +import javax.naming.ConfigurationException; import javax.naming.Context; import javax.naming.NamingException; -import javax.naming.directory.Attributes; -import javax.naming.directory.DirContext; +import java.util.Hashtable; -import org.apache.commons.lang.StringUtils; -import org.apache.directory.server.changepw.ChangePasswordConfiguration; -import org.apache.directory.server.changepw.ChangePasswordServer; -import org.apache.directory.server.configuration.ServerStartupConfiguration; -import org.apache.directory.server.constants.ApacheSchemaConstants; -import org.apache.directory.server.core.DirectoryService; -import org.apache.directory.server.core.jndi.CoreContextFactory; -import org.apache.directory.server.core.partition.PartitionNexus; -import org.apache.directory.server.dns.DnsConfiguration; -import org.apache.directory.server.dns.DnsServer; -import org.apache.directory.server.dns.store.RecordStore; -import org.apache.directory.server.dns.store.jndi.JndiRecordStoreImpl; -import org.apache.directory.server.kerberos.kdc.KdcConfiguration; -import org.apache.directory.server.kerberos.kdc.KerberosServer; -import org.apache.directory.server.kerberos.shared.store.JndiPrincipalStoreImpl; -import org.apache.directory.server.kerberos.shared.store.PrincipalStore; -import org.apache.directory.server.ldap.ExtendedOperationHandler; -import org.apache.directory.server.ldap.LdapConfiguration; -import org.apache.directory.server.ldap.LdapProtocolProvider; -import org.apache.directory.server.ldap.support.ssl.LdapsInitializer; -import org.apache.directory.server.ntp.NtpConfiguration; -import org.apache.directory.server.ntp.NtpServer; -import org.apache.directory.server.protocol.shared.store.LdifFileLoader; -import org.apache.directory.shared.ldap.constants.SchemaConstants; -import org.apache.directory.shared.ldap.exception.LdapConfigurationException; -import org.apache.directory.shared.ldap.exception.LdapNamingException; -import org.apache.directory.shared.ldap.message.AttributesImpl; -import org.apache.directory.shared.ldap.message.extended.NoticeOfDisconnect; -import org.apache.directory.shared.ldap.util.StringTools; -import org.apache.mina.common.ByteBuffer; -import org.apache.mina.common.DefaultIoFilterChainBuilder; -import org.apache.mina.common.IoAcceptor; -import org.apache.mina.common.IoFilterChainBuilder; -import org.apache.mina.common.IoSession; -import org.apache.mina.common.SimpleByteBufferAllocator; -import org.apache.mina.common.ThreadModel; -import org.apache.mina.common.WriteFuture; -import org.apache.mina.filter.executor.ExecutorFilter; -import org.apache.mina.transport.socket.nio.DatagramAcceptor; -import org.apache.mina.transport.socket.nio.DatagramAcceptorConfig; -import org.apache.mina.transport.socket.nio.SocketAcceptor; -import org.apache.mina.transport.socket.nio.SocketAcceptorConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Adds additional bootstrapping for server socket listeners when firing @@ -95,667 +40,19 @@ */ public class ServerContextFactory extends CoreContextFactory { - /** Logger for this class */ - private static final Logger log = LoggerFactory.getLogger( ServerContextFactory.class.getName() ); - private static final String LDIF_FILES_DN = "ou=loadedLdifFiles,ou=configuration,ou=system"; - - private DirectoryService directoryService; - - private static final Map contexts = - Collections.synchronizedMap(new IdentityHashMap()); - - private static class DirectoryServiceContext { - protected IoAcceptor tcpAcceptor; - protected IoAcceptor udpAcceptor; - protected ExecutorService ioExecutor; - protected ExecutorService logicExecutor; - - private boolean ldapStarted; - private boolean ldapsStarted; - private KerberosServer tcpKdcServer; - private KerberosServer udpKdcServer; - private ChangePasswordServer tcpChangePasswordServer; - private ChangePasswordServer udpChangePasswordServer; - private NtpServer tcpNtpServer; - private NtpServer udpNtpServer; - private DnsServer tcpDnsServer; - private DnsServer udpDnsServer; - } - - /** - * Initialize the SocketAcceptor so that the server can accept - * incomming requests. - * - * We will start N threads, spreaded on the available CPUs. - */ - public void beforeStartup( DirectoryService service ) - { - ByteBuffer.setAllocator(new SimpleByteBufferAllocator()); - ByteBuffer.setUseDirectBuffers(false); - - DirectoryServiceContext dsc = new DirectoryServiceContext(); - contexts.put(service, dsc); - - int maxThreads = ( ( ServerStartupConfiguration ) service.getConfiguration().getStartupConfiguration() ).getMaxThreads(); - dsc.ioExecutor = Executors.newCachedThreadPool(); - dsc.logicExecutor = Executors.newFixedThreadPool( maxThreads ); - dsc.udpAcceptor = new DatagramAcceptor(); - dsc.udpAcceptor.getFilterChain().addLast("executor", new ExecutorFilter(dsc.logicExecutor)); - dsc.tcpAcceptor = new SocketAcceptor( - Runtime.getRuntime().availableProcessors(), dsc.ioExecutor ); - dsc.tcpAcceptor.getFilterChain().addLast("executor", new ExecutorFilter(dsc.logicExecutor)); - - this.directoryService = service; - } - - - // @todo this was afterShutdown but perhaps it's best this occurs before shutdown - public void beforeShutdown( DirectoryService service ) - { - ServerStartupConfiguration cfg = ( ServerStartupConfiguration ) service.getConfiguration() - .getStartupConfiguration(); - - DirectoryServiceContext dsc = contexts.remove(service); - - LdapConfiguration ldapCfg = cfg.getLdapConfiguration(); - LdapConfiguration ldapsCfg = cfg.getLdapsConfiguration(); - - if ( dsc.ldapStarted ) - { - stopLDAP0( dsc, ldapCfg.getIpPort() ); - dsc.ldapStarted = false; - } - - if ( dsc.ldapsStarted ) - { - stopLDAP0( dsc, ldapsCfg.getIpPort() ); - dsc.ldapsStarted = false; - } - - if ( dsc.tcpKdcServer != null ) - { - dsc.tcpKdcServer.destroy(); - - if ( log.isInfoEnabled() ) - { - log.info( "Unbind of KRB5 Service (TCP) complete: " + dsc.tcpKdcServer ); - } - - dsc.tcpKdcServer = null; - } - - if ( dsc.udpKdcServer != null ) - { - dsc.udpKdcServer.destroy(); - - if ( log.isInfoEnabled() ) - { - log.info( "Unbind of KRB5 Service (UDP) complete: " + dsc.udpKdcServer ); - } - - dsc.udpKdcServer = null; - } - - if ( dsc.tcpChangePasswordServer != null ) - { - dsc.tcpChangePasswordServer.destroy(); - - if ( log.isInfoEnabled() ) - { - log.info( "Unbind of Change Password Service (TCP) complete: " + dsc.tcpChangePasswordServer ); - } - - dsc.tcpChangePasswordServer = null; - } - - if ( dsc.udpChangePasswordServer != null ) - { - dsc.udpChangePasswordServer.destroy(); - - if ( log.isInfoEnabled() ) - { - log.info( "Unbind of Change Password Service (UDP) complete: " + dsc.udpChangePasswordServer ); - } - - dsc.udpChangePasswordServer = null; - } - - if ( dsc.tcpNtpServer != null ) - { - dsc.tcpNtpServer.destroy(); - - if ( log.isInfoEnabled() ) - { - log.info( "Unbind of NTP Service (TCP) complete: " + dsc.tcpNtpServer ); - } - - dsc.tcpNtpServer = null; - } - - if ( dsc.udpNtpServer != null ) - { - dsc.udpNtpServer.destroy(); - - if ( log.isInfoEnabled() ) - { - log.info( "Unbind of NTP Service (UDP) complete: " + dsc.udpNtpServer ); - } - - dsc.udpNtpServer = null; - } - - if ( dsc.tcpDnsServer != null ) - { - dsc.tcpDnsServer.destroy(); - if ( log.isInfoEnabled() ) - { - log.info( "Unbind of DNS Service (TCP) complete: " + dsc.tcpDnsServer ); - } - dsc.tcpDnsServer = null; - } - - if ( dsc.udpDnsServer != null ) - { - dsc.udpDnsServer.destroy(); - if ( log.isInfoEnabled() ) - { - log.info( "Unbind of DNS Service (UDP) complete: " + dsc.udpDnsServer ); - } - dsc.udpDnsServer = null; - } - - dsc.logicExecutor.shutdown(); - for (;;) { - try { - if (dsc.logicExecutor.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS)) { - break; - } - } catch (InterruptedException e) { - } - } - dsc.ioExecutor.shutdown(); - for (;;) { - try { - if (dsc.ioExecutor.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS)) { - break; - } - } catch (InterruptedException e) { - } - } - } - - - public void afterStartup( DirectoryService service ) throws NamingException - { - DirectoryServiceContext dsc = contexts.get(service); - ServerStartupConfiguration cfg = ( ServerStartupConfiguration ) service.getConfiguration() - .getStartupConfiguration(); - Hashtable env = service.getConfiguration().getEnvironment(); - LdapConfiguration ldapCfg = cfg.getLdapConfiguration(); - LdapConfiguration ldapsCfg = cfg.getLdapsConfiguration(); - - if ( !cfg.isAllowAnonymousAccess() ) - { - ldapCfg.setAllowAnonymousAccess( false ); - ldapsCfg.setAllowAnonymousAccess( false ); - } - - loadLdifs( service ); - - if ( cfg.isEnableNetworking() ) - { - startLDAP( dsc, ldapCfg, env ); - startLDAPS( dsc, ldapsCfg, env ); - startKerberos( dsc, cfg.getKdcConfiguration() ); - startChangePassword( dsc, cfg.getChangePasswordConfiguration() ); - startNTP( dsc, cfg.getNtpConfiguration() ); - startDNS( dsc, cfg.getDnsConfiguration() ); - } - } - - - private void ensureLdifFileBase( DirContext root ) - { - Attributes entry = new AttributesImpl( SchemaConstants.OU_AT, "loadedLdifFiles", true ); - entry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC ); - entry.get( SchemaConstants.OBJECT_CLASS_AT ).add( SchemaConstants.ORGANIZATIONAL_UNIT_OC ); - - try - { - root.createSubcontext( LDIF_FILES_DN, entry ); - log.info( "Creating " + LDIF_FILES_DN ); - } - catch ( NamingException e ) - { - log.info( LDIF_FILES_DN + " exists" ); - } - } - - private final static String WINDOWSFILE_ATTR = "windowsFilePath"; - private final static String UNIXFILE_ATTR = "unixFilePath"; - - private String buildProtectedFileEntry( File ldif ) - { - StringBuffer buf = new StringBuffer(); - - buf.append( File.separatorChar == '\\' ? WINDOWSFILE_ATTR : UNIXFILE_ATTR ); - buf.append( "=" ); - - buf.append( StringTools.dumpHexPairs( StringTools.getBytesUtf8( getCanonical( ldif ) ) ) ); - - buf.append( "," ); - buf.append( LDIF_FILES_DN ); - - return buf.toString(); - } - - private void addFileEntry( DirContext root, File ldif ) throws NamingException - { - String rdnAttr = File.separatorChar == '\\' ? WINDOWSFILE_ATTR : UNIXFILE_ATTR; - String oc = File.separatorChar == '\\' ? ApacheSchemaConstants.WINDOWS_FILE_OC : ApacheSchemaConstants.UNIX_FILE_OC; - - Attributes entry = new AttributesImpl( rdnAttr, getCanonical( ldif ), true ); - entry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC ); - entry.get( SchemaConstants.OBJECT_CLASS_AT ).add( oc ); - root.createSubcontext( buildProtectedFileEntry( ldif ), entry ); - } - - - private Attributes getLdifFileEntry( DirContext root, File ldif ) - { - try - { - return root.getAttributes( buildProtectedFileEntry( ldif ), new String[] - { SchemaConstants.CREATE_TIMESTAMP_AT } ); - } - catch ( NamingException e ) - { - return null; - } - } - - - private String getCanonical( File file ) - { - String canonical = null; - - try - { - canonical = file.getCanonicalPath(); - } - catch ( IOException e ) - { - log.error( "could not get canonical path", e ); - return null; - } - - return StringUtils.replace( canonical, "\\", "\\\\" ); - } - - - private void loadLdifs( DirectoryService service ) throws NamingException - { - ServerStartupConfiguration cfg = ( ServerStartupConfiguration ) service.getConfiguration() - .getStartupConfiguration(); - - // log and bail if property not set - if ( cfg.getLdifDirectory() == null ) - { - log.info( "LDIF load directory not specified. No LDIF files will be loaded." ); - return; - } - - // log and bail if LDIF directory does not exists - if ( !cfg.getLdifDirectory().exists() ) - { - log.warn( "LDIF load directory '" + getCanonical( cfg.getLdifDirectory() ) - + "' does not exist. No LDIF files will be loaded." ); - return; - } - - // get an initial context to the rootDSE for creating the LDIF entries - @SuppressWarnings(value={"unchecked"}) - Hashtable env = ( Hashtable ) service.getConfiguration().getEnvironment().clone(); - env.put( Context.PROVIDER_URL, "" ); - DirContext root = ( DirContext ) this.getInitialContext( env ); - - // make sure the configuration area for loaded ldif files is present - ensureLdifFileBase( root ); - - // if ldif directory is a file try to load it - if ( !cfg.getLdifDirectory().isDirectory() ) - { - if ( log.isInfoEnabled() ) - { - log.info( "LDIF load directory '" + getCanonical( cfg.getLdifDirectory() ) - + "' is a file. Will attempt to load as LDIF." ); - } - - Attributes fileEntry = getLdifFileEntry( root, cfg.getLdifDirectory() ); - - if ( fileEntry != null ) - { - String time = ( String ) fileEntry.get( SchemaConstants.CREATE_TIMESTAMP_AT ).get(); - - if ( log.isInfoEnabled() ) - { - log.info( "Load of LDIF file '" + getCanonical( cfg.getLdifDirectory() ) - + "' skipped. It has already been loaded on " + time + "." ); - } - - return; - } - - LdifFileLoader loader = new LdifFileLoader( root, cfg.getLdifDirectory(), cfg.getLdifFilters() ); - loader.execute(); - - addFileEntry( root, cfg.getLdifDirectory() ); - return; - } - - // get all the ldif files within the directory (should be sorted alphabetically) - File[] ldifFiles = cfg.getLdifDirectory().listFiles( new FileFilter() - { - public boolean accept( File pathname ) - { - boolean isLdif = pathname.getName().toLowerCase().endsWith( ".ldif" ); - return pathname.isFile() && pathname.canRead() && isLdif; - } - } ); - - // log and bail if we could not find any LDIF files - if ( ldifFiles == null || ldifFiles.length == 0 ) - { - log.warn( "LDIF load directory '" + getCanonical( cfg.getLdifDirectory() ) - + "' does not contain any LDIF files. No LDIF files will be loaded." ); - return; - } - - // load all the ldif files and load each one that is loaded - for ( int ii = 0; ii < ldifFiles.length; ii++ ) - { - Attributes fileEntry = getLdifFileEntry( root, ldifFiles[ii] ); - - if ( fileEntry != null ) - { - String time = ( String ) fileEntry.get( SchemaConstants.CREATE_TIMESTAMP_AT ).get(); - log.info( "Load of LDIF file '" + getCanonical( ldifFiles[ii] ) - + "' skipped. It has already been loaded on " + time + "." ); - continue; - } - - LdifFileLoader loader = new LdifFileLoader( root, ldifFiles[ii], cfg.getLdifFilters() ); - int count = loader.execute(); - log.info( "Loaded " + count + " entries from LDIF file '" + getCanonical( ldifFiles[ii] ) + "'" ); - - if ( fileEntry == null ) - { - addFileEntry( root, ldifFiles[ii] ); - } - } - } - - - /** - * Starts up the LDAP protocol provider to service LDAP requests - * - * @throws NamingException if there are problems starting the LDAP provider - */ - private void startLDAP( DirectoryServiceContext dsc, LdapConfiguration ldapConfig, Hashtable env ) throws NamingException - { - // Skip if disabled - if ( !ldapConfig.isEnabled() ) - { - return; - } - - DefaultIoFilterChainBuilder chain = new DefaultIoFilterChainBuilder(); - - startLDAP0( dsc, ldapConfig, env, ldapConfig.getIpPort(), chain ); - } - - - /** - * Starts up the LDAPS protocol provider to service LDAPS requests - * - * @throws NamingException if there are problems starting the LDAPS provider - */ - private void startLDAPS( DirectoryServiceContext dsc, LdapConfiguration ldapsConfig, Hashtable env ) throws NamingException - { - // Skip if disabled - if ( !( ldapsConfig.isEnabled() && ldapsConfig.isEnableLdaps() ) ) - { - return; - } - - char[] certPasswordChars = ldapsConfig.getLdapsCertificatePassword().toCharArray(); - String storePath = ldapsConfig.getLdapsCertificateFile().getPath(); - - IoFilterChainBuilder chain = LdapsInitializer.init( certPasswordChars, storePath ); - dsc.ldapsStarted = true; - - startLDAP0( dsc, ldapsConfig, env, ldapsConfig.getIpPort(), chain ); - } - - - private void startLDAP0( DirectoryServiceContext dsc, LdapConfiguration ldapConfig, Hashtable env, int port, IoFilterChainBuilder chainBuilder ) - throws LdapNamingException, LdapConfigurationException + public final synchronized Context getInitialContext( Hashtable env ) throws NamingException { - // Register all extended operation handlers. - LdapProtocolProvider protocolProvider = new LdapProtocolProvider( ldapConfig, ( Hashtable ) env.clone() ); - - for ( Iterator i = ldapConfig.getExtendedOperationHandlers().iterator(); i.hasNext(); ) - { - ExtendedOperationHandler h = ( ExtendedOperationHandler ) i.next(); - protocolProvider.addExtendedOperationHandler( h ); - log.info( "Added Extended Request Handler: " + h.getOid() ); - h.setLdapProvider( protocolProvider ); - PartitionNexus nexus = directoryService.getConfiguration().getPartitionNexus(); - nexus.registerSupportedExtensions( h.getExtensionOids() ); - } + Hashtable cloned = new Hashtable(); + //noinspection unchecked + cloned.putAll( env ); + ApacheDS apacheDS = ( ApacheDS ) cloned.get( ApacheDS.JNDI_KEY ); - try - { - SocketAcceptorConfig acceptorCfg = new SocketAcceptorConfig(); - - // Disable the disconnection of the clients on unbind - acceptorCfg.setDisconnectOnUnbind( false ); - acceptorCfg.setReuseAddress( true ); - acceptorCfg.setFilterChainBuilder( chainBuilder ); - acceptorCfg.setThreadModel( ThreadModel.MANUAL ); - - acceptorCfg.getSessionConfig().setTcpNoDelay( true ); - - dsc.tcpAcceptor.bind( new InetSocketAddress( port ), protocolProvider.getHandler(), acceptorCfg ); - dsc.ldapStarted = true; - - if ( log.isInfoEnabled() ) - { - log.info( "Successful bind of an LDAP Service (" + port + ") is complete." ); - } - } - catch ( IOException e ) + if ( apacheDS == null ) { - String msg = "Failed to bind an LDAP service (" + port + ") to the service registry."; - LdapConfigurationException lce = new LdapConfigurationException( msg ); - lce.setRootCause( e ); - log.error( msg, e ); - throw lce; + throw new ConfigurationException( "Could not find ApacheDS in environment: " + env ); } - } - - private void startKerberos( DirectoryServiceContext dsc, KdcConfiguration kdcConfig ) - { - // Skip if disabled - if ( !kdcConfig.isEnabled() ) - { - return; - } - - try - { - PrincipalStore kdcStore = new JndiPrincipalStoreImpl( kdcConfig, this ); - - DatagramAcceptorConfig udpConfig = new DatagramAcceptorConfig(); - udpConfig.setThreadModel( ThreadModel.MANUAL ); - - SocketAcceptorConfig tcpConfig = new SocketAcceptorConfig(); - tcpConfig.setDisconnectOnUnbind( false ); - tcpConfig.setReuseAddress( true ); - tcpConfig.setThreadModel( ThreadModel.MANUAL ); - - dsc.tcpKdcServer = new KerberosServer( kdcConfig, dsc.tcpAcceptor, tcpConfig, kdcStore ); - dsc.udpKdcServer = new KerberosServer( kdcConfig, dsc.udpAcceptor, udpConfig, kdcStore ); - } - catch ( Throwable t ) - { - log.error( "Failed to start the Kerberos service", t ); - } - } - - - private void startChangePassword( DirectoryServiceContext dsc, ChangePasswordConfiguration changePasswordConfig ) - { - // Skip if disabled - if ( !changePasswordConfig.isEnabled() ) - { - return; - } - - try - { - PrincipalStore store = new JndiPrincipalStoreImpl( changePasswordConfig, this ); - - DatagramAcceptorConfig udpConfig = new DatagramAcceptorConfig(); - udpConfig.setThreadModel( ThreadModel.MANUAL ); - - SocketAcceptorConfig tcpConfig = new SocketAcceptorConfig(); - tcpConfig.setDisconnectOnUnbind( false ); - tcpConfig.setReuseAddress( true ); - tcpConfig.setThreadModel( ThreadModel.MANUAL ); - - dsc.tcpChangePasswordServer = new ChangePasswordServer( changePasswordConfig, dsc.tcpAcceptor, tcpConfig, store ); - dsc.udpChangePasswordServer = new ChangePasswordServer( changePasswordConfig, dsc.udpAcceptor, udpConfig, store ); - } - catch ( Throwable t ) - { - log.error( "Failed to start the Change Password service", t ); - } - } - - - private void startNTP( DirectoryServiceContext dsc, NtpConfiguration ntpConfig ) - { - // Skip if disabled - if ( !ntpConfig.isEnabled() ) - { - return; - } - - try - { - DatagramAcceptorConfig udpConfig = new DatagramAcceptorConfig(); - udpConfig.setThreadModel( ThreadModel.MANUAL ); - - SocketAcceptorConfig tcpConfig = new SocketAcceptorConfig(); - tcpConfig.setDisconnectOnUnbind( false ); - tcpConfig.setReuseAddress( true ); - tcpConfig.setThreadModel( ThreadModel.MANUAL ); - - dsc.tcpNtpServer = new NtpServer( ntpConfig, dsc.tcpAcceptor, tcpConfig ); - dsc.udpNtpServer = new NtpServer( ntpConfig, dsc.udpAcceptor, udpConfig ); - } - catch ( Throwable t ) - { - log.error( "Failed to start the NTP service", t ); - } - } - - - private void startDNS( DirectoryServiceContext dsc, DnsConfiguration dnsConfig ) - { - // Skip if disabled - if ( !dnsConfig.isEnabled() ) - { - return; - } - - try - { - RecordStore store = new JndiRecordStoreImpl( dnsConfig, this ); - - DatagramAcceptorConfig udpConfig = new DatagramAcceptorConfig(); - udpConfig.setThreadModel( ThreadModel.MANUAL ); - - SocketAcceptorConfig tcpConfig = new SocketAcceptorConfig(); - tcpConfig.setDisconnectOnUnbind( false ); - tcpConfig.setReuseAddress( true ); - tcpConfig.setThreadModel( ThreadModel.MANUAL ); - - dsc.tcpDnsServer = new DnsServer( dnsConfig, dsc.tcpAcceptor, tcpConfig, store ); - dsc.udpDnsServer = new DnsServer( dnsConfig, dsc.udpAcceptor, udpConfig, store ); - } - catch ( Throwable t ) - { - log.error( "Failed to start the DNS service", t ); - } - } - - - private void stopLDAP0( DirectoryServiceContext dsc, int port ) - { - try - { - // we should unbind the service before we begin sending the notice - // of disconnect so new connections are not formed while we process - List writeFutures = new ArrayList(); - - // If the socket has already been unbound as with a successful - // GracefulShutdownRequest then this will complain that the service - // is not bound - this is ok because the GracefulShutdown has already - // sent notices to to the existing active sessions - List sessions = null; - - try - { - sessions = new ArrayList( dsc.tcpAcceptor.getManagedSessions( new InetSocketAddress( port ) ) ); - } - catch ( IllegalArgumentException e ) - { - log.warn( "Seems like the LDAP service (" + port + ") has already been unbound." ); - return; - } - - dsc.tcpAcceptor.unbind( new InetSocketAddress( port ) ); - - if ( log.isInfoEnabled() ) - { - log.info( "Unbind of an LDAP service (" + port + ") is complete." ); - log.info( "Sending notice of disconnect to existing clients sessions." ); - } - - // Send Notification of Disconnection messages to all connected clients. - if ( sessions != null ) - { - for ( IoSession session:sessions ) - { - writeFutures.add( session.write( NoticeOfDisconnect.UNAVAILABLE ) ); - } - } - - // And close the connections when the NoDs are sent. - Iterator sessionIt = sessions.iterator(); - - for ( WriteFuture future:writeFutures ) - { - future.join( 1000 ); - sessionIt.next().close(); - } - } - catch ( Exception e ) - { - log.warn( "Failed to sent NoD.", e ); - } + cloned.put( DirectoryService.JNDI_KEY, apacheDS.getDirectoryService() ); + return super.getInitialContext( cloned ); } }