Spring integration: Shutdown application when the handling of files is completed - spring-boot

How to create automatic shutdown in spring integration after finish all process for all files?
My application download undefined number of files and process all files sequentially, the flow is like this:
file:inbound-channel-adapter --> Transformer --> Splitter -->
http-outbound-gateway --> int:aggregator --> mail:outbound-channel-adapter.
At the End, i should shutdown my app.
How to know that all files are processed?
Anyone has an experience about it ?
Thanks

In you case you need to track your inbound directory.
You have to add another step to your flow (probably to track the last file).
I would suggest an ETL technique: Read file descriptions then process them.
When it will be processed you can send event to shutdown the app.
Spring boot application can be stopped by using ConfigurableApplicationContext:
SpringApplication app = new SpringApplication(Application.class);
ConfigurableApplicationContext context = app.run(args);
context.close();
Also there is another way using Spring Actuator shutdown endpoint:
See How to shutdown a Spring Boot Application in a correct way?
Spring Boot documentation

Related

Spring Kafka Listener shutdown Application

I have an application that creates 3 KafkaListener per configuration in the ConcurrentKafkaListenerContainerFactory if any of these Listeners throws a specific Exception. I would like to shutdown the entire spring application.
Since these errors are non recoverable and need manual intervention.
How would i go about doin this?
Do i just inject the ApplicationContext into the Listener and close the application from there?
Or is there a more appropriate way of handling this?
That's one way, or you could just call System.exit(1).

Start Spring Batch job through JMS with Spring Cloud Dataflow

I have an application which listen to an activeMQ queue and start a Batch Job when receiving a message.
I'd like to use Spring Cloud Dataflow to provide an UI but I can't find informations on how to configure it.
Since it uses Spring Boot I should be able to replicate how my application currently works (use a REST API to make it listen to activeMQ and start job when receiving message), but I can't find anything on how to make it start the batch in Cloud Dataflow.
You have a few options here.
Option 1: Launch your application as-is and manually send message to launch task.
Any arbitrary Spring Boot application can be launched from Dataflow (simply register it as type = "App").
Taken from https://github.com/spring-cloud/spring-cloud-dataflow/blob/main/spring-cloud-dataflow-docs/src/main/asciidoc/streams.adoc#register-a-stream-application:
Registering an application by using --type app is the same as registering a source, processor or sink. Applications of the type app can be used only in the Stream Application DSL (which uses double pipes || instead of single pipes | in the DSL) and instructs Data Flow not to configure the Spring Cloud Stream binding properties of the application. The application that is registered using --type app does not have to be a Spring Cloud Stream application. It can be any Spring Boot application. See the Stream Application DSL introduction for more about using this application type.
You would have to send the task launch in your code. You can use the Dataflow REST client to do this. You can get an idea of how to do that by looking at https://github.com/spring-cloud/spring-cloud-dataflow/tree/main/spring-cloud-dataflow-tasklauncher/spring-cloud-dataflow-tasklauncher-sink.
Option 2: Use pre-built stream applications to model the same flow as your application.
The app you describe can be logically modeled as a Spring Cloud Stream application.
There is a JMS source (provides messages to signal the need to kickoff task/batch job)
There is a TaskLauncher sink (receives messages and kicks off the task/batch job)
This app can actually be constructed w/ little effort by using the pre-packaged applications to model this flow.
JMS Source
Dataflow Tasklauncher Sink
If you have to register these applications in the UI - they can be found at:
maven://org.springframework.cloud.stream.app:jms-source-kafka:3.1.1
maven://org.springframework.cloud:spring-cloud-dataflow-tasklauncher-sink-kafka:2.9.2
Stream definition:
jms-source | dataflow-tasklauncher-sink
The README(s) on the above source/sinks give details about the configuration options.
Option 3: Custom Spring Cloud Stream app w/ function composition
The previous option would create 2 separate apps. However, if you want to keep the logic in a single app then you can look into creating a custom Spring Cloud Stream app that uses function composition and leverage the pre-built reusable Java functions that the apps in option 2 are built upon.
JMS Supplier
TaskLauncherFunction

Spring-Batch interferes with Apache Camel

I am using Spring-Batch V3.0.6 with Spring V4.2.4 and Apache Camel 2.16.2 and in my configuration each time a Spring batch job (JSR API) is stopping, it stops my Camel context! It could be because of my config that I will try to explain.
First of all I am using only the JSR API and not native Spring Batch API. To be able to call/use Spring bean inside the job definition (JSR XML) I configured Spring-Batch context loading a shared context (loaded by the ContextLoaderListener). In that shared context I defined the CamelContext via the Spring-Camel tags (to be able also to use Spring beans inside the camel routes easily).
When none jobs ran, we do not have any issue, the Camel routes are up and work perfectly. The problem starts as soon a job is started and stops. Indeed, it seems that when a job is starting is trying to start and when the jobs ends it stops the Camel context by send a 'ContextClosedEvent' that is processed by the CamelContext. From this moment Camel is up only when a job is running.
What can I modify in my configuration and/or code to make it work and let my Camel context up? I maybe configured the shared context wrongly.

How to gracefully shutdown the spring boot application

I need to gracefully start and shutdown the spring boot application using a script . Is there any other way to do it except using an actuator module in the application. Currently i have to stop the spring boot process manually in the task manager.
Ultimately the spring boot application spins off a java process which needs to be killed. At present you are killing it manually.
You have a few options:
You can use SpringApplication.exit(ApplicationContext, ExitCodeGenerator...) method.
If your application is not a long running application then do you have some exit point where your application should stop. At that point you can System.exit(0)
You can use external manager tools, for example on unix you can use supervisor, here is a blog you can read about this.
SpringApplication.run gives you ApplicationContext which you can close.

Spring Boot 1.2.3.RELEASE ApplicationReadyEvent not found

I am reading Spring Boot reference (version 1.2.3-RELEASE) and in point
22.4 Application events and listeners point 4 states:
"An ApplicationReadyEvent is sent after the refresh and any related callbacks
have been processed to indicate the application is ready to service requests."
So I tried:
SpringApplication app = new SpringApplication(LearnSpringBootApplication.class);
app.addListeners(new ApplicationListener<ApplicationReadyEvent>() {
...
but it cannot find the ApplicationReadyEvent. Has it been removed ?
If so - is there any equivalent for it ?
I found this post here:
Spring Boot - Wait for web server to start
but was wondering if there is another way?

Resources