Exception handling in xml based spring integration - spring-integration

How to publish exception in error-channel whenever we encounter any exception in any of the route. We dont want to catch exception manually. It should automatically routed to error-channel?

No, it can't go automatically to the error-channel. That's not how plain Java works. So, if you call some java code you expect an exception from there and you definitely use a try...catch construction.
The error-channel makes sense only in the processes not started by end-users, some active processes like task executors and schedulers. For this purpose we indeed provide an error-channel hook do not let downstream error to disappear.
Another way to do a-la try...catch, but still send to the error-channel can be done via Messaging Gateway: https://docs.spring.io/spring-integration/docs/current/reference/html/messaging-endpoints-chapter.html#gateway-error-handling. This way the Framework wraps the whole flow to the try...catch and sends an ErrorMessage to the configured errorChannel.
Also for per-service purpose we provide an ExpressionEvaluatingRequestHandlerAdvice with its own in-scope failureChannel: https://docs.spring.io/spring-integration/docs/current/reference/html/messaging-endpoints-chapter.html#expression-advice

Related

Message persistence in Spring Integration Aggregator without MessageStore by using AMQP?

I would like to know if I can have persistence in my Spring Integration setup when I use a aggregator, which is not backed by a MessageStore, by leveraging the persistence of AMQP (RabbitMQ) queues before and after the aggregator.
I imagine that this would use ack's: The aggregator won't ack a message before it's collected all the parts and sent out the resulting message.
Additionally I would like to know if this is ever a good idea :)
I am new working with queue's, and am trying to get a good feel for patterns to use.
My business logic for this is as follows:
I receive a messages on one queue.
Each message must result in two unrelated webservice calls (preferably in parallel).
The results of these two calls must be combined with details from the original message.
The combination must then be sent out as a new message on a queue.
Messages are important, so they must not be lost.
I was/am hoping to use only one 'persistent' system, namely RabbitMQ, and not having to add a database as well.
I've tried to keep the question specific, but any other suggestions on how to approach this are greatly appreciated :)
What you would like to do recalls me Scatter-Gather EI Pattern.
So, you get a message from the AMQP send it into the ScatterGather endpoint and wait for the aggregated reply. That's enough for to stick with the default acknowledge.
Right, the scatterChannel can be PublishSubscribeChannel with an executor to call Web Services in parallel. Anyway the gatherer process will wait for replies according the release strategy and will block the original AMQP listener do not ack the message prematurely.

What is the retry logic to int-http:outbound-gateway?

I have a int-http:outbound-gateway in my spring integration config file that consumes a rest service.
I am trying to start the error handling part of the implementation, but I would like first to understand how the retry works. I can notice that when an error occurs, let's say a bad request, spring integration framework seems to retry to send the request to the rest service and, in fact, depending on the error - http code - I would like to handle it in a different way.
How can I avoid the retry depending on the http response code?
There is no inherent retry; retry is implemented using a retry advice.
It can be customized for different exception types, but not for status codes; you would need a custom advice for that - the documentation explains how to write one.

How to call security setup when message received using Spring Integration

I currently am using Spring Integration to get messages off of a queue and send them to a service using a service activator. My issue is that the service I am calling requires a security context to be in place for the current thread. This can be setup by calling a no-argument method, handleAuthentication(), of another bean. I am wondering what the best way is to call this whenever a new message is received, prior to calling the service activator service? I was originally thinking I would chain together two service activators, with the first one calling handleAuthentication(), but this seems incorrect as handleAuthentication() does not require any information from the actual message.
Yes, your assumption about the security handling is correct. It is really just a side-effect aspect which should not be tied with the business logic.
Therefore we should use something which allows us to follow with the same behavior in the program. It is called as an Aspect in the programming as well.
For this purpose Spring Integration suggests a hook like MessageChannelInterceptor, where you can implement your handleAuthentication() exactly in the preReceive() callback, according to your explanation.
Another trick can be achieved with the <request-handler-advice-chain> and MethodInterceptor implementation which should populate the SecurityContext into the current thread just before target service invocation.

Create programatically message-driven-channel-adapter to process the messages on queue

I would like process the message programmatically using message-driven-channel-adapter. Here is scenario which I have to implement:
My application during the startup read the configuration from a service. The configuration provides information about the queues which will contain the messages. Hence I would like to create a message-driven-channel-adapter for each queue to listen to messages asynchronously.
Any example which initializes all the spring integration context programatically instead of using XML will be useful.
If you are going to do everything programmatically, I'd suggest you bypass Spring Integration magic and just use DefaultMessageListenerContainer directly.
Afterwards you can send messages to an existing MessageChannel directly from the MessageListener implementation or using Messaging Gateway.
Please, be careful with programmatic configuration with that do not miss important attributes like ApplicationContext or invocation for afterPropertiesSet().

Simple Service Bus not happy replying after the handler has completed

I am using the Simple Service Bus from Codeplex and have a handler that provides me with a message and an IMessageContext.
public void Handle(MyEnquiryMessage message, IMessageContext context)
I store both these in a list and let the handler complete. At some point in the future I do some processing and try to send a reply by taking the context that I stored and calling:
context.Endpoint.MessageBus.Reply(myResponse)
Unfortunately this throws an exception “Object reference not set to an instance of an object”. Is this asynchronous way of replying possible or can “reply” only be used within the handler?
I don't know Simple Service Bus but I would guess that your context is only valid in the handler. If you want to send back a response you need to gather all the data you need from the context and simply do a 'send' at that later stage.
Even so, it sounds a bit strange performing process 'later' when it could probably be handled in another endpoint that processes a relevant message type. Without more information it is difficulty to tell, but your design may not be optimal.

Resources