What is Redelivery and Rollback in Apache Camel? - apache

I am new to apache camel and couldn't understand the difference between Redelivery and Rollback.. Could you please help me understand this ?

Redelivery = something failed, but try again.
Rollback = something failed dont try again, but stop routing and fail.
Error handling can be a complex area to understand and master with Camel. My book Camel in Action 2nd ed has a full chapter on this subject.
There is also some docs online with some details (although not as elegant written and fully up to date - our website and docs on Apache Camel is currently undergoing a transition to a new modern look and feel): http://camel.apache.org/error-handling-in-camel.html

Related

RTI DDS reader fails to identify topic

and subsequently obviously to read/take the topic. The problematic topic is published under BuiltinQosLibExp::Generic.KeepLastReliable.TransientLocal policy and the message is fired only once at the startup of the publisher application. Few things to consider:
Im not using this policy and taking the default policy configuration in code
dds::sub::qos::DataReaderQos tempQos = inSubScriber->default_datareader_qos();
m_EntitySpecReader = new dds::sub::DataReader<XXX_ICD::Entity_Specification_DT>(*inSubScriber, topicLocal, tempQos, m_EntitySpecListener);
from subscriber
The problem is not Firewall or some connection issue, as I know to receive other cyclic topics without any problem.
It is frustrating that I see this topic if Im trying to monitor either with rtiddsspy or RTI administration console.
Last bullet and most frustrating, when I actually felt stuck, is that I have a listener configured with all available callbacks and I thought to receive if not the data at least some callback clue regarding the possible mismatch, lost, something .... but it keeps silence no matter what Im trying to do :)
Will be more than happy to understand if somebody has an answer or potential direction to check :)
You are using the default QoS for your DataReader. This means that its Durability policy is VOLATILE. Even though the DataWriter is configured as TRANSIENT_LOCAL, it will not deliver "old" samples to your DataReader since it is not requesting those due to its volatile durability. In this context, "old" samples are samples that were written before the DataWriter discovered the DataReader.
Things should start working as expected when you configure your DataReader with a Durability policy as TRANSIENT_LOCAL as well.
If you instrumented a Listener on the DataReader, it should show you that a match has taken place though, or that it has failed. If you implemented both the on_subscription_matched and on_requested_incompatible_qos callbacks, then at least one of those two should fire if you have both applications started and if they are able to discover each other.
Since you discovered that the problem was a type mismatch, I wanted to show how the AdminConsole tool could have helped you finding that. Reproducing your issue, this is what it showed:

What would make expressjs 503?

I use expressjs for my server. A user hits a proxy service that hits mine. The proxy service is telling me that mine has given a 503. In this case, I can't really be logging that it happened since it seems express just error'ed out. All I know is that this other service receives a 503. Nowhere in my code do I set this up. I couldn't find anything when searching around, and if it weren't the proxy I wouldn't know the 503s are happening. In hundreds of thousands of requests, this happened just under 100 times.
I'm not expecting anyone to have the direct answer, however any clues would be much appreciated and any clue that gets to the answer will be marked as the answer with my comment below. Hoping some comments will help me give this question better information!
Well, one thing that comes to mind is server overload. If the route (s) you're checking are performing synchronous tasks, and you're sending alot of requests at once, you might end up blocking your server. Express recommend that every route handler you have should be async, so the server won't get blocked even if a lot of requests are happening.
I don't know if that's your case, but it's worth a check.
The solution relates to Envoy & Node. A coworker suggested server timeouts and I found https://github.com/envoyproxy/envoy/issues/1979.
In my case I added this: server.keepAliveTimeout = 0;
You can see docs over at https://nodejs.org/docs/latest-v10.x/api/http.html#http_server_keepalivetimeout.
I don't work on the infrastructure side of things so it took a bit for me to figure it was in that layer with folks on the teams who implemented the usage of Envoy.
When Envoy gets ECONNRESET it sends back a 503

Apache camel restarting the route

I have a something as following:
from("rabbitmq://...")
.process(processor1)
:
.process(processorn)
.process(SendToExternalAppProcessor)
The SendToExternalAppProcessor.process() uses producer template to send the some request formed from the contents in the exchange parameter to another rabbitmq2 with sendBody() method.
The issue is that once SendToExternalAppProcessor.process() executes and above route executes, it restarts above route again along with the listener of the rabbitmq2.
What I am missing here? Is there any apache camel configuration that is slipping from my attention?
PS: I know I have not given any concrete code here so as to replicate the scenario on your machine, but am in hope that experienced head and eyes will be quick to recall and suggest something. (Also I cannot straightway share my project code and also its big and complex)
Update:
I tried by commenting sendBody() and still restarts the route. I must be missing something weird basic setting here...
I think this is just a misunderstanding of the way routes work. 'from' is not a one-shot event; it will keep accepting messages from the source until you explicitly tell the route to stop.
"from " works as a normal rabbitmq consumer. The route is designed as always running.
If you just want to transfer exchanges to another rabbitmq , "to" is enough.
from("rabbitmq://...")
.process(processor1)
:
.process(processorn)
.to("rabbitmq://rabbit2...")
Please let us know which version of Camel you are using.
Are you using transacted camel flow? If any transaction mode is on then one possible issue could be JMS commit acknowledgment. May be Camel is consuming message and processing but not acknowledging rabbitmq. So message is still there and consuming again and again by camel route. By default it is AUTO_ACKNOWLEDGE, so that should not be the case if not transacted camel route.

Error notification on mule flows

I am relatively new to mule and Im wondering if there is a built in error notification if there an error on a mule flow or if this can be set up in the mmc to trigger an alert if something is wrong with the flow. Please advise.
Thanks and Have a good day!
You can do it in several ways.
The MMC can do log analysis send an email if matches a certain pattern.
You can simply had an exception handling in the flow like a Catch Exception and do the send of a mail there, I wrote a blog post having has sample this case
You can use mule notification system to create a java class that will manage this notification, maybe using log4j SMTP appender to easily send notification mails.
This are my opinion about the 3 methods
First method relies on the mmc being up, mmc creates load on your mule server anyway by making calls and in some production environnement it may be disabled depending on the internal policy of the company. Furthermore if for some reasons goes down you will not receive any notification so you also need to make sure your mmc stays high available. Not an option for me.
I find this method the most appropriate as is it similar to standard exception handling in programming. Manage your exception when you need to and never let them pass silently. When needed send some via mail.
This approach is not bad but not my favorite because lot of times you will see "fake exception" coming in that you need to filter. One example is when a client stops the connection to mule (closing the browser for example) you will get a socket exception that mule cannot write back, this is totally normal and I don't think you want to be spammed by this kind of mail. If you really want to use this system than keep in mind you will need to filter non critical exceptions.
Hope this helps

How to detect alarm-based blocking RabbitMQ producer?

I have a producer sending durable messages to a RabbitMQ exchange. If the RabbitMQ memory or disk exceeds the watermark threshold, RabbitMQ will block my producer. The documentation says that it stops reading from the socket, and also pauses heartbeats.
What I would like is a way to know in my producer code that I have been blocked. Currently, even with a heartbeat enabled, everything just pauses forever. I'd like to receive some sort of exception so that I know I've been blocked and I can warn the user and/or take some other action, but I can't find any way to do this. I am using both the Java and C# clients and would need this functionality in both. Any advice? Thanks.
Sorry to tell you but with RabbitMQ (at least with 2.8.6) this isn't possible :-(
had a similar problem, which centred around trying to establish a channel when the connection was blocked. The result was the same as what you're experiencing.
I did some investigation into the actual core of the RabbitMQ C# .Net Library and discovered the root cause of the problem is that it goes into an infinite blocking state.
You can see more details on the RabbitMQ mailing list here:
http://rabbitmq.1065348.n5.nabble.com/Net-Client-locks-trying-to-create-a-channel-on-a-blocked-connection-td21588.html
One suggestion (which we didn't implement) was to do the work inside of a thread and have some other component manage the timeout and kill the thread if it is exceeded. We just accepted the risk :-(
The Rabbitmq uses a blocking rpc call that listens for a reply indefinitely.
If you look the Java client api, what it does is:
AMQChannel.BlockingRpcContinuation k = new AMQChannel.SimpleBlockingRpcContinuation();
k.getReply(-1);
Now -1 passed in the argument blocks until a reply is received.
The good thing is you could pass in your timeout in order to make it return.
The bad thing is you will have to update the client jars.
If you are OK with doing that, you could pass in a timeout wherever a blocking call like above is made.
The code would look something like:
try {
return k.getReply(200);
} catch (TimeoutException e) {
throw new MyCustomRuntimeorTimeoutException("RabbitTimeout ex",e);
}
And in your code you could handle this exception and perform your logic in this event.
Some related classes that might require this fix would be:
com.rabbitmq.client.impl.AMQChannel
com.rabbitmq.client.impl.ChannelN
com.rabbitmq.client.impl.AMQConnection
FYI: I have tried this and it works.