You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2004/02/03 08:18:36 UTC

svn commit: rev 6451 - in incubator/directory/eve/trunk/eve/frontend/input/pojo-impl: . src src/docbook src/images src/java src/java/org src/java/org/apache src/java/org/apache/eve src/java/org/apache/eve/input

Author: akarasulu
Date: Mon Feb  2 23:18:36 2004
New Revision: 6451

Added:
   incubator/directory/eve/trunk/eve/frontend/input/pojo-impl/
   incubator/directory/eve/trunk/eve/frontend/input/pojo-impl/project.properties
   incubator/directory/eve/trunk/eve/frontend/input/pojo-impl/project.xml
   incubator/directory/eve/trunk/eve/frontend/input/pojo-impl/src/
   incubator/directory/eve/trunk/eve/frontend/input/pojo-impl/src/docbook/
   incubator/directory/eve/trunk/eve/frontend/input/pojo-impl/src/images/
   incubator/directory/eve/trunk/eve/frontend/input/pojo-impl/src/java/
   incubator/directory/eve/trunk/eve/frontend/input/pojo-impl/src/java/org/
   incubator/directory/eve/trunk/eve/frontend/input/pojo-impl/src/java/org/apache/
   incubator/directory/eve/trunk/eve/frontend/input/pojo-impl/src/java/org/apache/eve/
   incubator/directory/eve/trunk/eve/frontend/input/pojo-impl/src/java/org/apache/eve/input/
   incubator/directory/eve/trunk/eve/frontend/input/pojo-impl/src/java/org/apache/eve/input/DefaultInputManager.java
Log:
conforming to new layout


Added: incubator/directory/eve/trunk/eve/frontend/input/pojo-impl/project.properties
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/eve/frontend/input/pojo-impl/project.properties	Mon Feb  2 23:18:36 2004
@@ -0,0 +1,3 @@
+maven.xdoc.date=left
+maven.xdoc.version=${pom.currentVersion}
+merlin.debug=true

Added: incubator/directory/eve/trunk/eve/frontend/input/pojo-impl/project.xml
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/eve/frontend/input/pojo-impl/project.xml	Mon Feb  2 23:18:36 2004
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<project>
+    <extend>${basedir}/../../../project.xml</extend>
+    <groupId>directory</groupId>
+    <id>eve-frontend-input-pojo-impl</id>
+  
+    <name>Eve Frontend Input Manager Implementation</name>
+    <package>org.apache.eve.input</package>
+    <currentVersion>SNAPSHOT</currentVersion>
+    <inceptionYear>2003</inceptionYear>
+      
+    <shortDescription>
+    Eve's Frontend InputManager Implementation
+    </shortDescription>
+
+    <description>
+        Eve's frontend input manager reads input from client sockets bound to
+        the server.  The input manager responds to input events enqueued by
+        the listener modules which detects io to read from the socket channel.
+    </description>
+      
+    <dependencies>
+
+        <dependency>
+            <groupId>directory</groupId>
+            <artifactId>eve-frontend-common-api</artifactId>
+            <version>SNAPSHOT</version>
+            <url>http://directory.apache.org</url>
+        </dependency>
+
+        <dependency>
+            <groupId>directory</groupId>
+            <artifactId>eve-frontend-event-spi</artifactId>
+            <version>SNAPSHOT</version>
+            <url>http://directory.apache.org</url>
+        </dependency>
+
+        <dependency>
+            <groupId>directory</groupId>
+            <artifactId>eve-frontend-event-pojo-impl</artifactId>
+            <version>SNAPSHOT</version>
+            <url>http://directory.apache.org</url>
+        </dependency>
+
+        <dependency>
+            <groupId>directory</groupId>
+            <artifactId>eve-frontend-event-merlin-impl</artifactId>
+            <version>SNAPSHOT</version>
+            <url>http://directory.apache.org</url>
+        </dependency>
+
+        <dependency>
+            <groupId>directory</groupId>
+            <artifactId>eve-frontend-input-spi</artifactId>
+            <version>SNAPSHOT</version>
+            <url>http://directory.apache.org</url>
+        </dependency>
+
+        <dependency>
+            <groupId>directory</groupId>
+            <artifactId>eve-frontend-buffer-spi</artifactId>
+            <version>SNAPSHOT</version>
+            <url>http://directory.apache.org</url>
+        </dependency>
+
+        <dependency>
+            <groupId>directory</groupId>
+            <artifactId>eve-frontend-buffer-impl</artifactId>
+            <version>SNAPSHOT</version>
+            <url>http://directory.apache.org</url>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>3.8.1</version>
+            <url>http://junit.org</url>
+        </dependency>
+    </dependencies>
+</project>
+

Added: incubator/directory/eve/trunk/eve/frontend/input/pojo-impl/src/java/org/apache/eve/input/DefaultInputManager.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/eve/frontend/input/pojo-impl/src/java/org/apache/eve/input/DefaultInputManager.java	Mon Feb  2 23:18:36 2004
@@ -0,0 +1,400 @@
+/*
+
+ ============================================================================
+                   The Apache Software License, Version 1.1
+ ============================================================================
+
+ Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of  source code must  retain the above copyright  notice,
+    this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+
+ 3. The end-user documentation included with the redistribution, if any, must
+    include  the following  acknowledgment:  "This product includes  software
+    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+    Alternately, this  acknowledgment may  appear in the software itself,  if
+    and wherever such third-party acknowledgments normally appear.
+
+ 4. The names "Eve Directory Server", "Apache Directory Project", "Apache Eve" 
+    and "Apache Software Foundation"  must not be used to endorse or promote
+    products derived  from this  software without  prior written
+    permission. For written permission, please contact apache@apache.org.
+
+ 5. Products  derived from this software may not  be called "Apache", nor may
+    "Apache" appear  in their name,  without prior written permission  of the
+    Apache Software Foundation.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+ APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+ ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+ (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This software  consists of voluntary contributions made  by many individuals
+ on  behalf of the Apache Software  Foundation. For more  information on the
+ Apache Software Foundation, please see <http://www.apache.org/>.
+
+*/
+package org.apache.eve.input ;
+
+
+import java.util.Iterator ;
+import java.util.EventObject ;
+
+import java.io.IOException ;
+import java.nio.ByteBuffer ;
+import java.nio.channels.Selector ;
+import java.nio.channels.SelectionKey ;
+import java.nio.channels.SocketChannel ;
+
+import org.apache.eve.event.InputEvent ;
+import org.apache.eve.ResourceException ;
+import org.apache.eve.buffer.BufferPool ;
+import org.apache.eve.event.EventRouter ;
+import org.apache.eve.listener.ClientKey ;
+import org.apache.eve.event.ConnectEvent ;
+import org.apache.eve.event.DisconnectEvent ;
+import org.apache.eve.listener.KeyExpiryException ;
+
+
+/**
+ * Default InputManager implementation based on NIO selectors and channels.
+ *
+ * @author <a href="mailto:akarasulu@apache.org">Alex Karasulu</a>
+ * @author $Author: akarasulu $
+ * @version $Rev: 1452 $
+ */
+public class DefaultInputManager implements InputManager
+{
+    /** the thread driving this Runnable */ 
+    private Thread m_thread = null ;
+    /** parameter used to politely stop running thread */
+    private Boolean m_hasStarted = null ;
+    /** the buffer pool we get direct buffers from */
+    private BufferPool m_bp = null ;
+    /** event router used to decouple source to sink relationships */
+    private EventRouter m_router = null ;
+    /** selector used to select a ready socket channel */
+    private Selector m_selector = null ;
+    /** the input manager's monitor */
+    private InputManagerMonitor m_monitor = new InputManagerMonitorAdapter() ;
+
+    
+    // ------------------------------------------------------------------------
+    // C O N S T R U C T O R S
+    // ------------------------------------------------------------------------
+    
+    
+    /**
+     * Creates a default InputManager implementation
+     *  
+     * @param a_router an event router service
+     * @param a_bp a buffer pool service
+     */
+    public DefaultInputManager( EventRouter a_router, BufferPool a_bp )
+        throws IOException
+    {
+        m_bp = a_bp ;
+        m_router = a_router ;
+        m_hasStarted = new Boolean( false ) ;
+        m_selector = Selector.open() ;
+    }
+    
+
+        // ------------------------------------------------------------------------
+        // start, stop and runnable code
+        // ------------------------------------------------------------------------
+    
+    
+    /**
+     * Runnable used to drive the selection loop. 
+     *
+     * @author <a href="mailto:aok123@bellsouth.net">Alex Karasulu</a>
+     * @author $Author: akarasulu $
+     * @version $Revision$
+     */
+    class SelectionDriver implements Runnable
+    {
+        public void run()
+        {
+            while ( m_hasStarted.booleanValue() ) 
+            {
+                int l_count = 0 ;
+                
+                /*
+                 * check if we have input waiting and continue if there is
+                 * nothing to read from any of the registered channels  
+                 */
+                try
+                {
+                    if ( 0 == ( l_count = m_selector.select( 100 ) ) )
+                    {
+                        m_monitor.selectorReturned( m_selector ) ;
+                        continue ;
+                    }
+                } 
+                catch( IOException e )
+                {
+                    m_monitor.selectFailure( m_selector, e ) ;
+                    continue ;
+                }
+                
+                processInput() ;
+            }
+        }
+    }
+
+
+    /**
+     * Starts up this module.
+     */
+    public void start() 
+    {
+        synchronized( m_hasStarted )
+        {
+            if ( m_hasStarted.booleanValue() )
+            {
+                throw new IllegalStateException( "Already started!" ) ;
+            }
+            
+            m_hasStarted = new Boolean( true ) ;
+            m_thread = new Thread( new SelectionDriver() ) ;
+            m_thread.start() ;
+        }
+    }
+    
+    
+    /**
+     * Blocks calling thread until this module gracefully stops.
+     */
+    public void stop() throws InterruptedException
+    {
+        synchronized( m_hasStarted )
+        {
+            m_hasStarted = new Boolean( false ) ;
+            
+            while ( m_thread.isAlive() )
+            {
+                Thread.sleep( 100 ) ;
+            }
+        }
+    }
+    
+    
+    // ------------------------------------------------------------------------
+    // subscriber methods
+    // ------------------------------------------------------------------------
+    
+    
+    /**
+     * @see org.apache.eve.event.ConnectListener#
+     * connectPerformed(org.apache.eve.event.ConnectEvent)
+     */
+    public void inform( ConnectEvent an_event )
+    {
+        ClientKey l_key = null ;
+        SocketChannel l_channel = null ;
+        
+        try
+        {
+            l_key = an_event.getClientKey() ;
+            l_channel = l_key.getSocket().getChannel() ;
+            
+            // hands-off blocking sockets!
+            if ( null == l_channel )
+            {
+                return ;
+            }
+            
+            l_channel.configureBlocking( false ) ;
+            l_channel.register( m_selector, SelectionKey.OP_READ, l_key ) ;
+            m_monitor.registeredChannel( l_key, m_selector ) ;
+        }
+        catch ( KeyExpiryException e )
+        {
+            String l_msg = "Attempting session creation using expired key for "
+                + an_event.getClientKey() ;
+            m_monitor.keyExpiryFailure( l_key, e ) ;
+        }
+        catch ( IOException e )
+        {
+            String l_msg = "Input managmer registration failure for " +
+                an_event.getClientKey() + " due to exception." ;
+            m_monitor.channelRegistrationFailure( m_selector, l_channel, 
+                    SelectionKey.OP_READ, e ) ;
+        }
+    }
+
+    
+    /**
+     * @see org.apache.eve.event.DisconnectListener#
+     * inform(org.apache.eve.event.DisconnectEvent)
+     */
+    public void inform( DisconnectEvent an_event )
+    {
+        SelectionKey l_key = null ;
+        Iterator l_keys = m_selector.keys().iterator() ;
+        
+        while ( l_keys.hasNext() )
+        {
+            l_key = ( SelectionKey ) l_keys.next() ;
+            if ( l_key.attachment().equals( an_event.getClientKey() ) )
+            {
+                break ;
+            }
+        }
+
+        if ( null == l_key )
+        {
+            return ;
+        }
+        
+        try
+        {
+            l_key.channel().close() ;
+        }
+        catch ( IOException e )
+        {
+            m_monitor.channelCloseFailure( 
+                    ( SocketChannel ) l_key.channel(), e ) ;
+        }
+        
+        l_key.cancel() ;
+        m_monitor.disconnectedClient( an_event.getClientKey() ) ;
+    }
+    
+
+    /**
+     * @see org.apache.eve.event.Subscriber#inform(java.util.EventObject)
+     */
+    public void inform( EventObject an_event )
+    {
+        Class l_clazz = an_event.getClass() ;
+        
+        if ( l_clazz.isAssignableFrom( ConnectEvent.class ) )
+        {
+            inform( ( ConnectEvent ) an_event ) ;
+        }
+        else if ( l_clazz.isAssignableFrom( DisconnectEvent.class ) ) ;
+        {
+            inform( ( DisconnectEvent ) an_event ) ;
+        }
+    }
+    
+    
+    // ------------------------------------------------------------------------
+    // private utilities
+    // ------------------------------------------------------------------------
+    
+    
+    /**
+     * Processes input on channels of the read ready selected keys.
+     */
+    void processInput()
+    {
+        /*
+         * Process the selectors that are ready.  For each selector that
+         * is ready we read some data into a buffer we claim from a buffer
+         * pool.  Next we create an InputEvent using the buffer and publish
+         * it using the event notifier/router.
+         */
+        Iterator l_list = m_selector.selectedKeys().iterator() ;
+        while ( l_list.hasNext() )
+        {
+            SelectionKey l_key = ( SelectionKey ) l_list.next() ;
+            ClientKey l_client = ( ClientKey ) l_key.attachment() ; 
+                
+            if ( l_key.isReadable() )
+            {
+                ByteBuffer l_buf = null ;
+                SocketChannel l_channel = ( SocketChannel ) l_key.channel() ;
+
+                // claim a buffer and read & return buffer on errors 
+                try
+                {
+                    l_buf = m_bp.getBuffer( this ) ;
+                    l_channel.read( l_buf ) ;
+                }
+                catch ( ResourceException e )
+                {
+                    m_monitor.bufferUnavailable( m_bp, e ) ;
+                    continue ;
+                }
+                catch ( IOException e )
+                {
+                    m_monitor.readFailed( l_client, e ) ;
+                    m_bp.releaseClaim( l_buf, this ) ;
+                    continue ;
+                }
+                    
+                // report to monitor, create the event, and publish it
+                m_monitor.inputRecieved( l_client ) ;
+                InputEvent l_event = new ConcreteInputEvent( l_client, l_buf ) ;
+                m_router.publish( l_event ) ;
+                m_bp.releaseClaim( l_buf, this ) ;
+            }
+        }
+    }
+    
+    
+    /**
+     * A concrete InputEvent that uses the buffer pool to properly implement
+     * the interest claim and release methods.
+     *
+     * @author <a href="mailto:aok123@bellsouth.net">Alex Karasulu</a>
+     * @author $Author: akarasulu $
+     * @version $Revision$
+     */
+    class ConcreteInputEvent extends InputEvent
+    {
+        ConcreteInputEvent( ClientKey a_key, ByteBuffer a_buffer )
+        {
+            super( a_key, a_buffer ) ;
+        }
+        
+        public ByteBuffer claimInterest( Object a_party )
+        {
+            m_bp.claimInterest( m_buffer, a_party ) ;
+            return m_buffer.asReadOnlyBuffer() ;
+        }
+        
+        public void releaseInterest( Object a_party )
+        {
+            m_bp.releaseClaim( m_buffer, a_party ) ;
+        }
+    }
+    
+    
+    /**
+     * Gets the monitor associated with this InputManager.
+     * 
+     * @return returns the monitor
+     */
+    public InputManagerMonitor getMonitor()
+    {
+        return m_monitor ;
+    }
+
+    
+    /**
+     * Sets the monitor associated with this InputManager.
+     * 
+     * @param a_monitor the monitor to set
+     */
+    public void setMonitor( InputManagerMonitor a_monitor )
+    {
+        m_monitor = a_monitor ;
+    }
+}