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 }