Add actor testcontainer tests (#1192)

* Add actor testcontainer tests

Signed-off-by: Christian Kaps <ck-github@mohiva.com>

* adding auto config

Signed-off-by: Christian Kaps <ck-github@mohiva.com>

* updating ActorClient

Signed-off-by: Christian Kaps <ck-github@mohiva.com>

* registering?

Signed-off-by: Christian Kaps <ck-github@mohiva.com>

* updating actors test and actorruntime

Signed-off-by: Christian Kaps <ck-github@mohiva.com>

* updating ActorRuntime

Signed-off-by: Christian Kaps <ck-github@mohiva.com>

* Adding WorkflowTaskOptions and use it instead of TaskOptions (#1200)

Signed-off-by: Christian Kaps <ck-github@mohiva.com>

* Fix formatting issues

Signed-off-by: Christian Kaps <ck-github@mohiva.com>

* adding spring boot workflows integration (#1195)

Co-authored-by: Cassie Coyle <cassie@diagrid.io>
Signed-off-by: Christian Kaps <ck-github@mohiva.com>

* Register workflows and acitivities using instances along classes (#1201)

Signed-off-by: Christian Kaps <ck-github@mohiva.com>

* feat: Adding basic HTTPEndpoint configuration support in testcontainers module (#1210)

* feat: Adding basic HTTPEndpoint configuration support in testcontainers module

Signed-off-by: Laurent Broudoux <laurent.broudoux@gmail.com>

* feat: #1209 Adding test for HTTPEndpoint in testcontainers module

Signed-off-by: Laurent Broudoux <laurent.broudoux@gmail.com>

---------

Signed-off-by: Laurent Broudoux <laurent.broudoux@gmail.com>
Signed-off-by: Christian Kaps <ck-github@mohiva.com>

* fixing actors IT test and messaging IT with app-health-checks

Signed-off-by: Christian Kaps <ck-github@mohiva.com>

* Add app health check support to Dapr Testcontainer (#1213)

* Add app health check support to Dapr Testcontainer

Signed-off-by: Artur Ciocanu <ciocanu@adobe.com>

* Some minor cleanup

Signed-off-by: Artur Ciocanu <ciocanu@adobe.com>

* Move waiting to beforeEach, it looks more natural

Signed-off-by: Artur Ciocanu <ciocanu@adobe.com>

---------

Signed-off-by: Artur Ciocanu <ciocanu@adobe.com>
Co-authored-by: Artur Ciocanu <ciocanu@adobe.com>
Signed-off-by: Christian Kaps <ck-github@mohiva.com>

* adding license headers + adding wait for actors in test

Signed-off-by: Christian Kaps <ck-github@mohiva.com>

* Add app health check support to Dapr Testcontainer (#1213)

* Add app health check support to Dapr Testcontainer

Signed-off-by: Artur Ciocanu <ciocanu@adobe.com>

* Some minor cleanup

Signed-off-by: Artur Ciocanu <ciocanu@adobe.com>

* Move waiting to beforeEach, it looks more natural

Signed-off-by: Artur Ciocanu <ciocanu@adobe.com>

---------

Signed-off-by: Artur Ciocanu <ciocanu@adobe.com>
Co-authored-by: Artur Ciocanu <ciocanu@adobe.com>
Signed-off-by: Christian Kaps <ck-github@mohiva.com>

* Picks a port for DaprActorITS for test containers to avoid conflict.

Signed-off-by: Artur Souza <asouza.pro@gmail.com>
Signed-off-by: Christian Kaps <ck-github@mohiva.com>

* Add app health check support to Dapr Testcontainer (#1213)

* Add app health check support to Dapr Testcontainer

Signed-off-by: Artur Ciocanu <ciocanu@adobe.com>

* Some minor cleanup

Signed-off-by: Artur Ciocanu <ciocanu@adobe.com>

* Move waiting to beforeEach, it looks more natural

Signed-off-by: Artur Ciocanu <ciocanu@adobe.com>

---------

Signed-off-by: Artur Ciocanu <ciocanu@adobe.com>
Co-authored-by: Artur Ciocanu <ciocanu@adobe.com>
Signed-off-by: Christian Kaps <ck-github@mohiva.com>

* using random port thanks to @artur-ciocanu

Signed-off-by: Christian Kaps <ck-github@mohiva.com>

* Update TestRestController.java

Signed-off-by: artur-ciocanu <artur.ciocanu@gmail.com>

* Update DaprActorsIT.java

Signed-off-by: artur-ciocanu <artur.ciocanu@gmail.com>

* Update DaprContainer.java

Signed-off-by: artur-ciocanu <artur.ciocanu@gmail.com>

---------

Signed-off-by: Christian Kaps <ck-github@mohiva.com>
Signed-off-by: Laurent Broudoux <laurent.broudoux@gmail.com>
Signed-off-by: Artur Ciocanu <ciocanu@adobe.com>
Signed-off-by: Artur Souza <asouza.pro@gmail.com>
Signed-off-by: Artur Souza <artursouza.ms@outlook.com>
Signed-off-by: artur-ciocanu <artur.ciocanu@gmail.com>
Co-authored-by: salaboy <Salaboy@gmail.com>
Co-authored-by: artur-ciocanu <artur.ciocanu@gmail.com>
Co-authored-by: Cassie Coyle <cassie@diagrid.io>
Co-authored-by: Laurent Broudoux <laurent.broudoux@gmail.com>
Co-authored-by: Artur Ciocanu <ciocanu@adobe.com>
Co-authored-by: Artur Souza <asouza.pro@gmail.com>
Co-authored-by: Artur Souza <artursouza.ms@outlook.com>
This commit is contained in:
Christian Kaps 2025-03-01 19:00:52 +01:00 committed by GitHub
parent 5dbeafc24a
commit efce229985
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 332 additions and 69 deletions

View File

@ -13,6 +13,8 @@ limitations under the License.
package io.dapr.spring.boot.autoconfigure.client;
import io.dapr.actors.client.ActorClient;
import io.dapr.actors.runtime.ActorRuntime;
import io.dapr.client.DaprClient;
import io.dapr.client.DaprClientBuilder;
import io.dapr.config.Properties;
@ -70,6 +72,20 @@ public class DaprClientAutoConfiguration {
return new DaprWorkflowClient(properties);
}
@Bean
@ConditionalOnMissingBean
ActorClient daprActorClient(DaprConnectionDetails daprConnectionDetails) {
Properties properties = createPropertiesFromConnectionDetails(daprConnectionDetails);
return new ActorClient(properties);
}
@Bean
@ConditionalOnMissingBean
ActorRuntime daprActorRuntime(DaprConnectionDetails daprConnectionDetails) {
Properties properties = createPropertiesFromConnectionDetails(daprConnectionDetails);
return ActorRuntime.getInstance(properties);
}
@Bean
@ConditionalOnMissingBean
WorkflowRuntimeBuilder daprWorkflowRuntimeBuilder(DaprConnectionDetails daprConnectionDetails) {

View File

@ -15,6 +15,7 @@ package io.dapr.actors.client;
import io.dapr.client.resiliency.ResiliencyOptions;
import io.dapr.config.Properties;
import io.dapr.utils.NetworkUtils;
import io.dapr.utils.Version;
import io.dapr.v1.DaprGrpc;
import io.grpc.Channel;
@ -83,7 +84,7 @@ public class ActorClient implements AutoCloseable {
* @param resiliencyOptions Client resiliency options.
*/
public ActorClient(Properties overrideProperties, Map<String, String> metadata, ResiliencyOptions resiliencyOptions) {
this(buildManagedChannel(overrideProperties),
this(NetworkUtils.buildGrpcManagedChannel(overrideProperties),
metadata,
resiliencyOptions,
overrideProperties.getValue(Properties.API_TOKEN));
@ -129,25 +130,6 @@ public class ActorClient implements AutoCloseable {
}
}
/**
* Creates a GRPC managed channel (or null, if not applicable).
*
* @param overrideProperties Overrides
* @return GRPC managed channel or null.
*/
private static ManagedChannel buildManagedChannel(Properties overrideProperties) {
int port = overrideProperties.getValue(Properties.GRPC_PORT);
if (port <= 0) {
throw new IllegalArgumentException("Invalid port.");
}
var sidecarHost = overrideProperties.getValue(Properties.SIDECAR_IP);
return ManagedChannelBuilder.forAddress(sidecarHost, port)
.usePlaintext()
.userAgent(Version.getSdkVersion())
.build();
}
/**
* Build an instance of the Client based on the provided setup.

View File

@ -18,9 +18,8 @@ import io.dapr.actors.ActorTrace;
import io.dapr.config.Properties;
import io.dapr.serializer.DaprObjectSerializer;
import io.dapr.serializer.DefaultObjectSerializer;
import io.dapr.utils.Version;
import io.dapr.utils.NetworkUtils;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import reactor.core.publisher.Mono;
import java.io.Closeable;
@ -80,23 +79,32 @@ public class ActorRuntime implements Closeable {
* @throws IllegalStateException If cannot instantiate Runtime.
*/
private ActorRuntime() throws IllegalStateException {
this(buildManagedChannel());
this(new Properties());
}
/**
* The default constructor. This should not be called directly.
*
* @throws IllegalStateException If cannot instantiate Runtime.
*/
private ActorRuntime(Properties properties) throws IllegalStateException {
this(NetworkUtils.buildGrpcManagedChannel(properties));
}
/**
* Constructor once channel is available. This should not be called directly.
*
* @param channel GRPC managed channel to be closed (or null).
* @throws IllegalStateException If cannot instantiate Runtime.
* @throws IllegalStateException If you cannot instantiate Runtime.
*/
private ActorRuntime(ManagedChannel channel) throws IllegalStateException {
this(channel, buildDaprClient(channel));
this(channel, new DaprClientImpl(channel));
}
/**
* Constructor with dependency injection, useful for testing. This should not be called directly.
*
* @param channel GRPC managed channel to be closed (or null).
* @param channel GRPC managed channel to be closed (or null).
* @param daprClient Client to communicate with Dapr.
* @throws IllegalStateException If class has one instance already.
*/
@ -128,6 +136,24 @@ public class ActorRuntime implements Closeable {
return instance;
}
/**
* Returns an ActorRuntime object.
*
* @param properties Properties to be used for the runtime.
* @return An ActorRuntime object.
*/
public static ActorRuntime getInstance(Properties properties) {
if (instance == null) {
synchronized (ActorRuntime.class) {
if (instance == null) {
instance = new ActorRuntime(properties);
}
}
}
return instance;
}
/**
* Gets the Actor configuration for this runtime.
*
@ -149,11 +175,10 @@ public class ActorRuntime implements Closeable {
/**
* Registers an actor with the runtime, using {@link DefaultObjectSerializer} and {@link DefaultActorFactory}.
*
* {@link DefaultObjectSerializer} is not recommended for production scenarios.
*
* @param clazz The type of actor.
* @param <T> Actor class type.
* @param clazz The type of actor.
* @param <T> Actor class type.
*/
public <T extends AbstractActor> void registerActor(Class<T> clazz) {
registerActor(clazz, new DefaultObjectSerializer(), new DefaultObjectSerializer());
@ -161,12 +186,11 @@ public class ActorRuntime implements Closeable {
/**
* Registers an actor with the runtime, using {@link DefaultObjectSerializer}.
*
* {@link DefaultObjectSerializer} is not recommended for production scenarios.
*
* @param clazz The type of actor.
* @param actorFactory An optional factory to create actors. This can be used for dependency injection.
* @param <T> Actor class type.
* @param clazz The type of actor.
* @param actorFactory An optional factory to create actors. This can be used for dependency injection.
* @param <T> Actor class type.
*/
public <T extends AbstractActor> void registerActor(Class<T> clazz, ActorFactory<T> actorFactory) {
registerActor(clazz, actorFactory, new DefaultObjectSerializer(), new DefaultObjectSerializer());
@ -181,8 +205,8 @@ public class ActorRuntime implements Closeable {
* @param <T> Actor class type.
*/
public <T extends AbstractActor> void registerActor(
Class<T> clazz, DaprObjectSerializer objectSerializer, DaprObjectSerializer stateSerializer) {
registerActor(clazz, new DefaultActorFactory<T>(), objectSerializer, stateSerializer);
Class<T> clazz, DaprObjectSerializer objectSerializer, DaprObjectSerializer stateSerializer) {
registerActor(clazz, new DefaultActorFactory<T>(), objectSerializer, stateSerializer);
}
/**
@ -195,9 +219,9 @@ public class ActorRuntime implements Closeable {
* @param <T> Actor class type.
*/
public <T extends AbstractActor> void registerActor(
Class<T> clazz, ActorFactory<T> actorFactory,
DaprObjectSerializer objectSerializer,
DaprObjectSerializer stateSerializer) {
Class<T> clazz, ActorFactory<T> actorFactory,
DaprObjectSerializer objectSerializer,
DaprObjectSerializer stateSerializer) {
if (clazz == null) {
throw new IllegalArgumentException("Class is required.");
}
@ -216,12 +240,12 @@ public class ActorRuntime implements Closeable {
// Create ActorManager, if not yet registered.
this.actorManagers.computeIfAbsent(actorTypeInfo.getName(), (k) -> {
ActorRuntimeContext<T> context = new ActorRuntimeContext<>(
this,
objectSerializer,
actorFactory,
actorTypeInfo,
this.daprClient,
new DaprStateAsyncProvider(this.daprClient, stateSerializer));
this,
objectSerializer,
actorFactory,
actorTypeInfo,
this.daprClient,
new DaprStateAsyncProvider(this.daprClient, stateSerializer));
this.config.addRegisteredActorType(actorTypeInfo.getName());
return new ActorManager<T>(context);
});
@ -236,7 +260,7 @@ public class ActorRuntime implements Closeable {
*/
public Mono<Void> deactivate(String actorTypeName, String actorId) {
return Mono.fromSupplier(() -> this.getActorManager(actorTypeName))
.flatMap(m -> m.deactivateActor(new ActorId(actorId)));
.flatMap(m -> m.deactivateActor(new ActorId(actorId)));
}
/**
@ -252,8 +276,8 @@ public class ActorRuntime implements Closeable {
public Mono<byte[]> invoke(String actorTypeName, String actorId, String actorMethodName, byte[] payload) {
ActorId id = new ActorId(actorId);
return Mono.fromSupplier(() -> this.getActorManager(actorTypeName))
.flatMap(m -> m.activateActor(id).thenReturn(m))
.flatMap(m -> ((ActorManager)m).invokeMethod(id, actorMethodName, payload));
.flatMap(m -> m.activateActor(id).thenReturn(m))
.flatMap(m -> ((ActorManager) m).invokeMethod(id, actorMethodName, payload));
}
/**
@ -268,8 +292,8 @@ public class ActorRuntime implements Closeable {
public Mono<Void> invokeReminder(String actorTypeName, String actorId, String reminderName, byte[] params) {
ActorId id = new ActorId(actorId);
return Mono.fromSupplier(() -> this.getActorManager(actorTypeName))
.flatMap(m -> m.activateActor(id).thenReturn(m))
.flatMap(m -> ((ActorManager)m).invokeReminder(new ActorId(actorId), reminderName, params));
.flatMap(m -> m.activateActor(id).thenReturn(m))
.flatMap(m -> ((ActorManager) m).invokeReminder(new ActorId(actorId), reminderName, params));
}
/**
@ -284,8 +308,8 @@ public class ActorRuntime implements Closeable {
public Mono<Void> invokeTimer(String actorTypeName, String actorId, String timerName, byte[] params) {
ActorId id = new ActorId(actorId);
return Mono.fromSupplier(() -> this.getActorManager(actorTypeName))
.flatMap(m -> m.activateActor(id).thenReturn(m))
.flatMap(m -> ((ActorManager)m).invokeTimer(new ActorId(actorId), timerName, params));
.flatMap(m -> m.activateActor(id).thenReturn(m))
.flatMap(m -> ((ActorManager) m).invokeTimer(new ActorId(actorId), timerName, params));
}
/**
@ -318,23 +342,6 @@ public class ActorRuntime implements Closeable {
return new DaprClientImpl(channel);
}
/**
* Creates a GRPC managed channel (or null, if not applicable).
*
* @return GRPC managed channel or null.
*/
private static ManagedChannel buildManagedChannel() {
int port = Properties.GRPC_PORT.get();
if (port <= 0) {
throw new IllegalStateException("Invalid port.");
}
return ManagedChannelBuilder.forAddress(Properties.SIDECAR_IP.get(), port)
.usePlaintext()
.userAgent(Version.getSdkVersion())
.build();
}
/**
* {@inheritDoc}
*/

View File

@ -141,7 +141,7 @@ public class ActorStateIT extends BaseIT {
proxyBuilder = new ActorProxyBuilder(actorType, ActorProxy.class, deferClose(run2.newActorClient()));
ActorProxy newProxy = proxyBuilder.build(actorId);
// wating for actor to be activated
// waiting for actor to be activated
Thread.sleep(2000);
callWithRetry(() -> {

View File

@ -0,0 +1,107 @@
/*
* Copyright 2025 The Dapr Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
limitations under the License.
*/
package io.dapr.it.testcontainers;
import io.dapr.actors.ActorId;
import io.dapr.actors.client.ActorClient;
import io.dapr.actors.client.ActorProxyBuilder;
import io.dapr.actors.runtime.ActorRuntime;
import io.dapr.testcontainers.Component;
import io.dapr.testcontainers.DaprContainer;
import io.dapr.testcontainers.DaprLogLevel;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.Network;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import static org.junit.jupiter.api.Assertions.assertEquals;
@SpringBootTest(
webEnvironment = WebEnvironment.RANDOM_PORT,
classes = {
TestActorsApplication.class,
TestDaprActorsConfiguration.class
}
)
@Testcontainers
@Tag("testcontainers")
public class DaprActorsIT {
private static final Network DAPR_NETWORK = Network.newNetwork();
private static final Random RANDOM = new Random();
private static final int PORT = RANDOM.nextInt(1000) + 8000;
private static final String ACTORS_MESSAGE_PATTERN = ".*Actor API level in the cluster has been updated to 10.*";
@Container
private static final DaprContainer DAPR_CONTAINER = new DaprContainer("daprio/daprd:1.14.4")
.withAppName("actor-dapr-app")
.withNetwork(DAPR_NETWORK)
.withComponent(new Component("kvstore", "state.in-memory", "v1",
Map.of("actorStateStore", "true")))
.withDaprLogLevel(DaprLogLevel.DEBUG)
.withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String()))
.withAppChannelAddress("host.testcontainers.internal")
.withAppPort(PORT);
/**
* Expose the Dapr ports to the host.
*
* @param registry the dynamic property registry
*/
@DynamicPropertySource
static void daprProperties(DynamicPropertyRegistry registry) {
registry.add("dapr.http.endpoint", DAPR_CONTAINER::getHttpEndpoint);
registry.add("dapr.grpc.endpoint", DAPR_CONTAINER::getGrpcEndpoint);
registry.add("server.port", () -> PORT);
}
@Autowired
private ActorClient daprActorClient;
@Autowired
private ActorRuntime daprActorRuntime;
@BeforeEach
public void setUp(){
org.testcontainers.Testcontainers.exposeHostPorts(PORT);
daprActorRuntime.registerActor(TestActorImpl.class);
// Ensure the subscriptions are registered
Wait.forLogMessage(ACTORS_MESSAGE_PATTERN, 1).waitUntilReady(DAPR_CONTAINER);
}
@Test
public void testActors() {
ActorProxyBuilder<TestActor> builder = new ActorProxyBuilder<>(TestActor.class, daprActorClient);
ActorId actorId = ActorId.createRandom();
TestActor actor = builder.build(actorId);
String message = UUID.randomUUID().toString();
String echoedMessage = actor.echo(message);
assertEquals(echoedMessage, message);
}
}

View File

@ -0,0 +1,22 @@
/*
* Copyright 2025 The Dapr Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
limitations under the License.
*/
package io.dapr.it.testcontainers;
import io.dapr.actors.ActorMethod;
import io.dapr.actors.ActorType;
@ActorType(name = "TestActor")
public interface TestActor {
@ActorMethod(name = "echo_message")
String echo(String message);
}

View File

@ -0,0 +1,29 @@
/*
* Copyright 2025 The Dapr Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
limitations under the License.
*/
package io.dapr.it.testcontainers;
import io.dapr.actors.ActorId;
import io.dapr.actors.runtime.AbstractActor;
import io.dapr.actors.runtime.ActorRuntimeContext;
public class TestActorImpl extends AbstractActor implements TestActor {
public TestActorImpl(ActorRuntimeContext runtimeContext, ActorId id) {
super(runtimeContext, id);
}
@Override
public String echo(String message) {
return message;
}
}

View File

@ -0,0 +1,34 @@
/*
* Copyright 2024 The Dapr Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
limitations under the License.
*/
package io.dapr.it.testcontainers;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class TestActorsApplication {
public static void main(String[] args) {
SpringApplication.run(TestActorsApplication.class, args);
}
//Mocking the actuator health endpoint for the sidecar health check
@GetMapping("/actuator/health")
public String health(){
return "OK";
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright 2025 The Dapr Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
limitations under the License.
*/
package io.dapr.it.testcontainers;
import java.util.Map;
import io.dapr.actors.runtime.ActorRuntime;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import io.dapr.actors.client.ActorClient;
import io.dapr.config.Properties;
@Configuration
public class TestDaprActorsConfiguration {
@Bean
public ActorClient daprActorClient(
@Value("${dapr.http.endpoint}") String daprHttpEndpoint,
@Value("${dapr.grpc.endpoint}") String daprGrpcEndpoint
){
Map<String, String> overrides = Map.of(
"dapr.http.endpoint", daprHttpEndpoint,
"dapr.grpc.endpoint", daprGrpcEndpoint
);
return new ActorClient(new Properties(overrides));
}
@Bean
public ActorRuntime daprActorRuntime(
@Value("${dapr.http.endpoint}") String daprHttpEndpoint,
@Value("${dapr.grpc.endpoint}") String daprGrpcEndpoint
){
Map<String, String> overrides = Map.of(
"dapr.http.endpoint", daprHttpEndpoint,
"dapr.grpc.endpoint", daprGrpcEndpoint
);
return ActorRuntime.getInstance(new Properties(overrides));
}
}

View File

@ -1,3 +1,16 @@
/*
* Copyright 2025 The Dapr Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
limitations under the License.
*/
package io.dapr.it.testcontainers;
import com.fasterxml.jackson.databind.ObjectMapper;