View Javadoc
1 /*** 2 * Redistribution and use of this software and associated documentation 3 * ("Software"), with or without modification, are permitted provided 4 * that the following conditions are met: 5 * 6 * 1. Redistributions of source code must retain copyright 7 * statements and notices. Redistributions must also contain a 8 * copy of this document. 9 * 10 * 2. Redistributions in binary form must reproduce the 11 * above copyright notice, this list of conditions and the 12 * following disclaimer in the documentation and/or other 13 * materials provided with the distribution. 14 * 15 * 3. The name "Exolab" must not be used to endorse or promote 16 * products derived from this Software without prior written 17 * permission of Exoffice Technologies. For written permission, 18 * please contact info@exolab.org. 19 * 20 * 4. Products derived from this Software may not be called "Exolab" 21 * nor may "Exolab" appear in their names without prior written 22 * permission of Exoffice Technologies. Exolab is a registered 23 * trademark of Exoffice Technologies. 24 * 25 * 5. Due credit should be given to the Exolab Project 26 * (http://www.exolab.org/). 27 * 28 * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 32 * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 39 * OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * Copyright 2000-2003 (C) Exoffice Technologies Inc. All Rights Reserved. 42 * 43 * $Id: JmsServerConnectionManager.java,v 1.10 2003/08/17 01:32:26 tanderson Exp $ 44 * 45 * Date Author Changes 46 * 04/07/2000 jima Created 47 */ 48 package org.exolab.jms.server; 49 50 51 import java.util.Collections; 52 import java.util.HashMap; 53 import java.util.Iterator; 54 import java.util.Map; 55 56 import javax.jms.JMSException; 57 import javax.jms.JMSSecurityException; 58 59 import org.apache.commons.logging.Log; 60 import org.apache.commons.logging.LogFactory; 61 62 import org.exolab.core.foundation.HandleIfc; 63 import org.exolab.jms.authentication.AuthenticationMgr; 64 import org.exolab.jms.events.BasicEventManager; 65 import org.exolab.jms.events.Event; 66 import org.exolab.jms.events.EventHandler; 67 import org.exolab.jms.events.IllegalEventDefinedException; 68 69 70 /*** 71 * The connection manager is responsible for managing all connections to the 72 * JmsServer. The connection manager is a singleton (at this point anyway) 73 * that is accessible through the instance class method. It is also responsible 74 * for holding a list of connections. 75 * <p> 76 * A client uses a client identifier to create a connection and a connection 77 * type to identify the connection type- queue or topic. 78 * <p> 79 * TODO: 80 * Look at leasing connections and timing them out. 81 * 82 * @version $Revision: 1.10 $ $Date: 2003/08/17 01:32:26 $ 83 * @author <a href="mailto:jima@exoffice.com">Jim Alateras</a> 84 * @see JmsServerConnection 85 */ 86 public class JmsServerConnectionManager 87 implements EventHandler { 88 89 /*** 90 * The interval that garbage collection on the connection manager is 91 * executed to clean up abnormally terminated connections. This defaults 92 * to every minute. 93 */ 94 private long _gcInterval = 60 * 1000; 95 96 /*** 97 * holds a list of active connections 98 */ 99 private Map _connections = null; 100 101 /*** 102 * Holds the singleton instance of the class 103 */ 104 private static JmsServerConnectionManager _instance = null; 105 106 /*** 107 * Used to stop multiple threads trying to init the singleton 108 */ 109 private static final Object _initializer = new Object(); 110 111 /*** 112 * This is the event that is fired to initiate garbage collection 113 * in the database 114 */ 115 private static final int CONNECTION_GC_EVENT = 1; 116 117 /*** 118 * The logger 119 */ 120 private static final Log _log = 121 LogFactory.getLog(JmsServerConnectionManager.class); 122 123 /*** 124 * The private constructor initialises the manager. 125 */ 126 private JmsServerConnectionManager() { 127 _connections = Collections.synchronizedMap(new HashMap()); 128 129 // check to see whether the gcInterval has been overriden 130 if (System.getProperty("org.exolab.jms.connection.gcInterval") != null) { 131 try { 132 _gcInterval = Long.parseLong(System.getProperty( 133 "org.exolab.jms.connection.gcInterval")); 134 } catch (Exception ignore) { 135 // if the gcinterval is incorrectly specified then use 136 // the default 137 } 138 } 139 140 if (_gcInterval > 0) { 141 registerEvent(); 142 } 143 } 144 145 /*** 146 * The static method returns the singleton instance of the 147 * JmsConnectionManager. If one does not exist it is created prior to 148 * returning. 149 * 150 * @return JmsConnectionManager 151 */ 152 public static JmsServerConnectionManager instance() { 153 154 if (_instance == null) { 155 synchronized (_initializer) { 156 if (_instance == null) { 157 _instance = new JmsServerConnectionManager(); 158 } 159 } 160 } 161 162 return _instance; 163 } 164 165 /*** 166 * Create a connection with the specified client id. If the client already 167 * has an open connection then simply return a reference to this connection 168 * If a connection already exists for the specified client identity then 169 * simply return the exisiting connection 170 * 171 * @param id the client identity 172 * @param username the client's username 173 * @param password the client's password 174 * @return a new connection 175 * @throws JMSSecurityException if the client cannot be authenticated 176 * @throws JMSException if the connection cannot be created 177 */ 178 public JmsServerConnection createConnection(String id, String username, 179 String password) 180 throws JMSSecurityException, JMSException { 181 182 if (!AuthenticationMgr.instance().validateUser(username, password)) { 183 throw new JMSSecurityException("Failed to authenticate user " + 184 username); 185 } 186 187 JmsServerConnection result = (JmsServerConnection) _connections.get(id); 188 if (result == null) { 189 result = new JmsServerConnection(id); 190 191 // the connection is created in the stopped mode and is the 192 // added the list of connections 193 _connections.put(id, result); 194 } 195 196 return result; 197 } 198 199 /*** 200 * Return an Enumeration of all the connections currently registered with 201 * the connection manager 202 * 203 * @return Iterator 204 */ 205 public Iterator getConnections() { 206 return _connections.values().iterator(); 207 } 208 209 /*** 210 * Return the connection associated with a particular client identity. If 211 * such a connection does not exist then return null 212 * 213 * @param id identity of the client 214 * @return JmsConnection associated connection or null 215 */ 216 public JmsServerConnection getConnection(String id) { 217 return (JmsServerConnection) _connections.get(id); 218 } 219 220 /*** 221 * Close the connection associated with a particular client identity. If 222 * a connection for the client does not exist then do nothing. 223 * 224 * @param id identity of the client 225 */ 226 public void closeConnection(String id) { 227 JmsServerConnection connection = 228 (JmsServerConnection) _connections.remove(id); 229 230 if (connection != null) { 231 connection.close(); 232 } 233 } 234 235 // implementation of EventHandler.handleEvent 236 public void handleEvent(int event, Object callback, long time) { 237 try { 238 Object[] ids = _connections.keySet().toArray(); 239 for (int index = 0; index < ids.length; index++) { 240 JmsServerConnection connection = 241 (JmsServerConnection) _connections.get(ids[index]); 242 if ((connection != null) && 243 (!connection.isClientEndpointActive())) { 244 _log.info("Cleaning up connection " + ids[index]); 245 closeConnection((String) ids[index]); 246 } 247 } 248 } finally { 249 registerEvent(); 250 } 251 } 252 253 // implementation of EventHandler.getHandle 254 public HandleIfc getHandle() { 255 // not used 256 return null; 257 } 258 259 /*** 260 * Register an event with the event service. The event will tell the 261 * connection manager to initiate garbage collection 262 */ 263 private void registerEvent() { 264 try { 265 BasicEventManager.instance().registerEventRelative( 266 new Event(CONNECTION_GC_EVENT, this, null), 267 _gcInterval); 268 } catch (IllegalEventDefinedException exception) { 269 _log.error("JmsServerConnectionManager.registerEvent failed", 270 exception); 271 } 272 } 273 274 } //-- JmsServerConnectionManager 275

This page was automatically generated by Maven