mcconnell 2004/03/16 06:17:55
Added: cornerstone/connection/api .cvsignore project.xml
cornerstone/connection/api/src/java/org/apache/avalon/cornerstone/services/connection
ConnectionHandler.java
ConnectionHandlerFactory.java
ConnectionManager.java package.html
cornerstone/connection/impl .cvsignore maven.xml
project.properties project.xml
cornerstone/connection/impl/conf block.xml
cornerstone/connection/impl/src/java/org/apache/avalon/cornerstone/blocks/connection
Connection.java DefaultConnectionManager.java
DefaultConnectionManager.xinfo package.html
Log:
Migrate connection to use the avalon tags (while maintaining phoenix legacy). Bumped
impl version reflecting shift in dependency from deprecated excalibur versions to
clean excalibur versions. Moved implementation factrory classes from api space to impl
space.
Revision Changes Path
1.1 avalon-components/cornerstone/connection/api/.cvsignore
Index: .cvsignore
===================================================================
maven.log
velocity.log
build.properties
target
maven.log
1.1 avalon-components/cornerstone/connection/api/project.xml
Index: project.xml
===================================================================
<?xml version="1.0" encoding="ISO-8859-1"?>
<project>
<extend>${basedir}/../../project.xml</extend>
<groupId>cornerstone-connection</groupId>
<id>cornerstone-connection-api</id>
<name>Cornerstone Connection API</name>
<!--
bump to SNAPSHOT in prep for a 2.0 relase because the API references
cornerstone threads SNAPSHOT which references excalibur thread SNAPSHOT
which is bumped due to removal of deprecated interface references.
-->
<currentVersion>SNAPSHOT</currentVersion>
<package>org.apache.avalon.cornerstone.services.connection</package>
<inceptionYear>2001</inceptionYear>
<shortDescription>Cornerstone Connection API</shortDescription>
<dependencies>
<!-- cornerstone api dependencies -->
<dependency>
<groupId>cornerstone-sockets</groupId>
<artifactId>cornerstone-sockets-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>cornerstone-threads</groupId>
<artifactId>cornerstone-threads-api</artifactId>
<version>SNAPSHOT</version>
</dependency>
<!-- excalibur api dependencies -->
<dependency>
<groupId>avalon-framework</groupId>
<artifactId>avalon-framework-api</artifactId>
<version>4.1.5</version>
</dependency>
<dependency>
<groupId>excalibur-pool</groupId>
<artifactId>excalibur-pool-api</artifactId>
<version>SNAPSHOT</version>
</dependency>
<dependency>
<groupId>excalibur-thread</groupId>
<artifactId>excalibur-thread-api</artifactId>
<version>SNAPSHOT</version>
</dependency>
</dependencies>
</project>
1.1
avalon-components/cornerstone/connection/api/src/java/org/apache/avalon/cornerstone/services/connection/ConnectionHandler.java
Index: ConnectionHandler.java
===================================================================
/*
* Copyright 1999-2004 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.avalon.cornerstone.services.connection;
import java.io.IOException;
import java.net.ProtocolException;
import java.net.Socket;
/**
* This interface is the way in which incoming connections are processed.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
*/
public interface ConnectionHandler
{
/**
* Processes connections as they occur. The handler should not
* close the <tt>connection</tt>, the caller will do that.
*
* @param connection the connection
* @exception IOException if an error reading from socket occurs
* @exception ProtocolException if an error handling connection occurs
*/
void handleConnection( Socket connection )
throws IOException, ProtocolException;
}
1.1
avalon-components/cornerstone/connection/api/src/java/org/apache/avalon/cornerstone/services/connection/ConnectionHandlerFactory.java
Index: ConnectionHandlerFactory.java
===================================================================
/*
* Copyright 1999-2004 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.avalon.cornerstone.services.connection;
/**
* This interface is the way in which handlers are created.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
*/
public interface ConnectionHandlerFactory
{
/**
* Construct an appropriate ConnectionHandler.
*
* @return the new ConnectionHandler
* @exception Exception if an error occurs
*/
ConnectionHandler createConnectionHandler()
throws Exception;
/**
* Release a previously created ConnectionHandler.
* e.g. for spooling.
*/
void releaseConnectionHandler( ConnectionHandler connectionHandler );
}
1.1
avalon-components/cornerstone/connection/api/src/java/org/apache/avalon/cornerstone/services/connection/ConnectionManager.java
Index: ConnectionManager.java
===================================================================
/*
* Copyright 1999-2004 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.avalon.cornerstone.services.connection;
import java.net.ServerSocket;
import org.apache.excalibur.thread.ThreadPool;
/**
* This is the service through which ConnectionManagement occurs.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
*/
public interface ConnectionManager
{
String ROLE = ConnectionManager.class.getName();
/**
* 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 aquire handlers
* @param threadPool the thread pool to use
* @exception Exception if an error occurs
*/
void connect( String name,
ServerSocket socket,
ConnectionHandlerFactory handlerFactory,
ThreadPool threadPool )
throws Exception;
/**
* 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 aquire handlers
* @exception Exception if an error occurs
*/
void connect( String name,
ServerSocket socket,
ConnectionHandlerFactory handlerFactory )
throws Exception;
/**
* 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
*/
void disconnect( String name )
throws Exception;
/**
* This shuts down all handlers and socket.
* If tearDown is true then it will forcefully shutdown all connections 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
*/
void disconnect( String name, boolean tearDown )
throws Exception;
}
1.1
avalon-components/cornerstone/connection/api/src/java/org/apache/avalon/cornerstone/services/connection/package.html
Index: package.html
===================================================================
<body>
Defintion of the connection service.
</body>
1.1 avalon-components/cornerstone/connection/impl/.cvsignore
Index: .cvsignore
===================================================================
maven.log
velocity.log
build.properties
target
maven.log
1.1 avalon-components/cornerstone/connection/impl/maven.xml
Index: maven.xml
===================================================================
<project default="jar:install-snapshot">
<postGoal name="java:prepare-filesystem">
<attainGoal name="avalon:meta"/>
</postGoal>
</project>
1.1 avalon-components/cornerstone/connection/impl/project.properties
Index: project.properties
===================================================================
#
# set the meta-info postfix to xtype so we pick up classic avalon
# ahead of phoneix legacy content
#
avalon.meta.type.postfix=xtype
1.1 avalon-components/cornerstone/connection/impl/project.xml
Index: project.xml
===================================================================
<?xml version="1.0" encoding="ISO-8859-1"?>
<project>
<extend>${basedir}/../../project.xml</extend>
<groupId>cornerstone-connection</groupId>
<id>cornerstone-connection-impl</id>
<name>Cornerstone Connection Manager Implementation</name>
<!--
bump to SNAPSHOT in anticipation of a 2.0 release due to
link to excalibur threads API (without deprricated content) and the
transfer of factory classes from the api to the implementation.
-->
<currentVersion>SNAPSHOT</currentVersion>
<package>org.apache.avalon.cornerstone</package>
<inceptionYear>2001</inceptionYear>
<shortDescription>Cornerstone Connections</shortDescription>
<dependencies>
<!-- cornerstone api dependencies -->
<dependency>
<groupId>cornerstone-connection</groupId>
<artifactId>cornerstone-connection-api</artifactId>
<version>SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cornerstone-sockets</groupId>
<artifactId>cornerstone-sockets-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>cornerstone-threads</groupId>
<artifactId>cornerstone-threads-api</artifactId>
<version>SNAPSHOT</version>
</dependency>
<!-- excalibur api dependencies -->
<dependency>
<groupId>excalibur-thread</groupId>
<artifactId>excalibur-thread-api</artifactId>
<version>SNAPSHOT</version>
</dependency>
<!-- avalon dependencies -->
<dependency>
<groupId>avalon-framework</groupId>
<artifactId>avalon-framework-api</artifactId>
<version>4.1.5</version>
</dependency>
<dependency>
<groupId>avalon-framework</groupId>
<artifactId>avalon-framework-impl</artifactId>
<version>4.1.5</version>
</dependency>
<!-- pre JDK 1.4 dependencies -->
<dependency>
<id>xml-apis</id>
<version>1.0.b2</version>
<url>http://xml.apache.org/xerces2-j/</url>
</dependency>
<dependency>
<id>xerces</id>
<version>2.2.1</version>
<url>http://xml.apache.org/xerces2-j/</url>
</dependency>
</dependencies>
</project>
1.1 avalon-components/cornerstone/connection/impl/conf/block.xml
Index: block.xml
===================================================================
<!--
Thread Block deployment directive.
-->
<container name="connection">
<services>
<service
type="org.apache.avalon.cornerstone.services.connection.ConnectionManager">
<source>manager</source>
</service>
</services>
<classloader>
<classpath>
<repository>
<resource id="avalon-framework:avalon-framework-impl" version="4.1.5"/>
<resource id="excalibur-thread:excalibur-thread" version="1.1.1"/>
<resource id="cornerstone-threads:cornerstone-threads-api" version="1.0"/>
<resource id="cornerstone-sockets:cornerstone-sockets-api" version="1.0"/>
<resource id="cornerstone-connection:cornerstone-connection-api"
version="1.0"/>
<resource id="cornerstone-connection:cornerstone-connection-impl"
version="1.0"/>
</repository>
</classpath>
</classloader>
<component name="manager"
class="org.apache.avalon.cornerstone.blocks.connection.DefaultConnectionManager"
activation="startup">
<configuration>
<idle-timeout>300000</idle-timeout>
<max-connections>30</max-connections>
</configuration>
</component>
</container>
1.1
avalon-components/cornerstone/connection/impl/src/java/org/apache/avalon/cornerstone/blocks/connection/Connection.java
Index: Connection.java
===================================================================
/*
* Copyright 1999-2004 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.avalon.cornerstone.blocks.connection;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import org.apache.avalon.cornerstone.services.connection.ConnectionHandler;
import org.apache.avalon.cornerstone.services.connection.ConnectionHandlerFactory;
import org.apache.excalibur.thread.ThreadPool;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
/**
* Support class for the DefaultConnectionManager.
* This manages an individual ServerSocket.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
*/
class Connection
extends AbstractLogEnabled
implements Runnable
{
private final ServerSocket m_serverSocket;
private final ConnectionHandlerFactory m_handlerFactory;
private final ThreadPool m_threadPool;
private final Vector m_runners = new Vector();
//Need to synchronize access to thread object
private Thread m_thread;
public Connection( final ServerSocket serverSocket,
final ConnectionHandlerFactory handlerFactory,
final ThreadPool threadPool )
{
m_serverSocket = serverSocket;
m_handlerFactory = handlerFactory;
m_threadPool = threadPool;
}
public void dispose()
throws Exception
{
synchronized( this )
{
if( null != m_thread )
{
final Thread thread = m_thread;
m_thread = null;
thread.interrupt();
//Can not join as threads are part of pool
//and will never finish
//m_thread.join();
wait( /*1000*/ );
}
}
final Iterator runners = m_runners.iterator();
while( runners.hasNext() )
{
final ConnectionRunner runner = (ConnectionRunner)runners.next();
runner.dispose();
}
m_runners.clear();
}
public void run()
{
m_thread = Thread.currentThread();
while( null != m_thread && !Thread.interrupted() )
{
//synchronized( this )
//{
//if( null == m_thread ) break;
//}
try
{
final Socket socket = m_serverSocket.accept();
final ConnectionRunner runner =
new ConnectionRunner( socket, m_runners, m_handlerFactory );
setupLogger( runner );
m_threadPool.execute( runner );
}
catch( final InterruptedIOException iioe )
{
//Consume exception
}
catch( final IOException ioe )
{
final String message = "Exception accepting connection";
getLogger().error( message, ioe );
}
catch( final Exception e )
{
final String message = "Exception executing runner";
getLogger().error( message, e );
}
}
synchronized( this )
{
notifyAll();
m_thread = null;
}
}
}
class ConnectionRunner
extends AbstractLogEnabled
implements Runnable
{
private Socket m_socket;
private Thread m_thread;
private List m_runners;
private ConnectionHandlerFactory m_handlerFactory;
private boolean m_finished;
ConnectionRunner( final Socket socket,
final List runners,
final ConnectionHandlerFactory handlerFactory )
{
m_socket = socket;
m_runners = runners;
m_handlerFactory = handlerFactory;
}
public void dispose()
throws Exception
{
synchronized( this )
{
m_finished = true;
if( null != m_thread )
{
m_thread.interrupt();
m_thread = null;
//Can not join as threads are part of pool
//and will never finish
//m_thread.join();
wait( /*1000*/ );
}
}
}
public void run()
{
//Synchronized section to guard against
//dispose() being called before thread is
//run and reaches next section
synchronized( this )
{
if( m_finished )
{
shutdownSocket();
return;
}
m_thread = Thread.currentThread();
m_runners.add( this );
}
ConnectionHandler handler = null;
try
{
debugBanner( true );
handler = m_handlerFactory.createConnectionHandler();
handler.handleConnection( m_socket );
debugBanner( false );
}
catch( final Exception e )
{
final String message = "Error handling connection";
getLogger().warn( message, e );
}
if( null != handler )
{
m_handlerFactory.releaseConnectionHandler( handler );
}
shutdownSocket();
//Synchronized section to make sure that thread
//in dispose() will not hang due to race conditions
synchronized( this )
{
m_thread = null;
m_runners.remove( this );
notifyAll();
}
}
/**
* Print out debug banner indicating that handling of a connection
* is starting or ending.
*
* @param starting true if starting, false othrewise
*/
private void debugBanner( final boolean starting )
{
if( getLogger().isDebugEnabled() )
{
final String prefix = ( starting ) ? "Starting" : "Ending";
final String message =
prefix + " connection on " +
m_socket.getInetAddress().getHostAddress();
getLogger().debug( message );
}
}
/**
* Utility method for shutting down associated socket.
*/
private void shutdownSocket()
{
try
{
m_socket.close();
}
catch( final IOException ioe )
{
final String message = "Error shutting down connection";
getLogger().warn( message, ioe );
}
}
}
1.1
avalon-components/cornerstone/connection/impl/src/java/org/apache/avalon/cornerstone/blocks/connection/DefaultConnectionManager.java
Index: DefaultConnectionManager.java
===================================================================
/*
* Copyright 1999-2004 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.avalon.cornerstone.blocks.connection;
import java.net.ServerSocket;
import java.util.HashMap;
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.excalibur.thread.ThreadPool;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
/**
* This is the service through which ConnectionManagement occurs.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
* @avalon.component name="connection-manager" lifestyle="singleton"
* @avalon.service
type="org.apache.avalon.cornerstone.services.connection.ConnectionManager"
*/
public class DefaultConnectionManager
extends AbstractLogEnabled
implements ConnectionManager, Serviceable, Disposable
{
private final HashMap m_connections = new HashMap();
private ThreadManager m_threadManager;
/**
* @avalon.dependency
type="org.apache.avalon.cornerstone.services.threads.ThreadManager"
*/
public void service( final ServiceManager serviceManager )
throws ServiceException
{
m_threadManager = (ThreadManager)serviceManager.lookup( ThreadManager.ROLE );
}
public void dispose()
{
if( getLogger().isDebugEnabled() )
{
getLogger().debug( "disposal" );
}
final String[] names = (String[])m_connections.keySet().toArray( new String[
0 ] );
for( int i = 0; i < names.length; i++ )
{
try
{
disconnect( names[ i ] );
}
catch( final Exception e )
{
final String message = "Error disconnecting " + names[ i ];
getLogger().warn( message, e );
}
}
}
/**
* 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 aquire handlers
* @param threadPool the thread pool to use
* @exception Exception if an error occurs
*/
public synchronized void connect( String name,
ServerSocket socket,
ConnectionHandlerFactory handlerFactory,
ThreadPool threadPool )
throws Exception
{
if( null != m_connections.get( name ) )
{
final String message = "Connection already exists with name " + name;
throw new IllegalArgumentException( message );
}
//Make sure timeout is specified for socket.
if( 0 == socket.getSoTimeout() )
{
socket.setSoTimeout( 500 );
}
final Connection runner =
new Connection( socket, handlerFactory, threadPool );
setupLogger( runner );
m_connections.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 aquire handlers
* @exception Exception if an error occurs
*/
public void connect( String name,
ServerSocket socket,
ConnectionHandlerFactory handlerFactory )
throws Exception
{
connect( name, socket, handlerFactory,
m_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 all handlers and socket.
* If tearDown is true then it will forcefully shutdown all connections 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 synchronized void disconnect( final String name, final boolean tearDown )
throws Exception
{
final Connection connection = (Connection)m_connections.remove( name );
if( connection != null )
{
//TODO: Stop ignoring tearDown
connection.dispose();
}
else
{
final String error =
"Invalid request for the disconnection of an unrecognized connection
name: "
+ name;
throw new IllegalArgumentException( error );
}
}
}
1.1
avalon-components/cornerstone/connection/impl/src/java/org/apache/avalon/cornerstone/blocks/connection/DefaultConnectionManager.xinfo
Index: DefaultConnectionManager.xinfo
===================================================================
<?xml version="1.0"?>
<!DOCTYPE blockinfo PUBLIC "-//PHOENIX/Block Info DTD Version 1.0//EN"
"http://jakarta.apache.org/avalon/dtds/phoenix/blockinfo_1_0.dtd">
<blockinfo>
<block>
<version>1.0</version>
</block>
<services>
<service
name="org.apache.avalon.cornerstone.services.connection.ConnectionManager"/>
</services>
<dependencies>
<dependency>
<service name="org.apache.avalon.cornerstone.services.threads.ThreadManager"
version="1.0"/>
</dependency>
</dependencies>
</blockinfo>
1.1
avalon-components/cornerstone/connection/impl/src/java/org/apache/avalon/cornerstone/blocks/connection/package.html
Index: package.html
===================================================================
<body>
Default implementation of a connection manager.
</body>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]