1 17 18 package org.apache.james.util.connection; 19 20 import java.net.ServerSocket ; 21 import java.util.HashMap ; 22 23 import org.apache.avalon.excalibur.thread.ThreadPool; 24 25 import org.apache.avalon.cornerstone.services.connection.ConnectionHandlerFactory; 26 import org.apache.james.services.JamesConnectionManager; 27 import org.apache.avalon.cornerstone.services.threads.ThreadManager; 28 import org.apache.avalon.framework.activity.Initializable; 29 import org.apache.avalon.framework.component.ComponentException; 30 import org.apache.avalon.framework.component.ComponentManager; 31 import org.apache.avalon.framework.component.Composable; 32 import org.apache.avalon.framework.configuration.Configurable; 33 import org.apache.avalon.framework.configuration.Configuration; 34 import org.apache.avalon.framework.configuration.ConfigurationException; 35 36 import org.apache.avalon.framework.activity.Disposable; 37 import org.apache.avalon.framework.logger.AbstractLogEnabled; 38 39 40 46 public class SimpleConnectionManager extends AbstractLogEnabled 47 implements JamesConnectionManager, Composable, Configurable, Disposable { 48 49 58 private static final int DEFAULT_SOCKET_TIMEOUT = 5 * 60 * 1000; 59 60 64 private static final int DEFAULT_MAX_CONNECTIONS = 30; 65 66 70 private final HashMap connectionMap = new HashMap (); 71 72 75 protected int timeout = 0; 76 77 80 protected int maxOpenConn = 0; 81 82 85 private ThreadManager threadManager; 86 87 90 private volatile boolean disposed = false; 91 92 95 public void configure(final Configuration configuration) throws ConfigurationException { 96 timeout = configuration.getChild("idle-timeout").getValueAsInteger(DEFAULT_SOCKET_TIMEOUT); 97 maxOpenConn = configuration.getChild("max-connections").getValueAsInteger(DEFAULT_MAX_CONNECTIONS); 98 99 if (timeout < 0) { 100 StringBuffer exceptionBuffer = 101 new StringBuffer (128) 102 .append("Specified socket timeout value of ") 103 .append(timeout) 104 .append(" is not a legal value."); 105 throw new ConfigurationException(exceptionBuffer.toString()); 106 } 107 108 if (maxOpenConn < 0) { 109 StringBuffer exceptionBuffer = 110 new StringBuffer (128) 111 .append("Specified maximum number of open connections of ") 112 .append(maxOpenConn) 113 .append(" is not a legal value."); 114 throw new ConfigurationException(exceptionBuffer.toString()); 115 } 116 117 if (getLogger().isDebugEnabled()) { 118 getLogger().debug("Connection timeout is " 119 + (timeout == 0 ? "unlimited" : Long.toString(timeout))); 120 getLogger().debug("The maximum number of simultaneously open connections is " 121 + (maxOpenConn == 0 ? "unlimited" : Integer.toString(maxOpenConn))); 122 } 123 } 124 125 128 public void compose(ComponentManager componentManager) 129 throws ComponentException { 130 threadManager = (ThreadManager)componentManager.lookup( ThreadManager.ROLE ); 131 } 132 133 136 public void dispose() { 137 disposed = true; 138 if (getLogger().isDebugEnabled()) { 139 getLogger().debug("Starting SimpleConnectionManager dispose..."); 140 } 141 final String [] names = (String [])connectionMap.keySet().toArray( new String [ 0 ] ); 142 for( int i = 0; i < names.length; i++ ) { 143 try { 144 if (getLogger().isDebugEnabled()) { 145 getLogger().debug("Disconnecting ServerConnection " + names[i]); 146 } 147 disconnect( names[ i ], true); 148 } catch( final Exception e ) { 149 getLogger().warn( "Error disconnecting " + names[ i ], e ); 150 } 151 } 152 if (getLogger().isDebugEnabled()) { 153 getLogger().debug("Finishing SimpleConnectionManager dispose..."); 154 } 155 } 156 157 169 public void connect( String name, 170 ServerSocket socket, 171 ConnectionHandlerFactory handlerFactory, 172 ThreadPool threadPool, 173 int maxOpenConnections ) 174 throws Exception { 175 176 if (disposed) { 177 throw new IllegalStateException ("Connection manager has already been shutdown."); 178 } 179 if( null != connectionMap.get( name ) ) { 180 throw new IllegalArgumentException ( "Connection already exists with name " + 181 name ); 182 } 183 if (maxOpenConnections < 0) { 184 throw new IllegalArgumentException ( "The maximum number of client connections per server socket cannot be less that zero."); 185 } 186 ServerConnection runner = new ServerConnection(socket, handlerFactory, threadPool, timeout, maxOpenConnections); 187 setupLogger( runner ); 188 if (runner instanceof Initializable) { 189 ((Initializable)runner).initialize(); 190 } 191 connectionMap.put( name, runner ); 192 threadPool.execute(runner); 193 } 194 195 206 public void connect( String name, 207 ServerSocket socket, 208 ConnectionHandlerFactory handlerFactory, 209 ThreadPool threadPool ) 210 throws Exception { 211 212 connect(name, socket, handlerFactory, threadPool, maxOpenConn); 213 } 214 215 224 public void connect( String name, 225 ServerSocket socket, 226 ConnectionHandlerFactory handlerFactory ) 227 throws Exception { 228 connect( name, socket, handlerFactory, threadManager.getDefaultThreadPool() ); 229 } 230 231 241 public void connect( String name, 242 ServerSocket socket, 243 ConnectionHandlerFactory handlerFactory, 244 int maxOpenConnections ) 245 throws Exception { 246 connect( name, socket, handlerFactory, threadManager.getDefaultThreadPool(), maxOpenConnections ); 247 } 248 249 255 public void disconnect( final String name ) 256 throws Exception { 257 disconnect( name, false ); 258 } 259 260 270 public void disconnect( final String name, final boolean tearDown ) 271 throws Exception { 272 273 ServerConnection connection = (ServerConnection)connectionMap.remove( name ); 274 if( null == connection ) { 275 throw new IllegalArgumentException ( "No such connection with name " + 276 name ); 277 } 278 279 connection.dispose(); 281 } 282 283 289 public int getMaximumNumberOfOpenConnections() { 290 return maxOpenConn; 291 } 292 } 293 | Popular Tags |