Can Reactive Spring Integration work with DLQ? - spring

After reading the following issue Reactive DSL Error Handling with Flux Channels I’m still not sure - is there any other way I can stay reactive and yet trigger a DLQ in Spring Integration?
If so, how? Does this require the usage of Direct Channels? Or Flux Channels?
By mentioning the DLQ pattern I'm referring to error channels, provided by default in Spring Integration. I would like to understand these two concepts:
How does error handling should work in Reactive Spring Integration? I haven't seen any reference for the Reactor part of the docs, and I haven't seen any reference for Reactor in the error handling part of the docs. What's the official solution for this?
Is there an option of using the same functionality of the error handling of regular Spring Integration - e.g. error channels, for Reactive Spring Integration? From the Stackoverflow issue I've mentioned, there isn't such an option. Am I right?

I'm not sure why is the question and if you really tried that one. Technically it really works same way as it is with regular async endpoint. The FluxMessageChannel is subscribed in the ReactiveStreamsConsumer which has a ErrorHandler option with default exactly for publishing to the errorChannel - or headers or global default one.
The algorithm over there is like:
protected void hookOnNext(Message<?> value) {
try {
this.delegate.onNext(value);
}
catch (Exception ex) {
this.errorHandler.handleError(ex);
}
}
If handler is not a ReactiveMessageHandler.
We probably need to improve docs for this info: feel free to raise a GH issue.
However it looks like you need to share more info about your use-case. Not sure why you point to that SQS question...

Related

How correctly add RetryAdvice to Jms.messageDriverChannelAdapter

I'm very new to Spring Integration DSL and I need to add retrial with recovery to the existing IntegrationFlow. It takes data from Jms.messageDriverChannelAdapter and send it through different channels. I want to add RequestHandlerRetryAdvice for the whole flow.
My idea was to add it to the adapter, but it seems to support only ErrorChannel, without Advices & Retries and such. I've ended up wrapping the whole flow after Jms.messageDriverChannelAdapter in a .gateway with advice and .requireReply(false). It feels like a hack, but I couldn't find a better way to do it. Is there any better way to deal with such situation?
Unlike Spring AMQP's listener container a JMS one doesn't provide a hook to inject Advice chain into it, so, we really don't have choice and workaround it somehow. The RequestHandlerRetryAdvice and a .gateway() DSL is not so bad idea to go. The point is that a RequestHandlerRetryAdvice is applied only for the particular handleRequestMessage() method and is not propagated downstream. Having the flow wrapped into the gateway call from the mentioned handleRequestMessage() is the way to go.
I think we can come up with the solution on the JmsMessageDrivenEndpoint to wrap an internal listener with injected Advice chain, where one of them might be a RetryOperationsInterceptor.
Please, raise a GH issue and we'll think what we can do.

How can I do sendAndReceive with Spring EventListener?

With the (meanwhile deprecated) reactor-bus from project-reactor I had the API eventBus.sendAndReceive(Event e, Consumer<?> callback).
This allowed to trigger execution by publishing an event and automatically subscribe to a response.
With Spring eventListeners I can publish another event from an EventListener method, but I am missing the feature to directly subscribe to a return value.
How do I achieve the same behaviour with spring? How do I programmaticcaly register/unregister listeners and how do I make the topics dynamic?
With Spring's ApplicationEventMulticaster you can't subscribe to a response. You probably noticed that the onApplicationEvent method returns void! The reason for this is because literally all it does is either call the Subscriber (i.e. ApplicationListener) synchronously, or runs the listener method asynchronously on an executor without returning any type of Future.
Spring's Project Reactor evolved a while ago to match the Reactive Manifesto and similar frameworks (like RxJava) more closely. Now with Spring 5 (with which Reactor comes with by default) you can use Reactor and RxJava interchangeably.
That being the case, regarding your questions:
How do I achieve the same behaviour with spring?
You use the new version of Reactor Core and the functional programming features of Flux, Mono, etc.
With Spring eventListeners I can publish another event from an
EventListener method, but I am missing the feature to directly
subscribe to a return value.
If you look at the API for Flux, you'll see that it has a fluent and functional API (in some ways similar to Java 8 streams).
Flux.just(1, 2, 3, 4)
.map(value -> value + 1)
.subscribe(subscriber::function);
This way, you can operate on your "events" (i.e. 1,2,3,4 in this example), perform an operation on what would be a "return value" for those events, and then pipe those to some subscriber operation to consume those events.
How do I programmaticcaly register/unregister listeners and how do I
make the topics dynamic?
You should take a look at this SO answer.
To register/unregister, that's something you can do with what you might call "completors" in the Reactor framework. See the take functions in the Reactor API. They will signal upstream that they basically want to be unsubscribed, and that the upstream producer should stop emitting.

Which should I use mail outbound-channel-adapter or org.springframework.mail.MailSender [duplicate]

I have too many emails. I should write scheduler in order to send messages to them. Messages are different. I use spring framework 4.x.
I can write simple class, which connects to SMTP server. But in this case I should write my thread library too in order to send emails parallel.
Do spring have already written library which give me more flexible way to do this tasks? I do not want to use threads. It will be nice if spring already have this functionality.
Do I need Spring integration for this?
Best regards,
Yes, you definitely can do that with Spring Integration, because there is an ExecutorChannel implementation with can be supplied with an TaskExecutor from the Spring Core:
<channel id="sendEmailChannel">
<dispatcher task-executor="threadPoolTaskExecutor"/>
</channel>
<int-mail:outbound-channel-adapter channel="sendEmailChannel" mail-sender="mailSender"/>
But anyway you should keep in mind that all Spring Integration components are based on the Java and that ExecutorService is used on the background.
From other side if you need only the mail sending stuff from the Spring Integration, it would be an overhead and can simply use Core Spring Framework legacy like JavaMailSender as a bean and #Async for the sendMail method to achieve your parallel requirement.
UPDATE
could you tell me whether I need JMS for this situation?
I don't see any JMS-related stuff here. You don't have (or at least don't show) any real integration points in your solution. The same I can say even about Spring Integration just for email sending. However with the Spring Boot your SI config will be enough short. From other side if you'll study Spring Integration better eventually you'll get more gain to rely on the Integration components for your systems, as internally, as well as externally with other systems through JMS, AMQP, Kafka etc.
To be honest: a lot of years ago my first acquaintance with Spring Integration was due the requirement to get files from the FTP and have ability to pick up new files automatically. I found the solution only in the Spring Integration 1.0.0.M1. After that short XML config for the <int-ftp:inbound-channel-adapter> I loved Spring Integration and since that time it became as a part of my life. :-)
So, it's up to you to go ahead with Spring Integration in your simple app, or just follow with more formal solution with JavaMailSender direct usage.
You should use java executors framework. For example you can write something like the code below:
ExecutorService executor = Executors.newWorkStealingPool();
executor.execute(() -> mailSender.send(mail));

Camelize a spring boot application

We have a spring boot application that is growing in complexity because of integration needs - like send an email after you do this, or broadcast a jms message after you that etc. In looking for some higher level abstractions, I came across apache camel (haven't used camel ever before). The question that I have is what do I do with the spring boot application? The application has the standard spring controllers, services and uses spring-data for connecting to databases. I didn't find much help online on how to merge camel into a spring-boot restful application. Is that even something that is doable or is camel a completely different beast that the spring boot won't fit?
I did read that Camel tightly integrates with Spring, but still I didn't know if 1) Spring Controllers are still something that can be used along with Camel 2) If I can call the other spring beans from camel routes and whether I can call invoke a camel route from a spring bean (sorry if these sound like camel newbie questions to the experts)
As an example of what we have to do:
After finishing writing anything to the database about an order, we have to send an email out to the order processing department
If someone deletes a particular user address, we have to send to a jms topic so other applications can take action.
Every http request is coming in through the Spring MVC stack today.
Is there a way to "hand-off" the processing to camel after a particular task is complete? (like writing the order to the database successfully via the Spring MVC stack and hand off to camel to send a jms message and do other things)? Or should we completely replace Spring with Camel?
Not sure what the right path is. Can someone please guide us?
This question is slightly old, but though it was worth mentioning here that Apache Camel now includes a Spring Boot component.
Details can be found here
http://camel.apache.org/spring-boot.html
and they document an example here
http://camel.apache.org/spring-boot-example.html
Follow this for the current best practice in camelising a spring boot application!
One option is to
1> define camel routes either in Spring DSL or Java DSL or other means and define it in Spring Application context.
2> And have a class that implements ApplicationContextAware and cache the Spring ApplicationContext in a Static Variable.
3> For #Controller we can get this static variable and get hold of ApplicationContext .
4> With the camel context ID we can do a getBean from ApplicationContext.
5> This is the instance of DefaultCamelContext,with this we can do a createProducer and call camel routes from #Controller.
Like some others mentioned, spring-boot-camel (but use spring-boot-camel-starter as your dependency) works very well and it is really easy to set up. When you annotate your RouteBuilder extensions and your Processor implementations with #Component, they wire up directly into the context and you are good to go. Then, you can #Autowire a CamelContext or a ProducerTemplate into your classes and use them as necessary.
You asked about how Controllers can work with Camel, and if you #Autowire any of the things you need (probably a context or a producer template), then the answer is a definite "yes" that you can use them together quite easily. And when you use spring-web, your context will start and remain running without any additional configuration, etc.
Like Matthew Wells suggested, the links will get you pointed in the right direction. If you, or others on your team, are at all familiar with Camel, then it will be very easy for you to do what you need to do. But, ah, I notice that this question is from 2014, and you're probably well past the point of your question. At least if anyone else stops by this thread, they will have plenty of information to get going. If you come by and re-visit your question, please let us know how it went for you, and what you ended up doing. Cheers!

Spring Context Event

I am currently studying Spring.
While reading a Spring book, I met a part regarding Event.
By using context.publishEvent(..), I could trigger the event.
But I don't know what It's exactly for.
I can use other Method instead of using complicated publishEvent.
Please, tell me. thank you.
Spring Events are used to implement publish-subscribe model (or observer pattern) where two not-related parts of code must be somehow connected.
Think of the analogy of web applications where servlet container creates http sessions and your code is informed about this using javax.servlet.http.HttpSessionListener.
Spring uses this mechanism internally. It's much more visible in Spring Security where several parts of the code are informed about e.g., successfull authentication.

Resources