Skip to content

The driver making it convenient to use Temporal with Spring Boot.

License

Unknown and 2 other licenses found

Licenses found

Unknown
LICENSE.txt
Unknown
license-header-temporal.txt
Unknown
license-header.txt
Notifications You must be signed in to change notification settings

applicaai/spring-boot-starter-temporal

Repository files navigation

Spring Boot starter for Temporal.io

About

This is the driver making it convenient to use Temporal with Spring Boot. It is intended especially on making code that uses Services to start workflows, send signals to them or use queries. To make Activities be Services as well and use all the benefits of Spring to communicate with outside world.

Configuration

Gradle

implementation 'com.github.applicaai:spring-boot-starter-temporal:0.12.0-SNAPSHOT'

Maven

<dependency>
    <groupId>com.github.applicaai</groupId>
    <artifactId>spring-boot-starter-temporal</artifactId>
    <version>0.12.0-SNAPSHOT</version>
</dependency>
<repository>
    <id>oss-repo</id>
    <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
    <snapshots>
        <enabled>true</enabled>
        <updatePolicy>daily</updatePolicy>
    </snapshots>
</repository>

Usage

Instead of reading this README you can see examples in test directory samples folder.

First steps

First things first

For anything to work you will have to have application annotated with proper annotation:

@EnableTemporal
@SpringBootApplication
public class Application {
  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}

You will also need the source of application properties with something like this:

spring.temporal:
  # host: localhost
  # port: 7233
  # useSsl: false
  # createWorkers: true
  # namespace: default
  workflowDefaults:
    executiontimeout: 1000
    executiontimeoutUnit: SECONDS
    activityPoolSize: 100
    workflowPoolSize: 50
  workflows:
    one:
      taskQueue: one
    two:
      taskQueue: one
    cron:
      taskQueue: cron
      cronSchedule: '* * * * *'

For the docker running locally you do not need any configuration of the host. For the workflows it is convenient to define workflowDefaults as not to repeat same configuration on every workflow.

Defining workflow

Then for the workflow implementation there are some little changes from original Temporal:

@Component
@TemporalWorkflow("myflow")
public class WorkflowImpl implements HelloWorkflow {
  ...
}

As you can see you need to add @Componet and @TemporalWorkflow annotations for the implementation class. This will create worker for you so you do not need to start it anywhere. The parameter for @TemporalWorkflow is the name in configuration that specify options both for worker and its stubs:

 spring.temporal:
   workflows:
    myflow:
      executiontimeout: 1000
      executiontimeoutUnit: SECONDS
      activityPoolSize: 100
      workflowPoolSize: 50

Then for every activity in workflow implementation class instead of Activity stub instantiation you annotate it with @ActivityStub.

Or you can use:

  activityStubDefaults:
    scheduleToCloseTimeout: PT10S
  activityStubs:
    #values for GreetingActivities used in any workflow (default)
    GreetingActivities:
      scheduleToCloseTimeout: PT20S
    PropertiesActivity:
      scheduleToStartTimeout: PT1S
      startToCloseTimeout: PT15S
    #value for GreetingActivities used in HelloWorkflow interface implementation; it has higher precedence than the default
    #please notice, how to escape dot character in yaml keys 
    "[PropertiesDotWorkflow.PropertiesActivity]":
      scheduleToCloseTimeout: PT3M
    TimeoutPropertiesActivity:
      startToCloseTimeout: PT100H
      scheduleToCloseTimeout: PT1M

@ActivityStub

@ActivityStub(startToClose = "PT10S")
public SomeActivity someActivity;

Since 0.7.0-SNAPSHOT duration and durationUnits properties are deprecated.

Instead, please use one of:

  • scheduleToClose
  • scheduleToStart
  • startToClose
  • heartbeat

These are temporal equivalents of timeout properties. Their values are in Java duration format.

Defining activities

The only thing you need is for the activity to be a Spring Boot @Service.

@Service
public class SomeActivityImpl implements SomeActivity {
  public String say(String string) {
    ...
  }
}

If you would like to have the activity on separate worker add @TemporalActivity annotation:

@Service
@TemporalActivity("SomeName")
public class SomeActivityImpl implements SomeActivity {
  public String say(String string) {
    ...
  }
}

And add parameters to set task queue and optionally worker parameters:

  activityWorkerDefaults:
    activityPoolSize: 9
   activityWorkers:
    SomeName:
      activityPoolSize: 10
      taskQueue: someActivityQueue

If you do so remember to add taskQueue parameter to annotation of the activity stub on the workflow as well. You can find example of such a process in samples/app folder in the tests HelloActivitySepareteWorker.java.

Calling your workflow

To call your workflow you will need WorkflowFactory an one of its many makeStub methods:

  @Autowired private WorkflowFactory fact;
public void callWorkflowMethod() {
  MyWorkflow workflow = 
        fact.makeStub(MyWorkflow.class, MyWorkflow.class);
  workflow.process();
}

Adding child workflow

You can use child workflows only with dedicated queue ChildWorkflowOptions.newBuilder().setTaskQueue(TASK_QUEUE).build();. Spring Boot starter for Temporal.io do not support multi-workflow queues as for now so no workers without task queue can be called.

Advanced stuff

Adding options to the activity stubs

To add some additional options to activity stubs you use @ActivityOptionsModifier annotation on the method in service implementation you need it. You need to specify the class of your activity as first argument for the system to find your method and you will receive activity options builder as second argument.

@ActivityStub(duration = "PT10S")
private GreetingActivities activities;

@ActivityOptionsModifier
private ActivityOptions.Builder modifyOptions(
    Class<GreetingActivities> cls, ActivityOptions.Builder options) {
  options.setHeartbeatTimeout(Duration.ofSeconds(2)).build());
  return options;
}

Adding options to workflow stubs

Use WorkflowFactory#defaultOptionsBuilder and pass options builder to WorkflowFactory#makeStub.

Adding default options to stubs and to workers

Use TemporalOptionsConfiguration class instantiated as a bean in your configuration. Like this:

public class TestTemporalOptionsConfiguration implements TemporalOptionsConfiguration {

  @Override
  public WorkflowClientOptions.Builder modifyClientOptions(
      WorkflowClientOptions.Builder newBuilder) {
    return newBuilder;
  }

  @Override
  public WorkflowOptions.Builder modifyDefalutStubOptions(
      WorkflowOptions.Builder newBuilder) {
    return newBuilder;
  }
}

Disable automatic worker creation

Spring boot starter for Temporal will usually create workers for all implemented workflows. If for some reasons you do not wont it to happen. You can add to configuration:

spring.temporal:
  createWorkers: false

You can also disable creation of workflows for given test when testing using annotation @TemporalTest

Namespace

You can make your application use specific temporal's namespace (default namespace name is default).

spring.temporal:
  namespace: custom-namespace

If You leave namespace empty or set value to null, then default namespace will be used.

All workflows will use namespace defined in yaml, unless You override this setting in TemporalOptionsConfiguration.modifyClientOptions() using setNamespace() of WorkflowClientOptions.Builder class.

Writing tests

Please look into test directory samples folder in the sources.

About

The driver making it convenient to use Temporal with Spring Boot.

Resources

License

Unknown and 2 other licenses found

Licenses found

Unknown
LICENSE.txt
Unknown
license-header-temporal.txt
Unknown
license-header.txt

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages