Skip to content

Commit bf1a405

Browse files
Add Nexus sample (temporalio#686)
Add Nexus samples
1 parent ec1c615 commit bf1a405

File tree

17 files changed

+888
-1
lines changed

17 files changed

+888
-1
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ subprojects {
2828
ext {
2929
otelVersion = '1.30.1'
3030
otelVersionAlpha = "${otelVersion}-alpha"
31-
javaSDKVersion = '1.25.0'
31+
javaSDKVersion = '1.26.0'
3232
camelVersion = '3.22.1'
3333
jarVersion = '1.0.0'
3434
}

core/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ dependencies {
2828
implementation group: 'io.cloudevents', name: 'cloudevents-api', version: '4.0.1'
2929
implementation group: 'io.cloudevents', name: 'cloudevents-json-jackson', version: '3.0.0'
3030
implementation group: 'net.thisptr', name: 'jackson-jq', version: '1.0.0-preview.20240207'
31+
implementation group: 'commons-cli', name: 'commons-cli', version: '1.9.0'
3132

3233
// we don't update it to 2.1.0 because 2.1.0 requires Java 11
3334
implementation 'com.codingrodent:jackson-json-crypto:1.1.0'
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# Nexus
2+
3+
Temporal Nexus is a new feature of the Temporal platform designed to connect durable executions across team, namespace,
4+
region, and cloud boundaries. It promotes a more modular architecture for sharing a subset of your team’s capabilities
5+
via well-defined service API contracts for other teams to use, that abstract underlying Temporal primitives, like
6+
Workflows, or execute arbitrary code.
7+
8+
Learn more at [temporal.io/nexus](https://temporal.io/nexus).
9+
10+
This sample shows how to use Temporal for authoring a Nexus service and call it from a workflow.
11+
12+
### Sample directory structure
13+
14+
- [service](./service) - shared service definition
15+
- [caller](./caller) - caller workflows, worker, and starter
16+
- [handler](./handler) - handler workflow, operations, and worker
17+
- [options](./options) - command line argument parsing utility
18+
19+
## Getting started locally
20+
21+
### Get `temporal` CLI to enable local development
22+
23+
1. Follow the instructions on the [docs
24+
site](https://learn.temporal.io/getting_started/go/dev_environment/#set-up-a-local-temporal-service-for-development-with-temporal-cli)
25+
to install Temporal CLI.
26+
27+
> NOTE: Required version is at least v1.1.0.
28+
29+
### Spin up environment
30+
31+
#### Start temporal server
32+
33+
> HTTP port is required for Nexus communications
34+
35+
```
36+
temporal server start-dev --http-port 7243 --dynamic-config-value system.enableNexus=true
37+
```
38+
39+
### Initialize environment
40+
41+
In a separate terminal window
42+
43+
#### Create caller and target namespaces
44+
45+
```
46+
temporal operator namespace create --namespace my-target-namespace
47+
temporal operator namespace create --namespace my-caller-namespace
48+
```
49+
50+
#### Create Nexus endpoint
51+
52+
```
53+
temporal operator nexus endpoint create \
54+
--name my-nexus-endpoint-name \
55+
--target-namespace my-target-namespace \
56+
--target-task-queue my-handler-task-queue \
57+
--description-file ./service/description.md
58+
```
59+
60+
## Getting started with a self-hosted service or Temporal Cloud
61+
62+
Nexus is currently available as
63+
[Public Preview](https://docs.temporal.io/evaluate/development-production-features/release-stages).
64+
65+
Self hosted users can [try Nexus
66+
out](https://github.com/temporalio/temporal/blob/main/docs/architecture/nexus.md#trying-nexus-out) in single cluster
67+
deployments with server version 1.25.0.
68+
69+
### Make Nexus calls across namespace boundaries
70+
71+
> Instructions apply for local development, for Temporal Cloud or a self-hosted setups, supply the relevant [CLI
72+
> flags](./options/ClientOptions.java) to properly set up the connection.
73+
74+
In separate terminal windows:
75+
76+
### Nexus handler worker
77+
78+
```
79+
./gradlew -q execute -PmainClass=io.temporal.samples.nexus.handler.HandlerWorker \
80+
--args="-target-host localhost:7233 -namespace my-target-namespace"
81+
```
82+
83+
### Nexus caller worker
84+
85+
```
86+
./gradlew -q execute -PmainClass=io.temporal.samples.nexus.caller.CallerWorker \
87+
--args="-target-host localhost:7233 -namespace my-caller-namespace"
88+
```
89+
90+
### Start caller workflow
91+
92+
```
93+
./gradlew -q execute -PmainClass=io.temporal.samples.nexus.caller.CallerStarter \
94+
--args="-target-host localhost:7233 -namespace my-caller-namespace"
95+
```
96+
97+
### Output
98+
99+
which should result in:
100+
```
101+
[main] INFO i.t.s.nexus.caller.CallerStarter - Workflow result: Nexus Echo 👋
102+
[main] INFO i.t.s.nexus.caller.CallerStarter - Workflow result: ¡Hola! Nexus 👋
103+
```
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
3+
*
4+
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5+
*
6+
* Modifications copyright (C) 2017 Uber Technologies, Inc.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.samples.nexus.caller;
21+
22+
import io.temporal.client.WorkflowClient;
23+
import io.temporal.client.WorkflowOptions;
24+
import io.temporal.client.WorkflowStub;
25+
import io.temporal.samples.nexus.options.ClientOptions;
26+
import io.temporal.samples.nexus.service.NexusService;
27+
import org.slf4j.Logger;
28+
import org.slf4j.LoggerFactory;
29+
30+
public class CallerStarter {
31+
private static final Logger logger = LoggerFactory.getLogger(CallerStarter.class);
32+
33+
public static void main(String[] args) {
34+
WorkflowClient client = ClientOptions.getWorkflowClient(args);
35+
36+
WorkflowOptions workflowOptions =
37+
WorkflowOptions.newBuilder().setTaskQueue(CallerWorker.DEFAULT_TASK_QUEUE_NAME).build();
38+
EchoCallerWorkflow echoWorkflow =
39+
client.newWorkflowStub(EchoCallerWorkflow.class, workflowOptions);
40+
logger.info("Workflow result: {}", echoWorkflow.echo("Nexus Echo 👋"));
41+
logger.info(
42+
"Started workflow workflowId: {} runId: {}",
43+
WorkflowStub.fromTyped(echoWorkflow).getExecution().getWorkflowId(),
44+
WorkflowStub.fromTyped(echoWorkflow).getExecution().getRunId());
45+
HelloCallerWorkflow helloWorkflow =
46+
client.newWorkflowStub(HelloCallerWorkflow.class, workflowOptions);
47+
logger.info("Workflow result: {}", helloWorkflow.hello("Nexus", NexusService.Language.ES));
48+
logger.info(
49+
"Started workflow workflowId: {} runId: {}",
50+
WorkflowStub.fromTyped(helloWorkflow).getExecution().getWorkflowId(),
51+
WorkflowStub.fromTyped(helloWorkflow).getExecution().getRunId());
52+
}
53+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
3+
*
4+
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5+
*
6+
* Modifications copyright (C) 2017 Uber Technologies, Inc.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.samples.nexus.caller;
21+
22+
import io.temporal.client.WorkflowClient;
23+
import io.temporal.samples.nexus.options.ClientOptions;
24+
import io.temporal.worker.Worker;
25+
import io.temporal.worker.WorkerFactory;
26+
import io.temporal.worker.WorkflowImplementationOptions;
27+
import io.temporal.workflow.NexusServiceOptions;
28+
import java.util.Collections;
29+
30+
public class CallerWorker {
31+
public static final String DEFAULT_TASK_QUEUE_NAME = "my-caller-workflow-task-queue";
32+
33+
public static void main(String[] args) {
34+
WorkflowClient client = ClientOptions.getWorkflowClient(args);
35+
36+
WorkerFactory factory = WorkerFactory.newInstance(client);
37+
38+
Worker worker = factory.newWorker(DEFAULT_TASK_QUEUE_NAME);
39+
worker.registerWorkflowImplementationTypes(
40+
WorkflowImplementationOptions.newBuilder()
41+
.setNexusServiceOptions(
42+
Collections.singletonMap(
43+
"NexusService",
44+
NexusServiceOptions.newBuilder().setEndpoint("my-nexus-endpoint-name").build()))
45+
.build(),
46+
EchoCallerWorkflowImpl.class,
47+
HelloCallerWorkflowImpl.class);
48+
49+
factory.start();
50+
}
51+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
3+
*
4+
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5+
*
6+
* Modifications copyright (C) 2017 Uber Technologies, Inc.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.samples.nexus.caller;
21+
22+
import io.temporal.workflow.WorkflowInterface;
23+
import io.temporal.workflow.WorkflowMethod;
24+
25+
@WorkflowInterface
26+
public interface EchoCallerWorkflow {
27+
@WorkflowMethod
28+
String echo(String message);
29+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
3+
*
4+
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5+
*
6+
* Modifications copyright (C) 2017 Uber Technologies, Inc.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.samples.nexus.caller;
21+
22+
import io.temporal.samples.nexus.service.NexusService;
23+
import io.temporal.workflow.NexusOperationOptions;
24+
import io.temporal.workflow.NexusServiceOptions;
25+
import io.temporal.workflow.Workflow;
26+
import java.time.Duration;
27+
28+
public class EchoCallerWorkflowImpl implements EchoCallerWorkflow {
29+
NexusService nexusService =
30+
Workflow.newNexusServiceStub(
31+
NexusService.class,
32+
NexusServiceOptions.newBuilder()
33+
.setOperationOptions(
34+
NexusOperationOptions.newBuilder()
35+
.setScheduleToCloseTimeout(Duration.ofSeconds(10))
36+
.build())
37+
.build());
38+
39+
@Override
40+
public String echo(String message) {
41+
return nexusService.echo(new NexusService.EchoInput(message)).getMessage();
42+
}
43+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
3+
*
4+
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5+
*
6+
* Modifications copyright (C) 2017 Uber Technologies, Inc.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.samples.nexus.caller;
21+
22+
import io.temporal.samples.nexus.service.NexusService;
23+
import io.temporal.workflow.WorkflowInterface;
24+
import io.temporal.workflow.WorkflowMethod;
25+
26+
@WorkflowInterface
27+
public interface HelloCallerWorkflow {
28+
@WorkflowMethod
29+
String hello(String message, NexusService.Language language);
30+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
3+
*
4+
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5+
*
6+
* Modifications copyright (C) 2017 Uber Technologies, Inc.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.samples.nexus.caller;
21+
22+
import io.temporal.samples.nexus.service.NexusService;
23+
import io.temporal.workflow.NexusOperationHandle;
24+
import io.temporal.workflow.NexusOperationOptions;
25+
import io.temporal.workflow.NexusServiceOptions;
26+
import io.temporal.workflow.Workflow;
27+
import java.time.Duration;
28+
29+
public class HelloCallerWorkflowImpl implements HelloCallerWorkflow {
30+
NexusService nexusService =
31+
Workflow.newNexusServiceStub(
32+
NexusService.class,
33+
NexusServiceOptions.newBuilder()
34+
.setOperationOptions(
35+
NexusOperationOptions.newBuilder()
36+
.setScheduleToCloseTimeout(Duration.ofSeconds(10))
37+
.build())
38+
.build());
39+
40+
@Override
41+
public String hello(String message, NexusService.Language language) {
42+
NexusOperationHandle<NexusService.HelloOutput> handle =
43+
Workflow.startNexusOperation(
44+
nexusService::hello, new NexusService.HelloInput(message, language));
45+
// Optionally wait for the operation to be started. NexusOperationExecution will contain the
46+
// operation ID in case this operation is asynchronous.
47+
handle.getExecution().get();
48+
return handle.getResult().get().getMessage();
49+
}
50+
}

0 commit comments

Comments
 (0)