fix header + rm customports

Signed-off-by: Cassandra Coyle <cassie@diagrid.io>
This commit is contained in:
Cassandra Coyle 2025-08-21 13:12:38 -05:00 committed by Javier Aliaga
parent fcaf69976f
commit b5f541bc34
8 changed files with 107 additions and 50 deletions

View File

@ -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;

View File

@ -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();
}
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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 -> {

View File

@ -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,15 +163,20 @@ 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))
@ -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");
}
}
}

View File

@ -84,8 +84,7 @@ public class DaprContainer extends GenericContainer<DaprContainer> {
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<DaprContainer> {
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<DaprContainer> {
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<DaprContainer> {
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();
}