From 53b769b4159fc248cf7a3fa42c4c7f3a2a17327a Mon Sep 17 00:00:00 2001 From: Tihomir Surdilovic Date: Tue, 12 Aug 2025 09:20:34 -0400 Subject: [PATCH 01/14] test for updatewithstart and cancellation (#750) Signed-off-by: Tihomir Surdilovic --- .../hello/HelloUpdateAndCancellationTest.java | 210 ++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 core/src/test/java/io/temporal/samples/hello/HelloUpdateAndCancellationTest.java diff --git a/core/src/test/java/io/temporal/samples/hello/HelloUpdateAndCancellationTest.java b/core/src/test/java/io/temporal/samples/hello/HelloUpdateAndCancellationTest.java new file mode 100644 index 000000000..b6eec1fec --- /dev/null +++ b/core/src/test/java/io/temporal/samples/hello/HelloUpdateAndCancellationTest.java @@ -0,0 +1,210 @@ +package io.temporal.samples.hello; + +import io.temporal.activity.*; +import io.temporal.api.enums.v1.WorkflowIdConflictPolicy; +import io.temporal.client.*; +import io.temporal.failure.ActivityFailure; +import io.temporal.failure.CanceledFailure; +import io.temporal.testing.TestWorkflowRule; +import io.temporal.workflow.*; +import java.time.Duration; +import java.util.concurrent.TimeUnit; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; + +public class HelloUpdateAndCancellationTest { + @Rule + public TestWorkflowRule testWorkflowRule = + TestWorkflowRule.newBuilder() + .setWorkflowTypes(TestWorkflowImpl.class) + .setActivityImplementations(new TestActivitiesImpl()) + .build(); + + @Test + public void testUpdateAndWorkflowCancellation() { + // Start workflow with UpdateWithStart then cancel workflow before activity completes + TestWorkflow workflow = + testWorkflowRule + .getWorkflowClient() + .newWorkflowStub( + TestWorkflow.class, + WorkflowOptions.newBuilder() + .setWorkflowId("test-workflow-cancel") + .setTaskQueue(testWorkflowRule.getTaskQueue()) + .setWorkflowIdConflictPolicy( + WorkflowIdConflictPolicy.WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING) + .build()); + + WorkflowUpdateHandle updateHandle = + WorkflowClient.startUpdateWithStart( + workflow::mileStoneCompleted, + UpdateOptions.newBuilder() + .setWaitForStage(WorkflowUpdateStage.ACCEPTED) + .build(), + new WithStartWorkflowOperation<>(workflow::execute)); + + testWorkflowRule + .getTestEnvironment() + .registerDelayedCallback( + Duration.ofSeconds(3), + () -> { + WorkflowStub.fromTyped(workflow).cancel("canceled by test"); + }); + + String updateResult = updateHandle.getResult(); + Assert.assertEquals("milestone canceled", updateResult); + + try { + WorkflowStub.fromTyped(workflow).getResult(String.class); + Assert.fail("Workflow Execution should have been canceled"); + } catch (WorkflowFailedException e) { + // Our workflow should have been canceled + Assert.assertEquals(CanceledFailure.class, e.getCause().getClass()); + } + } + + @Test + public void testUpdateAndActivityCancellation() { + // Start workflow with UpdateWithStart then cancel the activity only by sending signal to + // execution + TestWorkflow workflow = + testWorkflowRule + .getWorkflowClient() + .newWorkflowStub( + TestWorkflow.class, + WorkflowOptions.newBuilder() + .setWorkflowId("test-activity-cancel") + .setTaskQueue(testWorkflowRule.getTaskQueue()) + .setWorkflowIdConflictPolicy( + WorkflowIdConflictPolicy.WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING) + .build()); + + WorkflowUpdateHandle updateHandle = + WorkflowClient.startUpdateWithStart( + workflow::mileStoneCompleted, + UpdateOptions.newBuilder() + .setWaitForStage(WorkflowUpdateStage.ACCEPTED) + .build(), + new WithStartWorkflowOperation<>(workflow::execute)); + + testWorkflowRule + .getTestEnvironment() + .registerDelayedCallback( + Duration.ofSeconds(3), + () -> { + WorkflowStub.fromTyped(workflow).signal("cancelActivity"); + }); + + String updateResult = updateHandle.getResult(); + Assert.assertEquals("milestone canceled", updateResult); + + try { + WorkflowStub.fromTyped(workflow).getResult(String.class); + Assert.fail("Workflow Execution should have failed"); + } catch (WorkflowFailedException e) { + // In this case we did not cancel workflow execution but we failed it by throwing + // ActivityFailure + Assert.assertEquals(ActivityFailure.class, e.getCause().getClass()); + ActivityFailure af = (ActivityFailure) e.getCause(); + // Since we canceled the activity still, the cause of ActivityFailure should be + // CanceledFailure + Assert.assertEquals(CanceledFailure.class, af.getCause().getClass()); + } + } + + @WorkflowInterface + public interface TestWorkflow { + @WorkflowMethod + String execute(); + + @UpdateMethod + String mileStoneCompleted(); + + @SignalMethod + void cancelActivity(); + } + + public static class TestWorkflowImpl implements TestWorkflow { + boolean milestoneDone, mileStoneCanceled; + CancellationScope scope; + TestActivities activities = + Workflow.newActivityStub( + TestActivities.class, + ActivityOptions.newBuilder() + .setHeartbeatTimeout(Duration.ofSeconds(3)) + .setStartToCloseTimeout(Duration.ofSeconds(10)) + .setCancellationType(ActivityCancellationType.WAIT_CANCELLATION_COMPLETED) + .build()); + + @Override + public String execute() { + scope = + Workflow.newCancellationScope( + () -> { + activities.runActivity(); + }); + + try { + scope.run(); + milestoneDone = true; + Workflow.await(Workflow::isEveryHandlerFinished); + return "workflow completed"; + } catch (ActivityFailure e) { + if (e.getCause() instanceof CanceledFailure) { + CancellationScope detached = + Workflow.newDetachedCancellationScope( + () -> { + mileStoneCanceled = true; + Workflow.await(Workflow::isEveryHandlerFinished); + }); + detached.run(); + } + throw e; + } + } + + @Override + public String mileStoneCompleted() { + Workflow.await(() -> milestoneDone || mileStoneCanceled); + // For sake of testing isEveryHandlerFinished block here for 2 seconds + Workflow.sleep(Duration.ofSeconds(2)); + return milestoneDone ? "milestone completed" : "milestone canceled"; + } + + @Override + public void cancelActivity() { + if (scope != null) { + scope.cancel("test reason"); + } + } + } + + @ActivityInterface + public interface TestActivities { + void runActivity(); + } + + public static class TestActivitiesImpl implements TestActivities { + + @Override + public void runActivity() { + ActivityExecutionContext context = Activity.getExecutionContext(); + for (int i = 0; i < 9; i++) { + sleep(1); + try { + context.heartbeat(i); + } catch (ActivityCompletionException e) { + throw e; + } + } + } + } + + private static void sleep(int seconds) { + try { + Thread.sleep(TimeUnit.SECONDS.toMillis(seconds)); + } catch (InterruptedException e) { + } + } +} From 0dbfe22c1156a4848c0f34a6a9f43b41a5bade86 Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Mon, 25 Aug 2025 13:53:07 -0700 Subject: [PATCH 02/14] Update Java SDK to v1.31.0 (#752) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a7ece2dce..8500fb315 100644 --- a/build.gradle +++ b/build.gradle @@ -26,7 +26,7 @@ subprojects { ext { otelVersion = '1.30.1' otelVersionAlpha = "${otelVersion}-alpha" - javaSDKVersion = '1.30.1' + javaSDKVersion = '1.31.0' camelVersion = '3.22.1' jarVersion = '1.0.0' } From 626bf032cd168ffd353305a7662c2e72f6bc0ce1 Mon Sep 17 00:00:00 2001 From: Spencer Judge Date: Wed, 17 Sep 2025 16:11:57 -0700 Subject: [PATCH 03/14] Create worker deployment based versioning sample (#754) --- .gitignore | 3 +- README.md | 3 +- .../samples/workerversioning/Activities.java | 38 ++++ .../workerversioning/ActivitiesImpl.java | 25 +++ .../AutoUpgradingWorkflow.java | 15 ++ .../AutoUpgradingWorkflowV1Impl.java | 52 ++++++ .../AutoUpgradingWorkflowV1bImpl.java | 65 +++++++ .../workerversioning/PinnedWorkflow.java | 15 ++ .../PinnedWorkflowV1Impl.java | 49 ++++++ .../PinnedWorkflowV2Impl.java | 51 ++++++ .../samples/workerversioning/README.md | 26 +++ .../samples/workerversioning/Starter.java | 163 ++++++++++++++++++ .../samples/workerversioning/WorkerV1.java | 38 ++++ .../samples/workerversioning/WorkerV1_1.java | 38 ++++ .../samples/workerversioning/WorkerV2.java | 38 ++++ 15 files changed, 617 insertions(+), 2 deletions(-) create mode 100644 core/src/main/java/io/temporal/samples/workerversioning/Activities.java create mode 100644 core/src/main/java/io/temporal/samples/workerversioning/ActivitiesImpl.java create mode 100644 core/src/main/java/io/temporal/samples/workerversioning/AutoUpgradingWorkflow.java create mode 100644 core/src/main/java/io/temporal/samples/workerversioning/AutoUpgradingWorkflowV1Impl.java create mode 100644 core/src/main/java/io/temporal/samples/workerversioning/AutoUpgradingWorkflowV1bImpl.java create mode 100644 core/src/main/java/io/temporal/samples/workerversioning/PinnedWorkflow.java create mode 100644 core/src/main/java/io/temporal/samples/workerversioning/PinnedWorkflowV1Impl.java create mode 100644 core/src/main/java/io/temporal/samples/workerversioning/PinnedWorkflowV2Impl.java create mode 100644 core/src/main/java/io/temporal/samples/workerversioning/README.md create mode 100644 core/src/main/java/io/temporal/samples/workerversioning/Starter.java create mode 100644 core/src/main/java/io/temporal/samples/workerversioning/WorkerV1.java create mode 100644 core/src/main/java/io/temporal/samples/workerversioning/WorkerV1_1.java create mode 100644 core/src/main/java/io/temporal/samples/workerversioning/WorkerV2.java diff --git a/.gitignore b/.gitignore index a560c2465..038d5ef43 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,5 @@ target .project .settings/ bin/ -core/.vscode/ \ No newline at end of file +core/.vscode/ +.claude/ diff --git a/README.md b/README.md index a62ed4c98..15e12b8e2 100644 --- a/README.md +++ b/README.md @@ -108,8 +108,9 @@ See the README.md file in each main sample directory for cut/paste Gradle comman - [**Custom Annotation**](/core/src/main/java/io/temporal/samples/customannotation): Demonstrates how to create a custom annotation using an interceptor. -- [**Asnyc Packet Delivery**](/core/src/main/java/io/temporal/samples/packetdelivery): Demonstrates running multiple execution paths async within single execution. +- [**Async Packet Delivery**](/core/src/main/java/io/temporal/samples/packetdelivery): Demonstrates running multiple execution paths async within single execution. +- [**Worker Versioning**](/core/src/main/java/io/temporal/samples/workerversioning): Demonstrates how to use worker versioning to manage workflow code changes. #### API demonstrations diff --git a/core/src/main/java/io/temporal/samples/workerversioning/Activities.java b/core/src/main/java/io/temporal/samples/workerversioning/Activities.java new file mode 100644 index 000000000..b41189d2a --- /dev/null +++ b/core/src/main/java/io/temporal/samples/workerversioning/Activities.java @@ -0,0 +1,38 @@ +package io.temporal.samples.workerversioning; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.temporal.activity.ActivityInterface; +import io.temporal.activity.ActivityMethod; + +@ActivityInterface +public interface Activities { + + @ActivityMethod + String someActivity(String calledBy); + + @ActivityMethod + String someIncompatibleActivity(IncompatibleActivityInput input); + + class IncompatibleActivityInput { + private final String calledBy; + private final String moreData; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public IncompatibleActivityInput( + @JsonProperty("calledBy") String calledBy, @JsonProperty("moreData") String moreData) { + this.calledBy = calledBy; + this.moreData = moreData; + } + + @JsonProperty("calledBy") + public String getCalledBy() { + return calledBy; + } + + @JsonProperty("moreData") + public String getMoreData() { + return moreData; + } + } +} diff --git a/core/src/main/java/io/temporal/samples/workerversioning/ActivitiesImpl.java b/core/src/main/java/io/temporal/samples/workerversioning/ActivitiesImpl.java new file mode 100644 index 000000000..b3e4e2c28 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/workerversioning/ActivitiesImpl.java @@ -0,0 +1,25 @@ +package io.temporal.samples.workerversioning; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ActivitiesImpl implements Activities { + + private static final Logger logger = LoggerFactory.getLogger(ActivitiesImpl.class); + + @Override + public String someActivity(String calledBy) { + logger.info("SomeActivity called by {}", calledBy); + return "SomeActivity called by " + calledBy; + } + + @Override + public String someIncompatibleActivity(IncompatibleActivityInput input) { + logger.info( + "SomeIncompatibleActivity called by {} with {}", input.getCalledBy(), input.getMoreData()); + return "SomeIncompatibleActivity called by " + + input.getCalledBy() + + " with " + + input.getMoreData(); + } +} diff --git a/core/src/main/java/io/temporal/samples/workerversioning/AutoUpgradingWorkflow.java b/core/src/main/java/io/temporal/samples/workerversioning/AutoUpgradingWorkflow.java new file mode 100644 index 000000000..8dff5f7cd --- /dev/null +++ b/core/src/main/java/io/temporal/samples/workerversioning/AutoUpgradingWorkflow.java @@ -0,0 +1,15 @@ +package io.temporal.samples.workerversioning; + +import io.temporal.workflow.SignalMethod; +import io.temporal.workflow.WorkflowInterface; +import io.temporal.workflow.WorkflowMethod; + +@WorkflowInterface +public interface AutoUpgradingWorkflow { + + @WorkflowMethod + void run(); + + @SignalMethod + void doNextSignal(String signal); +} diff --git a/core/src/main/java/io/temporal/samples/workerversioning/AutoUpgradingWorkflowV1Impl.java b/core/src/main/java/io/temporal/samples/workerversioning/AutoUpgradingWorkflowV1Impl.java new file mode 100644 index 000000000..645f0f70d --- /dev/null +++ b/core/src/main/java/io/temporal/samples/workerversioning/AutoUpgradingWorkflowV1Impl.java @@ -0,0 +1,52 @@ +package io.temporal.samples.workerversioning; + +import io.temporal.activity.ActivityOptions; +import io.temporal.common.VersioningBehavior; +import io.temporal.workflow.Workflow; +import io.temporal.workflow.WorkflowVersioningBehavior; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import org.slf4j.Logger; + +/** + * This workflow will automatically move to the latest worker version. We'll be making changes to + * it, which must be replay safe. Note that generally you won't want or need to include a version + * number in your workflow name if you're using the worker versioning feature. This sample does it + * to illustrate changes to the same code over time - but really what we're demonstrating here is + * the evolution of what would have been one workflow definition. + */ +public class AutoUpgradingWorkflowV1Impl implements AutoUpgradingWorkflow { + + private static final Logger logger = Workflow.getLogger(AutoUpgradingWorkflowV1Impl.class); + + private final List signals = new ArrayList<>(); + private final Activities activities = + Workflow.newActivityStub( + Activities.class, + ActivityOptions.newBuilder().setStartToCloseTimeout(Duration.ofSeconds(10)).build()); + + @Override + @WorkflowVersioningBehavior(VersioningBehavior.AUTO_UPGRADE) + public void run() { + logger.info("Changing workflow v1 started. StartTime: {}", Workflow.currentTimeMillis()); + + while (true) { + Workflow.await(() -> !signals.isEmpty()); + String signal = signals.remove(0); + + if ("do-activity".equals(signal)) { + logger.info("Changing workflow v1 running activity"); + activities.someActivity("v1"); + } else { + logger.info("Concluding workflow v1"); + return; + } + } + } + + @Override + public void doNextSignal(String signal) { + signals.add(signal); + } +} diff --git a/core/src/main/java/io/temporal/samples/workerversioning/AutoUpgradingWorkflowV1bImpl.java b/core/src/main/java/io/temporal/samples/workerversioning/AutoUpgradingWorkflowV1bImpl.java new file mode 100644 index 000000000..abedf8517 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/workerversioning/AutoUpgradingWorkflowV1bImpl.java @@ -0,0 +1,65 @@ +package io.temporal.samples.workerversioning; + +import io.temporal.activity.ActivityOptions; +import io.temporal.common.VersioningBehavior; +import io.temporal.workflow.Workflow; +import io.temporal.workflow.WorkflowVersioningBehavior; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import org.slf4j.Logger; + +/** + * This represents us having made *compatible* changes to AutoUpgradingWorkflowV1Impl. + * + *

The compatible changes we've made are: + * + *

    + *
  • Altering the log lines + *
  • Using the `Workflow.getVersion` API to properly introduce branching behavior while + * maintaining compatibility + *
+ */ +public class AutoUpgradingWorkflowV1bImpl implements AutoUpgradingWorkflow { + + private static final Logger logger = Workflow.getLogger(AutoUpgradingWorkflowV1bImpl.class); + + private final List signals = new ArrayList<>(); + private final Activities activities = + Workflow.newActivityStub( + Activities.class, + ActivityOptions.newBuilder().setStartToCloseTimeout(Duration.ofSeconds(10)).build()); + + @Override + @WorkflowVersioningBehavior(VersioningBehavior.AUTO_UPGRADE) + public void run() { + logger.info("Changing workflow v1b started. StartTime: {}", Workflow.currentTimeMillis()); + + while (true) { + Workflow.await(() -> !signals.isEmpty()); + String signal = signals.remove(0); + + if ("do-activity".equals(signal)) { + logger.info("Changing workflow v1b running activity"); + int version = Workflow.getVersion("DifferentActivity", Workflow.DEFAULT_VERSION, 1); + if (version == 1) { + activities.someIncompatibleActivity( + new Activities.IncompatibleActivityInput("v1b", "hello!")); + } else { + // Note it is a valid compatible change to alter the input to an activity. + // However, because we're using the getVersion API, this branch will never be + // taken. + activities.someActivity("v1b"); + } + } else { + logger.info("Concluding workflow v1b"); + break; + } + } + } + + @Override + public void doNextSignal(String signal) { + signals.add(signal); + } +} diff --git a/core/src/main/java/io/temporal/samples/workerversioning/PinnedWorkflow.java b/core/src/main/java/io/temporal/samples/workerversioning/PinnedWorkflow.java new file mode 100644 index 000000000..1d930a40e --- /dev/null +++ b/core/src/main/java/io/temporal/samples/workerversioning/PinnedWorkflow.java @@ -0,0 +1,15 @@ +package io.temporal.samples.workerversioning; + +import io.temporal.workflow.SignalMethod; +import io.temporal.workflow.WorkflowInterface; +import io.temporal.workflow.WorkflowMethod; + +@WorkflowInterface +public interface PinnedWorkflow { + + @WorkflowMethod + void run(); + + @SignalMethod + void doNextSignal(String signal); +} diff --git a/core/src/main/java/io/temporal/samples/workerversioning/PinnedWorkflowV1Impl.java b/core/src/main/java/io/temporal/samples/workerversioning/PinnedWorkflowV1Impl.java new file mode 100644 index 000000000..4826f715c --- /dev/null +++ b/core/src/main/java/io/temporal/samples/workerversioning/PinnedWorkflowV1Impl.java @@ -0,0 +1,49 @@ +package io.temporal.samples.workerversioning; + +import io.temporal.activity.ActivityOptions; +import io.temporal.common.VersioningBehavior; +import io.temporal.workflow.Workflow; +import io.temporal.workflow.WorkflowVersioningBehavior; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import org.slf4j.Logger; + +/** + * This workflow represents one that likely has a short lifetime, and we want to always stay pinned + * to the same version it began on. Note that generally you won't want or need to include a version + * number in your workflow name if you're using the worker versioning feature. This sample does it + * to illustrate changes to the same code over time - but really what we're demonstrating here is + * the evolution of what would have been one workflow definition. + */ +public class PinnedWorkflowV1Impl implements PinnedWorkflow { + + private static final Logger logger = Workflow.getLogger(PinnedWorkflowV1Impl.class); + + private final List signals = new ArrayList<>(); + private final Activities activities = + Workflow.newActivityStub( + Activities.class, + ActivityOptions.newBuilder().setStartToCloseTimeout(Duration.ofSeconds(10)).build()); + + @Override + @WorkflowVersioningBehavior(VersioningBehavior.PINNED) + public void run() { + logger.info("Pinned Workflow v1 started. StartTime: {}", Workflow.currentTimeMillis()); + + while (true) { + Workflow.await(() -> !signals.isEmpty()); + String signal = signals.remove(0); + if ("conclude".equals(signal)) { + break; + } + } + + activities.someActivity("Pinned-v1"); + } + + @Override + public void doNextSignal(String signal) { + signals.add(signal); + } +} diff --git a/core/src/main/java/io/temporal/samples/workerversioning/PinnedWorkflowV2Impl.java b/core/src/main/java/io/temporal/samples/workerversioning/PinnedWorkflowV2Impl.java new file mode 100644 index 000000000..a880b2dc1 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/workerversioning/PinnedWorkflowV2Impl.java @@ -0,0 +1,51 @@ +package io.temporal.samples.workerversioning; + +import io.temporal.activity.ActivityOptions; +import io.temporal.common.VersioningBehavior; +import io.temporal.workflow.Workflow; +import io.temporal.workflow.WorkflowVersioningBehavior; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import org.slf4j.Logger; + +/** + * This workflow has changes that would make it incompatible with v1, and aren't protected by a + * patch. + */ +public class PinnedWorkflowV2Impl implements PinnedWorkflow { + + private static final Logger logger = Workflow.getLogger(PinnedWorkflowV2Impl.class); + + private final List signals = new ArrayList<>(); + private final Activities activities = + Workflow.newActivityStub( + Activities.class, + ActivityOptions.newBuilder().setStartToCloseTimeout(Duration.ofSeconds(10)).build()); + + @Override + @WorkflowVersioningBehavior(VersioningBehavior.PINNED) + public void run() { + logger.info("Pinned Workflow v2 started. StartTime: {}", Workflow.currentTimeMillis()); + + // Here we call an activity where we didn't before, which is an incompatible change. + activities.someActivity("Pinned-v2"); + + while (true) { + Workflow.await(() -> !signals.isEmpty()); + String signal = signals.remove(0); + if ("conclude".equals(signal)) { + break; + } + } + + // We've also changed the activity type here, another incompatible change + activities.someIncompatibleActivity( + new Activities.IncompatibleActivityInput("Pinned-v2", "hi")); + } + + @Override + public void doNextSignal(String signal) { + signals.add(signal); + } +} diff --git a/core/src/main/java/io/temporal/samples/workerversioning/README.md b/core/src/main/java/io/temporal/samples/workerversioning/README.md new file mode 100644 index 000000000..c74b10488 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/workerversioning/README.md @@ -0,0 +1,26 @@ +# Worker Versioning + +This sample demonstrates how to use Temporal's Worker Versioning feature to safely deploy updates to workflow and activity code. It shows the difference between auto-upgrading and pinned workflows, and how to manage worker deployments with different build IDs. + +The sample creates multiple worker versions (1.0, 1.1, and 2.0) within one deployment and demonstrates: +- **Auto-upgrading workflows**: Automatically and controllably migrate to newer worker versions +- **Pinned workflows**: Stay on the original worker version throughout their lifecycle +- **Compatible vs incompatible changes**: How to make safe updates using `Workflow.getVersion` + +## Steps to run this sample: + +1) Run a [Temporal service](https://github.com/temporalio/samples-java/tree/main/#how-to-use). And + ensure that you're using at least Server version 1.28.0 (CLI version 1.4.0). + +2) Start the main application (this will guide you through the sample): + ```bash + ./gradlew -q execute -PmainClass=io.temporal.samples.workerversioning.Starter + ``` +3) Follow the prompts to start workers in separate terminals: + - When prompted, run: `./gradlew -q execute -PmainClass=io.temporal.samples.workerversioning.WorkerV1` + - When prompted, run: `./gradlew -q execute -PmainClass=io.temporal.samples.workerversioning.WorkerV1_1` + - When prompted, run: `./gradlew -q execute -PmainClass=io.temporal.samples.workerversioning.WorkerV2` + +Follow the prompts in the example to observe auto-upgrading workflows migrating to newer workers +while pinned workflows remain on their original versions. + diff --git a/core/src/main/java/io/temporal/samples/workerversioning/Starter.java b/core/src/main/java/io/temporal/samples/workerversioning/Starter.java new file mode 100644 index 000000000..a48902557 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/workerversioning/Starter.java @@ -0,0 +1,163 @@ +package io.temporal.samples.workerversioning; + +import io.temporal.api.workflowservice.v1.DescribeWorkerDeploymentRequest; +import io.temporal.api.workflowservice.v1.DescribeWorkerDeploymentResponse; +import io.temporal.api.workflowservice.v1.SetWorkerDeploymentCurrentVersionRequest; +import io.temporal.client.WorkflowClient; +import io.temporal.client.WorkflowOptions; +import io.temporal.client.WorkflowStub; +import io.temporal.common.WorkerDeploymentVersion; +import io.temporal.serviceclient.WorkflowServiceStubs; +import java.util.UUID; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Starter { + public static final String TASK_QUEUE = "worker-versioning"; + public static final String DEPLOYMENT_NAME = "my-deployment"; + + private static final Logger logger = LoggerFactory.getLogger(Starter.class); + + public static void main(String[] args) throws Exception { + WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + WorkflowClient client = WorkflowClient.newInstance(service); + + // Wait for v1 worker and set as current version + logger.info( + "Waiting for v1 worker to appear. Run `./gradlew -q execute -PmainClass=io.temporal.samples.workerversioning.WorkerV1` in another terminal"); + waitForWorkerAndMakeCurrent(client, service, "1.0"); + + // Start auto-upgrading and pinned workflows. Importantly, note that when we start the + // workflows, + // we are using a workflow type name which does *not* include the version number. We defined + // them + // with versioned names so we could show changes to the code, but here when the client invokes + // them, we're demonstrating that the client remains version-agnostic. + String autoUpgradeWorkflowId = "worker-versioning-versioning-autoupgrade_" + UUID.randomUUID(); + WorkflowStub autoUpgradeExecution = + client.newUntypedWorkflowStub( + "AutoUpgradingWorkflow", + WorkflowOptions.newBuilder() + .setWorkflowId(autoUpgradeWorkflowId) + .setTaskQueue(TASK_QUEUE) + .build()); + + String pinnedWorkflowId = "worker-versioning-versioning-pinned_" + UUID.randomUUID(); + WorkflowStub pinnedExecution = + client.newUntypedWorkflowStub( + "PinnedWorkflow", + WorkflowOptions.newBuilder() + .setWorkflowId(pinnedWorkflowId) + .setTaskQueue(TASK_QUEUE) + .build()); + + // Start workflows asynchronously + autoUpgradeExecution.start(); + pinnedExecution.start(); + + logger.info( + "Started auto-upgrading workflow: {}", autoUpgradeExecution.getExecution().getWorkflowId()); + logger.info("Started pinned workflow: {}", pinnedExecution.getExecution().getWorkflowId()); + + // Signal both workflows a few times to drive them + advanceWorkflows(autoUpgradeExecution, pinnedExecution); + + // Now wait for the v1.1 worker to appear and become current + logger.info( + "Waiting for v1.1 worker to appear. Run `./gradlew -q execute -PmainClass=io.temporal.samples.workerversioning.WorkerV1_1` in another terminal"); + waitForWorkerAndMakeCurrent(client, service, "1.1"); + + // Once it has, we will continue to advance the workflows. + // The auto-upgrade workflow will now make progress on the new worker, while the pinned one will + // keep progressing on the old worker. + advanceWorkflows(autoUpgradeExecution, pinnedExecution); + + // Finally we'll start the v2 worker, and again it'll become the new current version + logger.info( + "Waiting for v2 worker to appear. Run `./gradlew -q execute -PmainClass=io.temporal.samples.workerversioning.WorkerV2` in another terminal"); + waitForWorkerAndMakeCurrent(client, service, "2.0"); + + // Once it has we'll start one more new workflow, another pinned one, to demonstrate that new + // pinned workflows start on the current version. + String pinnedWorkflow2Id = "worker-versioning-versioning-pinned-2_" + UUID.randomUUID(); + WorkflowStub pinnedExecution2 = + client.newUntypedWorkflowStub( + "PinnedWorkflow", + WorkflowOptions.newBuilder() + .setWorkflowId(pinnedWorkflow2Id) + .setTaskQueue(TASK_QUEUE) + .build()); + pinnedExecution2.start(); + logger.info("Started pinned workflow v2: {}", pinnedExecution2.getExecution().getWorkflowId()); + + // Now we'll conclude all workflows. You should be able to see in your server UI that the pinned + // workflow always stayed on 1.0, while the auto-upgrading workflow migrated. + autoUpgradeExecution.signal("doNextSignal", "conclude"); + pinnedExecution.signal("doNextSignal", "conclude"); + pinnedExecution2.signal("doNextSignal", "conclude"); + + // Wait for all workflows to complete + autoUpgradeExecution.getResult(Void.class); + pinnedExecution.getResult(Void.class); + pinnedExecution2.getResult(Void.class); + + logger.info("All workflows completed"); + } + + private static void advanceWorkflows( + WorkflowStub autoUpgradeExecution, WorkflowStub pinnedExecution) { + // Signal both workflows a few times to drive them + for (int i = 0; i < 3; i++) { + autoUpgradeExecution.signal("doNextSignal", "do-activity"); + pinnedExecution.signal("doNextSignal", "some-signal"); + } + } + + private static void waitForWorkerAndMakeCurrent( + WorkflowClient client, WorkflowServiceStubs service, String buildId) + throws InterruptedException { + WorkerDeploymentVersion targetVersion = new WorkerDeploymentVersion(DEPLOYMENT_NAME, buildId); + + // Wait for the worker to appear + while (true) { + try { + DescribeWorkerDeploymentRequest describeRequest = + DescribeWorkerDeploymentRequest.newBuilder() + .setNamespace(client.getOptions().getNamespace()) + .setDeploymentName(DEPLOYMENT_NAME) + .build(); + + DescribeWorkerDeploymentResponse response = + service.blockingStub().describeWorkerDeployment(describeRequest); + + // Check if our version is present in the version summaries + boolean found = + response.getWorkerDeploymentInfo().getVersionSummariesList().stream() + .anyMatch( + versionSummary -> + targetVersion + .getDeploymentName() + .equals(versionSummary.getDeploymentVersion().getDeploymentName()) + && targetVersion + .getBuildId() + .equals(versionSummary.getDeploymentVersion().getBuildId())); + + if (found) { + break; + } + } catch (Exception ignored) { + } + Thread.sleep(1000); + } + + // Once the version is available, set it as current + SetWorkerDeploymentCurrentVersionRequest setRequest = + SetWorkerDeploymentCurrentVersionRequest.newBuilder() + .setNamespace(client.getOptions().getNamespace()) + .setDeploymentName(DEPLOYMENT_NAME) + .setBuildId(targetVersion.getBuildId()) + .build(); + + service.blockingStub().setWorkerDeploymentCurrentVersion(setRequest); + } +} diff --git a/core/src/main/java/io/temporal/samples/workerversioning/WorkerV1.java b/core/src/main/java/io/temporal/samples/workerversioning/WorkerV1.java new file mode 100644 index 000000000..6d90b82fd --- /dev/null +++ b/core/src/main/java/io/temporal/samples/workerversioning/WorkerV1.java @@ -0,0 +1,38 @@ +package io.temporal.samples.workerversioning; + +import io.temporal.client.WorkflowClient; +import io.temporal.common.WorkerDeploymentVersion; +import io.temporal.serviceclient.WorkflowServiceStubs; +import io.temporal.worker.Worker; +import io.temporal.worker.WorkerDeploymentOptions; +import io.temporal.worker.WorkerFactory; +import io.temporal.worker.WorkerOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WorkerV1 { + + private static final Logger logger = LoggerFactory.getLogger(WorkerV1.class); + + public static void main(String[] args) { + WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + WorkflowClient client = WorkflowClient.newInstance(service); + + WorkerDeploymentVersion version = new WorkerDeploymentVersion(Starter.DEPLOYMENT_NAME, "1.0"); + WorkerDeploymentOptions deploymentOptions = + WorkerDeploymentOptions.newBuilder().setUseVersioning(true).setVersion(version).build(); + + WorkerOptions workerOptions = + WorkerOptions.newBuilder().setDeploymentOptions(deploymentOptions).build(); + + WorkerFactory factory = WorkerFactory.newInstance(client); + Worker worker = factory.newWorker(Starter.TASK_QUEUE, workerOptions); + + worker.registerWorkflowImplementationTypes( + AutoUpgradingWorkflowV1Impl.class, PinnedWorkflowV1Impl.class); + worker.registerActivitiesImplementations(new ActivitiesImpl()); + + logger.info("Starting worker v1 (build 1.0)"); + factory.start(); + } +} diff --git a/core/src/main/java/io/temporal/samples/workerversioning/WorkerV1_1.java b/core/src/main/java/io/temporal/samples/workerversioning/WorkerV1_1.java new file mode 100644 index 000000000..5b1235460 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/workerversioning/WorkerV1_1.java @@ -0,0 +1,38 @@ +package io.temporal.samples.workerversioning; + +import io.temporal.client.WorkflowClient; +import io.temporal.common.WorkerDeploymentVersion; +import io.temporal.serviceclient.WorkflowServiceStubs; +import io.temporal.worker.Worker; +import io.temporal.worker.WorkerDeploymentOptions; +import io.temporal.worker.WorkerFactory; +import io.temporal.worker.WorkerOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WorkerV1_1 { + + private static final Logger logger = LoggerFactory.getLogger(WorkerV1_1.class); + + public static void main(String[] args) { + WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + WorkflowClient client = WorkflowClient.newInstance(service); + + WorkerDeploymentVersion version = new WorkerDeploymentVersion(Starter.DEPLOYMENT_NAME, "1.1"); + WorkerDeploymentOptions deploymentOptions = + WorkerDeploymentOptions.newBuilder().setUseVersioning(true).setVersion(version).build(); + + WorkerOptions workerOptions = + WorkerOptions.newBuilder().setDeploymentOptions(deploymentOptions).build(); + + WorkerFactory factory = WorkerFactory.newInstance(client); + Worker worker = factory.newWorker(Starter.TASK_QUEUE, workerOptions); + + worker.registerWorkflowImplementationTypes( + AutoUpgradingWorkflowV1bImpl.class, PinnedWorkflowV1Impl.class); + worker.registerActivitiesImplementations(new ActivitiesImpl()); + + logger.info("Starting worker v1.1 (build 1.1)"); + factory.start(); + } +} diff --git a/core/src/main/java/io/temporal/samples/workerversioning/WorkerV2.java b/core/src/main/java/io/temporal/samples/workerversioning/WorkerV2.java new file mode 100644 index 000000000..57edd0ed3 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/workerversioning/WorkerV2.java @@ -0,0 +1,38 @@ +package io.temporal.samples.workerversioning; + +import io.temporal.client.WorkflowClient; +import io.temporal.common.WorkerDeploymentVersion; +import io.temporal.serviceclient.WorkflowServiceStubs; +import io.temporal.worker.Worker; +import io.temporal.worker.WorkerDeploymentOptions; +import io.temporal.worker.WorkerFactory; +import io.temporal.worker.WorkerOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WorkerV2 { + + private static final Logger logger = LoggerFactory.getLogger(WorkerV2.class); + + public static void main(String[] args) { + WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + WorkflowClient client = WorkflowClient.newInstance(service); + + WorkerDeploymentVersion version = new WorkerDeploymentVersion(Starter.DEPLOYMENT_NAME, "2.0"); + WorkerDeploymentOptions deploymentOptions = + WorkerDeploymentOptions.newBuilder().setUseVersioning(true).setVersion(version).build(); + + WorkerOptions workerOptions = + WorkerOptions.newBuilder().setDeploymentOptions(deploymentOptions).build(); + + WorkerFactory factory = WorkerFactory.newInstance(client); + Worker worker = factory.newWorker(Starter.TASK_QUEUE, workerOptions); + + worker.registerWorkflowImplementationTypes( + AutoUpgradingWorkflowV1bImpl.class, PinnedWorkflowV2Impl.class); + worker.registerActivitiesImplementations(new ActivitiesImpl()); + + logger.info("Starting worker v2 (build 2.0)"); + factory.start(); + } +} From 175216aad6fc4749a33e8d30c7f8738ffb71155e Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Fri, 28 Nov 2025 09:57:11 -0800 Subject: [PATCH 04/14] Update Java SDK to v1.32.0 (#759) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 8500fb315..0377d028e 100644 --- a/build.gradle +++ b/build.gradle @@ -26,7 +26,7 @@ subprojects { ext { otelVersion = '1.30.1' otelVersionAlpha = "${otelVersion}-alpha" - javaSDKVersion = '1.31.0' + javaSDKVersion = '1.32.0' camelVersion = '3.22.1' jarVersion = '1.0.0' } From c93875b3a7d220a021f0b7af931e5e3917de798a Mon Sep 17 00:00:00 2001 From: Thomas Hardy Date: Sat, 29 Nov 2025 00:15:52 -0500 Subject: [PATCH 05/14] Standalone Client Environment Configuration Sample (#755) * env config sample * update temporal-envconfig dep --- README.md | 3 + core/build.gradle | 3 + .../samples/envconfig/LoadFromFile.java | 79 +++++++++++++++++ .../samples/envconfig/LoadProfile.java | 87 +++++++++++++++++++ .../io/temporal/samples/envconfig/README.md | 18 ++++ core/src/main/resources/config.toml | 40 +++++++++ 6 files changed, 230 insertions(+) create mode 100644 core/src/main/java/io/temporal/samples/envconfig/LoadFromFile.java create mode 100644 core/src/main/java/io/temporal/samples/envconfig/LoadProfile.java create mode 100644 core/src/main/java/io/temporal/samples/envconfig/README.md create mode 100644 core/src/main/resources/config.toml diff --git a/README.md b/README.md index 15e12b8e2..4d00e320b 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,9 @@ See the README.md file in each main sample directory for cut/paste Gradle comman - [**Worker Versioning**](/core/src/main/java/io/temporal/samples/workerversioning): Demonstrates how to use worker versioning to manage workflow code changes. +- [**Environment Configuration**](/core/src/main/java/io/temporal/samples/envconfig): +Load client configuration from TOML files with programmatic overrides. + #### API demonstrations - [**Async Untyped Child Workflow**](/core/src/main/java/io/temporal/samples/asyncuntypedchild): Demonstrates how to invoke an untyped child workflow async, that can complete after parent workflow is already completed. diff --git a/core/build.gradle b/core/build.gradle index 42ad4be2b..62fbfa8e9 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -4,6 +4,9 @@ dependencies { implementation "io.temporal:temporal-opentracing:$javaSDKVersion" testImplementation("io.temporal:temporal-testing:$javaSDKVersion") + // Environment configuration + implementation "io.temporal:temporal-envconfig:$javaSDKVersion" + // Needed for SDK related functionality implementation(platform("com.fasterxml.jackson:jackson-bom:2.17.2")) implementation "com.fasterxml.jackson.core:jackson-databind" diff --git a/core/src/main/java/io/temporal/samples/envconfig/LoadFromFile.java b/core/src/main/java/io/temporal/samples/envconfig/LoadFromFile.java new file mode 100644 index 000000000..b6a9f7187 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/envconfig/LoadFromFile.java @@ -0,0 +1,79 @@ +package io.temporal.samples.envconfig; + +import io.temporal.client.WorkflowClient; +import io.temporal.client.WorkflowClientOptions; +import io.temporal.envconfig.ClientConfigProfile; +import io.temporal.envconfig.LoadClientConfigProfileOptions; +import io.temporal.serviceclient.WorkflowServiceStubs; +import io.temporal.serviceclient.WorkflowServiceStubsOptions; +import java.nio.file.Paths; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This sample demonstrates loading the default environment configuration profile from a TOML file. + */ +public class LoadFromFile { + + private static final Logger logger = LoggerFactory.getLogger(LoadFromFile.class); + + public static void main(String[] args) { + try { + // For this sample to be self-contained, we explicitly provide the path to + // the config.toml file included in this directory. + // By default though, the config.toml file will be loaded from + // ~/.config/temporal/temporal.toml (or the equivalent standard config directory on your OS). + String configFilePath = + Paths.get(LoadFromFile.class.getResource("/config.toml").toURI()).toString(); + + logger.info("--- Loading 'default' profile from {} ---", configFilePath); + + // Load client profile from file. By default, this loads the "default" profile + // and applies any environment variable overrides. + ClientConfigProfile profile = + ClientConfigProfile.load( + LoadClientConfigProfileOptions.newBuilder() + .setConfigFilePath(configFilePath) + .build()); + + // Convert profile to client options (equivalent to Python's load_client_connect_config) + WorkflowServiceStubsOptions serviceStubsOptions = profile.toWorkflowServiceStubsOptions(); + WorkflowClientOptions clientOptions = profile.toWorkflowClientOptions(); + + logger.info("Loaded 'default' profile from {}", configFilePath); + logger.info(" Address: {}", serviceStubsOptions.getTarget()); + logger.info(" Namespace: {}", clientOptions.getNamespace()); + if (serviceStubsOptions.getHeaders() != null + && !serviceStubsOptions.getHeaders().keys().isEmpty()) { + logger.info(" gRPC Metadata keys: {}", serviceStubsOptions.getHeaders().keys()); + } + + logger.info("\nAttempting to connect to client..."); + + try { + // Create the workflow client using the loaded configuration + WorkflowClient client = + WorkflowClient.newInstance( + WorkflowServiceStubs.newServiceStubs(serviceStubsOptions), clientOptions); + + // Test the connection by getting system info + var systemInfo = + client + .getWorkflowServiceStubs() + .blockingStub() + .getSystemInfo( + io.temporal.api.workflowservice.v1.GetSystemInfoRequest.getDefaultInstance()); + + logger.info("βœ… Client connected successfully!"); + logger.info(" Server version: {}", systemInfo.getServerVersion()); + + } catch (Exception e) { + logger.error("❌ Failed to connect: {}", e.getMessage()); + } + + } catch (Exception e) { + logger.error("Failed to load configuration: {}", e.getMessage(), e); + System.exit(1); + } + } +} diff --git a/core/src/main/java/io/temporal/samples/envconfig/LoadProfile.java b/core/src/main/java/io/temporal/samples/envconfig/LoadProfile.java new file mode 100644 index 000000000..9d05b21f3 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/envconfig/LoadProfile.java @@ -0,0 +1,87 @@ +package io.temporal.samples.envconfig; + +import io.temporal.client.WorkflowClient; +import io.temporal.client.WorkflowClientOptions; +import io.temporal.envconfig.ClientConfigProfile; +import io.temporal.envconfig.LoadClientConfigProfileOptions; +import io.temporal.serviceclient.WorkflowServiceStubs; +import io.temporal.serviceclient.WorkflowServiceStubsOptions; +import java.nio.file.Paths; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This sample demonstrates loading a specific profile from a TOML configuration file with + * programmatic overrides. + */ +public class LoadProfile { + + private static final Logger logger = LoggerFactory.getLogger(LoadProfile.class); + + public static void main(String[] args) { + String profileName = "staging"; + + try { + // For this sample to be self-contained, we explicitly provide the path to + // the config.toml file included in this directory. + String configFilePath = + Paths.get(LoadProfile.class.getResource("/config.toml").toURI()).toString(); + + logger.info("--- Loading '{}' profile from {} ---", profileName, configFilePath); + + // Load specific profile from file with environment variable overrides + ClientConfigProfile profile = + ClientConfigProfile.load( + LoadClientConfigProfileOptions.newBuilder() + .setConfigFilePath(configFilePath) + .setConfigFileProfile(profileName) + .build()); + + // Demonstrate programmatic override - fix the incorrect address from staging profile + logger.info("\n--- Applying programmatic override ---"); + ClientConfigProfile.Builder profileBuilder = profile.toBuilder(); + profileBuilder.setAddress("localhost:7233"); // Override the incorrect address + profile = profileBuilder.build(); + logger.info(" Overridden address to: {}", profile.getAddress()); + + // Convert profile to client options (equivalent to Python's load_client_connect_config) + WorkflowServiceStubsOptions serviceStubsOptions = profile.toWorkflowServiceStubsOptions(); + WorkflowClientOptions clientOptions = profile.toWorkflowClientOptions(); + + logger.info("Loaded '{}' profile from {}", profileName, configFilePath); + logger.info(" Address: {}", serviceStubsOptions.getTarget()); + logger.info(" Namespace: {}", clientOptions.getNamespace()); + if (serviceStubsOptions.getHeaders() != null + && !serviceStubsOptions.getHeaders().keys().isEmpty()) { + logger.info(" gRPC Metadata keys: {}", serviceStubsOptions.getHeaders().keys()); + } + + logger.info("\nAttempting to connect to client..."); + + try { + // Create the workflow client using the loaded configuration + WorkflowClient client = + WorkflowClient.newInstance( + WorkflowServiceStubs.newServiceStubs(serviceStubsOptions), clientOptions); + + // Test the connection by getting system info + var systemInfo = + client + .getWorkflowServiceStubs() + .blockingStub() + .getSystemInfo( + io.temporal.api.workflowservice.v1.GetSystemInfoRequest.getDefaultInstance()); + + logger.info("βœ… Client connected successfully!"); + logger.info(" Server version: {}", systemInfo.getServerVersion()); + + } catch (Exception e) { + logger.error("❌ Failed to connect: {}", e.getMessage()); + } + + } catch (Exception e) { + logger.error("Failed to load configuration: {}", e.getMessage(), e); + System.exit(1); + } + } +} diff --git a/core/src/main/java/io/temporal/samples/envconfig/README.md b/core/src/main/java/io/temporal/samples/envconfig/README.md new file mode 100644 index 000000000..0cb5df5c1 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/envconfig/README.md @@ -0,0 +1,18 @@ +# Environment Configuration Sample + +This sample demonstrates how to configure a Temporal client using TOML configuration files. This allows you to manage connection settings across different environments without hardcoding them. + +The `config.toml` file defines three profiles: +- `[profile.default]`: Local development configuration +- `[profile.staging]`: Configuration with incorrect address to demonstrate overrides +- `[profile.prod]`: Example production configuration (not runnable) + +**Load from file (default profile):** +```bash +./gradlew -q execute -PmainClass=io.temporal.samples.envconfig.LoadFromFile +``` + +**Load specific profile with overrides:** +```bash +./gradlew -q execute -PmainClass=io.temporal.samples.envconfig.LoadProfile +``` \ No newline at end of file diff --git a/core/src/main/resources/config.toml b/core/src/main/resources/config.toml new file mode 100644 index 000000000..81f07f786 --- /dev/null +++ b/core/src/main/resources/config.toml @@ -0,0 +1,40 @@ +# This is a sample configuration file for demonstrating Temporal's environment +# configuration feature. It defines multiple profiles for different environments, +# such as local development, production, and staging. + +# Default profile for local development +[profile.default] +address = "localhost:7233" +namespace = "default" + +# Optional: Add custom gRPC headers +[profile.default.grpc_meta] +my-custom-header = "development-value" +trace-id = "dev-trace-123" + +# Staging profile with inline certificate data +[profile.staging] +address = "localhost:9999" +namespace = "staging" + +# An example production profile for Temporal Cloud +[profile.prod] +address = "your-namespace.a1b2c.tmprl.cloud:7233" +namespace = "your-namespace" +# Replace with your actual Temporal Cloud API key +api_key = "your-api-key-here" + +# TLS configuration for production +[profile.prod.tls] +# TLS is auto-enabled when an API key is present, but you can configure it +# explicitly. +# disabled = false + +# Use certificate files for mTLS. Replace with actual paths. +client_cert_path = "/etc/temporal/certs/client.pem" +client_key_path = "/etc/temporal/certs/client.key" + +# Custom headers for production +[profile.prod.grpc_meta] +environment = "production" +service-version = "v1.2.3" \ No newline at end of file From d3b90e6951aa62efd0259b427d70e91e25bef39f Mon Sep 17 00:00:00 2001 From: Thomas Hardy Date: Thu, 4 Dec 2025 11:25:35 -0800 Subject: [PATCH 06/14] Update samples to use env config (#756) * Update samples to use env config * fix envconfig import for springboot * update javaSDKVersion to 1.32.1 --- build.gradle | 2 +- .../temporal/samples/apikey/ApiKeyWorker.java | 19 ++++++++++-- .../io/temporal/samples/apikey/Starter.java | 19 ++++++++++-- .../temporal/samples/asyncchild/Starter.java | 31 ++++++++++++++----- .../samples/asyncuntypedchild/Starter.java | 15 +++++++-- .../samples/autoheartbeat/Starter.java | 15 +++++++-- .../HeartbeatingActivityBatchStarter.java | 16 ++++++++-- .../HeartbeatingActivityBatchWorker.java | 15 +++++++-- .../batch/iterator/IteratorBatchStarter.java | 16 ++++++++-- .../batch/iterator/IteratorBatchWorker.java | 15 +++++++-- .../SlidingWindowBatchStarter.java | 16 ++++++++-- .../SlidingWindowBatchWorker.java | 15 +++++++-- .../bookingsaga/TripBookingClient.java | 17 ++++++++-- .../bookingsaga/TripBookingWorker.java | 17 ++++++++-- .../bookingsyncsaga/TripBookingClient.java | 17 ++++++++-- .../bookingsyncsaga/TripBookingWorker.java | 15 +++++++-- .../common/QueryWorkflowExecution.java | 15 +++++++-- .../countinterceptor/InterceptorStarter.java | 13 +++++++- .../customannotation/CustomAnnotation.java | 15 +++++++-- .../CustomChangeVersionStarter.java | 15 +++++++-- .../java/io/temporal/samples/dsl/Starter.java | 19 ++++++++---- .../earlyreturn/EarlyReturnClient.java | 15 +++++++-- .../samples/encodefailures/Starter.java | 13 +++++++- .../EncryptedPayloadsActivity.java | 13 +++++++- .../RunMyWorkflows.java | 15 +++++++-- .../fileprocessing/FileProcessingStarter.java | 17 ++++++++-- .../fileprocessing/FileProcessingWorker.java | 17 ++++++++-- .../samples/getresultsasync/Worker.java | 23 ++++++++++++-- .../samples/hello/HelloAccumulator.java | 19 +++++++----- .../temporal/samples/hello/HelloActivity.java | 15 +++++++-- .../hello/HelloActivityExclusiveChoice.java | 15 +++++++-- .../samples/hello/HelloActivityRetry.java | 18 +++++++---- .../io/temporal/samples/hello/HelloAsync.java | 19 ++++++++---- .../hello/HelloAsyncActivityCompletion.java | 20 +++++++----- .../samples/hello/HelloAsyncLambda.java | 19 ++++++++---- .../io/temporal/samples/hello/HelloAwait.java | 19 ++++++++---- .../samples/hello/HelloCancellationScope.java | 19 ++++++++---- .../HelloCancellationScopeWithTimer.java | 15 +++++++-- .../io/temporal/samples/hello/HelloChild.java | 19 ++++++++---- .../io/temporal/samples/hello/HelloCron.java | 19 ++++++++---- .../samples/hello/HelloDelayedStart.java | 19 ++++++++---- .../hello/HelloDetachedCancellationScope.java | 15 +++++++-- .../temporal/samples/hello/HelloDynamic.java | 20 +++++++----- .../hello/HelloEagerWorkflowStart.java | 19 ++++++++---- .../samples/hello/HelloException.java | 18 +++++++---- .../samples/hello/HelloLocalActivity.java | 17 ++++++++-- .../samples/hello/HelloParallelActivity.java | 19 ++++++++---- .../temporal/samples/hello/HelloPeriodic.java | 19 ++++++++---- .../hello/HelloPolymorphicActivity.java | 19 ++++++++---- .../io/temporal/samples/hello/HelloQuery.java | 19 ++++++++---- .../io/temporal/samples/hello/HelloSaga.java | 19 ++++++++---- .../samples/hello/HelloSchedules.java | 19 ++++++++---- .../samples/hello/HelloSearchAttributes.java | 19 ++++++++---- .../samples/hello/HelloSideEffect.java | 20 +++++++----- .../temporal/samples/hello/HelloSignal.java | 19 ++++++++---- .../HelloSignalWithStartAndWorkflowInit.java | 15 +++++++-- .../samples/hello/HelloSignalWithTimer.java | 15 +++++++-- .../hello/HelloTypedSearchAttributes.java | 19 ++++++++---- .../temporal/samples/hello/HelloUpdate.java | 19 ++++++++---- .../samples/hello/HelloWorkflowTimer.java | 17 ++++++++-- .../awsencryptionsdk/EncryptedPayloads.java | 13 +++++++- .../samples/listworkflows/Starter.java | 20 ++++++++++-- .../samples/metrics/MetricsStarter.java | 18 +++++++++-- .../samples/metrics/MetricsWorker.java | 18 +++++++++-- .../moneybatch/AccountActivityWorker.java | 15 +++++++-- .../moneybatch/AccountTransferWorker.java | 15 +++++++-- .../samples/moneybatch/TransferRequester.java | 16 ++++++++-- .../moneytransfer/AccountActivityWorker.java | 17 ++++++++-- .../moneytransfer/AccountTransferWorker.java | 17 ++++++++-- .../moneytransfer/TransferRequester.java | 16 ++++++++-- .../samples/packetdelivery/Starter.java | 15 +++++++-- .../payloadconverter/cloudevents/Starter.java | 13 +++++++- .../payloadconverter/crypto/Starter.java | 13 +++++++- .../samples/peractivityoptions/Starter.java | 18 +++++++++-- .../frequent/FrequentPollingStarter.java | 20 ++++++++++-- .../infrequent/InfrequentPollingStarter.java | 20 ++++++++++-- ...nfrequentPollingWithRetryAfterStarter.java | 20 ++++++++++-- .../PeriodicPollingStarter.java | 20 ++++++++++-- .../FailureRequester.java | 15 +++++++-- .../MyWorkflowWorker.java | 15 +++++++-- .../QueryRequester.java | 15 +++++++-- .../RetryRequester.java | 15 +++++++-- .../ClusterManagerWorkflowStarter.java | 15 +++++++-- .../ClusterManagerWorkflowWorker.java | 15 +++++++-- .../samples/sleepfordays/Starter.java | 17 +++++++++- .../temporal/samples/sleepfordays/Worker.java | 18 +++++++++-- .../samples/terminateworkflow/Starter.java | 27 +++++++++++----- .../io/temporal/samples/tracing/Starter.java | 18 +++++++++-- .../samples/tracing/TracingWorker.java | 16 ++++++++-- .../DynamicSleepWorkflowStarter.java | 15 +++++++-- .../DynamicSleepWorkflowWorker.java | 15 +++++++-- .../updatabletimer/WakeUpTimeUpdater.java | 15 +++++++-- .../samples/workerversioning/Starter.java | 16 ++++++++-- .../samples/workerversioning/WorkerV1.java | 15 +++++++-- .../samples/workerversioning/WorkerV1_1.java | 15 +++++++-- .../samples/workerversioning/WorkerV2.java | 15 +++++++-- springboot/build.gradle | 3 ++ 97 files changed, 1313 insertions(+), 317 deletions(-) diff --git a/build.gradle b/build.gradle index 0377d028e..abb6487ba 100644 --- a/build.gradle +++ b/build.gradle @@ -26,7 +26,7 @@ subprojects { ext { otelVersion = '1.30.1' otelVersionAlpha = "${otelVersion}-alpha" - javaSDKVersion = '1.32.0' + javaSDKVersion = '1.32.1' camelVersion = '3.22.1' jarVersion = '1.0.0' } diff --git a/core/src/main/java/io/temporal/samples/apikey/ApiKeyWorker.java b/core/src/main/java/io/temporal/samples/apikey/ApiKeyWorker.java index 7425b88d6..2c4a326d4 100644 --- a/core/src/main/java/io/temporal/samples/apikey/ApiKeyWorker.java +++ b/core/src/main/java/io/temporal/samples/apikey/ApiKeyWorker.java @@ -2,15 +2,25 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowClientOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.serviceclient.WorkflowServiceStubsOptions; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; public class ApiKeyWorker { static final String TASK_QUEUE = "MyTaskQueue"; public static void main(String[] args) throws Exception { + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + // For temporal cloud this would be ${cloud-region}.{cloud}.api.temporal.io:7233 // Example us-east-1.aws.api.temporal.io:7233 String targetEndpoint = System.getenv("TEMPORAL_ENDPOINT"); @@ -24,10 +34,10 @@ public static void main(String[] args) throws Exception { "TEMPORAL_ENDPOINT, TEMPORAL_NAMESPACE, and TEMPORAL_API_KEY environment variables must be set"); } - // Create API Key enabled client + // Create API Key enabled client with environment config as base WorkflowServiceStubs service = WorkflowServiceStubs.newServiceStubs( - WorkflowServiceStubsOptions.newBuilder() + WorkflowServiceStubsOptions.newBuilder(profile.toWorkflowServiceStubsOptions()) .setTarget(targetEndpoint) .setEnableHttps(true) .addApiKey(() -> apiKey) @@ -36,7 +46,10 @@ public static void main(String[] args) throws Exception { // Now setup and start workflow worker WorkflowClient client = WorkflowClient.newInstance( - service, WorkflowClientOptions.newBuilder().setNamespace(namespace).build()); + service, + WorkflowClientOptions.newBuilder(profile.toWorkflowClientOptions()) + .setNamespace(namespace) + .build()); // worker factory that can be used to create workers for specific task queues WorkerFactory factory = WorkerFactory.newInstance(client); diff --git a/core/src/main/java/io/temporal/samples/apikey/Starter.java b/core/src/main/java/io/temporal/samples/apikey/Starter.java index 60afe7c21..ac0fbce8c 100644 --- a/core/src/main/java/io/temporal/samples/apikey/Starter.java +++ b/core/src/main/java/io/temporal/samples/apikey/Starter.java @@ -3,10 +3,12 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowClientOptions; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.serviceclient.WorkflowServiceStubsOptions; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; public class Starter { @@ -14,6 +16,14 @@ public class Starter { static final String WORKFLOW_ID = "HelloAPIKeyWorkflow"; public static void main(String[] args) throws Exception { + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + // For temporal cloud this would be ${cloud-region}.{cloud}.api.temporal.io:7233 // Example us-east-1.aws.api.temporal.io:7233 String targetEndpoint = System.getenv("TEMPORAL_ENDPOINT"); @@ -27,10 +37,10 @@ public static void main(String[] args) throws Exception { "TEMPORAL_ENDPOINT, TEMPORAL_NAMESPACE, and TEMPORAL_API_KEY environment variables must be set"); } - // Create API Key enabled client + // Create API Key enabled client with environment config as base WorkflowServiceStubs service = WorkflowServiceStubs.newServiceStubs( - WorkflowServiceStubsOptions.newBuilder() + WorkflowServiceStubsOptions.newBuilder(profile.toWorkflowServiceStubsOptions()) .setTarget(targetEndpoint) .setEnableHttps(true) .addApiKey(() -> apiKey) @@ -38,7 +48,10 @@ public static void main(String[] args) throws Exception { WorkflowClient client = WorkflowClient.newInstance( - service, WorkflowClientOptions.newBuilder().setNamespace(namespace).build()); + service, + WorkflowClientOptions.newBuilder(profile.toWorkflowClientOptions()) + .setNamespace(namespace) + .build()); WorkerFactory factory = WorkerFactory.newInstance(client); diff --git a/core/src/main/java/io/temporal/samples/asyncchild/Starter.java b/core/src/main/java/io/temporal/samples/asyncchild/Starter.java index b02f0dc4c..339bd94fd 100644 --- a/core/src/main/java/io/temporal/samples/asyncchild/Starter.java +++ b/core/src/main/java/io/temporal/samples/asyncchild/Starter.java @@ -6,20 +6,32 @@ import io.temporal.api.workflowservice.v1.DescribeWorkflowExecutionResponse; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; import java.util.concurrent.TimeUnit; public class Starter { public static final String TASK_QUEUE = "asyncChildTaskQueue"; - private static final WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - private static final WorkflowClient client = WorkflowClient.newInstance(service); - private static final WorkerFactory factory = WorkerFactory.newInstance(client); public static void main(String[] args) { - createWorker(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); + WorkerFactory factory = WorkerFactory.newInstance(client); + + createWorker(factory); WorkflowOptions parentWorkflowOptions = WorkflowOptions.newBuilder() @@ -33,25 +45,28 @@ public static void main(String[] args) { WorkflowExecution childWorkflowExecution = parentWorkflowStub.executeParent(); // Get the child workflow execution status (after parent completed) - System.out.println("Child execution status: " + getStatusAsString(childWorkflowExecution)); + System.out.println( + "Child execution status: " + getStatusAsString(childWorkflowExecution, client, service)); // Wait for child workflow to complete sleep(4); // Check the status of the child workflow again - System.out.println("Child execution status: " + getStatusAsString(childWorkflowExecution)); + System.out.println( + "Child execution status: " + getStatusAsString(childWorkflowExecution, client, service)); System.exit(0); } - private static void createWorker() { + private static void createWorker(WorkerFactory factory) { Worker worker = factory.newWorker(TASK_QUEUE); worker.registerWorkflowImplementationTypes(ParentWorkflowImpl.class, ChildWorkflowImpl.class); factory.start(); } - private static String getStatusAsString(WorkflowExecution execution) { + private static String getStatusAsString( + WorkflowExecution execution, WorkflowClient client, WorkflowServiceStubs service) { DescribeWorkflowExecutionRequest describeWorkflowExecutionRequest = DescribeWorkflowExecutionRequest.newBuilder() .setNamespace(client.getOptions().getNamespace()) diff --git a/core/src/main/java/io/temporal/samples/asyncuntypedchild/Starter.java b/core/src/main/java/io/temporal/samples/asyncuntypedchild/Starter.java index 6cf9da20f..885a0c05c 100644 --- a/core/src/main/java/io/temporal/samples/asyncuntypedchild/Starter.java +++ b/core/src/main/java/io/temporal/samples/asyncuntypedchild/Starter.java @@ -2,9 +2,11 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; /** * Sample Temporal Workflow Definition that demonstrates the execution of a Child Workflow. Child @@ -24,12 +26,21 @@ public class Starter { public static void main(String[] args) { // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); /* * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. */ - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/autoheartbeat/Starter.java b/core/src/main/java/io/temporal/samples/autoheartbeat/Starter.java index 67bb97ec3..ae438cc41 100644 --- a/core/src/main/java/io/temporal/samples/autoheartbeat/Starter.java +++ b/core/src/main/java/io/temporal/samples/autoheartbeat/Starter.java @@ -22,6 +22,7 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; import io.temporal.client.WorkflowStub; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.failure.CanceledFailure; import io.temporal.samples.autoheartbeat.activities.AutoActivitiesImpl; import io.temporal.samples.autoheartbeat.interceptor.AutoHeartbeatWorkerInterceptor; @@ -31,14 +32,24 @@ import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.worker.WorkerFactoryOptions; +import java.io.IOException; public class Starter { static final String TASK_QUEUE = "AutoheartbeatTaskQueue"; static final String WORKFLOW_ID = "AutoHeartbeatWorkflow"; public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); // Configure our auto heartbeat workflow interceptor which will apply // AutoHeartbeaterUtil to each activity workflow schedules which has a heartbeat diff --git a/core/src/main/java/io/temporal/samples/batch/heartbeatingactivity/HeartbeatingActivityBatchStarter.java b/core/src/main/java/io/temporal/samples/batch/heartbeatingactivity/HeartbeatingActivityBatchStarter.java index 89bb5652c..90dcb7c10 100644 --- a/core/src/main/java/io/temporal/samples/batch/heartbeatingactivity/HeartbeatingActivityBatchStarter.java +++ b/core/src/main/java/io/temporal/samples/batch/heartbeatingactivity/HeartbeatingActivityBatchStarter.java @@ -5,14 +5,26 @@ import io.temporal.api.common.v1.WorkflowExecution; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; +import java.io.IOException; /** Starts a single execution of HeartbeatingActivityBatchWorkflow. */ public class HeartbeatingActivityBatchStarter { public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient workflowClient = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient workflowClient = + WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkflowOptions options = WorkflowOptions.newBuilder().setTaskQueue(TASK_QUEUE).build(); HeartbeatingActivityBatchWorkflow batchWorkflow = workflowClient.newWorkflowStub(HeartbeatingActivityBatchWorkflow.class, options); diff --git a/core/src/main/java/io/temporal/samples/batch/heartbeatingactivity/HeartbeatingActivityBatchWorker.java b/core/src/main/java/io/temporal/samples/batch/heartbeatingactivity/HeartbeatingActivityBatchWorker.java index 9d2d7b4e1..cd63bacf5 100644 --- a/core/src/main/java/io/temporal/samples/batch/heartbeatingactivity/HeartbeatingActivityBatchWorker.java +++ b/core/src/main/java/io/temporal/samples/batch/heartbeatingactivity/HeartbeatingActivityBatchWorker.java @@ -1,9 +1,11 @@ package io.temporal.samples.batch.heartbeatingactivity; import io.temporal.client.WorkflowClient; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; /** * A worker process that hosts implementations of HeartbeatingActivityBatchWorkflow and @@ -14,8 +16,17 @@ public final class HeartbeatingActivityBatchWorker { static final String TASK_QUEUE = "HeartbeatingActivityBatch"; public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkerFactory factory = WorkerFactory.newInstance(client); Worker worker = factory.newWorker(TASK_QUEUE); diff --git a/core/src/main/java/io/temporal/samples/batch/iterator/IteratorBatchStarter.java b/core/src/main/java/io/temporal/samples/batch/iterator/IteratorBatchStarter.java index c89fc590c..fa43c467f 100644 --- a/core/src/main/java/io/temporal/samples/batch/iterator/IteratorBatchStarter.java +++ b/core/src/main/java/io/temporal/samples/batch/iterator/IteratorBatchStarter.java @@ -5,14 +5,26 @@ import io.temporal.api.common.v1.WorkflowExecution; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; +import java.io.IOException; /** Starts a single execution of IteratorBatchWorkflow. */ public class IteratorBatchStarter { public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient workflowClient = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient workflowClient = + WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkflowOptions options = WorkflowOptions.newBuilder().setTaskQueue(TASK_QUEUE).build(); IteratorBatchWorkflow batchWorkflow = workflowClient.newWorkflowStub(IteratorBatchWorkflow.class, options); diff --git a/core/src/main/java/io/temporal/samples/batch/iterator/IteratorBatchWorker.java b/core/src/main/java/io/temporal/samples/batch/iterator/IteratorBatchWorker.java index 88b8eacb7..adc023d7b 100644 --- a/core/src/main/java/io/temporal/samples/batch/iterator/IteratorBatchWorker.java +++ b/core/src/main/java/io/temporal/samples/batch/iterator/IteratorBatchWorker.java @@ -1,9 +1,11 @@ package io.temporal.samples.batch.iterator; import io.temporal.client.WorkflowClient; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; /** * A worker process that hosts implementations of IteratorBatchWorkflow and RecordProcessorWorkflow @@ -14,8 +16,17 @@ public final class IteratorBatchWorker { static final String TASK_QUEUE = "IteratorBatch"; public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkerFactory factory = WorkerFactory.newInstance(client); Worker worker = factory.newWorker(TASK_QUEUE); diff --git a/core/src/main/java/io/temporal/samples/batch/slidingwindow/SlidingWindowBatchStarter.java b/core/src/main/java/io/temporal/samples/batch/slidingwindow/SlidingWindowBatchStarter.java index f4d689f4a..e3a6b062d 100644 --- a/core/src/main/java/io/temporal/samples/batch/slidingwindow/SlidingWindowBatchStarter.java +++ b/core/src/main/java/io/temporal/samples/batch/slidingwindow/SlidingWindowBatchStarter.java @@ -4,14 +4,26 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; +import java.io.IOException; public class SlidingWindowBatchStarter { @SuppressWarnings("CatchAndPrintStackTrace") public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient workflowClient = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient workflowClient = + WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkflowOptions options = WorkflowOptions.newBuilder().setTaskQueue(TASK_QUEUE).build(); BatchWorkflow batchWorkflow = workflowClient.newWorkflowStub(BatchWorkflow.class, options); WorkflowClient.start(batchWorkflow::processBatch, 10, 25, 3); diff --git a/core/src/main/java/io/temporal/samples/batch/slidingwindow/SlidingWindowBatchWorker.java b/core/src/main/java/io/temporal/samples/batch/slidingwindow/SlidingWindowBatchWorker.java index 32dd8e09c..20caa5ead 100644 --- a/core/src/main/java/io/temporal/samples/batch/slidingwindow/SlidingWindowBatchWorker.java +++ b/core/src/main/java/io/temporal/samples/batch/slidingwindow/SlidingWindowBatchWorker.java @@ -1,9 +1,11 @@ package io.temporal.samples.batch.slidingwindow; import io.temporal.client.WorkflowClient; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; /** Hosts sliding window batch sample workflow and activity implementations. */ public final class SlidingWindowBatchWorker { @@ -11,8 +13,17 @@ public final class SlidingWindowBatchWorker { static final String TASK_QUEUE = "SlidingWindow"; public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkerFactory factory = WorkerFactory.newInstance(client); Worker worker = factory.newWorker(TASK_QUEUE); diff --git a/core/src/main/java/io/temporal/samples/bookingsaga/TripBookingClient.java b/core/src/main/java/io/temporal/samples/bookingsaga/TripBookingClient.java index b791065da..cb7d1e594 100644 --- a/core/src/main/java/io/temporal/samples/bookingsaga/TripBookingClient.java +++ b/core/src/main/java/io/temporal/samples/bookingsaga/TripBookingClient.java @@ -3,17 +3,28 @@ import com.google.common.base.Throwables; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; +import java.io.IOException; public class TripBookingClient { static final String TASK_QUEUE = "TripBooking"; public static void main(String[] args) { - // gRPC stubs wrapper that talks to the local docker instance of temporal service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + // gRPC stubs wrapper that talks to the temporal service. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); // client that can be used to start and signal workflows - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkflowOptions options = WorkflowOptions.newBuilder().setTaskQueue(TASK_QUEUE).setWorkflowId("Booking1").build(); diff --git a/core/src/main/java/io/temporal/samples/bookingsaga/TripBookingWorker.java b/core/src/main/java/io/temporal/samples/bookingsaga/TripBookingWorker.java index b538e0942..6c0fb87b2 100644 --- a/core/src/main/java/io/temporal/samples/bookingsaga/TripBookingWorker.java +++ b/core/src/main/java/io/temporal/samples/bookingsaga/TripBookingWorker.java @@ -1,18 +1,29 @@ package io.temporal.samples.bookingsaga; import io.temporal.client.WorkflowClient; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; public class TripBookingWorker { @SuppressWarnings("CatchAndPrintStackTrace") public static void main(String[] args) { - // gRPC stubs wrapper that talks to the local docker instance of temporal service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + // gRPC stubs wrapper that talks to the temporal service. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); // client that can be used to start and signal workflows - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); // worker factory that can be used to create workers for specific task queues WorkerFactory factory = WorkerFactory.newInstance(client); diff --git a/core/src/main/java/io/temporal/samples/bookingsyncsaga/TripBookingClient.java b/core/src/main/java/io/temporal/samples/bookingsyncsaga/TripBookingClient.java index cebbc93b8..74aa32b86 100644 --- a/core/src/main/java/io/temporal/samples/bookingsyncsaga/TripBookingClient.java +++ b/core/src/main/java/io/temporal/samples/bookingsyncsaga/TripBookingClient.java @@ -3,17 +3,28 @@ import com.google.common.base.Throwables; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; +import java.io.IOException; public class TripBookingClient { static final String TASK_QUEUE = "TripBookingSync"; public static void main(String[] args) { - // gRPC stubs wrapper that talks to the local docker instance of temporal service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + // gRPC stubs wrapper that talks to the temporal service. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); // client that can be used to start and signal workflows - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkflowOptions options = WorkflowOptions.newBuilder().setTaskQueue(TASK_QUEUE).setWorkflowId("Booking1").build(); diff --git a/core/src/main/java/io/temporal/samples/bookingsyncsaga/TripBookingWorker.java b/core/src/main/java/io/temporal/samples/bookingsyncsaga/TripBookingWorker.java index 151bd62ae..c70dc9481 100644 --- a/core/src/main/java/io/temporal/samples/bookingsyncsaga/TripBookingWorker.java +++ b/core/src/main/java/io/temporal/samples/bookingsyncsaga/TripBookingWorker.java @@ -1,18 +1,29 @@ package io.temporal.samples.bookingsyncsaga; import io.temporal.client.WorkflowClient; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; public class TripBookingWorker { @SuppressWarnings("CatchAndPrintStackTrace") public static void main(String[] args) { // gRPC stubs wrapper that talks to the local docker instance of temporal service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); // client that can be used to start and signal workflows - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); // worker factory that can be used to create workers for specific task queues WorkerFactory factory = WorkerFactory.newInstance(client); diff --git a/core/src/main/java/io/temporal/samples/common/QueryWorkflowExecution.java b/core/src/main/java/io/temporal/samples/common/QueryWorkflowExecution.java index 9be315a8a..9f9cbe797 100644 --- a/core/src/main/java/io/temporal/samples/common/QueryWorkflowExecution.java +++ b/core/src/main/java/io/temporal/samples/common/QueryWorkflowExecution.java @@ -3,7 +3,9 @@ import io.temporal.api.common.v1.WorkflowExecution; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowStub; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; +import java.io.IOException; import java.util.Optional; /** @@ -27,9 +29,18 @@ public static void main(String[] args) { String runId = args.length == 3 ? args[2] : ""; // gRPC stubs wrapper that talks to the local docker instance of temporal service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkflowExecution workflowExecution = WorkflowExecution.newBuilder().setWorkflowId(workflowId).setRunId(runId).build(); diff --git a/core/src/main/java/io/temporal/samples/countinterceptor/InterceptorStarter.java b/core/src/main/java/io/temporal/samples/countinterceptor/InterceptorStarter.java index bf8ddd793..30c73c14f 100644 --- a/core/src/main/java/io/temporal/samples/countinterceptor/InterceptorStarter.java +++ b/core/src/main/java/io/temporal/samples/countinterceptor/InterceptorStarter.java @@ -5,6 +5,7 @@ import io.temporal.client.WorkflowOptions; import io.temporal.client.WorkflowStub; import io.temporal.common.interceptors.WorkflowClientInterceptor; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.samples.countinterceptor.activities.MyActivitiesImpl; import io.temporal.samples.countinterceptor.workflow.MyChildWorkflowImpl; import io.temporal.samples.countinterceptor.workflow.MyWorkflow; @@ -13,6 +14,7 @@ import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.worker.WorkerFactoryOptions; +import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,7 +31,16 @@ public static void main(String[] args) { final ClientCounter clientCounter = new ClientCounter(); final WorkflowClientInterceptor clientInterceptor = new SimpleClientInterceptor(clientCounter); - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); WorkflowClient client = WorkflowClient.newInstance( service, WorkflowClientOptions.newBuilder().setInterceptors(clientInterceptor).build()); diff --git a/core/src/main/java/io/temporal/samples/customannotation/CustomAnnotation.java b/core/src/main/java/io/temporal/samples/customannotation/CustomAnnotation.java index 9f9fc667d..db6df4229 100644 --- a/core/src/main/java/io/temporal/samples/customannotation/CustomAnnotation.java +++ b/core/src/main/java/io/temporal/samples/customannotation/CustomAnnotation.java @@ -24,6 +24,7 @@ import io.temporal.activity.ActivityOptions; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; @@ -31,6 +32,7 @@ import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; public class CustomAnnotation { @@ -132,12 +134,21 @@ public synchronized String composeGreeting(String greeting, String name) { public static void main(String[] args) { // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); /* * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. */ - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/customchangeversion/CustomChangeVersionStarter.java b/core/src/main/java/io/temporal/samples/customchangeversion/CustomChangeVersionStarter.java index 82921b8dc..3bd8497b7 100644 --- a/core/src/main/java/io/temporal/samples/customchangeversion/CustomChangeVersionStarter.java +++ b/core/src/main/java/io/temporal/samples/customchangeversion/CustomChangeVersionStarter.java @@ -8,22 +8,33 @@ import io.temporal.client.WorkflowServiceException; import io.temporal.common.SearchAttributeKey; import io.temporal.common.SearchAttributes; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.OperatorServiceStubs; import io.temporal.serviceclient.OperatorServiceStubsOptions; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; import java.util.Collections; public class CustomChangeVersionStarter { private static SearchAttributeKey CUSTOM_CHANGE_VERSION = SearchAttributeKey.forKeyword("CustomChangeVersion"); - private static final WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - private static final WorkflowClient client = WorkflowClient.newInstance(service); private static final String taskQueue = "customChangeVersionTaskQueue"; private static final String workflowId = "CustomChangeVersionWorkflow"; public static void main(String[] args) { + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkerFactory workerFactory = WorkerFactory.newInstance(client); Worker worker = workerFactory.newWorker(taskQueue); diff --git a/core/src/main/java/io/temporal/samples/dsl/Starter.java b/core/src/main/java/io/temporal/samples/dsl/Starter.java index e0336d659..257531048 100644 --- a/core/src/main/java/io/temporal/samples/dsl/Starter.java +++ b/core/src/main/java/io/temporal/samples/dsl/Starter.java @@ -3,22 +3,29 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.samples.dsl.model.Flow; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; public class Starter { - public static final WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - public static final WorkflowClient client = WorkflowClient.newInstance(service); - public static final WorkerFactory factory = WorkerFactory.newInstance(client); - public static void main(String[] args) { Flow flow = getFlowFromResource(); - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkerFactory factory = WorkerFactory.newInstance(client); Worker worker = factory.newWorker("dsl-task-queue"); worker.registerWorkflowImplementationTypes(DslWorkflowImpl.class); diff --git a/core/src/main/java/io/temporal/samples/earlyreturn/EarlyReturnClient.java b/core/src/main/java/io/temporal/samples/earlyreturn/EarlyReturnClient.java index 623efa310..3abd20a7c 100644 --- a/core/src/main/java/io/temporal/samples/earlyreturn/EarlyReturnClient.java +++ b/core/src/main/java/io/temporal/samples/earlyreturn/EarlyReturnClient.java @@ -2,7 +2,9 @@ import io.temporal.api.enums.v1.WorkflowIdConflictPolicy; import io.temporal.client.*; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; +import java.io.IOException; public class EarlyReturnClient { private static final String TASK_QUEUE = "EarlyReturnTaskQueue"; @@ -15,8 +17,17 @@ public static void main(String[] args) { // Set up the WorkflowClient public static WorkflowClient setupWorkflowClient() { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - return WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + return WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); } // Run workflow using 'updateWithStart' diff --git a/core/src/main/java/io/temporal/samples/encodefailures/Starter.java b/core/src/main/java/io/temporal/samples/encodefailures/Starter.java index 9e4e17fe0..f08766881 100644 --- a/core/src/main/java/io/temporal/samples/encodefailures/Starter.java +++ b/core/src/main/java/io/temporal/samples/encodefailures/Starter.java @@ -8,10 +8,12 @@ import io.temporal.client.WorkflowOptions; import io.temporal.common.converter.CodecDataConverter; import io.temporal.common.converter.DefaultDataConverter; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.worker.WorkflowImplementationOptions; +import java.io.IOException; import java.util.Collections; public class Starter { @@ -19,7 +21,16 @@ public class Starter { private static final String WORKFLOW_ID = "CustomerValidationWorkflow"; public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); // CodecDataConverter defines our data converter and codec // sets encodeFailureAttributes to true diff --git a/core/src/main/java/io/temporal/samples/encryptedpayloads/EncryptedPayloadsActivity.java b/core/src/main/java/io/temporal/samples/encryptedpayloads/EncryptedPayloadsActivity.java index 00636fb29..83f10d95c 100644 --- a/core/src/main/java/io/temporal/samples/encryptedpayloads/EncryptedPayloadsActivity.java +++ b/core/src/main/java/io/temporal/samples/encryptedpayloads/EncryptedPayloadsActivity.java @@ -8,12 +8,14 @@ import io.temporal.client.WorkflowOptions; import io.temporal.common.converter.CodecDataConverter; import io.temporal.common.converter.DefaultDataConverter; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; import java.util.Collections; @@ -68,7 +70,16 @@ public String composeGreeting(String greeting, String name) { public static void main(String[] args) { // gRPC stubs wrapper that talks to the local docker instance of temporal service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); // client that can be used to start and signal workflows WorkflowClient client = WorkflowClient.newInstance( diff --git a/core/src/main/java/io/temporal/samples/excludefrominterceptor/RunMyWorkflows.java b/core/src/main/java/io/temporal/samples/excludefrominterceptor/RunMyWorkflows.java index b4bd1e825..4efe7d1f6 100644 --- a/core/src/main/java/io/temporal/samples/excludefrominterceptor/RunMyWorkflows.java +++ b/core/src/main/java/io/temporal/samples/excludefrominterceptor/RunMyWorkflows.java @@ -3,6 +3,7 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; import io.temporal.client.WorkflowStub; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.samples.excludefrominterceptor.activities.ForInterceptorActivitiesImpl; import io.temporal.samples.excludefrominterceptor.activities.MyActivitiesImpl; import io.temporal.samples.excludefrominterceptor.interceptor.MyWorkerInterceptor; @@ -11,13 +12,23 @@ import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.worker.WorkerFactoryOptions; +import java.io.IOException; import java.util.Arrays; import java.util.concurrent.CompletableFuture; public class RunMyWorkflows { public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkerFactoryOptions wfo = WorkerFactoryOptions.newBuilder() diff --git a/core/src/main/java/io/temporal/samples/fileprocessing/FileProcessingStarter.java b/core/src/main/java/io/temporal/samples/fileprocessing/FileProcessingStarter.java index f2c1ee95a..5020bf519 100644 --- a/core/src/main/java/io/temporal/samples/fileprocessing/FileProcessingStarter.java +++ b/core/src/main/java/io/temporal/samples/fileprocessing/FileProcessingStarter.java @@ -4,17 +4,28 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; +import java.io.IOException; import java.net.URL; /** Starts a file processing sample workflow. */ public class FileProcessingStarter { public static void main(String[] args) throws Exception { - // gRPC stubs wrapper that talks to the local docker instance of temporal service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + // gRPC stubs wrapper that talks to the temporal service. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); // client that can be used to start and signal workflows - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); FileProcessingWorkflow workflow = client.newWorkflowStub( FileProcessingWorkflow.class, diff --git a/core/src/main/java/io/temporal/samples/fileprocessing/FileProcessingWorker.java b/core/src/main/java/io/temporal/samples/fileprocessing/FileProcessingWorker.java index b154a2c23..711ca7343 100644 --- a/core/src/main/java/io/temporal/samples/fileprocessing/FileProcessingWorker.java +++ b/core/src/main/java/io/temporal/samples/fileprocessing/FileProcessingWorker.java @@ -1,9 +1,11 @@ package io.temporal.samples.fileprocessing; import io.temporal.client.WorkflowClient; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; import java.lang.management.ManagementFactory; /** @@ -21,10 +23,19 @@ public static void main(String[] args) { String hostSpecifiTaskQueue = ManagementFactory.getRuntimeMXBean().getName(); - // gRPC stubs wrapper that talks to the local docker instance of temporal service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + // gRPC stubs wrapper that talks to the temporal service. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); // client that can be used to start and signal workflows - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); // worker factory that can be used to create workers for specific task queues WorkerFactory factory = WorkerFactory.newInstance(client); diff --git a/core/src/main/java/io/temporal/samples/getresultsasync/Worker.java b/core/src/main/java/io/temporal/samples/getresultsasync/Worker.java index d9bb276be..4a91026f8 100644 --- a/core/src/main/java/io/temporal/samples/getresultsasync/Worker.java +++ b/core/src/main/java/io/temporal/samples/getresultsasync/Worker.java @@ -1,13 +1,30 @@ package io.temporal.samples.getresultsasync; import io.temporal.client.WorkflowClient; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.WorkerFactory; +import java.io.IOException; public class Worker { - public static final WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - public static final WorkflowClient client = WorkflowClient.newInstance(service); - public static final WorkerFactory factory = WorkerFactory.newInstance(client); + public static final WorkflowServiceStubs service; + public static final WorkflowClient client; + public static final WorkerFactory factory; + + static { + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + service = WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); + factory = WorkerFactory.newInstance(client); + } + public static final String TASK_QUEUE_NAME = "asyncstartqueue"; public static void main(String[] args) { diff --git a/core/src/main/java/io/temporal/samples/hello/HelloAccumulator.java b/core/src/main/java/io/temporal/samples/hello/HelloAccumulator.java index 38ea8f097..2f8d67457 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloAccumulator.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloAccumulator.java @@ -11,6 +11,7 @@ import io.temporal.client.WorkflowNotFoundException; import io.temporal.client.WorkflowOptions; import io.temporal.client.WorkflowStub; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; @@ -18,6 +19,7 @@ import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.io.Serializable; import java.time.Duration; import java.util.ArrayDeque; @@ -293,14 +295,17 @@ public void exit() { */ public static void main(String[] args) throws Exception { - // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query - * Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); client.getWorkflowServiceStubs().healthCheck(); /* diff --git a/core/src/main/java/io/temporal/samples/hello/HelloActivity.java b/core/src/main/java/io/temporal/samples/hello/HelloActivity.java index 3c890d3ab..9b202e0c2 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloActivity.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloActivity.java @@ -5,12 +5,14 @@ import io.temporal.activity.ActivityOptions; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -105,13 +107,22 @@ public String composeGreeting(String greeting, String name) { */ public static void main(String[] args) { + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); /* * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. */ - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloActivityExclusiveChoice.java b/core/src/main/java/io/temporal/samples/hello/HelloActivityExclusiveChoice.java index 1da873e2c..3f2309993 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloActivityExclusiveChoice.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloActivityExclusiveChoice.java @@ -4,12 +4,14 @@ import io.temporal.activity.ActivityOptions; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; import java.util.HashMap; import java.util.Map; @@ -165,12 +167,21 @@ public static void main(String[] args) { * Define the workflow service. It is a gRPC stubs wrapper which talks to the docker instance of * our locally running Temporal service. */ - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); /* * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. */ - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloActivityRetry.java b/core/src/main/java/io/temporal/samples/hello/HelloActivityRetry.java index f7f01b3a3..4f78cfa2f 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloActivityRetry.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloActivityRetry.java @@ -5,12 +5,14 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; import io.temporal.common.RetryOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; /** Sample Temporal workflow that demonstrates workflow activity retries. */ @@ -140,13 +142,17 @@ public synchronized String composeGreeting(String greeting, String name) { */ public static void main(String[] args) { - // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloAsync.java b/core/src/main/java/io/temporal/samples/hello/HelloAsync.java index 7b068f7bf..25e8c3c5f 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloAsync.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloAsync.java @@ -4,6 +4,7 @@ import io.temporal.activity.ActivityOptions; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; @@ -12,6 +13,7 @@ import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; /** Sample Temporal Workflow Definition that demonstrates an asynchronous Activity Execution. */ @@ -110,13 +112,18 @@ public String composeGreeting(String greeting, String name) { */ public static void main(String[] args) { - // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Get a Workflow service stub. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloAsyncActivityCompletion.java b/core/src/main/java/io/temporal/samples/hello/HelloAsyncActivityCompletion.java index 87f9cbee7..f52072738 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloAsyncActivityCompletion.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloAsyncActivityCompletion.java @@ -4,12 +4,14 @@ import io.temporal.client.ActivityCompletionClient; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; @@ -143,14 +145,18 @@ private void composeGreetingAsync(byte[] taskToken, String greeting, String name */ public static void main(String[] args) throws ExecutionException, InterruptedException { - // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow - * Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Get a Workflow service stub. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloAsyncLambda.java b/core/src/main/java/io/temporal/samples/hello/HelloAsyncLambda.java index 4da2b6ee1..6b68d85cb 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloAsyncLambda.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloAsyncLambda.java @@ -4,6 +4,7 @@ import io.temporal.activity.ActivityOptions; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; @@ -12,6 +13,7 @@ import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; /** Sample Temporal Workflow Definition that demonstrates an asynchronous Activity Executions. */ @@ -128,13 +130,18 @@ public String composeGreeting(String greeting, String name) { */ public static void main(String[] args) { - // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Get a Workflow service stub. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloAwait.java b/core/src/main/java/io/temporal/samples/hello/HelloAwait.java index 069f5bb65..588b9e3fc 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloAwait.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloAwait.java @@ -3,6 +3,7 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; import io.temporal.client.WorkflowStub; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.failure.ApplicationFailure; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; @@ -11,6 +12,7 @@ import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; /** @@ -80,13 +82,18 @@ public void waitForName(String name) { */ public static void main(String[] args) throws Exception { - // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Await, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Get a Workflow service stub. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloCancellationScope.java b/core/src/main/java/io/temporal/samples/hello/HelloCancellationScope.java index 59cc0c7c8..c98a6fac5 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloCancellationScope.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloCancellationScope.java @@ -8,6 +8,7 @@ import io.temporal.client.ActivityCompletionException; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.failure.ActivityFailure; import io.temporal.failure.CanceledFailure; import io.temporal.serviceclient.WorkflowServiceStubs; @@ -20,6 +21,7 @@ import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -231,13 +233,18 @@ private void sleep(int seconds) { */ public static void main(String[] args) { - // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Get a Workflow service stub. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloCancellationScopeWithTimer.java b/core/src/main/java/io/temporal/samples/hello/HelloCancellationScopeWithTimer.java index 6efb24b0a..5961b6833 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloCancellationScopeWithTimer.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloCancellationScopeWithTimer.java @@ -4,12 +4,14 @@ import io.temporal.client.ActivityCompletionException; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.failure.ActivityFailure; import io.temporal.failure.CanceledFailure; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.workflow.*; +import java.io.IOException; import java.time.Duration; import java.util.concurrent.TimeUnit; @@ -153,12 +155,21 @@ private void sleep(int seconds) { public static void main(String[] args) { // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); /* * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. */ - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloChild.java b/core/src/main/java/io/temporal/samples/hello/HelloChild.java index f631f5cbe..4c4c37276 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloChild.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloChild.java @@ -2,6 +2,7 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; @@ -10,6 +11,7 @@ import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; /** * Sample Temporal Workflow Definition that demonstrates the execution of a Child Workflow. Child @@ -105,13 +107,18 @@ public String composeGreeting(String greeting, String name) { */ public static void main(String[] args) { - // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Get a Workflow service stub. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the worker factory. It is used to create workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloCron.java b/core/src/main/java/io/temporal/samples/hello/HelloCron.java index 1d46d1c33..dafbfe11e 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloCron.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloCron.java @@ -7,12 +7,14 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowExecutionAlreadyStarted; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; /** @@ -108,13 +110,18 @@ public void greet(String greeting) { */ public static void main(String[] args) { - // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Get a Workflow service stub. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloDelayedStart.java b/core/src/main/java/io/temporal/samples/hello/HelloDelayedStart.java index 13d3d9041..a407e64d6 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloDelayedStart.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloDelayedStart.java @@ -3,12 +3,14 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; import io.temporal.common.WorkflowExecutionHistory; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; /** Sample Temporal Workflow Definition that shows how to use delayed start. */ @@ -50,13 +52,18 @@ public void start() { } public static void main(String[] args) { - // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Get a Workflow service stub. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloDetachedCancellationScope.java b/core/src/main/java/io/temporal/samples/hello/HelloDetachedCancellationScope.java index 8baaf2364..a40087894 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloDetachedCancellationScope.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloDetachedCancellationScope.java @@ -8,11 +8,13 @@ import io.temporal.client.WorkflowFailedException; import io.temporal.client.WorkflowOptions; import io.temporal.client.WorkflowStub; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.failure.ActivityFailure; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.workflow.*; +import java.io.IOException; import java.time.Duration; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -132,13 +134,22 @@ public String queryGreeting() { public static void main(String[] args) throws InterruptedException { // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); /* * Get a Workflow service client which can be used to start, Signal, and Query Workflow * Executions. */ - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloDynamic.java b/core/src/main/java/io/temporal/samples/hello/HelloDynamic.java index f770f4263..f779bdfc3 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloDynamic.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloDynamic.java @@ -7,6 +7,7 @@ import io.temporal.client.WorkflowOptions; import io.temporal.client.WorkflowStub; import io.temporal.common.converter.EncodedValues; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; @@ -14,6 +15,7 @@ import io.temporal.workflow.DynamicSignalHandler; import io.temporal.workflow.DynamicWorkflow; import io.temporal.workflow.Workflow; +import java.io.IOException; import java.time.Duration; public class HelloDynamic { @@ -71,14 +73,18 @@ public Object execute(EncodedValues args) { */ public static void main(String[] arg) { - // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow - * Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Get a Workflow service stub. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloEagerWorkflowStart.java b/core/src/main/java/io/temporal/samples/hello/HelloEagerWorkflowStart.java index feb0d45f1..4e1a3b533 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloEagerWorkflowStart.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloEagerWorkflowStart.java @@ -5,12 +5,14 @@ import io.temporal.activity.ActivityOptions; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -110,13 +112,18 @@ public String composeGreeting(String greeting, String name) { */ public static void main(String[] args) { - // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Get a Workflow service stub. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloException.java b/core/src/main/java/io/temporal/samples/hello/HelloException.java index 8c1daaccb..6b0788043 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloException.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloException.java @@ -8,6 +8,7 @@ import io.temporal.client.WorkflowException; import io.temporal.client.WorkflowOptions; import io.temporal.common.RetryOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; @@ -153,13 +154,18 @@ public String composeGreeting(String greeting, String name) { */ public static void main(String[] args) { - // Define the workflow service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Define the workflow service. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloLocalActivity.java b/core/src/main/java/io/temporal/samples/hello/HelloLocalActivity.java index 9436eab6b..c82a76e06 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloLocalActivity.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloLocalActivity.java @@ -5,12 +5,14 @@ import io.temporal.activity.LocalActivityOptions; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; /** @@ -90,10 +92,19 @@ public String composeGreeting(String greeting, String name) { } public static void main(String[] args) { - // gRPC stubs wrapper that talks to the local docker instance of temporal service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + // gRPC stubs wrapper that talks to the temporal service. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); // client that can be used to start and signal workflows - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); // worker factory that can be used to create workers for specific task queues WorkerFactory factory = WorkerFactory.newInstance(client); diff --git a/core/src/main/java/io/temporal/samples/hello/HelloParallelActivity.java b/core/src/main/java/io/temporal/samples/hello/HelloParallelActivity.java index ab3e7c789..21b716070 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloParallelActivity.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloParallelActivity.java @@ -4,10 +4,12 @@ import io.temporal.activity.ActivityOptions; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.workflow.*; +import java.io.IOException; import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; @@ -116,13 +118,18 @@ public List getGreetings(List names) { */ public static void main(String[] args) { - // Define the workflow service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Define the workflow service. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloPeriodic.java b/core/src/main/java/io/temporal/samples/hello/HelloPeriodic.java index 418244684..f26370f21 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloPeriodic.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloPeriodic.java @@ -7,6 +7,7 @@ import io.temporal.client.WorkflowExecutionAlreadyStarted; import io.temporal.client.WorkflowOptions; import io.temporal.client.WorkflowStub; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; @@ -14,6 +15,7 @@ import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; import java.util.Random; @@ -183,13 +185,18 @@ public void greet(String greeting) { "CatchAndPrintStackTrace") // in this simple example advanced error logging is not required public static void main(String[] args) throws InterruptedException { - // Define the workflow service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Define the workflow service. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloPolymorphicActivity.java b/core/src/main/java/io/temporal/samples/hello/HelloPolymorphicActivity.java index a6bb70f1f..71a2c3ffd 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloPolymorphicActivity.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloPolymorphicActivity.java @@ -4,12 +4,14 @@ import io.temporal.activity.ActivityOptions; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; /** @@ -150,13 +152,18 @@ public String composeGreeting(String name) { */ public static void main(String[] args) { - // Define the workflow service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Define the workflow service. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloQuery.java b/core/src/main/java/io/temporal/samples/hello/HelloQuery.java index 012ae1b97..e89f83f07 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloQuery.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloQuery.java @@ -2,6 +2,7 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; @@ -9,6 +10,7 @@ import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; /** Sample Temporal Workflow Definition that demonstrates how to Query a Workflow. */ @@ -78,13 +80,18 @@ public String queryGreeting() { */ public static void main(String[] args) throws InterruptedException { - // Define the workflow service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Define the workflow service. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloSaga.java b/core/src/main/java/io/temporal/samples/hello/HelloSaga.java index 5dfc0848b..4fb3bc6a1 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloSaga.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloSaga.java @@ -5,6 +5,7 @@ import io.temporal.activity.ActivityOptions; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; @@ -14,6 +15,7 @@ import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; /** @@ -258,13 +260,18 @@ public void execute() { */ public static void main(String[] args) { - // Define the workflow service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Define the workflow service. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloSchedules.java b/core/src/main/java/io/temporal/samples/hello/HelloSchedules.java index 7d3c5ef1a..698f4f83b 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloSchedules.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloSchedules.java @@ -9,12 +9,14 @@ import io.temporal.client.WorkflowOptions; import io.temporal.client.schedules.*; import io.temporal.common.converter.GlobalDataConverter; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; import java.time.Instant; import java.util.Collections; @@ -130,13 +132,18 @@ public void greet(String greeting) { */ public static void main(String[] args) throws InterruptedException { - // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Get a Workflow service stub. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloSearchAttributes.java b/core/src/main/java/io/temporal/samples/hello/HelloSearchAttributes.java index e2b1c0f9c..7115ebaa5 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloSearchAttributes.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloSearchAttributes.java @@ -12,12 +12,14 @@ import io.temporal.client.WorkflowOptions; import io.temporal.common.converter.DataConverter; import io.temporal.common.converter.GlobalDataConverter; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; import java.time.ZoneId; import java.time.ZonedDateTime; @@ -113,13 +115,18 @@ public String composeGreeting(String greeting, String name) { */ public static void main(String[] args) { - // Define the workflow service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Define the workflow service. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloSideEffect.java b/core/src/main/java/io/temporal/samples/hello/HelloSideEffect.java index e0c39bf91..f894dc343 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloSideEffect.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloSideEffect.java @@ -4,6 +4,7 @@ import io.temporal.activity.ActivityOptions; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; @@ -11,6 +12,7 @@ import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.security.SecureRandom; import java.time.Duration; import java.util.Random; @@ -159,14 +161,18 @@ public String sayGoodBye(String greeting) { */ public static void main(String[] args) { - // Define the workflow service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow - * Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Define the workflow service. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloSignal.java b/core/src/main/java/io/temporal/samples/hello/HelloSignal.java index cd5a488ab..e2e50fc85 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloSignal.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloSignal.java @@ -2,6 +2,7 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; @@ -9,6 +10,7 @@ import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -94,13 +96,18 @@ public void exit() { */ public static void main(String[] args) throws Exception { - // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Get a Workflow service stub. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloSignalWithStartAndWorkflowInit.java b/core/src/main/java/io/temporal/samples/hello/HelloSignalWithStartAndWorkflowInit.java index 096516b10..f579388ae 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloSignalWithStartAndWorkflowInit.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloSignalWithStartAndWorkflowInit.java @@ -6,11 +6,13 @@ import io.temporal.client.WorkflowFailedException; import io.temporal.client.WorkflowOptions; import io.temporal.client.WorkflowStub; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.worker.WorkflowImplementationOptions; import io.temporal.workflow.*; +import java.io.IOException; import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -147,8 +149,17 @@ public void setAge(int age) { } public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkerFactory factory = WorkerFactory.newInstance(client); Worker worker = factory.newWorker(TASK_QUEUE); diff --git a/core/src/main/java/io/temporal/samples/hello/HelloSignalWithTimer.java b/core/src/main/java/io/temporal/samples/hello/HelloSignalWithTimer.java index 26c22b2a2..ea2d29d2a 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloSignalWithTimer.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloSignalWithTimer.java @@ -5,11 +5,13 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; import io.temporal.client.WorkflowStub; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.failure.CanceledFailure; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.workflow.*; +import java.io.IOException; import java.time.Duration; import org.slf4j.Logger; @@ -116,8 +118,17 @@ public void processValue(String value) { } public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkerFactory factory = WorkerFactory.newInstance(client); Worker worker = factory.newWorker(TASK_QUEUE); diff --git a/core/src/main/java/io/temporal/samples/hello/HelloTypedSearchAttributes.java b/core/src/main/java/io/temporal/samples/hello/HelloTypedSearchAttributes.java index f0dfb76c4..8629dfd62 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloTypedSearchAttributes.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloTypedSearchAttributes.java @@ -6,12 +6,14 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; import io.temporal.common.SearchAttributeKey; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; import java.time.OffsetDateTime; import java.time.ZoneOffset; @@ -149,13 +151,18 @@ public String composeGreeting(String greeting, List salutations, String */ public static void main(String[] args) { - // Define the workflow service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Define the workflow service. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloUpdate.java b/core/src/main/java/io/temporal/samples/hello/HelloUpdate.java index 329569738..6df8a8694 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloUpdate.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloUpdate.java @@ -6,6 +6,7 @@ import io.temporal.client.WorkflowOptions; import io.temporal.client.WorkflowStub; import io.temporal.client.WorkflowUpdateException; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.failure.ApplicationFailure; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; @@ -16,6 +17,7 @@ import io.temporal.workflow.Workflow; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; +import java.io.IOException; import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -157,13 +159,18 @@ public void exit() { */ public static void main(String[] args) throws Exception { - // Get a Workflow service stub. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } - /* - * Get a Workflow service client which can be used to start, Signal, and Query Workflow Executions. - */ - WorkflowClient client = WorkflowClient.newInstance(service); + // Get a Workflow service stub. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); /* * Define the workflow factory. It is used to create workflow workers for a specific task queue. diff --git a/core/src/main/java/io/temporal/samples/hello/HelloWorkflowTimer.java b/core/src/main/java/io/temporal/samples/hello/HelloWorkflowTimer.java index 94570db98..ec6f8a5ba 100644 --- a/core/src/main/java/io/temporal/samples/hello/HelloWorkflowTimer.java +++ b/core/src/main/java/io/temporal/samples/hello/HelloWorkflowTimer.java @@ -5,6 +5,7 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; import io.temporal.client.WorkflowStub; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.failure.ActivityFailure; import io.temporal.failure.CanceledFailure; import io.temporal.failure.ChildWorkflowFailure; @@ -12,6 +13,7 @@ import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.workflow.*; +import java.io.IOException; import java.time.Duration; /** Sample shows how to use workflow timer instead of WorkflowOptions->Run/ExecutionTimeout */ @@ -190,10 +192,19 @@ public String executeChild(String input) { } public static void main(String[] args) { + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + // Create service stubs - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - // Crete workflow client - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + // Create workflow client + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); // Create worker factory WorkerFactory factory = WorkerFactory.newInstance(client); diff --git a/core/src/main/java/io/temporal/samples/keymanagementencryption/awsencryptionsdk/EncryptedPayloads.java b/core/src/main/java/io/temporal/samples/keymanagementencryption/awsencryptionsdk/EncryptedPayloads.java index f36f3176c..03392674c 100644 --- a/core/src/main/java/io/temporal/samples/keymanagementencryption/awsencryptionsdk/EncryptedPayloads.java +++ b/core/src/main/java/io/temporal/samples/keymanagementencryption/awsencryptionsdk/EncryptedPayloads.java @@ -5,10 +5,12 @@ import io.temporal.client.WorkflowOptions; import io.temporal.common.converter.CodecDataConverter; import io.temporal.common.converter.DefaultDataConverter; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.samples.hello.HelloActivity; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; import java.util.Collections; import software.amazon.cryptography.materialproviders.IKeyring; import software.amazon.cryptography.materialproviders.MaterialProviders; @@ -36,7 +38,16 @@ public static void main(String[] args) { CreateAwsKmsMultiKeyringInput.builder().generator(generatorKey).build(); final IKeyring kmsKeyring = materialProviders.CreateAwsKmsMultiKeyring(keyringInput); // gRPC stubs wrapper that talks to the local docker instance of temporal service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); // client that can be used to start and signal workflows WorkflowClient client = WorkflowClient.newInstance( diff --git a/core/src/main/java/io/temporal/samples/listworkflows/Starter.java b/core/src/main/java/io/temporal/samples/listworkflows/Starter.java index 1d9ef916c..ad7f62369 100644 --- a/core/src/main/java/io/temporal/samples/listworkflows/Starter.java +++ b/core/src/main/java/io/temporal/samples/listworkflows/Starter.java @@ -6,9 +6,11 @@ import io.temporal.api.workflowservice.v1.ListWorkflowExecutionsResponse; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -17,11 +19,23 @@ public class Starter { public static final String TASK_QUEUE = "customerTaskQueue"; - private static final WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - private static final WorkflowClient client = WorkflowClient.newInstance(service); - private static final WorkerFactory factory = WorkerFactory.newInstance(client); + private static WorkflowServiceStubs service; + private static WorkflowClient client; + private static WorkerFactory factory; public static void main(String[] args) { + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + service = WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); + factory = WorkerFactory.newInstance(client); + // create some fake customers List customers = new ArrayList<>(); customers.add(new Customer("c1", "John", "john@john.com", "new")); diff --git a/core/src/main/java/io/temporal/samples/metrics/MetricsStarter.java b/core/src/main/java/io/temporal/samples/metrics/MetricsStarter.java index a213c3f81..ffe222899 100644 --- a/core/src/main/java/io/temporal/samples/metrics/MetricsStarter.java +++ b/core/src/main/java/io/temporal/samples/metrics/MetricsStarter.java @@ -9,9 +9,11 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; import io.temporal.common.reporter.MicrometerClientStatsReporter; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.samples.metrics.workflow.MetricsWorkflow; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.serviceclient.WorkflowServiceStubsOptions; +import java.io.IOException; public class MetricsStarter { public static void main(String[] args) { @@ -35,12 +37,22 @@ public static void main(String[] args) { // scrape endpoint. Runtime.getRuntime().addShutdownHook(new Thread(() -> scrapeEndpoint.stop(1))); - // Add metrics scope to workflow service stub options + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + // Add metrics scope to workflow service stub options, preserving env config WorkflowServiceStubsOptions stubOptions = - WorkflowServiceStubsOptions.newBuilder().setMetricsScope(scope).build(); + WorkflowServiceStubsOptions.newBuilder(profile.toWorkflowServiceStubsOptions()) + .setMetricsScope(scope) + .build(); WorkflowServiceStubs service = WorkflowServiceStubs.newServiceStubs(stubOptions); - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkflowOptions workflowOptions = WorkflowOptions.newBuilder() diff --git a/core/src/main/java/io/temporal/samples/metrics/MetricsWorker.java b/core/src/main/java/io/temporal/samples/metrics/MetricsWorker.java index 4b5f3173f..9f95107cf 100644 --- a/core/src/main/java/io/temporal/samples/metrics/MetricsWorker.java +++ b/core/src/main/java/io/temporal/samples/metrics/MetricsWorker.java @@ -8,12 +8,14 @@ import io.micrometer.prometheus.PrometheusMeterRegistry; import io.temporal.client.WorkflowClient; import io.temporal.common.reporter.MicrometerClientStatsReporter; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.samples.metrics.activities.MetricsActivitiesImpl; import io.temporal.samples.metrics.workflow.MetricsWorkflowImpl; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.serviceclient.WorkflowServiceStubsOptions; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; public class MetricsWorker { @@ -41,12 +43,22 @@ public static void main(String[] args) { // Stopping the worker will stop the http server that exposes the // scrape endpoint. Runtime.getRuntime().addShutdownHook(new Thread(() -> scrapeEndpoint.stop(1))); - // Add metrics scope to workflow service stub options + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + // Add metrics scope to workflow service stub options, preserving env config WorkflowServiceStubsOptions stubOptions = - WorkflowServiceStubsOptions.newBuilder().setMetricsScope(scope).build(); + WorkflowServiceStubsOptions.newBuilder(profile.toWorkflowServiceStubsOptions()) + .setMetricsScope(scope) + .build(); WorkflowServiceStubs service = WorkflowServiceStubs.newServiceStubs(stubOptions); - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkerFactory factory = WorkerFactory.newInstance(client); Worker worker = factory.newWorker(DEFAULT_TASK_QUEUE_NAME); diff --git a/core/src/main/java/io/temporal/samples/moneybatch/AccountActivityWorker.java b/core/src/main/java/io/temporal/samples/moneybatch/AccountActivityWorker.java index ecee1ad05..d67014f80 100644 --- a/core/src/main/java/io/temporal/samples/moneybatch/AccountActivityWorker.java +++ b/core/src/main/java/io/temporal/samples/moneybatch/AccountActivityWorker.java @@ -1,9 +1,11 @@ package io.temporal.samples.moneybatch; import io.temporal.client.WorkflowClient; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; public class AccountActivityWorker { @@ -11,8 +13,17 @@ public class AccountActivityWorker { @SuppressWarnings("CatchAndPrintStackTrace") public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkerFactory factory = WorkerFactory.newInstance(client); Worker worker = factory.newWorker(TASK_QUEUE); diff --git a/core/src/main/java/io/temporal/samples/moneybatch/AccountTransferWorker.java b/core/src/main/java/io/temporal/samples/moneybatch/AccountTransferWorker.java index d9c5ef7cd..99529467d 100644 --- a/core/src/main/java/io/temporal/samples/moneybatch/AccountTransferWorker.java +++ b/core/src/main/java/io/temporal/samples/moneybatch/AccountTransferWorker.java @@ -1,16 +1,27 @@ package io.temporal.samples.moneybatch; import io.temporal.client.WorkflowClient; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; public class AccountTransferWorker { @SuppressWarnings("CatchAndPrintStackTrace") public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkerFactory factory = WorkerFactory.newInstance(client); Worker worker = factory.newWorker(AccountActivityWorker.TASK_QUEUE); diff --git a/core/src/main/java/io/temporal/samples/moneybatch/TransferRequester.java b/core/src/main/java/io/temporal/samples/moneybatch/TransferRequester.java index 8a63c02e3..31b2f507f 100644 --- a/core/src/main/java/io/temporal/samples/moneybatch/TransferRequester.java +++ b/core/src/main/java/io/temporal/samples/moneybatch/TransferRequester.java @@ -3,7 +3,9 @@ import io.temporal.client.BatchRequest; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; +import java.io.IOException; import java.util.Random; import java.util.UUID; @@ -16,8 +18,18 @@ public class TransferRequester { public static void main(String[] args) { String reference = UUID.randomUUID().toString(); int amountCents = (new Random().nextInt(5) + 1) * 25; - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient workflowClient = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient workflowClient = + WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); String from = "account1"; String to = "account2"; diff --git a/core/src/main/java/io/temporal/samples/moneytransfer/AccountActivityWorker.java b/core/src/main/java/io/temporal/samples/moneytransfer/AccountActivityWorker.java index a2bbee418..a3113fe5d 100644 --- a/core/src/main/java/io/temporal/samples/moneytransfer/AccountActivityWorker.java +++ b/core/src/main/java/io/temporal/samples/moneytransfer/AccountActivityWorker.java @@ -1,9 +1,11 @@ package io.temporal.samples.moneytransfer; import io.temporal.client.WorkflowClient; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; public class AccountActivityWorker { @@ -11,10 +13,19 @@ public class AccountActivityWorker { @SuppressWarnings("CatchAndPrintStackTrace") public static void main(String[] args) { - // gRPC stubs wrapper that talks to the local docker instance of temporal service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + // gRPC stubs wrapper that talks to the temporal service. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); // client that can be used to start and signal workflows - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); // worker factory that can be used to create workers for specific task queues WorkerFactory factory = WorkerFactory.newInstance(client); diff --git a/core/src/main/java/io/temporal/samples/moneytransfer/AccountTransferWorker.java b/core/src/main/java/io/temporal/samples/moneytransfer/AccountTransferWorker.java index 6d237d8fa..97ab56ff9 100644 --- a/core/src/main/java/io/temporal/samples/moneytransfer/AccountTransferWorker.java +++ b/core/src/main/java/io/temporal/samples/moneytransfer/AccountTransferWorker.java @@ -3,19 +3,30 @@ import static io.temporal.samples.moneytransfer.AccountActivityWorker.TASK_QUEUE; import io.temporal.client.WorkflowClient; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; public class AccountTransferWorker { @SuppressWarnings("CatchAndPrintStackTrace") public static void main(String[] args) { // Get worker to poll the common task queue. - // gRPC stubs wrapper that talks to the local docker instance of temporal service. - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + // gRPC stubs wrapper that talks to the temporal service. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); // client that can be used to start and signal workflows - WorkflowClient client = WorkflowClient.newInstance(service); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); // worker factory that can be used to create workers for specific task queues WorkerFactory factory = WorkerFactory.newInstance(client); diff --git a/core/src/main/java/io/temporal/samples/moneytransfer/TransferRequester.java b/core/src/main/java/io/temporal/samples/moneytransfer/TransferRequester.java index b333b9341..6fda6598e 100644 --- a/core/src/main/java/io/temporal/samples/moneytransfer/TransferRequester.java +++ b/core/src/main/java/io/temporal/samples/moneytransfer/TransferRequester.java @@ -4,7 +4,9 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; +import java.io.IOException; import java.util.Random; import java.util.UUID; @@ -21,9 +23,19 @@ public static void main(String[] args) { reference = args[0]; amountCents = Integer.parseInt(args[1]); } - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); // client that can be used to start and signal workflows - WorkflowClient workflowClient = WorkflowClient.newInstance(service); + WorkflowClient workflowClient = + WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); // now we can start running instances of the saga - its state will be persisted WorkflowOptions options = WorkflowOptions.newBuilder().setTaskQueue(TASK_QUEUE).build(); diff --git a/core/src/main/java/io/temporal/samples/packetdelivery/Starter.java b/core/src/main/java/io/temporal/samples/packetdelivery/Starter.java index e1d97e621..f6ca6000d 100644 --- a/core/src/main/java/io/temporal/samples/packetdelivery/Starter.java +++ b/core/src/main/java/io/temporal/samples/packetdelivery/Starter.java @@ -4,16 +4,27 @@ import io.temporal.client.WorkflowNotFoundException; import io.temporal.client.WorkflowOptions; import io.temporal.client.WorkflowStub; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; import java.util.Collections; import java.util.List; public class Starter { public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkerFactory factory = WorkerFactory.newInstance(client); Worker worker = factory.newWorker("packet-delivery-taskqueue"); diff --git a/core/src/main/java/io/temporal/samples/payloadconverter/cloudevents/Starter.java b/core/src/main/java/io/temporal/samples/payloadconverter/cloudevents/Starter.java index 2e17f4cb0..e9e368a3b 100644 --- a/core/src/main/java/io/temporal/samples/payloadconverter/cloudevents/Starter.java +++ b/core/src/main/java/io/temporal/samples/payloadconverter/cloudevents/Starter.java @@ -7,9 +7,11 @@ import io.temporal.client.WorkflowClientOptions; import io.temporal.client.WorkflowOptions; import io.temporal.common.converter.DefaultDataConverter; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; import java.net.URI; import java.nio.charset.Charset; import java.util.ArrayList; @@ -20,7 +22,16 @@ public class Starter { private static final String TASK_QUEUE = "CloudEventsConverterQueue"; public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); // Add CloudEventsPayloadConverter // It has the same encoding type as JacksonJsonPayloadConverter diff --git a/core/src/main/java/io/temporal/samples/payloadconverter/crypto/Starter.java b/core/src/main/java/io/temporal/samples/payloadconverter/crypto/Starter.java index dffdb41a1..4a5e121ef 100644 --- a/core/src/main/java/io/temporal/samples/payloadconverter/crypto/Starter.java +++ b/core/src/main/java/io/temporal/samples/payloadconverter/crypto/Starter.java @@ -9,16 +9,27 @@ import io.temporal.client.WorkflowOptions; import io.temporal.common.converter.DefaultDataConverter; import io.temporal.common.converter.JacksonJsonPayloadConverter; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; public class Starter { private static final String TASK_QUEUE = "CryptoConverterQueue"; private static final String encryptDecryptPassword = "encryptDecryptPassword"; public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); // Set crypto data converter in client options WorkflowClient client = diff --git a/core/src/main/java/io/temporal/samples/peractivityoptions/Starter.java b/core/src/main/java/io/temporal/samples/peractivityoptions/Starter.java index 7db5df86d..58062c176 100644 --- a/core/src/main/java/io/temporal/samples/peractivityoptions/Starter.java +++ b/core/src/main/java/io/temporal/samples/peractivityoptions/Starter.java @@ -5,20 +5,32 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; import io.temporal.common.RetryOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.worker.WorkflowImplementationOptions; +import java.io.IOException; import java.time.Duration; public class Starter { public static final String TASK_QUEUE = "perActivityTaskQueue"; - private static final WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - private static final WorkflowClient client = WorkflowClient.newInstance(service); - private static final WorkerFactory factory = WorkerFactory.newInstance(client); public static void main(String[] args) { + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); + WorkerFactory factory = WorkerFactory.newInstance(client); + // Create Worker Worker worker = factory.newWorker(TASK_QUEUE); // Register workflow impl and set the per-activity options diff --git a/core/src/main/java/io/temporal/samples/polling/frequent/FrequentPollingStarter.java b/core/src/main/java/io/temporal/samples/polling/frequent/FrequentPollingStarter.java index 4a52cab2f..ed8fa477f 100644 --- a/core/src/main/java/io/temporal/samples/polling/frequent/FrequentPollingStarter.java +++ b/core/src/main/java/io/temporal/samples/polling/frequent/FrequentPollingStarter.java @@ -2,15 +2,31 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.samples.polling.PollingWorkflow; import io.temporal.samples.polling.TestService; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; public class FrequentPollingStarter { - private static final WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - private static final WorkflowClient client = WorkflowClient.newInstance(service); + private static WorkflowServiceStubs service; + private static WorkflowClient client; + + static { + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + service = WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); + } + private static final String taskQueue = "pollingSampleQueue"; private static final String workflowId = "FrequentPollingSampleWorkflow"; diff --git a/core/src/main/java/io/temporal/samples/polling/infrequent/InfrequentPollingStarter.java b/core/src/main/java/io/temporal/samples/polling/infrequent/InfrequentPollingStarter.java index 2a6cb7a85..f778ce287 100644 --- a/core/src/main/java/io/temporal/samples/polling/infrequent/InfrequentPollingStarter.java +++ b/core/src/main/java/io/temporal/samples/polling/infrequent/InfrequentPollingStarter.java @@ -2,15 +2,31 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.samples.polling.PollingWorkflow; import io.temporal.samples.polling.TestService; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; public class InfrequentPollingStarter { - private static final WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - private static final WorkflowClient client = WorkflowClient.newInstance(service); + private static WorkflowServiceStubs service; + private static WorkflowClient client; + + static { + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + service = WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); + } + private static final String taskQueue = "pollingSampleQueue"; private static final String workflowId = "InfrequentPollingSampleWorkflow"; diff --git a/core/src/main/java/io/temporal/samples/polling/infrequentwithretryafter/InfrequentPollingWithRetryAfterStarter.java b/core/src/main/java/io/temporal/samples/polling/infrequentwithretryafter/InfrequentPollingWithRetryAfterStarter.java index 81853ec71..93e3c9e6b 100644 --- a/core/src/main/java/io/temporal/samples/polling/infrequentwithretryafter/InfrequentPollingWithRetryAfterStarter.java +++ b/core/src/main/java/io/temporal/samples/polling/infrequentwithretryafter/InfrequentPollingWithRetryAfterStarter.java @@ -2,15 +2,31 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.samples.polling.PollingWorkflow; import io.temporal.samples.polling.TestService; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; public class InfrequentPollingWithRetryAfterStarter { - private static final WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - private static final WorkflowClient client = WorkflowClient.newInstance(service); + private static WorkflowServiceStubs service; + private static WorkflowClient client; + + static { + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + service = WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); + } + private static final String taskQueue = "pollingSampleQueue"; private static final String workflowId = "InfrequentPollingWithRetryAfterWorkflow"; diff --git a/core/src/main/java/io/temporal/samples/polling/periodicsequence/PeriodicPollingStarter.java b/core/src/main/java/io/temporal/samples/polling/periodicsequence/PeriodicPollingStarter.java index f2ef3eb1f..34c3e8a5a 100644 --- a/core/src/main/java/io/temporal/samples/polling/periodicsequence/PeriodicPollingStarter.java +++ b/core/src/main/java/io/temporal/samples/polling/periodicsequence/PeriodicPollingStarter.java @@ -2,15 +2,31 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.samples.polling.PollingWorkflow; import io.temporal.samples.polling.TestService; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; public class PeriodicPollingStarter { - private static final WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - private static final WorkflowClient client = WorkflowClient.newInstance(service); + private static WorkflowServiceStubs service; + private static WorkflowClient client; + + static { + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + service = WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); + } + private static final String taskQueue = "pollingSampleQueue"; private static final String workflowId = "PeriodicPollingSampleWorkflow"; diff --git a/core/src/main/java/io/temporal/samples/retryonsignalinterceptor/FailureRequester.java b/core/src/main/java/io/temporal/samples/retryonsignalinterceptor/FailureRequester.java index cd3e546da..c948ba02e 100644 --- a/core/src/main/java/io/temporal/samples/retryonsignalinterceptor/FailureRequester.java +++ b/core/src/main/java/io/temporal/samples/retryonsignalinterceptor/FailureRequester.java @@ -3,7 +3,9 @@ import static io.temporal.samples.retryonsignalinterceptor.MyWorkflowWorker.WORKFLOW_ID; import io.temporal.client.WorkflowClient; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; +import java.io.IOException; /** * Send signal requesting that an exception thrown from the activity is propagated to the workflow. @@ -11,8 +13,17 @@ public class FailureRequester { public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); // Note that we use the listener interface that the interceptor registered dynamically, not the // workflow interface. diff --git a/core/src/main/java/io/temporal/samples/retryonsignalinterceptor/MyWorkflowWorker.java b/core/src/main/java/io/temporal/samples/retryonsignalinterceptor/MyWorkflowWorker.java index 42fd358bd..55b9ebe17 100644 --- a/core/src/main/java/io/temporal/samples/retryonsignalinterceptor/MyWorkflowWorker.java +++ b/core/src/main/java/io/temporal/samples/retryonsignalinterceptor/MyWorkflowWorker.java @@ -2,10 +2,12 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.worker.WorkerFactoryOptions; +import java.io.IOException; public class MyWorkflowWorker { @@ -14,8 +16,17 @@ public class MyWorkflowWorker { public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); // Register interceptor with the factory. WorkerFactoryOptions factoryOptions = WorkerFactoryOptions.newBuilder() diff --git a/core/src/main/java/io/temporal/samples/retryonsignalinterceptor/QueryRequester.java b/core/src/main/java/io/temporal/samples/retryonsignalinterceptor/QueryRequester.java index c54f8d0ab..08a7afcbb 100644 --- a/core/src/main/java/io/temporal/samples/retryonsignalinterceptor/QueryRequester.java +++ b/core/src/main/java/io/temporal/samples/retryonsignalinterceptor/QueryRequester.java @@ -3,13 +3,24 @@ import static io.temporal.samples.retryonsignalinterceptor.MyWorkflowWorker.WORKFLOW_ID; import io.temporal.client.WorkflowClient; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; +import java.io.IOException; public class QueryRequester { public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); // Note that we use the listener interface that the interceptor registered dynamically, not the // workflow interface. diff --git a/core/src/main/java/io/temporal/samples/retryonsignalinterceptor/RetryRequester.java b/core/src/main/java/io/temporal/samples/retryonsignalinterceptor/RetryRequester.java index b0cf85ef8..a5469d80f 100644 --- a/core/src/main/java/io/temporal/samples/retryonsignalinterceptor/RetryRequester.java +++ b/core/src/main/java/io/temporal/samples/retryonsignalinterceptor/RetryRequester.java @@ -3,13 +3,24 @@ import static io.temporal.samples.retryonsignalinterceptor.MyWorkflowWorker.WORKFLOW_ID; import io.temporal.client.WorkflowClient; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; +import java.io.IOException; public class RetryRequester { public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); // Note that we use the listener interface that the interceptor registered dynamically, not the // workflow interface. diff --git a/core/src/main/java/io/temporal/samples/safemessagepassing/ClusterManagerWorkflowStarter.java b/core/src/main/java/io/temporal/samples/safemessagepassing/ClusterManagerWorkflowStarter.java index 1913a3e40..71ae380cb 100644 --- a/core/src/main/java/io/temporal/samples/safemessagepassing/ClusterManagerWorkflowStarter.java +++ b/core/src/main/java/io/temporal/samples/safemessagepassing/ClusterManagerWorkflowStarter.java @@ -7,7 +7,9 @@ import io.temporal.client.WorkflowOptions; import io.temporal.client.WorkflowStub; import io.temporal.client.WorkflowUpdateStage; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; +import java.io.IOException; import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -29,8 +31,17 @@ public static void main(String[] args) { + " "); System.exit(1); } - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); boolean shouldTestContinueAsNew = args.length > 0 ? Boolean.parseBoolean(args[0]) : false; ClusterManagerWorkflow cluster = client.newWorkflowStub( diff --git a/core/src/main/java/io/temporal/samples/safemessagepassing/ClusterManagerWorkflowWorker.java b/core/src/main/java/io/temporal/samples/safemessagepassing/ClusterManagerWorkflowWorker.java index 2f063a663..a4fa8d69f 100644 --- a/core/src/main/java/io/temporal/samples/safemessagepassing/ClusterManagerWorkflowWorker.java +++ b/core/src/main/java/io/temporal/samples/safemessagepassing/ClusterManagerWorkflowWorker.java @@ -1,9 +1,11 @@ package io.temporal.samples.safemessagepassing; import io.temporal.client.WorkflowClient; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -13,8 +15,17 @@ public class ClusterManagerWorkflowWorker { static final String CLUSTER_MANAGER_WORKFLOW_ID = "ClusterManagerWorkflow"; public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkerFactory factory = WorkerFactory.newInstance(client); final Worker worker = factory.newWorker(TASK_QUEUE); worker.registerWorkflowImplementationTypes(ClusterManagerWorkflowImpl.class); diff --git a/core/src/main/java/io/temporal/samples/sleepfordays/Starter.java b/core/src/main/java/io/temporal/samples/sleepfordays/Starter.java index cf5e9a9a7..91ed89325 100644 --- a/core/src/main/java/io/temporal/samples/sleepfordays/Starter.java +++ b/core/src/main/java/io/temporal/samples/sleepfordays/Starter.java @@ -3,15 +3,30 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; import io.temporal.client.WorkflowStub; +import io.temporal.envconfig.ClientConfigProfile; +import io.temporal.serviceclient.WorkflowServiceStubs; +import java.io.IOException; public class Starter { public static final String TASK_QUEUE = "SleepForDaysTaskQueue"; public static void main(String[] args) { + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); + // Start a workflow execution. SleepForDaysWorkflow workflow = - Worker.client.newWorkflowStub( + client.newWorkflowStub( SleepForDaysWorkflow.class, WorkflowOptions.newBuilder().setTaskQueue(TASK_QUEUE).build()); diff --git a/core/src/main/java/io/temporal/samples/sleepfordays/Worker.java b/core/src/main/java/io/temporal/samples/sleepfordays/Worker.java index 301326c27..b5abac1cb 100644 --- a/core/src/main/java/io/temporal/samples/sleepfordays/Worker.java +++ b/core/src/main/java/io/temporal/samples/sleepfordays/Worker.java @@ -1,16 +1,28 @@ package io.temporal.samples.sleepfordays; import io.temporal.client.WorkflowClient; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.WorkerFactory; +import java.io.IOException; public class Worker { public static final String TASK_QUEUE = "SleepForDaysTaskQueue"; - public static final WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - public static final WorkflowClient client = WorkflowClient.newInstance(service); - public static final WorkerFactory factory = WorkerFactory.newInstance(client); public static void main(String[] args) { + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); + WorkerFactory factory = WorkerFactory.newInstance(client); + io.temporal.worker.Worker worker = factory.newWorker(TASK_QUEUE); worker.registerWorkflowImplementationTypes(SleepForDaysImpl.class); worker.registerActivitiesImplementations(new SendEmailActivityImpl()); diff --git a/core/src/main/java/io/temporal/samples/terminateworkflow/Starter.java b/core/src/main/java/io/temporal/samples/terminateworkflow/Starter.java index 20f0d171d..e36a407c7 100644 --- a/core/src/main/java/io/temporal/samples/terminateworkflow/Starter.java +++ b/core/src/main/java/io/temporal/samples/terminateworkflow/Starter.java @@ -7,21 +7,33 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowOptions; import io.temporal.client.WorkflowStub; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; import java.util.concurrent.TimeUnit; public class Starter { public static final String TASK_QUEUE = "terminateQueue"; - private static final WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - private static final WorkflowClient client = WorkflowClient.newInstance(service); - private static final WorkerFactory factory = WorkerFactory.newInstance(client); public static void main(String[] args) { + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); + WorkerFactory factory = WorkerFactory.newInstance(client); + // Create Worker - createWorker(); + createWorker(factory); // Create Workflow options WorkflowOptions workflowOptions = @@ -44,13 +56,13 @@ public static void main(String[] args) { untyped.terminate("Sample reason"); // Check workflow status, should be WORKFLOW_EXECUTION_STATUS_TERMINATED - System.out.println("Status: " + getStatusAsString(execution)); + System.out.println("Status: " + getStatusAsString(execution, client, service)); System.exit(0); } /** This method creates a Worker from the factory. */ - private static void createWorker() { + private static void createWorker(WorkerFactory factory) { Worker worker = factory.newWorker(TASK_QUEUE); worker.registerWorkflowImplementationTypes(MyWorkflowImpl.class); @@ -78,7 +90,8 @@ private static void sleepSeconds(int seconds) { * @param execution workflow execution * @return Workflow status */ - private static String getStatusAsString(WorkflowExecution execution) { + private static String getStatusAsString( + WorkflowExecution execution, WorkflowClient client, WorkflowServiceStubs service) { DescribeWorkflowExecutionRequest describeWorkflowExecutionRequest = DescribeWorkflowExecutionRequest.newBuilder() .setNamespace(client.getOptions().getNamespace()) diff --git a/core/src/main/java/io/temporal/samples/tracing/Starter.java b/core/src/main/java/io/temporal/samples/tracing/Starter.java index ebb830c19..bb1eaaae3 100644 --- a/core/src/main/java/io/temporal/samples/tracing/Starter.java +++ b/core/src/main/java/io/temporal/samples/tracing/Starter.java @@ -4,12 +4,13 @@ import io.temporal.client.WorkflowClientOptions; import io.temporal.client.WorkflowOptions; import io.temporal.client.WorkflowStub; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.opentracing.OpenTracingClientInterceptor; import io.temporal.samples.tracing.workflow.TracingWorkflow; import io.temporal.serviceclient.WorkflowServiceStubs; +import java.io.IOException; public class Starter { - public static final WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); public static final String TASK_QUEUE_NAME = "tracingTaskQueue"; public static void main(String[] args) { @@ -18,9 +19,20 @@ public static void main(String[] args) { type = args[0]; } - // Set the OpenTracing client interceptor + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + + // Set the OpenTracing client interceptor, preserving env config WorkflowClientOptions clientOptions = - WorkflowClientOptions.newBuilder() + profile.toWorkflowClientOptions().toBuilder() .setInterceptors(new OpenTracingClientInterceptor(JaegerUtils.getJaegerOptions(type))) .build(); WorkflowClient client = WorkflowClient.newInstance(service, clientOptions); diff --git a/core/src/main/java/io/temporal/samples/tracing/TracingWorker.java b/core/src/main/java/io/temporal/samples/tracing/TracingWorker.java index 221c3efef..b726bcaae 100644 --- a/core/src/main/java/io/temporal/samples/tracing/TracingWorker.java +++ b/core/src/main/java/io/temporal/samples/tracing/TracingWorker.java @@ -1,6 +1,7 @@ package io.temporal.samples.tracing; import io.temporal.client.WorkflowClient; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.opentracing.OpenTracingWorkerInterceptor; import io.temporal.samples.tracing.workflow.TracingActivitiesImpl; import io.temporal.samples.tracing.workflow.TracingChildWorkflowImpl; @@ -9,10 +10,9 @@ import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; import io.temporal.worker.WorkerFactoryOptions; +import java.io.IOException; public class TracingWorker { - private static final WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - private static final WorkflowClient client = WorkflowClient.newInstance(service); public static final String TASK_QUEUE_NAME = "tracingTaskQueue"; public static void main(String[] args) { @@ -21,6 +21,18 @@ public static void main(String[] args) { type = args[0]; } + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); + // Set the OpenTracing client interceptor WorkerFactoryOptions factoryOptions = WorkerFactoryOptions.newBuilder() diff --git a/core/src/main/java/io/temporal/samples/updatabletimer/DynamicSleepWorkflowStarter.java b/core/src/main/java/io/temporal/samples/updatabletimer/DynamicSleepWorkflowStarter.java index d1f38e1ab..0cd1bb14c 100644 --- a/core/src/main/java/io/temporal/samples/updatabletimer/DynamicSleepWorkflowStarter.java +++ b/core/src/main/java/io/temporal/samples/updatabletimer/DynamicSleepWorkflowStarter.java @@ -8,7 +8,9 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowExecutionAlreadyStarted; import io.temporal.client.WorkflowOptions; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; +import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,8 +19,17 @@ public class DynamicSleepWorkflowStarter { private static final Logger logger = LoggerFactory.getLogger(DynamicSleepWorkflowStarter.class); public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); DynamicSleepWorkflow workflow = client.newWorkflowStub( diff --git a/core/src/main/java/io/temporal/samples/updatabletimer/DynamicSleepWorkflowWorker.java b/core/src/main/java/io/temporal/samples/updatabletimer/DynamicSleepWorkflowWorker.java index d0a4e712b..a7db34126 100644 --- a/core/src/main/java/io/temporal/samples/updatabletimer/DynamicSleepWorkflowWorker.java +++ b/core/src/main/java/io/temporal/samples/updatabletimer/DynamicSleepWorkflowWorker.java @@ -1,9 +1,11 @@ package io.temporal.samples.updatabletimer; import io.temporal.client.WorkflowClient; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; +import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,8 +19,17 @@ public class DynamicSleepWorkflowWorker { static final String DYNAMIC_SLEEP_WORKFLOW_ID = "DynamicSleepWorkflow"; public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkerFactory factory = WorkerFactory.newInstance(client); final Worker worker = factory.newWorker(TASK_QUEUE); worker.registerWorkflowImplementationTypes(DynamicSleepWorkflowImpl.class); diff --git a/core/src/main/java/io/temporal/samples/updatabletimer/WakeUpTimeUpdater.java b/core/src/main/java/io/temporal/samples/updatabletimer/WakeUpTimeUpdater.java index 0a13ff071..3a8f935a2 100644 --- a/core/src/main/java/io/temporal/samples/updatabletimer/WakeUpTimeUpdater.java +++ b/core/src/main/java/io/temporal/samples/updatabletimer/WakeUpTimeUpdater.java @@ -3,7 +3,9 @@ import static io.temporal.samples.updatabletimer.DynamicSleepWorkflowWorker.DYNAMIC_SLEEP_WORKFLOW_ID; import io.temporal.client.WorkflowClient; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; +import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -12,8 +14,17 @@ public class WakeUpTimeUpdater { private static final Logger logger = LoggerFactory.getLogger(WakeUpTimeUpdater.class); public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); // Create a stub that points to an existing workflow with the given ID DynamicSleepWorkflow workflow = diff --git a/core/src/main/java/io/temporal/samples/workerversioning/Starter.java b/core/src/main/java/io/temporal/samples/workerversioning/Starter.java index a48902557..b743cf821 100644 --- a/core/src/main/java/io/temporal/samples/workerversioning/Starter.java +++ b/core/src/main/java/io/temporal/samples/workerversioning/Starter.java @@ -7,7 +7,9 @@ import io.temporal.client.WorkflowOptions; import io.temporal.client.WorkflowStub; import io.temporal.common.WorkerDeploymentVersion; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; +import java.io.IOException; import java.util.UUID; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,8 +21,17 @@ public class Starter { private static final Logger logger = LoggerFactory.getLogger(Starter.class); public static void main(String[] args) throws Exception { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); // Wait for v1 worker and set as current version logger.info( @@ -146,6 +157,7 @@ private static void waitForWorkerAndMakeCurrent( break; } } catch (Exception ignored) { + System.out.println(); } Thread.sleep(1000); } diff --git a/core/src/main/java/io/temporal/samples/workerversioning/WorkerV1.java b/core/src/main/java/io/temporal/samples/workerversioning/WorkerV1.java index 6d90b82fd..42ff216e0 100644 --- a/core/src/main/java/io/temporal/samples/workerversioning/WorkerV1.java +++ b/core/src/main/java/io/temporal/samples/workerversioning/WorkerV1.java @@ -2,11 +2,13 @@ import io.temporal.client.WorkflowClient; import io.temporal.common.WorkerDeploymentVersion; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerDeploymentOptions; import io.temporal.worker.WorkerFactory; import io.temporal.worker.WorkerOptions; +import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,8 +17,17 @@ public class WorkerV1 { private static final Logger logger = LoggerFactory.getLogger(WorkerV1.class); public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkerDeploymentVersion version = new WorkerDeploymentVersion(Starter.DEPLOYMENT_NAME, "1.0"); WorkerDeploymentOptions deploymentOptions = diff --git a/core/src/main/java/io/temporal/samples/workerversioning/WorkerV1_1.java b/core/src/main/java/io/temporal/samples/workerversioning/WorkerV1_1.java index 5b1235460..76ec8e278 100644 --- a/core/src/main/java/io/temporal/samples/workerversioning/WorkerV1_1.java +++ b/core/src/main/java/io/temporal/samples/workerversioning/WorkerV1_1.java @@ -2,11 +2,13 @@ import io.temporal.client.WorkflowClient; import io.temporal.common.WorkerDeploymentVersion; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerDeploymentOptions; import io.temporal.worker.WorkerFactory; import io.temporal.worker.WorkerOptions; +import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,8 +17,17 @@ public class WorkerV1_1 { private static final Logger logger = LoggerFactory.getLogger(WorkerV1_1.class); public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkerDeploymentVersion version = new WorkerDeploymentVersion(Starter.DEPLOYMENT_NAME, "1.1"); WorkerDeploymentOptions deploymentOptions = diff --git a/core/src/main/java/io/temporal/samples/workerversioning/WorkerV2.java b/core/src/main/java/io/temporal/samples/workerversioning/WorkerV2.java index 57edd0ed3..2c436a2dd 100644 --- a/core/src/main/java/io/temporal/samples/workerversioning/WorkerV2.java +++ b/core/src/main/java/io/temporal/samples/workerversioning/WorkerV2.java @@ -2,11 +2,13 @@ import io.temporal.client.WorkflowClient; import io.temporal.common.WorkerDeploymentVersion; +import io.temporal.envconfig.ClientConfigProfile; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; import io.temporal.worker.WorkerDeploymentOptions; import io.temporal.worker.WorkerFactory; import io.temporal.worker.WorkerOptions; +import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,8 +17,17 @@ public class WorkerV2 { private static final Logger logger = LoggerFactory.getLogger(WorkerV2.class); public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); + // Load configuration from environment and files + ClientConfigProfile profile; + try { + profile = ClientConfigProfile.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load client configuration", e); + } + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs(profile.toWorkflowServiceStubsOptions()); + WorkflowClient client = WorkflowClient.newInstance(service, profile.toWorkflowClientOptions()); WorkerDeploymentVersion version = new WorkerDeploymentVersion(Starter.DEPLOYMENT_NAME, "2.0"); WorkerDeploymentOptions deploymentOptions = diff --git a/springboot/build.gradle b/springboot/build.gradle index 7120304e9..aa632df51 100644 --- a/springboot/build.gradle +++ b/springboot/build.gradle @@ -9,6 +9,9 @@ dependencies { // we set this as impl depends to use embedded kafka in samples not just tests implementation "org.springframework.kafka:spring-kafka-test" implementation "io.temporal:temporal-spring-boot-starter:$javaSDKVersion" + + // Environment configuration + implementation "io.temporal:temporal-envconfig:$javaSDKVersion" implementation "org.apache.camel.springboot:camel-spring-boot-starter:$camelVersion" implementation "org.apache.camel.springboot:camel-servlet-starter:$camelVersion" runtimeOnly "io.micrometer:micrometer-registry-prometheus" From 8c313585970165aa344ad8c14abcb2b70cb0c91b Mon Sep 17 00:00:00 2001 From: Lenny Chen <55669665+lennessyy@users.noreply.github.com> Date: Tue, 9 Dec 2025 11:12:16 -0800 Subject: [PATCH 07/14] docs: add snipsync lines to envconfig samples (#763) * docs: add snipsync lines to envconfig samples * docs: fix gradle format issues --- .../java/io/temporal/samples/envconfig/LoadFromFile.java | 6 ++++++ .../java/io/temporal/samples/envconfig/LoadProfile.java | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/core/src/main/java/io/temporal/samples/envconfig/LoadFromFile.java b/core/src/main/java/io/temporal/samples/envconfig/LoadFromFile.java index b6a9f7187..2a79c449b 100644 --- a/core/src/main/java/io/temporal/samples/envconfig/LoadFromFile.java +++ b/core/src/main/java/io/temporal/samples/envconfig/LoadFromFile.java @@ -1,5 +1,8 @@ package io.temporal.samples.envconfig; +/** + * @@@SNIPSTART java-env-config-profile + */ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowClientOptions; import io.temporal.envconfig.ClientConfigProfile; @@ -77,3 +80,6 @@ public static void main(String[] args) { } } } +/** + * @@@SNIPEND + */ diff --git a/core/src/main/java/io/temporal/samples/envconfig/LoadProfile.java b/core/src/main/java/io/temporal/samples/envconfig/LoadProfile.java index 9d05b21f3..930912a74 100644 --- a/core/src/main/java/io/temporal/samples/envconfig/LoadProfile.java +++ b/core/src/main/java/io/temporal/samples/envconfig/LoadProfile.java @@ -1,5 +1,8 @@ package io.temporal.samples.envconfig; +/** + * @@@SNIPSTART java-env-config-profile-with-overrides + */ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowClientOptions; import io.temporal.envconfig.ClientConfigProfile; @@ -85,3 +88,6 @@ public static void main(String[] args) { } } } +/** + * @@@SNIPEND + */ From dfef8ac2652ce67c87e3f55eab5d50a5d43d9f6f Mon Sep 17 00:00:00 2001 From: Maxim Fateev Date: Mon, 12 Jan 2026 06:49:13 -0800 Subject: [PATCH 08/14] fix: use single-line comments for SNIP markers to avoid NotJavadoc warnings (#765) ErrorProne's NotJavadoc check flags `/**` block comments that aren't actual Javadoc. The SNIP markers are for documentation extraction, not Javadoc, so use `//` single-line comments instead. Co-authored-by: Maxim Fateev <1463622+mfateev@users.noreply.github.com> --- .../java/io/temporal/samples/envconfig/LoadFromFile.java | 8 ++------ .../java/io/temporal/samples/envconfig/LoadProfile.java | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/io/temporal/samples/envconfig/LoadFromFile.java b/core/src/main/java/io/temporal/samples/envconfig/LoadFromFile.java index 2a79c449b..cee9df5a5 100644 --- a/core/src/main/java/io/temporal/samples/envconfig/LoadFromFile.java +++ b/core/src/main/java/io/temporal/samples/envconfig/LoadFromFile.java @@ -1,8 +1,6 @@ package io.temporal.samples.envconfig; -/** - * @@@SNIPSTART java-env-config-profile - */ +// @@@SNIPSTART java-env-config-profile import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowClientOptions; import io.temporal.envconfig.ClientConfigProfile; @@ -80,6 +78,4 @@ public static void main(String[] args) { } } } -/** - * @@@SNIPEND - */ +// @@@SNIPEND diff --git a/core/src/main/java/io/temporal/samples/envconfig/LoadProfile.java b/core/src/main/java/io/temporal/samples/envconfig/LoadProfile.java index 930912a74..20270e1f0 100644 --- a/core/src/main/java/io/temporal/samples/envconfig/LoadProfile.java +++ b/core/src/main/java/io/temporal/samples/envconfig/LoadProfile.java @@ -1,8 +1,6 @@ package io.temporal.samples.envconfig; -/** - * @@@SNIPSTART java-env-config-profile-with-overrides - */ +// @@@SNIPSTART java-env-config-profile-with-overrides import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowClientOptions; import io.temporal.envconfig.ClientConfigProfile; @@ -88,6 +86,4 @@ public static void main(String[] args) { } } } -/** - * @@@SNIPEND - */ +// @@@SNIPEND From 6244cbe2ac899e39980d9979132ad8f0631ac97d Mon Sep 17 00:00:00 2001 From: Kent Gruber Date: Thu, 29 Jan 2026 13:00:57 -0500 Subject: [PATCH 09/14] Set explicit permissions for GitHub Actions workflows (#758) This change was made by an automated process to ensure all GitHub Actions workflows have explicitly defined permissions as per best practices. --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8fc0b023a..54deeb6eb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,5 +1,7 @@ name: "Continuous Integration" on: [push, pull_request] +permissions: + contents: read jobs: validation: @@ -47,4 +49,4 @@ jobs: uses: gradle/actions/setup-gradle@v3 - name: Run copyright and code format checks - run: ./gradlew --no-daemon spotlessCheck \ No newline at end of file + run: ./gradlew --no-daemon spotlessCheck From bf3515d0bfc70e348838c6ee3bf8a2e7023c40c6 Mon Sep 17 00:00:00 2001 From: tconley1428 Date: Thu, 29 Jan 2026 15:37:37 -0800 Subject: [PATCH 10/14] fix: propagate unit test exit codes in CI workflow (#768) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: propagate unit test exit codes in CI workflow Add --exit-code-from flag to docker compose command to ensure unit test failures properly fail the GitHub Actions job. πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * Fix springboot test --------- Co-authored-by: Claude --- .github/workflows/ci.yml | 2 +- springboot/src/test/resources/application.yaml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 54deeb6eb..6eac7d64b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: - name: Run unit tests run: | - docker compose -f ./docker/github/docker-compose.yaml up unit-test + docker compose -f ./docker/github/docker-compose.yaml up --exit-code-from unit-test unit-test code_format: name: Code format diff --git a/springboot/src/test/resources/application.yaml b/springboot/src/test/resources/application.yaml index b81a11934..017d28f90 100644 --- a/springboot/src/test/resources/application.yaml +++ b/springboot/src/test/resources/application.yaml @@ -15,6 +15,7 @@ spring: # enable test server for testing test-server: enabled: true + ignore-duplicate-definitions: true # data source config for tests that need it datasource: url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;DB_CLOSE_ON_EXIT=FALSE; From 385adc4816f01dc8429cf5032d6e54a2a1c44360 Mon Sep 17 00:00:00 2001 From: Evan Reynolds Date: Mon, 30 Mar 2026 14:38:45 -0700 Subject: [PATCH 11/14] Code samples for testing and mocking Nexus (#771) * Code samples for testing and mocking Nexus * Formatting changes from Spotless * Added two more classes that mock the Nexus Service itself * Renamed EchoHandler to EchoClient * Updating gradle wrapper validator * Changed NexusService name for clarity, modified two tests * Suppressing two false warnings that turned into build errors --- .github/workflows/ci.yml | 4 +- .../samples/nexus/caller/CallerStarter.java | 7 +- .../samples/nexus/caller/CallerWorker.java | 2 +- .../nexus/caller/EchoCallerWorkflowImpl.java | 8 +- .../nexus/caller/HelloCallerWorkflow.java | 4 +- .../nexus/caller/HelloCallerWorkflowImpl.java | 12 +- .../samples/nexus/handler/EchoClient.java | 7 ++ .../samples/nexus/handler/EchoClientImpl.java | 12 ++ .../samples/nexus/handler/HandlerWorker.java | 2 +- .../nexus/handler/HelloHandlerWorkflow.java | 4 +- .../handler/HelloHandlerWorkflowImpl.java | 14 +-- ...eImpl.java => SampleNexusServiceImpl.java} | 36 ++++-- ...usService.java => SampleNexusService.java} | 2 +- .../samples/nexus/service/description.md | 4 +- .../caller/CallerWorker.java | 4 +- .../caller/HelloCallerWorkflowImpl.java | 23 ++-- .../handler/HandlerWorker.java | 4 +- .../handler/HelloHandlerWorkflowImpl.java | 14 +-- .../samples/nexuscontextpropagation/README.MD | 2 +- .../caller/CallerStarter.java | 7 +- .../caller/CallerWorker.java | 2 +- .../caller/EchoCallerWorkflowImpl.java | 8 +- .../caller/HelloCallerWorkflowImpl.java | 12 +- .../handler/HandlerWorker.java | 2 +- .../handler/HelloHandlerWorkflowImpl.java | 14 +-- ...eImpl.java => SampleNexusServiceImpl.java} | 14 +-- .../caller/CallerStarter.java | 7 +- .../caller/CallerWorker.java | 2 +- .../caller/EchoCallerWorkflowImpl.java | 8 +- .../caller/HelloCallerWorkflow.java | 4 +- .../caller/HelloCallerWorkflowImpl.java | 12 +- .../handler/HandlerWorker.java | 2 +- .../handler/HelloHandlerWorkflow.java | 4 +- .../handler/HelloHandlerWorkflowImpl.java | 14 +-- ...eImpl.java => SampleNexusServiceImpl.java} | 12 +- .../caller/CallerWorkflowJunit5MockTest.java | 79 +++++++++++++ .../caller/CallerWorkflowJunit5Test.java | 58 ++++++++++ .../nexus/caller/CallerWorkflowMockTest.java | 92 +++++++++++++++ .../nexus/caller/CallerWorkflowTest.java | 53 ++++----- .../nexus/caller/NexusServiceJunit5Test.java | 105 ++++++++++++++++++ .../nexus/caller/NexusServiceMockTest.java | 104 +++++++++++++++++ 41 files changed, 629 insertions(+), 151 deletions(-) create mode 100644 core/src/main/java/io/temporal/samples/nexus/handler/EchoClient.java create mode 100644 core/src/main/java/io/temporal/samples/nexus/handler/EchoClientImpl.java rename core/src/main/java/io/temporal/samples/nexus/handler/{NexusServiceImpl.java => SampleNexusServiceImpl.java} (62%) rename core/src/main/java/io/temporal/samples/nexus/service/{NexusService.java => SampleNexusService.java} (97%) rename core/src/main/java/io/temporal/samples/nexuscontextpropagation/handler/{NexusServiceImpl.java => SampleNexusServiceImpl.java} (84%) rename core/src/main/java/io/temporal/samples/nexusmultipleargs/handler/{NexusServiceImpl.java => SampleNexusServiceImpl.java} (86%) create mode 100644 core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowJunit5MockTest.java create mode 100644 core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowJunit5Test.java create mode 100644 core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowMockTest.java create mode 100644 core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceJunit5Test.java create mode 100644 core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceMockTest.java diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6eac7d64b..e3a085782 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 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 be1cc788e..f207d64cf 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 @@ -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; @@ -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)); } } 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 55186489e..5480917ba 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 @@ -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, 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 948008772..f76edbfe4 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,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() @@ -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(); } } 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 173c0be8b..1f78e9c02 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,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); } 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 f1612e359..6a6fe8dce 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,6 +1,6 @@ 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; @@ -8,9 +8,9 @@ import java.time.Duration; public class HelloCallerWorkflowImpl implements HelloCallerWorkflow { - NexusService nexusService = + SampleNexusService sampleNexusService = Workflow.newNexusServiceStub( - NexusService.class, + SampleNexusService.class, NexusServiceOptions.newBuilder() .setOperationOptions( NexusOperationOptions.newBuilder() @@ -19,10 +19,10 @@ public class HelloCallerWorkflowImpl implements HelloCallerWorkflow { .build()); @Override - public String hello(String message, NexusService.Language language) { - NexusOperationHandle handle = + public String hello(String message, SampleNexusService.Language language) { + NexusOperationHandle 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(); diff --git a/core/src/main/java/io/temporal/samples/nexus/handler/EchoClient.java b/core/src/main/java/io/temporal/samples/nexus/handler/EchoClient.java new file mode 100644 index 000000000..74b6f6c69 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/nexus/handler/EchoClient.java @@ -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); +} diff --git a/core/src/main/java/io/temporal/samples/nexus/handler/EchoClientImpl.java b/core/src/main/java/io/temporal/samples/nexus/handler/EchoClientImpl.java new file mode 100644 index 000000000..1c9a2e524 --- /dev/null +++ b/core/src/main/java/io/temporal/samples/nexus/handler/EchoClientImpl.java @@ -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()); + } +} 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 3d8afa3d7..656b18c65 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 @@ -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(); } 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 3cae13b31..2c85d0792 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,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); } 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 c897a5181..b896ab523 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,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"); diff --git a/core/src/main/java/io/temporal/samples/nexus/handler/NexusServiceImpl.java b/core/src/main/java/io/temporal/samples/nexus/handler/SampleNexusServiceImpl.java similarity index 62% rename from core/src/main/java/io/temporal/samples/nexus/handler/NexusServiceImpl.java rename to core/src/main/java/io/temporal/samples/nexus/handler/SampleNexusServiceImpl.java index 2344f27ec..42952b72b 100644 --- a/core/src/main/java/io/temporal/samples/nexus/handler/NexusServiceImpl.java +++ b/core/src/main/java/io/temporal/samples/nexus/handler/SampleNexusServiceImpl.java @@ -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 echo() { - // OperationHandler.sync is a meant for exposing simple RPC handlers. + public OperationHandler 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 hello() { + public OperationHandler 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 @@ -39,10 +55,8 @@ public OperationHandler 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. // diff --git a/core/src/main/java/io/temporal/samples/nexus/service/NexusService.java b/core/src/main/java/io/temporal/samples/nexus/service/SampleNexusService.java similarity index 97% rename from core/src/main/java/io/temporal/samples/nexus/service/NexusService.java rename to core/src/main/java/io/temporal/samples/nexus/service/SampleNexusService.java index ad65b1b33..180f9ec28 100644 --- a/core/src/main/java/io/temporal/samples/nexus/service/NexusService.java +++ b/core/src/main/java/io/temporal/samples/nexus/service/SampleNexusService.java @@ -6,7 +6,7 @@ import io.nexusrpc.Service; @Service -public interface NexusService { +public interface SampleNexusService { enum Language { EN, FR, 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 index d79e151cd..b1cafb3a2 100644 --- a/core/src/main/java/io/temporal/samples/nexus/service/description.md +++ b/core/src/main/java/io/temporal/samples/nexus/service/description.md @@ -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. diff --git a/core/src/main/java/io/temporal/samples/nexuscancellation/caller/CallerWorker.java b/core/src/main/java/io/temporal/samples/nexuscancellation/caller/CallerWorker.java index cb05189cf..811cecde8 100644 --- a/core/src/main/java/io/temporal/samples/nexuscancellation/caller/CallerWorker.java +++ b/core/src/main/java/io/temporal/samples/nexuscancellation/caller/CallerWorker.java @@ -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; @@ -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); diff --git a/core/src/main/java/io/temporal/samples/nexuscancellation/caller/HelloCallerWorkflowImpl.java b/core/src/main/java/io/temporal/samples/nexuscancellation/caller/HelloCallerWorkflowImpl.java index 1bea801c8..6072906b4 100644 --- a/core/src/main/java/io/temporal/samples/nexuscancellation/caller/HelloCallerWorkflowImpl.java +++ b/core/src/main/java/io/temporal/samples/nexuscancellation/caller/HelloCallerWorkflowImpl.java @@ -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; @@ -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() @@ -33,7 +33,7 @@ public class HelloCallerWorkflowImpl implements HelloCallerWorkflow { @Override public String hello(String message) { - List> results = new ArrayList<>(languages.length); + List> results = new ArrayList<>(languages.length); /* * Create our CancellationScope. Within this scope we call the nexus operation asynchronously @@ -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))); } }); @@ -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 @@ -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 promise : results) { + for (Promise promise : results) { try { promise.get(); } catch (NexusOperationFailure e) { diff --git a/core/src/main/java/io/temporal/samples/nexuscancellation/handler/HandlerWorker.java b/core/src/main/java/io/temporal/samples/nexuscancellation/handler/HandlerWorker.java index 8b8949a70..f7d0f6940 100644 --- a/core/src/main/java/io/temporal/samples/nexuscancellation/handler/HandlerWorker.java +++ b/core/src/main/java/io/temporal/samples/nexuscancellation/handler/HandlerWorker.java @@ -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; @@ -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(); } diff --git a/core/src/main/java/io/temporal/samples/nexuscancellation/handler/HelloHandlerWorkflowImpl.java b/core/src/main/java/io/temporal/samples/nexuscancellation/handler/HelloHandlerWorkflowImpl.java index ca6510f60..de8b93557 100644 --- a/core/src/main/java/io/temporal/samples/nexuscancellation/handler/HelloHandlerWorkflowImpl.java +++ b/core/src/main/java/io/temporal/samples/nexuscancellation/handler/HelloHandlerWorkflowImpl.java @@ -3,7 +3,7 @@ import io.temporal.failure.ApplicationFailure; import io.temporal.failure.CanceledFailure; import io.temporal.samples.nexus.handler.HelloHandlerWorkflow; -import io.temporal.samples.nexus.service.NexusService; +import io.temporal.samples.nexus.service.SampleNexusService; import io.temporal.workflow.Workflow; import java.time.Duration; import org.slf4j.Logger; @@ -12,21 +12,21 @@ public class HelloHandlerWorkflowImpl implements HelloHandlerWorkflow { public static final Logger log = Workflow.getLogger(HelloHandlerWorkflowImpl.class); @Override - public NexusService.HelloOutput hello(NexusService.HelloInput input) { + public SampleNexusService.HelloOutput hello(SampleNexusService.HelloInput input) { // Sleep for a random duration to simulate some work try { Workflow.sleep(Duration.ofSeconds(Workflow.newRandom().nextInt(5))); 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"); diff --git a/core/src/main/java/io/temporal/samples/nexuscontextpropagation/README.MD b/core/src/main/java/io/temporal/samples/nexuscontextpropagation/README.MD index 79453cc4d..54e2bc4f9 100644 --- a/core/src/main/java/io/temporal/samples/nexuscontextpropagation/README.MD +++ b/core/src/main/java/io/temporal/samples/nexuscontextpropagation/README.MD @@ -40,6 +40,6 @@ INFO i.t.s.n.caller.CallerStarter - Workflow result: Hello Nexus πŸ‘‹ And this on the handler side: ``` -INFO i.t.s.n.handler.NexusServiceImpl - Echo called from a workflow with ID : 7ac97cb9-b457-4052-af94-d82478c35c5e +INFO i.t.s.n.handler.SampleNexusServiceImpl - Echo called from a workflow with ID : 7ac97cb9-b457-4052-af94-d82478c35c5e INFO i.t.s.n.h.HelloHandlerWorkflowImpl - HelloHandlerWorkflow called from a workflow with ID : 9e0bc89c-5709-4742-b7c0-868464c2fccf ``` diff --git a/core/src/main/java/io/temporal/samples/nexuscontextpropagation/caller/CallerStarter.java b/core/src/main/java/io/temporal/samples/nexuscontextpropagation/caller/CallerStarter.java index f0896221a..cfcc739de 100644 --- a/core/src/main/java/io/temporal/samples/nexuscontextpropagation/caller/CallerStarter.java +++ b/core/src/main/java/io/temporal/samples/nexuscontextpropagation/caller/CallerStarter.java @@ -7,7 +7,7 @@ import io.temporal.samples.nexus.caller.EchoCallerWorkflow; import io.temporal.samples.nexus.caller.HelloCallerWorkflow; import io.temporal.samples.nexus.options.ClientOptions; -import io.temporal.samples.nexus.service.NexusService; +import io.temporal.samples.nexus.service.SampleNexusService; import io.temporal.samples.nexuscontextpropagation.propagation.MDCContextPropagator; import java.util.Collections; import org.slf4j.Logger; @@ -35,11 +35,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)); } } diff --git a/core/src/main/java/io/temporal/samples/nexuscontextpropagation/caller/CallerWorker.java b/core/src/main/java/io/temporal/samples/nexuscontextpropagation/caller/CallerWorker.java index 13e568822..db3f1cfb9 100644 --- a/core/src/main/java/io/temporal/samples/nexuscontextpropagation/caller/CallerWorker.java +++ b/core/src/main/java/io/temporal/samples/nexuscontextpropagation/caller/CallerWorker.java @@ -28,7 +28,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, diff --git a/core/src/main/java/io/temporal/samples/nexuscontextpropagation/caller/EchoCallerWorkflowImpl.java b/core/src/main/java/io/temporal/samples/nexuscontextpropagation/caller/EchoCallerWorkflowImpl.java index 14e998629..3de27350d 100644 --- a/core/src/main/java/io/temporal/samples/nexuscontextpropagation/caller/EchoCallerWorkflowImpl.java +++ b/core/src/main/java/io/temporal/samples/nexuscontextpropagation/caller/EchoCallerWorkflowImpl.java @@ -1,7 +1,7 @@ package io.temporal.samples.nexuscontextpropagation.caller; import io.temporal.samples.nexus.caller.EchoCallerWorkflow; -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; @@ -9,9 +9,9 @@ import org.slf4j.MDC; public class EchoCallerWorkflowImpl implements EchoCallerWorkflow { - NexusService nexusService = + SampleNexusService sampleNexusService = Workflow.newNexusServiceStub( - NexusService.class, + SampleNexusService.class, NexusServiceOptions.newBuilder() .setOperationOptions( NexusOperationOptions.newBuilder() @@ -22,6 +22,6 @@ public class EchoCallerWorkflowImpl implements EchoCallerWorkflow { @Override public String echo(String message) { MDC.put("x-nexus-caller-workflow-id", Workflow.getInfo().getWorkflowId()); - return nexusService.echo(new NexusService.EchoInput(message)).getMessage(); + return sampleNexusService.echo(new SampleNexusService.EchoInput(message)).getMessage(); } } diff --git a/core/src/main/java/io/temporal/samples/nexuscontextpropagation/caller/HelloCallerWorkflowImpl.java b/core/src/main/java/io/temporal/samples/nexuscontextpropagation/caller/HelloCallerWorkflowImpl.java index fedefbc34..b817179a4 100644 --- a/core/src/main/java/io/temporal/samples/nexuscontextpropagation/caller/HelloCallerWorkflowImpl.java +++ b/core/src/main/java/io/temporal/samples/nexuscontextpropagation/caller/HelloCallerWorkflowImpl.java @@ -1,7 +1,7 @@ package io.temporal.samples.nexuscontextpropagation.caller; import io.temporal.samples.nexus.caller.HelloCallerWorkflow; -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; @@ -10,9 +10,9 @@ import org.slf4j.MDC; public class HelloCallerWorkflowImpl implements HelloCallerWorkflow { - NexusService nexusService = + SampleNexusService sampleNexusService = Workflow.newNexusServiceStub( - NexusService.class, + SampleNexusService.class, NexusServiceOptions.newBuilder() .setOperationOptions( NexusOperationOptions.newBuilder() @@ -21,11 +21,11 @@ public class HelloCallerWorkflowImpl implements HelloCallerWorkflow { .build()); @Override - public String hello(String message, NexusService.Language language) { + public String hello(String message, SampleNexusService.Language language) { MDC.put("x-nexus-caller-workflow-id", Workflow.getInfo().getWorkflowId()); - NexusOperationHandle handle = + NexusOperationHandle 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(); diff --git a/core/src/main/java/io/temporal/samples/nexuscontextpropagation/handler/HandlerWorker.java b/core/src/main/java/io/temporal/samples/nexuscontextpropagation/handler/HandlerWorker.java index c4f9ef54c..31b665a8a 100644 --- a/core/src/main/java/io/temporal/samples/nexuscontextpropagation/handler/HandlerWorker.java +++ b/core/src/main/java/io/temporal/samples/nexuscontextpropagation/handler/HandlerWorker.java @@ -29,7 +29,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(); } diff --git a/core/src/main/java/io/temporal/samples/nexuscontextpropagation/handler/HelloHandlerWorkflowImpl.java b/core/src/main/java/io/temporal/samples/nexuscontextpropagation/handler/HelloHandlerWorkflowImpl.java index a2db3cb0e..324ad34c1 100644 --- a/core/src/main/java/io/temporal/samples/nexuscontextpropagation/handler/HelloHandlerWorkflowImpl.java +++ b/core/src/main/java/io/temporal/samples/nexuscontextpropagation/handler/HelloHandlerWorkflowImpl.java @@ -2,7 +2,7 @@ import io.temporal.failure.ApplicationFailure; import io.temporal.samples.nexus.handler.HelloHandlerWorkflow; -import io.temporal.samples.nexus.service.NexusService; +import io.temporal.samples.nexus.service.SampleNexusService; import io.temporal.workflow.Workflow; import org.slf4j.Logger; import org.slf4j.MDC; @@ -11,7 +11,7 @@ public class HelloHandlerWorkflowImpl implements HelloHandlerWorkflow { public static final Logger log = Workflow.getLogger(HelloHandlerWorkflowImpl.class); @Override - public NexusService.HelloOutput hello(NexusService.HelloInput input) { + public SampleNexusService.HelloOutput hello(SampleNexusService.HelloInput input) { if (MDC.get("x-nexus-caller-workflow-id") != null) { log.info( "HelloHandlerWorkflow called from a workflow with ID : {}", @@ -19,15 +19,15 @@ public NexusService.HelloOutput hello(NexusService.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"); diff --git a/core/src/main/java/io/temporal/samples/nexuscontextpropagation/handler/NexusServiceImpl.java b/core/src/main/java/io/temporal/samples/nexuscontextpropagation/handler/SampleNexusServiceImpl.java similarity index 84% rename from core/src/main/java/io/temporal/samples/nexuscontextpropagation/handler/NexusServiceImpl.java rename to core/src/main/java/io/temporal/samples/nexuscontextpropagation/handler/SampleNexusServiceImpl.java index 4977ff0c0..fc69e756b 100644 --- a/core/src/main/java/io/temporal/samples/nexuscontextpropagation/handler/NexusServiceImpl.java +++ b/core/src/main/java/io/temporal/samples/nexuscontextpropagation/handler/SampleNexusServiceImpl.java @@ -7,7 +7,7 @@ import io.temporal.nexus.Nexus; import io.temporal.nexus.WorkflowRunOperation; import io.temporal.samples.nexus.handler.HelloHandlerWorkflow; -import io.temporal.samples.nexus.service.NexusService; +import io.temporal.samples.nexus.service.SampleNexusService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.MDC; @@ -15,12 +15,12 @@ // 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 { - private static final Logger logger = LoggerFactory.getLogger(NexusServiceImpl.class); +@ServiceImpl(service = SampleNexusService.class) +public class SampleNexusServiceImpl { + private static final Logger logger = LoggerFactory.getLogger(SampleNexusServiceImpl.class); @OperationImpl - public OperationHandler echo() { + public OperationHandler echo() { // OperationHandler.sync is a meant for exposing simple RPC handlers. return OperationHandler.sync( // The method is for making arbitrary short calls to other services or databases, or @@ -33,12 +33,12 @@ public OperationHandler echo() logger.info( "Echo called from a workflow with ID : {}", MDC.get("x-nexus-caller-workflow-id")); } - return new NexusService.EchoOutput(input.getMessage()); + return new SampleNexusService.EchoOutput(input.getMessage()); }); } @OperationImpl - public OperationHandler hello() { + public OperationHandler 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 diff --git a/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/CallerStarter.java b/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/CallerStarter.java index beebdf406..4d3e7cff5 100644 --- a/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/CallerStarter.java +++ b/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/CallerStarter.java @@ -7,7 +7,7 @@ import io.temporal.samples.nexus.caller.EchoCallerWorkflow; import io.temporal.samples.nexus.caller.HelloCallerWorkflow; 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; @@ -29,11 +29,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)); } } diff --git a/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/CallerWorker.java b/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/CallerWorker.java index 1db03a677..64272e6a2 100644 --- a/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/CallerWorker.java +++ b/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/CallerWorker.java @@ -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, diff --git a/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/EchoCallerWorkflowImpl.java b/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/EchoCallerWorkflowImpl.java index ea9aaabb0..20d875ddb 100644 --- a/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/EchoCallerWorkflowImpl.java +++ b/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/EchoCallerWorkflowImpl.java @@ -1,16 +1,16 @@ package io.temporal.samples.nexusmultipleargs.caller; import io.temporal.samples.nexus.caller.EchoCallerWorkflow; -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() @@ -20,6 +20,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(); } } diff --git a/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/HelloCallerWorkflow.java b/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/HelloCallerWorkflow.java index aeb7a13db..03a8635ed 100644 --- a/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/HelloCallerWorkflow.java +++ b/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/HelloCallerWorkflow.java @@ -1,11 +1,11 @@ package io.temporal.samples.nexusmultipleargs.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); } diff --git a/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/HelloCallerWorkflowImpl.java b/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/HelloCallerWorkflowImpl.java index 94f4c3fc5..5d3c0824b 100644 --- a/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/HelloCallerWorkflowImpl.java +++ b/core/src/main/java/io/temporal/samples/nexusmultipleargs/caller/HelloCallerWorkflowImpl.java @@ -1,7 +1,7 @@ package io.temporal.samples.nexusmultipleargs.caller; import io.temporal.samples.nexus.caller.HelloCallerWorkflow; -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; @@ -9,9 +9,9 @@ import java.time.Duration; public class HelloCallerWorkflowImpl implements HelloCallerWorkflow { - NexusService nexusService = + SampleNexusService sampleNexusService = Workflow.newNexusServiceStub( - NexusService.class, + SampleNexusService.class, NexusServiceOptions.newBuilder() .setOperationOptions( NexusOperationOptions.newBuilder() @@ -20,10 +20,10 @@ public class HelloCallerWorkflowImpl implements HelloCallerWorkflow { .build()); @Override - public String hello(String message, NexusService.Language language) { - NexusOperationHandle handle = + public String hello(String message, SampleNexusService.Language language) { + NexusOperationHandle 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(); diff --git a/core/src/main/java/io/temporal/samples/nexusmultipleargs/handler/HandlerWorker.java b/core/src/main/java/io/temporal/samples/nexusmultipleargs/handler/HandlerWorker.java index 0ec77889c..c3fd95e9f 100644 --- a/core/src/main/java/io/temporal/samples/nexusmultipleargs/handler/HandlerWorker.java +++ b/core/src/main/java/io/temporal/samples/nexusmultipleargs/handler/HandlerWorker.java @@ -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(); } diff --git a/core/src/main/java/io/temporal/samples/nexusmultipleargs/handler/HelloHandlerWorkflow.java b/core/src/main/java/io/temporal/samples/nexusmultipleargs/handler/HelloHandlerWorkflow.java index 0a443d468..d13906496 100644 --- a/core/src/main/java/io/temporal/samples/nexusmultipleargs/handler/HelloHandlerWorkflow.java +++ b/core/src/main/java/io/temporal/samples/nexusmultipleargs/handler/HelloHandlerWorkflow.java @@ -1,11 +1,11 @@ package io.temporal.samples.nexusmultipleargs.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(String name, NexusService.Language language); + SampleNexusService.HelloOutput hello(String name, SampleNexusService.Language language); } diff --git a/core/src/main/java/io/temporal/samples/nexusmultipleargs/handler/HelloHandlerWorkflowImpl.java b/core/src/main/java/io/temporal/samples/nexusmultipleargs/handler/HelloHandlerWorkflowImpl.java index b802cee34..9d9cc3733 100644 --- a/core/src/main/java/io/temporal/samples/nexusmultipleargs/handler/HelloHandlerWorkflowImpl.java +++ b/core/src/main/java/io/temporal/samples/nexusmultipleargs/handler/HelloHandlerWorkflowImpl.java @@ -1,22 +1,22 @@ package io.temporal.samples.nexusmultipleargs.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(String name, NexusService.Language language) { + public SampleNexusService.HelloOutput hello(String name, SampleNexusService.Language language) { switch (language) { case EN: - return new NexusService.HelloOutput("Hello " + name + " πŸ‘‹"); + return new SampleNexusService.HelloOutput("Hello " + name + " πŸ‘‹"); case FR: - return new NexusService.HelloOutput("Bonjour " + name + " πŸ‘‹"); + return new SampleNexusService.HelloOutput("Bonjour " + name + " πŸ‘‹"); case DE: - return new NexusService.HelloOutput("Hallo " + name + " πŸ‘‹"); + return new SampleNexusService.HelloOutput("Hallo " + name + " πŸ‘‹"); case ES: - return new NexusService.HelloOutput("Β‘Hola! " + name + " πŸ‘‹"); + return new SampleNexusService.HelloOutput("Β‘Hola! " + name + " πŸ‘‹"); case TR: - return new NexusService.HelloOutput("Merhaba " + name + " πŸ‘‹"); + return new SampleNexusService.HelloOutput("Merhaba " + name + " πŸ‘‹"); } throw ApplicationFailure.newFailure( "Unsupported language: " + language, "UNSUPPORTED_LANGUAGE"); diff --git a/core/src/main/java/io/temporal/samples/nexusmultipleargs/handler/NexusServiceImpl.java b/core/src/main/java/io/temporal/samples/nexusmultipleargs/handler/SampleNexusServiceImpl.java similarity index 86% rename from core/src/main/java/io/temporal/samples/nexusmultipleargs/handler/NexusServiceImpl.java rename to core/src/main/java/io/temporal/samples/nexusmultipleargs/handler/SampleNexusServiceImpl.java index 20d55fed8..b5d819267 100644 --- a/core/src/main/java/io/temporal/samples/nexusmultipleargs/handler/NexusServiceImpl.java +++ b/core/src/main/java/io/temporal/samples/nexusmultipleargs/handler/SampleNexusServiceImpl.java @@ -7,15 +7,15 @@ import io.temporal.nexus.Nexus; import io.temporal.nexus.WorkflowHandle; 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 { @OperationImpl - public OperationHandler echo() { + public OperationHandler echo() { // OperationHandler.sync is a meant for exposing simple RPC handlers. return OperationHandler.sync( // The method is for making arbitrary short calls to other services or databases, or @@ -23,11 +23,11 @@ public OperationHandler echo() // 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) -> new SampleNexusService.EchoOutput(input.getMessage())); } @OperationImpl - public OperationHandler hello() { + public OperationHandler hello() { // If the operation input parameters are different from the workflow input parameters, // use the WorkflowRunOperation.fromWorkflowHandler constructor and the appropriate constructor // method on WorkflowHandle to map the Nexus input to the workflow parameters. diff --git a/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowJunit5MockTest.java b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowJunit5MockTest.java new file mode 100644 index 000000000..ca038ee0e --- /dev/null +++ b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowJunit5MockTest.java @@ -0,0 +1,79 @@ +package io.temporal.samples.nexus.caller; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.*; + +import io.temporal.samples.nexus.handler.EchoClient; +import io.temporal.samples.nexus.handler.HelloHandlerWorkflow; +import io.temporal.samples.nexus.handler.SampleNexusServiceImpl; +import io.temporal.samples.nexus.service.SampleNexusService; +import io.temporal.testing.TestWorkflowEnvironment; +import io.temporal.testing.TestWorkflowExtension; +import io.temporal.worker.Worker; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +// This is an example of how to unit test Nexus services in JUnit5. The handlers are mocked, +// so that the caller classes interact with the mocks and not the handler classes themselves. + +public class CallerWorkflowJunit5MockTest { + + // Sync Nexus operations run inline in the handler thread β€” there is no backing workflow to + // register a factory for. To mock one, inject a mock dependency into the service implementation. + private static final EchoClient mockEchoClient = mock(EchoClient.class); + + @RegisterExtension + public static final TestWorkflowExtension testWorkflowExtension = + TestWorkflowExtension.newBuilder() + // If a Nexus service is registered as part of the test as in the following line of code, + // the TestWorkflowExtension will, by default, automatically create a Nexus service + // endpoint and workflows registered as part of the TestWorkflowExtension will + // automatically inherit the endpoint if none is set. + .setNexusServiceImplementation(new SampleNexusServiceImpl(mockEchoClient)) + // The Echo Nexus handler service just makes a call to a class, so no extra setup is + // needed. But the Hello Nexus service needs a worker for both the caller and handler + // in order to run, and the Echo Nexus caller service needs a worker. + // + // registerWorkflowImplementationTypes will take the classes given and create workers for + // them, enabling workflows to run. + .registerWorkflowImplementationTypes( + HelloCallerWorkflowImpl.class, EchoCallerWorkflowImpl.class) + .setDoNotStart(true) + .build(); + + @Test + public void testHelloWorkflow( + TestWorkflowEnvironment testEnv, Worker worker, HelloCallerWorkflow workflow) { + // Workflows started by a Nexus service can be mocked just like any other workflow + worker.registerWorkflowImplementationFactory( + HelloHandlerWorkflow.class, + () -> { + HelloHandlerWorkflow mockHandler = mock(HelloHandlerWorkflow.class); + when(mockHandler.hello(any())) + .thenReturn(new SampleNexusService.HelloOutput("Hello Mock World πŸ‘‹")); + return mockHandler; + }); + testEnv.start(); + + // Execute a workflow waiting for it to complete. + String greeting = workflow.hello("World", SampleNexusService.Language.EN); + assertEquals("Hello Mock World πŸ‘‹", greeting); + + testEnv.shutdown(); + } + + @Test + public void testEchoWorkflow( + TestWorkflowEnvironment testEnv, Worker worker, EchoCallerWorkflow workflow) { + // Sync Nexus operations run inline in the handler thread β€” there is no backing workflow to + // register a factory for. Instead, stub the injected EchoClient dependency directly. + when(mockEchoClient.echo(any())).thenReturn(new SampleNexusService.EchoOutput("mocked echo")); + testEnv.start(); + + // Execute a workflow waiting for it to complete. + String greeting = workflow.echo("Hello"); + assertEquals("mocked echo", greeting); + + testEnv.shutdown(); + } +} diff --git a/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowJunit5Test.java b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowJunit5Test.java new file mode 100644 index 000000000..3da730c14 --- /dev/null +++ b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowJunit5Test.java @@ -0,0 +1,58 @@ +package io.temporal.samples.nexus.caller; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import io.temporal.samples.nexus.handler.HelloHandlerWorkflowImpl; +import io.temporal.samples.nexus.handler.SampleNexusServiceImpl; +import io.temporal.samples.nexus.service.SampleNexusService; +import io.temporal.testing.TestWorkflowEnvironment; +import io.temporal.testing.TestWorkflowExtension; +import io.temporal.worker.Worker; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +// This is an example of how to unit test Nexus services in JUnit5. The handlers are not mocked, +// but are actually called by the testing framework by the caller classes. + +public class CallerWorkflowJunit5Test { + + @RegisterExtension + public static final TestWorkflowExtension testWorkflowExtension = + TestWorkflowExtension.newBuilder() + // If a Nexus service is registered as part of the test as in the following line of code, + // the TestWorkflowExtension will, by default, automatically create a Nexus service + // endpoint and workflows registered as part of the TestWorkflowExtension will + // automatically inherit the endpoint if none is set. + .setNexusServiceImplementation(new SampleNexusServiceImpl()) + // The Echo Nexus handler service just makes a call to a class, so no extra setup is + // needed. But the Hello Nexus service needs a worker for both the caller and handler + // in order to run, and the Echo Nexus caller service needs a worker. + // + // registerWorkflowImplementationTypes will take the classes given and create workers for + // them, enabling workflows to run. + .registerWorkflowImplementationTypes( + HelloCallerWorkflowImpl.class, + HelloHandlerWorkflowImpl.class, + EchoCallerWorkflowImpl.class) + // The workflow will start before each test, and will shut down after each test. + // See CallerWorkflowTest for an example of how to control this differently if needed. + .build(); + + // The TestWorkflowExtension extension in the Temporal testing library creates the + // arguments to the test cases and initializes them from the extension setup call above. + @Test + public void testHelloWorkflow( + TestWorkflowEnvironment testEnv, Worker worker, HelloCallerWorkflow workflow) { + // Execute a workflow waiting for it to complete. + String greeting = workflow.hello("World", SampleNexusService.Language.EN); + assertEquals("Hello World πŸ‘‹", greeting); + } + + @Test + public void testEchoWorkflow( + TestWorkflowEnvironment testEnv, Worker worker, EchoCallerWorkflow workflow) { + // Execute a workflow waiting for it to complete. + String greeting = workflow.echo("Hello"); + assertEquals("Hello", greeting); + } +} diff --git a/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowMockTest.java b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowMockTest.java new file mode 100644 index 000000000..c899713a2 --- /dev/null +++ b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowMockTest.java @@ -0,0 +1,92 @@ +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.EchoClient; +import io.temporal.samples.nexus.handler.HelloHandlerWorkflow; +import io.temporal.samples.nexus.handler.SampleNexusServiceImpl; +import io.temporal.samples.nexus.service.SampleNexusService; +import io.temporal.testing.TestWorkflowRule; +import org.junit.Rule; +import org.junit.Test; + +// This is an example of how to unit test Nexus services in JUnit4. The handlers are mocked, +// so that the caller classes interact with the mocks and not the handler classes themselves. + +public class CallerWorkflowMockTest { + + // Inject a mock EchoClient so sync Nexus operations can be stubbed per test. + // JUnit 4 creates a new test class instance per test method, so this mock is fresh each time. + private final EchoClient mockEchoClient = mock(EchoClient.class); + + @Rule + public TestWorkflowRule testWorkflowRule = + TestWorkflowRule.newBuilder() + // If a Nexus service is registered as part of the test as in the following line of code, + // 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 SampleNexusServiceImpl(mockEchoClient)) + // The Echo Nexus handler service just makes a call to a class, so no extra setup is + // needed. But the Hello Nexus service needs a worker for both the caller and handler + // in order to run. + // setWorkflowTypes will take the classes given and create workers for them, enabling + // workflows to run. This creates caller workflows, the handler workflows + // will be mocked in the test methods. + .setWorkflowTypes(HelloCallerWorkflowImpl.class, EchoCallerWorkflowImpl.class) + // Disable automatic worker startup as we are going to register some workflows manually + // per test + .setDoNotStart(true) + .build(); + + @Test + public void testHelloWorkflow() { + testWorkflowRule + .getWorker() + // Workflows started by a Nexus service can be mocked just like any other workflow + .registerWorkflowImplementationFactory( + HelloHandlerWorkflow.class, + () -> { + HelloHandlerWorkflow wf = mock(HelloHandlerWorkflow.class); + when(wf.hello(any())) + .thenReturn(new SampleNexusService.HelloOutput("Hello Mock World πŸ‘‹")); + return wf; + }); + testWorkflowRule.getTestEnvironment().start(); + + // Now create the caller workflow + HelloCallerWorkflow workflow = + testWorkflowRule + .getWorkflowClient() + .newWorkflowStub( + HelloCallerWorkflow.class, + WorkflowOptions.newBuilder().setTaskQueue(testWorkflowRule.getTaskQueue()).build()); + String greeting = workflow.hello("World", SampleNexusService.Language.EN); + assertEquals("Hello Mock World πŸ‘‹", greeting); + + testWorkflowRule.getTestEnvironment().shutdown(); + } + + @Test + public void testEchoWorkflow() { + // Sync Nexus operations run inline in the handler thread β€” there is no backing workflow to + // register a factory for. Instead, stub the injected EchoCient dependency directly. + when(mockEchoClient.echo(any())).thenReturn(new SampleNexusService.EchoOutput("mocked echo")); + testWorkflowRule.getTestEnvironment().start(); + + EchoCallerWorkflow workflow = + testWorkflowRule + .getWorkflowClient() + .newWorkflowStub( + EchoCallerWorkflow.class, + WorkflowOptions.newBuilder().setTaskQueue(testWorkflowRule.getTaskQueue()).build()); + String greeting = workflow.echo("Hello"); + assertEquals("mocked echo", greeting); + + testWorkflowRule.getTestEnvironment().shutdown(); + } +} 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 2d3a6e42a..682995e61 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,14 +1,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; -import io.temporal.samples.nexus.service.NexusService; +import io.temporal.samples.nexus.handler.HelloHandlerWorkflowImpl; +import io.temporal.samples.nexus.handler.SampleNexusServiceImpl; +import io.temporal.samples.nexus.service.SampleNexusService; import io.temporal.testing.TestWorkflowRule; import io.temporal.worker.WorkflowImplementationOptions; import io.temporal.workflow.NexusServiceOptions; @@ -16,16 +13,27 @@ import org.junit.Rule; import org.junit.Test; +// This is an example of how to unit test Nexus services in JUnit4. The handlers are not mocked, +// but are actually called by the testing framework by the caller classes. + 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) + // If a Nexus service is registered as part of the test as in the following line of code, + // 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 SampleNexusServiceImpl()) + // The Echo Nexus handler service just makes a call to a class, so no extra setup is + // needed. But the Hello Nexus service needs a worker for both the caller and handler + // in order to run. + // setWorkflowTypes will take the classes given and create workers for them, enabling + // workflows to run. This is not adding an EchoCallerWorkflow though - + // see the testEchoWorkflow test method below for an example of an alternate way + // to supply a worker that gives you more flexibility if needed. + .setWorkflowTypes(HelloCallerWorkflowImpl.class, HelloHandlerWorkflowImpl.class) // Disable automatic worker startup as we are going to register some workflows manually // per test .setDoNotStart(true) @@ -33,16 +41,6 @@ public class CallerWorkflowTest { @Test public void testHelloWorkflow() { - testWorkflowRule - .getWorker() - // Workflows started by a Nexus service can be mocked just like any other workflow - .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 = @@ -51,7 +49,7 @@ public void testHelloWorkflow() { .newWorkflowStub( HelloCallerWorkflow.class, WorkflowOptions.newBuilder().setTaskQueue(testWorkflowRule.getTaskQueue()).build()); - String greeting = workflow.hello("World", NexusService.Language.EN); + String greeting = workflow.hello("World", SampleNexusService.Language.EN); assertEquals("Hello World πŸ‘‹", greeting); testWorkflowRule.getTestEnvironment().shutdown(); @@ -61,15 +59,20 @@ 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. To demonstrate, this is creating the Nexus service for Echo, + // and registering a EchoCallerWorkflowImpl worker. + // + // It is much simpler to use the setWorkflowTypes in the rule definition above - and as + // this isn't easily do-able in JUnit5 (the nexus endpoint isn't exposed) should be + // used with caution. testWorkflowRule .getWorker() .registerWorkflowImplementationTypes( WorkflowImplementationOptions.newBuilder() .setNexusServiceOptions( Collections.singletonMap( - "NexusService", + "SampleNexusService", NexusServiceOptions.newBuilder() .setEndpoint(testWorkflowRule.getNexusEndpoint().getSpec().getName()) .build())) diff --git a/core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceJunit5Test.java b/core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceJunit5Test.java new file mode 100644 index 000000000..c5fd578c0 --- /dev/null +++ b/core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceJunit5Test.java @@ -0,0 +1,105 @@ +package io.temporal.samples.nexus.caller; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +import io.nexusrpc.handler.OperationHandler; +import io.nexusrpc.handler.OperationImpl; +import io.nexusrpc.handler.ServiceImpl; +import io.temporal.samples.nexus.service.SampleNexusService; +import io.temporal.testing.TestWorkflowEnvironment; +import io.temporal.testing.TestWorkflowExtension; +import io.temporal.worker.Worker; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +// This unit test example shows how to mock the Nexus service itself in JUnit4. +// This is the path to take when you don't have access to the service implementation so +// cannot mock it. Since the SampleNexusService itself is mocked, +// no handlers need to be set up or mocked. +public class NexusServiceJunit5Test { + + private final SampleNexusService mockNexusService = mock(SampleNexusService.class); + + /** + * A test-only Nexus service implementation that delegates to the Mockito mock defined above. Both + * operations are implemented as synchronous handlers that forward calls to the mock, allowing + * full control over return values and verification of inputs. + */ + @ServiceImpl(service = SampleNexusService.class) + public class TestNexusServiceImpl { + @OperationImpl + @SuppressWarnings("DirectInvocationOnMock") + public OperationHandler echo() { + return OperationHandler.sync((ctx, details, input) -> mockNexusService.echo(input)); + } + + @OperationImpl + @SuppressWarnings("DirectInvocationOnMock") + public OperationHandler hello() { + return OperationHandler.sync((ctx, details, input) -> mockNexusService.hello(input)); + } + } + + // Using OperationHandler.sync for both operations bypasses the need for a backing workflow, + // returning results inline just like a synchronous call. + // + // Note that the Mocks need to be done before the extension + // is defined, as creating the rule will fail if either call is still null. + + @RegisterExtension + public final TestWorkflowExtension testWorkflowExtension = + TestWorkflowExtension.newBuilder() + // If a Nexus service is registered as part of the test as in the following line of code, + // the TestWorkflowExtension will, by default, automatically create a Nexus service + // endpoint and workflows registered as part of the TestWorkflowExtension will + // automatically inherit the endpoint if none is set. + .setNexusServiceImplementation(new TestNexusServiceImpl()) + // The Echo Nexus handler service just makes a call to a class, so no extra setup is + // needed. But the Hello Nexus service needs a worker for both the caller and handler + // in order to run, and the Echo Nexus caller service needs a worker. + // + // registerWorkflowImplementationTypes will take the classes given and create workers for + // them, enabling workflows to run. + // Since both operations are mocked with OperationHandler.sync, no backing workflow is + // needed for hello β€” only the caller workflow types need to be registered. + .registerWorkflowImplementationTypes( + HelloCallerWorkflowImpl.class, EchoCallerWorkflowImpl.class) + // The workflow will start before each test, and will shut down after each test. + // See CallerWorkflowTest for an example of how to control this differently if needed. + .build(); + + // The TestWorkflowExtension extension in the Temporal testing library creates the + // arguments to the test cases and initializes them from the extension setup call above. + @Test + public void testHelloWorkflow( + TestWorkflowEnvironment testEnv, Worker worker, HelloCallerWorkflow workflow) { + + // Set the mock value to return + when(mockNexusService.hello(any())) + .thenReturn(new SampleNexusService.HelloOutput("Hello Mock World πŸ‘‹")); + + // Execute a workflow waiting for it to complete. + String greeting = workflow.hello("World", SampleNexusService.Language.EN); + assertEquals("Hello Mock World πŸ‘‹", greeting); + } + + @Test + public void testEchoWorkflow( + TestWorkflowEnvironment testEnv, Worker worker, EchoCallerWorkflow workflow) { + when(mockNexusService.echo(any())) + .thenReturn(new SampleNexusService.EchoOutput("echo response")); + + // Execute a workflow waiting for it to complete. + String greeting = workflow.echo("echo input"); + assertEquals("echo response", greeting); + + // Verify the echo operation was called exactly once and no other operations were invoked + verify(mockNexusService, times(1)).echo(any()); + // Verify the Nexus service was called with the correct input + verify(mockNexusService).echo(argThat(input -> "echo input".equals(input.getMessage()))); + + verifyNoMoreInteractions(mockNexusService); + } +} diff --git a/core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceMockTest.java b/core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceMockTest.java new file mode 100644 index 000000000..c2264ec65 --- /dev/null +++ b/core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceMockTest.java @@ -0,0 +1,104 @@ +package io.temporal.samples.nexus.caller; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +import io.nexusrpc.handler.OperationHandler; +import io.nexusrpc.handler.OperationImpl; +import io.nexusrpc.handler.ServiceImpl; +import io.temporal.client.WorkflowOptions; +import io.temporal.samples.nexus.service.SampleNexusService; +import io.temporal.testing.TestWorkflowRule; +import org.junit.Rule; +import org.junit.Test; + +// This unit test example shows how to mock the Nexus service itself in JUnit4. +// This is the path to take when you don't have access to the service implementation so +// cannot mock it. Since the SampleNexusService itself is mocked, +// no handlers need to be set up or mocked. +public class NexusServiceMockTest { + + private final SampleNexusService mockNexusService = mock(SampleNexusService.class); + + /** + * A test-only Nexus service implementation that delegates to the Mockito mock defined above. Both + * operations are implemented as synchronous handlers that forward calls to the mock, allowing + * full control over return values and verification of inputs. + */ + @ServiceImpl(service = SampleNexusService.class) + public class TestNexusServiceImpl { + @OperationImpl + @SuppressWarnings("DirectInvocationOnMock") + public OperationHandler echo() { + return OperationHandler.sync((ctx, details, input) -> mockNexusService.echo(input)); + } + + @OperationImpl + @SuppressWarnings("DirectInvocationOnMock") + public OperationHandler hello() { + return OperationHandler.sync((ctx, details, input) -> mockNexusService.hello(input)); + } + } + + // Using OperationHandler.sync for both operations bypasses the need for a backing workflow, + // returning results inline just like a synchronous call. + // + // Note that the Mocks need to be done before the rule + // is defined, as creating the rule will fail if either call is still null. + + @Rule + public TestWorkflowRule testWorkflowRule = + TestWorkflowRule.newBuilder() + .setNexusServiceImplementation(new TestNexusServiceImpl()) + .setWorkflowTypes(EchoCallerWorkflowImpl.class, HelloCallerWorkflowImpl.class) + .build(); + + @Test + public void testHelloCallerWithMockedService() { + when(mockNexusService.hello(any())) + .thenReturn(new SampleNexusService.HelloOutput("Bonjour World")); + + HelloCallerWorkflow workflow = + testWorkflowRule + .getWorkflowClient() + .newWorkflowStub( + HelloCallerWorkflow.class, + WorkflowOptions.newBuilder().setTaskQueue(testWorkflowRule.getTaskQueue()).build()); + + String result = workflow.hello("World", SampleNexusService.Language.FR); + assertEquals("Bonjour World", result); + + // Verify the Nexus service was called with the correct name and language + verify(mockNexusService) + .hello( + argThat( + input -> + "World".equals(input.getName()) + && SampleNexusService.Language.FR == input.getLanguage())); + } + + @Test + public void testEchoCallerWithMockedService() { + when(mockNexusService.echo(any())) + .thenReturn(new SampleNexusService.EchoOutput("echo response")); + + EchoCallerWorkflow workflow = + testWorkflowRule + .getWorkflowClient() + .newWorkflowStub( + EchoCallerWorkflow.class, + WorkflowOptions.newBuilder().setTaskQueue(testWorkflowRule.getTaskQueue()).build()); + + String echoOutput = workflow.echo("echo input"); + + assertEquals("echo response", echoOutput); + + // Verify the echo operation was called exactly once and no other operations were invoked + verify(mockNexusService, times(1)).echo(any()); + // Verify the Nexus service was called with the correct input + verify(mockNexusService).echo(argThat(input -> "echo input".equals(input.getMessage()))); + + verifyNoMoreInteractions(mockNexusService); + } +} From d6f0a08055a6aee674724998da0885393322cb11 Mon Sep 17 00:00:00 2001 From: Evan Reynolds Date: Thu, 2 Apr 2026 11:29:51 -0700 Subject: [PATCH 12/14] Adding snips for documentation pages (#772) --- .../samples/nexus/caller/CallerWorkflowJunit5MockTest.java | 3 +++ .../temporal/samples/nexus/caller/CallerWorkflowMockTest.java | 3 +++ .../temporal/samples/nexus/caller/NexusServiceJunit5Test.java | 4 ++++ .../temporal/samples/nexus/caller/NexusServiceMockTest.java | 4 ++++ 4 files changed, 14 insertions(+) diff --git a/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowJunit5MockTest.java b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowJunit5MockTest.java index ca038ee0e..2ba042308 100644 --- a/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowJunit5MockTest.java +++ b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowJunit5MockTest.java @@ -16,6 +16,7 @@ // This is an example of how to unit test Nexus services in JUnit5. The handlers are mocked, // so that the caller classes interact with the mocks and not the handler classes themselves. +// @@@SNIPSTART java-nexus-sample-junit5-mock public class CallerWorkflowJunit5MockTest { // Sync Nexus operations run inline in the handler thread β€” there is no backing workflow to @@ -77,3 +78,5 @@ public void testEchoWorkflow( testEnv.shutdown(); } } + +// @@@SNIPEND diff --git a/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowMockTest.java b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowMockTest.java index c899713a2..d6b793ffe 100644 --- a/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowMockTest.java +++ b/core/src/test/java/io/temporal/samples/nexus/caller/CallerWorkflowMockTest.java @@ -17,6 +17,7 @@ // This is an example of how to unit test Nexus services in JUnit4. The handlers are mocked, // so that the caller classes interact with the mocks and not the handler classes themselves. +// @@@SNIPSTART java-nexus-sample-junit4-mock public class CallerWorkflowMockTest { // Inject a mock EchoClient so sync Nexus operations can be stubbed per test. @@ -90,3 +91,5 @@ public void testEchoWorkflow() { testWorkflowRule.getTestEnvironment().shutdown(); } } + +// @@@SNIPEND diff --git a/core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceJunit5Test.java b/core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceJunit5Test.java index c5fd578c0..fe8a8b8c9 100644 --- a/core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceJunit5Test.java +++ b/core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceJunit5Test.java @@ -18,6 +18,8 @@ // This is the path to take when you don't have access to the service implementation so // cannot mock it. Since the SampleNexusService itself is mocked, // no handlers need to be set up or mocked. + +// @@@SNIPSTART java-nexus-service-sample-junit4-mock public class NexusServiceJunit5Test { private final SampleNexusService mockNexusService = mock(SampleNexusService.class); @@ -103,3 +105,5 @@ public void testEchoWorkflow( verifyNoMoreInteractions(mockNexusService); } } + +// @@@SNIPEND diff --git a/core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceMockTest.java b/core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceMockTest.java index c2264ec65..8dafc6388 100644 --- a/core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceMockTest.java +++ b/core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceMockTest.java @@ -17,6 +17,8 @@ // This is the path to take when you don't have access to the service implementation so // cannot mock it. Since the SampleNexusService itself is mocked, // no handlers need to be set up or mocked. + +// @@@SNIPSTART java-nexus-service-sample-junit4-mock public class NexusServiceMockTest { private final SampleNexusService mockNexusService = mock(SampleNexusService.class); @@ -102,3 +104,5 @@ public void testEchoCallerWithMockedService() { verifyNoMoreInteractions(mockNexusService); } } + +// @@@SNIPEND From d34d613a012e2a07586071e6d9aff69d433d45b9 Mon Sep 17 00:00:00 2001 From: Evan Reynolds Date: Thu, 2 Apr 2026 15:40:35 -0700 Subject: [PATCH 13/14] Updated snipstart tag (#774) --- .../temporal/samples/nexus/caller/NexusServiceJunit5Test.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceJunit5Test.java b/core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceJunit5Test.java index fe8a8b8c9..0b03b2d64 100644 --- a/core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceJunit5Test.java +++ b/core/src/test/java/io/temporal/samples/nexus/caller/NexusServiceJunit5Test.java @@ -19,7 +19,7 @@ // cannot mock it. Since the SampleNexusService itself is mocked, // no handlers need to be set up or mocked. -// @@@SNIPSTART java-nexus-service-sample-junit4-mock +// @@@SNIPSTART java-nexus-service-sample-junit5-mock public class NexusServiceJunit5Test { private final SampleNexusService mockNexusService = mock(SampleNexusService.class); From 4c1af4776630a02b2c6ec253d5617e6a266102e1 Mon Sep 17 00:00:00 2001 From: James Watkins-Harvey Date: Mon, 6 Apr 2026 23:28:29 -0400 Subject: [PATCH 14/14] Update Java SDK version to 1.34.0 (#773) --- build.gradle | 2 +- core/build.gradle | 1 + core/src/main/java/io/temporal/samples/ssl/Starter.java | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index abb6487ba..0cafde690 100644 --- a/build.gradle +++ b/build.gradle @@ -26,7 +26,7 @@ subprojects { ext { otelVersion = '1.30.1' otelVersionAlpha = "${otelVersion}-alpha" - javaSDKVersion = '1.32.1' + javaSDKVersion = '1.34.0' camelVersion = '3.22.1' jarVersion = '1.0.0' } diff --git a/core/build.gradle b/core/build.gradle index 62fbfa8e9..c5157db3d 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -8,6 +8,7 @@ dependencies { implementation "io.temporal:temporal-envconfig:$javaSDKVersion" // Needed for SDK related functionality + implementation "io.grpc:grpc-util" implementation(platform("com.fasterxml.jackson:jackson-bom:2.17.2")) implementation "com.fasterxml.jackson.core:jackson-databind" implementation "com.fasterxml.jackson.core:jackson-core" diff --git a/core/src/main/java/io/temporal/samples/ssl/Starter.java b/core/src/main/java/io/temporal/samples/ssl/Starter.java index c69101473..25b9df6ba 100644 --- a/core/src/main/java/io/temporal/samples/ssl/Starter.java +++ b/core/src/main/java/io/temporal/samples/ssl/Starter.java @@ -50,9 +50,9 @@ public static void main(String[] args) throws Exception { if (refreshPeriod > 0) { AdvancedTlsX509KeyManager clientKeyManager = new AdvancedTlsX509KeyManager(); // Reload credentials every minute - clientKeyManager.updateIdentityCredentialsFromFile( - clientKeyFile, + clientKeyManager.updateIdentityCredentials( clientCertFile, + clientKeyFile, refreshPeriod, TimeUnit.MINUTES, Executors.newScheduledThreadPool(1));