As described in the previous chapter, Spring Cloud Data Flow’s functionality is completely exposed via REST endpoints. While you can use those endpoints directly, Spring Cloud Data Flow also provides a Java-based API, which makes using those REST endpoints even easier.
The central entrypoint is the DataFlowTemplate
class in package org.springframework.cloud.dataflow.rest.client
.
This class implements the interface DataFlowOperations
and delegates to sub-templates
that provide the specific functionality for each feature-set:
Interface | Description |
---|---|
StreamOperations | REST client for stream operations |
CounterOperations | REST client for counter operations |
FieldValueCounterOperations | REST client for field value counter operations |
AggregateCounterOperations | REST client for aggregate counter operations |
TaskOperations | REST client for task operations |
JobOperations | REST client for job operations |
AppRegistryOperations | REST client for app registry operations |
CompletionOperations | REST client for completion operations |
RuntimeOperations | REST Client for runtime operations |
When the DataFlowTemplate
is being initialized, the sub-templates will be discovered
via the REST relations, which are provided by HATEOAS.[1]
Important | |
---|---|
If a resource cannot be resolved, the respective sub-template will result in being NULL. A common cause is that Spring Cloud Data Flow offers for specific sets of features to be enabled/disabled when launching. For more information see Chapter 12, Feature Toggles. |
When using the Data Flow Template the only needed Data Flow dependency is the Spring Cloud Data Flow Rest Client:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dataflow-rest-client</artifactId> <version>1.2.3.RELEASE</version> </dependency>
With that dependency you will get the DataFlowTemplate
class as well as all needed
dependencies to make calls to a Spring Cloud Data Flow server.
When instantiating the DataFlowTemplate
, you will also pass in a RestTemplate
.
Please be aware that the needed RestTemplate
requires some additional configuration
to be valid in the context of the DataFlowTemplate
. When declaring a RestTemplate
as a bean, the following configuration will suffice:
@Bean public static RestTemplate restTemplate() { RestTemplate restTemplate = new RestTemplate(); restTemplate.setErrorHandler(new VndErrorResponseErrorHandler(restTemplate.getMessageConverters())); for(HttpMessageConverter<?> converter : restTemplate.getMessageConverters()) { if (converter instanceof MappingJackson2HttpMessageConverter) { final MappingJackson2HttpMessageConverter jacksonConverter = (MappingJackson2HttpMessageConverter) converter; jacksonConverter.getObjectMapper() .registerModule(new Jackson2HalModule()) .addMixIn(JobExecution.class, JobExecutionJacksonMixIn.class) .addMixIn(JobParameters.class, JobParametersJacksonMixIn.class) .addMixIn(JobParameter.class, JobParameterJacksonMixIn.class) .addMixIn(JobInstance.class, JobInstanceJacksonMixIn.class) .addMixIn(ExitStatus.class, ExitStatusJacksonMixIn.class) .addMixIn(StepExecution.class, StepExecutionJacksonMixIn.class) .addMixIn(ExecutionContext.class, ExecutionContextJacksonMixIn.class) .addMixIn(StepExecutionHistory.class, StepExecutionHistoryJacksonMixIn.class); } } return restTemplate; }
Now you can instantiate the DataFlowTemplate
with:
DataFlowTemplate dataFlowTemplate = new DataFlowTemplate( new URI("http://localhost:9393/"), restTemplate);
Depending on your requirements, you can now make calls to the server. For instance, if you like to get a list of currently available applications you can execute:
PagedResources<AppRegistrationResource> apps = dataFlowTemplate.appRegistryOperations().list(); System.out.println(String.format("Retrieved %s application(s)", apps.getContent().size())); for (AppRegistrationResource app : apps.getContent()) { System.out.println(String.format("App Name: %s, App Type: %s, App URI: %s", app.getName(), app.getType(), app.getUri())); }