Skip to content
Draft
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
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ subprojects {
ext {
otelVersion = '1.30.1'
otelVersionAlpha = "${otelVersion}-alpha"
javaSDKVersion = '1.28.1'
javaSDKVersion = '1.28.4'
camelVersion = '3.22.1'
jarVersion = '1.0.0'
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Nexus Early Return

This sample demonstrates the early return pattern with Nexus.

For more details on the early return pattern see the [Early Return Sample](../earlyreturn/README.md)

To run this sample, set up your environment following the instructions in the main [Nexus Sample](../nexus/README.md).

In separate terminal windows:

### Nexus handler worker

```
./gradlew -q execute -PmainClass=io.temporal.samples.nexusEarlyReturn.handler.HandlerWorker \
--args="-target-host localhost:7233 -namespace my-target-namespace"
```

### Nexus caller worker

```
./gradlew -q execute -PmainClass=io.temporal.samples.nexusEarlyReturn.caller.CallerWorker \
--args="-target-host localhost:7233 -namespace my-caller-namespace"
```

### Start caller workflow

```
./gradlew -q execute -PmainClass=io.temporal.samples.nexusEarlyReturn.caller.CallerStarter \
--args="-target-host localhost:7233 -namespace my-caller-namespace"
```

### Output

which should result in:
```
10:52:08.542 { } [main] INFO i.t.s.n.caller.CallerStarter - Started TransferWorkflow workflowId: 1526a62a-cc76-49a9-bc10-b91d67b4f0e8 runId: 01974b85-7b59-76e5-80aa-3ab0dfb983ef
10:52:12.084 { } [main] INFO i.t.s.n.caller.CallerStarter - Workflow result: Transaction completed successfully.
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* 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.nexusEarlyReturn.caller;

import io.temporal.api.common.v1.WorkflowExecution;
import io.temporal.client.WorkflowClient;
import io.temporal.client.WorkflowOptions;
import io.temporal.samples.earlyreturn.TransactionRequest;
import io.temporal.samples.nexusEarlyReturn.options.ClientOptions;
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) {
WorkflowClient client = ClientOptions.getWorkflowClient(args);

WorkflowOptions workflowOptions =
WorkflowOptions.newBuilder().setTaskQueue(CallerWorker.DEFAULT_TASK_QUEUE_NAME).build();
TransferWorkflow transferWorkflow =
client.newWorkflowStub(TransferWorkflow.class, workflowOptions);
WorkflowExecution execution =
WorkflowClient.start(
transferWorkflow::transfer, new TransactionRequest("source", "target", 100));
logger.info(
"Started TransferWorkflow workflowId: {} runId: {}",
execution.getWorkflowId(),
execution.getRunId());
logger.info(
"Workflow result: {}",
transferWorkflow.transfer(new TransactionRequest("source", "target", 100)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* 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.nexusEarlyReturn.caller;

import io.temporal.client.WorkflowClient;
import io.temporal.samples.nexusEarlyReturn.options.ClientOptions;
import io.temporal.worker.Worker;
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";

public static void main(String[] args) {
WorkflowClient client = ClientOptions.getWorkflowClient(args);

WorkerFactory factory = WorkerFactory.newInstance(client);

Worker worker = factory.newWorker(DEFAULT_TASK_QUEUE_NAME);
worker.registerWorkflowImplementationTypes(
WorkflowImplementationOptions.newBuilder()
.setNexusServiceOptions(
Collections.singletonMap(
"TransactionService",
NexusServiceOptions.newBuilder().setEndpoint("my-nexus-endpoint-name").build()))
.build(),
TransferWorkflowImpl.class);

factory.start();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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.nexusEarlyReturn.caller;

import io.temporal.samples.earlyreturn.TransactionRequest;
import io.temporal.workflow.WorkflowInterface;
import io.temporal.workflow.WorkflowMethod;

@WorkflowInterface
public interface TransferWorkflow {
@WorkflowMethod
String transfer(TransactionRequest message);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* 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.nexusEarlyReturn.caller;

import io.temporal.failure.ApplicationFailure;
import io.temporal.failure.NexusOperationFailure;
import io.temporal.samples.earlyreturn.TransactionRequest;
import io.temporal.samples.earlyreturn.TxResult;
import io.temporal.samples.nexusEarlyReturn.service.TransactionService;
import io.temporal.workflow.NexusOperationOptions;
import io.temporal.workflow.NexusServiceOptions;
import io.temporal.workflow.Workflow;
import java.time.Duration;

/**
* TransferWorkflowImpl starts a transfer and waits for it to complete (if the transaction is
* successful or not).
*/
public class TransferWorkflowImpl implements TransferWorkflow {
TransactionService transactionService =
Workflow.newNexusServiceStub(
TransactionService.class,
NexusServiceOptions.newBuilder()
.setOperationOptions(
NexusOperationOptions.newBuilder()
.setScheduleToCloseTimeout(Duration.ofSeconds(10))
.build())
.build());

@Override
public String transfer(TransactionRequest request) {
try {
// Start a transaction using the TransactionService Nexus service. Once the transaction is
// started, it will run asynchronously, and we can check the result later.
TransactionService.StartTransactionResponse r =
transactionService.startTransaction(
new TransactionService.StartTransactionRequest(request));
// Note: this random sleep is to simulate some processing time before checking the result.
// Depending on how long the sleep is, the transaction may complete before we check the
// result.
Workflow.sleep(Duration.ofMillis(Workflow.newRandom().nextInt(100)));
TxResult result =
transactionService.getTransactionResult(
new TransactionService.GetTransactionResultRequest(r.getTransactionToken()));
return result.getStatus();
} catch (NexusOperationFailure of) {
// If the operation failed, we check if it was due to a transaction failure.
if (of.getCause() instanceof ApplicationFailure) {
ApplicationFailure af = (ApplicationFailure) of.getCause();
if (af.getType().equals("TransactionFailed")) {
// If the transaction failed, we can retrieve the transaction token from the details
// and use it to wait for the transaction to cancel.
String transactionToken = af.getDetails().get(String.class);
TxResult result =
transactionService.getTransactionResult(
new TransactionService.GetTransactionResultRequest(transactionToken));
return result.getStatus();
}
}
throw of;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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.nexusEarlyReturn.handler;

import io.temporal.client.WorkflowClient;
import io.temporal.samples.earlyreturn.TransactionActivitiesImpl;
import io.temporal.samples.earlyreturn.TransactionWorkflowImpl;
import io.temporal.samples.nexusEarlyReturn.options.ClientOptions;
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) {
WorkflowClient client = ClientOptions.getWorkflowClient(args);

WorkerFactory factory = WorkerFactory.newInstance(client);

Worker worker = factory.newWorker(DEFAULT_TASK_QUEUE_NAME);
worker.registerWorkflowImplementationTypes(TransactionWorkflowImpl.class);
worker.registerActivitiesImplementations(new TransactionActivitiesImpl());
worker.registerNexusServiceImplementation(new TransactionServiceImpl());

factory.start();
}
}
Loading
Loading