From 620c72906502b4786e37741f1ba22a0cb49e330b Mon Sep 17 00:00:00 2001 From: Matt C Date: Fri, 25 Sep 2020 09:18:54 -0500 Subject: [PATCH 01/35] Issue #92 - Refactor Flow and Job to StateMachine and Execution (#128) * Draft refactor - testing TODO * Fix refactor issues shown by mlUnitTests * Refactor to pass junit tests --- CONTRIBUTING.md | 6 +- README.md | 76 +- .../bin/runCorbDriver.sh | 4 +- .../cpf/state-conductor-work-action.sjs | 8 +- state-conductor-dataservices/README.md | 24 +- .../data/test.properties | 4 +- .../docker/Dockerfile | 6 +- .../src/main/java/com/.DS_Store | Bin 0 -> 6148 bytes .../src/main/java/com/marklogic/.DS_Store | Bin 0 -> 6148 bytes .../ForestSplitsStateConductorDriver.java | 30 +- .../com/marklogic/StateConductorDriver.java | 44 +- .../com/marklogic/StateConductorService.java | 156 ++-- .../config/StateConductorDriverConfig.java | 28 +- ...etJobsTask.java => GetExecutionsTask.java} | 59 +- .../marklogic/tasks/ProcessExecutionTask.java | 33 + .../com/marklogic/tasks/ProcessJobTask.java | 33 - .../src/main/resources/logback.xml | 2 +- ...rJob.java => StateConductorExecution.java} | 40 +- .../marklogic/StateConductorServiceMock.java | 28 +- .../marklogic/StateConductorServiceTest.java | 387 ++++---- .../ext/AbstractStateConductorTest.java | 30 +- .../ext/StateConductorTestConfig.java | 4 +- .../tests/GetExecutionStatusTest.java | 259 ++++++ .../com/marklogic/tests/GetJobStatusTest.java | 259 ------ .../badExecution1.json} | 8 +- .../job1.json => executions/execution1.json} | 8 +- .../job2.json => executions/execution2.json} | 8 +- .../job3.json => executions/execution3.json} | 8 +- .../job4.json => executions/execution4.json} | 8 +- .../job5.json => executions/execution5.json} | 8 +- .../test-state-machine.asl.json} | 0 .../test2-state-machine.asl.json} | 0 state-conductor-dhf5-example/README.md | 2 +- .../custom/MyCustomStep/main.sjs | 20 +- .../suites/StateConductorDHF5Suite/setup.sjs | 4 +- .../StateConductorDHF5Suite/suiteSetup.sjs | 32 +- .../StateConductorDHF5Suite/suiteTeardown.sjs | 4 +- .../StateConductorDHF5Suite/teardown.sjs | 2 +- .../custom-steps-state-machine.asl.json} | 2 +- .../missing-dhf-state-machine.asl.json} | 2 +- .../person-envelope-state-machine.asl.json} | 0 .../person-state-machine.asl.json} | 2 +- .../person-steps-state-machine.asl.json} | 4 +- .../test-scDhf5Integration.sjs | 48 +- .../test-stateConductorContext.sjs | 12 +- ....json => branching-state-machine.asl.json} | 12 +- ...json => chaining-state-machine-A.asl.json} | 4 +- ...json => chaining-state-machine-B.asl.json} | 2 +- .../collections.properties | 2 +- ...l.json => envelope-state-machine.asl.json} | 0 ...json => eventsTask-state-machine.asl.json} | 0 ....json => exception-state-machine.asl.json} | 4 +- ...json => kafka-data-state-machine.asl.json} | 0 ...l.json => periodic-state-machine.asl.json} | 2 +- .../permissions.properties | 2 +- ...> waitState-events-state-machine.asl.json} | 0 ... => waitState-time-state-machine.asl.json} | 0 .../enroll-in-mens-health.sjs | 0 .../enroll-in-womens-health.sjs | 0 .../flag-for-follow-up.sjs | 0 .../gender-is-female.sjs | 0 .../gender-is-male.sjs | 0 .../root/state-conductor/configuration.sjs | 10 +- .../java/com/marklogic/DriverServiceTest.java | 148 +-- ...ceTest.java => ExecutionsServiceTest.java} | 94 +- ...Test.java => StateMachineServiceTest.java} | 124 ++- .../java/com/marklogic/StatusServiceTest.java | 235 +++-- .../ext/AbstractStateConductorRestTest.java | 28 +- .../ext/StateConductorTestConfig.java | 4 +- .../StateConductorSuite/emitEvent-test.sjs | 18 +- .../executeChoiceState-tests.sjs | 58 +- ...s => executeStateByExecutionDoc-tests.sjs} | 190 ++-- ...-tests.sjs => execution-context-tests.sjs} | 34 +- .../getConfiguration-test.sjs | 2 +- ...b-tests.sjs => processExecution-tests.sjs} | 8 +- .../StateConductorSuite/provenanceTests.sjs | 108 +-- .../StateConductorSuite/resultPathTests.sjs | 54 +- .../resumeWaitingExecution-tests.sjs | 22 + ...eWaitingExecutionByExecutionDoc-tests.sjs} | 160 ++-- .../resumeWaitingJob-tests.sjs | 22 - .../{reties-tests.sjs => retries-tests.sjs} | 218 ++--- ...tryExecutionAtStateByExecutionDoc-test.sjs | 207 +++++ .../retryJobAtStateByJobDoc-test.sjs | 207 ----- .../StateConductorSuite/securityTest.sjs | 8 +- .../test/suites/StateConductorSuite/setup.sjs | 6 +- .../startProcessingFlowByJobDoc-tests.sjs | 164 ---- ...essingStateMachineByExecutionDoc-tests.sjs | 164 ++++ .../state-conductor-context-tests.sjs | 40 +- .../state-conductor-execution-tests.sjs | 201 ++++ .../state-conductor-flow-tests.sjs | 51 - .../state-conductor-job-tests.sjs | 201 ---- .../state-conductor-state-machine-tests.sjs | 51 + .../suites/StateConductorSuite/suiteSetup.sjs | 84 +- .../StateConductorSuite/suiteTeardown.sjs | 6 +- .../suites/StateConductorSuite/teardown.sjs | 4 +- .../bad-state-machine.asl.json} | 4 +- .../branching-state-machine.asl.json} | 10 +- .../choice-state-machine.asl.json} | 8 +- .../contextual-state-machine.asl.json} | 6 +- .../no-context-state-machine.asl.json} | 2 +- .../noStates-state-machine.asl.json} | 2 +- .../ref-path-state-machine.asl.json} | 0 .../retry-state-machine.asl.json} | 2 +- .../task-state-machine.asl.json} | 4 +- .../test-state-machine.asl.json} | 2 +- .../test-time-wait.asl.json | 0 .../wait-state-machine.asl.json} | 2 +- ...wait-job.json => test-wait-execution.json} | 6 +- .../StateConductorSuite/timeWait-test.sjs | 34 +- .../resources/{jobs => executions}/job1.json | 8 +- .../resources/{jobs => executions}/job2.json | 8 +- .../resources/{jobs => executions}/job3.json | 8 +- .../resources/{jobs => executions}/job4.json | 8 +- .../resources/{jobs => executions}/job5.json | 8 +- .../resources/{jobs => executions}/job6.json | 8 +- .../resources/{jobs => executions}/job7.json | 8 +- .../invalid-test-flow.asl.json | 0 .../rest-test-flow.asl.json | 0 .../rest-test-flow2.asl.json | 0 .../rest-test-flow3.asl.json | 0 .../rest-test-flow4.asl.json | 0 state-conductor-modules/driver.properties | 5 + .../state-conductor-jobs-database.json | 2 +- .../roles/state-conductor-execute-role.json | 8 +- ...tate-conductor-execution-writer-role.json} | 6 +- ...tor.json => state-conductor-operator.json} | 4 +- .../roles/state-conductor-reader-role.json | 2 +- .../state-conductor-item-create-trigger.json | 2 +- .../state-conductor-item-update-trigger.json | 2 +- .../collections.properties | 2 +- .../permissions.properties | 2 +- .../state-conductor/corb2/process-module.sjs | 4 +- .../state-conductor/corb2/uris-module.sjs | 20 +- .../dataservices/createExecution.api | 22 + .../{createJob.sjs => createExecution.sjs} | 10 +- .../dataservices/createJob.api | 22 - .../dataservices/deleteFlow.api | 13 - .../dataservices/deleteFlow.sjs | 27 - .../dataservices/deleteStateMachine.api | 13 + .../dataservices/deleteStateMachine.sjs | 27 + .../{getJobs.api => getExecutions.api} | 18 +- .../dataservices/getExecutions.sjs | 63 ++ .../state-conductor/dataservices/getFlow.sjs | 41 - .../state-conductor/dataservices/getJobs.sjs | 63 -- .../{getFlow.api => getStateMachine.api} | 8 +- .../dataservices/getStateMachine.sjs | 41 + ...owStatus.api => getStateMachineStatus.api} | 14 +- ...owStatus.sjs => getStateMachineStatus.sjs} | 18 +- .../dataservices/insertFlow.api | 20 - .../dataservices/insertFlow.sjs | 35 - .../dataservices/insertStateMachine.api | 20 + .../dataservices/insertStateMachine.sjs | 35 + .../{processJob.api => processExecution.api} | 6 +- .../{processJob.sjs => processExecution.sjs} | 6 +- ...ngJobs.sjs => resumeWaitingExecutions.sjs} | 2 +- .../root/state-conductor/sample.asl.json | 4 +- .../state-conductor/state-conductor-lib.sjs | 12 +- .../root/state-conductor/state-conductor.sjs | 870 +++++++++--------- ...idator.sjs => state-machine-validator.sjs} | 10 +- .../root/state-conductor/tasks/scheduler.sjs | 28 +- .../root/state-conductor/tasks/waitTask.sjs | 6 +- .../trigger/state-conductor-item-trigger.sjs | 22 +- ...obs.xml => state-conductor-executions.xml} | 8 +- .../metadata/state-conductor-resume.xml | 2 +- .../metadata/state-conductor-retry.xml | 2 +- .../services/state-conductor-driver.sjs | 20 +- ...obs.sjs => state-conductor-executions.sjs} | 28 +- .../services/state-conductor-flows.sjs | 94 -- .../services/state-conductor-resume.sjs | 10 +- .../services/state-conductor-retry.sjs | 12 +- .../state-conductor-state-machines.sjs | 94 ++ .../services/state-conductor-status.sjs | 12 +- 172 files changed, 3305 insertions(+), 3311 deletions(-) create mode 100644 state-conductor-dataservices/src/main/java/com/.DS_Store create mode 100644 state-conductor-dataservices/src/main/java/com/marklogic/.DS_Store rename state-conductor-dataservices/src/main/java/com/marklogic/tasks/{GetJobsTask.java => GetExecutionsTask.java} (51%) create mode 100644 state-conductor-dataservices/src/main/java/com/marklogic/tasks/ProcessExecutionTask.java delete mode 100644 state-conductor-dataservices/src/main/java/com/marklogic/tasks/ProcessJobTask.java rename state-conductor-dataservices/src/test/java/com/marklogic/{StateConductorJob.java => StateConductorExecution.java} (74%) create mode 100644 state-conductor-dataservices/src/test/java/com/marklogic/tests/GetExecutionStatusTest.java delete mode 100644 state-conductor-dataservices/src/test/java/com/marklogic/tests/GetJobStatusTest.java rename state-conductor-dataservices/src/test/resources/{jobs/badJob1.json => executions/badExecution1.json} (65%) rename state-conductor-dataservices/src/test/resources/{jobs/job1.json => executions/execution1.json} (67%) rename state-conductor-dataservices/src/test/resources/{jobs/job2.json => executions/execution2.json} (67%) rename state-conductor-dataservices/src/test/resources/{jobs/job3.json => executions/execution3.json} (62%) rename state-conductor-dataservices/src/test/resources/{jobs/job4.json => executions/execution4.json} (64%) rename state-conductor-dataservices/src/test/resources/{jobs/job5.json => executions/execution5.json} (63%) rename state-conductor-dataservices/src/test/resources/{flows/test-flow.asl.json => stateMachines/test-state-machine.asl.json} (100%) rename state-conductor-dataservices/src/test/resources/{flows/test2-flow.asl.json => stateMachines/test2-state-machine.asl.json} (100%) rename state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/{flows/custom-steps-flow.asl.json => stateMachines/custom-steps-state-machine.asl.json} (95%) rename state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/{flows/missing-dhf-flow.asl.json => stateMachines/missing-dhf-state-machine.asl.json} (92%) rename state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/{flows/person-envelope-flow.asl.json => stateMachines/person-envelope-state-machine.asl.json} (100%) rename state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/{flows/person-flow.asl.json => stateMachines/person-state-machine.asl.json} (94%) rename state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/{flows/person-steps-flow.asl.json => stateMachines/person-steps-state-machine.asl.json} (93%) rename state-conductor-example/src/main/ml-data/state-conductor-flow/{branching-flow.asl.json => branching-state-machine.asl.json} (80%) rename state-conductor-example/src/main/ml-data/state-conductor-flow/{chaining-flow-A.asl.json => chaining-state-machine-A.asl.json} (68%) rename state-conductor-example/src/main/ml-data/state-conductor-flow/{chaining-flow-B.asl.json => chaining-state-machine-B.asl.json} (80%) rename state-conductor-example/src/main/ml-data/state-conductor-flow/{envelope-flow.asl.json => envelope-state-machine.asl.json} (100%) rename state-conductor-example/src/main/ml-data/state-conductor-flow/{eventsTask-flow.asl.json => eventsTask-state-machine.asl.json} (100%) rename state-conductor-example/src/main/ml-data/state-conductor-flow/{exception-flow.asl.json => exception-state-machine.asl.json} (84%) rename state-conductor-example/src/main/ml-data/state-conductor-flow/{kafka-data-flow.asl.json => kafka-data-state-machine.asl.json} (100%) rename state-conductor-example/src/main/ml-data/state-conductor-flow/{periodic-flow.asl.json => periodic-state-machine.asl.json} (83%) rename state-conductor-example/src/main/ml-data/state-conductor-flow/{waitState-events-flow.asl.json => waitState-events-state-machine.asl.json} (100%) rename state-conductor-example/src/main/ml-data/state-conductor-flow/{waitState-time-flow.asl.json => waitState-time-state-machine.asl.json} (100%) rename state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/{branching-test-flow => branching-test-state-machine}/enroll-in-mens-health.sjs (100%) rename state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/{branching-test-flow => branching-test-state-machine}/enroll-in-womens-health.sjs (100%) rename state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/{branching-test-flow => branching-test-state-machine}/flag-for-follow-up.sjs (100%) rename state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/{branching-test-flow => branching-test-state-machine}/gender-is-female.sjs (100%) rename state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/{branching-test-flow => branching-test-state-machine}/gender-is-male.sjs (100%) rename state-conductor-example/src/test/java/com/marklogic/{JobsServiceTest.java => ExecutionsServiceTest.java} (61%) rename state-conductor-example/src/test/java/com/marklogic/{FlowServiceTest.java => StateMachineServiceTest.java} (50%) rename state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/{executeStateByJobDoc-tests.sjs => executeStateByExecutionDoc-tests.sjs} (57%) rename state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/{job-context-tests.sjs => execution-context-tests.sjs} (81%) rename state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/{processJob-tests.sjs => processExecution-tests.sjs} (50%) create mode 100644 state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/resumeWaitingExecution-tests.sjs rename state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/{resumeWaitingJobByJobDoc-tests.sjs => resumeWaitingExecutionByExecutionDoc-tests.sjs} (55%) delete mode 100644 state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/resumeWaitingJob-tests.sjs rename state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/{reties-tests.sjs => retries-tests.sjs} (66%) create mode 100644 state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/retryExecutionAtStateByExecutionDoc-test.sjs delete mode 100644 state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/retryJobAtStateByJobDoc-test.sjs delete mode 100644 state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/startProcessingFlowByJobDoc-tests.sjs create mode 100644 state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/startProcessingStateMachineByExecutionDoc-tests.sjs create mode 100644 state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-execution-tests.sjs delete mode 100644 state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-flow-tests.sjs delete mode 100644 state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-job-tests.sjs create mode 100644 state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-state-machine-tests.sjs rename state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/{flows/bad-flow.asl.json => stateMachines/bad-state-machine.asl.json} (85%) rename state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/{flows/branching-flow.asl.json => stateMachines/branching-state-machine.asl.json} (85%) rename state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/{flows/choice-flow.asl.json => stateMachines/choice-state-machine.asl.json} (79%) rename state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/{flows/contextual-flow.asl.json => stateMachines/contextual-state-machine.asl.json} (83%) rename state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/{flows/no-context-flow.asl.json => stateMachines/no-context-state-machine.asl.json} (86%) rename state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/{flows/noStates-flow.asl.json => stateMachines/noStates-state-machine.asl.json} (75%) rename state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/{flows/ref-path-flow.asl.json => stateMachines/ref-path-state-machine.asl.json} (100%) rename state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/{flows/retry-flow.asl.json => stateMachines/retry-state-machine.asl.json} (98%) rename state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/{flows/task-flow.asl.json => stateMachines/task-state-machine.asl.json} (82%) rename state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/{flows/test-flow.asl.json => stateMachines/test-state-machine.asl.json} (92%) rename state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/{flows => stateMachines}/test-time-wait.asl.json (100%) rename state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/{flows/wait-flow.asl.json => stateMachines/wait-state-machine.asl.json} (93%) rename state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/{test-wait-job.json => test-wait-execution.json} (84%) rename state-conductor-example/src/test/resources/{jobs => executions}/job1.json (64%) rename state-conductor-example/src/test/resources/{jobs => executions}/job2.json (64%) rename state-conductor-example/src/test/resources/{jobs => executions}/job3.json (59%) rename state-conductor-example/src/test/resources/{jobs => executions}/job4.json (63%) rename state-conductor-example/src/test/resources/{jobs => executions}/job5.json (64%) rename state-conductor-example/src/test/resources/{jobs => executions}/job6.json (60%) rename state-conductor-example/src/test/resources/{jobs => executions}/job7.json (63%) rename state-conductor-example/src/test/resources/{flows => stateMachines}/invalid-test-flow.asl.json (100%) rename state-conductor-example/src/test/resources/{flows => stateMachines}/rest-test-flow.asl.json (100%) rename state-conductor-example/src/test/resources/{flows => stateMachines}/rest-test-flow2.asl.json (100%) rename state-conductor-example/src/test/resources/{flows => stateMachines}/rest-test-flow3.asl.json (100%) rename state-conductor-example/src/test/resources/{flows => stateMachines}/rest-test-flow4.asl.json (100%) create mode 100644 state-conductor-modules/driver.properties rename state-conductor-modules/src/main/ml-config/security/roles/{state-conductor-job-writer-role.json => state-conductor-execution-writer-role.json} (60%) rename state-conductor-modules/src/main/ml-config/security/roles/{state-conductor-operetor.json => state-conductor-operator.json} (90%) create mode 100644 state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/createExecution.api rename state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/{createJob.sjs => createExecution.sjs} (69%) delete mode 100644 state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/createJob.api delete mode 100644 state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/deleteFlow.api delete mode 100644 state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/deleteFlow.sjs create mode 100644 state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/deleteStateMachine.api create mode 100644 state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/deleteStateMachine.sjs rename state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/{getJobs.api => getExecutions.api} (56%) create mode 100644 state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getExecutions.sjs delete mode 100644 state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getFlow.sjs delete mode 100644 state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getJobs.sjs rename state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/{getFlow.api => getStateMachine.api} (50%) create mode 100644 state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getStateMachine.sjs rename state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/{getFlowStatus.api => getStateMachineStatus.api} (59%) rename state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/{getFlowStatus.sjs => getStateMachineStatus.sjs} (55%) delete mode 100644 state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/insertFlow.api delete mode 100644 state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/insertFlow.sjs create mode 100644 state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/insertStateMachine.api create mode 100644 state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/insertStateMachine.sjs rename state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/{processJob.api => processExecution.api} (69%) rename state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/{processJob.sjs => processExecution.sjs} (83%) rename state-conductor-modules/src/main/ml-modules/root/state-conductor/{resumeWaitingJobs.sjs => resumeWaitingExecutions.sjs} (63%) rename state-conductor-modules/src/main/ml-modules/root/state-conductor/{flow-file-validator.sjs => state-machine-validator.sjs} (94%) rename state-conductor-modules/src/main/ml-modules/services/metadata/{state-conductor-jobs.xml => state-conductor-executions.xml} (51%) rename state-conductor-modules/src/main/ml-modules/services/{state-conductor-jobs.sjs => state-conductor-executions.sjs} (63%) delete mode 100644 state-conductor-modules/src/main/ml-modules/services/state-conductor-flows.sjs create mode 100644 state-conductor-modules/src/main/ml-modules/services/state-conductor-state-machines.sjs diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aaa5f648..ee05fa88 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,7 +13,7 @@ There are two sub-projects. State-conductor-modules which contains the core library that gets built into the mlBundle redistributable. -State-conductor-example which has unit tests, as well as example flows and actions. +State-conductor-example which has unit tests, as well as example state machines and actions. ## Found an Issue? If you find a bug in the source code or a mistake in the documentation, you can help us by submitting an issue to our [GitHub Issue Tracker][issue tracker]. Even better, you can submit a Pull Request with a fix for the issue you filed. @@ -254,10 +254,10 @@ Use `git rebase` (not `git merge`) to sync your work from time to time. $ ./gradlew -Dtest.single=TestName test ``` -- For best results, do not include the final word test. For example, suppose you want to run FlowRunnerTest: +- For best results, do not include the final word test. For example, suppose you want to run StateMachineRunnerTest: ```sh - $ ./gradlew -Dtest.single=FlowRunner test + $ ./gradlew -Dtest.single=StateMachineRunner test ``` You can run the e2e tests from Visual Studio Code or another IDE to perform fullstack debugging. To do so, add a run/debug diff --git a/README.md b/README.md index c3f23638..13192748 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,23 @@ # MarkLogic State Conductor The _MarkLogic State Conductor_ is an event-based orchestrator for manipulating MarkLogic database documents. -State Conductor flows are defined using a subset of [Amazon States Language (ASL)](https://states-language.net/spec.html). State actions are defined using server-side modules. The included driver utilizes MarkLogic's CPF and Triggers to move documents through the defined State flows. +State Conductor state machines are defined using a subset of [Amazon States Language (ASL)](https://states-language.net/spec.html). Actions are defined using server-side modules. The included driver utilizes MarkLogic's CPF and Triggers to move documents through the defined State Machines. The _State Conductor_ can be used to perform an arbitrary number of context-based processing actions on a subset of documents. Actions could include: invoking a [MarkLogic Data Hub](https://docs.marklogic.com/datahub/) flow, transforming a document, applying metadata, or calling an external process. -The _State Conductor_ requires a "Driver" to process documents and move them through the installed Flows' states. The _State Conductor_ supports a [Data Services](https://github.com/aclavio/marklogic-state-conductor/tree/develop/state-conductor-dataservices) driver, a [CoRB2](https://github.com/marklogic-community/corb2) driver, and a [CPF](https://docs.marklogic.com/guide/cpf) driver. +The _State Conductor_ requires a "Driver" to process documents and move them through the installed state machine states. The _State Conductor_ supports a [Data Services](https://github.com/aclavio/marklogic-state-conductor/tree/develop/state-conductor-dataservices) driver, a [CoRB2](https://github.com/marklogic-community/corb2) driver, and a [CPF](https://docs.marklogic.com/guide/cpf) driver. 1. [Quick Start Guide](https://github.com/aclavio/marklogic-state-conductor/wiki/QUICKSTART) 2. [Installation](#installation) 3. [Usage](#usage) -4. [Flow Files](#flow-files) -5. [Flow File Scope](#flow-file-scope) -6. [Flow File Actions](#flow-file-actions) -7. [Job Documents](#job-documents) +4. [State Machines](#state-machines) +5. [State Machine Scope](#state-machine-scope) +6. [State Machine Actions](#state-machine-actions) +7. [Execution Documents](#execution-documents) 8. [Provenance](#provenance) 9. [Services](#services) -10. [Jobs Service](#jobs-service) -11. [Flows Service](#flows-service) +10. [Executions Service](#execution-service) +11. [State Service](#state-machine-service) 12. [Status Service](#status-service) 13. [Roadmap](#roadmap) @@ -51,19 +51,19 @@ mlCpfDatabaseName=state-conductor-triggers ## Usage -Any documents created or modified having the `state-conductor-item` collection will trigger processing by the _State Conductor_. They will be evaluated against the context of all installed _Flow Files_. For each matching _Flow File_ a `Job` document will be created corresponding to the matching flow and triggering document. A property will be added to the triggering document's metadata indicating the `Job` file's id: +Any documents created or modified having the `state-conductor-item` collection will trigger processing by the _State Conductor_. They will be evaluated against the context of all installed _State Machines_. For each matching _State Machine_ an `Execution` document will be created corresponding to the matching execution and triggering document. A property will be added to the triggering document's metadata indicating the `Execution` file's id: ```xml - + ``` -> NOTE: Document modifications during, or after the competion of a Flow will not cause that document to be reprocessed by that same flow. To run a Flow on a document that it has already been processed by requires manual invokation of the [`Jobs Service`](#jobs-service). +> NOTE: Document modifications during, or after the competion of a State Machine will not cause that document to be reprocessed by that same state machine. To run a State Machine on a document that it has already been processed by requires manual invokation of the [`Execution Service`](#execution-service). -### Flow Files +### State Machines -Flow files define the states that documents will transition through. States can perform actions (utilizing SJS modules in MarkLogic), performing branching logic, or terminate processing. Flow files are json formatted documents within the application's content database; they should have the "state-conductor-flow" collection, and have the ".asl.json" file extension. +State Machine files define the states that documents will transition through. States can perform actions (utilizing SJS modules in MarkLogic), performing branching logic, or terminate processing. State Machines are json formatted documents within the application's content database; they should have the "state-conductor" collection, and have the ".asl.json" file extension. -Example Flow File: +Example State Machine File: ```json { @@ -84,7 +84,7 @@ Example Flow File: "States": { "set-prop1": { "Type": "Task", - "Comment": "initial state of the flow", + "Comment": "initial state", "Resource": "/state-conductor/actions/common/examples/set-prop1.sjs", "Parameters": { "foo": "bar" @@ -101,9 +101,9 @@ Example Flow File: } ``` -#### Flow File Scope +#### State Machine Scope -Flow files must define a context within an `mlDomain` property under the flow file's root. The context defines one or more scopes for which matching documents will have this State Conductor flow automatically applied. +State Machines must define a context within an `mlDomain` property under the state machine's root. The context defines one or more scopes for which matching documents will have this State Conductor state machine automatically applied. Example: @@ -128,9 +128,9 @@ Example: Valid scopes are `collection`, `directory`, and `query`. For scopes of type `query`, the value must be a string containing the JSON serialization of a cts query. -#### Flow File Actions +#### State Machine Actions -Flow File States of the type "Task" can define actions to perform on in-process documents. These actions take the form of Server-Side Javascript modules referenced by the "Resource" property. Action modules can perform custom activities such as updating the in-process document, performing a query, invoking an external service, etc. Action modules should export a "performAction" function with the following signature: +State Machine States of the type "Task" can define actions to perform on in-process documents. These actions take the form of Server-Side Javascript modules referenced by the "Resource" property. Action modules can perform custom activities such as updating the in-process document, performing a query, invoking an external service, etc. Action modules should export a "performAction" function with the following signature: ```javascript 'use strict'; @@ -142,62 +142,62 @@ function performAction(uri, parameters = {}, context = {}) { exports.performAction = performAction; ``` -Where `uri` is the document being processed by the flow; `parameters` is a json object configured via this State's Flow File "Parameters" property; and `context` contains the current in-process Flow's context. Any data returned by the performAction function will be stored in the in-process flow's context object. +Where `uri` is the document being processed by the state machine; `parameters` is a json object configured via this State's "Parameters" property; and `context` contains the current in-process state machine's context. Any data returned by the performAction function will be stored in the in-process context object. -### Job Documents +### Execution Documents -For every document processed by a _State Conductor_ flow there is a corresponding `Job` document. Job documents are stored in the `state-conductor-jobs` database (new in v0.3.0), in the `/stateConductorJob/` folder. These documents track the in-process document, and flow; they also store the flow's context and provenance information. +For every document processed by a _State Conductor_ state machine there is a corresponding `Execution` document. Execution documents are stored in the `state-conductor-executions` database (new in v0.3.0), in the `/execution/` folder. These documents track the in-process document, and state machine; they also store the context and provenance information. ### Provenance -Every time a document starts, stops, or transitions from one state to another within a Flow, the Provenance information stored in the Job document is updated. +Every time a document starts, stops, or transitions from one state to another within a State Machine, the Provenance information stored in the Excecution document is updated. --- ## Services -The _State Conductor_ includes MarkLogic REST service extensions for managing Flow files and State Conductor Jobs. +The _State Conductor_ includes MarkLogic REST service extensions for managing State Machines and State Conductor Executions. -### Jobs Service +### Execution Service -Create one or more _State Conductor_ Jobs: +Create one or more _State Conductor_ Executions: ``` -PUT /v1/resources/state-conductor-jobs?rs:uris=&rs:flowName= +PUT /v1/resources/state-conductor-executions?rs:uris=&rs:name= ``` -Get the job id for the given document and flow: +Get the execution id for the given document and state machine: ``` -GET /v1/resources/state-conductor-jobs?rs:uri=&rs:flowName= +GET /v1/resources/state-conductor-executions?rs:uri=&rs:name= ``` -### Flows Service +### State Machine Service -List the installed _State Conductor_ Flows: +List the installed _State Conductor_ State Machines: ``` -GET /v1/resources/state-conductor-flows?rs:flowName= +GET /v1/resources/state-conductor-state-machines?rs:name= ``` -Install a _State Conductor_ Flow: +Install a _State Conductor_ State Machine: ``` -PUT /v1/resources/state-conductor-flows?rs:flowName= +PUT /v1/resources/state-conductor-state-machines?rs:name= ``` -Remove an installed _State Conductor_ Flow: +Remove an installed _State Conductor_ State Machine: ``` -DELETE /v1/resources/state-conductor-flows?rs:flowName= +DELETE /v1/resources/state-conductor-state-machines?rs:name= ``` ### Status Service -List the status of the given _State Conductor_ Flow: +List the status of the given _State Conductor_ State Machine: ``` -GET /v1/resources/state-conductor-status?rs:flowName=&rs:startDate=&rs:endDate= +GET /v1/resources/state-conductor-state-machines?rs:name=&rs:startDate=&rs:endDate= ``` New (optional) temporal parameters `startDate` and `endDate` in v0.3.0. diff --git a/state-conductor-corb-example/bin/runCorbDriver.sh b/state-conductor-corb-example/bin/runCorbDriver.sh index 738f7bf5..37e15b52 100644 --- a/state-conductor-corb-example/bin/runCorbDriver.sh +++ b/state-conductor-corb-example/bin/runCorbDriver.sh @@ -1,7 +1,7 @@ #!/bin/bash for (( ; ; )) do - echo "processing jobs [ hit CTRL+C to stop]" + echo "processing executions [ hit CTRL+C to stop]" java -server -cp .:./libs/marklogic-xcc-10.0.3.jar:./libs/marklogic-corb-2.4.6.jar -DOPTIONS-FILE=corbDriver.properties com.marklogic.developer.corb.Manager "$@" code=$? if [ $code -eq 0 ] @@ -9,7 +9,7 @@ do continue elif [ $code -eq 3 ] then - echo "no jobs to process, sleeping 15 seconds..." + echo "no executions to process, sleeping 15 seconds..." sleep 15s continue else diff --git a/state-conductor-cpf/src/main/ml-modules/root/state-conductor/cpf/state-conductor-work-action.sjs b/state-conductor-cpf/src/main/ml-modules/root/state-conductor/cpf/state-conductor-work-action.sjs index fb6ad5af..910064a0 100644 --- a/state-conductor-cpf/src/main/ml-modules/root/state-conductor/cpf/state-conductor-work-action.sjs +++ b/state-conductor-cpf/src/main/ml-modules/root/state-conductor/cpf/state-conductor-work-action.sjs @@ -11,16 +11,16 @@ var transition; if (cpf.checkTransition(uri, transition)) { try { xdmp.trace(sc.TRACE_EVENT, `state-conductor-work-action for "${uri}"`); - const continueJob = sc.processJob(uri); - if (continueJob) { - // continue cpf processing - continuing the current flow or any others that apply + const continueExecution = sc.processExecution(uri); + if (continueExecution) { + // continue cpf processing - continuing the current state machine or any others that apply cpf.success(uri, transition, 'http://marklogic.com/states/working'); } else { // the default success action should transition us to the "done" cpf state and end processing cpf.success(uri, transition, null); } } catch (e) { - xdmp.log('error executing flow:' + xdmp.describe(e), 'error'); + xdmp.log('error executing state machine:' + xdmp.describe(e), 'error'); xdmp.log(e, 'error'); cpf.failure(uri, transition, json.transformFromJson(e), null); } diff --git a/state-conductor-dataservices/README.md b/state-conductor-dataservices/README.md index 27829cd4..86951acc 100644 --- a/state-conductor-dataservices/README.md +++ b/state-conductor-dataservices/README.md @@ -24,9 +24,9 @@ From the root of the State Conductor project, execute the `jar` task. The `generateStateConductorProxy` gradle task is used to generate the Java service proxy for the State Conductor. The proxy service provides the follow functions: -* `createJob` - creates a State Conductor Job -* `getJobs` - returns a list of Job documents to be processed -* `processJob` - invokes the State Conductor processing of a job +* `createExecution` - creates a State Conductor Execution +* `getExecution` - returns a list of Execution documents to be processed +* `processExecution` - invokes the State Conductor processing of a exection ## Testing From the root of the State Conductor project, execute the `mlDeploy` and `test` gradle tasks. @@ -50,14 +50,14 @@ From the root of the State Conductor project, execute the `mlDeploy` and `test` | externalName | (empty) | The external name to use to connect to MarkLogic | | certFile | (empty) | The external name to use to connect to MarkLogic | | certPassword | (empty) | The external name to use to connect to MarkLogic | -| jobsDatabase | state-conductor-jobs | The database where State Conductor jobs are stored | -| flowNames | (empty) | A list of flows names for which to process State Conductor jobs. Leave empty to process jobs from all installed flows. | -| flowStatus | (empty) | A list of flow statuses for which to process State Conductor jobs. If left empty, new jobs, working jobs, and waiting jobs will be processed. | -| pollSize | 1000 | How many jobs to fetch per poll | -| pollInterval | 1000 | (Milliseconds) How often to poll for new jobs | -| cooldownMillis | 5000 | (Milliseconds) If no valid jobs are found for processing, poll using this interval. | -| queueThreshold | 20000 | The upper limit for how many jobs the driver will cache for processing. After this limit is reached, polling for new jobs will fall back to the cooldownMillis interval, and jobs will not be added until the queue size falls below this threshold. | -| batchSize | 5 | How many jobs will be submitted for processing simultaneously | -| threadCount | 10 | The number of executor threads used to process jobs on the queue. Scale based on the number of available App Server threads for optimal performance. | +| executionDatabase | state-conductor-executions | The database where State Conductor executions are stored | +| names | (empty) | A list of state machine names for which to process State Conductor executions. Leave empty to process executions from all installed state machines. | +| status | (empty) | A list of state machine statuses for which to process State Conductor executions. If left empty, new executions, working executions, and waiting executions will be processed. | +| pollSize | 1000 | How many executions to fetch per poll | +| pollInterval | 1000 | (Milliseconds) How often to poll for new executions | +| cooldownMillis | 5000 | (Milliseconds) If no valid executions are found for processing, poll using this interval. | +| queueThreshold | 20000 | The upper limit for how many executions the driver will cache for processing. After this limit is reached, polling for new executions will fall back to the cooldownMillis interval, and executions will not be added until the queue size falls below this threshold. | +| batchSize | 5 | How many executions will be submitted for processing simultaneously | +| threadCount | 10 | The number of executor threads used to process executions on the queue. Scale based on the number of available App Server threads for optimal performance. | | metricsInterval | 5000 | (Milliseconds) How often metrics should be logged | diff --git a/state-conductor-dataservices/data/test.properties b/state-conductor-dataservices/data/test.properties index 5224cd98..3cf4eeb4 100644 --- a/state-conductor-dataservices/data/test.properties +++ b/state-conductor-dataservices/data/test.properties @@ -9,8 +9,8 @@ batchSize=5 threadCount=16 queueThreshold=5000 simpleSsl=false -flowNames= -flowStatus= +names= +status= cooldownMillis=10000 pollInterval=1000 metricsInterval=10000 diff --git a/state-conductor-dataservices/docker/Dockerfile b/state-conductor-dataservices/docker/Dockerfile index 9ce67bd6..58d5b1c6 100644 --- a/state-conductor-dataservices/docker/Dockerfile +++ b/state-conductor-dataservices/docker/Dockerfile @@ -13,9 +13,9 @@ ENV simpleSsl=false ENV externalName= ENV certFile= ENV certPassword= -ENV jobsDatabase=state-conductor-jobs -ENV flowNames= -ENV flowStatus= +ENV executionDatabase=state-conductor-executions +ENV names= +ENV status= ENV pollSize=1000 ENV pollInterval=1000 ENV cooldownMillis=5000 diff --git a/state-conductor-dataservices/src/main/java/com/.DS_Store b/state-conductor-dataservices/src/main/java/com/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..17de5968ac013da7247de71ed98f6c3be71467b7 GIT binary patch literal 6148 zcmeHK%}&BV5S|s(Eyl>fM2@|9;{cJLlSzYk@Mcn@2Q|=IB8@-^ln}+5zJ|V$PvGk~ zv%3WFUbbtEN>a8L&1MDdqehZg^5C#~eAXR4J}sV;msicNpe>Q?X;_YLON$L= zfEi#0n1Qusz+4n^XRTS_%`*ecKo$dZKG>*)j=@x;Iy!JrEdXL3mzAJRy#(dh1|5T` zM)aTvorlaB)YGxPt-?V#8hK;}n1NLWa(Y^% z`~MU_nan1CHHBx)05kB<7!dik+iu~e%-#B9dvw>@s9jVNic85rL3`yV04H>gl$2BZ cZL%@WF_>zkDzvWB5&1_z5yAsA@Cyul0%Yb)bpQYW literal 0 HcmV?d00001 diff --git a/state-conductor-dataservices/src/main/java/com/marklogic/.DS_Store b/state-conductor-dataservices/src/main/java/com/marklogic/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 jobUris = service.getJobs(1, batchSize, null, null, forestIds.stream(), null, null); + // grab any "new" and "working" executions + Stream executionUris = service.getExecutions(1, batchSize, null, null, forestIds.stream(), null, null); - // process each of the jobs - jobUris.forEach(uri -> { - logger.info("processing job: {}", uri); + // process each of the executions + executionUris.forEach(uri -> { + logger.info("processing execution: {}", uri); count.getAndIncrement(); try { - service.processJob(Arrays.stream(new String[]{uri})); + service.processExecution(Arrays.stream(new String[]{uri})); } catch (FailedRequestException ex) { failed.getAndIncrement(); - logger.error("error processing job:", ex); + logger.error("error processing execution:", ex); } }); - logger.info("[Forest {}] Processed {} Jobs, with {} Failures.", forestId, count.get(), failed.get()); + logger.info("[Forest {}] Processed {} Executions, with {} Failures.", forestId, count.get(), failed.get()); try { if (0 == count.get()) diff --git a/state-conductor-dataservices/src/main/java/com/marklogic/StateConductorDriver.java b/state-conductor-dataservices/src/main/java/com/marklogic/StateConductorDriver.java index 85753a88..4eddf489 100644 --- a/state-conductor-dataservices/src/main/java/com/marklogic/StateConductorDriver.java +++ b/state-conductor-dataservices/src/main/java/com/marklogic/StateConductorDriver.java @@ -7,9 +7,9 @@ import com.marklogic.client.ext.ConfiguredDatabaseClientFactory; import com.marklogic.client.ext.DefaultConfiguredDatabaseClientFactory; import com.marklogic.config.StateConductorDriverConfig; -import com.marklogic.tasks.GetJobsTask; +import com.marklogic.tasks.GetExecutionsTask; import com.marklogic.tasks.MetricsTask; -import com.marklogic.tasks.ProcessJobTask; +import com.marklogic.tasks.ProcessExecutionTask; import org.apache.commons.cli.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,8 +55,8 @@ public static Options getOptions() { num.setOptionalArg(true); Option threads = new Option("t", "threads", true, "Thread count"); threads.setOptionalArg(true); - Option jobsDb = new Option("db", "jobs-database", true, "Jobs Database Name"); - jobsDb.setOptionalArg(true); + Option executionsDb = new Option("db", "executions-database", true, "Executions Database Name"); + executionsDb.setOptionalArg(true); Option batch = new Option("b", "batch", true, "Batch Size"); batch.setOptionalArg(true); Option config = new Option("c", "config", true, "Configuration File"); @@ -69,7 +69,7 @@ public static Options getOptions() { opts.addOption(pass); opts.addOption(num); opts.addOption(threads); - opts.addOption(jobsDb); + opts.addOption(executionsDb); opts.addOption(batch); opts.addOption(config); opts.addOption(help); @@ -107,7 +107,7 @@ public static void main(String[] args) throws DestroyFailedException, IOExceptio if (cmd.hasOption("p")) props.put("mlPort", cmd.getOptionValue("p")); if (cmd.hasOption("u")) props.put("username", cmd.getOptionValue("u")); if (cmd.hasOption("x")) props.put("password", cmd.getOptionValue("x")); - if (cmd.hasOption("db")) props.put("jobsDatabase", cmd.getOptionValue("db")); + if (cmd.hasOption("db")) props.put("executionsDatabase", cmd.getOptionValue("db")); if (cmd.hasOption("n")) props.put("pollSize", cmd.getOptionValue("n")); if (cmd.hasOption("t")) props.put("threadCount", cmd.getOptionValue("t")); if (cmd.hasOption("b")) props.put("batchSize", cmd.getOptionValue("b")); @@ -152,7 +152,7 @@ public void run() { List> errored = new ArrayList<>(); List batch = new ArrayList<>(); - List jobBuckets = new ArrayList<>(); + List executionBuckets = new ArrayList<>(); // set up the thread pool ExecutorService pool = Executors.newFixedThreadPool(config.getThreadCount()); @@ -162,12 +162,12 @@ public void run() { Thread metricsThread = new Thread(metricsTask); metricsThread.start(); - // start the thread for getting jobs - Thread getJobsTask = new Thread(new GetJobsTask(service, config, urisBuffer, inProgressSet)); - getJobsTask.start(); + // start the thread for getting executions + Thread getExecutionsTask = new Thread(new GetExecutionsTask(service, config, urisBuffer, inProgressSet)); + getExecutionsTask.start(); while (keepRunning) { - jobBuckets.clear(); + executionBuckets.clear(); // create batches from any new buffered tasks synchronized (urisBuffer) { @@ -177,14 +177,14 @@ public void run() { String uri = uris.next(); batch.add(uri); if (batch.size() >= config.getBatchSize()) { - jobBuckets.add(new ProcessJobTask(batchCount.getAndIncrement(), service, batch)); + executionBuckets.add(new ProcessExecutionTask(batchCount.getAndIncrement(), service, batch)); batch = new ArrayList<>(); } } // cleanup batch if (batch.size() > 0) { - jobBuckets.add(new ProcessJobTask(batchCount.getAndIncrement(), service, batch)); + executionBuckets.add(new ProcessExecutionTask(batchCount.getAndIncrement(), service, batch)); batch = new ArrayList<>(); } @@ -192,14 +192,14 @@ public void run() { urisBuffer.clear(); } - // submit the jobs to the executor pool - for (ProcessJobTask bucket : jobBuckets) { + // submit the executions to the executor pool + for (ProcessExecutionTask bucket : executionBuckets) { Future future = pool.submit(bucket); results.add(future); } - if (jobBuckets.size() > 0) { - logger.info("Populated thread pool[{}] with {} batches", config.getThreadCount(), jobBuckets.size()); + if (executionBuckets.size() > 0) { + logger.info("Populated thread pool[{}] with {} batches", config.getThreadCount(), executionBuckets.size()); } // process any results that have come in @@ -210,13 +210,13 @@ public void run() { ArrayNode arr = (ArrayNode) jsonNodeFuture.get(); arr.forEach(jsonNode -> { total.getAndIncrement(); - String jobUri = jsonNode.get("job").asText(); - inProgressSet.remove(jobUri); + String executionUri = jsonNode.get("execution").asText(); + inProgressSet.remove(executionUri); boolean hasError = jsonNode.get("error") != null; if (hasError) errorCount.incrementAndGet(); }); - logger.info("batch result: {} jobs complete - with {} errors", arr.size(), errorCount.get()); + logger.info("batch result: {} executions complete - with {} errors", arr.size(), errorCount.get()); totalErrors.addAndGet(errorCount.get()); completed.add(jsonNodeFuture); } catch (Exception e) { @@ -240,8 +240,8 @@ public void run() { // initiate a thread shutdown pool.shutdown(); // stop fetching tasks - logger.info("Stopping GetJobsTask thread..."); - getJobsTask.interrupt(); + logger.info("Stopping GetExecutionsTask thread..."); + getExecutionsTask.interrupt(); metricsThread.interrupt(); // stop main loop keepRunning = false; diff --git a/state-conductor-dataservices/src/main/java/com/marklogic/StateConductorService.java b/state-conductor-dataservices/src/main/java/com/marklogic/StateConductorService.java index d3019db0..a37e840f 100644 --- a/state-conductor-dataservices/src/main/java/com/marklogic/StateConductorService.java +++ b/state-conductor-dataservices/src/main/java/com/marklogic/StateConductorService.java @@ -34,16 +34,28 @@ private StateConductorServiceImpl(DatabaseClient dbClient) { } @Override - public Stream getJobs(Integer start, Integer count, String flowNames, Stream flowStatus, Stream forestIds, String startDate, String endDate) { + public void deleteStateMachine(String name) { + baseProxy + .request("deleteStateMachine.sjs", BaseProxy.ParameterValuesKind.SINGLE_ATOMIC) + .withSession() + .withParams( + BaseProxy.atomicParam("name", false, BaseProxy.StringType.fromString(name))) + .withMethod("POST") + .responseNone(); + } + + + @Override + public Stream getExecutions(Integer start, Integer count, String names, Stream status, Stream forestIds, String startDate, String endDate) { return BaseProxy.StringType.toString( baseProxy - .request("getJobs.sjs", BaseProxy.ParameterValuesKind.MULTIPLE_ATOMICS) + .request("getExecutions.sjs", BaseProxy.ParameterValuesKind.MULTIPLE_ATOMICS) .withSession() .withParams( BaseProxy.atomicParam("start", true, BaseProxy.UnsignedIntegerType.fromInteger(start)), BaseProxy.atomicParam("count", true, BaseProxy.UnsignedIntegerType.fromInteger(count)), - BaseProxy.atomicParam("flowNames", true, BaseProxy.StringType.fromString(flowNames)), - BaseProxy.atomicParam("flowStatus", true, BaseProxy.StringType.fromString(flowStatus)), + BaseProxy.atomicParam("names", true, BaseProxy.StringType.fromString(names)), + BaseProxy.atomicParam("status", true, BaseProxy.StringType.fromString(status)), BaseProxy.atomicParam("forestIds", true, BaseProxy.StringType.fromString(forestIds)), BaseProxy.atomicParam("startDate", true, BaseProxy.DateTimeType.fromString(startDate)), BaseProxy.atomicParam("endDate", true, BaseProxy.DateTimeType.fromString(endDate))) @@ -54,13 +66,13 @@ public Stream getJobs(Integer start, Integer count, String flowNames, St @Override - public com.fasterxml.jackson.databind.node.ObjectNode getFlow(String flowName) { + public com.fasterxml.jackson.databind.node.ObjectNode getStateMachine(String name) { return BaseProxy.ObjectType.toObjectNode( baseProxy - .request("getFlow.sjs", BaseProxy.ParameterValuesKind.SINGLE_ATOMIC) + .request("getStateMachine.sjs", BaseProxy.ParameterValuesKind.SINGLE_ATOMIC) .withSession() .withParams( - BaseProxy.atomicParam("flowName", true, BaseProxy.StringType.fromString(flowName))) + BaseProxy.atomicParam("name", true, BaseProxy.StringType.fromString(name))) .withMethod("POST") .responseSingle(false, Format.JSON) ); @@ -68,54 +80,40 @@ public com.fasterxml.jackson.databind.node.ObjectNode getFlow(String flowName) { @Override - public void deleteFlow(String flowName) { - baseProxy - .request("deleteFlow.sjs", BaseProxy.ParameterValuesKind.SINGLE_ATOMIC) - .withSession() - .withParams( - BaseProxy.atomicParam("flowName", false, BaseProxy.StringType.fromString(flowName))) - .withMethod("POST") - .responseNone(); - } - - - @Override - public String createJob(String uri, String flowName) { - return BaseProxy.StringType.toString( + public com.fasterxml.jackson.databind.node.ArrayNode processExecution(Stream uri) { + return BaseProxy.ArrayType.toArrayNode( baseProxy - .request("createJob.sjs", BaseProxy.ParameterValuesKind.MULTIPLE_ATOMICS) + .request("processExecution.sjs", BaseProxy.ParameterValuesKind.MULTIPLE_ATOMICS) .withSession() .withParams( - BaseProxy.atomicParam("uri", false, BaseProxy.StringType.fromString(uri)), - BaseProxy.atomicParam("flowName", false, BaseProxy.StringType.fromString(flowName))) + BaseProxy.atomicParam("uri", false, BaseProxy.StringType.fromString(uri))) .withMethod("POST") - .responseSingle(false, null) + .responseSingle(false, Format.JSON) ); } @Override - public com.fasterxml.jackson.databind.node.ArrayNode processJob(Stream uri) { - return BaseProxy.ArrayType.toArrayNode( - baseProxy - .request("processJob.sjs", BaseProxy.ParameterValuesKind.MULTIPLE_ATOMICS) + public void insertStateMachine(String name, Reader stateMachine) { + baseProxy + .request("insertStateMachine.sjs", BaseProxy.ParameterValuesKind.MULTIPLE_MIXED) .withSession() .withParams( - BaseProxy.atomicParam("uri", false, BaseProxy.StringType.fromString(uri))) + BaseProxy.atomicParam("name", false, BaseProxy.StringType.fromString(name)), + BaseProxy.documentParam("stateMachine", false, BaseProxy.ObjectType.fromReader(stateMachine))) .withMethod("POST") - .responseSingle(false, Format.JSON) - ); + .responseNone(); } @Override - public com.fasterxml.jackson.databind.node.ObjectNode getFlowStatus(Stream flowNames, String startDate, String endDate, Boolean detailed) { + public com.fasterxml.jackson.databind.node.ObjectNode getStateMachineStatus(Stream names, String startDate, String endDate, Boolean detailed) { return BaseProxy.ObjectType.toObjectNode( baseProxy - .request("getFlowStatus.sjs", BaseProxy.ParameterValuesKind.MULTIPLE_ATOMICS) + .request("getStateMachineStatus.sjs", BaseProxy.ParameterValuesKind.MULTIPLE_ATOMICS) .withSession() .withParams( - BaseProxy.atomicParam("flowNames", true, BaseProxy.StringType.fromString(flowNames)), + BaseProxy.atomicParam("names", true, BaseProxy.StringType.fromString(names)), BaseProxy.atomicParam("startDate", true, BaseProxy.DateTimeType.fromString(startDate)), BaseProxy.atomicParam("endDate", true, BaseProxy.DateTimeType.fromString(endDate)), BaseProxy.atomicParam("detailed", true, BaseProxy.BooleanType.fromBoolean(detailed))) @@ -126,15 +124,17 @@ public com.fasterxml.jackson.databind.node.ObjectNode getFlowStatus(Stream getJobs(Integer start, Integer count, String flowNames, Stream flowStatus, Stream forestIds, String startDate, String endDate); + void deleteStateMachine(String name); /** - * Returns a single flow if flowName is specified or all flows otherwise. + * Returns a list of MarkLogic State Conductor Execution document URIs * - * @param flowName The name of the flow to return. Pass null to return all. + * @param start Return records starting from this position. + * @param count The number of uris to return + * @param names A list of state machine names to filter the returned execution documents + * @param status A list of state machine status's to filter the returned execution documents. Defaults to 'new' and 'working'. + * @param forestIds The returned list of execution documents will be limited to executions found in this list of forests. + * @param startDate Filter on executions created after this date and time. + * @param endDate Filter on executions created prior to this date and time. * @return as output */ - com.fasterxml.jackson.databind.node.ObjectNode getFlow(String flowName); + Stream getExecutions(Integer start, Integer count, String names, Stream status, Stream forestIds, String startDate, String endDate); /** - * Deletes a single flow. + * Returns a single stateMachine if name is specified or all stateMachines otherwise. * - * @param flowName The name of the flow to be created or updated. - * + * @param name The name of the stateMachine to return. Pass null to return all. + * @return as output */ - void deleteFlow(String flowName); + com.fasterxml.jackson.databind.node.ObjectNode getStateMachine(String name); /** - * Creates a MarkLogic State Conductor Job document for the given uri and flow. + * Invokes the processing of a MarkLogic State Conductor Execution * - * @param uri The uri of a document to be processed by the flow - * @param flowName The name of the State Conductor Flow - * @return The Job ID of the State Conductor Job document + * @param uri The uri of a State Conductor Execution document to be processed + * @return as output */ - String createJob(String uri, String flowName); + com.fasterxml.jackson.databind.node.ArrayNode processExecution(Stream uri); /** - * Invokes the processing of a MarkLogic State Conductor Job + * Creates or updates a single state machine. * - * @param uri The uri of a State Conductor Job document to be processed - * @return as output + * @param name The name of the state machine to be created or updated. + * @param stateMachine The stateMachine to be created or updated. + * */ - com.fasterxml.jackson.databind.node.ArrayNode processJob(Stream uri); + void insertStateMachine(String name, Reader stateMachine); /** - * Returns the status and states of one or more State Conductor flows. + * Returns the status and states of one or more State Conductor state machines. * - * @param flowNames The flow names for which to report status. - * @param startDate Filter on jobs created after this date and time. - * @param endDate Filter on jobs created prior to this date and time. - * @param detailed Include detailed breakdown of jobs per state per status? + * @param names The state machine names for which to report status. + * @param startDate Filter on executions created after this date and time. + * @param endDate Filter on executions created prior to this date and time. + * @param detailed Include detailed breakdown of executions per state per status? * @return as output */ - com.fasterxml.jackson.databind.node.ObjectNode getFlowStatus(Stream flowNames, String startDate, String endDate, Boolean detailed); + com.fasterxml.jackson.databind.node.ObjectNode getStateMachineStatus(Stream names, String startDate, String endDate, Boolean detailed); /** - * Creates or updates a single flow. + * Creates a MarkLogic State Conductor Execution document for the given uri and state machine name. * - * @param flowName The name of the flow to be created or updated. - * @param flow The flow to be created or updated. - * + * @param uri The uri of a document to be processed by the state machine + * @param name The name of the State Machine + * @return The Execution ID of the State Conductor Execution document */ - void insertFlow(String flowName, Reader flow); + String createExecution(String uri, String name); } diff --git a/state-conductor-dataservices/src/main/java/com/marklogic/config/StateConductorDriverConfig.java b/state-conductor-dataservices/src/main/java/com/marklogic/config/StateConductorDriverConfig.java index df16f20e..50b5582a 100644 --- a/state-conductor-dataservices/src/main/java/com/marklogic/config/StateConductorDriverConfig.java +++ b/state-conductor-dataservices/src/main/java/com/marklogic/config/StateConductorDriverConfig.java @@ -21,7 +21,7 @@ public class StateConductorDriverConfig { private Integer port = 8000; private String username; private String password; - private String jobsDatabase = "state-conductor-jobs"; + private String executionsDatabase = "state-conductor-executions"; private SecurityContextType securityContextType = SecurityContextType.DIGEST; private boolean simpleSsl = false; @@ -38,8 +38,8 @@ public class StateConductorDriverConfig { private Long pollInterval = 1000L; private Long metricsInterval = 5000L; - private String flowNames; - private String flowStatus; + private String names; + private String status; private StateConductorDriverConfig() { // do nothing @@ -87,7 +87,7 @@ public static StateConductorDriverConfig newConfig(Map... proper config.port = Integer.parseInt(getPropertyValue(props, "mlPort", "8000")); config.username = getPropertyValue(props, "username", null); config.password = getPropertyValue(props, "password", null); - config.jobsDatabase = getPropertyValue(props, "jobsDatabase", "state-conductor-jobs"); + config.executionsDatabase = getPropertyValue(props, "executionsDatabase", "state-conductor-executions"); config.securityContextType = SecurityContextType.valueOf(getPropertyValue(props, "securityContextType", "basic").toUpperCase()); config.simpleSsl = Boolean.parseBoolean(getPropertyValue(props, "simpleSsl", "false")); config.externalName = getPropertyValue(props, "externalName", null); @@ -101,8 +101,8 @@ public static StateConductorDriverConfig newConfig(Map... proper config.cooldownMillis = Long.parseLong(getPropertyValue(props, "cooldownMillis", "5000")); config.pollInterval = Long.parseLong(getPropertyValue(props, "pollInterval", "1000")); config.metricsInterval = Long.parseLong(getPropertyValue(props, "metricsInterval", "5000")); - config.flowNames = getPropertyValue(props, "flowNames", null); - config.flowStatus = getPropertyValue(props, "flowStatus", null); + config.names = getPropertyValue(props, "names", null); + config.status = getPropertyValue(props, "status", null); return config; } @@ -170,12 +170,12 @@ public void setPassword(String password) { this.password = password; } - public String getJobsDatabase() { - return jobsDatabase; + public String getExecutionsDatabase() { + return executionsDatabase; } - public void setJobsDatabase(String jobsDatabase) { - this.jobsDatabase = jobsDatabase; + public void setExecutionsDatabase(String executionsDatabase) { + this.executionsDatabase = executionsDatabase; } public Integer getQueueThreshold() { @@ -206,11 +206,11 @@ public void setMetricsInterval(Long metricsInterval) { this.metricsInterval = metricsInterval; } - public String getFlowNames() { return flowNames; } + public String getStateMachineNames() { return names; } - public void setFlowNames(String flowNames) { this.flowNames = flowNames; } + public void setStateMachineNames(String names) { this.names = names; } - public String getFlowStatus() { return flowStatus; } + public String getStateMachineStatus() { return status; } - public void setFlowStatus(String flowStatus) { this.flowStatus = flowStatus; } + public void setStateMachineStatus(String status) { this.status = status; } } diff --git a/state-conductor-dataservices/src/main/java/com/marklogic/tasks/GetJobsTask.java b/state-conductor-dataservices/src/main/java/com/marklogic/tasks/GetExecutionsTask.java similarity index 51% rename from state-conductor-dataservices/src/main/java/com/marklogic/tasks/GetJobsTask.java rename to state-conductor-dataservices/src/main/java/com/marklogic/tasks/GetExecutionsTask.java index 637ef9e4..0453b140 100644 --- a/state-conductor-dataservices/src/main/java/com/marklogic/tasks/GetJobsTask.java +++ b/state-conductor-dataservices/src/main/java/com/marklogic/tasks/GetExecutionsTask.java @@ -12,41 +12,42 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Stream; -public class GetJobsTask implements Runnable { +public class GetExecutionsTask implements Runnable { - private static Logger logger = LoggerFactory.getLogger(GetJobsTask.class); + private static Logger logger = LoggerFactory.getLogger(GetExecutionsTask.class); private StateConductorDriverConfig config; private StateConductorService service; private List urisBuffer; private Set inProgressSet; - public GetJobsTask(StateConductorService service, StateConductorDriverConfig config, List urisBuffer, Set inProgressSet) { + public GetExecutionsTask(StateConductorService service, StateConductorDriverConfig config, List urisBuffer, + Set inProgressSet) { this.service = service; this.config = config; this.urisBuffer = urisBuffer; this.inProgressSet = inProgressSet; } - private Stream FetchJobDocuments(int start) { - Stream jobUris = null; - Stream flowStatus = null; + private Stream FetchExecutionDocuments(int start) { + Stream executionUris = null; + Stream status = null; - if (config.getFlowStatus() != null) { - String[] status = config.getFlowStatus().split(","); - flowStatus = Arrays.stream(status); + if (config.getStateMachineStatus() != null) { + String[] statusArray = config.getStateMachineStatus().split(","); + status = Arrays.stream(statusArray); } try { - logger.info("Fetching Jobs Batch..."); - jobUris = service.getJobs(start, config.getPollSize(), config.getFlowNames(), flowStatus, null, null, null); + logger.info("Fetching Executions Batch..."); + executionUris = service.getExecutions(start, config.getPollSize(), config.getStateMachineNames(), status, null, null, null); } catch (Exception ex) { - logger.error("An error occurred fetching job documents: {}", ex.getMessage()); + logger.error("An error occurred fetching execution documents: {}", ex.getMessage()); ex.printStackTrace(); - jobUris = Stream.empty(); + executionUris = Stream.empty(); } - return jobUris; + return executionUris; } @Override @@ -61,35 +62,35 @@ public void run() { totalFetched.set(0); if (inProgressSet.size() < config.getQueueThreshold()) { - // grab job documents if we're below the queue threshold - Stream jobUris = FetchJobDocuments(start); - Iterator jobs = jobUris.iterator(); + // grab execution documents if we're below the queue threshold + Stream executionUris = FetchExecutionDocuments(start); + Iterator executions = executionUris.iterator(); synchronized (urisBuffer) { - while(jobs.hasNext()) { - String jobUri = jobs.next(); + while(executions.hasNext()) { + String executionUri = executions.next(); totalFetched.getAndIncrement(); - if (!inProgressSet.contains(jobUri)) { + if (!inProgressSet.contains(executionUri)) { totalNew.getAndIncrement(); - urisBuffer.add(jobUri); - inProgressSet.add(jobUri); + urisBuffer.add(executionUri); + inProgressSet.add(executionUri); } else { - logger.trace("got already in-progress job {}", jobUri); + logger.trace("got already in-progress execution {}", executionUri); } } } if (totalFetched.get() != totalNew.get()) { - logger.info("GetJobsTask got {} new jobs, out of {} total", totalNew.get(), totalFetched.get()); + logger.info("GetExecutionsTask got {} new executions, out of {} total", totalNew.get(), totalFetched.get()); } else { - logger.info("GetJobsTask got {} new jobs", totalNew.get()); + logger.info("GetExecutionsTask got {} new executions", totalNew.get()); } if (logger.isDebugEnabled()) logger.debug("in progress queue size: {}", inProgressSet.size()); } else { - logger.info("Queued jobs limit reached!"); + logger.info("Queued executions limit reached!"); } try { @@ -97,21 +98,21 @@ public void run() { // request next page start += config.getPollSize(); emptyCount = 0; - logger.debug("GetJobsTask requesting next page..."); + logger.debug("GetExecutionsTask requesting next page..."); Thread.sleep(10L); } else { start = 1; emptyCount = (totalNew.get() == 0) ? emptyCount + 1 : 0; if (emptyCount > 3) { - logger.debug("GetJobsTask cooldown..."); + logger.debug("GetExecutionsTask cooldown..."); Thread.sleep(config.getCooldownMillis()); } else { Thread.sleep(config.getPollInterval()); } } } catch (InterruptedException e) { - logger.info("Stopping GetJobsTask Thread..."); + logger.info("Stopping GetExecutionsTask Thread..."); Thread.currentThread().interrupt(); break; } diff --git a/state-conductor-dataservices/src/main/java/com/marklogic/tasks/ProcessExecutionTask.java b/state-conductor-dataservices/src/main/java/com/marklogic/tasks/ProcessExecutionTask.java new file mode 100644 index 00000000..70ee9e0a --- /dev/null +++ b/state-conductor-dataservices/src/main/java/com/marklogic/tasks/ProcessExecutionTask.java @@ -0,0 +1,33 @@ +package com.marklogic.tasks; + +import com.fasterxml.jackson.databind.JsonNode; +import com.marklogic.StateConductorService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.concurrent.Callable; + +public class ProcessExecutionTask implements Callable { + + Logger logger = LoggerFactory.getLogger(ProcessExecutionTask.class); + + private Long id; + private StateConductorService service; + private List executionUris; + + public ProcessExecutionTask(Long id, StateConductorService service, List executionUris) { + this.id = id; + this.service = service; + this.executionUris = executionUris; + } + + @Override + public JsonNode call() throws Exception { + logger.info("processing batch execution: {} [size: {}]", id, executionUris.size()); + if (logger.isDebugEnabled()) { + logger.debug("uris: {}", executionUris.toString()); + } + return service.processExecution(executionUris.stream()); + } +} diff --git a/state-conductor-dataservices/src/main/java/com/marklogic/tasks/ProcessJobTask.java b/state-conductor-dataservices/src/main/java/com/marklogic/tasks/ProcessJobTask.java deleted file mode 100644 index e5390143..00000000 --- a/state-conductor-dataservices/src/main/java/com/marklogic/tasks/ProcessJobTask.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.marklogic.tasks; - -import com.fasterxml.jackson.databind.JsonNode; -import com.marklogic.StateConductorService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; -import java.util.concurrent.Callable; - -public class ProcessJobTask implements Callable { - - Logger logger = LoggerFactory.getLogger(ProcessJobTask.class); - - private Long id; - private StateConductorService service; - private List jobUris; - - public ProcessJobTask(Long id, StateConductorService service, List jobUris) { - this.id = id; - this.service = service; - this.jobUris = jobUris; - } - - @Override - public JsonNode call() throws Exception { - logger.info("processing batch job: {} [size: {}]", id, jobUris.size()); - if (logger.isDebugEnabled()) { - logger.debug("uris: {}", jobUris.toString()); - } - return service.processJob(jobUris.stream()); - } -} diff --git a/state-conductor-dataservices/src/main/resources/logback.xml b/state-conductor-dataservices/src/main/resources/logback.xml index 55a3739c..3f00633d 100644 --- a/state-conductor-dataservices/src/main/resources/logback.xml +++ b/state-conductor-dataservices/src/main/resources/logback.xml @@ -16,7 +16,7 @@ - + diff --git a/state-conductor-dataservices/src/test/java/com/marklogic/StateConductorJob.java b/state-conductor-dataservices/src/test/java/com/marklogic/StateConductorExecution.java similarity index 74% rename from state-conductor-dataservices/src/test/java/com/marklogic/StateConductorJob.java rename to state-conductor-dataservices/src/test/java/com/marklogic/StateConductorExecution.java index 6790f39a..534b1d86 100644 --- a/state-conductor-dataservices/src/test/java/com/marklogic/StateConductorJob.java +++ b/state-conductor-dataservices/src/test/java/com/marklogic/StateConductorExecution.java @@ -4,12 +4,12 @@ import java.util.Arrays; -public class StateConductorJob { +public class StateConductorExecution { private String id; - private String flowName; - private String flowStatus; - private String flowState; + private String name; + private String status; + private String state; private String uri; private String database; private String modules; @@ -27,28 +27,28 @@ public void setId(String id) { this.id = id; } - public String getFlowName() { - return flowName; + public String getName() { + return name; } - public void setFlowName(String flowName) { - this.flowName = flowName; + public void setName(String name) { + this.name = name; } - public String getFlowStatus() { - return flowStatus; + public String getStatus() { + return status; } - public void setFlowStatus(String flowStatus) { - this.flowStatus = flowStatus; + public void setStatus(String status) { + this.status = status; } - public String getFlowState() { - return flowState; + public String getState() { + return state; } - public void setFlowState(String flowState) { - this.flowState = flowState; + public void setState(String state) { + this.state = state; } public String getUri() { @@ -117,11 +117,11 @@ public void setRetries(JsonNode retries) { @Override public String toString() { - return "StateConductorJob{" + + return "StateConductorExecution{" + "id='" + id + '\'' + - ", flowName='" + flowName + '\'' + - ", flowStatus='" + flowStatus + '\'' + - ", flowState='" + flowState + '\'' + + ", name='" + name + '\'' + + ", status='" + status + '\'' + + ", state='" + state + '\'' + ", uri='" + uri + '\'' + ", database='" + database + '\'' + ", modules='" + modules + '\'' + diff --git a/state-conductor-dataservices/src/test/java/com/marklogic/StateConductorServiceMock.java b/state-conductor-dataservices/src/test/java/com/marklogic/StateConductorServiceMock.java index 97c707eb..da53f62b 100644 --- a/state-conductor-dataservices/src/test/java/com/marklogic/StateConductorServiceMock.java +++ b/state-conductor-dataservices/src/test/java/com/marklogic/StateConductorServiceMock.java @@ -10,7 +10,7 @@ public class StateConductorServiceMock implements StateConductorService { @Override - public Stream getJobs(Integer start, Integer count, String flowNames, Stream flowStatus, + public Stream getExecutions(Integer start, Integer count, String names, Stream status, Stream forestIds, String startDate, String endDate) { List uris = new ArrayList<>(); for (int i = 1; i <= count; i++) { @@ -20,17 +20,17 @@ public Stream getJobs(Integer start, Integer count, String flowNames, St } @Override - public String createJob(String uri, String flowName) { + public String createExecution(String uri, String name) { return UUID.randomUUID().toString(); } @Override - public ArrayNode processJob(Stream uri) { + public ArrayNode processExecution(Stream uri) { ArrayNode arr = new ArrayNode(JsonNodeFactory.instance); uri.forEach(value -> { Map vals = new HashMap<>(); - vals.put("job", new TextNode(value)); + vals.put("execution", new TextNode(value)); vals.put("result", BooleanNode.getTrue()); arr.add(new ObjectNode(JsonNodeFactory.instance, vals)); }); @@ -39,22 +39,22 @@ public ArrayNode processJob(Stream uri) { } @Override - public ObjectNode getFlowStatus(Stream flowNames, String startDate, String endDate, Boolean detailed) { + public ObjectNode getStateMachineStatus(Stream names, String startDate, String endDate, Boolean detailed) { ObjectNode obj = new ObjectNode(JsonNodeFactory.instance); - flowNames.forEach(flowName -> { - ObjectNode flowStatus = new ObjectNode(JsonNodeFactory.instance); - flowStatus.put("flowName", flowName); - flowStatus.put("totalPerStatus", ""); - flowStatus.put("totalPerState", ""); - obj.set(flowName, flowStatus); + names.forEach(name -> { + ObjectNode status = new ObjectNode(JsonNodeFactory.instance); + status.put("name", name); + status.put("totalPerStatus", ""); + status.put("totalPerState", ""); + obj.set(name, status); }); return obj; } @Override - public com.fasterxml.jackson.databind.node.ObjectNode getFlow(String flowName) { + public com.fasterxml.jackson.databind.node.ObjectNode getStateMachine(String name) { // TODO Auto-generated method stub ObjectNode obj = new ObjectNode(JsonNodeFactory.instance); @@ -62,13 +62,13 @@ public com.fasterxml.jackson.databind.node.ObjectNode getFlow(String flowName) { } @Override - public void deleteFlow(String flowName) { + public void deleteStateMachine(String name) { // TODO Auto-generated method stub } @Override - public void insertFlow(String flowName, Reader flow) { + public void insertStateMachine(String name, Reader stateMachine) { // TODO Auto-generated method stub } diff --git a/state-conductor-dataservices/src/test/java/com/marklogic/StateConductorServiceTest.java b/state-conductor-dataservices/src/test/java/com/marklogic/StateConductorServiceTest.java index 2ddd4ab1..a23684ed 100644 --- a/state-conductor-dataservices/src/test/java/com/marklogic/StateConductorServiceTest.java +++ b/state-conductor-dataservices/src/test/java/com/marklogic/StateConductorServiceTest.java @@ -1,17 +1,10 @@ package com.marklogic; -import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeType; import com.fasterxml.jackson.databind.node.ObjectNode; import com.marklogic.client.FailedRequestException; -import com.marklogic.client.datamovement.DataMovementManager; -import com.marklogic.client.datamovement.DeleteListener; -import com.marklogic.client.datamovement.QueryBatcher; import com.marklogic.client.document.DocumentWriteSet; import com.marklogic.client.io.DocumentMetadataHandle; -import com.marklogic.client.query.StructuredQueryBuilder; -import com.marklogic.client.query.StructuredQueryDefinition; import com.marklogic.ext.AbstractStateConductorTest; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -33,12 +26,12 @@ public class StateConductorServiceTest extends AbstractStateConductorTest { final String data1Uri = "/test/doc1.json"; final String data2Uri = "/test/doc2.json"; - final String job1Uri = "/test/stateConductorJob/job1.json"; - final String job2Uri = "/test/stateConductorJob/job2.json"; - final String job3Uri = "/test/stateConductorJob/job3.json"; - final String job4Uri = "/test/stateConductorJob/job4.json"; - final String job5Uri = "/test/stateConductorJob/job5.json"; - final String badJob1Uri = "/test/stateConductorJob/badJob1.json"; + final String execution1Uri = "/test/stateConductorExecution/execution1.json"; + final String execution2Uri = "/test/stateConductorExecution/execution2.json"; + final String execution3Uri = "/test/stateConductorExecution/execution3.json"; + final String execution4Uri = "/test/stateConductorExecution/execution4.json"; + final String execution5Uri = "/test/stateConductorExecution/execution5.json"; + final String badExecution1Uri = "/test/stateConductorExecution/badExecution1.json"; StateConductorService mockService; StateConductorService service; @@ -54,19 +47,19 @@ public void setup() throws IOException { tokens.put("%DATABASE%", getContentDatabaseId()); tokens.put("%MODULES%", getModulesDatabaseId()); - // add job docs - DocumentWriteSet batch = getJobsManager().newWriteSet(); - DocumentMetadataHandle jobMeta = new DocumentMetadataHandle(); - jobMeta.getCollections().addAll("stateConductorJob", "test"); - jobMeta.getPermissions().add("state-conductor-reader-role", DocumentMetadataHandle.Capability.READ); - jobMeta.getPermissions().add("state-conductor-job-writer-role", DocumentMetadataHandle.Capability.UPDATE); - batch.add("/test/stateConductorJob/job1.json", jobMeta, loadTokenizedResource("jobs/job1.json", tokens)); - batch.add("/test/stateConductorJob/job2.json", jobMeta, loadTokenizedResource("jobs/job2.json", tokens)); - batch.add("/test/stateConductorJob/job3.json", jobMeta, loadTokenizedResource("jobs/job3.json", tokens)); - batch.add("/test/stateConductorJob/job4.json", jobMeta, loadTokenizedResource("jobs/job4.json", tokens)); - batch.add("/test/stateConductorJob/job5.json", jobMeta, loadTokenizedResource("jobs/job5.json", tokens)); - batch.add("/test/stateConductorJob/badJob1.json", jobMeta, loadTokenizedResource("jobs/badJob1.json", tokens)); - getJobsManager().write(batch); + // add execution docs + DocumentWriteSet batch = getExecutionsManager().newWriteSet(); + DocumentMetadataHandle executionMeta = new DocumentMetadataHandle(); + executionMeta.getCollections().addAll("stateConductorExecution", "test"); + executionMeta.getPermissions().add("state-conductor-reader-role", DocumentMetadataHandle.Capability.READ); + executionMeta.getPermissions().add("state-conductor-execution-writer-role", DocumentMetadataHandle.Capability.UPDATE); + batch.add("/test/stateConductorExecution/execution1.json", executionMeta, loadTokenizedResource("executions/execution1.json", tokens)); + batch.add("/test/stateConductorExecution/execution2.json", executionMeta, loadTokenizedResource("executions/execution2.json", tokens)); + batch.add("/test/stateConductorExecution/execution3.json", executionMeta, loadTokenizedResource("executions/execution3.json", tokens)); + batch.add("/test/stateConductorExecution/execution4.json", executionMeta, loadTokenizedResource("executions/execution4.json", tokens)); + batch.add("/test/stateConductorExecution/execution5.json", executionMeta, loadTokenizedResource("executions/execution5.json", tokens)); + batch.add("/test/stateConductorExecution/badExecution1.json", executionMeta, loadTokenizedResource("executions/badExecution1.json", tokens)); + getExecutionsManager().write(batch); // add data docs batch = getContentManager().newWriteSet(); @@ -74,23 +67,23 @@ public void setup() throws IOException { batch.add("/test/doc2.json", loadFileResource("data/doc2.json")); getContentManager().write(batch); - // add flow docs - DocumentMetadataHandle flowMeta = new DocumentMetadataHandle(); - flowMeta.getCollections().add("state-conductor-flow"); + // add state machine docs + DocumentMetadataHandle meta = new DocumentMetadataHandle(); + meta.getCollections().add("state-conductor-state-machine"); batch = getContentManager().newWriteSet(); - batch.add("/state-conductor-flow/test-flow.asl.json", flowMeta, loadFileResource("flows/test-flow.asl.json")); + batch.add("/state-conductor-state-machine/test-state-machine.asl.json", meta, loadFileResource("stateMachines/test-state-machine.asl.json")); getContentManager().write(batch); } @AfterEach public void teardown() { - deleteCollections(getJobsDatabaseClient(), "test"); + deleteCollections(getExecutionsDatabaseClient(), "test"); } @Test - public void testGetJobsMock() { + public void testGetExecutionsMock() { int count = 10; - Object[] uris = mockService.getJobs(1, count, null, null, null, null, null).toArray(); + Object[] uris = mockService.getExecutions(1, count, null, null, null, null, null).toArray(); assertEquals(count, uris.length); assertEquals("/test/test1.json", uris[0].toString()); assertEquals("/test/test2.json", uris[1].toString()); @@ -98,15 +91,15 @@ public void testGetJobsMock() { } @Test - public void testGetFlow() throws IOException { - final String flowName = "test-flow"; - final ObjectNode allFlows = service.getFlow(null); - assertEquals("does things", allFlows.get(flowName).get("Comment").asText()); - final ObjectNode testFlow = service.getFlow(flowName); - assertEquals("does things", testFlow.get("Comment").asText()); + public void testGetStateMachine() throws IOException { + final String stateMachineName = "test-state-machine"; + final ObjectNode allStateMachines = service.getStateMachine(null); + assertEquals("does things", allStateMachines.get(stateMachineName).get("Comment").asText()); + final ObjectNode testStateMachine = service.getStateMachine(stateMachineName); + assertEquals("does things", testStateMachine.get("Comment").asText()); try { - service.getFlow("test-flow-that-does-not-exist"); - assertTrue(false, "Failed to throw exception for bad flowName"); + service.getStateMachine("test-state-machine-that-does-not-exist"); + assertTrue(false, "Failed to throw exception for bad stateMachineName"); } catch(Exception e) { assertTrue(true); @@ -114,27 +107,28 @@ public void testGetFlow() throws IOException { } @Test - public void testInsertFlow() throws IOException { - final String flowName = "test-flow"; - final ObjectNode testFlow = service.getFlow(flowName); - assertEquals("does things", testFlow.get("Comment").asText()); - testFlow.put("Comment", "Also Does Other Things"); - service.insertFlow(flowName, new StringReader(testFlow.toString())); - final ObjectNode updatedTestFlow = service.getFlow(flowName); - assertEquals("Also Does Other Things", testFlow.get("Comment").asText()); + public void testInsertStateMachine() throws IOException { + final String stateMachineName = "test-state-machine"; + final ObjectNode testStateMachine = service.getStateMachine(stateMachineName); + assertEquals("does things", testStateMachine.get("Comment").asText()); + testStateMachine.put("Comment", "Also Does Other Things"); + service.insertStateMachine(stateMachineName, new StringReader(testStateMachine.toString())); + final ObjectNode updatedTestStateMachine = service.getStateMachine(stateMachineName); + assertNotNull(updatedTestStateMachine); + assertEquals("Also Does Other Things", testStateMachine.get("Comment").asText()); } @Test - public void testDeleteFlow() throws IOException { - final String newFlowName = "new-test-flow"; - final String flowName = "test-flow"; - service.insertFlow(newFlowName, new StringReader(service.getFlow(flowName).toString())); - final ObjectNode updatedTestFlow = service.getFlow(flowName); - assertEquals("does things", updatedTestFlow.get("Comment").asText()); - service.deleteFlow(newFlowName); + public void testDeleteStateMachine() throws IOException { + final String newName = "new-test-state-machine"; + final String stateMachineName = "test-state-machine"; + service.insertStateMachine(newName, new StringReader(service.getStateMachine(stateMachineName).toString())); + final ObjectNode updatedTestStateMachine = service.getStateMachine(stateMachineName); + assertEquals("does things", updatedTestStateMachine.get("Comment").asText()); + service.deleteStateMachine(newName); try { - service.getFlow(newFlowName); - assertTrue(false, "Failed to delete newFlowName"); + service.getStateMachine(newName); + assertTrue(false, "Failed to delete newName"); } catch(Exception e) { assertTrue(true); @@ -142,212 +136,210 @@ public void testDeleteFlow() throws IOException { } @Test - public void testGetJobs() throws IOException { + public void testGetExecutions() throws IOException { int count = 10; String[] status; String[] uris; - StateConductorJob jobDoc; - uris = service.getJobs(1, 1000, null, null, null, null, null).toArray(String[]::new); + uris = service.getExecutions(1, 1000, null, null, null, null, null).toArray(String[]::new); assertTrue(3 <= uris.length); for (int i = 0; i < uris.length; i++) { - String flowStatus = getJobDocument(uris[i]).getFlowStatus(); - assertTrue((flowStatus.equals("new") || flowStatus.equals("working"))); + String stateMachineStatus = getExecutionDocument(uris[i]).getStatus(); + assertTrue((stateMachineStatus.equals("new") || stateMachineStatus.equals("working"))); } status = new String[]{ "new" }; - uris = service.getJobs(1, count, null, Arrays.stream(status), null, null, null).toArray(String[]::new); + uris = service.getExecutions(1, count, null, Arrays.stream(status), null, null, null).toArray(String[]::new); assertTrue(2 <= uris.length); for (int i = 0; i < uris.length; i++) { - assertEquals("new", getJobDocument(uris[i]).getFlowStatus()); + assertEquals("new", getExecutionDocument(uris[i]).getStatus()); } status = new String[]{ "new" }; - uris = service.getJobs(1, count, "test-flow", Arrays.stream(status), null, null, null).toArray(String[]::new); + uris = service.getExecutions(1, count, "test-state-machine", Arrays.stream(status), null, null, null).toArray(String[]::new); assertTrue(2 <= uris.length); for (int i = 0; i < uris.length; i++) { - assertEquals("new", getJobDocument(uris[i]).getFlowStatus()); - assertEquals("test-flow", getJobDocument(uris[i]).getFlowName()); + assertEquals("new", getExecutionDocument(uris[i]).getStatus()); + assertEquals("test-state-machine", getExecutionDocument(uris[i]).getName()); } status = new String[]{ "working" }; - uris = service.getJobs(1, count, "test-flow", Arrays.stream(status), null, null, null).toArray(String[]::new); + uris = service.getExecutions(1, count, "test-state-machine", Arrays.stream(status), null, null, null).toArray(String[]::new); assertEquals(1, uris.length); - assertEquals("working", getJobDocument(uris[0]).getFlowStatus()); - assertEquals("test-flow", getJobDocument(uris[0]).getFlowName()); - assertEquals("job3", getJobDocument(uris[0]).getId()); + assertEquals("working", getExecutionDocument(uris[0]).getStatus()); + assertEquals("test-state-machine", getExecutionDocument(uris[0]).getName()); + assertEquals("execution3", getExecutionDocument(uris[0]).getId()); status = new String[]{ "complete" }; - uris = service.getJobs(1, count, "test-flow", Arrays.stream(status), null, null, null).toArray(String[]::new); + uris = service.getExecutions(1, count, "test-state-machine", Arrays.stream(status), null, null, null).toArray(String[]::new); assertEquals(1, uris.length); - assertEquals("complete", getJobDocument(uris[0]).getFlowStatus()); - assertEquals("test-flow", getJobDocument(uris[0]).getFlowName()); - assertEquals("job4", getJobDocument(uris[0]).getId()); + assertEquals("complete", getExecutionDocument(uris[0]).getStatus()); + assertEquals("test-state-machine", getExecutionDocument(uris[0]).getName()); + assertEquals("execution4", getExecutionDocument(uris[0]).getId()); status = new String[]{ "failed" }; - uris = service.getJobs(1, count, "test-flow", Arrays.stream(status), null, null, null).toArray(String[]::new); + uris = service.getExecutions(1, count, "test-state-machine", Arrays.stream(status), null, null, null).toArray(String[]::new); assertEquals(1, uris.length); - assertEquals("failed", getJobDocument(uris[0]).getFlowStatus()); - assertEquals("test-flow", getJobDocument(uris[0]).getFlowName()); - assertEquals("job5", getJobDocument(uris[0]).getId()); + assertEquals("failed", getExecutionDocument(uris[0]).getStatus()); + assertEquals("test-state-machine", getExecutionDocument(uris[0]).getName()); + assertEquals("execution5", getExecutionDocument(uris[0]).getId()); status = new String[]{ "complete", "failed" }; - uris = service.getJobs(1, count, "test-flow", Arrays.stream(status), null, null, null).toArray(String[]::new); + uris = service.getExecutions(1, count, "test-state-machine", Arrays.stream(status), null, null, null).toArray(String[]::new); assertTrue(2 <= uris.length); for (int i = 0; i < uris.length; i++) { - String flowStatus = getJobDocument(uris[i]).getFlowStatus(); - assertTrue((flowStatus.equals("complete") || flowStatus.equals("failed"))); - assertEquals("test-flow", getJobDocument(uris[i]).getFlowName()); + String stateMachineStatus = getExecutionDocument(uris[i]).getStatus(); + assertTrue((stateMachineStatus.equals("complete") || stateMachineStatus.equals("failed"))); + assertEquals("test-state-machine", getExecutionDocument(uris[i]).getName()); } - uris = service.getJobs(1, count, "fake-flow", null, null, null, null).toArray(String[]::new); + uris = service.getExecutions(1, count, "fake-state-machine", null, null, null, null).toArray(String[]::new); assertEquals(0, uris.length); } @Test - public void testCreateJobMock() { - String resp = mockService.createJob(data2Uri, "test-flow"); + public void testCreateExecutionMock() { + String resp = mockService.createExecution(data2Uri, "test-state-machine"); assertTrue(resp.length() > 0); } @Test - public void testCreateJob() throws IOException { - String resp = service.createJob(data2Uri, "test-flow"); + public void testCreateExecution() throws IOException { + String resp = service.createExecution(data2Uri, "test-state-machine"); assertTrue(resp.length() > 0); - StateConductorJob jobDoc = getJobDocument("/stateConductorJob/" + resp + ".json"); - assertTrue(jobDoc != null); - assertEquals(resp, jobDoc.getId()); - assertEquals(data2Uri, jobDoc.getUri()); - assertEquals("test-flow", jobDoc.getFlowName()); + StateConductorExecution executionDoc = getExecutionDocument("/stateConductorExecution/" + resp + ".json"); + assertTrue(executionDoc != null); + assertEquals(resp, executionDoc.getId()); + assertEquals(data2Uri, executionDoc.getUri()); + assertEquals("test-state-machine", executionDoc.getName()); assertThrows(FailedRequestException.class, () -> { - service.createJob("/my/fake/document.json", "test-flow"); + service.createExecution("/my/fake/document.json", "test-state-machine"); }); assertThrows(FailedRequestException.class, () -> { - service.createJob(data2Uri, "my-fake-flow"); + service.createExecution(data2Uri, "my-fake-state-machine"); }); } @Test - public void testProcessJobMock() { - ArrayNode resp = mockService.processJob(Arrays.stream(new String[]{"/test.json"})); - assertEquals("/test.json", resp.get(0).get("job").asText()); + public void testProcessExecutionMock() { + ArrayNode resp = mockService.processExecution(Arrays.stream(new String[]{"/test.json"})); + assertEquals("/test.json", resp.get(0).get("execution").asText()); assertEquals(true, resp.get(0).get("result").asBoolean()); } @Test - public void testProcessJob() throws IOException { + public void testProcessExecution() throws IOException { ArrayNode resp; DocumentMetadataHandle meta = new DocumentMetadataHandle(); - StateConductorJob job1Doc; + StateConductorExecution execution1Doc; - // start job 1 - resp = service.processJob(Arrays.stream(new String[]{job1Uri})); - job1Doc = getJobDocument(job1Uri); + // start execution 1 + resp = service.processExecution(Arrays.stream(new String[]{execution1Uri})); + execution1Doc = getExecutionDocument(execution1Uri); getContentManager().readMetadata(data1Uri, meta); - assertEquals(job1Uri, resp.get(0).get("job").asText()); + assertEquals(execution1Uri, resp.get(0).get("execution").asText()); assertEquals(true, resp.get(0).get("result").asBoolean()); assertEquals(false, meta.getCollections().contains("testcol1")); assertEquals(false, meta.getCollections().contains("testcol2")); - assertEquals("test-flow", job1Doc.getFlowName()); - assertEquals("working", job1Doc.getFlowStatus()); - assertEquals("add-collection-1", job1Doc.getFlowState()); - // continue job 1 - resp = service.processJob(Arrays.stream(new String[]{job1Uri})); - job1Doc = getJobDocument(job1Uri); + assertEquals("test-state-machine", execution1Doc.getName()); + assertEquals("working", execution1Doc.getStatus()); + assertEquals("add-collection-1", execution1Doc.getState()); + // continue execution 1 + resp = service.processExecution(Arrays.stream(new String[]{execution1Uri})); + execution1Doc = getExecutionDocument(execution1Uri); getContentManager().readMetadata(data1Uri, meta); - assertEquals(job1Uri, resp.get(0).get("job").asText()); + assertEquals(execution1Uri, resp.get(0).get("execution").asText()); assertEquals(true, resp.get(0).get("result").asBoolean()); assertEquals(true, meta.getCollections().contains("testcol1")); assertEquals(false, meta.getCollections().contains("testcol2")); - assertEquals("test-flow", job1Doc.getFlowName()); - assertEquals("working", job1Doc.getFlowStatus()); - assertEquals("add-collection-2", job1Doc.getFlowState()); - // continue job 1 - resp = service.processJob(Arrays.stream(new String[]{job1Uri})); - job1Doc = getJobDocument(job1Uri); + assertEquals("test-state-machine", execution1Doc.getName()); + assertEquals("working", execution1Doc.getStatus()); + assertEquals("add-collection-2", execution1Doc.getState()); + // continue execution 1 + resp = service.processExecution(Arrays.stream(new String[]{execution1Uri})); + execution1Doc = getExecutionDocument(execution1Uri); getContentManager().readMetadata(data1Uri, meta); - assertEquals(job1Uri, resp.get(0).get("job").asText()); + assertEquals(execution1Uri, resp.get(0).get("execution").asText()); assertEquals(true, resp.get(0).get("result").asBoolean()); assertEquals(true, meta.getCollections().contains("testcol1")); assertEquals(true, meta.getCollections().contains("testcol2")); - assertEquals("test-flow", job1Doc.getFlowName()); - assertEquals("working", job1Doc.getFlowStatus()); - assertEquals("success", job1Doc.getFlowState()); - // continue job 1 - resp = service.processJob(Arrays.stream(new String[]{job1Uri})); - job1Doc = getJobDocument(job1Uri); - assertEquals(job1Uri, resp.get(0).get("job").asText()); + assertEquals("test-state-machine", execution1Doc.getName()); + assertEquals("working", execution1Doc.getStatus()); + assertEquals("success", execution1Doc.getState()); + // continue execution 1 + resp = service.processExecution(Arrays.stream(new String[]{execution1Uri})); + execution1Doc = getExecutionDocument(execution1Uri); + assertEquals(execution1Uri, resp.get(0).get("execution").asText()); assertEquals(true, resp.get(0).get("result").asBoolean()); - assertEquals("test-flow", job1Doc.getFlowName()); - assertEquals("complete", job1Doc.getFlowStatus()); - assertEquals("success", job1Doc.getFlowState()); - // end job 1 - resp = service.processJob(Arrays.stream(new String[]{job1Uri})); - job1Doc = getJobDocument(job1Uri); - assertEquals(job1Uri, resp.get(0).get("job").asText()); + assertEquals("test-state-machine", execution1Doc.getName()); + assertEquals("complete", execution1Doc.getStatus()); + assertEquals("success", execution1Doc.getState()); + // end execution 1 + resp = service.processExecution(Arrays.stream(new String[]{execution1Uri})); + execution1Doc = getExecutionDocument(execution1Uri); + assertEquals(execution1Uri, resp.get(0).get("execution").asText()); assertEquals(false, resp.get(0).get("result").asBoolean()); - assertEquals("test-flow", job1Doc.getFlowName()); - assertEquals("complete", job1Doc.getFlowStatus()); - assertEquals("success", job1Doc.getFlowState()); + assertEquals("test-state-machine", execution1Doc.getName()); + assertEquals("complete", execution1Doc.getStatus()); + assertEquals("success", execution1Doc.getState()); } @Test - public void testBatchProcessJob() throws IOException { + public void testBatchProcessExecution() throws IOException { ArrayNode resp; - DocumentMetadataHandle meta = new DocumentMetadataHandle(); - String[] jobs = new String[] {job1Uri, job2Uri, job3Uri, job4Uri, job5Uri}; + String[] executions = new String[] {execution1Uri, execution2Uri, execution3Uri, execution4Uri, execution5Uri}; - // start job 1 - resp = service.processJob(Arrays.stream(jobs)); - assertEquals(job1Uri, resp.get(0).get("job").asText()); + // start execution 1 + resp = service.processExecution(Arrays.stream(executions)); + assertEquals(execution1Uri, resp.get(0).get("execution").asText()); assertEquals(true, resp.get(0).get("result").asBoolean()); - assertEquals(job2Uri, resp.get(1).get("job").asText()); + assertEquals(execution2Uri, resp.get(1).get("execution").asText()); assertEquals(true, resp.get(1).get("result").asBoolean()); - assertEquals(job3Uri, resp.get(2).get("job").asText()); + assertEquals(execution3Uri, resp.get(2).get("execution").asText()); assertEquals(true, resp.get(2).get("result").asBoolean()); - assertEquals(job4Uri, resp.get(3).get("job").asText()); + assertEquals(execution4Uri, resp.get(3).get("execution").asText()); assertEquals(false, resp.get(3).get("result").asBoolean()); - assertEquals(job5Uri, resp.get(4).get("job").asText()); + assertEquals(execution5Uri, resp.get(4).get("execution").asText()); assertEquals(false, resp.get(4).get("result").asBoolean()); } @Test - public void testProcessBadJob() throws IOException { + public void testProcessBadExecution() throws IOException { ArrayNode resp = null; Exception errorResp = null; - StateConductorJob badJob1Doc; + StateConductorExecution badExecution1Doc; try { - resp = service.processJob(Arrays.stream(new String[]{badJob1Uri})); + resp = service.processExecution(Arrays.stream(new String[]{badExecution1Uri})); } catch (Exception err) { errorResp = err; } - badJob1Doc = getJobDocument(badJob1Uri); - logger.info(badJob1Doc.toString()); + badExecution1Doc = getExecutionDocument(badExecution1Uri); + logger.info(badExecution1Doc.toString()); assertEquals(null, errorResp); assertNotNull(resp); - assertEquals("missing-flow", badJob1Doc.getFlowName()); - assertEquals("failed", badJob1Doc.getFlowStatus()); + assertEquals("missing-state-machine", badExecution1Doc.getName()); + assertEquals("failed", badExecution1Doc.getStatus()); } @Test - public void testBatchProcessWithBadJob() throws IOException { + public void testBatchProcessWithBadExecution() throws IOException { ArrayNode resp = null; Exception errorResp = null; - StateConductorJob jobDoc = null; + StateConductorExecution executionDoc = null; DocumentMetadataHandle meta = new DocumentMetadataHandle(); - String[] jobs = new String[] {job1Uri, job2Uri, badJob1Uri, job3Uri}; + String[] executions = new String[] {execution1Uri, execution2Uri, badExecution1Uri, execution3Uri}; - // this batch contains a job that will fail + // this batch contains a execution that will fail try { - resp = service.processJob(Arrays.stream(jobs)); + resp = service.processExecution(Arrays.stream(executions)); } catch (Exception ex) { errorResp = ex; } @@ -355,75 +347,75 @@ public void testBatchProcessWithBadJob() throws IOException { assertEquals(null, errorResp); assertNotNull(resp); - jobDoc = getJobDocument(job1Uri); - logger.info(jobDoc.toString()); - assertEquals("test-flow", jobDoc.getFlowName()); - assertEquals("working", jobDoc.getFlowStatus()); - assertEquals("add-collection-1", jobDoc.getFlowState()); + executionDoc = getExecutionDocument(execution1Uri); + logger.info(executionDoc.toString()); + assertEquals("test-state-machine", executionDoc.getName()); + assertEquals("working", executionDoc.getStatus()); + assertEquals("add-collection-1", executionDoc.getState()); - jobDoc = getJobDocument(job2Uri); - logger.info(jobDoc.toString()); - assertEquals("test-flow", jobDoc.getFlowName()); - assertEquals("working", jobDoc.getFlowStatus()); - assertEquals("add-collection-1", jobDoc.getFlowState()); + executionDoc = getExecutionDocument(execution2Uri); + logger.info(executionDoc.toString()); + assertEquals("test-state-machine", executionDoc.getName()); + assertEquals("working", executionDoc.getStatus()); + assertEquals("add-collection-1", executionDoc.getState()); - jobDoc = getJobDocument(job3Uri); - logger.info(jobDoc.toString()); + executionDoc = getExecutionDocument(execution3Uri); + logger.info(executionDoc.toString()); getContentManager().readMetadata(data2Uri, meta); - assertEquals("test-flow", jobDoc.getFlowName()); - assertEquals("working", jobDoc.getFlowStatus()); - assertEquals("add-collection-2", jobDoc.getFlowState()); + assertEquals("test-state-machine", executionDoc.getName()); + assertEquals("working", executionDoc.getStatus()); + assertEquals("add-collection-2", executionDoc.getState()); assertEquals(true, meta.getCollections().contains("testcol1")); - jobDoc = getJobDocument(badJob1Uri); - logger.info(jobDoc.toString()); - assertEquals("missing-flow", jobDoc.getFlowName()); - assertEquals("failed", jobDoc.getFlowStatus()); + executionDoc = getExecutionDocument(badExecution1Uri); + logger.info(executionDoc.toString()); + assertEquals("missing-state-machine", executionDoc.getName()); + assertEquals("failed", executionDoc.getStatus()); - assertEquals(job1Uri, resp.get(0).get("job").asText()); + assertEquals(execution1Uri, resp.get(0).get("execution").asText()); assertEquals(true, resp.get(0).get("result").asBoolean()); - assertEquals(job2Uri, resp.get(1).get("job").asText()); + assertEquals(execution2Uri, resp.get(1).get("execution").asText()); assertEquals(true, resp.get(1).get("result").asBoolean()); - assertEquals(badJob1Uri, resp.get(2).get("job").asText()); + assertEquals(badExecution1Uri, resp.get(2).get("execution").asText()); assertEquals(true, resp.get(2).get("result").asBoolean()); - assertEquals(job3Uri, resp.get(3).get("job").asText()); + assertEquals(execution3Uri, resp.get(3).get("execution").asText()); assertEquals(true, resp.get(3).get("result").asBoolean()); } @Test - public void testProcessFailedJob() throws IOException { - // this bad job will go into 'failed' the first time through - // the second attempt should return 'false' for the failed job + public void testProcessFailedExecution() throws IOException { + // this bad execution will go into 'failed' the first time through + // the second attempt should return 'false' for the failed execution ArrayNode resp = null; Exception errorResp = null; - StateConductorJob badJob1Doc; + StateConductorExecution badExecution1Doc; try { - resp = service.processJob(Arrays.stream(new String[]{badJob1Uri})); + resp = service.processExecution(Arrays.stream(new String[]{badExecution1Uri})); } catch (Exception err) { errorResp = err; } - badJob1Doc = getJobDocument(badJob1Uri); - logger.info(badJob1Doc.toString()); + badExecution1Doc = getExecutionDocument(badExecution1Uri); + logger.info(badExecution1Doc.toString()); assertEquals(null, errorResp); assertNotNull(resp); - assertEquals(badJob1Uri, resp.get(0).get("job").asText()); + assertEquals(badExecution1Uri, resp.get(0).get("execution").asText()); assertEquals(true, resp.get(0).get("result").asBoolean()); - assertEquals("missing-flow", badJob1Doc.getFlowName()); - assertEquals("failed", badJob1Doc.getFlowStatus()); + assertEquals("missing-state-machine", badExecution1Doc.getName()); + assertEquals("failed", badExecution1Doc.getStatus()); try { - resp = service.processJob(Arrays.stream(new String[]{badJob1Uri})); + resp = service.processExecution(Arrays.stream(new String[]{badExecution1Uri})); } catch (Exception err) { errorResp = err; } assertEquals(null, errorResp); assertNotNull(resp); - assertEquals(badJob1Uri, resp.get(0).get("job").asText()); + assertEquals(badExecution1Uri, resp.get(0).get("execution").asText()); assertEquals(false, resp.get(0).get("result").asBoolean()); } @@ -431,12 +423,11 @@ public void testProcessFailedJob() throws IOException { public void testExpectedExceptions() throws IOException { ArrayNode resp = null; Exception errorResp = null; - StateConductorJob badJob1Doc; - String[] jobs = new String[] {"/not/a/real/job1.json", "/not/a/real/job2.json"}; + String[] executions = new String[] {"/not/a/real/execution1.json", "/not/a/real/execution2.json"}; try { - resp = service.processJob(Arrays.stream(jobs)); + resp = service.processExecution(Arrays.stream(executions)); } catch (Exception err) { errorResp = err; } @@ -445,10 +436,10 @@ public void testExpectedExceptions() throws IOException { assertEquals(null, errorResp); assertNotNull(resp); - assertEquals("/not/a/real/job1.json", resp.get(0).get("job").asText()); + assertEquals("/not/a/real/execution1.json", resp.get(0).get("execution").asText()); assertEquals(false, resp.get(0).get("result").asBoolean()); assertNotNull(resp.get(0).get("error").asText()); - assertEquals("/not/a/real/job2.json", resp.get(1).get("job").asText()); + assertEquals("/not/a/real/execution2.json", resp.get(1).get("execution").asText()); assertEquals(false, resp.get(1).get("result").asBoolean()); assertNotNull(resp.get(1).get("error").asText()); } diff --git a/state-conductor-dataservices/src/test/java/com/marklogic/ext/AbstractStateConductorTest.java b/state-conductor-dataservices/src/test/java/com/marklogic/ext/AbstractStateConductorTest.java index 156050da..fde702cf 100644 --- a/state-conductor-dataservices/src/test/java/com/marklogic/ext/AbstractStateConductorTest.java +++ b/state-conductor-dataservices/src/test/java/com/marklogic/ext/AbstractStateConductorTest.java @@ -1,7 +1,7 @@ package com.marklogic.ext; import com.fasterxml.jackson.databind.ObjectMapper; -import com.marklogic.StateConductorJob; +import com.marklogic.StateConductorExecution; import com.marklogic.client.DatabaseClient; import com.marklogic.client.datamovement.DataMovementManager; import com.marklogic.client.datamovement.DeleteListener; @@ -55,11 +55,11 @@ protected DatabaseClient getDatabaseClient() { } @Autowired - @Qualifier("jobsDatabaseClientProvider") - protected DatabaseClientProvider jobsDatabaseClientProvider; + @Qualifier("executionsDatabaseClientProvider") + protected DatabaseClientProvider executionsDatabaseClientProvider; - protected DatabaseClient getJobsDatabaseClient() { - return jobsDatabaseClientProvider.getDatabaseClient(); + protected DatabaseClient getExecutionsDatabaseClient() { + return executionsDatabaseClientProvider.getDatabaseClient(); } private JSONDocumentManager contentManager; @@ -70,12 +70,12 @@ protected JSONDocumentManager getContentManager() { return contentManager; } - private JSONDocumentManager jobsManager; - protected JSONDocumentManager getJobsManager() { - if (jobsManager == null) { - jobsManager = getJobsDatabaseClient().newJSONDocumentManager(); + private JSONDocumentManager executionsManager; + protected JSONDocumentManager getExecutionsManager() { + if (executionsManager == null) { + executionsManager = getExecutionsDatabaseClient().newJSONDocumentManager(); } - return jobsManager; + return executionsManager; } private String contentDatabaseId; @@ -103,8 +103,8 @@ protected String getModulesDatabaseId() { /* @AfterAll public static void suiteTeardown() { - if (jobsClient != null) { - jobsClient.release(); + if (executionsClient != null) { + executionsClient.release(); } } */ @@ -135,9 +135,9 @@ protected StringHandle loadTokenizedResource(String name, Map to return new StringHandle(content); } - protected StateConductorJob getJobDocument(String uri) throws IOException { - String content = getJobsManager().readAs(uri, String.class); - return mapper.readValue(content, StateConductorJob.class); + protected StateConductorExecution getExecutionDocument(String uri) throws IOException { + String content = getExecutionsManager().readAs(uri, String.class); + return mapper.readValue(content, StateConductorExecution.class); } protected void deleteCollections(DatabaseClient client, String... collections) { diff --git a/state-conductor-dataservices/src/test/java/com/marklogic/ext/StateConductorTestConfig.java b/state-conductor-dataservices/src/test/java/com/marklogic/ext/StateConductorTestConfig.java index 2e85b0e3..08e4196a 100644 --- a/state-conductor-dataservices/src/test/java/com/marklogic/ext/StateConductorTestConfig.java +++ b/state-conductor-dataservices/src/test/java/com/marklogic/ext/StateConductorTestConfig.java @@ -60,9 +60,9 @@ public DatabaseClientProvider databaseClientProvider() { } @Bean - public DatabaseClientProvider jobsDatabaseClientProvider() { + public DatabaseClientProvider executionsDatabaseClientProvider() { DatabaseClientConfig config = new DatabaseClientConfig(getHost(), getRestPort(), getUsername(), getPassword()); - config.setDatabase("state-conductor-jobs"); + config.setDatabase("state-conductor-executions"); return new SimpleDatabaseClientProvider(config); } diff --git a/state-conductor-dataservices/src/test/java/com/marklogic/tests/GetExecutionStatusTest.java b/state-conductor-dataservices/src/test/java/com/marklogic/tests/GetExecutionStatusTest.java new file mode 100644 index 00000000..3e88eedc --- /dev/null +++ b/state-conductor-dataservices/src/test/java/com/marklogic/tests/GetExecutionStatusTest.java @@ -0,0 +1,259 @@ +package com.marklogic.tests; + +import com.fasterxml.jackson.databind.node.JsonNodeType; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.marklogic.StateConductorService; +import com.marklogic.StateConductorServiceMock; +import com.marklogic.client.document.DocumentWriteSet; +import com.marklogic.client.io.DocumentMetadataHandle; +import com.marklogic.ext.AbstractStateConductorTest; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; + +public class GetExecutionStatusTest extends AbstractStateConductorTest { + + static Logger logger = LoggerFactory.getLogger(GetExecutionStatusTest.class); + + StateConductorService mockService; + StateConductorService service; + + @BeforeEach + public void setup() throws IOException { + // setup the service + mockService = new StateConductorServiceMock(); + service = StateConductorService.on(getDatabaseClient()); + + DocumentWriteSet batch; + + // replacement tokens + Map tokens = new HashMap<>(); + tokens.put("%DATABASE%", getContentDatabaseId()); + tokens.put("%MODULES%", getModulesDatabaseId()); + + // add execution docs + batch = getExecutionsManager().newWriteSet(); + DocumentMetadataHandle executionMeta = new DocumentMetadataHandle(); + executionMeta.getCollections().addAll("stateConductorExecution", "test"); + executionMeta.getPermissions().add("state-conductor-reader-role", DocumentMetadataHandle.Capability.READ); + executionMeta.getPermissions().add("state-conductor-execution-writer-role", DocumentMetadataHandle.Capability.UPDATE); + batch.add("/test/stateConductorExecution/execution1.json", executionMeta, loadTokenizedResource("executions/execution1.json", tokens)); + batch.add("/test/stateConductorExecution/execution2.json", executionMeta, loadTokenizedResource("executions/execution2.json", tokens)); + batch.add("/test/stateConductorExecution/execution3.json", executionMeta, loadTokenizedResource("executions/execution3.json", tokens)); + batch.add("/test/stateConductorExecution/execution4.json", executionMeta, loadTokenizedResource("executions/execution4.json", tokens)); + batch.add("/test/stateConductorExecution/execution5.json", executionMeta, loadTokenizedResource("executions/execution5.json", tokens)); + getExecutionsManager().write(batch); + + // add stateMachine docs + DocumentMetadataHandle stateMachineMeta = new DocumentMetadataHandle(); + stateMachineMeta.getCollections().add("state-conductor-state-machine"); + batch = getContentManager().newWriteSet(); + batch.add("/state-conductor-state-machine/test-state-machine.asl.json", stateMachineMeta, loadFileResource("stateMachines/test-state-machine.asl.json")); + batch.add("/state-conductor-state-machine/test2-state-machine.asl.json", stateMachineMeta, loadFileResource("stateMachines/test2-state-machine.asl.json")); + getContentManager().write(batch); + } + + @AfterEach + public void teardown() { + deleteCollections(getExecutionsDatabaseClient(), "test"); + } + + @Test + public void testSimpleStatusMock() { + ObjectNode resp = mockService.getStateMachineStatus(Arrays.stream(new String[]{"fake-state-machine"}), null, null, null); + logger.info(resp.toString()); + + assertNotNull(resp); + assertEquals(JsonNodeType.OBJECT, resp.get("fake-state-machine").getNodeType()); + assertEquals("fake-state-machine", resp.get("fake-state-machine").get("name").asText()); + assertEquals("", resp.get("fake-state-machine").get("totalPerStatus").asText()); + assertEquals("", resp.get("fake-state-machine").get("totalPerState").asText()); + } + + @Test + public void testSimpleStatus() { + ObjectNode resp = service.getStateMachineStatus(null, null, null, null); + logger.info(resp.toString()); + + assertNotNull(resp); + assertEquals(JsonNodeType.OBJECT, resp.getNodeType()); + + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").getNodeType()); + assertEquals("test-state-machine", resp.get("test-state-machine").get("name").asText()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").get("totalPerStatus").getNodeType()); + assertTrue(2 <= resp.get("test-state-machine").get("totalPerStatus").get("new").asInt()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerStatus").get("working").asInt()); + assertTrue(0 == resp.get("test-state-machine").get("totalPerStatus").get("waiting").asInt()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerStatus").get("complete").asInt()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerStatus").get("failed").asInt()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").get("totalPerState").getNodeType()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerState").get("add-collection-1").asInt()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerState").get("add-collection-2").asInt()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerState").get("success").asInt()); + + assertEquals(JsonNodeType.OBJECT, resp.get("test2-state-machine").getNodeType()); + assertEquals("test2-state-machine", resp.get("test2-state-machine").get("name").asText()); + assertEquals(JsonNodeType.OBJECT, resp.get("test2-state-machine").get("totalPerStatus").getNodeType()); + assertTrue(0 <= resp.get("test2-state-machine").get("totalPerStatus").get("new").asInt()); + assertTrue(0 == resp.get("test2-state-machine").get("totalPerStatus").get("working").asInt()); + assertTrue(0 == resp.get("test2-state-machine").get("totalPerStatus").get("waiting").asInt()); + assertTrue(0 == resp.get("test2-state-machine").get("totalPerStatus").get("complete").asInt()); + assertTrue(0 == resp.get("test2-state-machine").get("totalPerStatus").get("failed").asInt()); + assertEquals(JsonNodeType.OBJECT, resp.get("test2-state-machine").get("totalPerState").getNodeType()); + assertTrue(0 == resp.get("test2-state-machine").get("totalPerState").get("add-collection").asInt()); + assertTrue(0 == resp.get("test2-state-machine").get("totalPerState").get("choose-wisely").asInt()); + assertTrue(0 == resp.get("test2-state-machine").get("totalPerState").get("success").asInt()); + assertTrue(0 == resp.get("test2-state-machine").get("totalPerState").get("failure").asInt()); + } + + @Test + public void testDetailedStatus() { + ObjectNode resp = service.getStateMachineStatus(null, null, null, true); + logger.info(resp.toString()); + + assertNotNull(resp); + assertEquals(JsonNodeType.OBJECT, resp.getNodeType()); + + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").getNodeType()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").get("detailedTotalPerStatus").getNodeType()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").get("detailedTotalPerStatus").get("new").getNodeType()); + assertTrue(0 == resp.get("test-state-machine").get("detailedTotalPerStatus").get("new").get("add-collection-1").asInt()); + assertTrue(0 == resp.get("test-state-machine").get("detailedTotalPerStatus").get("new").get("add-collection-2").asInt()); + assertTrue(0 == resp.get("test-state-machine").get("detailedTotalPerStatus").get("new").get("success").asInt()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").get("detailedTotalPerStatus").get("working").getNodeType()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").get("detailedTotalPerStatus").get("waiting").getNodeType()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").get("detailedTotalPerStatus").get("complete").getNodeType()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").get("detailedTotalPerStatus").get("failed").getNodeType()); + + assertEquals(JsonNodeType.OBJECT, resp.get("test2-state-machine").getNodeType()); + assertEquals(JsonNodeType.OBJECT, resp.get("test2-state-machine").get("detailedTotalPerStatus").getNodeType()); + assertEquals(JsonNodeType.OBJECT, resp.get("test2-state-machine").get("detailedTotalPerStatus").get("new").getNodeType()); + assertTrue(0 == resp.get("test2-state-machine").get("detailedTotalPerStatus").get("new").get("add-collection").asInt()); + assertTrue(0 == resp.get("test2-state-machine").get("detailedTotalPerStatus").get("new").get("choose-wisely").asInt()); + assertTrue(0 == resp.get("test2-state-machine").get("detailedTotalPerStatus").get("new").get("success").asInt()); + assertTrue(0 == resp.get("test2-state-machine").get("detailedTotalPerStatus").get("new").get("failure").asInt()); + assertEquals(JsonNodeType.OBJECT, resp.get("test2-state-machine").get("detailedTotalPerStatus").get("working").getNodeType()); + assertEquals(JsonNodeType.OBJECT, resp.get("test2-state-machine").get("detailedTotalPerStatus").get("waiting").getNodeType()); + assertEquals(JsonNodeType.OBJECT, resp.get("test2-state-machine").get("detailedTotalPerStatus").get("complete").getNodeType()); + assertEquals(JsonNodeType.OBJECT, resp.get("test2-state-machine").get("detailedTotalPerStatus").get("failed").getNodeType()); + } + + @Test + public void testSpecificStatus() { + ObjectNode resp = service.getStateMachineStatus(Arrays.stream(new String[]{"test-state-machine"}), null, null, null); + logger.info(resp.toString()); + + assertNotNull(resp); + assertEquals(JsonNodeType.OBJECT, resp.getNodeType()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").getNodeType()); + assertEquals("test-state-machine", resp.get("test-state-machine").get("name").asText()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").get("totalPerStatus").getNodeType()); + assertTrue(2 <= resp.get("test-state-machine").get("totalPerStatus").get("new").asInt()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerStatus").get("working").asInt()); + assertTrue(0 == resp.get("test-state-machine").get("totalPerStatus").get("waiting").asInt()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerStatus").get("complete").asInt()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerStatus").get("failed").asInt()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").get("totalPerState").getNodeType()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerState").get("add-collection-1").asInt()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerState").get("add-collection-2").asInt()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerState").get("success").asInt()); + + assertNull(resp.get("test2-state-machine")); + } + + @Test + public void testSpecificStatus2() { + ObjectNode resp = service.getStateMachineStatus(Arrays.stream(new String[]{"test2-state-machine"}), null, null, null); + logger.info(resp.toString()); + + assertNotNull(resp); + assertEquals(JsonNodeType.OBJECT, resp.getNodeType()); + assertEquals(JsonNodeType.OBJECT, resp.get("test2-state-machine").getNodeType()); + assertEquals("test2-state-machine", resp.get("test2-state-machine").get("name").asText()); + assertEquals(JsonNodeType.OBJECT, resp.get("test2-state-machine").get("totalPerStatus").getNodeType()); + assertTrue(0 <= resp.get("test2-state-machine").get("totalPerStatus").get("new").asInt()); + assertTrue(0 == resp.get("test2-state-machine").get("totalPerStatus").get("working").asInt()); + assertTrue(0 == resp.get("test2-state-machine").get("totalPerStatus").get("waiting").asInt()); + assertTrue(0 == resp.get("test2-state-machine").get("totalPerStatus").get("complete").asInt()); + assertTrue(0 == resp.get("test2-state-machine").get("totalPerStatus").get("failed").asInt()); + assertEquals(JsonNodeType.OBJECT, resp.get("test2-state-machine").get("totalPerState").getNodeType()); + assertTrue(0 == resp.get("test2-state-machine").get("totalPerState").get("add-collection").asInt()); + assertTrue(0 == resp.get("test2-state-machine").get("totalPerState").get("choose-wisely").asInt()); + assertTrue(0 == resp.get("test2-state-machine").get("totalPerState").get("success").asInt()); + assertTrue(0 == resp.get("test2-state-machine").get("totalPerState").get("failure").asInt()); + + assertNull(resp.get("test-state-machine")); + } + + @Test + public void testTemporalFilter1() { + ObjectNode resp = service.getStateMachineStatus(Arrays.stream(new String[]{"test-state-machine"}), "2020-03-30T13:59:00Z", null, null); + logger.info(resp.toString()); + + assertNotNull(resp); + assertEquals(JsonNodeType.OBJECT, resp.getNodeType()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").getNodeType()); + assertEquals("test-state-machine", resp.get("test-state-machine").get("name").asText()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").get("totalPerStatus").getNodeType()); + assertTrue(1 <= resp.get("test-state-machine").get("totalPerStatus").get("new").asInt()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerStatus").get("working").asInt()); + assertTrue(0 == resp.get("test-state-machine").get("totalPerStatus").get("waiting").asInt()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerStatus").get("complete").asInt()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerStatus").get("failed").asInt()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").get("totalPerState").getNodeType()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerState").get("add-collection-1").asInt()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerState").get("add-collection-2").asInt()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerState").get("success").asInt()); + } + + @Test + public void testTemporalFilter2() { + ObjectNode resp = service.getStateMachineStatus(Arrays.stream(new String[]{"test-state-machine"}), null, "2020-03-30T13:59:00Z", null); + logger.info(resp.toString()); + + assertNotNull(resp); + assertEquals(JsonNodeType.OBJECT, resp.getNodeType()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").getNodeType()); + assertEquals("test-state-machine", resp.get("test-state-machine").get("name").asText()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").get("totalPerStatus").getNodeType()); + assertTrue(1 <= resp.get("test-state-machine").get("totalPerStatus").get("new").asInt()); + assertTrue(0 == resp.get("test-state-machine").get("totalPerStatus").get("working").asInt()); + assertTrue(0 == resp.get("test-state-machine").get("totalPerStatus").get("waiting").asInt()); + assertTrue(0 == resp.get("test-state-machine").get("totalPerStatus").get("complete").asInt()); + assertTrue(0 == resp.get("test-state-machine").get("totalPerStatus").get("failed").asInt()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").get("totalPerState").getNodeType()); + assertTrue(0 == resp.get("test-state-machine").get("totalPerState").get("add-collection-1").asInt()); + assertTrue(0 == resp.get("test-state-machine").get("totalPerState").get("add-collection-2").asInt()); + assertTrue(0 == resp.get("test-state-machine").get("totalPerState").get("success").asInt()); + } + + @Test + public void testTemporalFilter3() { + ObjectNode resp = service.getStateMachineStatus(Arrays.stream(new String[]{"test-state-machine"}), "2020-03-30T15:19:00Z", "2020-03-30T15:21:00Z", null); + logger.info(resp.toString()); + + assertNotNull(resp); + assertEquals(JsonNodeType.OBJECT, resp.getNodeType()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").getNodeType()); + assertEquals("test-state-machine", resp.get("test-state-machine").get("name").asText()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").get("totalPerStatus").getNodeType()); + assertTrue(0 == resp.get("test-state-machine").get("totalPerStatus").get("new").asInt()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerStatus").get("working").asInt()); + assertTrue(0 == resp.get("test-state-machine").get("totalPerStatus").get("waiting").asInt()); + assertTrue(0 == resp.get("test-state-machine").get("totalPerStatus").get("complete").asInt()); + assertTrue(0 == resp.get("test-state-machine").get("totalPerStatus").get("failed").asInt()); + assertEquals(JsonNodeType.OBJECT, resp.get("test-state-machine").get("totalPerState").getNodeType()); + assertTrue(1 == resp.get("test-state-machine").get("totalPerState").get("add-collection-1").asInt()); + assertTrue(0 == resp.get("test-state-machine").get("totalPerState").get("add-collection-2").asInt()); + assertTrue(0 == resp.get("test-state-machine").get("totalPerState").get("success").asInt()); + } +} diff --git a/state-conductor-dataservices/src/test/java/com/marklogic/tests/GetJobStatusTest.java b/state-conductor-dataservices/src/test/java/com/marklogic/tests/GetJobStatusTest.java deleted file mode 100644 index 7ec8d490..00000000 --- a/state-conductor-dataservices/src/test/java/com/marklogic/tests/GetJobStatusTest.java +++ /dev/null @@ -1,259 +0,0 @@ -package com.marklogic.tests; - -import com.fasterxml.jackson.databind.node.JsonNodeType; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.marklogic.StateConductorService; -import com.marklogic.StateConductorServiceMock; -import com.marklogic.client.document.DocumentWriteSet; -import com.marklogic.client.io.DocumentMetadataHandle; -import com.marklogic.ext.AbstractStateConductorTest; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.*; - -public class GetJobStatusTest extends AbstractStateConductorTest { - - static Logger logger = LoggerFactory.getLogger(GetJobStatusTest.class); - - StateConductorService mockService; - StateConductorService service; - - @BeforeEach - public void setup() throws IOException { - // setup the service - mockService = new StateConductorServiceMock(); - service = StateConductorService.on(getDatabaseClient()); - - DocumentWriteSet batch; - - // replacement tokens - Map tokens = new HashMap<>(); - tokens.put("%DATABASE%", getContentDatabaseId()); - tokens.put("%MODULES%", getModulesDatabaseId()); - - // add job docs - batch = getJobsManager().newWriteSet(); - DocumentMetadataHandle jobMeta = new DocumentMetadataHandle(); - jobMeta.getCollections().addAll("stateConductorJob", "test"); - jobMeta.getPermissions().add("state-conductor-reader-role", DocumentMetadataHandle.Capability.READ); - jobMeta.getPermissions().add("state-conductor-job-writer-role", DocumentMetadataHandle.Capability.UPDATE); - batch.add("/test/stateConductorJob/job1.json", jobMeta, loadTokenizedResource("jobs/job1.json", tokens)); - batch.add("/test/stateConductorJob/job2.json", jobMeta, loadTokenizedResource("jobs/job2.json", tokens)); - batch.add("/test/stateConductorJob/job3.json", jobMeta, loadTokenizedResource("jobs/job3.json", tokens)); - batch.add("/test/stateConductorJob/job4.json", jobMeta, loadTokenizedResource("jobs/job4.json", tokens)); - batch.add("/test/stateConductorJob/job5.json", jobMeta, loadTokenizedResource("jobs/job5.json", tokens)); - getJobsManager().write(batch); - - // add flow docs - DocumentMetadataHandle flowMeta = new DocumentMetadataHandle(); - flowMeta.getCollections().add("state-conductor-flow"); - batch = getContentManager().newWriteSet(); - batch.add("/state-conductor-flow/test-flow.asl.json", flowMeta, loadFileResource("flows/test-flow.asl.json")); - batch.add("/state-conductor-flow/test2-flow.asl.json", flowMeta, loadFileResource("flows/test2-flow.asl.json")); - getContentManager().write(batch); - } - - @AfterEach - public void teardown() { - deleteCollections(getJobsDatabaseClient(), "test"); - } - - @Test - public void testSimpleStatusMock() { - ObjectNode resp = mockService.getFlowStatus(Arrays.stream(new String[]{"fake-flow"}), null, null, null); - logger.info(resp.toString()); - - assertNotNull(resp); - assertEquals(JsonNodeType.OBJECT, resp.get("fake-flow").getNodeType()); - assertEquals("fake-flow", resp.get("fake-flow").get("flowName").asText()); - assertEquals("", resp.get("fake-flow").get("totalPerStatus").asText()); - assertEquals("", resp.get("fake-flow").get("totalPerState").asText()); - } - - @Test - public void testSimpleStatus() { - ObjectNode resp = service.getFlowStatus(null, null, null, null); - logger.info(resp.toString()); - - assertNotNull(resp); - assertEquals(JsonNodeType.OBJECT, resp.getNodeType()); - - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").getNodeType()); - assertEquals("test-flow", resp.get("test-flow").get("flowName").asText()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").get("totalPerStatus").getNodeType()); - assertTrue(2 <= resp.get("test-flow").get("totalPerStatus").get("new").asInt()); - assertTrue(1 == resp.get("test-flow").get("totalPerStatus").get("working").asInt()); - assertTrue(0 == resp.get("test-flow").get("totalPerStatus").get("waiting").asInt()); - assertTrue(1 == resp.get("test-flow").get("totalPerStatus").get("complete").asInt()); - assertTrue(1 == resp.get("test-flow").get("totalPerStatus").get("failed").asInt()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").get("totalPerState").getNodeType()); - assertTrue(1 == resp.get("test-flow").get("totalPerState").get("add-collection-1").asInt()); - assertTrue(1 == resp.get("test-flow").get("totalPerState").get("add-collection-2").asInt()); - assertTrue(1 == resp.get("test-flow").get("totalPerState").get("success").asInt()); - - assertEquals(JsonNodeType.OBJECT, resp.get("test2-flow").getNodeType()); - assertEquals("test2-flow", resp.get("test2-flow").get("flowName").asText()); - assertEquals(JsonNodeType.OBJECT, resp.get("test2-flow").get("totalPerStatus").getNodeType()); - assertTrue(0 <= resp.get("test2-flow").get("totalPerStatus").get("new").asInt()); - assertTrue(0 == resp.get("test2-flow").get("totalPerStatus").get("working").asInt()); - assertTrue(0 == resp.get("test2-flow").get("totalPerStatus").get("waiting").asInt()); - assertTrue(0 == resp.get("test2-flow").get("totalPerStatus").get("complete").asInt()); - assertTrue(0 == resp.get("test2-flow").get("totalPerStatus").get("failed").asInt()); - assertEquals(JsonNodeType.OBJECT, resp.get("test2-flow").get("totalPerState").getNodeType()); - assertTrue(0 == resp.get("test2-flow").get("totalPerState").get("add-collection").asInt()); - assertTrue(0 == resp.get("test2-flow").get("totalPerState").get("choose-wisely").asInt()); - assertTrue(0 == resp.get("test2-flow").get("totalPerState").get("success").asInt()); - assertTrue(0 == resp.get("test2-flow").get("totalPerState").get("failure").asInt()); - } - - @Test - public void testDetailedStatus() { - ObjectNode resp = service.getFlowStatus(null, null, null, true); - logger.info(resp.toString()); - - assertNotNull(resp); - assertEquals(JsonNodeType.OBJECT, resp.getNodeType()); - - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").getNodeType()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").get("detailedTotalPerStatus").getNodeType()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").get("detailedTotalPerStatus").get("new").getNodeType()); - assertTrue(0 == resp.get("test-flow").get("detailedTotalPerStatus").get("new").get("add-collection-1").asInt()); - assertTrue(0 == resp.get("test-flow").get("detailedTotalPerStatus").get("new").get("add-collection-2").asInt()); - assertTrue(0 == resp.get("test-flow").get("detailedTotalPerStatus").get("new").get("success").asInt()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").get("detailedTotalPerStatus").get("working").getNodeType()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").get("detailedTotalPerStatus").get("waiting").getNodeType()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").get("detailedTotalPerStatus").get("complete").getNodeType()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").get("detailedTotalPerStatus").get("failed").getNodeType()); - - assertEquals(JsonNodeType.OBJECT, resp.get("test2-flow").getNodeType()); - assertEquals(JsonNodeType.OBJECT, resp.get("test2-flow").get("detailedTotalPerStatus").getNodeType()); - assertEquals(JsonNodeType.OBJECT, resp.get("test2-flow").get("detailedTotalPerStatus").get("new").getNodeType()); - assertTrue(0 == resp.get("test2-flow").get("detailedTotalPerStatus").get("new").get("add-collection").asInt()); - assertTrue(0 == resp.get("test2-flow").get("detailedTotalPerStatus").get("new").get("choose-wisely").asInt()); - assertTrue(0 == resp.get("test2-flow").get("detailedTotalPerStatus").get("new").get("success").asInt()); - assertTrue(0 == resp.get("test2-flow").get("detailedTotalPerStatus").get("new").get("failure").asInt()); - assertEquals(JsonNodeType.OBJECT, resp.get("test2-flow").get("detailedTotalPerStatus").get("working").getNodeType()); - assertEquals(JsonNodeType.OBJECT, resp.get("test2-flow").get("detailedTotalPerStatus").get("waiting").getNodeType()); - assertEquals(JsonNodeType.OBJECT, resp.get("test2-flow").get("detailedTotalPerStatus").get("complete").getNodeType()); - assertEquals(JsonNodeType.OBJECT, resp.get("test2-flow").get("detailedTotalPerStatus").get("failed").getNodeType()); - } - - @Test - public void testSpecificStatus() { - ObjectNode resp = service.getFlowStatus(Arrays.stream(new String[]{"test-flow"}), null, null, null); - logger.info(resp.toString()); - - assertNotNull(resp); - assertEquals(JsonNodeType.OBJECT, resp.getNodeType()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").getNodeType()); - assertEquals("test-flow", resp.get("test-flow").get("flowName").asText()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").get("totalPerStatus").getNodeType()); - assertTrue(2 <= resp.get("test-flow").get("totalPerStatus").get("new").asInt()); - assertTrue(1 == resp.get("test-flow").get("totalPerStatus").get("working").asInt()); - assertTrue(0 == resp.get("test-flow").get("totalPerStatus").get("waiting").asInt()); - assertTrue(1 == resp.get("test-flow").get("totalPerStatus").get("complete").asInt()); - assertTrue(1 == resp.get("test-flow").get("totalPerStatus").get("failed").asInt()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").get("totalPerState").getNodeType()); - assertTrue(1 == resp.get("test-flow").get("totalPerState").get("add-collection-1").asInt()); - assertTrue(1 == resp.get("test-flow").get("totalPerState").get("add-collection-2").asInt()); - assertTrue(1 == resp.get("test-flow").get("totalPerState").get("success").asInt()); - - assertNull(resp.get("test2-flow")); - } - - @Test - public void testSpecificStatus2() { - ObjectNode resp = service.getFlowStatus(Arrays.stream(new String[]{"test2-flow"}), null, null, null); - logger.info(resp.toString()); - - assertNotNull(resp); - assertEquals(JsonNodeType.OBJECT, resp.getNodeType()); - assertEquals(JsonNodeType.OBJECT, resp.get("test2-flow").getNodeType()); - assertEquals("test2-flow", resp.get("test2-flow").get("flowName").asText()); - assertEquals(JsonNodeType.OBJECT, resp.get("test2-flow").get("totalPerStatus").getNodeType()); - assertTrue(0 <= resp.get("test2-flow").get("totalPerStatus").get("new").asInt()); - assertTrue(0 == resp.get("test2-flow").get("totalPerStatus").get("working").asInt()); - assertTrue(0 == resp.get("test2-flow").get("totalPerStatus").get("waiting").asInt()); - assertTrue(0 == resp.get("test2-flow").get("totalPerStatus").get("complete").asInt()); - assertTrue(0 == resp.get("test2-flow").get("totalPerStatus").get("failed").asInt()); - assertEquals(JsonNodeType.OBJECT, resp.get("test2-flow").get("totalPerState").getNodeType()); - assertTrue(0 == resp.get("test2-flow").get("totalPerState").get("add-collection").asInt()); - assertTrue(0 == resp.get("test2-flow").get("totalPerState").get("choose-wisely").asInt()); - assertTrue(0 == resp.get("test2-flow").get("totalPerState").get("success").asInt()); - assertTrue(0 == resp.get("test2-flow").get("totalPerState").get("failure").asInt()); - - assertNull(resp.get("test-flow")); - } - - @Test - public void testTemporalFilter1() { - ObjectNode resp = service.getFlowStatus(Arrays.stream(new String[]{"test-flow"}), "2020-03-30T13:59:00Z", null, null); - logger.info(resp.toString()); - - assertNotNull(resp); - assertEquals(JsonNodeType.OBJECT, resp.getNodeType()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").getNodeType()); - assertEquals("test-flow", resp.get("test-flow").get("flowName").asText()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").get("totalPerStatus").getNodeType()); - assertTrue(1 <= resp.get("test-flow").get("totalPerStatus").get("new").asInt()); - assertTrue(1 == resp.get("test-flow").get("totalPerStatus").get("working").asInt()); - assertTrue(0 == resp.get("test-flow").get("totalPerStatus").get("waiting").asInt()); - assertTrue(1 == resp.get("test-flow").get("totalPerStatus").get("complete").asInt()); - assertTrue(1 == resp.get("test-flow").get("totalPerStatus").get("failed").asInt()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").get("totalPerState").getNodeType()); - assertTrue(1 == resp.get("test-flow").get("totalPerState").get("add-collection-1").asInt()); - assertTrue(1 == resp.get("test-flow").get("totalPerState").get("add-collection-2").asInt()); - assertTrue(1 == resp.get("test-flow").get("totalPerState").get("success").asInt()); - } - - @Test - public void testTemporalFilter2() { - ObjectNode resp = service.getFlowStatus(Arrays.stream(new String[]{"test-flow"}), null, "2020-03-30T13:59:00Z", null); - logger.info(resp.toString()); - - assertNotNull(resp); - assertEquals(JsonNodeType.OBJECT, resp.getNodeType()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").getNodeType()); - assertEquals("test-flow", resp.get("test-flow").get("flowName").asText()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").get("totalPerStatus").getNodeType()); - assertTrue(1 <= resp.get("test-flow").get("totalPerStatus").get("new").asInt()); - assertTrue(0 == resp.get("test-flow").get("totalPerStatus").get("working").asInt()); - assertTrue(0 == resp.get("test-flow").get("totalPerStatus").get("waiting").asInt()); - assertTrue(0 == resp.get("test-flow").get("totalPerStatus").get("complete").asInt()); - assertTrue(0 == resp.get("test-flow").get("totalPerStatus").get("failed").asInt()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").get("totalPerState").getNodeType()); - assertTrue(0 == resp.get("test-flow").get("totalPerState").get("add-collection-1").asInt()); - assertTrue(0 == resp.get("test-flow").get("totalPerState").get("add-collection-2").asInt()); - assertTrue(0 == resp.get("test-flow").get("totalPerState").get("success").asInt()); - } - - @Test - public void testTemporalFilter3() { - ObjectNode resp = service.getFlowStatus(Arrays.stream(new String[]{"test-flow"}), "2020-03-30T15:19:00Z", "2020-03-30T15:21:00Z", null); - logger.info(resp.toString()); - - assertNotNull(resp); - assertEquals(JsonNodeType.OBJECT, resp.getNodeType()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").getNodeType()); - assertEquals("test-flow", resp.get("test-flow").get("flowName").asText()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").get("totalPerStatus").getNodeType()); - assertTrue(0 == resp.get("test-flow").get("totalPerStatus").get("new").asInt()); - assertTrue(1 == resp.get("test-flow").get("totalPerStatus").get("working").asInt()); - assertTrue(0 == resp.get("test-flow").get("totalPerStatus").get("waiting").asInt()); - assertTrue(0 == resp.get("test-flow").get("totalPerStatus").get("complete").asInt()); - assertTrue(0 == resp.get("test-flow").get("totalPerStatus").get("failed").asInt()); - assertEquals(JsonNodeType.OBJECT, resp.get("test-flow").get("totalPerState").getNodeType()); - assertTrue(1 == resp.get("test-flow").get("totalPerState").get("add-collection-1").asInt()); - assertTrue(0 == resp.get("test-flow").get("totalPerState").get("add-collection-2").asInt()); - assertTrue(0 == resp.get("test-flow").get("totalPerState").get("success").asInt()); - } -} diff --git a/state-conductor-dataservices/src/test/resources/jobs/badJob1.json b/state-conductor-dataservices/src/test/resources/executions/badExecution1.json similarity index 65% rename from state-conductor-dataservices/src/test/resources/jobs/badJob1.json rename to state-conductor-dataservices/src/test/resources/executions/badExecution1.json index aaaab25e..0261f44c 100644 --- a/state-conductor-dataservices/src/test/resources/jobs/badJob1.json +++ b/state-conductor-dataservices/src/test/resources/executions/badExecution1.json @@ -1,8 +1,8 @@ { - "id": "badJob1", - "flowName": "missing-flow", - "flowStatus": "new", - "flowState": null, + "id": "badExecution1", + "name": "missing-state-machine", + "status": "new", + "state": null, "uri": "/test/doc1.json", "database": "%DATABASE%", "modules": "%MODULES%", diff --git a/state-conductor-dataservices/src/test/resources/jobs/job1.json b/state-conductor-dataservices/src/test/resources/executions/execution1.json similarity index 67% rename from state-conductor-dataservices/src/test/resources/jobs/job1.json rename to state-conductor-dataservices/src/test/resources/executions/execution1.json index d61cc936..aa33560c 100644 --- a/state-conductor-dataservices/src/test/resources/jobs/job1.json +++ b/state-conductor-dataservices/src/test/resources/executions/execution1.json @@ -1,8 +1,8 @@ { - "id": "job1", - "flowName": "test-flow", - "flowStatus": "new", - "flowState": null, + "id": "execution1", + "name": "test-state-machine", + "status": "new", + "state": null, "uri": "/test/doc1.json", "database": "%DATABASE%", "modules": "%MODULES%", diff --git a/state-conductor-dataservices/src/test/resources/jobs/job2.json b/state-conductor-dataservices/src/test/resources/executions/execution2.json similarity index 67% rename from state-conductor-dataservices/src/test/resources/jobs/job2.json rename to state-conductor-dataservices/src/test/resources/executions/execution2.json index ed173a02..6174ad79 100644 --- a/state-conductor-dataservices/src/test/resources/jobs/job2.json +++ b/state-conductor-dataservices/src/test/resources/executions/execution2.json @@ -1,8 +1,8 @@ { - "id": "job2", - "flowName": "test-flow", - "flowStatus": "new", - "flowState": null, + "id": "execution2", + "name": "test-state-machine", + "status": "new", + "state": null, "uri": "/test/doc2.json", "database": "%DATABASE%", "modules": "%MODULES%", diff --git a/state-conductor-dataservices/src/test/resources/jobs/job3.json b/state-conductor-dataservices/src/test/resources/executions/execution3.json similarity index 62% rename from state-conductor-dataservices/src/test/resources/jobs/job3.json rename to state-conductor-dataservices/src/test/resources/executions/execution3.json index 572ee149..f9e16362 100644 --- a/state-conductor-dataservices/src/test/resources/jobs/job3.json +++ b/state-conductor-dataservices/src/test/resources/executions/execution3.json @@ -1,8 +1,8 @@ { - "id": "job3", - "flowName": "test-flow", - "flowStatus": "working", - "flowState": "add-collection-1", + "id": "execution3", + "name": "test-state-machine", + "status": "working", + "state": "add-collection-1", "uri": "/test/doc2.json", "database": "%DATABASE%", "modules": "%MODULES%", diff --git a/state-conductor-dataservices/src/test/resources/jobs/job4.json b/state-conductor-dataservices/src/test/resources/executions/execution4.json similarity index 64% rename from state-conductor-dataservices/src/test/resources/jobs/job4.json rename to state-conductor-dataservices/src/test/resources/executions/execution4.json index 7f16bed3..b41837a2 100644 --- a/state-conductor-dataservices/src/test/resources/jobs/job4.json +++ b/state-conductor-dataservices/src/test/resources/executions/execution4.json @@ -1,8 +1,8 @@ { - "id": "job4", - "flowName": "test-flow", - "flowStatus": "complete", - "flowState": "success", + "id": "execution4", + "name": "test-state-machine", + "status": "complete", + "state": "success", "uri": "/test/doc2.json", "database": "%DATABASE%", "modules": "%MODULES%", diff --git a/state-conductor-dataservices/src/test/resources/jobs/job5.json b/state-conductor-dataservices/src/test/resources/executions/execution5.json similarity index 63% rename from state-conductor-dataservices/src/test/resources/jobs/job5.json rename to state-conductor-dataservices/src/test/resources/executions/execution5.json index af5e37ea..cc12dbb1 100644 --- a/state-conductor-dataservices/src/test/resources/jobs/job5.json +++ b/state-conductor-dataservices/src/test/resources/executions/execution5.json @@ -1,8 +1,8 @@ { - "id": "job5", - "flowName": "test-flow", - "flowStatus": "failed", - "flowState": "add-collection-2", + "id": "execution5", + "name": "test-state-machine", + "status": "failed", + "state": "add-collection-2", "uri": "/test/doc2.json", "database": "%DATABASE%", "modules": "%MODULES%", diff --git a/state-conductor-dataservices/src/test/resources/flows/test-flow.asl.json b/state-conductor-dataservices/src/test/resources/stateMachines/test-state-machine.asl.json similarity index 100% rename from state-conductor-dataservices/src/test/resources/flows/test-flow.asl.json rename to state-conductor-dataservices/src/test/resources/stateMachines/test-state-machine.asl.json diff --git a/state-conductor-dataservices/src/test/resources/flows/test2-flow.asl.json b/state-conductor-dataservices/src/test/resources/stateMachines/test2-state-machine.asl.json similarity index 100% rename from state-conductor-dataservices/src/test/resources/flows/test2-flow.asl.json rename to state-conductor-dataservices/src/test/resources/stateMachines/test2-state-machine.asl.json diff --git a/state-conductor-dhf5-example/README.md b/state-conductor-dhf5-example/README.md index 389180b6..98a5781f 100644 --- a/state-conductor-dhf5-example/README.md +++ b/state-conductor-dhf5-example/README.md @@ -1,3 +1,3 @@ # MarkLogic State Conductor DHF5 Example Project -This project demonstrates how the _State Conductor_ can be used to execute [Data Hub Framework](https://docs.marklogic.com/datahub/) flows. The State Conductor includes "action" modules for executing full DHF flows, or the individual steps of a DHF flow. See the included test data for example State Conductor flow definitions which invoke DHF flows. +This project demonstrates how the _State Conductor_ can be used to execute [Data Hub Framework](https://docs.marklogic.com/datahub/) flows. The State Conductor includes "action" modules for executing full DHF flows, or the individual steps of a DHF flow. See the included test data for example State Conductor state machine definitions which invoke DHF flows. diff --git a/state-conductor-dhf5-example/src/main/ml-modules/root/custom-modules/custom/MyCustomStep/main.sjs b/state-conductor-dhf5-example/src/main/ml-modules/root/custom-modules/custom/MyCustomStep/main.sjs index 83c3f83e..9bfe8e91 100644 --- a/state-conductor-dhf5-example/src/main/ml-modules/root/custom-modules/custom/MyCustomStep/main.sjs +++ b/state-conductor-dhf5-example/src/main/ml-modules/root/custom-modules/custom/MyCustomStep/main.sjs @@ -38,21 +38,21 @@ function main(content, options) { let context = content.context; //let's set our output format, so we know what we're exporting - let outputFormat = options.outputFormat ? options.outputFormat.toLowerCase() : datahub.flow.consts.DEFAULT_FORMAT; + let outputFormat = options.outputFormat ? options.outputFormat.toLowerCase() : datahub.stateMachine.consts.DEFAULT_FORMAT; //here we check to make sure we're not trying to push out a binary or text document, just xml or json - if (outputFormat !== datahub.flow.consts.JSON && outputFormat !== datahub.flow.consts.XML) { + if (outputFormat !== datahub.stateMachine.consts.JSON && outputFormat !== datahub.stateMachine.consts.XML) { datahub.debug.log({ - message: 'The output format of type ' + outputFormat + ' is invalid. Valid options are ' + datahub.flow.consts.XML + ' or ' + datahub.flow.consts.JSON + '.', + message: 'The output format of type ' + outputFormat + ' is invalid. Valid options are ' + datahub.stateMachine.consts.XML + ' or ' + datahub.stateMachine.consts.JSON + '.', type: 'error' }); - throw Error('The output format of type ' + outputFormat + ' is invalid. Valid options are ' + datahub.flow.consts.XML + ' or ' + datahub.flow.consts.JSON + '.'); + throw Error('The output format of type ' + outputFormat + ' is invalid. Valid options are ' + datahub.stateMachine.consts.XML + ' or ' + datahub.stateMachine.consts.JSON + '.'); } /* This scaffolding assumes we obtained the document from the database. If you are inserting information, you will have to map data from the content.value appropriately and create an instance (object), headers (object), and triples - (array) instead of using the flowUtils functions to grab them from a document that was pulled from MarkLogic. + (array) instead of using the stateMachineUtils functions to grab them from a document that was pulled from MarkLogic. Also you do not have to check if the document exists as in the code below. Example code for using data that was sent to MarkLogic server for the document @@ -77,13 +77,13 @@ function main(content, options) { } //get our instance, default shape of envelope is envelope/instance, else it'll return an empty object/array - let instance = datahub.flow.flowUtils.getInstanceAsObject(doc) || {}; + let instance = datahub.stateMachine.stateMachineUtils.getInstanceAsObject(doc) || {}; // get triples, return null if empty or cannot be found - let triples = datahub.flow.flowUtils.getTriplesAsObject(doc) || []; + let triples = datahub.stateMachine.stateMachineUtils.getTriplesAsObject(doc) || []; //gets headers, return null if cannot be found - let headers = datahub.flow.flowUtils.getHeadersAsObject(doc) || {}; + let headers = datahub.stateMachine.stateMachineUtils.getHeadersAsObject(doc) || {}; //If you want to set attachments, uncomment here // instance['$attachments'] = doc; @@ -103,11 +103,11 @@ function main(content, options) { //form our envelope here now, specifying our output format - let envelope = datahub.flow.flowUtils.makeEnvelope(instance, headers, triples, outputFormat); + let envelope = datahub.stateMachine.stateMachineUtils.makeEnvelope(instance, headers, triples, outputFormat); //create our return content object, we have a handy helper function for creating a json scaffolding, but you //can also do a node-based one by using nodebuilder, especially if you're dealing with xml! - let newContent = datahub.flow.flowUtils.createContentAsObject(); + let newContent = datahub.stateMachine.stateMachineUtils.createContentAsObject(); //assign our envelope value newContent.value = envelope; diff --git a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/setup.sjs b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/setup.sjs index f1e8bcd8..87601136 100644 --- a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/setup.sjs +++ b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/setup.sjs @@ -11,14 +11,14 @@ test.loadTestFile( xdmp.database(), '/data/johndoe.json', xdmp.defaultPermissions(), - [sc.FLOW_ITEM_COLLECTION, 'test'] + [sc.STATE_MACHINE_ITEM_COLLECTION, 'test'] ); test.loadTestFile( 'janedoe.json', xdmp.database(), '/data/janedoe.json', xdmp.defaultPermissions(), - [sc.FLOW_ITEM_COLLECTION, 'test'] + [sc.STATE_MACHINE_ITEM_COLLECTION, 'test'] ); test.log('StateConductorDHF5Suite Test Setup COMPLETE....'); diff --git a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/suiteSetup.sjs b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/suiteSetup.sjs index c85dbfc1..1bf3de64 100644 --- a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/suiteSetup.sjs +++ b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/suiteSetup.sjs @@ -5,41 +5,41 @@ declareUpdate(); const sc = require('/state-conductor/state-conductor.sjs'); const test = require('/test/test-helper.xqy'); -// insert the test flows +// insert the test stateMachines test.loadTestFile( - 'flows/person-flow.asl.json', + 'stateMachines/person-state-machine.asl.json', xdmp.database(), - sc.FLOW_DIRECTORY + 'person-flow.asl.json', + sc.STATE_MACHINE_DIRECTORY + 'person-state-machine.asl.json', xdmp.defaultPermissions(), - sc.FLOW_COLLECTION + sc.STATE_MACHINE_COLLECTION ); test.loadTestFile( - 'flows/person-steps-flow.asl.json', + 'stateMachines/person-steps-state-machine.asl.json', xdmp.database(), - sc.FLOW_DIRECTORY + 'person-steps-flow.asl.json', + sc.STATE_MACHINE_DIRECTORY + 'person-steps-state-machine.asl.json', xdmp.defaultPermissions(), - sc.FLOW_COLLECTION + sc.STATE_MACHINE_COLLECTION ); test.loadTestFile( - 'flows/person-envelope-flow.asl.json', + 'stateMachines/person-envelope-state-machine.asl.json', xdmp.database(), - sc.FLOW_DIRECTORY + 'person-envelope-flow.asl.json', + sc.STATE_MACHINE_DIRECTORY + 'person-envelope-state-machine.asl.json', xdmp.defaultPermissions(), - sc.FLOW_COLLECTION + sc.STATE_MACHINE_COLLECTION ); test.loadTestFile( - 'flows/custom-steps-flow.asl.json', + 'stateMachines/custom-steps-state-machine.asl.json', xdmp.database(), - sc.FLOW_DIRECTORY + 'custom-steps-flow.asl.json', + sc.STATE_MACHINE_DIRECTORY + 'custom-steps-state-machine.asl.json', xdmp.defaultPermissions(), - sc.FLOW_COLLECTION + sc.STATE_MACHINE_COLLECTION ); test.loadTestFile( - 'flows/missing-dhf-flow.asl.json', + 'stateMachines/missing-dhf-state-machine.asl.json', xdmp.database(), - sc.FLOW_DIRECTORY + 'missing-dhf-flow.asl.json', + sc.STATE_MACHINE_DIRECTORY + 'missing-dhf-state-machine.asl.json', xdmp.defaultPermissions(), - sc.FLOW_COLLECTION + sc.STATE_MACHINE_COLLECTION ); test.log('StateConductorDHF5Suite Suite Setup COMPLETE....'); diff --git a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/suiteTeardown.sjs b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/suiteTeardown.sjs index 6f976d30..b7926274 100644 --- a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/suiteTeardown.sjs +++ b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/suiteTeardown.sjs @@ -5,9 +5,9 @@ declareUpdate(); const sc = require('/state-conductor/state-conductor.sjs'); const test = require('/test/test-helper.xqy'); -xdmp.directoryDelete(sc.FLOW_DIRECTORY); +xdmp.directoryDelete(sc.STATE_MACHINE_DIRECTORY); xdmp.directoryDelete('/data/'); -xdmp.directoryDelete('/stateConductorJob/'); +xdmp.directoryDelete('/stateConductorExecution/'); xdmp.invokeFunction( () => { diff --git a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/teardown.sjs b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/teardown.sjs index e39aafd6..3caaddce 100644 --- a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/teardown.sjs +++ b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/teardown.sjs @@ -6,7 +6,7 @@ const sc = require('/state-conductor/state-conductor.sjs'); const test = require('/test/test-helper.xqy'); xdmp.directoryDelete('/data/'); -xdmp.directoryDelete('/stateConductorJob/'); +xdmp.directoryDelete('/stateConductorExecution/'); xdmp.invokeFunction( () => { diff --git a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/flows/custom-steps-flow.asl.json b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/custom-steps-state-machine.asl.json similarity index 95% rename from state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/flows/custom-steps-flow.asl.json rename to state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/custom-steps-state-machine.asl.json index b2943172..d3dcee39 100644 --- a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/flows/custom-steps-flow.asl.json +++ b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/custom-steps-state-machine.asl.json @@ -10,7 +10,7 @@ "Comment": "runs the dhf 5 flow step", "Resource": "/state-conductor/actions/common/dhf/dhf5RunFlowStepAction.sjs", "Parameters": { - "flowName": "CustomFlow", + "name": "CustomFlow", "step": 1, "flowOptions": { "secret": "find me!" diff --git a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/flows/missing-dhf-flow.asl.json b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/missing-dhf-state-machine.asl.json similarity index 92% rename from state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/flows/missing-dhf-flow.asl.json rename to state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/missing-dhf-state-machine.asl.json index cc27c36a..6b3a0f28 100644 --- a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/flows/missing-dhf-flow.asl.json +++ b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/missing-dhf-state-machine.asl.json @@ -10,7 +10,7 @@ "Comment": "runs the dhf 5 flow step", "Resource": "/state-conductor/actions/common/dhf/dhf5RunFlowStepAction.sjs", "Parameters": { - "flowName": "MissingFlow", + "name": "MissingFlow", "step": 1, "flowOptions": {} }, diff --git a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/flows/person-envelope-flow.asl.json b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/person-envelope-state-machine.asl.json similarity index 100% rename from state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/flows/person-envelope-flow.asl.json rename to state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/person-envelope-state-machine.asl.json diff --git a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/flows/person-flow.asl.json b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/person-state-machine.asl.json similarity index 94% rename from state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/flows/person-flow.asl.json rename to state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/person-state-machine.asl.json index 986abf8c..04c27022 100644 --- a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/flows/person-flow.asl.json +++ b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/person-state-machine.asl.json @@ -10,7 +10,7 @@ "Comment": "runs the dhf 5 flow", "Resource": "/state-conductor/actions/common/dhf/dhf5RunFlowAction.sjs", "Parameters": { - "flowName": "PersonFlow", + "name": "PersonFlow", "flowOptions": {} }, "Next": "Success", diff --git a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/flows/person-steps-flow.asl.json b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/person-steps-state-machine.asl.json similarity index 93% rename from state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/flows/person-steps-flow.asl.json rename to state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/person-steps-state-machine.asl.json index 713d8287..730351ea 100644 --- a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/flows/person-steps-flow.asl.json +++ b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/person-steps-state-machine.asl.json @@ -10,7 +10,7 @@ "Comment": "runs the dhf 5 flow step", "Resource": "/state-conductor/actions/common/dhf/dhf5RunFlowStepAction.sjs", "Parameters": { - "flowName": "PersonFlow", + "name": "PersonFlow", "step": 1, "flowOptions": {} }, @@ -27,7 +27,7 @@ "Comment": "runs the dhf 5 flow step", "Resource": "/state-conductor/actions/common/dhf/dhf5RunFlowStepAction.sjs", "Parameters": { - "flowName": "PersonFlow", + "name": "PersonFlow", "step": 2, "flowOptions": {} }, diff --git a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-scDhf5Integration.sjs b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-scDhf5Integration.sjs index 76d73aba..da20a551 100644 --- a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-scDhf5Integration.sjs +++ b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-scDhf5Integration.sjs @@ -23,24 +23,24 @@ function isolate(func, db) { } const assertions = []; -let jobDoc, error, respDoc, updated; +let executionDoc, error, respDoc, updated; // test reference to missing DHF flow -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'missing-dhf-flow', - flowStatus: 'working', - flowState: 'runStep1', + name: 'missing-dhf-state-machine', + status: 'working', + state: 'runStep1', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), provenance: [], }); -respDoc = sc.executeStateByJobDoc(jobDoc, false); +respDoc = sc.executeStateByExecutionDoc(executionDoc, false); xdmp.log(respDoc); assertions.push( - test.assertEqual('failed', respDoc.flowStatus, 'status check'), + test.assertEqual('failed', respDoc.status, 'status check'), test.assertEqual('JS-JAVASCRIPT', respDoc.errors['runStep1'].name, 'handled missing dhf flow'), test.assertTrue( respDoc.errors['runStep1'].data.includes( @@ -51,56 +51,56 @@ assertions.push( ); // test executing flow step -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'person-steps-flow', - flowStatus: 'working', - flowState: 'runStep1', + name: 'person-steps-state-machine', + status: 'working', + state: 'runStep1', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), provenance: [], }); -respDoc = sc.executeStateByJobDoc(jobDoc, false); +respDoc = sc.executeStateByExecutionDoc(executionDoc, false); assertions.push( - test.assertEqual(sc.FLOW_STATUS_WORKING, respDoc.flowStatus, 'excecuted step 1'), - test.assertEqual('runStep2', respDoc.flowState), + test.assertEqual(sc.STATE_MACHINE_STATUS_WORKING, respDoc.status, 'excecuted step 1'), + test.assertEqual('runStep2', respDoc.state), test.assertEqual(1, respDoc.context['PersonFlow']['1'].totalCount), test.assertEqual(0, respDoc.context['PersonFlow']['1'].errorCount), test.assertEqual('/data/johndoe.json', respDoc.context['PersonFlow']['1'].completedItems[0]) ); // proceed to next step -respDoc = sc.executeStateByJobDoc(xdmp.toJSON(respDoc), false); +respDoc = sc.executeStateByExecutionDoc(xdmp.toJSON(respDoc), false); assertions.push( - test.assertEqual(sc.FLOW_STATUS_WORKING, respDoc.flowStatus, 'excecuted step 2'), - test.assertEqual('Success', respDoc.flowState), + test.assertEqual(sc.STATE_MACHINE_STATUS_WORKING, respDoc.status, 'excecuted step 2'), + test.assertEqual('Success', respDoc.state), test.assertEqual(1, respDoc.context['PersonFlow']['2'].totalCount), test.assertEqual(0, respDoc.context['PersonFlow']['2'].errorCount), test.assertEqual('/data/johndoe.json', respDoc.context['PersonFlow']['2'].completedItems[0]) ); // test executing custom flow step -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'custom-steps-flow', - flowStatus: 'working', - flowState: 'runStep1', + name: 'custom-steps-state-machine', + status: 'working', + state: 'runStep1', uri: '/data/janedoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), provenance: [], }); -respDoc = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +respDoc = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); updated = isolate(() => cts.doc('/data/janedoe.json').toObject()); assertions.push( - test.assertEqual(sc.FLOW_STATUS_WORKING, respDoc.flowStatus, 'excecuted step 1'), - test.assertEqual('Success', respDoc.flowState), + test.assertEqual(sc.STATE_MACHINE_STATUS_WORKING, respDoc.status, 'excecuted step 1'), + test.assertEqual('Success', respDoc.state), test.assertEqual(1, respDoc.context['CustomFlow']['1'].totalCount), test.assertEqual(0, respDoc.context['CustomFlow']['1'].errorCount), test.assertEqual('/data/janedoe.json', respDoc.context['CustomFlow']['1'].completedItems[0]), diff --git a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-stateConductorContext.sjs b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-stateConductorContext.sjs index eda8fecc..577c15f7 100644 --- a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-stateConductorContext.sjs +++ b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-stateConductorContext.sjs @@ -22,14 +22,14 @@ function isolate(func, db) { } const assertions = []; -let jobDoc, assertion; +let executionDoc, assertion; //checks see if the new status check is working -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'custom-steps-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'runStep1', + name: 'custom-steps-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'runStep1', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -37,7 +37,7 @@ jobDoc = xdmp.toJSON({ context: {}, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push( test.assertTrue(assertion.context.hasOwnProperty('hasChanged'), 'hasOwnProperty hasChanged') diff --git a/state-conductor-example/src/main/ml-data/state-conductor-flow/branching-flow.asl.json b/state-conductor-example/src/main/ml-data/state-conductor-flow/branching-state-machine.asl.json similarity index 80% rename from state-conductor-example/src/main/ml-data/state-conductor-flow/branching-flow.asl.json rename to state-conductor-example/src/main/ml-data/state-conductor-flow/branching-state-machine.asl.json index e4b81402..2916ea68 100644 --- a/state-conductor-example/src/main/ml-data/state-conductor-flow/branching-flow.asl.json +++ b/state-conductor-example/src/main/ml-data/state-conductor-flow/branching-state-machine.asl.json @@ -1,5 +1,5 @@ { - "Comment": "example of a branching flow using a 'Choice' type state", + "Comment": "example of a branching stateMachine using a 'Choice' type state", "mlDomain": { "context": [ { @@ -15,11 +15,11 @@ "Comment": "determine's enrollee's gender", "Choices": [ { - "Resource": "/state-conductor/actions/custom/branching-test-flow/gender-is-male.sjs", + "Resource": "/state-conductor/actions/custom/branching-test-state-machine/gender-is-male.sjs", "Next": "enroll-in-mens-health" }, { - "Resource": "/state-conductor/actions/custom/branching-test-flow/gender-is-female.sjs", + "Resource": "/state-conductor/actions/custom/branching-test-state-machine/gender-is-female.sjs", "Next": "enroll-in-womens-health" } ], @@ -29,19 +29,19 @@ "Type": "Task", "End": true, "Comment": "adds enrollee to the men's health program", - "Resource": "/state-conductor/actions/custom/branching-test-flow/enroll-in-mens-health.sjs" + "Resource": "/state-conductor/actions/custom/branching-test-state-machine/enroll-in-mens-health.sjs" }, "enroll-in-womens-health": { "Type": "Task", "End": true, "Comment": "adds enrollee to the womens's health program", - "Resource": "/state-conductor/actions/custom/branching-test-flow/enroll-in-womens-health.sjs" + "Resource": "/state-conductor/actions/custom/branching-test-state-machine/enroll-in-womens-health.sjs" }, "has-undetermined-gender": { "Type": "Task", "End": true, "Comment": "flags enrollee for follow-up", - "Resource": "/state-conductor/actions/custom/branching-test-flow/flag-for-follow-up.sjs" + "Resource": "/state-conductor/actions/custom/branching-test-state-machine/flag-for-follow-up.sjs" } } } diff --git a/state-conductor-example/src/main/ml-data/state-conductor-flow/chaining-flow-A.asl.json b/state-conductor-example/src/main/ml-data/state-conductor-flow/chaining-state-machine-A.asl.json similarity index 68% rename from state-conductor-example/src/main/ml-data/state-conductor-flow/chaining-flow-A.asl.json rename to state-conductor-example/src/main/ml-data/state-conductor-flow/chaining-state-machine-A.asl.json index bccafe31..0dd15e2f 100644 --- a/state-conductor-example/src/main/ml-data/state-conductor-flow/chaining-flow-A.asl.json +++ b/state-conductor-example/src/main/ml-data/state-conductor-flow/chaining-state-machine-A.asl.json @@ -1,5 +1,5 @@ { - "Comment": "example of one flow that kicks off another", + "Comment": "example of one stateMachine that kicks off another", "mlDomain": { "context": [ { @@ -13,7 +13,7 @@ "add-collections": { "Type": "Task", "End": true, - "Comment": "adds a collection which chaining-flow-B should pick up on", + "Comment": "adds a collection which chaining-state-machine-B should pick up on", "Resource": "/state-conductor/actions/common/add-collections.sjs", "Parameters": { "collections": ["chain2"] diff --git a/state-conductor-example/src/main/ml-data/state-conductor-flow/chaining-flow-B.asl.json b/state-conductor-example/src/main/ml-data/state-conductor-flow/chaining-state-machine-B.asl.json similarity index 80% rename from state-conductor-example/src/main/ml-data/state-conductor-flow/chaining-flow-B.asl.json rename to state-conductor-example/src/main/ml-data/state-conductor-flow/chaining-state-machine-B.asl.json index 2b6dd927..06f50246 100644 --- a/state-conductor-example/src/main/ml-data/state-conductor-flow/chaining-flow-B.asl.json +++ b/state-conductor-example/src/main/ml-data/state-conductor-flow/chaining-state-machine-B.asl.json @@ -1,5 +1,5 @@ { - "Comment": "Example of a flow that picks up where another left off", + "Comment": "Example of a stateMachine that picks up where another left off", "mlDomain": { "context": [ { diff --git a/state-conductor-example/src/main/ml-data/state-conductor-flow/collections.properties b/state-conductor-example/src/main/ml-data/state-conductor-flow/collections.properties index 49849826..774560e8 100644 --- a/state-conductor-example/src/main/ml-data/state-conductor-flow/collections.properties +++ b/state-conductor-example/src/main/ml-data/state-conductor-flow/collections.properties @@ -1 +1 @@ -*=state-conductor-flow \ No newline at end of file +*=state-conductor-state-machine \ No newline at end of file diff --git a/state-conductor-example/src/main/ml-data/state-conductor-flow/envelope-flow.asl.json b/state-conductor-example/src/main/ml-data/state-conductor-flow/envelope-state-machine.asl.json similarity index 100% rename from state-conductor-example/src/main/ml-data/state-conductor-flow/envelope-flow.asl.json rename to state-conductor-example/src/main/ml-data/state-conductor-flow/envelope-state-machine.asl.json diff --git a/state-conductor-example/src/main/ml-data/state-conductor-flow/eventsTask-flow.asl.json b/state-conductor-example/src/main/ml-data/state-conductor-flow/eventsTask-state-machine.asl.json similarity index 100% rename from state-conductor-example/src/main/ml-data/state-conductor-flow/eventsTask-flow.asl.json rename to state-conductor-example/src/main/ml-data/state-conductor-flow/eventsTask-state-machine.asl.json diff --git a/state-conductor-example/src/main/ml-data/state-conductor-flow/exception-flow.asl.json b/state-conductor-example/src/main/ml-data/state-conductor-flow/exception-state-machine.asl.json similarity index 84% rename from state-conductor-example/src/main/ml-data/state-conductor-flow/exception-flow.asl.json rename to state-conductor-example/src/main/ml-data/state-conductor-flow/exception-state-machine.asl.json index f6a5612f..dfb2d935 100644 --- a/state-conductor-example/src/main/ml-data/state-conductor-flow/exception-flow.asl.json +++ b/state-conductor-example/src/main/ml-data/state-conductor-flow/exception-state-machine.asl.json @@ -1,5 +1,5 @@ { - "Comment": "bad flow demonstrating error catching", + "Comment": "bad stateMachine demonstrating error catching", "mlDomain": { "context": [ { @@ -13,7 +13,7 @@ "runDhf5MakeEnvelopeStep": { "Type": "Task", "End": true, - "Comment": "runs a dhf 5 flow", + "Comment": "runs a dhf 5 stateMachine", "Resource": "/state-conductor/actions/common/dhf/dhf5MakeEnvelopeStep.sjs", "Parameters": { "collections": ["dhf5MakeEnvelopeStep"] diff --git a/state-conductor-example/src/main/ml-data/state-conductor-flow/kafka-data-flow.asl.json b/state-conductor-example/src/main/ml-data/state-conductor-flow/kafka-data-state-machine.asl.json similarity index 100% rename from state-conductor-example/src/main/ml-data/state-conductor-flow/kafka-data-flow.asl.json rename to state-conductor-example/src/main/ml-data/state-conductor-flow/kafka-data-state-machine.asl.json diff --git a/state-conductor-example/src/main/ml-data/state-conductor-flow/periodic-flow.asl.json b/state-conductor-example/src/main/ml-data/state-conductor-flow/periodic-state-machine.asl.json similarity index 83% rename from state-conductor-example/src/main/ml-data/state-conductor-flow/periodic-flow.asl.json rename to state-conductor-example/src/main/ml-data/state-conductor-flow/periodic-state-machine.asl.json index 347db9c9..83fb7ef1 100644 --- a/state-conductor-example/src/main/ml-data/state-conductor-flow/periodic-flow.asl.json +++ b/state-conductor-example/src/main/ml-data/state-conductor-flow/periodic-state-machine.asl.json @@ -14,7 +14,7 @@ "log-message": { "Type": "Task", "Comment": "announces the time", - "Resource": "/ext/state-conductor/periodic-flow/town-crier.sjs", + "Resource": "/ext/state-conductor/periodic-state-machine/town-crier.sjs", "Next": "success" }, "success": { diff --git a/state-conductor-example/src/main/ml-data/state-conductor-flow/permissions.properties b/state-conductor-example/src/main/ml-data/state-conductor-flow/permissions.properties index c3c2df10..3161f325 100644 --- a/state-conductor-example/src/main/ml-data/state-conductor-flow/permissions.properties +++ b/state-conductor-example/src/main/ml-data/state-conductor-flow/permissions.properties @@ -1 +1 @@ -*=state-conductor-job-writer-role,read,state-conductor-job-writer-role,update +*=state-conductor-execution-writer-role,read,state-conductor-execution-writer-role,update diff --git a/state-conductor-example/src/main/ml-data/state-conductor-flow/waitState-events-flow.asl.json b/state-conductor-example/src/main/ml-data/state-conductor-flow/waitState-events-state-machine.asl.json similarity index 100% rename from state-conductor-example/src/main/ml-data/state-conductor-flow/waitState-events-flow.asl.json rename to state-conductor-example/src/main/ml-data/state-conductor-flow/waitState-events-state-machine.asl.json diff --git a/state-conductor-example/src/main/ml-data/state-conductor-flow/waitState-time-flow.asl.json b/state-conductor-example/src/main/ml-data/state-conductor-flow/waitState-time-state-machine.asl.json similarity index 100% rename from state-conductor-example/src/main/ml-data/state-conductor-flow/waitState-time-flow.asl.json rename to state-conductor-example/src/main/ml-data/state-conductor-flow/waitState-time-state-machine.asl.json diff --git a/state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-flow/enroll-in-mens-health.sjs b/state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-state-machine/enroll-in-mens-health.sjs similarity index 100% rename from state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-flow/enroll-in-mens-health.sjs rename to state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-state-machine/enroll-in-mens-health.sjs diff --git a/state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-flow/enroll-in-womens-health.sjs b/state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-state-machine/enroll-in-womens-health.sjs similarity index 100% rename from state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-flow/enroll-in-womens-health.sjs rename to state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-state-machine/enroll-in-womens-health.sjs diff --git a/state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-flow/flag-for-follow-up.sjs b/state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-state-machine/flag-for-follow-up.sjs similarity index 100% rename from state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-flow/flag-for-follow-up.sjs rename to state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-state-machine/flag-for-follow-up.sjs diff --git a/state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-flow/gender-is-female.sjs b/state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-state-machine/gender-is-female.sjs similarity index 100% rename from state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-flow/gender-is-female.sjs rename to state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-state-machine/gender-is-female.sjs diff --git a/state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-flow/gender-is-male.sjs b/state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-state-machine/gender-is-male.sjs similarity index 100% rename from state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-flow/gender-is-male.sjs rename to state-conductor-example/src/main/ml-modules/root/state-conductor/actions/custom/branching-test-state-machine/gender-is-male.sjs diff --git a/state-conductor-example/src/main/ml-modules/root/state-conductor/configuration.sjs b/state-conductor-example/src/main/ml-modules/root/state-conductor/configuration.sjs index 71d06030..83df443c 100644 --- a/state-conductor-example/src/main/ml-modules/root/state-conductor/configuration.sjs +++ b/state-conductor-example/src/main/ml-modules/root/state-conductor/configuration.sjs @@ -1,17 +1,17 @@ const configuration = { databases: { - jobs: 'state-conductor-jobs', + executions: 'state-conductor-executions', triggers: 'state-conductor-triggers', schemas: 'state-conductor-schemas', }, collections: { item: 'state-conductor-item', - job: 'stateConductorJob', - flow: 'state-conductor-flow', + execution: 'stateConductorExecution', + stateMachine: 'state-conductor-state-machine', }, URIPrefixes: { - flow: '/state-conductor-flow/', - job: '/stateConductorJob/', + stateMachine: '/state-conductor-state-machine/', + execution: '/stateConductorExecution/', }, }; diff --git a/state-conductor-example/src/test/java/com/marklogic/DriverServiceTest.java b/state-conductor-example/src/test/java/com/marklogic/DriverServiceTest.java index 4762ee07..3a1fdbd1 100644 --- a/state-conductor-example/src/test/java/com/marklogic/DriverServiceTest.java +++ b/state-conductor-example/src/test/java/com/marklogic/DriverServiceTest.java @@ -29,12 +29,12 @@ public class DriverServiceTest extends AbstractStateConductorRestTest { public void setup() throws IOException { now = LocalDateTime.now(); - // add flow docs - DocumentMetadataHandle flowMeta = new DocumentMetadataHandle(); - flowMeta.getCollections().add("state-conductor-flow"); + // add stateMachine docs + DocumentMetadataHandle stateMachineMeta = new DocumentMetadataHandle(); + stateMachineMeta.getCollections().add("state-conductor-state-machine"); DocumentWriteSet batch = getContentManager().newWriteSet(); - batch.add("/state-conductor-flow/rest-test-flow3.asl.json", flowMeta, loadFileResource("flows/rest-test-flow3.asl.json")); - batch.add("/state-conductor-flow/rest-test-flow4.asl.json", flowMeta, loadFileResource("flows/rest-test-flow4.asl.json")); + batch.add("/state-conductor-state-machine/rest-test-state-machine3.asl.json", stateMachineMeta, loadFileResource("stateMachines/rest-test-state-machine3.asl.json")); + batch.add("/state-conductor-state-machine/rest-test-state-machine4.asl.json", stateMachineMeta, loadFileResource("stateMachines/rest-test-state-machine4.asl.json")); getContentManager().write(batch); // add data docs @@ -51,26 +51,26 @@ public void setup() throws IOException { tokens.put("%DATE-YESTERDAY%", now.minusDays(1).format(DateTimeFormatter.ISO_DATE_TIME)); tokens.put("%DATE-TOMORROW%", now.plusDays(1).format(DateTimeFormatter.ISO_DATE_TIME)); - // add job docs - batch = getJobsManager().newWriteSet(); - DocumentMetadataHandle jobMeta = new DocumentMetadataHandle(); - jobMeta.getCollections().add("stateConductorJob"); - jobMeta.getPermissions().add("state-conductor-reader-role", DocumentMetadataHandle.Capability.READ); - jobMeta.getPermissions().add("state-conductor-job-writer-role", DocumentMetadataHandle.Capability.UPDATE); - batch.add("/test/stateConductorJob/job4.json", jobMeta, loadTokenizedResource("jobs/job4.json", tokens)); - batch.add("/test/stateConductorJob/job5.json", jobMeta, loadTokenizedResource("jobs/job5.json", tokens)); - batch.add("/test/stateConductorJob/job6.json", jobMeta, loadTokenizedResource("jobs/job6.json", tokens)); - batch.add("/test/stateConductorJob/job7.json", jobMeta, loadTokenizedResource("jobs/job7.json", tokens)); - getJobsManager().write(batch); + // add execution docs + batch = getExecutionsManager().newWriteSet(); + DocumentMetadataHandle executionMeta = new DocumentMetadataHandle(); + executionMeta.getCollections().add("stateConductorExecution"); + executionMeta.getPermissions().add("state-conductor-reader-role", DocumentMetadataHandle.Capability.READ); + executionMeta.getPermissions().add("state-conductor-execution-writer-role", DocumentMetadataHandle.Capability.UPDATE); + batch.add("/test/stateConductorExecution/execution4.json", executionMeta, loadTokenizedResource("executions/execution4.json", tokens)); + batch.add("/test/stateConductorExecution/execution5.json", executionMeta, loadTokenizedResource("executions/execution5.json", tokens)); + batch.add("/test/stateConductorExecution/execution6.json", executionMeta, loadTokenizedResource("executions/execution6.json", tokens)); + batch.add("/test/stateConductorExecution/execution7.json", executionMeta, loadTokenizedResource("executions/execution7.json", tokens)); + getExecutionsManager().write(batch); } @AfterEach public void teardown() { - clearTestJobs(); + clearTestExecutions(); } @Test - public void testListJobsDefault() { + public void testListExecutionsDefault() { given(). log().uri(). when(). @@ -83,7 +83,7 @@ public void testListJobsDefault() { } @Test - public void testListJobsFilterByCount() { + public void testListExecutionsFilterByCount() { given(). log().uri(). when(). @@ -130,12 +130,12 @@ public void testListJobsFilterByCount() { } @Test - public void testListJobsFilterByNames() { + public void testListExecutionsFilterByNames() { // list of names given(). log().uri(). when(). - queryParam("rs:flowNames", "rest-test-flow3,rest-test-flow4"). + queryParam("rs:names", "rest-test-state-machine3,rest-test-state-machine4"). get("/v1/resources/state-conductor-driver"). then(). log().body(). @@ -147,7 +147,7 @@ public void testListJobsFilterByNames() { given(). log().uri(). when(). - queryParam("rs:flowNames", "rest-test-flow3"). + queryParam("rs:names", "rest-test-state-machine3"). get("/v1/resources/state-conductor-driver"). then(). log().body(). @@ -159,7 +159,7 @@ public void testListJobsFilterByNames() { given(). log().uri(). when(). - queryParam("rs:flowNames", "rest-test-flow4"). + queryParam("rs:names", "rest-test-state-machine4"). get("/v1/resources/state-conductor-driver"). then(). log().body(). @@ -169,13 +169,13 @@ public void testListJobsFilterByNames() { } @Test - public void testListJobsFilterByStatus() { + public void testListExecutionsFilterByStatus() { // list of status given(). log().uri(). when(). - queryParam("rs:flowNames", "rest-test-flow3,rest-test-flow4"). - queryParam("rs:flowStatus", "new,working,waiting,complete,failed"). + queryParam("rs:names", "rest-test-state-machine3,rest-test-state-machine4"). + queryParam("rs:status", "new,working,waiting,complete,failed"). get("/v1/resources/state-conductor-driver"). then(). log().body(). @@ -187,39 +187,39 @@ public void testListJobsFilterByStatus() { given(). log().uri(). when(). - queryParam("rs:flowNames", "rest-test-flow3,rest-test-flow4"). - queryParam("rs:flowStatus", "new"). + queryParam("rs:names", "rest-test-state-machine3,rest-test-state-machine4"). + queryParam("rs:status", "new"). get("/v1/resources/state-conductor-driver"). then(). log().body(). statusCode(200). contentType(ContentType.JSON). body("size()", equalTo(3)). - body(".", hasItem("/test/stateConductorJob/job4.json")). - body(".", hasItem("/test/stateConductorJob/job5.json")). - body(".", hasItem("/test/stateConductorJob/job7.json")); + body(".", hasItem("/test/stateConductorExecution/execution4.json")). + body(".", hasItem("/test/stateConductorExecution/execution5.json")). + body(".", hasItem("/test/stateConductorExecution/execution7.json")); // individual status given(). log().uri(). when(). - queryParam("rs:flowNames", "rest-test-flow3,rest-test-flow4"). - queryParam("rs:flowStatus", "working"). + queryParam("rs:names", "rest-test-state-machine3,rest-test-state-machine4"). + queryParam("rs:status", "working"). get("/v1/resources/state-conductor-driver"). then(). log().body(). statusCode(200). contentType(ContentType.JSON). body("size()", equalTo(1)). - body(".", hasItem("/test/stateConductorJob/job6.json")); + body(".", hasItem("/test/stateConductorExecution/execution6.json")); } @Test - public void testListJobsFilterByStart() { + public void testListExecutionsFilterByStart() { given(). log().uri(). when(). - queryParam("rs:flowNames", "rest-test-flow3,rest-test-flow4"). + queryParam("rs:names", "rest-test-state-machine3,rest-test-state-machine4"). queryParam("rs:startDate", now.minusDays(1).format(DateTimeFormatter.ISO_DATE_TIME)). get("/v1/resources/state-conductor-driver"). then(). @@ -231,7 +231,7 @@ public void testListJobsFilterByStart() { given(). log().uri(). when(). - queryParam("rs:flowNames", "rest-test-flow3,rest-test-flow4"). + queryParam("rs:names", "rest-test-state-machine3,rest-test-state-machine4"). queryParam("rs:startDate", now.format(DateTimeFormatter.ISO_DATE_TIME)). get("/v1/resources/state-conductor-driver"). then(). @@ -239,14 +239,14 @@ public void testListJobsFilterByStart() { statusCode(200). contentType(ContentType.JSON). body("size()", equalTo(3)). - body(".", hasItem("/test/stateConductorJob/job4.json")). - body(".", hasItem("/test/stateConductorJob/job6.json")). - body(".", hasItem("/test/stateConductorJob/job7.json")); + body(".", hasItem("/test/stateConductorExecution/execution4.json")). + body(".", hasItem("/test/stateConductorExecution/execution6.json")). + body(".", hasItem("/test/stateConductorExecution/execution7.json")); given(). log().uri(). when(). - queryParam("rs:flowNames", "rest-test-flow3,rest-test-flow4"). + queryParam("rs:names", "rest-test-state-machine3,rest-test-state-machine4"). queryParam("rs:startDate", now.plusDays(1).format(DateTimeFormatter.ISO_DATE_TIME)). get("/v1/resources/state-conductor-driver"). then(). @@ -254,12 +254,12 @@ public void testListJobsFilterByStart() { statusCode(200). contentType(ContentType.JSON). body("size()", equalTo(1)). - body(".", hasItem("/test/stateConductorJob/job6.json")); + body(".", hasItem("/test/stateConductorExecution/execution6.json")); given(). log().uri(). when(). - queryParam("rs:flowNames", "rest-test-flow3,rest-test-flow4"). + queryParam("rs:names", "rest-test-state-machine3,rest-test-state-machine4"). queryParam("rs:startDate", now.plusDays(2).format(DateTimeFormatter.ISO_DATE_TIME)). get("/v1/resources/state-conductor-driver"). then(). @@ -270,11 +270,11 @@ public void testListJobsFilterByStart() { } @Test - public void testListJobsFilterByEnd() { + public void testListExecutionsFilterByEnd() { given(). log().uri(). when(). - queryParam("rs:flowNames", "rest-test-flow3,rest-test-flow4"). + queryParam("rs:names", "rest-test-state-machine3,rest-test-state-machine4"). queryParam("rs:endDate", now.plusDays(2).format(DateTimeFormatter.ISO_DATE_TIME)). get("/v1/resources/state-conductor-driver"). then(). @@ -286,7 +286,7 @@ public void testListJobsFilterByEnd() { given(). log().uri(). when(). - queryParam("rs:flowNames", "rest-test-flow3,rest-test-flow4"). + queryParam("rs:names", "rest-test-state-machine3,rest-test-state-machine4"). queryParam("rs:endDate", now.plusDays(1).format(DateTimeFormatter.ISO_DATE_TIME)). get("/v1/resources/state-conductor-driver"). then(). @@ -298,7 +298,7 @@ public void testListJobsFilterByEnd() { given(). log().uri(). when(). - queryParam("rs:flowNames", "rest-test-flow3,rest-test-flow4"). + queryParam("rs:names", "rest-test-state-machine3,rest-test-state-machine4"). queryParam("rs:endDate", now.format(DateTimeFormatter.ISO_DATE_TIME)). get("/v1/resources/state-conductor-driver"). then(). @@ -306,14 +306,14 @@ public void testListJobsFilterByEnd() { statusCode(200). contentType(ContentType.JSON). body("size()", equalTo(3)). - body(".", hasItem("/test/stateConductorJob/job4.json")). - body(".", hasItem("/test/stateConductorJob/job5.json")). - body(".", hasItem("/test/stateConductorJob/job7.json")); + body(".", hasItem("/test/stateConductorExecution/execution4.json")). + body(".", hasItem("/test/stateConductorExecution/execution5.json")). + body(".", hasItem("/test/stateConductorExecution/execution7.json")); given(). log().uri(). when(). - queryParam("rs:flowNames", "rest-test-flow3,rest-test-flow4"). + queryParam("rs:names", "rest-test-state-machine3,rest-test-state-machine4"). queryParam("rs:endDate", now.minusDays(1).format(DateTimeFormatter.ISO_DATE_TIME)). get("/v1/resources/state-conductor-driver"). then(). @@ -321,12 +321,12 @@ public void testListJobsFilterByEnd() { statusCode(200). contentType(ContentType.JSON). body("size()", equalTo(1)). - body(".", hasItem("/test/stateConductorJob/job5.json")); + body(".", hasItem("/test/stateConductorExecution/execution5.json")); given(). log().uri(). when(). - queryParam("rs:flowNames", "rest-test-flow3,rest-test-flow4"). + queryParam("rs:names", "rest-test-state-machine3,rest-test-state-machine4"). queryParam("rs:endDate", now.minusDays(2).format(DateTimeFormatter.ISO_DATE_TIME)). get("/v1/resources/state-conductor-driver"). then(). @@ -337,56 +337,56 @@ public void testListJobsFilterByEnd() { } @Test - public void testProcessJob() { - // start flow + public void testProcessExecution() { + // start stateMachine given(). log().uri(). when(). - queryParam("rs:uri", "/test/stateConductorJob/job4.json"). + queryParam("rs:uri", "/test/stateConductorExecution/execution4.json"). put("/v1/resources/state-conductor-driver"). then(). log().body(). statusCode(200). contentType(ContentType.JSON). body("reschedule", equalTo(true)); - // flow step 1 + // stateMachine step 1 given(). log().uri(). when(). - queryParam("rs:uri", "/test/stateConductorJob/job4.json"). + queryParam("rs:uri", "/test/stateConductorExecution/execution4.json"). put("/v1/resources/state-conductor-driver"). then(). log().body(). statusCode(200). contentType(ContentType.JSON). body("reschedule", equalTo(true)); - // flow step 2 + // stateMachine step 2 given(). log().uri(). when(). - queryParam("rs:uri", "/test/stateConductorJob/job4.json"). + queryParam("rs:uri", "/test/stateConductorExecution/execution4.json"). put("/v1/resources/state-conductor-driver"). then(). log().body(). statusCode(200). contentType(ContentType.JSON). body("reschedule", equalTo(true)); - // flow step 3 + // stateMachine step 3 given(). log().uri(). when(). - queryParam("rs:uri", "/test/stateConductorJob/job4.json"). + queryParam("rs:uri", "/test/stateConductorExecution/execution4.json"). put("/v1/resources/state-conductor-driver"). then(). log().body(). statusCode(200). contentType(ContentType.JSON). body("reschedule", equalTo(true)); - // flow final step + // stateMachine final step given(). log().uri(). when(). - queryParam("rs:uri", "/test/stateConductorJob/job4.json"). + queryParam("rs:uri", "/test/stateConductorExecution/execution4.json"). put("/v1/resources/state-conductor-driver"). then(). log().body(). @@ -396,45 +396,45 @@ public void testProcessJob() { } @Test - public void testProcessJob2() { - // start flow + public void testProcessExecution2() { + // start stateMachine given(). log().uri(). when(). - queryParam("rs:uri", "/test/stateConductorJob/job7.json"). + queryParam("rs:uri", "/test/stateConductorExecution/execution7.json"). put("/v1/resources/state-conductor-driver"). then(). log().body(). statusCode(200). contentType(ContentType.JSON). body("reschedule", equalTo(true)); - // flow step 1 + // stateMachine step 1 given(). log().uri(). when(). - queryParam("rs:uri", "/test/stateConductorJob/job7.json"). + queryParam("rs:uri", "/test/stateConductorExecution/execution7.json"). put("/v1/resources/state-conductor-driver"). then(). log().body(). statusCode(200). contentType(ContentType.JSON). body("reschedule", equalTo(true)); - // flow step 2 + // stateMachine step 2 given(). log().uri(). when(). - queryParam("rs:uri", "/test/stateConductorJob/job7.json"). + queryParam("rs:uri", "/test/stateConductorExecution/execution7.json"). put("/v1/resources/state-conductor-driver"). then(). log().body(). statusCode(200). contentType(ContentType.JSON). body("reschedule", equalTo(true)); - // flow final step + // stateMachine final step given(). log().uri(). when(). - queryParam("rs:uri", "/test/stateConductorJob/job7.json"). + queryParam("rs:uri", "/test/stateConductorExecution/execution7.json"). put("/v1/resources/state-conductor-driver"). then(). log().body(). @@ -448,7 +448,7 @@ public void testProcessBadUri() { } @Test - public void testProcessJobMissingUri() { + public void testProcessExecutionMissingUri() { given(). log().uri(). when(). diff --git a/state-conductor-example/src/test/java/com/marklogic/JobsServiceTest.java b/state-conductor-example/src/test/java/com/marklogic/ExecutionsServiceTest.java similarity index 61% rename from state-conductor-example/src/test/java/com/marklogic/JobsServiceTest.java rename to state-conductor-example/src/test/java/com/marklogic/ExecutionsServiceTest.java index e6e5daf8..4194e703 100644 --- a/state-conductor-example/src/test/java/com/marklogic/JobsServiceTest.java +++ b/state-conductor-example/src/test/java/com/marklogic/ExecutionsServiceTest.java @@ -12,26 +12,24 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.xml.namespace.QName; import java.io.IOException; import static io.restassured.RestAssured.*; -import static io.restassured.matcher.RestAssuredMatchers.*; import static org.hamcrest.Matchers.*; import static org.junit.jupiter.api.Assertions.*; -public class JobsServiceTest extends AbstractStateConductorRestTest { +public class ExecutionsServiceTest extends AbstractStateConductorRestTest { - Logger logger = LoggerFactory.getLogger(JobsServiceTest.class); + Logger logger = LoggerFactory.getLogger(ExecutionsServiceTest.class); @BeforeEach public void setup() throws IOException { - // add flow docs - DocumentMetadataHandle flowMeta = new DocumentMetadataHandle(); - flowMeta.getCollections().add("state-conductor-flow"); + // add stateMachine docs + DocumentMetadataHandle stateMachineMeta = new DocumentMetadataHandle(); + stateMachineMeta.getCollections().add("state-conductor-state-machine"); DocumentWriteSet batch = getContentManager().newWriteSet(); - batch.add("/state-conductor-flow/rest-test-flow.asl.json", flowMeta, loadFileResource("flows/rest-test-flow.asl.json")); - batch.add("/state-conductor-flow/rest-test-flow2.asl.json", flowMeta, loadFileResource("flows/rest-test-flow2.asl.json")); + batch.add("/state-conductor-state-machine/rest-test-state-machine.asl.json", stateMachineMeta, loadFileResource("stateMachines/rest-test-state-machine.asl.json")); + batch.add("/state-conductor-state-machine/rest-test-state-machine2.asl.json", stateMachineMeta, loadFileResource("stateMachines/rest-test-state-machine2.asl.json")); getContentManager().write(batch); // add data docs @@ -43,17 +41,17 @@ public void setup() throws IOException { @AfterEach public void teardown() { - clearTestJobs(); + clearTestExecutions(); } @Test - public void testCreateJob() { + public void testCreateExecution() { Response resp = given(). log().uri(). when(). queryParam("rs:uris", "/test/doc1.json"). - queryParam("rs:flowName", "rest-test-flow"). - put("/v1/resources/state-conductor-jobs"). + queryParam("rs:name", "rest-test-state-machine"). + put("/v1/resources/state-conductor-executions"). then(). log().body(). statusCode(201). @@ -69,13 +67,13 @@ public void testCreateJob() { } @Test - public void testCreateJobs() { + public void testCreateExecutions() { Response resp = given(). log().uri(). when(). queryParam("rs:uris", "/test/doc1.json,/test/doc2.json"). - queryParam("rs:flowName", "rest-test-flow2"). - put("/v1/resources/state-conductor-jobs"). + queryParam("rs:name", "rest-test-state-machine2"). + put("/v1/resources/state-conductor-executions"). then(). log().body(). statusCode(201). @@ -91,77 +89,77 @@ public void testCreateJobs() { } @Test - public void testCreateJobMissingUri() { + public void testCreateExecutionMissingUri() { given(). log().uri(). when(). - queryParam("rs:flowName", "rest-test-flow"). - put("/v1/resources/state-conductor-jobs"). + queryParam("rs:name", "rest-test-state-machine"). + put("/v1/resources/state-conductor-executions"). then(). log().body(). statusCode(400); } @Test - public void testCreateJobInvalidUri() { + public void testCreateExecutionInvalidUri() { given(). log().uri(). when(). queryParam("rs:uris", "/test/doc99999.json"). - queryParam("rs:flowName", "rest-test-flow"). - put("/v1/resources/state-conductor-jobs"). + queryParam("rs:name", "rest-test-state-machine"). + put("/v1/resources/state-conductor-executions"). then(). log().body(). statusCode(400); } @Test - public void testCreateJobMissingFlowName() { + public void testCreateExecutionMissingStateMachineName() { given(). log().uri(). when(). queryParam("rs:uris", "/test/doc1.json"). - put("/v1/resources/state-conductor-jobs"). + put("/v1/resources/state-conductor-executions"). then(). log().body(). statusCode(400); } @Test - public void testCreateJobBadFlowName() { + public void testCreateExecutionBadStateMachineName() { given(). log().uri(). when(). queryParam("rs:uris", "/test/doc1.json"). - queryParam("rs:flowName", "non-existent-flow"). - put("/v1/resources/state-conductor-jobs"). + queryParam("rs:name", "non-existent-state-machine"). + put("/v1/resources/state-conductor-executions"). then(). log().body(). statusCode(404); } @Test - public void testGetJobId() { - // no jobs yet + public void testGetExecutionId() { + // no executions yet given(). log().uri(). when(). queryParam("rs:uri", "/test/doc2.json"). - queryParam("rs:flowName", "rest-test-flow"). - get("/v1/resources/state-conductor-jobs"). + queryParam("rs:name", "rest-test-state-machine"). + get("/v1/resources/state-conductor-executions"). then(). log().body(). statusCode(200). contentType(ContentType.JSON). body("size()", equalTo(0)); - // create job + // create execution Response resp = given(). log().uri(). when(). queryParam("rs:uris", "/test/doc1.json"). - queryParam("rs:flowName", "rest-test-flow"). - put("/v1/resources/state-conductor-jobs"). + queryParam("rs:name", "rest-test-state-machine"). + put("/v1/resources/state-conductor-executions"). then(). log().body(). statusCode(201). @@ -174,13 +172,13 @@ public void testGetJobId() { String uuid = respObj.get("/test/doc1.json").asText(); assertTrue(uuid.length() > 0); - // get job id + // get execution id given(). log().uri(). when(). queryParam("rs:uri", "/test/doc1.json"). - queryParam("rs:flowName", "rest-test-flow"). - get("/v1/resources/state-conductor-jobs"). + queryParam("rs:name", "rest-test-state-machine"). + get("/v1/resources/state-conductor-executions"). then(). log().body(). statusCode(200). @@ -190,50 +188,50 @@ public void testGetJobId() { } @Test - public void testGetJobIdMissingUri() { + public void testGetExecutionIdMissingUri() { given(). log().uri(). when(). - queryParam("rs:flowName", "rest-test-flow"). - get("/v1/resources/state-conductor-jobs"). + queryParam("rs:name", "rest-test-state-machine"). + get("/v1/resources/state-conductor-executions"). then(). log().body(). statusCode(400); } @Test - public void testGetJobIdInvalidUri() { + public void testGetExecutionIdInvalidUri() { given(). log().uri(). when(). queryParam("rs:uri", "/test/doc999999.json"). - queryParam("rs:flowName", "rest-test-flow"). - get("/v1/resources/state-conductor-jobs"). + queryParam("rs:name", "rest-test-state-machine"). + get("/v1/resources/state-conductor-executions"). then(). log().body(). statusCode(404); } @Test - public void testGetJobIdMissingFlowName() { + public void testGetExecutionIdMissingStateMachineName() { given(). log().uri(). when(). queryParam("rs:uri", "/test/doc1.json"). - get("/v1/resources/state-conductor-jobs"). + get("/v1/resources/state-conductor-executions"). then(). log().body(). statusCode(400); } @Test - public void testGetJobIdInvalidFlowName() { + public void testGetExecutionIdInvalidStateMachineName() { given(). log().uri(). when(). queryParam("rs:uri", "/test/doc1.json"). - queryParam("rs:flowName", "non-existent-flow"). - get("/v1/resources/state-conductor-jobs"). + queryParam("rs:name", "non-existent-state-machine"). + get("/v1/resources/state-conductor-executions"). then(). log().body(). statusCode(404); diff --git a/state-conductor-example/src/test/java/com/marklogic/FlowServiceTest.java b/state-conductor-example/src/test/java/com/marklogic/StateMachineServiceTest.java similarity index 50% rename from state-conductor-example/src/test/java/com/marklogic/FlowServiceTest.java rename to state-conductor-example/src/test/java/com/marklogic/StateMachineServiceTest.java index 07a4cead..64505098 100644 --- a/state-conductor-example/src/test/java/com/marklogic/FlowServiceTest.java +++ b/state-conductor-example/src/test/java/com/marklogic/StateMachineServiceTest.java @@ -14,50 +14,48 @@ import java.io.IOException; import static io.restassured.RestAssured.*; -import static io.restassured.matcher.RestAssuredMatchers.*; import static org.hamcrest.Matchers.*; -import static org.junit.jupiter.api.Assertions.*; -public class FlowServiceTest extends AbstractStateConductorRestTest { +public class StateMachineServiceTest extends AbstractStateConductorRestTest { - Logger logger = LoggerFactory.getLogger(JobsServiceTest.class); + Logger logger = LoggerFactory.getLogger(ExecutionsServiceTest.class); @BeforeEach public void setup() throws IOException { - // add flow docs - DocumentMetadataHandle flowMeta = new DocumentMetadataHandle(); - flowMeta.getCollections().add("state-conductor-flow"); + // add stateMachine docs + DocumentMetadataHandle stateMachineMeta = new DocumentMetadataHandle(); + stateMachineMeta.getCollections().add("state-conductor-state-machine"); DocumentWriteSet batch = getContentManager().newWriteSet(); - batch.add("/state-conductor-flow/rest-test-flow.asl.json", flowMeta, loadFileResource("flows/rest-test-flow.asl.json")); - batch.add("/state-conductor-flow/rest-test-flow2.asl.json", flowMeta, loadFileResource("flows/rest-test-flow2.asl.json")); + batch.add("/state-conductor-state-machine/rest-test-state-machine.asl.json", stateMachineMeta, loadFileResource("stateMachines/rest-test-state-machine.asl.json")); + batch.add("/state-conductor-state-machine/rest-test-state-machine2.asl.json", stateMachineMeta, loadFileResource("stateMachines/rest-test-state-machine2.asl.json")); getContentManager().write(batch); } @Test - public void testListAllFlows() { + public void testListAllStateMachines() { given(). log().uri(). when(). - get("/v1/resources/state-conductor-flows"). + get("/v1/resources/state-conductor-state-machines"). then(). log().body(). statusCode(200). contentType(ContentType.JSON). - body("rest-test-flow", notNullValue()). - body("rest-test-flow.StartAt", equalTo("add-collection-1")). - body("rest-test-flow.States", notNullValue()). - body("rest-test-flow2", notNullValue()). - body("rest-test-flow2.StartAt", equalTo("test-data")). - body("rest-test-flow2.States", notNullValue()); + body("rest-test-state-machine", notNullValue()). + body("rest-test-state-machine.StartAt", equalTo("add-collection-1")). + body("rest-test-state-machine.States", notNullValue()). + body("rest-test-state-machine2", notNullValue()). + body("rest-test-state-machine2.StartAt", equalTo("test-data")). + body("rest-test-state-machine2.States", notNullValue()); } @Test - public void testListNamedFlow() { + public void testListNamedStateMachine() { given(). log().uri(). when(). - queryParam("rs:flowName", "rest-test-flow"). - get("/v1/resources/state-conductor-flows"). + queryParam("rs:stateMachineName", "rest-test-state-machine"). + get("/v1/resources/state-conductor-state-machines"). then(). log().body(). statusCode(200). @@ -71,8 +69,8 @@ public void testListNamedFlow() { given(). log().uri(). when(). - queryParam("rs:flowName", "rest-test-flow2"). - get("/v1/resources/state-conductor-flows"). + queryParam("rs:stateMachineName", "rest-test-state-machine2"). + get("/v1/resources/state-conductor-state-machines"). then(). log().body(). statusCode(200). @@ -84,12 +82,12 @@ public void testListNamedFlow() { } @Test - public void testListInvalidNamedFlow() { + public void testListInvalidNamedStateMachine() { given(). log().uri(). when(). - queryParam("rs:flowName", "non-existent-flow"). - get("/v1/resources/state-conductor-flows"). + queryParam("rs:stateMachineName", "non-existent-state-machine"). + get("/v1/resources/state-conductor-state-machines"). then(). log().body(). statusCode(404). @@ -97,16 +95,16 @@ public void testListInvalidNamedFlow() { } @Test - public void testInsertFlow() throws FileNotFoundException { - FileHandle fileHandle = loadFileResource("flows/rest-test-flow.asl.json"); - // insert a flow + public void testInsertStateMachine() throws FileNotFoundException { + FileHandle fileHandle = loadFileResource("stateMachines/rest-test-state-machine.asl.json"); + // insert a stateMachine given(). log().uri(). when(). - queryParam("rs:flowName", "rest-test-flow3"). + queryParam("rs:stateMachineName", "rest-test-state-machine3"). contentType(ContentType.JSON). body(fileHandle.get()). - put("/v1/resources/state-conductor-flows"). + put("/v1/resources/state-conductor-state-machines"). then(). log().body(). statusCode(201); @@ -114,8 +112,8 @@ public void testInsertFlow() throws FileNotFoundException { given(). log().uri(). when(). - queryParam("rs:flowName", "rest-test-flow3"). - get("/v1/resources/state-conductor-flows"). + queryParam("rs:stateMachineName", "rest-test-state-machine3"). + get("/v1/resources/state-conductor-state-machines"). then(). log().body(). statusCode(200). @@ -128,16 +126,16 @@ public void testInsertFlow() throws FileNotFoundException { } @Test - public void testInsertUnnamedFlow() throws FileNotFoundException { - FileHandle fileHandle = loadFileResource("flows/rest-test-flow.asl.json"); + public void testInsertUnnamedStateMachine() throws FileNotFoundException { + FileHandle fileHandle = loadFileResource("stateMachines/rest-test-state-machine.asl.json"); given(). log().uri(). when(). - queryParam("rs:flowName", ""). + queryParam("rs:stateMachineName", ""). contentType(ContentType.JSON). body(fileHandle.get()). - put("/v1/resources/state-conductor-flows"). + put("/v1/resources/state-conductor-state-machines"). then(). log().body(). statusCode(400); @@ -147,68 +145,68 @@ public void testInsertUnnamedFlow() throws FileNotFoundException { when(). contentType(ContentType.JSON). body(fileHandle.get()). - put("/v1/resources/state-conductor-flows"). + put("/v1/resources/state-conductor-state-machines"). then(). log().body(). statusCode(400); } @Test - public void testInsertMissingFlow() { + public void testInsertMissingStateMachine() { given(). log().uri(). when(). - queryParam("rs:flowName", "rest-test-flow3"). + queryParam("rs:stateMachineName", "rest-test-state-machine3"). contentType(ContentType.JSON). - put("/v1/resources/state-conductor-flows"). + put("/v1/resources/state-conductor-state-machines"). then(). log().body(). statusCode(400); } @Test - public void testInsertNonJsonFlow() throws FileNotFoundException { - FileHandle fileHandle = loadFileResource("flows/rest-test-flow.asl.json"); + public void testInsertNonJsonStateMachine() throws FileNotFoundException { + FileHandle fileHandle = loadFileResource("stateMachines/rest-test-state-machine.asl.json"); given(). log().uri(). when(). - queryParam("rs:flowName", "rest-test-flow3"). + queryParam("rs:stateMachineName", "rest-test-state-machine3"). contentType(ContentType.TEXT). body(fileHandle.get()). - put("/v1/resources/state-conductor-flows"). + put("/v1/resources/state-conductor-state-machines"). then(). log().body(). statusCode(400); } @Test - public void testInsertInvalidFlow() throws FileNotFoundException { - FileHandle fileHandle = loadFileResource("flows/invalid-test-flow.asl.json"); + public void testInsertInvalidStateMachine() throws FileNotFoundException { + FileHandle fileHandle = loadFileResource("stateMachines/invalid-test-state-machine.asl.json"); given(). log().uri(). when(). - queryParam("rs:flowName", "rest-test-flow3"). + queryParam("rs:stateMachineName", "rest-test-state-machine3"). contentType(ContentType.JSON). body(fileHandle.get()). - put("/v1/resources/state-conductor-flows"). + put("/v1/resources/state-conductor-state-machines"). then(). log().body(). statusCode(400); } @Test - public void testDeleteFlow() throws FileNotFoundException { - FileHandle fileHandle = loadFileResource("flows/rest-test-flow.asl.json"); - // insert a flow + public void testDeleteStateMachine() throws FileNotFoundException { + FileHandle fileHandle = loadFileResource("stateMachines/rest-test-state-machine.asl.json"); + // insert a stateMachine given(). log().uri(). when(). - queryParam("rs:flowName", "rest-test-flow3"). + queryParam("rs:stateMachineName", "rest-test-state-machine3"). contentType(ContentType.JSON). body(fileHandle.get()). - put("/v1/resources/state-conductor-flows"). + put("/v1/resources/state-conductor-state-machines"). then(). log().body(). statusCode(201); @@ -216,8 +214,8 @@ public void testDeleteFlow() throws FileNotFoundException { given(). log().uri(). when(). - queryParam("rs:flowName", "rest-test-flow3"). - get("/v1/resources/state-conductor-flows"). + queryParam("rs:stateMachineName", "rest-test-state-machine3"). + get("/v1/resources/state-conductor-state-machines"). then(). log().body(). statusCode(200). @@ -228,9 +226,9 @@ public void testDeleteFlow() throws FileNotFoundException { given(). log().uri(). when(). - queryParam("rs:flowName", "rest-test-flow3"). + queryParam("rs:stateMachineName", "rest-test-state-machine3"). contentType(ContentType.JSON). - delete("/v1/resources/state-conductor-flows"). + delete("/v1/resources/state-conductor-state-machines"). then(). log().body(). statusCode(204); @@ -238,21 +236,21 @@ public void testDeleteFlow() throws FileNotFoundException { given(). log().uri(). when(). - queryParam("rs:flowName", "rest-test-flow3"). - get("/v1/resources/state-conductor-flows"). + queryParam("rs:stateMachineName", "rest-test-state-machine3"). + get("/v1/resources/state-conductor-state-machines"). then(). log().body(). statusCode(404); } @Test - public void testDeleteUnnamedFlow() { + public void testDeleteUnnamedStateMachine() { given(). log().uri(). when(). - queryParam("rs:flowName", ""). + queryParam("rs:stateMachineName", ""). contentType(ContentType.JSON). - delete("/v1/resources/state-conductor-flows"). + delete("/v1/resources/state-conductor-state-machines"). then(). log().body(). statusCode(400); @@ -261,7 +259,7 @@ public void testDeleteUnnamedFlow() { log().uri(). when(). contentType(ContentType.JSON). - delete("/v1/resources/state-conductor-flows"). + delete("/v1/resources/state-conductor-state-machines"). then(). log().body(). statusCode(400); diff --git a/state-conductor-example/src/test/java/com/marklogic/StatusServiceTest.java b/state-conductor-example/src/test/java/com/marklogic/StatusServiceTest.java index 07e49e34..3a6f6b00 100644 --- a/state-conductor-example/src/test/java/com/marklogic/StatusServiceTest.java +++ b/state-conductor-example/src/test/java/com/marklogic/StatusServiceTest.java @@ -3,7 +3,6 @@ import com.marklogic.client.document.DocumentWriteSet; import com.marklogic.client.io.DocumentMetadataHandle; import com.marklogic.client.io.FileHandle; -import com.marklogic.client.io.StringHandle; import com.marklogic.ext.AbstractStateConductorRestTest; import io.restassured.http.ContentType; import org.junit.jupiter.api.*; @@ -19,21 +18,21 @@ public class StatusServiceTest extends AbstractStateConductorRestTest { - static FileHandle job1; - static FileHandle job2; - static FileHandle job3; - static FileHandle restTestFlow; - static FileHandle restTestFlow2; + static FileHandle execution1; + static FileHandle execution2; + static FileHandle execution3; + static FileHandle restTestStateMachine; + static FileHandle restTestStateMachine2; LocalDateTime now; @BeforeAll public static void setupSuite() throws IOException { - job1 = loadFileResource("jobs/job1.json"); - job2 = loadFileResource("jobs/job2.json"); - job3 = loadFileResource("jobs/job3.json"); - restTestFlow = loadFileResource("flows/rest-test-flow.asl.json"); - restTestFlow2 = loadFileResource("flows/rest-test-flow2.asl.json"); + execution1 = loadFileResource("executions/execution1.json"); + execution2 = loadFileResource("executions/execution2.json"); + execution3 = loadFileResource("executions/execution3.json"); + restTestStateMachine = loadFileResource("stateMachines/rest-test-state-machine.asl.json"); + restTestStateMachine2 = loadFileResource("stateMachines/rest-test-state-machine2.asl.json"); } @BeforeEach @@ -47,29 +46,29 @@ public void setup() throws IOException { tokens.put("%DATE-NOW%", now.format(DateTimeFormatter.ISO_DATE_TIME)); tokens.put("%DATE-YESTERDAY%", now.minusDays(1).format(DateTimeFormatter.ISO_DATE_TIME)); - // add job docs - DocumentWriteSet batch = getJobsManager().newWriteSet(); - DocumentMetadataHandle jobMeta = new DocumentMetadataHandle(); - jobMeta.getCollections().add("stateConductorJob"); - jobMeta.getPermissions().add("state-conductor-reader-role", DocumentMetadataHandle.Capability.READ); - jobMeta.getPermissions().add("state-conductor-job-writer-role", DocumentMetadataHandle.Capability.UPDATE); - batch.add("/test/stateConductorJob/job1.json", jobMeta, replaceTokensInResource(job1, tokens)); - batch.add("/test/stateConductorJob/job2.json", jobMeta, replaceTokensInResource(job2, tokens)); - batch.add("/test/stateConductorJob/job3.json", jobMeta, replaceTokensInResource(job3, tokens)); - getJobsManager().write(batch); + // add execution docs + DocumentWriteSet batch = getExecutionsManager().newWriteSet(); + DocumentMetadataHandle executionMeta = new DocumentMetadataHandle(); + executionMeta.getCollections().add("stateConductorExecution"); + executionMeta.getPermissions().add("state-conductor-reader-role", DocumentMetadataHandle.Capability.READ); + executionMeta.getPermissions().add("state-conductor-execution-writer-role", DocumentMetadataHandle.Capability.UPDATE); + batch.add("/test/stateConductorExecution/execution1.json", executionMeta, replaceTokensInResource(execution1, tokens)); + batch.add("/test/stateConductorExecution/execution2.json", executionMeta, replaceTokensInResource(execution2, tokens)); + batch.add("/test/stateConductorExecution/execution3.json", executionMeta, replaceTokensInResource(execution3, tokens)); + getExecutionsManager().write(batch); - // add flow docs - DocumentMetadataHandle flowMeta = new DocumentMetadataHandle(); - flowMeta.getCollections().add("state-conductor-flow"); + // add stateMachine docs + DocumentMetadataHandle stateMachineMeta = new DocumentMetadataHandle(); + stateMachineMeta.getCollections().add("state-conductor-state-machine"); batch = getContentManager().newWriteSet(); - batch.add("/state-conductor-flow/rest-test-flow.asl.json", flowMeta, restTestFlow); - batch.add("/state-conductor-flow/rest-test-flow2.asl.json", flowMeta, restTestFlow2); + batch.add("/state-conductor-state-machine/rest-test-state-machine.asl.json", stateMachineMeta, restTestStateMachine); + batch.add("/state-conductor-state-machine/rest-test-state-machine2.asl.json", stateMachineMeta, restTestStateMachine2); getContentManager().write(batch); } @AfterEach public void teardown() { - clearTestJobs(); + clearTestExecutions(); } @Test @@ -91,78 +90,78 @@ public void testNoQueryParams() { log().body(). statusCode(200). contentType(ContentType.JSON). - body("rest-test-flow", notNullValue()). - body("rest-test-flow.flowName", equalTo("rest-test-flow")). - body("rest-test-flow.totalPerStatus", notNullValue()). - body("rest-test-flow.totalPerStatus.new", greaterThanOrEqualTo(0)). - body("rest-test-flow.totalPerStatus.working", greaterThanOrEqualTo(0)). - body("rest-test-flow.totalPerStatus.waiting", greaterThanOrEqualTo(0)). - body("rest-test-flow.totalPerStatus.complete", greaterThanOrEqualTo(0)). - body("rest-test-flow.totalPerStatus.failed", greaterThanOrEqualTo(0)). - body("rest-test-flow.totalPerState", notNullValue()). - body("rest-test-flow.totalPerState.add-collection-1", greaterThanOrEqualTo(0)). - body("rest-test-flow.totalPerState.add-collection-2", greaterThanOrEqualTo(0)). - body("rest-test-flow.totalPerState.success", greaterThanOrEqualTo(0)). - body("rest-test-flow2", notNullValue()). - body("rest-test-flow2.flowName", equalTo("rest-test-flow2")). - body("rest-test-flow2.totalPerStatus", notNullValue()). - body("rest-test-flow2.totalPerStatus.new", greaterThanOrEqualTo(0)). - body("rest-test-flow2.totalPerStatus.working", greaterThanOrEqualTo(0)). - body("rest-test-flow2.totalPerStatus.waiting", greaterThanOrEqualTo(0)). - body("rest-test-flow2.totalPerStatus.complete", greaterThanOrEqualTo(0)). - body("rest-test-flow2.totalPerStatus.failed", greaterThanOrEqualTo(0)). - body("rest-test-flow2.totalPerState", notNullValue()). - body("rest-test-flow2.totalPerState.test-data", greaterThanOrEqualTo(0)). - body("rest-test-flow2.totalPerState.success", greaterThanOrEqualTo(0)); + body("rest-test-state-machine", notNullValue()). + body("rest-test-state-machine.name", equalTo("rest-test-state-machine")). + body("rest-test-state-machine.totalPerStatus", notNullValue()). + body("rest-test-state-machine.totalPerStatus.new", greaterThanOrEqualTo(0)). + body("rest-test-state-machine.totalPerStatus.working", greaterThanOrEqualTo(0)). + body("rest-test-state-machine.totalPerStatus.waiting", greaterThanOrEqualTo(0)). + body("rest-test-state-machine.totalPerStatus.complete", greaterThanOrEqualTo(0)). + body("rest-test-state-machine.totalPerStatus.failed", greaterThanOrEqualTo(0)). + body("rest-test-state-machine.totalPerState", notNullValue()). + body("rest-test-state-machine.totalPerState.add-collection-1", greaterThanOrEqualTo(0)). + body("rest-test-state-machine.totalPerState.add-collection-2", greaterThanOrEqualTo(0)). + body("rest-test-state-machine.totalPerState.success", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2", notNullValue()). + body("rest-test-state-machine2.name", equalTo("rest-test-state-machine2")). + body("rest-test-state-machine2.totalPerStatus", notNullValue()). + body("rest-test-state-machine2.totalPerStatus.new", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.totalPerStatus.working", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.totalPerStatus.waiting", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.totalPerStatus.complete", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.totalPerStatus.failed", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.totalPerState", notNullValue()). + body("rest-test-state-machine2.totalPerState.test-data", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.totalPerState.success", greaterThanOrEqualTo(0)); } @Test - public void testFlowNameParam() { + public void testStateMachineNameParam() { given(). log().uri(). when(). - queryParam("rs:flowName", "rest-test-flow"). + queryParam("rs:name", "rest-test-state-machine"). get("/v1/resources/state-conductor-status"). then(). log().body(). statusCode(200). contentType(ContentType.JSON). - body("rest-test-flow", notNullValue()). - body("rest-test-flow.flowName", equalTo("rest-test-flow")). - body("rest-test-flow.totalPerStatus", notNullValue()). - body("rest-test-flow.totalPerStatus.new", greaterThanOrEqualTo(0)). - body("rest-test-flow.totalPerStatus.working", greaterThanOrEqualTo(0)). - body("rest-test-flow.totalPerStatus.waiting", greaterThanOrEqualTo(0)). - body("rest-test-flow.totalPerStatus.complete", greaterThanOrEqualTo(0)). - body("rest-test-flow.totalPerStatus.failed", greaterThanOrEqualTo(0)). - body("rest-test-flow.totalPerState", notNullValue()). - body("rest-test-flow.totalPerState.add-collection-1", greaterThanOrEqualTo(0)). - body("rest-test-flow.totalPerState.add-collection-2", greaterThanOrEqualTo(0)). - body("rest-test-flow.totalPerState.success", greaterThanOrEqualTo(0)); + body("rest-test-state-machine", notNullValue()). + body("rest-test-state-machine.name", equalTo("rest-test-state-machine")). + body("rest-test-state-machine.totalPerStatus", notNullValue()). + body("rest-test-state-machine.totalPerStatus.new", greaterThanOrEqualTo(0)). + body("rest-test-state-machine.totalPerStatus.working", greaterThanOrEqualTo(0)). + body("rest-test-state-machine.totalPerStatus.waiting", greaterThanOrEqualTo(0)). + body("rest-test-state-machine.totalPerStatus.complete", greaterThanOrEqualTo(0)). + body("rest-test-state-machine.totalPerStatus.failed", greaterThanOrEqualTo(0)). + body("rest-test-state-machine.totalPerState", notNullValue()). + body("rest-test-state-machine.totalPerState.add-collection-1", greaterThanOrEqualTo(0)). + body("rest-test-state-machine.totalPerState.add-collection-2", greaterThanOrEqualTo(0)). + body("rest-test-state-machine.totalPerState.success", greaterThanOrEqualTo(0)); } @Test - public void testFlowName2Param() { + public void testStateMachineName2Param() { given(). log().uri(). when(). - queryParam("rs:flowName", "rest-test-flow2"). + queryParam("rs:name", "rest-test-state-machine2"). get("/v1/resources/state-conductor-status"). then(). log().body(). statusCode(200). contentType(ContentType.JSON). - body("rest-test-flow2", notNullValue()). - body("rest-test-flow2.flowName", equalTo("rest-test-flow2")). - body("rest-test-flow2.totalPerStatus", notNullValue()). - body("rest-test-flow2.totalPerStatus.new", greaterThanOrEqualTo(0)). - body("rest-test-flow2.totalPerStatus.working", greaterThanOrEqualTo(0)). - body("rest-test-flow2.totalPerStatus.waiting", greaterThanOrEqualTo(0)). - body("rest-test-flow2.totalPerStatus.complete", greaterThanOrEqualTo(0)). - body("rest-test-flow2.totalPerStatus.failed", greaterThanOrEqualTo(0)). - body("rest-test-flow2.totalPerState", notNullValue()). - body("rest-test-flow2.totalPerState.test-data", greaterThanOrEqualTo(0)). - body("rest-test-flow2.totalPerState.success", greaterThanOrEqualTo(0)); + body("rest-test-state-machine2", notNullValue()). + body("rest-test-state-machine2.name", equalTo("rest-test-state-machine2")). + body("rest-test-state-machine2.totalPerStatus", notNullValue()). + body("rest-test-state-machine2.totalPerStatus.new", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.totalPerStatus.working", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.totalPerStatus.waiting", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.totalPerStatus.complete", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.totalPerStatus.failed", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.totalPerState", notNullValue()). + body("rest-test-state-machine2.totalPerState.test-data", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.totalPerState.success", greaterThanOrEqualTo(0)); } @Test @@ -170,7 +169,7 @@ public void testTemporalParam() { given(). log().uri(). when(). - queryParam("rs:flowName", "rest-test-flow"). + queryParam("rs:name", "rest-test-state-machine"). queryParam("rs:startDate", now.minusHours(1).format(DateTimeFormatter.ISO_DATE_TIME)). queryParam("rs:endDate", now.plusHours(1).format(DateTimeFormatter.ISO_DATE_TIME)). get("/v1/resources/state-conductor-status"). @@ -178,17 +177,17 @@ public void testTemporalParam() { log().body(). statusCode(200). contentType(ContentType.JSON). - body("rest-test-flow", notNullValue()). - body("rest-test-flow.flowName", equalTo("rest-test-flow")). - body("rest-test-flow.totalPerStatus", notNullValue()). - body("rest-test-flow.totalPerStatus.complete", equalTo(0)). - body("rest-test-flow.totalPerStatus.working", equalTo(1)). - body("rest-test-flow.totalPerStatus.failed", equalTo(0)). - body("rest-test-flow.totalPerStatus.new", greaterThanOrEqualTo(1)). - body("rest-test-flow.totalPerState", notNullValue()). - body("rest-test-flow.totalPerState.add-collection-1", equalTo(1)). - body("rest-test-flow.totalPerState.add-collection-2", equalTo(0)). - body("rest-test-flow.totalPerState.success", equalTo(0)); + body("rest-test-state-machine", notNullValue()). + body("rest-test-state-machine.name", equalTo("rest-test-state-machine")). + body("rest-test-state-machine.totalPerStatus", notNullValue()). + body("rest-test-state-machine.totalPerStatus.complete", equalTo(0)). + body("rest-test-state-machine.totalPerStatus.working", equalTo(1)). + body("rest-test-state-machine.totalPerStatus.failed", equalTo(0)). + body("rest-test-state-machine.totalPerStatus.new", greaterThanOrEqualTo(1)). + body("rest-test-state-machine.totalPerState", notNullValue()). + body("rest-test-state-machine.totalPerState.add-collection-1", equalTo(1)). + body("rest-test-state-machine.totalPerState.add-collection-2", equalTo(0)). + body("rest-test-state-machine.totalPerState.success", equalTo(0)); } @Test @@ -196,47 +195,47 @@ public void testDetailedParam() { given(). log().uri(). when(). - queryParam("rs:flowName", "rest-test-flow2"). + queryParam("rs:name", "rest-test-state-machine2"). queryParam("rs:detailed", true). get("/v1/resources/state-conductor-status"). then(). log().body(). statusCode(200). contentType(ContentType.JSON). - body("rest-test-flow2", notNullValue()). - body("rest-test-flow2.flowName", equalTo("rest-test-flow2")). - body("rest-test-flow2.totalPerStatus", notNullValue()). - body("rest-test-flow2.totalPerStatus.complete", greaterThanOrEqualTo(0)). - body("rest-test-flow2.totalPerStatus.working", greaterThanOrEqualTo(0)). - body("rest-test-flow2.totalPerStatus.failed", greaterThanOrEqualTo(0)). - body("rest-test-flow2.totalPerStatus.new", greaterThanOrEqualTo(0)). - body("rest-test-flow2.totalPerState", notNullValue()). - body("rest-test-flow2.totalPerState.test-data", greaterThanOrEqualTo(0)). - body("rest-test-flow2.totalPerState.success", greaterThanOrEqualTo(0)). - body("rest-test-flow2.detailedTotalPerStatus", notNullValue()). - body("rest-test-flow2.detailedTotalPerStatus.new", notNullValue()). - body("rest-test-flow2.detailedTotalPerStatus.new.test-data", greaterThanOrEqualTo(0)). - body("rest-test-flow2.detailedTotalPerStatus.new.success", greaterThanOrEqualTo(0)). - body("rest-test-flow2.detailedTotalPerStatus.working", notNullValue()). - body("rest-test-flow2.detailedTotalPerStatus.working.test-data", greaterThanOrEqualTo(0)). - body("rest-test-flow2.detailedTotalPerStatus.working.success", greaterThanOrEqualTo(0)). - body("rest-test-flow2.detailedTotalPerStatus.waiting", notNullValue()). - body("rest-test-flow2.detailedTotalPerStatus.waiting.test-data", greaterThanOrEqualTo(0)). - body("rest-test-flow2.detailedTotalPerStatus.waiting.success", greaterThanOrEqualTo(0)). - body("rest-test-flow2.detailedTotalPerStatus.complete", notNullValue()). - body("rest-test-flow2.detailedTotalPerStatus.complete.test-data", greaterThanOrEqualTo(0)). - body("rest-test-flow2.detailedTotalPerStatus.complete.success", greaterThanOrEqualTo(0)). - body("rest-test-flow2.detailedTotalPerStatus.failed", notNullValue()). - body("rest-test-flow2.detailedTotalPerStatus.failed.test-data", greaterThanOrEqualTo(0)). - body("rest-test-flow2.detailedTotalPerStatus.failed.success", greaterThanOrEqualTo(0)); + body("rest-test-state-machine2", notNullValue()). + body("rest-test-state-machine2.name", equalTo("rest-test-state-machine2")). + body("rest-test-state-machine2.totalPerStatus", notNullValue()). + body("rest-test-state-machine2.totalPerStatus.complete", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.totalPerStatus.working", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.totalPerStatus.failed", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.totalPerStatus.new", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.totalPerState", notNullValue()). + body("rest-test-state-machine2.totalPerState.test-data", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.totalPerState.success", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.detailedTotalPerStatus", notNullValue()). + body("rest-test-state-machine2.detailedTotalPerStatus.new", notNullValue()). + body("rest-test-state-machine2.detailedTotalPerStatus.new.test-data", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.detailedTotalPerStatus.new.success", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.detailedTotalPerStatus.working", notNullValue()). + body("rest-test-state-machine2.detailedTotalPerStatus.working.test-data", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.detailedTotalPerStatus.working.success", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.detailedTotalPerStatus.waiting", notNullValue()). + body("rest-test-state-machine2.detailedTotalPerStatus.waiting.test-data", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.detailedTotalPerStatus.waiting.success", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.detailedTotalPerStatus.complete", notNullValue()). + body("rest-test-state-machine2.detailedTotalPerStatus.complete.test-data", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.detailedTotalPerStatus.complete.success", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.detailedTotalPerStatus.failed", notNullValue()). + body("rest-test-state-machine2.detailedTotalPerStatus.failed.test-data", greaterThanOrEqualTo(0)). + body("rest-test-state-machine2.detailedTotalPerStatus.failed.success", greaterThanOrEqualTo(0)); } @Test - public void testBadFlowName() { + public void testBadStateMachineName() { given(). log().uri(). when(). - queryParam("rs:flowName", "non-existent-flow"). + queryParam("rs:name", "non-existent-state-machine"). get("/v1/resources/state-conductor-status"). then(). log().body(). diff --git a/state-conductor-example/src/test/java/com/marklogic/ext/AbstractStateConductorRestTest.java b/state-conductor-example/src/test/java/com/marklogic/ext/AbstractStateConductorRestTest.java index 7385e80f..5b940f0b 100644 --- a/state-conductor-example/src/test/java/com/marklogic/ext/AbstractStateConductorRestTest.java +++ b/state-conductor-example/src/test/java/com/marklogic/ext/AbstractStateConductorRestTest.java @@ -6,8 +6,6 @@ import com.marklogic.client.io.FileHandle; import com.marklogic.client.io.StringHandle; import com.marklogic.junit5.AbstractMarkLogicTest; -import io.restassured.RestAssured; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.extension.ExtendWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,11 +52,11 @@ protected DatabaseClient getDatabaseClient() { } @Autowired - @Qualifier("jobsDatabaseClientProvider") - protected DatabaseClientProvider jobsDatabaseClientProvider; + @Qualifier("executionsDatabaseClientProvider") + protected DatabaseClientProvider executionsDatabaseClientProvider; - protected DatabaseClient getJobsDatabaseClient() { - return jobsDatabaseClientProvider.getDatabaseClient(); + protected DatabaseClient getExecutionsDatabaseClient() { + return executionsDatabaseClientProvider.getDatabaseClient(); } private JSONDocumentManager contentManager; @@ -69,12 +67,12 @@ protected JSONDocumentManager getContentManager() { return contentManager; } - private JSONDocumentManager jobsManager; - protected JSONDocumentManager getJobsManager() { - if (jobsManager == null) { - jobsManager = getJobsDatabaseClient().newJSONDocumentManager(); + private JSONDocumentManager executionsManager; + protected JSONDocumentManager getExecutionsManager() { + if (executionsManager == null) { + executionsManager = getExecutionsDatabaseClient().newJSONDocumentManager(); } - return jobsManager; + return executionsManager; } private String contentDatabaseId; @@ -147,10 +145,10 @@ protected void clearTestDatabase() { statusCode(200); } - protected void clearTestJobs() { clearTestJobs("/test/");} - protected void clearTestJobs(String root) { - logger.info("clearing test jobs \"{}\" ...", root); - getJobsDatabaseClient() + protected void clearTestExecutions() { clearTestExecutions("/test/");} + protected void clearTestExecutions(String root) { + logger.info("clearing test executions \"{}\" ...", root); + getExecutionsDatabaseClient() .newServerEval() .xquery(String.format("xdmp:directory-delete(\"%s\")", root)) .eval(); diff --git a/state-conductor-example/src/test/java/com/marklogic/ext/StateConductorTestConfig.java b/state-conductor-example/src/test/java/com/marklogic/ext/StateConductorTestConfig.java index 929e96fb..84856885 100644 --- a/state-conductor-example/src/test/java/com/marklogic/ext/StateConductorTestConfig.java +++ b/state-conductor-example/src/test/java/com/marklogic/ext/StateConductorTestConfig.java @@ -66,9 +66,9 @@ public DatabaseClientProvider databaseClientProvider() { } @Bean - public DatabaseClientProvider jobsDatabaseClientProvider() { + public DatabaseClientProvider executionsDatabaseClientProvider() { DatabaseClientConfig config = new DatabaseClientConfig(getHost(), getRestPort(), getUsername(), getPassword()); - config.setDatabase("state-conductor-jobs"); + config.setDatabase("state-conductor-executions"); return new SimpleDatabaseClientProvider(config); } diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/emitEvent-test.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/emitEvent-test.sjs index 39e99da9..7fafb616 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/emitEvent-test.sjs +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/emitEvent-test.sjs @@ -4,34 +4,34 @@ const sc = require('/state-conductor/state-conductor.sjs'); const test = require('/test/test-helper.xqy'); const assertions = []; -let jobDoc, error, assertion; +let executionDoc, error, assertion; -//"found waiting job") +//"found waiting execution") assertion = sc.emitEvent('series-of-clicks-and-beeps-connected', 100, false); //they dont come back as as string so we have to convert them -assertion = assertion.jobDocumentsTriggered.map((item) => item.toString()); +assertion = assertion.executionDocumentsTriggered.map((item) => item.toString()); assertions.push( - test.assertTrue(assertion.includes('/stateConductorJob/test-wait-job.json'), 'found waiting job') + test.assertTrue(assertion.includes('/stateConductorExecution/test-wait-execution.json'), 'found waiting execution') ); -//random event jobs shouldnt be found +//random event executions shouldnt be found assertion = sc.emitEvent('theEndOfDays', 100, false); //they dont come back as as string so we have to convert them -assertion = assertion.jobDocumentsTriggered.map((item) => item.toString()); +assertion = assertion.executionDocumentsTriggered.map((item) => item.toString()); -assertions.push(test.assertEqual(assertion, [], 'jobs shouldnt be found')); +assertions.push(test.assertEqual(assertion, [], 'executions shouldnt be found')); //context event assertion = sc.emitEvent('test', 100, false); -assertions.push(test.assertTrue(fn.exists(xdmp.toJSON(assertion).xpath("flowsTriggered[flowName = 'contextual-flow']")), 'context event')) +assertions.push(test.assertTrue(fn.exists(xdmp.toJSON(assertion).xpath("stateMachinesTriggered[stateMachineName = 'contextual-state-machine']")), 'context event')) //context event with another context assertion = sc.emitEvent('context-test', 100, false); -assertions.push(test.assertTrue(fn.empty(xdmp.toJSON(assertion).xpath("flowsTriggered[flowName = 'contextual-flow']")), 'context event with another context')) +assertions.push(test.assertTrue(fn.empty(xdmp.toJSON(assertion).xpath("stateMachinesTriggered[stateMachineName = 'contextual-state-machine']")), 'context event with another context')) assertions; diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/executeChoiceState-tests.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/executeChoiceState-tests.sjs index 0fb9caab..ec405f8c 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/executeChoiceState-tests.sjs +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/executeChoiceState-tests.sjs @@ -5,13 +5,13 @@ const sc = require('/state-conductor/state-conductor.sjs'); const test = require('/test/test-helper.xqy'); const assertions = []; -let jobDoc, error, resp; +let executionDoc, error, resp; -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: sem.uuidString(), - flowName: 'choice-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'find-gender', + name: 'choice-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'find-gender', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -23,19 +23,19 @@ jobDoc = xdmp.toJSON({ }, }); -resp = sc.executeStateByJobDoc(jobDoc, false); +resp = sc.executeStateByExecutionDoc(executionDoc, false); // tests that the correct choice state was applied assertions.push( - test.assertEqual(sc.FLOW_STATUS_WORKING, resp.flowStatus), - test.assertEqual('enroll-in-mens-health', resp.flowState) + test.assertEqual(sc.STATE_MACHINE_STATUS_WORKING, resp.status), + test.assertEqual('enroll-in-mens-health', resp.state) ); -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: sem.uuidString(), - flowName: 'choice-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'find-gender', + name: 'choice-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'find-gender', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -47,19 +47,19 @@ jobDoc = xdmp.toJSON({ }, }); -resp = sc.executeStateByJobDoc(jobDoc, false); +resp = sc.executeStateByExecutionDoc(executionDoc, false); // tests that the correct choice state was applied assertions.push( - test.assertEqual(sc.FLOW_STATUS_WORKING, resp.flowStatus), - test.assertEqual('enroll-in-mens-health', resp.flowState) + test.assertEqual(sc.STATE_MACHINE_STATUS_WORKING, resp.status), + test.assertEqual('enroll-in-mens-health', resp.state) ); -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: sem.uuidString(), - flowName: 'choice-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'find-gender', + name: 'choice-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'find-gender', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -71,19 +71,19 @@ jobDoc = xdmp.toJSON({ }, }); -resp = sc.executeStateByJobDoc(jobDoc, false); +resp = sc.executeStateByExecutionDoc(executionDoc, false); // tests that the correct choice state was applied assertions.push( - test.assertEqual(sc.FLOW_STATUS_WORKING, resp.flowStatus), - test.assertEqual('enroll-in-womens-health', resp.flowState) + test.assertEqual(sc.STATE_MACHINE_STATUS_WORKING, resp.status), + test.assertEqual('enroll-in-womens-health', resp.state) ); -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: sem.uuidString(), - flowName: 'choice-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'find-gender', + name: 'choice-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'find-gender', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -95,12 +95,12 @@ jobDoc = xdmp.toJSON({ }, }); -resp = sc.executeStateByJobDoc(jobDoc, false); +resp = sc.executeStateByExecutionDoc(executionDoc, false); // tests that the correct choice state was applied assertions.push( - test.assertEqual(sc.FLOW_STATUS_WORKING, resp.flowStatus), - test.assertEqual('enroll-in-womens-health', resp.flowState) + test.assertEqual(sc.STATE_MACHINE_STATUS_WORKING, resp.status), + test.assertEqual('enroll-in-womens-health', resp.state) ); // return diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/executeStateByJobDoc-tests.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/executeStateByExecutionDoc-tests.sjs similarity index 57% rename from state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/executeStateByJobDoc-tests.sjs rename to state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/executeStateByExecutionDoc-tests.sjs index c9225e0f..afcddc26 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/executeStateByJobDoc-tests.sjs +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/executeStateByExecutionDoc-tests.sjs @@ -5,14 +5,14 @@ const sc = require('/state-conductor/state-conductor.sjs'); const test = require('/test/test-helper.xqy'); const assertions = []; -let jobDoc, error, assertion; +let executionDoc, error, assertion; //checks see the working statuts -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'branching-flow', - flowStatus: 'new', - flowState: 'find-gender', + name: 'branching-state-machine', + status: 'new', + state: 'find-gender', uri: '/data/test-doc3.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -22,18 +22,18 @@ jobDoc = xdmp.toJSON({ error = null; try { - error = sc.executeStateByJobDoc(jobDoc, false); + error = sc.executeStateByExecutionDoc(executionDoc, false); } catch (e) { error = e; } -assertions.push(test.assertEqual('INVALID-FLOW-STATUS', error.name, 'status check working || new')); +assertions.push(test.assertEqual('INVALID-STATE_MACHINE-STATUS', error.name, 'status check working || new')); -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'branching-flow', - flowStatus: 'waiting', - flowState: 'find-gender', + name: 'branching-state-machine', + status: 'waiting', + state: 'find-gender', uri: '/data/test-doc3.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -43,79 +43,79 @@ jobDoc = xdmp.toJSON({ error = null; try { - error = sc.executeStateByJobDoc(jobDoc, false); + error = sc.executeStateByExecutionDoc(executionDoc, false); } catch (e) { error = e; } assertions.push( - test.assertEqual('INVALID-FLOW-STATUS', error.name, 'status check working || waiting') + test.assertEqual('INVALID-STATE_MACHINE-STATUS', error.name, 'status check working || waiting') ); //checks see the working statuts -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'branching-flow', - flowStatus: 'working', - flowState: 'find-gender', + name: 'branching-state-machine', + status: 'working', + state: 'find-gender', uri: '/data/test-doc3.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), provenance: [], }); -assertion = sc.executeStateByJobDoc(jobDoc, false); +assertion = sc.executeStateByExecutionDoc(executionDoc, false); assertions.push(test.assertEqual(1, assertion.provenance.length, 'provenance check')); //checks see if there are states -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'noStates-flow', - flowStatus: 'working', - flowState: 'find-gender', + name: 'noStates-state-machine', + status: 'working', + state: 'find-gender', uri: '/data/test-doc3.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), provenance: [], }); -assertion = sc.executeStateByJobDoc(jobDoc, false); +assertion = sc.executeStateByExecutionDoc(executionDoc, false); assertions.push( - test.assertEqual('failed', assertion.flowStatus, 'status check'), + test.assertEqual('failed', assertion.status, 'status check'), test.assertEqual('INVALID-STATE-DEFINITION', assertion.errors['find-gender'].name) ); //checks see if the context was updated with a task -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'task-flow', - flowStatus: 'working', - flowState: 'update-context', + name: 'task-state-machine', + status: 'working', + state: 'update-context', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), provenance: [], }); -assertion = sc.executeStateByJobDoc(jobDoc, false); +assertion = sc.executeStateByExecutionDoc(executionDoc, false); assertions.push(test.assertEqual('Hello Word', assertion.context, 'context check')); //checks see if the the parameters is used -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'task-flow', - flowStatus: 'working', - flowState: 'parameters-check', + name: 'task-state-machine', + status: 'working', + state: 'parameters-check', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), provenance: [], }); -assertion = sc.executeStateByJobDoc(jobDoc, false); +assertion = sc.executeStateByExecutionDoc(executionDoc, false); assertions.push( test.assertEqual( @@ -126,20 +126,20 @@ assertions.push( ); //checks a waiting state -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: 'working', - flowState: 'dialUp', + name: 'wait-state-machine', + status: 'working', + state: 'dialUp', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), provenance: [], }); -assertion = sc.executeStateByJobDoc(jobDoc, false); +assertion = sc.executeStateByExecutionDoc(executionDoc, false); -assertions.push(test.assertEqual('waiting', assertion.flowStatus, 'waiting flowStatus')); +assertions.push(test.assertEqual('waiting', assertion.status, 'waiting status')); assertions.push( test.assertEqual( 'series-of-clicks-and-beeps-connected', @@ -149,11 +149,11 @@ assertions.push( ); //eventPath tests start -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: 'working', - flowState: 'dialUpPath', + name: 'wait-state-machine', + status: 'working', + state: 'dialUpPath', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -163,9 +163,9 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = sc.executeStateByJobDoc(jobDoc, false); +assertion = sc.executeStateByExecutionDoc(executionDoc, false); -assertions.push(test.assertEqual('waiting', assertion.flowStatus, 'waiting flowStatus')); +assertions.push(test.assertEqual('waiting', assertion.status, 'waiting status')); assertions.push( test.assertEqual( 'series-of-clicks-and-beeps:1234', @@ -174,11 +174,11 @@ assertions.push( ) ); -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: 'working', - flowState: 'dialUpPath', + name: 'wait-state-machine', + status: 'working', + state: 'dialUpPath', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -188,10 +188,10 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = sc.executeStateByJobDoc(jobDoc, false); +assertion = sc.executeStateByExecutionDoc(executionDoc, false); assertions.push( - test.assertEqual('failed', assertion.flowStatus, 'status check'), + test.assertEqual('failed', assertion.status, 'status check'), test.assertEqual( 'INVALID-STATE-DEFINITION', assertion.errors['dialUpPath'].name, @@ -200,11 +200,11 @@ assertions.push( ); //checks a waiting state -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: 'working', - flowState: 'dialUpPath', + name: 'wait-state-machine', + status: 'working', + state: 'dialUpPath', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -212,10 +212,10 @@ jobDoc = xdmp.toJSON({ context: {}, }); -assertion = sc.executeStateByJobDoc(jobDoc, false); +assertion = sc.executeStateByExecutionDoc(executionDoc, false); assertions.push( - test.assertEqual('failed', assertion.flowStatus, 'status check'), + test.assertEqual('failed', assertion.status, 'status check'), test.assertEqual( 'INVALID-STATE-DEFINITION', assertion.errors['dialUpPath'].name, @@ -225,78 +225,78 @@ assertions.push( //eventPath tests end //unKnown database (content) -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'branching-flow', - flowStatus: 'working', - flowState: 'find-gender', + name: 'branching-state-machine', + status: 'working', + state: 'find-gender', uri: '/data/test-doc3.json', database: 1233456, modules: xdmp.modulesDatabase(), provenance: [], }); -assertion = sc.executeStateByJobDoc(jobDoc, false); +assertion = sc.executeStateByExecutionDoc(executionDoc, false); assertions.push( - test.assertEqual('failed', assertion.flowStatus, 'status check'), + test.assertEqual('failed', assertion.status, 'status check'), test.assertEqual('XDMP-NODB', assertion.errors['find-gender'].name, 'unknown database content') ); //unKnown module database -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'branching-flow', - flowStatus: 'working', - flowState: 'find-gender', + name: 'branching-state-machine', + status: 'working', + state: 'find-gender', uri: '/data/test-doc3.json', database: xdmp.database(), modules: 12345, provenance: [], }); -assertion = sc.executeStateByJobDoc(jobDoc, false); +assertion = sc.executeStateByExecutionDoc(executionDoc, false); assertions.push( - test.assertEqual('failed', assertion.flowStatus, 'status check'), + test.assertEqual('failed', assertion.status, 'status check'), test.assertEqual('XDMP-NODB', assertion.errors['find-gender'].name, 'unknown database modules') ); //unKnown database both -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'branching-flow', - flowStatus: 'working', - flowState: 'find-gender', + name: 'branching-state-machine', + status: 'working', + state: 'find-gender', uri: '/data/test-doc3.json', database: 12345, modules: 12345, provenance: [], }); -assertion = sc.executeStateByJobDoc(jobDoc, false); +assertion = sc.executeStateByExecutionDoc(executionDoc, false); assertions.push( - test.assertEqual('failed', assertion.flowStatus, 'status check'), + test.assertEqual('failed', assertion.status, 'status check'), test.assertEqual('XDMP-NODB', assertion.errors['find-gender'].name, 'unknown database both') ); // missing action modules test -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'bad-flow', - flowStatus: 'working', - flowState: 'set-prop1', + name: 'bad-state-machine', + status: 'working', + state: 'set-prop1', uri: '/data/test-doc3.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), provenance: [], }); -assertion = sc.executeStateByJobDoc(jobDoc, false); +assertion = sc.executeStateByExecutionDoc(executionDoc, false); assertions.push( - test.assertEqual('failed', assertion.flowStatus, 'status check'), + test.assertEqual('failed', assertion.status, 'status check'), test.assertEqual( 'XDMP-MODNOTFOUND', assertion.errors['set-prop1'].name, @@ -305,21 +305,21 @@ assertions.push( ); // missing condition modules test -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'bad-flow', - flowStatus: 'working', - flowState: 'branch', + name: 'bad-state-machine', + status: 'working', + state: 'branch', uri: '/data/test-doc3.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), provenance: [], }); -assertion = sc.executeStateByJobDoc(jobDoc, false); +assertion = sc.executeStateByExecutionDoc(executionDoc, false); assertions.push( - test.assertEqual('failed', assertion.flowStatus, 'status check'), + test.assertEqual('failed', assertion.status, 'status check'), test.assertEqual( 'XDMP-MODNOTFOUND', assertion.errors['branch'].name, @@ -327,20 +327,20 @@ assertions.push( ) ); -// checks that a flow that terminates in a "Fail" state has the "failed" status applied -jobDoc = xdmp.toJSON({ +// checks that a state machine that terminates in a "Fail" state has the "failed" status applied +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'test-flow', - flowStatus: 'working', - flowState: 'failed', + name: 'test-state-machine', + status: 'working', + state: 'failed', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), provenance: [], }); -assertion = sc.executeStateByJobDoc(jobDoc, false); +assertion = sc.executeStateByExecutionDoc(executionDoc, false); -assertions.push(test.assertEqual('failed', assertion.flowStatus, 'status check')); +assertions.push(test.assertEqual('failed', assertion.status, 'status check')); assertions; diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/job-context-tests.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/execution-context-tests.sjs similarity index 81% rename from state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/job-context-tests.sjs rename to state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/execution-context-tests.sjs index a95b6a69..ae579080 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/job-context-tests.sjs +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/execution-context-tests.sjs @@ -23,29 +23,29 @@ function isolate(func) { ); } -let resp, jobDoc; +let resp, executionDoc; /* This test utilizes the "create-doc" action module, which utilizes the context to create new documents based on old ones. It wraps the content of the previous document in an object with an "old" key. -The "contextual-flow" does this three times, and passes a new uri via context each time. +The "contextual-state-machine" does this three times, and passes a new uri via context each time. */ // start the processing -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: sem.uuidString(), - flowName: 'contextual-flow', - flowStatus: 'working', - flowState: 'createDoc1', + name: 'contextual-state-machine', + status: 'working', + state: 'createDoc1', uri: doc1Uri, database: xdmp.database(), modules: xdmp.modulesDatabase(), provenance: [], }); -resp = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +resp = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); // make sure newDocUri was set in the context assertions.push( @@ -67,11 +67,11 @@ assertions.push( ); // start the next step -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: sem.uuidString(), - flowName: 'contextual-flow', - flowStatus: 'working', - flowState: 'createDoc2', + name: 'contextual-state-machine', + status: 'working', + state: 'createDoc2', uri: doc1Uri, database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -81,7 +81,7 @@ jobDoc = xdmp.toJSON({ }, }); -resp = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +resp = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); // make sure newDocUri was set in the context assertions.push( @@ -103,11 +103,11 @@ assertions.push( ); // start the final step -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: sem.uuidString(), - flowName: 'contextual-flow', - flowStatus: 'working', - flowState: 'createDoc3', + name: 'contextual-state-machine', + status: 'working', + state: 'createDoc3', uri: doc1Uri, database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -117,7 +117,7 @@ jobDoc = xdmp.toJSON({ }, }); -resp = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +resp = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); // make sure newDocUri was set in the context assertions.push( diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/getConfiguration-test.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/getConfiguration-test.sjs index cdf07ea4..465ef858 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/getConfiguration-test.sjs +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/getConfiguration-test.sjs @@ -6,7 +6,7 @@ const test = require('/test/test-helper.xqy'); const assertions = []; let assertion; -//"found waiting job") +//"found waiting execution") assertion = sclib.getConfiguration(); assertions.push(test.assertTrue(assertion.foundCustomConfiguration, 'found Custom Configuration')); diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/processJob-tests.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/processExecution-tests.sjs similarity index 50% rename from state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/processJob-tests.sjs rename to state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/processExecution-tests.sjs index e9ff04ff..bf8dabc2 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/processJob-tests.sjs +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/processExecution-tests.sjs @@ -4,19 +4,19 @@ const sc = require('/state-conductor/state-conductor.sjs'); const test = require('/test/test-helper.xqy'); const assertions = []; -let jobDoc, error, assertion; +let executionDoc, error, assertion; //checks a waiting state working -jobDoc = '/randomUIR/thatis/not/here.json'; +executionDoc = '/randomUIR/thatis/not/here.json'; error = null; try { - error = sc.processJob(jobDoc); + error = sc.processExecution(executionDoc); } catch (e) { error = e; } -assertions.push(test.assertEqual('INVALID-JOB-DOCUMENT', error.name, 'check if job doc is there')); +assertions.push(test.assertEqual('INVALID-EXECUTION-DOCUMENT', error.name, 'check if execution doc is there')); assertions; diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/provenanceTests.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/provenanceTests.sjs index 0ed28bfb..966fd4bd 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/provenanceTests.sjs +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/provenanceTests.sjs @@ -4,7 +4,7 @@ const sc = require('/state-conductor/state-conductor.sjs'); const test = require('/test/test-helper.xqy'); const assertions = []; -let jobDoc, error, assertion; +let executionDoc, error, assertion; function isolate(func) { return fn.head( @@ -22,18 +22,18 @@ function isolate(func) { } //new check -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'branching-flow', - flowStatus: 'new', - flowState: 'find-gender', + name: 'branching-state-machine', + status: 'new', + state: 'find-gender', uri: '/data/test-doc3.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), provenance: [], }); -assertion = sc.startProcessingFlowByJobDoc(jobDoc, false); +assertion = sc.startProcessingStateMachineByExecutionDoc(executionDoc, false); assertions.push( test.assertTrue( @@ -55,17 +55,17 @@ assertions.push( ); //choice check -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'branching-flow', - flowStatus: 'working', - flowState: 'find-gender', + name: 'branching-state-machine', + status: 'working', + state: 'find-gender', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), }); -assertion = sc.executeStateByJobDoc(jobDoc, false); +assertion = sc.executeStateByExecutionDoc(executionDoc, false); assertions.push( test.assertTrue( @@ -87,17 +87,17 @@ assertions.push( ); //COMPLETED check -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'branching-flow', - flowStatus: 'working', - flowState: 'enroll-in-mens-health', + name: 'branching-state-machine', + status: 'working', + state: 'enroll-in-mens-health', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push( test.assertTrue( @@ -121,17 +121,17 @@ assertions.push( ); //task -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'task-flow', - flowStatus: 'working', - flowState: 'update-context', + name: 'task-state-machine', + status: 'working', + state: 'update-context', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push( test.assertTrue( @@ -152,12 +152,12 @@ assertions.push( ) ); -//resumeWaitingJobByJobDoc -jobDoc = xdmp.toJSON({ +//resumeWaitingExecutionByExecutionDoc +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: 'waiting', - flowState: 'dialUp', + name: 'wait-state-machine', + status: 'waiting', + state: 'dialUp', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -166,19 +166,19 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = sc.resumeWaitingJobByJobDoc(jobDoc, 'testing', false); +assertion = sc.resumeWaitingExecutionByExecutionDoc(executionDoc, 'testing', false); assertions.push( test.assertTrue( xdmp.castableAs('http://www.w3.org/2001/XMLSchema', 'dateTime', assertion.provenance[0].date), - 'resumeWaitingJobByJobDoc-date' + 'resumeWaitingExecutionByExecutionDoc-date' ) ); assertions.push( - test.assertEqual(assertion.provenance[0].state, 'dialUp', 'resumeWaitingJobByJobDoc-state') + test.assertEqual(assertion.provenance[0].state, 'dialUp', 'resumeWaitingExecutionByExecutionDoc-state') ); assertions.push( - test.assertEqual(assertion.provenance[0].resumeBy, 'testing', 'resumeWaitingJobByJobDoc-testing') + test.assertEqual(assertion.provenance[0].resumeBy, 'testing', 'resumeWaitingExecutionByExecutionDoc-testing') ); assertions.push( test.assertTrue( @@ -187,21 +187,21 @@ assertions.push( 'duration', assertion.provenance[0].executionTime ), - 'resumeWaitingJobByJobDoc-executionTime' + 'resumeWaitingExecutionByExecutionDoc-executionTime' ) ); assertions.push( test.assertTrue( xdmp.castableAs('http://www.w3.org/2001/XMLSchema', 'dateTime', assertion.provenance[1].date), - 'resumeWaitingJobByJobDoc-date2' + 'resumeWaitingExecutionByExecutionDoc-date2' ) ); assertions.push( - test.assertEqual(assertion.provenance[1].from, 'dialUp', 'resumeWaitingJobByJobDoc-from') + test.assertEqual(assertion.provenance[1].from, 'dialUp', 'resumeWaitingExecutionByExecutionDoc-from') ); assertions.push( - test.assertEqual(assertion.provenance[1].to, 'parameters-check', 'resumeWaitingJobByJobDoc-to') + test.assertEqual(assertion.provenance[1].to, 'parameters-check', 'resumeWaitingExecutionByExecutionDoc-to') ); assertions.push( test.assertTrue( @@ -210,35 +210,35 @@ assertions.push( 'duration', assertion.provenance[1].executionTime ), - 'resumeWaitingJobByJobDoc-executionTime2' + 'resumeWaitingExecutionByExecutionDoc-executionTime2' ) ); -//retryJobAtStateByJobDoc -jobDoc = xdmp.toJSON({ +//retryExecutionAtStateByExecutionDoc +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: sc.FLOW_STATUS_FAILED, - flowState: 'dialUp', + name: 'wait-state-machine', + status: sc.STATE_MACHINE_STATUS_FAILED, + state: 'dialUp', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), provenance: [], }); -assertion = sc.retryJobAtStateByJobDoc(jobDoc, 'dialUp', 'testing', false); +assertion = sc.retryExecutionAtStateByExecutionDoc(executionDoc, 'dialUp', 'testing', false); assertions.push( test.assertTrue( xdmp.castableAs('http://www.w3.org/2001/XMLSchema', 'dateTime', assertion.provenance[0].date), - 'retryJobAtStateByJobDoc-date' + 'retryExecutionAtStateByExecutionDoc-date' ) ); assertions.push( - test.assertEqual(assertion.provenance[0].state, 'dialUp', 'retryJobAtStateByJobDoc-state') + test.assertEqual(assertion.provenance[0].state, 'dialUp', 'retryExecutionAtStateByExecutionDoc-state') ); assertions.push( - test.assertEqual(assertion.provenance[0].retriedBy, 'testing', 'retryJobAtStateByJobDoc-testing') + test.assertEqual(assertion.provenance[0].retriedBy, 'testing', 'retryExecutionAtStateByExecutionDoc-testing') ); assertions.push( test.assertTrue( @@ -247,21 +247,21 @@ assertions.push( 'duration', assertion.provenance[0].executionTime ), - 'retryJobAtStateByJobDoc-executionTime' + 'retryExecutionAtStateByExecutionDoc-executionTime' ) ); assertions.push( test.assertTrue( xdmp.castableAs('http://www.w3.org/2001/XMLSchema', 'dateTime', assertion.provenance[1].date), - 'retryJobAtStateByJobDoc-date2' + 'retryExecutionAtStateByExecutionDoc-date2' ) ); assertions.push( - test.assertEqual(assertion.provenance[1].from, 'dialUp', 'retryJobAtStateByJobDoc-from') + test.assertEqual(assertion.provenance[1].from, 'dialUp', 'retryExecutionAtStateByExecutionDoc-from') ); assertions.push( - test.assertEqual(assertion.provenance[1].to, 'parameters-check', 'retryJobAtStateByJobDoc-to') + test.assertEqual(assertion.provenance[1].to, 'parameters-check', 'retryExecutionAtStateByExecutionDoc-to') ); assertions.push( test.assertTrue( @@ -270,16 +270,16 @@ assertions.push( 'duration', assertion.provenance[1].executionTime ), - 'retryJobAtStateByJobDoc-executionTime2' + 'retryExecutionAtStateByExecutionDoc-executionTime2' ) ); // retry -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'retry-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'errorOut', + name: 'retry-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'errorOut', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -287,7 +287,7 @@ jobDoc = xdmp.toJSON({ context: {}, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push( test.assertTrue( diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/resultPathTests.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/resultPathTests.sjs index c3fbddc5..c4ab36a4 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/resultPathTests.sjs +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/resultPathTests.sjs @@ -4,7 +4,7 @@ const sc = require('/state-conductor/state-conductor.sjs'); const test = require('/test/test-helper.xqy'); const assertions = []; -let jobDoc, resp, colls; +let executionDoc, resp, colls; let uri = '/data/test-doc1.json'; @@ -24,18 +24,18 @@ function isolate(func) { } // test filtering output by OutputPath -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: sem.uuidString(), - flowName: 'ref-path-flow', - flowStatus: 'working', - flowState: 'test-data', + name: 'ref-path-state-machine', + status: 'working', + state: 'test-data', uri: uri, database: xdmp.database(), modules: xdmp.modulesDatabase(), provenance: [], }); -resp = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +resp = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); colls = isolate(() => xdmp.documentGetCollections(uri)); assertions.push( @@ -48,34 +48,34 @@ assertions.push( resp.context.test, 'context was filtered by OutputPath' ), - test.assertEqual('add-collections', resp.flowState), + test.assertEqual('add-collections', resp.state), test.assertFalse(colls.includes('test-col-1'), 'doc does not yet have collection') ); // test filtering Parameters and output by OutputPath -resp = isolate(() => sc.executeStateByJobDoc(xdmp.toJSON(resp), false)); +resp = isolate(() => sc.executeStateByExecutionDoc(xdmp.toJSON(resp), false)); colls = isolate(() => xdmp.documentGetCollections(uri)); assertions.push( test.assertTrue(resp.context !== null, 'context was set'), test.assertEqual('testing, testing, 1-2-3', resp.context, 'context was filtered by OutputPath'), - test.assertEqual('success', resp.flowState), + test.assertEqual('success', resp.state), test.assertTrue(colls.includes('test-col-1'), 'doc had collection applied using params') ); // test root level OutputPath -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: sem.uuidString(), - flowName: 'ref-path-flow', - flowStatus: 'working', - flowState: 'test-data2', + name: 'ref-path-state-machine', + status: 'working', + state: 'test-data2', uri: uri, database: xdmp.database(), modules: xdmp.modulesDatabase(), provenance: [], }); -resp = sc.executeStateByJobDoc(jobDoc, false); +resp = sc.executeStateByExecutionDoc(executionDoc, false); assertions.push( test.assertTrue(resp.context !== null, 'context was set'), @@ -84,34 +84,34 @@ assertions.push( JSON.stringify(resp.context), 'context was returned at root level' ), - test.assertEqual('success', resp.flowState) + test.assertEqual('success', resp.state) ); -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: sem.uuidString(), - flowName: 'ref-path-flow', - flowStatus: 'working', - flowState: 'test-data3', + name: 'ref-path-state-machine', + status: 'working', + state: 'test-data3', uri: uri, database: xdmp.database(), modules: xdmp.modulesDatabase(), provenance: [], }); -resp = sc.executeStateByJobDoc(jobDoc, false); +resp = sc.executeStateByExecutionDoc(executionDoc, false); assertions.push( test.assertTrue(resp.context !== null, 'context was set'), test.assertEqual('foo', resp.context, 'context was returned at root level'), - test.assertEqual('success', resp.flowState) + test.assertEqual('success', resp.state) ); // test InputPath filtering -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: sem.uuidString(), - flowName: 'ref-path-flow', - flowStatus: 'working', - flowState: 'add-collections2', + name: 'ref-path-state-machine', + status: 'working', + state: 'add-collections2', uri: uri, database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -131,7 +131,7 @@ jobDoc = xdmp.toJSON({ colls = isolate(() => xdmp.documentGetCollections(uri)); assertions.push(test.assertFalse(colls.includes('test-col-2'), 'doc does not yet have collection')); -resp = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +resp = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); colls = isolate(() => xdmp.documentGetCollections(uri)); xdmp.log(resp); @@ -141,7 +141,7 @@ assertions.push( test.assertTrue(resp.context !== null, 'context was set'), test.assertTrue(colls.includes('test-col-2'), 'doc had collection applied using params'), test.assertEqual('hello world', resp.context, 'context was filtered by OutputPath'), - test.assertEqual('success', resp.flowState) + test.assertEqual('success', resp.state) ); // return diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/resumeWaitingExecution-tests.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/resumeWaitingExecution-tests.sjs new file mode 100644 index 00000000..1dea0d18 --- /dev/null +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/resumeWaitingExecution-tests.sjs @@ -0,0 +1,22 @@ +'use strict'; + +const sc = require('/state-conductor/state-conductor.sjs'); +const test = require('/test/test-helper.xqy'); + +const assertions = []; +let executionDoc, error, assertion; + +//checks a waiting state working +executionDoc = '/randomUIR/thatis/not/here.json'; + +error = null; + +try { + error = sc.resumeWaitingExecution(executionDoc); +} catch (e) { + error = e; +} + +assertions.push(test.assertEqual('INVALID-EXECUTION-DOCUMENT', error.name, 'check if execution doc is there')); + +assertions; diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/resumeWaitingJobByJobDoc-tests.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/resumeWaitingExecutionByExecutionDoc-tests.sjs similarity index 55% rename from state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/resumeWaitingJobByJobDoc-tests.sjs rename to state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/resumeWaitingExecutionByExecutionDoc-tests.sjs index 01628aab..8aec0ccf 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/resumeWaitingJobByJobDoc-tests.sjs +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/resumeWaitingExecutionByExecutionDoc-tests.sjs @@ -4,14 +4,14 @@ const sc = require('/state-conductor/state-conductor.sjs'); const test = require('/test/test-helper.xqy'); const assertions = []; -let jobDoc, error, assertion; +let executionDoc, error, assertion; //checks a waiting state working -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: 'working', - flowState: 'dialUp', + name: 'wait-state-machine', + status: 'working', + state: 'dialUp', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -24,19 +24,19 @@ jobDoc = xdmp.toJSON({ error = null; try { - error = sc.resumeWaitingJobByJobDoc(jobDoc, 'testing', false); + error = sc.resumeWaitingExecutionByExecutionDoc(executionDoc, 'testing', false); } catch (e) { error = e; } -assertions.push(test.assertEqual('INVALID-FLOW-STATUS', error.name, 'status check working')); +assertions.push(test.assertEqual('INVALID-STATE_MACHINE-STATUS', error.name, 'status check working')); //checks a waiting state working -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: 'new', - flowState: 'dialUp', + name: 'wait-state-machine', + status: 'new', + state: 'dialUp', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -49,19 +49,19 @@ jobDoc = xdmp.toJSON({ error = null; try { - error = sc.resumeWaitingJobByJobDoc(jobDoc, 'testing', false); + error = sc.resumeWaitingExecutionByExecutionDoc(executionDoc, 'testing', false); } catch (e) { error = e; } -assertions.push(test.assertEqual('INVALID-FLOW-STATUS', error.name, 'status check new')); +assertions.push(test.assertEqual('INVALID-STATE_MACHINE-STATUS', error.name, 'status check new')); //resume waiting -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: 'waiting', - flowState: 'dialUp', + name: 'wait-state-machine', + status: 'waiting', + state: 'dialUp', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -71,19 +71,19 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = sc.resumeWaitingJobByJobDoc(jobDoc, 'testing', false); +assertion = sc.resumeWaitingExecutionByExecutionDoc(executionDoc, 'testing', false); -assertions.push(test.assertEqual('working', assertion.flowStatus, 'working flowStatus')); +assertions.push(test.assertEqual('working', assertion.status, 'working status')); assertions.push( test.assertFalse(assertion.hasOwnProperty('currentlyWaiting'), 'waiting currentlyWaiting') ); //unKnown database (content) -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: 'waiting', - flowState: 'dialUp', + name: 'wait-state-machine', + status: 'waiting', + state: 'dialUp', uri: '/data/test-doc1.json', database: 1233456, modules: xdmp.modulesDatabase(), @@ -93,19 +93,19 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = sc.resumeWaitingJobByJobDoc(jobDoc, 'testing', false); +assertion = sc.resumeWaitingExecutionByExecutionDoc(executionDoc, 'testing', false); assertions.push( - test.assertEqual('failed', assertion.flowStatus, 'flowStatus check'), + test.assertEqual('failed', assertion.status, 'status check'), test.assertEqual('XDMP-NODB', assertion.errors['dialUp'].name, 'unknown database content') ); //unKnown module database -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: 'waiting', - flowState: 'dialUp', + name: 'wait-state-machine', + status: 'waiting', + state: 'dialUp', uri: '/data/test-doc1.json', database: xdmp.database(), modules: 12345, @@ -115,19 +115,19 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = sc.resumeWaitingJobByJobDoc(jobDoc, 'testing', false); +assertion = sc.resumeWaitingExecutionByExecutionDoc(executionDoc, 'testing', false); -assertions.push(test.assertEqual('working', assertion.flowStatus, 'working flowStatus')); +assertions.push(test.assertEqual('working', assertion.status, 'working status')); assertions.push( test.assertFalse(assertion.hasOwnProperty('currentlyWaiting'), 'waiting currentlyWaiting') ); //unKnown database both -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: 'waiting', - flowState: 'dialUp', + name: 'wait-state-machine', + status: 'waiting', + state: 'dialUp', uri: '/data/test-doc1.json', database: 12345, modules: 12345, @@ -139,17 +139,17 @@ jobDoc = xdmp.toJSON({ error = null; try { - error = sc.resumeWaitingJobByJobDoc(jobDoc, 'testing', false); + error = sc.resumeWaitingExecutionByExecutionDoc(executionDoc, 'testing', false); } catch (e) { error = e; } -//processJob event -jobDoc = xdmp.toJSON({ +//processExecution event +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: 'waiting', - flowState: 'dialUp', + name: 'wait-state-machine', + status: 'waiting', + state: 'dialUp', uri: '/data/test-doc1.json', database: xdmp.database(), modules: 12345, @@ -161,19 +161,19 @@ jobDoc = xdmp.toJSON({ error = null; try { - error = sc.resumeWaitingJobByJobDoc(jobDoc, 'processJob', false); + error = sc.resumeWaitingExecutionByExecutionDoc(executionDoc, 'processExecution', false); } catch (e) { error = e; } -assertions.push(test.assertEqual('INVALID-CurrentlyWaiting', error.name, 'processJob event')); +assertions.push(test.assertEqual('INVALID-CurrentlyWaiting', error.name, 'processExecution event')); -//processJob wait to early -jobDoc = xdmp.toJSON({ +//processExecution wait to early +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: 'waiting', - flowState: 'dialUp', + name: 'wait-state-machine', + status: 'waiting', + state: 'dialUp', uri: '/data/test-doc1.json', database: xdmp.database(), modules: 12345, @@ -185,21 +185,21 @@ jobDoc = xdmp.toJSON({ error = null; try { - error = sc.resumeWaitingJobByJobDoc(jobDoc, 'processJob', false); + error = sc.resumeWaitingExecutionByExecutionDoc(executionDoc, 'processExecution', false); } catch (e) { error = e; } assertions.push( - test.assertEqual('INVALID-CurrentlyWaiting', error.name, 'processJob wait to early') + test.assertEqual('INVALID-CurrentlyWaiting', error.name, 'processExecution wait to early') ); -//processJob wait after -jobDoc = xdmp.toJSON({ +//processExecution wait after +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: 'waiting', - flowState: 'dialUp', + name: 'wait-state-machine', + status: 'waiting', + state: 'dialUp', uri: '/data/test-doc1.json', database: xdmp.database(), modules: 12345, @@ -209,16 +209,16 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = sc.resumeWaitingJobByJobDoc(jobDoc, 'processJob', false); +assertion = sc.resumeWaitingExecutionByExecutionDoc(executionDoc, 'processExecution', false); -assertions.push(test.assertEqual('working', assertion.flowStatus, 'processJob wait after')); +assertions.push(test.assertEqual('working', assertion.status, 'processExecution wait after')); -//processJob wait now -jobDoc = xdmp.toJSON({ +//processExecution wait now +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: 'waiting', - flowState: 'dialUp', + name: 'wait-state-machine', + status: 'waiting', + state: 'dialUp', uri: '/data/test-doc1.json', database: xdmp.database(), modules: 12345, @@ -228,14 +228,14 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = sc.resumeWaitingJobByJobDoc(jobDoc, 'processJob', false); +assertion = sc.resumeWaitingExecutionByExecutionDoc(executionDoc, 'processExecution', false); //wait to early -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: 'waiting', - flowState: 'dialUp', + name: 'wait-state-machine', + status: 'waiting', + state: 'dialUp', uri: '/data/test-doc1.json', database: xdmp.database(), modules: 12345, @@ -247,7 +247,7 @@ jobDoc = xdmp.toJSON({ error = null; try { - error = sc.resumeWaitingJobByJobDoc(jobDoc, 'testing', false); + error = sc.resumeWaitingExecutionByExecutionDoc(executionDoc, 'testing', false); } catch (e) { error = e; } @@ -255,11 +255,11 @@ try { assertions.push(test.assertEqual('INVALID-CurrentlyWaiting', error.name, ' wait to early')); //wait after -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: 'waiting', - flowState: 'dialUp', + name: 'wait-state-machine', + status: 'waiting', + state: 'dialUp', uri: '/data/test-doc1.json', database: xdmp.database(), modules: 12345, @@ -269,16 +269,16 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = sc.resumeWaitingJobByJobDoc(jobDoc, 'testing', false); +assertion = sc.resumeWaitingExecutionByExecutionDoc(executionDoc, 'testing', false); -assertions.push(test.assertEqual('working', assertion.flowStatus, ' wait after')); +assertions.push(test.assertEqual('working', assertion.status, ' wait after')); //wait now -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: 'waiting', - flowState: 'dialUp', + name: 'wait-state-machine', + status: 'waiting', + state: 'dialUp', uri: '/data/test-doc1.json', database: xdmp.database(), modules: 12345, @@ -288,8 +288,8 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = sc.resumeWaitingJobByJobDoc(jobDoc, 'testing', false); +assertion = sc.resumeWaitingExecutionByExecutionDoc(executionDoc, 'testing', false); -assertions.push(test.assertEqual('working', assertion.flowStatus, ' wait now')); +assertions.push(test.assertEqual('working', assertion.status, ' wait now')); assertions; diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/resumeWaitingJob-tests.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/resumeWaitingJob-tests.sjs deleted file mode 100644 index 6a9ab380..00000000 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/resumeWaitingJob-tests.sjs +++ /dev/null @@ -1,22 +0,0 @@ -'use strict'; - -const sc = require('/state-conductor/state-conductor.sjs'); -const test = require('/test/test-helper.xqy'); - -const assertions = []; -let jobDoc, error, assertion; - -//checks a waiting state working -jobDoc = '/randomUIR/thatis/not/here.json'; - -error = null; - -try { - error = sc.resumeWaitingJob(jobDoc); -} catch (e) { - error = e; -} - -assertions.push(test.assertEqual('INVALID-JOB-DOCUMENT', error.name, 'check if job doc is there')); - -assertions; diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/reties-tests.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/retries-tests.sjs similarity index 66% rename from state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/reties-tests.sjs rename to state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/retries-tests.sjs index bbde27a7..21e899db 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/reties-tests.sjs +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/retries-tests.sjs @@ -21,14 +21,14 @@ function isolate(func, db) { } const assertions = []; -let jobDoc, assertion; +let executionDoc, assertion; //none prevous retries -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'retry-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'errorOut', + name: 'retry-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'errorOut', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -36,19 +36,19 @@ jobDoc = xdmp.toJSON({ context: {}, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push(test.assertEqual(1, assertion.retries['States.ALL'], 'none-All')); assertions.push(test.assertEqual(1, assertion.provenance[0]['retryNumber'], 'none-number')); -assertions.push(test.assertEqual('working', assertion.flowStatus, 'none-status')); +assertions.push(test.assertEqual('working', assertion.status, 'none-status')); assertions.push(test.assertEqual('error', assertion.errors.errorOut.name, 'none-error')); //one below max retry -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'retry-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'errorOut', + name: 'retry-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'errorOut', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -59,7 +59,7 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push( test.assertEqual(sc.DEFAULT_MAX_RETRY_ATTEMPTS, assertion.retries['States.ALL'], 'below-all') @@ -71,15 +71,15 @@ assertions.push( 'below-number' ) ); -assertions.push(test.assertEqual('working', assertion.flowStatus, 'below-stauts')); +assertions.push(test.assertEqual('working', assertion.status, 'below-stauts')); assertions.push(test.assertEqual('error', assertion.errors.errorOut.name, 'below-error')); //the limit -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'retry-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'errorOut', + name: 'retry-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'errorOut', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -90,21 +90,21 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push( test.assertEqual(sc.DEFAULT_MAX_RETRY_ATTEMPTS, assertion.retries['States.ALL'], 'limit-all') ); -assertions.push(test.assertEqual('failed', assertion.flowStatus, 'limit-status')); +assertions.push(test.assertEqual('failed', assertion.status, 'limit-status')); assertions.push(test.assertEqual('error', assertion.errors.errorOut.name, 'limit-error')); //more than the limit -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'retry-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'errorOut', + name: 'retry-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'errorOut', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -115,7 +115,7 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push( test.assertEqual( @@ -125,15 +125,15 @@ assertions.push( ) ); -assertions.push(test.assertEqual('failed', assertion.flowStatus, 'limitMore-status')); +assertions.push(test.assertEqual('failed', assertion.status, 'limitMore-status')); assertions.push(test.assertEqual('error', assertion.errors.errorOut.name, 'limitMore-error')); // MaxAttempts set at 4 -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'retry-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'fourMaxAttempts', + name: 'retry-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'fourMaxAttempts', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -144,23 +144,23 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push(test.assertEqual(4, assertion.retries['States.ALL'], 'MaxAttemptsSet-all')); assertions.push( test.assertEqual(4, assertion.provenance[0]['retryNumber'], 'MaxAttemptsSet-number') ); -assertions.push(test.assertEqual('working', assertion.flowStatus, 'MaxAttemptsSet-flowStatus')); +assertions.push(test.assertEqual('working', assertion.status, 'MaxAttemptsSet-status')); assertions.push( test.assertEqual('error', assertion.errors.fourMaxAttempts.name, 'MaxAttemptsSet-error') ); // named -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'retry-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'named', + name: 'retry-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'named', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -171,19 +171,19 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push(test.assertEqual(2, assertion.retries['error'], 'named-all')); assertions.push(test.assertEqual(2, assertion.provenance[0]['retryNumber'], 'named-number')); -assertions.push(test.assertEqual('working', assertion.flowStatus, 'named-flowStatus')); +assertions.push(test.assertEqual('working', assertion.status, 'named-status')); assertions.push(test.assertEqual('error', assertion.errors.named.name, 'named-error')); // star -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'retry-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'star', + name: 'retry-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'star', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -194,19 +194,19 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push(test.assertEqual(2, assertion.retries['*'], 'star-all')); assertions.push(test.assertEqual(2, assertion.provenance[0]['retryNumber'], 'star-number')); -assertions.push(test.assertEqual('working', assertion.flowStatus, 'star-flowStatus')); +assertions.push(test.assertEqual('working', assertion.status, 'star-status')); assertions.push(test.assertEqual('error', assertion.errors.star.name, 'star-error')); // multipleMatch -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'retry-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'multipleMatch', + name: 'retry-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'multipleMatch', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -217,23 +217,23 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push(test.assertEqual(2, assertion.retries['error'], 'multipleMatch-all')); assertions.push( test.assertEqual(2, assertion.provenance[0]['retryNumber'], 'multipleMatch-number') ); -assertions.push(test.assertEqual('working', assertion.flowStatus, 'multipleMatch-flowStatus')); +assertions.push(test.assertEqual('working', assertion.status, 'multipleMatch-status')); assertions.push( test.assertEqual('error', assertion.errors.multipleMatch.name, 'multipleMatch-error') ); // multipleMatch Max -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'retry-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'multipleMatch', + name: 'retry-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'multipleMatch', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -244,24 +244,24 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push(test.assertEqual(4, assertion.retries['error'], 'multipleMatchMax-all')); assertions.push(test.assertEqual(1, assertion.retries['*'], 'multipleMatchMax-all')); assertions.push( test.assertEqual(1, assertion.provenance[0]['retryNumber'], 'multipleMatchMax-number') ); -assertions.push(test.assertEqual('working', assertion.flowStatus, 'multipleMatchMax-flowStatus')); +assertions.push(test.assertEqual('working', assertion.status, 'multipleMatchMax-status')); assertions.push( test.assertEqual('error', assertion.errors.multipleMatch.name, 'multipleMatchMax-error') ); // multipleMatch MaxALL -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'retry-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'multipleMatch', + name: 'retry-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'multipleMatch', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -274,23 +274,23 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push(test.assertEqual(4, assertion.retries['error'], 'multipleMatchMaxALL-all')); assertions.push(test.assertEqual(4, assertion.retries['*'], 'multipleMatchMaxALL-all')); assertions.push(test.assertEqual(4, assertion.retries['States.ALL'], 'multipleMatchMaxALL-all')); -assertions.push(test.assertEqual('failed', assertion.flowStatus, 'multipleMatchMaxALL-flowStatus')); +assertions.push(test.assertEqual('failed', assertion.status, 'multipleMatchMaxALL-status')); assertions.push( test.assertEqual('error', assertion.errors.multipleMatch.name, 'multipleMatchMaxALL-error') ); // multiple -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'retry-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'multiple', + name: 'retry-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'multiple', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -301,19 +301,19 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push(test.assertEqual(2, assertion.retries['error'], 'multiple-all')); assertions.push(test.assertEqual(2, assertion.provenance[0]['retryNumber'], 'multiple-number')); -assertions.push(test.assertEqual('working', assertion.flowStatus, 'multiple-flowStatus')); +assertions.push(test.assertEqual('working', assertion.status, 'multiple-status')); assertions.push(test.assertEqual('error', assertion.errors.multiple.name, 'multiple-error')); // multipleMax -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'retry-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'multiple', + name: 'retry-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'multiple', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -324,19 +324,19 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push(test.assertEqual(4, assertion.retries['error'], 'multipleMax-all')); -assertions.push(test.assertEqual('failed', assertion.flowStatus, 'multipleMax-flowStatus')); +assertions.push(test.assertEqual('failed', assertion.status, 'multipleMax-status')); assertions.push(test.assertEqual('error', assertion.errors.multiple.name, 'multipleMax-error')); // multipleOnRetry -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'retry-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'multipleOnRetry', + name: 'retry-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'multipleOnRetry', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -347,23 +347,23 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push(test.assertEqual(2, assertion.retries['error,someName'], 'multipleOnRetry-all')); assertions.push( test.assertEqual(2, assertion.provenance[0]['retryNumber'], 'multipleOnRetry-number') ); -assertions.push(test.assertEqual('working', assertion.flowStatus, 'multipleOnRetry-flowStatus')); +assertions.push(test.assertEqual('working', assertion.status, 'multipleOnRetry-status')); assertions.push( test.assertEqual('error', assertion.errors.multipleOnRetry.name, 'multipleOnRetry-error') ); // multipleMultiple -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'retry-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'multipleMultiple', + name: 'retry-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'multipleMultiple', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -374,7 +374,7 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push( test.assertEqual(2, assertion.retries['error,*,States.ALL'], 'multipleMultiple-all') @@ -382,17 +382,17 @@ assertions.push( assertions.push( test.assertEqual(2, assertion.provenance[0]['retryNumber'], 'multipleMultiple-number') ); -assertions.push(test.assertEqual('working', assertion.flowStatus, 'multipleMultiple-flowStatus')); +assertions.push(test.assertEqual('working', assertion.status, 'multipleMultiple-status')); assertions.push( test.assertEqual('error', assertion.errors.multipleMultiple.name, 'multipleMultiple-error') ); // multipleMultipleMax -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'retry-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'multipleMultiple', + name: 'retry-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'multipleMultiple', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -403,23 +403,23 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push( test.assertEqual(4, assertion.retries['error,*,States.ALL'], 'multipleMultipleMax-all') ); -assertions.push(test.assertEqual('failed', assertion.flowStatus, 'multipleMultipleMax-flowStatus')); +assertions.push(test.assertEqual('failed', assertion.status, 'multipleMultipleMax-status')); assertions.push( test.assertEqual('error', assertion.errors.multipleMultiple.name, 'multipleMultipleMax-error') ); // multipleMultipleMatch -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'retry-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'multipleMultipleMatch', + name: 'retry-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'multipleMultipleMatch', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -430,7 +430,7 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push( test.assertEqual(2, assertion.retries['error,*,States.ALL'], 'multipleMultipleMatch-all') @@ -439,7 +439,7 @@ assertions.push( test.assertEqual(2, assertion.provenance[0]['retryNumber'], 'multipleMultipleMatch-number') ); assertions.push( - test.assertEqual('working', assertion.flowStatus, 'multipleMultipleMatch-flowStatus') + test.assertEqual('working', assertion.status, 'multipleMultipleMatch-status') ); assertions.push( test.assertEqual( @@ -450,11 +450,11 @@ assertions.push( ); // multipleMultipleMatchMax -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'retry-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'multipleMultipleMatch', + name: 'retry-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'multipleMultipleMatch', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -465,7 +465,7 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push( test.assertEqual(4, assertion.retries['error,*,States.ALL'], 'multipleMultipleMatchMax-all') @@ -478,7 +478,7 @@ assertions.push( test.assertEqual(1, assertion.provenance[0]['retryNumber'], 'multipleMultipleMatchMax-number') ); assertions.push( - test.assertEqual('working', assertion.flowStatus, 'multipleMultipleMatchMax-flowStatus') + test.assertEqual('working', assertion.status, 'multipleMultipleMatchMax-status') ); assertions.push( test.assertEqual( @@ -489,11 +489,11 @@ assertions.push( ); // multipleMultipleMatchMaxALL -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'retry-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'multipleMultipleMatch', + name: 'retry-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'multipleMultipleMatch', uri: '/data/johndoe.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -505,7 +505,7 @@ jobDoc = xdmp.toJSON({ }, }); -assertion = isolate(() => sc.executeStateByJobDoc(jobDoc, false)); +assertion = isolate(() => sc.executeStateByExecutionDoc(executionDoc, false)); assertions.push( test.assertEqual(4, assertion.retries['error,*,States.ALL'], 'multipleMultipleMatchMaxALL-all') @@ -515,7 +515,7 @@ assertions.push( ); assertions.push( - test.assertEqual('failed', assertion.flowStatus, 'multipleMultipleMatchMaxALL-flowStatus') + test.assertEqual('failed', assertion.status, 'multipleMultipleMatchMaxALL-status') ); assertions.push( test.assertEqual( diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/retryExecutionAtStateByExecutionDoc-test.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/retryExecutionAtStateByExecutionDoc-test.sjs new file mode 100644 index 00000000..f7273a0c --- /dev/null +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/retryExecutionAtStateByExecutionDoc-test.sjs @@ -0,0 +1,207 @@ +'use strict'; + +const sc = require('/state-conductor/state-conductor.sjs'); +const test = require('/test/test-helper.xqy'); + +const assertions = []; +let executionDoc, error, assertion; + +//checks a failed state working +executionDoc = xdmp.toJSON({ + id: '0405536f-dd84-4ca6-8de8-c57062b2252d', + name: 'wait-state-machine', + status: sc.STATE_MACHINE_STATUS_WORKING, + state: 'parameters-check', + uri: '/data/test-doc1.json', + database: xdmp.database(), + modules: xdmp.modulesDatabase(), + provenance: [], +}); + +error = null; + +try { + error = sc.retryExecutionAtStateByExecutionDoc(executionDoc, 'dialUp', 'testing', false); +} catch (e) { + error = e; +} + +assertions.push(test.assertEqual('INVALID-STATE_MACHINE-STATUS', error.name, 'status check working')); + +//checks a waiting state new +executionDoc = xdmp.toJSON({ + id: '0405536f-dd84-4ca6-8de8-c57062b2252d', + name: 'wait-state-machine', + status: sc.STATE_MACHINE_STATUS_NEW, + state: 'dialUp', + uri: '/data/test-doc1.json', + database: xdmp.database(), + modules: xdmp.modulesDatabase(), + provenance: [], +}); + +error = null; + +try { + error = sc.retryExecutionAtStateByExecutionDoc(executionDoc, 'dialUp', 'testing', false); +} catch (e) { + error = e; +} + +assertions.push(test.assertEqual('INVALID-STATE_MACHINE-STATUS', error.name, 'status check new')); + +//checks a waiting state waitting +executionDoc = xdmp.toJSON({ + id: '0405536f-dd84-4ca6-8de8-c57062b2252d', + name: 'wait-state-machine', + status: sc.STATE_MACHINE_STATUS_WATING, + state: 'dialUp', + uri: '/data/test-doc1.json', + database: xdmp.database(), + modules: xdmp.modulesDatabase(), + provenance: [], +}); + +error = null; + +try { + error = sc.retryExecutionAtStateByExecutionDoc(executionDoc, 'dialUp', 'testing', false); +} catch (e) { + error = e; +} + +assertions.push(test.assertEqual('INVALID-STATE_MACHINE-STATUS', error.name, 'status check new')); + +//checks a waiting state complete +executionDoc = xdmp.toJSON({ + id: '0405536f-dd84-4ca6-8de8-c57062b2252d', + name: 'wait-state-machine', + status: sc.STATE_MACHINE_STATUS_COMPLETE, + state: 'dialUp', + uri: '/data/test-doc1.json', + database: xdmp.database(), + modules: xdmp.modulesDatabase(), + provenance: [], +}); + +error = null; + +try { + error = sc.retryExecutionAtStateByExecutionDoc(executionDoc, 'dialUp', 'testing', false); +} catch (e) { + error = e; +} + +assertions.push(test.assertEqual('INVALID-STATE_MACHINE-STATUS', error.name, 'status check new')); + +//retry failed status +executionDoc = xdmp.toJSON({ + id: '0405536f-dd84-4ca6-8de8-c57062b2252d', + name: 'wait-state-machine', + status: sc.STATE_MACHINE_STATUS_FAILED, + state: 'dialUp', + uri: '/data/test-doc1.json', + database: xdmp.database(), + modules: xdmp.modulesDatabase(), + provenance: [], +}); + +assertion = sc.retryExecutionAtStateByExecutionDoc(executionDoc, 'dialUp', 'testing', false); + +assertions.push(test.assertEqual('working', assertion.status, 'working retry')); +assertions.push(test.assertFalse(assertion.hasOwnProperty('parameters-check'), 'next step retry')); + +//retry an unknown state +executionDoc = xdmp.toJSON({ + id: '0405536f-dd84-4ca6-8de8-c57062b2252d', + name: 'wait-state-machine', + status: sc.STATE_MACHINE_STATUS_FAILED, + state: 'dialUp', + uri: '/data/test-doc1.json', + database: xdmp.database(), + modules: xdmp.modulesDatabase(), + provenance: [], +}); + +assertion = sc.retryExecutionAtStateByExecutionDoc(executionDoc, 'unknownStep', 'testing', false); + +assertions.push( + test.assertEqual('failed', assertion.status, 'status check'), + test.assertEqual('INVALID-STATE-DEFINITION', assertion.errors['dialUp'].name, 'unknownStep') +); + +//retry an NEW state +executionDoc = xdmp.toJSON({ + id: '0405536f-dd84-4ca6-8de8-c57062b2252d', + name: 'wait-state-machine', + status: sc.STATE_MACHINE_STATUS_FAILED, + state: 'dialUp', + uri: '/data/test-doc1.json', + database: xdmp.database(), + modules: xdmp.modulesDatabase(), + provenance: [], +}); + +assertion = sc.retryExecutionAtStateByExecutionDoc(executionDoc, 'NEW', 'testing', false); + +assertions.push( + test.assertEqual('failed', assertion.status, 'status check'), + test.assertEqual('INVALID-STATE-DEFINITION', assertion.errors['dialUp'].name, 'NEW') +); + +//unKnown database (content) +executionDoc = xdmp.toJSON({ + id: '0405536f-dd84-4ca6-8de8-c57062b2252d', + name: 'wait-state-machine', + status: sc.STATE_MACHINE_STATUS_FAILED, + state: 'dialUp', + uri: '/data/test-doc1.json', + database: 1233456, + modules: xdmp.modulesDatabase(), + provenance: [], +}); + +assertion = sc.retryExecutionAtStateByExecutionDoc(executionDoc, 'dialUp', 'testing', false); + +assertions.push( + test.assertEqual('failed', assertion.status, 'status check'), + test.assertEqual('XDMP-NODB', assertion.errors['dialUp'].name, 'unknown database content') +); + +//unKnown module database +executionDoc = xdmp.toJSON({ + id: '0405536f-dd84-4ca6-8de8-c57062b2252d', + name: 'wait-state-machine', + status: sc.STATE_MACHINE_STATUS_FAILED, + state: 'dialUp', + uri: '/data/test-doc1.json', + database: xdmp.database(), + modules: 12345, + provenance: [], +}); + +assertion = sc.retryExecutionAtStateByExecutionDoc(executionDoc, 'dialUp', 'testing', false); + +assertions.push(test.assertEqual('working', assertion.status, 'working retry')); +assertions.push(test.assertFalse(assertion.hasOwnProperty('parameters-check'), 'next step retry')); + +//unKnown database both +executionDoc = xdmp.toJSON({ + id: '0405536f-dd84-4ca6-8de8-c57062b2252d', + name: 'wait-state-machine', + status: sc.STATE_MACHINE_STATUS_FAILED, + state: 'dialUp', + uri: '/data/test-doc1.json', + database: 12345, + modules: 12345, + provenance: [], +}); + +assertion = sc.retryExecutionAtStateByExecutionDoc(executionDoc, 'dialUp', 'testing', false); + +assertions.push( + test.assertEqual('failed', assertion.status, 'status check'), + test.assertEqual('XDMP-NODB', assertion.errors['dialUp'].name, 'unknown database both') +); + +assertions; diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/retryJobAtStateByJobDoc-test.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/retryJobAtStateByJobDoc-test.sjs deleted file mode 100644 index f125b616..00000000 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/retryJobAtStateByJobDoc-test.sjs +++ /dev/null @@ -1,207 +0,0 @@ -'use strict'; - -const sc = require('/state-conductor/state-conductor.sjs'); -const test = require('/test/test-helper.xqy'); - -const assertions = []; -let jobDoc, error, assertion; - -//checks a failed state working -jobDoc = xdmp.toJSON({ - id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: sc.FLOW_STATUS_WORKING, - flowState: 'parameters-check', - uri: '/data/test-doc1.json', - database: xdmp.database(), - modules: xdmp.modulesDatabase(), - provenance: [], -}); - -error = null; - -try { - error = sc.retryJobAtStateByJobDoc(jobDoc, 'dialUp', 'testing', false); -} catch (e) { - error = e; -} - -assertions.push(test.assertEqual('INVALID-FLOW-STATUS', error.name, 'status check working')); - -//checks a waiting state new -jobDoc = xdmp.toJSON({ - id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: sc.FLOW_STATUS_NEW, - flowState: 'dialUp', - uri: '/data/test-doc1.json', - database: xdmp.database(), - modules: xdmp.modulesDatabase(), - provenance: [], -}); - -error = null; - -try { - error = sc.retryJobAtStateByJobDoc(jobDoc, 'dialUp', 'testing', false); -} catch (e) { - error = e; -} - -assertions.push(test.assertEqual('INVALID-FLOW-STATUS', error.name, 'status check new')); - -//checks a waiting state waitting -jobDoc = xdmp.toJSON({ - id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: sc.FLOW_STATUS_WATING, - flowState: 'dialUp', - uri: '/data/test-doc1.json', - database: xdmp.database(), - modules: xdmp.modulesDatabase(), - provenance: [], -}); - -error = null; - -try { - error = sc.retryJobAtStateByJobDoc(jobDoc, 'dialUp', 'testing', false); -} catch (e) { - error = e; -} - -assertions.push(test.assertEqual('INVALID-FLOW-STATUS', error.name, 'status check new')); - -//checks a waiting state complete -jobDoc = xdmp.toJSON({ - id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: sc.FLOW_STATUS_COMPLETE, - flowState: 'dialUp', - uri: '/data/test-doc1.json', - database: xdmp.database(), - modules: xdmp.modulesDatabase(), - provenance: [], -}); - -error = null; - -try { - error = sc.retryJobAtStateByJobDoc(jobDoc, 'dialUp', 'testing', false); -} catch (e) { - error = e; -} - -assertions.push(test.assertEqual('INVALID-FLOW-STATUS', error.name, 'status check new')); - -//retry failed flowStatus -jobDoc = xdmp.toJSON({ - id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: sc.FLOW_STATUS_FAILED, - flowState: 'dialUp', - uri: '/data/test-doc1.json', - database: xdmp.database(), - modules: xdmp.modulesDatabase(), - provenance: [], -}); - -assertion = sc.retryJobAtStateByJobDoc(jobDoc, 'dialUp', 'testing', false); - -assertions.push(test.assertEqual('working', assertion.flowStatus, 'working retry')); -assertions.push(test.assertFalse(assertion.hasOwnProperty('parameters-check'), 'next step retry')); - -//retry an unknown state -jobDoc = xdmp.toJSON({ - id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: sc.FLOW_STATUS_FAILED, - flowState: 'dialUp', - uri: '/data/test-doc1.json', - database: xdmp.database(), - modules: xdmp.modulesDatabase(), - provenance: [], -}); - -assertion = sc.retryJobAtStateByJobDoc(jobDoc, 'unknownStep', 'testing', false); - -assertions.push( - test.assertEqual('failed', assertion.flowStatus, 'status check'), - test.assertEqual('INVALID-STATE-DEFINITION', assertion.errors['dialUp'].name, 'unknownStep') -); - -//retry an NEW state -jobDoc = xdmp.toJSON({ - id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: sc.FLOW_STATUS_FAILED, - flowState: 'dialUp', - uri: '/data/test-doc1.json', - database: xdmp.database(), - modules: xdmp.modulesDatabase(), - provenance: [], -}); - -assertion = sc.retryJobAtStateByJobDoc(jobDoc, 'NEW', 'testing', false); - -assertions.push( - test.assertEqual('failed', assertion.flowStatus, 'status check'), - test.assertEqual('INVALID-STATE-DEFINITION', assertion.errors['dialUp'].name, 'NEW') -); - -//unKnown database (content) -jobDoc = xdmp.toJSON({ - id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: sc.FLOW_STATUS_FAILED, - flowState: 'dialUp', - uri: '/data/test-doc1.json', - database: 1233456, - modules: xdmp.modulesDatabase(), - provenance: [], -}); - -assertion = sc.retryJobAtStateByJobDoc(jobDoc, 'dialUp', 'testing', false); - -assertions.push( - test.assertEqual('failed', assertion.flowStatus, 'status check'), - test.assertEqual('XDMP-NODB', assertion.errors['dialUp'].name, 'unknown database content') -); - -//unKnown module database -jobDoc = xdmp.toJSON({ - id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: sc.FLOW_STATUS_FAILED, - flowState: 'dialUp', - uri: '/data/test-doc1.json', - database: xdmp.database(), - modules: 12345, - provenance: [], -}); - -assertion = sc.retryJobAtStateByJobDoc(jobDoc, 'dialUp', 'testing', false); - -assertions.push(test.assertEqual('working', assertion.flowStatus, 'working retry')); -assertions.push(test.assertFalse(assertion.hasOwnProperty('parameters-check'), 'next step retry')); - -//unKnown database both -jobDoc = xdmp.toJSON({ - id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'wait-flow', - flowStatus: sc.FLOW_STATUS_FAILED, - flowState: 'dialUp', - uri: '/data/test-doc1.json', - database: 12345, - modules: 12345, - provenance: [], -}); - -assertion = sc.retryJobAtStateByJobDoc(jobDoc, 'dialUp', 'testing', false); - -assertions.push( - test.assertEqual('failed', assertion.flowStatus, 'status check'), - test.assertEqual('XDMP-NODB', assertion.errors['dialUp'].name, 'unknown database both') -); - -assertions; diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/securityTest.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/securityTest.sjs index d8653248..b638c068 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/securityTest.sjs +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/securityTest.sjs @@ -5,7 +5,7 @@ let assertion; let invokeDeveloperResult = xdmp .httpGet( - 'http://localhost:8010/v1/resources/state-conductor-flows?rs:flowName=waitState-time-flow', + 'http://localhost:8010/v1/resources/state-conductor-state-machines?rs:name=waitState-time-state-machine', { authentication: { username: 'state-conductor-test-developer', @@ -17,7 +17,7 @@ let invokeDeveloperResult = xdmp let invokeNonDeveloperResult = xdmp .httpGet( - 'http://localhost:8010/v1/resources/state-conductor-flows?rs:flowName=waitState-time-flow', + 'http://localhost:8010/v1/resources/state-conductor-state-machines?rs:name=waitState-time-state-machine', { authentication: { username: 'state-conductor-test-non-developer', @@ -37,11 +37,11 @@ assertions.push( const sc = require('/state-conductor/state-conductor.sjs'); let evalDeveloperResult = xdmp.eval('cts.uris().toArray().length', null, { - database: xdmp.database(sc.STATE_CONDUCTOR_JOBS_DB), + database: xdmp.database(sc.STATE_CONDUCTOR_EXECUTIONS_DB), userId: xdmp.user('state-conductor-test-developer'), }); let evalNonDeveloperResult = xdmp.eval('cts.uris().toArray().length', null, { - database: xdmp.database(sc.STATE_CONDUCTOR_JOBS_DB), + database: xdmp.database(sc.STATE_CONDUCTOR_EXECUTIONS_DB), userId: xdmp.user('state-conductor-test-non-developer'), }); assertion = evalDeveloperResult <= evalNonDeveloperResult ? true : false; diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/setup.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/setup.sjs index c666f76b..0acd088f 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/setup.sjs +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/setup.sjs @@ -12,8 +12,8 @@ test.loadTestFile('test-doc3.json', xdmp.database(), '/data/test-doc3.json'); test.loadTestFile('test-doc4.json', xdmp.database(), '/data/test-doc4.json'); test.loadTestFile('lorem.txt', xdmp.database(), '/data/lorem.txt'); -xdmp.documentAddCollections('/data/test-doc2.json', [sc.FLOW_ITEM_COLLECTION, 'test']); -xdmp.documentAddCollections('/data/test-doc3.json', [sc.FLOW_ITEM_COLLECTION, 'enrollee']); -xdmp.documentAddCollections('/data/test-doc4.json', [sc.FLOW_ITEM_COLLECTION, 'waitStateTest']); +xdmp.documentAddCollections('/data/test-doc2.json', [sc.STATE_MACHINE_ITEM_COLLECTION, 'test']); +xdmp.documentAddCollections('/data/test-doc3.json', [sc.STATE_MACHINE_ITEM_COLLECTION, 'enrollee']); +xdmp.documentAddCollections('/data/test-doc4.json', [sc.STATE_MACHINE_ITEM_COLLECTION, 'waitStateTest']); test.log('StateConductorSuite Test Setup COMPLETE....'); diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/startProcessingFlowByJobDoc-tests.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/startProcessingFlowByJobDoc-tests.sjs deleted file mode 100644 index c439db1d..00000000 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/startProcessingFlowByJobDoc-tests.sjs +++ /dev/null @@ -1,164 +0,0 @@ -'use strict'; - -const sc = require('/state-conductor/state-conductor.sjs'); -const test = require('/test/test-helper.xqy'); - -const assertions = []; -let jobDoc, error, assertion; - -//checks see if the new status check is working -jobDoc = xdmp.toJSON({ - id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'branching-flow', - flowStatus: 'working', - flowState: 'find-gender', - uri: '/data/test-doc3.json', - database: xdmp.database(), - modules: xdmp.modulesDatabase(), - provenance: [], -}); - -error = null; - -try { - error = sc.startProcessingFlowByJobDoc(jobDoc, false); -} catch (e) { - error = e; -} - -assertions.push(test.assertEqual('INVALID-FLOW-STATUS', error.name, 'status check working')); - -//check waiting status -jobDoc = xdmp.toJSON({ - id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'branching-flow', - flowStatus: 'waiting', - flowState: 'find-gender', - uri: '/data/test-doc3.json', - database: xdmp.database(), - modules: xdmp.modulesDatabase(), - provenance: [], -}); - -error = null; -try { - error = sc.startProcessingFlowByJobDoc(jobDoc, false); -} catch (e) { - error = e; -} - -assertions.push(test.assertEqual('INVALID-FLOW-STATUS', error.name, 'status check waiting')); - -//check for missing flow file -jobDoc = xdmp.toJSON({ - id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'random-flow', - flowStatus: 'new', - flowState: 'find-gender', - uri: '/data/test-doc3.json', - database: xdmp.database(), - modules: xdmp.modulesDatabase(), - provenance: [], -}); - -assertion = sc.startProcessingFlowByJobDoc(jobDoc, false); - -assertions.push( - test.assertEqual('failed', assertion.flowStatus, 'status check'), - test.assertEqual('MISSING-FLOW-FILE', assertion.errors['find-gender'].name, 'missing flow file') -); - -//check for missing flow file -jobDoc = xdmp.toJSON({ - id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'noStates-flow', - flowStatus: 'new', - flowState: 'find-gender', - uri: '/data/test-doc3.json', - database: xdmp.database(), - modules: xdmp.modulesDatabase(), - provenance: [], -}); - -assertion = sc.startProcessingFlowByJobDoc(jobDoc, false); - -assertions.push( - test.assertEqual('failed', assertion.flowStatus, 'status check'), - test.assertEqual( - 'INVALID-STATE-DEFINITION', - assertion.errors['find-gender'].name, - 'no StartAt step' - ) -); - -//check for missing flow file -jobDoc = xdmp.toJSON({ - id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'branching-flow', - flowStatus: 'new', - flowState: 'find-gender', - uri: '/data/test-doc3.json', - database: xdmp.database(), - modules: xdmp.modulesDatabase(), - provenance: [], -}); - -assertion = sc.startProcessingFlowByJobDoc(jobDoc, false); - -assertions.push(test.assertEqual('working', assertion.flowStatus, 'new flow')); - -//unKnown database (content) -jobDoc = xdmp.toJSON({ - id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'branching-flow', - flowStatus: 'new', - flowState: 'find-gender', - uri: '/data/test-doc3.json', - database: 1233456, - modules: xdmp.modulesDatabase(), - provenance: [], -}); - -assertion = sc.startProcessingFlowByJobDoc(jobDoc, false); - -assertions.push( - test.assertEqual('failed', assertion.flowStatus, 'status check'), - test.assertEqual('XDMP-NODB', assertion.errors['find-gender'].name, 'unknown database content') -); - -//unKnown database (module) -jobDoc = xdmp.toJSON({ - id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'branching-flow', - flowStatus: 'new', - flowState: 'find-gender', - uri: '/data/test-doc3.json', - database: xdmp.database(), - modules: 1233456, - provenance: [], -}); - -assertion = sc.startProcessingFlowByJobDoc(jobDoc, false); - -assertions.push(test.assertEqual('working', assertion.flowStatus, 'unKnown database module')); - -//unKnown database (both) -jobDoc = xdmp.toJSON({ - id: '0405536f-dd84-4ca6-8de8-c57062b2252d', - flowName: 'branching-flow', - flowStatus: 'new', - flowState: 'find-gender', - uri: '/data/test-doc3.json', - database: 9678094, - modules: 1233456, - provenance: [], -}); - -assertion = sc.startProcessingFlowByJobDoc(jobDoc, false); - -assertions.push( - test.assertEqual('failed', assertion.flowStatus, 'status check'), - test.assertEqual('XDMP-NODB', assertion.errors['find-gender'].name, 'unknown database both') -); - -assertions; diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/startProcessingStateMachineByExecutionDoc-tests.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/startProcessingStateMachineByExecutionDoc-tests.sjs new file mode 100644 index 00000000..6355a484 --- /dev/null +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/startProcessingStateMachineByExecutionDoc-tests.sjs @@ -0,0 +1,164 @@ +'use strict'; + +const sc = require('/state-conductor/state-conductor.sjs'); +const test = require('/test/test-helper.xqy'); + +const assertions = []; +let executionDoc, error, assertion; + +//checks see if the new status check is working +executionDoc = xdmp.toJSON({ + id: '0405536f-dd84-4ca6-8de8-c57062b2252d', + name: 'branching-state-machine', + status: 'working', + state: 'find-gender', + uri: '/data/test-doc3.json', + database: xdmp.database(), + modules: xdmp.modulesDatabase(), + provenance: [], +}); + +error = null; + +try { + error = sc.startProcessingStateMachineByExecutionDoc(executionDoc, false); +} catch (e) { + error = e; +} + +assertions.push(test.assertEqual('INVALID-STATE_MACHINE-STATUS', error.name, 'status check working')); + +//check waiting status +executionDoc = xdmp.toJSON({ + id: '0405536f-dd84-4ca6-8de8-c57062b2252d', + name: 'branching-state-machine', + status: 'waiting', + state: 'find-gender', + uri: '/data/test-doc3.json', + database: xdmp.database(), + modules: xdmp.modulesDatabase(), + provenance: [], +}); + +error = null; +try { + error = sc.startProcessingStateMachineByExecutionDoc(executionDoc, false); +} catch (e) { + error = e; +} + +assertions.push(test.assertEqual('INVALID-STATE_MACHINE-STATUS', error.name, 'status check waiting')); + +//check for missing stateMachine file +executionDoc = xdmp.toJSON({ + id: '0405536f-dd84-4ca6-8de8-c57062b2252d', + name: 'random-state-machine', + status: 'new', + state: 'find-gender', + uri: '/data/test-doc3.json', + database: xdmp.database(), + modules: xdmp.modulesDatabase(), + provenance: [], +}); + +assertion = sc.startProcessingStateMachineByExecutionDoc(executionDoc, false); + +assertions.push( + test.assertEqual('failed', assertion.status, 'status check'), + test.assertEqual('MISSING-STATE_MACHINE-FILE', assertion.errors['find-gender'].name, 'missing state machine') +); + +//check for missing stateMachine file +executionDoc = xdmp.toJSON({ + id: '0405536f-dd84-4ca6-8de8-c57062b2252d', + name: 'noStates-state-machine', + status: 'new', + state: 'find-gender', + uri: '/data/test-doc3.json', + database: xdmp.database(), + modules: xdmp.modulesDatabase(), + provenance: [], +}); + +assertion = sc.startProcessingStateMachineByExecutionDoc(executionDoc, false); + +assertions.push( + test.assertEqual('failed', assertion.status, 'status check'), + test.assertEqual( + 'INVALID-STATE-DEFINITION', + assertion.errors['find-gender'].name, + 'no StartAt step' + ) +); + +//check for missing stateMachine file +executionDoc = xdmp.toJSON({ + id: '0405536f-dd84-4ca6-8de8-c57062b2252d', + name: 'branching-state-machine', + status: 'new', + state: 'find-gender', + uri: '/data/test-doc3.json', + database: xdmp.database(), + modules: xdmp.modulesDatabase(), + provenance: [], +}); + +assertion = sc.startProcessingStateMachineByExecutionDoc(executionDoc, false); + +assertions.push(test.assertEqual('working', assertion.status, 'new stateMachine')); + +//unKnown database (content) +executionDoc = xdmp.toJSON({ + id: '0405536f-dd84-4ca6-8de8-c57062b2252d', + name: 'branching-state-machine', + status: 'new', + state: 'find-gender', + uri: '/data/test-doc3.json', + database: 1233456, + modules: xdmp.modulesDatabase(), + provenance: [], +}); + +assertion = sc.startProcessingStateMachineByExecutionDoc(executionDoc, false); + +assertions.push( + test.assertEqual('failed', assertion.status, 'status check'), + test.assertEqual('XDMP-NODB', assertion.errors['find-gender'].name, 'unknown database content') +); + +//unKnown database (module) +executionDoc = xdmp.toJSON({ + id: '0405536f-dd84-4ca6-8de8-c57062b2252d', + name: 'branching-state-machine', + status: 'new', + state: 'find-gender', + uri: '/data/test-doc3.json', + database: xdmp.database(), + modules: 1233456, + provenance: [], +}); + +assertion = sc.startProcessingStateMachineByExecutionDoc(executionDoc, false); + +assertions.push(test.assertEqual('working', assertion.status, 'unKnown database module')); + +//unKnown database (both) +executionDoc = xdmp.toJSON({ + id: '0405536f-dd84-4ca6-8de8-c57062b2252d', + name: 'branching-state-machine', + status: 'new', + state: 'find-gender', + uri: '/data/test-doc3.json', + database: 9678094, + modules: 1233456, + provenance: [], +}); + +assertion = sc.startProcessingStateMachineByExecutionDoc(executionDoc, false); + +assertions.push( + test.assertEqual('failed', assertion.status, 'status check'), + test.assertEqual('XDMP-NODB', assertion.errors['find-gender'].name, 'unknown database both') +); + +assertions; diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-context-tests.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-context-tests.sjs index f72c030b..5e4ff99c 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-context-tests.sjs +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-context-tests.sjs @@ -5,9 +5,9 @@ const test = require('/test/test-helper.xqy'); const assertions = []; -const testFlow = sc.getFlowDocument('test-flow').toObject(); -const branchingFlow = sc.getFlowDocument('branching-flow').toObject(); -const noContextFlow = sc.getFlowDocument('no-context-flow').toObject(); +const testStateMachine = sc.getStateMachine('test-state-machine').toObject(); +const branchingStateMachine = sc.getStateMachine('branching-state-machine').toObject(); +const noContextStateMachine = sc.getStateMachine('no-context-state-machine').toObject(); const doc1 = '/data/test-doc1.json'; const doc2 = '/data/test-doc2.json'; @@ -30,15 +30,15 @@ function isolate(func) { // initial state assertions.push( - test.assertEqual(false, sc.checkFlowContext(doc1, testFlow)), - test.assertEqual(false, sc.checkFlowContext(doc1, branchingFlow)), - test.assertEqual(true, sc.checkFlowContext(doc2, testFlow)), - test.assertEqual(false, sc.checkFlowContext(doc2, branchingFlow)), - test.assertEqual(false, sc.checkFlowContext(doc3, testFlow)), - test.assertEqual(true, sc.checkFlowContext(doc3, branchingFlow)), - test.assertEqual(false, sc.checkFlowContext(doc1, noContextFlow)), - test.assertEqual(false, sc.checkFlowContext(doc2, noContextFlow)), - test.assertEqual(false, sc.checkFlowContext(doc3, noContextFlow)) + test.assertEqual(false, sc.checkStateMachineContext(doc1, testStateMachine)), + test.assertEqual(false, sc.checkStateMachineContext(doc1, branchingStateMachine)), + test.assertEqual(true, sc.checkStateMachineContext(doc2, testStateMachine)), + test.assertEqual(false, sc.checkStateMachineContext(doc2, branchingStateMachine)), + test.assertEqual(false, sc.checkStateMachineContext(doc3, testStateMachine)), + test.assertEqual(true, sc.checkStateMachineContext(doc3, branchingStateMachine)), + test.assertEqual(false, sc.checkStateMachineContext(doc1, noContextStateMachine)), + test.assertEqual(false, sc.checkStateMachineContext(doc2, noContextStateMachine)), + test.assertEqual(false, sc.checkStateMachineContext(doc3, noContextStateMachine)) ); // update 1 @@ -46,15 +46,15 @@ isolate(() => xdmp.documentAddCollections(doc1, ['test'])); assertions.push( test.assertEqual( true, - isolate(() => sc.checkFlowContext(doc1, testFlow)) + isolate(() => sc.checkStateMachineContext(doc1, testStateMachine)) ), test.assertEqual( false, - isolate(() => sc.checkFlowContext(doc1, branchingFlow)) + isolate(() => sc.checkStateMachineContext(doc1, branchingStateMachine)) ), test.assertEqual( false, - isolate(() => sc.checkFlowContext(doc1, noContextFlow)) + isolate(() => sc.checkStateMachineContext(doc1, noContextStateMachine)) ) ); @@ -63,21 +63,21 @@ isolate(() => xdmp.documentAddCollections(doc1, ['enrollee'])); assertions.push( test.assertEqual( true, - isolate(() => sc.checkFlowContext(doc1, testFlow)) + isolate(() => sc.checkStateMachineContext(doc1, testStateMachine)) ), test.assertEqual( true, - isolate(() => sc.checkFlowContext(doc1, branchingFlow)) + isolate(() => sc.checkStateMachineContext(doc1, branchingStateMachine)) ), test.assertEqual( false, - isolate(() => sc.checkFlowContext(doc1, noContextFlow)) + isolate(() => sc.checkStateMachineContext(doc1, noContextStateMachine)) ) ); -// check no context flow's empty context produces a false query +// check no context stateMachine's empty context produces a false query assertions.push( - test.assertEqual(cts.falseQuery().toString(), sc.getFlowContextQuery(noContextFlow).toString()) + test.assertEqual(cts.falseQuery().toString(), sc.getStateMachineContextQuery(noContextStateMachine).toString()) ); assertions; diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-execution-tests.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-execution-tests.sjs new file mode 100644 index 00000000..460e2ff3 --- /dev/null +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-execution-tests.sjs @@ -0,0 +1,201 @@ +'use strict'; +declareUpdate(); + +const sc = require('/state-conductor/state-conductor.sjs'); +const test = require('/test/test-helper.xqy'); + +const assertions = []; +const doc1 = '/data/test-doc1.json'; +const doc2 = '/data/test-doc2.json'; +const doc3 = '/data/test-doc3.json'; + +function isolate(func, dbId) { + return fn.head( + xdmp.invokeFunction( + () => { + declareUpdate(); + return func(); + }, + { + isolation: 'different-transaction', + commit: 'auto', + database: dbId || xdmp.database(), + } + ) + ); +} + +function getExecutionDocById(id) { + return getExecutionDocByUri(`/stateConductorExecution/${id}.json`); +} + +function getExecutionDocByUri(uri) { + return isolate(() => cts.doc(uri).toObject(), xdmp.database(sc.STATE_CONDUCTOR_EXECUTIONS_DB)); +} + +// doc 1 - we manually add this to the branching stateMachine +const executionId1 = isolate(() => + sc.createStateConductorExecution('branching-state-machine', doc1, { collections: ['test'] }) +); +const executionDoc1 = getExecutionDocById(executionId1); + +assertions.push( + test.assertTrue(!!executionId1), + test.assertTrue(!!executionDoc1), + test.assertEqual(doc1, executionDoc1.uri), + test.assertEqual('branching-state-machine', executionDoc1.name), + test.assertEqual( + executionId1, + isolate(() => sc.getExecutionIds(doc1, 'branching-state-machine')[0]) + ) +); + +// doc 2 - is added to the test stateMachine during setup via trigger +const executionId2 = sc.getExecutionIds(doc2, 'test-state-machine')[0]; +const executionId2_2 = sc.getExecutionIds(doc2, 'branching-state-machine')[0]; +const executionDoc2 = getExecutionDocById(executionId2); + +assertions.push( + test.assertTrue(!!executionId2), + test.assertEqual(null, executionId2_2), + test.assertTrue(!!executionDoc2), + test.assertEqual('test-state-machine', executionDoc2.name) +); + +// doc 3 - is added to the branching stateMachine during setup via trigger +const executionId3 = sc.getExecutionIds(doc3, 'branching-state-machine')[0]; +const executionId3_2 = sc.getExecutionIds(doc3, 'test-state-machine')[0]; +const executionUri3 = `/stateConductorExecution/${executionId3}.json`; +const executionDoc3 = isolate( + () => cts.doc(executionUri3).toObject(), + xdmp.database(sc.STATE_CONDUCTOR_EXECUTIONS_DB) +); + +assertions.push( + test.assertTrue(!!executionId3), + test.assertEqual(null, executionId3_2), + test.assertTrue(!!executionDoc3), + test.assertEqual('branching-state-machine', executionDoc3.name) +); + +// getExecutionDocuments() tests + +const executionBatch1Time = new Date().toISOString(); +xdmp.sleep(100); +const executionBatch1 = isolate(() => + Array.from(Array(1000)).map(() => + sc.createStateConductorExecution('test-state-machine', null, {}, { collections: ['test'] }) + ) +); +xdmp.sleep(2000); +const executionBatch2Time = new Date().toISOString(); +xdmp.sleep(100); +const executionBatch2 = isolate(() => + Array.from(Array(1000)).map(() => + sc.createStateConductorExecution('task-state-machine', null, {}, { collections: ['test'] }) + ) +); +xdmp.sleep(2000); +const executionBatch3Time = new Date().toISOString(); +xdmp.sleep(100); +const executionBatch3 = isolate(() => + Array.from(Array(1000)).map(() => + sc.createStateConductorExecution('choice-state-machine', null, {}, { collections: ['test'] }) + ) +); + +console.log('executionBatch1Time', executionBatch1Time); +console.log('executionBatch2Time', executionBatch2Time); +console.log('executionBatch3Time', executionBatch3Time); + +const names = ['test-state-machine', 'task-state-machine', 'choice-state-machine']; + +let options = { + start: 1, + count: 2000, + status: null, + names: names, + forestIds: null, + startDate: null, + endDate: null, +}; + +const executionUris = isolate(() => sc.getExecutionDocuments(options)); +assertions.push(test.assertTrue(Array.isArray(executionUris)), test.assertEqual(2000, executionUris.length)); +executionUris.forEach((uri) => { + let executionDoc = getExecutionDocByUri(uri); + assertions.push(test.assertTrue(names.includes(executionDoc.name))); +}); + +// test page filters +options.start = 1; +options.count = 20; +const executionUris1 = isolate(() => sc.getExecutionDocuments(options)); + +options.start = 21; +options.count = 20; +const executionUris2 = isolate(() => sc.getExecutionDocuments(options)); + +options.start = 1001; +options.count = 20; +const executionUris3 = isolate(() => sc.getExecutionDocuments(options)); + +assertions.push( + test.assertTrue(Array.isArray(executionUris1)), + test.assertEqual(20, executionUris1.length), + test.assertTrue(Array.isArray(executionUris2)), + test.assertEqual(20, executionUris2.length), + test.assertTrue(Array.isArray(executionUris3)), + test.assertEqual(20, executionUris3.length), + test.assertTrue(JSON.stringify(executionUris1.sort()) !== JSON.stringify(executionUris2.sort())), + test.assertTrue(JSON.stringify(executionUris2.sort()) !== JSON.stringify(executionUris3.sort())), + test.assertTrue(JSON.stringify(executionUris3.sort()) !== JSON.stringify(executionUris1.sort())) +); + +// test time boxing +options.start = 1; +options.count = 2000; +options.startDate = executionBatch1Time; +options.endDate = executionBatch2Time; +const executionUrisBatch1Test = isolate(() => sc.getExecutionDocuments(options)); + +assertions.push( + test.assertTrue(Array.isArray(executionUrisBatch1Test)), + test.assertEqual(1000, executionUrisBatch1Test.length) +); +executionUrisBatch1Test.forEach((uri) => { + let executionDoc = getExecutionDocByUri(uri); + assertions.push(test.assertEqual('test-state-machine', executionDoc.name)); +}); + +options.start = 1; +options.count = 2000; +options.startDate = executionBatch2Time; +options.endDate = executionBatch3Time; +const executionUrisBatch2Test = isolate(() => sc.getExecutionDocuments(options)); + +assertions.push( + test.assertTrue(Array.isArray(executionUrisBatch2Test)), + test.assertEqual(1000, executionUrisBatch2Test.length) +); +executionUrisBatch2Test.forEach((uri) => { + let executionDoc = getExecutionDocByUri(uri); + assertions.push(test.assertEqual('task-state-machine', executionDoc.name)); +}); + +options.start = 1; +options.count = 2000; +options.startDate = executionBatch3Time; +options.endDate = null; +const executionUrisBatch3Test = isolate(() => sc.getExecutionDocuments(options)); + +assertions.push( + test.assertTrue(Array.isArray(executionUrisBatch3Test)), + test.assertEqual(1000, executionUrisBatch3Test.length) +); +executionUrisBatch3Test.forEach((uri) => { + let executionDoc = getExecutionDocByUri(uri); + assertions.push(test.assertEqual('choice-state-machine', executionDoc.name)); +}); + +assertions; diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-flow-tests.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-flow-tests.sjs deleted file mode 100644 index 339fca44..00000000 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-flow-tests.sjs +++ /dev/null @@ -1,51 +0,0 @@ -'use strict'; - -const sc = require('/state-conductor/state-conductor.sjs'); -const test = require('/test/test-helper.xqy'); - -const assertions = []; - -const flowDocuments = sc.getFlowDocuments().toArray(); -assertions.push(test.assertEqual(12, flowDocuments.length, 'Flow files are present')); - -const flowNames = sc.getFlowNames().sort(); -assertions.push( - test.assertEqual(12, flowNames.length, 'flowNames count'), - test.assertEqual('bad-flow', flowNames[0]), - test.assertEqual('branching-flow', flowNames[1]), - test.assertEqual('choice-flow', flowNames[2]), - test.assertEqual('contextual-flow', flowNames[3]), - test.assertEqual('no-context-flow', flowNames[4]), - test.assertEqual('noStates-flow', flowNames[5]), - test.assertEqual('ref-path-flow', flowNames[6]), - test.assertEqual('retry-flow', flowNames[7]), - test.assertEqual('task-flow', flowNames[8]), - test.assertEqual('test-flow', flowNames[9]), - test.assertEqual('test-time-wait', flowNames[10]), - test.assertEqual('wait-flow', flowNames[11]) -); - -const branchingFlow = sc.getFlowDocument('branching-flow'); -assertions.push( - test.assertTrue(!!branchingFlow), - test.assertEqual('find-gender', branchingFlow.toObject().StartAt) -); - -const testFlow = sc.getFlowDocument('test-flow'); -assertions.push( - test.assertTrue(!!testFlow), - test.assertEqual('set-prop1', testFlow.toObject().StartAt), - test.assertEqual(2, testFlow.toObject().mlDomain.context.length) -); - -assertions.push( - test.assertEqual('branching-flow', sc.getFlowNameFromUri(fn.documentUri(branchingFlow))), - test.assertEqual('test-flow', sc.getFlowNameFromUri(fn.documentUri(testFlow))) -); - -assertions.push( - test.assertEqual('set-prop1', sc.getInitialState(testFlow.toObject())), - test.assertEqual('find-gender', sc.getInitialState(branchingFlow.toObject())) -); - -assertions; diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-job-tests.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-job-tests.sjs deleted file mode 100644 index 5d711ecb..00000000 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-job-tests.sjs +++ /dev/null @@ -1,201 +0,0 @@ -'use strict'; -declareUpdate(); - -const sc = require('/state-conductor/state-conductor.sjs'); -const test = require('/test/test-helper.xqy'); - -const assertions = []; -const doc1 = '/data/test-doc1.json'; -const doc2 = '/data/test-doc2.json'; -const doc3 = '/data/test-doc3.json'; - -function isolate(func, dbId) { - return fn.head( - xdmp.invokeFunction( - () => { - declareUpdate(); - return func(); - }, - { - isolation: 'different-transaction', - commit: 'auto', - database: dbId || xdmp.database(), - } - ) - ); -} - -function getJobDocById(id) { - return getJobDocByUri(`/stateConductorJob/${id}.json`); -} - -function getJobDocByUri(uri) { - return isolate(() => cts.doc(uri).toObject(), xdmp.database(sc.STATE_CONDUCTOR_JOBS_DB)); -} - -// doc 1 - we manually add this to the branching flow -const jobId1 = isolate(() => - sc.createStateConductorJob('branching-flow', doc1, { collections: ['test'] }) -); -const jobDoc1 = getJobDocById(jobId1); - -assertions.push( - test.assertTrue(!!jobId1), - test.assertTrue(!!jobDoc1), - test.assertEqual(doc1, jobDoc1.uri), - test.assertEqual('branching-flow', jobDoc1.flowName), - test.assertEqual( - jobId1, - isolate(() => sc.getJobIds(doc1, 'branching-flow')[0]) - ) -); - -// doc 2 - is added to the test flow during setup via trigger -const jobId2 = sc.getJobIds(doc2, 'test-flow')[0]; -const jobId2_2 = sc.getJobIds(doc2, 'branching-flow')[0]; -const jobDoc2 = getJobDocById(jobId2); - -assertions.push( - test.assertTrue(!!jobId2), - test.assertEqual(null, jobId2_2), - test.assertTrue(!!jobDoc2), - test.assertEqual('test-flow', jobDoc2.flowName) -); - -// doc 3 - is added to the branching flow during setup via trigger -const jobId3 = sc.getJobIds(doc3, 'branching-flow')[0]; -const jobId3_2 = sc.getJobIds(doc3, 'test-flow')[0]; -const jobUri3 = `/stateConductorJob/${jobId3}.json`; -const jobDoc3 = isolate( - () => cts.doc(jobUri3).toObject(), - xdmp.database(sc.STATE_CONDUCTOR_JOBS_DB) -); - -assertions.push( - test.assertTrue(!!jobId3), - test.assertEqual(null, jobId3_2), - test.assertTrue(!!jobDoc3), - test.assertEqual('branching-flow', jobDoc3.flowName) -); - -// getJobDocuments() tests - -const jobBatch1Time = new Date().toISOString(); -xdmp.sleep(100); -const jobBatch1 = isolate(() => - Array.from(Array(1000)).map(() => - sc.createStateConductorJob('test-flow', null, {}, { collections: ['test'] }) - ) -); -xdmp.sleep(2000); -const jobBatch2Time = new Date().toISOString(); -xdmp.sleep(100); -const jobBatch2 = isolate(() => - Array.from(Array(1000)).map(() => - sc.createStateConductorJob('task-flow', null, {}, { collections: ['test'] }) - ) -); -xdmp.sleep(2000); -const jobBatch3Time = new Date().toISOString(); -xdmp.sleep(100); -const jobBatch3 = isolate(() => - Array.from(Array(1000)).map(() => - sc.createStateConductorJob('choice-flow', null, {}, { collections: ['test'] }) - ) -); - -console.log('jobBatch1Time', jobBatch1Time); -console.log('jobBatch2Time', jobBatch2Time); -console.log('jobBatch3Time', jobBatch3Time); - -const flowNames = ['test-flow', 'task-flow', 'choice-flow']; - -let options = { - start: 1, - count: 2000, - flowStatus: null, - flowNames: flowNames, - forestIds: null, - startDate: null, - endDate: null, -}; - -const jobUris = isolate(() => sc.getJobDocuments(options)); -assertions.push(test.assertTrue(Array.isArray(jobUris)), test.assertEqual(2000, jobUris.length)); -jobUris.forEach((uri) => { - let jobDoc = getJobDocByUri(uri); - assertions.push(test.assertTrue(flowNames.includes(jobDoc.flowName))); -}); - -// test page filters -options.start = 1; -options.count = 20; -const jobUris1 = isolate(() => sc.getJobDocuments(options)); - -options.start = 21; -options.count = 20; -const jobUris2 = isolate(() => sc.getJobDocuments(options)); - -options.start = 1001; -options.count = 20; -const jobUris3 = isolate(() => sc.getJobDocuments(options)); - -assertions.push( - test.assertTrue(Array.isArray(jobUris1)), - test.assertEqual(20, jobUris1.length), - test.assertTrue(Array.isArray(jobUris2)), - test.assertEqual(20, jobUris2.length), - test.assertTrue(Array.isArray(jobUris3)), - test.assertEqual(20, jobUris3.length), - test.assertTrue(JSON.stringify(jobUris1.sort()) !== JSON.stringify(jobUris2.sort())), - test.assertTrue(JSON.stringify(jobUris2.sort()) !== JSON.stringify(jobUris3.sort())), - test.assertTrue(JSON.stringify(jobUris3.sort()) !== JSON.stringify(jobUris1.sort())) -); - -// test time boxing -options.start = 1; -options.count = 2000; -options.startDate = jobBatch1Time; -options.endDate = jobBatch2Time; -const jobUrisBatch1Test = isolate(() => sc.getJobDocuments(options)); - -assertions.push( - test.assertTrue(Array.isArray(jobUrisBatch1Test)), - test.assertEqual(1000, jobUrisBatch1Test.length) -); -jobUrisBatch1Test.forEach((uri) => { - let jobDoc = getJobDocByUri(uri); - assertions.push(test.assertEqual('test-flow', jobDoc.flowName)); -}); - -options.start = 1; -options.count = 2000; -options.startDate = jobBatch2Time; -options.endDate = jobBatch3Time; -const jobUrisBatch2Test = isolate(() => sc.getJobDocuments(options)); - -assertions.push( - test.assertTrue(Array.isArray(jobUrisBatch2Test)), - test.assertEqual(1000, jobUrisBatch2Test.length) -); -jobUrisBatch2Test.forEach((uri) => { - let jobDoc = getJobDocByUri(uri); - assertions.push(test.assertEqual('task-flow', jobDoc.flowName)); -}); - -options.start = 1; -options.count = 2000; -options.startDate = jobBatch3Time; -options.endDate = null; -const jobUrisBatch3Test = isolate(() => sc.getJobDocuments(options)); - -assertions.push( - test.assertTrue(Array.isArray(jobUrisBatch3Test)), - test.assertEqual(1000, jobUrisBatch3Test.length) -); -jobUrisBatch3Test.forEach((uri) => { - let jobDoc = getJobDocByUri(uri); - assertions.push(test.assertEqual('choice-flow', jobDoc.flowName)); -}); - -assertions; diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-state-machine-tests.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-state-machine-tests.sjs new file mode 100644 index 00000000..9a070eb2 --- /dev/null +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/state-conductor-state-machine-tests.sjs @@ -0,0 +1,51 @@ +'use strict'; + +const sc = require('/state-conductor/state-conductor.sjs'); +const test = require('/test/test-helper.xqy'); + +const assertions = []; + +const stateMachineDocuments = sc.getStateMachines().toArray(); +assertions.push(test.assertEqual(12, stateMachineDocuments.length, 'StateMachine files are present')); + +const names = sc.getStateMachineNames().sort(); +assertions.push( + test.assertEqual(12, names.length, 'names count'), + test.assertEqual('bad-state-machine', names[0]), + test.assertEqual('branching-state-machine', names[1]), + test.assertEqual('choice-state-machine', names[2]), + test.assertEqual('contextual-state-machine', names[3]), + test.assertEqual('no-context-state-machine', names[4]), + test.assertEqual('noStates-state-machine', names[5]), + test.assertEqual('ref-path-state-machine', names[6]), + test.assertEqual('retry-state-machine', names[7]), + test.assertEqual('task-state-machine', names[8]), + test.assertEqual('test-state-machine', names[9]), + test.assertEqual('test-time-wait', names[10]), + test.assertEqual('wait-state-machine', names[11]) +); + +const branchingStateMachine = sc.getStateMachine('branching-state-machine'); +assertions.push( + test.assertTrue(!!branchingStateMachine), + test.assertEqual('find-gender', branchingStateMachine.toObject().StartAt) +); + +const testStateMachine = sc.getStateMachine('test-state-machine'); +assertions.push( + test.assertTrue(!!testStateMachine), + test.assertEqual('set-prop1', testStateMachine.toObject().StartAt), + test.assertEqual(2, testStateMachine.toObject().mlDomain.context.length) +); + +assertions.push( + test.assertEqual('branching-state-machine', sc.getStateMachineNameFromUri(fn.documentUri(branchingStateMachine))), + test.assertEqual('test-state-machine', sc.getStateMachineNameFromUri(fn.documentUri(testStateMachine))) +); + +assertions.push( + test.assertEqual('set-prop1', sc.getInitialState(testStateMachine.toObject())), + test.assertEqual('find-gender', sc.getInitialState(branchingStateMachine.toObject())) +); + +assertions; diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/suiteSetup.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/suiteSetup.sjs index a642b884..859c4b50 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/suiteSetup.sjs +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/suiteSetup.sjs @@ -5,110 +5,110 @@ declareUpdate(); const sc = require('/state-conductor/state-conductor.sjs'); const test = require('/test/test-helper.xqy'); -// insert the test flows +// insert the test stateMachines test.loadTestFile( - 'flows/test-flow.asl.json', + 'stateMachines/test-state-machine.asl.json', xdmp.database(), - sc.FLOW_DIRECTORY + 'test-flow.asl.json', + sc.STATE_MACHINE_DIRECTORY + 'test-state-machine.asl.json', xdmp.defaultPermissions(), - sc.FLOW_COLLECTION + sc.STATE_MACHINE_COLLECTION ); test.loadTestFile( - 'flows/branching-flow.asl.json', + 'stateMachines/branching-state-machine.asl.json', xdmp.database(), - sc.FLOW_DIRECTORY + 'branching-flow.asl.json', + sc.STATE_MACHINE_DIRECTORY + 'branching-state-machine.asl.json', xdmp.defaultPermissions(), - sc.FLOW_COLLECTION + sc.STATE_MACHINE_COLLECTION ); test.loadTestFile( - 'flows/no-context-flow.asl.json', + 'stateMachines/no-context-state-machine.asl.json', xdmp.database(), - sc.FLOW_DIRECTORY + 'no-context-flow.asl.json', + sc.STATE_MACHINE_DIRECTORY + 'no-context-state-machine.asl.json', xdmp.defaultPermissions(), - sc.FLOW_COLLECTION + sc.STATE_MACHINE_COLLECTION ); test.loadTestFile( - 'flows/noStates-flow.asl.json', + 'stateMachines/noStates-state-machine.asl.json', xdmp.database(), - sc.FLOW_DIRECTORY + 'noStates-flow.asl.json', + sc.STATE_MACHINE_DIRECTORY + 'noStates-state-machine.asl.json', xdmp.defaultPermissions(), - sc.FLOW_COLLECTION + sc.STATE_MACHINE_COLLECTION ); test.loadTestFile( - 'flows/task-flow.asl.json', + 'stateMachines/task-state-machine.asl.json', xdmp.database(), - sc.FLOW_DIRECTORY + 'task-flow.asl.json', + sc.STATE_MACHINE_DIRECTORY + 'task-state-machine.asl.json', xdmp.defaultPermissions(), - sc.FLOW_COLLECTION + sc.STATE_MACHINE_COLLECTION ); test.loadTestFile( - 'flows/wait-flow.asl.json', + 'stateMachines/wait-state-machine.asl.json', xdmp.database(), - sc.FLOW_DIRECTORY + 'wait-flow.asl.json', + sc.STATE_MACHINE_DIRECTORY + 'wait-state-machine.asl.json', xdmp.defaultPermissions(), - sc.FLOW_COLLECTION + sc.STATE_MACHINE_COLLECTION ); test.loadTestFile( - 'flows/bad-flow.asl.json', + 'stateMachines/bad-state-machine.asl.json', xdmp.database(), - sc.FLOW_DIRECTORY + 'bad-flow.asl.json', + sc.STATE_MACHINE_DIRECTORY + 'bad-state-machine.asl.json', xdmp.defaultPermissions(), - sc.FLOW_COLLECTION + sc.STATE_MACHINE_COLLECTION ); test.loadTestFile( - 'flows/contextual-flow.asl.json', + 'stateMachines/contextual-state-machine.asl.json', xdmp.database(), - sc.FLOW_DIRECTORY + 'contextual-flow.asl.json', + sc.STATE_MACHINE_DIRECTORY + 'contextual-state-machine.asl.json', xdmp.defaultPermissions(), - sc.FLOW_COLLECTION + sc.STATE_MACHINE_COLLECTION ); test.loadTestFile( - 'flows/test-time-wait.asl.json', + 'stateMachines/test-time-wait.asl.json', xdmp.database(), - sc.FLOW_DIRECTORY + 'test-time-wait.asl.json', + sc.STATE_MACHINE_DIRECTORY + 'test-time-wait.asl.json', xdmp.defaultPermissions(), - [sc.FLOW_COLLECTION, 'waitStateTest'] + [sc.STATE_MACHINE_COLLECTION, 'waitStateTest'] ); test.loadTestFile( - 'flows/ref-path-flow.asl.json', + 'stateMachines/ref-path-state-machine.asl.json', xdmp.database(), - sc.FLOW_DIRECTORY + 'ref-path-flow.asl.json', + sc.STATE_MACHINE_DIRECTORY + 'ref-path-state-machine.asl.json', xdmp.defaultPermissions(), - sc.FLOW_COLLECTION + sc.STATE_MACHINE_COLLECTION ); test.loadTestFile( - 'flows/choice-flow.asl.json', + 'stateMachines/choice-state-machine.asl.json', xdmp.database(), - sc.FLOW_DIRECTORY + 'choice-flow.asl.json', + sc.STATE_MACHINE_DIRECTORY + 'choice-state-machine.asl.json', xdmp.defaultPermissions(), - sc.FLOW_COLLECTION + sc.STATE_MACHINE_COLLECTION ); test.loadTestFile( - 'flows/retry-flow.asl.json', + 'stateMachines/retry-state-machine.asl.json', xdmp.database(), - sc.FLOW_DIRECTORY + 'retry-flow.asl.json', + sc.STATE_MACHINE_DIRECTORY + 'retry-state-machine.asl.json', xdmp.defaultPermissions(), - sc.FLOW_COLLECTION + sc.STATE_MACHINE_COLLECTION ); -// insert the test jobs +// insert the test executions test.loadTestFile( - 'test-wait-job.json', - xdmp.database(sc.STATE_CONDUCTOR_JOBS_DB), - '/stateConductorJob/test-wait-job.json', + 'test-wait-execution.json', + xdmp.database(sc.STATE_CONDUCTOR_EXECUTIONS_DB), + '/stateConductorExecution/test-wait-execution.json', xdmp.defaultPermissions(), - [sc.JOB_COLLECTION, 'unitTest'] + [sc.EXECUTION_COLLECTION, 'unitTest'] ); test.log('StateConductorSuite Suite Setup COMPLETE....'); diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/suiteTeardown.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/suiteTeardown.sjs index e1781e54..0f6bcc43 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/suiteTeardown.sjs +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/suiteTeardown.sjs @@ -5,9 +5,9 @@ declareUpdate(); const sc = require('/state-conductor/state-conductor.sjs'); const test = require('/test/test-helper.xqy'); -xdmp.directoryDelete(sc.FLOW_DIRECTORY); +xdmp.directoryDelete(sc.STATE_MACHINE_DIRECTORY); xdmp.directoryDelete('/data/'); -xdmp.directoryDelete('/stateConductorJob/'); +xdmp.directoryDelete('/stateConductorExecution/'); xdmp.invokeFunction( () => { @@ -15,7 +15,7 @@ xdmp.invokeFunction( xdmp.collectionDelete('unitTest'); }, { - database: xdmp.database(sc.STATE_CONDUCTOR_JOBS_DB), + database: xdmp.database(sc.STATE_CONDUCTOR_EXECUTIONS_DB), } ); diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/teardown.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/teardown.sjs index d0c2ce02..ed59b124 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/teardown.sjs +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/teardown.sjs @@ -6,7 +6,7 @@ const sc = require('/state-conductor/state-conductor.sjs'); const test = require('/test/test-helper.xqy'); xdmp.directoryDelete('/data/'); -xdmp.directoryDelete('/stateConductorJob/'); +xdmp.directoryDelete('/stateConductorExecution/'); xdmp.invokeFunction( () => { @@ -14,7 +14,7 @@ xdmp.invokeFunction( xdmp.collectionDelete('test'); }, { - database: xdmp.database(sc.STATE_CONDUCTOR_JOBS_DB), + database: xdmp.database(sc.STATE_CONDUCTOR_EXECUTIONS_DB), } ); diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/bad-flow.asl.json b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/bad-state-machine.asl.json similarity index 85% rename from state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/bad-flow.asl.json rename to state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/bad-state-machine.asl.json index 1f9a1a15..bf31ad1a 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/bad-flow.asl.json +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/bad-state-machine.asl.json @@ -1,5 +1,5 @@ { - "Comment": "bad flow file that references a non-existent module", + "Comment": "bad stateMachine file that references a non-existent module", "mlDomain": { "context": [ { @@ -12,7 +12,7 @@ "States": { "set-prop1": { "Type": "Task", - "Comment": "initial state of the flow", + "Comment": "initial state of the stateMachine", "Resource": "/state-conductor/actions/custom/missing-modules.sjs", "End": true }, diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/branching-flow.asl.json b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/branching-state-machine.asl.json similarity index 85% rename from state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/branching-flow.asl.json rename to state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/branching-state-machine.asl.json index 4bb43f5c..7f044ce3 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/branching-flow.asl.json +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/branching-state-machine.asl.json @@ -15,11 +15,11 @@ "Comment": "determine's enrollee's gender", "Choices": [ { - "Resource": "/state-conductor/actions/custom/branching-test-flow/gender-is-male.sjs", + "Resource": "/state-conductor/actions/custom/branching-test-state-machine/gender-is-male.sjs", "Next": "enroll-in-mens-health" }, { - "Resource": "/state-conductor/actions/custom/branching-test-flow/gender-is-female.sjs", + "Resource": "/state-conductor/actions/custom/branching-test-state-machine/gender-is-female.sjs", "Next": "enroll-in-womens-health" } ], @@ -29,19 +29,19 @@ "Type": "Task", "End": true, "Comment": "adds enrollee to the men's health program", - "Resource": "/state-conductor/actions/custom/branching-test-flow/enroll-in-mens-health.sjs" + "Resource": "/state-conductor/actions/custom/branching-test-state-machine/enroll-in-mens-health.sjs" }, "enroll-in-womens-health": { "Type": "Task", "End": true, "Comment": "adds enrollee to the womens's health program", - "Resource": "/state-conductor/actions/custom/branching-test-flow/enroll-in-womens-health.sjs" + "Resource": "/state-conductor/actions/custom/branching-test-state-machine/enroll-in-womens-health.sjs" }, "has-undetermined-gender": { "Type": "Task", "End": true, "Comment": "flags enrollee for follow-up", - "Resource": "/state-conductor/actions/custom/branching-test-flow/flag-for-follow-up.sjs" + "Resource": "/state-conductor/actions/custom/branching-test-state-machine/flag-for-follow-up.sjs" } } } diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/choice-flow.asl.json b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/choice-state-machine.asl.json similarity index 79% rename from state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/choice-flow.asl.json rename to state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/choice-state-machine.asl.json index e1f5d489..2446df83 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/choice-flow.asl.json +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/choice-state-machine.asl.json @@ -1,5 +1,5 @@ { - "Comment": "example of a branching flow using a 'Choice' type state", + "Comment": "example of a branching stateMachine using a 'Choice' type state", "mlDomain": { "context": [] }, @@ -51,19 +51,19 @@ "Type": "Task", "End": true, "Comment": "adds enrollee to the men's health program", - "Resource": "/state-conductor/actions/branching-test-flow/enroll-in-mens-health.sjs" + "Resource": "/state-conductor/actions/branching-test-state-machine/enroll-in-mens-health.sjs" }, "enroll-in-womens-health": { "Type": "Task", "End": true, "Comment": "adds enrollee to the womens's health program", - "Resource": "/state-conductor/actions/branching-test-flow/enroll-in-womens-health.sjs" + "Resource": "/state-conductor/actions/branching-test-state-machine/enroll-in-womens-health.sjs" }, "has-undetermined-gender": { "Type": "Task", "End": true, "Comment": "flags enrollee for follow-up", - "Resource": "/state-conductor/actions/branching-test-flow/flag-for-follow-up.sjs" + "Resource": "/state-conductor/actions/branching-test-state-machine/flag-for-follow-up.sjs" } } } diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/contextual-flow.asl.json b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/contextual-state-machine.asl.json similarity index 83% rename from state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/contextual-flow.asl.json rename to state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/contextual-state-machine.asl.json index 1cab79f2..bf926496 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/contextual-flow.asl.json +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/contextual-state-machine.asl.json @@ -1,5 +1,5 @@ { - "Comment": "example flow that utilizes the context to create new documents", + "Comment": "example stateMachine that utilizes the context to create new documents", "mlDomain": { "context": [ { @@ -9,6 +9,10 @@ { "scope": "event", "value": "test" + }, + { + "scope": "event", + "value": "series-of-clicks-and-beeps-connected" } ] }, diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/no-context-flow.asl.json b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/no-context-state-machine.asl.json similarity index 86% rename from state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/no-context-flow.asl.json rename to state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/no-context-state-machine.asl.json index 62fc8555..2c329b7c 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/no-context-flow.asl.json +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/no-context-state-machine.asl.json @@ -7,7 +7,7 @@ "States": { "set-prop1": { "Type": "Task", - "Comment": "initial state of the flow", + "Comment": "initial state of the stateMachine", "Resource": "/state-conductor/actions/custom/set-prop1.sjs", "Next": "set-prop2" }, diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/noStates-flow.asl.json b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/noStates-state-machine.asl.json similarity index 75% rename from state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/noStates-flow.asl.json rename to state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/noStates-state-machine.asl.json index c2b09167..da72e9f4 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/noStates-flow.asl.json +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/noStates-state-machine.asl.json @@ -1,5 +1,5 @@ { - "Comment": "a flow for unit testing", + "Comment": "a stateMachine for unit testing", "mlDomain": { "context": [ { diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/ref-path-flow.asl.json b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/ref-path-state-machine.asl.json similarity index 100% rename from state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/ref-path-flow.asl.json rename to state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/ref-path-state-machine.asl.json diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/retry-flow.asl.json b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/retry-state-machine.asl.json similarity index 98% rename from state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/retry-flow.asl.json rename to state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/retry-state-machine.asl.json index eca89ff0..1accc97d 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/retry-flow.asl.json +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/retry-state-machine.asl.json @@ -16,7 +16,7 @@ "States": { "errorOut": { "Type": "Task", - "Comment": "initial state of the flow", + "Comment": "initial state of the stateMachine", "Resource": "/state-conductor/actions/custom/errorOut.sjs", "Next": "fourMaxAttempts", "Retry": [ diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/task-flow.asl.json b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/task-state-machine.asl.json similarity index 82% rename from state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/task-flow.asl.json rename to state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/task-state-machine.asl.json index 0169c354..a6c056ed 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/task-flow.asl.json +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/task-state-machine.asl.json @@ -16,13 +16,13 @@ "States": { "update-context": { "Type": "Task", - "Comment": "initial state of the flow", + "Comment": "initial state of the stateMachine", "Resource": "/state-conductor/actions/custom/return-into-context.sjs", "Next": "parameters-check" }, "parameters-check": { "Type": "Task", - "Comment": "initial state of the flow", + "Comment": "initial state of the stateMachine", "Resource": "/state-conductor/actions/custom/parameters-check.sjs", "Parameters": { "name": ["David"] diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/test-flow.asl.json b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/test-state-machine.asl.json similarity index 92% rename from state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/test-flow.asl.json rename to state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/test-state-machine.asl.json index 75a4b741..6b0a71a4 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/test-flow.asl.json +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/test-state-machine.asl.json @@ -16,7 +16,7 @@ "States": { "set-prop1": { "Type": "Task", - "Comment": "initial state of the flow", + "Comment": "initial state of the stateMachine", "Resource": "/state-conductor/actions/custom/set-prop1.sjs", "Next": "set-prop2" }, diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/test-time-wait.asl.json b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/test-time-wait.asl.json similarity index 100% rename from state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/test-time-wait.asl.json rename to state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/test-time-wait.asl.json diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/wait-flow.asl.json b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/wait-state-machine.asl.json similarity index 93% rename from state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/wait-flow.asl.json rename to state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/wait-state-machine.asl.json index 4f32b4cb..5cce09d7 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/flows/wait-flow.asl.json +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/stateMachines/wait-state-machine.asl.json @@ -26,7 +26,7 @@ }, "parameters-check": { "Type": "Task", - "Comment": "initial state of the flow", + "Comment": "initial state of the stateMachine", "Resource": "/state-conductor/actions/custom/parameters-check.sjs", "Parameters": { "name": ["David"] diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/test-wait-job.json b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/test-wait-execution.json similarity index 84% rename from state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/test-wait-job.json rename to state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/test-wait-execution.json index 31da4f2b..582f3342 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/test-wait-job.json +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/test-data/test-wait-execution.json @@ -1,8 +1,8 @@ { "id": "0405536f-dd84-4ca6-8de8-c57062b2252d", - "flowName": "wait-flow", - "flowStatus": "waiting", - "flowState": "dialUp", + "name": "wait-state-machine", + "status": "waiting", + "state": "dialUp", "uri": "/data/test-doc1.json", "database": "18362886368181886203", "modules": "8102028357983228731", diff --git a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/timeWait-test.sjs b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/timeWait-test.sjs index 42c9752d..08fba355 100644 --- a/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/timeWait-test.sjs +++ b/state-conductor-example/src/test/ml-modules/root/test/suites/StateConductorSuite/timeWait-test.sjs @@ -4,13 +4,13 @@ const sc = require('/state-conductor/state-conductor.sjs'); const test = require('/test/test-helper.xqy'); const assertions = []; -let jobDoc, assertion; +let executionDoc, assertion; -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '4164b17b-06a5-499b-8870-539add9f69c2', - flowName: 'test-time-wait', - flowStatus: 'working', - flowState: 'run-in-the-future', + name: 'test-time-wait', + status: 'working', + state: 'run-in-the-future', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -20,11 +20,11 @@ jobDoc = xdmp.toJSON({ errors: {}, }); -//"test excute job") -//"test excute job") -assertion = sc.executeStateByJobDoc(jobDoc, false); +//"test excute execution") +//"test excute execution") +assertion = sc.executeStateByExecutionDoc(executionDoc, false); assertions.push( - test.assertEqual('waiting', assertion.flowStatus, 'waiting flowStatus')); + test.assertEqual('waiting', assertion.status, 'waiting status')); assertions.push( test.assertTrue(assertion.hasOwnProperty('currentlyWaiting')) ); @@ -35,11 +35,11 @@ assertions.push( test.assertTrue(assertion.provenance[0].waiting.hasOwnProperty("doneNextTaskTime")) ); -jobDoc = xdmp.toJSON({ +executionDoc = xdmp.toJSON({ id: '4164b17b-06a5-499b-8870-539add9f69c2', - flowName: 'test-time-wait', - flowStatus: 'waiting', - flowState: 'run-in-the-future', + name: 'test-time-wait', + status: 'waiting', + state: 'run-in-the-future', uri: '/data/test-doc1.json', database: xdmp.database(), modules: xdmp.modulesDatabase(), @@ -67,14 +67,14 @@ jobDoc = xdmp.toJSON({ }, }); -//"found waiting job") -assertion = sc.resumeWaitingJobByJobDoc(jobDoc, 'waitTask', false); -assertions.push(test.assertEqual('working', assertion.flowStatus, 'working flowStatus')); +//"found waiting execution") +assertion = sc.resumeWaitingExecutionByExecutionDoc(executionDoc, 'waitTask', false); +assertions.push(test.assertEqual('working', assertion.status, 'working status')); assertions.push( test.assertEqual('needs-envelope', assertion.provenance[3].to, 'went to next state') ); assertions.push( test.assertFalse(assertion.hasOwnProperty('currentlyWaiting'), 'waiting currentlyWaiting') ); -assertions.push(test.assertEqual('needs-envelope', assertion.flowState, 'working flowStatus')); +assertions.push(test.assertEqual('needs-envelope', assertion.state, 'working status')); assertions; diff --git a/state-conductor-example/src/test/resources/jobs/job1.json b/state-conductor-example/src/test/resources/executions/job1.json similarity index 64% rename from state-conductor-example/src/test/resources/jobs/job1.json rename to state-conductor-example/src/test/resources/executions/job1.json index d57111b8..62d68b5e 100644 --- a/state-conductor-example/src/test/resources/jobs/job1.json +++ b/state-conductor-example/src/test/resources/executions/job1.json @@ -1,8 +1,8 @@ { - "id": "job1", - "flowName": "rest-test-flow", - "flowStatus": "new", - "flowState": null, + "id": "execution1", + "name": "rest-test-state-machine", + "status": "new", + "state": null, "uri": "/test/doc1.json", "database": "%DATABASE%", "modules": "%MODULES%", diff --git a/state-conductor-example/src/test/resources/jobs/job2.json b/state-conductor-example/src/test/resources/executions/job2.json similarity index 64% rename from state-conductor-example/src/test/resources/jobs/job2.json rename to state-conductor-example/src/test/resources/executions/job2.json index 287db15b..6552a16c 100644 --- a/state-conductor-example/src/test/resources/jobs/job2.json +++ b/state-conductor-example/src/test/resources/executions/job2.json @@ -1,8 +1,8 @@ { - "id": "job2", - "flowName": "rest-test-flow", - "flowStatus": "new", - "flowState": null, + "id": "execution2", + "name": "rest-test-state-machine", + "status": "new", + "state": null, "uri": "/test/doc1.json", "database": "%DATABASE%", "modules": "%MODULES%", diff --git a/state-conductor-example/src/test/resources/jobs/job3.json b/state-conductor-example/src/test/resources/executions/job3.json similarity index 59% rename from state-conductor-example/src/test/resources/jobs/job3.json rename to state-conductor-example/src/test/resources/executions/job3.json index 7f643017..80278c08 100644 --- a/state-conductor-example/src/test/resources/jobs/job3.json +++ b/state-conductor-example/src/test/resources/executions/job3.json @@ -1,8 +1,8 @@ { - "id": "job3", - "flowName": "rest-test-flow", - "flowStatus": "working", - "flowState": "add-collection-1", + "id": "execution3", + "name": "rest-test-state-machine", + "status": "working", + "state": "add-collection-1", "uri": "/test/doc1.json", "database": "%DATABASE%", "modules": "%MODULES%", diff --git a/state-conductor-example/src/test/resources/jobs/job4.json b/state-conductor-example/src/test/resources/executions/job4.json similarity index 63% rename from state-conductor-example/src/test/resources/jobs/job4.json rename to state-conductor-example/src/test/resources/executions/job4.json index 744ebaf1..bd31bc30 100644 --- a/state-conductor-example/src/test/resources/jobs/job4.json +++ b/state-conductor-example/src/test/resources/executions/job4.json @@ -1,8 +1,8 @@ { - "id": "job4", - "flowName": "rest-test-flow3", - "flowStatus": "new", - "flowState": null, + "id": "execution4", + "name": "rest-test-state-machine3", + "status": "new", + "state": null, "uri": "/test/doc1.json", "database": "%DATABASE%", "modules": "%MODULES%", diff --git a/state-conductor-example/src/test/resources/jobs/job5.json b/state-conductor-example/src/test/resources/executions/job5.json similarity index 64% rename from state-conductor-example/src/test/resources/jobs/job5.json rename to state-conductor-example/src/test/resources/executions/job5.json index 22ecda53..ca5ad850 100644 --- a/state-conductor-example/src/test/resources/jobs/job5.json +++ b/state-conductor-example/src/test/resources/executions/job5.json @@ -1,8 +1,8 @@ { - "id": "job5", - "flowName": "rest-test-flow3", - "flowStatus": "new", - "flowState": null, + "id": "execution5", + "name": "rest-test-state-machine3", + "status": "new", + "state": null, "uri": "/test/doc1.json", "database": "%DATABASE%", "modules": "%MODULES%", diff --git a/state-conductor-example/src/test/resources/jobs/job6.json b/state-conductor-example/src/test/resources/executions/job6.json similarity index 60% rename from state-conductor-example/src/test/resources/jobs/job6.json rename to state-conductor-example/src/test/resources/executions/job6.json index 9fd677be..6e6373ea 100644 --- a/state-conductor-example/src/test/resources/jobs/job6.json +++ b/state-conductor-example/src/test/resources/executions/job6.json @@ -1,8 +1,8 @@ { - "id": "job6", - "flowName": "rest-test-flow3", - "flowStatus": "working", - "flowState": "add-collection-1", + "id": "execution6", + "name": "rest-test-state-machine3", + "status": "working", + "state": "add-collection-1", "uri": "/test/doc1.json", "database": "%DATABASE%", "modules": "%MODULES%", diff --git a/state-conductor-example/src/test/resources/jobs/job7.json b/state-conductor-example/src/test/resources/executions/job7.json similarity index 63% rename from state-conductor-example/src/test/resources/jobs/job7.json rename to state-conductor-example/src/test/resources/executions/job7.json index 3fc3f58a..6ee59be1 100644 --- a/state-conductor-example/src/test/resources/jobs/job7.json +++ b/state-conductor-example/src/test/resources/executions/job7.json @@ -1,8 +1,8 @@ { - "id": "job7", - "flowName": "rest-test-flow4", - "flowStatus": "new", - "flowState": null, + "id": "execution7", + "name": "rest-test-state-machine4", + "status": "new", + "state": null, "uri": "/test/doc2.json", "database": "%DATABASE%", "modules": "%MODULES%", diff --git a/state-conductor-example/src/test/resources/flows/invalid-test-flow.asl.json b/state-conductor-example/src/test/resources/stateMachines/invalid-test-flow.asl.json similarity index 100% rename from state-conductor-example/src/test/resources/flows/invalid-test-flow.asl.json rename to state-conductor-example/src/test/resources/stateMachines/invalid-test-flow.asl.json diff --git a/state-conductor-example/src/test/resources/flows/rest-test-flow.asl.json b/state-conductor-example/src/test/resources/stateMachines/rest-test-flow.asl.json similarity index 100% rename from state-conductor-example/src/test/resources/flows/rest-test-flow.asl.json rename to state-conductor-example/src/test/resources/stateMachines/rest-test-flow.asl.json diff --git a/state-conductor-example/src/test/resources/flows/rest-test-flow2.asl.json b/state-conductor-example/src/test/resources/stateMachines/rest-test-flow2.asl.json similarity index 100% rename from state-conductor-example/src/test/resources/flows/rest-test-flow2.asl.json rename to state-conductor-example/src/test/resources/stateMachines/rest-test-flow2.asl.json diff --git a/state-conductor-example/src/test/resources/flows/rest-test-flow3.asl.json b/state-conductor-example/src/test/resources/stateMachines/rest-test-flow3.asl.json similarity index 100% rename from state-conductor-example/src/test/resources/flows/rest-test-flow3.asl.json rename to state-conductor-example/src/test/resources/stateMachines/rest-test-flow3.asl.json diff --git a/state-conductor-example/src/test/resources/flows/rest-test-flow4.asl.json b/state-conductor-example/src/test/resources/stateMachines/rest-test-flow4.asl.json similarity index 100% rename from state-conductor-example/src/test/resources/flows/rest-test-flow4.asl.json rename to state-conductor-example/src/test/resources/stateMachines/rest-test-flow4.asl.json diff --git a/state-conductor-modules/driver.properties b/state-conductor-modules/driver.properties new file mode 100644 index 00000000..8f959022 --- /dev/null +++ b/state-conductor-modules/driver.properties @@ -0,0 +1,5 @@ +mlHost=localhost +mlPort=8010 +username=admin +password=admin + diff --git a/state-conductor-modules/src/main/ml-config/databases/state-conductor-jobs-database.json b/state-conductor-modules/src/main/ml-config/databases/state-conductor-jobs-database.json index 5a244bce..0c5d8332 100644 --- a/state-conductor-modules/src/main/ml-config/databases/state-conductor-jobs-database.json +++ b/state-conductor-modules/src/main/ml-config/databases/state-conductor-jobs-database.json @@ -1,5 +1,5 @@ { - "database-name": "state-conductor-jobs", + "database-name": "state-conductor-executions", "maintain-last-modified": true, "range-element-index": [ { diff --git a/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-execute-role.json b/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-execute-role.json index b79d3202..7e2b6673 100644 --- a/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-execute-role.json +++ b/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-execute-role.json @@ -1,13 +1,13 @@ { "role-name": "state-conductor-execute-role", - "description": "Permits reading flow documents and knowing flow status", + "description": "Permits reading stateMachine documents and knowing stateMachine status", "role": [ - "state-conductor-job-writer-role" + "state-conductor-execution-writer-role" ], "privilege": [ { - "privilege-name": "state-conductor-flow", - "action": "/state-conductor-flow/", + "privilege-name": "state-conductor-state-machine", + "action": "/state-conductor-state-machine/", "kind": "uri" } ] diff --git a/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-job-writer-role.json b/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-execution-writer-role.json similarity index 60% rename from state-conductor-modules/src/main/ml-config/security/roles/state-conductor-job-writer-role.json rename to state-conductor-modules/src/main/ml-config/security/roles/state-conductor-execution-writer-role.json index 24fc0372..376ad2e1 100644 --- a/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-job-writer-role.json +++ b/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-execution-writer-role.json @@ -1,6 +1,6 @@ { - "role-name": "state-conductor-job-writer-role", - "description": "Permits reading flow documents and knowing flow status", + "role-name": "state-conductor-execution-writer-role", + "description": "Permits reading stateMachine documents and knowing stateMachine status", "role": [ "state-conductor-reader-role" ], @@ -11,7 +11,7 @@ "kind": "execute" }, { - "privilege-name": "state-conductor-job", + "privilege-name": "state-conductor-execution", "action": "/state-conductor/", "kind": "uri" } diff --git a/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-operetor.json b/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-operator.json similarity index 90% rename from state-conductor-modules/src/main/ml-config/security/roles/state-conductor-operetor.json rename to state-conductor-modules/src/main/ml-config/security/roles/state-conductor-operator.json index c0b6e2ae..ae0d3226 100644 --- a/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-operetor.json +++ b/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-operator.json @@ -1,10 +1,10 @@ { "role-name": "state-conductor-operator", - "description": "Permits operating a state conductor, such as running flows and viewing job data.", + "description": "Permits operating a state conductor, such as running stateMachines and viewing execution data.", "role": [ "rest-extension-user", "rest-reader", - "state-conductor-job-writer-role" + "state-conductor-execution-writer-role" ], "privilege": [ { diff --git a/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-reader-role.json b/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-reader-role.json index 7dd43167..74d6d392 100644 --- a/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-reader-role.json +++ b/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-reader-role.json @@ -1,4 +1,4 @@ { "role-name": "state-conductor-reader-role", - "description": "Permits reading flow documents and knowing flow status" + "description": "Permits reading stateMachine documents and knowing stateMachine status" } diff --git a/state-conductor-modules/src/main/ml-config/triggers/state-conductor-item-create-trigger.json b/state-conductor-modules/src/main/ml-config/triggers/state-conductor-item-create-trigger.json index 53b79bb6..e3193c0d 100644 --- a/state-conductor-modules/src/main/ml-config/triggers/state-conductor-item-create-trigger.json +++ b/state-conductor-modules/src/main/ml-config/triggers/state-conductor-item-create-trigger.json @@ -1,6 +1,6 @@ { "name": "state-conductor-item-create-trigger", - "description": "creates a batch file pointing the triggering document and applicable flows for state condutor to operate on", + "description": "creates a batch file pointing the triggering document and applicable stateMachines for state condutor to operate on", "event": { "data-event": { "collection-scope": { diff --git a/state-conductor-modules/src/main/ml-config/triggers/state-conductor-item-update-trigger.json b/state-conductor-modules/src/main/ml-config/triggers/state-conductor-item-update-trigger.json index e7a9b387..8539e91c 100644 --- a/state-conductor-modules/src/main/ml-config/triggers/state-conductor-item-update-trigger.json +++ b/state-conductor-modules/src/main/ml-config/triggers/state-conductor-item-update-trigger.json @@ -1,6 +1,6 @@ { "name": "state-conductor-item-update-trigger", - "description": "creates a batch file pointing the triggering document and applicable flows for state condutor to operate on", + "description": "creates a batch file pointing the triggering document and applicable stateMachines for state condutor to operate on", "event": { "data-event": { "collection-scope": { diff --git a/state-conductor-modules/src/main/ml-data/state-conductor-flow/collections.properties b/state-conductor-modules/src/main/ml-data/state-conductor-flow/collections.properties index 49849826..774560e8 100644 --- a/state-conductor-modules/src/main/ml-data/state-conductor-flow/collections.properties +++ b/state-conductor-modules/src/main/ml-data/state-conductor-flow/collections.properties @@ -1 +1 @@ -*=state-conductor-flow \ No newline at end of file +*=state-conductor-state-machine \ No newline at end of file diff --git a/state-conductor-modules/src/main/ml-data/state-conductor-flow/permissions.properties b/state-conductor-modules/src/main/ml-data/state-conductor-flow/permissions.properties index c3c2df10..3161f325 100644 --- a/state-conductor-modules/src/main/ml-data/state-conductor-flow/permissions.properties +++ b/state-conductor-modules/src/main/ml-data/state-conductor-flow/permissions.properties @@ -1 +1 @@ -*=state-conductor-job-writer-role,read,state-conductor-job-writer-role,update +*=state-conductor-execution-writer-role,read,state-conductor-execution-writer-role,update diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/corb2/process-module.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/corb2/process-module.sjs index 1a1be065..19788f6f 100644 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/corb2/process-module.sjs +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/corb2/process-module.sjs @@ -12,9 +12,9 @@ var URI; xdmp.invokeFunction( () => { declareUpdate(); - return sc.processJob(URI); + return sc.processExecution(URI); }, { - database: xdmp.database(sc.STATE_CONDUCTOR_JOBS_DB), + database: xdmp.database(sc.STATE_CONDUCTOR_EXECUTIONS_DB), } ); diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/corb2/uris-module.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/corb2/uris-module.sjs index a0ac05e8..cf3326c1 100644 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/corb2/uris-module.sjs +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/corb2/uris-module.sjs @@ -5,27 +5,27 @@ const sc = require('/state-conductor/state-conductor.sjs'); // external variables -var jobCount; -var flowNames; +var executionCount; +var names; var resumeWait; -if (!jobCount) { - jobCount = 1000; +if (!executionCount) { + executionCount = 1000; } -if (flowNames) { - flowNames = flowNames.split(','); +if (names) { + names = names.split(','); } let options = { - count: jobCount, - flowStatus: [sc.FLOW_STATUS_NEW, sc.FLOW_STATUS_WORKING], - flowNames: flowNames, + count: executionCount, + status: [sc.STATE_MACHINE_STATUS_NEW, sc.STATE_MACHINE_STATUS_WORKING], + names: names, startDate: null, endDate: null, resumeWait: resumeWait, }; -const uris = sc.getJobDocuments(options); +const uris = sc.getExecutionDocuments(options); Sequence.from([uris.length, ...uris]); diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/createExecution.api b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/createExecution.api new file mode 100644 index 00000000..a3fd62b3 --- /dev/null +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/createExecution.api @@ -0,0 +1,22 @@ +{ + "functionName": "createExecution", + "desc": "Creates a MarkLogic State Conductor Execution document for the given uri and state machine name.", + "params": [ + { + "name": "uri", + "datatype": "string", + "desc": "The uri of a document to be processed by the state machine", + "nullable": false + }, + { + "name": "name", + "datatype": "string", + "desc": "The name of the State Machine", + "nullable": false + } + ], + "return": { + "datatype": "string", + "desc": "The Execution ID of the State Conductor Execution document" + } +} diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/createJob.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/createExecution.sjs similarity index 69% rename from state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/createJob.sjs rename to state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/createExecution.sjs index b05dea73..1640c9f6 100644 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/createJob.sjs +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/createExecution.sjs @@ -8,7 +8,7 @@ const sc = require('/state-conductor/state-conductor.sjs'); // external variables var uri; -var flowName; +var name; if (!fn.docAvailable(uri)) { fn.error( @@ -18,15 +18,15 @@ if (!fn.docAvailable(uri)) { ); } -if (!sc.getFlowDocument(flowName)) { +if (!sc.getStateMachine(name)) { fn.error( null, 'STATE-CONDUCTOR-ERROR', - Sequence.from([400, 'Bad Request', `Flow File "${flowName}" not found.`]) + Sequence.from([400, 'Bad Request', `State Machine "${name}" not found.`]) ); } -const jobId = sc.createStateConductorJob(flowName, uri); +const id = sc.createStateConductorExecution(name, uri); // return -jobId; +id; diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/createJob.api b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/createJob.api deleted file mode 100644 index 001f14c7..00000000 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/createJob.api +++ /dev/null @@ -1,22 +0,0 @@ -{ - "functionName": "createJob", - "desc": "Creates a MarkLogic State Conductor Job document for the given uri and flow.", - "params": [ - { - "name": "uri", - "datatype": "string", - "desc": "The uri of a document to be processed by the flow", - "nullable": false - }, - { - "name": "flowName", - "datatype": "string", - "desc": "The name of the State Conductor Flow", - "nullable": false - } - ], - "return": { - "datatype": "string", - "desc": "The Job ID of the State Conductor Job document" - } -} diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/deleteFlow.api b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/deleteFlow.api deleted file mode 100644 index dd9a2ccf..00000000 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/deleteFlow.api +++ /dev/null @@ -1,13 +0,0 @@ -{ - "functionName": "deleteFlow", - "desc": "Deletes a single flow.", - "params": [ - { - "name": "flowName", - "datatype": "string", - "desc": "The name of the flow to be created or updated.", - "nullable": false, - "multiple": false - } - ] -} \ No newline at end of file diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/deleteFlow.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/deleteFlow.sjs deleted file mode 100644 index af32d70f..00000000 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/deleteFlow.sjs +++ /dev/null @@ -1,27 +0,0 @@ -'use strict'; - -declareUpdate(); - -const sc = require('/state-conductor/state-conductor.sjs'); - -var flowName; - -deleteFlow(flowName); - -/** - * Delete a flow - * - * @param {string} flowName Name of the flow to be deleted - */ -function deleteFlow(flowName) { - const cleanFlowName = flowName ? flowName.trim() : ''; - if (cleanFlowName === '') { - fn.error(xs.QName("ERROR"), `Missing parameter "flowName"`); - } - const flow = sc.getFlowDocument(cleanFlowName); - if(!flow) { - fn.error(xs.QName("ERROR"), `Flow File "${cleanFlowName}" not found`); - } - const uri = fn.documentUri(flow); - xdmp.documentDelete(uri); -} diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/deleteStateMachine.api b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/deleteStateMachine.api new file mode 100644 index 00000000..a75a35b4 --- /dev/null +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/deleteStateMachine.api @@ -0,0 +1,13 @@ +{ + "functionName": "deleteStateMachine", + "desc": "Deletes a single state machine.", + "params": [ + { + "name": "name", + "datatype": "string", + "desc": "The name of the state machine to be deleted.", + "nullable": false, + "multiple": false + } + ] +} \ No newline at end of file diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/deleteStateMachine.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/deleteStateMachine.sjs new file mode 100644 index 00000000..0f335248 --- /dev/null +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/deleteStateMachine.sjs @@ -0,0 +1,27 @@ +'use strict'; + +declareUpdate(); + +const sc = require('/state-conductor/state-conductor.sjs'); + +var name; + +deleteStateMachine(name); + +/** + * Delete a state machine + * + * @param {string} name Name of the state machine to be deleted + */ +function deleteStateMachine(name) { + const cleanName = name ? name.trim() : ''; + if (cleanName === '') { + fn.error(xs.QName("ERROR"), `Missing parameter "name"`); + } + const stateMachine = sc.getStateMachine(cleanName); + if(!stateMachine) { + fn.error(xs.QName("ERROR"), `State Machine "${cleanName}" not found`); + } + const uri = fn.documentUri(stateMachine); + xdmp.documentDelete(uri); +} diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getJobs.api b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getExecutions.api similarity index 56% rename from state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getJobs.api rename to state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getExecutions.api index 22d660dd..ec5a1518 100644 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getJobs.api +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getExecutions.api @@ -1,6 +1,6 @@ { - "functionName": "getJobs", - "desc": "Returns a list of MarkLogic State Conductor Job document URIs", + "functionName": "getExecutions", + "desc": "Returns a list of MarkLogic State Conductor Execution document URIs", "params": [ { "name": "start", @@ -15,35 +15,35 @@ "nullable": true }, { - "name": "flowNames", + "name": "names", "datatype": "string", - "desc": "A list of flow names to filter the returned job documents", + "desc": "A list of state machine names to filter the returned execution documents", "nullable": true }, { - "name": "flowStatus", + "name": "status", "datatype": "string", - "desc": "A list of flow status's to filter the returned job documents. Defaults to 'new' and 'working'.", + "desc": "A list of state machine status's to filter the returned execution documents. Defaults to 'new' and 'working'.", "nullable": true, "multiple": true }, { "name": "forestIds", "datatype": "string", - "desc": "The returned list of job documents will be limited to jobs found in this list of forests.", + "desc": "The returned list of execution documents will be limited to executions found in this list of forests.", "nullable": true, "multiple": true }, { "name": "startDate", "datatype": "dateTime", - "desc": "Filter on jobs created after this date and time.", + "desc": "Filter on executions created after this date and time.", "nullable": true }, { "name": "endDate", "datatype": "dateTime", - "desc": "Filter on jobs created prior to this date and time.", + "desc": "Filter on executions created prior to this date and time.", "nullable": true } ], diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getExecutions.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getExecutions.sjs new file mode 100644 index 00000000..b71ae0e9 --- /dev/null +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getExecutions.sjs @@ -0,0 +1,63 @@ +/** + * DATA SERVICES MODULE + */ +'use strict'; +const sc = require('/state-conductor/state-conductor.sjs'); + +// external variables +var start; +var count; +var names; +var status; +var forestIds; +var startDate; +var endDate; + +xdmp.trace( + sc.TRACE_EVENT, + `Start: ${start}, Count: ${count}, names: ${xdmp.describe( + names + )}, status: ${xdmp.describe(status)}, startDate: ${startDate}, endDate: ${endDate}` +); + +start = start || 1; +count = count || 1000; + +if (names) { + names = names.split(','); +} + +if (Array.isArray(status)) { + // continue +} else if (status instanceof Sequence) { + status = status.toArray(); +} else if (typeof status === 'string') { + status = [status]; +} else { + status = [sc.STATE_MACHINE_STATUS_NEW, sc.STATE_MACHINE_STATUS_WORKING]; +} + +if (Array.isArray(forestIds)) { + // continue +} else if (forestIds instanceof Sequence) { + forestIds = forestIds.toArray(); +} else if (typeof forestIds === 'string') { + forestIds = forestIds.split(','); +} + +let options = { + start, + count, + status, + names, + forestIds, + startDate, + endDate, +}; + +const uris = sc.getExecutionDocuments(options); + +xdmp.trace(sc.TRACE_EVENT, `getExecutionDocuments found ${uris.length} execution documents`); + +// return +Sequence.from(uris); diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getFlow.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getFlow.sjs deleted file mode 100644 index fcf32c42..00000000 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getFlow.sjs +++ /dev/null @@ -1,41 +0,0 @@ -'use strict'; - -const sc = require('/state-conductor/state-conductor.sjs'); - -var flowName; - -let result; -if (flowName) { - result = getFlowDetail(flowName); -} -else { - result = getAllFlows(); -} -result - -/** - * Get a single flow by name - * - * @param {string} flowName The name of the flow to be returned - */ -function getFlowDetail(flowName) { - const flow = sc.getFlowDocument(flowName); - if (flow) { - return flow; - } - else { - fn.error(xs.QName("ERROR"), `Flow file "${flowName}" not found`); - } -} - -/** - * Get all available flows - */ -function getAllFlows() { - const flows = sc.getFlowDocuments(); - return flows.toArray().reduce((acc, flow) => { - let name = sc.getFlowNameFromUri(fn.documentUri(flow)); - acc[name] = flow.toObject(); - return acc; - }, {}); -} diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getJobs.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getJobs.sjs deleted file mode 100644 index d2f49594..00000000 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getJobs.sjs +++ /dev/null @@ -1,63 +0,0 @@ -/** - * DATA SERVICES MODULE - */ -'use strict'; -const sc = require('/state-conductor/state-conductor.sjs'); - -// external variables -var start; -var count; -var flowNames; -var flowStatus; -var forestIds; -var startDate; -var endDate; - -xdmp.trace( - sc.TRACE_EVENT, - `Start: ${start}, Count: ${count}, flowNames: ${xdmp.describe( - flowNames - )}, flowStatus: ${xdmp.describe(flowStatus)}, startDate: ${startDate}, endDate: ${endDate}` -); - -start = start || 1; -count = count || 1000; - -if (flowNames) { - flowNames = flowNames.split(','); -} - -if (Array.isArray(flowStatus)) { - // continue -} else if (flowStatus instanceof Sequence) { - flowStatus = flowStatus.toArray(); -} else if (typeof flowStatus === 'string') { - flowStatus = [flowStatus]; -} else { - flowStatus = [sc.FLOW_STATUS_NEW, sc.FLOW_STATUS_WORKING]; -} - -if (Array.isArray(forestIds)) { - // continue -} else if (forestIds instanceof Sequence) { - forestIds = forestIds.toArray(); -} else if (typeof forestIds === 'string') { - forestIds = forestIds.split(','); -} - -let options = { - start, - count, - flowStatus, - flowNames, - forestIds, - startDate, - endDate, -}; - -const uris = sc.getJobDocuments(options); - -xdmp.trace(sc.TRACE_EVENT, `getJobs found ${uris.length} job documents`); - -// return -Sequence.from(uris); diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getFlow.api b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getStateMachine.api similarity index 50% rename from state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getFlow.api rename to state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getStateMachine.api index ed12e6d5..76ed6f98 100644 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getFlow.api +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getStateMachine.api @@ -1,11 +1,11 @@ { - "functionName": "getFlow", - "desc": "Returns a single flow if flowName is specified or all flows otherwise.", + "functionName": "getStateMachine", + "desc": "Returns a single stateMachine if name is specified or all stateMachines otherwise.", "params": [ { - "name": "flowName", + "name": "name", "datatype": "string", - "desc": "The name of the flow to return. Pass null to return all.", + "desc": "The name of the stateMachine to return. Pass null to return all.", "nullable": true, "multiple": false } diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getStateMachine.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getStateMachine.sjs new file mode 100644 index 00000000..7f67d118 --- /dev/null +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getStateMachine.sjs @@ -0,0 +1,41 @@ +'use strict'; + +const sc = require('/state-conductor/state-conductor.sjs'); + +var name; + +let result; +if (name) { + result = getStateMachineDetail(name); +} +else { + result = getAllStateMachines(); +} +result + +/** + * Get a single state machine by name + * + * @param {string} name The name of the state machine to be returned + */ +function getStateMachineDetail(name) { + const stateMachine = sc.getStateMachine(name); + if (stateMachine) { + return stateMachine; + } + else { + fn.error(xs.QName("ERROR"), `State Machine "${name}" not found`); + } +} + +/** + * Get all available state machines + */ +function getAllStateMachines() { + const stateMachines = sc.getStateMachines(); + return stateMachines.toArray().reduce((acc, stateMachine) => { + let name = sc.getStateMachineNameFromUri(fn.documentUri(stateMachine)); + acc[name] = stateMachine.toObject(); + return acc; + }, {}); +} diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getFlowStatus.api b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getStateMachineStatus.api similarity index 59% rename from state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getFlowStatus.api rename to state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getStateMachineStatus.api index 503496dd..690bc825 100644 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getFlowStatus.api +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getStateMachineStatus.api @@ -1,30 +1,30 @@ { - "functionName": "getFlowStatus", - "desc": "Returns the status and states of one or more State Conductor flows.", + "functionName": "getStateMachineStatus", + "desc": "Returns the status and states of one or more State Conductor state machines.", "params": [ { - "name": "flowNames", + "name": "names", "datatype": "string", - "desc": "The flow names for which to report status.", + "desc": "The state machine names for which to report status.", "nullable": true, "multiple": true }, { "name": "startDate", "datatype": "dateTime", - "desc": "Filter on jobs created after this date and time.", + "desc": "Filter on executions created after this date and time.", "nullable": true }, { "name": "endDate", "datatype": "dateTime", - "desc": "Filter on jobs created prior to this date and time.", + "desc": "Filter on executions created prior to this date and time.", "nullable": true }, { "name": "detailed", "datatype": "boolean", - "desc": "Include detailed breakdown of jobs per state per status?", + "desc": "Include detailed breakdown of executions per state per status?", "nullable": true } ], diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getFlowStatus.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getStateMachineStatus.sjs similarity index 55% rename from state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getFlowStatus.sjs rename to state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getStateMachineStatus.sjs index 8383f75a..abdd81df 100644 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getFlowStatus.sjs +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/getStateMachineStatus.sjs @@ -5,19 +5,19 @@ const sc = require('/state-conductor/state-conductor.sjs'); // external variables -var flowNames; +var names; var startDate; var endDate; var detailed; -if (Array.isArray(flowNames)) { +if (Array.isArray(names)) { // continue -} else if (flowNames instanceof Sequence) { - flowNames = flowNames.toArray(); -} else if (typeof flowNames === 'string') { - flowNames = [flowNames]; +} else if (names instanceof Sequence) { + names = names.toArray(); +} else if (typeof names === 'string') { + names = [names]; } else { - flowNames = sc.getFlowNames(); + names = sc.getStateMachineNames(); } if (typeof detailed === 'string') { @@ -26,8 +26,8 @@ if (typeof detailed === 'string') { detailed = !!detailed; } -const resp = flowNames.reduce((acc, name) => { - acc[name] = sc.getFlowCounts(name, { +const resp = names.reduce((acc, name) => { + acc[name] = sc.getStateMachineCounts(name, { startDate, endDate, detailed, diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/insertFlow.api b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/insertFlow.api deleted file mode 100644 index 243432d1..00000000 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/insertFlow.api +++ /dev/null @@ -1,20 +0,0 @@ -{ - "functionName": "insertFlow", - "desc": "Creates or updates a single flow.", - "params": [ - { - "name": "flowName", - "datatype": "string", - "desc": "The name of the flow to be created or updated.", - "nullable": false, - "multiple": false - }, - { - "name": "flow", - "datatype": "object", - "desc": "The flow to be created or updated.", - "nullable": false, - "multiple": false - } - ] -} \ No newline at end of file diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/insertFlow.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/insertFlow.sjs deleted file mode 100644 index a4e3ab62..00000000 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/insertFlow.sjs +++ /dev/null @@ -1,35 +0,0 @@ -'use strict'; - -declareUpdate(); - -const sc = require('/state-conductor/state-conductor.sjs'); -const validator = require('/state-conductor/flow-file-validator.sjs'); - -var flowName; -var flow; - -insertFlow(flowName, flow); - -/** - * Create or update a flow - * - * @param {string} flowName Name of the flow to be created or updated - * @param {object} flow Flow to be created or updated - */ -function insertFlow(flowName, flow) { - const cleanFlowName = flowName ? flowName.trim() : ''; - if (cleanFlowName === '') { - fn.error(xs.QName("ERROR"), `Missing parameter "flowName"`); - } - if(!flow || typeof flow != 'object') { - fn.error(xs.QName("ERROR"), `Invalid parameter "flow"`); - } - if(!validator.validateFlowFile(flow)) { - fn.error(xs.QName("ERROR"), `Invalid state-conductor flow`); - } - const uri = `${sc.FLOW_DIRECTORY}${cleanFlowName}.asl.json`; - xdmp.documentInsert(uri, flow, { - permissions: xdmp.defaultPermissions(), - collections: [sc.FLOW_COLLECTION], - }); -} diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/insertStateMachine.api b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/insertStateMachine.api new file mode 100644 index 00000000..0fe666fe --- /dev/null +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/insertStateMachine.api @@ -0,0 +1,20 @@ +{ + "functionName": "insertStateMachine", + "desc": "Creates or updates a single state machine.", + "params": [ + { + "name": "name", + "datatype": "string", + "desc": "The name of the state machine to be created or updated.", + "nullable": false, + "multiple": false + }, + { + "name": "stateMachine", + "datatype": "object", + "desc": "The stateMachine to be created or updated.", + "nullable": false, + "multiple": false + } + ] +} \ No newline at end of file diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/insertStateMachine.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/insertStateMachine.sjs new file mode 100644 index 00000000..a21f5cdc --- /dev/null +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/insertStateMachine.sjs @@ -0,0 +1,35 @@ +'use strict'; + +declareUpdate(); + +const sc = require('/state-conductor/state-conductor.sjs'); +const validator = require('/state-conductor/state-machine-validator.sjs'); + +var name; +var stateMachine; + +insertStateMachine(name, stateMachine); + +/** + * Create or update a state machine + * + * @param {string} name Name of the state machine to be created or updated + * @param {object} stateMachine State Machine to be created or updated + */ +function insertStateMachine(name, stateMachine) { + const cleanName = name ? name.trim() : ''; + if (cleanName === '') { + fn.error(xs.QName("ERROR"), `Missing parameter "stateMachine"`); + } + if(!stateMachine || typeof stateMachine != 'object') { + fn.error(xs.QName("ERROR"), `Invalid parameter "stateMachine"`); + } + if(!validator.validateStateMachineFile(stateMachine)) { + fn.error(xs.QName("ERROR"), `Invalid state-conductor stateMachine`); + } + const uri = `${sc.STATE_MACHINE_DIRECTORY}${cleanName}.asl.json`; + xdmp.documentInsert(uri, stateMachine, { + permissions: xdmp.defaultPermissions(), + collections: [sc.STATE_MACHINE_COLLECTION], + }); +} diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/processJob.api b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/processExecution.api similarity index 69% rename from state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/processJob.api rename to state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/processExecution.api index 40f207e2..10741af4 100644 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/processJob.api +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/processExecution.api @@ -1,11 +1,11 @@ { - "functionName": "processJob", - "desc": "Invokes the processing of a MarkLogic State Conductor Job", + "functionName": "processExecution", + "desc": "Invokes the processing of a MarkLogic State Conductor Execution", "params": [ { "name": "uri", "datatype": "string", - "desc": "The uri of a State Conductor Job document to be processed", + "desc": "The uri of a State Conductor Execution document to be processed", "nullable": false, "multiple": true } diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/processJob.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/processExecution.sjs similarity index 83% rename from state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/processJob.sjs rename to state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/processExecution.sjs index 6113e714..ae2c5e3a 100644 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/processJob.sjs +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/dataservices/processExecution.sjs @@ -25,10 +25,10 @@ let resp = uri.map((value) => { result = sc.invokeOrApplyFunction( () => { declareUpdate(); - return sc.processJob(value); + return sc.processExecution(value); }, { - database: xdmp.database(sc.STATE_CONDUCTOR_JOBS_DB), + database: xdmp.database(sc.STATE_CONDUCTOR_EXECUTIONS_DB), } ); } catch (err) { @@ -36,7 +36,7 @@ let resp = uri.map((value) => { } return { - job: value, + execution: value, result: result, error: error, }; diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/resumeWaitingJobs.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/resumeWaitingExecutions.sjs similarity index 63% rename from state-conductor-modules/src/main/ml-modules/root/state-conductor/resumeWaitingJobs.sjs rename to state-conductor-modules/src/main/ml-modules/root/state-conductor/resumeWaitingExecutions.sjs index 23188e40..92eaaed4 100644 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/resumeWaitingJobs.sjs +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/resumeWaitingExecutions.sjs @@ -8,4 +8,4 @@ var save; const sc = require('/state-conductor/state-conductor.sjs'); -uriArray.forEach((uri) => sc.resumeWaitingJob(uri, resumeBy, save)); +uriArray.forEach((uri) => sc.resumeWaitingExecution(uri, resumeBy, save)); diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/sample.asl.json b/state-conductor-modules/src/main/ml-modules/root/state-conductor/sample.asl.json index f2b3f045..3fa84b87 100644 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/sample.asl.json +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/sample.asl.json @@ -12,7 +12,7 @@ }, { "scope": "query", - "value": "{\"andQuery\":{\"queries\":[{\"collectionQuery\":{\"uris\":[\"flow-time\"]}}, {\"elementValueQuery\":{\"element\":[\"name\"], \"text\":[\"Cobb Pauley\"], \"options\":[\"lang=en\"]}}]}}" + "value": "{\"andQuery\":{\"queries\":[{\"collectionQuery\":{\"uris\":[\"stateMachine-time\"]}}, {\"elementValueQuery\":{\"element\":[\"name\"], \"text\":[\"Cobb Pauley\"], \"options\":[\"lang=en\"]}}]}}" } ] }, @@ -20,7 +20,7 @@ "States": { "A": { "Type": "Choice", - "Comment": "initial state of the flow", + "Comment": "initial state of the stateMachine", "Resource": "/uri/to/action1.sjs", "Choices": [ { diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/state-conductor-lib.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/state-conductor-lib.sjs index 09fb06ba..bd89ee7e 100644 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/state-conductor-lib.sjs +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/state-conductor-lib.sjs @@ -10,18 +10,18 @@ const TRACE_EVENT = 'state-conductor'; function getConfiguration() { const defaultconfigurationDefaults = { databases: { - jobs: 'state-conductor-jobs', + executions: 'state-conductor-executions', triggers: 'state-conductor-triggers', schemas: 'state-conductor-schemas', }, collections: { item: 'state-conductor-item', - job: 'stateConductorJob', - flow: 'state-conductor-flow', + execution: 'stateConductorExecution', + stateMachine: 'state-conductor-state-machine', }, URIPrefixes: { - flow: '/state-conductor-flow/', - job: '/stateConductorJob/', + stateMachine: '/state-conductor-state-machine/', + execution: '/stateConductorExecution/', }, }; @@ -169,7 +169,7 @@ function evaluateChoiceRule(rule = {}, context = {}) { } /** - * Given a flow context with the "scheduled" scope, determines + * Given a stateMachine context with the "scheduled" scope, determines * if the scheduled period has elapsed. * * @param {*} context diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/state-conductor.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/state-conductor.sjs index fba98812..ccf7ec91 100644 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/state-conductor.sjs +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/state-conductor.sjs @@ -5,27 +5,27 @@ const lib = require('/state-conductor/state-conductor-lib.sjs'); const configuration = lib.getConfiguration(); // configurable // -const STATE_CONDUCTOR_JOBS_DB = configuration.databases.jobs; +const STATE_CONDUCTOR_EXECUTIONS_DB = configuration.databases.executions; const STATE_CONDUCTOR_TRIGGERS_DB = configuration.databases.triggers; const STATE_CONDUCTOR_SCHEMAS_DB = configuration.databases.schemas; -const FLOW_ITEM_COLLECTION = configuration.collections.item; -const JOB_COLLECTION = configuration.collections.job; -const FLOW_COLLECTION = configuration.collections.flow; -const FLOW_DIRECTORY = configuration.URIPrefixes.flow; -const JOB_DIRECTORY = configuration.URIPrefixes.job; +const STATE_MACHINE_ITEM_COLLECTION = configuration.collections.item; +const EXECUTION_COLLECTION = configuration.collections.execution; +const STATE_MACHINE_COLLECTION = configuration.collections.stateMachine; +const STATE_MACHINE_DIRECTORY = configuration.URIPrefixes.stateMachine; +const EXECUTION_DIRECTORY = configuration.URIPrefixes.execution; // non-configurable // -const JOB_DOC_READ_PERMISSION = 'state-conductor-reader-role'; -const JOB_DOC_WRITE_PERMISSION = 'state-conductor-job-writer-role'; +const EXECUTION_DOC_READ_PERMISSION = 'state-conductor-reader-role'; +const EXECUTION_DOC_WRITE_PERMISSION = 'state-conductor-execution-writer-role'; const TRACE_EVENT = 'state-conductor'; -const FLOW_FILE_EXTENSION = '.asl.json'; -const FLOW_JOBID_PROP_NAME = 'state-conductor-job'; -const FLOW_STATUS_NEW = 'new'; -const FLOW_STATUS_WORKING = 'working'; -const FLOW_STATUS_WAITING = 'waiting'; -const FLOW_STATUS_COMPLETE = 'complete'; -const FLOW_STATUS_FAILED = 'failed'; -const FLOW_NEW_STEP = 'NEW'; +const STATE_MACHINE_FILE_EXTENSION = '.asl.json'; +const STATE_MACHINE_EXECUTIONID_PROP_NAME = 'state-conductor-execution'; +const STATE_MACHINE_STATUS_NEW = 'new'; +const STATE_MACHINE_STATUS_WORKING = 'working'; +const STATE_MACHINE_STATUS_WAITING = 'waiting'; +const STATE_MACHINE_STATUS_COMPLETE = 'complete'; +const STATE_MACHINE_STATUS_FAILED = 'failed'; +const STATE_MACHINE_NEW_STEP = 'NEW'; const DATE_TIME_REGEX = '^[-]?((1[6789]|[2-9][0-9])[0-9]{2}-(0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))T([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])([Z]|.[0-9]{4}|[-|+]([0-1][0-9]|2[0-3]):([0-5][0-9]))?$|^[-]?((1[6789]|[2-9][0-9])[0-9]{2}-(0[469]|11)-(0[1-9]|[12][0-9]|30))T([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])([Z]|.[0-9]{4}|[-|+]([0-1][0-9]|2[0-3]):([0-5][0-9]))?$|^[-]?((16|[248][048]|[3579][26])00)|(1[6789]|[2-9][0-9])(0[48]|[13579][26]|[2468][048])-02-(0[1-9]|1[0-9]|2[0-9])T([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])([Z]|.[0-9]{4}|[-|+]([0-1][0-9]|2[0-3]):([0-5][0-9]))?$|^[-]?(1[6789]|[2-9][0-9])[0-9]{2}-02-(0[1-9]|1[0-9]|2[0-8])T([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])([Z]|.[0-9]{4}|[-|+]([0-1][0-9]|2[0-3]):([0-5][0-9]))?$'; @@ -52,7 +52,7 @@ const parseSerializedQuery = (serializedQuery) => { /** * This function should be called when ever we are - * invoking for the jobs/content database. + * invoking for the executions/content database. * Since now its possible that they are * already with in that database * @param {*} name @@ -82,18 +82,18 @@ function invokeOrApplyFunction(functionIn, optionsIn) { } /** - * Gets a flow definition by flowName + * Gets a stateMachine definition by name * * @param {*} name - * @returns the flow document or null if not found + * @returns the stateMachine document or null if not found */ -function getFlowDocument(name) { - let nameWithExtension = fn.normalizeSpace(name) + FLOW_FILE_EXTENSION; +function getStateMachine(name) { + let nameWithExtension = fn.normalizeSpace(name) + STATE_MACHINE_FILE_EXTENSION; const uri = fn.head( cts.uriMatch( '*' + nameWithExtension, ['document', 'case-sensitive'], - cts.collectionQuery(FLOW_COLLECTION) + cts.collectionQuery(STATE_MACHINE_COLLECTION) ) ); @@ -101,21 +101,21 @@ function getFlowDocument(name) { } /** - * Gets a flow definition by flowName from the given database. + * Gets a stateMachine definition by name from the given database. * Throws an error if not found * * @param {*} name * @param {*} databaseId * @returns */ -function getFlowDocumentFromDatabase(name, databaseId) { +function getStateMachineFromDatabase(name, databaseId) { let resp = invokeOrApplyFunction( () => { - let flow = getFlowDocument(name); - if (!flow) { - fn.error(null, 'MISSING-FLOW-FILE', `Cannot find a a flow file with the name: ${name}`); + let stateMachine = getStateMachine(name); + if (!stateMachine) { + fn.error(null, 'MISSING-STATE_MACHINE-FILE', `Cannot find a a stateMachine file with the name: ${name}`); } - return flow; + return stateMachine; }, { database: databaseId, @@ -125,108 +125,108 @@ function getFlowDocumentFromDatabase(name, databaseId) { } /** - * Gets all flow definition documents + * Gets all stateMachine definition documents * * @returns */ -function getFlowDocuments() { - return fn.collection(FLOW_COLLECTION); +function getStateMachines() { + return fn.collection(STATE_MACHINE_COLLECTION); } /** - * Gets all flow definition names + * Gets all stateMachine definition names * * @returns */ -function getFlowNames() { +function getStateMachineNames() { return cts - .uris('/', ['document'], cts.collectionQuery(FLOW_COLLECTION)) + .uris('/', ['document'], cts.collectionQuery(STATE_MACHINE_COLLECTION)) .toArray() - .map((uri) => getFlowNameFromUri(uri)); + .map((uri) => getStateMachineNameFromUri(uri)); } /** - * Given a flow definition URI, determine it's flow name + * Given a stateMachine definition URI, determine it's stateMachine name * * @param {*} uri * @returns */ -function getFlowNameFromUri(uri) { +function getStateMachineNameFromUri(uri) { uri = uri.toString(); uri = uri.slice(uri.lastIndexOf('/') + 1); - return uri.lastIndexOf(FLOW_FILE_EXTENSION) !== -1 - ? uri.slice(0, uri.lastIndexOf(FLOW_FILE_EXTENSION)) + return uri.lastIndexOf(STATE_MACHINE_FILE_EXTENSION) !== -1 + ? uri.slice(0, uri.lastIndexOf(STATE_MACHINE_FILE_EXTENSION)) : uri; } /** * Returns the initial state for the given state machine definition * - * @param {*} { flowName, StartAt } + * @param {*} { name, StartAt } * @returns */ -function getInitialState({ flowName, StartAt }) { +function getInitialState({ name, StartAt }) { if (!StartAt || StartAt.length === 0) { fn.error( null, 'INVALID-STATE-DEFINITION', - `no "StartAt" defined for state machine "${flowName}"` + `no "StartAt" defined for state machine "${name}"` ); } return StartAt; } /** - * Gets the value of the property which links a document to a State Conductor job + * Gets the value of the property which links a document to a State Conductor execution * * @param {*} uri - * @param {*} flowName + * @param {*} name * @returns */ -function getJobMetadatProperty(uri, flowName) { +function getExecutionMetadataProperty(uri, name) { xdmp.securityAssert('http://marklogic.com/state-conductor/privilege/execute', 'execute'); if (fn.docAvailable(uri)) { return xdmp - .documentGetProperties(uri, fn.QName('', FLOW_JOBID_PROP_NAME)) + .documentGetProperties(uri, fn.QName('', STATE_MACHINE_EXECUTIONID_PROP_NAME)) .toArray() - .filter((prop) => prop.getAttributeNode('flow-name').nodeValue === flowName); + .filter((prop) => prop.getAttributeNode('stateMachine-name').nodeValue === name); } } /** - * Links the given document to a state conductor job + * Links the given document to a state conductor execution * * @param {*} uri - * @param {*} flowName - * @param {*} jobId + * @param {*} name + * @param {*} executionId */ -function addJobMetadata(uri, flowName, jobId) { +function addExecutionMetadata(uri, name, executionId) { const builder = new NodeBuilder(); - builder.startElement(FLOW_JOBID_PROP_NAME); - builder.addAttribute('flow-name', flowName); - builder.addAttribute('job-id', jobId); + builder.startElement(STATE_MACHINE_EXECUTIONID_PROP_NAME); + builder.addAttribute('stateMachine-name', name); + builder.addAttribute('execution-id', executionId); builder.addAttribute('date', new Date().toISOString()); builder.endElement(); - let jobMetaElem = builder.toNode(); - xdmp.documentAddProperties(uri, [jobMetaElem]); + let executionMetaElem = builder.toNode(); + xdmp.documentAddProperties(uri, [executionMetaElem]); } -function getJobIds(uri, flowName) { +function getExecutionIds(uri, name) { xdmp.securityAssert('http://marklogic.com/state-conductor/privilege/execute', 'execute'); - const jobProps = getJobMetadatProperty(uri, flowName); - return jobProps.map((prop) => prop.getAttributeNode('job-id').nodeValue); + const executionProps = getExecutionMetadataProperty(uri, name); + return executionProps.map((prop) => prop.getAttributeNode('execution-id').nodeValue); } /** - * Determines if the given document matches the given flow's context + * Determines if the given document matches the given stateMachine's context * * @param {*} uri - * @param {*} flow + * @param {*} stateMachine * @returns */ -function checkFlowContext(uri, flow) { +function checkStateMachineContext(uri, stateMachine) { if (fn.docAvailable(uri)) { - const query = getFlowContextQuery(flow); + const query = getStateMachineContextQuery(stateMachine); const uris = cts.uris('', 'limit=1', cts.andQuery([cts.documentQuery(uri), query])); return uri === fn.string(fn.head(uris)); } @@ -235,32 +235,32 @@ function checkFlowContext(uri, flow) { } /** - * Given a document's uri, finds all the flows whose context applies, + * Given a document's uri, finds all the stateMachines whose context applies, * and which have not previously processed this document. * * @param {*} uri * @returns */ -function getApplicableFlows(uri) { - const flows = getFlowDocuments() +function getApplicableStateMachines(uri) { + const stateMachines = getStateMachines() .toArray() - .filter((flow) => { - let flowName = getFlowNameFromUri(fn.documentUri(flow)); - let flowOjb = flow.toObject(); - return getJobIds(uri, flowName).length === 0 && checkFlowContext(uri, flowOjb); + .filter((stateMachine) => { + let name = getStateMachineNameFromUri(fn.documentUri(stateMachine)); + let stateMachineOjb = stateMachine.toObject(); + return getExecutionIds(uri, name).length === 0 && checkStateMachineContext(uri, stateMachineOjb); }); - return flows; + return stateMachines; } /** - * Given a flow, generate a cts query for it's context + * Given a stateMachine, generate a cts query for it's context * - * @param {*} flow + * @param {*} stateMachine * @returns */ -function getFlowContextQuery(flow) { - const domain = flow.mlDomain; +function getStateMachineContextQuery(stateMachine) { + const domain = stateMachine.mlDomain; const context = domain.context || []; let queries = context.map((ctx) => { if (ctx.scope === 'collection') { @@ -285,14 +285,14 @@ function getFlowContextQuery(flow) { } /** - * Generate a cts query matching the context of all flows + * Generate a cts query matching the context of all stateMachines * * @returns */ -function getAllFlowsContextQuery() { - let queries = getFlowDocuments() +function getAllStateMachinesContextQuery() { + let queries = getStateMachines() .toArray() - .map((flow) => getFlowContextQuery(flow.toObject())); + .map((stateMachine) => getStateMachineContextQuery(stateMachine.toObject())); if (queries.length === 0) { queries = cts.falseQuery(); @@ -306,306 +306,306 @@ function getAllFlowsContextQuery() { } /** - * Main unit of processing for a job document. Performs state actions and transitions to next state. + * Main unit of processing for a execution document. Performs state actions and transitions to next state. * - * @param {*} uri - the uri of the job document - * @returns (boolean) indicates if processing of the job document should continue + * @param {*} uri - the uri of the execution document + * @returns (boolean) indicates if processing of the execution document should continue */ -function processJob(uri) { +function processExecution(uri) { xdmp.securityAssert('http://marklogic.com/state-conductor/privilege/execute', 'execute'); - xdmp.trace(TRACE_EVENT, `state-conductor job processing for job document "${uri}"`); + xdmp.trace(TRACE_EVENT, `state-conductor execution processing for execution document "${uri}"`); // sanity check if (!fn.docAvailable(uri)) { - fn.error(null, 'INVALID-JOB-DOCUMENT', `State Conductor job document "${uri}" not found!`); + fn.error(null, 'INVALID-EXECUTION-DOCUMENT', `State Conductor execution document "${uri}" not found!`); } - const jobDoc = cts.doc(uri); - const job = jobDoc.toObject(); - const status = job.flowStatus; + const executionDoc = cts.doc(uri); + const execution = executionDoc.toObject(); + const status = execution.status; - // check the flow state - if (FLOW_STATUS_WORKING === status) { + // check the stateMachine state + if (STATE_MACHINE_STATUS_WORKING === status) { // execute state actions and transition to next state - executeStateByJobDoc(jobDoc); + executeStateByExecutionDoc(executionDoc); // continue processing return true; - } else if (FLOW_STATUS_WAITING === status) { + } else if (STATE_MACHINE_STATUS_WAITING === status) { // execute resume - resumeWaitingJobByJobDoc(jobDoc, 'processJob'); + resumeWaitingExecutionByExecutionDoc(executionDoc, 'processExecution'); // continue processing return true; - } else if (FLOW_STATUS_NEW === status) { - // job document is not being processed, grab the embedded flow, and start the initial state - // begin the flow processing - startProcessingFlowByJobDoc(jobDoc); + } else if (STATE_MACHINE_STATUS_NEW === status) { + // execution document is not being processed, grab the embedded stateMachine, and start the initial state + // begin the stateMachine processing + startProcessingStateMachineByExecutionDoc(executionDoc); // continue processing return true; } else { - // we're done processing the flow - xdmp.trace(TRACE_EVENT, `state-conductor flow completed for job document "${uri}"`); + // we're done processing the stateMachine + xdmp.trace(TRACE_EVENT, `state-conductor stateMachine completed for execution document "${uri}"`); // end processing return false; } } -function startProcessingFlowByJobDoc(jobDoc, save = true) { +function startProcessingStateMachineByExecutionDoc(executionDoc, save = true) { xdmp.securityAssert('http://marklogic.com/state-conductor/privilege/execute', 'execute'); - const jobObj = scaffoldJobDoc(jobDoc.toObject()); - const currFlowName = jobObj.flowName; - const status = jobObj.flowStatus; + const executionObj = scaffoldExecutionDoc(executionDoc.toObject()); + const currStateMachineName = executionObj.name; + const status = executionObj.status; // sanity check - if (FLOW_STATUS_NEW !== status) { + if (STATE_MACHINE_STATUS_NEW !== status) { xdmp.trace( TRACE_EVENT, - `INVALID-FLOW-STATUS: Cannot start a flow that is not in the ${FLOW_STATUS_NEW} status` + `INVALID-STATE_MACHINE-STATUS: Cannot start a stateMachine that is not in the ${STATE_MACHINE_STATUS_NEW} status` ); - fn.error(null, 'INVALID-FLOW-STATUS', 'Cannot start a flow not in the NEW status'); + fn.error(null, 'INVALID-STATE_MACHINE-STATUS', 'Cannot start a stateMachine not in the NEW status'); } try { - // grab the flow definition from the correct db - const currFlow = getFlowDocumentFromDatabase(currFlowName, jobObj.database).toObject(); - currFlow.flowName = jobObj.flowName; - let initialState = getInitialState(currFlow); + // grab the stateMachine definition from the correct db + const currStateMachine = getStateMachineFromDatabase(currStateMachineName, executionObj.database).toObject(); + currStateMachine.name = executionObj.name; + let initialState = getInitialState(currStateMachine); - // update job state, status, and provenence - jobObj.flowStatus = FLOW_STATUS_WORKING; - jobObj.flowState = initialState; + // update execution state, status, and provenence + executionObj.status = STATE_MACHINE_STATUS_WORKING; + executionObj.state = initialState; xdmp.trace( TRACE_EVENT, - `adding document to flow: "${currFlowName}" in state: "${initialState}"` + `adding document to stateMachine: "${currStateMachineName}" in state: "${initialState}"` ); - jobObj.provenance.push({ + executionObj.provenance.push({ date: new Date().toISOString(), - from: FLOW_NEW_STEP, + from: STATE_MACHINE_NEW_STEP, to: initialState, executionTime: xdmp.elapsedTime(), }); if (save) { - xdmp.nodeReplace(jobDoc.root, jobObj); + xdmp.nodeReplace(executionDoc.root, executionObj); } } catch (err) { return handleError( err.name, - `startProcessingFlowByJobDoc error for flow "${currFlowName}"`, + `startProcessingStateMachineByExecutionDoc error for stateMachine "${currStateMachineName}"`, err, - jobDoc, - jobObj, + executionDoc, + executionObj, save ); } - return jobObj; + return executionObj; } /** * Performs the actions and transitions for a state. * - * @param {*} uri - the job document's uri + * @param {*} uri - the execution document's uri */ -function resumeWaitingJob(uri, resumeBy = 'unspecified', save = true) { +function resumeWaitingExecution(uri, resumeBy = 'unspecified', save = true) { xdmp.securityAssert('http://marklogic.com/state-conductor/privilege/execute', 'execute'); // checks if document is there if (!fn.docAvailable(uri)) { - fn.error(null, 'INVALID-JOB-DOCUMENT', `Document Job "${uri}" not found."`); + fn.error(null, 'INVALID-EXECUTION-DOCUMENT', `Document Execution "${uri}" not found."`); } - const jobDoc = cts.doc(uri); - resumeWaitingJobByJobDoc(jobDoc, resumeBy, save); + const executionDoc = cts.doc(uri); + resumeWaitingExecutionByExecutionDoc(executionDoc, resumeBy, save); } -function resumeWaitingJobByJobDoc(jobDoc, resumeBy, save = true) { +function resumeWaitingExecutionByExecutionDoc(executionDoc, resumeBy, save = true) { xdmp.securityAssert('http://marklogic.com/state-conductor/privilege/execute', 'execute'); - const uri = xdmp.nodeUri(jobDoc); - const jobObj = scaffoldJobDoc(jobDoc.toObject()); - const flowName = jobObj.flowName; - const stateName = jobObj.flowState; - const flowStatus = jobObj.flowStatus; + const uri = xdmp.nodeUri(executionDoc); + const executionObj = scaffoldExecutionDoc(executionDoc.toObject()); + const name = executionObj.name; + const stateName = executionObj.state; + const status = executionObj.status; let state; - let flowObj; + let stateMachineObj; - xdmp.trace(TRACE_EVENT, `resumeWaitingJob uri "${uri}"`); - xdmp.trace(TRACE_EVENT, `resumeWaitingJob flow "${flowName}"`); - xdmp.trace(TRACE_EVENT, `resumeWaitingJob flow state "${stateName}"`); + xdmp.trace(TRACE_EVENT, `resumeWaitingExecution uri "${uri}"`); + xdmp.trace(TRACE_EVENT, `resumeWaitingExecution stateMachine "${name}"`); + xdmp.trace(TRACE_EVENT, `resumeWaitingExecution stateMachine state "${stateName}"`); // sanity check - if (FLOW_STATUS_WAITING !== flowStatus) { + if (STATE_MACHINE_STATUS_WAITING !== status) { xdmp.trace( TRACE_EVENT, - `INVALID-FLOW-STATUS: Cannot resume a flow that is not in the ${FLOW_STATUS_WAITING} status` + `INVALID-STATE_MACHINE-STATUS: Cannot resume a stateMachine that is not in the ${STATE_MACHINE_STATUS_WAITING} status` ); return fn.error( null, - 'INVALID-FLOW-STATUS', - 'Cannot resume a flow that is not in the ' + FLOW_STATUS_WAITING + ' status' + 'INVALID-STATE_MACHINE-STATUS', + 'Cannot resume a stateMachine that is not in the ' + STATE_MACHINE_STATUS_WAITING + ' status' ); } - // wait state check for processJob event - if (resumeBy === 'processJob' && jobObj.currentlyWaiting.hasOwnProperty('event')) { + // wait state check for processExecution event + if (resumeBy === 'processExecution' && executionObj.currentlyWaiting.hasOwnProperty('event')) { xdmp.trace( TRACE_EVENT, - `INVALID-CurrentlyWaiting: Cannot resume a flow that is an event by processJob for uri: "${uri}"` + `INVALID-CurrentlyWaiting: Cannot resume a stateMachine that is an event by processExecution for uri: "${uri}"` ); return fn.error( null, 'INVALID-CurrentlyWaiting', - `Cannot resume a flow that is an event by processJob for uri: "${uri}"` + `Cannot resume a stateMachine that is an event by processExecution for uri: "${uri}"` ); } // check if current time is greater than nextTaskTime if ( - jobObj.currentlyWaiting.hasOwnProperty('nextTaskTime') && - xs.dateTime(jobObj.currentlyWaiting.nextTaskTime) > fn.currentDateTime() + xdmp.elapsedTime() + executionObj.currentlyWaiting.hasOwnProperty('nextTaskTime') && + xs.dateTime(executionObj.currentlyWaiting.nextTaskTime) > fn.currentDateTime() + xdmp.elapsedTime() ) { xdmp.trace( TRACE_EVENT, - `INVALID-CurrentlyWaiting: Cannot resume a flow where is wait time has not passed for uri: "${uri}"` + `INVALID-CurrentlyWaiting: Cannot resume a stateMachine where is wait time has not passed for uri: "${uri}"` ); return fn.error( null, 'INVALID-CurrentlyWaiting', - `Cannot resume a flow where is wait time has not passed for uri: "${uri}"` + `Cannot resume a stateMachine where is wait time has not passed for uri: "${uri}"` ); } try { - flowObj = getFlowDocumentFromDatabase(flowName, jobObj.database).toObject(); + stateMachineObj = getStateMachineFromDatabase(name, executionObj.database).toObject(); try { - state = flowObj.States[stateName]; + state = stateMachineObj.States[stateName]; } catch (e) { return fn.error( null, 'INVALID-STATE-DEFINITION', - `Can't Find the state "${stateName}" in flow "${flowName}"` + `Can't Find the state "${stateName}" in stateMachine "${name}"` ); } } catch (err) { return handleError( err.name, - `resumeWaitingJobByJobDoc error for flow "${flowName}"`, + `resumeWaitingExecutionByExecutionDoc error for stateMachine "${name}"`, err, - jobDoc, - jobObj, + executionDoc, + executionObj, save ); } try { //removes old waiting data - delete jobObj.currentlyWaiting; + delete executionObj.currentlyWaiting; - jobObj.flowStatus = FLOW_STATUS_WORKING; - jobObj.provenance.push({ + executionObj.status = STATE_MACHINE_STATUS_WORKING; + executionObj.provenance.push({ date: new Date().toISOString(), state: stateName, resumeBy: resumeBy, executionTime: xdmp.elapsedTime(), }); - return transition(jobDoc, jobObj, stateName, state, flowObj, save); + return transition(executionDoc, executionObj, stateName, state, stateMachineObj, save); } catch (err) { - return handleStateFailure(uri, flowName, flowObj, stateName, err, save, jobDoc); + return handleStateFailure(uri, name, stateMachineObj, stateName, err, save, executionDoc); } } /** * Performs the actions and transitions for a state. * - * @param {*} uri - the job document's uri + * @param {*} uri - the execution document's uri */ -function retryJobAtState(uri, stateName = FLOW_NEW_STEP, retriedBy = 'unspecified', save = true) { +function retryExecutionAtState(uri, stateName = STATE_MACHINE_NEW_STEP, retriedBy = 'unspecified', save = true) { // checks if document is there if (!fn.docAvailable(uri)) { - fn.error(null, 'INVALID-JOB-DOCUMENT', `Document Job "${uri}" not found."`); + fn.error(null, 'INVALID-EXECUTION-DOCUMENT', `Document Execution "${uri}" not found."`); } - const jobDoc = cts.doc(uri); - retryJobAtStateByJobDoc(jobDoc, stateName, retriedBy, save); + const executionDoc = cts.doc(uri); + retryExecutionAtStateByExecutionDoc(executionDoc, stateName, retriedBy, save); } -function retryJobAtStateByJobDoc(jobDoc, stateName, retriedBy, save = true) { - const uri = xdmp.nodeUri(jobDoc); - const jobObj = scaffoldJobDoc(jobDoc.toObject()); - const flowName = jobObj.flowName; - const flowStatus = jobObj.flowStatus; +function retryExecutionAtStateByExecutionDoc(executionDoc, stateName, retriedBy, save = true) { + const uri = xdmp.nodeUri(executionDoc); + const executionObj = scaffoldExecutionDoc(executionDoc.toObject()); + const name = executionObj.name; + const status = executionObj.status; let state; - let flowObj; + let stateMachineObj; - xdmp.trace(TRACE_EVENT, `retryJobAtStateByJobDoc uri "${uri}"`); - xdmp.trace(TRACE_EVENT, `retryJobAtStateByJobDoc flow "${flowName}"`); - xdmp.trace(TRACE_EVENT, `retryJobAtStateByJobDoc flow state "${stateName}"`); + xdmp.trace(TRACE_EVENT, `retryExecutionAtStateByExecutionDoc uri "${uri}"`); + xdmp.trace(TRACE_EVENT, `retryExecutionAtStateByExecutionDoc stateMachine "${name}"`); + xdmp.trace(TRACE_EVENT, `retryExecutionAtStateByExecutionDoc stateMachine state "${stateName}"`); // sanity check - if (FLOW_STATUS_FAILED !== flowStatus) { + if (STATE_MACHINE_STATUS_FAILED !== status) { xdmp.trace( TRACE_EVENT, - `INVALID-FLOW-STATUS: Cannot retry a flow that is not in the ${FLOW_STATUS_FAILED} status` + `INVALID-STATE_MACHINE-STATUS: Cannot retry a stateMachine that is not in the ${STATE_MACHINE_STATUS_FAILED} status` ); return fn.error( null, - 'INVALID-FLOW-STATUS', - 'Cannot try a flow that is not in the ' + FLOW_STATUS_FAILED + ' status' + 'INVALID-STATE_MACHINE-STATUS', + 'Cannot try a stateMachine that is not in the ' + STATE_MACHINE_STATUS_FAILED + ' status' ); } try { - flowObj = getFlowDocumentFromDatabase(flowName, jobObj.database).toObject(); - state = flowObj.States[stateName]; + stateMachineObj = getStateMachineFromDatabase(name, executionObj.database).toObject(); + state = stateMachineObj.States[stateName]; if (!state) { fn.error( null, 'INVALID-STATE-DEFINITION', - `Can't Find the state "${stateName}" in flow "${flowName}"` + `Can't Find the state "${stateName}" in stateMachine "${name}"` ); } } catch (err) { return handleError( err.name, - `retryJobAtStateByJobDoc error for flow "${flowName}"`, + `retryExecutionAtStateByExecutionDoc error for stateMachine "${name}"`, err, - jobDoc, - jobObj, + executionDoc, + executionObj, save ); } try { //removes old waiting data - delete jobObj.currentlyWaiting; + delete executionObj.currentlyWaiting; - jobObj.flowStatus = FLOW_STATUS_WORKING; - jobObj.provenance.push({ + executionObj.status = STATE_MACHINE_STATUS_WORKING; + executionObj.provenance.push({ date: new Date().toISOString(), state: stateName, retriedBy: retriedBy, executionTime: xdmp.elapsedTime(), }); - return transition(jobDoc, jobObj, stateName, state, flowObj, save); + return transition(executionDoc, executionObj, stateName, state, stateMachineObj, save); } catch (err) { - return handleStateFailure(uri, flowName, flowObj, stateName, err, save, jobObj); + return handleStateFailure(uri, name, stateMachineObj, stateName, err, save, executionObj); } } /** * transition to the next state. * - * @param {*} jobDoc - the job document - * @param {*} jobObj - the job object - * @param {*} stateName - the name of the state most like coming from flowState + * @param {*} executionDoc - the execution document + * @param {*} executionObj - the execution object + * @param {*} stateName - the name of the state most like coming from state * @param {*} state - the state object - * @param {*} flowObj - the flow object + * @param {*} stateMachineObj - the stateMachine object */ -function transition(jobDoc, jobObj, stateName, state, flowObj, save = true) { +function transition(executionDoc, executionObj, stateName, state, stateMachineObj, save = true) { xdmp.securityAssert('http://marklogic.com/state-conductor/privilege/execute', 'execute'); try { @@ -614,23 +614,23 @@ function transition(jobDoc, jobObj, stateName, state, flowObj, save = true) { xdmp.trace( TRACE_EVENT, - `executing transitions for state: ${stateName} with status of ${jobObj.flowStatus}` + `executing transitions for state: ${stateName} with status of ${executionObj.status}` ); - if (jobObj.flowStatus === FLOW_STATUS_WAITING) { + if (executionObj.status === STATE_MACHINE_STATUS_WAITING) { xdmp.trace(TRACE_EVENT, `transition wait: ${stateName}`); - let pro = JSON.parse(JSON.stringify(jobObj.currentlyWaiting)); + let pro = JSON.parse(JSON.stringify(executionObj.currentlyWaiting)); pro['doneNextTaskTime'] = pro['nextTaskTime']; delete pro['nextTaskTime']; - jobObj.provenance.push({ + executionObj.provenance.push({ date: new Date().toISOString(), state: stateName, waiting: pro, executionTime: xdmp.elapsedTime(), }); - } else if (!inTerminalState(jobObj, flowObj)) { + } else if (!inTerminalState(executionObj, stateMachineObj)) { xdmp.trace(TRACE_EVENT, `transition from non-terminal state: ${stateName}`); if (STATE_TASK === state.Type.toLowerCase()) { @@ -648,18 +648,18 @@ function transition(jobDoc, jobObj, stateName, state, flowObj, save = true) { let resp = fn.head( executeConditionModule( choice.Resource, - jobObj.uri, + executionObj.uri, choice.Parameters, - jobObj.context, + executionObj.context, { - database: jobObj.database, - modules: jobObj.modules, + database: executionObj.database, + modules: executionObj.modules, } ) ); targetState = resp ? choice.Next : null; } else { - let resp = lib.evaluateChoiceRule(choice, jobObj.context); + let resp = lib.evaluateChoiceRule(choice, executionObj.context); targetState = resp ? choice.Next : null; } } @@ -674,13 +674,13 @@ function transition(jobDoc, jobObj, stateName, state, flowObj, save = true) { } } catch (err) { return handleStateFailure( - xdmp.nodeUri(jobDoc), - flowObj.flowName, - flowObj, + xdmp.nodeUri(executionDoc), + stateMachineObj.name, + stateMachineObj, stateName, err, save, - jobObj + executionObj ); } } else { @@ -693,9 +693,9 @@ function transition(jobDoc, jobObj, stateName, state, flowObj, save = true) { // perform the transition if (targetState) { - jobObj.flowState = targetState; + executionObj.state = targetState; - jobObj.provenance.push({ + executionObj.provenance.push({ date: new Date().toISOString(), from: stateName, to: targetState, @@ -713,13 +713,13 @@ function transition(jobDoc, jobObj, stateName, state, flowObj, save = true) { // determine the final status if (STATE_FAIL === state.Type.toLowerCase()) { - jobObj.flowStatus = FLOW_STATUS_FAILED; + executionObj.status = STATE_MACHINE_STATUS_FAILED; } else { - jobObj.flowStatus = FLOW_STATUS_COMPLETE; + executionObj.status = STATE_MACHINE_STATUS_COMPLETE; } // terminal states have no "Next" target state - jobObj.provenance.push({ + executionObj.provenance.push({ date: new Date().toISOString(), from: stateName, to: 'COMPLETED', @@ -728,76 +728,76 @@ function transition(jobDoc, jobObj, stateName, state, flowObj, save = true) { } //resets the retries since the step has completed succesfully - jobObj.retries = {}; + executionObj.retries = {}; - // update the state status and provenence in the job doc + // update the state status and provenence in the execution doc if (save) { - xdmp.nodeReplace(jobDoc.root, jobObj); + xdmp.nodeReplace(executionDoc.root, executionObj); } } catch (err) { return handleError( 'TRANSITIONERROR', `transition error for state "${stateName}"`, err, - jobDoc, - jobObj, + executionDoc, + executionObj, save ); } - return jobObj; + return executionObj; } /** * Performs the actions and transitions for a state. * - * @param {*} jobDoc - the job document + * @param {*} executionDoc - the execution document */ -function executeStateByJobDoc(jobDoc, save = true) { +function executeStateByExecutionDoc(executionDoc, save = true) { xdmp.securityAssert('http://marklogic.com/state-conductor/privilege/execute', 'execute'); - const uri = xdmp.nodeUri(jobDoc); - const jobObj = scaffoldJobDoc(jobDoc.toObject()); - const flowName = jobObj.flowName; - const stateName = jobObj.flowState; + const uri = xdmp.nodeUri(executionDoc); + const executionObj = scaffoldExecutionDoc(executionDoc.toObject()); + const name = executionObj.name; + const stateName = executionObj.state; let state; - let flowObj; - xdmp.trace(TRACE_EVENT, `executing flow "${flowName}"`); - xdmp.trace(TRACE_EVENT, `flow state "${stateName}"`); + let stateMachineObj; + xdmp.trace(TRACE_EVENT, `executing stateMachine "${name}"`); + xdmp.trace(TRACE_EVENT, `stateMachine state "${stateName}"`); // sanity check - if (FLOW_STATUS_WORKING !== jobObj.flowStatus) { + if (STATE_MACHINE_STATUS_WORKING !== executionObj.status) { xdmp.trace( TRACE_EVENT, - 'INVALID-FLOW-STATUS: Cannot execute a flow that is not in the WORKING status' + 'INVALID-STATE_MACHINE-STATUS: Cannot execute a stateMachine that is not in the WORKING status' ); return fn.error( null, - 'INVALID-FLOW-STATUS', - 'Cannot execute a flow that is not in the WORKING status' + 'INVALID-STATE_MACHINE-STATUS', + 'Cannot execute a stateMachine that is not in the WORKING status' ); } try { - flowObj = getFlowDocumentFromDatabase(flowName, jobObj.database).toObject(); + stateMachineObj = getStateMachineFromDatabase(name, executionObj.database).toObject(); try { - state = flowObj.States[stateName]; + state = stateMachineObj.States[stateName]; } catch (e) { fn.error( null, 'INVALID-STATE-DEFINITION', - `Can't Find the state "${stateName}" in flow "${flowName}"` + `Can't Find the state "${stateName}" in stateMachine "${name}"` ); } } catch (err) { return handleError( err.name, - `executeStateByJobDoc error for flow "${flowName}"`, + `executeStateByExecutionDoc error for stateMachine "${name}"`, err, - jobDoc, - jobObj, + executionDoc, + executionObj, save ); } @@ -805,14 +805,14 @@ function executeStateByJobDoc(jobDoc, save = true) { if (state) { try { //removes old waiting data - delete jobObj.currentlyWaiting; + delete executionObj.currentlyWaiting; // perform the actions for the "Task" state if (state.Type && state.Type.toLowerCase() === STATE_TASK) { xdmp.trace(TRACE_EVENT, `executing action for state: ${stateName}`); if (state.Resource) { - let context = jobObj.context; + let context = executionObj.context; // filter the context through the InputPath if set if (state.InputPath && state.InputPath !== '$') { @@ -820,17 +820,17 @@ function executeStateByJobDoc(jobDoc, save = true) { } // execute the resource modules - let resp = executeActionModule(state.Resource, jobObj.uri, state.Parameters, context, { - database: jobObj.database, - modules: jobObj.modules, + let resp = executeActionModule(state.Resource, executionObj.uri, state.Parameters, context, { + database: executionObj.database, + modules: executionObj.modules, }); - // add the data from the result to the job's context + // add the data from the result to the execution's context if (state.OutputPath && state.OutputPath !== '$') { - // update the job context with the response optionally modified by the OutputPath config - jobObj.context = lib.materializeReferencePath(state.OutputPath, resp); + // update the execution context with the response optionally modified by the OutputPath config + executionObj.context = lib.materializeReferencePath(state.OutputPath, resp); } else { - jobObj.context = resp; + executionObj.context = resp; } } else { fn.error( @@ -843,12 +843,12 @@ function executeStateByJobDoc(jobDoc, save = true) { if (state.Result) { let result = state.Result; - // add the data from the result to the job's context + // add the data from the result to the execution's context if (state.OutputPath && state.OutputPath !== '$') { - // update the job context with the result data optionally modified by the OutputPath config - jobObj.context = lib.materializeReferencePath(state.OutputPath, result); + // update the execution context with the result data optionally modified by the OutputPath config + executionObj.context = lib.materializeReferencePath(state.OutputPath, result); } else { - jobObj.context = result; + executionObj.context = result; } } } else if ( @@ -856,7 +856,7 @@ function executeStateByJobDoc(jobDoc, save = true) { state.Type.toLowerCase() === STATE_WAIT && (state.Event || state.EventPath) ) { - //updated the job Doc to have info about why its waiting + //updated the execution Doc to have info about why its waiting xdmp.trace(TRACE_EVENT, `waiting for state: ${stateName}`); @@ -864,7 +864,7 @@ function executeStateByJobDoc(jobDoc, save = true) { ///checks if there is EventPath use that over using Event if (state.hasOwnProperty('EventPath')) { - eventToWaitFor = lib.materializeReferencePath(state.EventPath, jobObj.context); + eventToWaitFor = lib.materializeReferencePath(state.EventPath, executionObj.context); } else { eventToWaitFor = state.Event; } @@ -879,12 +879,12 @@ function executeStateByJobDoc(jobDoc, save = true) { } /* eventToWaitFor = state.Event; */ - jobObj.currentlyWaiting = { + executionObj.currentlyWaiting = { event: eventToWaitFor, }; - jobObj.flowStatus = FLOW_STATUS_WAITING; + executionObj.status = STATE_MACHINE_STATUS_WAITING; } else if (state.Type && state.Type.toLowerCase() === STATE_WAIT && state.Seconds) { - //updated the job Doc to have info about why its waiting + //updated the execution Doc to have info about why its waiting xdmp.trace(TRACE_EVENT, `waiting for state: ${stateName}`); if (state.Seconds) { let waitTime = Number(state.Seconds); @@ -895,11 +895,11 @@ function executeStateByJobDoc(jobDoc, save = true) { xs.dayTimeDuration('PT' + WaitTimeToMinutes + 'M' + WaitTimeToSeconds + 'S') ); xdmp.trace(TRACE_EVENT, `waiting for state nextTaskTime : ${nextTaskTime}`); - jobObj.currentlyWaiting = { + executionObj.currentlyWaiting = { seconds: state.Seconds, nextTaskTime: nextTaskTime, }; - jobObj.flowStatus = FLOW_STATUS_WAITING; + executionObj.status = STATE_MACHINE_STATUS_WAITING; } else { fn.error( null, @@ -908,7 +908,7 @@ function executeStateByJobDoc(jobDoc, save = true) { ); } } else if (state.Type && state.Type.toLowerCase() === STATE_WAIT && state.Timestamp) { - //updated the job Doc to have info about why its waiting + //updated the execution Doc to have info about why its waiting xdmp.trace(TRACE_EVENT, `waiting for state Timestamp : ${stateName}`); if (state.Timestamp) { xdmp.trace(TRACE_EVENT, ` timestamp value is : ${state.Timestamp}`); @@ -922,7 +922,7 @@ function executeStateByJobDoc(jobDoc, save = true) { if (nextTaskTime < fn.currentDateTime()) { xdmp.trace(TRACE_EVENT, `Time for Schedule task has passed : ${nextTaskTime}`); } - jobObj.currentlyWaiting = { + executionObj.currentlyWaiting = { timestamp: timestamp, nextTaskTime: nextTaskTime, }; @@ -934,7 +934,7 @@ function executeStateByJobDoc(jobDoc, save = true) { ); } - jobObj.flowStatus = FLOW_STATUS_WAITING; + executionObj.status = STATE_MACHINE_STATUS_WAITING; } else { fn.error( null, @@ -944,16 +944,16 @@ function executeStateByJobDoc(jobDoc, save = true) { } } } catch (err) { - return handleStateFailure(uri, flowName, flowObj, stateName, err, save, jobObj); + return handleStateFailure(uri, name, stateMachineObj, stateName, err, save, executionObj); } - return transition(jobDoc, jobObj, stateName, state, flowObj, save); + return transition(executionDoc, executionObj, stateName, state, stateMachineObj, save); } else { return handleError( 'INVALID-STATE-DEFINITION', - Sequence.from([`state "${stateName}" not found in flow`]), + Sequence.from([`state "${stateName}" not found in stateMachine`]), null, - jobDoc, - jobObj, + executionDoc, + executionObj, save ); } @@ -965,7 +965,7 @@ function executeStateByJobDoc(jobDoc, save = true) { * @param {*} modulePath the uri of the module to execute * @param {*} uri the uri of the in-process document * @param {*} params the parameters passed to this state - * @param {*} context the current job's context + * @param {*} context the current execution's context * @param {*} options { database, modules } the execution context of the module * @returns the action module's resposne */ @@ -1003,7 +1003,7 @@ function executeActionModule(modulePath, uri, params, context, { database, modul * @param {*} modulePath the uri of the module to execute * @param {*} uri the uri of the in-process document * @param {*} params the parameters passed to this Choice rule - * @param {*} context the current job's context + * @param {*} context the current execution's context * @param {*} options { database, modules } the execution context of the module * @returns boolean response of the module */ @@ -1043,16 +1043,16 @@ function executeConditionModule(modulePath, uri, params, context, { database, mo * Uses "Choices" to transition to a failure state * * @param {*} uri - * @param {*} flowName - * @param {*} flow + * @param {*} name + * @param {*} stateMachine * @param {*} stateName * @param {*} err * @param {*} save - * @param {*} jobDoc + * @param {*} executionDoc * @returns */ -function handleStateFailure(uri, flowName, flow, stateName, err, save = true, jobDocIn) { - const currState = flow.States[stateName]; +function handleStateFailure(uri, name, stateMachine, stateName, err, save = true, executionDocIn) { + const currState = stateMachine.States[stateName]; xdmp.trace(TRACE_EVENT, `handling state failures for state: ${stateName}`); xdmp.trace(TRACE_EVENT, Sequence.from([err])); @@ -1064,14 +1064,14 @@ function handleStateFailure(uri, flowName, flow, stateName, err, save = true, jo ); } - let jobDoc; - let jobObj; + let executionDoc; + let executionObj; if (save) { - jobDoc = cts.doc(uri); - jobObj = jobDoc.toObject(); + executionDoc = cts.doc(uri); + executionObj = executionDoc.toObject(); } else { - jobObj = jobDocIn; + executionObj = executionDocIn; } if ( @@ -1088,8 +1088,8 @@ function handleStateFailure(uri, flowName, flow, stateName, err, save = true, jo (retry.ErrorEquals.includes(err.name) || retry.ErrorEquals.includes('States.ALL') || retry.ErrorEquals.includes('*')) && - (!jobObj.retries.hasOwnProperty(errorEquals) || - jobObj.retries[errorEquals] < (retry.MaxAttempts || DEFAULT_MAX_RETRY_ATTEMPTS)) + (!executionObj.retries.hasOwnProperty(errorEquals) || + executionObj.retries[errorEquals] < (retry.MaxAttempts || DEFAULT_MAX_RETRY_ATTEMPTS)) ) { acc = retry; } @@ -1100,17 +1100,17 @@ function handleStateFailure(uri, flowName, flow, stateName, err, save = true, jo if (target) { let errorEquals = target.ErrorEquals.join(','); - let retryNumber = 1 + (jobObj.retries[errorEquals] || 0); + let retryNumber = 1 + (executionObj.retries[errorEquals] || 0); - jobObj.retries[errorEquals] = retryNumber; + executionObj.retries[errorEquals] = retryNumber; - xdmp.trace(TRACE_EVENT, `retrying job "${uri}"`); + xdmp.trace(TRACE_EVENT, `retrying execution "${uri}"`); - // changes job doc to retry state - jobObj.flowStatus = FLOW_STATUS_WORKING; - jobObj.flowState = stateName; + // changes execution doc to retry state + executionObj.status = STATE_MACHINE_STATUS_WORKING; + executionObj.state = stateName; - jobObj.provenance.push({ + executionObj.provenance.push({ date: new Date().toISOString(), from: stateName, to: stateName, @@ -1119,13 +1119,13 @@ function handleStateFailure(uri, flowName, flow, stateName, err, save = true, jo }); // capture error message in context - jobObj.errors[stateName] = err; + executionObj.errors[stateName] = err; if (save) { - xdmp.nodeReplace(jobDoc.root, jobObj); + xdmp.nodeReplace(executionDoc.root, executionObj); } - return jobObj; + return executionObj; } } @@ -1148,22 +1148,22 @@ function handleStateFailure(uri, flowName, flow, stateName, err, save = true, jo if (target) { xdmp.trace(TRACE_EVENT, `transitioning to fallback state "${target}"`); // move to the target state - jobObj.flowStatus = FLOW_STATUS_WORKING; - jobObj.flowState = target; - jobObj.provenance.push({ + executionObj.status = STATE_MACHINE_STATUS_WORKING; + executionObj.state = target; + executionObj.provenance.push({ date: new Date().toISOString(), from: stateName, to: target, executionTime: xdmp.elapsedTime(), }); // capture error message in context - jobObj.errors[stateName] = err; + executionObj.errors[stateName] = err; if (save) { - xdmp.nodeReplace(jobDoc.root, jobObj); + xdmp.nodeReplace(executionDoc.root, executionObj); } - return jobObj; + return executionObj; } } } @@ -1172,22 +1172,22 @@ function handleStateFailure(uri, flowName, flow, stateName, err, save = true, jo 'INVALID-STATE-DEFINITION', `no Catch defined for error "${err.name}" in state "${stateName}"`, err, - jobDoc, - jobObj, + executionDoc, + executionObj, save ); } /** - * Determines if the given document is in terminal (final) state for the given flow + * Determines if the given document is in terminal (final) state for the given stateMachine * * @param {*} uri - * @param {*} flow + * @param {*} stateMachine * @returns */ -function inTerminalState(job, flow) { - const currStateName = job.flowState; - let currState = flow.States[currStateName]; +function inTerminalState(execution, stateMachine) { + const currStateName = execution.state; + let currState = stateMachine.States[currStateName]; if (currState && !SUPPORTED_STATE_TYPES.includes(currState.Type.toLowerCase())) { fn.error(null, 'INVALID-STATE-DEFINITION', `unsupported state type: "${currState.Type}"`); @@ -1201,20 +1201,20 @@ function inTerminalState(job, flow) { } /** - * Calculates the state of documents being processed by, and completed through this flow + * Calculates the state of documents being processed by, and completed through this stateMachine * - * @param {*} flowName + * @param {*} name * @returns */ -function getFlowCounts(flowName, { startDate, endDate, detailed = false }) { - const flow = getFlowDocument(flowName).toObject(); - const states = Object.keys(flow.States); +function getStateMachineCounts(name, { startDate, endDate, detailed = false }) { + const stateMachine = getStateMachine(name).toObject(); + const states = Object.keys(stateMachine.States); const statuses = [ - FLOW_STATUS_NEW, - FLOW_STATUS_WORKING, - FLOW_STATUS_WAITING, - FLOW_STATUS_COMPLETE, - FLOW_STATUS_FAILED, + STATE_MACHINE_STATUS_NEW, + STATE_MACHINE_STATUS_WORKING, + STATE_MACHINE_STATUS_WAITING, + STATE_MACHINE_STATUS_COMPLETE, + STATE_MACHINE_STATUS_FAILED, ]; let baseQuery = []; @@ -1233,8 +1233,8 @@ function getFlowCounts(flowName, { startDate, endDate, detailed = false }) { cts.andQuery( [].concat( baseQuery, - cts.jsonPropertyValueQuery('flowName', flowName), - cts.jsonPropertyValueQuery('flowStatus', status) + cts.jsonPropertyValueQuery('name', name), + cts.jsonPropertyValueQuery('status', status) ) ) ) @@ -1248,16 +1248,16 @@ function getFlowCounts(flowName, { startDate, endDate, detailed = false }) { cts.andQuery( [].concat( baseQuery, - cts.jsonPropertyValueQuery('flowName', flowName), - cts.jsonPropertyValueQuery('flowStatus', status), - cts.jsonPropertyValueQuery('flowState', state) + cts.jsonPropertyValueQuery('name', name), + cts.jsonPropertyValueQuery('status', status), + cts.jsonPropertyValueQuery('state', state) ) ) ) ); const resp = { - flowName: flowName, + name: name, totalPerStatus: {}, totalPerState: {}, }; @@ -1282,7 +1282,7 @@ function getFlowCounts(flowName, { startDate, endDate, detailed = false }) { } }, { - database: xdmp.database(STATE_CONDUCTOR_JOBS_DB), + database: xdmp.database(STATE_CONDUCTOR_EXECUTIONS_DB), } ); @@ -1290,16 +1290,16 @@ function getFlowCounts(flowName, { startDate, endDate, detailed = false }) { } /** - * Should be used when take a job doc from the database + * Should be used when take a execution doc from the database * insures all the needed properties are there - * @param {*} jobDoc + * @param {*} executionDoc */ -function scaffoldJobDoc(jobDoc) { +function scaffoldExecutionDoc(executionDoc) { const needProps = { id: null, - flowName: null, - flowStatus: null, - flowState: null, + name: null, + status: null, + state: null, uri: null, database: null, modules: null, @@ -1310,34 +1310,34 @@ function scaffoldJobDoc(jobDoc) { retries: {}, }; - return Object.assign(needProps, jobDoc); + return Object.assign(needProps, executionDoc); } /** - * Convienence function to create a job record for a document to be - * processed by a state conductor flow. + * Convienence function to create a execution record for a document to be + * processed by a state conductor stateMachine. * - * @param {*} flowName + * @param {*} name * @param {*} uri * @param {*} [context={}] * @param {*} [options={}] */ -function createStateConductorJob(flowName, uri, context = {}, options = {}) { +function createStateConductorExecution(name, uri, context = {}, options = {}) { xdmp.securityAssert('http://marklogic.com/state-conductor/privilege/execute', 'execute'); - const collections = [JOB_COLLECTION].concat(options.collections || []); - const directory = options.directory || '/' + JOB_COLLECTION + '/'; + const collections = [EXECUTION_COLLECTION].concat(options.collections || []); + const directory = options.directory || '/' + EXECUTION_COLLECTION + '/'; const database = options.database || xdmp.database(); const modules = options.modules || xdmp.modulesDatabase(); const id = sem.uuidString(); - const jobUri = directory + id + '.json'; + const executionUri = directory + id + '.json'; - const job = scaffoldJobDoc({ + const execution = scaffoldExecutionDoc({ id: id, - flowName: flowName, - flowStatus: FLOW_STATUS_NEW, - flowState: null, + name: name, + status: STATE_MACHINE_STATUS_NEW, + state: null, uri: uri, database: database, modules: modules, @@ -1345,44 +1345,44 @@ function createStateConductorJob(flowName, uri, context = {}, options = {}) { context: context, }); - // insert the job document - xdmp.trace(TRACE_EVENT, `inserting job document: ${jobUri} into db ${STATE_CONDUCTOR_JOBS_DB}`); + // insert the execution document + xdmp.trace(TRACE_EVENT, `inserting execution document: ${executionUri} into db ${STATE_CONDUCTOR_EXECUTIONS_DB}`); invokeOrApplyFunction( () => { declareUpdate(); - xdmp.documentInsert(jobUri, job, { + xdmp.documentInsert(executionUri, execution, { permissions: [ - xdmp.permission(JOB_DOC_READ_PERMISSION, 'read'), - xdmp.permission(JOB_DOC_WRITE_PERMISSION, 'update'), + xdmp.permission(EXECUTION_DOC_READ_PERMISSION, 'read'), + xdmp.permission(EXECUTION_DOC_WRITE_PERMISSION, 'update'), ], collections: collections, }); }, { - database: xdmp.database(STATE_CONDUCTOR_JOBS_DB), + database: xdmp.database(STATE_CONDUCTOR_EXECUTIONS_DB), } ); - // add job metadata to the target document (if one was passed) + // add execution metadata to the target document (if one was passed) if (uri) { - addJobMetadata(uri, flowName, id); // prevents updates to the target from retriggering this flow + addExecutionMetadata(uri, name, id); // prevents updates to the target from retriggering this stateMachine } return id; } /** - * Convienence function to create job records for a batch of documents to be - * processed by a state conductor flow. + * Convienence function to create execution records for a batch of documents to be + * processed by a state conductor stateMachine. * - * @param {*} flowName + * @param {*} name * @param {*} [uris=[]] * @param {*} [context={}] * @param {*} [options={}] * @returns */ -function batchCreateStateConductorJob(flowName, uris = [], context = {}, options = {}) { - const ids = uris.map((uri) => createStateConductorJob(flowName, uri, context, options)); +function batchCreateStateConductorExecution(name, uris = [], context = {}, options = {}) { + const ids = uris.map((uri) => createStateConductorExecution(name, uri, context, options)); return ids; } @@ -1398,14 +1398,14 @@ function emitEvent(event, batchSize = 100, save = true) { () => { declareUpdate(); - //handle job documents - let waitingURIJobsForEvent = cts + //handle execution documents + let waitingURIExecutionsForEvent = cts .uris( null, null, cts.andQuery([ - cts.collectionQuery(JOB_COLLECTION), - cts.jsonPropertyValueQuery('flowStatus', FLOW_STATUS_WAITING), + cts.collectionQuery(EXECUTION_COLLECTION), + cts.jsonPropertyValueQuery('status', STATE_MACHINE_STATUS_WAITING), cts.jsonPropertyScopeQuery( 'currentlyWaiting', cts.jsonPropertyValueQuery('event', event) @@ -1415,18 +1415,18 @@ function emitEvent(event, batchSize = 100, save = true) { .toArray(); /* splits the array into groups of the batchSize - this is to handle the the case where there are many waiting jobs + this is to handle the the case where there are many waiting executions */ - var arrayOfwaitingURIJobsForEvent = []; + var arrayOfwaitingURIExecutionsForEvent = []; - for (var i = 0; i < waitingURIJobsForEvent.length; i += batchSize) { - arrayOfwaitingURIJobsForEvent.push(waitingURIJobsForEvent.slice(i, i + batchSize)); + for (var i = 0; i < waitingURIExecutionsForEvent.length; i += batchSize) { + arrayOfwaitingURIExecutionsForEvent.push(waitingURIExecutionsForEvent.slice(i, i + batchSize)); } //loops through all the arrays if (save) { - arrayOfwaitingURIJobsForEvent.forEach(function (uriArray) { - xdmp.spawn('/state-conductor/resumeWaitingJobs.sjs', { + arrayOfwaitingURIExecutionsForEvent.forEach(function (uriArray) { + xdmp.spawn('/state-conductor/resumeWaitingExecutions.sjs', { uriArray: uriArray, resumeBy: 'emit event: ' + event, save: save, @@ -1434,63 +1434,63 @@ function emitEvent(event, batchSize = 100, save = true) { }); } - return waitingURIJobsForEvent; + return waitingURIExecutionsForEvent; }, { - database: xdmp.database(STATE_CONDUCTOR_JOBS_DB), + database: xdmp.database(STATE_CONDUCTOR_EXECUTIONS_DB), } ); - // handle flows - // grab all state conductor flows with a event context and matching event - const flows = cts + // handle stateMachines + // grab all state conductor stateMachines with a event context and matching event + const stateMachines = cts .search( cts.andQuery([ - cts.collectionQuery(FLOW_COLLECTION), + cts.collectionQuery(STATE_MACHINE_COLLECTION), cts.jsonPropertyScopeQuery('mlDomain', cts.jsonPropertyValueQuery('scope', 'event')), cts.jsonPropertyScopeQuery('mlDomain', cts.jsonPropertyValueQuery('value', event)), ]) ) .toArray(); - // determine which flows should run and create state conductor jobs - let flowsToTrigger = flows.filter((flow) => { - // find the flows where the event and scope are in the same object - let eventContext = flow.xpath("mlDomain/context[scope = 'event' and value = '" + event + "' ]"); + // determine which stateMachines should run and create state conductor executions + let stateMachinesToTrigger = stateMachines.filter((stateMachine) => { + // find the stateMachines where the event and scope are in the same object + let eventContext = stateMachine.xpath("mlDomain/context[scope = 'event' and value = '" + event + "' ]"); return fn.exists(eventContext); }); - let flowsToTriggerResp = flowsToTrigger.map((flow) => { - // create a state conductor job for the event flows - let flowName = getFlowNameFromUri(fn.documentUri(flow)); - let resp = createStateConductorJob(flowName, null); - xdmp.trace(TRACE_EVENT, `created state conductor job for event flow: ${resp}`); - return { flowName: flowName, JobId: resp }; + let stateMachinesToTriggerResp = stateMachinesToTrigger.map((stateMachine) => { + // create a state conductor execution for the event stateMachines + let name = getStateMachineNameFromUri(fn.documentUri(stateMachine)); + let resp = createStateConductorExecution(name, null); + xdmp.trace(TRACE_EVENT, `created state conductor execution for event stateMachine: ${resp}`); + return { stateMachineName: name, executionId: resp }; }); const output = { - jobDocumentsTriggered: fn.head(uris), - flowsTriggered: flowsToTriggerResp, + executionDocumentsTriggered: fn.head(uris), + stateMachinesTriggered: stateMachinesToTriggerResp, }; return output; } /** - * Query for job document uris, matching the given options + * Query for execution document uris, matching the given options * * @param {*} options * @returns */ -function getJobDocuments(options) { +function getExecutionDocuments(options) { xdmp.securityAssert('http://marklogic.com/state-conductor/privilege/execute', 'execute'); const start = options.start || 1; const count = options.count || 100; - const flowStatus = Array.isArray(options.flowStatus) - ? options.flowStatus - : [FLOW_STATUS_NEW, FLOW_STATUS_WORKING]; - const flowNames = Array.isArray(options.flowNames) ? options.flowNames : []; + const status = Array.isArray(options.status) + ? options.status + : [STATE_MACHINE_STATUS_NEW, STATE_MACHINE_STATUS_WORKING]; + const names = Array.isArray(options.names) ? options.names : []; const resumeWait = options.resumeWait; const forestIds = options.forestIds; let uris = []; @@ -1498,12 +1498,12 @@ function getJobDocuments(options) { invokeOrApplyFunction( () => { const queries = [ - cts.collectionQuery('stateConductorJob'), - cts.jsonPropertyValueQuery('flowStatus', flowStatus), + cts.collectionQuery('stateConductorExecution'), + cts.jsonPropertyValueQuery('status', status), ]; - if (flowNames.length > 0) { - queries.push(cts.jsonPropertyValueQuery('flowName', flowNames)); + if (names.length > 0) { + queries.push(cts.jsonPropertyValueQuery('name', names)); } if (options.startDate) { queries.push( @@ -1516,12 +1516,12 @@ function getJobDocuments(options) { let ctsQuery = cts.andQuery(queries); - // add any "waiting" jobs that should be resumed - unless explicitly told not to + // add any "waiting" executions that should be resumed - unless explicitly told not to if (!fn.exists(resumeWait) || resumeWait) { ctsQuery = cts.orQuery([ ctsQuery, cts.andQuery([ - cts.collectionQuery('stateConductorJob'), + cts.collectionQuery('stateConductorExecution'), cts.jsonPropertyScopeQuery( 'currentlyWaiting', cts.jsonPropertyRangeQuery('nextTaskTime', '<=', fn.currentDateTime()) @@ -1537,7 +1537,7 @@ function getJobDocuments(options) { ); }, { - database: xdmp.database(STATE_CONDUCTOR_JOBS_DB), + database: xdmp.database(STATE_CONDUCTOR_EXECUTIONS_DB), } ); return uris; @@ -1545,73 +1545,73 @@ function getJobDocuments(options) { /** * Convienence function to handle error - * puts the job document in an error state - * return the job object + * puts the execution document in an error state + * return the execution object * errors out * * @param {*} name the name of the error * @param {*} message the error message * @param {*} err the error object if gotten from a catch - * @param {*} jobObj the job object - * @param {*} save while to update the job document + * @param {*} executionObj the execution object + * @param {*} save while to update the execution document **/ -function handleError(name, message, err, jobDoc, jobObj, save = true) { +function handleError(name, message, err, executionDoc, executionObj, save = true) { xdmp.trace(TRACE_EVENT, name + ':' + message); - const state = jobObj.flowState || FLOW_NEW_STEP; + const state = executionObj.state || STATE_MACHINE_NEW_STEP; - // update the job document - jobObj.flowStatus = FLOW_STATUS_FAILED; - jobObj.errors[state] = err; + // update the execution document + executionObj.status = STATE_MACHINE_STATUS_FAILED; + executionObj.errors[state] = err; if (save) { - xdmp.nodeReplace(jobDoc.root, jobObj); + xdmp.nodeReplace(executionDoc.root, executionObj); } // trigger CPF error state (intentionally commented out) //fn.error(null, name, Sequence.from([message, err])); - return jobObj; + return executionObj; } module.exports = { TRACE_EVENT, - STATE_CONDUCTOR_JOBS_DB, + STATE_CONDUCTOR_EXECUTIONS_DB, STATE_CONDUCTOR_TRIGGERS_DB, STATE_CONDUCTOR_SCHEMAS_DB, DEFAULT_MAX_RETRY_ATTEMPTS, - FLOW_COLLECTION, - FLOW_DIRECTORY, - FLOW_ITEM_COLLECTION, - FLOW_STATUS_NEW, - FLOW_STATUS_WORKING, - FLOW_STATUS_WAITING, - FLOW_STATUS_COMPLETE, - FLOW_STATUS_FAILED, - JOB_COLLECTION, - JOB_DIRECTORY, - addJobMetadata, - batchCreateStateConductorJob, - checkFlowContext, - createStateConductorJob, + STATE_MACHINE_COLLECTION, + STATE_MACHINE_DIRECTORY, + STATE_MACHINE_ITEM_COLLECTION, + STATE_MACHINE_STATUS_NEW, + STATE_MACHINE_STATUS_WORKING, + STATE_MACHINE_STATUS_WAITING, + STATE_MACHINE_STATUS_COMPLETE, + STATE_MACHINE_STATUS_FAILED, + EXECUTION_COLLECTION, + EXECUTION_DIRECTORY, + addExecutionMetadata, + batchCreateStateConductorExecution, + checkStateMachineContext, + createStateConductorExecution, emitEvent, - executeStateByJobDoc, - getAllFlowsContextQuery, - getApplicableFlows, - getFlowContextQuery, - getFlowCounts, - getFlowDocument, - getFlowDocumentFromDatabase, - getFlowDocuments, - getFlowNameFromUri, - getFlowNames, + executeStateByExecutionDoc, + getAllStateMachinesContextQuery, + getApplicableStateMachines, + getStateMachineContextQuery, + getStateMachineCounts, + getStateMachine, + getStateMachineFromDatabase, + getStateMachines, + getStateMachineNameFromUri, + getStateMachineNames, getInitialState, - getJobDocuments, - getJobIds, + getExecutionDocuments, + getExecutionIds, invokeOrApplyFunction, - processJob, - resumeWaitingJob, - resumeWaitingJobByJobDoc, - retryJobAtState, - retryJobAtStateByJobDoc, - startProcessingFlowByJobDoc, + processExecution, + resumeWaitingExecution, + resumeWaitingExecutionByExecutionDoc, + retryExecutionAtState, + retryExecutionAtStateByExecutionDoc, + startProcessingStateMachineByExecutionDoc, }; diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/flow-file-validator.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/state-machine-validator.sjs similarity index 94% rename from state-conductor-modules/src/main/ml-modules/root/state-conductor/flow-file-validator.sjs rename to state-conductor-modules/src/main/ml-modules/root/state-conductor/state-machine-validator.sjs index 8bc49c40..0921c885 100644 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/flow-file-validator.sjs +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/state-machine-validator.sjs @@ -134,15 +134,15 @@ const schema = { }; /** - * Given a state conductor flow, validate against the + * Given a state conductor stateMachine, validate against the * MarkLogic implementation of Amazon State Language * - * @param {*} flow + * @param {*} stateMachine * @returns */ -function validateFlowFile(flow) { +function validateStateMachineFile(stateMachine) { try { - xdmp.jsonValidateNode(flow, schema); + xdmp.jsonValidateNode(stateMachine, schema); return true; } catch (err) { return false; @@ -150,5 +150,5 @@ function validateFlowFile(flow) { } module.exports = { - validateFlowFile, + validateStateMachineFile, }; diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/tasks/scheduler.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/tasks/scheduler.sjs index f53f7a23..9d587fde 100644 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/tasks/scheduler.sjs +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/tasks/scheduler.sjs @@ -45,34 +45,34 @@ const now = new Date(); } */ -// grab all state conductor flows with a 'scheduled' context -const flows = cts +// grab all state conductor stateMachines with a 'scheduled' context +const stateMachines = cts .search( cts.andQuery([ - cts.collectionQuery(sc.FLOW_COLLECTION), + cts.collectionQuery(sc.STATE_MACHINE_COLLECTION), cts.jsonPropertyScopeQuery('mlDomain', cts.jsonPropertyValueQuery('scope', 'scheduled')), ]) ) .toArray(); -xdmp.trace(sc.TRACE_EVENT, `found ${flows.length} scheduled flows`); +xdmp.trace(sc.TRACE_EVENT, `found ${stateMachines.length} scheduled stateMachines`); -// determine which flows should run and create state conductor jobs -flows - .filter((flow) => { - // find the flows with an elapsed time period - let contexts = flow.toObject().mlDomain.context; +// determine which stateMachines should run and create state conductor executions +stateMachines + .filter((stateMachine) => { + // find the stateMachines with an elapsed time period + let contexts = stateMachine.toObject().mlDomain.context; let elapsed = false; contexts.forEach((ctx) => { elapsed = elapsed || scLib.hasScheduleElapsed(ctx, now); }); return elapsed; }) - .forEach((flow) => { - // create a state conductor job for the elapsed flows - let flowName = sc.getFlowNameFromUri(fn.documentUri(flow)); - let resp = sc.createStateConductorJob(flowName, null); - xdmp.trace(sc.TRACE_EVENT, `created state conductor job for scheduled flow: ${resp}`); + .forEach((stateMachine) => { + // create a state conductor execution for the elapsed stateMachines + let stateMachineName = sc.getStateMachineNameFromUri(fn.documentUri(stateMachine)); + let resp = sc.createStateConductorExecution(stateMachineName, null); + xdmp.trace(sc.TRACE_EVENT, `created state conductor execution for scheduled stateMachine: ${resp}`); }); xdmp.trace(sc.TRACE_EVENT, `state-conductor-scheduler-task completed in "${xdmp.elapsedTime()}"`); diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/tasks/waitTask.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/tasks/waitTask.sjs index a3ee6ede..f39ec0da 100644 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/tasks/waitTask.sjs +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/tasks/waitTask.sjs @@ -13,7 +13,7 @@ sc.invokeOrApplyFunction( 'limit=1000', cts.andQuery([ - cts.collectionQuery('stateConductorJob'), + cts.collectionQuery(sc.EXECUTION_COLLECTION), cts.jsonPropertyScopeQuery( 'currentlyWaiting', cts.jsonPropertyRangeQuery('nextTaskTime', '<=', fn.currentDateTime()) @@ -26,12 +26,12 @@ sc.invokeOrApplyFunction( if (uris.length > 0) { uris.forEach((uri) => { - sc.resumeWaitingJob(uri, 'waitTask'); + sc.resumeWaitingExecution(uri, 'waitTask'); }); } }, { - database: xdmp.database(sc.STATE_CONDUCTOR_JOBS_DB), + database: xdmp.database(sc.STATE_CONDUCTOR_EXECUTIONS_DB), } ); diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/trigger/state-conductor-item-trigger.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/trigger/state-conductor-item-trigger.sjs index d3e5fb8f..6e4b49f7 100644 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/trigger/state-conductor-item-trigger.sjs +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/trigger/state-conductor-item-trigger.sjs @@ -19,7 +19,7 @@ function executeContextRegQuery(uri, regQueryId) { } function registerCtxQuery() { - let query = sc.getAllFlowsContextQuery(); + let query = sc.getAllStateMachinesContextQuery(); let regCtxQueryId = cts.register(query); xdmp.setServerField(FIELD_CTX_QUERY_ID, regCtxQueryId); xdmp.setServerField(FIELD_CTX_QUERY_TIMESTAMP, new Date().getTime()); @@ -64,27 +64,27 @@ function checkUriAgainstContext(uri) { } } - // does this uri match the flow context? + // does this uri match the stateMachine context? return uri === fn.string(fn.head(resp)); } xdmp.trace(sc.TRACE_EVENT, `state-conductor-item-trigger check for "${uri}"`); -// does this doc match any state-conductor flows' context? +// does this doc match any state-conductor stateMachines' context? if (checkUriAgainstContext(uri)) { - // find the specific flow that applies - const flows = sc.getApplicableFlows(uri); + // find the specific stateMachine that applies + const stateMachines = sc.getApplicableStateMachines(uri); xdmp.trace( sc.TRACE_EVENT, - `state-conductor-item-trigger found "${flows.length}" matching flows in ${DATABASE_NAME} for ${uri}` + `state-conductor-item-trigger found "${stateMachines.length}" matching stateMachines in ${DATABASE_NAME} for ${uri}` ); - // create a state conductor job for each flow that applies - flows.forEach((flow) => { - const flowName = sc.getFlowNameFromUri(fn.documentUri(flow)); - sc.createStateConductorJob(flowName, uri); + // create a state conductor execution for each stateMachine that applies + stateMachines.forEach((stateMachine) => { + const stateMachineName = sc.getStateMachineNameFromUri(fn.documentUri(stateMachine)); + sc.createStateConductorExecution(stateMachineName, uri); }); } else { - xdmp.trace(sc.TRACE_EVENT, `no matching flows in ${DATABASE_NAME} for ${uri}`); + xdmp.trace(sc.TRACE_EVENT, `no matching stateMachines in ${DATABASE_NAME} for ${uri}`); } xdmp.trace(sc.TRACE_EVENT, `state-conductor-item-trigger completed in "${xdmp.elapsedTime()}"`); diff --git a/state-conductor-modules/src/main/ml-modules/services/metadata/state-conductor-jobs.xml b/state-conductor-modules/src/main/ml-modules/services/metadata/state-conductor-executions.xml similarity index 51% rename from state-conductor-modules/src/main/ml-modules/services/metadata/state-conductor-jobs.xml rename to state-conductor-modules/src/main/ml-modules/services/metadata/state-conductor-executions.xml index 88361ae5..cff8c100 100644 --- a/state-conductor-modules/src/main/ml-modules/services/metadata/state-conductor-jobs.xml +++ b/state-conductor-modules/src/main/ml-modules/services/metadata/state-conductor-executions.xml @@ -1,14 +1,14 @@ - State Conductor Jobs Service + State Conductor Executions Service -

Service for managing State Conductor Jobs

+

Service for managing State Conductor Executions

- + - +
diff --git a/state-conductor-modules/src/main/ml-modules/services/metadata/state-conductor-resume.xml b/state-conductor-modules/src/main/ml-modules/services/metadata/state-conductor-resume.xml index fef277b1..6572e430 100644 --- a/state-conductor-modules/src/main/ml-modules/services/metadata/state-conductor-resume.xml +++ b/state-conductor-modules/src/main/ml-modules/services/metadata/state-conductor-resume.xml @@ -1,7 +1,7 @@ State Conductor Resume -

Service for Resumming jobs within the State Conductor

+

Service for Resuming executions within the State Conductor

diff --git a/state-conductor-modules/src/main/ml-modules/services/metadata/state-conductor-retry.xml b/state-conductor-modules/src/main/ml-modules/services/metadata/state-conductor-retry.xml index 383881b2..2f0e743d 100644 --- a/state-conductor-modules/src/main/ml-modules/services/metadata/state-conductor-retry.xml +++ b/state-conductor-modules/src/main/ml-modules/services/metadata/state-conductor-retry.xml @@ -1,7 +1,7 @@ State Conductor Retry -

Service for Retry jobs by State within the State Conductor

+

Service for Retrying executions by State within the State Conductor

diff --git a/state-conductor-modules/src/main/ml-modules/services/state-conductor-driver.sjs b/state-conductor-modules/src/main/ml-modules/services/state-conductor-driver.sjs index e1c21702..08f7326a 100644 --- a/state-conductor-modules/src/main/ml-modules/services/state-conductor-driver.sjs +++ b/state-conductor-modules/src/main/ml-modules/services/state-conductor-driver.sjs @@ -18,47 +18,47 @@ function parseArrayParam(input, delim = ',') { } /** - * Searches for state conductor job documents matching the parameters + * Searches for state conductor execution documents matching the parameters */ function get(context, params) { let options = { count: Math.max(0, parseInt('0' + params.count)), - flowStatus: parseArrayParam(params.flowStatus), - flowNames: parseArrayParam(params.flowNames), + status: parseArrayParam(params.status), + names: parseArrayParam(params.names), startDate: params.startDate, endDate: params.endDate, }; - const uris = sc.getJobDocuments(options); + const uris = sc.getExecutionDocuments(options); - xdmp.trace(sc.TRACE_EVENT, `state-conductor-driver found ${uris.length} job documents`); + xdmp.trace(sc.TRACE_EVENT, `state-conductor-driver found ${uris.length} execution documents`); context.outputStatus = [200, 'OK']; return uris; } /** - * Executes the given state conductor job - performing state actions and transitions + * Executes the given state conductor execution - performing state actions and transitions */ function put(context, { uri = '' }) { if (uri.length === 0) { returnError(400, 'Bad Request', 'Missing required parameter "uri"'); } - const continueJob = fn.head( + const continueExecution = fn.head( xdmp.invokeFunction( () => { declareUpdate(); - return sc.processJob(uri); + return sc.processExecution(uri); }, { - database: xdmp.database(sc.STATE_CONDUCTOR_JOBS_DB), + database: xdmp.database(sc.STATE_CONDUCTOR_EXECUTIONS_DB), } ) ); const resp = { - reschedule: continueJob, + reschedule: continueExecution, }; context.outputStatus = [200, 'OK']; diff --git a/state-conductor-modules/src/main/ml-modules/services/state-conductor-jobs.sjs b/state-conductor-modules/src/main/ml-modules/services/state-conductor-executions.sjs similarity index 63% rename from state-conductor-modules/src/main/ml-modules/services/state-conductor-jobs.sjs rename to state-conductor-modules/src/main/ml-modules/services/state-conductor-executions.sjs index aa8f6d56..ac9fb47e 100644 --- a/state-conductor-modules/src/main/ml-modules/services/state-conductor-jobs.sjs +++ b/state-conductor-modules/src/main/ml-modules/services/state-conductor-executions.sjs @@ -11,31 +11,31 @@ function returnError(statusCode, statusMsg, body) { } /** - * Lists the job id for the given document of the named State Conductor Flow + * Lists the execution id for the given document of the named State Conductor State Machine */ function get(context, params) { if (!params.uri) { returnError(400, 'Bad Request', 'Missing required parameter "uri"'); } - if (!params.flowName) { - returnError(400, 'Bad Request', 'Missing required parameter "flowName"'); + if (!params.name) { + returnError(400, 'Bad Request', 'Missing required parameter "name"'); } if (!fn.docAvailable(params.uri)) { returnError(404, 'NOT FOUND', `Document at uri "${params.uri}" not found.`); } - if (!sc.getFlowDocument(params.flowName)) { - returnError(404, 'NOT FOUND', `Flow File "${params.flowName}" not found.`); + if (!sc.getStateMachine(params.name)) { + returnError(404, 'NOT FOUND', `StateMachine "${params.name}" not found.`); } context.outputStatus = [200, 'Success']; - return sc.getJobIds(params.uri, params.flowName); + return sc.getExecutionIds(params.uri, params.name); } /** - * Inserts a State Conductor Job for one or more uris + * Inserts a State Conductor Execution for one or more uris */ -function put(context, { uris = [], flowName = '' }, input) { +function put(context, { uris = [], name = '' }, input) { if (typeof uris === 'string') { uris = uris.split(','); } @@ -43,17 +43,17 @@ function put(context, { uris = [], flowName = '' }, input) { if (uris.length === 0) { returnError(400, 'Bad Request', 'Missing required parameter "uris"'); } - if (flowName === '') { - returnError(400, 'Bad Request', 'Missing required parameter "flowName"'); + if (name === '') { + returnError(400, 'Bad Request', 'Missing required parameter "name"'); } - if (!sc.getFlowDocument(flowName)) { - returnError(404, 'NOT FOUND', `Flow File "${flowName}" not found.`); + if (!sc.getStateMachine(name)) { + returnError(404, 'NOT FOUND', `StateMachine File "${name}" not found.`); } const resp = uris.reduce((acc, uri) => { if (fn.docAvailable(uri)) { - const jobId = sc.createStateConductorJob(flowName, uri); - acc[uri] = jobId; + const executionId = sc.createStateConductorExecution(name, uri); + acc[uri] = executionId; return acc; } else { returnError(400, 'Bad Request', `Document "${uri}" not found.`); diff --git a/state-conductor-modules/src/main/ml-modules/services/state-conductor-flows.sjs b/state-conductor-modules/src/main/ml-modules/services/state-conductor-flows.sjs deleted file mode 100644 index f0029303..00000000 --- a/state-conductor-modules/src/main/ml-modules/services/state-conductor-flows.sjs +++ /dev/null @@ -1,94 +0,0 @@ -'use strict'; - -const sc = require('/state-conductor/state-conductor.sjs'); -const validator = require('/state-conductor/flow-file-validator.sjs'); - -function returnError(statusCode, statusMsg, body) { - fn.error( - null, - 'RESTAPI-SRVEXERR', - Sequence.from([statusCode, statusMsg, body]) - ); -} - -/** - * Lists the installed State Conductor Flows - */ -function get(context, params) { - if (params.flowName) { - const flow = sc.getFlowDocument(params.flowName); - if (flow) { - context.outputStatus = [200, 'Success']; - return flow; - } else { - returnError( - 404, - 'NOT FOUND', - `Flow File "${params.flowName}" not found.` - ); - } - } else { - const flows = sc.getFlowDocuments(); - const resp = flows.toArray().reduce((acc, flow) => { - let name = sc.getFlowNameFromUri(fn.documentUri(flow)); - acc[name] = flow.toObject(); - return acc; - }, {}); - context.outputStatus = [200, 'Success']; - return resp; - } -} - -/** - * Inserts or Updates an installed State Conductor Flow - */ -function put(context, params, input) { - const flowName = params.flowName ? params.flowName.trim() : ''; - if (flowName === '') { - returnError(400, 'Bad Request', 'Missing parameter "flowName"'); - } else if ( - !input || - !context.inputTypes || - context.inputTypes[0] !== 'application/json' - ) { - returnError(400, 'Bad Request', 'Invalid request body'); - } else if (!validator.validateFlowFile(input.toObject())) { - returnError(400, 'Bad Request', 'Invalid state-conductor flow file'); - } else { - const uri = `${sc.FLOW_DIRECTORY}${flowName}.asl.json`; - xdmp.documentInsert(uri, input, { - permissions: xdmp.defaultPermissions(), - collections: [sc.FLOW_COLLECTION], - }); - context.outputStatus = [201, 'Created']; - return ''; - } -} - -/** - * Removes an installed State Conductor Flow - */ -function deleteFunction(context, params) { - const flowName = params.flowName ? params.flowName.trim() : ''; - if (flowName === '') { - returnError(400, 'Bad Request', 'Missing parameter "flowName"'); - } else { - const flow = sc.getFlowDocument(flowName); - if (!flow) { - returnError( - 404, - 'NOT FOUND', - `Flow File "${params.flowName}" not found.` - ); - } else { - const uri = fn.documentUri(flow); - xdmp.documentDelete(uri); - context.outputStatus = [204, 'Deleted']; - return ''; - } - } -} - -exports.GET = get; -exports.PUT = put; -exports.DELETE = deleteFunction; diff --git a/state-conductor-modules/src/main/ml-modules/services/state-conductor-resume.sjs b/state-conductor-modules/src/main/ml-modules/services/state-conductor-resume.sjs index 2db77b7d..a9031d3a 100644 --- a/state-conductor-modules/src/main/ml-modules/services/state-conductor-resume.sjs +++ b/state-conductor-modules/src/main/ml-modules/services/state-conductor-resume.sjs @@ -11,7 +11,7 @@ function returnError(statusCode, statusMsg, body) { } /** - * resumes the jobs with the URIS sent + * resumes the executions with the URIS sent */ function put(context, { uris = [], resumeBy = 'unspecified' }, input) { if (typeof uris === 'string') { @@ -26,10 +26,10 @@ function put(context, { uris = [], resumeBy = 'unspecified' }, input) { const resp = { uris: [], - jobs: {}, + executions: {}, }; - //runs the update in the jobs database + //runs the update in the executions database sc.invokeOrApplyFunction( () => { declareUpdate(); @@ -37,11 +37,11 @@ function put(context, { uris = [], resumeBy = 'unspecified' }, input) { uris.forEach(function (uri) { resp.uris.push(uri); - resp.jobs[uri] = sc.resumeWaitingJob(uri, resumeBy); + resp.executions[uri] = sc.resumeWaitingExecution(uri, resumeBy); }); }, { - database: xdmp.database(sc.STATE_CONDUCTOR_JOBS_DB), + database: xdmp.database(sc.STATE_CONDUCTOR_EXECUTIONS_DB), } ); diff --git a/state-conductor-modules/src/main/ml-modules/services/state-conductor-retry.sjs b/state-conductor-modules/src/main/ml-modules/services/state-conductor-retry.sjs index ba9fdc60..18efadfa 100644 --- a/state-conductor-modules/src/main/ml-modules/services/state-conductor-retry.sjs +++ b/state-conductor-modules/src/main/ml-modules/services/state-conductor-retry.sjs @@ -11,11 +11,11 @@ function returnError(statusCode, statusMsg, body) { } /** - * resumes the jobs with the URIS sent + * resumes the executions with the URIS sent */ function put( context, - { uris = [], stateName = sc.FLOW_NEW_STEP, retriedBy = 'unspecified' }, + { uris = [], stateName = sc.STATE_MACHINE_NEW_STEP, retriedBy = 'unspecified' }, input ) { if (typeof uris === 'string') { @@ -30,10 +30,10 @@ function put( const resp = { uris: [], - jobs: {}, + executions: {}, }; - //runs the update in the jobs database + //runs the update in the executions database sc.invokeOrApplyFunction( () => { declareUpdate(); @@ -41,11 +41,11 @@ function put( uris.forEach(function (uri) { resp.uris.push(uri); - resp.jobs[uri] = sc.retryJobAtState(uri, stateName, retriedBy); + resp.executions[uri] = sc.retryExecutionAtState(uri, stateName, retriedBy); }); }, { - database: xdmp.database(sc.STATE_CONDUCTOR_JOBS_DB), + database: xdmp.database(sc.STATE_CONDUCTOR_EXECUTIONS_DB), } ); diff --git a/state-conductor-modules/src/main/ml-modules/services/state-conductor-state-machines.sjs b/state-conductor-modules/src/main/ml-modules/services/state-conductor-state-machines.sjs new file mode 100644 index 00000000..68125f79 --- /dev/null +++ b/state-conductor-modules/src/main/ml-modules/services/state-conductor-state-machines.sjs @@ -0,0 +1,94 @@ +'use strict'; + +const sc = require('/state-conductor/state-conductor.sjs'); +const validator = require('/state-conductor/state-machine-validator.sjs'); + +function returnError(statusCode, statusMsg, body) { + fn.error( + null, + 'RESTAPI-SRVEXERR', + Sequence.from([statusCode, statusMsg, body]) + ); +} + +/** + * Lists the installed State Conductor StateMachines + */ +function get(context, params) { + if (params.name) { + const stateMachine = sc.getStateMachine(params.name); + if (stateMachine) { + context.outputStatus = [200, 'Success']; + return stateMachine; + } else { + returnError( + 404, + 'NOT FOUND', + `StateMachine File "${params.name}" not found.` + ); + } + } else { + const stateMachines = sc.getStateMachines(); + const resp = stateMachines.toArray().reduce((acc, stateMachine) => { + let name = sc.getStateMachineNameFromUri(fn.documentUri(stateMachine)); + acc[name] = stateMachine.toObject(); + return acc; + }, {}); + context.outputStatus = [200, 'Success']; + return resp; + } +} + +/** + * Inserts or Updates an installed State Conductor StateMachine + */ +function put(context, params, input) { + const name = params.name ? params.name.trim() : ''; + if (name === '') { + returnError(400, 'Bad Request', 'Missing parameter "name"'); + } else if ( + !input || + !context.inputTypes || + context.inputTypes[0] !== 'application/json' + ) { + returnError(400, 'Bad Request', 'Invalid request body'); + } else if (!validator.validateStateMachineFile(input.toObject())) { + returnError(400, 'Bad Request', 'Invalid state-conductor stateMachine file'); + } else { + const uri = `${sc.STATE_MACHINE_DIRECTORY}${name}.asl.json`; + xdmp.documentInsert(uri, input, { + permissions: xdmp.defaultPermissions(), + collections: [sc.STATE_MACHINE_COLLECTION], + }); + context.outputStatus = [201, 'Created']; + return ''; + } +} + +/** + * Removes an installed State Conductor StateMachine + */ +function deleteFunction(context, params) { + const name = params.name ? params.name.trim() : ''; + if (name === '') { + returnError(400, 'Bad Request', 'Missing parameter "name"'); + } else { + const stateMachine = sc.getStateMachine(name); + if (!stateMachine) { + returnError( + 404, + 'NOT FOUND', + `StateMachine File "${params.name}" not found.` + ); + } else { + const uri = fn.documentUri(stateMachine); + xdmp.documentDelete(uri); + context.outputStatus = [204, 'Deleted']; + return ''; + } + } +} + +exports.GET = get; +exports.PUT = put; +exports.DELETE = deleteFunction; diff --git a/state-conductor-modules/src/main/ml-modules/services/state-conductor-status.sjs b/state-conductor-modules/src/main/ml-modules/services/state-conductor-status.sjs index d2bd07f1..70d3345b 100644 --- a/state-conductor-modules/src/main/ml-modules/services/state-conductor-status.sjs +++ b/state-conductor-modules/src/main/ml-modules/services/state-conductor-status.sjs @@ -16,11 +16,11 @@ function isValidTemporal(value) { } /** - * Lists the status of the given State Conductor Flow + * Lists the status of the given State Conductor StateMachine */ function get(context, params) { - if (params.flowName && !sc.getFlowDocument(params.flowName)) { - returnError(404, 'NOT FOUND', `Flow File "${params.flowName}" not found.`); + if (params.stateMachineName && !sc.getStateMachine(params.stateMachineName)) { + returnError(404, 'NOT FOUND', `StateMachine File "${params.stateMachineName}" not found.`); } if (params.startDate && !isValidTemporal(params.startDate)) { @@ -31,13 +31,13 @@ function get(context, params) { returnError(400, 'BAD REQUEST', `Invalid endDate: "${params.endDate}".`); } - const flowNames = params.flowName ? [params.flowName] : sc.getFlowNames(); + const stateMachineNames = params.stateMachineName ? [params.stateMachineName] : sc.getStateMachineNames(); const startDate = params.startDate; const endDate = params.endDate; const detailed = params.detailed === 'true'; - const resp = flowNames.reduce((acc, name) => { - acc[name] = sc.getFlowCounts(name, { + const resp = stateMachineNames.reduce((acc, name) => { + acc[name] = sc.getStateMachineCounts(name, { startDate: startDate, endDate: endDate, detailed: detailed, From 281d42ce7277d5c0700c2c92e22d5c277f752732 Mon Sep 17 00:00:00 2001 From: Anthony Clavio Date: Thu, 1 Oct 2020 16:03:32 -0400 Subject: [PATCH 02/35] Update README.md --- README.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/README.md b/README.md index c3f23638..0669bdd8 100644 --- a/README.md +++ b/README.md @@ -37,16 +37,10 @@ repositories { } } dependencies { - mlBundle "com.marklogic:marklogic-state-conductor:0.7.0" + mlBundle "com.marklogic:marklogic-state-conductor:0.8.0" } ``` -The _State Conductor_ utilizes MarkLogic's Content Processing Framework. Add the following to your gradle project's properties file to ensure that the CPF configurations are installed in the required location: - -``` -mlCpfDatabaseName=state-conductor-triggers -``` - --- ## Usage From 1ee1f700f6dde3d6ff8c61337bf86498192bc7ef Mon Sep 17 00:00:00 2001 From: Anthony Clavio Date: Thu, 1 Oct 2020 16:04:27 -0400 Subject: [PATCH 03/35] Update README.md --- state-conductor-dataservices/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/state-conductor-dataservices/README.md b/state-conductor-dataservices/README.md index 3af28fc9..f8583805 100644 --- a/state-conductor-dataservices/README.md +++ b/state-conductor-dataservices/README.md @@ -9,7 +9,7 @@ The `com.marklogic.StateConductorDriver` main class provides an implementation o Run the stand-alone jar file: ``` -java -jar state-conductor-dataservices-0.6.1.jar --config driver.properties +java -jar state-conductor-dataservices-0.8.0.jar --config driver.properties ``` ## Generating the Driver Jar From 1e1fe9648e08c8a639a17dfac888fdec621bdc8d Mon Sep 17 00:00:00 2001 From: Anthony Clavio Date: Thu, 1 Oct 2020 16:05:54 -0400 Subject: [PATCH 04/35] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0669bdd8..4daa7987 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # MarkLogic State Conductor The _MarkLogic State Conductor_ is an event-based orchestrator for manipulating MarkLogic database documents. -State Conductor flows are defined using a subset of [Amazon States Language (ASL)](https://states-language.net/spec.html). State actions are defined using server-side modules. The included driver utilizes MarkLogic's CPF and Triggers to move documents through the defined State flows. +State Conductor flows are defined using a subset of [Amazon States Language (ASL)](https://states-language.net/spec.html). State actions are defined using server-side modules. The _State Conductor_ can be used to perform an arbitrary number of context-based processing actions on a subset of documents. Actions could include: invoking a [MarkLogic Data Hub](https://docs.marklogic.com/datahub/) flow, transforming a document, applying metadata, or calling an external process. From ca9a38536dba249d7a93005c8d4c10b7ec5822f6 Mon Sep 17 00:00:00 2001 From: Tyler Replogle Date: Fri, 2 Oct 2020 15:52:48 -0400 Subject: [PATCH 05/35] added .DS_Store --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 80256ca4..83b79dfc 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ build gradle-local.properties *.settings* *.classpath -state-conductor-example/bin/ \ No newline at end of file +state-conductor-example/bin/ +.DS_Store From d2c558871c5c39bb10c6f6e948833933e2565c9c Mon Sep 17 00:00:00 2001 From: Tyler Replogle Date: Fri, 2 Oct 2020 15:55:24 -0400 Subject: [PATCH 06/35] fixed the dhf5 flowname issue --- .../stateMachines/custom-steps-state-machine.asl.json | 2 +- .../stateMachines/missing-dhf-state-machine.asl.json | 2 +- .../test-data/stateMachines/person-state-machine.asl.json | 2 +- .../stateMachines/person-steps-state-machine.asl.json | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/custom-steps-state-machine.asl.json b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/custom-steps-state-machine.asl.json index d3dcee39..b2943172 100644 --- a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/custom-steps-state-machine.asl.json +++ b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/custom-steps-state-machine.asl.json @@ -10,7 +10,7 @@ "Comment": "runs the dhf 5 flow step", "Resource": "/state-conductor/actions/common/dhf/dhf5RunFlowStepAction.sjs", "Parameters": { - "name": "CustomFlow", + "flowName": "CustomFlow", "step": 1, "flowOptions": { "secret": "find me!" diff --git a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/missing-dhf-state-machine.asl.json b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/missing-dhf-state-machine.asl.json index 6b3a0f28..cc27c36a 100644 --- a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/missing-dhf-state-machine.asl.json +++ b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/missing-dhf-state-machine.asl.json @@ -10,7 +10,7 @@ "Comment": "runs the dhf 5 flow step", "Resource": "/state-conductor/actions/common/dhf/dhf5RunFlowStepAction.sjs", "Parameters": { - "name": "MissingFlow", + "flowName": "MissingFlow", "step": 1, "flowOptions": {} }, diff --git a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/person-state-machine.asl.json b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/person-state-machine.asl.json index 04c27022..986abf8c 100644 --- a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/person-state-machine.asl.json +++ b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/person-state-machine.asl.json @@ -10,7 +10,7 @@ "Comment": "runs the dhf 5 flow", "Resource": "/state-conductor/actions/common/dhf/dhf5RunFlowAction.sjs", "Parameters": { - "name": "PersonFlow", + "flowName": "PersonFlow", "flowOptions": {} }, "Next": "Success", diff --git a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/person-steps-state-machine.asl.json b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/person-steps-state-machine.asl.json index 730351ea..713d8287 100644 --- a/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/person-steps-state-machine.asl.json +++ b/state-conductor-dhf5-example/src/test/ml-modules/root/test/suites/StateConductorDHF5Suite/test-data/stateMachines/person-steps-state-machine.asl.json @@ -10,7 +10,7 @@ "Comment": "runs the dhf 5 flow step", "Resource": "/state-conductor/actions/common/dhf/dhf5RunFlowStepAction.sjs", "Parameters": { - "name": "PersonFlow", + "flowName": "PersonFlow", "step": 1, "flowOptions": {} }, @@ -27,7 +27,7 @@ "Comment": "runs the dhf 5 flow step", "Resource": "/state-conductor/actions/common/dhf/dhf5RunFlowStepAction.sjs", "Parameters": { - "name": "PersonFlow", + "flowName": "PersonFlow", "step": 2, "flowOptions": {} }, From 7a1563c8332b9e62803c3cc07cdf688aaa20203a Mon Sep 17 00:00:00 2001 From: Tyler Replogle Date: Fri, 2 Oct 2020 16:02:00 -0400 Subject: [PATCH 07/35] removed CPF and then fixed the v0.3.0 of the data base name --- README.md | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 13192748..1f9c19c3 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # MarkLogic State Conductor The _MarkLogic State Conductor_ is an event-based orchestrator for manipulating MarkLogic database documents. -State Conductor state machines are defined using a subset of [Amazon States Language (ASL)](https://states-language.net/spec.html). Actions are defined using server-side modules. The included driver utilizes MarkLogic's CPF and Triggers to move documents through the defined State Machines. +State Conductor state machines are defined using a subset of [Amazon States Language (ASL)](https://states-language.net/spec.html). Actions are defined using server-side modules. There project includes drivers and Triggers to move documents through the defined State Machines. -The _State Conductor_ can be used to perform an arbitrary number of context-based processing actions on a subset of documents. Actions could include: invoking a [MarkLogic Data Hub](https://docs.marklogic.com/datahub/) flow, transforming a document, applying metadata, or calling an external process. +The _State Conductor_ can be used to perform an arbitrary number of context-based processing actions on a subset of documents. Actions could include: invoking a [MarkLogic Data Hub](https://docs.marklogic.com/datahub/) flow or step, transforming a document, applying metadata, or calling an external process. -The _State Conductor_ requires a "Driver" to process documents and move them through the installed state machine states. The _State Conductor_ supports a [Data Services](https://github.com/aclavio/marklogic-state-conductor/tree/develop/state-conductor-dataservices) driver, a [CoRB2](https://github.com/marklogic-community/corb2) driver, and a [CPF](https://docs.marklogic.com/guide/cpf) driver. +The _State Conductor_ requires a "Driver" to process documents and move them through the installed state machine states. The _State Conductor_ supports a [Data Services](https://github.com/aclavio/marklogic-state-conductor/tree/develop/state-conductor-dataservices) driver and a [CoRB2](https://github.com/marklogic-community/corb2) driver. 1. [Quick Start Guide](https://github.com/aclavio/marklogic-state-conductor/wiki/QUICKSTART) 2. [Installation](#installation) @@ -41,14 +41,6 @@ dependencies { } ``` -The _State Conductor_ utilizes MarkLogic's Content Processing Framework. Add the following to your gradle project's properties file to ensure that the CPF configurations are installed in the required location: - -``` -mlCpfDatabaseName=state-conductor-triggers -``` - ---- - ## Usage Any documents created or modified having the `state-conductor-item` collection will trigger processing by the _State Conductor_. They will be evaluated against the context of all installed _State Machines_. For each matching _State Machine_ an `Execution` document will be created corresponding to the matching execution and triggering document. A property will be added to the triggering document's metadata indicating the `Execution` file's id: @@ -146,7 +138,7 @@ Where `uri` is the document being processed by the state machine; `parameters` i ### Execution Documents -For every document processed by a _State Conductor_ state machine there is a corresponding `Execution` document. Execution documents are stored in the `state-conductor-executions` database (new in v0.3.0), in the `/execution/` folder. These documents track the in-process document, and state machine; they also store the context and provenance information. +For every document processed by a _State Conductor_ state machine there is a corresponding `Execution` document. Execution documents are stored in the `state-conductor-executions` database, in the `/execution/` folder. These documents track the in-process document, and state machine; they also store the context and provenance information. ### Provenance From d0a990ca804189815d98b15b9e4cd3e485d554a4 Mon Sep 17 00:00:00 2001 From: Tyler Replogle Date: Fri, 2 Oct 2020 16:05:28 -0400 Subject: [PATCH 08/35] fixed the flow name issues here --- .../custom/MyCustomStep/main.sjs | 51 +++++++++++-------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/state-conductor-dhf5-example/src/main/ml-modules/root/custom-modules/custom/MyCustomStep/main.sjs b/state-conductor-dhf5-example/src/main/ml-modules/root/custom-modules/custom/MyCustomStep/main.sjs index 9bfe8e91..59f8082d 100644 --- a/state-conductor-dhf5-example/src/main/ml-modules/root/custom-modules/custom/MyCustomStep/main.sjs +++ b/state-conductor-dhf5-example/src/main/ml-modules/root/custom-modules/custom/MyCustomStep/main.sjs @@ -1,12 +1,9 @@ /* Copyright 2012-2019 MarkLogic Corporation - 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. @@ -16,17 +13,15 @@ /* Custom steps for data hub 5 are 'on rails' code execution within a single transaction, after which the output from these steps will create in-memory objects that will then be written in one single, isolated transaction. - This is designed to run in QUERY (read-only) mode by default. If you need transactionally consistent updates or serializable read locking on documents, then you must upgrade to an UPDATE transaction either through an update (such as declareUpdate()) or by setting the value of 'stepUpdate' as true in the options and it will be executed in update mode. */ -const DataHub = require("/data-hub/5/datahub.sjs"); +const DataHub = require('/data-hub/5/datahub.sjs'); const datahub = new DataHub(); function main(content, options) { - //changes the stateConductorContext //is used for a unit test options.stateConductorContext.hasChanged = true; @@ -38,23 +33,39 @@ function main(content, options) { let context = content.context; //let's set our output format, so we know what we're exporting - let outputFormat = options.outputFormat ? options.outputFormat.toLowerCase() : datahub.stateMachine.consts.DEFAULT_FORMAT; + let outputFormat = options.outputFormat + ? options.outputFormat.toLowerCase() + : datahub.flow.consts.DEFAULT_FORMAT; //here we check to make sure we're not trying to push out a binary or text document, just xml or json - if (outputFormat !== datahub.stateMachine.consts.JSON && outputFormat !== datahub.stateMachine.consts.XML) { + if (outputFormat !== datahub.flow.consts.JSON && outputFormat !== datahub.flow.consts.XML) { datahub.debug.log({ - message: 'The output format of type ' + outputFormat + ' is invalid. Valid options are ' + datahub.stateMachine.consts.XML + ' or ' + datahub.stateMachine.consts.JSON + '.', - type: 'error' + message: + 'The output format of type ' + + outputFormat + + ' is invalid. Valid options are ' + + datahub.flow.consts.XML + + ' or ' + + datahub.flow.consts.JSON + + '.', + type: 'error', }); - throw Error('The output format of type ' + outputFormat + ' is invalid. Valid options are ' + datahub.stateMachine.consts.XML + ' or ' + datahub.stateMachine.consts.JSON + '.'); + throw Error( + 'The output format of type ' + + outputFormat + + ' is invalid. Valid options are ' + + datahub.flow.consts.XML + + ' or ' + + datahub.flow.consts.JSON + + '.' + ); } /* This scaffolding assumes we obtained the document from the database. If you are inserting information, you will have to map data from the content.value appropriately and create an instance (object), headers (object), and triples - (array) instead of using the stateMachineUtils functions to grab them from a document that was pulled from MarkLogic. + (array) instead of using the flowUtils functions to grab them from a document that was pulled from MarkLogic. Also you do not have to check if the document exists as in the code below. - Example code for using data that was sent to MarkLogic server for the document let instance = content.value; let triples = []; @@ -77,13 +88,13 @@ function main(content, options) { } //get our instance, default shape of envelope is envelope/instance, else it'll return an empty object/array - let instance = datahub.stateMachine.stateMachineUtils.getInstanceAsObject(doc) || {}; + let instance = datahub.flow.flowUtils.getInstanceAsObject(doc) || {}; // get triples, return null if empty or cannot be found - let triples = datahub.stateMachine.stateMachineUtils.getTriplesAsObject(doc) || []; + let triples = datahub.flow.flowUtils.getTriplesAsObject(doc) || []; //gets headers, return null if cannot be found - let headers = datahub.stateMachine.stateMachineUtils.getHeadersAsObject(doc) || {}; + let headers = datahub.flow.flowUtils.getHeadersAsObject(doc) || {}; //If you want to set attachments, uncomment here // instance['$attachments'] = doc; @@ -92,7 +103,6 @@ function main(content, options) { //instance['$title'] = 'myEntity'; //instance['$version'] = '0.0.1' - //insert code to manipulate the instance, triples, headers, uri, context metadata, etc. headers.randomUuid = sem.uuidString(); @@ -101,13 +111,12 @@ function main(content, options) { instance = content.value; - //form our envelope here now, specifying our output format - let envelope = datahub.stateMachine.stateMachineUtils.makeEnvelope(instance, headers, triples, outputFormat); + let envelope = datahub.flow.flowUtils.makeEnvelope(instance, headers, triples, outputFormat); //create our return content object, we have a handy helper function for creating a json scaffolding, but you //can also do a node-based one by using nodebuilder, especially if you're dealing with xml! - let newContent = datahub.stateMachine.stateMachineUtils.createContentAsObject(); + let newContent = datahub.flow.flowUtils.createContentAsObject(); //assign our envelope value newContent.value = envelope; @@ -123,5 +132,5 @@ function main(content, options) { } module.exports = { - main: main + main: main, }; From e2a66fd6d1fd698c1278cd9c707a1889a3ecc35f Mon Sep 17 00:00:00 2001 From: Tyler Replogle Date: Fri, 2 Oct 2020 16:24:21 -0400 Subject: [PATCH 09/35] changed the database filename --- ...obs-database.json => state-conductor-executions-database.json} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename state-conductor-modules/src/main/ml-config/databases/{state-conductor-jobs-database.json => state-conductor-executions-database.json} (100%) diff --git a/state-conductor-modules/src/main/ml-config/databases/state-conductor-jobs-database.json b/state-conductor-modules/src/main/ml-config/databases/state-conductor-executions-database.json similarity index 100% rename from state-conductor-modules/src/main/ml-config/databases/state-conductor-jobs-database.json rename to state-conductor-modules/src/main/ml-config/databases/state-conductor-executions-database.json From 80e1f9319cadd31509266c376200e6ba7fc22571 Mon Sep 17 00:00:00 2001 From: Tyler Replogle Date: Fri, 2 Oct 2020 16:25:40 -0400 Subject: [PATCH 10/35] fixed type O of a --- .../root/state-conductor/state-conductor.sjs | 75 ++++++++++++++----- 1 file changed, 55 insertions(+), 20 deletions(-) diff --git a/state-conductor-modules/src/main/ml-modules/root/state-conductor/state-conductor.sjs b/state-conductor-modules/src/main/ml-modules/root/state-conductor/state-conductor.sjs index ccf7ec91..007de441 100644 --- a/state-conductor-modules/src/main/ml-modules/root/state-conductor/state-conductor.sjs +++ b/state-conductor-modules/src/main/ml-modules/root/state-conductor/state-conductor.sjs @@ -113,7 +113,11 @@ function getStateMachineFromDatabase(name, databaseId) { () => { let stateMachine = getStateMachine(name); if (!stateMachine) { - fn.error(null, 'MISSING-STATE_MACHINE-FILE', `Cannot find a a stateMachine file with the name: ${name}`); + fn.error( + null, + 'MISSING-STATE_MACHINE-FILE', + `Cannot find a stateMachine file with the name: ${name}` + ); } return stateMachine; }, @@ -167,11 +171,7 @@ function getStateMachineNameFromUri(uri) { */ function getInitialState({ name, StartAt }) { if (!StartAt || StartAt.length === 0) { - fn.error( - null, - 'INVALID-STATE-DEFINITION', - `no "StartAt" defined for state machine "${name}"` - ); + fn.error(null, 'INVALID-STATE-DEFINITION', `no "StartAt" defined for state machine "${name}"`); } return StartAt; } @@ -247,7 +247,9 @@ function getApplicableStateMachines(uri) { .filter((stateMachine) => { let name = getStateMachineNameFromUri(fn.documentUri(stateMachine)); let stateMachineOjb = stateMachine.toObject(); - return getExecutionIds(uri, name).length === 0 && checkStateMachineContext(uri, stateMachineOjb); + return ( + getExecutionIds(uri, name).length === 0 && checkStateMachineContext(uri, stateMachineOjb) + ); }); return stateMachines; @@ -317,7 +319,11 @@ function processExecution(uri) { // sanity check if (!fn.docAvailable(uri)) { - fn.error(null, 'INVALID-EXECUTION-DOCUMENT', `State Conductor execution document "${uri}" not found!`); + fn.error( + null, + 'INVALID-EXECUTION-DOCUMENT', + `State Conductor execution document "${uri}" not found!` + ); } const executionDoc = cts.doc(uri); const execution = executionDoc.toObject(); @@ -342,7 +348,10 @@ function processExecution(uri) { return true; } else { // we're done processing the stateMachine - xdmp.trace(TRACE_EVENT, `state-conductor stateMachine completed for execution document "${uri}"`); + xdmp.trace( + TRACE_EVENT, + `state-conductor stateMachine completed for execution document "${uri}"` + ); // end processing return false; } @@ -360,12 +369,19 @@ function startProcessingStateMachineByExecutionDoc(executionDoc, save = true) { TRACE_EVENT, `INVALID-STATE_MACHINE-STATUS: Cannot start a stateMachine that is not in the ${STATE_MACHINE_STATUS_NEW} status` ); - fn.error(null, 'INVALID-STATE_MACHINE-STATUS', 'Cannot start a stateMachine not in the NEW status'); + fn.error( + null, + 'INVALID-STATE_MACHINE-STATUS', + 'Cannot start a stateMachine not in the NEW status' + ); } try { // grab the stateMachine definition from the correct db - const currStateMachine = getStateMachineFromDatabase(currStateMachineName, executionObj.database).toObject(); + const currStateMachine = getStateMachineFromDatabase( + currStateMachineName, + executionObj.database + ).toObject(); currStateMachine.name = executionObj.name; let initialState = getInitialState(currStateMachine); @@ -462,7 +478,8 @@ function resumeWaitingExecutionByExecutionDoc(executionDoc, resumeBy, save = tru // check if current time is greater than nextTaskTime if ( executionObj.currentlyWaiting.hasOwnProperty('nextTaskTime') && - xs.dateTime(executionObj.currentlyWaiting.nextTaskTime) > fn.currentDateTime() + xdmp.elapsedTime() + xs.dateTime(executionObj.currentlyWaiting.nextTaskTime) > + fn.currentDateTime() + xdmp.elapsedTime() ) { xdmp.trace( TRACE_EVENT, @@ -522,7 +539,12 @@ function resumeWaitingExecutionByExecutionDoc(executionDoc, resumeBy, save = tru * * @param {*} uri - the execution document's uri */ -function retryExecutionAtState(uri, stateName = STATE_MACHINE_NEW_STEP, retriedBy = 'unspecified', save = true) { +function retryExecutionAtState( + uri, + stateName = STATE_MACHINE_NEW_STEP, + retriedBy = 'unspecified', + save = true +) { // checks if document is there if (!fn.docAvailable(uri)) { fn.error(null, 'INVALID-EXECUTION-DOCUMENT', `Document Execution "${uri}" not found."`); @@ -820,10 +842,16 @@ function executeStateByExecutionDoc(executionDoc, save = true) { } // execute the resource modules - let resp = executeActionModule(state.Resource, executionObj.uri, state.Parameters, context, { - database: executionObj.database, - modules: executionObj.modules, - }); + let resp = executeActionModule( + state.Resource, + executionObj.uri, + state.Parameters, + context, + { + database: executionObj.database, + modules: executionObj.modules, + } + ); // add the data from the result to the execution's context if (state.OutputPath && state.OutputPath !== '$') { @@ -1346,7 +1374,10 @@ function createStateConductorExecution(name, uri, context = {}, options = {}) { }); // insert the execution document - xdmp.trace(TRACE_EVENT, `inserting execution document: ${executionUri} into db ${STATE_CONDUCTOR_EXECUTIONS_DB}`); + xdmp.trace( + TRACE_EVENT, + `inserting execution document: ${executionUri} into db ${STATE_CONDUCTOR_EXECUTIONS_DB}` + ); invokeOrApplyFunction( () => { declareUpdate(); @@ -1420,7 +1451,9 @@ function emitEvent(event, batchSize = 100, save = true) { var arrayOfwaitingURIExecutionsForEvent = []; for (var i = 0; i < waitingURIExecutionsForEvent.length; i += batchSize) { - arrayOfwaitingURIExecutionsForEvent.push(waitingURIExecutionsForEvent.slice(i, i + batchSize)); + arrayOfwaitingURIExecutionsForEvent.push( + waitingURIExecutionsForEvent.slice(i, i + batchSize) + ); } //loops through all the arrays @@ -1456,7 +1489,9 @@ function emitEvent(event, batchSize = 100, save = true) { // determine which stateMachines should run and create state conductor executions let stateMachinesToTrigger = stateMachines.filter((stateMachine) => { // find the stateMachines where the event and scope are in the same object - let eventContext = stateMachine.xpath("mlDomain/context[scope = 'event' and value = '" + event + "' ]"); + let eventContext = stateMachine.xpath( + "mlDomain/context[scope = 'event' and value = '" + event + "' ]" + ); return fn.exists(eventContext); }); From 6b688df2d9742f17ebb07406d0528a43e5ca9bcc Mon Sep 17 00:00:00 2001 From: Tyler Replogle Date: Wed, 7 Oct 2020 10:49:39 -0400 Subject: [PATCH 11/35] added the privileges --- .../security/privileges/state-conductor-execute.json | 5 +++++ .../privileges/state-conductor-state-machine.json | 5 +++++ .../security/roles/state-conductor-developer.json | 8 ++------ .../security/roles/state-conductor-execute-role.json | 4 +--- .../roles/state-conductor-execution-writer-role.json | 5 +---- .../security/roles/state-conductor-operator.json | 6 +----- 6 files changed, 15 insertions(+), 18 deletions(-) create mode 100644 state-conductor-modules/src/main/ml-config/security/privileges/state-conductor-execute.json create mode 100644 state-conductor-modules/src/main/ml-config/security/privileges/state-conductor-state-machine.json diff --git a/state-conductor-modules/src/main/ml-config/security/privileges/state-conductor-execute.json b/state-conductor-modules/src/main/ml-config/security/privileges/state-conductor-execute.json new file mode 100644 index 00000000..9a095647 --- /dev/null +++ b/state-conductor-modules/src/main/ml-config/security/privileges/state-conductor-execute.json @@ -0,0 +1,5 @@ +{ + "privilege-name": "state-conductor-execute", + "action": "http://marklogic.com/state-conductor/privilege/execute", + "kind": "execute" +} diff --git a/state-conductor-modules/src/main/ml-config/security/privileges/state-conductor-state-machine.json b/state-conductor-modules/src/main/ml-config/security/privileges/state-conductor-state-machine.json new file mode 100644 index 00000000..669fc786 --- /dev/null +++ b/state-conductor-modules/src/main/ml-config/security/privileges/state-conductor-state-machine.json @@ -0,0 +1,5 @@ +{ + "privilege-name": "state-conductor-state-machine", + "action": "/state-conductor-state-machine/", + "kind": "uri" +} diff --git a/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-developer.json b/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-developer.json index beefc65c..9e72ec2a 100644 --- a/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-developer.json +++ b/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-developer.json @@ -1,18 +1,14 @@ { "role-name": "state-conductor-developer", "description": "Permits developing and operating Marklogic State onductor", - "role": [ - "state-conductor-execute-role", - "rest-reader", - "rest-extension-user" - ], + "role": ["state-conductor-execute-role", "rest-reader", "rest-extension-user"], "privilege": [ { "privilege-name": "any-uri", "action": "http://marklogic.com/xdmp/privileges/any-uri", "kind": "execute" }, - { + { "privilege-name": "xdmp:eval", "action": "http://marklogic.com/xdmp/privileges/xdmp-eval", "kind": "execute" diff --git a/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-execute-role.json b/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-execute-role.json index 7e2b6673..d8a7a0ec 100644 --- a/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-execute-role.json +++ b/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-execute-role.json @@ -1,9 +1,7 @@ { "role-name": "state-conductor-execute-role", "description": "Permits reading stateMachine documents and knowing stateMachine status", - "role": [ - "state-conductor-execution-writer-role" - ], + "role": ["state-conductor-execution-writer-role"], "privilege": [ { "privilege-name": "state-conductor-state-machine", diff --git a/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-execution-writer-role.json b/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-execution-writer-role.json index 376ad2e1..b15a3305 100644 --- a/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-execution-writer-role.json +++ b/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-execution-writer-role.json @@ -1,9 +1,7 @@ { "role-name": "state-conductor-execution-writer-role", "description": "Permits reading stateMachine documents and knowing stateMachine status", - "role": [ - "state-conductor-reader-role" - ], + "role": ["state-conductor-reader-role"], "privilege": [ { "privilege-name": "state-conductor-execute", @@ -17,4 +15,3 @@ } ] } - diff --git a/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-operator.json b/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-operator.json index ae0d3226..3f370f67 100644 --- a/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-operator.json +++ b/state-conductor-modules/src/main/ml-config/security/roles/state-conductor-operator.json @@ -1,11 +1,7 @@ { "role-name": "state-conductor-operator", "description": "Permits operating a state conductor, such as running stateMachines and viewing execution data.", - "role": [ - "rest-extension-user", - "rest-reader", - "state-conductor-execution-writer-role" - ], + "role": ["rest-extension-user", "rest-reader", "state-conductor-execution-writer-role"], "privilege": [ { "privilege-name": "any-uri", From 87b578addc937bd16f4698046c9092569572fc74 Mon Sep 17 00:00:00 2001 From: Tyler Replogle Date: Thu, 8 Oct 2020 11:12:31 -0400 Subject: [PATCH 12/35] got the build working with an query that can be ran on qc. --- .../main/entity-config/exp-final-entity-options.xml | 10 ++++++++++ .../entity-config/exp-staging-entity-options.xml | 10 ++++++++++ .../privileges/state-conductor-state-machine.json | 5 ----- ...veloper.json => 1-state-conductor-developer.json} | 2 +- .../roles/2-state-conductor-reader-role.json | 4 ++++ ... => 3-state-conductor-execution-writer-role.json} | 5 ----- ...operator.json => 4-state-conductor-operator.json} | 0 .../security/roles/state-conductor-execute-role.json | 12 ------------ .../security/roles/state-conductor-reader-role.json | 4 ---- 9 files changed, 25 insertions(+), 27 deletions(-) delete mode 100644 state-conductor-modules/src/main/ml-config/security/privileges/state-conductor-state-machine.json rename state-conductor-modules/src/main/ml-config/security/roles/{state-conductor-developer.json => 1-state-conductor-developer.json} (90%) create mode 100644 state-conductor-modules/src/main/ml-config/security/roles/2-state-conductor-reader-role.json rename state-conductor-modules/src/main/ml-config/security/roles/{state-conductor-execution-writer-role.json => 3-state-conductor-execution-writer-role.json} (75%) rename state-conductor-modules/src/main/ml-config/security/roles/{state-conductor-operator.json => 4-state-conductor-operator.json} (100%) delete mode 100644 state-conductor-modules/src/main/ml-config/security/roles/state-conductor-execute-role.json delete mode 100644 state-conductor-modules/src/main/ml-config/security/roles/state-conductor-reader-role.json diff --git a/state-conductor-dhf5-example/src/main/entity-config/exp-final-entity-options.xml b/state-conductor-dhf5-example/src/main/entity-config/exp-final-entity-options.xml index fd8d7e54..ba396b05 100644 --- a/state-conductor-dhf5-example/src/main/entity-config/exp-final-entity-options.xml +++ b/state-conductor-dhf5-example/src/main/entity-config/exp-final-entity-options.xml @@ -43,6 +43,16 @@ + + + Person + + + + + + +