Consume ActiveMQ advisory messages in tomEE mdb - activemq

I have an MDB that manages to consume ActiveMQ advisory messages when deployed on glassfish.
But when i deploy on tomEE this MDB doesnt consume any advisory messages. Is there something I need to turn on?
#MessageDriven(mappedName = "ActiveMQ.Advisory.Consumer.Queue", activationConfig = {
#ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
#ActivationConfigProperty(propertyName = "destination", propertyValue = "ActiveMQ.Advisory.Consumer.Queue.User.*") })
public class AdvisoryMdb implements MessageListener {
private final Logger logger = LoggerFactory.getLogger(getClass().getName());
#Override
public void onMessage(Message message) {
logger.info("onMessage() {}", message);
}
}
(In TomEE I manage to successfully produce and consume messages on these queues i want to advisories for)
edit: i tested to consume on one of these advisory topics with a standalone client and got the messages as expected. So the advisory messages are successfully sent, just that my mdb doesnt pick them up properly.

What Advisory messages are you trying to consume?
Taking a look at the documentation here... I see ActiveMQ.Advisory.Consumer.Queue is listed meaning as Consumer start & stop messages on a Queue. Your target is ActiveMQ.Advisory.Consumer.Queue.User.*, So do you have a queue called User? Is this a single queue or are there multiple queues underneath User?
Also reading the doc, there seems to be some changes over the years of the Advisory queue names. Can you check the ActiveMQ versions across the platforms and make sure you're comparing apples to apples? Also, on the documentation page I listed, I kind of wonder if some of the advisories are disabled. It doesn't list that particular queue as one that can be disabled, but you might try explicitly enabling all advisories and see if that helps.

By chance i attempted to remove
mappedName = "ActiveMQ.Advisory.Consumer.Queue"
from the #MessageDriven annotation and suddenly it works on both TomEE and glassfish. Not sure why I added that in the first place, guess it was not needed for glassfish either.

Related

MassTransit generates _skipped queues which I want to ignore

Can anyone guess what the problem can be because I'm clueless on how to solve this. MassTransit generates _skipped queues and I don't have a clue why it is generating those. It is being generated when doing a publish request response.
Request Client is created using following method in MassTransit.RequestClientExtensions
public static IRequestClient<TRequest, TResponse> CreatePublishRequestClient<TRequest, TResponse>(this IBus bus, TimeSpan timeout, TimeSpan? ttl = null, Action<SendContext<TRequest>> callback = null) where TRequest : class where TResponse : class
{
return (IRequestClient<TRequest, TResponse>) new PublishRequestClient<TRequest, TResponse>(bus, timeout, ttl, callback);
}
And Request is done as follows:
TResponse response = TaskUtil.Await(() => requestClient.Request(request));
As you can see this is Request Response scenario where Request is being sent to all consumers. But because at the moment we have only one consumer it only is being sent to that consumer. deadletters appear easily if a publishrequestresponse is done to multiple consumers, once a consumer responds, the other consumer doesn't know where to respond and a deadletter is generated. But because we have one consumer here, we can eliminate this possibility.
So what could be other reasons for these skipped queues? Huge thanks for any help on how I can troubleshoot this...
I have to say, in the Consume method, in some condition, we raise a RequestTimeoutException and catch it in the requesting application. This is tested and this doesn't generate skipped queues.
Skipped queue is a dead letter queue. It means that your endpoint queue has a binding to some message exchange but there is no consumer for that message any longer. Maybe you change the topology and moved the consumer. You can go to the RMQ management UI and check the bindings for your endpoint exchange. If you look at messages that ended up in the skipped queue, you will find out what message types to look for.
Exchanges are named after message types so it will be easy to find the obsolete binding.
Then, in the management UI, you can manually remove the binding that is obsolete and there will be no more messages coming to the skipped queue.

rabbitListener execute task when no message in the queue

we are using #RabbitListener to listen to the queue and when there are messages we process them. However I want to do some reporting task when queue is empty, this happens when our app just processed tons of messages in the queue and no more message for a while. that's the time I want to report. How can i do that with #RabbitListener?
here is my code:
#RabbitListener(queues = "${consumer.queue}", containerFactory = "ListenerContainerFactory")
public void handleMessage(Message message) {
processEvent(message);
}
As I answered your other question a few weeks ago there is no mechanism in AMQP (and hence Spring AMQP) to notify the consumer that there are currently no messages in the queue.
We could modify the container to fire an ApplicationEvent once, when no message is found after messages have been processed, but that would require a modification to the framework. Your listener would have to implement ApplicationListener to get such an event.
Feel free to open a New Feature JIRA Issue if you want and we might be able to take a look at it.

Empty a jms queue in JBOSS 7 using HornetQ

I am using jboss 7.1.1 final and HornetQ 2.2.13 final.
I have a couple of queues configured and one of them is "full" of messages, couple of thousands. I cant delete the messages.
Ive tried deleting them using jboss cli with the command
/subsystem=messaging/hornetq-server=default/jms-queue=Queue:remove-messages
it responds with success, but the messages are still there...
Ive tried deleting them using JConsole with a jmx command. It responds with the number zero and the count messages are still the same.
Ive tried deleting the queue inside Jboss Console and restarting the AS. After I configure the queue again, the messages are still there cause its persisted.
The only way it worked was configuring hornetq server to disable persistence inside standalone.xml.
Does anybody know how to do it using jconsole or jboss cli?
All you have to do is to call the method:
from the jboss-cli:
/subsystem=messaging/hornetq-server=default/jms-queue=testQueue:remove-messages
I just tried at the exact versions you tried by adding a large ammount of messages, including with paging.. and everything worked fine.
I configured my system to page, and used this to create a few thousand messages:
HornetQConnectionFactory cf = HornetQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, new TransportConfiguration(NETTY_CONNECTOR_FACTORY));
Connection conn = cf.createConnection("guest", "hello");
Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
javax.jms.Queue queue = sess.createQueue("testQueue");
MessageProducer prod = sess.createProducer(queue);
for (int i = 0 ; i < 50000; i++)
{
TextMessage msg = sess.createTextMessage("hello " + i);
prod.send(msg);
if (i % 500 == 0)
{
System.out.println("Sent " + i);
System.out.println("commit");
sess.commit();
}
}
sess.commit();
conn.close();
I then tried the remove method and it worked:
/subsystem=messaging/hornetq-server=default/jms-queue=testQueue:remove-messages
If this is not working there are two possibilities:
We changed how the locks are held on the queue during delivery. Perhaps you are hitting a fixed bug and you would have to move to a newer version.
You have queues in delivery on consumers. We can't delete messages if they are on the Consumer's buffer in delivery state. You would have to remove consumers to delete all messages.
I'm adding this answer here as I did a lot of research trying to replicate your issue and everything worked like a charm. I would need more information to what's going.
I think the best would be the user's forum where we can discuss it further. SOF is going to simple questions / answer. It's not a place for investigating bugs or anything like that.
https://community.jboss.org/en/hornetq?view=discussions

Consumer is not receiving messages from ActiveMQ

We are facing a random issue with ActiveMQ and its consumers. We observe that, few consumers are not receiving messages, even though they are connected to ActiveMQ queue. But it works fine after the consumer restart.
We have a queue named testQueue at ActiveMQ side. A consumer is trying to de-queue the messages from this queue. We are using Spring's DefaultMessageListenerContainer for this purpose. Message is being delivered to the consumer node from ActiveMQ Broker. From the tcpdump as well, it was obvious that, message is reaching the consumer node, But the actual consumer code is not able to see the message. In other words, the message seems to be stuck either in ActiveMQ consumer code or in Spring’s DefaultMessageListenerContainer.
See refer to the below fig. for more clarity on the issue. Message is reaching Consumer node, but it is not reaching the “Actual Consumer Class”, which means that the message got stuck either in AMQ consumer code or Spring DMLC.
Below are the details captured from ActiveMQ admin.
Queue-Name /Pending-Message-Count /Consumer-Count /Messages-Enqueued /Messages-Dequeued
testQueue /9 /1 /9 /0
Below are the more details.
Connection-ID /SessionId /Selector /Enqueues /Dequeues /Dispatched /Dispatched-Queue /Prefetch
ID:bearsvir52-45176-1375519181268-3:5 /1 / /9 /0 /9 /9 /250
From the second table it is obvious that, messages are being delivered to the consumer, but the consumer is not acknowledging the message. Hence the messages are stuck in Dispatched-Queue at broker side.
Few points for to your notice:
1)There is no time difference b/w Broker node and consumer node.
2)Observed the tcpdump at consumer side. We can see MessageDispatch(Openwire) packet being transferred to consumer node, But could not find the MessageAck(Openwire) for the same.
3)Sometimes it is working on a node, and sometimes it is creating problem on the same node.
One cause of this can be incorrectly using a CachingConnectionFactory (with cached consumers) with a listener container that dynamically adjusts the consumers (max consumers > consumers). You can end up with a cached consumer just sitting in the pool and not being actively used. You never need to cache consumers with a listener container.
For problems like this, I generally recommend running with TRACE logging and you can see all the consumer activity.
It took lot of time to figure out the solution. There seems to be some issue with the org.apache.activemq.ActiveMQConnection.java class, in case of AMQ fail over. The connection object is not getting started at consumer side in such cases.
Following is the fix i have added in ActiveMQConnection.java file and compiled the sources to create activemq-core-x.x.x.jar
private final Object startMutex = new Object();
added a check in createSession method
public Session createSession(boolean transacted, int acknowledgeMode) throws JMSException {
synchronized (startMutex) {
if(!isStarted()) {
start();
}
}

Bus Configuration with Autofac: Issue with RabbitMQ vs Loopback?

For some reason I can not post to the masstransit google group, even though I joined, I am told that I do not have permission to post to this group. So I am going to post here...
Now for my problem:
I am using MassTransit v2.7.2, with AutoFac v2.6.3. I am trying to configure Autofac to scan an assembly and register my consumers; all types that implement the IConsumer interface. This seems to work.
I am using the MassTransit.AutofacIntegration assembly and the LoadFrom(...) extension method to register the consumers from the container with MassTransit when I configure the bus. Here is the code:
var builder = new ContainerBuilder();
builder
.RegisterAssemblyTypes(typeof (CreateElectionCommandHandler).Assembly)
.Where(type => type.Implements<IConsumer>())
.AsSelf();
var container = builder.Build();
var localBus = ServiceBusFactory.New(configurator =>
{
//configurator.ReceiveFrom("loopback://localhost/testqueue");
configurator.ReceiveFrom("rabbitmq://localhost/commandqueue");
configurator.UseRabbitMq();
configurator.Subscribe(sbc => sbc.LoadFrom(container));
});
Assert.IsTrue(container.IsRegistered<CreateElectionCommandHandler>());
Assert.IsTrue(container.IsRegistered<TerminateElectionCommandHandler>());
Assert.AreEqual(1, localBus.HasSubscription<CreateElection>().Count());
Assert.AreEqual(1, localBus.HasSubscription<TerminateElection>().Count());
If I run the above code using the loopback
configurator.ReceiveFrom("loopback://localhost/testqueue");
configuration (comment out the rabbitmq conifig), the test will pass.
If I comment out the "loopback" config and comment in the
configurator.ReceiveFrom("rabbitmq://localhost/commandqueue");
configurator.UseRabbitMq();
config, the test will fail. (Note: The rabbitmq queue is already up and running - I have been using it as part of my POC). Specifically, it will fail on the assertion:
Assert.AreEqual(1, localBus.HasSubscription<CreateElection>().Count());
Assert.AreEqual(1, localBus.HasSubscription<TerminateElection>().Count());
Can anybody help me understand what is going on here? I am new to MT so fully anticipating that I am missing something, or not configuring something correctly.
Am I correct to assume that if there are no message subscriptions registered, then the bus will not be able to deliver to any of my consumers (even though the consumers are registered)?
Any help much appreciated!
With RabbitMQ, subscriptions are not added to the outbound bus until a message is published. This is due to how the classes are inspected and outbound endpoints to the appropriate exchanges are created and added to the pipeline.
So yes, this test will fail with RabbitMQ, but it will in fact work properly when the message is published.
The HasSubscription() calls are really meant for verifying that consumers and such are properly configured using the loopback transport, and really just for vetting out things that are not really integration issues but just making sure the internal MassTransit code is working.
So, if you were to add a Publish() call of one of those types, and then call the HasSubscription() extension method, it would pass.
I would check to see if MassTransit creates an exchange the message types in question. Messages are sent to the exchange and all consumer queues are bound to the exchange. You can look at the Rabbit config to see if that's happened or not as well. And with no consumers registered, no messages will be delivered. Chris has been working on adding options to error is there's consumers so you can handle it in your code.
I would join the mailing list https://groups.google.com/forum/?fromgroups=#!forum/masstransit-discuss to get help. There's a lot more people that can ask the right questions to get you where you need to be.