diff --git a/.github/workflows/ci-test.yml b/.github/workflows/ci-integ-test.yml similarity index 67% rename from .github/workflows/ci-test.yml rename to .github/workflows/ci-integ-test.yml index 828fb3c..04063a2 100644 --- a/.github/workflows/ci-test.yml +++ b/.github/workflows/ci-integ-test.yml @@ -1,4 +1,4 @@ -name: Test Build +name: Integration Test on: pull_request: push: @@ -7,10 +7,12 @@ on: jobs: tests: - name: "Test build" + name: "Integration Test" runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + - name: "Set up xdb environment" + run: wget https://raw.githubusercontent.com/xdblab/xdb/main/docker-compose/docker-compose-postgres14-example.yaml && docker compose -f docker-compose-postgres14-example.yaml up -d - uses: actions/setup-java@v3 with: distribution: zulu diff --git a/README.md b/README.md index b494618..4f70948 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # xdb-java-sdk [![Coverage Status](https://codecov.io/github/xdblab/xdb-java-sdk/coverage.svg?branch=main)](https://app.codecov.io/gh/xdblab/xdb-java-sdk/branch/main) -[![Build status](https://github.com/xdblab/xdb-java-sdk/actions/workflows/ci-test.yml/badge.svg?branch=main)](https://github.com/xdblab/xdb-java-sdk/actions/workflows/ci-test.yml) +[![Build status](https://github.com/xdblab/xdb-java-sdk/actions/workflows/ci-integ-test.yml/badge.svg?branch=main)](https://github.com/xdblab/xdb-java-sdk/actions/workflows/ci-integ-test.yml) Java SDK for [xdb](https://github.com/xdblab/xdb) diff --git a/build.gradle b/build.gradle index 61f614f..c58145b 100644 --- a/build.gradle +++ b/build.gradle @@ -14,6 +14,11 @@ plugins { id 'signing' id 'jacoco' id 'com.diffplug.spotless' version "6.13.0" + id "org.springframework.boot" version "2.7.16" +} + +bootJar { + enabled = false } java { @@ -46,6 +51,7 @@ dependencies { testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0' testCompileOnly 'org.projectlombok:lombok:1.18.30' testAnnotationProcessor 'org.projectlombok:lombok:1.18.30' + testImplementation 'org.springframework.boot:spring-boot-starter-web:2.7.16' } // open api diff --git a/src/main/java/io/xdb/core/client/Client.java b/src/main/java/io/xdb/core/client/Client.java index 726b247..aaab4fa 100644 --- a/src/main/java/io/xdb/core/client/Client.java +++ b/src/main/java/io/xdb/core/client/Client.java @@ -4,9 +4,9 @@ import io.xdb.core.registry.Registry; import io.xdb.core.state.AsyncState; import io.xdb.core.utils.ProcessUtil; -import io.xdb.gen.models.AsyncStateConfig; import io.xdb.gen.models.ProcessExecutionDescribeResponse; import io.xdb.gen.models.ProcessExecutionStartRequest; +import java.time.Duration; public class Client { @@ -39,10 +39,14 @@ public String startProcess( final String processId, final Object input ) { - final String processType = ProcessUtil.getClassSimpleName(processClass); + final String processType = ProcessUtil.getProcessType(processClass); return startProcessInternal(processType, processId, input); } + public ProcessExecutionDescribeResponse describeCurrentProcessExecution(final String processId) { + return describeCurrentProcessExecution(ProcessUtil.DEFAULT_NAMESPACE, processId); + } + public ProcessExecutionDescribeResponse describeCurrentProcessExecution( final String namespace, final String processId @@ -50,6 +54,16 @@ public ProcessExecutionDescribeResponse describeCurrentProcessExecution( return basicClient.describeCurrentProcessExecution(namespace, processId); } + // TODO: placeholder to be used in integration test for now + public void getProcessResultWithWait(final String processId) { + System.out.println(processId); + try { + Thread.sleep(Duration.ofSeconds(2).toMillis()); + } catch (final InterruptedException e) { + throw new RuntimeException(e); + } + } + private String startProcessInternal(final String processType, final String processId, final Object input) { final Process process = registry.getProcess(processType); @@ -65,7 +79,7 @@ private String startProcessInternal(final String processType, final String proce if (startingState != null) { request .startStateId(startingState.getOptions().getId(startingState.getClass())) - .startStateConfig(new AsyncStateConfig().skipWaitUntil(AsyncState.shouldSkipWaitUntil(startingState))); + .startStateConfig(ProcessUtil.getAsyncStateConfig(startingState)); } return basicClient.startProcess(request); diff --git a/src/main/java/io/xdb/core/process/ProcessOptions.java b/src/main/java/io/xdb/core/process/ProcessOptions.java index adbb861..495b24a 100644 --- a/src/main/java/io/xdb/core/process/ProcessOptions.java +++ b/src/main/java/io/xdb/core/process/ProcessOptions.java @@ -1,5 +1,7 @@ package io.xdb.core.process; +import static io.xdb.core.utils.ProcessUtil.DEFAULT_NAMESPACE; + import com.google.common.base.Strings; import io.xdb.core.utils.ProcessUtil; import io.xdb.gen.models.ProcessStartConfig; @@ -14,11 +16,11 @@ public class ProcessOptions { private final ProcessStartConfig processStartConfig; public String getNamespace() { - return Strings.isNullOrEmpty(namespace) ? "default" : namespace; + return Strings.isNullOrEmpty(namespace) ? DEFAULT_NAMESPACE : namespace; } public String getType(final Class processClass) { - return Strings.isNullOrEmpty(type) ? ProcessUtil.getClassSimpleName(processClass) : type; + return Strings.isNullOrEmpty(type) ? ProcessUtil.getProcessType(processClass) : type; } public ProcessStartConfig getProcessStartConfig() { diff --git a/src/main/java/io/xdb/core/registry/Registry.java b/src/main/java/io/xdb/core/registry/Registry.java index 12a75b0..b7d12d4 100644 --- a/src/main/java/io/xdb/core/registry/Registry.java +++ b/src/main/java/io/xdb/core/registry/Registry.java @@ -5,9 +5,7 @@ import io.xdb.core.state.AsyncState; import java.util.HashMap; import java.util.Map; -import lombok.Getter; -@Getter public class Registry { // process type: process @@ -36,6 +34,15 @@ public Process getProcess(final String type) { } public AsyncState getProcessState(final String type, final String stateId) { + if (!processStatesStore.containsKey(type) || !processStatesStore.get(type).containsKey(stateId)) { + throw new ProcessDefinitionException( + String.format( + "Process type %s or state id %s has not been registered in processStatesStore.", + type, + stateId + ) + ); + } return processStatesStore.get(type).get(stateId); } diff --git a/src/main/java/io/xdb/core/state/AsyncState.java b/src/main/java/io/xdb/core/state/AsyncState.java index 13373d7..cd21c2b 100644 --- a/src/main/java/io/xdb/core/state/AsyncState.java +++ b/src/main/java/io/xdb/core/state/AsyncState.java @@ -1,7 +1,6 @@ package io.xdb.core.state; import io.xdb.gen.models.CommandRequest; -import io.xdb.gen.models.StateDecision; import java.lang.reflect.Method; import lombok.NonNull; diff --git a/src/main/java/io/xdb/core/state/AsyncStateOptions.java b/src/main/java/io/xdb/core/state/AsyncStateOptions.java index cb559b9..8d976fd 100644 --- a/src/main/java/io/xdb/core/state/AsyncStateOptions.java +++ b/src/main/java/io/xdb/core/state/AsyncStateOptions.java @@ -10,6 +10,6 @@ public class AsyncStateOptions { private final String id; public String getId(final Class stateClass) { - return Strings.isNullOrEmpty(id) ? ProcessUtil.getClassSimpleName(stateClass) : id; + return Strings.isNullOrEmpty(id) ? ProcessUtil.getStateId(stateClass) : id; } } diff --git a/src/main/java/io/xdb/core/state/StateDecision.java b/src/main/java/io/xdb/core/state/StateDecision.java new file mode 100644 index 0000000..881cb1c --- /dev/null +++ b/src/main/java/io/xdb/core/state/StateDecision.java @@ -0,0 +1,96 @@ +package io.xdb.core.state; + +import com.google.common.collect.ImmutableList; +import io.xdb.core.utils.ProcessUtil; +import io.xdb.gen.models.ThreadCloseDecision; +import io.xdb.gen.models.ThreadCloseType; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class StateDecision { + + // directly return stateDecision if it presents + private final io.xdb.gen.models.StateDecision stateDecision; + private final List nextStates; + + public static StateDecision deadEnd() { + return StateDecision + .builder() + .stateDecision( + new io.xdb.gen.models.StateDecision() + .threadCloseDecision(new ThreadCloseDecision().closeType(ThreadCloseType.DEAD_END)) + ) + .build(); + } + + public static StateDecision gracefulCompleteProcess() { + return StateDecision + .builder() + .stateDecision( + new io.xdb.gen.models.StateDecision() + .threadCloseDecision(new ThreadCloseDecision().closeType(ThreadCloseType.GRACEFUL_COMPLETE_PROCESS)) + ) + .build(); + } + + public static StateDecision forceCompleteProcess() { + return StateDecision + .builder() + .stateDecision( + new io.xdb.gen.models.StateDecision() + .threadCloseDecision(new ThreadCloseDecision().closeType(ThreadCloseType.FORCE_COMPLETE_PROCESS)) + ) + .build(); + } + + public static StateDecision forceFailProcess() { + return StateDecision + .builder() + .stateDecision( + new io.xdb.gen.models.StateDecision() + .threadCloseDecision(new ThreadCloseDecision().closeType(ThreadCloseType.FORCE_FAIL_PROCESS)) + ) + .build(); + } + + // TODO: option override + public static StateDecision singleNextState(final Class stateClass, final Object stateInput) { + final StateMovement stateMovement = StateMovement + .builder() + .stateId(ProcessUtil.getStateId(stateClass)) + .stateInput(stateInput) + .build(); + return StateDecision.builder().nextStates(ImmutableList.of(stateMovement)).build(); + } + + public static StateDecision singleNextState(final String stateId, final Object stateInput) { + final StateMovement stateMovement = StateMovement.builder().stateId(stateId).stateInput(stateInput).build(); + return StateDecision.builder().nextStates(ImmutableList.of(stateMovement)).build(); + } + + public static StateDecision multipleNextStates(final Class... stateClasses) { + final ArrayList stateMovements = new ArrayList<>(); + for (final Class stateClass : stateClasses) { + stateMovements.add(StateMovement.builder().stateId(ProcessUtil.getStateId(stateClass)).build()); + } + return StateDecision.builder().nextStates(stateMovements).build(); + } + + public static StateDecision multipleNextStates(final String... stateIds) { + final ArrayList stateMovements = new ArrayList<>(); + for (final String stateId : stateIds) { + stateMovements.add(StateMovement.builder().stateId(stateId).build()); + } + return StateDecision.builder().nextStates(stateMovements).build(); + } + + public static StateDecision multipleNextStates(final StateMovement... stateMovements) { + return StateDecision.builder().nextStates(Arrays.stream(stateMovements).collect(Collectors.toList())).build(); + } +} diff --git a/src/main/java/io/xdb/core/state/StateMovement.java b/src/main/java/io/xdb/core/state/StateMovement.java new file mode 100644 index 0000000..f9ccd2c --- /dev/null +++ b/src/main/java/io/xdb/core/state/StateMovement.java @@ -0,0 +1,12 @@ +package io.xdb.core.state; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class StateMovement { + + private final String stateId; + private final Object stateInput; +} diff --git a/src/main/java/io/xdb/core/utils/ProcessUtil.java b/src/main/java/io/xdb/core/utils/ProcessUtil.java index 9ddaf0a..0398a1c 100644 --- a/src/main/java/io/xdb/core/utils/ProcessUtil.java +++ b/src/main/java/io/xdb/core/utils/ProcessUtil.java @@ -1,9 +1,22 @@ package io.xdb.core.utils; -// mainly to return default values for null cases +import io.xdb.core.process.Process; +import io.xdb.core.state.AsyncState; +import io.xdb.gen.models.AsyncStateConfig; + public class ProcessUtil { - public static String getClassSimpleName(final Class obejctClass) { - return obejctClass.getSimpleName(); + public static final String DEFAULT_NAMESPACE = "default"; + + public static String getProcessType(final Class processClass) { + return processClass.getSimpleName(); + } + + public static String getStateId(final Class stateClass) { + return stateClass.getSimpleName(); + } + + public static AsyncStateConfig getAsyncStateConfig(final AsyncState state) { + return new AsyncStateConfig().skipWaitUntil(AsyncState.shouldSkipWaitUntil(state)); } } diff --git a/src/main/java/io/xdb/core/worker/WorkerService.java b/src/main/java/io/xdb/core/worker/WorkerService.java index 8af5a6b..d86ec99 100644 --- a/src/main/java/io/xdb/core/worker/WorkerService.java +++ b/src/main/java/io/xdb/core/worker/WorkerService.java @@ -2,12 +2,16 @@ import io.xdb.core.registry.Registry; import io.xdb.core.state.AsyncState; +import io.xdb.core.utils.ProcessUtil; import io.xdb.gen.models.AsyncStateExecuteRequest; import io.xdb.gen.models.AsyncStateExecuteResponse; import io.xdb.gen.models.AsyncStateWaitUntilRequest; import io.xdb.gen.models.AsyncStateWaitUntilResponse; import io.xdb.gen.models.CommandRequest; import io.xdb.gen.models.StateDecision; +import io.xdb.gen.models.StateMovement; +import java.util.List; +import java.util.stream.Collectors; public class WorkerService { @@ -41,8 +45,31 @@ public AsyncStateExecuteResponse handleAsyncStateExecute(final AsyncStateExecute .decode(request.getStateInput(), state.getInputType()); // TODO - final StateDecision stateDecision = state.execute(input); + final io.xdb.core.state.StateDecision stateDecision = state.execute(input); - return new AsyncStateExecuteResponse().stateDecision(stateDecision); + return new AsyncStateExecuteResponse().stateDecision(toServerModel(request.getProcessType(), stateDecision)); + } + + private StateDecision toServerModel(final String processType, final io.xdb.core.state.StateDecision stateDecision) { + if (stateDecision.getStateDecision() != null) { + return stateDecision.getStateDecision(); + } + + final List stateMovements = stateDecision + .getNextStates() + .stream() + .map(stateMovement -> + new StateMovement() + .stateId(stateMovement.getStateId()) + .stateInput(workerServiceOptions.getObjectEncoder().encode(stateMovement.getStateInput())) + .stateConfig( + ProcessUtil.getAsyncStateConfig( + registry.getProcessState(processType, stateMovement.getStateId()) + ) + ) + ) + .collect(Collectors.toList()); + + return new StateDecision().nextStates(stateMovements); } } diff --git a/src/test/java/integ/basic/BasicProcess.java b/src/test/java/integ/basic/BasicProcess.java new file mode 100644 index 0000000..aa52b2f --- /dev/null +++ b/src/test/java/integ/basic/BasicProcess.java @@ -0,0 +1,107 @@ +package integ.basic; + +import static integ.basic.BasicProcess.INPUT; +import static integ.basic.BasicProcess.STATE_ID_NEXT_1; +import static integ.basic.BasicProcess.STATE_ID_NEXT_2; + +import io.xdb.core.process.Process; +import io.xdb.core.state.AsyncState; +import io.xdb.core.state.AsyncStateOptions; +import io.xdb.core.state.StateDecision; +import io.xdb.core.state.StateMovement; +import io.xdb.core.state.StateSchema; +import io.xdb.gen.models.CommandRequest; +import io.xdb.gen.models.CommandWaitingType; +import lombok.NonNull; +import org.junit.jupiter.api.Assertions; +import org.springframework.stereotype.Component; + +@Component +public class BasicProcess implements Process { + + public static final String STATE_ID_NEXT_1 = "STATE_ID_NEXT_1"; + public static final String STATE_ID_NEXT_2 = "STATE_ID_NEXT_2"; + public static final Integer INPUT = 11; + + @Override + public @NonNull StateSchema getStateSchema() { + return StateSchema.withStartingState(new BasicStartingState(), new NextState1(), new NextState2()); + } +} + +class BasicStartingState implements AsyncState { + + @Override + public Class getInputType() { + return Integer.class; + } + + @Override + public CommandRequest waitUntil(final Integer input) { + System.out.println("BasicStartingState.waitUntil: " + input); + Assertions.assertEquals(INPUT, input); + + return new CommandRequest().waitingType(CommandWaitingType.EMPTYCOMMAND); + } + + @Override + public StateDecision execute(final Integer input) { + System.out.println("BasicStartingState.execute: " + input); + Assertions.assertEquals(INPUT, input); + + return StateDecision.multipleNextStates( + StateMovement.builder().stateId(STATE_ID_NEXT_1).stateInput(input + 1).build(), + StateMovement.builder().stateId(STATE_ID_NEXT_2).stateInput(input + 2).build() + ); + } +} + +class NextState1 implements AsyncState { + + @Override + public Class getInputType() { + return Integer.class; + } + + @Override + public @NonNull AsyncStateOptions getOptions() { + return AsyncStateOptions.builder().id(STATE_ID_NEXT_1).build(); + } + + @Override + public StateDecision execute(final Integer input) { + System.out.println("NextState1.execute: " + input); + Assertions.assertEquals(INPUT + 1, input); + + return StateDecision.deadEnd(); + } +} + +class NextState2 implements AsyncState { + + @Override + public Class getInputType() { + return Integer.class; + } + + @Override + public @NonNull AsyncStateOptions getOptions() { + return AsyncStateOptions.builder().id(STATE_ID_NEXT_2).build(); + } + + @Override + public CommandRequest waitUntil(final Integer input) { + System.out.println("NextState2.waitUntil: " + input); + Assertions.assertEquals(INPUT + 2, input); + + return new CommandRequest().waitingType(CommandWaitingType.EMPTYCOMMAND); + } + + @Override + public StateDecision execute(final Integer input) { + System.out.println("NextState2.execute: " + input); + Assertions.assertEquals(INPUT + 2, input); + + return StateDecision.deadEnd(); + } +} diff --git a/src/test/java/integ/basic/BasicTest.java b/src/test/java/integ/basic/BasicTest.java new file mode 100644 index 0000000..6f1b3df --- /dev/null +++ b/src/test/java/integ/basic/BasicTest.java @@ -0,0 +1,40 @@ +package integ.basic; + +import static integ.basic.BasicProcess.INPUT; +import static integ.spring.WorkerForTesting.WORKER_PORT; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import integ.spring.WorkerServiceForTesting; +import integ.spring.XdbConfig; +import io.xdb.core.client.Client; +import io.xdb.gen.models.ProcessExecutionDescribeResponse; +import io.xdb.gen.models.ProcessStatus; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class BasicTest { + + @BeforeEach + public void setup() { + WorkerServiceForTesting.startWorkerIfNotUp(); + } + + @Test + public void testBasicProcess() { + final Client client = XdbConfig.client; + + final String processId = "basic-process-" + System.currentTimeMillis() / 1000; + + final String processExecutionId = client.startProcess(BasicProcess.class, processId, INPUT); + + client.getProcessResultWithWait(processExecutionId); + + final ProcessExecutionDescribeResponse response = client.describeCurrentProcessExecution(processId); + assertEquals(processExecutionId, response.getProcessExecutionId()); + assertEquals("BasicProcess", response.getProcessType()); + assertEquals("http://localhost:" + WORKER_PORT, response.getWorkerUrl()); + + // TODO: to complete the workflow with RPC + assertEquals(ProcessStatus.RUNNING, response.getStatus()); + } +} diff --git a/src/test/java/integ/spring/SpringMainApplication.java b/src/test/java/integ/spring/SpringMainApplication.java new file mode 100644 index 0000000..67f1848 --- /dev/null +++ b/src/test/java/integ/spring/SpringMainApplication.java @@ -0,0 +1,14 @@ +package integ.spring; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@ComponentScan(basePackages = { "integ.spring", "integ.basic" }) +public class SpringMainApplication { + + public static void main(final String[] args) { + SpringApplication.run(SpringMainApplication.class, args); + } +} diff --git a/src/test/java/integ/spring/WorkerForTesting.java b/src/test/java/integ/spring/WorkerForTesting.java new file mode 100644 index 0000000..13973c5 --- /dev/null +++ b/src/test/java/integ/spring/WorkerForTesting.java @@ -0,0 +1,23 @@ +package integ.spring; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.springframework.boot.SpringApplication; + +public class WorkerForTesting { + + public static final int WORKER_PORT = 8802; + + final ExecutorService executor = Executors.newSingleThreadExecutor(); + + public void start() throws ExecutionException, InterruptedException { + System.getProperties().put("server.port", WORKER_PORT); + + executor + .submit(() -> { + SpringApplication.run(SpringMainApplication.class); + }) + .get(); + } +} diff --git a/src/test/java/integ/spring/WorkerServiceForTesting.java b/src/test/java/integ/spring/WorkerServiceForTesting.java new file mode 100644 index 0000000..c1c7109 --- /dev/null +++ b/src/test/java/integ/spring/WorkerServiceForTesting.java @@ -0,0 +1,17 @@ +package integ.spring; + +public class WorkerServiceForTesting { + + private static WorkerForTesting testWorker; + + public static void startWorkerIfNotUp() { + if (testWorker == null) { + testWorker = new WorkerForTesting(); + try { + testWorker.start(); + } catch (final Exception e) { + throw new RuntimeException(e); + } + } + } +} diff --git a/src/test/java/integ/spring/XdbConfig.java b/src/test/java/integ/spring/XdbConfig.java new file mode 100644 index 0000000..a9821d4 --- /dev/null +++ b/src/test/java/integ/spring/XdbConfig.java @@ -0,0 +1,35 @@ +package integ.spring; + +import io.xdb.core.client.Client; +import io.xdb.core.client.ClientOptions; +import io.xdb.core.process.Process; +import io.xdb.core.registry.Registry; +import io.xdb.core.worker.WorkerService; +import io.xdb.core.worker.WorkerServiceOptions; +import java.util.Arrays; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class XdbConfig { + + public static Client client; + + @Bean + public Registry registry() { + return new Registry(); + } + + @Bean + public static Client client(final Registry registry) { + client = new Client(registry, ClientOptions.getDefaultLocal()); + // the unit test could not autowire the Client + return client; + } + + @Bean + public WorkerService workerService(final Registry registry, final Process... processes) { + Arrays.stream(processes).forEach(registry::addProcess); + return new WorkerService(registry, WorkerServiceOptions.getDefault()); + } +} diff --git a/src/test/java/integ/spring/XdbWorkerApiController.java b/src/test/java/integ/spring/XdbWorkerApiController.java new file mode 100644 index 0000000..27744e0 --- /dev/null +++ b/src/test/java/integ/spring/XdbWorkerApiController.java @@ -0,0 +1,36 @@ +package integ.spring; + +import static io.xdb.core.worker.WorkerService.API_PATH_ASYNC_STATE_EXECUTE; +import static io.xdb.core.worker.WorkerService.API_PATH_ASYNC_STATE_WAIT_UNTIL; + +import io.xdb.core.worker.WorkerService; +import io.xdb.gen.models.AsyncStateExecuteRequest; +import io.xdb.gen.models.AsyncStateExecuteResponse; +import io.xdb.gen.models.AsyncStateWaitUntilRequest; +import io.xdb.gen.models.AsyncStateWaitUntilResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +public class XdbWorkerApiController { + + private final WorkerService workerService; + + @PostMapping(API_PATH_ASYNC_STATE_WAIT_UNTIL) + public ResponseEntity handleAsyncStateWaitUntil( + final @RequestBody AsyncStateWaitUntilRequest request + ) { + return ResponseEntity.ok(workerService.handleAsyncStateWaitUntil(request)); + } + + @PostMapping(API_PATH_ASYNC_STATE_EXECUTE) + public ResponseEntity handleAsyncStateExecute( + final @RequestBody AsyncStateExecuteRequest request + ) { + return ResponseEntity.ok(workerService.handleAsyncStateExecute(request)); + } +} diff --git a/src/test/java/io/xdb/core/common/process/ProcessNoStartingState.java b/src/test/java/io/xdb/core/common/process/ProcessNoStartingState.java deleted file mode 100644 index 01fd1aa..0000000 --- a/src/test/java/io/xdb/core/common/process/ProcessNoStartingState.java +++ /dev/null @@ -1,13 +0,0 @@ -package io.xdb.core.common.process; - -import io.xdb.core.common.state.StateWithWaitUntil; -import io.xdb.core.process.Process; -import io.xdb.core.state.StateSchema; - -public class ProcessNoStartingState implements Process { - - @Override - public StateSchema getStateSchema() { - return StateSchema.noStartingState(new StateWithWaitUntil()); - } -} diff --git a/src/test/java/io/xdb/core/common/process/ProcessWithStartingState.java b/src/test/java/io/xdb/core/common/process/ProcessWithStartingState.java deleted file mode 100644 index 7d343dc..0000000 --- a/src/test/java/io/xdb/core/common/process/ProcessWithStartingState.java +++ /dev/null @@ -1,20 +0,0 @@ -package io.xdb.core.common.process; - -import io.xdb.core.common.state.StateNoWaitUntil; -import io.xdb.core.common.state.StateWithWaitUntil; -import io.xdb.core.process.Process; -import io.xdb.core.process.ProcessOptions; -import io.xdb.core.state.StateSchema; - -public class ProcessWithStartingState implements Process { - - @Override - public ProcessOptions getOptions() { - return ProcessOptions.builder().type("testType").build(); - } - - @Override - public StateSchema getStateSchema() { - return StateSchema.withStartingState(new StateNoWaitUntil(), new StateWithWaitUntil()); - } -} diff --git a/src/test/java/io/xdb/core/common/state/StateNoWaitUntil.java b/src/test/java/io/xdb/core/common/state/StateNoWaitUntil.java deleted file mode 100644 index 60c5a9a..0000000 --- a/src/test/java/io/xdb/core/common/state/StateNoWaitUntil.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.xdb.core.common.state; - -import io.xdb.core.state.AsyncState; -import io.xdb.gen.models.StateDecision; - -public class StateNoWaitUntil implements AsyncState { - - @Override - public Class getInputType() { - return Void.class; - } - - @Override - public StateDecision execute(final Void input) { - return null; - } -} diff --git a/src/test/java/io/xdb/core/common/state/StateWithWaitUntil.java b/src/test/java/io/xdb/core/common/state/StateWithWaitUntil.java deleted file mode 100644 index dcdc3e8..0000000 --- a/src/test/java/io/xdb/core/common/state/StateWithWaitUntil.java +++ /dev/null @@ -1,29 +0,0 @@ -package io.xdb.core.common.state; - -import io.xdb.core.state.AsyncState; -import io.xdb.core.state.AsyncStateOptions; -import io.xdb.gen.models.CommandRequest; -import io.xdb.gen.models.StateDecision; - -public class StateWithWaitUntil implements AsyncState { - - @Override - public AsyncStateOptions getOptions() { - return AsyncStateOptions.builder().id("testStateId").build(); - } - - @Override - public Class getInputType() { - return Integer.class; - } - - @Override - public CommandRequest waitUntil(final Integer input) { - return null; - } - - @Override - public StateDecision execute(final Integer input) { - return null; - } -} diff --git a/src/test/java/io/xdb/core/registry/RegistryTest.java b/src/test/java/io/xdb/core/registry/RegistryTest.java deleted file mode 100644 index 6ebcff5..0000000 --- a/src/test/java/io/xdb/core/registry/RegistryTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package io.xdb.core.registry; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import io.xdb.core.common.process.ProcessNoStartingState; -import io.xdb.core.common.process.ProcessWithStartingState; -import io.xdb.core.utils.ProcessUtil; -import org.junit.jupiter.api.Test; - -public class RegistryTest { - - @Test - void addProcessesTest() { - final Registry registry = new Registry(); - final ProcessWithStartingState processWithStartingState = new ProcessWithStartingState(); - final ProcessNoStartingState processNoStartingState = new ProcessNoStartingState(); - - registry.addProcesses(processWithStartingState, processNoStartingState); - - assertEquals( - processWithStartingState, - registry.getProcess(ProcessUtil.getProcessType(processWithStartingState)) - ); - assertEquals(processNoStartingState, registry.getProcess(ProcessUtil.getProcessType(processNoStartingState))); - - assertTrue(registry.getProcessStartingState(ProcessUtil.getProcessType(processWithStartingState)).isPresent()); - assertFalse(registry.getProcessStartingState(ProcessUtil.getProcessType(processNoStartingState)).isPresent()); - } -} diff --git a/src/test/java/io/xdb/core/state/AsyncStateTest.java b/src/test/java/io/xdb/core/state/AsyncStateTest.java deleted file mode 100644 index be1ff2c..0000000 --- a/src/test/java/io/xdb/core/state/AsyncStateTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package io.xdb.core.state; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import io.xdb.core.common.state.StateNoWaitUntil; -import io.xdb.core.common.state.StateWithWaitUntil; -import io.xdb.core.utils.ProcessUtil; -import org.junit.jupiter.api.Test; - -public class AsyncStateTest { - - @Test - void shouldSkipWaitUntilTest() { - final StateNoWaitUntil stateNoWaitUntil = new StateNoWaitUntil(); - assertTrue(AsyncState.shouldSkipWaitUntil(stateNoWaitUntil)); - assertEquals("StateNoWaitUntil", ProcessUtil.getStateId(stateNoWaitUntil)); - assertEquals(Void.class, stateNoWaitUntil.getInputType()); - - final StateWithWaitUntil stateWithWaitUntil = new StateWithWaitUntil(); - assertFalse(AsyncState.shouldSkipWaitUntil(stateWithWaitUntil)); - assertEquals("testStateId", ProcessUtil.getStateId(stateWithWaitUntil)); - assertEquals(Integer.class, stateWithWaitUntil.getInputType()); - } -} diff --git a/src/test/java/io/xdb/core/state/StateSchemaTest.java b/src/test/java/io/xdb/core/state/StateSchemaTest.java deleted file mode 100644 index 304d893..0000000 --- a/src/test/java/io/xdb/core/state/StateSchemaTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package io.xdb.core.state; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import io.xdb.core.common.state.StateNoWaitUntil; -import io.xdb.core.common.state.StateWithWaitUntil; -import org.junit.jupiter.api.Test; - -public class StateSchemaTest { - - @Test - void withStartingStateTest() { - final StateNoWaitUntil startingState = new StateNoWaitUntil(); - final StateSchema stateSchema = StateSchema.withStartingState(startingState, new StateWithWaitUntil()); - - assertEquals(startingState, stateSchema.getStartingState()); - assertEquals(2, stateSchema.getAllStates().size()); - } - - @Test - void noStartingStateTest() { - final StateSchema stateSchema = StateSchema.noStartingState(new StateNoWaitUntil(), new StateWithWaitUntil()); - - assertEquals(null, stateSchema.getStartingState()); - assertEquals(2, stateSchema.getAllStates().size()); - } -}