in my Java application I get MQQueue object using
MQQueue tQueue = qManager.accessQueue(tqName, tqOptions);
The queue is a remote queue. Is there way to get corresponding local transmission queue ?
(Using MQ 7.5)
Thanks
Yes, using runmqsc console.
First on a command prompt run
runmqsc <qmgr>.
Once the console opens run
dis qr<remote q> XMITQ
to display the transmit queue used by the remote queue definition.
UPDATE
Another method is to use PCF classes.
PCFMessageAgent pcfma = new PCFMessageAgent("QM");
PCFMessage pcfCmd = new PCFMessage(MQConstants.MQCMD_INQUIRE_Q);
pcfCmd.addParameter(MQConstants.MQCA_Q_NAME, "Q.REMOTE");
PCFMessage[] pcfResponse = pcfma.send(pcfCmd);
String xmitQName = (String) pcfResponse[0].getParameterValue(MQConstants.MQCA_XMIT_Q_NAME);
System.out.println("XmitQ name " + xmitQName);
When MQ opens a queue it runs a name resolution process to resolve which local queue to open. If the app opens a QRemote, it generally resolves to a transmission queue.
Finding out the name of the resolved queue is easy. Just ask MQ for it after the queue is successfully opened:
public java.lang.String getResolvedQName( )
Related
I am working on a utility to browse/read all the messages from each of the queues in a Queue Manager. I am successful in creating a rest web service which can read the specified number of messages from the specified Queue.I am using MQ APIs in my classes to establish the connections.
MQQueueManager queueManager = new MQQueueManager(queueManagerName);
int openOptions = CMQC.MQOO_INQUIRE + CMQC.MQOO_FAIL_IF_QUIESCING + CMQC.MQOO_INPUT_SHARED;
My url looks like :
http://localhost:8090/queueManager/{queueManagerName}/queue/{queueName}?msgsToRead=-1&&saveMsgs=false
Now I want to create something which doesn't need to specify the queue name instead just take the Queue Manager name and read all the messages from each queue.
I want to a url like this :
http://localhost:8090/queueManager/{queueManagerName}
Can someone guide me to list all the Queues of a QueueManager using MQ API Classes.
I am in a bit of a bind. I am trying to read a message of a WMQ via jms and then convert it to a pcf message for processing. I have only been able to find one resource on this and it hasn't been very helpful [bottom of http://www-01.ibm.com/support/docview.wss?uid=swg21395682 ]
I have tried to implement the technique in the above doc but every time I get to line
PCFMessage response = new PCFMessage(dataInput);
I throw MQRC 3013 - MQRCCF_STRUCTURE_TYPE_ERROR
This is the way my code looks, maybe you can see something I don't.
BytesMessage message = null;
do {
// The consumer will wait 10 seconds (10,000 milliseconds)
message = (BytesMessage) myConsumer.receive(10000);
// get the size of the bytes message & read into an array
int bodySize = (int) message.getBodyLength();
byte[] data = new byte[bodySize];
message.readBytes(data, bodySize);
// Read into Stream and DataInput Stream
ByteArrayInputStream bais = new ByteArrayInputStream(data);
DataInput dataInput = new DataInputStream(bais);
// Pass to PCF Message to process
//MQException.logExclude(new Integer(2079));
PCFMessage qStatsPcf = new PCFMessage(dataInput);
session.commit();
if (message != null) {
processMessage(qStatsPcf);
}
} while (message != null);
myConsumer.close();
A couple updates in response to T.Rob's answer.
I am currently running MQ 7.0. This is a what it is type thing, I can't currently upgrade.
As to what I am trying to do, I am pulling messages from SYSTEM.ADMIN.STATISTICS.QUEUE and I want to parse that information for auditing purposes. The reasoning behind converting to a PCF message is that I am looking to pull some PCF parameters from these messages - for example .getParameter(PCFConstants.MQIAMO_PUTS)
I am not attempting to send messages to MQ in anyway, just pull messages off and process them.
A couple problems with this question:
There is no mention of the version of the version of MQ jms client that is in use. Since IBM has repackaged the Java/JMS classes several times, it is necessary to mention which version you are working with to get a better answer.
It is unclear what it is you are trying to do. An MQ PCF message is processed by the MQ Command Server. The messages are a binary format consisting of a linked list of name/type/value tuples. If your message body is not already in PCF name/type/value format, then casting it as a PCF message is expected to fail.
Since it is not possible to respond to the question as worded with a solution, I'll provide some recommendations based on wild guesses as to what it is you might be trying to do.
Use a modern MQ client. The Technote you linked to is for out-of-support versions of MQ client. You want one that is at least MQ v7.1, but preferably v8.0. since any version of MQ client works with any version of MQ, use the version that is most current. Just remember, the functionality you get is based on the oldest version of MQ used at the client or server. A v8.0 client doesn't get you v8.0 function on a v7.0 QMgr. Go to the SupportPacs page and look for entries with names like MQC**. The MQ v8.0 client is current and it is SupportPac MQC8.
If you really are trying to submit PCF messages to MQ's command processor, instantiate a PCF Agent to do it. Then construct the PCF message using one of the PCF message constructors that lets you specify the selectors and their values.
What happened when you tried using the PCF Java samples? Did they also fail? Did they work? If so, how does your code differ? You did look at IBM's PCF samples, right? Please see Installation directories for samples for the location for the sample programs, including the PCF samples.
If you are not attempting to send messages to the MQ Command Processor, please update the question to let us know what it is you are trying to do and why you believe you need PCF messages to do it.
my 2 cents...
Why are you using JMS to retrieve PCF Messages?
MQ Java is best placed to handle all statistics and event message. My suggestion is go with MQQueueManager object and retrieve a MQMessage out of SYSTEM.ADMIN.STATISTICS.QUEUE and pass it to PCFMessage constructor.
I have not compiled or tested the following, but it gives an outline.
//no try catch block to keep it simple
//assumed MQQueueManager (qmgr object) is already created
//assumed statQueue is available through qmgr.accessQueue() method
do {
MQMessage message = new MQMessage();
//gmo as CMQC.MQGMO_FAIL_IF_QUIESCING | CMQC.MQGMO_WAIT | CMQC.MQGMO_SYNCPOINT | CMQC.MQGMO_CONVERT;
message = statQueue.get(message, gmo);
// Pass to PCF Message to process
PCFMessage qStatsPcf = new PCFMessage(message);
qmgr.commit();
if (message != null) {
processMessage(qStatsPcf);
}
} while (message != null);
statQueue.close();
qmgr.close();
I am trying to create an application which keeps on checking the number of queues up and running in activemq.
And Any way to check whether queue's are working or not i.e. if corrupted and not able to process messages.
Kindly suggest how to do it.
Thanks in Advance.
You can try following code.
public static void main(String[] args) throws Exception
{
// get the initial context
InitialContext ctx = new InitialContext();
// lookup the queue object
Queue queue = (Queue) ctx.lookup("queue/queue0");
// lookup the queue connection factory
QueueConnectionFactory connFactory = (QueueConnectionFactory) ctx.
lookup("queue/connectionFactory");
// create a queue connection
QueueConnection queueConn = connFactory.createQueueConnection();
// create a queue session
QueueSession queueSession = queueConn.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);
// create a queue browser
QueueBrowser queueBrowser = queueSession.createBrowser(queue);
// start the connection
queueConn.start();
// browse the messages
Enumeration e = queueBrowser.getEnumeration();
int numMsgs = 0;
// count number of messages
while (e.hasMoreElements()) {
Message message = (Message) e.nextElement();
numMsgs++;
}
System.out.println(queue + " has " + numMsgs + " messages");
// close the queue connection
queueConn.close();
}
You can ask for stats using the statistics plugin on the broker and the plain JMS api. I.e. to count the number of messages on FOO.BAR, send an empty message to ActiveMQ.Statistics.Destination.TEST.FOO and specify the replyTo header. In the response message, which is of typ MapMessage, you can find the message counter.
Another way is to browse only the first message of the queue using a simple queue browser (similar to the way praveen_programmer suggests) and check the timestamp of that message. If it's older than some threshold, you might have a problem with that consumer. I.e. no messages has been processed in the last hour/minute/day.
Yet another way is to use JMX, or preferably the jolokia REST/HTTP management api.
Just query the destination using http and you get a queue depth back:
To query the queue "q" on localhost, use the following api (you need to supply the user/password for the web console):
http://localhost:8161/api/jolokia/read/org.apache.activemq:type=Broker,brokerName=localhost,destinationType=Queue,destinationName=q
Take a look at Advisory messages. You need to enable them in your config , but you can get a lot of useful about your current activemq instances info through simple JMS messaging. http://activemq.apache.org/advisory-message.html I was using them to highlight slow producer and consumer scenarios.
I haven't been able to figure this one out from Google alone. I am connecting to a non-durable EMS topic, which publishes updates to a set of data. If I skip a few updates, it doesn't matter, as the following update will overwrite it anyway.
The number of messages being published on the EMS topic is quite high, and occasionally for whatever reason the consumer lags behind. Is there a way, on the client connection side, to determine a 'time to live' for messages? I know there is on other brokers, but specifically on Tibco I have been unable to figure out whether it's possible or not, only that this parameter can definitely be set on the server side for all clients (this is not an option for me).
I am creating my connection factory and then creating an Apache Camel jms endpoint with the following code:
TibjmsConnectionFactory connectionFactory = new TibjmsConnectionFactory();
connectionFactory.setServerUrl(properties.getProperty(endpoints.getServerUrl()));
connectionFactory.setUserName(properties.getProperty(endpoints.getUsername()));
connectionFactory.setUserPassword(properties.getProperty(endpoints.getPassword()));
JmsComponent emsComponent = JmsComponent.jmsComponent(connectionFactory);
emsComponent.setAsyncConsumer(true);
emsComponent.setConcurrentConsumers(Integer.parseInt(properties.getProperty("jms.concurrent.consumers")));
emsComponent.setDeliveryPersistent(false);
emsComponent.setClientId("MyClient." + ManagementFactory.getRuntimeMXBean().getName() + "." + emsConnectionNumber.getAndIncrement());
return emsComponent;
I am using tibjms-6.0.1, tibjmsufo-6.0.1, and various other tib***-6.0.1.
The JMSExpiration property can be set per message or, more globally, at the destination level (in which case the JMSExpiration of all messages received in this destination is overridden). It cannot be set per consumer.
One option would be to create a bridge from the topic to a custom queue that only your consumer application will listen to, and set the "expiration" property of this queue to 0 (unlimited). All messages published on the topic will then be copied to this queue and won't ever expire, whatever their JMSExpiration value.
I haven't touched any J2EE stuff in years and I need to whip up a quick JMS client for a demo.
I'm using Eclipse, on OS X and I can't even get started because I can't seem to figure out how to get the required libraries.
This is supposed to be a simple stand alone application (not running in a container) that pulls messages from a topic.
Every JMS implementation has its own set of libraries that specify how you get the initial connection factory. If you have an existing server from which to pull messages, you need to examine the documentation of that server to determine where to find the libraries to put in your classpath and how to create your initial connection factory. If you want to create a server for the purposes of the demonstration, I recommend using an embedded Active MQ broker.
Once you have your connection factory, polling for messages from a topic is pretty straightforward. Here is some example code which can be called to drain a topic of its current messages.
// Implementation specific code
public void drainTopic(TopicConnectionFactory factory, String topicName, String subscriberId)
// set factory properties like the server ID
Connection conn = factory.createConnection();
conn.start();
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = session.createTopic(topicName);
MessageConsumer consumer = session.createDurableSubscriber(topic, subscriberId);
Message message;
while (null != (message = consumer.receive(1000))) {
// do work on the message
}
conn.close();
}
Note the use of a durable subscriber. This means that I don't have to try to maintain a single connection all the time and handle the errors if it times out somehow. But because the subscription is durable, the server knows to retain any messages the topic receives while I'm not connected and provide them on my next connection. This code would be the same regardless of the host OS. The only tricky part is the creation of the provider specific connection factory.