Skip to content

Commit 69f2407

Browse files
salaboyhhunter-msartursouzadapr-bot
authored
Workflows alignment with Spring Boot (Dependency Injection for Workflows and Activities) (#1170)
* evaluating annotations Signed-off-by: salaboy <[email protected]> * adding workflows autoconfig Signed-off-by: salaboy <[email protected]> * initial @EnableDaprWorkflows implementation Signed-off-by: salaboy <[email protected]> * validating managed beans for workflows and activities Signed-off-by: salaboy <[email protected]> * [docs] remove 'beta' for Java SDK workflow docs (#1169) * fix link Signed-off-by: Hannah Hunter <[email protected]> * fix one more link Signed-off-by: Hannah Hunter <[email protected]> * remove beta from Java SDK workflow Signed-off-by: Hannah Hunter <[email protected]> --------- Signed-off-by: Hannah Hunter <[email protected]> Signed-off-by: salaboy <[email protected]> * Fix create release to run with right JDK (#1171) Signed-off-by: Artur Souza <[email protected]> Signed-off-by: salaboy <[email protected]> * Remove test from create release script. (#1172) Signed-off-by: Artur Souza <[email protected]> Signed-off-by: salaboy <[email protected]> * Fix typo crashing release script. (#1173) Signed-off-by: Artur Souza <[email protected]> Signed-off-by: salaboy <[email protected]> * Update master version to 1.14.0-SNAPSHOT (#1174) Signed-off-by: Dapr Bot <[email protected]> Signed-off-by: salaboy <[email protected]> * Generate updated javadocs for 1.13.1 (#1179) Signed-off-by: Dapr Bot <[email protected]> Co-authored-by: Dapr Bot <[email protected]> Signed-off-by: salaboy <[email protected]> * upgrading snap Signed-off-by: salaboy <[email protected]> * fix checkstyle Signed-off-by: salaboy <[email protected]> * Fix conflict and build trigger on right branch for SNAPSHOT. (#1180) Signed-off-by: Artur Souza <[email protected]> Signed-off-by: salaboy <[email protected]> * private internals Signed-off-by: salaboy <[email protected]> --------- Signed-off-by: salaboy <[email protected]> Signed-off-by: Hannah Hunter <[email protected]> Signed-off-by: Artur Souza <[email protected]> Signed-off-by: Dapr Bot <[email protected]> Co-authored-by: Hannah Hunter <[email protected]> Co-authored-by: Artur Souza <[email protected]> Co-authored-by: Dapr Bot <[email protected]> Co-authored-by: Dapr Bot <[email protected]>
1 parent 3a54a5e commit 69f2407

File tree

11 files changed

+249
-0
lines changed

11 files changed

+249
-0
lines changed

dapr-spring/dapr-spring-boot-autoconfigure/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@
2727
<version>${project.parent.version}</version>
2828
<optional>true</optional>
2929
</dependency>
30+
<dependency>
31+
<groupId>io.dapr.spring</groupId>
32+
<artifactId>dapr-spring-workflows</artifactId>
33+
<version>${project.parent.version}</version>
34+
<optional>true</optional>
35+
</dependency>
3036
<dependency>
3137
<groupId>org.springframework.boot</groupId>
3238
<artifactId>spring-boot-starter</artifactId>

dapr-spring/dapr-spring-boot-autoconfigure/src/main/java/io/dapr/spring/boot/autoconfigure/client/DaprClientAutoConfiguration.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,17 @@
1616
import io.dapr.client.DaprClient;
1717
import io.dapr.client.DaprClientBuilder;
1818
import io.dapr.config.Properties;
19+
import io.dapr.workflows.client.DaprWorkflowClient;
20+
import io.dapr.workflows.runtime.WorkflowRuntimeBuilder;
1921
import org.springframework.boot.autoconfigure.AutoConfiguration;
2022
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
2123
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2224
import org.springframework.boot.context.properties.EnableConfigurationProperties;
2325
import org.springframework.context.annotation.Bean;
2426

27+
import java.util.HashMap;
28+
import java.util.Map;
29+
2530
@AutoConfiguration
2631
@ConditionalOnClass(DaprClient.class)
2732
@EnableConfigurationProperties(DaprClientProperties.class)
@@ -58,4 +63,29 @@ DaprClient daprClient(DaprClientBuilder daprClientBuilder) {
5863
return daprClientBuilder.build();
5964
}
6065

66+
@Bean
67+
@ConditionalOnMissingBean
68+
DaprWorkflowClient daprWorkflowClient(DaprConnectionDetails daprConnectionDetails) {
69+
Properties properties = createPropertiesFromConnectionDetails(daprConnectionDetails);
70+
return new DaprWorkflowClient(properties);
71+
}
72+
73+
@Bean
74+
@ConditionalOnMissingBean
75+
WorkflowRuntimeBuilder daprWorkflowRuntimeBuilder(DaprConnectionDetails daprConnectionDetails) {
76+
Properties properties = createPropertiesFromConnectionDetails(daprConnectionDetails);
77+
return new WorkflowRuntimeBuilder(properties);
78+
}
79+
80+
private Properties createPropertiesFromConnectionDetails(DaprConnectionDetails daprConnectionDetails) {
81+
final Map<String, String> propertyOverrides = new HashMap<>();
82+
propertyOverrides.put(Properties.HTTP_ENDPOINT.getName(), daprConnectionDetails.httpEndpoint());
83+
propertyOverrides.put(Properties.HTTP_PORT.getName(), String.valueOf(daprConnectionDetails.httpPort()));
84+
propertyOverrides.put(Properties.GRPC_ENDPOINT.getName(), daprConnectionDetails.grpcEndpoint());
85+
propertyOverrides.put(Properties.GRPC_PORT.getName(), String.valueOf(daprConnectionDetails.grpcPort()));
86+
return new Properties(propertyOverrides);
87+
}
88+
89+
90+
6191
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package io.dapr.spring.boot.autoconfigure.client;
2+
3+
import io.dapr.spring.boot.autoconfigure.client.workflows.TestActivity;
4+
import io.dapr.spring.boot.autoconfigure.client.workflows.TestWorkflow;
5+
import io.dapr.workflows.client.DaprWorkflowClient;
6+
import io.dapr.workflows.runtime.WorkflowRuntimeBuilder;
7+
import org.junit.jupiter.api.Test;
8+
import org.springframework.beans.factory.annotation.Autowired;
9+
import org.springframework.boot.test.context.SpringBootTest;
10+
11+
import static org.junit.jupiter.api.Assertions.assertNotNull;
12+
13+
@SpringBootTest(classes = {WorkflowTestApplication.class, DaprClientAutoConfiguration.class, TestActivity.class, TestWorkflow.class})
14+
public class DaprWorkflowsRegistrationTests {
15+
16+
@Autowired
17+
private DaprWorkflowClient daprWorkflowClient;
18+
19+
@Autowired
20+
private WorkflowRuntimeBuilder workflowRuntimeBuilder;
21+
22+
@Autowired
23+
private TestActivity testActivity;
24+
25+
@Autowired
26+
private TestWorkflow testWorkflow;
27+
28+
@Test
29+
public void testWorkflowInjection(){
30+
31+
//I cannot test here if the client works, as it needs the runtime
32+
assertNotNull(daprWorkflowClient);
33+
34+
//@TODO: there is no way to assert the runtime and its registered workflows and activities
35+
assertNotNull(workflowRuntimeBuilder);
36+
37+
//Check that both Activities and Workflows are managed beans
38+
assertNotNull(testActivity);
39+
assertNotNull(testWorkflow);
40+
assertNotNull(testActivity.getRestTemplate());
41+
assertNotNull(testWorkflow.getRestTemplate());
42+
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package io.dapr.spring.boot.autoconfigure.client;
2+
3+
import io.dapr.spring.workflows.config.EnableDaprWorkflows;
4+
import org.springframework.boot.SpringApplication;
5+
import org.springframework.boot.autoconfigure.SpringBootApplication;
6+
import org.springframework.context.annotation.Bean;
7+
import org.springframework.context.annotation.Configuration;
8+
import org.springframework.web.client.RestTemplate;
9+
10+
@SpringBootApplication
11+
@EnableDaprWorkflows
12+
public class WorkflowTestApplication {
13+
public static void main(String[] args) {
14+
SpringApplication.run(WorkflowTestApplication.class, args);
15+
}
16+
17+
@Configuration
18+
static class Config {
19+
@Bean
20+
RestTemplate restTemplate(){
21+
return new RestTemplate();
22+
}
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package io.dapr.spring.boot.autoconfigure.client.workflows;
2+
3+
import io.dapr.workflows.runtime.WorkflowActivity;
4+
import io.dapr.workflows.runtime.WorkflowActivityContext;
5+
import org.springframework.beans.factory.annotation.Autowired;
6+
import org.springframework.web.client.RestTemplate;
7+
8+
public class TestActivity implements WorkflowActivity {
9+
10+
@Autowired
11+
private RestTemplate restTemplate;
12+
13+
@Override
14+
public Object run(WorkflowActivityContext ctx) {
15+
return "OK";
16+
}
17+
18+
public RestTemplate getRestTemplate() {
19+
return restTemplate;
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package io.dapr.spring.boot.autoconfigure.client.workflows;
2+
3+
import io.dapr.workflows.Workflow;
4+
import io.dapr.workflows.WorkflowStub;
5+
import org.springframework.beans.factory.annotation.Autowired;
6+
import org.springframework.web.client.RestTemplate;
7+
8+
public class TestWorkflow extends Workflow {
9+
10+
@Autowired
11+
private RestTemplate restTemplate;
12+
13+
@Override
14+
public WorkflowStub create() {
15+
return ctx -> {
16+
ctx.callActivity(TestActivity.class.getName(), null).await();
17+
};
18+
}
19+
20+
public RestTemplate getRestTemplate() {
21+
return restTemplate;
22+
}
23+
}

dapr-spring/dapr-spring-boot-starters/dapr-spring-boot-starter/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@
4040
<artifactId>dapr-spring-messaging</artifactId>
4141
<version>${project.parent.version}</version>
4242
</dependency>
43+
<dependency>
44+
<groupId>io.dapr.spring</groupId>
45+
<artifactId>dapr-spring-workflows</artifactId>
46+
<version>${project.parent.version}</version>
47+
</dependency>
4348
</dependencies>
4449

4550
</project>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<parent>
7+
<groupId>io.dapr.spring</groupId>
8+
<artifactId>dapr-spring-parent</artifactId>
9+
<version>0.14.0-SNAPSHOT</version>
10+
</parent>
11+
12+
<artifactId>dapr-spring-workflows</artifactId>
13+
<name>dapr-spring-workflows</name>
14+
<description>Dapr Spring Workflows</description>
15+
<packaging>jar</packaging>
16+
17+
<dependencies>
18+
<dependency>
19+
<groupId>io.dapr</groupId>
20+
<artifactId>dapr-sdk-workflows</artifactId>
21+
<version>${project.version}</version>
22+
</dependency>
23+
</dependencies>
24+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package io.dapr.spring.workflows.config;
2+
3+
import io.dapr.workflows.Workflow;
4+
import io.dapr.workflows.runtime.WorkflowActivity;
5+
import io.dapr.workflows.runtime.WorkflowRuntime;
6+
import io.dapr.workflows.runtime.WorkflowRuntimeBuilder;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
import org.springframework.beans.BeansException;
10+
import org.springframework.beans.factory.annotation.Autowired;
11+
import org.springframework.context.ApplicationContext;
12+
import org.springframework.context.ApplicationContextAware;
13+
import org.springframework.context.annotation.Configuration;
14+
15+
import java.util.Map;
16+
17+
@Configuration
18+
public class DaprWorkflowsConfiguration implements ApplicationContextAware {
19+
private static final Logger LOGGER = LoggerFactory.getLogger(DaprWorkflowsConfiguration.class);
20+
21+
private WorkflowRuntimeBuilder workflowRuntimeBuilder;
22+
23+
public DaprWorkflowsConfiguration(WorkflowRuntimeBuilder workflowRuntimeBuilder) {
24+
this.workflowRuntimeBuilder = workflowRuntimeBuilder;
25+
}
26+
27+
/**
28+
* Register workflows and activities to the workflowRuntimeBuilder.
29+
* @param applicationContext Spring Application Context
30+
*/
31+
private void registerWorkflowsAndActivities(ApplicationContext applicationContext) {
32+
LOGGER.info("Registering Dapr Workflows and Activities");
33+
Map<String, Workflow> workflowBeans = applicationContext.getBeansOfType(Workflow.class);
34+
for (Workflow w : workflowBeans.values()) {
35+
LOGGER.info("Dapr Workflow: '{}' registered", w.getClass().getName());
36+
workflowRuntimeBuilder.registerWorkflow(w.getClass());
37+
}
38+
39+
Map<String, WorkflowActivity> workflowActivitiesBeans = applicationContext.getBeansOfType(WorkflowActivity.class);
40+
for (WorkflowActivity a : workflowActivitiesBeans.values()) {
41+
LOGGER.info("Dapr Workflow Activity: '{}' registered", a.getClass().getName());
42+
workflowRuntimeBuilder.registerActivity(a.getClass());
43+
}
44+
45+
try (WorkflowRuntime runtime = workflowRuntimeBuilder.build()) {
46+
LOGGER.info("Starting workflow runtime ... ");
47+
runtime.start(false);
48+
}
49+
}
50+
51+
@Override
52+
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
53+
registerWorkflowsAndActivities(applicationContext);
54+
}
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package io.dapr.spring.workflows.config;
2+
3+
4+
import org.springframework.context.annotation.Import;
5+
6+
import java.lang.annotation.Retention;
7+
import java.lang.annotation.Target;
8+
9+
import static java.lang.annotation.ElementType.TYPE;
10+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
11+
12+
@Retention(RUNTIME)
13+
@Target(TYPE)
14+
@Import(DaprWorkflowsConfiguration.class)
15+
public @interface EnableDaprWorkflows {
16+
}

dapr-spring/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
<modules>
2121
<module>dapr-spring-data</module>
2222
<module>dapr-spring-messaging</module>
23+
<module>dapr-spring-workflows</module>
2324
<module>dapr-spring-boot-autoconfigure</module>
2425
<module>dapr-spring-boot-tests</module>
2526
<module>dapr-spring-boot-starters/dapr-spring-boot-starter</module>

0 commit comments

Comments
 (0)