-
Notifications
You must be signed in to change notification settings - Fork 39
Spring Boot guide
Spring Boot is a popular way for creating stand-alone Spring applications. This page contains instructions for setting up nFlow on top of vanilla Spring Boot project using Gradle.
The bare minimum includes the bare minimum nFlow engine configuration for Spring Boot. The database is in-memory H2. The full working example can be found from nFlow Github repository.
-
Generate Spring Boot application using Initializr. Use Gradle and add JDBC and H2 dependencies.
-
Enable
nflow.db.h2
profile and disable verbose logging by adding the following lines tosrc/main/resources/application.properties
:
spring.profiles.active=nflow.db.h2
logging.level.root=WARN
- Add
nflow-engine
dependency tobuild.gradle
dependencies:
compile("io.nflow:nflow-engine:4.2.0")
- Import nFlow engine configuration in Spring Boot application class:
@Import(EngineConfiguration.class)
-
Create example definition that increments and outputs a counter every 10 seconds.
-
Build the Spring Boot application in command line:
./gradlew build
- Start the Spring Boot application and observe the counter value is printed every 10 seconds on each
ExampleWorkflow
step:
java -jar build/libs/bare-minimum-0.0.1-SNAPSHOT.jar
The full stack includes the nFlow engine, REST API and Explorer user interface for Spring Boot. The database is in-memory H2. The full working example can be found from nFlow Github repository.
-
Generate Spring Boot application using Initializr. Use Gradle and add web, Jersey, JDBC and H2 dependencies.
-
Enable
nflow.db.h2
profile, disable verbose logging and define context path for Jersey resources by adding the following lines tosrc/main/resources/application.properties
:
spring.profiles.active=nflow.db.h2
logging.level.root=WARN
spring.jersey.application-path=/rest
- Add
nflow-rest-api
tobuild.gradle
dependencies:
compile("io.nflow:nflow-rest-api:4.2.0")
- Import nFlow engine configuration in Spring Boot application class
@Import(RestConfiguration.class)
-
Create example definition that increments and outputs a counter every 10 seconds.
-
nFlow uses internally two Jackson
ObjectMapper
s. Spring Boot needs to know the preferredObjectMapper
although Spring Boot is not used in this example for any JSON serialization. Just make one of theObjectMapper
s primary so that Spring Boot is happy.
@Bean
@Primary
public ObjectMapper springWebObjectMapper(@NFlow ObjectMapper nflowObjectMapper) {
return nflowObjectMapper;
}
- nFlow REST API is JAX-RS compatible module, so setup Jersey and register nFlow REST endpoints. Note: Jersey package scanning does not work for Spring Boot custom uberjar packaging, so resources need to be registered explicitly.
@Bean
public JerseyResourceConfig jerseyResourceConfig() {
return new JerseyResourceConfig();
}
private static class JerseyResourceConfig extends ResourceConfig {
public JerseyResourceConfig() {
register(ArchiveResource.class);
register(WorkflowDefinitionResource.class);
register(WorkflowExecutorResource.class);
register(WorkflowInstanceResource.class);
register(StatisticsResource.class);
register(DateTimeParamConverterProvider.class);
register(JacksonFeature.class);
}
}
- Download and package nFlow Explorer static resources inside Spring Boot uberjar by adding the following configuration to
build.gradle
:
plugins {
id 'de.undercouch.download' version '3.1.1'
}
configurations {
nflowExplorer
}
// add to dependencies
nflowExplorer group: 'com.nitorcreations', name: 'nflow-explorer', version: '1.2.5', ext: 'tar.gz'
task resolveNflowExplorer(type: Copy) {
destinationDir = file("$buildDir/resources/main/static/explorer")
from { tarTree(resources.gzip(configurations.nflowExplorer.singleFile)) }
}
processResources.dependsOn resolveNflowExplorer
- In addition to static resources, nFlow Explorer needs to know the address and configuration of the nFlow REST API. Add nFlow Explorer configuration by creating a file
src/main/resources/static/explorer/config.js
.
var Config = function () {
this.nflowEndpoints = [
{
id: 'Full stack example',
title: 'Full stack example API',
apiUrl: '/rest/nflow'
}
];
this.radiator = {
// poll period in seconds
pollPeriod: 15,
// max number of items to keep in memory
maxHistorySize: 10000
};
};
- Build the Spring Boot application in command line
./gradlew build
- Start the Spring Boot application and observe the counter value is printed every 10 seconds on each
ExampleWorkflow
step. You can also open up local nFlow Explorer user interface.
java -jar build/libs/full-stack-0.0.1-SNAPSHOT.jar
- Copy & paste the following workflow definition to a new class file
ExampleWorkflow
import org.joda.time.DateTime;
import io.nflow.engine.workflow.definition.NextAction;
import io.nflow.engine.workflow.definition.StateExecution;
import io.nflow.engine.workflow.definition.WorkflowDefinition;
import io.nflow.engine.workflow.definition.WorkflowStateType;
import static io.nflow.engine.workflow.definition.WorkflowStateType.manual;
import static io.nflow.engine.workflow.definition.WorkflowStateType.start;
public class ExampleWorkflow extends WorkflowDefinition<ExampleWorkflow.State> {
public static final String TYPE = "repeatingWorkflow";
public static final String VAR_COUNTER = "VAR_COUNTER";
public enum State implements io.nflow.engine.workflow.definition.WorkflowState {
repeat(start, "Repeating state"),
error(manual, "Error state");
private WorkflowStateType type;
private String description;
State(WorkflowStateType type, String description) {
this.type = type;
this.description = description;
}
@Override
public WorkflowStateType getType() {
return type;
}
@Override
public String getDescription() {
return description;
}
}
public ExampleWorkflow() {
super(TYPE, State.repeat, State.error);
permit(State.repeat, State.repeat);
}
public NextAction repeat(StateExecution execution) {
System.out.println("Counter: " + execution.getVariable(VAR_COUNTER));
execution.setVariable(VAR_COUNTER, execution.getVariable(VAR_COUNTER, Integer.class) + 1);
return NextAction.moveToStateAfter(State.repeat, DateTime.now().plusSeconds(10), "Next iteration");
}
}
- Add an
ExampleWorkflow
bean to your Spring Boot application:
@Bean
public ExampleWorkflow exampleWorkflow() {
return new ExampleWorkflow();
}
- Create a new
ExampleWorkflow
instance by usingWorkflowInstanceFactory
andWorkflowInstanceService
in the Spring Boot application
@Inject
private WorkflowInstanceService workflowInstances;
@Inject
private WorkflowInstanceFactory workflowInstanceFactory;
@PostConstruct
public void createExampleWorkflowInstance() {
workflowInstances.insertWorkflowInstance(workflowInstanceFactory.newWorkflowInstanceBuilder()
.setType(ExampleWorkflow.TYPE)
.setExternalId("example")
.putStateVariable(ExampleWorkflow.VAR_COUNTER, 0)
.build());
}