diff --git a/.gitignore b/.gitignore
index 0314f663d..d39d713b8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -49,3 +49,6 @@ hs_err_pid*
/docs/dapr-sdk
/proto/dapr
/proto/daprclient
+
+# macOS
+.DS_Store
diff --git a/README.md b/README.md
index b36dfb006..89d2e0c05 100644
--- a/README.md
+++ b/README.md
@@ -68,6 +68,12 @@ For a Maven project, add the following to your `pom.xml` file:
dapr-sdk-actors
0.3.0
+
+
+ io.dapr
+ dapr-sdk-springboot
+ 0.4.0-SNAPSHOT
+
com.squareup.okhttp3
@@ -103,6 +109,8 @@ dependencies {
compile('io.dapr:dapr-sdk:0.3.0')
// Dapr's SDK for Actors (optional).
compile('io.dapr:dapr-sdk-actors:0.3.0')
+ // Dapr's SDK integration with SpringBoot (optional).
+ compile('io.dapr:dapr-sdk-springboot:0.4.0-SNAPSHOT')
// If needed, force conflict resolution for okhttp3.
configurations.all {
diff --git a/examples/pom.xml b/examples/pom.xml
index 46b01054e..856f66d57 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -73,6 +73,11 @@
spring-boot-autoconfigure
2.2.2.RELEASE
+
+ io.dapr
+ dapr-sdk-springboot
+ ${project.version}
+
io.dapr
dapr-sdk-actors
diff --git a/examples/src/main/java/io/dapr/examples/actors/http/DemoActorService.java b/examples/src/main/java/io/dapr/examples/actors/http/DemoActorService.java
index 077d47937..b7ecbebbb 100644
--- a/examples/src/main/java/io/dapr/examples/actors/http/DemoActorService.java
+++ b/examples/src/main/java/io/dapr/examples/actors/http/DemoActorService.java
@@ -12,6 +12,8 @@ import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
+import java.time.Duration;
+
/**
* Service for Actor runtime.
* 1. Build and install jars:
@@ -36,7 +38,16 @@ public class DemoActorService {
CommandLine cmd = parser.parse(options, args);
// If port string is not valid, it will throw an exception.
- int port = Integer.parseInt(cmd.getOptionValue("port"));
+ final int port = Integer.parseInt(cmd.getOptionValue("port"));
+
+ // Idle timeout until actor instance is deactivated.
+ ActorRuntime.getInstance().getConfig().setActorIdleTimeout(Duration.ofSeconds(30));
+ // How often actor instances are scanned for deactivation and balance.
+ ActorRuntime.getInstance().getConfig().setActorScanInterval(Duration.ofSeconds(10));
+ // How long to wait until for draining an ongoing API call for an actor instance.
+ ActorRuntime.getInstance().getConfig().setDrainOngoingCallTimeout(Duration.ofSeconds(10));
+ // Determines whether to drain API calls for actors instances being balanced.
+ ActorRuntime.getInstance().getConfig().setDrainBalancedActors(true);
// Register the Actor class.
ActorRuntime.getInstance().registerActor(DemoActorImpl.class);
diff --git a/examples/src/main/java/io/dapr/examples/actors/http/README.md b/examples/src/main/java/io/dapr/examples/actors/http/README.md
index f48706ebe..3e151872e 100644
--- a/examples/src/main/java/io/dapr/examples/actors/http/README.md
+++ b/examples/src/main/java/io/dapr/examples/actors/http/README.md
@@ -38,7 +38,6 @@ mvn install
The first Java class is `DemoActorService`. Its job is to register an implementation of `DemoActor` in the Dapr's Actor runtime. In `DemoActorService.java` file, you will find the `DemoActorService` class and the `main` method. See the code snippet below:
```java
-@SpringBootApplication
public class DemoActorService {
public static void main(String[] args) throws Exception {
diff --git a/examples/src/main/java/io/dapr/examples/pubsub/http/README.md b/examples/src/main/java/io/dapr/examples/pubsub/http/README.md
index 611c7dd11..840b18dbb 100644
--- a/examples/src/main/java/io/dapr/examples/pubsub/http/README.md
+++ b/examples/src/main/java/io/dapr/examples/pubsub/http/README.md
@@ -44,18 +44,14 @@ public class Subscriber {
```
`DaprApplication.start()` Method will run an Spring Boot application that registers the `SubscriberController`, which exposes the message retrieval as a POST request. The Dapr's sidecar is the one that performs the actual call to the controller, based on the pubsub features.
-This Spring Controller handles the message endpoint, Printing the recieved message which is recieved as the POST body. See the code snippet below:
+This Spring Controller handles the message endpoint, Printing the message which is received as the POST body. The topic subscription in Dapr is handled automatically via the `@Topic` annotation. See the code snippet below:
```java
@RestController
public class SubscriberController {
///...
- @GetMapping("/dapr/subscribe")
- public byte[] daprConfig() throws Exception {
- return SERIALIZER.serialize(new String[] { "message" });
- }
-
- @PostMapping(path = "/message")
+ @Topic(name = "testingtopic")
+ @PostMapping(path = "/testingtopic")
public Mono handleMessage(@RequestBody(required = false) byte[] body,
@RequestHeader Map headers) {
return Mono.fromRunnable(() -> {
diff --git a/examples/src/main/java/io/dapr/examples/pubsub/http/SubscriberController.java b/examples/src/main/java/io/dapr/examples/pubsub/http/SubscriberController.java
index 2700ba63e..8106ab18f 100644
--- a/examples/src/main/java/io/dapr/examples/pubsub/http/SubscriberController.java
+++ b/examples/src/main/java/io/dapr/examples/pubsub/http/SubscriberController.java
@@ -5,6 +5,7 @@
package io.dapr.examples.pubsub.http;
+import io.dapr.Topic;
import io.dapr.client.domain.CloudEvent;
import io.dapr.serializer.DefaultObjectSerializer;
import org.springframework.web.bind.annotation.GetMapping;
@@ -22,22 +23,13 @@ import java.util.Map;
@RestController
public class SubscriberController {
- /**
- * Dapr's default serializer/deserializer.
- */
- private static final DefaultObjectSerializer SERIALIZER = new DefaultObjectSerializer();
-
- @GetMapping("/dapr/subscribe")
- public byte[] daprConfig() throws Exception {
- return SERIALIZER.serialize(new String[]{"testingtopic"});
- }
-
/**
* Handles a registered publish endpoint on this app.
* @param body The body of the http message.
* @param headers The headers of the http message.
* @return A message containing the time.
*/
+ @Topic(name = "testingtopic")
@PostMapping(path = "/testingtopic")
public Mono handleMessage(@RequestBody(required = false) byte[] body,
@RequestHeader Map headers) {
diff --git a/examples/src/main/java/io/dapr/springboot/DaprApplication.java b/examples/src/main/java/io/dapr/springboot/DaprApplication.java
index 22d22ea6b..f97c7bc36 100644
--- a/examples/src/main/java/io/dapr/springboot/DaprApplication.java
+++ b/examples/src/main/java/io/dapr/springboot/DaprApplication.java
@@ -10,6 +10,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Dapr's HTTP callback implementation via SpringBoot.
+ * Scanning package io.dapr.springboot is required.
*/
@SpringBootApplication(scanBasePackages = {"io.dapr.springboot", "io.dapr.examples"})
public class DaprApplication {
diff --git a/pom.xml b/pom.xml
index dffc777f9..25cb78b89 100644
--- a/pom.xml
+++ b/pom.xml
@@ -252,6 +252,7 @@
sdk-autogen
sdk
sdk-actors
+ sdk-springboot
examples
diff --git a/sdk-springboot/pom.xml b/sdk-springboot/pom.xml
new file mode 100644
index 000000000..9aa580dda
--- /dev/null
+++ b/sdk-springboot/pom.xml
@@ -0,0 +1,168 @@
+
+ 4.0.0
+
+
+ io.dapr
+ dapr-sdk-parent
+ 0.4.0-SNAPSHOT
+
+
+ dapr-sdk-springboot
+ jar
+ 0.4.0-SNAPSHOT
+ dapr-sdk-springboot
+ SDK extension for Springboot
+
+
+
+
+ false
+
+ central
+ libs-release
+ https://repo.spring.io/libs-release
+
+
+
+
+ false
+
+
+
+
+ io.dapr
+ dapr-sdk
+ ${project.version}
+
+
+ io.dapr
+ dapr-sdk-actors
+ ${project.version}
+
+
+ junit
+ junit
+ test
+
+
+ org.mockito
+ mockito-core
+ test
+
+
+ com.github.gmazzo
+ okhttp-mock
+ 1.3.2
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.5.2
+ test
+
+
+ org.springframework
+ spring-beans
+ 5.2.3.RELEASE
+ compile
+
+
+ org.springframework
+ spring-web
+ 5.2.2.RELEASE
+ compile
+
+
+ org.springframework
+ spring-web
+ 5.2.2.RELEASE
+ compile
+
+
+ org.springframework
+ spring-context
+ 5.2.2.RELEASE
+ compile
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.2.0
+
+
+ attach-sources
+
+ jar-no-fork
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.1.1
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.8.4
+
+
+ default-prepare-agent
+
+ prepare-agent
+
+
+
+ report
+ test
+
+ report
+
+
+ target/jacoco-report/
+
+
+
+ check
+
+ check
+
+
+
+
+ BUNDLE
+
+
+ LINE
+ COVEREDRATIO
+ 80%
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sdk-springboot/src/main/java/io/dapr/springboot/DaprBeanPostProcessor.java b/sdk-springboot/src/main/java/io/dapr/springboot/DaprBeanPostProcessor.java
new file mode 100644
index 000000000..c247c1dbd
--- /dev/null
+++ b/sdk-springboot/src/main/java/io/dapr/springboot/DaprBeanPostProcessor.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ */
+
+package io.dapr.springboot;
+
+import io.dapr.Topic;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.Method;
+
+@Component
+public class DaprBeanPostProcessor implements BeanPostProcessor {
+
+ @Override
+ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
+ if (bean == null) {
+ return null;
+ }
+
+ subscribeToTopics(bean.getClass());
+
+ return bean;
+ }
+
+ @Override
+ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
+ return bean;
+ }
+
+ private static void subscribeToTopics(Class clazz) {
+ if (clazz == null) {
+ return;
+ }
+
+ subscribeToTopics(clazz.getSuperclass());
+ for (Method method : clazz.getDeclaredMethods()) {
+ Topic topic = method.getAnnotation(Topic.class);
+ if (topic == null) {
+ continue;
+ }
+
+ String topicName = topic.name();
+ if ((topicName != null) && (topicName.length() > 0)) {
+ DaprRuntime.getInstance().addSubscribedTopic(topicName);
+ }
+ }
+ }
+}
diff --git a/examples/src/main/java/io/dapr/springboot/DaprController.java b/sdk-springboot/src/main/java/io/dapr/springboot/DaprController.java
similarity index 85%
rename from examples/src/main/java/io/dapr/springboot/DaprController.java
rename to sdk-springboot/src/main/java/io/dapr/springboot/DaprController.java
index c1b46885d..35000fe2e 100644
--- a/examples/src/main/java/io/dapr/springboot/DaprController.java
+++ b/sdk-springboot/src/main/java/io/dapr/springboot/DaprController.java
@@ -6,6 +6,7 @@
package io.dapr.springboot;
import io.dapr.actors.runtime.ActorRuntime;
+import io.dapr.serializer.DefaultObjectSerializer;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -21,16 +22,21 @@ import reactor.core.publisher.Mono;
@RestController
public class DaprController {
- @GetMapping("/")
- public String index() {
- return "Greetings from Dapr!";
- }
+ /**
+ * Dapr's default serializer/deserializer.
+ */
+ private static final DefaultObjectSerializer SERIALIZER = new DefaultObjectSerializer();
@GetMapping("/dapr/config")
public byte[] daprConfig() throws Exception {
return ActorRuntime.getInstance().serializeConfig();
}
+ @GetMapping("/dapr/subscribe")
+ public byte[] daprSubscribe() throws Exception {
+ return SERIALIZER.serialize(DaprRuntime.getInstance().listSubscribedTopics());
+ }
+
@PostMapping(path = "/actors/{type}/{id}")
public Mono activateActor(@PathVariable("type") String type,
@PathVariable("id") String id) throws Exception {
diff --git a/sdk-springboot/src/main/java/io/dapr/springboot/DaprRuntime.java b/sdk-springboot/src/main/java/io/dapr/springboot/DaprRuntime.java
new file mode 100644
index 000000000..7739cc485
--- /dev/null
+++ b/sdk-springboot/src/main/java/io/dapr/springboot/DaprRuntime.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ */
+
+package io.dapr.springboot;
+
+import java.util.HashSet;
+import java.util.Set;
+
+class DaprRuntime {
+
+ /**
+ * The singleton instance.
+ */
+ private static volatile DaprRuntime instance;
+
+ private final Set subscribedTopics = new HashSet<>();
+
+ /**
+ * Private constructor to make this singleton.
+ */
+ private DaprRuntime() {
+ }
+
+ /**
+ * Returns an DaprRuntime object.
+ *
+ * @return An DaprRuntime object.
+ */
+ public static DaprRuntime getInstance() {
+ if (instance == null) {
+ synchronized (DaprRuntime.class) {
+ if (instance == null) {
+ instance = new DaprRuntime();
+ }
+ }
+ }
+
+ return instance;
+ }
+
+ public synchronized void addSubscribedTopic(String topicName) {
+ if (!this.subscribedTopics.contains(topicName)) {
+ this.subscribedTopics.add(topicName);
+ }
+ }
+
+ public synchronized String[] listSubscribedTopics() {
+ return this.subscribedTopics.toArray(new String[0]);
+ }
+}
diff --git a/sdk-tests/pom.xml b/sdk-tests/pom.xml
index 66012bcff..235a2f51d 100644
--- a/sdk-tests/pom.xml
+++ b/sdk-tests/pom.xml
@@ -41,6 +41,12 @@
${dapr.sdk.version}
test
+
+ io.dapr
+ dapr-sdk-springboot
+ ${dapr.sdk.version}
+ test
+
junit
junit
diff --git a/sdk-tests/src/test/java/io/dapr/it/actors/app/TestApplication.java b/sdk-tests/src/test/java/io/dapr/it/actors/app/TestApplication.java
index 7847c0218..4a1089e95 100644
--- a/sdk-tests/src/test/java/io/dapr/it/actors/app/TestApplication.java
+++ b/sdk-tests/src/test/java/io/dapr/it/actors/app/TestApplication.java
@@ -11,7 +11,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Dapr's HTTP callback implementation via SpringBoot.
*/
-@SpringBootApplication(scanBasePackages = {"io.dapr.it.actors.app"})
+@SpringBootApplication(scanBasePackages = {"io.dapr.springboot", "io.dapr.it.actors.app"})
public class TestApplication {
/**
diff --git a/sdk-tests/src/test/java/io/dapr/it/actors/app/TestController.java b/sdk-tests/src/test/java/io/dapr/it/actors/app/TestController.java
deleted file mode 100644
index de289b526..000000000
--- a/sdk-tests/src/test/java/io/dapr/it/actors/app/TestController.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) Microsoft Corporation.
- * Licensed under the MIT License.
- */
-
-package io.dapr.it.actors.app;
-
-import io.dapr.actors.runtime.ActorRuntime;
-import org.springframework.web.bind.annotation.*;
-import reactor.core.publisher.Mono;
-
-/**
- * SpringBoot Controller to handle callback APIs for Dapr.
- */
-@RestController
-class TestController {
-
- @GetMapping("/")
- public String index() {
- return "Greetings from Dapr!";
- }
-
- @GetMapping("/dapr/config")
- public byte[] daprConfig() throws Exception {
- return ActorRuntime.getInstance().serializeConfig();
- }
-
- @PostMapping(path = "/actors/{type}/{id}")
- public Mono activateActor(@PathVariable("type") String type,
- @PathVariable("id") String id) throws Exception {
- return ActorRuntime.getInstance().activate(type, id);
- }
-
- @DeleteMapping(path = "/actors/{type}/{id}")
- public Mono deactivateActor(@PathVariable("type") String type,
- @PathVariable("id") String id) throws Exception {
- return ActorRuntime.getInstance().deactivate(type, id);
- }
-
- @PutMapping(path = "/actors/{type}/{id}/method/{method}")
- public Mono invokeActorMethod(@PathVariable("type") String type,
- @PathVariable("id") String id,
- @PathVariable("method") String method,
- @RequestBody(required = false) byte[] body) {
- return ActorRuntime.getInstance().invoke(type, id, method, body);
- }
-
- @PutMapping(path = "/actors/{type}/{id}/method/timer/{timer}")
- public Mono invokeActorTimer(@PathVariable("type") String type,
- @PathVariable("id") String id,
- @PathVariable("timer") String timer) {
- return ActorRuntime.getInstance().invokeTimer(type, id, timer);
- }
-
- @PutMapping(path = "/actors/{type}/{id}/method/remind/{reminder}")
- public Mono invokeActorReminder(@PathVariable("type") String type,
- @PathVariable("id") String id,
- @PathVariable("reminder") String reminder,
- @RequestBody(required = false) byte[] body) {
- return ActorRuntime.getInstance().invokeReminder(type, id, reminder, body);
- }
-}
diff --git a/sdk-tests/src/test/java/io/dapr/it/actors/services/springboot/DaprApplication.java b/sdk-tests/src/test/java/io/dapr/it/actors/services/springboot/DaprApplication.java
index 6045fc405..520b2db57 100644
--- a/sdk-tests/src/test/java/io/dapr/it/actors/services/springboot/DaprApplication.java
+++ b/sdk-tests/src/test/java/io/dapr/it/actors/services/springboot/DaprApplication.java
@@ -11,7 +11,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Dapr's HTTP callback implementation via SpringBoot.
*/
-@SpringBootApplication(scanBasePackages = {"io.dapr.it.actors.services.springboot"})
+@SpringBootApplication(scanBasePackages = {"io.dapr.springboot", "io.dapr.it.actors.services.springboot"})
public class DaprApplication {
/**
diff --git a/sdk-tests/src/test/java/io/dapr/it/actors/services/springboot/DaprController.java b/sdk-tests/src/test/java/io/dapr/it/actors/services/springboot/DaprController.java
deleted file mode 100644
index 3d6df071d..000000000
--- a/sdk-tests/src/test/java/io/dapr/it/actors/services/springboot/DaprController.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) Microsoft Corporation.
- * Licensed under the MIT License.
- */
-
-package io.dapr.it.actors.services.springboot;
-
-import io.dapr.actors.runtime.ActorRuntime;
-import org.springframework.web.bind.annotation.*;
-import reactor.core.publisher.Mono;
-
-/**
- * SpringBoot Controller to handle callback APIs for Dapr.
- */
-@RestController
-public class DaprController {
-
- @GetMapping("/")
- public String index() {
- return "Greetings from Dapr!";
- }
-
- @GetMapping("/dapr/config")
- public byte[] daprConfig() throws Exception {
- return ActorRuntime.getInstance().serializeConfig();
- }
-
- @PostMapping(path = "/actors/{type}/{id}")
- public Mono activateActor(@PathVariable("type") String type,
- @PathVariable("id") String id) throws Exception {
- return ActorRuntime.getInstance().activate(type, id);
- }
-
- @DeleteMapping(path = "/actors/{type}/{id}")
- public Mono deactivateActor(@PathVariable("type") String type,
- @PathVariable("id") String id) throws Exception {
- return ActorRuntime.getInstance().deactivate(type, id);
- }
-
- @PutMapping(path = "/actors/{type}/{id}/method/{method}")
- public Mono invokeActorMethod(@PathVariable("type") String type,
- @PathVariable("id") String id,
- @PathVariable("method") String method,
- @RequestBody(required = false) byte[] body) {
- return ActorRuntime.getInstance().invoke(type, id, method, body);
- }
-
- @PutMapping(path = "/actors/{type}/{id}/method/timer/{timer}")
- public Mono invokeActorTimer(@PathVariable("type") String type,
- @PathVariable("id") String id,
- @PathVariable("timer") String timer) {
- return ActorRuntime.getInstance().invokeTimer(type, id, timer);
- }
-
- @PutMapping(path = "/actors/{type}/{id}/method/remind/{reminder}")
- public Mono invokeActorReminder(@PathVariable("type") String type,
- @PathVariable("id") String id,
- @PathVariable("reminder") String reminder,
- @RequestBody(required = false) byte[] body) {
- return ActorRuntime.getInstance().invokeReminder(type, id, reminder, body);
- }
-}
diff --git a/sdk-tests/src/test/java/io/dapr/it/binding/http/InputBindingController.java b/sdk-tests/src/test/java/io/dapr/it/binding/http/InputBindingController.java
index 1fd35f23a..2bd4bdfac 100644
--- a/sdk-tests/src/test/java/io/dapr/it/binding/http/InputBindingController.java
+++ b/sdk-tests/src/test/java/io/dapr/it/binding/http/InputBindingController.java
@@ -22,11 +22,6 @@ public class InputBindingController {
private static final List messagesReceived = new ArrayList();
- @GetMapping("/dapr/config")
- public String daprConfig() throws Exception {
- return "{}";
- }
-
@PostMapping(path = "/sample123")
@PutMapping(path = "/sample123")
public void handleInputBinding(@RequestBody(required = false) String body) {
diff --git a/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeService.java b/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeService.java
index f2dd6f6df..70817bc56 100644
--- a/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeService.java
+++ b/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeService.java
@@ -12,7 +12,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Service for subscriber.
*/
-@SpringBootApplication(scanBasePackages = {"io.dapr.it.methodinvoke.http"})
+@SpringBootApplication
public class MethodInvokeService {
public static final String SUCCESS_MESSAGE = "dapr initialized. Status: Running. Init Elapsed";
diff --git a/sdk-tests/src/test/java/io/dapr/it/pubsub/http/SubscriberController.java b/sdk-tests/src/test/java/io/dapr/it/pubsub/http/SubscriberController.java
index 507676879..16e772a5f 100644
--- a/sdk-tests/src/test/java/io/dapr/it/pubsub/http/SubscriberController.java
+++ b/sdk-tests/src/test/java/io/dapr/it/pubsub/http/SubscriberController.java
@@ -5,6 +5,7 @@
package io.dapr.it.pubsub.http;
+import io.dapr.Topic;
import io.dapr.client.domain.CloudEvent;
import io.dapr.serializer.DefaultObjectSerializer;
import org.springframework.web.bind.annotation.*;
@@ -22,21 +23,12 @@ public class SubscriberController {
private static final List messagesReceived = new ArrayList();
- /**
- * Dapr's default serializer/deserializer.
- */
- private static final DefaultObjectSerializer SERIALIZER = new DefaultObjectSerializer ();
-
- @GetMapping("/dapr/subscribe")
- public byte[] daprConfig() throws Exception {
- return SERIALIZER.serialize(new String[] { "testingtopic" });
- }
-
@GetMapping(path = "/messages")
public List getMessages() {
return messagesReceived;
}
+ @Topic(name = "testingtopic")
@PostMapping(path = "/testingtopic")
public Mono handleMessage(@RequestBody(required = false) byte[] body,
@RequestHeader Map headers) {
diff --git a/sdk-tests/src/test/java/io/dapr/it/pubsub/http/SubscriberService.java b/sdk-tests/src/test/java/io/dapr/it/pubsub/http/SubscriberService.java
index 4426ec22e..169a2028d 100644
--- a/sdk-tests/src/test/java/io/dapr/it/pubsub/http/SubscriberService.java
+++ b/sdk-tests/src/test/java/io/dapr/it/pubsub/http/SubscriberService.java
@@ -13,7 +13,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Service for subscriber.
*/
-@SpringBootApplication(scanBasePackages = {"io.dapr.it.pubsub.http"})
+@SpringBootApplication(scanBasePackages = {"io.dapr.springboot", "io.dapr.it.pubsub.http"})
public class SubscriberService {
public static final String SUCCESS_MESSAGE = "dapr initialized. Status: Running. Init Elapsed";
diff --git a/sdk-tests/src/test/java/io/dapr/it/secrets/SecretsClientIT.java b/sdk-tests/src/test/java/io/dapr/it/secrets/SecretsClientIT.java
index d3582ade9..f045a8057 100644
--- a/sdk-tests/src/test/java/io/dapr/it/secrets/SecretsClientIT.java
+++ b/sdk-tests/src/test/java/io/dapr/it/secrets/SecretsClientIT.java
@@ -7,7 +7,6 @@ package io.dapr.it.secrets;
import com.bettercloud.vault.Vault;
import com.bettercloud.vault.VaultConfig;
-import com.bettercloud.vault.response.LogicalResponse;
import io.dapr.client.DaprClient;
import io.dapr.client.DaprClientBuilder;
import io.dapr.client.DaprClientGrpc;
diff --git a/sdk/src/main/java/io/dapr/Topic.java b/sdk/src/main/java/io/dapr/Topic.java
new file mode 100644
index 000000000..167005238
--- /dev/null
+++ b/sdk/src/main/java/io/dapr/Topic.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ */
+
+package io.dapr;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Documented
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Topic {
+
+ /**
+ * Name of topic to be subscribed to.
+ *
+ * @return Topic's name.
+ */
+ String name();
+}