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>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<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>
|
<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.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>
|
<dapr.sdk-workflows.version>0.11.0-SNAPSHOT</dapr.sdk-workflows.version>
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.deploy.skip>false</maven.deploy.skip>
|
<maven.deploy.skip>false</maven.deploy.skip>
|
||||||
<grpc.version>1.42.1</grpc.version>
|
<grpc.version>1.59.0</grpc.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<protobuf.output.directory>${project.build.directory}/generated-sources</protobuf.output.directory>
|
<protobuf.output.directory>${project.build.directory}/generated-sources</protobuf.output.directory>
|
||||||
<protobuf.input.directory>${project.build.directory}/proto</protobuf.input.directory>
|
<protobuf.input.directory>${project.build.directory}/proto</protobuf.input.directory>
|
||||||
<maven.deploy.skip>false</maven.deploy.skip>
|
<maven.deploy.skip>false</maven.deploy.skip>
|
||||||
<grpc.version>1.42.1</grpc.version>
|
<grpc.version>1.59.0</grpc.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<dapr.sdk.version>1.11.0-SNAPSHOT</dapr.sdk.version>
|
<dapr.sdk.version>1.11.0-SNAPSHOT</dapr.sdk.version>
|
||||||
<protobuf.output.directory>${project.build.directory}/generated-sources</protobuf.output.directory>
|
<protobuf.output.directory>${project.build.directory}/generated-sources</protobuf.output.directory>
|
||||||
<protobuf.input.directory>${project.basedir}/proto</protobuf.input.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>
|
<protobuf.version>3.17.3</protobuf.version>
|
||||||
<opentelemetry.version>0.14.0</opentelemetry.version>
|
<opentelemetry.version>0.14.0</opentelemetry.version>
|
||||||
<spring-boot.version>2.7.8</spring-boot.version>
|
<spring-boot.version>2.7.8</spring-boot.version>
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.microsoft</groupId>
|
<groupId>com.microsoft</groupId>
|
||||||
<artifactId>durabletask-client</artifactId>
|
<artifactId>durabletask-client</artifactId>
|
||||||
<version>1.1.1</version>
|
<version>1.5.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--
|
<!--
|
||||||
manually declare durabletask-client's jackson dependencies
|
manually declare durabletask-client's jackson dependencies
|
||||||
|
|
|
@ -27,6 +27,7 @@ import javax.annotation.Nullable;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class DaprWorkflowContextImpl implements WorkflowContext {
|
public class DaprWorkflowContextImpl implements WorkflowContext {
|
||||||
private final TaskOrchestrationContext innerContext;
|
private final TaskOrchestrationContext innerContext;
|
||||||
|
@ -204,4 +205,12 @@ public class DaprWorkflowContextImpl implements WorkflowContext {
|
||||||
public void continueAsNew(Object input, boolean preserveUnprocessedEvents) {
|
public void continueAsNew(Object input, boolean preserveUnprocessedEvents) {
|
||||||
this.innerContext.continueAsNew(input, 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.time.ZonedDateTime;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Context object used by workflow implementations to perform actions such as scheduling activities,
|
* Context object used by workflow implementations to perform actions such as scheduling activities,
|
||||||
|
@ -514,4 +515,19 @@ public interface WorkflowContext {
|
||||||
* history, otherwise {@code false}
|
* history, otherwise {@code false}
|
||||||
*/
|
*/
|
||||||
void continueAsNew(Object input, boolean preserveUnprocessedEvents);
|
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;
|
package io.dapr.workflows;
|
||||||
|
|
||||||
|
import com.microsoft.durabletask.CompositeTaskFailedException;
|
||||||
import com.microsoft.durabletask.RetryPolicy;
|
import com.microsoft.durabletask.RetryPolicy;
|
||||||
import com.microsoft.durabletask.Task;
|
import com.microsoft.durabletask.Task;
|
||||||
|
import com.microsoft.durabletask.TaskCanceledException;
|
||||||
import com.microsoft.durabletask.TaskOptions;
|
import com.microsoft.durabletask.TaskOptions;
|
||||||
import com.microsoft.durabletask.TaskOrchestrationContext;
|
import com.microsoft.durabletask.TaskOrchestrationContext;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
|
@ -37,11 +42,95 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
public class DaprWorkflowContextImplTest {
|
public class DaprWorkflowContextImplTest {
|
||||||
private DaprWorkflowContextImpl context;
|
private DaprWorkflowContextImpl context;
|
||||||
private TaskOrchestrationContext mockInnerContext;
|
private TaskOrchestrationContext mockInnerContext;
|
||||||
|
private WorkflowContext testWorkflowContext;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
mockInnerContext = mock(TaskOrchestrationContext.class);
|
mockInnerContext = mock(TaskOrchestrationContext.class);
|
||||||
context = new DaprWorkflowContextImpl(mockInnerContext);
|
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
|
@Test
|
||||||
|
@ -207,4 +296,17 @@ public class DaprWorkflowContextImplTest {
|
||||||
context.callSubWorkflow(expectedName, expectedInput, String.class);
|
context.callSubWorkflow(expectedName, expectedInput, String.class);
|
||||||
verify(mockInnerContext, times(1)).callSubOrchestrator(expectedName, expectedInput, null, null, 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>
|
<properties>
|
||||||
<maven.deploy.skip>false</maven.deploy.skip>
|
<maven.deploy.skip>false</maven.deploy.skip>
|
||||||
<grpc.version>1.42.1</grpc.version>
|
<grpc.version>1.59.0</grpc.version>
|
||||||
<argLine>
|
<argLine>
|
||||||
--add-opens java.base/java.util=ALL-UNNAMED
|
--add-opens java.base/java.util=ALL-UNNAMED
|
||||||
</argLine>
|
</argLine>
|
||||||
|
|
Loading…
Reference in New Issue