Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ jobs:
name: "Gradle wrapper validation"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: gradle/wrapper-validation-action@v3
- uses: actions/checkout@v6
- uses: gradle/actions/wrapper-validation@v5

unittest:
name: Unit Tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import io.temporal.client.WorkflowClient;
import io.temporal.client.WorkflowOptions;
import io.temporal.samples.nexus.options.ClientOptions;
import io.temporal.samples.nexus.service.NexusService;
import io.temporal.samples.nexus.service.SampleNexusService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -26,11 +26,12 @@ public static void main(String[] args) {
logger.info("Workflow result: {}", echoWorkflow.echo("Nexus Echo 👋"));
HelloCallerWorkflow helloWorkflow =
client.newWorkflowStub(HelloCallerWorkflow.class, workflowOptions);
execution = WorkflowClient.start(helloWorkflow::hello, "Nexus", NexusService.Language.EN);
execution = WorkflowClient.start(helloWorkflow::hello, "Nexus", SampleNexusService.Language.EN);
logger.info(
"Started HelloCallerWorkflow workflowId: {} runId: {}",
execution.getWorkflowId(),
execution.getRunId());
logger.info("Workflow result: {}", helloWorkflow.hello("Nexus", NexusService.Language.ES));
logger.info(
"Workflow result: {}", helloWorkflow.hello("Nexus", SampleNexusService.Language.ES));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public static void main(String[] args) {
WorkflowImplementationOptions.newBuilder()
.setNexusServiceOptions(
Collections.singletonMap(
"NexusService",
"SampleNexusService",
NexusServiceOptions.newBuilder().setEndpoint("my-nexus-endpoint-name").build()))
.build(),
EchoCallerWorkflowImpl.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package io.temporal.samples.nexus.caller;

import io.temporal.samples.nexus.service.NexusService;
import io.temporal.samples.nexus.service.SampleNexusService;
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 =
SampleNexusService sampleNexusService =
Workflow.newNexusServiceStub(
NexusService.class,
SampleNexusService.class,
NexusServiceOptions.newBuilder()
.setOperationOptions(
NexusOperationOptions.newBuilder()
Expand All @@ -19,6 +19,6 @@ public class EchoCallerWorkflowImpl implements EchoCallerWorkflow {

@Override
public String echo(String message) {
return nexusService.echo(new NexusService.EchoInput(message)).getMessage();
return sampleNexusService.echo(new SampleNexusService.EchoInput(message)).getMessage();
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package io.temporal.samples.nexus.caller;

import io.temporal.samples.nexus.service.NexusService;
import io.temporal.samples.nexus.service.SampleNexusService;
import io.temporal.workflow.WorkflowInterface;
import io.temporal.workflow.WorkflowMethod;

@WorkflowInterface
public interface HelloCallerWorkflow {
@WorkflowMethod
String hello(String message, NexusService.Language language);
String hello(String message, SampleNexusService.Language language);
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package io.temporal.samples.nexus.caller;

import io.temporal.samples.nexus.service.NexusService;
import io.temporal.samples.nexus.service.SampleNexusService;
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 =
SampleNexusService sampleNexusService =
Workflow.newNexusServiceStub(
NexusService.class,
SampleNexusService.class,
NexusServiceOptions.newBuilder()
.setOperationOptions(
NexusOperationOptions.newBuilder()
Expand All @@ -19,10 +19,10 @@ public class HelloCallerWorkflowImpl implements HelloCallerWorkflow {
.build());

@Override
public String hello(String message, NexusService.Language language) {
NexusOperationHandle<NexusService.HelloOutput> handle =
public String hello(String message, SampleNexusService.Language language) {
NexusOperationHandle<SampleNexusService.HelloOutput> handle =
Workflow.startNexusOperation(
nexusService::hello, new NexusService.HelloInput(message, language));
sampleNexusService::hello, new SampleNexusService.HelloInput(message, language));
// Optionally wait for the operation to be started. NexusOperationExecution will contain the
// operation token in case this operation is asynchronous.
handle.getExecution().get();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.temporal.samples.nexus.handler;

import io.temporal.samples.nexus.service.SampleNexusService;

public interface EchoClient {
SampleNexusService.EchoOutput echo(SampleNexusService.EchoInput input);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.temporal.samples.nexus.handler;

import io.temporal.samples.nexus.service.SampleNexusService;

// Note that this is a class, not a Temporal worker. This is to demonstrate that Nexus services can
// simply call a class instead of a worker for fast operations that don't need retry handling.
public class EchoClientImpl implements EchoClient {
@Override
public SampleNexusService.EchoOutput echo(SampleNexusService.EchoInput input) {
return new SampleNexusService.EchoOutput(input.getMessage());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public static void main(String[] args) {

Worker worker = factory.newWorker(DEFAULT_TASK_QUEUE_NAME);
worker.registerWorkflowImplementationTypes(HelloHandlerWorkflowImpl.class);
worker.registerNexusServiceImplementation(new NexusServiceImpl());
worker.registerNexusServiceImplementation(new SampleNexusServiceImpl());

factory.start();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package io.temporal.samples.nexus.handler;

import io.temporal.samples.nexus.service.NexusService;
import io.temporal.samples.nexus.service.SampleNexusService;
import io.temporal.workflow.WorkflowInterface;
import io.temporal.workflow.WorkflowMethod;

@WorkflowInterface
public interface HelloHandlerWorkflow {
@WorkflowMethod
NexusService.HelloOutput hello(NexusService.HelloInput input);
SampleNexusService.HelloOutput hello(SampleNexusService.HelloInput input);
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
package io.temporal.samples.nexus.handler;

import io.temporal.failure.ApplicationFailure;
import io.temporal.samples.nexus.service.NexusService;
import io.temporal.samples.nexus.service.SampleNexusService;

public class HelloHandlerWorkflowImpl implements HelloHandlerWorkflow {
@Override
public NexusService.HelloOutput hello(NexusService.HelloInput input) {
public SampleNexusService.HelloOutput hello(SampleNexusService.HelloInput input) {
switch (input.getLanguage()) {
case EN:
return new NexusService.HelloOutput("Hello " + input.getName() + " 👋");
return new SampleNexusService.HelloOutput("Hello " + input.getName() + " 👋");
case FR:
return new NexusService.HelloOutput("Bonjour " + input.getName() + " 👋");
return new SampleNexusService.HelloOutput("Bonjour " + input.getName() + " 👋");
case DE:
return new NexusService.HelloOutput("Hallo " + input.getName() + " 👋");
return new SampleNexusService.HelloOutput("Hallo " + input.getName() + " 👋");
case ES:
return new NexusService.HelloOutput("¡Hola! " + input.getName() + " 👋");
return new SampleNexusService.HelloOutput("¡Hola! " + input.getName() + " 👋");
case TR:
return new NexusService.HelloOutput("Merhaba " + input.getName() + " 👋");
return new SampleNexusService.HelloOutput("Merhaba " + input.getName() + " 👋");
}
throw ApplicationFailure.newFailure(
"Unsupported language: " + input.getLanguage(), "UNSUPPORTED_LANGUAGE");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,43 @@
import io.temporal.client.WorkflowOptions;
import io.temporal.nexus.Nexus;
import io.temporal.nexus.WorkflowRunOperation;
import io.temporal.samples.nexus.service.NexusService;
import io.temporal.samples.nexus.service.SampleNexusService;

// 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 {
@ServiceImpl(service = SampleNexusService.class)
public class SampleNexusServiceImpl {
private final EchoClient echoClient;

// The injected EchoClient makes this class unit-testable.
// The no-arg constructor provides a default; the second allows tests to inject a mock.
// If you are not using the sync call or do not need to mock a handler, then you will not
// need this constructor pairing.
public SampleNexusServiceImpl() {
this(new EchoClientImpl());
}

public SampleNexusServiceImpl(EchoClient echoClient) {
this.echoClient = echoClient;
}

// The Echo Nexus Service exemplifies making a synchronous call using OperationHandler.sync.
// In this case, it is calling the EchoClient class - not a workflow - and simply returning the
// result.
@OperationImpl
public OperationHandler<NexusService.EchoInput, NexusService.EchoOutput> echo() {
// OperationHandler.sync is a meant for exposing simple RPC handlers.
public OperationHandler<SampleNexusService.EchoInput, SampleNexusService.EchoOutput> echo() {
return OperationHandler.sync(
// The method is for making arbitrary short calls to other services or databases, or
// perform simple computations such as this one. Users can also access a workflow client by
// calling
// Nexus.getOperationContext().getWorkflowClient(ctx) to make arbitrary calls such as
// signaling, querying, or listing workflows.
(ctx, details, input) -> new NexusService.EchoOutput(input.getMessage()));
(ctx, details, input) -> echoClient.echo(input));
}

@OperationImpl
public OperationHandler<NexusService.HelloInput, NexusService.HelloOutput> hello() {
public OperationHandler<SampleNexusService.HelloInput, SampleNexusService.HelloOutput> hello() {
// Use the WorkflowRunOperation.fromWorkflowMethod constructor, which is the easiest
// way to expose a workflow as an operation. To expose a workflow with a different input
// parameters then the operation or from an untyped stub, use the
Expand All @@ -39,10 +55,8 @@ public OperationHandler<NexusService.HelloInput, NexusService.HelloOutput> hello
.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
// 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.
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import io.nexusrpc.Service;

@Service
public interface NexusService {
public interface SampleNexusService {
enum Language {
EN,
FR,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Service: [NexusService](https://github.com/temporalio/samples-java/blob/main/core/src/main/java/io/temporal/samples/nexus/service/NexusService.java)
## Service: [SampleNexusService](https://github.com/temporalio/samples-java/blob/main/core/src/main/java/io/temporal/samples/nexus/service/SampleNexusService.java)
- operation: `echo`
- operation: `hello`

See https://github.com/temporalio/samples-java/blob/main/core/src/main/java/io/temporal/samples/nexus/service/NexusService.java for Input / Output types.
See https://github.com/temporalio/samples-java/blob/main/core/src/main/java/io/temporal/samples/nexus/service/SampleNexusService.java for Input / Output types.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import io.temporal.client.WorkflowClient;
import io.temporal.samples.nexus.options.ClientOptions;
import io.temporal.samples.nexus.service.NexusService;
import io.temporal.samples.nexus.service.SampleNexusService;
import io.temporal.worker.Worker;
import io.temporal.worker.WorkerFactory;
import io.temporal.worker.WorkflowImplementationOptions;
Expand All @@ -22,7 +22,7 @@ public static void main(String[] args) {
WorkflowImplementationOptions.newBuilder()
.setNexusServiceOptions(
Collections.singletonMap(
NexusService.class.getSimpleName(),
SampleNexusService.class.getSimpleName(),
NexusServiceOptions.newBuilder().setEndpoint("my-nexus-endpoint-name").build()))
.build(),
HelloCallerWorkflowImpl.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package io.temporal.samples.nexuscancellation.caller;

import static io.temporal.samples.nexus.service.NexusService.Language.*;
import static io.temporal.samples.nexus.service.SampleNexusService.Language.*;

import io.temporal.failure.CanceledFailure;
import io.temporal.failure.NexusOperationFailure;
import io.temporal.samples.nexus.service.NexusService;
import io.temporal.samples.nexus.service.SampleNexusService;
import io.temporal.workflow.*;
import java.time.Duration;
import java.util.ArrayList;
Expand All @@ -13,11 +13,11 @@

public class HelloCallerWorkflowImpl implements HelloCallerWorkflow {
public static final Logger log = Workflow.getLogger(HelloCallerWorkflowImpl.class);
private static final NexusService.Language[] languages =
new NexusService.Language[] {EN, FR, DE, ES, TR};
NexusService nexusService =
private static final SampleNexusService.Language[] languages =
new SampleNexusService.Language[] {EN, FR, DE, ES, TR};
SampleNexusService sampleNexusService =
Workflow.newNexusServiceStub(
NexusService.class,
SampleNexusService.class,
NexusServiceOptions.newBuilder()
.setOperationOptions(
NexusOperationOptions.newBuilder()
Expand All @@ -33,7 +33,7 @@ public class HelloCallerWorkflowImpl implements HelloCallerWorkflow {

@Override
public String hello(String message) {
List<Promise<NexusService.HelloOutput>> results = new ArrayList<>(languages.length);
List<Promise<SampleNexusService.HelloOutput>> results = new ArrayList<>(languages.length);

/*
* Create our CancellationScope. Within this scope we call the nexus operation asynchronously
Expand All @@ -42,10 +42,11 @@ public String hello(String message) {
CancellationScope scope =
Workflow.newCancellationScope(
() -> {
for (NexusService.Language language : languages) {
for (SampleNexusService.Language language : languages) {
results.add(
Async.function(
nexusService::hello, new NexusService.HelloInput(message, language)));
sampleNexusService::hello,
new SampleNexusService.HelloInput(message, language)));
}
});

Expand All @@ -56,7 +57,7 @@ public String hello(String message) {
scope.run();

// We use "anyOf" here to wait for one of the nexus operation invocations to return
NexusService.HelloOutput result = Promise.anyOf(results).get();
SampleNexusService.HelloOutput result = Promise.anyOf(results).get();

// Trigger cancellation of all uncompleted nexus operations invocations within the cancellation
// scope
Expand All @@ -67,7 +68,7 @@ public String hello(String message) {
// Note: Once the workflow completes any pending cancellation requests are dropped by the
// server. In general, it is a good practice to wait for all cancellation requests to be
// processed before completing the workflow.
for (Promise<NexusService.HelloOutput> promise : results) {
for (Promise<SampleNexusService.HelloOutput> promise : results) {
try {
promise.get();
} catch (NexusOperationFailure e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.temporal.samples.nexuscancellation.handler;

import io.temporal.client.WorkflowClient;
import io.temporal.samples.nexus.handler.NexusServiceImpl;
import io.temporal.samples.nexus.handler.SampleNexusServiceImpl;
import io.temporal.samples.nexus.options.ClientOptions;
import io.temporal.worker.Worker;
import io.temporal.worker.WorkerFactory;
Expand All @@ -16,7 +16,7 @@ public static void main(String[] args) {

Worker worker = factory.newWorker(DEFAULT_TASK_QUEUE_NAME);
worker.registerWorkflowImplementationTypes(HelloHandlerWorkflowImpl.class);
worker.registerNexusServiceImplementation(new NexusServiceImpl());
worker.registerNexusServiceImplementation(new SampleNexusServiceImpl());

factory.start();
}
Expand Down
Loading
Loading