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 * Date Author Changes
44 * 04/07/2000 jima Created
45 */
46 package org.exolab.jms.server;
47
48
49 import java.util.Collections;
50 import java.util.HashMap;
51 import java.util.Iterator;
52 import java.util.Map;
53
54 import javax.jms.JMSException;
55 import javax.jms.JMSSecurityException;
56
57 import org.apache.commons.logging.Log;
58 import org.apache.commons.logging.LogFactory;
59
60 import org.exolab.core.foundation.HandleIfc;
61 import org.exolab.jms.authentication.AuthenticationMgr;
62 import org.exolab.jms.events.BasicEventManager;
63 import org.exolab.jms.events.Event;
64 import org.exolab.jms.events.EventHandler;
65 import org.exolab.jms.events.IllegalEventDefinedException;
66
67
68 /***
69 * The admin connection manager is responsible for managing all admin
70 * connections to the JmsServer.
71 * The connection manager is a singleton (at this point anyway)
72 * that is accessible through the instance class method. It is also responsible
73 * for holding a list of adminconnections.
74 *
75 * @version $Revision: 1.2 $ $Date: 2003/08/07 13:33:08 $
76 * @author <a href="mailto:knut@lerpold.no">Knut Lerpold</a>
77 * @see org.exolab.jms.server.AdminConnection
78 */
79 public class AdminConnectionManager implements EventHandler {
80
81 /***
82 * The interval that garbage collection on the connection manager is
83 * executed to clean up abnormally terminated connections. This defaults
84 * to every minute.
85 */
86 private long _gcInterval = 60 * 1000;
87
88 /***
89 * holds a list of active connections
90 */
91 private Map _connections = null;
92
93 /***
94 * Holds the singleton instance of the class
95 */
96 private static AdminConnectionManager _instance = null;
97
98 /***
99 * Used to stop multiple threads trying to init the singleton
100 */
101 private static final Object _initializer = new Object();
102
103 /***
104 * This is the event that is fired to initiate garbage collection
105 * in the database
106 */
107 private static final int CONNECTION_GC_EVENT = 1;
108
109 /***
110 * The logger
111 */
112 private static final Log _log =
113 LogFactory.getLog(AdminConnectionManager.class);
114
115 /***
116 * The private constructor initialises the manager.
117 */
118 private AdminConnectionManager() {
119 _connections = Collections.synchronizedMap(new HashMap());
120
121 // check to see whether the gcInterval has been overriden
122 if (System.getProperty("org.exolab.jms.connection.gcInterval")
123 != null) {
124 try {
125 _gcInterval = Long.parseLong(System.getProperty(
126 "org.exolab.jms.connection.gcInterval"));
127 } catch (Exception ignore) {
128 // if the gcinterval is incorrectly specified then use
129 // the default
130 }
131 }
132
133 if (_gcInterval > 0) {
134 registerEvent();
135 }
136 }
137
138 /***
139 * The static method returns the singleton instance of the
140 * AdminConnectionManager. If one does not exist it is created prior to
141 * returning.
142 *
143 * @return AdminConnectionManager
144 */
145 public static AdminConnectionManager instance() {
146
147 if (_instance == null) {
148 synchronized (_initializer) {
149 if (_instance == null) {
150 _instance = new AdminConnectionManager();
151 }
152 }
153 }
154
155 return _instance;
156 }
157
158 /***
159 * Create a connection with the specified client id.
160 * The connection contains
161 *
162 *
163 * @param id the client identity
164 * @param username the client's username
165 * @param password the client's password
166 * @return a new admin connection
167 * @throws JMSSecurityException if the client cannot be authenticated
168 * @throws JMSException if the connection cannot be created
169 */
170 public AdminConnection createConnection(String id, String username,
171 String password)
172 throws JMSSecurityException, JMSException {
173
174 if (!AuthenticationMgr.instance().validateUser(username, password)) {
175 throw new JMSSecurityException("Failed to authenticate user "
176 + username);
177 }
178
179 //creates a new connection for every connect.
180 AdminConnection result = new AdminConnection(id);
181 _connections.put(result.getIdentifierId(), result);
182
183 return result;
184 }
185
186 /***
187 * Return an Enumeration of all the connections currently registered with
188 * the connection manager
189 *
190 * @return Iterator
191 */
192 public Iterator getConnections() {
193 return _connections.values().iterator();
194 }
195
196 /***
197 * Return the connection associated with a particular client identity. If
198 * such a connection does not exist then return null
199 *
200 * @param id identity of the client
201 * @return JmsConnection associated connection or null
202 */
203 public AdminConnection getConnection(String id) {
204 return (AdminConnection) _connections.get(id);
205 }
206
207 /***
208 * Close the connection associated with a particular client identity. If
209 * a connection for the client does not exist then do nothing.
210 *
211 * @param identifierId the unique id for this connection
212 */
213 public void closeConnection(String identifierId) {
214 AdminConnection connection =
215 (AdminConnection) _connections.remove(identifierId);
216
217 if (connection != null) {
218 connection.close();
219 }
220 }
221
222 // implementation of EventHandler.handleEvent
223 public void handleEvent(int event, Object callback, long time) {
224 try {
225 Object[] ids = _connections.keySet().toArray();
226 for (int index = 0; index < ids.length; index++) {
227 AdminConnection connection =
228 (AdminConnection) _connections.get(ids[index]);
229 if ((connection != null)
230 && (!connection.isClientActive())) {
231 _log.info("Cleaning up connection " + ids[index]);
232 closeConnection((String) ids[index]);
233 }
234 }
235 } finally {
236 registerEvent();
237 }
238 }
239
240 // implementation of EventHandler.getHandle
241 public HandleIfc getHandle() {
242 // not used
243 return null;
244 }
245
246 /***
247 * Register an event with the event service. The event will tell the
248 * connection manager to initiate garbage collection
249 */
250 private void registerEvent() {
251 try {
252 BasicEventManager.instance().registerEventRelative(
253 new Event(CONNECTION_GC_EVENT, this, null),
254 _gcInterval);
255 } catch (IllegalEventDefinedException exception) {
256 _log.error("AdminConnectionManager.registerEvent failed",
257 exception);
258 }
259 }
260
261 } //-- AdminConnectionManager
262
This page was automatically generated by Maven