From efce22998532b5b8ae68352995003d5ac2fbb79f Mon Sep 17 00:00:00 2001 From: Christian Kaps <307006+akkie@users.noreply.github.com> Date: Sat, 1 Mar 2025 19:00:52 +0100 Subject: [PATCH] Add actor testcontainer tests (#1192) * Add actor testcontainer tests Signed-off-by: Christian Kaps * adding auto config Signed-off-by: Christian Kaps * updating ActorClient Signed-off-by: Christian Kaps * registering? Signed-off-by: Christian Kaps * updating actors test and actorruntime Signed-off-by: Christian Kaps * updating ActorRuntime Signed-off-by: Christian Kaps * Adding WorkflowTaskOptions and use it instead of TaskOptions (#1200) Signed-off-by: Christian Kaps * Fix formatting issues Signed-off-by: Christian Kaps * adding spring boot workflows integration (#1195) Co-authored-by: Cassie Coyle Signed-off-by: Christian Kaps * Register workflows and acitivities using instances along classes (#1201) Signed-off-by: Christian Kaps * feat: Adding basic HTTPEndpoint configuration support in testcontainers module (#1210) * feat: Adding basic HTTPEndpoint configuration support in testcontainers module Signed-off-by: Laurent Broudoux * feat: #1209 Adding test for HTTPEndpoint in testcontainers module Signed-off-by: Laurent Broudoux --------- Signed-off-by: Laurent Broudoux Signed-off-by: Christian Kaps * fixing actors IT test and messaging IT with app-health-checks Signed-off-by: Christian Kaps * Add app health check support to Dapr Testcontainer (#1213) * Add app health check support to Dapr Testcontainer Signed-off-by: Artur Ciocanu * Some minor cleanup Signed-off-by: Artur Ciocanu * Move waiting to beforeEach, it looks more natural Signed-off-by: Artur Ciocanu --------- Signed-off-by: Artur Ciocanu Co-authored-by: Artur Ciocanu Signed-off-by: Christian Kaps * adding license headers + adding wait for actors in test Signed-off-by: Christian Kaps * Add app health check support to Dapr Testcontainer (#1213) * Add app health check support to Dapr Testcontainer Signed-off-by: Artur Ciocanu * Some minor cleanup Signed-off-by: Artur Ciocanu * Move waiting to beforeEach, it looks more natural Signed-off-by: Artur Ciocanu --------- Signed-off-by: Artur Ciocanu Co-authored-by: Artur Ciocanu Signed-off-by: Christian Kaps * Picks a port for DaprActorITS for test containers to avoid conflict. Signed-off-by: Artur Souza Signed-off-by: Christian Kaps * Add app health check support to Dapr Testcontainer (#1213) * Add app health check support to Dapr Testcontainer Signed-off-by: Artur Ciocanu * Some minor cleanup Signed-off-by: Artur Ciocanu * Move waiting to beforeEach, it looks more natural Signed-off-by: Artur Ciocanu --------- Signed-off-by: Artur Ciocanu Co-authored-by: Artur Ciocanu Signed-off-by: Christian Kaps * using random port thanks to @artur-ciocanu Signed-off-by: Christian Kaps * Update TestRestController.java Signed-off-by: artur-ciocanu * Update DaprActorsIT.java Signed-off-by: artur-ciocanu * Update DaprContainer.java Signed-off-by: artur-ciocanu --------- Signed-off-by: Christian Kaps Signed-off-by: Laurent Broudoux Signed-off-by: Artur Ciocanu Signed-off-by: Artur Souza Signed-off-by: Artur Souza Signed-off-by: artur-ciocanu Co-authored-by: salaboy Co-authored-by: artur-ciocanu Co-authored-by: Cassie Coyle Co-authored-by: Laurent Broudoux Co-authored-by: Artur Ciocanu Co-authored-by: Artur Souza Co-authored-by: Artur Souza --- .../client/DaprClientAutoConfiguration.java | 16 +++ .../io/dapr/actors/client/ActorClient.java | 22 +--- .../io/dapr/actors/runtime/ActorRuntime.java | 103 +++++++++-------- .../java/io/dapr/it/actors/ActorStateIT.java | 2 +- .../dapr/it/testcontainers/DaprActorsIT.java | 107 ++++++++++++++++++ .../io/dapr/it/testcontainers/TestActor.java | 22 ++++ .../dapr/it/testcontainers/TestActorImpl.java | 29 +++++ .../testcontainers/TestActorsApplication.java | 34 ++++++ .../TestDaprActorsConfiguration.java | 53 +++++++++ .../TestDaprWorkflowsConfiguration.java | 13 +++ 10 files changed, 332 insertions(+), 69 deletions(-) create mode 100644 sdk-tests/src/test/java/io/dapr/it/testcontainers/DaprActorsIT.java create mode 100644 sdk-tests/src/test/java/io/dapr/it/testcontainers/TestActor.java create mode 100644 sdk-tests/src/test/java/io/dapr/it/testcontainers/TestActorImpl.java create mode 100644 sdk-tests/src/test/java/io/dapr/it/testcontainers/TestActorsApplication.java create mode 100644 sdk-tests/src/test/java/io/dapr/it/testcontainers/TestDaprActorsConfiguration.java diff --git a/dapr-spring/dapr-spring-boot-autoconfigure/src/main/java/io/dapr/spring/boot/autoconfigure/client/DaprClientAutoConfiguration.java b/dapr-spring/dapr-spring-boot-autoconfigure/src/main/java/io/dapr/spring/boot/autoconfigure/client/DaprClientAutoConfiguration.java index 7e10c1f8f..ebd6a18d7 100644 --- a/dapr-spring/dapr-spring-boot-autoconfigure/src/main/java/io/dapr/spring/boot/autoconfigure/client/DaprClientAutoConfiguration.java +++ b/dapr-spring/dapr-spring-boot-autoconfigure/src/main/java/io/dapr/spring/boot/autoconfigure/client/DaprClientAutoConfiguration.java @@ -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) { diff --git a/sdk-actors/src/main/java/io/dapr/actors/client/ActorClient.java b/sdk-actors/src/main/java/io/dapr/actors/client/ActorClient.java index 08c0a1c9e..1fe2d4f19 100644 --- a/sdk-actors/src/main/java/io/dapr/actors/client/ActorClient.java +++ b/sdk-actors/src/main/java/io/dapr/actors/client/ActorClient.java @@ -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 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. diff --git a/sdk-actors/src/main/java/io/dapr/actors/runtime/ActorRuntime.java b/sdk-actors/src/main/java/io/dapr/actors/runtime/ActorRuntime.java index 8eb09bc7d..d329946e5 100644 --- a/sdk-actors/src/main/java/io/dapr/actors/runtime/ActorRuntime.java +++ b/sdk-actors/src/main/java/io/dapr/actors/runtime/ActorRuntime.java @@ -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 Actor class type. + * @param clazz The type of actor. + * @param Actor class type. */ public void registerActor(Class 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 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 Actor class type. */ public void registerActor(Class clazz, ActorFactory actorFactory) { registerActor(clazz, actorFactory, new DefaultObjectSerializer(), new DefaultObjectSerializer()); @@ -181,8 +205,8 @@ public class ActorRuntime implements Closeable { * @param Actor class type. */ public void registerActor( - Class clazz, DaprObjectSerializer objectSerializer, DaprObjectSerializer stateSerializer) { - registerActor(clazz, new DefaultActorFactory(), objectSerializer, stateSerializer); + Class clazz, DaprObjectSerializer objectSerializer, DaprObjectSerializer stateSerializer) { + registerActor(clazz, new DefaultActorFactory(), objectSerializer, stateSerializer); } /** @@ -195,9 +219,9 @@ public class ActorRuntime implements Closeable { * @param Actor class type. */ public void registerActor( - Class clazz, ActorFactory actorFactory, - DaprObjectSerializer objectSerializer, - DaprObjectSerializer stateSerializer) { + Class clazz, ActorFactory 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 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(context); }); @@ -236,7 +260,7 @@ public class ActorRuntime implements Closeable { */ public Mono 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 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 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 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} */ diff --git a/sdk-tests/src/test/java/io/dapr/it/actors/ActorStateIT.java b/sdk-tests/src/test/java/io/dapr/it/actors/ActorStateIT.java index 67d6b9659..90bab85e5 100644 --- a/sdk-tests/src/test/java/io/dapr/it/actors/ActorStateIT.java +++ b/sdk-tests/src/test/java/io/dapr/it/actors/ActorStateIT.java @@ -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(() -> { diff --git a/sdk-tests/src/test/java/io/dapr/it/testcontainers/DaprActorsIT.java b/sdk-tests/src/test/java/io/dapr/it/testcontainers/DaprActorsIT.java new file mode 100644 index 000000000..69eefd962 --- /dev/null +++ b/sdk-tests/src/test/java/io/dapr/it/testcontainers/DaprActorsIT.java @@ -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 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); + } +} diff --git a/sdk-tests/src/test/java/io/dapr/it/testcontainers/TestActor.java b/sdk-tests/src/test/java/io/dapr/it/testcontainers/TestActor.java new file mode 100644 index 000000000..c5457fa55 --- /dev/null +++ b/sdk-tests/src/test/java/io/dapr/it/testcontainers/TestActor.java @@ -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); +} diff --git a/sdk-tests/src/test/java/io/dapr/it/testcontainers/TestActorImpl.java b/sdk-tests/src/test/java/io/dapr/it/testcontainers/TestActorImpl.java new file mode 100644 index 000000000..c17164299 --- /dev/null +++ b/sdk-tests/src/test/java/io/dapr/it/testcontainers/TestActorImpl.java @@ -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; + } +} diff --git a/sdk-tests/src/test/java/io/dapr/it/testcontainers/TestActorsApplication.java b/sdk-tests/src/test/java/io/dapr/it/testcontainers/TestActorsApplication.java new file mode 100644 index 000000000..e55646218 --- /dev/null +++ b/sdk-tests/src/test/java/io/dapr/it/testcontainers/TestActorsApplication.java @@ -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"; + } +} diff --git a/sdk-tests/src/test/java/io/dapr/it/testcontainers/TestDaprActorsConfiguration.java b/sdk-tests/src/test/java/io/dapr/it/testcontainers/TestDaprActorsConfiguration.java new file mode 100644 index 000000000..23f2cf2e0 --- /dev/null +++ b/sdk-tests/src/test/java/io/dapr/it/testcontainers/TestDaprActorsConfiguration.java @@ -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 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 overrides = Map.of( + "dapr.http.endpoint", daprHttpEndpoint, + "dapr.grpc.endpoint", daprGrpcEndpoint + ); + + return ActorRuntime.getInstance(new Properties(overrides)); + } +} diff --git a/sdk-tests/src/test/java/io/dapr/it/testcontainers/TestDaprWorkflowsConfiguration.java b/sdk-tests/src/test/java/io/dapr/it/testcontainers/TestDaprWorkflowsConfiguration.java index 982d7e89f..0a2487b70 100644 --- a/sdk-tests/src/test/java/io/dapr/it/testcontainers/TestDaprWorkflowsConfiguration.java +++ b/sdk-tests/src/test/java/io/dapr/it/testcontainers/TestDaprWorkflowsConfiguration.java @@ -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;