Spring JavaMailSender: Making it asynchronous and persistent - spring

Is there an easy/lightweight way to add persistence to Spring's JavaMailSender and have it operate asynchronously? Does Spring provide any "built-in" support for this? I'm currently looking at queues with JMS, but they seem like overkill for the task at hand (looking at ActiveMQ and RabbitMQ). Is there a lightweight JMS option?

Your approach with jms is fine. Unfortunately persistence and asynchronous processing is not such a simple task and you will have to code a bit.
However have a look at Spring integration, it provides built-in support for JMS inbounds and e-mail outbounds - all you have to do is connect the pieces via XML DSL.

If you want to make any method in Spring asynchronous, all you need to do is configure task namespace in the xml config via <task:annotation-driven/>. Then, you just annotate the method with #Async and it will run in its own thread. Note that an async call will run in its own transaction, as Spring grabs a new thread from its internal pool to service the call. If you do this, then you don't need JMS for aynchronous processing.

Related

Thread model for Async API implementation using Spring

I am working on the micro-service developed using Spring Boot . I have implemented following layers:
Controller layer: Invoked when user sends API request
Service layer: Processes the request. Either sends request to third-part service or sends request to database
Repository layer: Used to interact with the
database
.
Methods in all of above layers returns the CompletableFuture. I have following questions related to this setup:
Is it good practice to return Completable future from all methods across all layers?
Is it always recommended to use #Async annotation when using CompletableFuture? what happens when I use default fork-join pool to process the requests?
How can I configure the threads for above methods? Will it be a good idea to configure the thread pool per layer? what are other configurations I can consider here?
Which metrics I should focus while optimizing performance for this micro-service?
If the work your application is doing can be done on the request thread without too much latency, I would recommend it. You can always move to an async model if you find that your web server is running out of worker threads.
The #Async annotation is basically helping with scheduling. If you can, use it - it can keep the code free of the references to the thread pool on which the work will be scheduled. As for what thread actually does your async work, that's really up to you. If you can, use your own pool. That will make sure you can add instrumentation and expose configuration options that you may need once your service is running.
Technically you will have two pools in play. One that Spring will use to consume the result of your future, and another that you will use to do the async work. If I recall correctly, Spring Boot will configure its pool if you don't already have one, and will log a warning if you didn't explicitly configure one. As for your worker threads, start simple. Consider using Spring's ThreadPoolTaskExecutor.
Regarding which metrics to monitor, start first by choosing how you will monitor. Using something like Spring Sleuth coupled with Spring Actuator will give you a lot of information out of the box. There are a lot of services that can collect all the metrics actuator generates into time-based databases that you can then use to analyze performance and get some ideas on what to tweak.
One final recommendation is that Spring's Web Flux is designed from the start to be async. It has a learning curve for sure since reactive code is very different from the usual MVC stuff. However, that framework is also thinking about all the questions you are asking so it might be better suited for your application, specially if you want to make everything async by default.

Communication between two java classes using Spring

I have two java classes that implements Runnable within the same application, let's say A and B classes.
These two classes share a BlockingQueue to pass some data. Class A sends data to class B through BlockingQueue. Then class B takes the data and process it. What I am trying to do is that when some conditions happen in class B as a result of process this data, it sends a messages to class A, and class A prints these messages.
So I was having a look at Spring messaging using Apache ActiveMQ, but it seems a broker must be started in order communication works using "activemq start" command. Is there any possibility to do this without having this broker started?
What is the best option to do this? I would like to do this using Spring framework so can be done using some kind of approach in Spring? Or the only possiblity using spring is through apache activemq?
Take a looks at Spring Integration; components communicate using Messages.
You can use an entirely in-memory configuration or provide persistence via some broker such as ActiveMQ.
The components themselves are not concerned with that; they simply send/receive messages.
Create the Queue in spring and inject it into both Runnables

spring-integration (SI), deploy as EAR

I just recently started learning about spring-integration since I need to replace the a MDB(J2EE) application.
The application is composed of mostly MDB which does, splitting, aggregating and scheduling. Which, I think is the perfect criteria to use spring-integration.
I tried out some JMS examples and tried to deploy it but could not figure out how to use the jms-inbound-gateway to replace the MDB.
Is there a way to do this? Or is the only option is still to use MDB and calling the spring-integration service from the MDB's onMessage?
Use a message-driven-channel-adapter instead of an inbound gateway.
With Spring Integration, gateways are for two-way (request/reply) integraton; channel adapters are for one way integration; more like MDBs.
If you need to send some other JMS message downstream, use an outbound channel adapter later in the flow.
It's unusual to keep the MDBs, but you can do it if you really want to, and send a message to an integration flow.

Add spring-integration inbound-channel-adapter after the application has started

I have a spring-integration channel hooked up to a service-activator using the XML configuration. I've attached an sftp inbound-channel-adapter to the same channel. This is working quite well.
I would like to allow my clients to add/remove SFTP inbound-channel-adapters to the channel through my web interface, but instantiating spring-integration components appears to be fairly tightly coupled to the XML Spring context (see org.springframework.integration.sftp.config.SftpInboundChannelAdapterParser).
Is there a way to add/remove SFTP inbound-channel-adapters after the application has started?
This is not trivial task.
All Spring Integration components are Spring beans, at least.
So, if you want to do something with Spring at runtime you should Application Context, who provides Dependency Injection features.
I suggest to take a look into this sample: https://github.com/spring-projects/spring-integration-samples/tree/master/advanced/dynamic-ftp
It demonstrates some dynamic registration technique.

Distributing business logic across different servers(like JBoss/Glassfish) using Spring and still under one transaction

I am willing to create an example(code) using Spring in which business logic to be distibuted across different servers like JBoss or Glassfish and still under one transaction? First of all is this possible in Spring. I know using EJB has this option. Likewise do we have a similar technique in Spring also? I am looking for Synchronous communication approach and not using asynchronous message oriented middleware. Any help/pointer appreciated.
Thanks
Prakash
Spring has support for RMI or provides its own remoting mechamism HttpInvoker but according to the doc they don't provide any remote transaction propagation.
Similar questions:
Spring Distributed Transaction Involving RMI calls possible?
Transaction propagation in multiple servlet context with multiple data source

Resources