From a99826c894433287f97329629f3e99b9d9928e9c Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Mon, 7 Oct 2024 10:50:27 -0700 Subject: [PATCH 1/8] Add Nexus samples --- build.gradle | 4 +- core/build.gradle | 1 + .../java/io/temporal/samples/nexus/README.MD | 99 +++++++++++++++++++ .../samples/nexus/caller/CallerStarter.java | 30 ++++++ .../samples/nexus/caller/CallerWorker.java | 34 +++++++ .../nexus/caller/EchoCallerWorkflow.java | 10 ++ .../nexus/caller/EchoCallerWorkflowImpl.java | 13 +++ .../nexus/caller/HelloCallerWorkflow.java | 11 +++ .../nexus/caller/HelloCallerWorkflowImpl.java | 21 ++++ .../samples/nexus/handler/HandlerWorker.java | 27 +++++ .../nexus/handler/HelloHandlerWorkflow.java | 11 +++ .../handler/HelloHandlerWorkflowImpl.java | 24 +++++ .../nexus/handler/NexusServiceImpl.java | 44 +++++++++ .../samples/nexus/service/NexusService.java | 87 ++++++++++++++++ .../samples/nexus/service/description.md | 8 ++ 15 files changed, 423 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/io/temporal/samples/nexus/README.MD create mode 100644 core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java create mode 100644 core/src/main/java/io/temporal/samples/nexus/caller/CallerWorker.java create mode 100644 core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflow.java create mode 100644 core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflowImpl.java create mode 100644 core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflow.java create mode 100644 core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflowImpl.java create mode 100644 core/src/main/java/io/temporal/samples/nexus/handler/HandlerWorker.java create mode 100644 core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflow.java create mode 100644 core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflowImpl.java create mode 100644 core/src/main/java/io/temporal/samples/nexus/handler/NexusServiceImpl.java create mode 100644 core/src/main/java/io/temporal/samples/nexus/service/NexusService.java create mode 100644 core/src/main/java/io/temporal/samples/nexus/service/description.md diff --git a/build.gradle b/build.gradle index 065224a6..eaf29032 100644 --- a/build.gradle +++ b/build.gradle @@ -28,12 +28,14 @@ subprojects { ext { otelVersion = '1.30.1' otelVersionAlpha = "${otelVersion}-alpha" - javaSDKVersion = '1.25.0' + javaSDKVersion = '1.23.0-SNAPSHOT' camelVersion = '3.22.1' jarVersion = '1.0.0' + nexusVersion = '0.1.0-alpha1' } repositories { + mavenLocal() maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } diff --git a/core/build.gradle b/core/build.gradle index c73ce227..1f445b99 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -8,6 +8,7 @@ dependencies { implementation(platform("com.fasterxml.jackson:jackson-bom:2.17.2")) implementation "com.fasterxml.jackson.core:jackson-databind" implementation "com.fasterxml.jackson.core:jackson-core" + implementation "io.nexusrpc:nexus-sdk:$nexusVersion" implementation "io.micrometer:micrometer-registry-prometheus" diff --git a/core/src/main/java/io/temporal/samples/nexus/README.MD b/core/src/main/java/io/temporal/samples/nexus/README.MD new file mode 100644 index 00000000..e77daba5 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/nexus/README.MD @@ -0,0 +1,99 @@ +# Nexus + +Temporal Nexus is a new feature of the Temporal platform designed to connect durable executions across team, namespace, +region, and cloud boundaries. It promotes a more modular architecture for sharing a subset of your team’s capabilities +via well-defined service API contracts for other teams to use, that abstract underlying Temporal primitives, like +Workflows, or execute arbitrary code. + +Learn more at [temporal.io/nexus](https://temporal.io/nexus). + +This sample shows how to use Temporal for authoring a Nexus service and call it from a workflow. + +### Sample directory structure + +- [service](./service) - shared service defintion +- [caller](./caller) - caller workflows, worker, and starter +- [handler](./handler) - handler workflow, operations, and worker +- [options](./options) - command line argument parsing utility + +## Getting started locally + +### Get `temporal` CLI to enable local development + +1. Follow the instructions on the [docs + site](https://learn.temporal.io/getting_started/go/dev_environment/#set-up-a-local-temporal-service-for-development-with-temporal-cli) + to install Temporal CLI. + +> NOTE: Required version is at least v1.1.0. + +### Spin up environment + +#### Start temporal server + +> HTTP port is required for Nexus communications + +``` +temporal server start-dev --http-port 7243 --dynamic-config-value system.enableNexus=true +``` + +### Initialize environment + +In a separate terminal window + +#### Create caller and target namespaces + +``` +temporal operator namespace create --namespace my-target-namespace +temporal operator namespace create --namespace my-caller-namespace +``` + +#### Create Nexus endpoint + +``` +temporal operator nexus endpoint create \ + --name my-nexus-endpoint-name \ + --target-namespace my-target-namespace \ + --target-task-queue my-handler-task-queue + ``` + +## Getting started with a self-hosted service or Temporal Cloud + +Nexus is currently available as +[Public Preview](https://docs.temporal.io/evaluate/development-production-features/release-stages). + +Self hosted users can [try Nexus +out](https://github.com/temporalio/temporal/blob/main/docs/architecture/nexus.md#trying-nexus-out) in single cluster +deployments with server version 1.25.0. + +### Make Nexus calls across namespace boundaries + +> Instructions apply for local development, for Temporal Cloud or a self hosted setups, supply the relevant [CLI +> flags](./options/cli.go) to properly set up the connection. + +In separate terminal windows: + +### Nexus handler worker + +``` +./gradlew -q execute -PmainClass=io.temporal.samples.nexus.handler.HandlerWorker +``` + +### Nexus caller worker + +``` +./gradlew -q execute -PmainClass=io.temporal.samples.nexus.caller.CallerWorker +``` + +### Start caller workflow + +``` +./gradlew -q execute -PmainClass=io.temporal.samples.nexus.caller.CallerStarter +``` + +### Output + +which should result in: +``` +[main] INFO i.t.s.nexus.caller.CallerStarter - Workflow result: Nexus Echo πŸ‘‹ +[main] INFO i.t.s.nexus.caller.CallerStarter - Workflow result: Hola Nexus πŸ‘‹ +``` diff --git a/core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java b/core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java new file mode 100644 index 00000000..f7c70f5b --- /dev/null +++ b/core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java @@ -0,0 +1,30 @@ +package io.temporal.samples.nexus.caller; + +import io.temporal.client.WorkflowClient; +import io.temporal.client.WorkflowClientOptions; +import io.temporal.client.WorkflowOptions; +import io.temporal.samples.nexus.service.NexusService; +import io.temporal.serviceclient.WorkflowServiceStubs; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CallerStarter { + private static final Logger logger = LoggerFactory.getLogger(CallerStarter.class); + + public static void main(String[] args) { + WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + WorkflowClient client = + WorkflowClient.newInstance( + service, + WorkflowClientOptions.newBuilder().setNamespace("my-caller-namespace").build()); + + WorkflowOptions workflowOptions = + WorkflowOptions.newBuilder().setTaskQueue(CallerWorker.DEFAULT_TASK_QUEUE_NAME).build(); + EchoCallerWorkflow echoWorkflow = + client.newWorkflowStub(EchoCallerWorkflow.class, workflowOptions); + logger.info("Workflow result: " + echoWorkflow.echo("Nexus Echo πŸ‘‹")); + HelloCallerWorkflow helloWorkflow = + client.newWorkflowStub(HelloCallerWorkflow.class, workflowOptions); + logger.info("Workflow result: " + helloWorkflow.hello("Nexus", NexusService.Language.ES)); + } +} diff --git a/core/src/main/java/io/temporal/samples/nexus/caller/CallerWorker.java b/core/src/main/java/io/temporal/samples/nexus/caller/CallerWorker.java new file mode 100644 index 00000000..c585dd70 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/nexus/caller/CallerWorker.java @@ -0,0 +1,34 @@ +package io.temporal.samples.nexus.caller; + +import io.temporal.client.WorkflowClient; +import io.temporal.client.WorkflowClientOptions; +import io.temporal.serviceclient.WorkflowServiceStubs; +import io.temporal.worker.Worker; +import io.temporal.worker.WorkerFactory; +import io.temporal.worker.WorkflowImplementationOptions; +import io.temporal.workflow.NexusServiceOptions; + +public class CallerWorker { + public static final String DEFAULT_TASK_QUEUE_NAME = "my-caller-workflow-task-queue"; + + public static void main(String[] args) { + WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + + WorkflowClient client = + WorkflowClient.newInstance( + service, + WorkflowClientOptions.newBuilder().setNamespace("my-caller-namespace").build()); + WorkerFactory factory = WorkerFactory.newInstance(client); + + Worker worker = factory.newWorker(DEFAULT_TASK_QUEUE_NAME); + worker.registerWorkflowImplementationTypes( + WorkflowImplementationOptions.newBuilder() + .setDefaultNexusServiceOptions( + NexusServiceOptions.newBuilder().setEndpoint("my-nexus-endpoint-name").build()) + .build(), + EchoCallerWorkflowImpl.class, + HelloCallerWorkflowImpl.class); + + factory.start(); + } +} diff --git a/core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflow.java b/core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflow.java new file mode 100644 index 00000000..b4c7fac8 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflow.java @@ -0,0 +1,10 @@ +package io.temporal.samples.nexus.caller; + +import io.temporal.workflow.WorkflowInterface; +import io.temporal.workflow.WorkflowMethod; + +@WorkflowInterface +public interface EchoCallerWorkflow { + @WorkflowMethod + String echo(String message); +} diff --git a/core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflowImpl.java b/core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflowImpl.java new file mode 100644 index 00000000..e36da75c --- /dev/null +++ b/core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflowImpl.java @@ -0,0 +1,13 @@ +package io.temporal.samples.nexus.caller; + +import io.temporal.samples.nexus.service.NexusService; +import io.temporal.workflow.Workflow; + +public class EchoCallerWorkflowImpl implements EchoCallerWorkflow { + NexusService nexusService = Workflow.newNexusServiceStub(NexusService.class); + + @Override + public String echo(String message) { + return nexusService.echo(new NexusService.EchoInput(message)).getMessage(); + } +} diff --git a/core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflow.java b/core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflow.java new file mode 100644 index 00000000..173c0be8 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflow.java @@ -0,0 +1,11 @@ +package io.temporal.samples.nexus.caller; + +import io.temporal.samples.nexus.service.NexusService; +import io.temporal.workflow.WorkflowInterface; +import io.temporal.workflow.WorkflowMethod; + +@WorkflowInterface +public interface HelloCallerWorkflow { + @WorkflowMethod + String hello(String message, NexusService.Language language); +} diff --git a/core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflowImpl.java b/core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflowImpl.java new file mode 100644 index 00000000..e95dce17 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflowImpl.java @@ -0,0 +1,21 @@ +package io.temporal.samples.nexus.caller; + +import io.temporal.samples.nexus.service.NexusService; +import io.temporal.workflow.NexusOperationHandle; +import io.temporal.workflow.Workflow; + +public class HelloCallerWorkflowImpl implements HelloCallerWorkflow { + NexusService nexusService = Workflow.newNexusServiceStub(NexusService.class); + + @Override + public String hello(String message, NexusService.Language language) { + NexusOperationHandle handle = + Workflow.startNexusOperation( + nexusService::hello, new NexusService.HelloInput(message, language)); + // Optionally wait for the operation to be started. NexusOperationExecution will contain the + // operation ID in + // case this operation is asynchronous. + handle.getExecution().get(); + return handle.getResult().get().getMessage(); + } +} diff --git a/core/src/main/java/io/temporal/samples/nexus/handler/HandlerWorker.java b/core/src/main/java/io/temporal/samples/nexus/handler/HandlerWorker.java new file mode 100644 index 00000000..16d404f6 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/nexus/handler/HandlerWorker.java @@ -0,0 +1,27 @@ +package io.temporal.samples.nexus.handler; + +import io.temporal.client.WorkflowClient; +import io.temporal.client.WorkflowClientOptions; +import io.temporal.serviceclient.WorkflowServiceStubs; +import io.temporal.worker.Worker; +import io.temporal.worker.WorkerFactory; + +public class HandlerWorker { + public static final String DEFAULT_TASK_QUEUE_NAME = "my-handler-task-queue"; + + public static void main(String[] args) { + WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + + WorkflowClient client = + WorkflowClient.newInstance( + service, + WorkflowClientOptions.newBuilder().setNamespace("my-target-namespace").build()); + WorkerFactory factory = WorkerFactory.newInstance(client); + + Worker worker = factory.newWorker(DEFAULT_TASK_QUEUE_NAME); + worker.registerWorkflowImplementationTypes(HelloHandlerWorkflowImpl.class); + worker.registerNexusServiceImplementation(new NexusServiceImpl()); + + factory.start(); + } +} diff --git a/core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflow.java b/core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflow.java new file mode 100644 index 00000000..3cae13b3 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflow.java @@ -0,0 +1,11 @@ +package io.temporal.samples.nexus.handler; + +import io.temporal.samples.nexus.service.NexusService; +import io.temporal.workflow.WorkflowInterface; +import io.temporal.workflow.WorkflowMethod; + +@WorkflowInterface +public interface HelloHandlerWorkflow { + @WorkflowMethod + NexusService.HelloOutput hello(NexusService.HelloInput input); +} diff --git a/core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflowImpl.java b/core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflowImpl.java new file mode 100644 index 00000000..84787b65 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflowImpl.java @@ -0,0 +1,24 @@ +package io.temporal.samples.nexus.handler; + +import io.temporal.failure.ApplicationFailure; +import io.temporal.samples.nexus.service.NexusService; + +public class HelloHandlerWorkflowImpl implements HelloHandlerWorkflow { + @Override + public NexusService.HelloOutput hello(NexusService.HelloInput input) { + switch (input.getLanguage()) { + case EN: + return new NexusService.HelloOutput("Hello " + input.getName() + " πŸ‘‹"); + case FR: + return new NexusService.HelloOutput("Bonjour " + input.getName() + " πŸ‘‹"); + case DE: + return new NexusService.HelloOutput("Hallo " + input.getName() + " πŸ‘‹"); + case ES: + return new NexusService.HelloOutput("Hola " + input.getName() + " πŸ‘‹"); + case TR: + return new NexusService.HelloOutput("Merhaba " + input.getName() + " πŸ‘‹"); + } + throw ApplicationFailure.newFailure( + "Unsupported language: " + input.getLanguage(), "UNSUPPORTED_LANGUAGE"); + } +} diff --git a/core/src/main/java/io/temporal/samples/nexus/handler/NexusServiceImpl.java b/core/src/main/java/io/temporal/samples/nexus/handler/NexusServiceImpl.java new file mode 100644 index 00000000..023cb869 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/nexus/handler/NexusServiceImpl.java @@ -0,0 +1,44 @@ +package io.temporal.samples.nexus.handler; + +import io.nexusrpc.handler.OperationHandler; +import io.nexusrpc.handler.OperationImpl; +import io.nexusrpc.handler.ServiceImpl; +import io.temporal.client.WorkflowOptions; +import io.temporal.nexus.WorkflowClientOperationHandlers; +import io.temporal.samples.nexus.service.NexusService; + +@ServiceImpl(service = NexusService.class) +public class NexusServiceImpl { + @OperationImpl + public OperationHandler echo() { + // WorkflowClientOperationHandlers.sync is a meant for exposing simple RPC handlers. + return WorkflowClientOperationHandlers.sync( + // The method is provided with an SDK client that can be used for arbitrary calls such as + // signaling, querying, + // and listing workflows but implementations are free to make arbitrary calls to other + // services or databases, or + // perform simple computations such as this one. + (ctx, details, client, input) -> new NexusService.EchoOutput(input.getMessage())); + } + + @OperationImpl + public OperationHandler hello() { + // Use the WorkflowClientOperationHandlers.fromWorkflowMethod constructor, which is the easiest + // way to expose a workflow as an operation. + // See alternatives at TODO. + return WorkflowClientOperationHandlers.fromWorkflowMethod( + (ctx, details, client, input) -> + client.newWorkflowStub( + HelloHandlerWorkflow.class, + // Workflow IDs should typically be business meaningful IDs and are used to + // dedupe workflow starts. + // For this example, we're using the request ID allocated by Temporal when the + // caller workflow schedules + // the operation, this ID is guaranteed to be stable across retries of this + // operation. + // + // Task queue defaults to the task queue this operation is handled on. + WorkflowOptions.newBuilder().setWorkflowId(details.getRequestId()).build()) + ::hello); + } +} diff --git a/core/src/main/java/io/temporal/samples/nexus/service/NexusService.java b/core/src/main/java/io/temporal/samples/nexus/service/NexusService.java new file mode 100644 index 00000000..ad65b1b3 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/nexus/service/NexusService.java @@ -0,0 +1,87 @@ +package io.temporal.samples.nexus.service; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.nexusrpc.Operation; +import io.nexusrpc.Service; + +@Service +public interface NexusService { + enum Language { + EN, + FR, + DE, + ES, + TR + } + + class HelloInput { + private final String name; + private final Language language; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public HelloInput( + @JsonProperty("name") String name, @JsonProperty("language") Language language) { + this.name = name; + this.language = language; + } + + @JsonProperty("name") + public String getName() { + return name; + } + + @JsonProperty("language") + public Language getLanguage() { + return language; + } + } + + class HelloOutput { + private final String message; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public HelloOutput(@JsonProperty("message") String message) { + this.message = message; + } + + @JsonProperty("message") + public String getMessage() { + return message; + } + } + + class EchoInput { + private final String message; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public EchoInput(@JsonProperty("message") String message) { + this.message = message; + } + + @JsonProperty("message") + public String getMessage() { + return message; + } + } + + class EchoOutput { + private final String message; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public EchoOutput(@JsonProperty("message") String message) { + this.message = message; + } + + @JsonProperty("message") + public String getMessage() { + return message; + } + } + + @Operation + HelloOutput hello(HelloInput input); + + @Operation + EchoOutput echo(EchoInput input); +} diff --git a/core/src/main/java/io/temporal/samples/nexus/service/description.md b/core/src/main/java/io/temporal/samples/nexus/service/description.md new file mode 100644 index 00000000..74eb4d88 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/nexus/service/description.md @@ -0,0 +1,8 @@ +Service Name: +my-hello-service +Operation Names: +echo +say-hello + +Input / Output arguments are in the following repository: +https://github.com/temporalio/samples-java/core/src/main/java/io/temporal/samples/nexus/service/NexusService.java From 13b72ea3edc30f06626d660ead2cc7017f2155d7 Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Sun, 13 Oct 2024 11:40:15 -0700 Subject: [PATCH 2/8] Add cli options --- core/build.gradle | 2 +- .../java/io/temporal/samples/nexus/README.MD | 14 ++- .../samples/nexus/caller/CallerStarter.java | 9 +- .../samples/nexus/caller/CallerWorker.java | 9 +- .../samples/nexus/handler/HandlerWorker.java | 9 +- .../samples/nexus/options/ClientOptions.java | 98 +++++++++++++++++++ 6 files changed, 114 insertions(+), 27 deletions(-) create mode 100644 core/src/main/java/io/temporal/samples/nexus/options/ClientOptions.java diff --git a/core/build.gradle b/core/build.gradle index 1f445b99..b4653f82 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -8,7 +8,6 @@ dependencies { implementation(platform("com.fasterxml.jackson:jackson-bom:2.17.2")) implementation "com.fasterxml.jackson.core:jackson-databind" implementation "com.fasterxml.jackson.core:jackson-core" - implementation "io.nexusrpc:nexus-sdk:$nexusVersion" implementation "io.micrometer:micrometer-registry-prometheus" @@ -29,6 +28,7 @@ dependencies { implementation group: 'io.cloudevents', name: 'cloudevents-api', version: '4.0.1' implementation group: 'io.cloudevents', name: 'cloudevents-json-jackson', version: '3.0.0' implementation group: 'net.thisptr', name: 'jackson-jq', version: '1.0.0-preview.20240207' + implementation group: 'commons-cli', name: 'commons-cli', version: '1.9.0' // we don't update it to 2.1.0 because 2.1.0 requires Java 11 implementation 'com.codingrodent:jackson-json-crypto:1.1.0' diff --git a/core/src/main/java/io/temporal/samples/nexus/README.MD b/core/src/main/java/io/temporal/samples/nexus/README.MD index e77daba5..3798e203 100644 --- a/core/src/main/java/io/temporal/samples/nexus/README.MD +++ b/core/src/main/java/io/temporal/samples/nexus/README.MD @@ -53,8 +53,9 @@ temporal operator namespace create --namespace my-caller-namespace temporal operator nexus endpoint create \ --name my-nexus-endpoint-name \ --target-namespace my-target-namespace \ - --target-task-queue my-handler-task-queue - ``` + --target-task-queue my-handler-task-queue \ + --description-file ./service/description.md +``` ## Getting started with a self-hosted service or Temporal Cloud @@ -75,19 +76,22 @@ In separate terminal windows: ### Nexus handler worker ``` -./gradlew -q execute -PmainClass=io.temporal.samples.nexus.handler.HandlerWorker +./gradlew -q execute -PmainClass=io.temporal.samples.nexus.handler.HandlerWorker \ + --args="-target-host localhost:7233 -namespace my-target-namespace" ``` ### Nexus caller worker ``` -./gradlew -q execute -PmainClass=io.temporal.samples.nexus.caller.CallerWorker +./gradlew -q execute -PmainClass=io.temporal.samples.nexus.caller.CallerWorker \ + --args="-target-host localhost:7233 -namespace my-caller-namespace" ``` ### Start caller workflow ``` -./gradlew -q execute -PmainClass=io.temporal.samples.nexus.caller.CallerStarter +./gradlew -q execute -PmainClass=io.temporal.samples.nexus.caller.CallerStarter \ + --args="-target-host localhost:7233 -namespace my-caller-namespace" ``` ### Output diff --git a/core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java b/core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java index f7c70f5b..3d209831 100644 --- a/core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java +++ b/core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java @@ -1,10 +1,9 @@ package io.temporal.samples.nexus.caller; import io.temporal.client.WorkflowClient; -import io.temporal.client.WorkflowClientOptions; import io.temporal.client.WorkflowOptions; +import io.temporal.samples.nexus.options.ClientOptions; import io.temporal.samples.nexus.service.NexusService; -import io.temporal.serviceclient.WorkflowServiceStubs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -12,11 +11,7 @@ public class CallerStarter { private static final Logger logger = LoggerFactory.getLogger(CallerStarter.class); public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = - WorkflowClient.newInstance( - service, - WorkflowClientOptions.newBuilder().setNamespace("my-caller-namespace").build()); + WorkflowClient client = ClientOptions.getWorkflowClient(args); WorkflowOptions workflowOptions = WorkflowOptions.newBuilder().setTaskQueue(CallerWorker.DEFAULT_TASK_QUEUE_NAME).build(); diff --git a/core/src/main/java/io/temporal/samples/nexus/caller/CallerWorker.java b/core/src/main/java/io/temporal/samples/nexus/caller/CallerWorker.java index c585dd70..f8679ed3 100644 --- a/core/src/main/java/io/temporal/samples/nexus/caller/CallerWorker.java +++ b/core/src/main/java/io/temporal/samples/nexus/caller/CallerWorker.java @@ -1,8 +1,7 @@ package io.temporal.samples.nexus.caller; import io.temporal.client.WorkflowClient; -import io.temporal.client.WorkflowClientOptions; -import io.temporal.serviceclient.WorkflowServiceStubs; +import io.temporal.samples.nexus.options.ClientOptions; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.worker.WorkflowImplementationOptions; @@ -12,12 +11,8 @@ public class CallerWorker { public static final String DEFAULT_TASK_QUEUE_NAME = "my-caller-workflow-task-queue"; public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + WorkflowClient client = ClientOptions.getWorkflowClient(args); - WorkflowClient client = - WorkflowClient.newInstance( - service, - WorkflowClientOptions.newBuilder().setNamespace("my-caller-namespace").build()); WorkerFactory factory = WorkerFactory.newInstance(client); Worker worker = factory.newWorker(DEFAULT_TASK_QUEUE_NAME); diff --git a/core/src/main/java/io/temporal/samples/nexus/handler/HandlerWorker.java b/core/src/main/java/io/temporal/samples/nexus/handler/HandlerWorker.java index 16d404f6..3d8afa3d 100644 --- a/core/src/main/java/io/temporal/samples/nexus/handler/HandlerWorker.java +++ b/core/src/main/java/io/temporal/samples/nexus/handler/HandlerWorker.java @@ -1,8 +1,7 @@ package io.temporal.samples.nexus.handler; import io.temporal.client.WorkflowClient; -import io.temporal.client.WorkflowClientOptions; -import io.temporal.serviceclient.WorkflowServiceStubs; +import io.temporal.samples.nexus.options.ClientOptions; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; @@ -10,12 +9,8 @@ public class HandlerWorker { public static final String DEFAULT_TASK_QUEUE_NAME = "my-handler-task-queue"; public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + WorkflowClient client = ClientOptions.getWorkflowClient(args); - WorkflowClient client = - WorkflowClient.newInstance( - service, - WorkflowClientOptions.newBuilder().setNamespace("my-target-namespace").build()); WorkerFactory factory = WorkerFactory.newInstance(client); Worker worker = factory.newWorker(DEFAULT_TASK_QUEUE_NAME); diff --git a/core/src/main/java/io/temporal/samples/nexus/options/ClientOptions.java b/core/src/main/java/io/temporal/samples/nexus/options/ClientOptions.java new file mode 100644 index 00000000..564c0c7a --- /dev/null +++ b/core/src/main/java/io/temporal/samples/nexus/options/ClientOptions.java @@ -0,0 +1,98 @@ +package io.temporal.samples.nexus.options; + +import io.grpc.netty.shaded.io.netty.handler.ssl.SslContextBuilder; +import io.temporal.client.WorkflowClient; +import io.temporal.client.WorkflowClientOptions; +import io.temporal.serviceclient.WorkflowServiceStubs; +import io.temporal.serviceclient.WorkflowServiceStubsOptions; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.Arrays; +import javax.net.ssl.SSLException; +import org.apache.commons.cli.*; + +public class ClientOptions { + public static WorkflowClient getWorkflowClient(String[] args) { + System.out.println(Arrays.toString(args)); + Options options = new Options(); + Option targetHostOption = new Option("target-host", true, "Host:port for the Temporal service"); + targetHostOption.setRequired(false); + options.addOption(targetHostOption); + + Option namespaceOption = new Option("namespace", true, "Namespace to connect to"); + namespaceOption.setRequired(false); + options.addOption(namespaceOption); + + Option serverRootCaOption = + new Option("server-root-ca-cert", true, "Optional path to root server CA cert"); + serverRootCaOption.setRequired(false); + options.addOption(serverRootCaOption); + + Option clientCertOption = new Option("client-cert", true, "Optional path to client cert"); + clientCertOption.setRequired(false); + options.addOption(clientCertOption); + + Option clientKeyOption = new Option("client-key", true, "Optional path to client key"); + clientKeyOption.setRequired(false); + options.addOption(clientKeyOption); + + Option serverNameOption = + new Option( + "server-name", true, "Server name to use for verifying the server's certificate"); + serverNameOption.setRequired(false); + options.addOption(serverNameOption); + + Option insercureSkipVerifyOption = + new Option( + "insecure-skip-verify", + true, + "Skip verification of the server's certificate and host name"); + insercureSkipVerifyOption.setRequired(false); + options.addOption(insercureSkipVerifyOption); + + CommandLineParser parser = new DefaultParser(); + HelpFormatter formatter = new HelpFormatter(); + CommandLine cmd = null; + + try { + cmd = parser.parse(options, args); + } catch (ParseException e) { + System.out.println(e.getMessage()); + formatter.printHelp("utility-name", options); + + System.exit(1); + } + + String targetHost = cmd.getOptionValue("target-host", "localhost:7233"); + String namespace = cmd.getOptionValue("namespace", "default"); + String serverRootCaCert = cmd.getOptionValue("server-root-ca-cert", ""); + String clientCert = cmd.getOptionValue("client-cert", ""); + String clientKey = cmd.getOptionValue("client-key", ""); + String serverName = cmd.getOptionValue("server-name", ""); + + WorkflowServiceStubsOptions.Builder serviceStubOptionsBuilder = + WorkflowServiceStubsOptions.newBuilder().setTarget(targetHost); + if (!clientCert.isEmpty()) { + try { + SslContextBuilder sslContext = + SslContextBuilder.forClient() + .keyManager(new FileInputStream(clientCert), new FileInputStream(clientKey)); + if (serverRootCaCert != null && !serverRootCaCert.isEmpty()) { + sslContext.trustManager(new FileInputStream(serverRootCaCert)); + } + serviceStubOptionsBuilder.setSslContext(sslContext.build()); + } catch (SSLException e) { + throw new RuntimeException(e); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + } + if (serverName != null && !serverName.isEmpty()) { + serviceStubOptionsBuilder.setChannelInitializer(c -> c.overrideAuthority(serverName)); + } + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(serviceStubOptionsBuilder.build()); + return WorkflowClient.newInstance( + service, WorkflowClientOptions.newBuilder().setNamespace(namespace).build()); + } +} From 08b311b72d8199c7cc5c0bf5b9f8766193c906c9 Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Mon, 14 Oct 2024 22:19:53 -0700 Subject: [PATCH 3/8] Begin adding tests --- .../java/io/temporal/samples/nexus/README.MD | 2 +- .../samples/nexus/caller/CallerStarter.java | 13 ++- .../nexus/caller/HelloCallerWorkflowImpl.java | 16 +++- .../handler/HelloHandlerWorkflowImpl.java | 2 +- .../nexus/handler/NexusServiceImpl.java | 4 +- .../nexus/caller/CallerWorkflowTest.java | 80 +++++++++++++++++++ 6 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java diff --git a/core/src/main/java/io/temporal/samples/nexus/README.MD b/core/src/main/java/io/temporal/samples/nexus/README.MD index 3798e203..497ddc51 100644 --- a/core/src/main/java/io/temporal/samples/nexus/README.MD +++ b/core/src/main/java/io/temporal/samples/nexus/README.MD @@ -99,5 +99,5 @@ In separate terminal windows: which should result in: ``` [main] INFO i.t.s.nexus.caller.CallerStarter - Workflow result: Nexus Echo πŸ‘‹ -[main] INFO i.t.s.nexus.caller.CallerStarter - Workflow result: Hola Nexus πŸ‘‹ +[main] INFO i.t.s.nexus.caller.CallerStarter - Workflow result: Β‘Hola! Nexus πŸ‘‹ ``` diff --git a/core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java b/core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java index 3d209831..fa68b230 100644 --- a/core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java +++ b/core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java @@ -2,6 +2,7 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.client.WorkflowStub; import io.temporal.samples.nexus.options.ClientOptions; import io.temporal.samples.nexus.service.NexusService; import org.slf4j.Logger; @@ -17,9 +18,17 @@ public static void main(String[] args) { WorkflowOptions.newBuilder().setTaskQueue(CallerWorker.DEFAULT_TASK_QUEUE_NAME).build(); EchoCallerWorkflow echoWorkflow = client.newWorkflowStub(EchoCallerWorkflow.class, workflowOptions); - logger.info("Workflow result: " + echoWorkflow.echo("Nexus Echo πŸ‘‹")); + logger.info("Workflow result: {}", echoWorkflow.echo("Nexus Echo πŸ‘‹")); + logger.info( + "Started workflow workflowId: {} runId; {}", + WorkflowStub.fromTyped(echoWorkflow).getExecution().getWorkflowId(), + WorkflowStub.fromTyped(echoWorkflow).getExecution().getRunId()); HelloCallerWorkflow helloWorkflow = client.newWorkflowStub(HelloCallerWorkflow.class, workflowOptions); - logger.info("Workflow result: " + helloWorkflow.hello("Nexus", NexusService.Language.ES)); + logger.info("Workflow result: {}", helloWorkflow.hello("Nexus", NexusService.Language.ES)); + logger.info( + "Started workflow workflowId: {} runId; {}", + WorkflowStub.fromTyped(helloWorkflow).getExecution().getWorkflowId(), + WorkflowStub.fromTyped(helloWorkflow).getExecution().getRunId()); } } diff --git a/core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflowImpl.java b/core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflowImpl.java index e95dce17..90486dbf 100644 --- a/core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflowImpl.java +++ b/core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflowImpl.java @@ -2,10 +2,21 @@ import io.temporal.samples.nexus.service.NexusService; import io.temporal.workflow.NexusOperationHandle; +import io.temporal.workflow.NexusOperationOptions; +import io.temporal.workflow.NexusServiceOptions; import io.temporal.workflow.Workflow; +import java.time.Duration; public class HelloCallerWorkflowImpl implements HelloCallerWorkflow { - NexusService nexusService = Workflow.newNexusServiceStub(NexusService.class); + NexusService nexusService = + Workflow.newNexusServiceStub( + NexusService.class, + NexusServiceOptions.newBuilder() + .setOperationOptions( + NexusOperationOptions.newBuilder() + .setScheduleToCloseTimeout(Duration.ofSeconds(10)) + .build()) + .build()); @Override public String hello(String message, NexusService.Language language) { @@ -13,8 +24,7 @@ public String hello(String message, NexusService.Language language) { Workflow.startNexusOperation( nexusService::hello, new NexusService.HelloInput(message, language)); // Optionally wait for the operation to be started. NexusOperationExecution will contain the - // operation ID in - // case this operation is asynchronous. + // operation ID in case this operation is asynchronous. handle.getExecution().get(); return handle.getResult().get().getMessage(); } diff --git a/core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflowImpl.java b/core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflowImpl.java index 84787b65..c897a518 100644 --- a/core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflowImpl.java +++ b/core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflowImpl.java @@ -14,7 +14,7 @@ public NexusService.HelloOutput hello(NexusService.HelloInput input) { case DE: return new NexusService.HelloOutput("Hallo " + input.getName() + " πŸ‘‹"); case ES: - return new NexusService.HelloOutput("Hola " + input.getName() + " πŸ‘‹"); + return new NexusService.HelloOutput("Β‘Hola! " + input.getName() + " πŸ‘‹"); case TR: return new NexusService.HelloOutput("Merhaba " + input.getName() + " πŸ‘‹"); } diff --git a/core/src/main/java/io/temporal/samples/nexus/handler/NexusServiceImpl.java b/core/src/main/java/io/temporal/samples/nexus/handler/NexusServiceImpl.java index 023cb869..aa3cc81e 100644 --- a/core/src/main/java/io/temporal/samples/nexus/handler/NexusServiceImpl.java +++ b/core/src/main/java/io/temporal/samples/nexus/handler/NexusServiceImpl.java @@ -7,6 +7,9 @@ import io.temporal.nexus.WorkflowClientOperationHandlers; import io.temporal.samples.nexus.service.NexusService; +// To create a service implementation, annotate the class with @ServiceImpl and provide the +// interface that the service implements. The service implementation class should have methods that +// return OperationHandler that correspond to the operations defined in the service interface. @ServiceImpl(service = NexusService.class) public class NexusServiceImpl { @OperationImpl @@ -25,7 +28,6 @@ public OperationHandler echo() public OperationHandler hello() { // Use the WorkflowClientOperationHandlers.fromWorkflowMethod constructor, which is the easiest // way to expose a workflow as an operation. - // See alternatives at TODO. return WorkflowClientOperationHandlers.fromWorkflowMethod( (ctx, details, client, input) -> client.newWorkflowStub( diff --git a/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java new file mode 100644 index 00000000..4bbea043 --- /dev/null +++ b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java @@ -0,0 +1,80 @@ +package io.temporal.samples.nexus.caller; + +import io.temporal.client.WorkflowOptions; +import io.temporal.samples.nexus.handler.HelloHandlerWorkflow; +import io.temporal.samples.nexus.handler.NexusServiceImpl; +import io.temporal.samples.nexus.service.NexusService; +import io.temporal.testing.TestWorkflowRule; +import io.temporal.worker.WorkflowImplementationOptions; +import io.temporal.workflow.NexusServiceOptions; +import org.junit.Rule; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class CallerWorkflowTest { + + @Rule + public TestWorkflowRule testWorkflowRule = + TestWorkflowRule.newBuilder() + // If a Nexus service is registered as part of the test, the TestWorkflowRule will ,by + // default, automatically create a Nexus service endpoint and workflows registered as part + // of the TestWorkflowRule will automatically inherit the endpoint if none is set. + .setNexusServiceImplementation(new NexusServiceImpl()) + .setWorkflowTypes(HelloCallerWorkflowImpl.class) + .setDoNotStart(true) + .build(); + + @Test + public void testHelloWorkflow() { + testWorkflowRule + .getWorker() + .registerWorkflowImplementationFactory( + HelloHandlerWorkflow.class, + () -> { + HelloHandlerWorkflow wf = mock(HelloHandlerWorkflow.class); + when(wf.hello(any())).thenReturn(new NexusService.HelloOutput("Hello World πŸ‘‹")); + return wf; + }); + testWorkflowRule.getTestEnvironment().start(); + + HelloCallerWorkflow workflow = + testWorkflowRule + .getWorkflowClient() + .newWorkflowStub( + HelloCallerWorkflow.class, + WorkflowOptions.newBuilder().setTaskQueue(testWorkflowRule.getTaskQueue()).build()); + String greeting = workflow.hello("World", NexusService.Language.EN); + assertEquals("Hello World πŸ‘‹", greeting); + + testWorkflowRule.getTestEnvironment().shutdown(); + } + + @Test + public void testEchoWorkflow() { + testWorkflowRule + .getWorker() + .registerWorkflowImplementationTypes( + WorkflowImplementationOptions.newBuilder() + .setDefaultNexusServiceOptions( + NexusServiceOptions.newBuilder() + .setEndpoint(testWorkflowRule.getNexusEndpoint().getSpec().getName()) + .build()) + .build(), + EchoCallerWorkflowImpl.class); + testWorkflowRule.getTestEnvironment().start(); + + EchoCallerWorkflow workflow = + testWorkflowRule + .getWorkflowClient() + .newWorkflowStub( + EchoCallerWorkflow.class, + WorkflowOptions.newBuilder().setTaskQueue(testWorkflowRule.getTaskQueue()).build()); + String greeting = workflow.echo("Hello"); + assertEquals("Hello", greeting); + testWorkflowRule.getTestEnvironment().shutdown(); + } +} From fd3139c785b6cbb02ff08ead660b6eef3d7b3d83 Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Tue, 15 Oct 2024 10:41:20 -0700 Subject: [PATCH 4/8] Add licenses --- .../samples/nexus/caller/CallerStarter.java | 19 +++++++++++++++++++ .../samples/nexus/caller/CallerWorker.java | 19 +++++++++++++++++++ .../nexus/caller/EchoCallerWorkflow.java | 19 +++++++++++++++++++ .../nexus/caller/EchoCallerWorkflowImpl.java | 19 +++++++++++++++++++ .../nexus/caller/HelloCallerWorkflow.java | 19 +++++++++++++++++++ .../nexus/caller/HelloCallerWorkflowImpl.java | 19 +++++++++++++++++++ .../samples/nexus/handler/HandlerWorker.java | 19 +++++++++++++++++++ .../nexus/handler/HelloHandlerWorkflow.java | 19 +++++++++++++++++++ .../handler/HelloHandlerWorkflowImpl.java | 19 +++++++++++++++++++ .../nexus/handler/NexusServiceImpl.java | 19 +++++++++++++++++++ .../samples/nexus/options/ClientOptions.java | 19 +++++++++++++++++++ .../samples/nexus/service/NexusService.java | 19 +++++++++++++++++++ .../nexus/caller/CallerWorkflowTest.java | 19 +++++++++++++++++++ 13 files changed, 247 insertions(+) diff --git a/core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java b/core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java index fa68b230..19c0d7e0 100644 --- a/core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java +++ b/core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved + * + * Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Modifications copyright (C) 2017 Uber Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not + * use this file except in compliance with the License. A copy of the License is + * located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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.temporal.samples.nexus.caller; import io.temporal.client.WorkflowClient; diff --git a/core/src/main/java/io/temporal/samples/nexus/caller/CallerWorker.java b/core/src/main/java/io/temporal/samples/nexus/caller/CallerWorker.java index f8679ed3..3f7442d0 100644 --- a/core/src/main/java/io/temporal/samples/nexus/caller/CallerWorker.java +++ b/core/src/main/java/io/temporal/samples/nexus/caller/CallerWorker.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved + * + * Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Modifications copyright (C) 2017 Uber Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not + * use this file except in compliance with the License. A copy of the License is + * located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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.temporal.samples.nexus.caller; import io.temporal.client.WorkflowClient; diff --git a/core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflow.java b/core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflow.java index b4c7fac8..5f830855 100644 --- a/core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflow.java +++ b/core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflow.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved + * + * Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Modifications copyright (C) 2017 Uber Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not + * use this file except in compliance with the License. A copy of the License is + * located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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.temporal.samples.nexus.caller; import io.temporal.workflow.WorkflowInterface; diff --git a/core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflowImpl.java b/core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflowImpl.java index e36da75c..ea084ca1 100644 --- a/core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflowImpl.java +++ b/core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflowImpl.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved + * + * Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Modifications copyright (C) 2017 Uber Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not + * use this file except in compliance with the License. A copy of the License is + * located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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.temporal.samples.nexus.caller; import io.temporal.samples.nexus.service.NexusService; diff --git a/core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflow.java b/core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflow.java index 173c0be8..6e943c17 100644 --- a/core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflow.java +++ b/core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflow.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved + * + * Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Modifications copyright (C) 2017 Uber Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not + * use this file except in compliance with the License. A copy of the License is + * located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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.temporal.samples.nexus.caller; import io.temporal.samples.nexus.service.NexusService; diff --git a/core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflowImpl.java b/core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflowImpl.java index 90486dbf..dcc8d1a0 100644 --- a/core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflowImpl.java +++ b/core/src/main/java/io/temporal/samples/nexus/caller/HelloCallerWorkflowImpl.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved + * + * Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Modifications copyright (C) 2017 Uber Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not + * use this file except in compliance with the License. A copy of the License is + * located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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.temporal.samples.nexus.caller; import io.temporal.samples.nexus.service.NexusService; diff --git a/core/src/main/java/io/temporal/samples/nexus/handler/HandlerWorker.java b/core/src/main/java/io/temporal/samples/nexus/handler/HandlerWorker.java index 3d8afa3d..71a78f91 100644 --- a/core/src/main/java/io/temporal/samples/nexus/handler/HandlerWorker.java +++ b/core/src/main/java/io/temporal/samples/nexus/handler/HandlerWorker.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved + * + * Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Modifications copyright (C) 2017 Uber Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not + * use this file except in compliance with the License. A copy of the License is + * located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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.temporal.samples.nexus.handler; import io.temporal.client.WorkflowClient; diff --git a/core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflow.java b/core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflow.java index 3cae13b3..caa34d98 100644 --- a/core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflow.java +++ b/core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflow.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved + * + * Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Modifications copyright (C) 2017 Uber Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not + * use this file except in compliance with the License. A copy of the License is + * located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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.temporal.samples.nexus.handler; import io.temporal.samples.nexus.service.NexusService; diff --git a/core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflowImpl.java b/core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflowImpl.java index c897a518..ea5203eb 100644 --- a/core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflowImpl.java +++ b/core/src/main/java/io/temporal/samples/nexus/handler/HelloHandlerWorkflowImpl.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved + * + * Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Modifications copyright (C) 2017 Uber Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not + * use this file except in compliance with the License. A copy of the License is + * located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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.temporal.samples.nexus.handler; import io.temporal.failure.ApplicationFailure; diff --git a/core/src/main/java/io/temporal/samples/nexus/handler/NexusServiceImpl.java b/core/src/main/java/io/temporal/samples/nexus/handler/NexusServiceImpl.java index aa3cc81e..4d6cb3ca 100644 --- a/core/src/main/java/io/temporal/samples/nexus/handler/NexusServiceImpl.java +++ b/core/src/main/java/io/temporal/samples/nexus/handler/NexusServiceImpl.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved + * + * Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Modifications copyright (C) 2017 Uber Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not + * use this file except in compliance with the License. A copy of the License is + * located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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.temporal.samples.nexus.handler; import io.nexusrpc.handler.OperationHandler; diff --git a/core/src/main/java/io/temporal/samples/nexus/options/ClientOptions.java b/core/src/main/java/io/temporal/samples/nexus/options/ClientOptions.java index 564c0c7a..5b1629a1 100644 --- a/core/src/main/java/io/temporal/samples/nexus/options/ClientOptions.java +++ b/core/src/main/java/io/temporal/samples/nexus/options/ClientOptions.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved + * + * Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Modifications copyright (C) 2017 Uber Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not + * use this file except in compliance with the License. A copy of the License is + * located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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.temporal.samples.nexus.options; import io.grpc.netty.shaded.io.netty.handler.ssl.SslContextBuilder; diff --git a/core/src/main/java/io/temporal/samples/nexus/service/NexusService.java b/core/src/main/java/io/temporal/samples/nexus/service/NexusService.java index ad65b1b3..e12dcbe9 100644 --- a/core/src/main/java/io/temporal/samples/nexus/service/NexusService.java +++ b/core/src/main/java/io/temporal/samples/nexus/service/NexusService.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved + * + * Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Modifications copyright (C) 2017 Uber Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not + * use this file except in compliance with the License. A copy of the License is + * located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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.temporal.samples.nexus.service; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java index 4bbea043..9af08174 100644 --- a/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java +++ b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved + * + * Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Modifications copyright (C) 2017 Uber Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not + * use this file except in compliance with the License. A copy of the License is + * located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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.temporal.samples.nexus.caller; import io.temporal.client.WorkflowOptions; From 6de76d06703a8fc5fda69bd5c610b9880cd37b75 Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Tue, 15 Oct 2024 16:39:25 -0700 Subject: [PATCH 5/8] Point sample at released SDK --- build.gradle | 3 +-- .../nexus/caller/EchoCallerWorkflowImpl.java | 13 ++++++++++++- .../nexus/caller/CallerWorkflowTest.java | 18 ++++++++++++++---- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index eaf29032..0f03ee0a 100644 --- a/build.gradle +++ b/build.gradle @@ -28,14 +28,13 @@ subprojects { ext { otelVersion = '1.30.1' otelVersionAlpha = "${otelVersion}-alpha" - javaSDKVersion = '1.23.0-SNAPSHOT' + javaSDKVersion = '1.26.0' camelVersion = '3.22.1' jarVersion = '1.0.0' nexusVersion = '0.1.0-alpha1' } repositories { - mavenLocal() maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } diff --git a/core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflowImpl.java b/core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflowImpl.java index ea084ca1..7c5d5f78 100644 --- a/core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflowImpl.java +++ b/core/src/main/java/io/temporal/samples/nexus/caller/EchoCallerWorkflowImpl.java @@ -20,10 +20,21 @@ package io.temporal.samples.nexus.caller; import io.temporal.samples.nexus.service.NexusService; +import io.temporal.workflow.NexusOperationOptions; +import io.temporal.workflow.NexusServiceOptions; import io.temporal.workflow.Workflow; +import java.time.Duration; public class EchoCallerWorkflowImpl implements EchoCallerWorkflow { - NexusService nexusService = Workflow.newNexusServiceStub(NexusService.class); + NexusService nexusService = + Workflow.newNexusServiceStub( + NexusService.class, + NexusServiceOptions.newBuilder() + .setOperationOptions( + NexusOperationOptions.newBuilder() + .setScheduleToCloseTimeout(Duration.ofSeconds(10)) + .build()) + .build()); @Override public String echo(String message) { diff --git a/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java index 9af08174..97dfd2ef 100644 --- a/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java +++ b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java @@ -29,6 +29,8 @@ import org.junit.Rule; import org.junit.Test; +import java.util.Collections; + import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; @@ -44,6 +46,8 @@ public class CallerWorkflowTest { // of the TestWorkflowRule will automatically inherit the endpoint if none is set. .setNexusServiceImplementation(new NexusServiceImpl()) .setWorkflowTypes(HelloCallerWorkflowImpl.class) + // Disable automatic worker startup as we are going to register some workflows manually + // per test .setDoNotStart(true) .build(); @@ -51,6 +55,7 @@ public class CallerWorkflowTest { public void testHelloWorkflow() { testWorkflowRule .getWorker() + // Workflows started by a Nexus service can be mocked just like any other workflow .registerWorkflowImplementationFactory( HelloHandlerWorkflow.class, () -> { @@ -74,14 +79,19 @@ public void testHelloWorkflow() { @Test public void testEchoWorkflow() { + // If Workflows are registered later than the endpoint can be set manually + // either by setting the endpoint in the NexusServiceOptions in the Workflow implementation or by setting the + // NexusServiceOptions on the WorkflowImplementationOptions when registering the Workflow. testWorkflowRule .getWorker() .registerWorkflowImplementationTypes( WorkflowImplementationOptions.newBuilder() - .setDefaultNexusServiceOptions( - NexusServiceOptions.newBuilder() - .setEndpoint(testWorkflowRule.getNexusEndpoint().getSpec().getName()) - .build()) + .setNexusServiceOptions( + Collections.singletonMap( + "NexusService", + NexusServiceOptions.newBuilder() + .setEndpoint(testWorkflowRule.getNexusEndpoint().getSpec().getName()) + .build())) .build(), EchoCallerWorkflowImpl.class); testWorkflowRule.getTestEnvironment().start(); From c944c4ed3076d913481bcfacbcc6d32a2f2cbd96 Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Tue, 15 Oct 2024 17:28:04 -0700 Subject: [PATCH 6/8] format --- .../samples/nexus/caller/CallerWorkflowTest.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java index 97dfd2ef..21fe2057 100644 --- a/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java +++ b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java @@ -19,6 +19,11 @@ package io.temporal.samples.nexus.caller; +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import io.temporal.client.WorkflowOptions; import io.temporal.samples.nexus.handler.HelloHandlerWorkflow; import io.temporal.samples.nexus.handler.NexusServiceImpl; @@ -26,16 +31,10 @@ import io.temporal.testing.TestWorkflowRule; import io.temporal.worker.WorkflowImplementationOptions; import io.temporal.workflow.NexusServiceOptions; +import java.util.Collections; import org.junit.Rule; import org.junit.Test; -import java.util.Collections; - -import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - public class CallerWorkflowTest { @Rule @@ -80,7 +79,8 @@ public void testHelloWorkflow() { @Test public void testEchoWorkflow() { // If Workflows are registered later than the endpoint can be set manually - // either by setting the endpoint in the NexusServiceOptions in the Workflow implementation or by setting the + // either by setting the endpoint in the NexusServiceOptions in the Workflow implementation or + // by setting the // NexusServiceOptions on the WorkflowImplementationOptions when registering the Workflow. testWorkflowRule .getWorker() From 1470cd24e64cd2ba7ebb9fad744e6c36079edf54 Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Wed, 16 Oct 2024 09:11:34 -0700 Subject: [PATCH 7/8] Add insecure-skip-verify --- build.gradle | 1 - .../samples/nexus/options/ClientOptions.java | 12 ++++++++++-- .../samples/nexus/caller/CallerWorkflowTest.java | 4 ++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 0f03ee0a..e9a3cae2 100644 --- a/build.gradle +++ b/build.gradle @@ -31,7 +31,6 @@ subprojects { javaSDKVersion = '1.26.0' camelVersion = '3.22.1' jarVersion = '1.0.0' - nexusVersion = '0.1.0-alpha1' } repositories { diff --git a/core/src/main/java/io/temporal/samples/nexus/options/ClientOptions.java b/core/src/main/java/io/temporal/samples/nexus/options/ClientOptions.java index 5b1629a1..49d0dde2 100644 --- a/core/src/main/java/io/temporal/samples/nexus/options/ClientOptions.java +++ b/core/src/main/java/io/temporal/samples/nexus/options/ClientOptions.java @@ -20,6 +20,7 @@ package io.temporal.samples.nexus.options; import io.grpc.netty.shaded.io.netty.handler.ssl.SslContextBuilder; +import io.grpc.netty.shaded.io.netty.handler.ssl.util.InsecureTrustManagerFactory; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowClientOptions; import io.temporal.serviceclient.WorkflowServiceStubs; @@ -64,7 +65,7 @@ public static WorkflowClient getWorkflowClient(String[] args) { Option insercureSkipVerifyOption = new Option( "insecure-skip-verify", - true, + false, "Skip verification of the server's certificate and host name"); insercureSkipVerifyOption.setRequired(false); options.addOption(insercureSkipVerifyOption); @@ -88,10 +89,14 @@ public static WorkflowClient getWorkflowClient(String[] args) { String clientCert = cmd.getOptionValue("client-cert", ""); String clientKey = cmd.getOptionValue("client-key", ""); String serverName = cmd.getOptionValue("server-name", ""); + boolean insecureSkipVerify = cmd.hasOption("insecure-skip-verify"); WorkflowServiceStubsOptions.Builder serviceStubOptionsBuilder = WorkflowServiceStubsOptions.newBuilder().setTarget(targetHost); - if (!clientCert.isEmpty()) { + if (!clientCert.isEmpty() || !clientKey.isEmpty()) { + if (clientCert.isEmpty() || clientKey.isEmpty()) { + throw new IllegalArgumentException("Both client-cert and client-key must be provided"); + } try { SslContextBuilder sslContext = SslContextBuilder.forClient() @@ -99,6 +104,9 @@ public static WorkflowClient getWorkflowClient(String[] args) { if (serverRootCaCert != null && !serverRootCaCert.isEmpty()) { sslContext.trustManager(new FileInputStream(serverRootCaCert)); } + if (insecureSkipVerify) { + sslContext.trustManager(InsecureTrustManagerFactory.INSTANCE); + } serviceStubOptionsBuilder.setSslContext(sslContext.build()); } catch (SSLException e) { throw new RuntimeException(e); diff --git a/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java index 21fe2057..ba1bba46 100644 --- a/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java +++ b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowTest.java @@ -80,8 +80,8 @@ public void testHelloWorkflow() { public void testEchoWorkflow() { // If Workflows are registered later than the endpoint can be set manually // either by setting the endpoint in the NexusServiceOptions in the Workflow implementation or - // by setting the - // NexusServiceOptions on the WorkflowImplementationOptions when registering the Workflow. + // by setting the NexusServiceOptions on the WorkflowImplementationOptions when registering the + // Workflow. testWorkflowRule .getWorker() .registerWorkflowImplementationTypes( From a908df22e982fdd599b2c591c4a523a800ae4490 Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Wed, 16 Oct 2024 10:15:21 -0700 Subject: [PATCH 8/8] Clean up --- core/src/main/java/io/temporal/samples/nexus/README.MD | 6 +++--- .../io/temporal/samples/nexus/caller/CallerStarter.java | 4 ++-- .../io/temporal/samples/nexus/caller/CallerWorker.java | 7 +++++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/io/temporal/samples/nexus/README.MD b/core/src/main/java/io/temporal/samples/nexus/README.MD index 497ddc51..2483a8b3 100644 --- a/core/src/main/java/io/temporal/samples/nexus/README.MD +++ b/core/src/main/java/io/temporal/samples/nexus/README.MD @@ -11,7 +11,7 @@ This sample shows how to use Temporal for authoring a Nexus service and call it ### Sample directory structure -- [service](./service) - shared service defintion +- [service](./service) - shared service definition - [caller](./caller) - caller workflows, worker, and starter - [handler](./handler) - handler workflow, operations, and worker - [options](./options) - command line argument parsing utility @@ -68,8 +68,8 @@ deployments with server version 1.25.0. ### Make Nexus calls across namespace boundaries -> Instructions apply for local development, for Temporal Cloud or a self hosted setups, supply the relevant [CLI -> flags](./options/cli.go) to properly set up the connection. +> Instructions apply for local development, for Temporal Cloud or a self-hosted setups, supply the relevant [CLI +> flags](./options/ClientOptions.java) to properly set up the connection. In separate terminal windows: diff --git a/core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java b/core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java index 19c0d7e0..23dd0f5e 100644 --- a/core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java +++ b/core/src/main/java/io/temporal/samples/nexus/caller/CallerStarter.java @@ -39,14 +39,14 @@ public static void main(String[] args) { client.newWorkflowStub(EchoCallerWorkflow.class, workflowOptions); logger.info("Workflow result: {}", echoWorkflow.echo("Nexus Echo πŸ‘‹")); logger.info( - "Started workflow workflowId: {} runId; {}", + "Started workflow workflowId: {} runId: {}", WorkflowStub.fromTyped(echoWorkflow).getExecution().getWorkflowId(), WorkflowStub.fromTyped(echoWorkflow).getExecution().getRunId()); HelloCallerWorkflow helloWorkflow = client.newWorkflowStub(HelloCallerWorkflow.class, workflowOptions); logger.info("Workflow result: {}", helloWorkflow.hello("Nexus", NexusService.Language.ES)); logger.info( - "Started workflow workflowId: {} runId; {}", + "Started workflow workflowId: {} runId: {}", WorkflowStub.fromTyped(helloWorkflow).getExecution().getWorkflowId(), WorkflowStub.fromTyped(helloWorkflow).getExecution().getRunId()); } diff --git a/core/src/main/java/io/temporal/samples/nexus/caller/CallerWorker.java b/core/src/main/java/io/temporal/samples/nexus/caller/CallerWorker.java index 3f7442d0..e7be0ae4 100644 --- a/core/src/main/java/io/temporal/samples/nexus/caller/CallerWorker.java +++ b/core/src/main/java/io/temporal/samples/nexus/caller/CallerWorker.java @@ -25,6 +25,7 @@ import io.temporal.worker.WorkerFactory; import io.temporal.worker.WorkflowImplementationOptions; import io.temporal.workflow.NexusServiceOptions; +import java.util.Collections; public class CallerWorker { public static final String DEFAULT_TASK_QUEUE_NAME = "my-caller-workflow-task-queue"; @@ -37,8 +38,10 @@ public static void main(String[] args) { Worker worker = factory.newWorker(DEFAULT_TASK_QUEUE_NAME); worker.registerWorkflowImplementationTypes( WorkflowImplementationOptions.newBuilder() - .setDefaultNexusServiceOptions( - NexusServiceOptions.newBuilder().setEndpoint("my-nexus-endpoint-name").build()) + .setNexusServiceOptions( + Collections.singletonMap( + "NexusService", + NexusServiceOptions.newBuilder().setEndpoint("my-nexus-endpoint-name").build())) .build(), EchoCallerWorkflowImpl.class, HelloCallerWorkflowImpl.class);