From 04c3b175d2d056f09a706e55fa6c284cc709240f Mon Sep 17 00:00:00 2001 From: seanbollin Date: Tue, 25 Aug 2026 13:55:25 -0700 Subject: [PATCH 1/6] Add Cloud Run worker sample with worker identity and deployment versioning Add a runnable Temporal Java worker sample for a Google Cloud Run worker pool. It uses io.temporal:temporal-gcp-cloud-run's GoogleCloudRunMetadata to derive the worker identity and a PINNED Worker Deployment Version from Cloud Run instance metadata, reads TEMPORAL_ADDRESS / TEMPORAL_NAMESPACE / TEMPORAL_TASK_QUEUE (plaintext connection), registers a small greeting workflow and activity, and runs until SIGTERM. Mirrors the lambda-worker sample's layout and README style, with a Dockerfile and gcloud worker-pools deploy instructions. temporal-gcp-cloud-run is not yet released, so settings.gradle wires the sample against a local SDK checkout with a Gradle composite build, defaulting to ../sdk-java-2 and overridable with -PtemporalSdkPath. This is temporary until the module is released; the PR stays a draft until then. Co-Authored-By: Claude Opus 4.8 --- cloud-run-worker-id/Dockerfile | 22 +++ cloud-run-worker-id/README.md | 163 ++++++++++++++++++ cloud-run-worker-id/build.gradle | 21 +++ .../cloudrunworkerid/CloudRunWorker.java | 92 ++++++++++ .../cloudrunworkerid/GreetingActivities.java | 12 ++ .../GreetingActivitiesImpl.java | 16 ++ .../cloudrunworkerid/GreetingWorkflow.java | 12 ++ .../GreetingWorkflowImpl.java | 28 +++ .../src/main/resources/logback.xml | 14 ++ .../GreetingWorkflowTest.java | 31 ++++ settings.gradle | 16 ++ 11 files changed, 427 insertions(+) create mode 100644 cloud-run-worker-id/Dockerfile create mode 100644 cloud-run-worker-id/README.md create mode 100644 cloud-run-worker-id/build.gradle create mode 100644 cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/CloudRunWorker.java create mode 100644 cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingActivities.java create mode 100644 cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingActivitiesImpl.java create mode 100644 cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflow.java create mode 100644 cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflowImpl.java create mode 100644 cloud-run-worker-id/src/main/resources/logback.xml create mode 100644 cloud-run-worker-id/src/test/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflowTest.java diff --git a/cloud-run-worker-id/Dockerfile b/cloud-run-worker-id/Dockerfile new file mode 100644 index 00000000..e18c6c1e --- /dev/null +++ b/cloud-run-worker-id/Dockerfile @@ -0,0 +1,22 @@ +FROM eclipse-temurin:17-jdk-jammy AS build + +WORKDIR /workspace +COPY . . + +# TEMPORARY (draft): this sample depends on io.temporal:temporal-gcp-cloud-run, which is not yet +# released to Maven Central. Until it ships, the Gradle build resolves it from a local Temporal Java +# SDK checkout through a composite build (see README.md and settings.gradle). For an image build the +# local SDK checkout must be available in the build context (or the module published to Maven Local); +# once the module is released, bump javaSDKVersion in the samples root build.gradle and this builds +# unchanged from Maven Central. +RUN ./gradlew --no-daemon :cloud-run-worker-id:installDist + +FROM eclipse-temurin:17-jre-jammy + +RUN useradd --create-home --uid 10001 temporal +WORKDIR /app +COPY --from=build --chown=temporal:temporal \ + /workspace/cloud-run-worker-id/build/install/cloud-run-worker-id/ /app/ + +USER 10001 +ENTRYPOINT ["/app/bin/cloud-run-worker-id"] diff --git a/cloud-run-worker-id/README.md b/cloud-run-worker-id/README.md new file mode 100644 index 00000000..c7360b97 --- /dev/null +++ b/cloud-run-worker-id/README.md @@ -0,0 +1,163 @@ +# Cloud Run Worker (Worker Identity + Deployment Versioning) + +This sample runs a continuously polling Temporal Java Worker in a Google Cloud Run +**worker pool**. It uses the `temporal-gcp-cloud-run` helper to derive the Worker's Temporal +identity and its Worker Deployment Version from Cloud Run instance metadata, so every Cloud Run +revision registers as a distinct, `PINNED` Worker Deployment Version. It registers a small greeting +Workflow and Activity and runs until Cloud Run stops the instance. + +Cloud Run runs a long-lived container rather than a per-request handler, so there is no function to +wrap: the Worker fetches the metadata once at startup and applies it to the client and worker option +builders. + +> Experimental: Google Cloud Run support is experimental and may change without notice. + +## Unreleased SDK dependency + +This sample depends on `io.temporal:temporal-gcp-cloud-run`, which is **not yet released** to Maven +Central. Until it ships, the samples build wires the module from a local Temporal Java SDK checkout +through a Gradle composite build (`includeBuild`), configured in the samples root `settings.gradle`. + +- It defaults to a sibling `../sdk-java-2` checkout on the `cloud-run-worker-id` branch. +- Override the location with `-PtemporalSdkPath=/path/to/sdk-java`. +- When that checkout is absent, the composite build is skipped and only this module is affected; the + other samples still build. + +Once `temporal-gcp-cloud-run` is released, remove the composite-build block from `settings.gradle` +and bump `javaSDKVersion` in the samples root `build.gradle` to the released version; the standard +Maven Central build then works without the local checkout. This sample's pull request stays a draft +until then. + +## Prerequisites + +- Java 17+ +- The Temporal CLI (to create the Worker Deployment Version and start Workflows) +- The Google Cloud CLI (`gcloud`) with a project that has Cloud Run enabled +- A Temporal Service reachable from Cloud Run. A plaintext connection is used by default; configure + TLS or an API key in `CloudRunWorker.java` for a secured Service such as Temporal Cloud. + +## Layout + +- `src/main/java/io/temporal/samples/cloudrunworkerid/CloudRunWorker.java` fetches the Cloud Run + metadata, applies the derived identity and deployment version, and runs a long-lived Worker with a + bounded shutdown on `SIGTERM`. +- `GreetingWorkflow` / `GreetingWorkflowImpl` and `GreetingActivities` / `GreetingActivitiesImpl` are + the sample Workflow and Activity. The Workflow method is annotated + `@WorkflowVersioningBehavior(PINNED)` to match the Worker's PINNED default. +- `Dockerfile` packages the Gradle application as the Worker container. + +## How it works + +Cloud Run **worker pools** set `CLOUD_RUN_WORKER_POOL` and `CLOUD_RUN_REVISION` on every instance +(Cloud Run **services** set `K_SERVICE` and `K_REVISION`). `GoogleCloudRunMetadata.fetch()` resolves: + +- **deployment name**: the first non-empty of `CLOUD_RUN_WORKER_POOL` then `K_SERVICE`. +- **revision**: the first non-empty of `CLOUD_RUN_REVISION` then `K_REVISION`. +- **instance id**: a single HTTP `GET` to the Cloud Run metadata server + (`http://metadata.google.internal/computeMetadata/v1/instance/id`, header `Metadata-Flavor: + Google`). + +The Worker then applies the metadata: + +- `applyTo(WorkflowClientOptions.Builder)` sets the Worker identity to `@` + (falling back to `@` and then ``). +- `applyTo(WorkerOptions.Builder)` enables Worker Deployment Versioning with the deployment name as + the deployment, the revision as the build id, and a `PINNED` default versioning behavior, so + in-flight Workflows stay on the revision that started them. + +The Worker reads its connection settings from the environment: + +```bash +TEMPORAL_ADDRESS # host:port of the Temporal frontend (default 127.0.0.1:7233) +TEMPORAL_NAMESPACE # Temporal Namespace (default "default") +TEMPORAL_TASK_QUEUE # Task Queue to poll (default "cloud-run-worker-id") +``` + +`CLOUD_RUN_WORKER_POOL` and `CLOUD_RUN_REVISION` are injected by Cloud Run and do not need to be set +manually. + +## Build and test locally + +The unit test uses `TestWorkflowRule` and needs neither Cloud Run nor a running Temporal Service: + +```bash +./gradlew :cloud-run-worker-id:test +``` + +Build the runnable application (from a local SDK checkout, per the note above): + +```bash +./gradlew -PtemporalSdkPath=/path/to/sdk-java :cloud-run-worker-id:installDist +``` + +## Deploy to a Cloud Run worker pool + +Worker pools keep CPU allocated so the Temporal Worker can poll continuously; they are not +request-driven Cloud Run services. Set your connection values and deploy from the sample directory: + +```bash +export REGION=us-central1 +export TEMPORAL_ADDRESS=..tmprl.cloud:7233 +export TEMPORAL_NAMESPACE=. +export TEMPORAL_TASK_QUEUE=cloud-run-worker-id + +gcloud run worker-pools deploy cloud-run-worker-id \ + --source . \ + --region "$REGION" \ + --set-env-vars "TEMPORAL_ADDRESS=$TEMPORAL_ADDRESS,TEMPORAL_NAMESPACE=$TEMPORAL_NAMESPACE,TEMPORAL_TASK_QUEUE=$TEMPORAL_TASK_QUEUE" +``` + +`--source .` builds the container from the included `Dockerfile`. Because the image build resolves +the unreleased `temporal-gcp-cloud-run` module, a remote source build succeeds only once that module +is released (or published to your Maven Local and made available to the build). Until then, build the +image locally against your SDK checkout and deploy it with `--image` instead: + +```bash +gcloud run worker-pools deploy cloud-run-worker-id \ + --image "$REGION-docker.pkg.dev/$PROJECT_ID//cloud-run-worker-id:latest" \ + --region "$REGION" \ + --set-env-vars "TEMPORAL_ADDRESS=$TEMPORAL_ADDRESS,TEMPORAL_NAMESPACE=$TEMPORAL_NAMESPACE,TEMPORAL_TASK_QUEUE=$TEMPORAL_TASK_QUEUE" +``` + +Each Cloud Run deployment creates a new revision, which the Worker reports as a new build id under +the same deployment name. + +## Create the Worker Deployment Version and start a Workflow + +After the Worker is polling, register and route the Worker Deployment Version, then start the sample +Workflow. Use the deployment name (the worker pool name, `cloud-run-worker-id`) and the build id +(the Cloud Run revision) that the Worker logs at startup: + +```bash +temporal worker deployment set-current-version \ + --deployment-name cloud-run-worker-id \ + --build-id \ + --yes + +temporal workflow start \ + --task-queue cloud-run-worker-id \ + --type GreetingWorkflow \ + --workflow-id cloud-run-greeting \ + --input '"Cloud Run"' +``` + +## Shutdown + +Cloud Run sends `SIGTERM` and allows a short grace period before `SIGKILL`. The shutdown hook stops +polling, waits up to six seconds for in-flight tasks to drain, escalates to a forced shutdown if +needed, and then closes the service connection. Long-running Activities should still heartbeat and +handle cancellation so they can stop within the platform's shutdown window. + +## Clean up + +Reset routing before deleting the Worker Deployment Version, then delete the worker pool: + +```bash +temporal worker deployment set-current-version \ + --deployment-name cloud-run-worker-id \ + --unversioned \ + --allow-no-pollers \ + --yes + +gcloud run worker-pools delete cloud-run-worker-id --region "$REGION" +``` diff --git a/cloud-run-worker-id/build.gradle b/cloud-run-worker-id/build.gradle new file mode 100644 index 00000000..3ba56045 --- /dev/null +++ b/cloud-run-worker-id/build.gradle @@ -0,0 +1,21 @@ +apply plugin: 'application' + +dependencies { + implementation "io.temporal:temporal-sdk:$javaSDKVersion" + implementation "io.temporal:temporal-gcp-cloud-run:$javaSDKVersion" + runtimeOnly group: 'ch.qos.logback', name: 'logback-classic', version: '1.5.6' + + testImplementation "io.temporal:temporal-testing:$javaSDKVersion" + testImplementation "junit:junit:4.13.2" + testImplementation(platform("org.junit:junit-bom:5.10.3")) + testRuntimeOnly "org.junit.vintage:junit-vintage-engine" + + dependencies { + errorproneJavac('com.google.errorprone:javac:9+181-r4173-1') + errorprone('com.google.errorprone:error_prone_core:2.28.0') + } +} + +application { + mainClass = 'io.temporal.samples.cloudrunworkerid.CloudRunWorker' +} diff --git a/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/CloudRunWorker.java b/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/CloudRunWorker.java new file mode 100644 index 00000000..0a6d1da9 --- /dev/null +++ b/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/CloudRunWorker.java @@ -0,0 +1,92 @@ +package io.temporal.samples.cloudrunworkerid; + +import io.temporal.client.WorkflowClient; +import io.temporal.client.WorkflowClientOptions; +import io.temporal.gcp.cloudrun.GoogleCloudRunMetadata; +import io.temporal.serviceclient.WorkflowServiceStubs; +import io.temporal.serviceclient.WorkflowServiceStubsOptions; +import io.temporal.worker.Worker; +import io.temporal.worker.WorkerFactory; +import io.temporal.worker.WorkerOptions; +import java.util.concurrent.TimeUnit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** A continuously polling Temporal Worker for a Google Cloud Run worker pool. */ +public final class CloudRunWorker { + private static final Logger logger = LoggerFactory.getLogger(CloudRunWorker.class); + + static final String ADDRESS_ENV = "TEMPORAL_ADDRESS"; + static final String NAMESPACE_ENV = "TEMPORAL_NAMESPACE"; + static final String TASK_QUEUE_ENV = "TEMPORAL_TASK_QUEUE"; + + static final String DEFAULT_ADDRESS = "127.0.0.1:7233"; + static final String DEFAULT_NAMESPACE = "default"; + static final String DEFAULT_TASK_QUEUE = "cloud-run-worker-id"; + + private CloudRunWorker() {} + + public static void main(String[] args) { + // Read Cloud Run instance metadata once during startup. This performs a single HTTP request to + // the Cloud Run metadata server and throws IllegalStateException when it is unreachable, which + // usually means the process is not running on Google Cloud Run. + GoogleCloudRunMetadata metadata = GoogleCloudRunMetadata.fetch(); + + String address = envOrDefault(ADDRESS_ENV, DEFAULT_ADDRESS); + String namespace = envOrDefault(NAMESPACE_ENV, DEFAULT_NAMESPACE); + String taskQueue = envOrDefault(TASK_QUEUE_ENV, DEFAULT_TASK_QUEUE); + + // Plaintext connection to the Temporal Service. Configure TLS or an API key here for a secured + // deployment such as Temporal Cloud. + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs( + WorkflowServiceStubsOptions.newBuilder().setTarget(address).build()); + + // applyTo(WorkflowClientOptions.Builder) sets the derived worker identity on the client. + WorkflowClient client = + WorkflowClient.newInstance( + service, + metadata.applyTo(WorkflowClientOptions.newBuilder().setNamespace(namespace)).build()); + + WorkerFactory factory = WorkerFactory.newInstance(client); + + // applyTo(WorkerOptions.Builder) enables Worker Deployment Versioning with the Cloud Run name + // as the deployment name, the revision as the build id, and a PINNED default versioning + // behavior. + WorkerOptions workerOptions = metadata.applyTo(WorkerOptions.newBuilder()).build(); + Worker worker = factory.newWorker(taskQueue, workerOptions); + worker.registerWorkflowImplementationTypes(GreetingWorkflowImpl.class); + worker.registerActivitiesImplementations(new GreetingActivitiesImpl()); + + Runtime.getRuntime() + .addShutdownHook(new Thread(() -> shutdown(factory, service), "temporal-worker-shutdown")); + + factory.start(); + logger.info( + "Temporal worker started (identity={}, deployment={}, buildId={}, taskQueue={})", + metadata.workerIdentity(), + metadata.getName(), + metadata.getRevision(), + taskQueue); + + // Cloud Run worker pools are continuous workloads, so keep the process alive until SIGTERM. + factory.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); + } + + private static void shutdown(WorkerFactory factory, WorkflowServiceStubs service) { + // Cloud Run sends SIGTERM and allows a short grace period before SIGKILL. Stop polling, drain + // in-flight tasks, then close the service connection. + factory.shutdown(); + factory.awaitTermination(6, TimeUnit.SECONDS); + if (!factory.isTerminated()) { + factory.shutdownNow(); + factory.awaitTermination(1, TimeUnit.SECONDS); + } + service.shutdown(); + } + + private static String envOrDefault(String name, String defaultValue) { + String value = System.getenv(name); + return value == null || value.trim().isEmpty() ? defaultValue : value; + } +} diff --git a/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingActivities.java b/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingActivities.java new file mode 100644 index 00000000..86e9b9b1 --- /dev/null +++ b/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingActivities.java @@ -0,0 +1,12 @@ +package io.temporal.samples.cloudrunworkerid; + +import io.temporal.activity.ActivityInterface; +import io.temporal.activity.ActivityMethod; + +/** Activity interface used by {@link GreetingWorkflow}. */ +@ActivityInterface +public interface GreetingActivities { + + @ActivityMethod + String composeGreeting(String name); +} diff --git a/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingActivitiesImpl.java b/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingActivitiesImpl.java new file mode 100644 index 00000000..f2f7ddfd --- /dev/null +++ b/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingActivitiesImpl.java @@ -0,0 +1,16 @@ +package io.temporal.samples.cloudrunworkerid; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** Activity implementation that returns a simple greeting. */ +public final class GreetingActivitiesImpl implements GreetingActivities { + + private static final Logger logger = LoggerFactory.getLogger(GreetingActivitiesImpl.class); + + @Override + public String composeGreeting(String name) { + logger.info("Composing greeting for {}", name); + return "Hello, " + name + "!"; + } +} diff --git a/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflow.java b/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflow.java new file mode 100644 index 00000000..1e68f3fa --- /dev/null +++ b/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflow.java @@ -0,0 +1,12 @@ +package io.temporal.samples.cloudrunworkerid; + +import io.temporal.workflow.WorkflowInterface; +import io.temporal.workflow.WorkflowMethod; + +/** A small greeting workflow run by the Cloud Run worker. */ +@WorkflowInterface +public interface GreetingWorkflow { + + @WorkflowMethod + String getGreeting(String name); +} diff --git a/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflowImpl.java b/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflowImpl.java new file mode 100644 index 00000000..6ccad02c --- /dev/null +++ b/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflowImpl.java @@ -0,0 +1,28 @@ +package io.temporal.samples.cloudrunworkerid; + +import io.temporal.activity.ActivityOptions; +import io.temporal.common.VersioningBehavior; +import io.temporal.workflow.Workflow; +import io.temporal.workflow.WorkflowVersioningBehavior; +import java.time.Duration; + +/** + * Greeting workflow implementation. + * + *

The method is annotated {@link VersioningBehavior#PINNED}, matching the PINNED default that + * {@link io.temporal.gcp.cloudrun.GoogleCloudRunMetadata} applies to the worker, so executions stay + * on the Cloud Run revision that started them. + */ +public final class GreetingWorkflowImpl implements GreetingWorkflow { + + private final GreetingActivities activities = + Workflow.newActivityStub( + GreetingActivities.class, + ActivityOptions.newBuilder().setStartToCloseTimeout(Duration.ofSeconds(10)).build()); + + @Override + @WorkflowVersioningBehavior(VersioningBehavior.PINNED) + public String getGreeting(String name) { + return activities.composeGreeting(name); + } +} diff --git a/cloud-run-worker-id/src/main/resources/logback.xml b/cloud-run-worker-id/src/main/resources/logback.xml new file mode 100644 index 00000000..28eb2cba --- /dev/null +++ b/cloud-run-worker-id/src/main/resources/logback.xml @@ -0,0 +1,14 @@ + + + + %d{HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n + + + + + + + + + + diff --git a/cloud-run-worker-id/src/test/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflowTest.java b/cloud-run-worker-id/src/test/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflowTest.java new file mode 100644 index 00000000..cfc8e39d --- /dev/null +++ b/cloud-run-worker-id/src/test/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflowTest.java @@ -0,0 +1,31 @@ +package io.temporal.samples.cloudrunworkerid; + +import static org.junit.Assert.assertEquals; + +import io.temporal.client.WorkflowOptions; +import io.temporal.testing.TestWorkflowRule; +import org.junit.Rule; +import org.junit.Test; + +/** Unit test for the sample Workflow and Activity. */ +public class GreetingWorkflowTest { + + @Rule + public TestWorkflowRule testWorkflowRule = + TestWorkflowRule.newBuilder() + .setWorkflowTypes(GreetingWorkflowImpl.class) + .setActivityImplementations(new GreetingActivitiesImpl()) + .build(); + + @Test + public void returnsGreeting() { + GreetingWorkflow workflow = + testWorkflowRule + .getWorkflowClient() + .newWorkflowStub( + GreetingWorkflow.class, + WorkflowOptions.newBuilder().setTaskQueue(testWorkflowRule.getTaskQueue()).build()); + + assertEquals("Hello, Cloud Run!", workflow.getGreeting("Cloud Run")); + } +} diff --git a/settings.gradle b/settings.gradle index b19f2fd7..d502a239 100644 --- a/settings.gradle +++ b/settings.gradle @@ -9,3 +9,19 @@ include 'springboot' include 'springboot-basic' include 'lambda-worker:starter' include 'lambda-worker:worker' +include 'cloud-run-worker-id' + +// TEMPORARY (draft): the cloud-run-worker-id sample depends on io.temporal:temporal-gcp-cloud-run +// (and the worker-identity APIs it builds on), which are not yet released to Maven Central. Until +// they ship, wire the sample against a local Temporal Java SDK checkout with a Gradle composite +// build so it can compile and run. Defaults to a sibling ../sdk-java-2 checkout on the +// cloud-run-worker-id branch; override the location with -PtemporalSdkPath=/path/to/sdk-java. When +// the checkout is absent (for example on CI building the other samples) the composite build is +// skipped and only the cloud-run-worker-id module is affected. Remove this block and bump +// javaSDKVersion in build.gradle once temporal-gcp-cloud-run is released. +def temporalSdkPath = gradle.startParameter.projectProperties['temporalSdkPath'] ?: '../sdk-java-2' +def temporalSdkFile = new File(temporalSdkPath) +def temporalSdkDir = temporalSdkFile.isAbsolute() ? temporalSdkFile : new File(settingsDir, temporalSdkPath) +if (temporalSdkDir.isDirectory()) { + includeBuild temporalSdkPath +} From 38fea2aa48888581b1ed100e117aa8dacaddf15c Mon Sep 17 00:00:00 2001 From: seanbollin Date: Mon, 31 Aug 2026 13:23:59 -0700 Subject: [PATCH 2/6] Use CloudRunPlugin in the Cloud Run worker sample Register CloudRunPlugin on the workflow client instead of calling the removed GoogleCloudRunMetadata.applyTo(...) overloads. The metadata is still fetched once at startup (so the sample can log the identity, deployment name, and build id) and handed to the plugin, which sets the client identity and each worker's PINNED deployment version as it propagates from the client to its workers. The worker no longer needs per-worker WorkerOptions. README updated to match. Co-Authored-By: Claude Opus 4.8 --- cloud-run-worker-id/README.md | 30 ++++++++++--------- .../cloudrunworkerid/CloudRunWorker.java | 20 ++++++++----- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/cloud-run-worker-id/README.md b/cloud-run-worker-id/README.md index c7360b97..544668f9 100644 --- a/cloud-run-worker-id/README.md +++ b/cloud-run-worker-id/README.md @@ -1,14 +1,15 @@ # Cloud Run Worker (Worker Identity + Deployment Versioning) This sample runs a continuously polling Temporal Java Worker in a Google Cloud Run -**worker pool**. It uses the `temporal-gcp-cloud-run` helper to derive the Worker's Temporal -identity and its Worker Deployment Version from Cloud Run instance metadata, so every Cloud Run -revision registers as a distinct, `PINNED` Worker Deployment Version. It registers a small greeting -Workflow and Activity and runs until Cloud Run stops the instance. +**worker pool**. It registers the `CloudRunPlugin` from the `temporal-gcp-cloud-run` module on the +Temporal client to derive the Worker's Temporal identity and its Worker Deployment Version from +Cloud Run instance metadata, so every Cloud Run revision registers as a distinct, `PINNED` Worker +Deployment Version. It registers a small greeting Workflow and Activity and runs until Cloud Run +stops the instance. Cloud Run runs a long-lived container rather than a per-request handler, so there is no function to -wrap: the Worker fetches the metadata once at startup and applies it to the client and worker option -builders. +wrap: registering the plugin on the client fetches the metadata once at startup and applies the +derived identity and deployment version to the client and its Workers. > Experimental: Google Cloud Run support is experimental and may change without notice. @@ -39,8 +40,8 @@ until then. ## Layout - `src/main/java/io/temporal/samples/cloudrunworkerid/CloudRunWorker.java` fetches the Cloud Run - metadata, applies the derived identity and deployment version, and runs a long-lived Worker with a - bounded shutdown on `SIGTERM`. + metadata, registers `CloudRunPlugin` on the client to apply the derived identity and deployment + version, and runs a long-lived Worker with a bounded shutdown on `SIGTERM`. - `GreetingWorkflow` / `GreetingWorkflowImpl` and `GreetingActivities` / `GreetingActivitiesImpl` are the sample Workflow and Activity. The Workflow method is annotated `@WorkflowVersioningBehavior(PINNED)` to match the Worker's PINNED default. @@ -57,13 +58,14 @@ Cloud Run **worker pools** set `CLOUD_RUN_WORKER_POOL` and `CLOUD_RUN_REVISION` (`http://metadata.google.internal/computeMetadata/v1/instance/id`, header `Metadata-Flavor: Google`). -The Worker then applies the metadata: +`CloudRunPlugin`, registered on the client with `WorkflowClientOptions.Builder.setPlugins(...)`, then +applies the metadata through the SDK plugin hooks and propagates from the client to its Workers: -- `applyTo(WorkflowClientOptions.Builder)` sets the Worker identity to `@` - (falling back to `@` and then ``). -- `applyTo(WorkerOptions.Builder)` enables Worker Deployment Versioning with the deployment name as - the deployment, the revision as the build id, and a `PINNED` default versioning behavior, so - in-flight Workflows stay on the revision that started them. +- On the client, it sets the Worker identity to `@` (falling back to + `@` and then ``), unless an identity is already set. +- On each Worker, it enables Worker Deployment Versioning with the deployment name as the deployment, + the revision as the build id, and a `PINNED` default versioning behavior, so in-flight Workflows + stay on the revision that started them. The Worker reads its connection settings from the environment: diff --git a/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/CloudRunWorker.java b/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/CloudRunWorker.java index 0a6d1da9..e6f358fc 100644 --- a/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/CloudRunWorker.java +++ b/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/CloudRunWorker.java @@ -2,12 +2,12 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowClientOptions; +import io.temporal.gcp.cloudrun.CloudRunPlugin; import io.temporal.gcp.cloudrun.GoogleCloudRunMetadata; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.serviceclient.WorkflowServiceStubsOptions; import io.temporal.worker.Worker; import io.temporal.worker.WorkerFactory; -import io.temporal.worker.WorkerOptions; import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,19 +42,23 @@ public static void main(String[] args) { WorkflowServiceStubs.newServiceStubs( WorkflowServiceStubsOptions.newBuilder().setTarget(address).build()); - // applyTo(WorkflowClientOptions.Builder) sets the derived worker identity on the client. + // Register CloudRunPlugin on the client. It sets the derived worker identity on the client and, + // as it propagates to workers, enables Worker Deployment Versioning with the Cloud Run name as + // the deployment name, the revision as the build id, and a PINNED default versioning behavior. + // Passing the already-fetched metadata avoids a second call to the Cloud Run metadata server. WorkflowClient client = WorkflowClient.newInstance( service, - metadata.applyTo(WorkflowClientOptions.newBuilder().setNamespace(namespace)).build()); + WorkflowClientOptions.newBuilder() + .setNamespace(namespace) + .setPlugins(new CloudRunPlugin(metadata)) + .build()); WorkerFactory factory = WorkerFactory.newInstance(client); - // applyTo(WorkerOptions.Builder) enables Worker Deployment Versioning with the Cloud Run name - // as the deployment name, the revision as the build id, and a PINNED default versioning - // behavior. - WorkerOptions workerOptions = metadata.applyTo(WorkerOptions.newBuilder()).build(); - Worker worker = factory.newWorker(taskQueue, workerOptions); + // The plugin configures the worker's deployment version as the worker is created, so no + // per-worker options are needed here. + Worker worker = factory.newWorker(taskQueue); worker.registerWorkflowImplementationTypes(GreetingWorkflowImpl.class); worker.registerActivitiesImplementations(new GreetingActivitiesImpl()); From 7b5a8b767dbc26ac16e1bf00f4c954f00334d28a Mon Sep 17 00:00:00 2001 From: seanbollin Date: Mon, 31 Aug 2026 15:41:16 -0700 Subject: [PATCH 3/6] Use WorkerIdPlugin in the Cloud Run worker-id sample The temporal-gcp-cloud-run module renamed CloudRunPlugin to WorkerIdPlugin (Cloud Run can host multiple plugins in that module), so update the sample worker and its README to construct WorkerIdPlugin. Import ordering is adjusted to keep google-java-format's spotlessCheck clean. Co-Authored-By: Claude Opus 4.8 --- cloud-run-worker-id/README.md | 6 +++--- .../temporal/samples/cloudrunworkerid/CloudRunWorker.java | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cloud-run-worker-id/README.md b/cloud-run-worker-id/README.md index 544668f9..7eaf8acb 100644 --- a/cloud-run-worker-id/README.md +++ b/cloud-run-worker-id/README.md @@ -1,7 +1,7 @@ # Cloud Run Worker (Worker Identity + Deployment Versioning) This sample runs a continuously polling Temporal Java Worker in a Google Cloud Run -**worker pool**. It registers the `CloudRunPlugin` from the `temporal-gcp-cloud-run` module on the +**worker pool**. It registers the `WorkerIdPlugin` from the `temporal-gcp-cloud-run` module on the Temporal client to derive the Worker's Temporal identity and its Worker Deployment Version from Cloud Run instance metadata, so every Cloud Run revision registers as a distinct, `PINNED` Worker Deployment Version. It registers a small greeting Workflow and Activity and runs until Cloud Run @@ -40,7 +40,7 @@ until then. ## Layout - `src/main/java/io/temporal/samples/cloudrunworkerid/CloudRunWorker.java` fetches the Cloud Run - metadata, registers `CloudRunPlugin` on the client to apply the derived identity and deployment + metadata, registers `WorkerIdPlugin` on the client to apply the derived identity and deployment version, and runs a long-lived Worker with a bounded shutdown on `SIGTERM`. - `GreetingWorkflow` / `GreetingWorkflowImpl` and `GreetingActivities` / `GreetingActivitiesImpl` are the sample Workflow and Activity. The Workflow method is annotated @@ -58,7 +58,7 @@ Cloud Run **worker pools** set `CLOUD_RUN_WORKER_POOL` and `CLOUD_RUN_REVISION` (`http://metadata.google.internal/computeMetadata/v1/instance/id`, header `Metadata-Flavor: Google`). -`CloudRunPlugin`, registered on the client with `WorkflowClientOptions.Builder.setPlugins(...)`, then +`WorkerIdPlugin`, registered on the client with `WorkflowClientOptions.Builder.setPlugins(...)`, then applies the metadata through the SDK plugin hooks and propagates from the client to its Workers: - On the client, it sets the Worker identity to `@` (falling back to diff --git a/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/CloudRunWorker.java b/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/CloudRunWorker.java index e6f358fc..ec42da13 100644 --- a/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/CloudRunWorker.java +++ b/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/CloudRunWorker.java @@ -2,8 +2,8 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowClientOptions; -import io.temporal.gcp.cloudrun.CloudRunPlugin; import io.temporal.gcp.cloudrun.GoogleCloudRunMetadata; +import io.temporal.gcp.cloudrun.WorkerIdPlugin; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.serviceclient.WorkflowServiceStubsOptions; import io.temporal.worker.Worker; @@ -42,7 +42,7 @@ public static void main(String[] args) { WorkflowServiceStubs.newServiceStubs( WorkflowServiceStubsOptions.newBuilder().setTarget(address).build()); - // Register CloudRunPlugin on the client. It sets the derived worker identity on the client and, + // Register WorkerIdPlugin on the client. It sets the derived worker identity on the client and, // as it propagates to workers, enables Worker Deployment Versioning with the Cloud Run name as // the deployment name, the revision as the build id, and a PINNED default versioning behavior. // Passing the already-fetched metadata avoids a second call to the Cloud Run metadata server. @@ -51,7 +51,7 @@ public static void main(String[] args) { service, WorkflowClientOptions.newBuilder() .setNamespace(namespace) - .setPlugins(new CloudRunPlugin(metadata)) + .setPlugins(new WorkerIdPlugin(metadata)) .build()); WorkerFactory factory = WorkerFactory.newInstance(client); From fa9d7f04c7b233918cf33eea0f6a68b015905eff Mon Sep 17 00:00:00 2001 From: seanbollin Date: Wed, 9 Sep 2026 15:35:27 -0700 Subject: [PATCH 4/6] Move Cloud Run worker-identity sample under gcp/cloud-run/workerid Mirror the sibling OpenTelemetry sample's gcp/cloud-run/opentelemetry layout: move cloud-run-worker-id/ to gcp/cloud-run/workerid/, rename the Java package io.temporal.samples.cloudrunworkerid to io.temporal.samples.gcp.cloudrun.workerid, and register the module as gcp:cloud-run:workerid in settings.gradle. The worker-identity plugin is now identity-only. Depend on the split-out temporal-gcp-cloud-run-worker-id module (package io.temporal.gcp.cloudrun.workerid), register WorkerIdPlugin, log only the derived identity and task queue, and drop the stale worker-deployment-versioning references from the sample sources and README. Co-Authored-By: Claude Opus 4.8 --- cloud-run-worker-id/Dockerfile | 22 ----- gcp/cloud-run/workerid/Dockerfile | 22 +++++ .../cloud-run/workerid}/README.md | 91 ++++++++----------- .../cloud-run/workerid}/build.gradle | 7 +- .../cloudrun/workerid}/CloudRunWorker.java | 19 ++-- .../workerid}/GreetingActivities.java | 2 +- .../workerid}/GreetingActivitiesImpl.java | 2 +- .../cloudrun/workerid}/GreetingWorkflow.java | 2 +- .../workerid}/GreetingWorkflowImpl.java | 13 +-- .../workerid}/src/main/resources/logback.xml | 0 .../workerid}/GreetingWorkflowTest.java | 2 +- settings.gradle | 19 ++-- 12 files changed, 88 insertions(+), 113 deletions(-) delete mode 100644 cloud-run-worker-id/Dockerfile create mode 100644 gcp/cloud-run/workerid/Dockerfile rename {cloud-run-worker-id => gcp/cloud-run/workerid}/README.md (53%) rename {cloud-run-worker-id => gcp/cloud-run/workerid}/build.gradle (62%) rename {cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid => gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid}/CloudRunWorker.java (83%) rename {cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid => gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid}/GreetingActivities.java (84%) rename {cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid => gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid}/GreetingActivitiesImpl.java (89%) rename {cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid => gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid}/GreetingWorkflow.java (83%) rename {cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid => gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid}/GreetingWorkflowImpl.java (50%) rename {cloud-run-worker-id => gcp/cloud-run/workerid}/src/main/resources/logback.xml (100%) rename {cloud-run-worker-id/src/test/java/io/temporal/samples/cloudrunworkerid => gcp/cloud-run/workerid/src/test/java/io/temporal/samples/gcp/cloudrun/workerid}/GreetingWorkflowTest.java (94%) diff --git a/cloud-run-worker-id/Dockerfile b/cloud-run-worker-id/Dockerfile deleted file mode 100644 index e18c6c1e..00000000 --- a/cloud-run-worker-id/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -FROM eclipse-temurin:17-jdk-jammy AS build - -WORKDIR /workspace -COPY . . - -# TEMPORARY (draft): this sample depends on io.temporal:temporal-gcp-cloud-run, which is not yet -# released to Maven Central. Until it ships, the Gradle build resolves it from a local Temporal Java -# SDK checkout through a composite build (see README.md and settings.gradle). For an image build the -# local SDK checkout must be available in the build context (or the module published to Maven Local); -# once the module is released, bump javaSDKVersion in the samples root build.gradle and this builds -# unchanged from Maven Central. -RUN ./gradlew --no-daemon :cloud-run-worker-id:installDist - -FROM eclipse-temurin:17-jre-jammy - -RUN useradd --create-home --uid 10001 temporal -WORKDIR /app -COPY --from=build --chown=temporal:temporal \ - /workspace/cloud-run-worker-id/build/install/cloud-run-worker-id/ /app/ - -USER 10001 -ENTRYPOINT ["/app/bin/cloud-run-worker-id"] diff --git a/gcp/cloud-run/workerid/Dockerfile b/gcp/cloud-run/workerid/Dockerfile new file mode 100644 index 00000000..64b82d34 --- /dev/null +++ b/gcp/cloud-run/workerid/Dockerfile @@ -0,0 +1,22 @@ +FROM eclipse-temurin:17-jdk-jammy AS build + +WORKDIR /workspace +COPY . . + +# TEMPORARY (draft): this sample depends on io.temporal:temporal-gcp-cloud-run-worker-id, which is +# not yet released to Maven Central. Until it ships, the Gradle build resolves it from a local +# Temporal Java SDK checkout through a composite build (see README.md and settings.gradle). For an +# image build the local SDK checkout must be available in the build context (or the module published +# to Maven Local); once the module is released, bump javaSDKVersion in the samples root build.gradle +# and this builds unchanged from Maven Central. +RUN ./gradlew --no-daemon :gcp:cloud-run:workerid:installDist + +FROM eclipse-temurin:17-jre-jammy + +RUN useradd --create-home --uid 10001 temporal +WORKDIR /app +COPY --from=build --chown=temporal:temporal \ + /workspace/gcp/cloud-run/workerid/build/install/cloud-run-worker-id/ /app/ + +USER 10001 +ENTRYPOINT ["/app/bin/cloud-run-worker-id"] diff --git a/cloud-run-worker-id/README.md b/gcp/cloud-run/workerid/README.md similarity index 53% rename from cloud-run-worker-id/README.md rename to gcp/cloud-run/workerid/README.md index 7eaf8acb..369227d5 100644 --- a/cloud-run-worker-id/README.md +++ b/gcp/cloud-run/workerid/README.md @@ -1,50 +1,49 @@ -# Cloud Run Worker (Worker Identity + Deployment Versioning) +# Temporal Cloud Run worker-identity worker -This sample runs a continuously polling Temporal Java Worker in a Google Cloud Run -**worker pool**. It registers the `WorkerIdPlugin` from the `temporal-gcp-cloud-run` module on the -Temporal client to derive the Worker's Temporal identity and its Worker Deployment Version from -Cloud Run instance metadata, so every Cloud Run revision registers as a distinct, `PINNED` Worker -Deployment Version. It registers a small greeting Workflow and Activity and runs until Cloud Run -stops the instance. +This sample runs a continuously polling Temporal Java Worker in a Google Cloud Run **worker pool**. +It registers the `WorkerIdPlugin` from the `temporal-gcp-cloud-run-worker-id` module on the Temporal +client so the Worker's Temporal identity is derived from Cloud Run instance metadata as +`{instanceId}@{revision}`. It registers a small greeting Workflow and Activity and runs until Cloud +Run stops the instance. Identity only: the plugin sets the worker identity and nothing else. Cloud Run runs a long-lived container rather than a per-request handler, so there is no function to wrap: registering the plugin on the client fetches the metadata once at startup and applies the -derived identity and deployment version to the client and its Workers. +derived identity to the client and the Workers created from it. > Experimental: Google Cloud Run support is experimental and may change without notice. ## Unreleased SDK dependency -This sample depends on `io.temporal:temporal-gcp-cloud-run`, which is **not yet released** to Maven -Central. Until it ships, the samples build wires the module from a local Temporal Java SDK checkout -through a Gradle composite build (`includeBuild`), configured in the samples root `settings.gradle`. +This sample depends on `io.temporal:temporal-gcp-cloud-run-worker-id`, which is **not yet released** +to Maven Central. Until it ships, the samples build wires the module from a local Temporal Java SDK +checkout through a Gradle composite build (`includeBuild`), configured in the samples root +`settings.gradle`. - It defaults to a sibling `../sdk-java-2` checkout on the `cloud-run-worker-id` branch. - Override the location with `-PtemporalSdkPath=/path/to/sdk-java`. - When that checkout is absent, the composite build is skipped and only this module is affected; the other samples still build. -Once `temporal-gcp-cloud-run` is released, remove the composite-build block from `settings.gradle` -and bump `javaSDKVersion` in the samples root `build.gradle` to the released version; the standard -Maven Central build then works without the local checkout. This sample's pull request stays a draft -until then. +Once `temporal-gcp-cloud-run-worker-id` is released, remove the composite-build block from +`settings.gradle` and bump `javaSDKVersion` in the samples root `build.gradle` to the released +version; the standard Maven Central build then works without the local checkout. This sample's pull +request stays a draft until then. ## Prerequisites - Java 17+ -- The Temporal CLI (to create the Worker Deployment Version and start Workflows) +- The Temporal CLI (to start Workflows) - The Google Cloud CLI (`gcloud`) with a project that has Cloud Run enabled - A Temporal Service reachable from Cloud Run. A plaintext connection is used by default; configure TLS or an API key in `CloudRunWorker.java` for a secured Service such as Temporal Cloud. -## Layout +## Files -- `src/main/java/io/temporal/samples/cloudrunworkerid/CloudRunWorker.java` fetches the Cloud Run - metadata, registers `WorkerIdPlugin` on the client to apply the derived identity and deployment - version, and runs a long-lived Worker with a bounded shutdown on `SIGTERM`. +- `src/main/java/io/temporal/samples/gcp/cloudrun/workerid/CloudRunWorker.java` fetches the Cloud + Run metadata, registers `WorkerIdPlugin` on the client to apply the derived identity, and runs a + long-lived Worker with a bounded shutdown on `SIGTERM`. - `GreetingWorkflow` / `GreetingWorkflowImpl` and `GreetingActivities` / `GreetingActivitiesImpl` are - the sample Workflow and Activity. The Workflow method is annotated - `@WorkflowVersioningBehavior(PINNED)` to match the Worker's PINNED default. + the sample Workflow and Activity. - `Dockerfile` packages the Gradle application as the Worker container. ## How it works @@ -52,20 +51,16 @@ until then. Cloud Run **worker pools** set `CLOUD_RUN_WORKER_POOL` and `CLOUD_RUN_REVISION` on every instance (Cloud Run **services** set `K_SERVICE` and `K_REVISION`). `GoogleCloudRunMetadata.fetch()` resolves: -- **deployment name**: the first non-empty of `CLOUD_RUN_WORKER_POOL` then `K_SERVICE`. +- **name**: the first non-empty of `CLOUD_RUN_WORKER_POOL` then `K_SERVICE`. - **revision**: the first non-empty of `CLOUD_RUN_REVISION` then `K_REVISION`. - **instance id**: a single HTTP `GET` to the Cloud Run metadata server (`http://metadata.google.internal/computeMetadata/v1/instance/id`, header `Metadata-Flavor: Google`). `WorkerIdPlugin`, registered on the client with `WorkflowClientOptions.Builder.setPlugins(...)`, then -applies the metadata through the SDK plugin hooks and propagates from the client to its Workers: - -- On the client, it sets the Worker identity to `@` (falling back to - `@` and then ``), unless an identity is already set. -- On each Worker, it enables Worker Deployment Versioning with the deployment name as the deployment, - the revision as the build id, and a `PINNED` default versioning behavior, so in-flight Workflows - stay on the revision that started them. +sets the Worker identity to `{instanceId}@{revision}` (falling back to `{instanceId}@{name}` and then +`{instanceId}`) unless an identity is already set. Workers created from the client inherit that +identity; the plugin sets nothing else on them. The Worker reads its connection settings from the environment: @@ -83,13 +78,13 @@ manually. The unit test uses `TestWorkflowRule` and needs neither Cloud Run nor a running Temporal Service: ```bash -./gradlew :cloud-run-worker-id:test +./gradlew :gcp:cloud-run:workerid:test ``` Build the runnable application (from a local SDK checkout, per the note above): ```bash -./gradlew -PtemporalSdkPath=/path/to/sdk-java :cloud-run-worker-id:installDist +./gradlew -PtemporalSdkPath=/path/to/sdk-java :gcp:cloud-run:workerid:installDist ``` ## Deploy to a Cloud Run worker pool @@ -110,9 +105,9 @@ gcloud run worker-pools deploy cloud-run-worker-id \ ``` `--source .` builds the container from the included `Dockerfile`. Because the image build resolves -the unreleased `temporal-gcp-cloud-run` module, a remote source build succeeds only once that module -is released (or published to your Maven Local and made available to the build). Until then, build the -image locally against your SDK checkout and deploy it with `--image` instead: +the unreleased `temporal-gcp-cloud-run-worker-id` module, a remote source build succeeds only once +that module is released (or published to your Maven Local and made available to the build). Until +then, build the image locally against your SDK checkout and deploy it with `--image` instead: ```bash gcloud run worker-pools deploy cloud-run-worker-id \ @@ -121,21 +116,14 @@ gcloud run worker-pools deploy cloud-run-worker-id \ --set-env-vars "TEMPORAL_ADDRESS=$TEMPORAL_ADDRESS,TEMPORAL_NAMESPACE=$TEMPORAL_NAMESPACE,TEMPORAL_TASK_QUEUE=$TEMPORAL_TASK_QUEUE" ``` -Each Cloud Run deployment creates a new revision, which the Worker reports as a new build id under -the same deployment name. +Each Cloud Run revision starts a fresh instance whose Worker reports a distinct identity, which the +Worker logs at startup. -## Create the Worker Deployment Version and start a Workflow +## Start a Workflow -After the Worker is polling, register and route the Worker Deployment Version, then start the sample -Workflow. Use the deployment name (the worker pool name, `cloud-run-worker-id`) and the build id -(the Cloud Run revision) that the Worker logs at startup: +After the Worker is polling, start the sample Workflow on the same Task Queue: ```bash -temporal worker deployment set-current-version \ - --deployment-name cloud-run-worker-id \ - --build-id \ - --yes - temporal workflow start \ --task-queue cloud-run-worker-id \ --type GreetingWorkflow \ @@ -143,6 +131,9 @@ temporal workflow start \ --input '"Cloud Run"' ``` +The Worker's identity appears on its Task Queue pollers (for example in `temporal task-queue +describe`) and on the events it records. + ## Shutdown Cloud Run sends `SIGTERM` and allows a short grace period before `SIGKILL`. The shutdown hook stops @@ -152,14 +143,8 @@ handle cancellation so they can stop within the platform's shutdown window. ## Clean up -Reset routing before deleting the Worker Deployment Version, then delete the worker pool: +Delete the worker pool when you are done: ```bash -temporal worker deployment set-current-version \ - --deployment-name cloud-run-worker-id \ - --unversioned \ - --allow-no-pollers \ - --yes - gcloud run worker-pools delete cloud-run-worker-id --region "$REGION" ``` diff --git a/cloud-run-worker-id/build.gradle b/gcp/cloud-run/workerid/build.gradle similarity index 62% rename from cloud-run-worker-id/build.gradle rename to gcp/cloud-run/workerid/build.gradle index 3ba56045..8e6eb290 100644 --- a/cloud-run-worker-id/build.gradle +++ b/gcp/cloud-run/workerid/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'application' dependencies { implementation "io.temporal:temporal-sdk:$javaSDKVersion" - implementation "io.temporal:temporal-gcp-cloud-run:$javaSDKVersion" + implementation "io.temporal:temporal-gcp-cloud-run-worker-id:$javaSDKVersion" runtimeOnly group: 'ch.qos.logback', name: 'logback-classic', version: '1.5.6' testImplementation "io.temporal:temporal-testing:$javaSDKVersion" @@ -17,5 +17,8 @@ dependencies { } application { - mainClass = 'io.temporal.samples.cloudrunworkerid.CloudRunWorker' + mainClass = 'io.temporal.samples.gcp.cloudrun.workerid.CloudRunWorker' + // Keep a stable launcher/installDist name independent of the nested Gradle + // project name (:gcp:cloud-run:workerid), which the Dockerfile relies on. + applicationName = 'cloud-run-worker-id' } diff --git a/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/CloudRunWorker.java b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/CloudRunWorker.java similarity index 83% rename from cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/CloudRunWorker.java rename to gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/CloudRunWorker.java index ec42da13..379953ba 100644 --- a/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/CloudRunWorker.java +++ b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/CloudRunWorker.java @@ -1,9 +1,9 @@ -package io.temporal.samples.cloudrunworkerid; +package io.temporal.samples.gcp.cloudrun.workerid; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowClientOptions; -import io.temporal.gcp.cloudrun.GoogleCloudRunMetadata; -import io.temporal.gcp.cloudrun.WorkerIdPlugin; +import io.temporal.gcp.cloudrun.workerid.GoogleCloudRunMetadata; +import io.temporal.gcp.cloudrun.workerid.WorkerIdPlugin; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.serviceclient.WorkflowServiceStubsOptions; import io.temporal.worker.Worker; @@ -37,14 +37,13 @@ public static void main(String[] args) { String taskQueue = envOrDefault(TASK_QUEUE_ENV, DEFAULT_TASK_QUEUE); // Plaintext connection to the Temporal Service. Configure TLS or an API key here for a secured - // deployment such as Temporal Cloud. + // Service such as Temporal Cloud. WorkflowServiceStubs service = WorkflowServiceStubs.newServiceStubs( WorkflowServiceStubsOptions.newBuilder().setTarget(address).build()); - // Register WorkerIdPlugin on the client. It sets the derived worker identity on the client and, - // as it propagates to workers, enables Worker Deployment Versioning with the Cloud Run name as - // the deployment name, the revision as the build id, and a PINNED default versioning behavior. + // Register WorkerIdPlugin on the client. It sets the derived worker identity + // ({instanceId}@{revision}) on the client, and workers created from the client inherit it. // Passing the already-fetched metadata avoids a second call to the Cloud Run metadata server. WorkflowClient client = WorkflowClient.newInstance( @@ -56,8 +55,6 @@ public static void main(String[] args) { WorkerFactory factory = WorkerFactory.newInstance(client); - // The plugin configures the worker's deployment version as the worker is created, so no - // per-worker options are needed here. Worker worker = factory.newWorker(taskQueue); worker.registerWorkflowImplementationTypes(GreetingWorkflowImpl.class); worker.registerActivitiesImplementations(new GreetingActivitiesImpl()); @@ -67,10 +64,8 @@ public static void main(String[] args) { factory.start(); logger.info( - "Temporal worker started (identity={}, deployment={}, buildId={}, taskQueue={})", + "Temporal worker started (identity={}, taskQueue={})", metadata.workerIdentity(), - metadata.getName(), - metadata.getRevision(), taskQueue); // Cloud Run worker pools are continuous workloads, so keep the process alive until SIGTERM. diff --git a/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingActivities.java b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivities.java similarity index 84% rename from cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingActivities.java rename to gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivities.java index 86e9b9b1..f04446b5 100644 --- a/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingActivities.java +++ b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivities.java @@ -1,4 +1,4 @@ -package io.temporal.samples.cloudrunworkerid; +package io.temporal.samples.gcp.cloudrun.workerid; import io.temporal.activity.ActivityInterface; import io.temporal.activity.ActivityMethod; diff --git a/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingActivitiesImpl.java b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivitiesImpl.java similarity index 89% rename from cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingActivitiesImpl.java rename to gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivitiesImpl.java index f2f7ddfd..ae83f37d 100644 --- a/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingActivitiesImpl.java +++ b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivitiesImpl.java @@ -1,4 +1,4 @@ -package io.temporal.samples.cloudrunworkerid; +package io.temporal.samples.gcp.cloudrun.workerid; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflow.java b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflow.java similarity index 83% rename from cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflow.java rename to gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflow.java index 1e68f3fa..4fc2a7de 100644 --- a/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflow.java +++ b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflow.java @@ -1,4 +1,4 @@ -package io.temporal.samples.cloudrunworkerid; +package io.temporal.samples.gcp.cloudrun.workerid; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; diff --git a/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflowImpl.java b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowImpl.java similarity index 50% rename from cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflowImpl.java rename to gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowImpl.java index 6ccad02c..f63908c1 100644 --- a/cloud-run-worker-id/src/main/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflowImpl.java +++ b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowImpl.java @@ -1,18 +1,10 @@ -package io.temporal.samples.cloudrunworkerid; +package io.temporal.samples.gcp.cloudrun.workerid; import io.temporal.activity.ActivityOptions; -import io.temporal.common.VersioningBehavior; import io.temporal.workflow.Workflow; -import io.temporal.workflow.WorkflowVersioningBehavior; import java.time.Duration; -/** - * Greeting workflow implementation. - * - *

The method is annotated {@link VersioningBehavior#PINNED}, matching the PINNED default that - * {@link io.temporal.gcp.cloudrun.GoogleCloudRunMetadata} applies to the worker, so executions stay - * on the Cloud Run revision that started them. - */ +/** Greeting workflow implementation. */ public final class GreetingWorkflowImpl implements GreetingWorkflow { private final GreetingActivities activities = @@ -21,7 +13,6 @@ public final class GreetingWorkflowImpl implements GreetingWorkflow { ActivityOptions.newBuilder().setStartToCloseTimeout(Duration.ofSeconds(10)).build()); @Override - @WorkflowVersioningBehavior(VersioningBehavior.PINNED) public String getGreeting(String name) { return activities.composeGreeting(name); } diff --git a/cloud-run-worker-id/src/main/resources/logback.xml b/gcp/cloud-run/workerid/src/main/resources/logback.xml similarity index 100% rename from cloud-run-worker-id/src/main/resources/logback.xml rename to gcp/cloud-run/workerid/src/main/resources/logback.xml diff --git a/cloud-run-worker-id/src/test/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflowTest.java b/gcp/cloud-run/workerid/src/test/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowTest.java similarity index 94% rename from cloud-run-worker-id/src/test/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflowTest.java rename to gcp/cloud-run/workerid/src/test/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowTest.java index cfc8e39d..a4f6d457 100644 --- a/cloud-run-worker-id/src/test/java/io/temporal/samples/cloudrunworkerid/GreetingWorkflowTest.java +++ b/gcp/cloud-run/workerid/src/test/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowTest.java @@ -1,4 +1,4 @@ -package io.temporal.samples.cloudrunworkerid; +package io.temporal.samples.gcp.cloudrun.workerid; import static org.junit.Assert.assertEquals; diff --git a/settings.gradle b/settings.gradle index d502a239..1a9e9b2e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -9,16 +9,17 @@ include 'springboot' include 'springboot-basic' include 'lambda-worker:starter' include 'lambda-worker:worker' -include 'cloud-run-worker-id' +include 'gcp:cloud-run:workerid' -// TEMPORARY (draft): the cloud-run-worker-id sample depends on io.temporal:temporal-gcp-cloud-run -// (and the worker-identity APIs it builds on), which are not yet released to Maven Central. Until -// they ship, wire the sample against a local Temporal Java SDK checkout with a Gradle composite -// build so it can compile and run. Defaults to a sibling ../sdk-java-2 checkout on the -// cloud-run-worker-id branch; override the location with -PtemporalSdkPath=/path/to/sdk-java. When -// the checkout is absent (for example on CI building the other samples) the composite build is -// skipped and only the cloud-run-worker-id module is affected. Remove this block and bump -// javaSDKVersion in build.gradle once temporal-gcp-cloud-run is released. +// TEMPORARY (draft): the gcp:cloud-run:workerid sample depends on +// io.temporal:temporal-gcp-cloud-run-worker-id (and the worker-identity APIs it builds on), which +// are not yet released to Maven Central. Until they ship, wire the sample against a local Temporal +// Java SDK checkout with a Gradle composite build so it can compile and run. Defaults to a sibling +// ../sdk-java-2 checkout on the cloud-run-worker-id branch; override the location with +// -PtemporalSdkPath=/path/to/sdk-java. When the checkout is absent (for example on CI building the +// other samples) the composite build is skipped and only the gcp:cloud-run:workerid module is +// affected. Remove this block and bump javaSDKVersion in build.gradle once +// temporal-gcp-cloud-run-worker-id is released. def temporalSdkPath = gradle.startParameter.projectProperties['temporalSdkPath'] ?: '../sdk-java-2' def temporalSdkFile = new File(temporalSdkPath) def temporalSdkDir = temporalSdkFile.isAbsolute() ? temporalSdkFile : new File(settingsDir, temporalSdkPath) From 9dc533b70d8ca12b8b83f720dc60d7184c7d14aa Mon Sep 17 00:00:00 2001 From: seanbollin Date: Fri, 18 Sep 2026 10:37:53 -0700 Subject: [PATCH 5/6] Fix Cloud Run identity sample for renamed SDK module and trim docs --- gcp/cloud-run/workerid/Dockerfile | 7 +- gcp/cloud-run/workerid/README.md | 150 ++++-------------- gcp/cloud-run/workerid/build.gradle | 5 +- .../gcp/cloudrun/workerid/CloudRunWorker.java | 23 +-- .../cloudrun/workerid/GreetingActivities.java | 4 - .../workerid/GreetingActivitiesImpl.java | 1 - .../cloudrun/workerid/GreetingWorkflow.java | 2 - .../workerid/GreetingWorkflowImpl.java | 2 - .../workerid/GreetingWorkflowTest.java | 2 - settings.gradle | 16 +- 10 files changed, 43 insertions(+), 169 deletions(-) diff --git a/gcp/cloud-run/workerid/Dockerfile b/gcp/cloud-run/workerid/Dockerfile index 64b82d34..35a87b96 100644 --- a/gcp/cloud-run/workerid/Dockerfile +++ b/gcp/cloud-run/workerid/Dockerfile @@ -3,12 +3,7 @@ FROM eclipse-temurin:17-jdk-jammy AS build WORKDIR /workspace COPY . . -# TEMPORARY (draft): this sample depends on io.temporal:temporal-gcp-cloud-run-worker-id, which is -# not yet released to Maven Central. Until it ships, the Gradle build resolves it from a local -# Temporal Java SDK checkout through a composite build (see README.md and settings.gradle). For an -# image build the local SDK checkout must be available in the build context (or the module published -# to Maven Local); once the module is released, bump javaSDKVersion in the samples root build.gradle -# and this builds unchanged from Maven Central. +# temporal-gcp-cloud-run-id is unreleased; the composite build resolves it from a local SDK checkout (see README). RUN ./gradlew --no-daemon :gcp:cloud-run:workerid:installDist FROM eclipse-temurin:17-jre-jammy diff --git a/gcp/cloud-run/workerid/README.md b/gcp/cloud-run/workerid/README.md index 369227d5..68b55a7f 100644 --- a/gcp/cloud-run/workerid/README.md +++ b/gcp/cloud-run/workerid/README.md @@ -1,150 +1,60 @@ -# Temporal Cloud Run worker-identity worker +# Temporal Cloud Run worker-identity sample -This sample runs a continuously polling Temporal Java Worker in a Google Cloud Run **worker pool**. -It registers the `WorkerIdPlugin` from the `temporal-gcp-cloud-run-worker-id` module on the Temporal -client so the Worker's Temporal identity is derived from Cloud Run instance metadata as -`{instanceId}@{revision}`. It registers a small greeting Workflow and Activity and runs until Cloud -Run stops the instance. Identity only: the plugin sets the worker identity and nothing else. +A continuously polling Temporal Java worker for a Google Cloud Run **worker pool** that registers +`CloudRunIdPlugin` from `io.temporal:temporal-gcp-cloud-run-id` on the client, so the worker identity +is derived from Cloud Run instance metadata as `{instanceId}@{revision}`. The plugin sets identity +only. A small greeting workflow and activity run until Cloud Run stops the instance. -Cloud Run runs a long-lived container rather than a per-request handler, so there is no function to -wrap: registering the plugin on the client fetches the metadata once at startup and applies the -derived identity to the client and the Workers created from it. - -> Experimental: Google Cloud Run support is experimental and may change without notice. +> Google Cloud Run support is experimental and may change without notice. ## Unreleased SDK dependency -This sample depends on `io.temporal:temporal-gcp-cloud-run-worker-id`, which is **not yet released** -to Maven Central. Until it ships, the samples build wires the module from a local Temporal Java SDK -checkout through a Gradle composite build (`includeBuild`), configured in the samples root -`settings.gradle`. - -- It defaults to a sibling `../sdk-java-2` checkout on the `cloud-run-worker-id` branch. -- Override the location with `-PtemporalSdkPath=/path/to/sdk-java`. -- When that checkout is absent, the composite build is skipped and only this module is affected; the - other samples still build. - -Once `temporal-gcp-cloud-run-worker-id` is released, remove the composite-build block from -`settings.gradle` and bump `javaSDKVersion` in the samples root `build.gradle` to the released -version; the standard Maven Central build then works without the local checkout. This sample's pull -request stays a draft until then. - -## Prerequisites - -- Java 17+ -- The Temporal CLI (to start Workflows) -- The Google Cloud CLI (`gcloud`) with a project that has Cloud Run enabled -- A Temporal Service reachable from Cloud Run. A plaintext connection is used by default; configure - TLS or an API key in `CloudRunWorker.java` for a secured Service such as Temporal Cloud. - -## Files - -- `src/main/java/io/temporal/samples/gcp/cloudrun/workerid/CloudRunWorker.java` fetches the Cloud - Run metadata, registers `WorkerIdPlugin` on the client to apply the derived identity, and runs a - long-lived Worker with a bounded shutdown on `SIGTERM`. -- `GreetingWorkflow` / `GreetingWorkflowImpl` and `GreetingActivities` / `GreetingActivitiesImpl` are - the sample Workflow and Activity. -- `Dockerfile` packages the Gradle application as the Worker container. +`temporal-gcp-cloud-run-id` is not yet released. `settings.gradle` resolves it (and the other +`io.temporal:*` modules) from a local SDK checkout via a Gradle composite build, defaulting to +`../sdk-java` and overridable with `-PtemporalSdkPath`. CI has no checkout, so its build stays red +until the module ships; then drop the composite block and bump `javaSDKVersion`. ## How it works -Cloud Run **worker pools** set `CLOUD_RUN_WORKER_POOL` and `CLOUD_RUN_REVISION` on every instance -(Cloud Run **services** set `K_SERVICE` and `K_REVISION`). `GoogleCloudRunMetadata.fetch()` resolves: +Cloud Run worker pools set `CLOUD_RUN_WORKER_POOL` and `CLOUD_RUN_REVISION` (services set `K_SERVICE` +and `K_REVISION`). `CloudRunIdPlugin` reads those plus the instance id from the Cloud Run metadata +server and sets the client identity to `{instanceId}@{revision}` unless one is already set; workers +created from the client inherit it. `GoogleCloudRunMetadata.fetch().identity()` exposes the same +value, which the worker logs at startup. -- **name**: the first non-empty of `CLOUD_RUN_WORKER_POOL` then `K_SERVICE`. -- **revision**: the first non-empty of `CLOUD_RUN_REVISION` then `K_REVISION`. -- **instance id**: a single HTTP `GET` to the Cloud Run metadata server - (`http://metadata.google.internal/computeMetadata/v1/instance/id`, header `Metadata-Flavor: - Google`). +The worker reads `TEMPORAL_ADDRESS` (default `127.0.0.1:7233`), `TEMPORAL_NAMESPACE` (default +`default`), and `TEMPORAL_TASK_QUEUE` (default `cloud-run-worker-id`). A plaintext connection is used; +configure TLS or an API key in `CloudRunWorker.java` for a secured Service such as Temporal Cloud. -`WorkerIdPlugin`, registered on the client with `WorkflowClientOptions.Builder.setPlugins(...)`, then -sets the Worker identity to `{instanceId}@{revision}` (falling back to `{instanceId}@{name}` and then -`{instanceId}`) unless an identity is already set. Workers created from the client inherit that -identity; the plugin sets nothing else on them. - -The Worker reads its connection settings from the environment: - -```bash -TEMPORAL_ADDRESS # host:port of the Temporal frontend (default 127.0.0.1:7233) -TEMPORAL_NAMESPACE # Temporal Namespace (default "default") -TEMPORAL_TASK_QUEUE # Task Queue to poll (default "cloud-run-worker-id") -``` - -`CLOUD_RUN_WORKER_POOL` and `CLOUD_RUN_REVISION` are injected by Cloud Run and do not need to be set -manually. - -## Build and test locally - -The unit test uses `TestWorkflowRule` and needs neither Cloud Run nor a running Temporal Service: +## Build and test ```bash ./gradlew :gcp:cloud-run:workerid:test -``` - -Build the runnable application (from a local SDK checkout, per the note above): - -```bash ./gradlew -PtemporalSdkPath=/path/to/sdk-java :gcp:cloud-run:workerid:installDist ``` -## Deploy to a Cloud Run worker pool +## Deploy -Worker pools keep CPU allocated so the Temporal Worker can poll continuously; they are not -request-driven Cloud Run services. Set your connection values and deploy from the sample directory: +Worker pools keep CPU allocated for continuous polling. Until `temporal-gcp-cloud-run-id` is released +a remote `--source` build cannot resolve it, so build the image locally against your SDK checkout and +deploy it by tag: ```bash export REGION=us-central1 -export TEMPORAL_ADDRESS=..tmprl.cloud:7233 -export TEMPORAL_NAMESPACE=. -export TEMPORAL_TASK_QUEUE=cloud-run-worker-id - -gcloud run worker-pools deploy cloud-run-worker-id \ - --source . \ - --region "$REGION" \ - --set-env-vars "TEMPORAL_ADDRESS=$TEMPORAL_ADDRESS,TEMPORAL_NAMESPACE=$TEMPORAL_NAMESPACE,TEMPORAL_TASK_QUEUE=$TEMPORAL_TASK_QUEUE" -``` - -`--source .` builds the container from the included `Dockerfile`. Because the image build resolves -the unreleased `temporal-gcp-cloud-run-worker-id` module, a remote source build succeeds only once -that module is released (or published to your Maven Local and made available to the build). Until -then, build the image locally against your SDK checkout and deploy it with `--image` instead: - -```bash gcloud run worker-pools deploy cloud-run-worker-id \ --image "$REGION-docker.pkg.dev/$PROJECT_ID//cloud-run-worker-id:latest" \ --region "$REGION" \ - --set-env-vars "TEMPORAL_ADDRESS=$TEMPORAL_ADDRESS,TEMPORAL_NAMESPACE=$TEMPORAL_NAMESPACE,TEMPORAL_TASK_QUEUE=$TEMPORAL_TASK_QUEUE" + --set-env-vars "TEMPORAL_ADDRESS=,TEMPORAL_NAMESPACE=,TEMPORAL_TASK_QUEUE=cloud-run-worker-id" ``` -Each Cloud Run revision starts a fresh instance whose Worker reports a distinct identity, which the -Worker logs at startup. +Each revision starts a fresh instance whose worker reports a distinct identity. -## Start a Workflow - -After the Worker is polling, start the sample Workflow on the same Task Queue: +## Start a workflow ```bash -temporal workflow start \ - --task-queue cloud-run-worker-id \ - --type GreetingWorkflow \ - --workflow-id cloud-run-greeting \ - --input '"Cloud Run"' +temporal workflow start --type GreetingWorkflow --task-queue cloud-run-worker-id \ + --workflow-id cloud-run-greeting --input '"Cloud Run"' ``` -The Worker's identity appears on its Task Queue pollers (for example in `temporal task-queue -describe`) and on the events it records. - -## Shutdown - -Cloud Run sends `SIGTERM` and allows a short grace period before `SIGKILL`. The shutdown hook stops -polling, waits up to six seconds for in-flight tasks to drain, escalates to a forced shutdown if -needed, and then closes the service connection. Long-running Activities should still heartbeat and -handle cancellation so they can stop within the platform's shutdown window. - -## Clean up - -Delete the worker pool when you are done: - -```bash -gcloud run worker-pools delete cloud-run-worker-id --region "$REGION" -``` +The identity appears on the task-queue pollers (`temporal task-queue describe`) and recorded events. +Delete the pool with `gcloud run worker-pools delete cloud-run-worker-id --region "$REGION"`. diff --git a/gcp/cloud-run/workerid/build.gradle b/gcp/cloud-run/workerid/build.gradle index 8e6eb290..6fe4cda9 100644 --- a/gcp/cloud-run/workerid/build.gradle +++ b/gcp/cloud-run/workerid/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'application' dependencies { implementation "io.temporal:temporal-sdk:$javaSDKVersion" - implementation "io.temporal:temporal-gcp-cloud-run-worker-id:$javaSDKVersion" + implementation "io.temporal:temporal-gcp-cloud-run-id:$javaSDKVersion" runtimeOnly group: 'ch.qos.logback', name: 'logback-classic', version: '1.5.6' testImplementation "io.temporal:temporal-testing:$javaSDKVersion" @@ -18,7 +18,6 @@ dependencies { application { mainClass = 'io.temporal.samples.gcp.cloudrun.workerid.CloudRunWorker' - // Keep a stable launcher/installDist name independent of the nested Gradle - // project name (:gcp:cloud-run:workerid), which the Dockerfile relies on. + // Stable launcher name the Dockerfile relies on, independent of the Gradle project path. applicationName = 'cloud-run-worker-id' } diff --git a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/CloudRunWorker.java b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/CloudRunWorker.java index 379953ba..6b6be7d1 100644 --- a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/CloudRunWorker.java +++ b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/CloudRunWorker.java @@ -2,8 +2,8 @@ import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowClientOptions; -import io.temporal.gcp.cloudrun.workerid.GoogleCloudRunMetadata; -import io.temporal.gcp.cloudrun.workerid.WorkerIdPlugin; +import io.temporal.gcp.cloudrun.id.CloudRunIdPlugin; +import io.temporal.gcp.cloudrun.id.GoogleCloudRunMetadata; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.serviceclient.WorkflowServiceStubsOptions; import io.temporal.worker.Worker; @@ -27,30 +27,22 @@ public final class CloudRunWorker { private CloudRunWorker() {} public static void main(String[] args) { - // Read Cloud Run instance metadata once during startup. This performs a single HTTP request to - // the Cloud Run metadata server and throws IllegalStateException when it is unreachable, which - // usually means the process is not running on Google Cloud Run. - GoogleCloudRunMetadata metadata = GoogleCloudRunMetadata.fetch(); - String address = envOrDefault(ADDRESS_ENV, DEFAULT_ADDRESS); String namespace = envOrDefault(NAMESPACE_ENV, DEFAULT_NAMESPACE); String taskQueue = envOrDefault(TASK_QUEUE_ENV, DEFAULT_TASK_QUEUE); - // Plaintext connection to the Temporal Service. Configure TLS or an API key here for a secured - // Service such as Temporal Cloud. + // Plaintext connection; add TLS or an API key here for Temporal Cloud. WorkflowServiceStubs service = WorkflowServiceStubs.newServiceStubs( WorkflowServiceStubsOptions.newBuilder().setTarget(address).build()); - // Register WorkerIdPlugin on the client. It sets the derived worker identity - // ({instanceId}@{revision}) on the client, and workers created from the client inherit it. - // Passing the already-fetched metadata avoids a second call to the Cloud Run metadata server. + // CloudRunIdPlugin sets the client identity to {instanceId}@{revision} from metadata. WorkflowClient client = WorkflowClient.newInstance( service, WorkflowClientOptions.newBuilder() .setNamespace(namespace) - .setPlugins(new WorkerIdPlugin(metadata)) + .setPlugins(new CloudRunIdPlugin()) .build()); WorkerFactory factory = WorkerFactory.newInstance(client); @@ -65,7 +57,7 @@ public static void main(String[] args) { factory.start(); logger.info( "Temporal worker started (identity={}, taskQueue={})", - metadata.workerIdentity(), + GoogleCloudRunMetadata.fetch().identity(), taskQueue); // Cloud Run worker pools are continuous workloads, so keep the process alive until SIGTERM. @@ -73,8 +65,7 @@ public static void main(String[] args) { } private static void shutdown(WorkerFactory factory, WorkflowServiceStubs service) { - // Cloud Run sends SIGTERM and allows a short grace period before SIGKILL. Stop polling, drain - // in-flight tasks, then close the service connection. + // Cloud Run sends SIGTERM before SIGKILL; stop polling, drain in-flight tasks, then close. factory.shutdown(); factory.awaitTermination(6, TimeUnit.SECONDS); if (!factory.isTerminated()) { diff --git a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivities.java b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivities.java index f04446b5..cf344da0 100644 --- a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivities.java +++ b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivities.java @@ -1,12 +1,8 @@ package io.temporal.samples.gcp.cloudrun.workerid; import io.temporal.activity.ActivityInterface; -import io.temporal.activity.ActivityMethod; -/** Activity interface used by {@link GreetingWorkflow}. */ @ActivityInterface public interface GreetingActivities { - - @ActivityMethod String composeGreeting(String name); } diff --git a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivitiesImpl.java b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivitiesImpl.java index ae83f37d..7b808e74 100644 --- a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivitiesImpl.java +++ b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivitiesImpl.java @@ -3,7 +3,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** Activity implementation that returns a simple greeting. */ public final class GreetingActivitiesImpl implements GreetingActivities { private static final Logger logger = LoggerFactory.getLogger(GreetingActivitiesImpl.class); diff --git a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflow.java b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflow.java index 4fc2a7de..e8e21c96 100644 --- a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflow.java +++ b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflow.java @@ -3,10 +3,8 @@ import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; -/** A small greeting workflow run by the Cloud Run worker. */ @WorkflowInterface public interface GreetingWorkflow { - @WorkflowMethod String getGreeting(String name); } diff --git a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowImpl.java b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowImpl.java index f63908c1..2ba25195 100644 --- a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowImpl.java +++ b/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowImpl.java @@ -4,9 +4,7 @@ import io.temporal.workflow.Workflow; import java.time.Duration; -/** Greeting workflow implementation. */ public final class GreetingWorkflowImpl implements GreetingWorkflow { - private final GreetingActivities activities = Workflow.newActivityStub( GreetingActivities.class, diff --git a/gcp/cloud-run/workerid/src/test/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowTest.java b/gcp/cloud-run/workerid/src/test/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowTest.java index a4f6d457..14f596dd 100644 --- a/gcp/cloud-run/workerid/src/test/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowTest.java +++ b/gcp/cloud-run/workerid/src/test/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowTest.java @@ -7,9 +7,7 @@ import org.junit.Rule; import org.junit.Test; -/** Unit test for the sample Workflow and Activity. */ public class GreetingWorkflowTest { - @Rule public TestWorkflowRule testWorkflowRule = TestWorkflowRule.newBuilder() diff --git a/settings.gradle b/settings.gradle index 1a9e9b2e..518f3a76 100644 --- a/settings.gradle +++ b/settings.gradle @@ -11,18 +11,8 @@ include 'lambda-worker:starter' include 'lambda-worker:worker' include 'gcp:cloud-run:workerid' -// TEMPORARY (draft): the gcp:cloud-run:workerid sample depends on -// io.temporal:temporal-gcp-cloud-run-worker-id (and the worker-identity APIs it builds on), which -// are not yet released to Maven Central. Until they ship, wire the sample against a local Temporal -// Java SDK checkout with a Gradle composite build so it can compile and run. Defaults to a sibling -// ../sdk-java-2 checkout on the cloud-run-worker-id branch; override the location with -// -PtemporalSdkPath=/path/to/sdk-java. When the checkout is absent (for example on CI building the -// other samples) the composite build is skipped and only the gcp:cloud-run:workerid module is -// affected. Remove this block and bump javaSDKVersion in build.gradle once -// temporal-gcp-cloud-run-worker-id is released. -def temporalSdkPath = gradle.startParameter.projectProperties['temporalSdkPath'] ?: '../sdk-java-2' -def temporalSdkFile = new File(temporalSdkPath) -def temporalSdkDir = temporalSdkFile.isAbsolute() ? temporalSdkFile : new File(settingsDir, temporalSdkPath) -if (temporalSdkDir.isDirectory()) { +// The gcp:cloud-run samples use unreleased temporal-gcp-cloud-run-* modules; resolve them from a local SDK checkout (default ../sdk-java, override with -PtemporalSdkPath) via composite build. +def temporalSdkPath = gradle.startParameter.projectProperties['temporalSdkPath'] ?: '../sdk-java' +if (file(temporalSdkPath).isDirectory()) { includeBuild temporalSdkPath } From 976a3a020f5df98a3ad710afe555dcdc51bd2d53 Mon Sep 17 00:00:00 2001 From: seanbollin Date: Fri, 18 Sep 2026 16:23:57 -0700 Subject: [PATCH 6/6] Rename Cloud Run Id sample to match SDK module and drop long-lived wording --- gcp/cloud-run/{workerid => id}/Dockerfile | 6 ++-- gcp/cloud-run/{workerid => id}/README.md | 30 +++++++++---------- gcp/cloud-run/{workerid => id}/build.gradle | 4 +-- .../gcp/cloudrun/id}/CloudRunWorker.java | 8 ++--- .../gcp/cloudrun/id}/GreetingActivities.java | 2 +- .../cloudrun/id}/GreetingActivitiesImpl.java | 2 +- .../gcp/cloudrun/id}/GreetingWorkflow.java | 2 +- .../cloudrun/id}/GreetingWorkflowImpl.java | 2 +- .../src/main/resources/logback.xml | 0 .../cloudrun/id}/GreetingWorkflowTest.java | 2 +- settings.gradle | 2 +- 11 files changed, 30 insertions(+), 30 deletions(-) rename gcp/cloud-run/{workerid => id}/Dockerfile (64%) rename gcp/cloud-run/{workerid => id}/README.md (61%) rename gcp/cloud-run/{workerid => id}/build.gradle (86%) rename gcp/cloud-run/{workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid => id/src/main/java/io/temporal/samples/gcp/cloudrun/id}/CloudRunWorker.java (91%) rename gcp/cloud-run/{workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid => id/src/main/java/io/temporal/samples/gcp/cloudrun/id}/GreetingActivities.java (74%) rename gcp/cloud-run/{workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid => id/src/main/java/io/temporal/samples/gcp/cloudrun/id}/GreetingActivitiesImpl.java (88%) rename gcp/cloud-run/{workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid => id/src/main/java/io/temporal/samples/gcp/cloudrun/id}/GreetingWorkflow.java (79%) rename gcp/cloud-run/{workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid => id/src/main/java/io/temporal/samples/gcp/cloudrun/id}/GreetingWorkflowImpl.java (90%) rename gcp/cloud-run/{workerid => id}/src/main/resources/logback.xml (100%) rename gcp/cloud-run/{workerid/src/test/java/io/temporal/samples/gcp/cloudrun/workerid => id/src/test/java/io/temporal/samples/gcp/cloudrun/id}/GreetingWorkflowTest.java (94%) diff --git a/gcp/cloud-run/workerid/Dockerfile b/gcp/cloud-run/id/Dockerfile similarity index 64% rename from gcp/cloud-run/workerid/Dockerfile rename to gcp/cloud-run/id/Dockerfile index 35a87b96..76bf90c3 100644 --- a/gcp/cloud-run/workerid/Dockerfile +++ b/gcp/cloud-run/id/Dockerfile @@ -4,14 +4,14 @@ WORKDIR /workspace COPY . . # temporal-gcp-cloud-run-id is unreleased; the composite build resolves it from a local SDK checkout (see README). -RUN ./gradlew --no-daemon :gcp:cloud-run:workerid:installDist +RUN ./gradlew --no-daemon :gcp:cloud-run:id:installDist FROM eclipse-temurin:17-jre-jammy RUN useradd --create-home --uid 10001 temporal WORKDIR /app COPY --from=build --chown=temporal:temporal \ - /workspace/gcp/cloud-run/workerid/build/install/cloud-run-worker-id/ /app/ + /workspace/gcp/cloud-run/id/build/install/cloud-run-id/ /app/ USER 10001 -ENTRYPOINT ["/app/bin/cloud-run-worker-id"] +ENTRYPOINT ["/app/bin/cloud-run-id"] diff --git a/gcp/cloud-run/workerid/README.md b/gcp/cloud-run/id/README.md similarity index 61% rename from gcp/cloud-run/workerid/README.md rename to gcp/cloud-run/id/README.md index 68b55a7f..111ed970 100644 --- a/gcp/cloud-run/workerid/README.md +++ b/gcp/cloud-run/id/README.md @@ -1,9 +1,9 @@ -# Temporal Cloud Run worker-identity sample +# Temporal Cloud Run Id sample -A continuously polling Temporal Java worker for a Google Cloud Run **worker pool** that registers -`CloudRunIdPlugin` from `io.temporal:temporal-gcp-cloud-run-id` on the client, so the worker identity -is derived from Cloud Run instance metadata as `{instanceId}@{revision}`. The plugin sets identity -only. A small greeting workflow and activity run until Cloud Run stops the instance. +A Temporal Java Worker for a Google Cloud Run **worker pool** that registers +`CloudRunIdPlugin` from `io.temporal:temporal-gcp-cloud-run-id` on the client, so the Temporal +client identity is set from Cloud Run instance metadata as `{instanceId}@{revision}`. The plugin +sets identity only. A small greeting workflow and activity run until Cloud Run stops the instance. > Google Cloud Run support is experimental and may change without notice. @@ -23,28 +23,28 @@ created from the client inherit it. `GoogleCloudRunMetadata.fetch().identity()` value, which the worker logs at startup. The worker reads `TEMPORAL_ADDRESS` (default `127.0.0.1:7233`), `TEMPORAL_NAMESPACE` (default -`default`), and `TEMPORAL_TASK_QUEUE` (default `cloud-run-worker-id`). A plaintext connection is used; +`default`), and `TEMPORAL_TASK_QUEUE` (default `cloud-run-id`). A plaintext connection is used; configure TLS or an API key in `CloudRunWorker.java` for a secured Service such as Temporal Cloud. ## Build and test ```bash -./gradlew :gcp:cloud-run:workerid:test -./gradlew -PtemporalSdkPath=/path/to/sdk-java :gcp:cloud-run:workerid:installDist +./gradlew :gcp:cloud-run:id:test +./gradlew -PtemporalSdkPath=/path/to/sdk-java :gcp:cloud-run:id:installDist ``` ## Deploy -Worker pools keep CPU allocated for continuous polling. Until `temporal-gcp-cloud-run-id` is released -a remote `--source` build cannot resolve it, so build the image locally against your SDK checkout and +Worker pools keep CPU allocated between requests. Until `temporal-gcp-cloud-run-id` is released a +remote `--source` build cannot resolve it, so build the image locally against your SDK checkout and deploy it by tag: ```bash export REGION=us-central1 -gcloud run worker-pools deploy cloud-run-worker-id \ - --image "$REGION-docker.pkg.dev/$PROJECT_ID//cloud-run-worker-id:latest" \ +gcloud run worker-pools deploy cloud-run-id \ + --image "$REGION-docker.pkg.dev/$PROJECT_ID//cloud-run-id:latest" \ --region "$REGION" \ - --set-env-vars "TEMPORAL_ADDRESS=,TEMPORAL_NAMESPACE=,TEMPORAL_TASK_QUEUE=cloud-run-worker-id" + --set-env-vars "TEMPORAL_ADDRESS=,TEMPORAL_NAMESPACE=,TEMPORAL_TASK_QUEUE=cloud-run-id" ``` Each revision starts a fresh instance whose worker reports a distinct identity. @@ -52,9 +52,9 @@ Each revision starts a fresh instance whose worker reports a distinct identity. ## Start a workflow ```bash -temporal workflow start --type GreetingWorkflow --task-queue cloud-run-worker-id \ +temporal workflow start --type GreetingWorkflow --task-queue cloud-run-id \ --workflow-id cloud-run-greeting --input '"Cloud Run"' ``` The identity appears on the task-queue pollers (`temporal task-queue describe`) and recorded events. -Delete the pool with `gcloud run worker-pools delete cloud-run-worker-id --region "$REGION"`. +Delete the pool with `gcloud run worker-pools delete cloud-run-id --region "$REGION"`. diff --git a/gcp/cloud-run/workerid/build.gradle b/gcp/cloud-run/id/build.gradle similarity index 86% rename from gcp/cloud-run/workerid/build.gradle rename to gcp/cloud-run/id/build.gradle index 6fe4cda9..a92468df 100644 --- a/gcp/cloud-run/workerid/build.gradle +++ b/gcp/cloud-run/id/build.gradle @@ -17,7 +17,7 @@ dependencies { } application { - mainClass = 'io.temporal.samples.gcp.cloudrun.workerid.CloudRunWorker' + mainClass = 'io.temporal.samples.gcp.cloudrun.id.CloudRunWorker' // Stable launcher name the Dockerfile relies on, independent of the Gradle project path. - applicationName = 'cloud-run-worker-id' + applicationName = 'cloud-run-id' } diff --git a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/CloudRunWorker.java b/gcp/cloud-run/id/src/main/java/io/temporal/samples/gcp/cloudrun/id/CloudRunWorker.java similarity index 91% rename from gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/CloudRunWorker.java rename to gcp/cloud-run/id/src/main/java/io/temporal/samples/gcp/cloudrun/id/CloudRunWorker.java index 6b6be7d1..a1e91468 100644 --- a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/CloudRunWorker.java +++ b/gcp/cloud-run/id/src/main/java/io/temporal/samples/gcp/cloudrun/id/CloudRunWorker.java @@ -1,4 +1,4 @@ -package io.temporal.samples.gcp.cloudrun.workerid; +package io.temporal.samples.gcp.cloudrun.id; import io.temporal.client.WorkflowClient; import io.temporal.client.WorkflowClientOptions; @@ -12,7 +12,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** A continuously polling Temporal Worker for a Google Cloud Run worker pool. */ +/** A Temporal Worker for a Google Cloud Run worker pool. */ public final class CloudRunWorker { private static final Logger logger = LoggerFactory.getLogger(CloudRunWorker.class); @@ -22,7 +22,7 @@ public final class CloudRunWorker { static final String DEFAULT_ADDRESS = "127.0.0.1:7233"; static final String DEFAULT_NAMESPACE = "default"; - static final String DEFAULT_TASK_QUEUE = "cloud-run-worker-id"; + static final String DEFAULT_TASK_QUEUE = "cloud-run-id"; private CloudRunWorker() {} @@ -60,7 +60,7 @@ public static void main(String[] args) { GoogleCloudRunMetadata.fetch().identity(), taskQueue); - // Cloud Run worker pools are continuous workloads, so keep the process alive until SIGTERM. + // Keep the process alive until Cloud Run sends SIGTERM. factory.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); } diff --git a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivities.java b/gcp/cloud-run/id/src/main/java/io/temporal/samples/gcp/cloudrun/id/GreetingActivities.java similarity index 74% rename from gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivities.java rename to gcp/cloud-run/id/src/main/java/io/temporal/samples/gcp/cloudrun/id/GreetingActivities.java index cf344da0..836b24d6 100644 --- a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivities.java +++ b/gcp/cloud-run/id/src/main/java/io/temporal/samples/gcp/cloudrun/id/GreetingActivities.java @@ -1,4 +1,4 @@ -package io.temporal.samples.gcp.cloudrun.workerid; +package io.temporal.samples.gcp.cloudrun.id; import io.temporal.activity.ActivityInterface; diff --git a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivitiesImpl.java b/gcp/cloud-run/id/src/main/java/io/temporal/samples/gcp/cloudrun/id/GreetingActivitiesImpl.java similarity index 88% rename from gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivitiesImpl.java rename to gcp/cloud-run/id/src/main/java/io/temporal/samples/gcp/cloudrun/id/GreetingActivitiesImpl.java index 7b808e74..0b790d03 100644 --- a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingActivitiesImpl.java +++ b/gcp/cloud-run/id/src/main/java/io/temporal/samples/gcp/cloudrun/id/GreetingActivitiesImpl.java @@ -1,4 +1,4 @@ -package io.temporal.samples.gcp.cloudrun.workerid; +package io.temporal.samples.gcp.cloudrun.id; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflow.java b/gcp/cloud-run/id/src/main/java/io/temporal/samples/gcp/cloudrun/id/GreetingWorkflow.java similarity index 79% rename from gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflow.java rename to gcp/cloud-run/id/src/main/java/io/temporal/samples/gcp/cloudrun/id/GreetingWorkflow.java index e8e21c96..3adbcc86 100644 --- a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflow.java +++ b/gcp/cloud-run/id/src/main/java/io/temporal/samples/gcp/cloudrun/id/GreetingWorkflow.java @@ -1,4 +1,4 @@ -package io.temporal.samples.gcp.cloudrun.workerid; +package io.temporal.samples.gcp.cloudrun.id; import io.temporal.workflow.WorkflowInterface; import io.temporal.workflow.WorkflowMethod; diff --git a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowImpl.java b/gcp/cloud-run/id/src/main/java/io/temporal/samples/gcp/cloudrun/id/GreetingWorkflowImpl.java similarity index 90% rename from gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowImpl.java rename to gcp/cloud-run/id/src/main/java/io/temporal/samples/gcp/cloudrun/id/GreetingWorkflowImpl.java index 2ba25195..f934fbdf 100644 --- a/gcp/cloud-run/workerid/src/main/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowImpl.java +++ b/gcp/cloud-run/id/src/main/java/io/temporal/samples/gcp/cloudrun/id/GreetingWorkflowImpl.java @@ -1,4 +1,4 @@ -package io.temporal.samples.gcp.cloudrun.workerid; +package io.temporal.samples.gcp.cloudrun.id; import io.temporal.activity.ActivityOptions; import io.temporal.workflow.Workflow; diff --git a/gcp/cloud-run/workerid/src/main/resources/logback.xml b/gcp/cloud-run/id/src/main/resources/logback.xml similarity index 100% rename from gcp/cloud-run/workerid/src/main/resources/logback.xml rename to gcp/cloud-run/id/src/main/resources/logback.xml diff --git a/gcp/cloud-run/workerid/src/test/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowTest.java b/gcp/cloud-run/id/src/test/java/io/temporal/samples/gcp/cloudrun/id/GreetingWorkflowTest.java similarity index 94% rename from gcp/cloud-run/workerid/src/test/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowTest.java rename to gcp/cloud-run/id/src/test/java/io/temporal/samples/gcp/cloudrun/id/GreetingWorkflowTest.java index 14f596dd..f312acb4 100644 --- a/gcp/cloud-run/workerid/src/test/java/io/temporal/samples/gcp/cloudrun/workerid/GreetingWorkflowTest.java +++ b/gcp/cloud-run/id/src/test/java/io/temporal/samples/gcp/cloudrun/id/GreetingWorkflowTest.java @@ -1,4 +1,4 @@ -package io.temporal.samples.gcp.cloudrun.workerid; +package io.temporal.samples.gcp.cloudrun.id; import static org.junit.Assert.assertEquals; diff --git a/settings.gradle b/settings.gradle index 518f3a76..91299945 100644 --- a/settings.gradle +++ b/settings.gradle @@ -9,7 +9,7 @@ include 'springboot' include 'springboot-basic' include 'lambda-worker:starter' include 'lambda-worker:worker' -include 'gcp:cloud-run:workerid' +include 'gcp:cloud-run:id' // The gcp:cloud-run samples use unreleased temporal-gcp-cloud-run-* modules; resolve them from a local SDK checkout (default ../sdk-java, override with -PtemporalSdkPath) via composite build. def temporalSdkPath = gradle.startParameter.projectProperties['temporalSdkPath'] ?: '../sdk-java'