mirror of https://github.com/dapr/java-sdk.git
Starting package to handle SpringBoot integration. (#69)
This commit is contained in:
parent
d4c467aec5
commit
30b784cb86
|
@ -7,38 +7,29 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>io.dapr</groupId>
|
<groupId>io.dapr</groupId>
|
||||||
<artifactId>dapr-sdk-parent</artifactId>
|
<artifactId>dapr-sdk-parent</artifactId>
|
||||||
<version>0.2.0-preview01</version>
|
<version>0.2.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
<groupId>io.dapr</groupId>
|
||||||
<artifactId>dapr-sdk-examples</artifactId>
|
<artifactId>dapr-sdk-examples</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<version>0.2.0-preview01</version>
|
<version>0.2.0</version>
|
||||||
<name>dapr-sdk-examples</name>
|
<name>dapr-sdk-examples</name>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<protobuf.output.directory>${project.build.directory}/generated-sources</protobuf.output.directory>
|
<protobuf.output.directory>${project.build.directory}/generated-sources</protobuf.output.directory>
|
||||||
<protobuf.input.directory>${project.parent.basedir}/proto</protobuf.input.directory>
|
<protobuf.input.directory>${project.basedir}/proto</protobuf.input.directory>
|
||||||
<java.version>11</java.version>
|
<java.version>11</java.version>
|
||||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>io.undertow</groupId>
|
|
||||||
<artifactId>undertow-servlet</artifactId>
|
|
||||||
<version>2.0.26.Final</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-cli</groupId>
|
<groupId>commons-cli</groupId>
|
||||||
<artifactId>commons-cli</artifactId>
|
<artifactId>commons-cli</artifactId>
|
||||||
<version>1.4</version>
|
<version>1.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>commons-io</groupId>
|
|
||||||
<artifactId>commons-io</artifactId>
|
|
||||||
<version>2.6</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.json</groupId>
|
<groupId>org.json</groupId>
|
||||||
<artifactId>json</artifactId>
|
<artifactId>json</artifactId>
|
||||||
|
@ -47,18 +38,27 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.grpc</groupId>
|
<groupId>io.grpc</groupId>
|
||||||
<artifactId>grpc-protobuf</artifactId>
|
<artifactId>grpc-protobuf</artifactId>
|
||||||
|
<version>${grpc.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.grpc</groupId>
|
<groupId>io.grpc</groupId>
|
||||||
<artifactId>grpc-stub</artifactId>
|
<artifactId>grpc-stub</artifactId>
|
||||||
|
<version>${grpc.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.grpc</groupId>
|
||||||
|
<artifactId>grpc-api</artifactId>
|
||||||
|
<version>${grpc.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.annotation</groupId>
|
<groupId>javax.annotation</groupId>
|
||||||
<artifactId>javax.annotation-api</artifactId>
|
<artifactId>javax.annotation-api</artifactId>
|
||||||
|
<version>1.3.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.grpc</groupId>
|
<groupId>io.grpc</groupId>
|
||||||
<artifactId>grpc-testing</artifactId>
|
<artifactId>grpc-testing</artifactId>
|
||||||
|
<version>${grpc.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -71,10 +71,25 @@
|
||||||
<artifactId>protoc-jar-maven-plugin</artifactId>
|
<artifactId>protoc-jar-maven-plugin</artifactId>
|
||||||
<version>3.10.1</version>
|
<version>3.10.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
<version>2.2.2.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||||
|
<version>2.2.2.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.dapr</groupId>
|
||||||
|
<artifactId>dapr-sdk-springboot</artifactId>
|
||||||
|
<version>0.2.0</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.dapr</groupId>
|
<groupId>io.dapr</groupId>
|
||||||
<artifactId>dapr-sdk</artifactId>
|
<artifactId>dapr-sdk</artifactId>
|
||||||
<version>0.2.0-preview01</version>
|
<version>0.2.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
@ -96,7 +111,7 @@
|
||||||
<includeMavenTypes>direct</includeMavenTypes>
|
<includeMavenTypes>direct</includeMavenTypes>
|
||||||
<includeStdTypes>true</includeStdTypes>
|
<includeStdTypes>true</includeStdTypes>
|
||||||
<inputDirectories>
|
<inputDirectories>
|
||||||
<include>${protobuf.input.directory}/examples</include>
|
<include>${protobuf.input.directory}</include>
|
||||||
</inputDirectories>
|
</inputDirectories>
|
||||||
<outputTargets>
|
<outputTargets>
|
||||||
<outputTarget>
|
<outputTarget>
|
||||||
|
|
|
@ -5,29 +5,14 @@
|
||||||
|
|
||||||
package io.dapr.examples.actors.http;
|
package io.dapr.examples.actors.http;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonFactory;
|
|
||||||
import com.fasterxml.jackson.core.JsonGenerator;
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import io.dapr.actors.runtime.ActorRuntime;
|
import io.dapr.actors.runtime.ActorRuntime;
|
||||||
import io.undertow.Undertow;
|
import io.dapr.springboot.DaprApplication;
|
||||||
import io.undertow.server.HttpHandler;
|
|
||||||
import io.undertow.server.HttpServerExchange;
|
|
||||||
import io.undertow.server.RoutingHandler;
|
|
||||||
import io.undertow.util.Headers;
|
|
||||||
import org.apache.commons.cli.CommandLine;
|
import org.apache.commons.cli.CommandLine;
|
||||||
import org.apache.commons.cli.CommandLineParser;
|
import org.apache.commons.cli.CommandLineParser;
|
||||||
import org.apache.commons.cli.DefaultParser;
|
import org.apache.commons.cli.DefaultParser;
|
||||||
import org.apache.commons.cli.Options;
|
import org.apache.commons.cli.Options;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.io.Writer;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Deque;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service for Actor runtime.
|
* Service for Actor runtime.
|
||||||
|
@ -36,193 +21,26 @@ import java.util.Map;
|
||||||
* 2. Run the server:
|
* 2. Run the server:
|
||||||
* dapr run --app-id demoactorservice --app-port 3000 --port 3005 -- mvn exec:java -pl=examples -Dexec.mainClass=io.dapr.examples.actors.http.DemoActorService -Dexec.args="-p 3000"
|
* dapr run --app-id demoactorservice --app-port 3000 --port 3005 -- mvn exec:java -pl=examples -Dexec.mainClass=io.dapr.examples.actors.http.DemoActorService -Dexec.args="-p 3000"
|
||||||
*/
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
public class DemoActorService {
|
public class DemoActorService {
|
||||||
|
|
||||||
private static final JsonFactory JSON_FACTORY = new JsonFactory();
|
|
||||||
|
|
||||||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
|
||||||
|
|
||||||
private static final HttpHandler ROUTES = new RoutingHandler()
|
|
||||||
.get("/", DemoActorService::handleDaprConfig)
|
|
||||||
.get("/dapr/config", DemoActorService::handleDaprConfig)
|
|
||||||
.post("/actors/{actorType}/{id}", DemoActorService::handleActorActivate)
|
|
||||||
.delete("/actors/{actorType}/{id}", DemoActorService::handleActorDeactivate)
|
|
||||||
.put("/actors/{actorType}/{id}/method/{methodName}", DemoActorService::handleActorInvoke)
|
|
||||||
.put("/actors/{actorType}/{id}/method/timer/{timerName}", DemoActorService::handleActorTimer)
|
|
||||||
.put("/actors/{actorType}/{id}/method/remind/{reminderName}", DemoActorService::handleActorReminder);
|
|
||||||
|
|
||||||
private final int port;
|
|
||||||
|
|
||||||
private final Undertow server;
|
|
||||||
|
|
||||||
private DemoActorService(int port) {
|
|
||||||
this.port = port;
|
|
||||||
this.server = Undertow
|
|
||||||
.builder()
|
|
||||||
.addHttpListener(port, "localhost")
|
|
||||||
.setHandler(ROUTES)
|
|
||||||
.build();
|
|
||||||
ActorRuntime.getInstance().registerActor(DemoActorImpl.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void start() {
|
|
||||||
// Now we handle ctrl+c (or any other JVM shutdown)
|
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
System.out.println("Server: shutting down gracefully ...");
|
|
||||||
DemoActorService.this.server.stop();
|
|
||||||
System.out.println("Server: Bye.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
System.out.println(String.format("Server: listening on port %d ...", this.port));
|
|
||||||
this.server.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void handleDaprConfig(HttpServerExchange exchange) throws IOException {
|
|
||||||
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/json");
|
|
||||||
String result = "";
|
|
||||||
try (Writer writer = new StringWriter()) {
|
|
||||||
JsonGenerator generator = JSON_FACTORY.createGenerator(writer);
|
|
||||||
generator.writeStartObject();
|
|
||||||
generator.writeArrayFieldStart("entities");
|
|
||||||
for(String actorClass : ActorRuntime.getInstance().getRegisteredActorTypes()) {
|
|
||||||
generator.writeString(actorClass);
|
|
||||||
}
|
|
||||||
generator.writeEndArray();
|
|
||||||
generator.writeStringField("actorIdleTimeout", "10s");
|
|
||||||
generator.writeStringField("actorScanInterval", "1s");
|
|
||||||
generator.writeStringField("drainOngoingCallTimeout", "1s");
|
|
||||||
generator.writeBooleanField("drainBalancedActors", true);
|
|
||||||
generator.writeEndObject();
|
|
||||||
generator.close();
|
|
||||||
writer.flush();
|
|
||||||
result = writer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
exchange.getResponseSender().send(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void handleActorActivate(HttpServerExchange exchange) {
|
|
||||||
if (exchange.isInIoThread()) {
|
|
||||||
exchange.dispatch(DemoActorService::handleActorActivate);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String actorType = findParamValueOrNull(exchange, "actorType");
|
|
||||||
String actorId = findParamValueOrNull(exchange, "id");
|
|
||||||
ActorRuntime.getInstance().activate(actorType, actorId).block();
|
|
||||||
exchange.getResponseSender().send("");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void handleActorDeactivate(HttpServerExchange exchange) {
|
|
||||||
if (exchange.isInIoThread()) {
|
|
||||||
exchange.dispatch(DemoActorService::handleActorDeactivate);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String actorType = findParamValueOrNull(exchange, "actorType");
|
|
||||||
String actorId = findParamValueOrNull(exchange, "id");
|
|
||||||
ActorRuntime.getInstance().deactivate(actorType, actorId).block();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void handleActorInvoke(HttpServerExchange exchange) throws IOException {
|
|
||||||
if (exchange.isInIoThread()) {
|
|
||||||
exchange.dispatch(DemoActorService::handleActorInvoke);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String actorType = findParamValueOrNull(exchange, "actorType");
|
|
||||||
String actorId = findParamValueOrNull(exchange, "id");
|
|
||||||
String methodName = findParamValueOrNull(exchange, "methodName");
|
|
||||||
exchange.startBlocking();
|
|
||||||
String data = findMethodData(exchange.getInputStream());
|
|
||||||
String result = ActorRuntime.getInstance().invoke(actorType, actorId, methodName, data).block();
|
|
||||||
exchange.getResponseSender().send(buildResponse(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void handleActorTimer(HttpServerExchange exchange) throws IOException {
|
|
||||||
if (exchange.isInIoThread()) {
|
|
||||||
exchange.dispatch(DemoActorService::handleActorTimer);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String actorType = findParamValueOrNull(exchange, "actorType");
|
|
||||||
String actorId = findParamValueOrNull(exchange, "id");
|
|
||||||
String timerName = findParamValueOrNull(exchange, "timerName");
|
|
||||||
ActorRuntime.getInstance().invokeTimer(actorType, actorId, timerName).block();
|
|
||||||
exchange.getResponseSender().send("");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void handleActorReminder(HttpServerExchange exchange) throws IOException {
|
|
||||||
if (exchange.isInIoThread()) {
|
|
||||||
exchange.dispatch(DemoActorService::handleActorReminder);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String actorType = findParamValueOrNull(exchange, "actorType");
|
|
||||||
String actorId = findParamValueOrNull(exchange, "id");
|
|
||||||
String reminderName = findParamValueOrNull(exchange, "reminderName");
|
|
||||||
exchange.startBlocking();
|
|
||||||
String params = IOUtils.toString(exchange.getInputStream(), StandardCharsets.UTF_8);
|
|
||||||
ActorRuntime.getInstance().invokeReminder(actorType, actorId, reminderName, params).block();
|
|
||||||
exchange.getResponseSender().send("");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String findParamValueOrNull(HttpServerExchange exchange, String name) {
|
|
||||||
Map<String, Deque<String>> params = exchange.getQueryParameters();
|
|
||||||
if (params == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Deque<String> values = params.get(name);
|
|
||||||
if ((values == null) || (values.isEmpty())) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return values.getFirst();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String findMethodData(InputStream stream) throws IOException {
|
|
||||||
JsonNode root = OBJECT_MAPPER.readTree(stream);
|
|
||||||
if (root == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonNode dataNode = root.get("data");
|
|
||||||
if (dataNode == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new String(dataNode.binaryValue(), StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String buildResponse(String data) throws IOException {
|
|
||||||
try (Writer writer = new StringWriter()) {
|
|
||||||
JsonGenerator generator = JSON_FACTORY.createGenerator(writer);
|
|
||||||
generator.writeStartObject();
|
|
||||||
if (data != null) {
|
|
||||||
generator.writeBinaryField("data", data.getBytes());
|
|
||||||
}
|
|
||||||
generator.writeEndObject();
|
|
||||||
generator.close();
|
|
||||||
writer.flush();
|
|
||||||
return writer.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
Options options = new Options();
|
Options options = new Options();
|
||||||
options.addRequiredOption("p", "port", true, "Port to listen to.");
|
options.addRequiredOption("p", "port", true, "Port Dapr will listen to.");
|
||||||
|
|
||||||
CommandLineParser parser = new DefaultParser();
|
CommandLineParser parser = new DefaultParser();
|
||||||
CommandLine cmd = parser.parse(options, args);
|
CommandLine cmd = parser.parse(options, args);
|
||||||
|
|
||||||
// If port string is not valid, it will throw an exception.
|
// If port string is not valid, it will throw an exception.
|
||||||
int port = Integer.parseInt(cmd.getOptionValue("port"));
|
int port = Integer.parseInt(cmd.getOptionValue("port"));
|
||||||
final DemoActorService service = new DemoActorService(port);
|
|
||||||
service.start();
|
// Register the Actor class.
|
||||||
|
ActorRuntime.getInstance().registerActor(DemoActorImpl.class);
|
||||||
|
|
||||||
|
// Start Dapr's callback endpoint.
|
||||||
|
DaprApplication.start(port);
|
||||||
|
|
||||||
|
// Start application's endpoint.
|
||||||
|
SpringApplication.run(DemoActorService.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
* Licensed under the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.dapr.examples.actors.http;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class HelloController {
|
||||||
|
|
||||||
|
@RequestMapping("/")
|
||||||
|
public String index() {
|
||||||
|
return "Greetings from your Spring Boot Application!";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
8
pom.xml
8
pom.xml
|
@ -7,7 +7,7 @@
|
||||||
<groupId>io.dapr</groupId>
|
<groupId>io.dapr</groupId>
|
||||||
<artifactId>dapr-sdk-parent</artifactId>
|
<artifactId>dapr-sdk-parent</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<version>0.2.0-preview01</version>
|
<version>0.2.0</version>
|
||||||
<name>dapr-sdk-parent</name>
|
<name>dapr-sdk-parent</name>
|
||||||
<description>SDK for Dapr.</description>
|
<description>SDK for Dapr.</description>
|
||||||
<url>https://dapr.io</url>
|
<url>https://dapr.io</url>
|
||||||
|
@ -33,6 +33,11 @@
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.grpc</groupId>
|
||||||
|
<artifactId>grpc-api</artifactId>
|
||||||
|
<version>${grpc.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.annotation</groupId>
|
<groupId>javax.annotation</groupId>
|
||||||
<artifactId>javax.annotation-api</artifactId>
|
<artifactId>javax.annotation-api</artifactId>
|
||||||
|
@ -79,6 +84,7 @@
|
||||||
<modules>
|
<modules>
|
||||||
<module>sdk-autogen</module>
|
<module>sdk-autogen</module>
|
||||||
<module>sdk</module>
|
<module>sdk</module>
|
||||||
|
<module>sdk-springboot</module>
|
||||||
<module>examples</module>
|
<module>examples</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,12 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>io.dapr</groupId>
|
<groupId>io.dapr</groupId>
|
||||||
<artifactId>dapr-sdk-parent</artifactId>
|
<artifactId>dapr-sdk-parent</artifactId>
|
||||||
<version>0.2.0-preview01</version>
|
<version>0.2.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>dapr-sdk-autogen</artifactId>
|
<artifactId>dapr-sdk-autogen</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<version>0.2.0-preview01</version>
|
<version>0.2.0</version>
|
||||||
<name>dapr-sdk-autogen</name>
|
<name>dapr-sdk-autogen</name>
|
||||||
<description>Auto-generated SDK for Dapr</description>
|
<description>Auto-generated SDK for Dapr</description>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
<project
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>io.dapr</groupId>
|
||||||
|
<artifactId>dapr-sdk-parent</artifactId>
|
||||||
|
<version>0.2.0</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>io.dapr</groupId>
|
||||||
|
<artifactId>dapr-sdk-springboot</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<version>0.2.0</version>
|
||||||
|
<name>dapr-sdk-springboot</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>8</java.version>
|
||||||
|
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||||
|
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.annotation</groupId>
|
||||||
|
<artifactId>javax.annotation-api</artifactId>
|
||||||
|
<version>1.3.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot</artifactId>
|
||||||
|
<version>2.2.2.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
<version>2.2.2.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.dapr</groupId>
|
||||||
|
<artifactId>dapr-sdk</artifactId>
|
||||||
|
<version>0.2.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<configuration>
|
||||||
|
<release>8</release>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
* Licensed under the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.dapr.springboot;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dapr's callback implementation via SpringBoot.
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
public class DaprApplication {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts Dapr's callback in a given port.
|
||||||
|
* @param port Port to listen to.
|
||||||
|
*/
|
||||||
|
public static void start(int port) {
|
||||||
|
SpringApplication app = new SpringApplication(DaprApplication.class);
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.setProperty("server.port", Integer.toString(port));
|
||||||
|
app.setDefaultProperties(properties);
|
||||||
|
app.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main for SpringBoot requirements.
|
||||||
|
* @param args Command line arguments.
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(DaprApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
* Licensed under the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.dapr.springboot;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonFactory;
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import io.dapr.actors.runtime.ActorRuntime;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SpringBoot Controller to handle callback APIs for Dapr.
|
||||||
|
* TODO: use POJOs instead of String when possible.
|
||||||
|
* TODO: JavaDocs.
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
public class DaprController {
|
||||||
|
|
||||||
|
private static final JsonFactory JSON_FACTORY = new JsonFactory();
|
||||||
|
|
||||||
|
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||||
|
|
||||||
|
@RequestMapping("/")
|
||||||
|
public String index() {
|
||||||
|
return "Greetings from Dapr!";
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/dapr/config")
|
||||||
|
public String daprConfig() throws Exception {
|
||||||
|
try (Writer writer = new StringWriter()) {
|
||||||
|
JsonGenerator generator = JSON_FACTORY.createGenerator(writer);
|
||||||
|
generator.writeStartObject();
|
||||||
|
generator.writeArrayFieldStart("entities");
|
||||||
|
for (String actorClass : ActorRuntime.getInstance().getRegisteredActorTypes()) {
|
||||||
|
generator.writeString(actorClass);
|
||||||
|
}
|
||||||
|
generator.writeEndArray();
|
||||||
|
generator.writeStringField("actorIdleTimeout", "10s");
|
||||||
|
generator.writeStringField("actorScanInterval", "1s");
|
||||||
|
generator.writeStringField("drainOngoingCallTimeout", "1s");
|
||||||
|
generator.writeBooleanField("drainBalancedActors", true);
|
||||||
|
generator.writeEndObject();
|
||||||
|
generator.close();
|
||||||
|
writer.flush();
|
||||||
|
return writer.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.POST, path = "/actors/{type}/{id}")
|
||||||
|
public Mono<Void> activateActor(@PathVariable("type") String type,
|
||||||
|
@PathVariable("id") String id) throws Exception {
|
||||||
|
return ActorRuntime.getInstance().activate(type, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.DELETE, path = "/actors/{type}/{id}")
|
||||||
|
public Mono<Void> deactivateActor(@PathVariable("type") String type,
|
||||||
|
@PathVariable("id") String id) throws Exception {
|
||||||
|
return ActorRuntime.getInstance().deactivate(type, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.PUT, path = "/actors/{type}/{id}/method/{method}")
|
||||||
|
public Mono<String> invokeActorMethod(@PathVariable("type") String type,
|
||||||
|
@PathVariable("id") String id,
|
||||||
|
@PathVariable("method") String method,
|
||||||
|
@RequestBody(required = false) String body) {
|
||||||
|
try {
|
||||||
|
String data = findMethodData(body);
|
||||||
|
return ActorRuntime.getInstance().invoke(type, id, method, data).map(r -> buildResponse(r));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Mono.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.PUT, path = "/actors/{type}/{id}/method/timer/{timer}")
|
||||||
|
public Mono<Void> invokeActorTimer(@PathVariable("type") String type,
|
||||||
|
@PathVariable("id") String id,
|
||||||
|
@PathVariable("timer") String timer) {
|
||||||
|
return ActorRuntime.getInstance().invokeTimer(type, id, timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.PUT, path = "/actors/{type}/{id}/method/remind/{reminder}")
|
||||||
|
public Mono<Void> invokeActorReminder(@PathVariable("type") String type,
|
||||||
|
@PathVariable("id") String id,
|
||||||
|
@PathVariable("reminder") String reminder,
|
||||||
|
@RequestBody(required = false) String body) {
|
||||||
|
return ActorRuntime.getInstance().invokeReminder(type, id, reminder, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String findMethodData(String body) throws IOException {
|
||||||
|
if (body == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonNode root = OBJECT_MAPPER.readTree(body);
|
||||||
|
if (root == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonNode dataNode = root.get("data");
|
||||||
|
if (dataNode == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new String(dataNode.binaryValue(), StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String buildResponse(String data) throws RuntimeException {
|
||||||
|
try {
|
||||||
|
try (Writer writer = new StringWriter()) {
|
||||||
|
JsonGenerator generator = JSON_FACTORY.createGenerator(writer);
|
||||||
|
generator.writeStartObject();
|
||||||
|
if (data != null) {
|
||||||
|
generator.writeBinaryField("data", data.getBytes());
|
||||||
|
}
|
||||||
|
generator.writeEndObject();
|
||||||
|
generator.close();
|
||||||
|
writer.flush();
|
||||||
|
return writer.toString();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Make Mono happy.
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,12 +7,12 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>io.dapr</groupId>
|
<groupId>io.dapr</groupId>
|
||||||
<artifactId>dapr-sdk-parent</artifactId>
|
<artifactId>dapr-sdk-parent</artifactId>
|
||||||
<version>0.2.0-preview01</version>
|
<version>0.2.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>dapr-sdk</artifactId>
|
<artifactId>dapr-sdk</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<version>0.2.0-preview01</version>
|
<version>0.2.0</version>
|
||||||
<name>dapr-sdk</name>
|
<name>dapr-sdk</name>
|
||||||
<description>SDK for Dapr</description>
|
<description>SDK for Dapr</description>
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.dapr</groupId>
|
<groupId>io.dapr</groupId>
|
||||||
<artifactId>dapr-sdk-autogen</artifactId>
|
<artifactId>dapr-sdk-autogen</artifactId>
|
||||||
<version>0.2.0-preview01</version>
|
<version>0.2.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
|
Loading…
Reference in New Issue