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-2001,2003 (C) Exoffice Technologies Inc. All Rights Reserved.
42 *
43 * $Id: JmsServerConnection.java,v 1.16 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 import java.util.Enumeration;
51 import java.util.Hashtable;
52
53 import javax.jms.JMSException;
54
55 import org.exolab.jms.util.UUID;
56
57
58 /***
59 * A connection is created for every client connecting to the JmsServer. A
60 * connection supports multiple sessions.
61 *
62 * @version $Revision: 1.16 $ $Date: 2003/08/17 01:32:26 $
63 * @author <a href="mailto:jima@exoffice.com">Jim Alateras</a>
64 * @see JmsServerConnectionManager
65 */
66 public class JmsServerConnection {
67
68 /***
69 * The maximum number of consecutive failed attempts to ping the client
70 * before considering that the connection is inactive
71 */
72 private static final int MAX_PING_ATTEMPTS = 3;
73
74 /***
75 * manage all sessions allocated through this connection.
76 */
77 private Hashtable _sessions = null;
78
79 /***
80 * This is the client that is responsible for this connection. It should
81 * map back to a client-side entity
82 */
83 private String _clientId = null;
84
85 /***
86 * The connection id is unique within the context of a JMS server
87 */
88 private String _connectionId = null;
89
90 /***
91 * Indicates if message delivery has been stopped for this connection
92 */
93 private boolean _stopped = true;
94
95 /***
96 * Store the number of consecutive failed attempts to ping the client
97 * side of the connection
98 */
99 private int _consecutiveFailedPingAttempts = 0;
100
101
102 /***
103 * Instantiate an instance of this class for the specified client identity.
104 * The JmsConnection object can only be instantiated by classes in the same
105 * package (i.e ConnectionManager). The ConnectionManager is responsible
106 * for allocating the client identity which is passed to the constructor
107 *
108 * @param id client identity
109 */
110 JmsServerConnection(String id) {
111 _clientId = id;
112 _sessions = new Hashtable(20);
113 _connectionId = UUID.next();
114 _stopped = true;
115 }
116
117 /***
118 * Returns the client identifier
119 *
120 * @return the client identifier
121 */
122 public String getID() {
123 return _clientId;
124 }
125
126 /***
127 * Create a sesion for the specified connection. Assign the clientId to
128 * the sessions. The created session is initially in the stopped mode.
129 * <p>
130 * The created session represents an endpoint with the JmsServer where
131 * you can create consumers. producers and destinations.
132 *
133 * @param ackMode the ackmode for the session
134 * @param transacted true if the session is transacted
135 * @return JmsSession created session
136 */
137 public JmsServerSession createSession(int ackMode, boolean transacted) {
138 JmsServerSession session = new JmsServerSession(this, _clientId,
139 ackMode, transacted);
140 session.setSessionId(UUID.next());
141 _sessions.put(session.getSessionId(), session);
142 if (!_stopped) {
143 session.start();
144 }
145
146 return session;
147 }
148
149 /***
150 * Delete the specified session. If the session does not exist then
151 * fail silently.
152 *
153 * @param session session to delete
154 */
155 public void deleteSession(JmsServerSession session) {
156 _sessions.remove(session.getSessionId());
157 }
158
159 /***
160 * Return the number of sessions currently allocated to this connection.
161 *
162 * @return int
163 */
164 public int getSessionCount() {
165 return _sessions.size();
166 }
167
168 /***
169 * Return an enumeration of all the sessions associated with this
170 * connection
171 *
172 * @return Enumeration
173 */
174 public Enumeration getSessions() {
175 return _sessions.elements();
176 }
177
178 /***
179 * Start all the sessions allocated to this connection.
180 */
181 public void start() {
182 if (_stopped) {
183 Enumeration sessions = _sessions.elements();
184
185 while (sessions.hasMoreElements()) {
186 JmsServerSession session = (JmsServerSession)
187 sessions.nextElement();
188 session.start();
189 }
190 _stopped = false;
191 }
192 }
193
194 /***
195 * Stop all the sessions allocated to this collection. Do not reemove
196 * the session
197 */
198 public void stop() {
199 if (!_stopped) {
200 Enumeration sessions = _sessions.elements();
201
202 while (sessions.hasMoreElements()) {
203 JmsServerSession session = (JmsServerSession)
204 sessions.nextElement();
205 session.stop();
206 }
207 _stopped = true;
208 }
209 }
210
211 /***
212 * Close all the sessions allocated to this collection. This will also
213 * remove the session from the allocated list of sessions
214 */
215 public void close() {
216 Enumeration sessions = _sessions.elements();
217 try {
218 while (sessions.hasMoreElements()) {
219 JmsServerSession session = (JmsServerSession) sessions.nextElement();
220 session.close();
221 }
222 } catch (JMSException exception) {
223 // log the message
224 }
225
226 // remove all the sessions
227 _sessions.clear();
228 }
229
230 /***
231 * Retrive the JmsServerSession with the given sessionId. Return null
232 * if the session does not exist.
233 *
234 * @param sessionId The id of the required session.
235 * @return JmsServerSession The requested session if it exists.
236 *
237 */
238 public JmsServerSession getSession(String sessionId) {
239 return (JmsServerSession) _sessions.get(sessionId);
240 }
241
242 /***
243 * Retrieve the identity of this conection. If this method does not
244 * complete successfully then throw JMSException.
245 *
246 * @return String
247 */
248 public String getConnectionId() {
249 return _connectionId;
250 }
251
252 /***
253 * Determine whether the endpoint is active by trying to ping the first
254 * session in the list. If there are no active sessions then assume that
255 * the connection is active...(need to probably fix this up).
256 *
257 * @return boolean true if active; false otherwise
258 */
259 boolean isClientEndpointActive() {
260 boolean active = true;
261
262 JmsServerSession[] sessions;
263 synchronized (_sessions) {
264 // get a copy of the list of sessions to avoid
265 // ConcurrentModificationExceptions
266 sessions = (JmsServerSession[]) _sessions.values().toArray(
267 new JmsServerSession[0]);
268 }
269 for (int i = 0; i < sessions.length; ++i) {
270 JmsServerSession session = sessions[i];
271 if (session.isClientEndpointActive()) {
272 // if there is one active session then mark the connection
273 // as active
274 active = true;
275 _consecutiveFailedPingAttempts = 0;
276 break;
277 } else {
278 if (++_consecutiveFailedPingAttempts > MAX_PING_ATTEMPTS) {
279 active = false;
280 } else {
281 active = true;
282 }
283 }
284 }
285
286 return active;
287 }
288 }
This page was automatically generated by Maven