Skip to content

Commit

Permalink
Merge branch 'master' into on-conflict-options
Browse files Browse the repository at this point in the history
  • Loading branch information
rodrigozhou committed Feb 27, 2025
2 parents 44f562e + 6b05cd8 commit 8158ab0
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 8 deletions.
79 changes: 79 additions & 0 deletions releases/v1.28.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# **💥 BREAKING CHANGES**

### Nexus (Public Preview)

- ⚠️ **IMPORTANT** ⚠️ This SDK release requires server `>=1.27.0` to properly support the full set of changes from the previous SDK release. Most notably the built-in error translation logic changed in a way that may cause Nexus tasks to retry until the caller specified schedule-to-close timeout on certain failures, see more below.
- Setting `WorkflowIDConflictPolicy` to `WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING` has been temporarily disabled, and will fail requests with a retryable internal error.
- This is to protect users from making a false assumption that the same workflow can be used to back multiple operations. This capability will be enabled in a follow up release.
- `WorkflowClientOperationHandlers` was renamed to `WorkflowRunOperation`
- `OperationId` was renamed to `OperationToken` and the content for a `WorkflowRunOperation` of it was changed to a structured token instead of copying the workflow ID directly.
- Removed `WorkflowClient` from the input of all Temporal nexus handlers, a client can now be accessed by calling `Nexus.getOperationContext().getWorkflowClient()`
- `FailureConverter` now supports serializing and deserializing `HandlerException` . Previously these may have been deserialized as `ApplicationFailure` .
- Note: This is can potentially cause Non-Determinism exceptions if users were handling `ApplicationFailure` .
- The promise returned from `NexusOperationHandle.getExecution()` now correctly will return the appropriate exception if the underlying nexus fails in a synchronous manner
- Note: This is can potentially cause Non-Determinism exceptions if users called `NexusOperationHandle.getExecution()`

### Failure Converter

The `FailureConverter` interface was changed. `FailureConverter.failureToException` now can return any type implementing `RuntimeException` instead of just types implementing `TemporalFailure`

### Java Protobuf 3/4 Support

The Temporal Java SDK now supports `protobuf-java` 3.x and 4.x. To support these, the Temporal Java SDK allows any protobuf library >= 3.25. Temporal strongly recommends using the latest `protobuf-java` 4.x library unless you absolutely cannot. If you cannot use protobuf-java 3.25 >=, you can try `temporal-shaded` which includes a shaded version of the `protobuf-java` library.

# **Highlights**

### Spring Boot API Key support

The Java SDK Spring Boot integration now directly supports API key authentication.

For documentation see: https://github.com/temporalio/sdk-java/tree/master/temporal-spring-boot-autoconfigure#api-keys

### Spring Boot Multi-Namespace support (Experimental)

The Java SDK Spring Boot integration now has experimental support for running multiple none-root namespace along side the root namespace.

For documentation see: https://github.com/temporalio/sdk-java/tree/master/temporal-spring-boot-autoconfigure#running-multiple-name-space-experimental

# What's Changed

2024-12-09 - e1bef897 - Update protocloud submodule (#2344)
2024-12-12 - 53a8af7e - Remove Experimental annotations from Update APIs (#2347)
2024-12-27 - c3e0e779 - Set request Id on SignalWorkflowExecutionRequest (#2352)
2025-01-06 - 82d3c93d - Update Java SDK for Temporal Sever v1.26.2 (#2357)
2025-01-06 - 9a8894af - Set LastHeartbeatDetails on activity failure (#2354)
2025-01-06 - ff333ca7 - Add javadocs for ActivityCompletionClient (#2353)
2025-01-08 - cf061311 - Test server support for Nexus operation complete before start (#2348)
2025-01-15 - 35e390ea - Add method to get workflow client from an activity (#2369)
2025-01-16 - 90e51259 - Fix NDE caused by removing Workflow.getVersion with a succeeding Work… (#2370)
2025-01-16 - b187644b - Add details to manifest (#2355)
2025-01-16 - b593b35b - [OpenTracing] Wrap returned promises in OutboundCallsInterceptor (#2366)
2025-01-17 - 3ad0b0e6 - Avoid lock up on unexpected ExecutorService errors while executing Local Activities (#2371)
2025-01-22 - b471e13e - Access to workflow/activity instance from context (#2384)
2025-01-22 - c51e5d19 - Upgrade some test dependencies (#2382)
2025-01-22 - cdbc520a - Split up & use more appropriate timeouts for parallel LAs test (#2385)
2025-01-28 - 8b17a526 - Support Proto 3 and 4 (#2383)
2025-01-28 - ce90d24e - Enable speculative workflow tasks (#2390)
2025-01-28 - f93910b1 - Make sure GetVersion never yields (#2376)
2025-02-03 - de33b3ad - Update docs for max workflow task timeout (#2396)
2025-02-04 - fd65ea97 - Inject namespace header (#2400)
2025-02-07 - 32df8d4b - Remove Nexus sync client handler (#2403)
2025-02-07 - 76630fef - Update max task timeout (#2407)
2025-02-10 - 32fbf020 - Fix kotlin child workflow execute varargs (#2395)
2025-02-10 - f9a9cad9 - Rename WorkflowClientOperationHandlers->WorkflowRunOperation (#2405)
2025-02-10 - fc4d714b - Update proto v1.44.0 (#2406)
2025-02-11 - 00f7dd02 - Add API key property to Springboot (#2408)
2025-02-11 - 24f225c7 - Java test server support for attaching links to signal and signal with start requests (#2411)
2025-02-12 - c6e0306a - Special behavior for Temporal built-in prefixes (#2409)
2025-02-17 - c6375d67 - feat: multi namespace support (#2378)
2025-02-18 - 436d0800 - Add Graal reflection config for UwS (#2363)
2025-02-18 - 6f4621de - Update readme for multi namespace support (#2416)
2025-02-18 - a2455aff - Make sure workflow_task_execution_failed always has a failure_reason (#2419)
2025-02-18 - a643a799 - Add nexus configuration to spring boot readme (#2417)
2025-02-20 - f92b53c2 - 💥 Nexus error rehydration (#2365)
2025-02-21 - 963ea9ff - Add sdk name/version to task completions when unset or changed (#2422)
2025-02-24 - 49bd366a - Add support for operation timeout header (#2427)
2025-02-24 - 729e25e3 - Workflow run token (#2421)
2025-02-24 - d0cf3f37 - Add support for attaching to a running workflow (#2424)
2025-02-25 - 7cd49327 - fix documentation in CapacityConfigurationProperties (#2429)
2025-02-25 - f90c57b5 - Block using conflict policy UseExisting for Nexus WorkflowRunOperation (#2428)
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@

import com.google.common.base.Defaults;
import io.nexusrpc.Header;
import io.nexusrpc.handler.HandlerException;
import io.nexusrpc.handler.ServiceImplInstance;
import io.temporal.api.common.v1.Callback;
import io.temporal.api.enums.v1.TaskQueueKind;
import io.temporal.api.enums.v1.WorkflowIdConflictPolicy;
import io.temporal.api.taskqueue.v1.TaskQueue;
import io.temporal.client.OnConflictOptions;
import io.temporal.client.WorkflowOptions;
Expand All @@ -35,6 +37,7 @@
import io.temporal.internal.client.NexusStartWorkflowRequest;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;
import java.util.stream.Collectors;
import org.slf4j.Logger;
Expand Down Expand Up @@ -151,6 +154,17 @@ public static WorkflowStub createNexusBoundStub(
.setAttachLinks(true)
.setAttachCompletionCallbacks(true)
.build());

// TODO(klassenq) temporarily blocking conflict policy USE_EXISTING.
if (Objects.equals(
WorkflowIdConflictPolicy.WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING,
options.getWorkflowIdConflictPolicy())) {
throw new HandlerException(
HandlerException.ErrorType.INTERNAL,
new IllegalArgumentException(
"Workflow ID conflict policy UseExisting is not supported for Nexus WorkflowRunOperation."),
HandlerException.RetryBehavior.NON_RETRYABLE);
}
return stub.newInstance(nexusWorkflowOptions.build());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (C) 2022 Temporal Technologies, Inc. All Rights Reserved.
*
* Copyright (C) 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this material except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.temporal.workflow.nexus;

import io.nexusrpc.Operation;
import io.nexusrpc.Service;
import io.nexusrpc.handler.OperationHandler;
import io.nexusrpc.handler.OperationImpl;
import io.nexusrpc.handler.ServiceImpl;
import io.temporal.testing.internal.SDKTestWorkflowRule;
import io.temporal.workflow.*;
import java.util.Map;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;

// Test the start operation handler receives the correct headers
public class HeaderTest {
@Rule
public SDKTestWorkflowRule testWorkflowRule =
SDKTestWorkflowRule.newBuilder()
.setWorkflowTypes(TestNexus.class)
.setNexusServiceImplementation(new TestNexusServiceImpl())
.build();

@Test
public void testOperationHeaders() {
TestWorkflow workflowStub = testWorkflowRule.newWorkflowStubTimeoutOptions(TestWorkflow.class);
Map<String, String> headers = workflowStub.execute(testWorkflowRule.getTaskQueue());
Assert.assertTrue(headers.containsKey("operation-timeout"));
Assert.assertTrue(headers.containsKey("request-timeout"));
}

@WorkflowInterface
public interface TestWorkflow {
@WorkflowMethod
Map<String, String> execute(String arg);
}

public static class TestNexus implements TestWorkflow {
@Override
public Map<String, String> execute(String input) {
// Try to call with the typed stub
TestNexusService serviceStub = Workflow.newNexusServiceStub(TestNexusService.class);
return serviceStub.operation();
}
}

@Service
public interface TestNexusService {
@Operation
Map<String, String> operation();
}

@ServiceImpl(service = TestNexusService.class)
public static class TestNexusServiceImpl {
@OperationImpl
public OperationHandler<Void, Map<String, String>> operation() {
return OperationHandler.sync((context, details, input) -> context.getHeaders());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,9 @@
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.*;

@Ignore("Skipping until we can support USE_EXISTING")
public class WorkflowHandleUseExistingOnConflictCancelTest {
@Rule
public SDKTestWorkflowRule testWorkflowRule =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,9 @@
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.*;

@Ignore("Skipping until we can support USE_EXISTING")
public class WorkflowHandleUseExistingOnConflictTest {
@Rule
public SDKTestWorkflowRule testWorkflowRule =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public static class CapacityConfigurationProperties {

/**
* @param maxConcurrentWorkflowTaskExecutors defines {@link
* io.temporal.worker.WorkerOptions.Builder#setMaxConcurrentWorkflowTaskPollers(int)}
* io.temporal.worker.WorkerOptions.Builder#setMaxConcurrentWorkflowTaskExecutionSize(int)}
* @param maxConcurrentActivityExecutors defines {@link
* io.temporal.worker.WorkerOptions.Builder#setMaxConcurrentActivityExecutionSize(int)}
* @param maxConcurrentLocalActivityExecutors defines {@link
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,9 @@ private static void scheduleNexusOperation(
io.temporal.api.nexus.v1.Request.newBuilder()
.setScheduledTime(ctx.currentTime())
.putAllHeader(attr.getNexusHeaderMap())
.putHeader(
io.nexusrpc.Header.OPERATION_TIMEOUT.toLowerCase(),
attr.getScheduleToCloseTimeout().toString())
.setStartOperation(
StartOperationRequest.newBuilder()
.setService(attr.getService())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,9 @@ public void pollNexusTaskQueue(
String taskTimeout =
String.valueOf(Timestamps.between(store.currentTime(), task.getDeadline()).getSeconds());
Request.Builder req =
task.getTask().getRequestBuilder().putHeader(Header.REQUEST_TIMEOUT, taskTimeout + "s");
task.getTask()
.getRequestBuilder()
.putHeader(Header.REQUEST_TIMEOUT.toLowerCase(), taskTimeout + "s");
PollNexusTaskQueueResponse.Builder resp = task.getTask().setRequest(req);

responseObserver.onNext(resp.build());
Expand Down

0 comments on commit 8158ab0

Please sign in to comment.