sendNoticeOfDisconnect( requestor );
sendNoticeOfDisconnect( sessions, requestor );
    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;    }