DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Avoiding If-Else: Advanced Approaches and Alternatives
  • Dust: Open-Source Actors for Java
  • Redefining Java Object Equality
  • Workarounds for Oracle Restrictions on the Size of Expression Lists

Trending

  • Scalability 101: How to Build, Measure, and Improve It
  • Zero Trust Isn't Just for Networks: Applying Zero-Trust Principles to CI/CD Pipelines
  • Selenium Pagination Tutorial: How to Handle Page Navigation
  • How Clojure Shapes Teams and Products
  1. DZone
  2. Data Engineering
  3. Data
  4. Recurrent Workflows With Cloud Native Dapr Jobs

Recurrent Workflows With Cloud Native Dapr Jobs

Workflow scheduling is something we see often. As part of this article, we will look at how Dapr Jobs helps to easily run periodic workloads.

By 
Siri Varma Vegiraju user avatar
Siri Varma Vegiraju
DZone Core CORE ·
May. 05, 25 · Tutorial
Likes (0)
Comment
Save
Tweet
Share
2.0K Views

Join the DZone community and get the full member experience.

Join For Free

We have been learning quite a lot about Dapr now. 

These are some of my previous articles about Dapr Workflows and Dapr Conversation AI components. Today, we will discuss Jobs, another important building block of the Dapr ecosystem.

Many times, you will need to run workflows on a schedule. For example, 

  • Regular file backups: Periodic backups help restore data when there is a failure. So, you could schedule one to back up your data on a regular basis.
  • Performing maintenance tasks: Things like file cleanups, recycling VM nodes, and batch processing data are some other scenarios where Dapr Jobs can help.

Jobs Architecture

Jobs architecture 

  • MyApp is the Java application we will be creating today, responsible for scheduling and registering the job.
  • When creating the cron job, the application needs to register a callback endpoint so that the Dapr runtime can invoke it at the scheduled time.
    • The endpoint should be a POST request with a URL pattern similar to /jobs/{jobName}, where jobName corresponds to the name used when registering the job.

Now, let's look at a practical demonstration. In the sample app, we will create a simple job that runs every 10 seconds. The callback URL registered will print the name of the job that is being invoked.
Because we have used .NET SDK in all the previous articles, this time we will go with the java-sdk.

Step 1

Download the Dapr CLI and install it. There is also an MSI that you could use to install the latest version here: https://github.com/dapr/cli/releases.

PowerShell
 
powershell -Command "iwr -useb https://raw.githubusercontent.com/dapr/cli/master/install/install.ps1 | iex"


Step 2

Verify the installation using the following command.

PowerShell
 
dapr -h


Make sure you have Docker running too because the cli downloads docker images of runtime, scheduler and placement services.

Next, it is time to set up the app. For this, we will create a maven project and use the dapr maven dependencies. Gradle could be another choice.

Step 3

Create a Maven project. Add the following Dapr dependency to it.

Java
 
<dependency>
  <groupId>io.dapr</groupId>
  <artifactId>dapr-sdk</artifactId>
  <version>${project.version}</version>
</dependency>


We also discussed registering an endpoint that the scheduler could call. In this case, we are using the Spring framework to register an endpoint. You could also use JAX-RS or any other framework of your choice.

Java
 
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <version>${springboot.version}</version>
</dependency>


Step 4

App logic to register the job.

Java
 
import io.dapr.client.DaprClientBuilder;
import io.dapr.client.DaprPreviewClient;
import io.dapr.client.domain.GetJobRequest;
import io.dapr.client.domain.GetJobResponse;
import io.dapr.client.domain.JobSchedule;
import io.dapr.client.domain.ScheduleJobRequest;
import io.dapr.config.Properties;
import io.dapr.config.Property;

import java.util.Map;

public class DemoJobsClient {

  /**
   * The main method of this app to register and fetch jobs.
   */
  public static void main(String[] args) throws Exception {
    Map<Property<?>, String> overrides = Map.of(
        Properties.HTTP_PORT, "3500",
        Properties.GRPC_PORT, "51439"
    );

    try (DaprPreviewClient client = new DaprClientBuilder().withPropertyOverrides(overrides).buildPreviewClient()) {

      // Schedule a job.
      System.out.println("**** Scheduling a Job with name dapr-jobs *****");
      ScheduleJobRequest scheduleJobRequest = new ScheduleJobRequest("dapr-job",
          JobSchedule.fromString("*/10 * * * * *")).setData("Hello World!".getBytes());
      client.scheduleJob(scheduleJobRequest).block();

      System.out.println("**** Scheduling job with name dapr-jobs completed *****");

      // Get a job.
      System.out.println("**** Retrieving a Job with name dapr-jobs *****");
      GetJobResponse getJobResponse = client.getJob(new GetJobRequest("dapr-job")).block();
      
      // Delete a job.
      DeleteJobResponse deleteJobResponse = client.deleteJob(new DeleteJobRequest("dapr-job")).block();
    }
  }
}


  • We have created a simple Java class with a main method. Because Jobs is still a preview feature, DaprPreviewClient is used to schedule, get, or delete a Job.
  • The ScheduleJobRequest constructor takes in two parameters, the name of the job and the cron expression, which in this case is to run every 10 seconds. 
  • Finally, we call the scheduleJob() method that will schedule a job with the Dapper runtime.
  • The getJob() method is used to retrieve the job details of an existing job.


Step 5

Register a callback endpoint.

Java
 
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

/**
 * SpringBoot Controller to handle jobs callback.
 */
@RestController
public class JobsController {

  /**
   * Handles jobs callback from Dapr.
   *
   * @param jobName name of the job.
   * @param payload data from the job if payload exists.
   * @return Empty Mono.
   */
  @PostMapping("/job/{jobName}")
  public Mono<Void> handleJob(@PathVariable("jobName") String jobName,
                              @RequestBody(required = false) byte[] payload) {
    System.out.println("Job Name: " + jobName);
    System.out.println("Job Payload: " + new String(payload));

    return Mono.empty();
  }
}


Once it is time to run the scheduled job, the Dapr runtime will call the following endpoint. You could define a PostMapping with the specific Job name like "/job/dapr-job" or use a path param like we did above.

Step 6

Write the startup file for the Spring Boot app.

Java
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Spring Boot application to demonstrate Dapr Jobs callback API.
 * <p>
 * This application demonstrates how to use Dapr Jobs API with Spring Boot.
 * </p>
 */
@SpringBootApplication
public class DemoJobsSpringApplication {

  public static void main(String[] args) throws Exception {
    SpringApplication.run(DemoJobsSpringApplication.class, args);
  }
}


Step 7

Now, it is time to run the application. Go to the Maven project folder and run the following command. Change the name of the jar and class if required.

PowerShell
 
dapr run --app-id myapp --app-port 8080 --dapr-http-port 3500 --dapr-grpc-port 51439  --log-level debug -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.jobs.DemoJobsSpringApplication


Output from the command.

Output


Step 8

Finally, run the DemoJobsClient.

PowerShell
 
java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.jobs.DemoJobsClient


Output from the command.

Plain Text
 
**** Scheduling a Job with name dapr-jobs *****


Switching back to the other window where we ran the command from Step 8, you will notice the following console log.

Plain Text
 
== APP == Job Name: dapr-job
== APP == Job Payload: Hello World!


Conclusion

Dapr Jobs is a powerful tool that can help you schedule workloads without having to take the complexity of using CRON libraries. Go try it out.

Java (programming language) workflow Data Types

Opinions expressed by DZone contributors are their own.

Related

  • Avoiding If-Else: Advanced Approaches and Alternatives
  • Dust: Open-Source Actors for Java
  • Redefining Java Object Equality
  • Workarounds for Oracle Restrictions on the Size of Expression Lists

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • [email protected]

Let's be friends: