Peter,
Current HEAD compiles fine, but there's a parsing error at runtime due
to a couple of typos in src/conf/james-config.xml - here is the patch.
Nathan Carter
[EMAIL PROTECTED] wrote:
>pgoldstein 2002/10/07 00:16:46
>
> Modified: src/conf james-assembly.xml james-config.xml
> Added: src/java/org/apache/james/util/connection
> ServerConnection.java SimpleConnectionManager.java
> SimpleConnectionManager.xinfo package.html
> Log:
> Added the SimpleConnectionManager and supporting class ServerConnection.
>
> Changed the configuration/assembly -
> i) Replaced tabs with spaces
> ii) Added comments
> iii) Removed AuthService references
> iv) Increased max number of threads in thread pool
> v) Changed ConnectionManager to default to
>org.apache.james.util.connection.SimpleConnectionManager
> vi) Added commented authRequired element to NNTP server
>
> Revision Changes Path
> 1.12 +1 -6 jakarta-james/src/conf/james-assembly.xml
>
> Index: james-assembly.xml
> ===================================================================
> RCS file: /home/cvs/jakarta-james/src/conf/james-assembly.xml,v
> retrieving revision 1.11
> retrieving revision 1.12
> diff -u -r1.11 -r1.12
> --- james-assembly.xml 2 Oct 2002 09:53:37 -0000 1.11
> +++ james-assembly.xml 7 Oct 2002 07:16:46 -0000 1.12
> @@ -99,11 +99,6 @@
> role="org.apache.james.nntpserver.repository.NNTPRepository"/>
> </block>
>
> - <!-- NNTP Authentication Service -->
> - <block name="nntpauth" class="org.apache.james.nntpserver.AuthServiceImpl" >
> - <provide name="users-store" role="org.apache.james.services.UsersStore"/>
> - </block>
> -
> <!-- NNTP Repository -->
> <block name="nntp-repository"
>class="org.apache.james.nntpserver.repository.NNTPRepositoryImpl" />
>
> @@ -142,7 +137,7 @@
>
> <!-- The Connection Manager block -->
> <block name="connections"
> -
>class="org.apache.avalon.cornerstone.blocks.connection.DefaultConnectionManager" >
> + class="org.apache.james.util.connection.SimpleConnectionManager" >
> <provide name="thread-manager"
> role="org.apache.avalon.cornerstone.services.threads.ThreadManager" />
> </block>
>
>
>
> 1.34 +92 -49 jakarta-james/src/conf/james-config.xml
>
> Index: james-config.xml
> ===================================================================
> RCS file: /home/cvs/jakarta-james/src/conf/james-config.xml,v
> retrieving revision 1.33
> retrieving revision 1.34
> diff -u -r1.33 -r1.34
> --- james-config.xml 27 Sep 2002 16:31:06 -0000 1.33
> +++ james-config.xml 7 Oct 2002 07:16:46 -0000 1.34
> @@ -7,10 +7,10 @@
> README!
>
> This configuration file is designed to run without alteration for simple tests.
> -It assumes you have a DNS server on localhost and assigns a root pasword of root.
> +It assumes you have a DNS server on localhost and assigns a root password of root.
>
> In case the defaults do not suit you, the items you are most likely to need to
>change
> -are preceeded by a CHECKME! or CONFIRM? comment in the left margin.
> +are preceded by a CHECKME! or CONFIRM? comment in the left margin.
>
> For production use you will probably need to make more extensive changes, see
> http://jakarta.apache.org/james/configuration_v2_0.html
> @@ -30,16 +30,16 @@
> If autodetectIP is not FALSE, James will also allow add the IP address
>for each servername.
> The automatic IP detection is to support RFC 2821, Sec 4.1.3, address
>literals.
> By default, the servername 'localhost' is specified. This can be
>removed, if required. -->
> - <servernames autodetect="TRUE" autodetectIP="TRUE">
> + <servernames autodetect="true" autodetectIP="true">
> <!--<servername>To override autodetected server names uncomment this.
></servername> -->
> <servername>localhost</servername>
> - <!-- IMPORTANT if you are using fetchpop it is important to include
>the -->
> - <!-- fetched domains here to prevent looping
> -->
> + <!-- IMPORTANT if you are using fetchpop it is important to include the -->
> + <!-- fetched domains here to prevent looping -->
> </servernames>
>
> <!-- Set whether user names are case sensitive or case insensitive -->
> <!-- Set whether to enable local aliases -->
> - <usernames ignoreCase="TRUE" enableAliases="TRUE" enableForwarding="TRUE"/>
> + <usernames ignoreCase="true" enableAliases="true" enableForwarding="true"/>
>
> <!-- The inbox repository is the location for users inboxes -->
> <!-- Default setting: file based repository - enter path ( use "file:///"
>for absolute) -->
> @@ -62,22 +62,22 @@
> <!-- fetched domains in the <servernames> section of the <James> block -->
> <!-- above. fetchpop is disabled by default.
>-->
>
> - <fetchpop enabled="false">
> - <!-- you can have as many fetch tasks as you want to -->
> - <!-- but each must have a unique name to identify itself by -->
> - <fetch name="mydomain.com">
> - <!-- host name or IP address -->
> - <host>mail.mydomain.com</host>
> - <!-- acount login username -->
> - <user>username</user>
> - <!-- account login password -->
> - <password>pass</password>
> - <!-- Interval to check this account in milliseconds, 600000 is
>every ten minutes -->
> - <interval>600000</interval>
> - </fetch>
> - </fetchpop>
> -
> -
> + <fetchpop enabled="false">
> + <!-- you can have as many fetch tasks as you want to -->
> + <!-- but each must have a unique name to identify itself by -->
> + <fetch name="mydomain.com">
> + <!-- host name or IP address -->
> + <host>mail.mydomain.com</host>
> + <!-- acount login username -->
> + <user>username</user>
> + <!-- account login password -->
> + <password>pass</password>
> + <!-- Interval to check this account in milliseconds, 600000 is every
>ten minutes -->
> + <interval>600000</interval>
> + </fetch>
> + </fetchpop>
> +
> +
> <!-- The James Spool Manager block -->
> <spoolmanager>
> <!-- number of spool threads -->
> @@ -119,7 +119,7 @@
> <!-- Sample matching to kill a message (send to Null) -->
> <mailet match="RecipientIs=badboy@badhost" class="Null"/>
>
> - <!-- Send remaining mails to the transport processor for either local or
>remote delivery -->
> + <!-- Send remaining mails to the transport processor for either local or
>remote delivery -->
> <mailet match="All" class="ToProcessor">
> <processor> transport </processor>
> </mailet>
> @@ -142,7 +142,7 @@
> <!--<mailet match="All" class="NotifyPostmaster"/>-->
> </processor>
>
> - <!-- Processor CONFIGURATION SAMPLE: transport is a sample custom
>processor for local or remote delivery -->
> + <!-- Processor CONFIGURATION SAMPLE: transport is a sample custom processor
>for local or remote delivery -->
> <processor name="transport">
>
> <!-- Is the recipient is for a local account, deliver it locally -->
> @@ -153,7 +153,7 @@
> <processor>error</processor>
> </mailet>
>
> - <!-- CHECKME! Anti-relay mailet: Add your network address here,
> + <!-- CHECKME! Anti-relay mailet: Add your network address here,
> e.g. "RemoteAddrNotInNetwork=127.0.0.1, abc.de.*, 192.168.0.*"-->
>
> <!-- This matcher-mailet pair can prevent relaying...
> @@ -244,7 +244,7 @@
> autodetect is TRUE, James will attempt to discover its own name OR
> use 'localhost'. If autodetect is FALSE, James will use the value
> given OR 'localhost' -->
> - <helloName autodetect="TRUE">myMailServer</helloName>
> + <helloName autodetect="true">myMailServer</helloName>
> <administrator_accounts>
> <!-- CHECKME! Change the default password! -->
> <!-- FILL ME!!!!!! You must provide a password for your administrator accounts
>(cannot be blank) -->
> @@ -254,9 +254,9 @@
> </handler>
> </remotemanager>
>
> - <!-- The POP3 server is enabled by default -->
> - <!-- Disabling blocks will stop them from listening, -->
> - <!-- but does not free as many resources as removing them would -->
> + <!-- The POP3 server is enabled by default -->
> + <!-- Disabling blocks will stop them from listening, -->
> + <!-- but does not free as many resources as removing them would -->
> <pop3server enabled="true">
> <!-- port 995 is the well-known/IANA registered port for POP3S ie over
>SSL/TLS -->
> <!-- port 100 is the well-known/IANA registered port for Standard POP3 -->
> @@ -273,14 +273,14 @@
> autodetect is TRUE, James will attempt to discover its own name OR
> use 'localhost'. If autodetect is FALSE, James will use the value
> given OR 'localhost' -->
> - <helloName autodetect="TRUE">myMailServer</helloName>
> + <helloName autodetect="true">myMailServer</helloName>
> <connectiontimeout>120000</connectiontimeout>
> </handler>
> </pop3server>
>
> - <!-- The SMTP server is enabled by default -->
> - <!-- Disabling blocks will stop them from listening, -->
> - <!-- but does not free as many resources as removing them would -->
> + <!-- The SMTP server is enabled by default -->
> + <!-- Disabling blocks will stop them from listening, -->
> + <!-- but does not free as many resources as removing them would -->
> <smtpserver enabled="true">
> <port>25</port>
>
> @@ -295,7 +295,7 @@
> autodetect is TRUE, James will attempt to discover its own name OR
> use 'localhost'. If autodetect is FALSE, James will use the value
> given OR 'localhost' -->
> - <helloName autodetect="TRUE">myMailServer</helloName>
> + <helloName autodetect="true">myMailServer</helloName>
> <connectiontimeout>360000</connectiontimeout>
> <!-- uncomment this if you want
> SMTP AUTH support. This is useful if you have users who need to use
> @@ -313,9 +313,9 @@
> </handler>
> </smtpserver>
>
> - <!-- The NNTP server is enabled by default -->
> - <!-- Disabling blocks will stop them from listening, -->
> - <!-- but does not free as many resources as removing them would -->
> + <!-- The NNTP server is enabled by default -->
> + <!-- Disabling blocks will stop them from listening, -->
> + <!-- but does not free as many resources as removing them would -->
> <nntpserver enabled="true">
> <!-- port 563 is the well-known/IANA registered port for nntp over SSL/TLS
>-->
> <!-- port 119 is the well-known/IANA registered port for Standard nntp -->
> @@ -332,16 +332,13 @@
> autodetect is TRUE, James will attempt to discover its own name OR
> use 'localhost'. If autodetect is FALSE, James will use the value
> given OR 'localhost' -->
> - <helloName autodetect="TRUE">myMailServer</helloName>
> + <helloName autodetect="true">myMailServer</helloName>
> <connectiontimeout>120000</connectiontimeout>
> + <!-- Set the authRequired value to true to enable authenticated NNTP -->
> + <authRequired>false</authRequired>
> </handler>
> </nntpserver>
>
> - <nntpauth>
> - <!-- make this true, if you want only authenticated users to access NNTP-->
> - <authRequired>false</authRequired>
> - </nntpauth>
> -
> <nntp-repository>
> <!-- make this true to disallow posting to all newsgroups-->
> <readOnly>false</readOnly>
> @@ -460,8 +457,8 @@
> User repositories are required for the following purposes:
> - holding information about Users of the James mail server
> - holding lists of users for the listserv mailet
> - Currently, 2 different storage options are available:
> - - file-based storage using Java serialisation
> + Currently, two different storage options are available:
> + - file-based storage using Java serialization
> - database-backed storage
> (Use of database or file-system is defined on a "per-repository" basis)
> Note: Two user repositories are required for default configuration:
> @@ -533,8 +530,19 @@
> </data-sources>
> </database-connections>
>
> - <!-- Configuration for Cornerstone Blocks only after here NOTHING BELOW THIS
>SHOULD NEED CHANGING,
> - (unless you want secure sockets (TLS)) -->
> + <!-- Configuration for Cornerstone Services -->
> + <!-- -->
> + <!-- For a simple configuration, nothing beneath this line should require -->
> + <!-- alteration. -->
> + <!-- -->
> + <!-- You will need to adjust the Socket Manager service configuration if you
>want -->
> + <!-- to enable secure sockets (TLS) for any James service.
> -->
> + <!-- -->
> + <!-- Complex or high volume configurations may require changes to the
>parameters -->
> + <!-- in this section. Please read the James and Avalon documentation before -->
> + <!-- attempting to adjust this section. -->
> + <!-- -->
> +
> <!-- The Storage block -->
> <objectstorage>
> <repositories>
> @@ -566,7 +574,42 @@
> </repository>
> </repositories>
> </objectstorage>
> + <!-- The Connection Manager block -->
> + <!-- -->
> + <!-- The idle-timeout is the number of milliseconds that it will take for idle
>-->
> + <!-- client connections managed by this connection manager to be marked at
>timed out. -->
> + <!-- If no value is specified, the value defaults to 5 minutes, 300000
>milliseconds -->
> + <!-- A value of 0 means that client sockets will not timeout. -->
> + <!-- -->
> + <!-- The max-connections parameter specifies the maximum number of client
>connections -->
> + <!-- that this connection manager will allow per managed server socket. -->
> + <!-- If no value is specified, the value defaults to 30. -->
> + <!-- A value of 0 means that there is no limit imposed by the connection
>manager, although -->
> + <!-- resource limitations imposed by other components (i.e. max # of threads)
>may -->
> + <!-- serve to limit the number of open connections. -->
> + <!-- -->
> + <connections>
> + <idle-timeout>300000<idle-timeout>
> + <max-connections>30<max-connections>
> + </connections>
> <!-- The Socket Manager block -->
> + <!-- -->
> + <!-- The server-sockets element has a number of factory sub-elements. -->
> + <!-- Each of the factory elements has a name and class attribute -->
> + <!-- The name attribute for each factory element must be unique. -->
> + <!-- The class attribute is the name of a class that implements the -->
> + <!-- interface org.apache.avalon.cornerstone.services.ServerSocketFactory -->
> + <!-- Specific factory elements may require some sub-elements. This is -->
> + <!-- factory class dependent. -->
> + <!-- -->
> + <!-- The client-sockets element has a number of factory sub-elements. -->
> + <!-- Each of the factory elements has a name and class attribute -->
> + <!-- The name attribute for each factory element must be unique. -->
> + <!-- The class attribute is the name of a class that implements the -->
> + <!-- interface org.apache.avalon.cornerstone.services.SocketFactory -->
> + <!-- Specific factory elements may require some sub-elements. This is -->
> + <!-- factory class dependent. -->
> + <!-- -->
> <sockets>
> <server-sockets>
> <factory name="plain"
>class="org.apache.avalon.cornerstone.blocks.sockets.DefaultServerSocketFactory"/>
> @@ -592,7 +635,7 @@
> <priority>5</priority>
> <!-- are threads daemon threads ? -->
> <is-daemon>false</is-daemon>
> - <max-threads>40</max-threads>
> + <max-threads>100</max-threads>
> <!-- these are ignored at the moment but will be fixed in later revisions
>-->
> <min-threads>20</min-threads>
> <min-spare-threads>20</min-spare-threads>
>
>
>
> 1.1
>jakarta-james/src/java/org/apache/james/util/connection/ServerConnection.java
>
> Index: ServerConnection.java
> ===================================================================
> /*
> * Copyright (C) The Apache Software Foundation. All rights reserved.
> *
> * This software is published under the terms of the Apache Software License
> * version 1.1, a copy of which has been included with this distribution in
> * the LICENSE.txt file.
> */
> package org.apache.james.util.connection;
>
> import java.io.IOException;
> import java.io.InterruptedIOException;
> import java.net.ServerSocket;
> import java.net.Socket;
> import java.net.SocketException;
> import java.util.ArrayList;
> import java.util.Iterator;
> import java.util.List;
>
> import org.apache.avalon.cornerstone.services.connection.ConnectionHandler;
> import org.apache.avalon.cornerstone.services.connection.ConnectionHandlerFactory;
> import org.apache.avalon.excalibur.thread.ThreadPool;
> import org.apache.avalon.framework.component.Component;
> import org.apache.avalon.framework.logger.AbstractLogEnabled;
>
>
> /**
> * Represents a single server socket managed by a connection manager.
> * The connection manager will spawn a single ServerConnection for each
> * server socket that the connection manager is managing.
> *
> * @author Andrei Ivanov
> * @author Peter M. Goldstein <[EMAIL PROTECTED]>
> */
> public class ServerConnection extends AbstractLogEnabled
> implements Component, Runnable {
>
> /**
> * This is a hack to deal with the fact that there appears to be
> * no platform-independent way to break out of a ServerSocket
> * accept() call. On some platforms closing either the ServerSocket
> * itself, or its associated InputStream, causes the accept
> * method to exit. Unfortunately, this behavior is not consistent
> * across platforms. The deal with this, we introduce a polling
> * loop of 20 seconds for the server socket. This introduces a
> * cost across platforms, but is necessary to maintain cross-platform
> * functionality.
> */
> private static int POLLING_INTERVAL = 20*1000;
>
> /**
> * The server socket which this connection is managing
> */
> private ServerSocket serverSocket;
>
> /**
> * The connection handler factory that generates connection
> * handlers to manage client connections to this server socket
> */
> private ConnectionHandlerFactory handlerFactory;
>
> /**
> * The thread pool used to spawn individual threads used to manage each
> * client connection.
> */
> private ThreadPool connThreadPool;
>
> /**
> * The timeout for client sockets spawned off this connection.
> */
> private int socketTimeout;
>
> /**
> * The maximum number of open client connections that this server
> * connection will allow.
> */
> private int maxOpenConn;
>
> /**
> * A collection of client connection runners.
> */
> private final ArrayList clientConnectionRunners = new ArrayList();
>
> /**
> * The current number of open client connections.
> */
> private int openConnections = 0;
>
> /**
> * The thread used to manage this server connection.
> */
> private Thread serverConnectionThread;
>
> /**
> * The sole constructor for a ServerConnection.
> *
> * @param serverSocket the ServerSocket associated with this ServerConnection
> * @param handlerFactory the factory that generates ConnectionHandlers for the
>client
> * connections spawned off this ServerConnection
> * @param threadPool the ThreadPool used to obtain handler threads
> * @param timeout the client idle timeout for this ServerConnection's client
>connections
> * @param maxOpenConn the maximum number of open client connections allowed for
>this
> * ServerConnection
> */
> public ServerConnection(ServerSocket serverSocket,
> ConnectionHandlerFactory handlerFactory,
> ThreadPool threadPool,
> int timeout,
> int maxOpenConn) {
> this.serverSocket = serverSocket;
> this.handlerFactory = handlerFactory;
> connThreadPool = threadPool;
> socketTimeout = timeout;
> this.maxOpenConn = maxOpenConn;
> }
>
> /**
> * The dispose operation is called by the owning ConnectionManager
> * at the end of its lifecycle. Cleans up the server connection, forcing
> * everything to finish.
> */
> public void dispose() {
> if (getLogger().isDebugEnabled()) {
> getLogger().debug("Disposing server connection..." + this.toString());
> }
> synchronized( this ) {
> if( null != serverConnectionThread ) {
> // Execution of this block means that the run() method
> // hasn't finished yet. So we interrupt the thread
> // to terminate run() and wait for the run() method
> // to finish. The notifyAll() at the end of run() will
> // wake this thread and allow dispose() to end.
> Thread thread = serverConnectionThread;
> serverConnectionThread = null;
> thread.interrupt();
> try {
> serverSocket.close();
> } catch (IOException ie) {
> // Ignored - we're doing this to break out of the
> // accept. This minimizes the time required to
> // shutdown the server. Unfortunately, this is
> // not guaranteed to work on all platforms. See
> // the comments for POLLING_INTERVAL
> }
> try {
> if (POLLING_INTERVAL > 0) {
> wait(2L*POLLING_INTERVAL);
> } else {
> wait();
> }
> } catch (InterruptedException ie) {
> // Expected - just complete dispose()
> }
> }
> }
>
> getLogger().debug("Closed server connection - cleaning up clients - " +
>this.toString());
>
> synchronized (clientConnectionRunners) {
> Iterator runnerIterator = clientConnectionRunners.iterator();
> while( runnerIterator.hasNext() )
> {
> ClientConnectionRunner runner =
>(ClientConnectionRunner)runnerIterator.next();
> runner.dispose();
> runner = null;
> }
> clientConnectionRunners.clear();
> openConnections = 0;
> }
>
> getLogger().debug("Cleaned up clients - " + this.toString());
>
> }
>
> /**
> * Adds a ClientConnectionRunner to the set managed by this ServerConnection
>object.
> *
> * @param clientConnectionRunner the ClientConnectionRunner to be added
> */
> private void addClientConnectionRunner(ClientConnectionRunner
>clientConnectionRunner) {
> synchronized (clientConnectionRunners) {
> clientConnectionRunners.add(clientConnectionRunner);
> openConnections++;
> }
> }
>
> /**
> * Removes a ClientConnectionRunner from the set managed by this
>ServerConnection object.
> *
> * @param clientConnectionRunner the ClientConnectionRunner to be removed
> */
> private void removeClientConnectionRunner(ClientConnectionRunner
>clientConnectionRunner) {
> synchronized (clientConnectionRunners) {
> clientConnectionRunners.remove(clientConnectionRunner);
> openConnections--;
> }
> }
>
> /**
> * Provides the body for the thread of execution for a ServerConnection.
> * Connections made to the server socket are passed to an appropriate,
> * newly created, ClientConnectionRunner
> */
> public void run() {
> serverConnectionThread = Thread.currentThread();
>
> int ioExceptionCount = 0;
> try {
> serverSocket.setSoTimeout(POLLING_INTERVAL);
> } catch (SocketException se) {
> // Ignored - for the moment
> }
> while( null != serverConnectionThread &&
>!serverConnectionThread.isInterrupted() ) {
> try {
> Socket clientSocket = null;
> try {
> clientSocket = serverSocket.accept();
> } catch( InterruptedIOException iioe ) {
> // This exception is expected upon ServerConnection shutdown.
> // See the POLLING_INTERVAL comment
> continue;
> } catch( IOException se ) {
> if (ioExceptionCount > 0) {
> getLogger().error( "Fatal exception while listening on
>server socket. Terminating connection.", se );
> break;
> } else {
> continue;
> }
> } catch( SecurityException se ) {
> getLogger().error( "Fatal exception while listening on server
>socket. Terminating connection.", se );
> break;
> }
> ClientConnectionRunner runner = null;
> synchronized (clientConnectionRunners) {
> if ((maxOpenConn > 0) && (openConnections >= maxOpenConn)) {
> if (getLogger().isWarnEnabled()) {
> getLogger().warn("Maximum number of open connections
>exceeded - refusing connection. Current number of connections is " +
>openConnections);
> }
> try {
> clientSocket.close();
> } catch (IOException ignored) {
> // We ignore this exception, as we already have an
>error condition.
> }
> continue;
> } else {
> clientSocket.setSoTimeout(socketTimeout);
> runner =
> new ClientConnectionRunner(clientSocket,
>handlerFactory);
> }
> }
> setupLogger( runner );
> connThreadPool.execute( runner );
> } catch( IOException ioe ) {
> getLogger().error( "Exception accepting connection", ioe );
> } catch( Exception e ) {
> getLogger().error( "Exception executing client connection runner: "
>+ e.getMessage() );
> }
> }
> synchronized( this ) {
> serverConnectionThread = null;
> notifyAll();
> }
> }
>
> /**
> * An inner class to provide the actual body of the thread of execution
> * that occurs upon a client connection.
> *
> * @author Andrei Ivanov
> * @author Peter M. Goldstein <[EMAIL PROTECTED]>
> */
> class ClientConnectionRunner extends AbstractLogEnabled
> implements Runnable, Component {
>
> /**
> * The Socket that this client connection is using for transport.
> */
> private Socket clientSocket;
>
> /**
> * The thread of execution associated with this client connection.
> */
> private Thread clientSocketThread;
>
> /**
> * The ConnectionHandlerFactory that generates a ConnectionHandler for
> * this client connection.
> */
> private ConnectionHandlerFactory clientConnectionHandlerFactory;
>
> /**
> * The constructor for a ClientConnectionRunner.
> *
> * @param socket the client socket associated with this
>ClientConnectionRunner
> * @param handlerFactory the factory that generates ConnectionHandlers for
>this
> * connection
> */
> public ClientConnectionRunner(Socket socket,
> ConnectionHandlerFactory handlerFactory) {
> clientSocket = socket;
> clientConnectionHandlerFactory = handlerFactory;
> }
>
> /**
> * The dispose operation that terminates the runner. Should only be
> * called by the ServerConnection that owns the ClientConnectionRunner
> */
> public void dispose() {
> synchronized( this ) {
> if (null != clientSocketThread) {
> // Execution of this block means that the run() method
> // hasn't finished yet. So we interrupt the thread
> // to terminate run() and wait for the run() method
> // to finish. The notifyAll() at the end of run() will
> // wake this thread and allow dispose() to end.
> clientSocketThread.interrupt();
> clientSocketThread = null;
> try {
> wait();
> } catch (InterruptedException ie) {
> // Expected - return from the method
> }
> }
> }
> }
>
> /**
> * Provides the body for the thread of execution dealing with a particular
>client
> * connection. An appropriate ConnectionHandler is created, applied,
>executed,
> * and released.
> */
> public void run() {
> ConnectionHandler handler = null;
> try {
> clientSocketThread = Thread.currentThread();
> ServerConnection.this.addClientConnectionRunner(this);
>
> handler = clientConnectionHandlerFactory.createConnectionHandler();
> String connectionString = null;
> if( getLogger().isDebugEnabled() ) {
> connectionString = getConnectionString();
> String message = "Starting " + connectionString;
> getLogger().debug( message );
> }
>
> handler.handleConnection(clientSocket);
>
> if( getLogger().isDebugEnabled() ) {
> String message = "Ending " + connectionString;
> getLogger().debug( message );
> }
> } catch( Exception e ) {
> getLogger().warn( "Error handling connection", e );
> } finally {
>
> // Close the underlying socket
> try {
> clientSocket.close();
> } catch( IOException ioe ) {
> getLogger().warn( "Error shutting down connection", ioe );
> }
>
> // Release the handler and kill the reference to the handler factory
> if (handler != null) {
> clientConnectionHandlerFactory.releaseConnectionHandler(
>handler );
> handler = null;
> }
> clientConnectionHandlerFactory = null;
>
> // Remove this runner from the list of active connections.
> ServerConnection.this.removeClientConnectionRunner(this);
>
> // Null out the thread, notify other threads to encourage
> // a context switch
> synchronized( this ) {
> clientSocketThread = null;
> notifyAll();
> }
> }
> }
>
> /**
> * Helper method to return a formatted string with connection transport
>information.
> *
> * @return a formatted string
> */
> private String getConnectionString() {
> if (clientSocket == null) {
> return "invalid socket";
> }
> StringBuffer connectionBuffer
> = new StringBuffer(256)
> .append("connection on ")
>
>.append(clientSocket.getLocalAddress().getHostAddress().toString())
> .append(":")
> .append(clientSocket.getLocalPort())
> .append(" from ")
>
>.append(clientSocket.getInetAddress().getHostAddress().toString())
> .append(":")
> .append(clientSocket.getPort());
> return connectionBuffer.toString();
> }
> }
> }
>
>
>
>
>
> 1.1
>jakarta-james/src/java/org/apache/james/util/connection/SimpleConnectionManager.java
>
> Index: SimpleConnectionManager.java
> ===================================================================
> /*
> * Copyright (C) The Apache Software Foundation. All rights reserved.
> *
> * This software is published under the terms of the Apache Software License
> * version 1.1, a copy of which has been included with this distribution in
> * the LICENSE file.
> */
> package org.apache.james.util.connection;
>
> import java.net.ServerSocket;
> import java.util.HashMap;
>
> import org.apache.avalon.excalibur.thread.ThreadPool;
>
> import org.apache.avalon.cornerstone.services.connection.ConnectionHandlerFactory;
> import org.apache.avalon.cornerstone.services.connection.ConnectionManager;
> import org.apache.avalon.cornerstone.services.threads.ThreadManager;
> import org.apache.avalon.framework.component.ComponentException;
> import org.apache.avalon.framework.component.ComponentManager;
> import org.apache.avalon.framework.component.Composable;
> import org.apache.avalon.framework.configuration.Configurable;
> import org.apache.avalon.framework.configuration.Configuration;
> import org.apache.avalon.framework.configuration.ConfigurationException;
>
> import org.apache.avalon.framework.activity.Disposable;
> import org.apache.avalon.framework.logger.AbstractLogEnabled;
>
>
> /**
> * An implementation of ConnectionManager that supports configurable
> * idle timeouts and a configurable value for the maximum number of
> * client connections to a particular port.
> *
> * @author Andrei Ivanov
> * @author Peter M. Goldstein <[EMAIL PROTECTED]>
> */
> public class SimpleConnectionManager extends AbstractLogEnabled
> implements ConnectionManager, Composable, Configurable, Disposable {
>
> /**
> * The default value for client socket idle timeouts. The
> * Java default is 0, meaning no timeout. That's dangerous
> * for a connection handler like this one, because it can
> * easily lead to consumption of network resources. So we
> * allow users to configure the system to allow no timeout,
> * but if no timeout is specified in the configuration, we
> * use a timeout of 5 minutes.
> */
> private static final int DEFAULT_SOCKET_TIMEOUT = 5 * 60 * 1000;
>
> /**
> * The default value for the maximum number of allowed client
> * connections.
> */
> private static final int DEFAULT_MAX_CONNECTIONS = 30;
>
> /**
> * The map of connection name / server connections managed by this connection
> * manager.
> */
> private final HashMap connectionMap = new HashMap();
>
> /**
> * The idle timeout for the individual sockets spawed from the server socket.
> */
> protected int timeout = 0;
>
> /**
> * The maximum number of client connections allowed per server connection.
> */
> protected int maxOpenConn = 0;
>
> /**
> * The ThreadManager component that is used to provide a default thread pool.
> */
> private ThreadManager threadManager;
>
> /**
> * Whether the SimpleConnectionManager has been disposed.
> */
> private volatile boolean disposed = false;
>
> /**
> * @see
>org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
> */
> public void configure(final Configuration configuration) throws
>ConfigurationException {
> timeout =
>configuration.getChild("idle-timeout").getValueAsInteger(DEFAULT_SOCKET_TIMEOUT);
> maxOpenConn =
>configuration.getChild("max-connections").getValueAsInteger(DEFAULT_MAX_CONNECTIONS);
>
> if (timeout < 0) {
> StringBuffer exceptionBuffer =
> new StringBuffer(128)
> .append("Specified socket timeout value of ")
> .append(timeout)
> .append(" is not a legal value.");
> throw new ConfigurationException(exceptionBuffer.toString());
> }
>
> if (maxOpenConn < 0) {
> StringBuffer exceptionBuffer =
> new StringBuffer(128)
> .append("Specified maximum number of open connections of ")
> .append(maxOpenConn)
> .append(" is not a legal value.");
> throw new ConfigurationException(exceptionBuffer.toString());
> }
>
> if (getLogger().isDebugEnabled()) {
> getLogger().debug("Connection timeout is "
> + (timeout == 0 ? "unlimited" :
>Long.toString(timeout)));
> getLogger().debug("The maximum number of simultaneously open
>connections is "
> + (maxOpenConn == 0 ? "unlimited" :
>Integer.toString(maxOpenConn)));
> }
> }
>
> /**
> * @see
>org.apache.avalon.framework.component.Composable#compose(ComponentManager)
> */
> public void compose(ComponentManager componentManager)
> throws ComponentException {
> threadManager = (ThreadManager)componentManager.lookup( ThreadManager.ROLE
>);
> }
>
> /**
> * Disconnects all the underlying ServerConnections
> */
> public void dispose() {
> disposed = true;
> if (getLogger().isDebugEnabled()) {
> getLogger().debug("Starting SimpleConnectionManager dispose...");
> }
> final String[] names = (String[])connectionMap.keySet().toArray( new
>String[ 0 ] );
> for( int i = 0; i < names.length; i++ ) {
> try {
> if (getLogger().isDebugEnabled()) {
> getLogger().debug("Disconnecting ServerConnection " + names[i]);
> }
> disconnect( names[ i ], true);
> } catch( final Exception e ) {
> getLogger().warn( "Error disconnecting " + names[ i ], e );
> }
> }
> if (getLogger().isDebugEnabled()) {
> getLogger().debug("Finishing SimpleConnectionManager dispose...");
> }
> }
>
> /**
> * Start managing a connection.
> * Management involves accepting connections and farming them out to threads
> * from pool to be handled.
> *
> * @param name the name of connection
> * @param socket the ServerSocket from which to
> * @param handlerFactory the factory from which to acquire handlers
> * @param threadPool the thread pool to use
> * @exception Exception if an error occurs
> */
> public void connect( String name,
> ServerSocket socket,
> ConnectionHandlerFactory handlerFactory,
> ThreadPool threadPool )
> throws Exception {
>
> if (disposed) {
> throw new IllegalStateException("Connection manager has already been
>shutdown.");
> }
> if( null != connectionMap.get( name ) ) {
> throw new IllegalArgumentException( "Connection already exists with
>name " +
> name );
> }
>
> ServerConnection runner = new ServerConnection(socket, handlerFactory,
>threadPool, timeout, maxOpenConn);
> setupLogger( runner );
> connectionMap.put( name, runner );
> threadPool.execute(runner);
> }
>
> /**
> * Start managing a connection.
> * This is similar to other connect method except that it uses default thread
>pool.
> *
> * @param name the name of connection
> * @param socket the ServerSocket from which to
> * @param handlerFactory the factory from which to acquire handlers
> * @exception Exception if an error occurs
> */
> public void connect( String name,
> ServerSocket socket,
> ConnectionHandlerFactory handlerFactory )
> throws Exception
> {
> connect( name, socket, handlerFactory, threadManager.getDefaultThreadPool()
>);
> }
>
>
> /**
> * This shuts down all handlers and socket, waiting for each to gracefully
>shutdown.
> *
> * @param name the name of connection
> * @exception Exception if an error occurs
> */
> public void disconnect( final String name )
> throws Exception {
>
> disconnect( name, false );
> }
>
> /**
> * This shuts down a connection.
> * If tearDown is true then it will forcefully the connection and try
> * to return as soon as possible. Otherwise it will behave the same as
> * void disconnect( String name );
> *
> * @param name the name of connection
> * @param tearDown if true will forcefully tear down all handlers
> * @exception Exception if an error occurs
> */
> public void disconnect( final String name, final boolean tearDown )
> throws Exception {
>
> ServerConnection connection = (ServerConnection)connectionMap.remove( name
>);
> if( null == connection ) {
> throw new IllegalArgumentException( "No such connection with name " +
> name );
> }
>
> // TODO: deal with tear down
> connection.dispose();
> }
>
> }
>
>
>
> 1.1
>jakarta-james/src/java/org/apache/james/util/connection/SimpleConnectionManager.xinfo
>
> Index: SimpleConnectionManager.xinfo
> ===================================================================
> <?xml version="1.0"?>
>
>
> <blockinfo>
>
> <!-- section to describe block -->
> <block>
> <name>SimpleConnectionManager</name>
> <version>1.0</version>
> </block>
>
> <!-- services that are offered by this block -->
> <services>
> <service
>name="org.apache.avalon.cornerstone.services.connection.ConnectionManager"/>
> </services>
>
> <!-- services that are required by this block -->
> <dependencies>
> <dependency>
> <service name="org.apache.avalon.cornerstone.services.threads.ThreadManager"/>
> </dependency>
> </dependencies>
>
> </blockinfo>
>
>
>
> 1.1
>jakarta-james/src/java/org/apache/james/util/connection/package.html
>
> Index: package.html
> ===================================================================
> <body>
> <p>Provides classes that implement Avalon Cornerstone connection services. It
>would be desirable to have these classes eventually moved to Cornerstone.</p>
> </body>
>
>
>
>
>--
>To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
>For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
>
>
>
>
Index: src/conf/james-config.xml
===================================================================
RCS file: /home/cvspublic/jakarta-james/src/conf/james-config.xml,v
retrieving revision 1.34
diff -u -r1.34 james-config.xml
--- src/conf/james-config.xml 7 Oct 2002 07:16:46 -0000 1.34
+++ src/conf/james-config.xml 8 Oct 2002 21:52:47 -0000
@@ -589,8 +589,8 @@
<!-- serve to limit the number of open connections. -->
<!-- -->
<connections>
- <idle-timeout>300000<idle-timeout>
- <max-connections>30<max-connections>
+ <idle-timeout>300000</idle-timeout>
+ <max-connections>30</max-connections>
</connections>
<!-- The Socket Manager block -->
<!-- -->
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>