Skip to content
5 changes: 5 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
Verify Compilation:
```shell
./gradlew compileJava
```

Build & test:

```shell
Expand Down
41 changes: 39 additions & 2 deletions client/src/main/java/io/dapr/durabletask/TaskOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,51 @@
public final class TaskOptions {
private final RetryPolicy retryPolicy;
private final RetryHandler retryHandler;
private final String appID;

public TaskOptions(RetryPolicy retryPolicy, RetryHandler retryHandler, String appID) {
this.retryPolicy = retryPolicy;
this.retryHandler = retryHandler;
this.appID = appID;
}

public TaskOptions(RetryPolicy retryPolicy, RetryHandler retryHandler) {
this.retryPolicy = retryPolicy;
this.retryHandler = retryHandler;
this.appID = null;
}

/**
* Creates a new {@code TaskOptions} object from a {@link RetryPolicy}.
* @param retryPolicy the retry policy to use in the new {@code TaskOptions} object.
*/
public TaskOptions(RetryPolicy retryPolicy) {
this(retryPolicy, null);
this(retryPolicy, null, null);
}

/**
* Creates a new {@code TaskOptions} object from a {@link RetryHandler}.
* @param retryHandler the retry handler to use in the new {@code TaskOptions} object.
*/
public TaskOptions(RetryHandler retryHandler) {
this(null, retryHandler);
this(null, retryHandler, null);
}

/**
* Creates a new {@code TaskOptions} object with the specified app ID.
* @param appID the app ID to use for cross-app workflow routing
*/
public TaskOptions(String appID) {
this(null, null, appID);
}

/**
* Creates a new {@code TaskOptions} object with the specified retry policy and app ID.
* @param retryPolicy the retry policy to use
* @param appID the app ID to use for cross-app workflow routing
*/
public TaskOptions(RetryPolicy retryPolicy, String appID) {
this(retryPolicy, null, appID);
}

boolean hasRetryPolicy() {
Expand All @@ -53,4 +78,16 @@ boolean hasRetryHandler() {
public RetryHandler getRetryHandler() {
return this.retryHandler;
}

/**
* Gets the configured app ID value or {@code null} if none was configured.
* @return the configured app ID
*/
public String getAppID() {
return this.appID;
}

boolean hasAppID() {
return this.appID != null && !this.appID.isEmpty();
}
}
88 changes: 88 additions & 0 deletions client/src/test/java/io/dapr/durabletask/TaskOptionsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright 2025 The Dapr Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file 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.dapr.durabletask;

import org.junit.jupiter.api.Test;
import java.time.Duration;

import static org.junit.jupiter.api.Assertions.*;

/**
* Unit tests for TaskOptions with cross-app workflow support.
*/
public class TaskOptionsTest {

@Test
void taskOptionsWithAppID() {
TaskOptions options = new TaskOptions("app1");

assertTrue(options.hasAppID());
assertEquals("app1", options.getAppID());
assertFalse(options.hasRetryPolicy());
assertFalse(options.hasRetryHandler());
}

@Test
void taskOptionsWithRetryPolicyAndAppID() {
RetryPolicy retryPolicy = new RetryPolicy(3, Duration.ofSeconds(1));
TaskOptions options = new TaskOptions(retryPolicy, null, "app2");

assertTrue(options.hasAppID());
assertEquals("app2", options.getAppID());
assertTrue(options.hasRetryPolicy());
assertEquals(retryPolicy, options.getRetryPolicy());
assertFalse(options.hasRetryHandler());
}

@Test
void taskOptionsWithRetryHandlerAndAppID() {
RetryHandler retryHandler = new RetryHandler() {
@Override
public boolean handle(RetryContext context) {
return context.getLastAttemptNumber() < 2;
}
};
TaskOptions options = new TaskOptions(null, retryHandler, "app3");

assertTrue(options.hasAppID());
assertEquals("app3", options.getAppID());
assertFalse(options.hasRetryPolicy());
assertTrue(options.hasRetryHandler());
assertEquals(retryHandler, options.getRetryHandler());
}

@Test
void taskOptionsWithoutAppID() {
TaskOptions options = new TaskOptions(null, null, null);

assertFalse(options.hasAppID());
assertNull(options.getAppID());
}

@Test
void taskOptionsWithEmptyAppID() {
TaskOptions options = new TaskOptions("");

assertFalse(options.hasAppID());
assertEquals("", options.getAppID());
}

@Test
void taskOptionsWithNullAppID() {
TaskOptions options = new TaskOptions(null, null, null);

assertFalse(options.hasAppID());
assertNull(options.getAppID());
}
}