Get queues depth from java code - java

Can anyone help in doing the code in java of getting the depth of the queues. We are having 4 queues in IBM WebSphere MQ and inside them there are messages.
I want to write a jsp to read the queue names and their depth while running the report. How do I do that?
Can anyone help in getting the full solution because I don't know what to do

I doens't think there is a way to retrieve the queue depth using JMS. You can however use MQ Series specific Java API to retrieve this information. Here is the sample code. Pay attention to int openOptions = MQC.MQOO_INQUIRE;
Here is the reference guide
int depth = 0;
MQQueueManager qMgr; // define a queue manager object
String mqHost = "";
String mqPort = "";
String mqChannel = "";
String mqQMgr = "";
String mqQueue = "";
try {
// Set up MQSeries environment
MQEnvironment.hostname = mqHost;
MQEnvironment.port = Integer.valueOf(mqPort).intValue();
MQEnvironment.channel = mqChannel;
MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY,
MQC.TRANSPORT_MQSERIES);
qMgr = new MQQueueManager(mqQMgr);
int openOptions = MQC.MQOO_INQUIRE;
MQQueue destQueue = qMgr.accessQueue(mqQueue, openOptions);
depth = destQueue.getCurrentDepth();
destQueue.close();
qMgr.disconnect();
} catch (Exception err) {
err.printStackTrace();
}

If you install the WMQ client from the IBM download (as opposed to just grabbing the class libs from the QMgr installation) you get sample code. Among the samples provided are several that list queue names, inquire on object properties and create objects. In a default installation on Win 7 these can be found at C:\Program Files (x86)\IBM\WebSphere MQ\tools\pcf\samples.
Download the WMQ client libraries here:
WMQ v6.0 is SupportPac MQC6 (End of life is September 2012)
WMQ v7.0 is SupportPac MQC7
WMQ v7.1 is SupportPac MQC71
The SupportPac landing page is here.
You are STRONGLY encouraged to use the latest WMQ client for any new development. It will work for all prior versions of WMQ at whatever level of functionality is provided by the target QMgr. Please see the Compatibility & Interop statement in the Infocenter. You can find the Infocenter for the WMQ version of server or client that you are using from the WMQ Library landing page.

A few of these functions are depreciated in IIB, so am pasting the updated code. It works :)
Enjoy
Getting MQ Queue Depth From Java:
try {
int depth = 0;
MQQueueManager qMgr; // define a queue manager object
String mqHost = "";
String mqPort = "";
String mqChannel = "";
String mqQMgr = "";
String mqQueue = "";
try {
// Set up MQSeries environment
MQEnvironment.hostname = mqHost;
MQEnvironment.port = Integer.valueOf(mqPort).intValue();
MQEnvironment.channel = mqChannel;
//MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY,MQC.TRANSPORT_MQSERIES);
qMgr = new MQQueueManager(mqQMgr);
//int openOptions = 1;//MQC.MQOO_INQUIRE;
int openOptions = CMQC.MQOO_INQUIRE + CMQC.MQOO_FAIL_IF_QUIESCING + CMQC.MQOO_INPUT_SHARED;
MQQueue destQueue = qMgr.accessQueue(mqQueue, openOptions);
depth = destQueue.getCurrentDepth();
destQueue.close();
qMgr.disconnect();
MbMessage outMessage = new MbMessage();
outAssembly = new MbMessageAssembly(inAssembly, outMessage);
MbElement root = outMessage.getRootElement();
MbElement outXmlRoot = root.createElementAsLastChild(MbXMLNSC.PARSER_NAME);
MbElement Appointment = outXmlRoot.createElementAsLastChild(MbElement.TYPE_NAME, "RootElementXMLName", null);
Appointment.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "Q_DepthFromServer", depth);
out.propagate(outAssembly);
}

Related

Setting connection's `max_frame_size` in Qpid Proton AMQP 1.0 client library

I would like to simply open an AMQP 1.0 connection with a specific max_frame_size using the Apache Qpid Proton client library. This is inside a testsuite, not a real world application.
The Java library seems more advanced than the C library and its various bindings for other languages, so I started to use the Java one. Unfortunately, I can't find a way to set this parameter, though there must be a way: there is this Transport class which offers to get or set max_frame_size.
I first tried with the Messenger API, then I played with the Engine API. I couldn't figure out how to access the transport instance. In the case of the Engine API, I see there is a Connection.getTransport() and tried that, but it's NULL at the time I call this function.
Here is my last test:
private void do_test_with_frame_size(int frame_size, int payload_size) {
Connection conn = Connection.Factory.create();
Transport transport = conn.getTransport();
transport.setMaxFrameSize(frame_size);
Session session = conn.session();
Sender sender = session.sender("sender");
conn.open();
session.open();
sender.open();
if (sender.getCredit() > 0) {
String uri = System.getProperty("broker_uri");
assertNotNull(uri);
String address = String.format("%s/fragmentation-%d-%d",
uri, frame_size, payload_size);
Message message = Proton.message();
message.setAddress(address);
message.setBody(new AmqpValue(new byte[payload_size]));
byte[] msgData = new byte[1024];
int length;
while(true) {
try {
length = message.encode(msgData, 0, msgData.length);
break;
} catch(BufferOverflowException e) {
msgData = new byte[msgData.length * 2];
}
}
byte[] tag = "0".getBytes();
Delivery delivery = sender.delivery(tag);
sender.send(msgData, 0, length);
delivery.settle();
sender.advance();
sender.close();
sender.getSession().close();
sender.getSession().getConnection().close();
}
}
I admit I have very limited knowledge of Java. Could you please confirm it is even possible to set this parameter and, if yes, tell me how to?
You need to create a Transport instance for the connection to use and then bind the transport to the connection instance. A created Connection does not have an implicit Transport bound to it which is why you get a null returned to you currently.
private final Transport protonTransport = Proton.transport();
private final Connection protonConnection = Proton.connection();
...
this.protonTransport.setMaxFrameSize(maxFrameSize);
this.protonTransport.setChannelMax(CHANNEL_MAX);
this.protonTransport.bind(this.protonConnection);

Restore emails from local file system to exchange account in ews api

I am trying to restore emails from local file system to any exchange account in java, I have tried with copyItems(ItemId itemId, Destination folderId) and moveItems(ItemId itemId, Destination folderId) methods of EWS(Exchange api) but its throws an exception as "ErrorInvalidIdMalformed", so can you please help me to resolve this..
for (Object obj : emlFiles) {
File file = (File) obj;
InputStream source = null;
EmailMessage message = null;
source = new FileInputStream(file);
MimeMessage msg = new MimeMessage(null, source);
message = new EmailMessage(service);
// Set properties on the email message.
message.ParentId = msg.getMessageID();
ItemId id = (ItemId.getItemIdFromString(message.ParentId));
//service is exchange service object..
service.moveItem(id,destinationFolder.getId());
}
Thanks in advance!!
Using MoveItem won't work in this instance because you can only move an existing store item from one place to other. Just call save on the Item you created and use the destination Folder you want to save it to. eg
message.save(destinationFolder.getId());
You may also want to set the SentFlag so the message won't show as a draft eg see the example in https://msdn.microsoft.com/en-us/library/office/dn672319(v=exchg.150).aspx
ExtendedPropertyDefinition PR_MESSAGE_FLAGS_msgflag_read = new ExtendedPropertyDefinition(3591, MapiPropertyType.Integer);
email.SetExtendedProperty(PR_MESSAGE_FLAGS_msgflag_read, 1);
Cheers
Glen

Migrating IBM MQ to javax.jms.* implementation - How does MQOPEN translate to JMS API?

How do you get the same effect as ibm's proprietary mq api's openOptions when using MQ with JMS api?
Is there even a concept of openOptions in the JMS API? If so, what is the equivilent in terms of the API classes/methods?
Related stackoverflow question - migrating-from-ibm-mq-to-javax-jms-weblogic
You are comparing apples and oranges. Yes, both are fruit but they are completely different fruit. There is no direct comparison between the 2.
1) A JMS session with "transacted" and "createSender" is basically an open output with syncpoint.
i.e.
// Open Options
int oo = MQC.MQOO_OUTPUT + MQC.MQOO_INQUIRE + MQC.MQOO_FAIL_IF_QUIESCING;
// Put Msg Options
MQPutMessageOptions pmo = new MQPutMessageOptions();
pmo.options = MQC.MQPMO_SYNCPOINT + MQC.MQPMO_FAIL_IF_QUIESCING;
2) A JMS session with "createReceiver" (non-transacted) is basically an open input.
i.e.
int oo = MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_INQUIRE + MQC.MQOO_FAIL_IF_QUIESCING;
// Get Msg Options
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = MQC.MQGMO_FAIL_IF_QUIESCING;
This simple example shows to how to send a Message (using JBoss MQ):
final Properties initialContextProperties = new Properties();
initialContextProperties.put("java.naming.factory.initial",
"org.jnp.interfaces.NamingContextFactory");
initialContextProperties.put("java.naming.provider.url",
"jnp://localhost:1099");
//
final InitialContext ic = new InitialContext(initialContextProperties);
final QueueConnectionFactory qcf = (QueueConnectionFactory) ic
.lookup("XAConnectionFactory");
final Queue queue = (Queue) ic.lookup("queue/A");
//
final QueueConnection queueConnection = qcf.createQueueConnection();
final boolean transacted = false;
final QueueSession queueSession = queueConnection.createQueueSession(
transacted, Session.AUTO_ACKNOWLEDGE);
final QueueSender queueSender = queueSession.createSender(queue);
final TextMessage textMessage = queueSession.createTextMessage("Hello");
queueSender.send(textMessage);
so there are different options on different stages/levels:
You normally need to have some properties for the JNDI lookup (to get the InitialContext).
You have to lookup the factory and the queue by name using JNDI.
There are some settings when you create the QueueSession: transacted, acknowledge.
The usage is specified when you call createSender, createReceiver, createBrowser on the QueueSession instance.

Browse, read, and remove a message from a queue using IBM MQ classes

I'm writing a simple Java application using MQ classes for Java with Eclipse.
Right now I'm able to browse a remote queue without removing the messages stored.
Here is the code of the reading cycle:
MQQueueManager QMgr = new MQQueueManager(qManager); //<-- qManager is a String with the QMgr name
int openOptions = MQC.MQOO_FAIL_IF_QUIESCING | MQC.MQOO_INPUT_SHARED | MQC.MQOO_BROWSE;
MQQueue queue = QMgr.accessQueue(queueName, openOptions);
MQMessage theMessage = new MQMessage();
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options=MQC.MQGMO_WAIT | MQC.MQGMO_BROWSE_FIRST;
gmo.matchOptions=MQC.MQMO_NONE;
gmo.waitInterval=5000;
boolean thereAreMessages=true;
while(thereAreMessages){
try{
//read the message
queue.get(theMessage,gmo);
//print the text
String msgText = theMessage.readString(theMessage.getMessageLength());
System.out.println("msg text: "+msgText);
// <--- Solution code Here
//move cursor to the next message
gmo.options = MQC.MQGMO_WAIT | MQC.MQGMO_BROWSE_NEXT;
}catch(MQException e){
if(e.reasonCode == e.MQRC_NO_MSG_AVAILABLE) {
System.out.println("no more message available or retrived");
}
thereAreMessages=false;
} catch (IOException e) {
System.out.println("ERROR: "+e.getMessage());
}
}
Main question:
After the read message line and before moving the cursor to the next message how can I remove the message from the queue?
Secondary question:
Eclispe is warning me that all the costants used for the options are deprecated; which are the correct ones to use?
Solution:
Here the solution I'm really looking for:
// set te cursor to remove the message from the queue
gmo.options = CMQC.MQGMO_MSG_UNDER_CURSOR;
queue.get(theMessage, gmo);
these lines have to be inserted in the question code
I've found it here: http://www.velocityreviews.com/forums/t124676-mq-series-messages-browse-and-delete.html
Solution:
Here the solution I'm really looking for:
// set te cursor to remove the message from the queue
gmo.options = CMQC.MQGMO_MSG_UNDER_CURSOR;
queue.get(theMessage, gmo);
these lines have to be inserted in the question code
I've found it here: http://www.velocityreviews.com/forums/t124676-mq-series-messages-browse-and-delete.html
To delete a message, follow the procedure described in the MQ documentation.
For deprecated constant values, check again the Javadoc, the recommended way is described.
MQC.MQOO_INPUT_SHARED --> CMQC.MQOO_INPUT_SHARED

MQ Pure Java Client Lib

I am evaluating Websphere MQ7. I am a traditionally a TibRV guy. One thing I do not like is the fact that the IBM java client libs require C++ libs in order to run. Is there anyway to run the IBM java client libs without requiring the C++ libs? e.g. is there a pure java client library for MQ ?
I have previously written a JMS client to MQSeries v6 (not your version, I know) without needing to install native libs. The only IBM libraries I required were titled:
com.ibm.mq-6.jar
com.ibm.mqbind.jar
com.ibm.mqjms-6.jar
According to this post they come with the client install. I assume you can install it once, then re-use the jars (any licensing issues and expert opinions aside).
EDIT: In response to your comment, here's the client code I hacked up. It is for reading messages from a queue and blatting them to files. It's written in Scala. I hope it helps somewhat.
import com.ibm.mq._
import java.text._
import java.io._
case class QueueDetails(hostname: String, channel: String,
port: Int, queueManager: String, queue: String)
class Reader(details: QueueDetails) {
def read = {
MQEnvironment.hostname = details.hostname
MQEnvironment.channel = details.channel
MQEnvironment.port = details.port
val props = new java.util.Hashtable[String, String]
props.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES)
MQEnvironment.properties = props
val qm = new MQQueueManager(details.queueManager)
val options = MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_INQUIRE
val q = qm.accessQueue(details.queue, options, null, null, null)
val depth = q.getCurrentDepth
val indexFormat = new DecimalFormat(depth.toString.replaceAll(".", "0"))
def exportMessage(index: Int): Unit = {
if (index < depth) {
val msg = new MQMessage
q.get(msg, new MQGetMessageOptions)
val msgLength = msg.getMessageLength
val text = msg.readStringOfByteLength(msgLength)
val file = new File("message_%s.txt".format(indexFormat.format(index)))
val writer = new BufferedWriter(new FileWriter(file))
writer.write(text)
writer.close
println(file.getAbsolutePath)
exportMessage(index + 1)
}
}
exportMessage(0)
q.close
qm.disconnect
}
}

Categories