To post a message to a remote Queue using Web-Logic - jms

I have gained some knowledge on consuming messages that are posted to a resource. In the process I used a stand-alone which posts messages to the local queue. Now, the task is to post messages to a remote queue, which resides in a server(say TIBCO), other than Web-Logic, which I use here.
My question is :
a) Are there any notable differences to be taken care of, when posting to a remote queue?

Sending a message to a remote server is pretty simple. All you need is the URL of the remote server and the port number on which the JMS provider is listening for the incoming connections. Once you have these details then you do a JNDI Lookup for the Queue and establish a Session to send out the message. Something like below:
// Provide the details of remote JMS Server
Properties props = new Properties();
props.put(Context.PROVIDER_URL, "mq://localhost:7676");
// Create the initial context for remote JMS server
InitialContext cntxt = new InitialContext(props);
System.out.println("Context Created");
// JNDI Lookup for QueueConnectionFactory in remote JMS Provider
QueueConnectionFactory qFactory = (QueueConnectionFactory)cntxt.lookup("TestQueueConnectionFactory");
// Create a Connection from QueueConnectionFactory
Connection connection = qFactory.createConnection();
System.out.println("Connection established with JMS Provide ");
See this JMS Client Server Example for full code details. I am guess you are only interested in the client code from this example.

What do you want to achieve?
If you simply want to post a message to a queue on any JMS compliant broker i would give a try to the Hermes Tool: http://www.hermesjms.com/confluence/display/HJMS/Home
Cheers

Related

Spring JMS Consumers to a TIBCO EMS Server expire on their own

We have built a Spring Boot messaging service that listens to a JMS queue hosted on a TIBCO EMS (Enterprise Messaging Service) Server. It is a fairly straightforward application that receives a JMS message, does some data manipulation and updates a database.
The issue is that, occasionally, there are no JMS consumers on the queue, and incoming messages are not processed. However the Spring Boot app is up and running (verified by ps -ef). Restarting the app restores the consumer, but unfortunately this is not a feasible solution in production etc.
Other facts of interest:
We have observed this to happen when the JMS server accepts SSL traffic and is on deployed as a Fault Tolerant pair (although this has been a conculsive observation yet)
There is absolutely no indication in the log (like an error) when the consumer goes down.
We are using Spring-JMS (4.1.0) and TIBCO EMS (8.3.0)
Code Snippet of instantiating a DefaultJmsListenerContainerFactory:
#Bean
public DefaultJmsListenerContainerFactory listenerJmsContainerFactory() {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
TibjmsQueueConnectionFactory cf = new TibjmsQueueConnectionFactory("tcp://localhost:7222");
cf.setUserName("admin");
cf.setUserPassword("");
factory.setConnectionFactory(cf);
return factory;
}
The JMS Listener:
#JmsListener(destination = "queue.sample", containerFactory = "listenerJmsContainerFactory")
public void listen(TextMessage message, Session session) throws JMSException{
System.out.println("Received Message: "+message.getJMSMessageID());
System.out.println("Acknowledgement Mode: "+session.getAcknowledgeMode());
// Some more application specific stuff
}
While we are trying to setup additional logging on both the Spring Boot and TIBCO side, we would like to check some points like:
Can there be a situation where a consumer idle for more than a certain time, automatically expires?
Is this something that is governed by DMLC settings like idleConsumerLimit, idleTaskExecutionLimit etc.?
Can these properties be viewed in the Spring Boot code mentioned above? For instance in the code above, the JMS Listener is being created under the hood by the DefaultJmsListenerContainerFactory. So how can we access the DMLC object so that we can invoke methods like getIdleConsumerLimit(), getIdleTaskExecutionLimit() etc.
Thanks for the inputs,
Prabal
Most likely, something in the network (router, firewall etc) is silently dropping idle connections.
While not part of the JMS spec, most vendors implement some kind of heartbeat mechanism so that the client/server exchange pings from time to time, to prevent such actions by network components and/or to detect such conditions.
Look at the Tibco documentation to figure out how to configure heartbeats (they might call it something else).

How to access multiple MQ server endpoints from one Java client

I would like my Java MQ client to be able to access (do puts) to multiple MQ server endpoints (by endpoint i mean 'host/port/Qmanager/Queue/Channel'). Basically this Java app will get a request to put a message and the endpoint detail along with the request. It should be able to find the corresponding connection pool for the endpoint and use it to do the put.
From my limited understanding so far, the MQEnvironment is a global configuration (only one is possible in one JVM?) which can be configured to one endpoint at a time. So if the idea is multiple threads accessing multiple MQserver endpoints parallely - this does not seem to implementable with current understanding.
You can also use a Hashtable to pass connection parameters while creating a connection to queue manager. For example:
Hashtable<String, Object> properties;
properties = new Hashtable<String, Object>();
properties.put("hostname", "remotehost");
properties.put("port", new Integer(1414));
properties.put("channel", "REMOTEQM.SVRCONN");
MQQueueManager queueManager = new MQQueueManager(queueManagerName, properties);
Either you don't understand MQ very well or your MQ environment is not set up correctly.
Your MQ application should be connecting (and stay connected) to a single queue manager. The queue managers in your MQ environment should be interconnected such that when your MQ application puts a message destined for another queue manager, the local queue manager (that your application is connected to) will route the message to the correct queue manager.

JMS Set Reply To Queue Manager

I want to set the required queue manager when sending a JMS message.
Currently I am able to set the destination queue in the JMSReplyTO method, but I don't know how to also specify the queue manager.
TextMessage message = queueSession.createTextMessage();
message.setText(messageStr);
message.setJMSReplyTo(destinationQueue);
queueSender.send(message);
Here you go (for WebSphere MQ):
MQQueue replyToQ = new MQQueue(QMgrName, ReplyQueue);
Destination replyTo = (Destination) replyToQ;
message.setJMSReplyTo(replyTo);
I don't know which MQ you're using, but your class names look like WebSphere's ones, so I'll guess that's it.
The queue manager name can be set on the connection factory, before you get a connection from it. Use MQConnectionFactory#setBrokerQueueManager(String).
The IBM javadocs for the method are here, on publib.
If you're using ActiveMQ, then you can't set the queue manager, since ActiveMQ doesn't support that abstraction. You could name your broker to be whatever you want your messages to use as their queue manager, since ActiveMQ brokers and MQ managers are roughly equivalent. I have no idea if that will help at all, though. You may have to switch to using WebSphere's own MQ.

single jms consumer for multiple jms servers

I am using a distributed jms queue and weblogic is my app server. There are three jms servers deployed in my clustered enviroment. The producers just send the message using name of queue jndi lookup 'udq' for example. Now I have associated a consumer for each jms server and I was able to consume the message, no problem so far.
Here is question, can I have a single consumer to consume the messages from the 3 jms servers. The weblogic allows jndi naming for destination lookup with following syntax #
qsession1 = qcon1.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
qsession2 = qcon2.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
qsession3 = qcon3.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue1 = (Queue)ctx.lookup("JMSServer-1#UDQ");
queue2 = (Queue)ctx.lookup("JMSServer-2#UDQ");
queue3 = (Queue)ctx.lookup("JMSServer-3#UDQ");
qreceiver1 = qsession1.createReceiver(queue1);
qreceiver2 = qsession2.createReceiver(queue2);
qreceiver3 = qsession3.createReceiver(queue3);
qreceiver1.setMessageListener(this);
qreceiver2.setMessageListener(this);
qreceiver3.setMessageListener(this);
qcon1.start();
qcon2.start();
qcon3.start();
I have only one OnMessage implemented for the above consumer. This does not work. Any suggestions please..
No, you can't have a consumer receiving messages from more than one JMS server. A consumer can receive messages from only one JMS server. You need to create multiple consumers to receive messages from multiple JMS servers.
you can use "Queue Forwarding" function.
From online documentation of wls 10.3:
"Queue members can forward messages to other queue members by configuring the Forward Delay attribute in the Administration Console, which is disabled by default. This attribute defines the amount of time, in seconds, that a distributed queue member with messages, but which has no consumers, will wait before forwarding its messages to other queue members that do have consumers."
here a link: http://docs.oracle.com/cd/E13222_01/wls/docs103/jms/dds.html#wp1260816
You can configure this feature from administration of each single queue.

Oracle Service Bus (OSB) Proxy Service Endpoint URI change

We have an OSB Proxy Service which is currently setup to receive messages from an external jms queue endpoint URI. We have been tasked with creating a JMS bridge over which to receive external messages.
To this end, we have created a bridge with local jms in/out queues and proceeded to edit the OSB Proxy Service's Endpoint URI from that of the old external jms queue to that of our new local bridge's jms queue. However, when we try to activate the changes, we get: Exception in AppMerge flows' progression message.
Being quite new to all things OSB, I am unsure as to what this error means and whether re-pointing a Proxy Service's Endpoint URI from remote jms queue to local bridge's jms queue is enough for what we are attempting to do.
Any thoughts on this matter would be much appreciated!
Our OSB version is 10gR3.
Regards,
PM.
I think your Proxy is not deployed correctly. I think after creating the bridge and queues, restart your server and then try to work.

Resources