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 2004-2005 (C) Exoffice Technologies Inc. All Rights Reserved.
42 *
43 * $Id: RemoteServerSession.java,v 1.3 2005/08/30 05:24:21 tanderson Exp $
44 */
45 package org.exolab.jms.server.net;
46
47 import java.rmi.RemoteException;
48 import java.util.List;
49 import javax.jms.JMSException;
50 import javax.transaction.xa.XAException;
51 import javax.transaction.xa.Xid;
52
53 import org.exolab.jms.client.JmsDestination;
54 import org.exolab.jms.client.JmsMessageListener;
55 import org.exolab.jms.client.JmsQueue;
56 import org.exolab.jms.client.JmsTopic;
57 import org.exolab.jms.message.MessageImpl;
58 import org.exolab.jms.net.orb.ORB;
59 import org.exolab.jms.net.orb.UnicastObject;
60 import org.exolab.jms.server.ServerSession;
61
62
63 /***
64 * Implementation of the {@link ServerSession} interface which wraps an {@link
65 * ServerSession} to make it remotable.
66 *
67 * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a>
68 * @version $Revision: 1.3 $ $Date: 2005/08/30 05:24:21 $
69 */
70 public class RemoteServerSession
71 extends UnicastObject
72 implements ServerSession {
73
74 /***
75 * The connection that created this.
76 */
77 private RemoteServerConnection _connection;
78
79 /***
80 * The session to delegate calls to.
81 */
82 private ServerSession _session;
83
84
85 /***
86 * Construct a new <code>RemoteServerSession</code>.
87 *
88 * @param orb the ORB to export this with
89 * @param connection the connection that created this
90 * @param session the session to delegate calls to
91 * @throws RemoteException if this can't be exported
92 */
93 public RemoteServerSession(ORB orb, RemoteServerConnection connection,
94 ServerSession session)
95 throws RemoteException {
96 super(orb, null, true);
97 if (connection == null) {
98 throw new IllegalArgumentException("Argument 'connection' is null");
99 }
100 if (session == null) {
101 throw new IllegalArgumentException("Argument 'session' is null");
102 }
103 _connection = connection;
104 _session = session;
105 }
106
107 /***
108 * Close and release any resource allocated to this session.
109 *
110 * @throws JMSException if the session can't be closed
111 */
112 public synchronized void close() throws JMSException {
113 if (_session != null) {
114 try {
115 _session.close();
116 } finally {
117 try {
118 unexportObject();
119 } catch (RemoteException exception) {
120 JMSException error = new JMSException(
121 exception.getMessage());
122 error.setLinkedException(exception);
123 throw error;
124 } finally {
125 _connection.closed(this);
126 _connection = null;
127 _session = null;
128 }
129 }
130 }
131 }
132
133 /***
134 * Acknowledge that a message has been processed.
135 *
136 * @param consumerId the identity of the consumer performing the ack
137 * @param messageId the message identifier
138 * @throws JMSException for any error
139 */
140 public void acknowledgeMessage(long consumerId, String messageId)
141 throws JMSException {
142 _session.acknowledgeMessage(consumerId, messageId);
143 }
144
145 /***
146 * Send a message.
147 *
148 * @param message the message to send
149 * @throws JMSException for any error
150 */
151 public void send(MessageImpl message) throws JMSException {
152 _session.send(message);
153 }
154
155 /***
156 * Send a set of messages.
157 *
158 * @param messages a list of <code>MessageImpl</code> instances
159 * @throws JMSException for any JMS error
160 */
161 public void send(List messages) throws JMSException {
162 _session.send(messages);
163 }
164
165 /***
166 * Return the next available mesage to the specified consumer.
167 * <p/>
168 * This method is non-blocking. If no messages are available, it will return
169 * immediately.
170 *
171 * @param consumerId the consumer identifier
172 * @return the next message or <code>null</code> if none is available
173 * @throws JMSException for any JMS error
174 */
175 public MessageImpl receiveNoWait(long consumerId) throws JMSException {
176 return _session.receiveNoWait(consumerId);
177 }
178
179 /***
180 * Return the next available message to the specified consumer.
181 * <p/>
182 * This method is non-blocking. However, clients can specify a
183 * <code>wait</code> interval to indicate how long they are prepared to wait
184 * for a message. If no message is available, and the client indicates that
185 * it will wait, it will be notified via the registered {@link
186 * JmsMessageListener} if one subsequently becomes available.
187 *
188 * @param consumerId the consumer identifier
189 * @param wait number of milliseconds to wait. A value of <code>0
190 * </code> indicates to wait indefinitely
191 * @return the next message or <code>null</code> if none is available
192 * @throws JMSException for any JMS error
193 */
194 public MessageImpl receive(long consumerId, long wait) throws JMSException {
195 return _session.receive(consumerId, wait);
196 }
197
198 /***
199 * Browse up to count messages.
200 *
201 * @param consumerId the consumer identifier
202 * @param count the maximum number of messages to receive
203 * @return a list of {@link MessageImpl} instances
204 * @throws JMSException for any JMS error
205 */
206 public List browse(long consumerId, int count) throws JMSException {
207 return _session.browse(consumerId, count);
208 }
209
210 /***
211 * Create a new message consumer.
212 *
213 * @param destination the destination to consume messages from
214 * @param selector the message selector. May be <code>null</code>
215 * @param noLocal if true, and the destination is a topic, inhibits the
216 * delivery of messages published by its own connection.
217 * The behavior for <code>noLocal</code> is not specified
218 * if the destination is a queue.
219 * @return the identifty of the message consumer
220 * @throws JMSException for any JMS error
221 */
222 public long createConsumer(JmsDestination destination, String selector,
223 boolean noLocal) throws JMSException {
224 return _session.createConsumer(destination, selector, noLocal);
225 }
226
227 /***
228 * Create a new durable consumer. Durable consumers may only consume from
229 * non-temporary <code>Topic</code> destinations.
230 *
231 * @param topic the non-temporary <code>Topic</code> to subscribe to
232 * @param name the name used to identify this subscription
233 * @param selector only messages with properties matching the message
234 * selector expression are delivered. A value of null or an
235 * empty string indicates that there is no message selector
236 * for the message consumer.
237 * @param noLocal if set, inhibits the delivery of messages published by
238 * its own connection
239 * @return the identity of the durable consumer
240 * @throws JMSException for any JMS error
241 */
242 public long createDurableConsumer(JmsTopic topic, String name,
243 String selector, boolean noLocal)
244 throws JMSException {
245 return _session.createDurableConsumer(topic, name, selector, noLocal);
246 }
247
248 /***
249 * Create a queue browser for this session. This allows clients to browse a
250 * queue without removing any messages.
251 *
252 * @param queue the queue to browse
253 * @param selector the message selector. May be <code>null</code>
254 * @return the identity of the queue browser
255 * @throws JMSException for any JMS error
256 */
257 public long createBrowser(JmsQueue queue, String selector)
258 throws JMSException {
259 return _session.createBrowser(queue, selector);
260 }
261
262 /***
263 * Close a message consumer.
264 *
265 * @param consumerId the identity of the consumer to close
266 * @throws JMSException for any JMS error
267 */
268 public void closeConsumer(long consumerId) throws JMSException {
269 _session.closeConsumer(consumerId);
270 }
271
272 /***
273 * Unsubscribe a durable subscription.
274 *
275 * @param name the name used to identify the subscription
276 * @throws JMSException for any JMS error
277 */
278 public void unsubscribe(String name) throws JMSException {
279 _session.unsubscribe(name);
280 }
281
282 /***
283 * Start message delivery to this session.
284 *
285 * @throws JMSException for any JMS error
286 */
287 public void start() throws JMSException {
288 _session.start();
289 }
290
291 /***
292 * Stop message delivery to this session.
293 *
294 * @throws JMSException for any JMS error
295 */
296 public void stop() throws JMSException {
297 _session.stop();
298 }
299
300 /***
301 * Set the listener for this session.
302 * <p/>
303 * The listener is notified whenever a message for the session is present.
304 *
305 * @param listener the message listener
306 */
307 public void setMessageListener(JmsMessageListener listener) {
308 _session.setMessageListener(listener);
309 }
310
311 /***
312 * Enable or disable asynchronous message delivery for a particular
313 * consumer.
314 *
315 * @param consumerId the consumer identifier
316 * @param enable true to enable; false to disable
317 * @throws JMSException for any JMS error
318 */
319 public void setAsynchronous(long consumerId, boolean enable)
320 throws JMSException {
321 _session.setAsynchronous(consumerId, enable);
322 }
323
324 /***
325 * Recover the session. This means all unacknowledged messages are resent
326 * with the redelivery flag set
327 *
328 * @throws JMSException if the session cannot be recovered
329 */
330 public void recover() throws JMSException {
331 _session.recover();
332 }
333
334 /***
335 * Commit the session which will send all the published messages and
336 * acknowledge all received messages.
337 *
338 * @throws JMSException if the session cannot be committed
339 */
340 public void commit() throws JMSException {
341 _session.commit();
342 }
343
344 /***
345 * Rollback the session, which will not acknowledge any of the sent
346 * messages.
347 *
348 * @throws JMSException if the session cannot be rolled back
349 */
350 public void rollback() throws JMSException {
351 _session.rollback();
352 }
353
354 /***
355 * Start work on behalf of a transaction branch specified in xid If TMJOIN
356 * is specified, the start is for joining a transaction previously seen by
357 * the resource manager.
358 *
359 * @param xid the xa transaction identity
360 * @param flags One of TMNOFLAGS, TMJOIN, or TMRESUME
361 * @throws XAException if there is a problem completing the call
362 */
363 public void start(Xid xid, int flags) throws XAException {
364 _session.start(xid, flags);
365 }
366
367 /***
368 * Ask the resource manager to prepare for a transaction commit of the
369 * transaction specified in xid.
370 *
371 * @param xid the xa transaction identity
372 * @return XA_RDONLY or XA_OK
373 * @throws XAException if there is a problem completing the call
374 */
375 public int prepare(Xid xid) throws XAException {
376 return _session.prepare(xid);
377 }
378
379 /***
380 * Commits an XA transaction that is in progress.
381 *
382 * @param xid the xa transaction identity
383 * @param onePhase true if it is a one phase commit
384 * @throws XAException if there is a problem completing the call
385 */
386 public void commit(Xid xid, boolean onePhase) throws XAException {
387 _session.commit(xid, onePhase);
388 }
389
390 /***
391 * Ends the work performed on behalf of a transaction branch. The resource
392 * manager disassociates the XA resource from the transaction branch
393 * specified and let the transaction be completedCommits an XA transaction
394 * that is in progress.
395 *
396 * @param xid the xa transaction identity
397 * @param flags one of TMSUCCESS, TMFAIL, or TMSUSPEND
398 * @throws XAException if there is a problem completing the call
399 */
400 public void end(Xid xid, int flags) throws XAException {
401 _session.end(xid, flags);
402 }
403
404 /***
405 * Tell the resource manager to forget about a heuristically completed
406 * transaction branch.
407 *
408 * @param xid the xa transaction identity
409 * @throws XAException if there is a problem completing the call
410 */
411 public void forget(Xid xid) throws XAException {
412 _session.forget(xid);
413 }
414
415 /***
416 * Obtain a list of prepared transaction branches from a resource manager.
417 * The transaction manager calls this method during recovery to obtain the
418 * list of transaction branches that are currently in prepared or
419 * heuristically completed states.
420 *
421 * @param flag One of TMSTARTRSCAN, TMENDRSCAN, TMNOFLAGS. TMNOFLAGS
422 * @return the set of Xids to recover
423 * @throws XAException - if there is a problem completing the call
424 */
425 public Xid[] recover(int flag) throws XAException {
426 return _session.recover(flag);
427 }
428
429 /***
430 * Inform the resource manager to roll back work done on behalf of a
431 * transaction branch.
432 *
433 * @param xid the xa transaction identity
434 * @throws XAException if there is a problem completing the call
435 */
436 public void rollback(Xid xid) throws XAException {
437 _session.rollback(xid);
438 }
439
440 /***
441 * Return the transaction timeout for this instance of the resource
442 * manager.
443 *
444 * @return the timeout in seconds
445 * @throws XAException if there is a problem completing the call
446 */
447 public int getTransactionTimeout() throws XAException {
448 return _session.getTransactionTimeout();
449 }
450
451 /***
452 * Set the current transaction timeout value for this XAResource instance.
453 *
454 * @param seconds timeout in seconds
455 * @return if the new transaction timeout was accepted
456 * @throws XAException if there is a problem completing the call
457 */
458 public boolean setTransactionTimeout(int seconds) throws XAException {
459 return _session.setTransactionTimeout(seconds);
460 }
461
462 /***
463 * Return the identity of the associated resource manager.
464 *
465 * @return the identity of the resource manager
466 * @throws XAException if there is a problem completing the call
467 */
468 public String getResourceManagerId() throws XAException {
469 return _session.getResourceManagerId();
470 }
471
472 }