OSB - JMS - Error Handler - osb

I'm having some troubles trying to catch an error on OSB when I put a message on queue and JMS Server is down, I have a proxy service calling a business service that have a jms configured.
My proxy service already have Transaction Required and Same Transaction For Response enabled.
The error on Admin log:
Destination unreachable; nested exception is:
java.net.ConnectException: Connection refused: connect; No available
router to destination
But the exception don't catch on ErrorHandler :(

I found the error, the problem is that I was using Publish instead of Routing, after I changed everything worked.

Yes that correct , Publish thread is like fire and forget(completely asynchronous) while a Route or ServiceCallout will latch on to the exception in ErrorHandler

Publish is fire-and-forget, by default with no wait for an answer. This comes from the fact, that default QualityOfService=BestEffort for publish action. You can change that, by using RoutingOptions block, and setting QualityOfService=ExactlyOnce. OSB will then wait for action to execute, hence will be also able to catch potential errors.

Related

Camel: Routing from queue to HTTP

Bit of a Camel newbie but here goes.
I have the following route:
from("activemq:queue:outputQueue").inputType(HelloWorld.class)
.to("log:stream")
.marshal().json(JsonLibrary.Jackson, HelloWorld.class)
.to("http:localhost:5000/messageForYouSir?bridgeEndpoint=true");
This retrieves messages from the queue and sends them to the HTTP endpoint as JSON. Fine.
But what if there is an error? Say a HTTP error code of 400? Then I want the message to stay on the queue. I have tried looking into not acknowledging the message, but have not been able to make it work.
Also I have made an Exception handler
onException(HttpOperationFailedException.class)
.handled(false)
.setBody().constant("Vi fekk ein feil");
But still the messages are gone from the queue. Is there some magic spell that can make Camel not acknowledge the messages when there is some error?
You have to consume transacted from the queue to be able to do a rollback. This is configured on the connection configuration to the broker.
Take a look at the Camel JMS docs (the ActiveMQ component extends the JMS component), especially the sections about cache levels and transacted consumption.
The most simple setup is using broker transactions by simply set transacted = true and lazyCreateTransactionManager = false on the JmsConfiguration. This way no Spring TX manager is required.
If transacted consumption is in place and the HTTP server returns an error (basically if an Exception occurs in the Camel Route), Camel does automatically a rollback (if you don't catch the error).

Camel Transacted: MQ Session closed on every commit

I have:
Camel route (transacted=true), consuming from an MQ Queue
Using Spring's WebSphereUowTransactionManager
Transactionality works
Running on IBM Liberty
But, I get this message:
Setup of JMS message listener invoker failed for destination 'MY.QUEUE' - trying to recover.
Cause: Local JMS transaction failed to commit; nested exception is com.ibm.msg.client.jms.DetailedIllegalStateException:
MQJCA1020: The session is closed.
The application attempted to use a JMS session after it had closed the session.
Modify the application so that it closes the JMS session only after it has finished using the session.
This appears to be related to this other Stack Overflow question, but I've tried changing the configuration in server.xml, with no success.
You can try setting cacheLevelName=CACHE_CONSUMER which allows to re-use the JMS consumer and avoids endless of creation/destruction of JMS resources, as indicated by the error message may be the cause.
You can see more about the importanse of cache levels on the Camel JMS documentation: http://camel.apache.org/jms

CAMEL - Channel Closed exception not caught using onException

I am opening this question as I didn't find any answer to problem in the web.
I have used camel to implement a TCP/IP server and I have defined a route like this:
from("netty4:tcp://0.0.0.0:3510")
.to("file:target/outbox");
and I have a client which sends data to this server. When I disconnect this client I can see in my logs this exception:
[Camel (camel-client) thread #0 - NettyEventExecutorGroup] WARN o.a.c.component.netty4.NettyConsumer - Closing channel as an exception was thrown from Netty. Caused by: [java.io.IOException - an existing connection was forcibly closed by the remote host]
My problem is that I am not able to catch this exception using onException clause.
onException(IOException.class)
.log("Exception: ${body}")
.handled(true)
.process(new ExceptionProcessor());
The program does not stop but I want to catch it to handle when the client is disconnected.
Note that I can catch other exceptions which are thrown inside my route.
You cannot handle it as exception, because exception is already catched in netty and logged. This exception is not propagated from netty to netty component.
The solution is a bit tricky. You can extend SimpleChannelInboundHandler and override method channelInactive as described in How can I detect network disconnection in Apache Camel?.
In this custom handler you can set custom properties on exchange with additional information, which is relevant in your application.

Camel : Impact on route execution when connection with external client closes unexpectedly

We are exposing a SOAP/HTTP based camel-cxf web service where on receiving a request from 'Client-A', the route execution starts which involves calling one or more external web services lets say 'Server1', 'Server2' and 'Server3' in a sequentialmanner. In this case, we need to understand what happens to the execution of the route, when the original TCP connection with 'Client-A' is closed unexpectedly.
Will the route get executed successfully and an error is logged when it tries to send the final response?
Or will the route execution be stopped immediately as soon as the TCP connection is closed?
You can capture any errors during the route execution by camel's error handling mechanism and then define the policy on how you want to handle the exception, for example you can setup rules that state how many times to try redelivery, and the delay in between attempts, and so forth.
For more information you can refer to this link:
http://camel.apache.org/redeliverypolicy.html

Apache camel retry logic while polling from remote server

I am trying to pull files from a remote server and if not able to connect to remote server want to implement below scenarios:
Would like to retry 'N' times,
If the connection is not successful after retrying want to stop polling and throw an exception to consumer saying "Server is not responding"
In your route you need a bean that connects to the remote server. If it can't connect, it should through an exception.
Then add an onException handler in your route
onException(CannotConnectException.class)
.maximumRedeliveries(3)
.processRef("doSomething")
The "doSomething" process has to take care of stop polling and inform consumer part of the route. For example, to stop polling you could call a method of the connection bean to stop it polling. The best solution is really going to depend on how you rest of your system fits together.
I would use a polling strategy for this. So the commit and rollback methods will decide on what to do if there is an issue with the route of some sort

Resources