Author |
Message
|
RGFanta |
Posted: Wed Sep 15, 2010 11:47 am Post subject: Setting MQ exclusive-read client properties in JMS |
|
|
Novice
Joined: 03 Sep 2010 Posts: 12
|
Hi,
Is there any way to MQSeries properties like Exclusive Read: On, Shareability: Off for JMS MQSeries clients?
While we can set this up on the MQ server side using default properties on the queue, we'd also like to be able to set this on the JMS client-side application.
Any suggestions on how to do this via MQSeries JMS?
e.g. Can we get the underlying MQ connection or such (beneath the generic jms connection wrapper) and set the options there?
Many thanks,
Rick |
|
Back to top |
|
 |
fjb_saper |
Posted: Wed Sep 15, 2010 12:09 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
You'd probably set it on the Destination definition in form of URI:
"queue://qmgr/qname?attr1=val1&attr2=val2...&attrn=valn"
Have fun  _________________ MQ & Broker admin |
|
Back to top |
|
 |
ksrjo24 |
Posted: Wed Sep 15, 2010 1:50 pm Post subject: Setting MQ exclusive-read client properties in JMS |
|
|
Newbie
Joined: 15 Sep 2010 Posts: 4
|
What would the attribute and value pair looks like.
I could not find any attribute that matches with MQOO_EXCLUSIVE_INPUT.
Do you have a sample URI?? |
|
Back to top |
|
 |
fjb_saper |
Posted: Wed Sep 15, 2010 7:21 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Cast your Queue to an MQQueue, set the attributes and then print the Queue name attribute. It should show you the URI....
Have fun  _________________ MQ & Broker admin |
|
Back to top |
|
 |
ksrjo24 |
Posted: Thu Sep 16, 2010 6:34 am Post subject: Setting MQ exclusive-read client properties in JMS |
|
|
Newbie
Joined: 15 Sep 2010 Posts: 4
|
Thanks for the reply. I know how to print out the URI,
I wanted to know the actual attribute value pair that shoudl be used and i was askign if you had a sample URI that shows those attibute value pairs in them. Not just any attribute value pair showing URI, but the uri that atcually shows the attribute that would be set to get an exclusive connection to the Queue. Please let me knwo if you have that information.
Thanks. |
|
Back to top |
|
 |
fjb_saper |
Posted: Mon Sep 20, 2010 2:05 pm Post subject: Re: Setting MQ exclusive-read client properties in JMS |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
ksrjo24 wrote: |
Thanks for the reply. I know how to print out the URI,
I wanted to know the actual attribute value pair that shoudl be used and i was askign if you had a sample URI that shows those attibute value pairs in them. Not just any attribute value pair showing URI, but the uri that atcually shows the attribute that would be set to get an exclusive connection to the Queue. Please let me knwo if you have that information.
Thanks. |
The way to get there as I said is to open a Queue Destination, cast it to MQQueue, set the attributes you need, and then use the Queue object to print the corresponding URI...  _________________ MQ & Broker admin |
|
Back to top |
|
 |
RGFanta |
Posted: Tue Sep 21, 2010 12:26 pm Post subject: Same issue, not seeing how/where to set exclusive property |
|
|
Novice
Joined: 03 Sep 2010 Posts: 12
|
Hi,
I'm having the same issue trying to set the equivalent of MQOO_INPUT_EXCLUSIVE=1, MQOO_INPUT_SHARED=0 for a JMS based application.
Below is my sample code.
Nothing I have tried has worked so far, even using several features of the v7 MQSeries client.
Does this have to be done using the factory.setCCDTURL to set the channel properties on the queue connection factory, or is there a simpler way that I'm missing???
Many thanks,
R
Code: |
package samples;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;
import com.ibm.jms.JMSMessage;
import com.ibm.jms.JMSTextMessage;
import com.ibm.mq.MQMessage;
import com.ibm.mq.jms.JMSC;
//import com.ibm.mq.jms.MQQueue;
import com.ibm.mq.jms.MQQueue;
import com.ibm.mq.jms.MQQueueConnection;
import com.ibm.mq.jms.MQQueueConnectionFactory;
import com.ibm.mq.jms.MQQueueReceiver;
import com.ibm.mq.jms.MQQueueSender;
import com.ibm.mq.jms.MQQueueSession;
import com.ibm.msg.client.wmq.WMQConstants;
@SuppressWarnings("deprecation")
class MQMessageReaderJMS {
MQQueueSession session;
MQQueueConnection connection;
MQQueue queue;
MQQueueSender sender;
MQQueueReceiver receiver;
int iThread=0;
public MQMessageReaderJMS(int i) {
iThread=i;
try {
MQQueueConnectionFactory cf = new MQQueueConnectionFactory();
cf.setHostName("my.host.name");
cf.setPort(1414);
cf.setTransportType(1);
cf.setQueueManager("MYQUEUEMGR");
cf.setChannel("MY.CHANNEL");
//cf.setCCDTURL(arg0); //I'm a bit of a novice at writing these channel configurations, so I haven't attempted this yet...
// Thes options cause openning of the queue to fail
/*
cf.setMQConnectionOptions(CMQC.MQOO_INPUT_EXCLUSIVE);
cf.setMQConnectionOptions(CMQC.MQOO_INPUT_SHARED);
*/
//cf.setMQConnectionOptions(MQC.MQOO_INPUT_EXCLUSIVE);
//cf.setMQConnectionOptions(CMQC.MQOO_INPUT_SHARED);
connection = (MQQueueConnection) cf.createQueueConnection();
session = (MQQueueSession) connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
// These options seem to get ignored....
queue = (MQQueue) session.createQueue("queue:///MY.TEST.QUEUE?MQC.MQOO_INPUT_EXCLUSIVE=1&MQC.MQOO_INPUT_SHARED=0");
sender = (MQQueueSender) session.createSender(queue);
receiver = (MQQueueReceiver) session.createReceiver(queue);
connection.start();
} catch (JMSException e) {
// TODO Auto-generated catch block
System.out.println("JMS Exception in MQMessageReaderJMS constructor, exception="+e);
e.printStackTrace();
}
}
public void send(String message){
try {
JMSTextMessage jmsTextMessage = (JMSTextMessage) session.createTextMessage(message);
//sender.send(message);
System.out.println("Sent message:\\n" + jmsTextMessage);
} catch (JMSException e) {
// TODO Auto-generated catch block
System.out.println("JMS Exception in MQMessageReaderJMS constructor, exception="+e);
e.printStackTrace();
}
}
public void receive() {
try {
Message receivedMessage = (Message) receiver.receive(1000);
if (receivedMessage instanceof TextMessage) {
String replyString = ((TextMessage) receivedMessage).getText();
System.out.println("Reply Message received by Thread:"+iThread+", reply="+replyString);
//System.out.println("\\nReceived message:\\n" + receivedMessage);
System.out.println("\\nSUCCESS\\n");
} else {
// Print error message if Message was not a TextMessage.
System.out.println("Reply message was not a TextMessage");
}
} catch (JMSException e) {
// TODO Auto-generated catch block
System.out.println("JMS Exception in MQMessageReaderJMS constructor, exception="+e);
e.printStackTrace();
}
}
public void close() {
try {
sender.close();
receiver.close();
session.close();
connection.close();
} catch (JMSException e) {
// TODO Auto-generated catch block
System.out.println("JMS Exception in MQMessageReaderJMS constructor, exception="+e);
e.printStackTrace();
}
}
}
public class MQMessageReaderJMSTest {
public static void main(String[] args) {
final MQMessageReaderJMS mqReader1 = new MQMessageReaderJMS(1);
final MQMessageReaderJMS mqReader2 = new MQMessageReaderJMS(2);
new Thread() {
public void run() {
while(true) {
long uniqueNumber1 = System.currentTimeMillis() % 1000;
mqReader1.send("SimplePTP "+ uniqueNumber1);
mqReader1.receive();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
new Thread() {
public void run() {
while(true) {
long uniqueNumber2 = System.currentTimeMillis() % 1000;
mqReader2.send("SimplePTP "+ uniqueNumber2);
mqReader2.receive();
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
}
} |
|
|
Back to top |
|
 |
fjb_saper |
Posted: Tue Sep 21, 2010 2:30 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Your queue URI
Quote: |
queue = (MQQueue) session.createQueue("queue:///MY.TEST.QUEUE?MQC.MQOO_INPUT_EXCLUSIVE=1&MQC.MQOO_INPUT_SHARED=0") |
looks blatantly wrong to me.
Cast the queue to an MQQueue, check what properties you can set, set the properties and then use the Queue object to write out the URI.
Have fun  _________________ MQ & Broker admin |
|
Back to top |
|
 |
RGFanta |
Posted: Wed Sep 22, 2010 5:34 am Post subject: How to set properties?? |
|
|
Novice
Joined: 03 Sep 2010 Posts: 12
|
Yes, trying to set the properties like this is wrong but harmless and has no effect:
Code: |
Quote:
queue = (MQQueue) session.createQueue("queue:///MY.TEST.QUEUE?MQC.MQOO_INPUT_EXCLUSIVE=1&MQC.MQOO_INPUT_SHARED=0")
|
Quote: |
Cast the queue to an MQQueue, check what properties you can set, set the properties and then use the Queue object to write out the URI.
|
I did cast to an MQQueue as shown above. Despite a lot of digging in the documentation and trying a few things, it's not at all clear to me how to set any properties that could help.
The signature for setProperty is:
Code: |
mqQueue.setProperty(String name, String value) |
==>Where do I get the String names for properties like the above (input exclusive on, input shared off) and the possible String values???
Also, I don't see what you mean about using the queue object to write out the URL.
Thanks for your help. |
|
Back to top |
|
 |
bruce2359 |
Posted: Wed Sep 22, 2010 6:04 am Post subject: |
|
|
 Poobah
Joined: 05 Jan 2008 Posts: 9469 Location: US: west coast, almost. Otherwise, enroute.
|
Moved to Java/JMS forum. _________________ I like deadlines. I like to wave as they pass by.
ב''ה
Lex Orandi, Lex Credendi, Lex Vivendi. As we Worship, So we Believe, So we Live. |
|
Back to top |
|
 |
fjb_saper |
Posted: Wed Sep 22, 2010 12:21 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
You might want to open a PMR to get the right property name/value
Unless you use the as Q_DEF property and set the queue to be exclusive, I don't know how you would set that property on the Destination.
Look at the JMSConstants class and other MQ7 constants. You might find the property name there...  _________________ MQ & Broker admin |
|
Back to top |
|
 |
RGFanta |
Posted: Wed Sep 22, 2010 12:32 pm Post subject: Problem is simple, the solution seems needlessly difficult. |
|
|
Novice
Joined: 03 Sep 2010 Posts: 12
|
In a non-JMS Java MQ application you just set MQOO_INPUT_EXCLUSIVE=1, MQOO_INPUT_SHARED=0 as open options and it works well. [i.e. The first reader gets the connection, others block.]
How to use MQ JMS extensions to achieve the same thing is not at all clear. JMS uses MQ underneath, so the above should be readily possible and exposed.
[What in the world is the point of having MQ extensions to JMS if not to easily enable MQ custom behavior to a JMS application??]
Have tried several things already like
MQCNO_SERIALIZE_CONN_TAG_Q_MGR, MQCNO_SERIALIZE_CONN_TAG_QSG and many others from WMQConstants (new to V7) and other places, all to no avail.
I don't understand why this is simple issue is so difficult to resolve easily. |
|
Back to top |
|
 |
Vitor |
Posted: Wed Sep 22, 2010 12:41 pm Post subject: Re: Problem is simple, the solution seems needlessly difficu |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
RGFanta wrote: |
JMS uses MQ underneath, so the above should be readily possible and exposed. |
Not true. JMS is a standard which applies to all providers (WMQ, ActiveMQ, SonicMQ, etc) and things that JMS does not allow are not accessable even if WMQ allows them.
For instance, try directly setting a message or correlation id in a JMS application. _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
RGFanta |
Posted: Wed Sep 22, 2010 1:07 pm Post subject: That won't work |
|
|
Novice
Joined: 03 Sep 2010 Posts: 12
|
Again,
Quote: |
What in the world is the point of having MQ extensions to JMS if not to easily enable MQ custom behavior to a JMS application?? |
In this case, the goal is very simple. I want to use MQ JMS to have automatic failover in the same way that I can easily do with (non-JMS) MQ using Java.
Being able to use Exclusive Read: On, Shareability: Off allows you to make sure that only one reader is active on a queue, but makes failover trivial. e.g. You spin up 2 applications that each try to connect to the same queue; the first one gets the connection and consumes msgs, and the 2nd one blocks. If the first one ever fails, the 2nd one takes over almost immediately (while the 1st one is recycled).
I can do this trivially using MQ with Java. Figuring out how to do the same thing with JMS MQ extensions is much more work than it should be and I still haven't found a way that works.
Testing all the Property possibilities is combinatorial..... |
|
Back to top |
|
 |
fjb_saper |
Posted: Wed Sep 22, 2010 6:42 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
It all depends on whether you want to control the attribute from JMS on just be subjected to it.
To just have to deal with it you can set the destination attributes as Queue Defined and change the Queue in MQ from the default open shared to open exclusive.
Going the controlling route you'd need to set the attribute on the destination.
This is where there is some difficulty as the attribute is not readily available when you cast the Queue to an MQQueue. However you do have the capability to do a setProperty(name, value) on the Queue / Destination.
Finding the right values for this, or whether controlling this attribute from JMS is even possible is a matter for a PMR.
Be at the same time aware that you are severely restricting JMS scalability because at that point you can only have at best 1 MDB instance.
Looking at the fact that MDB's work with a browse and get connection at minimum (2 open connections) I fear that this is just not possible for an MDB as with an exclusive lock on the queue the MDB might not be able to work at all. MQ 7 with connection sharing might be able to alleviate this to some extend (however I don't know of the quality of the solution before 7.0.1.4). There are a lot of fixes in that area targeted for MQ 7.0.1.4....
Your best bet is still a PMR
My advice: It looks like your design has a serious message affinity problem (you cannot have multiple instances of the consumer receiving messages concurrently). Solve your message affinity problem and not only will this requirement be moot, but you will greatly gain in throughput and scalability.
Have fun  _________________ MQ & Broker admin |
|
Back to top |
|
 |
|