From 055ceaf55fcbbf8b032f1f847d1255b32d75d76d Mon Sep 17 00:00:00 2001 From: Ktrops Date: Thu, 14 Nov 2024 09:11:37 -0800 Subject: [PATCH] IWF-122: add set search attributes and set data attributes (#262) Co-authored-by: Katie Atrops --- script/.env | 1 + script/docker-compose-init.sh | 4 +- script/docker-compose.yml | 2 +- src/main/java/io/iworkflow/core/Client.java | 113 +++++++++++++++++ .../io/iworkflow/core/UnregisteredClient.java | 45 ++++++- .../persistence/SearchAttributeRWImpl.java | 4 +- .../io/iworkflow/integ/PersistenceTest.java | 120 ++++++++++++++++++ .../persistence/SetDataObjectWorkflow.java | 32 +++++ .../SetDataObjectWorkflowState1.java | 45 +++++++ .../SetSearchAttributeWorkflow.java | 40 ++++++ .../SetSearchAttributeWorkflowState1.java | 46 +++++++ 11 files changed, 448 insertions(+), 4 deletions(-) create mode 100644 src/test/java/io/iworkflow/integ/persistence/SetDataObjectWorkflow.java create mode 100644 src/test/java/io/iworkflow/integ/persistence/SetDataObjectWorkflowState1.java create mode 100644 src/test/java/io/iworkflow/integ/persistence/SetSearchAttributeWorkflow.java create mode 100644 src/test/java/io/iworkflow/integ/persistence/SetSearchAttributeWorkflowState1.java diff --git a/script/.env b/script/.env index ac506144..eca4ba6c 100644 --- a/script/.env +++ b/script/.env @@ -3,4 +3,5 @@ ELASTICSEARCH_VERSION=7.16.2 MYSQL_VERSION=8 POSTGRESQL_VERSION=13 TEMPORAL_VERSION=1.25 +TEMPORAL_ADMIN_TOOLS_VERSION=1.25.2-tctl-1.18.1-cli-1.1.1 TEMPORAL_UI_VERSION=2.31.2 \ No newline at end of file diff --git a/script/docker-compose-init.sh b/script/docker-compose-init.sh index a6f58e0b..054b8a7c 100755 --- a/script/docker-compose-init.sh +++ b/script/docker-compose-init.sh @@ -30,8 +30,10 @@ for run in {1..120}; do sleep 0.1 temporal operator search-attribute create --name CustomStringField --type Text sleep 0.1 + temporal operator search-attribute create --name CustomKeywordArrayField --type KeywordList + sleep 0.1 - if checkExists "IwfWorkflowType" && checkExists "IwfGlobalWorkflowVersion" && checkExists "IwfExecutingStateIds" && checkExists "CustomKeywordField" && checkExists "CustomIntField" && checkExists "CustomBoolField" && checkExists "CustomDoubleField" && checkExists "CustomDatetimeField" && checkExists "CustomStringField"; then + if checkExists "IwfWorkflowType" && checkExists "IwfGlobalWorkflowVersion" && checkExists "IwfExecutingStateIds" && checkExists "CustomKeywordField" && checkExists "CustomIntField" && checkExists "CustomBoolField" && checkExists "CustomDoubleField" && checkExists "CustomDatetimeField" && checkExists "CustomStringField" && checkExists "CustomKeywordArrayField"; then echo "All search attributes are registered" break fi diff --git a/script/docker-compose.yml b/script/docker-compose.yml index 0cbfb3db..82d72341 100644 --- a/script/docker-compose.yml +++ b/script/docker-compose.yml @@ -58,7 +58,7 @@ services: environment: - TEMPORAL_ADDRESS=temporal:7233 - TEMPORAL_CLI_ADDRESS=temporal:7233 - image: temporalio/admin-tools:${TEMPORAL_VERSION} + image: temporalio/admin-tools:${TEMPORAL_ADMIN_TOOLS_VERSION} networks: - temporal-network stdin_open: true diff --git a/src/main/java/io/iworkflow/core/Client.java b/src/main/java/io/iworkflow/core/Client.java index 9d497da3..25f5a1e5 100644 --- a/src/main/java/io/iworkflow/core/Client.java +++ b/src/main/java/io/iworkflow/core/Client.java @@ -615,6 +615,68 @@ private Map doGetWorkflowDataAttributes( return result; } + /** + * Set the value for data attributes aka objects for a workflow + * + * @param workflowClass required + * @param workflowId required + * @param workflowRunId optional, can be empty + * @param dataAttributes required + * */ + public void setWorkflowDataAttributes( + final Class workflowClass, + final String workflowId, + final String workflowRunId, + final Map dataAttributes) { + doSetWorkflowDataAttributes(workflowClass, workflowId, workflowRunId, dataAttributes); + } + + /** + * Set the value for data attributes aka objects for a workflow + * + * @param workflowClass required + * @param workflowId required + * @param dataAttributes required + * */ + public void setWorkflowDataAttributes( + final Class workflowClass, + final String workflowId, + final Map dataAttributes) { + doSetWorkflowDataAttributes(workflowClass, workflowId, "", dataAttributes); + } + + private void doSetWorkflowDataAttributes( + final Class workflowClass, + final String workflowId, + final String workflowRunId, + final Map dataAttributes + ) { + //check if workflow type exists + final String wfType = workflowClass.getSimpleName(); + checkWorkflowTypeExists(wfType); + + for (final Map.Entry entry : dataAttributes.entrySet()) { + final String key = entry.getKey(); + //check that key exists in the store + if (!registry.getDataAttributeTypeStore(wfType).isValidNameOrPrefix(key)) { + throw new IllegalArgumentException(String.format("data attribute %s is not registered", key)); + } + + final Class registeredType = registry.getDataAttributeTypeStore(wfType).getType(key); + final Class requestedType = entry.getValue().getClass(); + //check that type is registered in schema + if (!requestedType.isAssignableFrom(registeredType)) { + throw new IllegalArgumentException( + String.format( + "registered type %s is not assignable from %s", + registeredType.getName(), + requestedType.getName())); + } + } + + unregisteredClient.setAnyWorkflowDataObjects(workflowId, workflowRunId, dataAttributes); + } + /** * This is a simplified API to search without pagination, use the other searchWorkflow API for pagination feature * @@ -834,6 +896,37 @@ public Map getAllSearchAttributes( return doGetWorkflowSearchAttributes(workflowClass, workflowId, workflowRunId, null); } + + /** + * Set the value of search attributes for a workflow + * + * @param workflowClass required + * @param workflowId required + * @param searchAttributes required + * */ + public void setWorkflowSearchAttributes( + final Class workflowClass, + final String workflowId, + final List searchAttributes) { + doSetWorkflowSearchAttributes(workflowClass, workflowId, "", searchAttributes); + } + + /** + * Set the value of search attributes for a workflow + * + * @param workflowClass required + * @param workflowId required + * @param workflowRunId optional, can be empty + * @param searchAttributes required + * */ + public void setWorkflowSearchAttributes( + final Class workflowClass, + final String workflowId, + final String workflowRunId, + final List searchAttributes) { + doSetWorkflowSearchAttributes(workflowClass, workflowId, workflowRunId, searchAttributes); + } + /** * Get all the search attributes of a workflow * @@ -934,6 +1027,26 @@ private Map doGetWorkflowSearchAttributes( return result; } + private void doSetWorkflowSearchAttributes( + final Class workflowClass, + final String workflowId, + final String workflowRunId, + final List searchAttributes + ) { + final String wfType = workflowClass.getSimpleName(); + checkWorkflowTypeExists(wfType); + + final Map searchAttributeKeyToTypeMap = registry.getSearchAttributeKeyToTypeMap(wfType); + //Check that the requested sa type is registered to the key + searchAttributes.forEach(sa -> { + final SearchAttributeValueType registeredValueType = searchAttributeKeyToTypeMap.get(sa.getKey()); + if (sa.getValueType() != null && registeredValueType != null && !registeredValueType.equals(sa.getValueType())) { + throw new IllegalArgumentException(String.format("Search attribute key, %s is registered to type %s, but tried to add search attribute type %s", sa.getKey(), registeredValueType.getValue(), sa.getValueType().getValue())); + } + }); + unregisteredClient.setAnyWorkflowSearchAttributes(workflowId, workflowRunId, searchAttributes); + } + static Object getSearchAttributeValue(final SearchAttributeValueType saType, final SearchAttribute searchAttribute) { switch (saType) { case INT: diff --git a/src/main/java/io/iworkflow/core/UnregisteredClient.java b/src/main/java/io/iworkflow/core/UnregisteredClient.java index 27483a2d..f0df952f 100644 --- a/src/main/java/io/iworkflow/core/UnregisteredClient.java +++ b/src/main/java/io/iworkflow/core/UnregisteredClient.java @@ -9,10 +9,11 @@ import io.iworkflow.gen.api.ApiClient; import io.iworkflow.gen.api.DefaultApi; import io.iworkflow.gen.models.EncodedObject; +import io.iworkflow.gen.models.KeyValue; import io.iworkflow.gen.models.PersistenceLoadingPolicy; +import io.iworkflow.gen.models.SearchAttribute; import io.iworkflow.gen.models.SearchAttributeKeyAndType; import io.iworkflow.gen.models.StateCompletionOutput; -import io.iworkflow.gen.models.WorkflowAlreadyStartedOptions; import io.iworkflow.gen.models.WorkflowGetDataObjectsRequest; import io.iworkflow.gen.models.WorkflowGetDataObjectsResponse; import io.iworkflow.gen.models.WorkflowGetRequest; @@ -25,6 +26,8 @@ import io.iworkflow.gen.models.WorkflowRpcResponse; import io.iworkflow.gen.models.WorkflowSearchRequest; import io.iworkflow.gen.models.WorkflowSearchResponse; +import io.iworkflow.gen.models.WorkflowSetDataObjectsRequest; +import io.iworkflow.gen.models.WorkflowSetSearchAttributesRequest; import io.iworkflow.gen.models.WorkflowSignalRequest; import io.iworkflow.gen.models.WorkflowSkipTimerRequest; import io.iworkflow.gen.models.WorkflowStartOptions; @@ -35,6 +38,7 @@ import io.iworkflow.gen.models.WorkflowWaitForStateCompletionRequest; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; /** @@ -613,6 +617,28 @@ public WorkflowGetDataObjectsResponse getAnyWorkflowDataObjects( } } + public void setAnyWorkflowDataObjects( + final String workflowId, + final String workflowRunId, + final Map dataObjects + ) { + final List encodedObjects = dataObjects.entrySet().stream().map(entry -> new KeyValue() + .key(entry.getKey()) + .value(clientOptions.getObjectEncoder().encode(entry.getValue()))) + .collect(Collectors.toList()); + + try { + defaultApi.apiV1WorkflowDataobjectsSetPost( + new WorkflowSetDataObjectsRequest() + .workflowId(workflowId) + .workflowRunId(workflowRunId) + .objects(encodedObjects) + ); + } catch (final FeignException.FeignClientException exp) { + throw IwfHttpException.fromFeignException(clientOptions.getObjectEncoder(), exp); + } + } + public WorkflowSearchResponse searchWorkflow(final String query, final int pageSize) { try { @@ -650,6 +676,23 @@ public WorkflowGetSearchAttributesResponse getAnyWorkflowSearchAttributes( } } + public void setAnyWorkflowSearchAttributes( + final String workflowId, + final String workflowRunId, + final List searchAttributes + ) { + try { + defaultApi.apiV1WorkflowSearchattributesSetPost( + new WorkflowSetSearchAttributesRequest() + .workflowId(workflowId) + .workflowRunId(workflowRunId) + .searchAttributes(searchAttributes) + ); + } catch (final FeignException.FeignClientException exp) { + throw IwfHttpException.fromFeignException(clientOptions.getObjectEncoder(), exp); + } + } + public T invokeRpc( Class valueClass, final Object input, diff --git a/src/main/java/io/iworkflow/core/persistence/SearchAttributeRWImpl.java b/src/main/java/io/iworkflow/core/persistence/SearchAttributeRWImpl.java index ff3ea007..ad602f3f 100644 --- a/src/main/java/io/iworkflow/core/persistence/SearchAttributeRWImpl.java +++ b/src/main/java/io/iworkflow/core/persistence/SearchAttributeRWImpl.java @@ -46,6 +46,8 @@ public SearchAttributeRWImpl(final Map keyToTy case INT: int64AttributeMap.put(sa.getKey(), sa.getIntegerValue()); break; + case DOUBLE: + doubleAttributeMap.put(sa.getKey(), sa.getDoubleValue()); case BOOL: boolAttributeMap.put(sa.getKey(), sa.getBoolValue()); break; @@ -53,7 +55,7 @@ public SearchAttributeRWImpl(final Map keyToTy stringArrayAttributeMap.put(sa.getKey(), sa.getStringArrayValue()); break; default: - throw new IllegalStateException("empty search attribute value type shouldn't exist"); + throw new IllegalStateException(String.format("empty or not supported search attribute value type, %s", type)); } }); } diff --git a/src/test/java/io/iworkflow/integ/PersistenceTest.java b/src/test/java/io/iworkflow/integ/PersistenceTest.java index 4efbf4bb..0265a508 100644 --- a/src/test/java/io/iworkflow/integ/PersistenceTest.java +++ b/src/test/java/io/iworkflow/integ/PersistenceTest.java @@ -3,7 +3,11 @@ import com.google.common.collect.ImmutableMap; import io.iworkflow.core.Client; import io.iworkflow.core.ClientOptions; +import io.iworkflow.gen.models.SearchAttribute; +import io.iworkflow.gen.models.SearchAttributeValueType; import io.iworkflow.integ.persistence.BasicPersistenceWorkflow; +import io.iworkflow.integ.persistence.SetDataObjectWorkflow; +import io.iworkflow.integ.persistence.SetSearchAttributeWorkflow; import io.iworkflow.spring.TestSingletonWorkerService; import io.iworkflow.spring.controller.WorkflowRegistry; import org.junit.jupiter.api.Assertions; @@ -11,13 +15,32 @@ import org.junit.jupiter.api.Test; import java.util.Arrays; +import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; import static io.iworkflow.integ.persistence.BasicPersistenceWorkflow.TEST_SEARCH_ATTRIBUTE_INT; import static io.iworkflow.integ.persistence.BasicPersistenceWorkflow.TEST_SEARCH_ATTRIBUTE_KEYWORD; +import static io.iworkflow.integ.persistence.SetDataObjectWorkflow.DATA_OBJECT_KEY; +import static io.iworkflow.integ.persistence.SetDataObjectWorkflow.DATA_OBJECT_KEY_PREFIX; +import static io.iworkflow.integ.persistence.SetDataObjectWorkflow.DATA_OBJECT_MODEL_KEY; +import static io.iworkflow.integ.persistence.SetSearchAttributeWorkflow.SEARCH_ATTRIBUTE_BOOL; +import static io.iworkflow.integ.persistence.SetSearchAttributeWorkflow.SEARCH_ATTRIBUTE_DATE_TIME; +import static io.iworkflow.integ.persistence.SetSearchAttributeWorkflow.SEARCH_ATTRIBUTE_DOUBLE; +import static io.iworkflow.integ.persistence.SetSearchAttributeWorkflow.SEARCH_ATTRIBUTE_INT; +import static io.iworkflow.integ.persistence.SetSearchAttributeWorkflow.SEARCH_ATTRIBUTE_KEYWORD; +import static io.iworkflow.integ.persistence.SetSearchAttributeWorkflow.SEARCH_ATTRIBUTE_KEYWORD_ARRAY; +import static io.iworkflow.integ.persistence.SetSearchAttributeWorkflow.SEARCH_ATTRIBUTE_TEXT; public class PersistenceTest { + public final static String KEYWORD_VALUE_1 = "keyword-1"; + public final static String KEYWORD_VALUE_2 = "keyword-2"; + public final static String TEXT_VALUE_1 = "text-1"; + public final static Double DOUBLE_VALUE_1 = 01d; + public final static Long INTEGER_VALUE_1 = 1L; + public final static Boolean BOOLEAN_VALUE_1 = Boolean.TRUE; + public final static List ARRAY_STRING_VALUE_1 = Arrays.asList(KEYWORD_VALUE_1, KEYWORD_VALUE_2); + public final static String DATE_VALUE_1 = "2024-11-12T16:00:01.731455544-08:00"; @BeforeEach public void setup() throws ExecutionException, InterruptedException { @@ -87,4 +110,101 @@ public void testPersistenceWorkflow() throws InterruptedException { // .build(), searchAttributes2); } + @Test + public void testSetSearchAttributes() { + final Client client = new Client(WorkflowRegistry.registry, ClientOptions.localDefault); + final String wfId = "set-search-attribute-test-id" + System.currentTimeMillis() / 1000; + final String runId = client.startWorkflow( + SetSearchAttributeWorkflow.class, wfId, 10, "start"); + + client.setWorkflowSearchAttributes(SetSearchAttributeWorkflow.class, wfId, Arrays.asList( + new SearchAttribute() + .key(SEARCH_ATTRIBUTE_KEYWORD) + .stringValue(KEYWORD_VALUE_1) + .valueType(SearchAttributeValueType.KEYWORD), + new SearchAttribute() + .key(SEARCH_ATTRIBUTE_TEXT) + .stringValue(TEXT_VALUE_1) + .valueType(SearchAttributeValueType.TEXT), + new SearchAttribute() + .key(SEARCH_ATTRIBUTE_DOUBLE) + .doubleValue(DOUBLE_VALUE_1) + .valueType(SearchAttributeValueType.DOUBLE), + new SearchAttribute() + .key(SEARCH_ATTRIBUTE_INT) + .integerValue(INTEGER_VALUE_1) + .valueType(SearchAttributeValueType.INT), + new SearchAttribute() + .key(SEARCH_ATTRIBUTE_BOOL) + .boolValue(BOOLEAN_VALUE_1) + .valueType(SearchAttributeValueType.BOOL), + new SearchAttribute() + .key(SEARCH_ATTRIBUTE_KEYWORD_ARRAY) + .stringArrayValue(ARRAY_STRING_VALUE_1) + .valueType(SearchAttributeValueType.KEYWORD_ARRAY), + new SearchAttribute() + .key(SEARCH_ATTRIBUTE_DATE_TIME) + .stringValue(DATE_VALUE_1) + .valueType(SearchAttributeValueType.DATETIME) + )); + + //Wait for workflow to complete to ensure search attribute values were added + final String result = client.waitForWorkflowCompletion(String.class, wfId); + Assertions.assertEquals("test-result", result); + + final Map returnedSearchAttributes = client.getWorkflowSearchAttributes( + SetSearchAttributeWorkflow.class, + wfId, + runId, + Arrays.asList( + SEARCH_ATTRIBUTE_KEYWORD, + SEARCH_ATTRIBUTE_TEXT, + SEARCH_ATTRIBUTE_DOUBLE, + SEARCH_ATTRIBUTE_INT, + SEARCH_ATTRIBUTE_BOOL, + SEARCH_ATTRIBUTE_KEYWORD_ARRAY, + SEARCH_ATTRIBUTE_DATE_TIME)); + + final Map expectedSearchAttributes = ImmutableMap.of( + SEARCH_ATTRIBUTE_KEYWORD, KEYWORD_VALUE_1, + SEARCH_ATTRIBUTE_TEXT, TEXT_VALUE_1, + SEARCH_ATTRIBUTE_DOUBLE, DOUBLE_VALUE_1, + SEARCH_ATTRIBUTE_INT, INTEGER_VALUE_1, + SEARCH_ATTRIBUTE_BOOL, BOOLEAN_VALUE_1, + SEARCH_ATTRIBUTE_KEYWORD_ARRAY, ARRAY_STRING_VALUE_1, + SEARCH_ATTRIBUTE_DATE_TIME, "2024-11-13T00:00:01.731455544Z" //This is a bug. The iwf-server always returns utc time. See https://github.com/indeedeng/iwf/issues/261 + ); + Assertions.assertEquals(expectedSearchAttributes, returnedSearchAttributes); + } + + @Test + public void testSetDataObjects() { + final Client client = new Client(WorkflowRegistry.registry, ClientOptions.localDefault); + final String wfId = "set-data-objects-test-id" + System.currentTimeMillis() / 1000; + final String runId = client.startWorkflow( + SetDataObjectWorkflow.class, wfId, 10, "start"); + + final String dataObjectKeyWithPrefix = DATA_OBJECT_KEY_PREFIX + "1"; + final Map dataObjects = ImmutableMap.of( + DATA_OBJECT_KEY, "query-start", + DATA_OBJECT_MODEL_KEY, new io.iworkflow.gen.models.Context(), + dataObjectKeyWithPrefix, 20L); + + client.setWorkflowDataAttributes( + SetDataObjectWorkflow.class, + wfId, + runId, + dataObjects); + + //Wait for workflow to complete to ensure data objects values were added + final String result = client.waitForWorkflowCompletion(String.class, wfId); + Assertions.assertEquals("test-result", result); + + final Map actualDataObjects = client.getWorkflowDataAttributes( + SetDataObjectWorkflow.class, + wfId, + Arrays.asList(DATA_OBJECT_KEY, DATA_OBJECT_MODEL_KEY, dataObjectKeyWithPrefix)); + Assertions.assertEquals(dataObjects, actualDataObjects); + } + } diff --git a/src/test/java/io/iworkflow/integ/persistence/SetDataObjectWorkflow.java b/src/test/java/io/iworkflow/integ/persistence/SetDataObjectWorkflow.java new file mode 100644 index 00000000..d2344eb8 --- /dev/null +++ b/src/test/java/io/iworkflow/integ/persistence/SetDataObjectWorkflow.java @@ -0,0 +1,32 @@ +package io.iworkflow.integ.persistence; + +import io.iworkflow.core.ObjectWorkflow; +import io.iworkflow.core.StateDef; +import io.iworkflow.core.persistence.DataAttributeDef; +import io.iworkflow.core.persistence.PersistenceFieldDef; +import io.iworkflow.gen.models.Context; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; + +@Component +public class SetDataObjectWorkflow implements ObjectWorkflow { + public static final String DATA_OBJECT_KEY = "data-obj-key-1"; + public static final String DATA_OBJECT_MODEL_KEY = "data-obj-1"; + public static final String DATA_OBJECT_KEY_PREFIX = "data-obj-key-prefix-"; + + @Override + public List getWorkflowStates() { + return Arrays.asList(StateDef.startingState(new SetDataObjectWorkflowState1())); + } + + @Override + public List getPersistenceSchema() { + return Arrays.asList( + DataAttributeDef.create(String.class, DATA_OBJECT_KEY), + DataAttributeDef.create(Context.class, DATA_OBJECT_MODEL_KEY), + DataAttributeDef.createByPrefix(Long.class, DATA_OBJECT_KEY_PREFIX) + ); + } +} diff --git a/src/test/java/io/iworkflow/integ/persistence/SetDataObjectWorkflowState1.java b/src/test/java/io/iworkflow/integ/persistence/SetDataObjectWorkflowState1.java new file mode 100644 index 00000000..976a839d --- /dev/null +++ b/src/test/java/io/iworkflow/integ/persistence/SetDataObjectWorkflowState1.java @@ -0,0 +1,45 @@ +package io.iworkflow.integ.persistence; + +import io.iworkflow.core.Context; +import io.iworkflow.core.ImmutableStateDecision; +import io.iworkflow.core.StateDecision; +import io.iworkflow.core.StateMovement; +import io.iworkflow.core.WorkflowState; +import io.iworkflow.core.command.CommandRequest; +import io.iworkflow.core.command.CommandResults; +import io.iworkflow.core.communication.Communication; +import io.iworkflow.core.communication.SignalCommand; +import io.iworkflow.core.persistence.Persistence; + +import java.util.Arrays; + +public class SetDataObjectWorkflowState1 implements WorkflowState { + public static final String STATE_ID = "setDataObject-s1"; + + @Override + public String getStateId() { + return STATE_ID; + } + + @Override + public Class getInputType() { + return String.class; + } + + @Override + public CommandRequest waitUntil(Context context, String input, Persistence persistence, Communication communication) { + return CommandRequest.forAnyCommandCompleted(SignalCommand.create("__IwfSystem_ExecuteRpc", 1)); + } + + @Override + public StateDecision execute( + final Context context, + final String input, + final CommandResults commandResults, + final Persistence persistence, + final Communication communication) { + return ImmutableStateDecision.builder() + .nextStates(Arrays.asList(StateMovement.gracefulCompleteWorkflow("test-result"))) + .build(); + } +} diff --git a/src/test/java/io/iworkflow/integ/persistence/SetSearchAttributeWorkflow.java b/src/test/java/io/iworkflow/integ/persistence/SetSearchAttributeWorkflow.java new file mode 100644 index 00000000..ddd89ef8 --- /dev/null +++ b/src/test/java/io/iworkflow/integ/persistence/SetSearchAttributeWorkflow.java @@ -0,0 +1,40 @@ +package io.iworkflow.integ.persistence; + +import io.iworkflow.core.ObjectWorkflow; +import io.iworkflow.core.StateDef; +import io.iworkflow.core.persistence.PersistenceFieldDef; +import io.iworkflow.core.persistence.SearchAttributeDef; +import io.iworkflow.gen.models.SearchAttributeValueType; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; + +@Component +public class SetSearchAttributeWorkflow implements ObjectWorkflow { + public static final String SEARCH_ATTRIBUTE_KEYWORD = "CustomKeywordField"; + public static final String SEARCH_ATTRIBUTE_TEXT = "CustomTextField"; + public static final String SEARCH_ATTRIBUTE_DOUBLE = "CustomDoubleField"; + public static final String SEARCH_ATTRIBUTE_INT = "CustomIntField"; + public static final String SEARCH_ATTRIBUTE_BOOL = "CustomBoolField"; + public static final String SEARCH_ATTRIBUTE_KEYWORD_ARRAY = "CustomKeywordArrayField"; + public static final String SEARCH_ATTRIBUTE_DATE_TIME = "CustomDatetimeField"; + + @Override + public List getWorkflowStates() { + return Arrays.asList(StateDef.startingState(new SetSearchAttributeWorkflowState1())); + } + + @Override + public List getPersistenceSchema() { + return Arrays.asList( + SearchAttributeDef.create(SearchAttributeValueType.INT, SEARCH_ATTRIBUTE_INT), + SearchAttributeDef.create(SearchAttributeValueType.KEYWORD, SEARCH_ATTRIBUTE_KEYWORD), + SearchAttributeDef.create(SearchAttributeValueType.DATETIME, SEARCH_ATTRIBUTE_DATE_TIME), + SearchAttributeDef.create(SearchAttributeValueType.TEXT, SEARCH_ATTRIBUTE_TEXT), + SearchAttributeDef.create(SearchAttributeValueType.DOUBLE, SEARCH_ATTRIBUTE_DOUBLE), + SearchAttributeDef.create(SearchAttributeValueType.BOOL, SEARCH_ATTRIBUTE_BOOL), + SearchAttributeDef.create(SearchAttributeValueType.KEYWORD_ARRAY, SEARCH_ATTRIBUTE_KEYWORD_ARRAY) + ); + } +} diff --git a/src/test/java/io/iworkflow/integ/persistence/SetSearchAttributeWorkflowState1.java b/src/test/java/io/iworkflow/integ/persistence/SetSearchAttributeWorkflowState1.java new file mode 100644 index 00000000..7efd48e4 --- /dev/null +++ b/src/test/java/io/iworkflow/integ/persistence/SetSearchAttributeWorkflowState1.java @@ -0,0 +1,46 @@ +package io.iworkflow.integ.persistence; + +import io.iworkflow.core.Context; +import io.iworkflow.core.ImmutableStateDecision; +import io.iworkflow.core.StateDecision; +import io.iworkflow.core.StateMovement; +import io.iworkflow.core.WorkflowState; +import io.iworkflow.core.command.CommandRequest; +import io.iworkflow.core.command.CommandResults; +import io.iworkflow.core.communication.Communication; +import io.iworkflow.core.communication.SignalCommand; +import io.iworkflow.core.persistence.Persistence; + +import java.util.Arrays; + +public class SetSearchAttributeWorkflowState1 implements WorkflowState { + public static final String STATE_ID = "setSearchAttribute-s1"; + + @Override + public String getStateId() { + return STATE_ID; + } + + @Override + public Class getInputType() { + return String.class; + } + + @Override + public CommandRequest waitUntil(Context context, String input, Persistence persistence, Communication communication) { + + return CommandRequest.forAnyCommandCompleted(SignalCommand.create("__IwfSystem_ExecuteRpc", 1)); + } + + @Override + public StateDecision execute( + final Context context, + final String input, + final CommandResults commandResults, + final Persistence persistence, + final Communication communication) { + return ImmutableStateDecision.builder() + .nextStates(Arrays.asList(StateMovement.gracefulCompleteWorkflow("test-result"))) + .build(); + } +}