From b5f541bc34302d9fbd8750476838959794a44abd Mon Sep 17 00:00:00 2001 From: Cassandra Coyle Date: Thu, 21 Aug 2025 13:12:38 -0500 Subject: [PATCH] fix header + rm customports Signed-off-by: Cassandra Coyle --- .../crossapp/App2TransformActivity.java | 4 +- .../workflows/crossapp/App2Worker.java | 40 +++++++++++ .../crossapp/App3FinalizeActivity.java | 4 +- .../workflows/crossapp/App3Worker.java | 4 +- .../workflows/crossapp/CrossAppWorker.java | 4 +- .../workflows/crossapp/CrossAppWorkflow.java | 6 +- .../WorkflowsCrossAppCallActivityIT.java | 66 ++++++++++++++----- .../io/dapr/testcontainers/DaprContainer.java | 29 +------- 8 files changed, 107 insertions(+), 50 deletions(-) create mode 100644 sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/App2Worker.java diff --git a/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/App2TransformActivity.java b/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/App2TransformActivity.java index 534558fac..0fa473306 100644 --- a/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/App2TransformActivity.java +++ b/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/App2TransformActivity.java @@ -2,12 +2,14 @@ * 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.workflows.crossapp; diff --git a/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/App2Worker.java b/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/App2Worker.java new file mode 100644 index 000000000..f9748f302 --- /dev/null +++ b/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/App2Worker.java @@ -0,0 +1,40 @@ +/* + * 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.workflows.crossapp; + +import io.dapr.workflows.runtime.WorkflowRuntime; +import io.dapr.workflows.runtime.WorkflowRuntimeBuilder; + +/** + * App2Worker - registers the App2TransformActivity. + * This app will handle cross-app activity calls from the main workflow. + */ +public class App2Worker { + + public static void main(String[] args) throws Exception { + System.out.println("=== Starting App2Worker (App2TransformActivity) ==="); + + // Register the Activity with the builder + WorkflowRuntimeBuilder builder = new WorkflowRuntimeBuilder() + .registerActivity(App2TransformActivity.class); + + // Build and start the workflow runtime + try (WorkflowRuntime runtime = builder.build()) { + System.out.println("App2Worker started - registered App2TransformActivity only"); + System.out.println("App2 is ready to receive cross-app activity calls..."); + System.out.println("Waiting for cross-app activity calls..."); + runtime.start(); + } + } +} diff --git a/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/App3FinalizeActivity.java b/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/App3FinalizeActivity.java index c01ad3235..e74976b4c 100644 --- a/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/App3FinalizeActivity.java +++ b/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/App3FinalizeActivity.java @@ -2,12 +2,14 @@ * 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.workflows.crossapp; diff --git a/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/App3Worker.java b/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/App3Worker.java index 7ac67db33..be1d8de46 100644 --- a/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/App3Worker.java +++ b/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/App3Worker.java @@ -2,12 +2,14 @@ * 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.workflows.crossapp; diff --git a/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/CrossAppWorker.java b/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/CrossAppWorker.java index b5cc2db41..36a2fdf79 100644 --- a/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/CrossAppWorker.java +++ b/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/CrossAppWorker.java @@ -2,12 +2,14 @@ * 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.workflows.crossapp; diff --git a/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/CrossAppWorkflow.java b/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/CrossAppWorkflow.java index 624f6e172..514f7c59e 100644 --- a/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/CrossAppWorkflow.java +++ b/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/CrossAppWorkflow.java @@ -2,12 +2,14 @@ * 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.workflows.crossapp; @@ -18,6 +20,8 @@ import org.slf4j.Logger; public class CrossAppWorkflow implements Workflow { + + @Override public WorkflowStub create() { return ctx -> { diff --git a/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/WorkflowsCrossAppCallActivityIT.java b/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/WorkflowsCrossAppCallActivityIT.java index f0034685d..3dff1bba4 100644 --- a/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/WorkflowsCrossAppCallActivityIT.java +++ b/sdk-tests/src/test/java/io/dapr/it/testcontainers/workflows/crossapp/WorkflowsCrossAppCallActivityIT.java @@ -2,12 +2,14 @@ * 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.workflows.crossapp; @@ -34,6 +36,7 @@ import org.testcontainers.containers.wait.strategy.Wait; import java.time.Duration; import java.util.Collections; import java.util.Map; +import java.io.File; import static io.dapr.it.testcontainers.ContainerConstants.DAPR_RUNTIME_IMAGE_TAG; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -75,6 +78,9 @@ public class WorkflowsCrossAppCallActivityIT { @BeforeAll public static void setUp() throws Exception { + // Ensure dependencies are copied for container classpath + ensureDependenciesCopied(); + sharedPlacementContainer = new DaprPlacementContainer("daprio/placement:1.16.0-rc.3") .withNetwork(DAPR_NETWORK) .withNetworkAliases("placement") @@ -111,8 +117,6 @@ public class WorkflowsCrossAppCallActivityIT { .withNetworkAliases("app2-sidecar") .withPlacementContainer(sharedPlacementContainer) .withSchedulerContainer(sharedSchedulerContainer) - .withCustomHttpPort(3501) - .withCustomGrpcPort(50002) .withAppChannelAddress("main-workflow-sidecar:3500") .withDaprLogLevel(DaprLogLevel.DEBUG) .withComponent(new Component("kvstore", "state.in-memory", "v1", @@ -120,8 +124,9 @@ public class WorkflowsCrossAppCallActivityIT { .withComponent(new Component("pubsub", "pubsub.in-memory", "v1", Collections.emptyMap())) .withSubscription(new Subscription("local", "pubsub", "topic", "/events")) .withLogConsumer(outputFrame -> System.out.println("APP2: " + outputFrame.getUtf8String())) + .withExposedPorts(3500, 50001) .waitingFor(Wait.forHttp("/v1.0/healthz/outbound") - .forPort(3501) + .forPort(3500) .forStatusCode(200) .forStatusCode(204)); @@ -131,8 +136,6 @@ public class WorkflowsCrossAppCallActivityIT { .withNetworkAliases("app3-sidecar") .withPlacementContainer(sharedPlacementContainer) .withSchedulerContainer(sharedSchedulerContainer) - .withCustomHttpPort(3502) - .withCustomGrpcPort(50003) .withAppChannelAddress("main-workflow-sidecar:3500") .withDaprLogLevel(DaprLogLevel.DEBUG) .withComponent(new Component("kvstore", "state.in-memory", "v1", @@ -140,16 +143,12 @@ public class WorkflowsCrossAppCallActivityIT { .withComponent(new Component("pubsub", "pubsub.in-memory", "v1", Collections.emptyMap())) .withSubscription(new Subscription("local", "pubsub", "topic", "/events")) .withLogConsumer(outputFrame -> System.out.println("APP3: " + outputFrame.getUtf8String())) + .withExposedPorts(3500, 50001) .waitingFor(Wait.forHttp("/v1.0/healthz/outbound") - .forPort(3502) + .forPort(3500) .forStatusCode(200) .forStatusCode(204)); - // Start the Dapr containers - MAIN_WORKFLOW_CONTAINER.start(); - APP2_CONTAINER.start(); - APP3_CONTAINER.start(); - // Start crossapp worker (connects to MAIN_WORKFLOW_CONTAINER) crossappWorker = new GenericContainer<>("openjdk:17-jdk-slim") .withCopyFileToContainer(MountableFile.forHostPath("target/test-classes"), "/app/classes") @@ -164,20 +163,25 @@ public class WorkflowsCrossAppCallActivityIT { .waitingFor(Wait.forLogMessage(".*CrossAppWorker started.*", 1)) .withLogConsumer(outputFrame -> System.out.println("CrossAppWorker: " + outputFrame.getUtf8String())); - // Start app2 worker (connects to APP2_CONTAINER) + // Start all Dapr containers + MAIN_WORKFLOW_CONTAINER.start(); + APP2_CONTAINER.start(); + APP3_CONTAINER.start(); + + // Start app2 worker (connects to APP2_CONTAINER) app2Worker = new GenericContainer<>("openjdk:17-jdk-slim") .withCopyFileToContainer(MountableFile.forHostPath("target/test-classes"), "/app/classes") .withCopyFileToContainer(MountableFile.forHostPath("target/dependency"), "/app/libs") .withWorkingDirectory("/app") .withCommand("java", "-cp", "/app/classes:/app/libs/*", "-Ddapr.app.id=app2", - "-Ddapr.grpc.endpoint=app2-sidecar:50002", - "-Ddapr.http.endpoint=app2-sidecar:3501", + "-Ddapr.grpc.endpoint=app2-sidecar:50001", + "-Ddapr.http.endpoint=app2-sidecar:3500", "io.dapr.it.testcontainers.workflows.crossapp.App2Worker") .withNetwork(DAPR_NETWORK) .waitingFor(Wait.forLogMessage(".*App2Worker started.*", 1)) .withLogConsumer(outputFrame -> System.out.println("App2Worker: " + outputFrame.getUtf8String())); - + // Start app3 worker (connects to APP3_CONTAINER) app3Worker = new GenericContainer<>("openjdk:17-jdk-slim") .withCopyFileToContainer(MountableFile.forHostPath("target/test-classes"), "/app/classes") @@ -185,8 +189,8 @@ public class WorkflowsCrossAppCallActivityIT { .withWorkingDirectory("/app") .withCommand("java", "-cp", "/app/classes:/app/libs/*", "-Ddapr.app.id=app3", - "-Ddapr.grpc.endpoint=app3-sidecar:50003", - "-Ddapr.http.endpoint=app3-sidecar:3502", + "-Ddapr.grpc.endpoint=app3-sidecar:50001", + "-Ddapr.http.endpoint=app3-sidecar:3500", "io.dapr.it.testcontainers.workflows.crossapp.App3Worker") .withNetwork(DAPR_NETWORK) .waitingFor(Wait.forLogMessage(".*App3Worker started.*", 1)) @@ -264,4 +268,30 @@ public class WorkflowsCrossAppCallActivityIT { workflowClient.close(); } } + + /** + * Ensures that dependencies are copied to target/dependency for container classpath. + * This is needed because the containers need access to the workflow runtime classes. + */ + private static void ensureDependenciesCopied() { + File dependencyDir = new File("target/dependency"); + if (!dependencyDir.exists() || dependencyDir.listFiles() == null || dependencyDir.listFiles().length == 0) { + System.out.println("Dependencies not found in target/dependency, copying..."); + try { + ProcessBuilder pb = new ProcessBuilder("mvn", "dependency:copy-dependencies", + "-Dspotbugs.skip=true", "-Dcheckstyle.skip=true"); + pb.inheritIO(); + Process process = pb.start(); + int exitCode = process.waitFor(); + if (exitCode != 0) { + throw new RuntimeException("Failed to copy dependencies, exit code: " + exitCode); + } + System.out.println("Dependencies copied successfully"); + } catch (Exception e) { + throw new RuntimeException("Failed to ensure dependencies are copied", e); + } + } else { + System.out.println("Dependencies already exist in target/dependency"); + } + } } diff --git a/testcontainers-dapr/src/main/java/io/dapr/testcontainers/DaprContainer.java b/testcontainers-dapr/src/main/java/io/dapr/testcontainers/DaprContainer.java index 0845a6994..3517e1049 100644 --- a/testcontainers-dapr/src/main/java/io/dapr/testcontainers/DaprContainer.java +++ b/testcontainers-dapr/src/main/java/io/dapr/testcontainers/DaprContainer.java @@ -84,8 +84,7 @@ public class DaprContainer extends GenericContainer { private boolean shouldReusePlacement; private boolean shouldReuseScheduler; - private Integer customHttpPort; - private Integer customGrpcPort; + /** * Creates a new Dapr container. @@ -170,15 +169,7 @@ public class DaprContainer extends GenericContainer { return this; } - public DaprContainer withCustomHttpPort(Integer port) { - this.customHttpPort = port; - return this; - } - public DaprContainer withCustomGrpcPort(Integer port) { - this.customGrpcPort = port; - return this; - } public DaprContainer withAppName(String appName) { this.appName = appName; @@ -370,16 +361,6 @@ public class DaprContainer extends GenericContainer { cmds.add("--dapr-listen-addresses=0.0.0.0"); - if (customHttpPort != null) { - cmds.add("--dapr-http-port"); - cmds.add(Integer.toString(customHttpPort)); - } - - if (customGrpcPort != null) { - cmds.add("--dapr-grpc-port"); - cmds.add(Integer.toString(customGrpcPort)); - } - cmds.add("--app-protocol"); cmds.add(DAPR_PROTOCOL.getName()); cmds.add("--placement-host-address"); @@ -429,13 +410,7 @@ public class DaprContainer extends GenericContainer { withCommand(cmdArray); - // Update exposed ports and wait strategy if custom ports are specified - if (customHttpPort != null && customGrpcPort != null) { - withExposedPorts(customHttpPort, customGrpcPort); - setWaitStrategy(Wait.forHttp("/v1.0/healthz/outbound") - .forPort(customHttpPort) - .forStatusCodeMatching(statusCode -> statusCode >= 200 && statusCode <= 399)); - } + super.start(); }