My question is pretty simple, but I am having a bad time finding a solution.
I want to be able to get all the queues in the server (or session, that would also be ok). Is that possible?
My situation is the following:
I am new to openMQ, Glassfish, activeMQ and so on. I developed a monitoring system for activeMQ in which I get all the existing queues and show to the user, so it can get information about number of messages and so on.
To do that, I have this code:
ActiveMQConnection.makeConnection("tcp://localhost:61616");
activeMQConnection.start();
//Get queues
DestinationSource destinationSource = activeMQConnection.getDestinationSource();
Set<ActiveMQQueue> queues = destinationSource.getQueues();
this last line gets all the queues for the connection, and this is exactly what I need. But this was my code for ActiveMQ.
Now the team decided to change to openMQ, and I have to adapt my monitoring system to be able to handle that. I would like to use LDAP so I can do it technology-independent. After a lot of research I came to this code:
ConnectionFactory connectionFactory = (ConnectionFactory) ctx.lookup("cn=QueueConnectionFactory");
Connection connection = connectionFactory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue myQueue = session.createQueue("myQueue");
This is good, because it would be completely independente (I think, have to test it). But the problem is that I have to register the queue, something I would not like to do. I would like to get all the existing queues in the server without any need for registering, but I can't find any GetQueues() method or any way to mimic its behavior.
I also found out the the DestinationSource class in activeMQ inherits from MessageListener, but this class doesn't provides any similar method :(
Could you please help me?
thank you,
Oscar
I was able to do that using JMX, here is the code:
HashMap environment = new HashMap();
String[] credentials = new String[] { "user", "pass" };
environment.put(JMXConnector.CREDENTIALS, credentials);
JMXServiceURL url = new JMXServiceURL("URL");
// Get JMX connector, supplying user name and password
JMXConnector jmxc1 = JMXConnectorFactory.connect(url, environment);
// Get MBean server connection
MBeanServerConnection mbsc = jmxc1.getMBeanServerConnection();
ObjectName destMgrConfigName = new ObjectName(MQObjectName.DESTINATION_MANAGER_MONITOR_MBEAN_NAME);
// Create operation's parameter and signature arrays
Object opParams[] = {};
String opSig[] = {};
// Invoke operation
ObjectName[] objectNames = (ObjectName[]) mbsc.invoke(destMgrConfigName, DestinationOperations.GET_DESTINATIONS, opParams, opSig);
for (ObjectName objectName : objectNames) {
System.out.println(objectName.getCanonicalName());
System.out.println(objectName.getKeyProperty("name"));
}
more references here: http://forums.oracle.com/forums/thread.jspa?threadID=2129291&tstart=0
Related
Can someone please help me how to fetch the Enqueue Count for a particular queue in Active MQ?
Here is my code:
BrokerService broker = new BrokerService()
String queueName= "queue.Test"
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory('ACTIVEMQ URL')
Connection connection = connectionFactory.createConnection()
connection.start()
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)
ActiveMQDestination requestDestination = session.createTopic(queueName)
QueueViewMBean view = (QueueViewMBean)broker.getDestination(requestDestination)
println("Count = "+view.getEnqueueCount())
But this does not seem to be working. How can I fix it?
You appear to be trying to cast ActiveMQ JMS client resources into JMX MBeans which of course would never work. You need to use JMX to access the management capabilities of the broker.
Some examples of using the MBeans can be found in the unit tests of the broker
Is it possible to set the ActiveMQ transport parameters such as maxReconnectAttempts using a java API at the runtime?
In my case I'm creating the ActiveMQ connection factory initially by providing a basic failover url failover:
ActiveMQSslConnectionFactory connectionFactory = new ActiveMQSslConnectionFactory("(ssl://192.168.1.112:61617,ssl://192.168.1.112:61619)?randomize=false")
However later I would require to set transport parameter to this connection factory such as maxReconnectAttempts. Is it possible?
certainly, simply like this:
ActiveMQSslConnectionFactory connectionFactory = new ActiveMQSslConnectionFactory("failover:(ssl://192.168.1.112:61617,ssl://192.168.1.112:61619)?randomize=false&maxReconnectAttempts=Value")
All failover Transport Options can be set in the url
http://activemq.apache.org/failover-transport-reference.html
If you want to change the url later, you can call connectionFactory.setBrokerURL("newURL"), after that all new connections created will be configured with the new parameters of the url.
if you want to change that after the creation of the ConnectionFactory, keep in mind that a new instance of FailoverTransport is created for each new Connection based on the url parameters and each Connection holds an instance of his FailoverTransport, so to change his state you can access it like this :
((FailoverTransport) ((TransportFilter) ((TransportFilter) ((ActiveMQConnection) connection).getTransport()).getNext()).getNext())
.setMaxReconnectAttempts(10);
or more readable :
org.apache.activemq.transport.TransportFilter responseCorrelator = (TransportFilter) ((ActiveMQConnection) connection).getTransport();
TransportFilter mutexTransport = (TransportFilter) responseCorrelator.getNext();
FailoverTransport failoverTransport = (FailoverTransport) mutexTransport.getNext();
failoverTransport.setMaxReconnectAttempts(10);
to understand why all these casts, you can take a look at source code of this method :
org.apache.activemq.transport.failover.FailoverTransportFactory.doConnect(URI)
here https://github.com/apache/activemq/blob/master/activemq-client/src/main/java/org/apache/activemq/transport/failover/FailoverTransportFactory.java
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.
environment.put(Context.INITIAL_CONTEXT_FACTORY,QUEUE_CONTEXT);
System.out.println("QUEUE_URL -> " + QUEUE_URL);
environment.put(Context.PROVIDER_URL,QUEUE_URL);
try{
ctx = new InitialDirContext(environment);
String MYCF_LOOKUP_NAME = QUEUE_CONTEXT_FACTORY;
connectionFactory = (ConnectionFactory) ctx.lookup(MYCF_LOOKUP_NAME);
connection = ((MQQueueConnectionFactory) connectionFactory)
.createQueueConnection();
I dont know whther it correct or not.. It gives me connectivity issue
n the first program it asks for queue manager name but in the second program it doesn't require Queue Manager name. I need to replace the First program code with the second program.. Can anyone help me on this ..??
You're using JNDI here - JNDI is a store of Java Obects. For JMS this will be ConnectionFactorys and Destinations (Queues or Topics).
So you need to put into JNDI an Connection Factory as the code suggets you already have and also a Queue.
Would suggest if this is not clear why you need to do this I suggest searching for a JNDI tuturial and also a JMS one - to get the very basic background.
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.