Merge branch 'master' into release-1.0

This commit is contained in:
Artur Souza 2021-01-27 15:58:15 -08:00
commit a42120f7f1
151 changed files with 4736 additions and 2664 deletions

View File

@ -22,11 +22,11 @@ jobs:
GOARCH: amd64
GOPROXY: https://proxy.golang.org
JDK_VER: 13.0.x
DAPR_CLI_VER: 1.0.0-rc.2
DAPR_RUNTIME_VER: 1.0.0-rc.1
DAPR_CLI_VER: 1.0.0-rc.3
DAPR_RUNTIME_VER: 1.0.0-rc.2
DAPR_INSTALL_URL: https://raw.githubusercontent.com/dapr/cli/3dacfb672d55f1436c249057aaebbe597e1066f3/install/install.sh
DAPR_CLI_REF: 3dacfb672d55f1436c249057aaebbe597e1066f3
DAPR_REF: 3cca3cc1567f1cb955ae69b8fd784f075f62ad42
DAPR_CLI_REF:
DAPR_REF: 5a15b3e0f093d2d0938b12f144c7047474a290fe
OSSRH_USER_TOKEN: ${{ secrets.OSSRH_USER_TOKEN }}
OSSRH_PWD_TOKEN: ${{ secrets.OSSRH_PWD_TOKEN }}
GPG_KEY: ${{ secrets.GPG_KEY }}
@ -91,8 +91,6 @@ jobs:
run: |
docker-compose -f ./sdk-tests/deploy/local-test-vault.yml up -d
docker ps
- name: Setup Vault's test token
run: echo myroot > /tmp/.hashicorp_vault_token
- name: Clean up files
run: mvn clean
- name: Build sdk

View File

@ -4,6 +4,7 @@ metadata:
name: statestore
spec:
type: state.redis
version: 1
metadata:
- name: redisHost
value: localhost:6379

View File

@ -4,6 +4,7 @@ metadata:
name: sample123
spec:
type: bindings.kafka
version: 1
metadata:
# Kafka broker connection setting
- name: brokers

View File

@ -4,6 +4,7 @@ metadata:
name: messagebus
spec:
type: pubsub.redis
version: 1
metadata:
- name: redisHost
value: localhost:6379

View File

@ -4,6 +4,7 @@ metadata:
name: vault
spec:
type: secretstores.hashicorp.vault
version: 1
metadata:
- name: vaultAddr
value: "http://127.0.0.1:8200"

View File

@ -4,6 +4,7 @@ metadata:
name: statestore
spec:
type: state.redis
version: 1
metadata:
- name: redisHost
value: localhost:6379

View File

@ -173,7 +173,7 @@
<goal>repackage</goal>
</goals>
<configuration>
<mainClass>io.dapr.springboot.DaprMainApplication</mainClass>
<mainClass>io.dapr.examples.DaprMainApplication</mainClass>
<classifier>exec</classifier>
<finalName>dapr-java-sdk-examples</finalName>
</configuration>

View File

@ -3,16 +3,15 @@
* Licensed under the MIT License.
*/
package io.dapr.springboot;
package io.dapr.examples;
import org.springframework.boot.SpringApplication;
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"})
@SpringBootApplication
public class DaprApplication {
/**

View File

@ -0,0 +1,22 @@
/*
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License.
*/
package io.dapr.examples;
import io.dapr.client.DaprClient;
import io.dapr.client.DaprClientBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DaprConfig {
private static final DaprClientBuilder BUILDER = new DaprClientBuilder();
@Bean
public DaprClient buildDaprClient() {
return BUILDER.build();
}
}

View File

@ -3,7 +3,7 @@
* Licensed under the MIT License.
*/
package io.dapr.springboot;
package io.dapr.examples;
import java.lang.reflect.Method;
import java.util.Arrays;

View File

@ -3,14 +3,13 @@
* Licensed under the MIT License.
*/
package io.dapr.springboot;
package io.dapr.examples;
import io.dapr.examples.invoke.http.InvokeClient;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.propagation.HttpTraceContext;
import io.opentelemetry.context.propagation.DefaultContextPropagators;
import io.opentelemetry.exporter.logging.LoggingSpanExporter;
import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
@ -64,10 +63,6 @@ public class OpenTelemetryConfig {
System.out.println("WARNING: Zipkin is not available.");
}
final LoggingSpanExporter loggingExporter = new LoggingSpanExporter();
OpenTelemetrySdk.getGlobalTracerManagement()
.addSpanProcessor(SimpleSpanProcessor.builder(loggingExporter).build());
return tracer;
}

View File

@ -3,15 +3,12 @@
* Licensed under the MIT License.
*/
package io.dapr.springboot;
package io.dapr.examples;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.TextMapPropagator;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@ -36,8 +33,6 @@ public class OpenTelemetryInterceptor implements HandlerInterceptor {
return carrier.getHeader(key);
}
};
@Autowired
Tracer tracer;
@Override
public boolean preHandle(
@ -49,43 +44,15 @@ public class OpenTelemetryInterceptor implements HandlerInterceptor {
return true;
}
Span span;
try {
Context context = textFormat.extract(Context.current(), request, HTTP_SERVLET_REQUEST_GETTER);
request.setAttribute("opentelemetry-context", context);
span = tracer.spanBuilder(request.getRequestURI()).setParent(context).startSpan();
span.setAttribute("handler", "pre");
} catch (Exception e) {
span = tracer.spanBuilder(request.getRequestURI()).startSpan();
span.setAttribute("handler", "pre");
span.addEvent(e.toString());
span.setAttribute("error", true);
}
request.setAttribute("opentelemetry-span", span);
Context context = textFormat.extract(Context.current(), request, HTTP_SERVLET_REQUEST_GETTER);
request.setAttribute("opentelemetry-context", context);
return true;
}
@Override
public void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception exception) {
Object contextObject = request.getAttribute("opentelemetry-context");
Object spanObject = request.getAttribute("opentelemetry-span");
if ((contextObject == null) || (spanObject == null)) {
return;
}
Context context = (Context) contextObject;
Span span = (Span) spanObject;
span.setAttribute("handler", "afterCompletion");
final TextMapPropagator textFormat = OpenTelemetry.getGlobalPropagators().getTextMapPropagator();
textFormat.inject(context, response, HttpServletResponse::addHeader);
span.end();
ModelAndView modelAndView) {
}
}

View File

@ -3,7 +3,7 @@
* Licensed under the MIT License.
*/
package io.dapr.springboot;
package io.dapr.examples;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

View File

@ -17,6 +17,7 @@ public interface DemoActor {
void registerReminder();
@ActorMethod(name = "echo_message")
String say(String something);
void clock(String message);

View File

@ -6,6 +6,7 @@
package io.dapr.examples.actors;
import io.dapr.actors.ActorId;
import io.dapr.actors.client.ActorClient;
import io.dapr.actors.client.ActorProxyBuilder;
import java.util.ArrayList;
@ -30,7 +31,8 @@ public class DemoActorClient {
* @throws InterruptedException If program has been interrupted.
*/
public static void main(String[] args) throws InterruptedException {
try (ActorProxyBuilder<DemoActor> builder = new ActorProxyBuilder(DemoActor.class)) {
try (ActorClient client = new ActorClient()) {
ActorProxyBuilder<DemoActor> builder = new ActorProxyBuilder(DemoActor.class, client);
List<Thread> threads = new ArrayList<>(NUM_ACTORS);
// Creates multiple actors.

View File

@ -6,7 +6,7 @@
package io.dapr.examples.actors;
import io.dapr.actors.runtime.ActorRuntime;
import io.dapr.springboot.DaprApplication;
import io.dapr.examples.DaprApplication;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;

View File

@ -105,6 +105,8 @@ public class DemoActorImpl extends AbstractActor implements DemoActor, Remindabl
An actor inherits from `AbstractActor` and implements the constructor to pass through `ActorRuntimeContext` and `ActorId`. By default, the actor's name will be the same as the class' name. Optionally, it can be annotated with `ActorType` and override the actor's name. The actor's methods can be synchronously or use [Project Reactor's Mono](https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html) return type. Finally, state management is done via methods in `super.getActorStateManager()`. The `DemoActor` interface is used by the Actor runtime and also client. See how `DemoActor` interface can be annotated as Dapr Actor.
```java
import io.dapr.actors.ActorMethod;
/**
* Example of implementation of an Actor.
*/
@ -113,6 +115,7 @@ public interface DemoActor {
void registerReminder();
@ActorMethod(name = "echo_message")
String say(String something);
void clock(String message);
@ -123,7 +126,10 @@ public interface DemoActor {
```
The `@ActorType` annotation indicates the Dapr Java SDK that this interface is an Actor Type, allowing a name for the type to be defined. Some methods can return a `Mono` object. In these cases, the `@ActorMethod` annotation is used to hint the Dapr Java SDK of the type encapsulated in the `Mono` object. You can read more about Java generic type erasure [here](https://docs.oracle.com/javase/tutorial/java/generics/erasure.html).
The `@ActorType` annotation indicates the Dapr Java SDK that this interface is an Actor Type, allowing a name for the type to be defined.
The `@ActorMethod` annotation can be applied to an interface method to specify configuration for that method. In this example, the `say` method, is renamed to `echo_message` - this can be used when invoking an actor method implemented in a different programming language (like C# or Python) and the method name does not match Java's naming conventions.
Some methods can return a `Mono` object. In these cases, the `@ActorMethod` annotation is used to hint the Dapr Java SDK of the type encapsulated in the `Mono` object. You can read more about Java generic type erasure [here](https://docs.oracle.com/javase/tutorial/java/generics/erasure.html).
Now, execute the following script in order to run DemoActorService:
@ -143,7 +149,8 @@ public class DemoActorClient {
private static final int NUM_ACTORS = 3;
public static void main(String[] args) throws InterruptedException {
try (ActorProxyBuilder<DemoActor> builder = new ActorProxyBuilder(DemoActor.class)) {
try (ActorClient client = new ActorClient()) {
ActorProxyBuilder<DemoActor> builder = new ActorProxyBuilder(DemoActor.class, client);
///...
for (int i = 0; i < NUM_ACTORS; i++) {
DemoActor actor = builder.build(ActorId.createRandom());
@ -183,7 +190,7 @@ public class DemoActorClient {
}
```
First, the client defines how many actors it is going to create. The main method declares a `ActorProxyBuilder` to create instances of the `DemoActor` interface, which are implemented automatically by the SDK and make remote calls to the equivalent methods in Actor runtime. `ActorProxyBuilder` implements `Closeable`, which means it holds resources that need to be closed. In this example, we use the "try-resource" feature in Java.
First, the client defines how many actors it is going to create. The main method declares a `ActorClient` and `ActorProxyBuilder` to create instances of the `DemoActor` interface, which are implemented automatically by the SDK and make remote calls to the equivalent methods in Actor runtime. `ActorClient` is reusable for different actor types and should be instantiated only once in your code. `ActorClient` also implements `AutoCloseable`, which means it holds resources that need to be closed. In this example, we use the "try-resource" feature in Java.
Then, the code executes the `callActorForever` private method once per actor. Initially, it will invoke `registerReminder()`, which sets the due time and period for the reminder. Then, `incrementAndGet()` increments a counter, persists it and sends it back as response. Finally `say` method which will print a message containing the received string along with the formatted server time.

View File

@ -5,7 +5,7 @@
package io.dapr.examples.bindings.http;
import io.dapr.springboot.DaprApplication;
import io.dapr.examples.DaprApplication;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;

View File

@ -170,4 +170,4 @@ For bringing down the kafka cluster that was started in the beginning, run
docker-compose -f ./src/main/java/io/dapr/examples/bindings/http/docker-compose-single-kafka.yml down
```
For more details on Dapr Spring Boot integration, please refer to [Dapr Spring Boot](../../../springboot/DaprApplication.java) Application implementation.
For more details on Dapr Spring Boot integration, please refer to [Dapr Spring Boot](../../DaprApplication.java) Application implementation.

View File

@ -53,7 +53,7 @@ public class Client {
}
```
The code uses the `DaprClient` created by the `DaprClientBuilder`. It tries to get a state from state store but provides an unknown state store. It causes Dapr sidecar to return error, which is converted to a `DaprException` to the application. To be compatible with Project Reactor, `DaprException` extends from `RuntimeException` - making it an unchecked exception.
The code uses the `DaprClient` created by the `DaprClientBuilder`. It tries to get a state from state store but provides an unknown state store. It causes Dapr sidecar to return error, which is converted to a `DaprException` to the application. To be compatible with Project Reactor, `DaprException` extends from `RuntimeException` - making it an unchecked exception. Applications might also get `IllegalArgumentException` when invoking methods with invalid input parameters that are validated at the client side.
The Dapr client is also within a try-with-resource block to properly close the client at the end.

View File

@ -33,7 +33,7 @@ public class HelloWorldClient {
while (true) {
String message = "Message #" + (count++);
System.out.println("Sending message: " + message);
client.invokeService(serviceAppId, method, message, HttpExtension.NONE).block();
client.invokeMethod(serviceAppId, method, message, HttpExtension.NONE).block();
System.out.println("Message sent: " + message);
Thread.sleep(1000);

View File

@ -8,7 +8,6 @@ package io.dapr.examples.invoke.grpc;
import com.google.protobuf.Any;
import io.dapr.v1.AppCallbackGrpc;
import io.dapr.v1.CommonProtos;
import io.dapr.v1.DaprAppCallbackProtos;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;

View File

@ -96,7 +96,7 @@ private static class HelloWorldClient {
while (true) {
String message = "Message #" + (count++);
System.out.println("Sending message: " + message);
client.invokeService(serviceAppId, method, message, HttpExtension.NONE).block();
client.invokeMethod(serviceAppId, method, message, HttpExtension.NONE).block();
System.out.println("Message sent: " + message);
Thread.sleep(1000);
@ -113,7 +113,7 @@ private static class HelloWorldClient {
First, it creates an instance of `DaprClient` via `DaprClientBuilder`. The protocol used by DaprClient is transparent to the application. The HTTP and GRPC ports used by Dapr's sidecar are automatically chosen and exported as environment variables: `DAPR_HTTP_PORT` and `DAPR_GRPC_PORT`. Dapr's Java SDK references these environment variables when communicating to Dapr's sidecar. The Dapr client is also within a try-with-resource block to properly close the client at the end.
Finally, it will go through in an infinite loop and invoke the `say` method every second. Notice the use of `block()` on the return from `invokeService` - it is required to actually make the service invocation via a [Mono](https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html) object.
Finally, it will go through in an infinite loop and invoke the `say` method every second. Notice the use of `block()` on the return from `invokeMethod` - it is required to actually make the service invocation via a [Mono](https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html) object.
Finally, open a new command line terminal and run the client code to send some messages.

View File

@ -5,7 +5,7 @@
package io.dapr.examples.invoke.http;
import io.dapr.springboot.DaprApplication;
import io.dapr.examples.DaprApplication;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;

View File

@ -32,7 +32,7 @@ public class InvokeClient {
public static void main(String[] args) throws Exception {
try (DaprClient client = (new DaprClientBuilder()).build()) {
for (String message : args) {
byte[] response = client.invokeService(SERVICE_APP_ID, "say", message, HttpExtension.POST, null,
byte[] response = client.invokeMethod(SERVICE_APP_ID, "say", message, HttpExtension.POST, null,
byte[].class).block();
System.out.println(new String(response));
}

View File

@ -113,7 +113,7 @@ private static final String SERVICE_APP_ID = "invokedemo";
public static void main(String[] args) throws Exception {
try (DaprClient client = (new DaprClientBuilder()).build()) {
for (String message : args) {
byte[] response = client.invokeService(SERVICE_APP_ID, "say", message, HttpExtension.POST, null,
byte[] response = client.invokeMethod(SERVICE_APP_ID, "say", message, HttpExtension.POST, null,
byte[].class).block();
System.out.println(new String(response));
}
@ -127,7 +127,7 @@ public static void main(String[] args) throws Exception {
}
```
The class knows the app id for the remote application. It uses the the static `Dapr.getInstance().invokeService` method to invoke the remote method defining the parameters: The verb, application id, method name, and proper data and metadata, as well as the type of the expected return type. The returned payload for this method invocation is plain text and not a [JSON String](https://www.w3schools.com/js/js_json_datatypes.asp), so we expect `byte[]` to get the raw response and not try to deserialize it.
The class knows the app id for the remote application. It uses the the static `Dapr.getInstance().invokeMethod` method to invoke the remote method defining the parameters: The verb, application id, method name, and proper data and metadata, as well as the type of the expected return type. The returned payload for this method invocation is plain text and not a [JSON String](https://www.w3schools.com/js/js_json_datatypes.asp), so we expect `byte[]` to get the raw response and not try to deserialize it.
Execute the follow script in order to run the InvokeClient example, passing two messages for the remote method:
```sh
@ -139,4 +139,4 @@ Once running, the output should display the messages sent from invoker in the de
Method have been remotely invoked and displaying the remote messages.
For more details on Dapr Spring Boot integration, please refer to [Dapr Spring Boot](../../../springboot/DaprApplication.java) Application implementation.
For more details on Dapr Spring Boot integration, please refer to [Dapr Spring Boot](../../DaprApplication.java) Application implementation.

View File

@ -7,9 +7,9 @@ package io.dapr.examples.pubsub.http;
import io.dapr.client.DaprClient;
import io.dapr.client.DaprClientBuilder;
import io.dapr.client.domain.Metadata;
import java.io.IOException;
import java.util.Collections;
import static java.util.Collections.singletonMap;
/**
* Message publisher.
@ -22,12 +22,16 @@ import java.util.Collections;
*/
public class Publisher {
//Number of messages to be sent: 10
//Number of messages to be sent.
private static final int NUM_MESSAGES = 10;
//Time-to-live for messages published.
private static final String MESSAGE_TTL_IN_SECONDS = "1000";
//The title of the topic to be used for publishing
private static final String TOPIC_NAME = "testingtopic";
//The name of the pubseb
//The name of the pubsub
private static final String PUBSUB_NAME = "messagebus";
/**
@ -41,7 +45,11 @@ public class Publisher {
for (int i = 0; i < NUM_MESSAGES; i++) {
String message = String.format("This is message #%d", i);
//Publishing messages
client.publishEvent(PUBSUB_NAME, TOPIC_NAME, message).block();
client.publishEvent(
PUBSUB_NAME,
TOPIC_NAME,
message,
singletonMap(Metadata.TTL_IN_SECONDS, MESSAGE_TTL_IN_SECONDS)).block();
System.out.println("Published message: " + message);
try {
@ -53,14 +61,6 @@ public class Publisher {
}
}
//Publishing a single bite: Example of non-string based content published
client.publishEvent(
PUBSUB_NAME,
TOPIC_NAME,
new byte[]{1},
Collections.singletonMap("content-type", "application/octet-stream")).block();
System.out.println("Published one byte.");
// This is an example, so for simplicity we are just exiting here.
// Normally a dapr app would be a web service and not exit main.
System.out.println("Done.");

View File

@ -135,14 +135,112 @@ dapr run --components-path ./components/pubsub --app-id publisher -- java -jar t
Once running, the Publisher should print the output as follows:
![publisheroutput](../../../../../../resources/img/publisher.png)
```txt
✅ You're up and running! Both Dapr and your app logs will appear here.
== APP == Published message: This is message #0
== APP == Published message: This is message #1
== APP == Published message: This is message #2
== APP == Published message: This is message #3
== APP == Published message: This is message #4
== APP == Published message: This is message #5
== APP == Published message: This is message #6
== APP == Published message: This is message #7
== APP == Published message: This is message #8
== APP == Published message: This is message #9
== APP == Done.
```
Messages have been published in the topic.
Once running, the Subscriber should print the output as follows:
![publisheroutput](../../../../../../resources/img/subscriber.png)
```txt
== APP == Subscriber got: {"id":"1f646657-0032-4797-b59b-c57b4f40743b","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #3","expiration":"2020-12-24T05:29:12Z"}
== APP == Subscriber got: {"id":"a22b97ce-9008-4fba-8b57-c3c3e1f031b6","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #8","expiration":"2020-12-24T05:29:15Z"}
== APP == Subscriber got: {"id":"abb2f110-6862-49f7-8c8d-189f6dcd177d","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #0","expiration":"2020-12-24T05:29:11Z"}
== APP == Subscriber got: {"id":"043f31d3-c13a-4a02-ac89-64ecca946598","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #7","expiration":"2020-12-24T05:29:14Z"}
== APP == Subscriber got: {"id":"acc554f4-7109-4c31-9374-0e5936b90180","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #2","expiration":"2020-12-24T05:29:12Z"}
== APP == Subscriber got: {"id":"8b3ad160-368d-4b0f-9925-8fa2a2fbf5ca","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #9","expiration":"2020-12-24T05:29:15Z"}
== APP == Subscriber got: {"id":"e41d4512-511a-4a2b-80f3-a0a4d091c9a5","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #1","expiration":"2020-12-24T05:29:11Z"}
== APP == Subscriber got: {"id":"33e21664-128e-4fc4-b5c4-ed257f758336","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #4","expiration":"2020-12-24T05:29:13Z"}
== APP == Subscriber got: {"id":"bd14f1ee-ca6b-47f7-8130-dd1e6de5b03c","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #6","expiration":"2020-12-24T05:29:14Z"}
== APP == Subscriber got: {"id":"acc57cd6-71da-4ba3-9a12-9c921ca49af7","source":"publisher","type":"com.dapr.event.sent","specversion":"1.0","datacontenttype":"application/json","data":"This is message #5","expiration":"2020-12-24T05:29:13Z"}
```
Messages have been retrieved from the topic.
For more details on Dapr Spring Boot integration, please refer to [Dapr Spring Boot](../../../springboot/DaprApplication.java) Application implementation.
### Message expiration (Optional)
Optionally, you can see how Dapr can automatically drop expired messages on behalf of the subscriber.
First, make sure the publisher and the subscriber applications are stopped.
Then, change the TTL constant in the `Publisher.java` file from:
```java
private static final String MESSAGE_TTL_IN_SECONDS = "1000";
```
To:
```java
private static final String MESSAGE_TTL_IN_SECONDS = "1";
```
Now rebuild the example:
```sh
mvn install
```
Run the publisher app:
```sh
dapr run --components-path ./components/pubsub --app-id publisher -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.pubsub.http.Publisher
```
Wait until all 10 messages are published like before, then wait for a few more seconds and run the subscriber app:
```sh
dapr run --components-path ./components/pubsub --app-id subscriber --app-port 3000 -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.pubsub.http.Subscriber -p 3000
```
No message is consumed by the subscriber app and warnings messages are emitted from Dapr sidecar:
```txt
== DAPR == time="2020-12-23T21:21:59.085797-08:00" level=warning msg="dropping expired pub/sub event 461546c1-d2df-42bd-a6b8-3beeb952fe1e as of 2020-12-24T05:21:50Z" app_id=subscriber instance=myhost scope=dapr.runtime type=log ver=edge
== DAPR == time="2020-12-23T21:21:59.085841-08:00" level=warning msg="dropping expired pub/sub event 2d8cf9a6-4019-4dda-95fd-59218a19381b as of 2020-12-24T05:21:48Z" app_id=subscriber instance=myhost scope=dapr.runtime type=log ver=edge
== DAPR == time="2020-12-23T21:21:59.085871-08:00" level=warning msg="dropping expired pub/sub event d2a199e0-a4b8-4067-9618-6688391ad68f as of 2020-12-24T05:21:53Z" app_id=subscriber instance=myhost scope=dapr.runtime type=log ver=edge
== DAPR == time="2020-12-23T21:21:59.085894-08:00" level=warning msg="dropping expired pub/sub event 30719f17-ad8f-4dea-91b5-b77958f360d4 as of 2020-12-24T05:21:49Z" app_id=subscriber instance=myhost scope=dapr.runtime type=log ver=edge
== DAPR == time="2020-12-23T21:21:59.085797-08:00" level=warning msg="dropping expired pub/sub event d136d5ae-5561-418c-a850-9d1698bc8840 as of 2020-12-24T05:21:51Z" app_id=subscriber instance=myhost scope=dapr.runtime type=log ver=edge
== DAPR == time="2020-12-23T21:21:59.085958-08:00" level=warning msg="dropping expired pub/sub event 82b334a2-e295-48ea-8c6c-c45b1c4fcd2d as of 2020-12-24T05:21:50Z" app_id=subscriber instance=myhost scope=dapr.runtime type=log ver=edge
== DAPR == time="2020-12-23T21:21:59.085973-08:00" level=warning msg="dropping expired pub/sub event f6eb3f9f-185f-492f-9df9-45af8c91932b as of 2020-12-24T05:21:53Z" app_id=subscriber instance=myhost scope=dapr.runtime type=log ver=edge
== DAPR == time="2020-12-23T21:21:59.086041-08:00" level=warning msg="dropping expired pub/sub event a536eb9f-34e0-49fc-ba29-a34854398d96 as of 2020-12-24T05:21:52Z" app_id=subscriber instance=myhost scope=dapr.runtime type=log ver=edge
== DAPR == time="2020-12-23T21:21:59.085995-08:00" level=warning msg="dropping expired pub/sub event 52cc9528-f9d4-44f4-8f78-8f32341a743a as of 2020-12-24T05:21:49Z" app_id=subscriber instance=myhost scope=dapr.runtime type=log ver=edge
== DAPR == time="2020-12-23T21:21:59.085797-08:00" level=warning msg="dropping expired pub/sub event 7cf927e8-e832-4f8a-911a-1cae5a1369d2 as of 2020-12-24T05:21:48Z" app_id=subscriber instance=myhost scope=dapr.runtime type=log ver=edge
```
For more details on Dapr Spring Boot integration, please refer to [Dapr Spring Boot](../../DaprApplication.java) Application implementation.

View File

@ -5,7 +5,7 @@
package io.dapr.examples.pubsub.http;
import io.dapr.springboot.DaprApplication;
import io.dapr.examples.DaprApplication;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;

View File

@ -5,40 +5,33 @@
package io.dapr.examples.pubsub.http;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.dapr.Topic;
import io.dapr.client.domain.CloudEvent;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import java.util.Map;
/**
* SpringBoot Controller to handle input binding.
*/
@RestController
public class SubscriberController {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
/**
* Handles a registered publish endpoint on this app.
* @param body The body of the http message.
* @param headers The headers of the http message.
* @param cloudEvent The cloud event received.
* @return A message containing the time.
*/
@Topic(name = "testingtopic", pubsubName = "messagebus")
@PostMapping(path = "/testingtopic")
public Mono<Void> handleMessage(@RequestBody(required = false) byte[] body,
@RequestHeader Map<String, String> headers) {
public Mono<Void> handleMessage(@RequestBody(required = false) CloudEvent cloudEvent) {
return Mono.fromRunnable(() -> {
try {
// Dapr's event is compliant to CloudEvent.
CloudEvent envelope = CloudEvent.deserialize(body);
String message = envelope.getData() == null ? "" : envelope.getData();
System.out.println("Subscriber got message: " + message);
System.out.println("Subscriber got: " + OBJECT_MAPPER.writeValueAsString(cloudEvent));
} catch (Exception e) {
throw new RuntimeException(e);
}

View File

@ -9,7 +9,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import io.dapr.client.DaprClient;
import io.dapr.client.DaprClientBuilder;
import java.io.IOException;
import java.util.Map;
/**

View File

@ -43,6 +43,10 @@ public class StateClient {
///...
public static void main(String[] args) throws Exception {
try (DaprClient client = new DaprClientBuilder().build()) {
System.out.println("Waiting for Dapr sidecar ...");
client.waitForSidecar(10000).block();
System.out.println("Dapr sidecar is ready.");
String message = args.length == 0 ? " " : args[0];
MyClass myClass = new MyClass();
@ -67,7 +71,7 @@ public class StateClient {
operationList.add(new TransactionalStateOperation<>(TransactionalStateOperation.OperationType.UPSERT,
new State<>(secondState, SECOND_KEY_NAME, "")));
client.executeTransaction(STATE_STORE_NAME, operationList).block();
client.executeStateTransaction(STATE_STORE_NAME, operationList).block();
// get multiple states
Mono<List<State<MyClass>>> retrievedMessagesMono = client.getStates(STATE_STORE_NAME,
@ -76,17 +80,30 @@ public class StateClient {
retrievedMessagesMono.block().forEach(System.out::println);
System.out.println("Deleting states...");
System.out.println("Verify delete key request is aborted if an etag different from stored is passed.");
// delete state API
Mono<Void> mono = client.deleteState(STATE_STORE_NAME, FIRST_KEY_NAME);
mono.block();
try {
client.deleteState(STATE_STORE_NAME, FIRST_KEY_NAME, "100", null).block();
} catch (DaprException ex) {
if (ex.getErrorCode().equals(Status.Code.ABORTED.toString())) {
// Expected error due to etag mismatch.
System.out.println(String.format("Expected failure. %s ", ex.getMessage()));
} else {
System.out.println("Unexpected exception.");
throw ex;
}
}
System.out.println("Trying to delete again with correct etag.");
String storedEtag = client.getState(STATE_STORE_NAME, FIRST_KEY_NAME, MyClass.class).block().getEtag();
client.deleteState(STATE_STORE_NAME, FIRST_KEY_NAME, storedEtag, null).block();
// Delete operation using transaction API
operationList.clear();
operationList.add(new TransactionalStateOperation<>(TransactionalStateOperation.OperationType.DELETE,
new State<>(SECOND_KEY_NAME)));
mono = client.executeTransaction(STATE_STORE_NAME, operationList);
mono.block();
client.executeStateTransaction(STATE_STORE_NAME, operationList).block();
Mono<List<State<MyClass>>> retrievedDeletedMessageMono = client.getStates(STATE_STORE_NAME,
Arrays.asList(FIRST_KEY_NAME, SECOND_KEY_NAME), MyClass.class);
@ -102,13 +119,14 @@ public class StateClient {
```
The code uses the `DaprClient` created by the `DaprClientBuilder`. Notice that this builder uses default settings. Internally, it is using `DefaultObjectSerializer` for two properties: `objectSerializer` is for Dapr's sent and received objects, and `stateSerializer` is for objects to be persisted.
This example performs multiple operations:
This example performs multiple operations:
* `client.waitForSidecar(...)` for waiting until Dapr sidecar is ready.
* `client.saveState(...)` for persisting an instance of `MyClass`.
* `client.getState(...)` operation in order to retrieve back the persisted state using the same key.
* `client.executeTransaction(...)` operation in order to update existing state and add new state.
* `client.getStates(...)` operation in order to retrieve back the persisted states using the same keys.
* `client.deleteState(...)` operation to remove one of the persisted states.
* `client.executeTransaction(...)` operation in order to remove the other persisted state.
* `client.executeStateTransaction(...)` operation in order to update existing state and add new state.
* `client.getBulkState(...)` operation in order to retrieve back the persisted states using the same keys.
* `client.deleteState(...)` operation to remove one of the persisted states. An example of etag mismatch error if a different than current etag is added to request.
* `client.executeStateTransaction(...)` operation in order to remove the other persisted state.
Finally, the code tries to retrieve the deleted states, which should not be found.

View File

@ -9,6 +9,8 @@ import io.dapr.client.DaprClient;
import io.dapr.client.DaprClientBuilder;
import io.dapr.client.domain.State;
import io.dapr.client.domain.TransactionalStateOperation;
import io.dapr.exceptions.DaprException;
import io.grpc.Status;
import reactor.core.publisher.Mono;
import java.util.ArrayList;
@ -46,6 +48,10 @@ public class StateClient {
*/
public static void main(String[] args) throws Exception {
try (DaprClient client = new DaprClientBuilder().build()) {
System.out.println("Waiting for Dapr sidecar ...");
client.waitForSidecar(10000).block();
System.out.println("Dapr sidecar is ready.");
String message = args.length == 0 ? " " : args[0];
MyClass myClass = new MyClass();
@ -70,28 +76,40 @@ public class StateClient {
operationList.add(new TransactionalStateOperation<>(TransactionalStateOperation.OperationType.UPSERT,
new State<>(secondState, SECOND_KEY_NAME, "")));
client.executeTransaction(STATE_STORE_NAME, operationList).block();
client.executeStateTransaction(STATE_STORE_NAME, operationList).block();
// get multiple states
Mono<List<State<MyClass>>> retrievedMessagesMono = client.getStates(STATE_STORE_NAME,
Mono<List<State<MyClass>>> retrievedMessagesMono = client.getBulkState(STATE_STORE_NAME,
Arrays.asList(FIRST_KEY_NAME, SECOND_KEY_NAME), MyClass.class);
System.out.println("Retrieved messages using bulk get:");
retrievedMessagesMono.block().forEach(System.out::println);
System.out.println("Deleting states...");
System.out.println("Verify delete key request is aborted if an etag different from stored is passed.");
// delete state API
Mono<Void> mono = client.deleteState(STATE_STORE_NAME, FIRST_KEY_NAME);
mono.block();
try {
client.deleteState(STATE_STORE_NAME, FIRST_KEY_NAME, "100", null).block();
} catch (DaprException ex) {
if (ex.getErrorCode().equals(Status.Code.ABORTED.toString())) {
// Expected error due to etag mismatch.
System.out.println(String.format("Expected failure. %s ", ex.getMessage()));
} else {
System.out.println("Unexpected exception.");
throw ex;
}
}
System.out.println("Trying to delete again with correct etag.");
String storedEtag = client.getState(STATE_STORE_NAME, FIRST_KEY_NAME, MyClass.class).block().getEtag();
client.deleteState(STATE_STORE_NAME, FIRST_KEY_NAME, storedEtag, null).block();
// Delete operation using transaction API
operationList.clear();
operationList.add(new TransactionalStateOperation<>(TransactionalStateOperation.OperationType.DELETE,
new State<>(SECOND_KEY_NAME)));
mono = client.executeTransaction(STATE_STORE_NAME, operationList);
mono.block();
client.executeStateTransaction(STATE_STORE_NAME, operationList).block();
Mono<List<State<MyClass>>> retrievedDeletedMessageMono = client.getStates(STATE_STORE_NAME,
Mono<List<State<MyClass>>> retrievedDeletedMessageMono = client.getBulkState(STATE_STORE_NAME,
Arrays.asList(FIRST_KEY_NAME, SECOND_KEY_NAME), MyClass.class);
System.out.println("Trying to retrieve deleted states: ");
retrievedDeletedMessageMono.block().forEach(System.out::println);

View File

@ -8,9 +8,9 @@ package io.dapr.examples.tracing;
import io.dapr.client.DaprClient;
import io.dapr.client.DaprClientBuilder;
import io.dapr.client.domain.HttpExtension;
import io.dapr.client.domain.InvokeServiceRequest;
import io.dapr.client.domain.InvokeServiceRequestBuilder;
import io.dapr.springboot.OpenTelemetryConfig;
import io.dapr.client.domain.InvokeMethodRequest;
import io.dapr.client.domain.InvokeMethodRequestBuilder;
import io.dapr.examples.OpenTelemetryConfig;
import io.dapr.utils.TypeRef;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
@ -31,7 +31,7 @@ public class InvokeClient {
/**
* Identifier in Dapr for the service this client will invoke.
*/
private static final String SERVICE_APP_ID = "tracingdemo";
private static final String SERVICE_APP_ID = "tracingdemoproxy";
/**
* Starts the invoke client.
@ -45,19 +45,19 @@ public class InvokeClient {
try (DaprClient client = (new DaprClientBuilder()).build()) {
for (String message : args) {
try (Scope scope = span.makeCurrent()) {
InvokeServiceRequestBuilder builder = new InvokeServiceRequestBuilder(SERVICE_APP_ID, "echo");
InvokeServiceRequest request
InvokeMethodRequestBuilder builder = new InvokeMethodRequestBuilder(SERVICE_APP_ID, "proxy_echo");
InvokeMethodRequest request
= builder.withBody(message).withHttpExtension(HttpExtension.POST).withContext(Context.current()).build();
client.invokeService(request, TypeRef.get(byte[].class))
client.invokeMethod(request, TypeRef.get(byte[].class))
.map(r -> {
System.out.println(new String(r.getObject()));
return r;
})
.flatMap(r -> {
InvokeServiceRequest sleepRequest = new InvokeServiceRequestBuilder(SERVICE_APP_ID, "sleep")
InvokeMethodRequest sleepRequest = new InvokeMethodRequestBuilder(SERVICE_APP_ID, "proxy_sleep")
.withHttpExtension(HttpExtension.POST)
.withContext(r.getContext()).build();
return client.invokeService(sleepRequest, TypeRef.get(Void.class));
return client.invokeMethod(sleepRequest, TypeRef.get(Void.class));
}).block();
}
}

View File

@ -3,7 +3,9 @@
In this sample, we'll create two java applications: a service application, which exposes two methods, and a client application which will invoke the methods from the service using Dapr.
This sample includes:
* TracingDemoService (Exposes the method to be remotely accessed)
* TracingDemoService (Exposes the methods to be remotely accessed)
* TracingDemoServiceController (Implements two methods: `echo` and `sleep`)
* TracingDemoMiddleServiceController (Implements two methods: `proxy_echo` and `proxy_sleep`)
* InvokeClient (Invokes the exposed methods from TracingDemoService)
Also consider [getting started with observability in Dapr](https://github.com/dapr/quickstarts/tree/master/observability).
@ -54,7 +56,7 @@ CONTAINER ID IMAGE COMMAND CREATED
If Zipkin is not working, [install the newest version of Dapr Cli and initialize it](https://github.com/dapr/cli#install-dapr-on-your-local-machine-self-hosted).
### Running the Demo service sample
### Running the Demo service app
The Demo service application exposes two methods that can be remotely invoked. In this example, the service code has two parts:
@ -82,11 +84,11 @@ This Rest Controller exposes the `echo` and `sleep` methods. The `echo` method r
public class TracingDemoServiceController {
///...
@PostMapping(path = "/echo")
public Mono<String> handleMethod(@RequestBody(required = false) byte[] body,
public Mono<String> handleMethod(@RequestBody(required = false) String body,
@RequestHeader Map<String, String> headers) {
return Mono.fromSupplier(() -> {
try {
String message = body == null ? "" : new String(body, StandardCharsets.UTF_8);
String message = body == null ? "" : body;
Calendar utcNow = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
String utcNowAsString = DATE_FORMAT.format(utcNow.getTime());
@ -95,7 +97,7 @@ public class TracingDemoServiceController {
// Handles the request by printing message.
System.out.println(
"Server: " + message + " @ " + utcNowAsString + " and metadata: " + metadataString);
"Server: " + message + " @ " + utcNowAsString + " and metadata: " + metadataString);
return utcNowAsString;
} catch (Exception e) {
@ -130,15 +132,67 @@ dapr run --app-id tracingdemo --app-port 3000 -- java -jar target/dapr-java-sdk-
Once running, the TracingDemoService is now ready to be invoked by Dapr.
### Running the Demo middle service app
### Running the InvokeClient sample
This service will handle the `proxy_echo` and `proxy_sleep` methods and invoke the corresponding methods in the service above.
In the code below, the `opentelemetry-context` attribute is used to propagate the tracing context among service invocations in multiple layers.
This sample code uses the Dapr SDK for invoking two remote methods (`echo` and `sleep`). It is also instrumented with OpenTelemetry. See the code snippet below:
```java
@RestController
public class TracingDemoMiddleServiceController {
// ...
@PostMapping(path = "/proxy_echo")
public Mono<byte[]> echo(
@RequestAttribute(name = "opentelemetry-context") Context context,
@RequestBody(required = false) String body) {
InvokeServiceRequestBuilder builder = new InvokeServiceRequestBuilder(INVOKE_APP_ID, "echo");
InvokeServiceRequest request
= builder.withBody(body).withHttpExtension(HttpExtension.POST).withContext(context).build();
return client.invokeMethod(request, TypeRef.get(byte[].class)).map(r -> r.getObject());
}
// ...
@PostMapping(path = "/proxy_sleep")
public Mono<Void> sleep(@RequestAttribute(name = "opentelemetry-context") Context context) {
InvokeServiceRequestBuilder builder = new InvokeServiceRequestBuilder(INVOKE_APP_ID, "sleep");
InvokeServiceRequest request = builder.withHttpExtension(HttpExtension.POST).withContext(context).build();
return client.invokeMethod(request, TypeRef.get(byte[].class)).then();
}
}
```
The request attribute `opentelemetry-context` in created by parsing the tracing headers in the [OpenTelemetryInterceptor](../OpenTelemetryInterceptor.java) class. See the code below:
```java
@Component
public class OpenTelemetryInterceptor implements HandlerInterceptor {
// ...
@Override
public boolean preHandle(
HttpServletRequest request, HttpServletResponse response, Object handler) {
final TextMapPropagator textFormat = OpenTelemetry.getGlobalPropagators().getTextMapPropagator();
// ...
Context context = textFormat.extract(Context.current(), request, HTTP_SERVLET_REQUEST_GETTER);
request.setAttribute("opentelemetry-context", context);
return true;
}
// ...
}
```
Use the follow command to execute the service:
```sh
dapr run --app-id tracingdemoproxy --app-port 3001 -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.tracing.TracingDemoService -p 3001
```
### Running the InvokeClient app
This sample code uses the Dapr SDK for invoking two remote methods (`proxy_echo` and `proxy_sleep`). It is also instrumented with OpenTelemetry. See the code snippet below:
```java
public class InvokeClient {
private static final String SERVICE_APP_ID = "invokedemo";
private static final String SERVICE_APP_ID = "tracingdemoproxy";
///...
public static void main(String[] args) throws Exception {
Tracer tracer = OpenTelemetryConfig.createTracer(InvokeClient.class.getCanonicalName());
@ -147,7 +201,7 @@ private static final String SERVICE_APP_ID = "invokedemo";
try (DaprClient client = (new DaprClientBuilder()).build()) {
for (String message : args) {
try (Scope scope = tracer.withSpan(span)) {
InvokeServiceRequestBuilder builder = new InvokeServiceRequestBuilder(SERVICE_APP_ID, "echo");
InvokeServiceRequestBuilder builder = new InvokeServiceRequestBuilder(SERVICE_APP_ID, "proxy_echo");
InvokeServiceRequest request
= builder.withBody(message).withHttpExtension(HttpExtension.POST).withContext(Context.current()).build();
client.invokeService(request, TypeRef.get(byte[].class))
@ -156,10 +210,10 @@ private static final String SERVICE_APP_ID = "invokedemo";
return r;
})
.flatMap(r -> {
InvokeServiceRequest sleepRequest = new InvokeServiceRequestBuilder(SERVICE_APP_ID, "sleep")
InvokeServiceRequest sleepRequest = new InvokeServiceRequestBuilder(SERVICE_APP_ID, "proxy_sleep")
.withHttpExtension(HttpExtension.POST)
.withContext(r.getContext()).build();
return client.invokeService(sleepRequest, TypeRef.get(Void.class));
return client.invokeMethod(sleepRequest, TypeRef.get(Void.class));
}).block();
}
}
@ -175,7 +229,7 @@ private static final String SERVICE_APP_ID = "invokedemo";
}
```
The class knows the app id for the remote application. It uses `invokeService` method to invoke API calls on the service endpoint. The request object includes an instance of `io.opentelemetry.context.Context` for the proper tracing headers to be propagated.
The class knows the app id for the remote application. It uses `invokeMethod` method to invoke API calls on the service endpoint. The request object includes an instance of `io.opentelemetry.context.Context` for the proper tracing headers to be propagated.
Execute the follow script in order to run the InvokeClient example, passing two messages for the remote method:
```sh

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License.
*/
package io.dapr.examples.tracing;
import io.dapr.client.DaprClient;
import io.dapr.client.domain.HttpExtension;
import io.dapr.client.domain.InvokeMethodRequest;
import io.dapr.client.domain.InvokeMethodRequestBuilder;
import io.dapr.examples.OpenTelemetryInterceptor;
import io.dapr.utils.TypeRef;
import io.opentelemetry.context.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
/**
* SpringBoot Controller to handle service invocation.
*
* <p>Instrumentation is handled in {@link OpenTelemetryInterceptor}.
*/
@RestController
public class TracingDemoMiddleServiceController {
private static final String INVOKE_APP_ID = "tracingdemo";
/**
* Dapr client.
*/
@Autowired
private DaprClient client;
/**
* Handles the 'echo' method invocation, by proxying a call into another service.
*
* @param context The tracing context for the request.
* @param body The body of the http message.
* @return A message containing the time.
*/
@PostMapping(path = "/proxy_echo")
public Mono<byte[]> echo(
@RequestAttribute(name = "opentelemetry-context") Context context,
@RequestBody(required = false) String body) {
InvokeMethodRequestBuilder builder = new InvokeMethodRequestBuilder(INVOKE_APP_ID, "echo");
InvokeMethodRequest request
= builder.withBody(body).withHttpExtension(HttpExtension.POST).withContext(context).build();
return client.invokeMethod(request, TypeRef.get(byte[].class)).map(r -> r.getObject());
}
/**
* Handles the 'sleep' method invocation, by proxying a call into another service.
*
* @param context The tracing context for the request.
* @return A message containing the time.
*/
@PostMapping(path = "/proxy_sleep")
public Mono<Void> sleep(@RequestAttribute(name = "opentelemetry-context") Context context) {
InvokeMethodRequestBuilder builder = new InvokeMethodRequestBuilder(INVOKE_APP_ID, "sleep");
InvokeMethodRequest request = builder.withHttpExtension(HttpExtension.POST).withContext(context).build();
return client.invokeMethod(request, TypeRef.get(byte[].class)).then();
}
}

View File

@ -5,7 +5,8 @@
package io.dapr.examples.tracing;
import io.dapr.springboot.DaprApplication;
import io.dapr.examples.DaprApplication;
import io.dapr.examples.OpenTelemetryInterceptor;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
@ -14,7 +15,7 @@ import org.apache.commons.cli.Options;
/**
* Main method to invoke DemoService to test tracing.
*
* <p>Instrumentation is handled in {@link io.dapr.springboot.OpenTelemetryInterceptor}.
* <p>Instrumentation is handled in {@link OpenTelemetryInterceptor}.
*
* <p>1. Build and install jars:
* mvn clean install
@ -22,6 +23,9 @@ import org.apache.commons.cli.Options;
* 3. Run in server mode:
* dapr run --app-id tracingdemo --app-port 3000 \
* -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.tracing.TracingDemoService -p 3000
* 4. Run middle server:
* dapr run --app-id tracingdemoproxy --app-port 3001 \
* -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.tracing.TracingDemoService -p 3001
*/
public class TracingDemoService {

View File

@ -6,6 +6,7 @@
package io.dapr.examples.tracing;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.dapr.examples.OpenTelemetryInterceptor;
import io.opentelemetry.api.trace.Tracer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
@ -14,7 +15,6 @@ import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
@ -24,7 +24,7 @@ import java.util.TimeZone;
/**
* SpringBoot Controller to handle service invocation.
*
* <p>Instrumentation is handled in {@link io.dapr.springboot.OpenTelemetryInterceptor}.
* <p>Instrumentation is handled in {@link OpenTelemetryInterceptor}.
*/
@RestController
public class TracingDemoServiceController {
@ -53,11 +53,11 @@ public class TracingDemoServiceController {
* @return A message containing the time.
*/
@PostMapping(path = "/echo")
public Mono<String> handleMethod(@RequestBody(required = false) byte[] body,
public Mono<String> handleMethod(@RequestBody(required = false) String body,
@RequestHeader Map<String, String> headers) {
return Mono.fromSupplier(() -> {
try {
String message = body == null ? "" : new String(body, StandardCharsets.UTF_8);
String message = body == null ? "" : body;
Calendar utcNow = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
String utcNowAsString = DATE_FORMAT.format(utcNow.getTime());

Binary file not shown.

Before

Width:  |  Height:  |  Size: 405 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 4.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 341 KiB

View File

@ -16,7 +16,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<grpc.version>1.33.1</grpc.version>
<protobuf.version>3.13.0</protobuf.version>
<dapr.proto.baseurl>https://raw.githubusercontent.com/dapr/dapr/3cca3cc1567f1cb955ae69b8fd784f075f62ad42/dapr/proto</dapr.proto.baseurl>
<dapr.proto.baseurl>https://raw.githubusercontent.com/dapr/dapr/4a6369caaba9cf46eae9bfa4fa6e76b474854c89/dapr/proto</dapr.proto.baseurl>
<os-maven-plugin.version>1.6.2</os-maven-plugin.version>
<maven-dependency-plugin.version>3.1.1</maven-dependency-plugin.version>
<maven-antrun-plugin.version>1.8</maven-antrun-plugin.version>

View File

@ -21,5 +21,13 @@ public @interface ActorMethod {
*
* @return Actor's method return type.
*/
Class returns();
Class returns() default Undefined.class;
/**
* Actor's method name. This is optional and will override the method's default name for actor invocation.
*
* @return Actor's method name.
*/
String name() default "";
}

View File

@ -0,0 +1,16 @@
/*
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License.
*/
package io.dapr.actors;
/**
* Internal class to represent the undefined value for an optional Class attribute.
*/
final class Undefined {
private Undefined() {
}
}

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License.
*/
package io.dapr.actors.client;
import io.dapr.client.DaprApiProtocol;
import io.dapr.client.DaprHttpBuilder;
import io.dapr.config.Properties;
import io.dapr.v1.DaprGrpc;
import io.grpc.Channel;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import reactor.core.publisher.Mono;
/**
* Holds a client for Dapr sidecar communication. ActorClient should be reused.
*/
public class ActorClient implements AutoCloseable {
/**
* gRPC channel for communication with Dapr sidecar.
*/
private final ManagedChannel grpcManagedChannel;
/**
* Dapr's client.
*/
private final DaprClient daprClient;
/**
* Instantiates a new channel for Dapr sidecar communication.
*/
public ActorClient() {
this(Properties.API_PROTOCOL.get());
}
/**
* Instantiates a new channel for Dapr sidecar communication.
*
* @param apiProtocol Dapr's API protocol.
*/
private ActorClient(DaprApiProtocol apiProtocol) {
this(apiProtocol, buildManagedChannel(apiProtocol));
}
/**
* Instantiates a new channel for Dapr sidecar communication.
*
* @param apiProtocol Dapr's API protocol.
*/
private ActorClient(DaprApiProtocol apiProtocol, ManagedChannel grpcManagedChannel) {
this.grpcManagedChannel = grpcManagedChannel;
this.daprClient = buildDaprClient(apiProtocol, grpcManagedChannel);
}
/**
* Invokes an Actor method on Dapr.
*
* @param actorType Type of actor.
* @param actorId Actor Identifier.
* @param methodName Method name to invoke.
* @param jsonPayload Serialized body.
* @return Asynchronous result with the Actor's response.
*/
Mono<byte[]> invoke(String actorType, String actorId, String methodName, byte[] jsonPayload) {
return daprClient.invoke(actorType, actorId, methodName, jsonPayload);
}
/**
* {@inheritDoc}
*/
@Override
public void close() {
if (grpcManagedChannel != null && !grpcManagedChannel.isShutdown()) {
grpcManagedChannel.shutdown();
}
}
/**
* Creates a GRPC managed channel (or null, if not applicable).
*
* @param apiProtocol Dapr's API protocol.
* @return GRPC managed channel or null.
*/
private static ManagedChannel buildManagedChannel(DaprApiProtocol apiProtocol) {
if (apiProtocol != DaprApiProtocol.GRPC) {
return null;
}
int port = Properties.GRPC_PORT.get();
if (port <= 0) {
throw new IllegalArgumentException("Invalid port.");
}
return ManagedChannelBuilder.forAddress(Properties.SIDECAR_IP.get(), port).usePlaintext().build();
}
/**
* Build an instance of the Client based on the provided setup.
*
* @return an instance of the setup Client
* @throws java.lang.IllegalStateException if any required field is missing
*/
private static DaprClient buildDaprClient(DaprApiProtocol apiProtocol, Channel grpcManagedChannel) {
switch (apiProtocol) {
case GRPC: return new DaprGrpcClient(DaprGrpc.newFutureStub(grpcManagedChannel));
case HTTP: return new DaprHttpClient(new DaprHttpBuilder().build());
default: throw new IllegalStateException("Unsupported protocol: " + apiProtocol.name());
}
}
}

View File

@ -36,7 +36,7 @@ public interface ActorProxy {
* @param <T> The type to be returned.
* @return Asynchronous result with the Actor's response.
*/
<T> Mono<T> invokeActorMethod(String methodName, TypeRef<T> type);
<T> Mono<T> invokeMethod(String methodName, TypeRef<T> type);
/**
* Invokes an Actor method on Dapr.
@ -46,7 +46,7 @@ public interface ActorProxy {
* @param <T> The type to be returned.
* @return Asynchronous result with the Actor's response.
*/
<T> Mono<T> invokeActorMethod(String methodName, Class<T> clazz);
<T> Mono<T> invokeMethod(String methodName, Class<T> clazz);
/**
* Invokes an Actor method on Dapr.
@ -57,7 +57,7 @@ public interface ActorProxy {
* @param <T> The type to be returned.
* @return Asynchronous result with the Actor's response.
*/
<T> Mono<T> invokeActorMethod(String methodName, Object data, TypeRef<T> type);
<T> Mono<T> invokeMethod(String methodName, Object data, TypeRef<T> type);
/**
* Invokes an Actor method on Dapr.
@ -68,7 +68,7 @@ public interface ActorProxy {
* @param <T> The type to be returned.
* @return Asynchronous result with the Actor's response.
*/
<T> Mono<T> invokeActorMethod(String methodName, Object data, Class<T> clazz);
<T> Mono<T> invokeMethod(String methodName, Object data, Class<T> clazz);
/**
* Invokes an Actor method on Dapr.
@ -76,7 +76,7 @@ public interface ActorProxy {
* @param methodName Method name to invoke.
* @return Asynchronous result with the Actor's response.
*/
Mono<Void> invokeActorMethod(String methodName);
Mono<Void> invokeMethod(String methodName);
/**
* Invokes an Actor method on Dapr.
@ -85,6 +85,6 @@ public interface ActorProxy {
* @param data Object with the data.
* @return Asynchronous result with the Actor's response.
*/
Mono<Void> invokeActorMethod(String methodName, Object data);
Mono<Void> invokeMethod(String methodName, Object data);
}

View File

@ -7,28 +7,15 @@ package io.dapr.actors.client;
import io.dapr.actors.ActorId;
import io.dapr.actors.ActorUtils;
import io.dapr.client.DaprHttpBuilder;
import io.dapr.config.Properties;
import io.dapr.serializer.DaprObjectSerializer;
import io.dapr.serializer.DefaultObjectSerializer;
import io.dapr.v1.DaprGrpc;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import java.io.Closeable;
import java.lang.reflect.Proxy;
import static io.dapr.exceptions.DaprException.throwIllegalArgumentException;
/**
* Builder to generate an ActorProxy instance. Builder can be reused for multiple instances.
*/
public class ActorProxyBuilder<T> implements Closeable {
/**
* Determine if this builder will create GRPC clients instead of HTTP clients.
*/
private final boolean useGrpc;
public class ActorProxyBuilder<T> {
/**
* Actor's type.
@ -46,14 +33,9 @@ public class ActorProxyBuilder<T> implements Closeable {
private DaprObjectSerializer objectSerializer;
/**
* Builds Dapr HTTP client.
* Client for communication with Dapr's Actor APIs.
*/
private DaprHttpBuilder daprHttpBuilder;
/**
* Channel for communication with Dapr.
*/
private final ManagedChannel channel;
private final ActorClient actorClient;
/**
* Instantiates a new builder for a given Actor type, using {@link DefaultObjectSerializer} by default.
@ -61,9 +43,10 @@ public class ActorProxyBuilder<T> implements Closeable {
* {@link DefaultObjectSerializer} is not recommended for production scenarios.
*
* @param actorTypeClass Actor's type class.
* @param actorClient Dapr's sidecar client for Actor APIs.
*/
public ActorProxyBuilder(Class<T> actorTypeClass) {
this(ActorUtils.findActorTypeName(actorTypeClass), actorTypeClass);
public ActorProxyBuilder(Class<T> actorTypeClass, ActorClient actorClient) {
this(ActorUtils.findActorTypeName(actorTypeClass), actorTypeClass, actorClient);
}
/**
@ -73,21 +56,23 @@ public class ActorProxyBuilder<T> implements Closeable {
*
* @param actorType Actor's type.
* @param actorTypeClass Actor's type class.
* @param actorClient Dapr's sidecar client for Actor APIs.
*/
public ActorProxyBuilder(String actorType, Class<T> actorTypeClass) {
public ActorProxyBuilder(String actorType, Class<T> actorTypeClass, ActorClient actorClient) {
if ((actorType == null) || actorType.isEmpty()) {
throwIllegalArgumentException("ActorType is required.");
throw new IllegalArgumentException("ActorType is required.");
}
if (actorTypeClass == null) {
throwIllegalArgumentException("ActorTypeClass is required.");
throw new IllegalArgumentException("ActorTypeClass is required.");
}
if (actorClient == null) {
throw new IllegalArgumentException("ActorClient is required.");
}
this.useGrpc = Properties.USE_GRPC.get();
this.actorType = actorType;
this.objectSerializer = new DefaultObjectSerializer();
this.clazz = actorTypeClass;
this.daprHttpBuilder = new DaprHttpBuilder();
this.channel = buildManagedChannel();
this.actorClient = actorClient;
}
/**
@ -98,7 +83,7 @@ public class ActorProxyBuilder<T> implements Closeable {
*/
public ActorProxyBuilder<T> withObjectSerializer(DaprObjectSerializer objectSerializer) {
if (objectSerializer == null) {
throwIllegalArgumentException("Serializer is required.");
throw new IllegalArgumentException("Serializer is required.");
}
this.objectSerializer = objectSerializer;
@ -113,14 +98,14 @@ public class ActorProxyBuilder<T> implements Closeable {
*/
public T build(ActorId actorId) {
if (actorId == null) {
throwIllegalArgumentException("Cannot instantiate an Actor without Id.");
throw new IllegalArgumentException("Cannot instantiate an Actor without Id.");
}
ActorProxyImpl proxy = new ActorProxyImpl(
this.actorType,
actorId,
this.objectSerializer,
buildDaprClient());
this.actorClient);
if (this.clazz.equals(ActorProxy.class)) {
// If users want to use the not strongly typed API, we respect that here.
@ -133,45 +118,4 @@ public class ActorProxyBuilder<T> implements Closeable {
proxy);
}
/**
* Build an instance of the Client based on the provided setup.
*
* @return an instance of the setup Client
* @throws java.lang.IllegalStateException if any required field is missing
*/
private DaprClient buildDaprClient() {
if (this.useGrpc) {
return new DaprGrpcClient(DaprGrpc.newFutureStub(this.channel));
}
return new DaprHttpClient(daprHttpBuilder.build());
}
/**
* {@inheritDoc}
*/
@Override
public void close() {
if (channel != null && !channel.isShutdown()) {
channel.shutdown();
}
}
/**
* Creates a GRPC managed channel (or null, if not applicable).
*
* @return GRPC managed channel or null.
*/
private static ManagedChannel buildManagedChannel() {
if (!Properties.USE_GRPC.get()) {
return null;
}
int port = Properties.GRPC_PORT.get();
if (port <= 0) {
throwIllegalArgumentException("Invalid port.");
}
return ManagedChannelBuilder.forAddress(Properties.SIDECAR_IP.get(), port).usePlaintext().build();
}
}

View File

@ -21,6 +21,8 @@ import java.lang.reflect.Method;
*/
class ActorProxyImpl implements ActorProxy, InvocationHandler {
private static final String UNDEFINED_CLASS_NAME = "io.dapr.actors.Undefined";
/**
* Actor's identifier for this Actor instance.
*/
@ -39,7 +41,7 @@ class ActorProxyImpl implements ActorProxy, InvocationHandler {
/**
* Client to talk to the Dapr's API.
*/
private final DaprClient daprClient;
private final ActorClient actorClient;
/**
* Creates a new instance of {@link ActorProxyImpl}.
@ -47,12 +49,12 @@ class ActorProxyImpl implements ActorProxy, InvocationHandler {
* @param actorType actor implementation type of the actor associated with the proxy object.
* @param actorId The actorId associated with the proxy
* @param serializer Serializer and deserializer for method calls.
* @param daprClient Dapr client.
* @param actorClient Dapr client for Actor APIs.
*/
ActorProxyImpl(String actorType, ActorId actorId, DaprObjectSerializer serializer, DaprClient daprClient) {
ActorProxyImpl(String actorType, ActorId actorId, DaprObjectSerializer serializer, ActorClient actorClient) {
this.actorType = actorType;
this.actorId = actorId;
this.daprClient = daprClient;
this.actorClient = actorClient;
this.serializer = serializer;
}
@ -74,8 +76,8 @@ class ActorProxyImpl implements ActorProxy, InvocationHandler {
* {@inheritDoc}
*/
@Override
public <T> Mono<T> invokeActorMethod(String methodName, Object data, TypeRef<T> type) {
return this.daprClient.invokeActorMethod(actorType, actorId.toString(), methodName, this.serialize(data))
public <T> Mono<T> invokeMethod(String methodName, Object data, TypeRef<T> type) {
return this.actorClient.invoke(actorType, actorId.toString(), methodName, this.serialize(data))
.filter(s -> s.length > 0)
.map(s -> deserialize(s, type));
}
@ -84,16 +86,16 @@ class ActorProxyImpl implements ActorProxy, InvocationHandler {
* {@inheritDoc}
*/
@Override
public <T> Mono<T> invokeActorMethod(String methodName, Object data, Class<T> clazz) {
return this.invokeActorMethod(methodName, data, TypeRef.get(clazz));
public <T> Mono<T> invokeMethod(String methodName, Object data, Class<T> clazz) {
return this.invokeMethod(methodName, data, TypeRef.get(clazz));
}
/**
* {@inheritDoc}
*/
@Override
public <T> Mono<T> invokeActorMethod(String methodName, TypeRef<T> type) {
return this.daprClient.invokeActorMethod(actorType, actorId.toString(), methodName, null)
public <T> Mono<T> invokeMethod(String methodName, TypeRef<T> type) {
return this.actorClient.invoke(actorType, actorId.toString(), methodName, null)
.filter(s -> s.length > 0)
.map(s -> deserialize(s, type));
}
@ -102,24 +104,24 @@ class ActorProxyImpl implements ActorProxy, InvocationHandler {
* {@inheritDoc}
*/
@Override
public <T> Mono<T> invokeActorMethod(String methodName, Class<T> clazz) {
return this.invokeActorMethod(methodName, TypeRef.get(clazz));
public <T> Mono<T> invokeMethod(String methodName, Class<T> clazz) {
return this.invokeMethod(methodName, TypeRef.get(clazz));
}
/**
* {@inheritDoc}
*/
@Override
public Mono<Void> invokeActorMethod(String methodName) {
return this.daprClient.invokeActorMethod(actorType, actorId.toString(), methodName, null).then();
public Mono<Void> invokeMethod(String methodName) {
return this.actorClient.invoke(actorType, actorId.toString(), methodName, null).then();
}
/**
* {@inheritDoc}
*/
@Override
public Mono<Void> invokeActorMethod(String methodName, Object data) {
return this.daprClient.invokeActorMethod(actorType, actorId.toString(), methodName, this.serialize(data)).then();
public Mono<Void> invokeMethod(String methodName, Object data) {
return this.actorClient.invoke(actorType, actorId.toString(), methodName, this.serialize(data)).then();
}
/**
@ -136,29 +138,33 @@ class ActorProxyImpl implements ActorProxy, InvocationHandler {
throw new UnsupportedOperationException("Actor methods can only have zero or one arguments.");
}
ActorMethod actorMethodAnnotation = method.getDeclaredAnnotation(ActorMethod.class);
String methodName = method.getName();
if ((actorMethodAnnotation != null) && !actorMethodAnnotation.name().isEmpty()) {
methodName = actorMethodAnnotation.name();
}
if (method.getParameterCount() == 0) {
if (method.getReturnType().equals(Mono.class)) {
ActorMethod actorMethodAnnotation = method.getDeclaredAnnotation(ActorMethod.class);
if (actorMethodAnnotation == null) {
return invokeActorMethod(method.getName());
if ((actorMethodAnnotation == null) || UNDEFINED_CLASS_NAME.equals(actorMethodAnnotation.returns().getName())) {
return invokeMethod(methodName);
}
return invokeActorMethod(method.getName(), actorMethodAnnotation.returns());
return invokeMethod(methodName, actorMethodAnnotation.returns());
}
return invokeActorMethod(method.getName(), method.getReturnType()).block();
return invokeMethod(methodName, method.getReturnType()).block();
}
if (method.getReturnType().equals(Mono.class)) {
ActorMethod actorMethodAnnotation = method.getDeclaredAnnotation(ActorMethod.class);
if (actorMethodAnnotation == null) {
return invokeActorMethod(method.getName(), args[0]);
if ((actorMethodAnnotation == null) || UNDEFINED_CLASS_NAME.equals(actorMethodAnnotation.returns().getName())) {
return invokeMethod(methodName, args[0]);
}
return invokeActorMethod(method.getName(), args[0], actorMethodAnnotation.returns());
return invokeMethod(methodName, args[0], actorMethodAnnotation.returns());
}
return invokeActorMethod(method.getName(), args[0], method.getReturnType()).block();
return invokeMethod(methodName, args[0], method.getReturnType()).block();
}
/**

View File

@ -21,6 +21,6 @@ interface DaprClient {
* @param jsonPayload Serialized body.
* @return Asynchronous result with the Actor's response.
*/
Mono<byte[]> invokeActorMethod(String actorType, String actorId, String methodName, byte[] jsonPayload);
Mono<byte[]> invoke(String actorType, String actorId, String methodName, byte[] jsonPayload);
}

View File

@ -40,7 +40,7 @@ class DaprGrpcClient implements DaprClient {
* {@inheritDoc}
*/
@Override
public Mono<byte[]> invokeActorMethod(String actorType, String actorId, String methodName, byte[] jsonPayload) {
public Mono<byte[]> invoke(String actorType, String actorId, String methodName, byte[] jsonPayload) {
return Mono.fromCallable(DaprException.wrap(() -> {
DaprProtos.InvokeActorRequest req =
DaprProtos.InvokeActorRequest.newBuilder()

View File

@ -15,16 +15,6 @@ import reactor.core.publisher.Mono;
*/
class DaprHttpClient implements DaprClient {
/**
* Base URL for Dapr Actor APIs.
*/
private static final String ACTORS_BASE_URL = DaprHttp.API_VERSION + "/" + "actors";
/**
* String format for Actors method invocation relative url.
*/
private static final String ACTOR_METHOD_RELATIVE_URL_FORMAT = ACTORS_BASE_URL + "/%s/%s/method/%s";
/**
* The HTTP client to be used.
*
@ -45,10 +35,10 @@ class DaprHttpClient implements DaprClient {
* {@inheritDoc}
*/
@Override
public Mono<byte[]> invokeActorMethod(String actorType, String actorId, String methodName, byte[] jsonPayload) {
String url = String.format(ACTOR_METHOD_RELATIVE_URL_FORMAT, actorType, actorId, methodName);
public Mono<byte[]> invoke(String actorType, String actorId, String methodName, byte[] jsonPayload) {
String[] pathSegments = new String[] { DaprHttp.API_VERSION, "actors", actorType, actorId, "method", methodName };
Mono<DaprHttp.Response> responseMono =
this.client.invokeApi(DaprHttp.HttpMethods.POST.name(), url, null, jsonPayload, null, null);
this.client.invokeApi(DaprHttp.HttpMethods.POST.name(), pathSegments, null, jsonPayload, null, null);
return responseMono.map(r -> r.getBody());
}
}

View File

@ -114,7 +114,7 @@ public abstract class AbstractActor {
try {
byte[] data = this.actorRuntimeContext.getObjectSerializer().serialize(state);
ActorReminderParams params = new ActorReminderParams(data, dueTime, period);
return this.actorRuntimeContext.getDaprClient().registerActorReminder(
return this.actorRuntimeContext.getDaprClient().registerReminder(
this.actorRuntimeContext.getActorTypeInformation().getName(),
this.id.toString(),
reminderName,
@ -157,7 +157,7 @@ public abstract class AbstractActor {
byte[] data = this.actorRuntimeContext.getObjectSerializer().serialize(state);
ActorTimerParams actorTimer = new ActorTimerParams(callback, data, dueTime, period);
return this.actorRuntimeContext.getDaprClient().registerActorTimer(
return this.actorRuntimeContext.getDaprClient().registerTimer(
this.actorRuntimeContext.getActorTypeInformation().getName(),
this.id.toString(),
name,
@ -174,7 +174,7 @@ public abstract class AbstractActor {
* @return Asynchronous void response.
*/
protected Mono<Void> unregisterTimer(String timerName) {
return this.actorRuntimeContext.getDaprClient().unregisterActorTimer(
return this.actorRuntimeContext.getDaprClient().unregisterTimer(
this.actorRuntimeContext.getActorTypeInformation().getName(),
this.id.toString(),
timerName);
@ -187,7 +187,7 @@ public abstract class AbstractActor {
* @return Asynchronous void response.
*/
protected Mono<Void> unregisterReminder(String reminderName) {
return this.actorRuntimeContext.getDaprClient().unregisterActorReminder(
return this.actorRuntimeContext.getDaprClient().unregisterReminder(
this.actorRuntimeContext.getActorTypeInformation().getName(),
this.id.toString(),
reminderName);

View File

@ -5,6 +5,8 @@
package io.dapr.actors.runtime;
import io.dapr.actors.ActorMethod;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
@ -35,7 +37,12 @@ class ActorMethodInfoMap {
if (methodInfo.getParameterCount() <= 1) {
// If Actor class uses overloading, then one will win.
// Document this behavior, so users know how to write their code.
methods.put(methodInfo.getName(), methodInfo);
String methodName = methodInfo.getName();
ActorMethod actorMethodAnnotation = methodInfo.getAnnotation(ActorMethod.class);
if ((actorMethodAnnotation != null) && !actorMethodAnnotation.name().isEmpty()) {
methodName = actorMethodAnnotation.name();
}
methods.put(methodName, methodInfo);
}
}
}

View File

@ -7,6 +7,7 @@ package io.dapr.actors.runtime;
import io.dapr.actors.ActorId;
import io.dapr.actors.ActorTrace;
import io.dapr.client.DaprApiProtocol;
import io.dapr.client.DaprHttpBuilder;
import io.dapr.config.Properties;
import io.dapr.serializer.DaprObjectSerializer;
@ -307,7 +308,7 @@ public class ActorRuntime implements Closeable {
* @throws java.lang.IllegalStateException if any required field is missing
*/
private static DaprClient buildDaprClient(ManagedChannel channel) {
if (Properties.USE_GRPC.get()) {
if (Properties.API_PROTOCOL.get() == DaprApiProtocol.GRPC) {
return new DaprGrpcClient(channel);
}
@ -320,7 +321,7 @@ public class ActorRuntime implements Closeable {
* @return GRPC managed channel or null.
*/
private static ManagedChannel buildManagedChannel() {
if (!Properties.USE_GRPC.get()) {
if (Properties.API_PROTOCOL.get() != DaprApiProtocol.GRPC) {
return null;
}

View File

@ -22,7 +22,7 @@ interface DaprClient {
* @param keyName State name.
* @return Asynchronous result with current state value.
*/
Mono<byte[]> getActorState(String actorType, String actorId, String keyName);
Mono<byte[]> getState(String actorType, String actorId, String keyName);
/**
* Saves state batch to Dapr.
@ -32,7 +32,7 @@ interface DaprClient {
* @param operations State transaction operations.
* @return Asynchronous void result.
*/
Mono<Void> saveActorStateTransactionally(String actorType, String actorId, List<ActorStateOperation> operations);
Mono<Void> saveStateTransactionally(String actorType, String actorId, List<ActorStateOperation> operations);
/**
* Register a reminder.
@ -43,7 +43,7 @@ interface DaprClient {
* @param reminderParams Parameters for the reminder.
* @return Asynchronous void result.
*/
Mono<Void> registerActorReminder(
Mono<Void> registerReminder(
String actorType,
String actorId,
String reminderName,
@ -57,7 +57,7 @@ interface DaprClient {
* @param reminderName Name of reminder to be unregistered.
* @return Asynchronous void result.
*/
Mono<Void> unregisterActorReminder(String actorType, String actorId, String reminderName);
Mono<Void> unregisterReminder(String actorType, String actorId, String reminderName);
/**
* Register a timer.
@ -68,7 +68,7 @@ interface DaprClient {
* @param timerParams Parameters for the timer.
* @return Asynchronous void result.
*/
Mono<Void> registerActorTimer(String actorType, String actorId, String timerName, ActorTimerParams timerParams);
Mono<Void> registerTimer(String actorType, String actorId, String timerName, ActorTimerParams timerParams);
/**
* Unregisters a timer.
@ -78,5 +78,5 @@ interface DaprClient {
* @param timerName Name of timer to be unregistered.
* @return Asynchronous void result.
*/
Mono<Void> unregisterActorTimer(String actorType, String actorId, String timerName);
Mono<Void> unregisterTimer(String actorType, String actorId, String timerName);
}

View File

@ -66,7 +66,7 @@ class DaprGrpcClient implements DaprClient {
* {@inheritDoc}
*/
@Override
public Mono<byte[]> getActorState(String actorType, String actorId, String keyName) {
public Mono<byte[]> getState(String actorType, String actorId, String keyName) {
return Mono.fromCallable(() -> {
DaprProtos.GetActorStateRequest req =
DaprProtos.GetActorStateRequest.newBuilder()
@ -84,7 +84,7 @@ class DaprGrpcClient implements DaprClient {
* {@inheritDoc}
*/
@Override
public Mono<Void> saveActorStateTransactionally(
public Mono<Void> saveStateTransactionally(
String actorType,
String actorId,
List<ActorStateOperation> operations) {
@ -134,7 +134,7 @@ class DaprGrpcClient implements DaprClient {
* {@inheritDoc}
*/
@Override
public Mono<Void> registerActorReminder(
public Mono<Void> registerReminder(
String actorType,
String actorId,
String reminderName,
@ -160,7 +160,7 @@ class DaprGrpcClient implements DaprClient {
* {@inheritDoc}
*/
@Override
public Mono<Void> unregisterActorReminder(String actorType, String actorId, String reminderName) {
public Mono<Void> unregisterReminder(String actorType, String actorId, String reminderName) {
return Mono.fromCallable(() -> {
DaprProtos.UnregisterActorReminderRequest req =
DaprProtos.UnregisterActorReminderRequest.newBuilder()
@ -179,7 +179,7 @@ class DaprGrpcClient implements DaprClient {
* {@inheritDoc}
*/
@Override
public Mono<Void> registerActorTimer(
public Mono<Void> registerTimer(
String actorType,
String actorId,
String timerName,
@ -206,7 +206,7 @@ class DaprGrpcClient implements DaprClient {
* {@inheritDoc}
*/
@Override
public Mono<Void> unregisterActorTimer(String actorType, String actorId, String timerName) {
public Mono<Void> unregisterTimer(String actorType, String actorId, String timerName) {
return Mono.fromCallable(() -> {
DaprProtos.UnregisterActorTimerRequest req =
DaprProtos.UnregisterActorTimerRequest.newBuilder()

View File

@ -29,31 +29,6 @@ class DaprHttpClient implements DaprClient {
*/
private static final JsonFactory JSON_FACTORY = new JsonFactory();
/**
* Base URL for Dapr Actor APIs.
*/
private static final String ACTORS_BASE_URL = DaprHttp.API_VERSION + "/" + "actors";
/**
* String format for Actors state management relative url.
*/
private static final String ACTOR_STATE_KEY_RELATIVE_URL_FORMAT = ACTORS_BASE_URL + "/%s/%s/state/%s";
/**
* String format for Actors state management relative url.
*/
private static final String ACTOR_STATE_RELATIVE_URL_FORMAT = ACTORS_BASE_URL + "/%s/%s/state";
/**
* String format for Actors reminder registration relative url.
*/
private static final String ACTOR_REMINDER_RELATIVE_URL_FORMAT = ACTORS_BASE_URL + "/%s/%s/reminders/%s";
/**
* String format for Actors timer registration relative url.
*/
private static final String ACTOR_TIMER_RELATIVE_URL_FORMAT = ACTORS_BASE_URL + "/%s/%s/timers/%s";
/**
* The HTTP client to be used.
*
@ -74,10 +49,10 @@ class DaprHttpClient implements DaprClient {
* {@inheritDoc}
*/
@Override
public Mono<byte[]> getActorState(String actorType, String actorId, String keyName) {
String url = String.format(ACTOR_STATE_KEY_RELATIVE_URL_FORMAT, actorType, actorId, keyName);
public Mono<byte[]> getState(String actorType, String actorId, String keyName) {
String[] pathSegments = new String[] { DaprHttp.API_VERSION, "actors", actorType, actorId, "state", keyName };
Mono<DaprHttp.Response> responseMono =
this.client.invokeApi(DaprHttp.HttpMethods.GET.name(), url, null, "", null, null);
this.client.invokeApi(DaprHttp.HttpMethods.GET.name(), pathSegments, null, "", null, null);
return responseMono.map(r -> {
if ((r.getStatusCode() != 200) && (r.getStatusCode() != 204)) {
throw new IllegalStateException(
@ -91,7 +66,7 @@ class DaprHttpClient implements DaprClient {
* {@inheritDoc}
*/
@Override
public Mono<Void> saveActorStateTransactionally(
public Mono<Void> saveStateTransactionally(
String actorType,
String actorId,
List<ActorStateOperation> operations) {
@ -144,23 +119,30 @@ class DaprHttpClient implements DaprClient {
return Mono.error(e);
}
String url = String.format(ACTOR_STATE_RELATIVE_URL_FORMAT, actorType, actorId);
return this.client.invokeApi(DaprHttp.HttpMethods.PUT.name(), url, null, payload, null, null).then();
String[] pathSegments = new String[] { DaprHttp.API_VERSION, "actors", actorType, actorId, "state" };
return this.client.invokeApi(DaprHttp.HttpMethods.PUT.name(), pathSegments, null, payload, null, null).then();
}
/**
* {@inheritDoc}
*/
@Override
public Mono<Void> registerActorReminder(
public Mono<Void> registerReminder(
String actorType,
String actorId,
String reminderName,
ActorReminderParams reminderParams) {
String url = String.format(ACTOR_REMINDER_RELATIVE_URL_FORMAT, actorType, actorId, reminderName);
String[] pathSegments = new String[] {
DaprHttp.API_VERSION,
"actors",
actorType,
actorId,
"reminders",
reminderName
};
return Mono.fromCallable(() -> INTERNAL_SERIALIZER.serialize(reminderParams))
.flatMap(data ->
this.client.invokeApi(DaprHttp.HttpMethods.PUT.name(), url, null, data, null, null)
this.client.invokeApi(DaprHttp.HttpMethods.PUT.name(), pathSegments, null, data, null, null)
).then();
}
@ -168,24 +150,38 @@ class DaprHttpClient implements DaprClient {
* {@inheritDoc}
*/
@Override
public Mono<Void> unregisterActorReminder(String actorType, String actorId, String reminderName) {
String url = String.format(ACTOR_REMINDER_RELATIVE_URL_FORMAT, actorType, actorId, reminderName);
return this.client.invokeApi(DaprHttp.HttpMethods.DELETE.name(), url, null, null, null).then();
public Mono<Void> unregisterReminder(String actorType, String actorId, String reminderName) {
String[] pathSegments = new String[] {
DaprHttp.API_VERSION,
"actors",
actorType,
actorId,
"reminders",
reminderName
};
return this.client.invokeApi(DaprHttp.HttpMethods.DELETE.name(), pathSegments, null, null, null).then();
}
/**
* {@inheritDoc}
*/
@Override
public Mono<Void> registerActorTimer(
public Mono<Void> registerTimer(
String actorType,
String actorId,
String timerName,
ActorTimerParams timerParams) {
return Mono.fromCallable(() -> INTERNAL_SERIALIZER.serialize(timerParams))
.flatMap(data -> {
String url = String.format(ACTOR_TIMER_RELATIVE_URL_FORMAT, actorType, actorId, timerName);
return this.client.invokeApi(DaprHttp.HttpMethods.PUT.name(), url, null, data, null, null);
String[] pathSegments = new String[] {
DaprHttp.API_VERSION,
"actors",
actorType,
actorId,
"timers",
timerName
};
return this.client.invokeApi(DaprHttp.HttpMethods.PUT.name(), pathSegments, null, data, null, null);
}).then();
}
@ -193,9 +189,9 @@ class DaprHttpClient implements DaprClient {
* {@inheritDoc}
*/
@Override
public Mono<Void> unregisterActorTimer(String actorType, String actorId, String timerName) {
String url = String.format(ACTOR_TIMER_RELATIVE_URL_FORMAT, actorType, actorId, timerName);
return this.client.invokeApi(DaprHttp.HttpMethods.DELETE.name(), url, null, null, null).then();
public Mono<Void> unregisterTimer(String actorType, String actorId, String timerName) {
String[] pathSegments = new String[] { DaprHttp.API_VERSION, "actors", actorType, actorId, "timers", timerName };
return this.client.invokeApi(DaprHttp.HttpMethods.DELETE.name(), pathSegments, null, null, null).then();
}
}

View File

@ -60,7 +60,7 @@ class DaprStateAsyncProvider {
}
<T> Mono<T> load(String actorType, ActorId actorId, String stateName, TypeRef<T> type) {
Mono<byte[]> result = this.daprClient.getActorState(actorType, actorId.toString(), stateName);
Mono<byte[]> result = this.daprClient.getState(actorType, actorId.toString(), stateName);
return result.flatMap(s -> {
try {
@ -88,7 +88,7 @@ class DaprStateAsyncProvider {
}
Mono<Boolean> contains(String actorType, ActorId actorId, String stateName) {
Mono<byte[]> result = this.daprClient.getActorState(actorType, actorId.toString(), stateName);
Mono<byte[]> result = this.daprClient.getState(actorType, actorId.toString(), stateName);
return result.map(s -> s.length > 0).defaultIfEmpty(false);
}
@ -155,7 +155,7 @@ class DaprStateAsyncProvider {
operations.add(new ActorStateOperation(operationName, key, value));
}
return this.daprClient.saveActorStateTransactionally(actorType, actorId.toString(), operations);
return this.daprClient.saveStateTransactionally(actorType, actorId.toString(), operations);
}
}

View File

@ -7,44 +7,56 @@ package io.dapr.actors.client;
import io.dapr.actors.ActorId;
import io.dapr.actors.ActorType;
import io.dapr.exceptions.DaprException;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
public class ActorProxyBuilderTest {
@Test(expected = DaprException.class)
private static ActorClient actorClient;
@BeforeClass
public static void initClass() {
actorClient = new ActorClient();
}
@AfterClass
public static void tearDownClass() {
actorClient.close();
}
@Test(expected = IllegalArgumentException.class)
public void buildWithNullActorId() {
new ActorProxyBuilder("test", Object.class)
new ActorProxyBuilder("test", Object.class, actorClient)
.build(null);
}
@Test(expected = DaprException.class)
@Test(expected = IllegalArgumentException.class)
public void buildWithEmptyActorType() {
new ActorProxyBuilder("", Object.class)
.build(new ActorId("100"));
new ActorProxyBuilder("", Object.class, actorClient);
}
@Test(expected = DaprException.class)
@Test(expected = IllegalArgumentException.class)
public void buildWithNullActorType() {
new ActorProxyBuilder(null, Object.class)
.build(new ActorId("100"));
new ActorProxyBuilder(null, Object.class, actorClient);
}
@Test(expected = DaprException.class)
@Test(expected = IllegalArgumentException.class)
public void buildWithNullSerializer() {
new ActorProxyBuilder("MyActor", Object.class)
new ActorProxyBuilder("MyActor", Object.class, actorClient)
.withObjectSerializer(null)
.build(new ActorId("100"));
}
@Test(expected = IllegalArgumentException.class)
public void buildWithNullClient() {
new ActorProxyBuilder("MyActor", Object.class, null);
}
@Test()
public void build() {
ActorProxyBuilder<ActorProxy> builder = new ActorProxyBuilder("test", ActorProxy.class);
ActorProxyBuilder<ActorProxy> builder = new ActorProxyBuilder("test", ActorProxy.class, actorClient);
ActorProxy actorProxy = builder.build(new ActorId("100"));
Assert.assertNotNull(actorProxy);
@ -54,7 +66,7 @@ public class ActorProxyBuilderTest {
@Test()
public void buildWithType() {
ActorProxyBuilder<MyActor> builder = new ActorProxyBuilder(MyActor.class);
ActorProxyBuilder<MyActor> builder = new ActorProxyBuilder(MyActor.class, actorClient);
MyActor actorProxy = builder.build(new ActorId("100"));
Assert.assertNotNull(actorProxy);
@ -62,8 +74,8 @@ public class ActorProxyBuilderTest {
@Test()
public void buildWithTypeDefaultName() {
ActorProxyBuilder<MyActorWithDefaultName> builder = new ActorProxyBuilder(MyActorWithDefaultName.class);
MyActorWithDefaultName actorProxy = builder.build(new ActorId("100"));
ActorProxyBuilder<ActorWithDefaultName> builder = new ActorProxyBuilder(ActorWithDefaultName.class, actorClient);
ActorWithDefaultName actorProxy = builder.build(new ActorId("100"));
Assert.assertNotNull(actorProxy);
}
@ -72,6 +84,7 @@ public class ActorProxyBuilderTest {
public interface MyActor {
}
public interface MyActorWithDefaultName {
public interface ActorWithDefaultName {
}
}
}

View File

@ -1,16 +0,0 @@
/*
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License.
*/
package io.dapr.actors.client;
import io.dapr.actors.ActorId;
import io.dapr.serializer.DaprObjectSerializer;
public class ActorProxyForTestsImpl extends ActorProxyImpl {
public ActorProxyForTestsImpl(String actorType, ActorId actorId, DaprObjectSerializer serializer, DaprClient daprClient) {
super(actorType, actorId, serializer, daprClient);
}
}

View File

@ -0,0 +1,16 @@
/*
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License.
*/
package io.dapr.actors.client;
import io.dapr.actors.ActorId;
import io.dapr.serializer.DaprObjectSerializer;
public class ActorProxyImplForTests extends ActorProxyImpl {
public ActorProxyImplForTests(String actorType, ActorId actorId, DaprObjectSerializer serializer, ActorClient actorClient) {
super(actorType, actorId, serializer, actorClient);
}
}

View File

@ -23,7 +23,7 @@ public class ActorProxyImplTest {
@Test()
public void constructorActorProxyTest() {
final DaprClient daprClient = mock(DaprClient.class);
final ActorClient daprClient = mock(ActorClient.class);
final DaprObjectSerializer serializer = mock(DaprObjectSerializer.class);
final ActorProxyImpl actorProxy = new ActorProxyImpl(
"myActorType",
@ -36,11 +36,11 @@ public class ActorProxyImplTest {
@Test()
public void invokeActorMethodWithoutDataWithReturnType() {
final DaprClient daprClient = mock(DaprClient.class);
final ActorClient daprClient = mock(ActorClient.class);
Mono<byte[]> daprResponse = Mono.just(
"{\n\t\t\"propertyA\": \"valueA\",\n\t\t\"propertyB\": \"valueB\"\n\t}".getBytes());
when(daprClient.invokeActorMethod(anyString(), anyString(), anyString(), Mockito.isNull()))
when(daprClient.invoke(anyString(), anyString(), anyString(), Mockito.isNull()))
.thenReturn(daprResponse);
final ActorProxy actorProxy = new ActorProxyImpl(
@ -49,7 +49,7 @@ public class ActorProxyImplTest {
new DefaultObjectSerializer(),
daprClient);
Mono<MyData> result = actorProxy.invokeActorMethod("getData", MyData.class);
Mono<MyData> result = actorProxy.invokeMethod("getData", MyData.class);
MyData myData = result.block();
Assert.assertNotNull(myData);
Assert.assertEquals("valueA", myData.getPropertyA());
@ -58,11 +58,11 @@ public class ActorProxyImplTest {
@Test()
public void invokeActorMethodWithoutDataWithReturnTypeViaReflection() throws NoSuchMethodException {
final DaprClient daprClient = mock(DaprClient.class);
final ActorClient daprClient = mock(ActorClient.class);
Mono<byte[]> daprResponse = Mono.just(
"{\n\t\t\"propertyA\": \"valueA\",\n\t\t\"propertyB\": \"valueB\"\n\t}".getBytes());
when(daprClient.invokeActorMethod(anyString(), anyString(), anyString(), Mockito.isNull()))
when(daprClient.invoke(anyString(), anyString(), anyString(), Mockito.isNull()))
.thenReturn(daprResponse);
final ActorProxyImpl actorProxy = new ActorProxyImpl(
@ -79,11 +79,11 @@ public class ActorProxyImplTest {
@Test()
public void invokeActorMethodWithoutDataWithReturnMonoTypeViaReflection() throws NoSuchMethodException {
final DaprClient daprClient = mock(DaprClient.class);
final ActorClient daprClient = mock(ActorClient.class);
Mono<byte[]> daprResponse = Mono.just(
"{\n\t\t\"propertyA\": \"valueA\",\n\t\t\"propertyB\": \"valueB\"\n\t}".getBytes());
when(daprClient.invokeActorMethod(anyString(), anyString(), anyString(), Mockito.isNull()))
when(daprClient.invoke(anyString(), anyString(), anyString(), Mockito.isNull()))
.thenReturn(daprResponse);
final ActorProxyImpl actorProxy = new ActorProxyImpl(
@ -102,11 +102,11 @@ public class ActorProxyImplTest {
@Test()
public void invokeActorMethodWithDataWithReturnTypeViaReflection() throws NoSuchMethodException {
final DaprClient daprClient = mock(DaprClient.class);
final ActorClient daprClient = mock(ActorClient.class);
Mono<byte[]> daprResponse = Mono.just(
"\"OK\"".getBytes());
when(daprClient.invokeActorMethod(anyString(), anyString(), anyString(), Mockito.eq("\"hello world\"".getBytes())))
when(daprClient.invoke(anyString(), anyString(), anyString(), Mockito.eq("\"hello world\"".getBytes())))
.thenReturn(daprResponse);
final ActorProxyImpl actorProxy = new ActorProxyImpl(
@ -125,11 +125,11 @@ public class ActorProxyImplTest {
@Test()
public void invokeActorMethodWithDataWithReturnMonoTypeViaReflection() throws NoSuchMethodException {
final DaprClient daprClient = mock(DaprClient.class);
final ActorClient daprClient = mock(ActorClient.class);
Mono<byte[]> daprResponse = Mono.just(
"\"OK\"".getBytes());
when(daprClient.invokeActorMethod(anyString(), anyString(), anyString(), Mockito.eq("\"hello world\"".getBytes())))
when(daprClient.invoke(anyString(), anyString(), anyString(), Mockito.eq("\"hello world\"".getBytes())))
.thenReturn(daprResponse);
final ActorProxyImpl actorProxy = new ActorProxyImpl(
@ -149,10 +149,10 @@ public class ActorProxyImplTest {
@Test()
public void invokeActorMethodWithoutDataWithoutReturnTypeViaReflection() throws NoSuchMethodException {
final DaprClient daprClient = mock(DaprClient.class);
final ActorClient daprClient = mock(ActorClient.class);
Mono<byte[]> daprResponse = Mono.empty();
when(daprClient.invokeActorMethod(anyString(), anyString(), anyString(), Mockito.isNull()))
when(daprClient.invoke(anyString(), anyString(), anyString(), Mockito.isNull()))
.thenReturn(daprResponse);
final ActorProxyImpl actorProxy = new ActorProxyImpl(
@ -167,10 +167,10 @@ public class ActorProxyImplTest {
@Test()
public void invokeActorMethodWithoutDataWithoutReturnTypeMonoViaReflection() throws NoSuchMethodException {
final DaprClient daprClient = mock(DaprClient.class);
final ActorClient daprClient = mock(ActorClient.class);
Mono<byte[]> daprResponse = Mono.empty();
when(daprClient.invokeActorMethod(anyString(), anyString(), anyString(), Mockito.isNull()))
when(daprClient.invoke(anyString(), anyString(), anyString(), Mockito.isNull()))
.thenReturn(daprResponse);
final ActorProxyImpl actorProxy = new ActorProxyImpl(
@ -186,10 +186,10 @@ public class ActorProxyImplTest {
@Test()
public void invokeActorMethodWithDataWithoutReturnTypeMonoViaReflection() throws NoSuchMethodException {
final DaprClient daprClient = mock(DaprClient.class);
final ActorClient daprClient = mock(ActorClient.class);
Mono<byte[]> daprResponse = Mono.empty();
when(daprClient.invokeActorMethod(anyString(), anyString(), anyString(), Mockito.eq("\"hello world\"".getBytes())))
when(daprClient.invoke(anyString(), anyString(), anyString(), Mockito.eq("\"hello world\"".getBytes())))
.thenReturn(daprResponse);
final ActorProxyImpl actorProxy = new ActorProxyImpl(
@ -209,7 +209,7 @@ public class ActorProxyImplTest {
@Test(expected = UnsupportedOperationException.class)
public void invokeActorMethodWithTooManyArgsViaReflection() throws NoSuchMethodException {
final DaprClient daprClient = mock(DaprClient.class);
final ActorClient daprClient = mock(ActorClient.class);
final ActorProxyImpl actorProxy = new ActorProxyImpl(
"myActorType",
@ -228,10 +228,10 @@ public class ActorProxyImplTest {
@Test()
public void invokeActorMethodWithDataWithoutReturnTypeViaReflection() throws NoSuchMethodException {
final DaprClient daprClient = mock(DaprClient.class);
final ActorClient daprClient = mock(ActorClient.class);
Mono<byte[]> daprResponse = Mono.empty();
when(daprClient.invokeActorMethod(anyString(), anyString(), anyString(), Mockito.eq("\"hello world\"".getBytes())))
when(daprClient.invoke(anyString(), anyString(), anyString(), Mockito.eq("\"hello world\"".getBytes())))
.thenReturn(daprResponse);
final ActorProxyImpl actorProxy = new ActorProxyImpl(
@ -250,8 +250,8 @@ public class ActorProxyImplTest {
@Test()
public void invokeActorMethodWithoutDataWithEmptyReturnType() {
final DaprClient daprClient = mock(DaprClient.class);
when(daprClient.invokeActorMethod(anyString(), anyString(), anyString(), Mockito.isNull()))
final ActorClient daprClient = mock(ActorClient.class);
when(daprClient.invoke(anyString(), anyString(), anyString(), Mockito.isNull()))
.thenReturn(Mono.just("".getBytes()));
final ActorProxy actorProxy = new ActorProxyImpl(
@ -260,15 +260,15 @@ public class ActorProxyImplTest {
new DefaultObjectSerializer(),
daprClient);
Mono<MyData> result = actorProxy.invokeActorMethod("getData", MyData.class);
Mono<MyData> result = actorProxy.invokeMethod("getData", MyData.class);
MyData myData = result.block();
Assert.assertNull(myData);
}
@Test(expected = RuntimeException.class)
public void invokeActorMethodWithIncorrectReturnType() {
final DaprClient daprClient = mock(DaprClient.class);
when(daprClient.invokeActorMethod(anyString(), anyString(), anyString(), Mockito.isNull()))
final ActorClient daprClient = mock(ActorClient.class);
when(daprClient.invoke(anyString(), anyString(), anyString(), Mockito.isNull()))
.thenReturn(Mono.just("{test}".getBytes()));
final ActorProxy actorProxy = new ActorProxyImpl(
@ -277,7 +277,7 @@ public class ActorProxyImplTest {
new DefaultObjectSerializer(),
daprClient);
Mono<MyData> result = actorProxy.invokeActorMethod("getData", MyData.class);
Mono<MyData> result = actorProxy.invokeMethod("getData", MyData.class);
result.doOnSuccess(x ->
Assert.fail("Not exception was throw"))
@ -287,8 +287,8 @@ public class ActorProxyImplTest {
@Test()
public void invokeActorMethodSavingDataWithReturnType() {
final DaprClient daprClient = mock(DaprClient.class);
when(daprClient.invokeActorMethod(anyString(), anyString(), anyString(), Mockito.isNotNull()))
final ActorClient daprClient = mock(ActorClient.class);
when(daprClient.invoke(anyString(), anyString(), anyString(), Mockito.isNotNull()))
.thenReturn(
Mono.just("{\n\t\t\"propertyA\": \"valueA\",\n\t\t\"propertyB\": \"valueB\"\n\t}".getBytes()));
@ -302,7 +302,7 @@ public class ActorProxyImplTest {
saveData.setPropertyA("valueA");
saveData.setPropertyB("valueB");
Mono<MyData> result = actorProxy.invokeActorMethod("getData", saveData, MyData.class);
Mono<MyData> result = actorProxy.invokeMethod("getData", saveData, MyData.class);
MyData myData = result.block();
Assert.assertNotNull(myData);
Assert.assertEquals("valueA", myData.getPropertyA());
@ -312,8 +312,8 @@ public class ActorProxyImplTest {
@Test(expected = DaprException.class)
public void invokeActorMethodSavingDataWithIncorrectReturnType() {
final DaprClient daprClient = mock(DaprClient.class);
when(daprClient.invokeActorMethod(anyString(), anyString(), anyString(), Mockito.isNotNull()))
final ActorClient daprClient = mock(ActorClient.class);
when(daprClient.invoke(anyString(), anyString(), anyString(), Mockito.isNotNull()))
.thenReturn(Mono.just("{test}".getBytes()));
final ActorProxy actorProxy = new ActorProxyImpl(
@ -326,7 +326,7 @@ public class ActorProxyImplTest {
saveData.setPropertyA("valueA");
saveData.setPropertyB("valueB");
Mono<MyData> result = actorProxy.invokeActorMethod("getData", saveData, MyData.class);
Mono<MyData> result = actorProxy.invokeMethod("getData", saveData, MyData.class);
result.doOnSuccess(x ->
Assert.fail("Not exception was throw"))
.doOnError(Throwable::printStackTrace
@ -336,8 +336,8 @@ public class ActorProxyImplTest {
@Test()
public void invokeActorMethodSavingDataWithEmptyReturnType() {
final DaprClient daprClient = mock(DaprClient.class);
when(daprClient.invokeActorMethod(anyString(), anyString(), anyString(), Mockito.isNotNull()))
final ActorClient daprClient = mock(ActorClient.class);
when(daprClient.invoke(anyString(), anyString(), anyString(), Mockito.isNotNull()))
.thenReturn(Mono.just("".getBytes()));
final ActorProxy actorProxy = new ActorProxyImpl(
@ -350,7 +350,7 @@ public class ActorProxyImplTest {
saveData.setPropertyA("valueA");
saveData.setPropertyB("valueB");
Mono<MyData> result = actorProxy.invokeActorMethod("getData", saveData, MyData.class);
Mono<MyData> result = actorProxy.invokeMethod("getData", saveData, MyData.class);
MyData myData = result.block();
Assert.assertNull(myData);
}
@ -358,8 +358,8 @@ public class ActorProxyImplTest {
@Test(expected = DaprException.class)
public void invokeActorMethodSavingDataWithIncorrectInputType() {
final DaprClient daprClient = mock(DaprClient.class);
when(daprClient.invokeActorMethod(anyString(), anyString(), anyString(), Mockito.isNotNull()))
final ActorClient daprClient = mock(ActorClient.class);
when(daprClient.invoke(anyString(), anyString(), anyString(), Mockito.isNotNull()))
.thenReturn(Mono.just("{test}".getBytes()));
final ActorProxy actorProxy = new ActorProxyImpl(
@ -373,7 +373,7 @@ public class ActorProxyImplTest {
saveData.setPropertyB("valueB");
saveData.setMyData(saveData);
Mono<MyData> result = actorProxy.invokeActorMethod("getData", saveData, MyData.class);
Mono<MyData> result = actorProxy.invokeMethod("getData", saveData, MyData.class);
result.doOnSuccess(x ->
Assert.fail("Not exception was throw"))
.doOnError(Throwable::printStackTrace
@ -387,8 +387,8 @@ public class ActorProxyImplTest {
saveData.setPropertyA("valueA");
saveData.setPropertyB("valueB");
final DaprClient daprClient = mock(DaprClient.class);
when(daprClient.invokeActorMethod(anyString(), anyString(), anyString(), Mockito.isNotNull()))
final ActorClient daprClient = mock(ActorClient.class);
when(daprClient.invoke(anyString(), anyString(), anyString(), Mockito.isNotNull()))
.thenReturn(Mono.empty());
final ActorProxy actorProxy = new ActorProxyImpl(
@ -397,7 +397,7 @@ public class ActorProxyImplTest {
new DefaultObjectSerializer(),
daprClient);
Mono<Void> result = actorProxy.invokeActorMethod("getData", saveData);
Mono<Void> result = actorProxy.invokeMethod("getData", saveData);
Void emptyResponse = result.block();
Assert.assertNull(emptyResponse);
}
@ -410,8 +410,8 @@ public class ActorProxyImplTest {
saveData.setPropertyB("valueB");
saveData.setMyData(saveData);
final DaprClient daprClient = mock(DaprClient.class);
when(daprClient.invokeActorMethod(anyString(), anyString(), anyString(), Mockito.isNotNull()))
final ActorClient daprClient = mock(ActorClient.class);
when(daprClient.invoke(anyString(), anyString(), anyString(), Mockito.isNotNull()))
.thenReturn(Mono.empty());
final ActorProxy actorProxy = new ActorProxyImpl(
@ -420,15 +420,15 @@ public class ActorProxyImplTest {
new DefaultObjectSerializer(),
daprClient);
Mono<Void> result = actorProxy.invokeActorMethod("getData", saveData);
Mono<Void> result = actorProxy.invokeMethod("getData", saveData);
Void emptyResponse = result.doOnError(Throwable::printStackTrace).block();
Assert.assertNull(emptyResponse);
}
@Test()
public void invokeActorMethodWithoutDataWithVoidReturnType() {
final DaprClient daprClient = mock(DaprClient.class);
when(daprClient.invokeActorMethod(anyString(), anyString(), anyString(), Mockito.isNull()))
final ActorClient daprClient = mock(ActorClient.class);
when(daprClient.invoke(anyString(), anyString(), anyString(), Mockito.isNull()))
.thenReturn(Mono.empty());
final ActorProxy actorProxy = new ActorProxyImpl(
@ -437,7 +437,7 @@ public class ActorProxyImplTest {
new DefaultObjectSerializer(),
daprClient);
Mono<Void> result = actorProxy.invokeActorMethod("getData");
Mono<Void> result = actorProxy.invokeMethod("getData");
Void emptyResponse = result.block();
Assert.assertNull(emptyResponse);
}

View File

@ -7,10 +7,10 @@ package io.dapr.actors.client;
import reactor.core.publisher.Mono;
public class DaprClientStub implements DaprClient {
public class DaprClientStub extends ActorClient implements DaprClient {
@Override
public Mono<byte[]> invokeActorMethod(String actorType, String actorId, String methodName, byte[] jsonPayload) {
public Mono<byte[]> invoke(String actorType, String actorId, String methodName, byte[] jsonPayload) {
return Mono.just(new byte[0]);
}

View File

@ -54,7 +54,7 @@ public class DaprGrpcClientTest {
assertArrayEquals(payload, argument.getData().toByteArray());
return true;
}))).thenReturn(settableFuture);
Mono<byte[]> result = client.invokeActorMethod(ACTOR_TYPE, ACTOR_ID, methodName, payload);
Mono<byte[]> result = client.invoke(ACTOR_TYPE, ACTOR_ID, methodName, payload);
assertArrayEquals(response, result.block());
}
@ -73,7 +73,7 @@ public class DaprGrpcClientTest {
assertArrayEquals(new byte[0], argument.getData().toByteArray());
return true;
}))).thenReturn(settableFuture);
Mono<byte[]> result = client.invokeActorMethod(ACTOR_TYPE, ACTOR_ID, methodName, null);
Mono<byte[]> result = client.invoke(ACTOR_TYPE, ACTOR_ID, methodName, null);
assertArrayEquals(response, result.block());
}
@ -91,7 +91,7 @@ public class DaprGrpcClientTest {
assertArrayEquals(new byte[0], argument.getData().toByteArray());
return true;
}))).thenReturn(settableFuture);
Mono<byte[]> result = client.invokeActorMethod(ACTOR_TYPE, ACTOR_ID, methodName, null);
Mono<byte[]> result = client.invoke(ACTOR_TYPE, ACTOR_ID, methodName, null);
assertThrowsDaprException(
ExecutionException.class,
@ -114,7 +114,7 @@ public class DaprGrpcClientTest {
assertArrayEquals(new byte[0], argument.getData().toByteArray());
return true;
}))).thenReturn(settableFuture);
client.invokeActorMethod(ACTOR_TYPE, ACTOR_ID, methodName, null);
client.invoke(ACTOR_TYPE, ACTOR_ID, methodName, null);
// No exception thrown because Mono is ignored here.
}

View File

@ -43,7 +43,7 @@ public class DaprHttpClientTest {
DaprHttp daprHttp = new DaprHttpProxy(Properties.SIDECAR_IP.get(), 3000, okHttpClient);
DaprHttpClient = new DaprHttpClient(daprHttp);
Mono<byte[]> mono =
DaprHttpClient.invokeActorMethod("DemoActor", "1", "Payment", "".getBytes());
DaprHttpClient.invoke("DemoActor", "1", "Payment", "".getBytes());
assertEquals(new String(mono.block()), EXPECTED_RESULT);
}
@ -58,7 +58,7 @@ public class DaprHttpClientTest {
DaprHttp daprHttp = new DaprHttpProxy(Properties.SIDECAR_IP.get(), 3000, okHttpClient);
DaprHttpClient = new DaprHttpClient(daprHttp);
Mono<byte[]> mono =
DaprHttpClient.invokeActorMethod("DemoActor", "1", "Payment", "".getBytes());
DaprHttpClient.invoke("DemoActor", "1", "Payment", "".getBytes());
assertThrowsDaprException(
"ERR_SOMETHING",

View File

@ -8,7 +8,7 @@ package io.dapr.actors.runtime;
import io.dapr.actors.ActorId;
import io.dapr.actors.ActorType;
import io.dapr.actors.client.ActorProxy;
import io.dapr.actors.client.ActorProxyForTestsImpl;
import io.dapr.actors.client.ActorProxyImplForTests;
import io.dapr.actors.client.DaprClientStub;
import io.dapr.serializer.DaprObjectSerializer;
import org.junit.Assert;
@ -98,7 +98,7 @@ public class ActorCustomSerializerTest {
ActorProxy actorProxy = createActorProxy();
MyData d = new MyData("hi", 3);
MyData response = actorProxy.invokeActorMethod("classInClassOut", d, MyData.class).block();
MyData response = actorProxy.invokeMethod("classInClassOut", d, MyData.class).block();
Assert.assertEquals("hihi", response.getName());
Assert.assertEquals(6, response.getNum());
@ -107,7 +107,7 @@ public class ActorCustomSerializerTest {
@Test
public void stringInStringOut() {
ActorProxy actorProxy = createActorProxy();
String response = actorProxy.invokeActorMethod("stringInStringOut", "oi", String.class).block();
String response = actorProxy.invokeMethod("stringInStringOut", "oi", String.class).block();
Assert.assertEquals("oioi", response);
}
@ -115,7 +115,7 @@ public class ActorCustomSerializerTest {
@Test
public void intInIntOut() {
ActorProxy actorProxy = createActorProxy();
int response = actorProxy.invokeActorMethod("intInIntOut", 2, int.class).block();
int response = actorProxy.invokeMethod("intInIntOut", 2, int.class).block();
Assert.assertEquals(4, response);
}
@ -130,7 +130,7 @@ public class ActorCustomSerializerTest {
// Mock daprClient for ActorProxy only, not for runtime.
DaprClientStub daprClient = mock(DaprClientStub.class);
when(daprClient.invokeActorMethod(
when(daprClient.invoke(
eq(context.getActorTypeInformation().getName()),
eq(actorId.toString()),
any(),
@ -143,7 +143,7 @@ public class ActorCustomSerializerTest {
this.manager.activateActor(actorId).block();
return new ActorProxyForTestsImpl(
return new ActorProxyImplForTests(
context.getActorTypeInformation().getName(),
actorId,
CUSTOM_SERIALIZER,
@ -153,10 +153,10 @@ public class ActorCustomSerializerTest {
private static <T extends AbstractActor> ActorRuntimeContext createContext() {
DaprClient daprClient = mock(DaprClient.class);
when(daprClient.registerActorTimer(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.registerActorReminder(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterActorTimer(any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterActorReminder(any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.registerTimer(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.registerReminder(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterTimer(any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterReminder(any(), any(), any())).thenReturn(Mono.empty());
return new ActorRuntimeContext(
mock(ActorRuntime.class),

View File

@ -287,10 +287,10 @@ public class ActorManagerTest {
private static <T extends AbstractActor> ActorRuntimeContext createContext(Class<T> clazz) {
DaprClient daprClient = mock(DaprClient.class);
when(daprClient.registerActorTimer(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.registerActorReminder(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterActorTimer(any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterActorReminder(any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.registerTimer(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.registerReminder(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterTimer(any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterReminder(any(), any(), any())).thenReturn(Mono.empty());
return new ActorRuntimeContext(
mock(ActorRuntime.class),

View File

@ -6,9 +6,10 @@
package io.dapr.actors.runtime;
import io.dapr.actors.ActorId;
import io.dapr.actors.ActorMethod;
import io.dapr.actors.ActorType;
import io.dapr.actors.client.ActorProxy;
import io.dapr.actors.client.ActorProxyForTestsImpl;
import io.dapr.actors.client.ActorProxyImplForTests;
import io.dapr.actors.client.DaprClientStub;
import io.dapr.serializer.DefaultObjectSerializer;
import org.junit.Assert;
@ -43,6 +44,8 @@ public class ActorNoStateTest {
Mono<MyData> classInClassOut(MyData input);
Mono<String> registerBadCallbackName();
String registerTimerAutoName();
@ActorMethod(name = "DotNetMethodASync")
Mono<Void> dotNetMethod();
}
@ActorType(name = "MyActor")
@ -108,6 +111,11 @@ public class ActorNoStateTest {
public String registerTimerAutoName() {
return super.registerActorTimer("", "anything", "state", Duration.ofSeconds(1), Duration.ofSeconds(1)).block();
}
@Override
public Mono<Void> dotNetMethod() {
return Mono.empty();
}
}
static class MyData {
@ -139,7 +147,7 @@ public class ActorNoStateTest {
Assert.assertEquals(
proxy.getActorId().toString(),
proxy.invokeActorMethod("getMyId", String.class).block());
proxy.invokeMethod("getMyId", String.class).block());
}
@Test
@ -149,7 +157,7 @@ public class ActorNoStateTest {
// these should only call the actor methods for ActorChild. The implementations in ActorParent will throw.
Assert.assertEquals(
"abcabc",
proxy.invokeActorMethod("stringInStringOut", "abc", String.class).block());
proxy.invokeMethod("stringInStringOut", "abc", String.class).block());
}
@Test
@ -159,11 +167,11 @@ public class ActorNoStateTest {
// these should only call the actor methods for ActorChild. The implementations in ActorParent will throw.
Assert.assertEquals(
false,
proxy.invokeActorMethod("stringInBooleanOut", "hello world", Boolean.class).block());
proxy.invokeMethod("stringInBooleanOut", "hello world", Boolean.class).block());
Assert.assertEquals(
true,
proxy.invokeActorMethod("stringInBooleanOut", "true", Boolean.class).block());
proxy.invokeMethod("stringInBooleanOut", "true", Boolean.class).block());
}
@Test(expected = IllegalMonitorStateException.class)
@ -171,7 +179,13 @@ public class ActorNoStateTest {
ActorProxy actorProxy = createActorProxy();
// these should only call the actor methods for ActorChild. The implementations in ActorParent will throw.
actorProxy.invokeActorMethod("stringInVoidOutIntentionallyThrows", "hello world").block();
actorProxy.invokeMethod("stringInVoidOutIntentionallyThrows", "hello world").block();
}
@Test
public void testMethodNameChange() {
MyActor actor = createActorProxy(MyActor.class);
actor.dotNetMethod();
}
@Test
@ -180,7 +194,7 @@ public class ActorNoStateTest {
MyData d = new MyData("hi", 3);
// this should only call the actor methods for ActorChild. The implementations in ActorParent will throw.
MyData response = actorProxy.invokeActorMethod("classInClassOut", d, MyData.class).block();
MyData response = actorProxy.invokeMethod("classInClassOut", d, MyData.class).block();
Assert.assertEquals(
"hihi",
@ -218,7 +232,7 @@ public class ActorNoStateTest {
// Mock daprClient for ActorProxy only, not for runtime.
DaprClientStub daprClient = mock(DaprClientStub.class);
when(daprClient.invokeActorMethod(
when(daprClient.invoke(
eq(context.getActorTypeInformation().getName()),
eq(actorId.toString()),
any(),
@ -231,7 +245,7 @@ public class ActorNoStateTest {
this.manager.activateActor(actorId).block();
return new ActorProxyForTestsImpl(
return new ActorProxyImplForTests(
context.getActorTypeInformation().getName(),
actorId,
new DefaultObjectSerializer(),
@ -244,7 +258,7 @@ public class ActorNoStateTest {
// Mock daprClient for ActorProxy only, not for runtime.
DaprClientStub daprClient = mock(DaprClientStub.class);
when(daprClient.invokeActorMethod(
when(daprClient.invoke(
eq(context.getActorTypeInformation().getName()),
eq(actorId.toString()),
any(),
@ -257,13 +271,13 @@ public class ActorNoStateTest {
this.manager.activateActor(actorId).block();
ActorProxyForTestsImpl proxy = new ActorProxyForTestsImpl(
ActorProxyImplForTests proxy = new ActorProxyImplForTests(
context.getActorTypeInformation().getName(),
actorId,
new DefaultObjectSerializer(),
daprClient);
return (T) Proxy.newProxyInstance(
ActorProxyForTestsImpl.class.getClassLoader(),
ActorProxyImplForTests.class.getClassLoader(),
new Class[]{clazz},
proxy);
}
@ -271,10 +285,10 @@ public class ActorNoStateTest {
private static <T extends AbstractActor> ActorRuntimeContext createContext() {
DaprClient daprClient = mock(DaprClient.class);
when(daprClient.registerActorTimer(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.registerActorReminder(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterActorTimer(any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterActorReminder(any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.registerTimer(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.registerReminder(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterTimer(any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterReminder(any(), any(), any())).thenReturn(Mono.empty());
return new ActorRuntimeContext(
mock(ActorRuntime.class),

View File

@ -8,7 +8,7 @@ package io.dapr.actors.runtime;
import io.dapr.actors.ActorId;
import io.dapr.actors.ActorType;
import io.dapr.actors.client.ActorProxy;
import io.dapr.actors.client.ActorProxyForTestsImpl;
import io.dapr.actors.client.ActorProxyImplForTests;
import io.dapr.actors.client.DaprClientStub;
import io.dapr.serializer.DefaultObjectSerializer;
import io.dapr.utils.TypeRef;
@ -289,33 +289,33 @@ public class ActorStatefulTest {
public void happyGetSetDeleteContains() {
ActorProxy proxy = newActorProxy();
Assert.assertEquals(
proxy.getActorId().toString(), proxy.invokeActorMethod("getIdString", String.class).block());
Assert.assertFalse(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
proxy.getActorId().toString(), proxy.invokeMethod("getIdString", String.class).block());
Assert.assertFalse(proxy.invokeMethod("hasMessage", Boolean.class).block());
proxy.invokeActorMethod("setMessage", "hello world").block();
Assert.assertTrue(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
proxy.invokeMethod("setMessage", "hello world").block();
Assert.assertTrue(proxy.invokeMethod("hasMessage", Boolean.class).block());
Assert.assertEquals(
"hello world", proxy.invokeActorMethod("getMessage", String.class).block());
"hello world", proxy.invokeMethod("getMessage", String.class).block());
Assert.assertEquals(
executeSayMethod("hello world"),
proxy.invokeActorMethod("setMessage", "hello world", String.class).block());
proxy.invokeMethod("setMessage", "hello world", String.class).block());
proxy.invokeActorMethod("deleteMessage").block();
Assert.assertFalse(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
proxy.invokeMethod("deleteMessage").block();
Assert.assertFalse(proxy.invokeMethod("hasMessage", Boolean.class).block());
}
@Test(expected = IllegalStateException.class)
public void lazyGet() {
ActorProxy proxy = newActorProxy();
Assert.assertFalse(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
proxy.invokeActorMethod("setMessage", "first message").block();
Assert.assertFalse(proxy.invokeMethod("hasMessage", Boolean.class).block());
proxy.invokeMethod("setMessage", "first message").block();
// Creates the mono plan but does not call it yet.
Mono<String> getMessageCall = proxy.invokeActorMethod("getMessage", String.class);
Mono<String> getMessageCall = proxy.invokeMethod("getMessage", String.class);
proxy.invokeActorMethod("deleteMessage").block();
proxy.invokeMethod("deleteMessage").block();
// Call should fail because the message was deleted.
getMessageCall.block();
@ -324,96 +324,96 @@ public class ActorStatefulTest {
@Test
public void lazySet() {
ActorProxy proxy = newActorProxy();
Assert.assertFalse(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
Assert.assertFalse(proxy.invokeMethod("hasMessage", Boolean.class).block());
// Creates the mono plan but does not call it yet.
Mono<Void> setMessageCall = proxy.invokeActorMethod("setMessage", "first message");
Mono<Void> setMessageCall = proxy.invokeMethod("setMessage", "first message");
// No call executed yet, so message should not be set.
Assert.assertFalse(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
Assert.assertFalse(proxy.invokeMethod("hasMessage", Boolean.class).block());
setMessageCall.block();
// Now the message has been set.
Assert.assertTrue(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
Assert.assertTrue(proxy.invokeMethod("hasMessage", Boolean.class).block());
}
@Test
public void lazyContains() {
ActorProxy proxy = newActorProxy();
Assert.assertFalse(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
Assert.assertFalse(proxy.invokeMethod("hasMessage", Boolean.class).block());
// Creates the mono plan but does not call it yet.
Mono<Boolean> hasMessageCall = proxy.invokeActorMethod("hasMessage", Boolean.class);
Mono<Boolean> hasMessageCall = proxy.invokeMethod("hasMessage", Boolean.class);
// Sets the message.
proxy.invokeActorMethod("setMessage", "hello world").block();
proxy.invokeMethod("setMessage", "hello world").block();
// Now we check if message is set.
hasMessageCall.block();
// Now the message should be set.
Assert.assertTrue(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
Assert.assertTrue(proxy.invokeMethod("hasMessage", Boolean.class).block());
}
@Test
public void lazyDelete() {
ActorProxy proxy = newActorProxy();
Assert.assertFalse(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
Assert.assertFalse(proxy.invokeMethod("hasMessage", Boolean.class).block());
proxy.invokeActorMethod("setMessage", "first message").block();
proxy.invokeMethod("setMessage", "first message").block();
// Message is set.
Assert.assertTrue(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
Assert.assertTrue(proxy.invokeMethod("hasMessage", Boolean.class).block());
// Created the mono plan but does not execute it yet.
Mono<Void> deleteMessageCall = proxy.invokeActorMethod("deleteMessage");
Mono<Void> deleteMessageCall = proxy.invokeMethod("deleteMessage");
// Message is still set.
Assert.assertTrue(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
Assert.assertTrue(proxy.invokeMethod("hasMessage", Boolean.class).block());
deleteMessageCall.block();
// Now message is not set.
Assert.assertFalse(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
Assert.assertFalse(proxy.invokeMethod("hasMessage", Boolean.class).block());
}
@Test
public void lazyAdd() {
ActorProxy proxy = newActorProxy();
Assert.assertFalse(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
Assert.assertFalse(proxy.invokeMethod("hasMessage", Boolean.class).block());
proxy.invokeActorMethod("setMessage", "first message").block();
proxy.invokeMethod("setMessage", "first message").block();
// Message is set.
Assert.assertTrue(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
Assert.assertTrue(proxy.invokeMethod("hasMessage", Boolean.class).block());
// Created the mono plan but does not execute it yet.
Mono<Void> addMessageCall = proxy.invokeActorMethod("addMessage", "second message");
Mono<Void> addMessageCall = proxy.invokeMethod("addMessage", "second message");
// Message is still set.
Assert.assertEquals("first message",
proxy.invokeActorMethod("getMessage", String.class).block());
proxy.invokeMethod("getMessage", String.class).block());
// Delete message
proxy.invokeActorMethod("deleteMessage").block();
proxy.invokeMethod("deleteMessage").block();
// Should work since previous message was deleted.
addMessageCall.block();
// New message is still set.
Assert.assertEquals("second message",
proxy.invokeActorMethod("getMessage", String.class).block());
proxy.invokeMethod("getMessage", String.class).block());
}
@Test
public void onActivateAndOnDeactivate() {
ActorProxy proxy = newActorProxy();
Assert.assertTrue(proxy.invokeActorMethod("isActive", Boolean.class).block());
Assert.assertTrue(proxy.invokeMethod("isActive", Boolean.class).block());
Assert.assertFalse(DEACTIVATED_ACTOR_IDS.contains(proxy.getActorId().toString()));
proxy.invokeActorMethod("hasMessage", Boolean.class).block();
proxy.invokeMethod("hasMessage", Boolean.class).block();
this.manager.deactivateActor(proxy.getActorId()).block();
@ -424,15 +424,15 @@ public class ActorStatefulTest {
public void onPreMethodAndOnPostMethod() {
ActorProxy proxy = newActorProxy();
proxy.invokeActorMethod("hasMessage", Boolean.class).block();
proxy.invokeMethod("hasMessage", Boolean.class).block();
MyMethodContext preContext =
proxy.invokeActorMethod("getPreCallMethodContext", MyMethodContext.class).block();
proxy.invokeMethod("getPreCallMethodContext", MyMethodContext.class).block();
Assert.assertEquals("hasMessage", preContext.getName());
Assert.assertEquals(ActorCallType.ACTOR_INTERFACE_METHOD.toString(), preContext.getType());
MyMethodContext postContext =
proxy.invokeActorMethod("getPostCallMethodContext", MyMethodContext.class).block();
proxy.invokeMethod("getPostCallMethodContext", MyMethodContext.class).block();
Assert.assertEquals("hasMessage", postContext.getName());
Assert.assertEquals(ActorCallType.ACTOR_INTERFACE_METHOD.toString(), postContext.getType());
}
@ -444,12 +444,12 @@ public class ActorStatefulTest {
this.manager.invokeTimer(proxy.getActorId(), "mytimer", "{ \"callback\": \"hasMessage\" }".getBytes()).block();
MyMethodContext preContext =
proxy.invokeActorMethod("getPreCallMethodContext", MyMethodContext.class).block();
proxy.invokeMethod("getPreCallMethodContext", MyMethodContext.class).block();
Assert.assertEquals("mytimer", preContext.getName());
Assert.assertEquals(ActorCallType.TIMER_METHOD.toString(), preContext.getType());
MyMethodContext postContext =
proxy.invokeActorMethod("getPostCallMethodContext", MyMethodContext.class).block();
proxy.invokeMethod("getPostCallMethodContext", MyMethodContext.class).block();
Assert.assertEquals("mytimer", postContext.getName());
Assert.assertEquals(ActorCallType.TIMER_METHOD.toString(), postContext.getType());
}
@ -467,7 +467,7 @@ public class ActorStatefulTest {
public void invokeTimerAfterUnregister() {
ActorProxy proxy = newActorProxy();
proxy.invokeActorMethod("unregisterTimerAndReminder").block();
proxy.invokeMethod("unregisterTimerAndReminder").block();
// This call succeeds because the SDK does not control register/unregister timer, the Dapr runtime does.
this.manager.invokeTimer(proxy.getActorId(), "mytimer", "{ \"callback\": \"hasMessage\" }".getBytes()).block();
@ -490,12 +490,12 @@ public class ActorStatefulTest {
this.manager.invokeReminder(proxy.getActorId(), "myreminder", params).block();
MyMethodContext preContext =
proxy.invokeActorMethod("getPreCallMethodContext", MyMethodContext.class).block();
proxy.invokeMethod("getPreCallMethodContext", MyMethodContext.class).block();
Assert.assertEquals("myreminder", preContext.getName());
Assert.assertEquals(ActorCallType.REMINDER_METHOD.toString(), preContext.getType());
MyMethodContext postContext =
proxy.invokeActorMethod("getPostCallMethodContext", MyMethodContext.class).block();
proxy.invokeMethod("getPostCallMethodContext", MyMethodContext.class).block();
Assert.assertEquals("myreminder", postContext.getName());
Assert.assertEquals(ActorCallType.REMINDER_METHOD.toString(), postContext.getType());
}
@ -517,8 +517,8 @@ public class ActorStatefulTest {
MyMethodContext expectedContext = new MyMethodContext().setName("MyName").setType("MyType");
proxy.invokeActorMethod("setMethodContext", expectedContext).block();
MyMethodContext context = proxy.invokeActorMethod("getMethodContext", MyMethodContext.class).block();
proxy.invokeMethod("setMethodContext", expectedContext).block();
MyMethodContext context = proxy.invokeMethod("getMethodContext", MyMethodContext.class).block();
Assert.assertEquals(expectedContext.getName(), context.getName());
Assert.assertEquals(expectedContext.getType(), context.getType());
@ -528,8 +528,8 @@ public class ActorStatefulTest {
public void intTypeRequestResponseInStateStore() {
ActorProxy proxy = newActorProxy();
Assert.assertEquals(1, (int)proxy.invokeActorMethod("incrementAndGetCount", 1, int.class).block());
Assert.assertEquals(6, (int)proxy.invokeActorMethod("incrementAndGetCount", 5, int.class).block());
Assert.assertEquals(1, (int)proxy.invokeMethod("incrementAndGetCount", 1, int.class).block());
Assert.assertEquals(6, (int)proxy.invokeMethod("incrementAndGetCount", 5, int.class).block());
}
@Test(expected = NumberFormatException.class)
@ -537,68 +537,68 @@ public class ActorStatefulTest {
ActorProxy proxy = newActorProxy();
// Zero is a magic input that will make method throw an exception.
proxy.invokeActorMethod("incrementAndGetCount", 0, int.class).block();
proxy.invokeMethod("incrementAndGetCount", 0, int.class).block();
}
@Test(expected = IllegalStateException.class)
public void intTypeWithRuntimeException() {
ActorProxy proxy = newActorProxy();
proxy.invokeActorMethod("getCountButThrowsException", int.class).block();
proxy.invokeMethod("getCountButThrowsException", int.class).block();
}
@Test(expected = IllegalStateException.class)
public void actorRuntimeException() {
ActorProxy proxy = newActorProxy();
Assert.assertFalse(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
Assert.assertFalse(proxy.invokeMethod("hasMessage", Boolean.class).block());
proxy.invokeActorMethod("forceDuplicateException").block();
proxy.invokeMethod("forceDuplicateException").block();
}
@Test(expected = IllegalCharsetNameException.class)
public void actorMethodException() {
ActorProxy proxy = newActorProxy();
Assert.assertFalse(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
Assert.assertFalse(proxy.invokeMethod("hasMessage", Boolean.class).block());
proxy.invokeActorMethod("throwsWithoutSaving").block();
proxy.invokeMethod("throwsWithoutSaving").block();
Assert.assertFalse(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
Assert.assertFalse(proxy.invokeMethod("hasMessage", Boolean.class).block());
}
@Test
public void rollbackChanges() {
ActorProxy proxy = newActorProxy();
Assert.assertFalse(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
Assert.assertFalse(proxy.invokeMethod("hasMessage", Boolean.class).block());
// Runs a method that will add one message but fail because tries to add a second one.
proxy.invokeActorMethod("forceDuplicateException")
proxy.invokeMethod("forceDuplicateException")
.onErrorResume(throwable -> Mono.empty())
.block();
// No message is set
Assert.assertFalse(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
Assert.assertFalse(proxy.invokeMethod("hasMessage", Boolean.class).block());
}
@Test
public void partialChanges() {
ActorProxy proxy = newActorProxy();
Assert.assertFalse(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
Assert.assertFalse(proxy.invokeMethod("hasMessage", Boolean.class).block());
// Runs a method that will add one message, commit but fail because tries to add a second one.
proxy.invokeActorMethod("forcePartialChange")
proxy.invokeMethod("forcePartialChange")
.onErrorResume(throwable -> Mono.empty())
.block();
// Message is set.
Assert.assertTrue(proxy.invokeActorMethod("hasMessage", Boolean.class).block());
Assert.assertTrue(proxy.invokeMethod("hasMessage", Boolean.class).block());
// It is first message and not the second due to a save() in the middle but an exception in the end.
Assert.assertEquals("first message",
proxy.invokeActorMethod("getMessage", String.class).block());
proxy.invokeMethod("getMessage", String.class).block());
}
private ActorProxy newActorProxy() {
@ -607,7 +607,7 @@ public class ActorStatefulTest {
// Mock daprClient for ActorProxy only, not for runtime.
DaprClientStub daprClient = mock(DaprClientStub.class);
when(daprClient.invokeActorMethod(
when(daprClient.invoke(
eq(context.getActorTypeInformation().getName()),
eq(actorId.toString()),
any(),
@ -620,7 +620,7 @@ public class ActorStatefulTest {
this.manager.activateActor(actorId).block();
return new ActorProxyForTestsImpl(
return new ActorProxyImplForTests(
context.getActorTypeInformation().getName(),
actorId,
new DefaultObjectSerializer(),
@ -644,10 +644,10 @@ public class ActorStatefulTest {
private static <T extends AbstractActor> ActorRuntimeContext createContext() {
DaprClient daprClient = mock(DaprClient.class);
when(daprClient.registerActorTimer(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.registerActorReminder(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterActorTimer(any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterActorReminder(any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.registerTimer(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.registerReminder(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterTimer(any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterReminder(any(), any(), any())).thenReturn(Mono.empty());
return new ActorRuntimeContext(
mock(ActorRuntime.class),

View File

@ -56,7 +56,7 @@ public class DaprGrpcClientTest {
ACTOR_ID,
"MyKey"
)))).thenReturn(settableFuture);
Mono<byte[]> result = client.getActorState(ACTOR_TYPE, ACTOR_ID, "MyKey");
Mono<byte[]> result = client.getState(ACTOR_TYPE, ACTOR_ID, "MyKey");
Exception exception = assertThrows(Exception.class, () -> result.block());
assertTrue(exception.getCause().getCause() instanceof ArithmeticException);
}
@ -72,7 +72,7 @@ public class DaprGrpcClientTest {
ACTOR_ID,
"MyKey"
)))).thenReturn(settableFuture);
Mono<byte[]> result = client.getActorState(ACTOR_TYPE, ACTOR_ID, "MyKey");
Mono<byte[]> result = client.getState(ACTOR_TYPE, ACTOR_ID, "MyKey");
assertArrayEquals(data, result.block());
}
@ -86,7 +86,7 @@ public class DaprGrpcClientTest {
ACTOR_ID,
new ArrayList<>()
)))).thenReturn(settableFuture);
Mono<Void> result = client.saveActorStateTransactionally(ACTOR_TYPE, ACTOR_ID, new ArrayList<>());
Mono<Void> result = client.saveStateTransactionally(ACTOR_TYPE, ACTOR_ID, new ArrayList<>());
Exception exception = assertThrows(Exception.class, () -> result.block());
assertTrue(exception.getCause().getCause() instanceof ArithmeticException);
}
@ -106,7 +106,7 @@ public class DaprGrpcClientTest {
ACTOR_ID,
Arrays.asList(operations)
)))).thenReturn(settableFuture);
Mono<Void> result = client.saveActorStateTransactionally(ACTOR_TYPE, ACTOR_ID, Arrays.asList(operations));
Mono<Void> result = client.saveStateTransactionally(ACTOR_TYPE, ACTOR_ID, Arrays.asList(operations));
result.block();
}
@ -125,7 +125,7 @@ public class DaprGrpcClientTest {
ACTOR_ID,
Arrays.asList(operations)
)))).thenReturn(settableFuture);
Mono<Void> result = client.saveActorStateTransactionally(ACTOR_TYPE, ACTOR_ID, Arrays.asList(operations));
Mono<Void> result = client.saveStateTransactionally(ACTOR_TYPE, ACTOR_ID, Arrays.asList(operations));
result.block();
}
@ -136,7 +136,7 @@ public class DaprGrpcClientTest {
new ActorStateOperation("delete", "mykey", null),
};
Mono<Void> result = client.saveActorStateTransactionally(ACTOR_TYPE, ACTOR_ID, Arrays.asList(operations));
Mono<Void> result = client.saveStateTransactionally(ACTOR_TYPE, ACTOR_ID, Arrays.asList(operations));
assertThrows(IllegalArgumentException.class, () -> result.block());
}
@ -161,7 +161,7 @@ public class DaprGrpcClientTest {
assertEquals(DurationUtils.convertDurationToDaprFormat(params.getPeriod()), argument.getPeriod());
return true;
}))).thenReturn(settableFuture);
Mono<Void> result = client.registerActorReminder(ACTOR_TYPE, ACTOR_ID, reminderName, params);
Mono<Void> result = client.registerReminder(ACTOR_TYPE, ACTOR_ID, reminderName, params);
result.block();
}
@ -178,7 +178,7 @@ public class DaprGrpcClientTest {
assertEquals(reminderName, argument.getName());
return true;
}))).thenReturn(settableFuture);
Mono<Void> result = client.unregisterActorReminder(ACTOR_TYPE, ACTOR_ID, reminderName);
Mono<Void> result = client.unregisterReminder(ACTOR_TYPE, ACTOR_ID, reminderName);
result.block();
}
@ -205,7 +205,7 @@ public class DaprGrpcClientTest {
assertEquals(DurationUtils.convertDurationToDaprFormat(params.getPeriod()), argument.getPeriod());
return true;
}))).thenReturn(settableFuture);
Mono<Void> result = client.registerActorTimer(ACTOR_TYPE, ACTOR_ID, timerName, params);
Mono<Void> result = client.registerTimer(ACTOR_TYPE, ACTOR_ID, timerName, params);
result.block();
}
@ -222,7 +222,7 @@ public class DaprGrpcClientTest {
assertEquals(timerName, argument.getName());
return true;
}))).thenReturn(settableFuture);
Mono<Void> result = client.unregisterActorTimer(ACTOR_TYPE, ACTOR_ID, timerName);
Mono<Void> result = client.unregisterTimer(ACTOR_TYPE, ACTOR_ID, timerName);
result.block();
}

View File

@ -54,7 +54,7 @@ public class DaprHttpClientTest {
.respond(EXPECTED_RESULT);
DaprHttp daprHttp = new DaprHttpProxy(Properties.SIDECAR_IP.get(), 3000, okHttpClient);
DaprHttpClient = new DaprHttpClient(daprHttp);
Mono<byte[]> mono = DaprHttpClient.getActorState("DemoActor", "1", "order");
Mono<byte[]> mono = DaprHttpClient.getState("DemoActor", "1", "order");
assertEquals(new String(mono.block()), EXPECTED_RESULT);
}
@ -67,7 +67,7 @@ public class DaprHttpClientTest {
DaprHttp daprHttp = new DaprHttpProxy(Properties.SIDECAR_IP.get(), 3000, okHttpClient);
DaprHttpClient = new DaprHttpClient(daprHttp);
List<ActorStateOperation> ops = Collections.singletonList(new ActorStateOperation("UPSERT", "key", "value"));
Mono<Void> mono = DaprHttpClient.saveActorStateTransactionally("DemoActor", "1", ops);
Mono<Void> mono = DaprHttpClient.saveStateTransactionally("DemoActor", "1", ops);
assertNull(mono.block());
}
@ -79,7 +79,7 @@ public class DaprHttpClientTest {
DaprHttp daprHttp = new DaprHttpProxy(Properties.SIDECAR_IP.get(), 3000, okHttpClient);
DaprHttpClient = new DaprHttpClient(daprHttp);
Mono<Void> mono =
DaprHttpClient.registerActorReminder(
DaprHttpClient.registerReminder(
"DemoActor",
"1",
"reminder",
@ -94,7 +94,7 @@ public class DaprHttpClientTest {
.respond(EXPECTED_RESULT);
DaprHttp daprHttp = new DaprHttpProxy(Properties.SIDECAR_IP.get(), 3000, okHttpClient);
DaprHttpClient = new DaprHttpClient(daprHttp);
Mono<Void> mono = DaprHttpClient.unregisterActorReminder("DemoActor", "1", "reminder");
Mono<Void> mono = DaprHttpClient.unregisterReminder("DemoActor", "1", "reminder");
assertNull(mono.block());
}
@ -127,7 +127,7 @@ public class DaprHttpClientTest {
DaprHttp daprHttp = new DaprHttpProxy(Properties.SIDECAR_IP.get(), 3000, okHttpClient);
DaprHttpClient = new DaprHttpClient(daprHttp);
Mono<Void> mono =
DaprHttpClient.registerActorTimer(
DaprHttpClient.registerTimer(
"DemoActor",
"1",
"timer",
@ -146,7 +146,7 @@ public class DaprHttpClientTest {
.respond(EXPECTED_RESULT);
DaprHttp daprHttp = new DaprHttpProxy(Properties.SIDECAR_IP.get(), 3000, okHttpClient);
DaprHttpClient = new DaprHttpClient(daprHttp);
Mono<Void> mono = DaprHttpClient.unregisterActorTimer("DemoActor", "1", "timer");
Mono<Void> mono = DaprHttpClient.unregisterTimer("DemoActor", "1", "timer");
assertNull(mono.block());
}
}

View File

@ -78,7 +78,7 @@ public class DaprStateAsyncProviderTest {
public void happyCaseApply() {
DaprClient daprClient = mock(DaprClient.class);
when(daprClient
.saveActorStateTransactionally(
.saveStateTransactionally(
eq("MyActor"),
eq("123"),
argThat(operations -> {
@ -133,41 +133,41 @@ public class DaprStateAsyncProviderTest {
createUpdateChange("bytes", new byte[]{0x1}))
.block();
verify(daprClient).saveActorStateTransactionally(eq("MyActor"), eq("123"), any());
verify(daprClient).saveStateTransactionally(eq("MyActor"), eq("123"), any());
}
@Test
public void happyCaseLoad() throws Exception {
DaprClient daprClient = mock(DaprClient.class);
when(daprClient
.getActorState(any(), any(), eq("name")))
.getState(any(), any(), eq("name")))
.thenReturn(Mono.just(SERIALIZER.serialize("Jon Doe")));
when(daprClient
.getActorState(any(), any(), eq("zipcode")))
.getState(any(), any(), eq("zipcode")))
.thenReturn(Mono.just(SERIALIZER.serialize(98021)));
when(daprClient
.getActorState(any(), any(), eq("goals")))
.getState(any(), any(), eq("goals")))
.thenReturn(Mono.just(SERIALIZER.serialize(98)));
when(daprClient
.getActorState(any(), any(), eq("balance")))
.getState(any(), any(), eq("balance")))
.thenReturn(Mono.just(SERIALIZER.serialize(46.55)));
when(daprClient
.getActorState(any(), any(), eq("active")))
.getState(any(), any(), eq("active")))
.thenReturn(Mono.just(SERIALIZER.serialize(true)));
when(daprClient
.getActorState(any(), any(), eq("customer")))
.getState(any(), any(), eq("customer")))
.thenReturn(Mono.just("{ \"id\": 1000, \"name\": \"Roxane\"}".getBytes()));
when(daprClient
.getActorState(any(), any(), eq("anotherCustomer")))
.getState(any(), any(), eq("anotherCustomer")))
.thenReturn(Mono.just("{ \"id\": 2000, \"name\": \"Max\"}".getBytes()));
when(daprClient
.getActorState(any(), any(), eq("nullCustomer")))
.getState(any(), any(), eq("nullCustomer")))
.thenReturn(Mono.empty());
when(daprClient
.getActorState(any(), any(), eq("bytes")))
.getState(any(), any(), eq("bytes")))
.thenReturn(Mono.just("\"QQ==\"".getBytes()));
when(daprClient
.getActorState(any(), any(), eq("emptyBytes")))
.getState(any(), any(), eq("emptyBytes")))
.thenReturn(Mono.just(new byte[0]));
DaprStateAsyncProvider provider = new DaprStateAsyncProvider(daprClient, SERIALIZER);
@ -203,33 +203,33 @@ public class DaprStateAsyncProviderTest {
// Keys that exists.
when(daprClient
.getActorState(any(), any(), eq("name")))
.getState(any(), any(), eq("name")))
.thenReturn(Mono.just("Jon Doe".getBytes()));
when(daprClient
.getActorState(any(), any(), eq("zipcode")))
.getState(any(), any(), eq("zipcode")))
.thenReturn(Mono.just("98021".getBytes()));
when(daprClient
.getActorState(any(), any(), eq("goals")))
.getState(any(), any(), eq("goals")))
.thenReturn(Mono.just("98".getBytes()));
when(daprClient
.getActorState(any(), any(), eq("balance")))
.getState(any(), any(), eq("balance")))
.thenReturn(Mono.just("46.55".getBytes()));
when(daprClient
.getActorState(any(), any(), eq("active")))
.getState(any(), any(), eq("active")))
.thenReturn(Mono.just("true".getBytes()));
when(daprClient
.getActorState(any(), any(), eq("customer")))
.getState(any(), any(), eq("customer")))
.thenReturn(Mono.just("{ \"id\": \"3000\", \"name\": \"Ely\" }".getBytes()));
// Keys that do not exist.
when(daprClient
.getActorState(any(), any(), eq("Does not exist")))
.getState(any(), any(), eq("Does not exist")))
.thenReturn(Mono.empty());
when(daprClient
.getActorState(any(), any(), eq("NAME")))
.getState(any(), any(), eq("NAME")))
.thenReturn(Mono.empty());
when(daprClient
.getActorState(any(), any(), eq(null)))
.getState(any(), any(), eq(null)))
.thenReturn(Mono.empty());
DaprStateAsyncProvider provider = new DaprStateAsyncProvider(daprClient, SERIALIZER);

View File

@ -8,7 +8,7 @@ package io.dapr.actors.runtime;
import io.dapr.actors.ActorId;
import io.dapr.actors.ActorType;
import io.dapr.actors.client.ActorProxy;
import io.dapr.actors.client.ActorProxyForTestsImpl;
import io.dapr.actors.client.ActorProxyImplForTests;
import io.dapr.actors.client.DaprClientStub;
import io.dapr.serializer.DefaultObjectSerializer;
import org.junit.Assert;
@ -223,7 +223,7 @@ public class DerivedActorTest {
// these should only call the actor methods for ActorChild. The implementations in ActorParent will throw.
Assert.assertEquals(
"abcabc",
proxy.invokeActorMethod("stringInStringOut", "abc", String.class).block());
proxy.invokeMethod("stringInStringOut", "abc", String.class).block());
}
@Test
@ -233,11 +233,11 @@ public class DerivedActorTest {
// these should only call the actor methods for ActorChild. The implementations in ActorParent will throw.
Assert.assertEquals(
false,
proxy.invokeActorMethod("stringInBooleanOut", "hello world", Boolean.class).block());
proxy.invokeMethod("stringInBooleanOut", "hello world", Boolean.class).block());
Assert.assertEquals(
true,
proxy.invokeActorMethod("stringInBooleanOut", "true", Boolean.class).block());
proxy.invokeMethod("stringInBooleanOut", "true", Boolean.class).block());
}
@Test
@ -247,14 +247,14 @@ public class DerivedActorTest {
// stringInVoidOut() has not been invoked so this is false
Assert.assertEquals(
false,
actorProxy.invokeActorMethod("methodReturningVoidInvoked", Boolean.class).block());
actorProxy.invokeMethod("methodReturningVoidInvoked", Boolean.class).block());
// these should only call the actor methods for ActorChild. The implementations in ActorParent will throw.
actorProxy.invokeActorMethod("stringInVoidOut", "hello world").block();
actorProxy.invokeMethod("stringInVoidOut", "hello world").block();
Assert.assertEquals(
true,
actorProxy.invokeActorMethod("methodReturningVoidInvoked", Boolean.class).block());
actorProxy.invokeMethod("methodReturningVoidInvoked", Boolean.class).block());
}
@Test(expected = IllegalMonitorStateException.class)
@ -262,7 +262,7 @@ public class DerivedActorTest {
ActorProxy actorProxy = createActorProxyForActorChild();
// these should only call the actor methods for ActorChild. The implementations in ActorParent will throw.
actorProxy.invokeActorMethod("stringInVoidOutIntentionallyThrows", "hello world").block();
actorProxy.invokeMethod("stringInVoidOutIntentionallyThrows", "hello world").block();
}
@Test
@ -271,7 +271,7 @@ public class DerivedActorTest {
MyData d = new MyData("hi", 3);
// this should only call the actor methods for ActorChild. The implementations in ActorParent will throw.
MyData response = actorProxy.invokeActorMethod("classInClassOut", d, MyData.class).block();
MyData response = actorProxy.invokeMethod("classInClassOut", d, MyData.class).block();
Assert.assertEquals(
"hihi",
@ -288,26 +288,26 @@ public class DerivedActorTest {
Assert.assertEquals(
"www",
actorProxy.invokeActorMethod("onlyImplementedInParentStringInStringOut", "w", String.class).block());
actorProxy.invokeMethod("onlyImplementedInParentStringInStringOut", "w", String.class).block());
Assert.assertEquals(
true,
actorProxy.invokeActorMethod("onlyImplementedInParentStringInBooleanOut", "icecream", Boolean.class).block());
actorProxy.invokeMethod("onlyImplementedInParentStringInBooleanOut", "icecream", Boolean.class).block());
// onlyImplementedInParentStringInVoidOut() has not been invoked so this is false
Assert.assertEquals(
false,
actorProxy.invokeActorMethod("methodReturningVoidInvoked", Boolean.class).block());
actorProxy.invokeMethod("methodReturningVoidInvoked", Boolean.class).block());
actorProxy.invokeActorMethod("onlyImplementedInParentStringInVoidOut", "icecream", Boolean.class).block();
actorProxy.invokeMethod("onlyImplementedInParentStringInVoidOut", "icecream", Boolean.class).block();
// now it should return true.
Assert.assertEquals(
true,
actorProxy.invokeActorMethod("methodReturningVoidInvoked", Boolean.class).block());
actorProxy.invokeMethod("methodReturningVoidInvoked", Boolean.class).block());
MyData d = new MyData("hi", 3);
MyData response = actorProxy.invokeActorMethod("onlyImplementedInParentClassInClassOut", d, MyData.class).block();
MyData response = actorProxy.invokeMethod("onlyImplementedInParentClassInClassOut", d, MyData.class).block();
Assert.assertEquals(
"hihihi",
@ -327,7 +327,7 @@ public class DerivedActorTest {
// Mock daprClient for ActorProxy only, not for runtime.
DaprClientStub daprClient = mock(DaprClientStub.class);
when(daprClient.invokeActorMethod(
when(daprClient.invoke(
eq(context.getActorTypeInformation().getName()),
eq(actorId.toString()),
any(),
@ -340,7 +340,7 @@ public class DerivedActorTest {
this.manager.activateActor(actorId).block();
return new ActorProxyForTestsImpl(
return new ActorProxyImplForTests(
context.getActorTypeInformation().getName(),
actorId,
new DefaultObjectSerializer(),
@ -350,10 +350,10 @@ public class DerivedActorTest {
private static <T extends AbstractActor> ActorRuntimeContext createContext() {
DaprClient daprClient = mock(DaprClient.class);
when(daprClient.registerActorTimer(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.registerActorReminder(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterActorTimer(any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterActorReminder(any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.registerTimer(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.registerReminder(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterTimer(any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterReminder(any(), any(), any())).thenReturn(Mono.empty());
return new ActorRuntimeContext(
mock(ActorRuntime.class),

View File

@ -8,7 +8,7 @@ package io.dapr.actors.runtime;
import io.dapr.actors.ActorId;
import io.dapr.actors.ActorType;
import io.dapr.actors.client.ActorProxy;
import io.dapr.actors.client.ActorProxyForTestsImpl;
import io.dapr.actors.client.ActorProxyImplForTests;
import io.dapr.actors.client.DaprClientStub;
import io.dapr.serializer.DefaultObjectSerializer;
import org.junit.Assert;
@ -121,7 +121,7 @@ public class ThrowFromPreAndPostActorMethodsTest {
// these should only call the actor methods for ActorChild. The implementations in ActorParent will throw.
Assert.assertEquals(
false,
proxy.invokeActorMethod("stringInBooleanOut", "hello world", Boolean.class).block());
proxy.invokeMethod("stringInBooleanOut", "hello world", Boolean.class).block());
}
// IllegalMonitorStateException should be intentionally thrown. This type was chosen for this test just because
@ -133,7 +133,7 @@ public class ThrowFromPreAndPostActorMethodsTest {
// these should only call the actor methods for ActorChild. The implementations in ActorParent will throw.
Assert.assertEquals(
true,
proxy.invokeActorMethod("stringInBooleanOut", "true", Boolean.class).block());
proxy.invokeMethod("stringInBooleanOut", "true", Boolean.class).block());
}
private static ActorId newActorId() {
@ -146,7 +146,7 @@ public class ThrowFromPreAndPostActorMethodsTest {
// Mock daprClient for ActorProxy only, not for runtime.
DaprClientStub daprClient = mock(DaprClientStub.class);
when(daprClient.invokeActorMethod(
when(daprClient.invoke(
eq(context.getActorTypeInformation().getName()),
eq(actorId.toString()),
any(),
@ -159,7 +159,7 @@ public class ThrowFromPreAndPostActorMethodsTest {
this.manager.activateActor(actorId).block();
return new ActorProxyForTestsImpl(
return new ActorProxyImplForTests(
context.getActorTypeInformation().getName(),
actorId,
new DefaultObjectSerializer(),
@ -169,10 +169,10 @@ public class ThrowFromPreAndPostActorMethodsTest {
private static <T extends AbstractActor> ActorRuntimeContext createContext() {
DaprClient daprClient = mock(DaprClient.class);
when(daprClient.registerActorTimer(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.registerActorReminder(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterActorTimer(any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterActorReminder(any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.registerTimer(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.registerReminder(any(), any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterTimer(any(), any(), any())).thenReturn(Mono.empty());
when(daprClient.unregisterReminder(any(), any(), any())).thenReturn(Mono.empty());
return new ActorRuntimeContext(
mock(ActorRuntime.class),

View File

@ -29,8 +29,21 @@
<properties>
<maven.deploy.skip>false</maven.deploy.skip>
<springboot.version>2.3.5.RELEASE</springboot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${springboot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.dapr</groupId>
@ -88,6 +101,17 @@
<version>5.2.10.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
</dependencies>
<build>

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License.
*/
package io.dapr.springboot;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* Dapr's Spring Boot AutoConfiguration.
*/
@Configuration
@ConditionalOnWebApplication
@ComponentScan("io.dapr.springboot")
public class DaprAutoConfiguration {
}

View File

@ -7,11 +7,8 @@ package io.dapr.springboot;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.dapr.Topic;
import io.dapr.client.ObjectSerializer;
import io.dapr.serializer.DefaultObjectSerializer;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

View File

@ -12,7 +12,6 @@ import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

View File

@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
io.dapr.springboot.DaprAutoConfiguration

View File

@ -0,0 +1 @@
myroot

View File

@ -4,6 +4,7 @@ metadata:
name: sample123
spec:
type: bindings.kafka
version: 1
metadata:
# Kafka broker connection setting
- name: brokers

View File

@ -4,6 +4,7 @@ metadata:
name: messagebus
spec:
type: pubsub.redis
version: 1
metadata:
- name: redisHost
value: localhost:6379

View File

@ -4,6 +4,7 @@ metadata:
name: statestore
spec:
type: state.redis
version: 1
metadata:
- name: redisHost
value: localhost:6379

View File

@ -4,12 +4,13 @@ metadata:
name: vault
spec:
type: secretstores.hashicorp.vault
version: 1
metadata:
- name: vaultAddr
value: "http://127.0.0.1:8200"
- name: skipVerify
value : true
- name: vaultTokenMountPath
value : "/tmp/.hashicorp_vault_token"
value : ".hashicorp_vault_token"
- name: vaultKVPrefix
value : "dapr"

View File

@ -16,6 +16,6 @@ public class DaprClientHttpUtils {
String actorType,
String actorId,
String reminderName) throws Exception {
new DaprHttpClient(client).unregisterActorReminder(actorType, actorId, reminderName).block();
new DaprHttpClient(client).unregisterReminder(actorType, actorId, reminderName).block();
}
}

View File

@ -5,6 +5,7 @@
package io.dapr.it;
import io.dapr.client.DaprApiProtocol;
import io.dapr.config.Properties;
import java.io.IOException;
@ -19,7 +20,7 @@ import static io.dapr.it.Retry.callWithRetry;
public class AppRun implements Stoppable {
private static final String APP_COMMAND =
"mvn exec:java -D exec.mainClass=%s -D exec.classpathScope=test -D exec.args=\"%s\" -D dapr.grpc.enabled=%b";
"mvn exec:java -D exec.mainClass=%s -D exec.classpathScope=test -D exec.args=\"%s\" -D %s=%s -D %s=%s";
private final DaprPorts ports;
@ -31,10 +32,10 @@ public class AppRun implements Stoppable {
String successMessage,
Class serviceClass,
int maxWaitMilliseconds,
boolean useGRPC) {
DaprApiProtocol protocol) {
this.command = new Command(
successMessage,
buildCommand(serviceClass, ports, useGRPC),
buildCommand(serviceClass, ports, protocol),
new HashMap<>() {{
put("DAPR_HTTP_PORT", ports.getHttpPort().toString());
put("DAPR_GRPC_PORT", ports.getGrpcPort().toString());
@ -72,10 +73,11 @@ public class AppRun implements Stoppable {
}
}
private static String buildCommand(Class serviceClass, DaprPorts ports, boolean useGRPC) {
private static String buildCommand(Class serviceClass, DaprPorts ports, DaprApiProtocol protocol) {
return String.format(APP_COMMAND, serviceClass.getCanonicalName(),
ports.getAppPort() != null ? ports.getAppPort().toString() : "",
useGRPC);
Properties.API_PROTOCOL.getName(), protocol,
Properties.API_METHOD_INVOCATION_PROTOCOL.getName(), protocol);
}
private static void assertListeningOnPort(int port) {

View File

@ -5,12 +5,11 @@
package io.dapr.it;
import io.dapr.actors.client.ActorClient;
import io.dapr.client.DaprApiProtocol;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.junit.AfterClass;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
@ -24,7 +23,7 @@ public abstract class BaseIT {
private static final Queue<Stoppable> TO_BE_STOPPED = new LinkedList<>();
private static final Queue<Closeable> TO_BE_CLOSED = new LinkedList<>();
private static final Queue<AutoCloseable> TO_BE_CLOSED = new LinkedList<>();
protected static DaprRun startDaprApp(
String testName,
@ -32,7 +31,7 @@ public abstract class BaseIT {
Class serviceClass,
Boolean useAppPort,
int maxWaitMilliseconds) throws Exception {
return startDaprApp(testName, successMessage, serviceClass, useAppPort, maxWaitMilliseconds, true);
return startDaprApp(testName, successMessage, serviceClass, useAppPort, maxWaitMilliseconds, DaprApiProtocol.GRPC);
}
protected static DaprRun startDaprApp(
@ -41,14 +40,15 @@ public abstract class BaseIT {
Class serviceClass,
Boolean useAppPort,
int maxWaitMilliseconds,
boolean useGRPC) throws Exception {
return startDaprApp(testName, successMessage, serviceClass, useAppPort, true, maxWaitMilliseconds, useGRPC);
DaprApiProtocol protocol) throws Exception {
return startDaprApp(testName, successMessage, serviceClass, useAppPort, true, maxWaitMilliseconds, protocol);
}
protected static DaprRun startDaprApp(
String testName,
int maxWaitMilliseconds) throws Exception {
return startDaprApp(testName, "You're up and running!", null, false, true, maxWaitMilliseconds, true);
return startDaprApp(
testName, "You're up and running!", null, false, true, maxWaitMilliseconds, DaprApiProtocol.GRPC);
}
protected static DaprRun startDaprApp(
@ -58,13 +58,13 @@ public abstract class BaseIT {
Boolean useAppPort,
Boolean useDaprPorts,
int maxWaitMilliseconds,
boolean useGRPC) throws Exception {
DaprApiProtocol protocol) throws Exception {
DaprRun.Builder builder = new DaprRun.Builder(
testName,
() -> DaprPorts.build(useAppPort, useDaprPorts, useDaprPorts),
successMessage,
maxWaitMilliseconds,
useGRPC).withServiceClass(serviceClass);
protocol).withServiceClass(serviceClass);
DaprRun run = builder.build();
TO_BE_STOPPED.add(run);
DAPR_RUN_BUILDERS.put(run.getAppName(), builder);
@ -79,7 +79,8 @@ public abstract class BaseIT {
Class serviceClass,
Boolean useAppPort,
int maxWaitMilliseconds) throws Exception {
return startSplitDaprAndApp(testName, successMessage, serviceClass, useAppPort, maxWaitMilliseconds, true);
return startSplitDaprAndApp(
testName, successMessage, serviceClass, useAppPort, maxWaitMilliseconds, DaprApiProtocol.GRPC);
}
protected static ImmutablePair<AppRun, DaprRun> startSplitDaprAndApp(
@ -88,13 +89,13 @@ public abstract class BaseIT {
Class serviceClass,
Boolean useAppPort,
int maxWaitMilliseconds,
boolean useGRPC) throws Exception {
DaprApiProtocol protocol) throws Exception {
DaprRun.Builder builder = new DaprRun.Builder(
testName,
() -> DaprPorts.build(useAppPort, true, true),
successMessage,
maxWaitMilliseconds,
useGRPC).withServiceClass(serviceClass);
protocol).withServiceClass(serviceClass);
ImmutablePair<AppRun, DaprRun> runs = builder.splitBuild();
TO_BE_STOPPED.add(runs.left);
TO_BE_STOPPED.add(runs.right);
@ -108,18 +109,17 @@ public abstract class BaseIT {
@AfterClass
public static void cleanUp() throws Exception {
while (!TO_BE_CLOSED.isEmpty()) {
Closeable toBeClosed = TO_BE_CLOSED.remove();
toBeClosed.close();
TO_BE_CLOSED.remove().close();
}
while (!TO_BE_STOPPED.isEmpty()) {
Stoppable toBeStopped = TO_BE_STOPPED.remove();
toBeStopped.stop();
TO_BE_STOPPED.remove().stop();
}
}
protected static <T extends Closeable> T deferClose(T closeable) {
TO_BE_CLOSED.add(closeable);
return closeable;
protected ActorClient newActorClient() {
ActorClient client = new ActorClient();
TO_BE_CLOSED.add(client);
return client;
}
}

View File

@ -5,6 +5,7 @@
package io.dapr.it;
import io.dapr.client.DaprApiProtocol;
import io.dapr.config.Properties;
import org.apache.commons.lang3.tuple.ImmutablePair;
@ -23,7 +24,7 @@ public class DaprRun implements Stoppable {
// the arg in -Dexec.args is the app's port
private static final String DAPR_COMMAND =
" -- mvn exec:java -D exec.mainClass=%s -D exec.classpathScope=test -D exec.args=\"%s\" -D dapr.grpc.enabled=%s";
" -- mvn exec:java -D exec.mainClass=%s -D exec.classpathScope=test -D exec.args=\"%s\" -D %s=%s -D %s=%s";
private final DaprPorts ports;
@ -44,11 +45,11 @@ public class DaprRun implements Stoppable {
String successMessage,
Class serviceClass,
int maxWaitMilliseconds,
boolean useGRPC) {
DaprApiProtocol protocol) {
// The app name needs to be deterministic since we depend on it to kill previous runs.
this.appName = serviceClass == null ? testName : String.format("%s_%s", testName, serviceClass.getSimpleName());
this.startCommand =
new Command(successMessage, buildDaprCommand(this.appName, serviceClass, ports, useGRPC));
new Command(successMessage, buildDaprCommand(this.appName, serviceClass, ports, protocol));
this.listCommand = new Command(
this.appName,
"dapr list");
@ -132,20 +133,24 @@ public class DaprRun implements Stoppable {
public void use() {
if (this.ports.getHttpPort() != null) {
System.getProperties().setProperty("dapr.http.port", String.valueOf(this.ports.getHttpPort()));
System.getProperties().setProperty(Properties.HTTP_PORT.getName(), String.valueOf(this.ports.getHttpPort()));
}
if (this.ports.getGrpcPort() != null) {
System.getProperties().setProperty("dapr.grpc.port", String.valueOf(this.ports.getGrpcPort()));
System.getProperties().setProperty(Properties.GRPC_PORT.getName(), String.valueOf(this.ports.getGrpcPort()));
}
System.getProperties().setProperty("dapr.grpc.enabled", Boolean.TRUE.toString());
System.getProperties().setProperty(Properties.API_PROTOCOL.getName(), DaprApiProtocol.GRPC.name());
}
public void switchToGRPC() {
System.getProperties().setProperty("dapr.grpc.enabled", Boolean.TRUE.toString());
System.getProperties().setProperty(Properties.API_PROTOCOL.getName(), DaprApiProtocol.GRPC.name());
}
public void switchToHTTP() {
System.getProperties().setProperty("dapr.grpc.enabled", Boolean.FALSE.toString());
System.getProperties().setProperty(Properties.API_PROTOCOL.getName(), DaprApiProtocol.HTTP.name());
}
public void switchToProtocol(DaprApiProtocol protocol) {
System.getProperties().setProperty(Properties.API_PROTOCOL.getName(), protocol.name());
}
public int getGrpcPort() {
@ -164,14 +169,17 @@ public class DaprRun implements Stoppable {
return appName;
}
private static String buildDaprCommand(String appName, Class serviceClass, DaprPorts ports, boolean useGRPC) {
private static String buildDaprCommand(
String appName, Class serviceClass, DaprPorts ports, DaprApiProtocol protocol) {
StringBuilder stringBuilder = new StringBuilder(String.format(DAPR_RUN, appName))
.append(ports.getAppPort() != null ? " --app-port " + ports.getAppPort() : "")
.append(ports.getHttpPort() != null ? " --dapr-http-port " + ports.getHttpPort() : "")
.append(ports.getGrpcPort() != null ? " --dapr-grpc-port " + ports.getGrpcPort() : "")
.append(serviceClass == null ? "" :
String.format(DAPR_COMMAND, serviceClass.getCanonicalName(),
ports.getAppPort() != null ? ports.getAppPort().toString() : "", useGRPC));
ports.getAppPort() != null ? ports.getAppPort().toString() : "",
Properties.API_PROTOCOL.getName(), protocol,
Properties.API_METHOD_INVOCATION_PROTOCOL.getName(), protocol));
return stringBuilder.toString();
}
@ -200,19 +208,19 @@ public class DaprRun implements Stoppable {
private Class serviceClass;
private boolean useGRPC;
private DaprApiProtocol protocol;
Builder(
String testName,
Supplier<DaprPorts> portsSupplier,
String successMessage,
int maxWaitMilliseconds,
boolean useGRPC) {
DaprApiProtocol protocol) {
this.testName = testName;
this.portsSupplier = portsSupplier;
this.successMessage = successMessage;
this.maxWaitMilliseconds = maxWaitMilliseconds;
this.useGRPC = useGRPC;
this.protocol = protocol;
}
public Builder withServiceClass(Class serviceClass) {
@ -227,7 +235,7 @@ public class DaprRun implements Stoppable {
this.successMessage,
this.serviceClass,
this.maxWaitMilliseconds,
this.useGRPC);
this.protocol);
}
/**
@ -241,7 +249,7 @@ public class DaprRun implements Stoppable {
this.successMessage,
this.serviceClass,
this.maxWaitMilliseconds,
this.useGRPC);
this.protocol);
DaprRun daprRun = new DaprRun(
this.testName,
@ -249,7 +257,7 @@ public class DaprRun implements Stoppable {
DAPR_SUCCESS_MESSAGE,
null,
this.maxWaitMilliseconds,
this.useGRPC);
this.protocol);
return new ImmutablePair<>(appRun, daprRun);
}

View File

@ -38,7 +38,7 @@ public class ActivationDeactivationIT extends BaseIT {
final AtomicInteger atomicInteger = new AtomicInteger(1);
logger.debug("Creating proxy builder");
ActorProxyBuilder<DemoActor> proxyBuilder = deferClose(new ActorProxyBuilder(DemoActor.class));
ActorProxyBuilder<DemoActor> proxyBuilder = new ActorProxyBuilder(DemoActor.class, newActorClient());
logger.debug("Creating actorId");
ActorId actorId1 = new ActorId(Integer.toString(atomicInteger.getAndIncrement()));
logger.debug("Building proxy");

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License.
*/
package io.dapr.it.actors;
import io.dapr.actors.ActorId;
import io.dapr.actors.client.ActorProxy;
import io.dapr.actors.client.ActorProxyBuilder;
import io.dapr.it.BaseIT;
import io.dapr.it.actors.app.MyActor;
import io.dapr.it.actors.app.MyActorService;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static io.dapr.it.Retry.callWithRetry;
import static org.junit.Assert.assertTrue;
public class ActorMethodNameIT extends BaseIT {
private static Logger logger = LoggerFactory.getLogger(ActorMethodNameIT.class);
@Test
public void actorMethodNameChange() throws Exception {
// The call below will fail if service cannot start successfully.
startDaprApp(
ActorMethodNameIT.class.getSimpleName(),
MyActorService.SUCCESS_MESSAGE,
MyActorService.class,
true,
60000);
logger.debug("Creating proxy builder");
ActorProxyBuilder<MyActor> proxyBuilder =
new ActorProxyBuilder("MyActorTest", MyActor.class, newActorClient());
logger.debug("Creating actorId");
ActorId actorId1 = new ActorId("1");
logger.debug("Building proxy");
MyActor proxy = proxyBuilder.build(actorId1);
callWithRetry(() -> {
logger.debug("Invoking dotNetMethod from Proxy");
boolean response = proxy.dotNetMethod();
logger.debug("asserting true response: [" + response + "]");
assertTrue(response);
}, 60000);
logger.debug("Creating proxy builder 2");
ActorProxyBuilder<ActorProxy> proxyBuilder2 =
new ActorProxyBuilder("MyActorTest", ActorProxy.class, newActorClient());
logger.debug("Building proxy 2");
ActorProxy proxy2 = proxyBuilder2.build(actorId1);
callWithRetry(() -> {
logger.debug("Invoking DotNetMethodAsync from Proxy 2");
boolean response = proxy2.invokeMethod("DotNetMethodAsync", boolean.class).block();
logger.debug("asserting true response 2: [" + response + "]");
assertTrue(response);
}, 60000);
}
}

View File

@ -20,7 +20,9 @@ import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.UUID;
import static io.dapr.it.actors.MyActorTestUtils.*;
import static io.dapr.it.actors.MyActorTestUtils.countMethodCalls;
import static io.dapr.it.actors.MyActorTestUtils.fetchMethodCallLogs;
import static io.dapr.it.actors.MyActorTestUtils.validateMethodCalls;
import static org.junit.Assert.assertNotEquals;
public class ActorReminderFailoverIT extends BaseIT {
@ -61,7 +63,8 @@ public class ActorReminderFailoverIT extends BaseIT {
String actorType="MyActorTest";
logger.debug("Creating proxy builder");
ActorProxyBuilder<ActorProxy> proxyBuilder = deferClose(new ActorProxyBuilder(actorType, ActorProxy.class));
ActorProxyBuilder<ActorProxy> proxyBuilder =
new ActorProxyBuilder(actorType, ActorProxy.class, newActorClient());
logger.debug("Creating actorId");
logger.debug("Building proxy");
proxy = proxyBuilder.build(actorId);
@ -71,7 +74,7 @@ public class ActorReminderFailoverIT extends BaseIT {
public void tearDown() {
// call unregister
logger.debug("Calling actor method 'stopReminder' to unregister reminder");
proxy.invokeActorMethod("stopReminder", "myReminder").block();
proxy.invokeMethod("stopReminder", "myReminder").block();
}
/**
@ -83,7 +86,7 @@ public class ActorReminderFailoverIT extends BaseIT {
clientAppRun.use();
logger.debug("Invoking actor method 'startReminder' which will register a reminder");
proxy.invokeActorMethod("startReminder", "myReminder").block();
proxy.invokeMethod("startReminder", "myReminder").block();
logger.debug("Pausing 7 seconds to allow reminder to fire");
Thread.sleep(7000);
@ -92,7 +95,7 @@ public class ActorReminderFailoverIT extends BaseIT {
validateMethodCalls(logs, METHOD_NAME, 3);
int originalActorHostIdentifier = Integer.parseInt(
proxy.invokeActorMethod("getIdentifier", String.class).block());
proxy.invokeMethod("getIdentifier", String.class).block());
if (originalActorHostIdentifier == firstAppRun.getHttpPort()) {
firstAppRun.stop();
}
@ -110,7 +113,7 @@ public class ActorReminderFailoverIT extends BaseIT {
validateMethodCalls(newLogs2, METHOD_NAME, countMethodCalls(newLogs, METHOD_NAME) + 4);
int newActorHostIdentifier = Integer.parseInt(
proxy.invokeActorMethod("getIdentifier", String.class).block());
proxy.invokeMethod("getIdentifier", String.class).block());
assertNotEquals(originalActorHostIdentifier, newActorHostIdentifier);
}

View File

@ -22,7 +22,9 @@ import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.UUID;
import static io.dapr.it.actors.MyActorTestUtils.*;
import static io.dapr.it.actors.MyActorTestUtils.countMethodCalls;
import static io.dapr.it.actors.MyActorTestUtils.fetchMethodCallLogs;
import static io.dapr.it.actors.MyActorTestUtils.validateMethodCalls;
public class ActorReminderRecoveryIT extends BaseIT {
@ -49,7 +51,8 @@ public class ActorReminderRecoveryIT extends BaseIT {
String actorType="MyActorTest";
logger.debug("Creating proxy builder");
ActorProxyBuilder<ActorProxy> proxyBuilder = deferClose(new ActorProxyBuilder(actorType, ActorProxy.class));
ActorProxyBuilder<ActorProxy> proxyBuilder =
new ActorProxyBuilder(actorType, ActorProxy.class, newActorClient());
logger.debug("Creating actorId");
logger.debug("Building proxy");
proxy = proxyBuilder.build(actorId);
@ -59,7 +62,7 @@ public class ActorReminderRecoveryIT extends BaseIT {
public void tearDown() {
// call unregister
logger.debug("Calling actor method 'stopReminder' to unregister reminder");
proxy.invokeActorMethod("stopReminder", "myReminder").block();
proxy.invokeMethod("stopReminder", "myReminder").block();
}
/**
@ -69,7 +72,7 @@ public class ActorReminderRecoveryIT extends BaseIT {
@Test
public void reminderRecoveryTest() throws Exception {
logger.debug("Invoking actor method 'startReminder' which will register a reminder");
proxy.invokeActorMethod("startReminder", "myReminder").block();
proxy.invokeMethod("startReminder", "myReminder").block();
logger.debug("Pausing 7 seconds to allow reminder to fire");
Thread.sleep(7000);

View File

@ -8,6 +8,7 @@ package io.dapr.it.actors;
import io.dapr.actors.ActorId;
import io.dapr.actors.client.ActorProxy;
import io.dapr.actors.client.ActorProxyBuilder;
import io.dapr.client.DaprApiProtocol;
import io.dapr.it.BaseIT;
import io.dapr.it.DaprRun;
import io.dapr.it.actors.services.springboot.StatefulActor;
@ -22,7 +23,9 @@ import java.util.Arrays;
import java.util.Collection;
import static io.dapr.it.Retry.callWithRetry;
import static org.junit.Assert.*;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
@RunWith(Parameterized.class)
public class ActorStateIT extends BaseIT {
@ -36,14 +39,19 @@ public class ActorStateIT extends BaseIT {
*/
@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] { { false, false }, { false, true }, { true, false }, { true, true } });
return Arrays.asList(new Object[][] {
{ DaprApiProtocol.HTTP, DaprApiProtocol.HTTP },
{ DaprApiProtocol.HTTP, DaprApiProtocol.GRPC },
{ DaprApiProtocol.GRPC, DaprApiProtocol.HTTP },
{ DaprApiProtocol.GRPC, DaprApiProtocol.GRPC },
});
}
@Parameterized.Parameter(0)
public boolean useGrpc;
public DaprApiProtocol daprClientProtocol;
@Parameterized.Parameter(1)
public boolean useGrpcInService;
public DaprApiProtocol serviceAppProtocol;
@Test
public void writeReadState() throws Exception {
@ -55,39 +63,36 @@ public class ActorStateIT extends BaseIT {
StatefulActorService.class,
true,
60000,
useGrpcInService);
serviceAppProtocol);
if (this.useGrpc) {
runtime.switchToGRPC();
} else {
runtime.switchToHTTP();
}
runtime.switchToProtocol(this.daprClientProtocol);
String message = "This is a message to be saved and retrieved.";
String name = "Jon Doe";
byte[] bytes = new byte[] { 0x1 };
ActorId actorId = new ActorId(
String.format("%d-%b-%b", System.currentTimeMillis(), this.useGrpc, this.useGrpcInService));
String.format("%d-%b-%b", System.currentTimeMillis(), this.daprClientProtocol, this.serviceAppProtocol));
String actorType = "StatefulActorTest";
logger.debug("Building proxy ...");
ActorProxyBuilder<ActorProxy> proxyBuilder = deferClose(new ActorProxyBuilder(actorType, ActorProxy.class));
ActorProxyBuilder<ActorProxy> proxyBuilder =
new ActorProxyBuilder(actorType, ActorProxy.class, newActorClient());
ActorProxy proxy = proxyBuilder.build(actorId);
// Validate conditional read works.
callWithRetry(() -> {
logger.debug("Invoking readMessage where data is not present yet ... ");
String result = proxy.invokeActorMethod("readMessage", String.class).block();
String result = proxy.invokeMethod("readMessage", String.class).block();
assertNull(result);
}, 5000);
callWithRetry(() -> {
logger.debug("Invoking writeMessage ... ");
proxy.invokeActorMethod("writeMessage", message).block();
proxy.invokeMethod("writeMessage", message).block();
}, 5000);
callWithRetry(() -> {
logger.debug("Invoking readMessage where data is probably still cached ... ");
String result = proxy.invokeActorMethod("readMessage", String.class).block();
String result = proxy.invokeMethod("readMessage", String.class).block();
assertEquals(message, result);
}, 5000);
@ -96,45 +101,45 @@ public class ActorStateIT extends BaseIT {
mydata.value = "My data value.";
callWithRetry(() -> {
logger.debug("Invoking writeData with object ... ");
proxy.invokeActorMethod("writeData", mydata).block();
proxy.invokeMethod("writeData", mydata).block();
}, 5000);
callWithRetry(() -> {
logger.debug("Invoking readData where data is probably still cached ... ");
StatefulActor.MyData result = proxy.invokeActorMethod("readData", StatefulActor.MyData.class).block();
StatefulActor.MyData result = proxy.invokeMethod("readData", StatefulActor.MyData.class).block();
assertEquals(mydata.value, result.value);
}, 5000);
callWithRetry(() -> {
logger.debug("Invoking writeName ... ");
proxy.invokeActorMethod("writeName", name).block();
proxy.invokeMethod("writeName", name).block();
}, 5000);
callWithRetry(() -> {
logger.debug("Invoking readName where data is probably still cached ... ");
String result = proxy.invokeActorMethod("readName", String.class).block();
String result = proxy.invokeMethod("readName", String.class).block();
assertEquals(name, result);
}, 5000);
callWithRetry(() -> {
logger.debug("Invoking writeName with empty content... ");
proxy.invokeActorMethod("writeName", "").block();
proxy.invokeMethod("writeName", "").block();
}, 5000);
callWithRetry(() -> {
logger.debug("Invoking readName where empty content is probably still cached ... ");
String result = proxy.invokeActorMethod("readName", String.class).block();
String result = proxy.invokeMethod("readName", String.class).block();
assertEquals("", result);
}, 5000);
callWithRetry(() -> {
logger.debug("Invoking writeBytes ... ");
proxy.invokeActorMethod("writeBytes", bytes).block();
proxy.invokeMethod("writeBytes", bytes).block();
}, 5000);
callWithRetry(() -> {
logger.debug("Invoking readBytes where data is probably still cached ... ");
byte[] result = proxy.invokeActorMethod("readBytes", byte[].class).block();
byte[] result = proxy.invokeMethod("readBytes", byte[].class).block();
assertArrayEquals(bytes, result);
}, 5000);
@ -151,40 +156,36 @@ public class ActorStateIT extends BaseIT {
StatefulActorService.class,
true,
60000,
useGrpcInService);
serviceAppProtocol);
if (this.useGrpc) {
run2.switchToGRPC();
} else {
run2.switchToHTTP();
}
runtime.switchToProtocol(this.daprClientProtocol);
// Need new proxy builder because the proxy builder holds the channel.
proxyBuilder = deferClose(new ActorProxyBuilder(actorType, ActorProxy.class));
proxyBuilder = new ActorProxyBuilder(actorType, ActorProxy.class, newActorClient());
ActorProxy newProxy = proxyBuilder.build(actorId);
callWithRetry(() -> {
logger.debug("Invoking readMessage where data is not cached ... ");
String result = newProxy.invokeActorMethod("readMessage", String.class).block();
String result = newProxy.invokeMethod("readMessage", String.class).block();
assertEquals(message, result);
}, 5000);
callWithRetry(() -> {
logger.debug("Invoking readData where data is not cached ... ");
StatefulActor.MyData result = newProxy.invokeActorMethod("readData", StatefulActor.MyData.class).block();
StatefulActor.MyData result = newProxy.invokeMethod("readData", StatefulActor.MyData.class).block();
assertEquals(mydata.value, result.value);
}, 5000);
logger.debug("Finished testing actor string state.");
callWithRetry(() -> {
logger.debug("Invoking readName where empty content is not cached ... ");
String result = newProxy.invokeActorMethod("readName", String.class).block();
String result = newProxy.invokeMethod("readName", String.class).block();
assertEquals("", result);
}, 5000);
callWithRetry(() -> {
logger.debug("Invoking readBytes where content is not cached ... ");
byte[] result = newProxy.invokeActorMethod("readBytes", byte[].class).block();
byte[] result = newProxy.invokeMethod("readBytes", byte[].class).block();
assertArrayEquals(bytes, result);
}, 5000);
}

View File

@ -47,14 +47,15 @@ public class ActorTimerRecoveryIT extends BaseIT {
String actorType="MyActorTest";
logger.debug("Creating proxy builder");
ActorProxyBuilder<ActorProxy> proxyBuilder = deferClose(new ActorProxyBuilder(actorType, ActorProxy.class));
ActorProxyBuilder<ActorProxy> proxyBuilder =
new ActorProxyBuilder(actorType, ActorProxy.class, newActorClient());
logger.debug("Creating actorId");
ActorId actorId = new ActorId(UUID.randomUUID().toString());
logger.debug("Building proxy");
ActorProxy proxy = proxyBuilder.build(actorId);
logger.debug("Invoking actor method 'startTimer' which will register a timer");
proxy.invokeActorMethod("startTimer", "myTimer").block();
proxy.invokeMethod("startTimer", "myTimer").block();
logger.debug("Pausing 7 seconds to allow timer to fire");
Thread.sleep(7000);
@ -80,7 +81,7 @@ public class ActorTimerRecoveryIT extends BaseIT {
// call unregister
logger.debug("Calling actor method 'stopTimer' to unregister timer");
proxy.invokeActorMethod("stopTimer", "myTimer").block();
proxy.invokeMethod("stopTimer", "myTimer").block();
}
}

View File

@ -80,7 +80,8 @@ public class ActorTurnBasedConcurrencyIT extends BaseIT {
String actorType="MyActorTest";
logger.debug("Creating proxy builder");
ActorProxyBuilder<ActorProxy> proxyBuilder = deferClose(new ActorProxyBuilder(actorType, ActorProxy.class));
ActorProxyBuilder<ActorProxy> proxyBuilder =
new ActorProxyBuilder(actorType, ActorProxy.class, newActorClient());
logger.debug("Creating actorId");
ActorId actorId1 = new ActorId(ACTOR_ID);
logger.debug("Building proxy");
@ -89,13 +90,13 @@ public class ActorTurnBasedConcurrencyIT extends BaseIT {
logger.debug("Invoking Say from Proxy");
callWithRetry(() -> {
logger.debug("Invoking Say from Proxy");
String sayResponse = proxy.invokeActorMethod("say", "message", String.class).block();
String sayResponse = proxy.invokeMethod("say", "message", String.class).block();
logger.debug("asserting not null response: [" + sayResponse + "]");
assertNotNull(sayResponse);
}, 60000);
logger.debug("Invoking actor method 'startTimer' which will register a timer");
proxy.invokeActorMethod("startTimer", "myTimer").block();
proxy.invokeMethod("startTimer", "myTimer").block();
// invoke a bunch of calls in parallel to validate turn-based concurrency
logger.debug("Invoking an actor method 'say' in parallel");
@ -108,12 +109,12 @@ public class ActorTurnBasedConcurrencyIT extends BaseIT {
// the actor method called below should reverse the input
String msg = "message" + i;
String reversedString = new StringBuilder(msg).reverse().toString();
String output = proxy.invokeActorMethod("say", "message" + i, String.class).block();
String output = proxy.invokeMethod("say", "message" + i, String.class).block();
assertTrue(reversedString.equals(output));
});
logger.debug("Calling method to register reminder named " + REMINDER_NAME);
proxy.invokeActorMethod("startReminder", REMINDER_NAME).block();
proxy.invokeMethod("startReminder", REMINDER_NAME).block();
logger.debug("Pausing 7 seconds to allow timer and reminders to fire");
Thread.sleep(7000);
@ -126,14 +127,14 @@ public class ActorTurnBasedConcurrencyIT extends BaseIT {
// call unregister
logger.debug("Calling actor method 'stopTimer' to unregister timer");
proxy.invokeActorMethod("stopTimer", "myTimer").block();
proxy.invokeMethod("stopTimer", "myTimer").block();
logger.debug("Calling actor method 'stopReminder' to unregister reminder");
proxy.invokeActorMethod("stopReminder", REMINDER_NAME).block();
proxy.invokeMethod("stopReminder", REMINDER_NAME).block();
// make some more actor method calls and sleep a bit to see if the timer fires (it should not)
sayMessages.parallelStream().forEach( i -> {
proxy.invokeActorMethod("say", "message" + i, String.class).block();
proxy.invokeMethod("say", "message" + i, String.class).block();
});
logger.debug("Pausing 5 seconds to allow time for timer and reminders to fire if there is a bug. They should not since we have unregistered them.");

View File

@ -54,7 +54,7 @@ public class MyActorTestUtils {
* @return List of call log.
*/
static List<MethodEntryTracker> fetchMethodCallLogs(ActorProxy proxy) {
ArrayList<String> logs = proxy.invokeActorMethod("getCallLog", ArrayList.class).block();
ArrayList<String> logs = proxy.invokeMethod("getCallLog", ArrayList.class).block();
ArrayList<MethodEntryTracker> trackers = new ArrayList<MethodEntryTracker>();
for(String t : logs) {
String[] toks = t.split("\\|");

View File

@ -5,6 +5,8 @@
package io.dapr.it.actors.app;
import io.dapr.actors.ActorMethod;
import java.util.ArrayList;
import java.util.List;
@ -26,4 +28,7 @@ public interface MyActor {
ArrayList<String> getCallLog();
String getIdentifier();
@ActorMethod(name = "DotNetMethodAsync")
boolean dotNetMethod();
}

View File

@ -199,6 +199,11 @@ public class MyActorImpl extends AbstractActor implements MyActor, Remindable<St
return System.getenv("DAPR_HTTP_PORT");
}
@Override
public boolean dotNetMethod() {
return true;
}
private void formatAndLog(boolean isEnter, String methodName) {
Calendar utcNow = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

View File

@ -11,7 +11,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Dapr's HTTP callback implementation via SpringBoot.
*/
@SpringBootApplication(scanBasePackages = {"io.dapr.springboot", "io.dapr.it.actors.app"})
@SpringBootApplication
public class TestApplication {
/**

View File

@ -11,7 +11,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Dapr's HTTP callback implementation via SpringBoot.
*/
@SpringBootApplication(scanBasePackages = {"io.dapr.springboot", "io.dapr.it.actors.services.springboot"})
@SpringBootApplication
public class DaprApplication {
/**

Some files were not shown because too many files have changed in this diff Show More