directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From akaras...@apache.org
Subject svn commit: r373408 - in /directory/trunks: apacheds/core/src/main/java/org/apache/ldap/server/configuration/ apacheds/protocols/ldap/src/main/java/org/apache/ldap/server/protocol/ apacheds/protocols/ldap/src/main/java/org/apache/ldap/server/protocol/g...
Date Mon, 30 Jan 2006 00:57:40 GMT
Author: akarasulu
Date: Sun Jan 29 16:57:25 2006
New Revision: 373408

URL: http://svn.apache.org/viewcvs?rev=373408&view=rev
Log:
changes ...

 o added untested rudimentary implememtation of the GracefulShutdown extended
   request handler 
 o removed extended request handler setup for diagnostic ui extended request 
   out of the protocol provider itself because it can be setup using the
   configuration
 o added extended request handler configuration entries to two server.xml files
 o injected special handling code for the GracefulShutdown handler which 
   might require changes to the ExtendedRequestHandler interface to keep things
   generic
 o made 3 options of NoD into static constants
 o added new exitVmOnShutdown configuration parameter which can be used to
   determine if we should exit the jvm when a gracefulShutdown is delivered
   

Added:
    directory/trunks/apacheds/protocols/ldap/src/main/java/org/apache/ldap/server/protocol/support/extended/GracefulShutdownHandler.java
Modified:
    directory/trunks/apacheds/core/src/main/java/org/apache/ldap/server/configuration/MutableStartupConfiguration.java
    directory/trunks/apacheds/core/src/main/java/org/apache/ldap/server/configuration/StartupConfiguration.java
    directory/trunks/apacheds/protocols/ldap/src/main/java/org/apache/ldap/server/protocol/LdapProtocolProvider.java
    directory/trunks/apacheds/protocols/ldap/src/main/java/org/apache/ldap/server/protocol/gui/SessionsFrame.java
    directory/trunks/apacheds/standalone/installers/test/src/main/installers/server.xml
    directory/trunks/apacheds/standalone/simple/jndi/src/main/java/org/apache/ldap/server/configuration/MutableServerStartupConfiguration.java
    directory/trunks/apacheds/standalone/simple/jndi/src/main/java/org/apache/ldap/server/jndi/ServerContextFactory.java
    directory/trunks/apacheds/standalone/simple/main/server.xml
    directory/trunks/apacheds/standalone/simple/unit/src/test/java/org/apache/ldap/server/ModifyRdnTest.java
    directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/message/extended/GracefulShutdownRequest.java
    directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/message/extended/NoticeOfDisconnect.java

Modified: directory/trunks/apacheds/core/src/main/java/org/apache/ldap/server/configuration/MutableStartupConfiguration.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/core/src/main/java/org/apache/ldap/server/configuration/MutableStartupConfiguration.java?rev=373408&r1=373407&r2=373408&view=diff
==============================================================================
--- directory/trunks/apacheds/core/src/main/java/org/apache/ldap/server/configuration/MutableStartupConfiguration.java
(original)
+++ directory/trunks/apacheds/core/src/main/java/org/apache/ldap/server/configuration/MutableStartupConfiguration.java
Sun Jan 29 16:57:25 2006
@@ -113,4 +113,10 @@
     {
         super.setShutdownHookEnabled( shutdownHookEnabled );
     }
+
+
+    public void setExitVmOnShutdown( boolean exitVmOnShutdown )
+    {
+        super.setExitVmOnShutdown( exitVmOnShutdown );
+    }
 }

Modified: directory/trunks/apacheds/core/src/main/java/org/apache/ldap/server/configuration/StartupConfiguration.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/core/src/main/java/org/apache/ldap/server/configuration/StartupConfiguration.java?rev=373408&r1=373407&r2=373408&view=diff
==============================================================================
--- directory/trunks/apacheds/core/src/main/java/org/apache/ldap/server/configuration/StartupConfiguration.java
(original)
+++ directory/trunks/apacheds/core/src/main/java/org/apache/ldap/server/configuration/StartupConfiguration.java
Sun Jan 29 16:57:25 2006
@@ -54,6 +54,7 @@
     private static final long serialVersionUID = 4826762196566871677L;
 
     private File workingDirectory = new File( "server-work" );
+    private boolean exitVmOnShutdown = true; // allow by default
     private boolean shutdownHookEnabled = true; // allow by default
     private boolean allowAnonymousAccess = true; // allow by default
     private boolean accessControlEnabled = false; // turn off by default
@@ -404,5 +405,17 @@
     public boolean isShutdownHookEnabled()
     {
         return shutdownHookEnabled;
+    }
+
+
+    protected void setExitVmOnShutdown( boolean exitVmOnShutdown )
+    {
+        this.exitVmOnShutdown = exitVmOnShutdown;
+    }
+    
+    
+    public boolean isExitVmOnShutdown()
+    {
+        return exitVmOnShutdown;
     }
 }

Modified: directory/trunks/apacheds/protocols/ldap/src/main/java/org/apache/ldap/server/protocol/LdapProtocolProvider.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/protocols/ldap/src/main/java/org/apache/ldap/server/protocol/LdapProtocolProvider.java?rev=373408&r1=373407&r2=373408&view=diff
==============================================================================
--- directory/trunks/apacheds/protocols/ldap/src/main/java/org/apache/ldap/server/protocol/LdapProtocolProvider.java
(original)
+++ directory/trunks/apacheds/protocols/ldap/src/main/java/org/apache/ldap/server/protocol/LdapProtocolProvider.java
Sun Jan 29 16:57:25 2006
@@ -72,7 +72,6 @@
 import org.apache.ldap.server.protocol.support.ModifyHandler;
 import org.apache.ldap.server.protocol.support.SearchHandler;
 import org.apache.ldap.server.protocol.support.UnbindHandler;
-import org.apache.ldap.server.protocol.support.extended.LaunchDiagnosticUiHandler;
 import org.apache.mina.common.IoFilterChain;
 import org.apache.mina.common.IoHandler;
 import org.apache.mina.common.IoSession;
@@ -86,6 +85,7 @@
 import org.apache.mina.handler.demux.MessageHandler;
 import org.apache.mina.util.SessionLog;
 
+
 /**
  * An LDAP protocol provider implementation which dynamically associates
  * handlers.
@@ -224,7 +224,6 @@
         }
 
         this.codecFactory = new ProtocolCodecFactoryImpl( copy );
-        addExtendedOperationHandler( new LaunchDiagnosticUiHandler() );
     }
 
     /**
@@ -437,7 +436,7 @@
         {
             SessionLog.warn( session, 
                 "Unexpected exception forcing session to close: sending disconnect notice
to client.", cause );
-            session.write( new NoticeOfDisconnect( ResultCodeEnum.PROTOCOLERROR ) );
+            session.write( NoticeOfDisconnect.PROTOCOLERROR );
             SessionRegistry.getSingleton().remove( session );
             session.close();
         }

Modified: directory/trunks/apacheds/protocols/ldap/src/main/java/org/apache/ldap/server/protocol/gui/SessionsFrame.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/protocols/ldap/src/main/java/org/apache/ldap/server/protocol/gui/SessionsFrame.java?rev=373408&r1=373407&r2=373408&view=diff
==============================================================================
--- directory/trunks/apacheds/protocols/ldap/src/main/java/org/apache/ldap/server/protocol/gui/SessionsFrame.java
(original)
+++ directory/trunks/apacheds/protocols/ldap/src/main/java/org/apache/ldap/server/protocol/gui/SessionsFrame.java
Sun Jan 29 16:57:25 2006
@@ -18,10 +18,10 @@
 import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
 
-import org.apache.ldap.common.message.ResultCodeEnum;
 import org.apache.ldap.common.message.extended.NoticeOfDisconnect;
 import org.apache.ldap.server.protocol.SessionRegistry;
 import org.apache.mina.common.IoSession;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -405,7 +405,7 @@
             {
                 public void actionPerformed(java.awt.event.ActionEvent e)
                 {
-                    selected.write( new NoticeOfDisconnect( ResultCodeEnum.UNAVAILABLE )
); 
+                    selected.write( NoticeOfDisconnect.UNAVAILABLE ); 
                     try
                     {
                         Thread.sleep( 250 );
@@ -437,7 +437,7 @@
             {
                 public void actionPerformed(java.awt.event.ActionEvent e)
                 {
-                    selected.write( new NoticeOfDisconnect( ResultCodeEnum.PROTOCOLERROR
) ); 
+                    selected.write( NoticeOfDisconnect.PROTOCOLERROR ); 
                     try
                     {
                         Thread.sleep( 250 );
@@ -469,7 +469,7 @@
             {
                 public void actionPerformed(java.awt.event.ActionEvent e)
                 {
-                    selected.write( new NoticeOfDisconnect( ResultCodeEnum.STRONGAUTHREQUIRED
) ); 
+                    selected.write( NoticeOfDisconnect.STRONGAUTHREQUIRED ); 
                     try
                     {
                         Thread.sleep( 250 );

Added: directory/trunks/apacheds/protocols/ldap/src/main/java/org/apache/ldap/server/protocol/support/extended/GracefulShutdownHandler.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/protocols/ldap/src/main/java/org/apache/ldap/server/protocol/support/extended/GracefulShutdownHandler.java?rev=373408&view=auto
==============================================================================
--- directory/trunks/apacheds/protocols/ldap/src/main/java/org/apache/ldap/server/protocol/support/extended/GracefulShutdownHandler.java
(added)
+++ directory/trunks/apacheds/protocols/ldap/src/main/java/org/apache/ldap/server/protocol/support/extended/GracefulShutdownHandler.java
Sun Jan 29 16:57:25 2006
@@ -0,0 +1,318 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.ldap.server.protocol.support.extended;
+
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.naming.NamingException;
+import javax.naming.ldap.LdapContext;
+
+import org.apache.ldap.common.message.ExtendedRequest;
+import org.apache.ldap.common.message.ResultCodeEnum;
+import org.apache.ldap.common.message.extended.GracefulDisconnect;
+import org.apache.ldap.common.message.extended.GracefulShutdownRequest;
+import org.apache.ldap.common.message.extended.GracefulShutdownResponse;
+import org.apache.ldap.common.message.extended.NoticeOfDisconnect;
+
+import org.apache.ldap.server.DirectoryService;
+import org.apache.ldap.server.configuration.StartupConfiguration;
+import org.apache.ldap.server.jndi.ServerLdapContext;
+import org.apache.ldap.server.partition.DirectoryPartitionNexus;
+import org.apache.ldap.server.protocol.ExtendedOperationHandler;
+import org.apache.ldap.server.protocol.SessionRegistry;
+
+import org.apache.mina.common.IoAcceptor;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.common.WriteFuture;
+import org.apache.mina.registry.Service;
+import org.apache.mina.registry.ServiceRegistry;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class GracefulShutdownHandler implements ExtendedOperationHandler
+{
+    private static final Logger log = LoggerFactory.getLogger( GracefulShutdownHandler.class
);
+    
+    private ServiceRegistry serviceRegistry;
+    private Service ldapService;
+    
+    
+    public void setLdapService( Service ldapService )
+    {
+        this.ldapService = ldapService;
+    }
+
+
+    public void setServiceRegistry( ServiceRegistry registry )
+    {
+        this.serviceRegistry = registry;
+    }
+
+
+    public String getOid()
+    {
+        return GracefulShutdownRequest.EXTENSION_OID;
+    }
+
+    
+    public void handleExtendedOperation( IoSession requestor, SessionRegistry registry, ExtendedRequest
req ) 
+        throws NamingException 
+    {
+        DirectoryService service = null;
+        ServerLdapContext slc = null;
+        LdapContext ctx = registry.getLdapContext( requestor, null, false );
+        ctx = ( LdapContext ) ctx.lookup( "" );
+
+        // setup some of the variables we need and make sure they are of the 
+        // right types otherwise send back an operations error in response
+        if ( ctx instanceof ServerLdapContext )
+        {
+            slc = ( ServerLdapContext ) ctx;
+            service = slc.getService();
+        }
+        else
+        {
+            log.error( "Encountered session context which was not a ServerLdapContext" );
+            GracefulShutdownResponse msg = new GracefulShutdownResponse( req.getMessageId(),

+                ResultCodeEnum.OPERATIONSERROR );
+            msg.getLdapResult().setErrorMessage( "The session context was not a ServerLdapContext"
);
+            requestor.write( msg );
+            return;
+        }
+
+        // make sue only the administrator can issue this shutdown request if 
+        // not we respond to the requestor with with insufficientAccessRights(50)
+        if ( ! slc.getPrincipal().getName().equalsIgnoreCase( DirectoryPartitionNexus.ADMIN_PRINCIPAL
) )
+        {
+            if ( log.isInfoEnabled() )
+            {
+                log.info( "Rejected with insufficientAccessRights to attempt for server shutdown
by " 
+                    + slc.getPrincipal().getName() );
+            }
+            
+            requestor.write( new GracefulShutdownResponse( req.getMessageId(), 
+                ResultCodeEnum.INSUFFICIENTACCESSRIGHTS ) );
+            return;
+        }
+        
+        // -------------------------------------------------------------------
+        // handle the body of this operation below here
+        // -------------------------------------------------------------------
+        
+        StartupConfiguration cfg = service.getConfiguration().getStartupConfiguration();
+        GracefulShutdownRequest gsreq = ( GracefulShutdownRequest ) req;
+
+        // build the graceful disconnect message with replicationContexts
+        GracefulDisconnect notice = new GracefulDisconnect( gsreq.getTimeOffline(), gsreq.getDelay()
);
+        // @todo add the referral objects for replication contexts using setup code below
+//        DirectoryPartitionNexus nexus = service.getConfiguration().getPartitionNexus();
+//        Iterator list = nexus.listSuffixes( true );
+//        while ( list.hasNext() )
+//        {
+//            LdapName dn = new LdapName( ( String ) list.next() );
+//            DirectoryPartition partition = nexus.getPartition( dn );
+//        }
+
+        // send (synch) the GracefulDisconnect to each client before unbinding
+        sendGracefulDisconnect( notice, requestor );
+
+        // wait for the specified delay before we unbind the service 
+        if ( gsreq.getDelay() > 0 )
+        {
+            // delay is in seconds
+            long delay = gsreq.getDelay() * 1000;
+            long startTime = System.currentTimeMillis();
+            
+            while ( ( System.currentTimeMillis() - startTime ) < delay )
+            {
+                try
+                {
+                    Thread.sleep( 250 );
+                }
+                catch ( InterruptedException e )
+                {
+                    log.warn( "Got interrupted while waiting for delay before shutdown",
e );
+                }
+            }
+        }
+        
+        // unbind the server socket for the LDAP service here so no new 
+        // connections are accepted while we process this shutdown request
+        // note that the following must be issued before binding the ldap
+        // service in order to prevent client disconnects on service unbind:
+        // 
+        // minaRegistry.getAcceptor( service.getTransportType() ).setDisconnectClientsOnUnbind(
false );
+        //
+        serviceRegistry.unbind( ldapService );
+        
+        // -------------------------------------------------------------------
+        // synchronously send a NoD to clients that are not aware of this resp
+        // after sending the NoD the client is disconnected if still connected
+        // -------------------------------------------------------------------
+
+        sendNoticeOfDisconnect( requestor );
+
+        // -------------------------------------------------------------------
+        // respond back to the client that requested the graceful shutdown w/
+        // a success resultCode which confirms all clients have been notified
+        // via the graceful disconnect or NoD and the service has been unbound
+        // preventing new connections; after recieving this response the 
+        // requestor should disconnect and stop using the connection
+        // -------------------------------------------------------------------
+
+        GracefulShutdownResponse msg = new GracefulShutdownResponse( req.getMessageId(),
ResultCodeEnum.SUCCESS );
+        WriteFuture future = requestor.write( msg );
+        future.join();
+        if ( future.isWritten() )
+        {
+            if ( log.isInfoEnabled() )
+            {
+                log.info( "Sent GracefulShutdownResponse to client: " + requestor.getRemoteAddress()
);
+            }
+        }
+        else
+        {
+            log.error( "Failed to write GracefulShutdownResponse to client: " + requestor.getRemoteAddress()
);
+        }
+        requestor.close();
+
+        if ( cfg.isExitVmOnShutdown() )
+        {
+            System.exit( 0 );
+        }
+        
+        return;
+    }
+    
+    
+    /**
+     * Blocks to synchronously send the same GracefulDisconnect message to all 
+     * managed sessions except for the requestor of the GracefulShutdown.
+     * 
+     * @param msg the graceful disconnec extended request to send
+     * @param requestor the session of the graceful shutdown requestor
+     */
+    private void sendGracefulDisconnect( GracefulDisconnect msg, IoSession requestor )
+    {
+        IoAcceptor acceptor = serviceRegistry.getAcceptor( ldapService.getTransportType()
);
+        List sessions = new ArrayList( acceptor.getManagedSessions( ldapService.getAddress()
) );
+        List writeFutures = new ArrayList();
+        
+        // asynchronously send GracefulDisconnection messages to all connected
+        // clients giving time for the message to arrive before we block 
+        // waiting for message delivery to the client in the loop below
+        
+        if( sessions != null )
+        {
+            for( Iterator i = sessions.iterator(); i.hasNext(); )
+            {
+                IoSession session = session = ( IoSession ) i.next();
+                
+                // make sure we do not send the disconnect mesasge to the 
+                // client which sent the initiating GracefulShutdown request
+                if ( session.equals( requestor ) )
+                {
+                    continue;
+                }
+                
+                try
+                {
+                    writeFutures.add( session.write( msg ) );
+                }
+                catch( Exception 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(); )
+        {
+            WriteFuture future = ( WriteFuture ) i.next();
+            try
+            {
+                future.join( 1000 );
+            }
+            catch( Exception e )
+            {
+                log.warn( "Failed to sent GracefulDisconnect", e );
+            }
+        }
+    }
+
+
+    /**
+     * Blocks to synchronously send the a NoticeOfDisconnect message with
+     * the resultCode set to unavailable(52) to all managed sessions except 
+     * for the requestor of the GracefulShutdown.
+     * 
+     * @param requestor the session of the graceful shutdown requestor
+     */
+    private void sendNoticeOfDisconnect( IoSession requestor )
+    {
+        IoAcceptor acceptor = serviceRegistry.getAcceptor( ldapService.getTransportType()
);
+        List sessions = new ArrayList( acceptor.getManagedSessions( ldapService.getAddress()
) );
+        List writeFutures = new ArrayList();
+        
+        // Send Notification of Disconnection messages to all connected clients.
+        if( sessions != null )
+        {
+            for( Iterator i = sessions.iterator(); i.hasNext(); )
+            {
+                IoSession session = session = ( IoSession ) i.next();
+                
+                // make sure we do not send the disconnect mesasge to the 
+                // client which sent the initiating GracefulShutdown request
+                if ( session.equals( requestor ) )
+                {
+                    continue;
+                }
+
+                try
+                {
+                    writeFutures.add( session.write( NoticeOfDisconnect.UNAVAILABLE ) );
+                }
+                catch( Exception 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(); )
+        {
+            WriteFuture future = ( WriteFuture ) i.next();
+            try
+            {
+                future.join( 1000 );
+                ( ( IoSession ) sessionIt.next() ).close();
+            }
+            catch( Exception e )
+            {
+                log.warn( "Failed to sent NoD.", e );
+            }
+        }
+    }
+}

Modified: directory/trunks/apacheds/standalone/installers/test/src/main/installers/server.xml
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/standalone/installers/test/src/main/installers/server.xml?rev=373408&r1=373407&r2=373408&view=diff
==============================================================================
--- directory/trunks/apacheds/standalone/installers/test/src/main/installers/server.xml (original)
+++ directory/trunks/apacheds/standalone/installers/test/src/main/installers/server.xml Sun
Jan 29 16:57:25 2006
@@ -81,6 +81,13 @@
       </set>
     </property>
     
+    <property name="extendedOperationHandlers">
+      <list>
+        <bean class="org.apache.ldap.server.protocol.support.extended.GracefulShutdownHandler"/>
+        <bean class="org.apache.ldap.server.protocol.support.extended.LaunchDiagnosticUiHandler"/>
+      </list>
+    </property>
+    
     <property name="interceptorConfigurations">
       <list>
         <bean class="org.apache.ldap.server.configuration.MutableInterceptorConfiguration">

Modified: directory/trunks/apacheds/standalone/simple/jndi/src/main/java/org/apache/ldap/server/configuration/MutableServerStartupConfiguration.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/standalone/simple/jndi/src/main/java/org/apache/ldap/server/configuration/MutableServerStartupConfiguration.java?rev=373408&r1=373407&r2=373408&view=diff
==============================================================================
--- directory/trunks/apacheds/standalone/simple/jndi/src/main/java/org/apache/ldap/server/configuration/MutableServerStartupConfiguration.java
(original)
+++ directory/trunks/apacheds/standalone/simple/jndi/src/main/java/org/apache/ldap/server/configuration/MutableServerStartupConfiguration.java
Sun Jan 29 16:57:25 2006
@@ -145,4 +145,9 @@
     {
         super.setShutdownHookEnabled( shutdownHookEnabled );
     }
+
+    public void setExitVmOnShutdown( boolean exitVmOnShutdown )
+    {
+        super.setExitVmOnShutdown( exitVmOnShutdown );
+    }
 }

Modified: directory/trunks/apacheds/standalone/simple/jndi/src/main/java/org/apache/ldap/server/jndi/ServerContextFactory.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/standalone/simple/jndi/src/main/java/org/apache/ldap/server/jndi/ServerContextFactory.java?rev=373408&r1=373407&r2=373408&view=diff
==============================================================================
--- directory/trunks/apacheds/standalone/simple/jndi/src/main/java/org/apache/ldap/server/jndi/ServerContextFactory.java
(original)
+++ directory/trunks/apacheds/standalone/simple/jndi/src/main/java/org/apache/ldap/server/jndi/ServerContextFactory.java
Sun Jan 29 16:57:25 2006
@@ -42,12 +42,12 @@
 import org.apache.kerberos.store.PrincipalStore;
 import org.apache.ldap.common.exception.LdapConfigurationException;
 import org.apache.ldap.common.exception.LdapNamingException;
-import org.apache.ldap.common.message.ResultCodeEnum;
 import org.apache.ldap.common.message.extended.NoticeOfDisconnect;
 import org.apache.ldap.server.DirectoryService;
 import org.apache.ldap.server.configuration.ServerStartupConfiguration;
 import org.apache.ldap.server.protocol.ExtendedOperationHandler;
 import org.apache.ldap.server.protocol.LdapProtocolProvider;
+import org.apache.ldap.server.protocol.support.extended.GracefulShutdownHandler;
 import org.apache.mina.common.DefaultIoFilterChainBuilder;
 import org.apache.mina.common.IoAcceptor;
 import org.apache.mina.common.IoFilterChainBuilder;
@@ -406,6 +406,13 @@
             ExtendedOperationHandler h = ( ExtendedOperationHandler ) i.next();
             protocolProvider.addExtendedOperationHandler( h );
             log.info( "Added Extended Request Handler: " + h.getOid() );
+            
+            if ( h instanceof GracefulShutdownHandler )
+            {
+                GracefulShutdownHandler gsh = ( GracefulShutdownHandler ) h;
+                gsh.setLdapService( service );
+                gsh.setServiceRegistry( minaRegistry );
+            }
         }
         
         try
@@ -484,12 +491,20 @@
     {
         if ( ldapService != null )
         {
-            IoAcceptor acceptor = minaRegistry.getAcceptor( service.getTransportType() );
+            
             try
             {
-                NoticeOfDisconnect nod = new NoticeOfDisconnect( ResultCodeEnum.UNAVAILABLE
);
-                List sessions = new ArrayList( acceptor.getManagedSessions( service.getAddress()
) );
+                // 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();
+                IoAcceptor acceptor = minaRegistry.getAcceptor( service.getTransportType()
);
+                List sessions = new ArrayList( acceptor.getManagedSessions( service.getAddress()
) );
+                minaRegistry.unbind( service );
+                if ( log.isInfoEnabled() )
+                {
+                    log.info( "Unbind of " + service.getName() + " Service complete: " +
ldapService );
+                    log.info( "Sending notice of disconnect to existing clients sessions."
);
+                }
                 
                 // Send Notification of Disconnection messages to all connected clients.
                 if( sessions != null )
@@ -497,7 +512,7 @@
                     for( Iterator i = sessions.iterator(); i.hasNext(); )
                     {
                         IoSession session = ( IoSession ) i.next();
-                        writeFutures.add( session.write( nod ) );
+                        writeFutures.add( session.write( NoticeOfDisconnect.UNAVAILABLE )
);
                     }
                 }
 
@@ -513,13 +528,6 @@
             catch( Exception e )
             {
                 log.warn( "Failed to sent NoD.", e );
-            }
-
-            minaRegistry.unbind( service );
-
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Unbind of " + service.getName() + " Service complete: " + ldapService
);
             }
         }
 

Modified: directory/trunks/apacheds/standalone/simple/main/server.xml
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/standalone/simple/main/server.xml?rev=373408&r1=373407&r2=373408&view=diff
==============================================================================
--- directory/trunks/apacheds/standalone/simple/main/server.xml (original)
+++ directory/trunks/apacheds/standalone/simple/main/server.xml Sun Jan 29 16:57:25 2006
@@ -81,6 +81,13 @@
       </set>
     </property>
     
+    <property name="extendedOperationHandlers">
+      <list>
+        <bean class="org.apache.ldap.server.protocol.support.extended.GracefulShutdownHandler"/>
+        <bean class="org.apache.ldap.server.protocol.support.extended.LaunchDiagnosticUiHandler"/>
+      </list>
+    </property>
+
     <property name="interceptorConfigurations">
       <list>
         <bean class="org.apache.ldap.server.configuration.MutableInterceptorConfiguration">

Modified: directory/trunks/apacheds/standalone/simple/unit/src/test/java/org/apache/ldap/server/ModifyRdnTest.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/standalone/simple/unit/src/test/java/org/apache/ldap/server/ModifyRdnTest.java?rev=373408&r1=373407&r2=373408&view=diff
==============================================================================
--- directory/trunks/apacheds/standalone/simple/unit/src/test/java/org/apache/ldap/server/ModifyRdnTest.java
(original)
+++ directory/trunks/apacheds/standalone/simple/unit/src/test/java/org/apache/ldap/server/ModifyRdnTest.java
Sun Jan 29 16:57:25 2006
@@ -71,9 +71,7 @@
         env.put("java.naming.security.principal", "uid=admin,ou=system" ); 
         env.put("java.naming.security.credentials", "secret" );
         env.put("java.naming.security.authentication", "simple");
-
         ctx = new InitialLdapContext(env, null);
-
         assertNotNull(ctx);
     }
 

Modified: directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/message/extended/GracefulShutdownRequest.java
URL: http://svn.apache.org/viewcvs/directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/message/extended/GracefulShutdownRequest.java?rev=373408&r1=373407&r2=373408&view=diff
==============================================================================
--- directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/message/extended/GracefulShutdownRequest.java
(original)
+++ directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/message/extended/GracefulShutdownRequest.java
Sun Jan 29 16:57:25 2006
@@ -43,7 +43,7 @@
 {
     private static final Logger log = LoggerFactory.getLogger( GracefulShutdownRequest.class
);
     private static final long serialVersionUID = -4682291068700593492L;
-    public static final String OID = "1.2.6.1.4.1.18060.1.1.1.100.3";
+    public static final String EXTENSION_OID = "1.2.6.1.4.1.18060.1.1.1.100.3";
 
     /** Undetermined value used for timeOffline */
     public static final int UNDETERMINED = 0;
@@ -67,7 +67,7 @@
     public GracefulShutdownRequest( int messageId, int timeOffline, int delay )
     {
         super( messageId );
-        setOid( OID );
+        setOid( EXTENSION_OID );
         this.timeOffline = timeOffline;
         this.delay = delay;
     }

Modified: directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/message/extended/NoticeOfDisconnect.java
URL: http://svn.apache.org/viewcvs/directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/message/extended/NoticeOfDisconnect.java?rev=373408&r1=373407&r2=373408&view=diff
==============================================================================
--- directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/message/extended/NoticeOfDisconnect.java
(original)
+++ directory/trunks/common/ldap/src/main/java/org/apache/ldap/common/message/extended/NoticeOfDisconnect.java
Sun Jan 29 16:57:25 2006
@@ -102,8 +102,12 @@
     public static final String OID = "1.3.6.1.4.1.1466.20036";
     private static final byte[] EMPTY_RESPONSE = new byte[0];
     
+    public static NoticeOfDisconnect UNAVAILABLE = new NoticeOfDisconnect( ResultCodeEnum.UNAVAILABLE
);
+    public static NoticeOfDisconnect PROTOCOLERROR = new NoticeOfDisconnect( ResultCodeEnum.PROTOCOLERROR
);
+    public static NoticeOfDisconnect STRONGAUTHREQUIRED = new NoticeOfDisconnect( ResultCodeEnum.STRONGAUTHREQUIRED
);
     
-    public NoticeOfDisconnect( ResultCodeEnum rcode )
+    
+    private NoticeOfDisconnect( ResultCodeEnum rcode )
     {
         super( 0 );
         



Mime
View raw message