diff --git a/dapr-spring/dapr-spring-boot-autoconfigure/src/main/java/io/dapr/spring/boot/autoconfigure/client/DaprClientAutoConfiguration.java b/dapr-spring/dapr-spring-boot-autoconfigure/src/main/java/io/dapr/spring/boot/autoconfigure/client/DaprClientAutoConfiguration.java index ec26af03e..ed261ef05 100644 --- a/dapr-spring/dapr-spring-boot-autoconfigure/src/main/java/io/dapr/spring/boot/autoconfigure/client/DaprClientAutoConfiguration.java +++ b/dapr-spring/dapr-spring-boot-autoconfigure/src/main/java/io/dapr/spring/boot/autoconfigure/client/DaprClientAutoConfiguration.java @@ -17,6 +17,7 @@ import io.dapr.client.DaprClientBuilder; import io.dapr.config.Properties; import io.dapr.workflows.client.DaprWorkflowClient; +import io.dapr.workflows.runtime.WorkflowRuntimeBuilder; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -65,14 +66,26 @@ DaprClient daprClient(DaprClientBuilder daprClientBuilder) { @Bean @ConditionalOnMissingBean DaprWorkflowClient daprWorkflowClient(DaprConnectionDetails daprConnectionDetails) { + final Properties properties = createPropertiesFromConnectionDetails(daprConnectionDetails); + return new DaprWorkflowClient(properties); + } + + @Bean + @ConditionalOnMissingBean + WorkflowRuntimeBuilder daprWorkflowRuntimeBuilder(DaprConnectionDetails daprConnectionDetails) { + final Properties properties = createPropertiesFromConnectionDetails(daprConnectionDetails); + return new WorkflowRuntimeBuilder(properties); + } + + private Properties createPropertiesFromConnectionDetails(DaprConnectionDetails daprConnectionDetails) { final Map propertyOverrides = new HashMap<>(); propertyOverrides.put(Properties.HTTP_ENDPOINT.getName(), daprConnectionDetails.httpEndpoint()); propertyOverrides.put(Properties.HTTP_PORT.getName(), String.valueOf(daprConnectionDetails.httpPort())); propertyOverrides.put(Properties.GRPC_ENDPOINT.getName(), daprConnectionDetails.grpcEndpoint()); propertyOverrides.put(Properties.GRPC_PORT.getName(), String.valueOf(daprConnectionDetails.grpcPort())); - final Properties properties = new Properties(propertyOverrides); - return new DaprWorkflowClient(properties); + return new Properties(propertyOverrides); } + } diff --git a/dapr-spring/dapr-spring-boot-autoconfigure/src/test/java/io/dapr/spring/boot/autoconfigure/client/DaprWorkflowsRegistrationTests.java b/dapr-spring/dapr-spring-boot-autoconfigure/src/test/java/io/dapr/spring/boot/autoconfigure/client/DaprWorkflowsRegistrationTests.java new file mode 100644 index 000000000..b52657202 --- /dev/null +++ b/dapr-spring/dapr-spring-boot-autoconfigure/src/test/java/io/dapr/spring/boot/autoconfigure/client/DaprWorkflowsRegistrationTests.java @@ -0,0 +1,23 @@ +package io.dapr.spring.boot.autoconfigure.client; + +import io.dapr.spring.boot.autoconfigure.client.workflows.TestActivity; +import io.dapr.spring.boot.autoconfigure.client.workflows.TestWorkflow; +import io.dapr.workflows.client.DaprWorkflowClient; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@SpringBootTest(classes = {WorkflowTestApplication.class, DaprClientAutoConfiguration.class, TestActivity.class, TestWorkflow.class}) +public class DaprWorkflowsRegistrationTests { + + @Autowired + private DaprWorkflowClient daprWorkflowClient; + + @Test + public void doThat(){ + assertNotNull(daprWorkflowClient); + + } +} diff --git a/dapr-spring/dapr-spring-boot-autoconfigure/src/test/java/io/dapr/spring/boot/autoconfigure/client/WorkflowTestApplication.java b/dapr-spring/dapr-spring-boot-autoconfigure/src/test/java/io/dapr/spring/boot/autoconfigure/client/WorkflowTestApplication.java new file mode 100644 index 000000000..4b0cee746 --- /dev/null +++ b/dapr-spring/dapr-spring-boot-autoconfigure/src/test/java/io/dapr/spring/boot/autoconfigure/client/WorkflowTestApplication.java @@ -0,0 +1,14 @@ +package io.dapr.spring.boot.autoconfigure.client; + +import io.dapr.spring.workflows.config.EnableDaprWorkflows; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +@EnableDaprWorkflows +public class WorkflowTestApplication { + public static void main(String[] args) { + SpringApplication.run(WorkflowTestApplication.class, args); + + } +} diff --git a/dapr-spring/dapr-spring-boot-autoconfigure/src/test/java/io/dapr/spring/boot/autoconfigure/client/workflows/TestActivity.java b/dapr-spring/dapr-spring-boot-autoconfigure/src/test/java/io/dapr/spring/boot/autoconfigure/client/workflows/TestActivity.java new file mode 100644 index 000000000..e5a56c699 --- /dev/null +++ b/dapr-spring/dapr-spring-boot-autoconfigure/src/test/java/io/dapr/spring/boot/autoconfigure/client/workflows/TestActivity.java @@ -0,0 +1,11 @@ +package io.dapr.spring.boot.autoconfigure.client.workflows; + +import io.dapr.workflows.runtime.WorkflowActivity; +import io.dapr.workflows.runtime.WorkflowActivityContext; + +public class TestActivity implements WorkflowActivity { + @Override + public Object run(WorkflowActivityContext ctx) { + return null; + } +} diff --git a/dapr-spring/dapr-spring-boot-autoconfigure/src/test/java/io/dapr/spring/boot/autoconfigure/client/workflows/TestWorkflow.java b/dapr-spring/dapr-spring-boot-autoconfigure/src/test/java/io/dapr/spring/boot/autoconfigure/client/workflows/TestWorkflow.java new file mode 100644 index 000000000..81692355a --- /dev/null +++ b/dapr-spring/dapr-spring-boot-autoconfigure/src/test/java/io/dapr/spring/boot/autoconfigure/client/workflows/TestWorkflow.java @@ -0,0 +1,12 @@ +package io.dapr.spring.boot.autoconfigure.client.workflows; + +import io.dapr.workflows.Workflow; +import io.dapr.workflows.WorkflowStub; + +public class TestWorkflow extends Workflow { + + @Override + public WorkflowStub create() { + return null; + } +} diff --git a/dapr-spring/dapr-spring-boot-starters/dapr-spring-boot-starter/pom.xml b/dapr-spring/dapr-spring-boot-starters/dapr-spring-boot-starter/pom.xml index d06998b45..c9d7f22ee 100644 --- a/dapr-spring/dapr-spring-boot-starters/dapr-spring-boot-starter/pom.xml +++ b/dapr-spring/dapr-spring-boot-starters/dapr-spring-boot-starter/pom.xml @@ -40,6 +40,11 @@ dapr-spring-messaging ${project.parent.version} + + io.dapr.spring + dapr-spring-workflows + ${project.parent.version} + diff --git a/dapr-spring/dapr-spring-workflows/src/main/java/io/dapr/spring/workflows/config/DaprWorkflowsConfig.java b/dapr-spring/dapr-spring-workflows/src/main/java/io/dapr/spring/workflows/config/DaprWorkflowsConfig.java new file mode 100644 index 000000000..f018a29d1 --- /dev/null +++ b/dapr-spring/dapr-spring-workflows/src/main/java/io/dapr/spring/workflows/config/DaprWorkflowsConfig.java @@ -0,0 +1,57 @@ +package io.dapr.spring.workflows.config; + +import io.dapr.workflows.Workflow; +import io.dapr.workflows.runtime.WorkflowActivity; +import io.dapr.workflows.runtime.WorkflowRuntime; +import io.dapr.workflows.runtime.WorkflowRuntimeBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; + +import java.util.Map; + +@Configuration +@ComponentScan("io.dapr.spring.workflows.config") +public class DaprWorkflowsConfig implements ApplicationContextAware { + private static final Logger LOGGER = LoggerFactory.getLogger(DaprWorkflowsConfig.class); + @Autowired + private WorkflowRuntimeBuilder workflowRuntimeBuilder; + + private static ApplicationContext context; + + /** + * Register workflows and activities to the workflowRuntimeBuilder. + */ + public void registerWorkflowsAndActivities() { + LOGGER.info("Registering Dapr Workflows and Activities"); + Map workflowBeans = context.getBeansOfType(Workflow.class); + for (Workflow w : workflowBeans.values()) { + LOGGER.info("Dapr Workflow: '{}' registered", w.getClass().getName()); + workflowRuntimeBuilder.registerWorkflow(w.getClass()); + } + + Map workflowActivitiesBeans = context.getBeansOfType(WorkflowActivity.class); + for (WorkflowActivity a : workflowActivitiesBeans.values()) { + LOGGER.info("Dapr Workflow Activity: '{}' registered", a.getClass().getName()); + workflowRuntimeBuilder.registerActivity(a.getClass()); + } + + try (WorkflowRuntime runtime = workflowRuntimeBuilder.build()) { + LOGGER.info("Starting workflow runtime ... "); + runtime.start(false); + } + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + context = applicationContext; + registerWorkflowsAndActivities(); + } +} diff --git a/dapr-spring/dapr-spring-workflows/src/main/java/io/dapr/spring/workflows/config/EnableDaprWorkflows.java b/dapr-spring/dapr-spring-workflows/src/main/java/io/dapr/spring/workflows/config/EnableDaprWorkflows.java new file mode 100644 index 000000000..d2bd9522a --- /dev/null +++ b/dapr-spring/dapr-spring-workflows/src/main/java/io/dapr/spring/workflows/config/EnableDaprWorkflows.java @@ -0,0 +1,16 @@ +package io.dapr.spring.workflows.config; + + +import org.springframework.context.annotation.Import; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Retention(RUNTIME) +@Target(TYPE) +@Import(DaprWorkflowsConfig.class) +public @interface EnableDaprWorkflows { +}