Camel and LRA Saga: when the compensation action is executed? - spring-boot

I would use the Camel SAGA component available at https://camel.apache.org/components/3.20.x/eips/saga-eip.html
I can easily understand that a "compensation action" is executed when the respective SAGA action fails, but it's not clear what is the meaning of "failure".
I mean, on which basis does Camel mark a SAGA action as "failed"?
Is it considered failed when Camel throws an Exception?
Thank you

Related

non-Controller SpringBoot exception interceptor

I have a spring boot microservice with no controller endpoints. It operates entirely on a workflow using inbound-channel-adapter to query databases and perform some Service action when necessary.
I'd like to intercept all exceptions and judiciously send an alert to the appropriate parties when appropriate.
`#ControllerAdvice doesn't cut it, because there are no controllers.
Any recommendations on how to trap exceptions via an ExceptionHandler or Filter or other means?
Our app uses a org.springframework.integration.handler.LoggingHandler to log exceptions, extending that could be an option. I'd prefer not to have all my services extend a single base class that defines an #ExceptionHandler.
What is the "spring way" to trap exceptions from workflow channels and send notifications (email/slack/otherwise) to the appropriate user?
As Martin points in his comment, an errorChannel approach is used Spring Integration to handle exceptions in the flow. See error-channel option on that inbound-channel-adapter. It is errorChannel by default and it has indeed a LoggingHandler as a subscriber. You can stay with that global errorChannel as is and just have your own service-activator as a subscriber. Or you can configure your own, flow-specific error channel and its subscriber.
See more in documentation:
https://docs.spring.io/spring-integration/docs/current/reference/html/error-handling.html#error-handling

How to do Stateful retry with spring kafka batch listener

I'm reading through the docs here https://docs.spring.io/spring-kafka/docs/2.2.6.RELEASE/reference/html/#retrying-deliveries and I cannot figure out what the correct way is for implementing stateful retry with a batch listener
The docs say that a "retry adapter is not provided for batch message listeners because the framework has no knowledge of where in a batch the failure occurred".
This is not a problem for my use case as I want to just retry the whole batch.
The docs recommend that I use a RetryTemplate within the listener itself. Ok, I can do that.
The problem comes in the next section where it discusses using the stateful retry flag to make the consumer poll between retries in order to prevent the broker from dropping my consumer.
How do I configure a batch listener to do that? Is the stateful retry flag supported for batch listeners? If My retry logic is in within the listener itself, wouldn't that prevent the polling? What exactly does the statefulRetry flag even do?
The latest version of spring kafka has a special RetryingBatchErrorHandler. https://docs.spring.io/spring-kafka/docs/2.4.6.RELEASE/reference/html/#retrying-batch-eh Thanks, Spring Kafka Team!
No; you can't add a RetryTemplate to the container factory for a batch listener.
java.lang.ClassCastException: org.springframework.kafka.listener.adapter.BatchMessagingMessageListenerAdapter cannot be cast to org.springframework.kafka.listener.MessageListener
We will clean that up with a more meaningful error..
With the upcoming 2.3 release (release candidate currently due next Friday) you can add a BackOff to the SeekToCurrentErrorHandler which provides similar functionality to the RetryTemplate; with current releases, the redelivery will be attempted immediately.
Furthermore, another new feature recently merged provides a mechanism to retry from a specific index in a batch.

Configure spring integration poller based on some event

I am using jdbc-inbound-channel-adapter to poll data from database and with a poller having fixed-rate. Now I don't want to constantly look into the database. I want to have the database change notification in place to send the notification on our application and depending on that notification/event we need to invoke the poller for retrieving data.
Can you please help me what could be the configuration for the same? It would be much helpful if we can configure an event based poller for polling the data.
Thanks in advance,
Sandip
Pollers are based on the Spring Framework Trigger; you can't change the poll until the next trigger occurs.
Spring Integration provides a Conditional Pollers which allow you to ignore a poll until some condition is true. Not really event-driven, but closer to what you want.
You could also use the jdbc outbound gateway for event-driven processing.

Asynchronous push of messages in channel (spring-integration)

I have a simple JMS topic listener that i would like to hook with a spring-integration chain.
Basically, when a JMS message is received in the listener it has to be pushed into the chain's channel. Eventually the message is processed and pushed to an outbound-channel-adapter to be consumed.
The Spring Integration documentation mentions the use of asynchronous gateways but that uses Futures.
Isn't there a simple way to just put the message on a channel?
If there is an example that you can point to it would be great.
Thanks
Regards
Martin
If you want to run the flow on the listener thread, simply use a regular gateway (not an async one); this will allow the message to roll-back if the flow fails for any reason.
If you want to "fire and forget" you can make the request channel from the gateway an ExecutorChannel - see here.

camel, JMS, CLIENT_ACKNOWLEDGE mode

I know that Camel's JMS component, for receiving messages, uses Springs DefaultMessageListenerContainer. It can be configured to use CLIENT_ACKNOWLEDGE mode for acknowledging messages. My question is, when exactly the message.acknowledge() method gets called? Is it called internally by the spring's listener container?
Or can I somehow acknowledge message at my will?
I'd like to avoid scenario that messages get lost because my app crashed during processing of these messages and making it transactional seems a bit too heavy for me
OK. After some some debugging and scanning throug source code I've found out that Camel uses spring MessageListenerContainers. The AbstractMessageListenerContainer, in case of CLIENT_AKNOWLEDGE mode, invokes comitIfNecessary method acknowledging message. This happens only AFTER registered MessageListener processes message succesfully (no exceptions)
Camel uses EndpointMessageListener which, eventually, invokes process method of next processor (or Producer) down the route. As this is classic chain of responsibilities, if any processor down the route throws exception or sets exception on the Exchange, it will be re-thrown by EndpointMessageListener preventing the AbstractMessageListener to acknowledge message.

Resources