Spring Cloud Task for Java Development




Technology: Spring Cloud Task is the framework for developing short lived java based micro services using spring boot most popular framework for developing micro services. It allows short lived JVM Process to execute task on demand.
Pre-requisites: Developing Applications using Spring Cloud Task need Java 7 or later version of java (preferably Java 8) and for building applications it need Maven build tool.
Database Requirements: Spring Cloud Task is developed using Spring Data (one of the JPA provider), it will support most of the favorite databases like MySql, Oracle, Postgres, Microsoft SQL Server, by default Spring Cloud Task will use in-memory database for storing the tasks, for status of completion of the task.
Developing Applications using Spring Cloud Task:
Creating Spring Cloud Task Applications:
Creating pom.xml file:
1) We can the sample application using http://start.spring.io where we can select
Cloud Task as the dependency.

2) We can create a sample maven project and do the below changes.
Add parent for created project to make the spring boot project.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
<relativePath/>
</parent>
Add below spring cloud task dependency.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-task-core</artifactId>
<version>1.0.0.RELEASE</version>
</dependency>
Writing Code:
For example in the current blog we are going to write a task for extracting the zip file, by passing zipfile path and extraction directory location.
We can create a simple java file for unzip task:
package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.task.configuration.EnableTask;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableTask
public class UnZipTask {

public static void main(String[] args) {
SpringApplication.run(UnZipTask.class, args);
}
@Bean
public UnZipCommandRunner commandRunner()
{
return new UnZipCommandRunner();
}
}
And unzipCommandRunner class will be
package com.example;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;

public class UnZipCommandRunner implements CommandLineRunner {
private static final int BUFFER_SIZE = 4096;
@Autowired
private UnZipProperties properties;

@Override
public void run(String… args) throws Exception {
File extractDir = new File(properties.getExtractDir());
if (!extractDir.exists()) {
extractDir.mkdirs();
}
ZipInputStream zipStream = new ZipInputStream(new FileInputStream(new File(properties.getZipFilePath())));
ZipEntry zipEntry = zipStream.getNextEntry();
while (zipEntry != null) {
String filePath = extractDir + File.separator + zipEntry.getName();
System.out.println(“extracting file:: “+zipEntry.getName());
if (zipEntry.isDirectory()) {
File file = new File(filePath);
file.mkdir();
} else {
extractFile(zipStream,filePath);
}
zipEntry = zipStream.getNextEntry();
}
}
public void extractFile(ZipInputStream zipInputStream,String filePath) throws Exception
{
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(filePath));
byte[] bytes =new byte[BUFFER_SIZE];
int readBytesCount =0;
while((readBytesCount = zipInputStream.read(bytes))!=-1)
{
outputStream.write(bytes, 0, readBytesCount);
}
outputStream.flush();
outputStream.close();
}
}
For enabling log4j debugging we can add below property in application.properties in src/main/resources folder.
logging.level.org.springframework.cloud.task=DEBUG
We can specify the application name using spring.application.name=unZipTask property.
@EnableTask Annotation: This class level annotation tells spring cloud task to bootstrap functionality. This annotation is importing SimpleTaskConfiguration class, this will register all needed beans like TaskRepository etc…, and if we are not configuring any dataSource then map based task repository will be used.
The above UnZipCommandRunner will extract the files from specified compressed file, Spring Cloud Task provides TaskLifecyceListener to record the starting and ending of the tasks.
The CommandLineRunner Class:
Spring Boot provides *Runner (CommandLineRunner or ApplicationRunner) interfaces to bootstrap the logic, the custom task must be implement either of these two interface to bootstrap automatically on application startup.
Configuring to External Database:
We can configure our custom task using by implementing TaskConfigurer interface. Spring cloud Task provides DefaultTaskConfigurer default implementation, we can extend this class to provide datasource details.

UnZipTaskConfigurer.java:
package com.example;

import javax.sql.DataSource;

import org.springframework.cloud.task.configuration.DefaultTaskConfigurer;

public class UnZipTaskConfigurer extends DefaultTaskConfigurer{

public UnZipTaskConfigurer(DataSource dataSource) {
super(dataSource);
}

}
And we need to mark this as spring bean, by adding below method in UnZipTask.java file
@Autowired
private DataSource dataSource;
@Bean
public UnZipTaskConfigurer getTaskConfigurer()
{
return new UnZipTaskConfigurer(dataSource);
}
Additional classpath dependencies:
We need to below dependencies in pom.xml file.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
And if you are using mysql as your datastore then we need to add the mysql dependency, we can use any datastore supported by JPA.
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
Changes needed in application.properties:
We need to add the below properties in application.properties file:
spring.datasource.url= jdbc:mysql://localhost:3306/springbootdb?useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

But these details may be depending on your datastore and credentials of your server.
The spring data jpa will auto configure the datasource and it will create a bean of this type.
If we run the same task again then we can observe the below lines in console.
DEBUG 10568 — [ main] o.s.c.t.r.s.TaskRepositoryInitializer : Initializing task schema for mysql database
NFO 10568 — [ main] o.s.jdbc.datasource.init.ScriptUtils : Executing SQL script from class path resource [org/springframework/cloud/task/schema-mysql.sql]
INFO 10568 — [ main] o.s.jdbc.datasource.init.ScriptUtils : Executed SQL script from class path resource [org/springframework/cloud/task/schema-mysql.sql] in 1536 ms.
The spring cloud Task contains required schema for each supported database in folder (org.springframework.cloud.task), the schema will be executed according to the configured database.
Passing parameters to Spring Cloud Task:
We can also pass properties to spring cloud task, first we need to implement one java class and create variables for each property and mark it as spring bean using @component annotation.
Create spring-configuration-metadata-whitelist.properties in src/main/resources/META-INF/ folder. Spring cloud task will read this file by default.
We need to specify the properties file classes under configuration-properties.classes key in file.
Example: suppose if need zipFilePath,extractDir properties for running the unzip task, zipFilePath property point to location of the zip file and extractDir is the property point to extraction folder path.
We need to create one java class with these properties.
package com.example;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@ConfigurationProperties(prefix = “sravan”)
@Component
public class UnZipProperties {
private String zipFilePath;

private String extractDir;

public String getZipFilePath() {
return zipFilePath;
}

public void setZipFilePath(String zipFilePath) {
this.zipFilePath = zipFilePath;
}

public String getExtractDir() {
return extractDir;
}

public void setExtractDir(String extractDir) {
this.extractDir = extractDir;
}
}
And we need to add the below property in spring-configuration-metadata-whitelist.properties
configuration-properties.classes = com.example.UnZipProperties
Running Applications with Properties:
We can specify the properties in command line arguments or through IDE:

And we can deploy our spring cloud task into spring data flow server to execute short lived micro services.
Conclusion: Spring Cloud task is the framework for developing short lived micro services, we can monitor the task using TaskLifecyceListener listeners, we can configure with external data sources by extending DefaultTaskConfigurer class. We can externalize the properties using spring-configuration-metadata-whitelist.properties file, we can deploy the custom task in spring data flow server for re-usable task.
You can download source code from GitHub:
https://github.com/sravan4rmhyd/UnzipCloudTask.git
Just in case you have got any query, ask the outsource java development team straightaway. You can make comments below and share your thoughts and views with other readers.

 

 

 

 




Be the first to comment on "Spring Cloud Task for Java Development"

Leave a comment

Your email address will not be published.


*