mirror of https://github.com/dapr/java-sdk.git
Add determinstic UUID generation (#947)
* add determinstic UUID generation Signed-off-by: kaibocai <89094811+kaibocai@users.noreply.github.com> * add unit test to improve coverage Signed-off-by: kaibocai <89094811+kaibocai@users.noreply.github.com> * update grpc version to 1.59.0 to be compatible updated durabletask-java Signed-off-by: kaibocai <kaibocai@microsoft.com> --------- Signed-off-by: kaibocai <89094811+kaibocai@users.noreply.github.com> Signed-off-by: kaibocai <kaibocai@microsoft.com> Co-authored-by: Artur Souza <artursouza.ms@outlook.com>
This commit is contained in:
parent
1bd2c22b69
commit
4c63abd07d
2
pom.xml
2
pom.xml
|
@ -14,7 +14,7 @@
|
|||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<grpc.version>1.42.1</grpc.version>
|
||||
<grpc.version>1.59.0</grpc.version>
|
||||
<protobuf.version>3.17.3</protobuf.version>
|
||||
<dapr.proto.baseurl>https://raw.githubusercontent.com/dapr/dapr/v1.12.0-rc.2/dapr/proto</dapr.proto.baseurl>
|
||||
<dapr.sdk-workflows.version>0.11.0-SNAPSHOT</dapr.sdk-workflows.version>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
<properties>
|
||||
<maven.deploy.skip>false</maven.deploy.skip>
|
||||
<grpc.version>1.42.1</grpc.version>
|
||||
<grpc.version>1.59.0</grpc.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<protobuf.output.directory>${project.build.directory}/generated-sources</protobuf.output.directory>
|
||||
<protobuf.input.directory>${project.build.directory}/proto</protobuf.input.directory>
|
||||
<maven.deploy.skip>false</maven.deploy.skip>
|
||||
<grpc.version>1.42.1</grpc.version>
|
||||
<grpc.version>1.59.0</grpc.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<dapr.sdk.version>1.11.0-SNAPSHOT</dapr.sdk.version>
|
||||
<protobuf.output.directory>${project.build.directory}/generated-sources</protobuf.output.directory>
|
||||
<protobuf.input.directory>${project.basedir}/proto</protobuf.input.directory>
|
||||
<grpc.version>1.42.1</grpc.version>
|
||||
<grpc.version>1.59.0</grpc.version>
|
||||
<protobuf.version>3.17.3</protobuf.version>
|
||||
<opentelemetry.version>0.14.0</opentelemetry.version>
|
||||
<spring-boot.version>2.7.8</spring-boot.version>
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
<dependency>
|
||||
<groupId>com.microsoft</groupId>
|
||||
<artifactId>durabletask-client</artifactId>
|
||||
<version>1.1.1</version>
|
||||
<version>1.5.0</version>
|
||||
</dependency>
|
||||
<!--
|
||||
manually declare durabletask-client's jackson dependencies
|
||||
|
|
|
@ -27,6 +27,7 @@ import javax.annotation.Nullable;
|
|||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class DaprWorkflowContextImpl implements WorkflowContext {
|
||||
private final TaskOrchestrationContext innerContext;
|
||||
|
@ -204,4 +205,12 @@ public class DaprWorkflowContextImpl implements WorkflowContext {
|
|||
public void continueAsNew(Object input, boolean preserveUnprocessedEvents) {
|
||||
this.innerContext.continueAsNew(input, preserveUnprocessedEvents);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public UUID newUuid() {
|
||||
return this.innerContext.newUUID();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.time.Instant;
|
|||
import java.time.ZonedDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Context object used by workflow implementations to perform actions such as scheduling activities,
|
||||
|
@ -514,4 +515,19 @@ public interface WorkflowContext {
|
|||
* history, otherwise {@code false}
|
||||
*/
|
||||
void continueAsNew(Object input, boolean preserveUnprocessedEvents);
|
||||
|
||||
/**
|
||||
* Create a new UUID that is safe for replay within a workflow.
|
||||
*
|
||||
* <p>
|
||||
* The default implementation of this method creates a name-based UUID
|
||||
* using the algorithm from RFC 4122 §4.3. The name input used to generate
|
||||
* this value is a combination of the workflow instance ID and an
|
||||
* internally managed sequence number.
|
||||
*</p>
|
||||
* @return a deterministic UUID
|
||||
*/
|
||||
default UUID newUuid() {
|
||||
throw new RuntimeException("No implementation found.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,20 +13,25 @@ limitations under the License.
|
|||
|
||||
package io.dapr.workflows;
|
||||
|
||||
import com.microsoft.durabletask.CompositeTaskFailedException;
|
||||
import com.microsoft.durabletask.RetryPolicy;
|
||||
import com.microsoft.durabletask.Task;
|
||||
import com.microsoft.durabletask.TaskCanceledException;
|
||||
import com.microsoft.durabletask.TaskOptions;
|
||||
import com.microsoft.durabletask.TaskOrchestrationContext;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
|
@ -37,11 +42,95 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
|||
public class DaprWorkflowContextImplTest {
|
||||
private DaprWorkflowContextImpl context;
|
||||
private TaskOrchestrationContext mockInnerContext;
|
||||
private WorkflowContext testWorkflowContext;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
mockInnerContext = mock(TaskOrchestrationContext.class);
|
||||
context = new DaprWorkflowContextImpl(mockInnerContext);
|
||||
testWorkflowContext = new WorkflowContext() {
|
||||
@Override
|
||||
public Logger getLogger() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstanceId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant getCurrentInstant() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void complete(Object output) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> Task<V> waitForExternalEvent(String name, Duration timeout, Class<V> dataType)
|
||||
throws TaskCanceledException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> Task<Void> waitForExternalEvent(String name, Duration timeout) throws TaskCanceledException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> Task<Void> waitForExternalEvent(String name) throws TaskCanceledException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> Task<V> callActivity(String name, Object input, TaskOptions options, Class<V> returnType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReplaying() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> Task<List<V>> allOf(List<Task<V>> tasks) throws CompositeTaskFailedException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task<Task<?>> anyOf(List<Task<?>> tasks) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task<Void> createTimer(Duration duration) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> V getInput(Class<V> targetType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> Task<V> callSubWorkflow(String name, @Nullable Object input, @Nullable String instanceID,
|
||||
@Nullable TaskOptions options, Class<V> returnType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void continueAsNew(Object input, boolean preserveUnprocessedEvents) {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -207,4 +296,17 @@ public class DaprWorkflowContextImplTest {
|
|||
context.callSubWorkflow(expectedName, expectedInput, String.class);
|
||||
verify(mockInnerContext, times(1)).callSubOrchestrator(expectedName, expectedInput, null, null, String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void newUuidTest() {
|
||||
context.newUuid();
|
||||
verify(mockInnerContext, times(1)).newUUID();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void newUuidTestNoImplementationExceptionTest() {
|
||||
RuntimeException runtimeException = assertThrows(RuntimeException.class, testWorkflowContext::newUuid);
|
||||
String expectedMessage = "No implementation found.";
|
||||
assertEquals(expectedMessage, runtimeException.getMessage());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
<properties>
|
||||
<maven.deploy.skip>false</maven.deploy.skip>
|
||||
<grpc.version>1.42.1</grpc.version>
|
||||
<grpc.version>1.59.0</grpc.version>
|
||||
<argLine>
|
||||
--add-opens java.base/java.util=ALL-UNNAMED
|
||||
</argLine>
|
||||
|
|
Loading…
Reference in New Issue