You can absolutely do this in JMS, just use a local queue for storing the messages; send to remote queue when receiver is available.
Option 1 (Ideal, Safe)
1) First, create a JMS Server in WebLogic, LocalJMSServer
.
2) Make sure to target this resource only to the local WebLogic instance only.
3) Create a queue, tempQueue
, for LocalJMSServer
.
4) Your application always sends messages to tempQueue
. Since that queue is local, the messages just sit on the queue, and they are persisted too which is nice in case server crashes.
5) You'll need a separate JMSServer configuration in WebLogic to host the remoteQueue
since that queue will be targeted to a remote WebLogic instance.
6) Your application periodically checks the remote receiver for availability:
if( receiverIsAvailable()){
...
}
...when the receiver is available, dequeue messages from tempQueue
and send to remoteQueue
...
Queue tempQueue = (Queue) ctx.lookup("tempQueue");
QueueSession queueLocalSession =
queueConn.createQueueSession(false,
Session.CLIENT_ACKNOWLEDGE);
QueueReceiver queueReceiver = queueLocalSession.createReceiver(tempQueue);
TextMessage localMessage = (TextMessage) queueReceiver.receive();
//send to remote queue
Queue remoteQueue = (Queue) ctx.lookup("remoteQueue");
QueueSender queueSender = queueRemoteSession.createSender(remoteQueue);
Message newMessage = queueRemoteSession.createTextMessage(
localMessage.getText());
queueSender.send( newMessage);
//now acknowledge the message since we safely sent to remoteQueue
localMessage.acknowledge();
I like this approach because it's fully transactional; if anything goes wrong, you don't lose messages provided you use PERSISTENT mode. Also, when pulling message from tempQueue
, you must use a synchronous receiver (as above), you can't use onMessage()
since it processes messages from the local queue immediately.
Option 2 (Simpler, Less Safe)
You can also use in-memory queue (not JMS ) for storing the message content locally:
ArrayBlockingQueue queue = new ArrayBlockingQueue<String>();
queue.add(messageContents1);
queue.add(messageContents2);
...
Your application checks for resource availability on the receiving side, if it's available, just dequeue and send the real JMS messages with no delay:
if( receiverIsAvailable()){
while(!queue.isEmpty()){
Message message = session.createTextMessage();
message.setText(queue.take());
queueSender.send(message);
}
}
The problem with this approach is that messages stored in queue
reside in memory; if the sender crashes, you'll lose those message.
Hope it helps!