@wmfs/tymly-schedule-plugin 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.version +1 -1
- package/CHANGELOG.md +26 -0
- package/lib/blueprints/schedule-blueprint/card-templates/create-scheduled-task.json +97 -0
- package/lib/blueprints/schedule-blueprint/card-templates/view-all-scheduled-tasks.json +36 -0
- package/lib/blueprints/schedule-blueprint/card-templates/view-scheduled-task.json +148 -0
- package/lib/blueprints/schedule-blueprint/categories/schedule.json +8 -0
- package/lib/blueprints/schedule-blueprint/functions/generate-key.js +16 -0
- package/lib/blueprints/schedule-blueprint/functions/get-available-state-machines.js +18 -0
- package/lib/blueprints/schedule-blueprint/models/task.json +0 -14
- package/lib/blueprints/schedule-blueprint/state-machines/create-scheduled-task.json +66 -0
- package/lib/blueprints/schedule-blueprint/state-machines/modify-scheduled-task.json +74 -0
- package/lib/blueprints/schedule-blueprint/state-machines/start-task.json +36 -0
- package/lib/blueprints/schedule-blueprint/state-machines/stop-task.json +36 -0
- package/lib/blueprints/schedule-blueprint/state-machines/view-all-scheduled-tasks.json +69 -0
- package/lib/blueprints/schedule-blueprint/state-machines/view-scheduled-task.json +46 -0
- package/lib/blueprints/schedule-blueprint/template-roles/schedule-admin.json +4 -0
- package/lib/components/services/schedule/index.js +77 -23
- package/lib/components/state-resources/create-scheduled-task/doc/example.json +8 -0
- package/lib/components/state-resources/create-scheduled-task/doc/index.js +4 -0
- package/lib/components/state-resources/create-scheduled-task/index.js +56 -0
- package/lib/components/state-resources/find-scheduled-executions/doc/example.json +8 -0
- package/lib/components/state-resources/find-scheduled-executions/doc/index.js +4 -0
- package/lib/components/state-resources/find-scheduled-executions/index.js +12 -0
- package/lib/components/state-resources/start-scheduled-task/doc/example.json +8 -0
- package/lib/components/state-resources/start-scheduled-task/doc/index.js +4 -0
- package/lib/components/state-resources/start-scheduled-task/index.js +12 -0
- package/lib/components/state-resources/stop-scheduled-task/doc/example.json +8 -0
- package/lib/components/state-resources/stop-scheduled-task/doc/index.js +4 -0
- package/lib/components/state-resources/stop-scheduled-task/index.js +12 -0
- package/lib/components/state-resources/update-scheduled-state-machine-config/doc/example.json +12 -0
- package/lib/components/state-resources/update-scheduled-state-machine-config/doc/index.js +4 -0
- package/lib/components/state-resources/update-scheduled-state-machine-config/index.js +35 -0
- package/lib/components/state-resources/update-scheduled-task/doc/example.json +13 -0
- package/lib/components/state-resources/update-scheduled-task/doc/index.js +4 -0
- package/lib/components/state-resources/update-scheduled-task/index.js +26 -0
- package/package.json +2 -1
- package/plugin.json +1 -1
- package/test/schedule-tests.js +17 -14
package/.version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
VERSION=1.0
|
|
1
|
+
VERSION=1.1.0
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
# [1.1.0](https://github.com/wmfs/tymly-schedule-plugin/compare/v1.0.1...v1.1.0) (2022-03-16)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### ✨ Features
|
|
5
|
+
|
|
6
|
+
* ability to create/modify tasks from ui ([b7d56c5](https://github.com/wmfs/tymly-schedule-plugin/commit/b7d56c5e44609d4b2b14dbdc4e13a6c91f784eee))
|
|
7
|
+
* admin tools to create scheduled task ([b0e6ddc](https://github.com/wmfs/tymly-schedule-plugin/commit/b0e6ddc5325ace6332516275893471b39703c1ba))
|
|
8
|
+
* admin tools to start/stop tasks ([106f5fa](https://github.com/wmfs/tymly-schedule-plugin/commit/106f5fa7daedca13030b49fac473a891c5c6d9e1))
|
|
9
|
+
* admin tools to update schedule of state machine ([c6df466](https://github.com/wmfs/tymly-schedule-plugin/commit/c6df4669823e002916d4b86a0458e4e1d57ab45d))
|
|
10
|
+
* admin tools to update state machine config ([e26928a](https://github.com/wmfs/tymly-schedule-plugin/commit/e26928a276c1783fb92785eb2355570dd01f32ac))
|
|
11
|
+
* admin tools to view all and view specific tasks ([b9f80c8](https://github.com/wmfs/tymly-schedule-plugin/commit/b9f80c89077115ae2c783c0b03e8de322111319f))
|
|
12
|
+
* admin tools to view scheduled executions ([89b9094](https://github.com/wmfs/tymly-schedule-plugin/commit/89b90941de1b48a14896043ec3710df2c2440949))
|
|
13
|
+
* remove last ran start/end and total run count, as these can be found from executions ([d6c673b](https://github.com/wmfs/tymly-schedule-plugin/commit/d6c673b926654c564d08f6de1b5f22bcf61b3783))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### 🐛 Bug Fixes
|
|
17
|
+
|
|
18
|
+
* issue with finding scheduled executions ([b198bd1](https://github.com/wmfs/tymly-schedule-plugin/commit/b198bd1bf49ffb517229309eadaf7fdaed9f1ff7))
|
|
19
|
+
* use function from service to get executions ([b9082bc](https://github.com/wmfs/tymly-schedule-plugin/commit/b9082bc49ccdbd39c1316c786f83efddd7396a7d))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### 🚨 Tests
|
|
23
|
+
|
|
24
|
+
* fix status after re-boot with datetime schedule in past ([e4e9cba](https://github.com/wmfs/tymly-schedule-plugin/commit/e4e9cba84fbdaf91838e880b7dacda4659e60119))
|
|
25
|
+
* remove unused executions model ([92e888d](https://github.com/wmfs/tymly-schedule-plugin/commit/92e888d266803dac531a27f0c8d74ff6d6b22e52))
|
|
26
|
+
|
|
1
27
|
## [1.0.1](https://github.com/wmfs/tymly-schedule-plugin/compare/v1.0.0...v1.0.1) (2022-03-15)
|
|
2
28
|
|
|
3
29
|
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
{
|
|
2
|
+
"templateMeta": {
|
|
3
|
+
"name": "create-scheduled-task",
|
|
4
|
+
"title": "Configure a Scheduled State Machine",
|
|
5
|
+
"category": "schedule"
|
|
6
|
+
},
|
|
7
|
+
"hooks": {
|
|
8
|
+
"afterSubmit": {
|
|
9
|
+
"actions": [
|
|
10
|
+
{
|
|
11
|
+
"type": "Action.PushCard",
|
|
12
|
+
"stateMachineName": "schedule_viewScheduledTask_1_0",
|
|
13
|
+
"input": {
|
|
14
|
+
"key": "$.key"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"type": "AdaptiveCard",
|
|
21
|
+
"body": [
|
|
22
|
+
{
|
|
23
|
+
"showWhen": "data.editing !== true",
|
|
24
|
+
"id": "name",
|
|
25
|
+
"type": "Input.Text",
|
|
26
|
+
"title": "Schedule name",
|
|
27
|
+
"validation": {
|
|
28
|
+
"requiredIf": "data.editing !== true"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": "scheduleType",
|
|
33
|
+
"type": "Input.ChoiceSet",
|
|
34
|
+
"title": "What type of schedule?",
|
|
35
|
+
"choices": [
|
|
36
|
+
{
|
|
37
|
+
"title": "Interval",
|
|
38
|
+
"value": "interval"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"title": "Date/time",
|
|
42
|
+
"value": "datetime"
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"validation": {
|
|
46
|
+
"required": true
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"showWhen": "data.scheduleType === 'interval'",
|
|
51
|
+
"id": "interval",
|
|
52
|
+
"type": "Input.Text",
|
|
53
|
+
"title": "Interval",
|
|
54
|
+
"validation": {
|
|
55
|
+
"requiredIf": "data.scheduleType === 'interval'"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"showWhen": "data.scheduleType === 'datetime'",
|
|
60
|
+
"id": "datetime",
|
|
61
|
+
"type": "Input.DateTime",
|
|
62
|
+
"title": "Date/time",
|
|
63
|
+
"validation": {
|
|
64
|
+
"requiredIf": "data.scheduleType === 'datetime'"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"id": "stateMachineName",
|
|
69
|
+
"type": "Input.ChoiceSet",
|
|
70
|
+
"title": "Which state machine?",
|
|
71
|
+
"filter": true,
|
|
72
|
+
"choicesPath": "data.availableStateMachines",
|
|
73
|
+
"validation": {
|
|
74
|
+
"required": true
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"id": "inputStr",
|
|
79
|
+
"type": "Input.Text",
|
|
80
|
+
"title": "Input",
|
|
81
|
+
"isMultiline": true,
|
|
82
|
+
"value": "{}"
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
"actions": [
|
|
86
|
+
{
|
|
87
|
+
"type": "Action.Cancel",
|
|
88
|
+
"title": "Cancel"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"type": "Action.Submit",
|
|
92
|
+
"title": "Submit"
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
|
|
96
|
+
"version": "1.0"
|
|
97
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"templateMeta": {
|
|
3
|
+
"name": "view-scheduled-tasks",
|
|
4
|
+
"title": "View Scheduled State Machines",
|
|
5
|
+
"category": "schedule"
|
|
6
|
+
},
|
|
7
|
+
"type": "AdaptiveCard",
|
|
8
|
+
"body": [
|
|
9
|
+
{
|
|
10
|
+
"type": "MarkupTable",
|
|
11
|
+
"title": "Scheduled State Machines",
|
|
12
|
+
"arrayPath": "data.tasks",
|
|
13
|
+
"clickToLaunch": true,
|
|
14
|
+
"columns": [
|
|
15
|
+
{
|
|
16
|
+
"title": "Key",
|
|
17
|
+
"value": "{{ item.key }}"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"title": "Schedule",
|
|
21
|
+
"value": "{{ item.scheduleType === 'datetime' ? item.datetime : item.interval }}"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"title": "State machine name",
|
|
25
|
+
"value": "{{ item.stateMachineName }}"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"title": "Status",
|
|
29
|
+
"value": "{{ item.status }}"
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
|
|
35
|
+
"version": "1.0"
|
|
36
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
{
|
|
2
|
+
"templateMeta": {
|
|
3
|
+
"name": "view-scheduled-task",
|
|
4
|
+
"title": "View Scheduled State Machine",
|
|
5
|
+
"category": "schedule"
|
|
6
|
+
},
|
|
7
|
+
"type": "AdaptiveCard",
|
|
8
|
+
"body": [
|
|
9
|
+
{
|
|
10
|
+
"type": "Container",
|
|
11
|
+
"color": "accent",
|
|
12
|
+
"spacing": "none",
|
|
13
|
+
"items": [
|
|
14
|
+
{
|
|
15
|
+
"type": "TextBlock",
|
|
16
|
+
"text": "{{ data.key }}",
|
|
17
|
+
"weight": "bolder",
|
|
18
|
+
"spacing": "none"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"type": "ColumnSet",
|
|
24
|
+
"columns": [
|
|
25
|
+
{
|
|
26
|
+
"type": "Column",
|
|
27
|
+
"width": 8,
|
|
28
|
+
"items": [
|
|
29
|
+
{
|
|
30
|
+
"type": "FactSet",
|
|
31
|
+
"showAllIfUndefined": true,
|
|
32
|
+
"facts": [
|
|
33
|
+
{
|
|
34
|
+
"title": "Key",
|
|
35
|
+
"value": "{{ data.key }}"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"title": "Schedule",
|
|
39
|
+
"value": "{{ data.scheduleType === 'datetime' ? data.datetime : data.interval }}"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"title": "State machine name",
|
|
43
|
+
"value": "{{ data.stateMachineName }}"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"title": "Input",
|
|
47
|
+
"value": "{{ JSON.stringify(data.input) }}"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"title": "Send response",
|
|
51
|
+
"value": "{{ data.sendResponse }}"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"title": "Start on boot?",
|
|
55
|
+
"value": "{{ data.startOnBoot ? 'Yes' : 'No' }}"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"title": "Status",
|
|
59
|
+
"value": "{{ data.status }}"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"title": "Created",
|
|
63
|
+
"value": "{{ formatDate(data.created, 'DD/MM/YYYY HH:mm') }}"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"title": "Created by",
|
|
67
|
+
"value": "{{ data.createdBy || '-' }}"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"title": "Modified",
|
|
71
|
+
"value": "{{ formatDate(data.modified, 'DD/MM/YYYY HH:mm') }}"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"title": "Modified by",
|
|
75
|
+
"value": "{{ data.modifiedBy || '-' }}"
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"type": "Column",
|
|
83
|
+
"width": 4,
|
|
84
|
+
"items": [
|
|
85
|
+
{
|
|
86
|
+
"type": "ActionSet",
|
|
87
|
+
"actions": [
|
|
88
|
+
{
|
|
89
|
+
"showWhen": "data.status === 'STARTED'",
|
|
90
|
+
"type": "Action.PushCard",
|
|
91
|
+
"title": "Stop task",
|
|
92
|
+
"stateMachineName": "schedule_stopTask_1_0",
|
|
93
|
+
"input": {
|
|
94
|
+
"key": "$.key"
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"showWhen": "data.status !== 'STARTED'",
|
|
99
|
+
"type": "Action.PushCard",
|
|
100
|
+
"title": "Start task",
|
|
101
|
+
"stateMachineName": "schedule_startTask_1_0",
|
|
102
|
+
"input": {
|
|
103
|
+
"key": "$.key"
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"type": "Action.PushCard",
|
|
108
|
+
"title": "Modify schedule",
|
|
109
|
+
"stateMachineName": "schedule_modifyScheduledTask_1_0",
|
|
110
|
+
"input": {
|
|
111
|
+
"key": "$.key"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"title": "State machine executions",
|
|
122
|
+
"type": "Table",
|
|
123
|
+
"arrayPath": "data.executions",
|
|
124
|
+
"columns": [
|
|
125
|
+
{
|
|
126
|
+
"title": "Execution name",
|
|
127
|
+
"field": "executionName"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"title": "Status",
|
|
131
|
+
"field": "status"
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"title": "Created",
|
|
135
|
+
"field": "created",
|
|
136
|
+
"format": "formatDate(val, 'DD/MM/YYYY HH:mm')"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"title": "Modified",
|
|
140
|
+
"field": "modified",
|
|
141
|
+
"format": "formatDate(val, 'DD/MM/YYYY HH:mm')"
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
],
|
|
146
|
+
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
|
|
147
|
+
"version": "1.0"
|
|
148
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const capitalise = str => str.charAt(0).toUpperCase() + str.slice(1)
|
|
2
|
+
const schema = 'schedule'
|
|
3
|
+
|
|
4
|
+
module.exports = function () {
|
|
5
|
+
return function (event, env) {
|
|
6
|
+
const now = env.bootedServices.timestamp.now()
|
|
7
|
+
|
|
8
|
+
const key = [
|
|
9
|
+
schema,
|
|
10
|
+
event.trim().split(' ').map((n, i) => i === 0 ? n : capitalise(n)).join(''),
|
|
11
|
+
now.format('YYYYMMDD-HHmm')
|
|
12
|
+
].join('_')
|
|
13
|
+
|
|
14
|
+
return { key }
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module.exports = function () {
|
|
2
|
+
return async function getAvailableStateMachines (event, env) {
|
|
3
|
+
const availableStateMachines = env.bootedServices.statebox
|
|
4
|
+
.listStateMachines()
|
|
5
|
+
.map(({ name }) => {
|
|
6
|
+
return {
|
|
7
|
+
title: name,
|
|
8
|
+
value: name
|
|
9
|
+
}
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
availableStateMachines,
|
|
14
|
+
availableStateMachinesOrig: availableStateMachines,
|
|
15
|
+
availableStateMachinesFilt: availableStateMachines
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -35,20 +35,6 @@
|
|
|
35
35
|
"startOnBoot": {
|
|
36
36
|
"type": "boolean"
|
|
37
37
|
},
|
|
38
|
-
"lastRanStart": {
|
|
39
|
-
"type": "string",
|
|
40
|
-
"format": "date-time"
|
|
41
|
-
},
|
|
42
|
-
"lastRanEnd": {
|
|
43
|
-
"type": "string",
|
|
44
|
-
"format": "date-time"
|
|
45
|
-
},
|
|
46
|
-
"lastRanExecutionName": {
|
|
47
|
-
"type": "string"
|
|
48
|
-
},
|
|
49
|
-
"totalRunCount": {
|
|
50
|
-
"type": "integer"
|
|
51
|
-
},
|
|
52
38
|
"status": {
|
|
53
39
|
"type": "string"
|
|
54
40
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Comment": "Set up a Scheduled State Machine",
|
|
3
|
+
"name": "Set up a Scheduled State Machine",
|
|
4
|
+
"version": "1.0",
|
|
5
|
+
"categories": [
|
|
6
|
+
"schedule"
|
|
7
|
+
],
|
|
8
|
+
"instigators": [
|
|
9
|
+
"user"
|
|
10
|
+
],
|
|
11
|
+
"instigatorGroup": "form",
|
|
12
|
+
"StartAt": "GetStateMachines",
|
|
13
|
+
"States": {
|
|
14
|
+
"GetStateMachines": {
|
|
15
|
+
"Type": "Task",
|
|
16
|
+
"Resource": "function:schedule_getAvailableStateMachines",
|
|
17
|
+
"ResultPath": "$",
|
|
18
|
+
"Next": "DefaultInput"
|
|
19
|
+
},
|
|
20
|
+
"DefaultInput": {
|
|
21
|
+
"Type": "Pass",
|
|
22
|
+
"ResultSelector": {
|
|
23
|
+
"inputStr": "{}"
|
|
24
|
+
},
|
|
25
|
+
"Next": "View"
|
|
26
|
+
},
|
|
27
|
+
"View": {
|
|
28
|
+
"Type": "Task",
|
|
29
|
+
"Resource": "module:awaitingHumanInput",
|
|
30
|
+
"ResourceConfig": {
|
|
31
|
+
"uiType": "app",
|
|
32
|
+
"uiName": "schedule_createScheduledTask",
|
|
33
|
+
"dataPath": "$"
|
|
34
|
+
},
|
|
35
|
+
"Next": "GenerateKey"
|
|
36
|
+
},
|
|
37
|
+
"GenerateKey": {
|
|
38
|
+
"Type": "Task",
|
|
39
|
+
"InputPath": "$.name",
|
|
40
|
+
"Resource": "function:schedule_generateKey",
|
|
41
|
+
"ResultPath": "$",
|
|
42
|
+
"Next": "CreateScheduledTask"
|
|
43
|
+
},
|
|
44
|
+
"CreateScheduledTask": {
|
|
45
|
+
"Type": "Task",
|
|
46
|
+
"Parameters": {
|
|
47
|
+
"key.$": "$.key",
|
|
48
|
+
"scheduleType.$": "$.scheduleType",
|
|
49
|
+
"datetime.$": "$.datetime",
|
|
50
|
+
"interval.$": "$.interval",
|
|
51
|
+
"stateMachineName.$": "$.stateMachineName",
|
|
52
|
+
"input.$": "$.inputStr"
|
|
53
|
+
},
|
|
54
|
+
"Resource": "module:createScheduledTask",
|
|
55
|
+
"End": true
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"restrictions": [
|
|
59
|
+
{
|
|
60
|
+
"roleId": "schedule_scheduleAdmin",
|
|
61
|
+
"allows": [
|
|
62
|
+
"*"
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Comment": "Modify a Scheduled State Machine",
|
|
3
|
+
"name": "Modify a Scheduled State Machine",
|
|
4
|
+
"version": "1.0",
|
|
5
|
+
"categories": [
|
|
6
|
+
"schedule"
|
|
7
|
+
],
|
|
8
|
+
"StartAt": "SetAsEditing",
|
|
9
|
+
"States": {
|
|
10
|
+
"SetAsEditing": {
|
|
11
|
+
"Type": "Pass",
|
|
12
|
+
"Result": {
|
|
13
|
+
"editing": true
|
|
14
|
+
},
|
|
15
|
+
"ResultPath": "$",
|
|
16
|
+
"Next": "FindTask"
|
|
17
|
+
},
|
|
18
|
+
"FindTask": {
|
|
19
|
+
"Type": "Task",
|
|
20
|
+
"InputPath": "$.key",
|
|
21
|
+
"Resource": "module:findingById",
|
|
22
|
+
"ResourceConfig": {
|
|
23
|
+
"modelId": "schedule_task"
|
|
24
|
+
},
|
|
25
|
+
"ResultPath": "$",
|
|
26
|
+
"Next": "GetStateMachines"
|
|
27
|
+
},
|
|
28
|
+
"GetStateMachines": {
|
|
29
|
+
"Type": "Task",
|
|
30
|
+
"Resource": "function:schedule_getAvailableStateMachines",
|
|
31
|
+
"ResultPath": "$",
|
|
32
|
+
"Next": "View"
|
|
33
|
+
},
|
|
34
|
+
"View": {
|
|
35
|
+
"Type": "Task",
|
|
36
|
+
"Resource": "module:awaitingHumanInput",
|
|
37
|
+
"ResourceConfig": {
|
|
38
|
+
"uiType": "app",
|
|
39
|
+
"uiName": "schedule_createScheduledTask",
|
|
40
|
+
"dataPath": "$"
|
|
41
|
+
},
|
|
42
|
+
"Next": "UpdateScheduledTask"
|
|
43
|
+
},
|
|
44
|
+
"UpdateScheduledTask": {
|
|
45
|
+
"Type": "Task",
|
|
46
|
+
"Parameters": {
|
|
47
|
+
"key.$": "$.key",
|
|
48
|
+
"scheduleType.$": "$.scheduleType",
|
|
49
|
+
"datetime.$": "$.datetime",
|
|
50
|
+
"interval.$": "$.interval"
|
|
51
|
+
},
|
|
52
|
+
"Resource": "module:updateScheduledTask",
|
|
53
|
+
"Next": "UpdateScheduledStateMachineConfig"
|
|
54
|
+
},
|
|
55
|
+
"UpdateScheduledStateMachineConfig": {
|
|
56
|
+
"Type": "Task",
|
|
57
|
+
"Parameters": {
|
|
58
|
+
"key.$": "$.key",
|
|
59
|
+
"stateMachineName.$": "$.stateMachineName",
|
|
60
|
+
"input.$": "$.inputStr"
|
|
61
|
+
},
|
|
62
|
+
"Resource": "module:updateScheduledStateMachineConfig",
|
|
63
|
+
"End": true
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"restrictions": [
|
|
67
|
+
{
|
|
68
|
+
"roleId": "schedule_scheduleAdmin",
|
|
69
|
+
"allows": [
|
|
70
|
+
"*"
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Comment": "Start Scheduled State Machine",
|
|
3
|
+
"name": "Start Scheduled State Machine",
|
|
4
|
+
"version": "1.0",
|
|
5
|
+
"categories": [
|
|
6
|
+
"schedule"
|
|
7
|
+
],
|
|
8
|
+
"StartAt": "StartScheduledTask",
|
|
9
|
+
"States": {
|
|
10
|
+
"StartScheduledTask": {
|
|
11
|
+
"Type": "Task",
|
|
12
|
+
"InputPath": "$.key",
|
|
13
|
+
"Resource": "module:startScheduledTask",
|
|
14
|
+
"Next": "View"
|
|
15
|
+
},
|
|
16
|
+
"View": {
|
|
17
|
+
"Type": "Task",
|
|
18
|
+
"Parameters": {
|
|
19
|
+
"key.$": "$.key"
|
|
20
|
+
},
|
|
21
|
+
"Resource": "module:runStateMachine",
|
|
22
|
+
"ResourceConfig": {
|
|
23
|
+
"stateMachine": "schedule_viewScheduledTask_1_0"
|
|
24
|
+
},
|
|
25
|
+
"End": true
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"restrictions": [
|
|
29
|
+
{
|
|
30
|
+
"roleId": "schedule_scheduleAdmin",
|
|
31
|
+
"allows": [
|
|
32
|
+
"*"
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Comment": "Stop Scheduled State Machine",
|
|
3
|
+
"name": "Stop Scheduled State Machine",
|
|
4
|
+
"version": "1.0",
|
|
5
|
+
"categories": [
|
|
6
|
+
"schedule"
|
|
7
|
+
],
|
|
8
|
+
"StartAt": "StopScheduledTask",
|
|
9
|
+
"States": {
|
|
10
|
+
"StopScheduledTask": {
|
|
11
|
+
"Type": "Task",
|
|
12
|
+
"InputPath": "$.key",
|
|
13
|
+
"Resource": "module:stopScheduledTask",
|
|
14
|
+
"Next": "View"
|
|
15
|
+
},
|
|
16
|
+
"View": {
|
|
17
|
+
"Type": "Task",
|
|
18
|
+
"Parameters": {
|
|
19
|
+
"key.$": "$.key"
|
|
20
|
+
},
|
|
21
|
+
"Resource": "module:runStateMachine",
|
|
22
|
+
"ResourceConfig": {
|
|
23
|
+
"stateMachine": "schedule_viewScheduledTask_1_0"
|
|
24
|
+
},
|
|
25
|
+
"End": true
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"restrictions": [
|
|
29
|
+
{
|
|
30
|
+
"roleId": "schedule_scheduleAdmin",
|
|
31
|
+
"allows": [
|
|
32
|
+
"*"
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Comment": "View Scheduled State Machines",
|
|
3
|
+
"name": "View Scheduled State Machines",
|
|
4
|
+
"version": "1.0",
|
|
5
|
+
"categories": [
|
|
6
|
+
"schedule"
|
|
7
|
+
],
|
|
8
|
+
"instigators": [
|
|
9
|
+
"user"
|
|
10
|
+
],
|
|
11
|
+
"instigatorGroup": "app",
|
|
12
|
+
"StartAt": "FindTasks",
|
|
13
|
+
"States": {
|
|
14
|
+
"FindTasks": {
|
|
15
|
+
"Type": "Task",
|
|
16
|
+
"Resource": "module:finding",
|
|
17
|
+
"ResourceConfig": {
|
|
18
|
+
"modelId": "schedule_task"
|
|
19
|
+
},
|
|
20
|
+
"ResultPath": "$.tasks",
|
|
21
|
+
"Next": "AddTaskLaunches"
|
|
22
|
+
},
|
|
23
|
+
"AddTaskLaunches": {
|
|
24
|
+
"Type": "Map",
|
|
25
|
+
"ItemsPath": "$.tasks",
|
|
26
|
+
"Iterator": {
|
|
27
|
+
"StartAt": "AddLaunches",
|
|
28
|
+
"States": {
|
|
29
|
+
"AddLaunches": {
|
|
30
|
+
"Type": "Pass",
|
|
31
|
+
"Parameters": {
|
|
32
|
+
"launches": [
|
|
33
|
+
{
|
|
34
|
+
"title": "View",
|
|
35
|
+
"stateMachineName": "schedule_viewScheduledTask",
|
|
36
|
+
"input": {
|
|
37
|
+
"key.$": "$.key"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
"ResultPath": "$",
|
|
43
|
+
"End": true
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"ResultPath": "$.tasks",
|
|
48
|
+
"Next": "View"
|
|
49
|
+
},
|
|
50
|
+
"View": {
|
|
51
|
+
"Type": "Task",
|
|
52
|
+
"Resource": "module:awaitingHumanInput",
|
|
53
|
+
"ResourceConfig": {
|
|
54
|
+
"uiType": "app",
|
|
55
|
+
"uiName": "schedule_viewAllScheduledTasks",
|
|
56
|
+
"dataPath": "$"
|
|
57
|
+
},
|
|
58
|
+
"End": true
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"restrictions": [
|
|
62
|
+
{
|
|
63
|
+
"roleId": "schedule_scheduleAdmin",
|
|
64
|
+
"allows": [
|
|
65
|
+
"*"
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Comment": "View Scheduled State Machine",
|
|
3
|
+
"name": "View Scheduled State Machine",
|
|
4
|
+
"version": "1.0",
|
|
5
|
+
"categories": [
|
|
6
|
+
"schedule"
|
|
7
|
+
],
|
|
8
|
+
"StartAt": "FindTask",
|
|
9
|
+
"States": {
|
|
10
|
+
"FindTask": {
|
|
11
|
+
"Type": "Task",
|
|
12
|
+
"InputPath": "$.key",
|
|
13
|
+
"Resource": "module:findingById",
|
|
14
|
+
"ResourceConfig": {
|
|
15
|
+
"modelId": "schedule_task"
|
|
16
|
+
},
|
|
17
|
+
"ResultPath": "$",
|
|
18
|
+
"Next": "FindExecutions"
|
|
19
|
+
},
|
|
20
|
+
"FindExecutions": {
|
|
21
|
+
"Type": "Task",
|
|
22
|
+
"InputPath": "$.key",
|
|
23
|
+
"Resource": "module:findScheduledExecutions",
|
|
24
|
+
"ResultPath": "$.executions",
|
|
25
|
+
"Next": "View"
|
|
26
|
+
},
|
|
27
|
+
"View": {
|
|
28
|
+
"Type": "Task",
|
|
29
|
+
"Resource": "module:awaitingHumanInput",
|
|
30
|
+
"ResourceConfig": {
|
|
31
|
+
"uiType": "app",
|
|
32
|
+
"uiName": "schedule_viewScheduledTask",
|
|
33
|
+
"dataPath": "$"
|
|
34
|
+
},
|
|
35
|
+
"End": true
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"restrictions": [
|
|
39
|
+
{
|
|
40
|
+
"roleId": "schedule_scheduleAdmin",
|
|
41
|
+
"allows": [
|
|
42
|
+
"*"
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const INSTIGATING_CLIENT_DOMAIN = 'tymly-schedule-plugin'
|
|
2
|
+
|
|
1
3
|
const nodeSchedule = require('node-schedule')
|
|
2
4
|
const ruleToDatetime = require('./utils/rule-to-datetime')
|
|
3
5
|
const datetimeToRule = require('./utils/datetime-to-rule')
|
|
@@ -6,6 +8,9 @@ class CronService {
|
|
|
6
8
|
async boot (options) {
|
|
7
9
|
this.statebox = options.bootedServices.statebox
|
|
8
10
|
this.taskModel = options.bootedServices.storage.models.schedule_task
|
|
11
|
+
this.executionModel = options.bootedServices.storage.models.tymly_execution
|
|
12
|
+
|
|
13
|
+
// todo: rename blueprint component to scheduled-tasks, blueprint component to have "type": "stateMachineName"
|
|
9
14
|
this.scheduledTasks = await this.findTasks(options.blueprintComponents.stateMachineSchedules)
|
|
10
15
|
|
|
11
16
|
for (const [key, task] of Object.entries(this.scheduledTasks)) {
|
|
@@ -54,11 +59,11 @@ class CronService {
|
|
|
54
59
|
jobOptions,
|
|
55
60
|
() => {
|
|
56
61
|
console.log(`Running scheduled state machine ${stateMachineName}`)
|
|
57
|
-
const startedAt = new Date()
|
|
58
62
|
const executionOptions = {
|
|
59
63
|
instigatingClient: {
|
|
60
64
|
appName: 'tymly',
|
|
61
|
-
domain:
|
|
65
|
+
domain: INSTIGATING_CLIENT_DOMAIN,
|
|
66
|
+
scheduleKey: key
|
|
62
67
|
},
|
|
63
68
|
sendResponse
|
|
64
69
|
}
|
|
@@ -66,7 +71,6 @@ class CronService {
|
|
|
66
71
|
if (err) {
|
|
67
72
|
console.log(`There was an error on execution of scheduled state machine ${stateMachineName}`)
|
|
68
73
|
}
|
|
69
|
-
await this.updateTaskOnExecution(key, executionDescription.executionName, startedAt)
|
|
70
74
|
}
|
|
71
75
|
this.statebox.startExecution(input, stateMachineName, executionOptions, cb)
|
|
72
76
|
}
|
|
@@ -74,7 +78,7 @@ class CronService {
|
|
|
74
78
|
|
|
75
79
|
this.scheduledTasks[key] = task
|
|
76
80
|
|
|
77
|
-
return this.updateTaskStatus(key, 'STARTED')
|
|
81
|
+
return this.updateTaskStatus(key, task.job === null ? 'STOPPED' : 'STARTED')
|
|
78
82
|
} // startTask
|
|
79
83
|
|
|
80
84
|
stopTask (key) {
|
|
@@ -105,7 +109,7 @@ class CronService {
|
|
|
105
109
|
setMissingPropertiesToNull: false
|
|
106
110
|
}
|
|
107
111
|
)
|
|
108
|
-
}
|
|
112
|
+
} // updateTaskStatus
|
|
109
113
|
|
|
110
114
|
stopTasks () {
|
|
111
115
|
return Promise.all(
|
|
@@ -129,6 +133,11 @@ class CronService {
|
|
|
129
133
|
continue
|
|
130
134
|
}
|
|
131
135
|
|
|
136
|
+
const stateMachineOk = this.checkIfStateMachineExists(config.stateMachineName)
|
|
137
|
+
if (!stateMachineOk) {
|
|
138
|
+
continue
|
|
139
|
+
}
|
|
140
|
+
|
|
132
141
|
// todo: recurrence rules?
|
|
133
142
|
|
|
134
143
|
if (typeof config.interval === 'string') {
|
|
@@ -140,6 +149,10 @@ class CronService {
|
|
|
140
149
|
config.interval = null
|
|
141
150
|
}
|
|
142
151
|
|
|
152
|
+
config.input = typeof config.input === 'object'
|
|
153
|
+
? config.input
|
|
154
|
+
: {}
|
|
155
|
+
|
|
143
156
|
tasks[key] = config
|
|
144
157
|
|
|
145
158
|
await this.persistTask(key, config)
|
|
@@ -158,35 +171,44 @@ class CronService {
|
|
|
158
171
|
interval: config.interval,
|
|
159
172
|
datetime: config.datetime,
|
|
160
173
|
startOnBoot: config.startOnBoot,
|
|
161
|
-
lastRanStart: null,
|
|
162
|
-
lastRanEnd: null,
|
|
163
|
-
lastRanExecutionName: null,
|
|
164
|
-
totalRunCount: 0,
|
|
165
174
|
status: null
|
|
166
175
|
})
|
|
167
|
-
}
|
|
176
|
+
} // persistTask
|
|
168
177
|
|
|
169
|
-
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
178
|
+
checkIfStateMachineExists (stateMachineName) {
|
|
179
|
+
const [stateMachineOk, errStateMachineDesc] = this.statebox.checkIfStateMachineExists(stateMachineName)
|
|
180
|
+
|
|
181
|
+
if (!stateMachineOk) {
|
|
182
|
+
console.log('State machine error', errStateMachineDesc)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return stateMachineOk
|
|
186
|
+
} // checkIfStateMachineExists
|
|
187
|
+
|
|
188
|
+
async stopAndUpdateStateMachineConfig (key, stateMachineName, input) {
|
|
189
|
+
await this.stopTask(key)
|
|
190
|
+
|
|
191
|
+
const stateMachineOk = this.checkIfStateMachineExists(stateMachineName)
|
|
192
|
+
if (!stateMachineOk) {
|
|
193
|
+
return
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
this.scheduledTasks[key].stateMachineName = stateMachineName
|
|
197
|
+
this.scheduledTasks[key].input = typeof input === 'object'
|
|
198
|
+
? input
|
|
199
|
+
: {}
|
|
176
200
|
|
|
177
201
|
return this.taskModel.update(
|
|
178
202
|
{
|
|
179
203
|
key,
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
lastRanExecutionName: executionName,
|
|
183
|
-
totalRunCount: totalRunCount + 1
|
|
204
|
+
stateMachineName: this.scheduledTasks[key].stateMachineName,
|
|
205
|
+
input: this.scheduledTasks[key].input
|
|
184
206
|
},
|
|
185
207
|
{
|
|
186
208
|
setMissingPropertiesToNull: false
|
|
187
209
|
}
|
|
188
210
|
)
|
|
189
|
-
}
|
|
211
|
+
} // stopAndUpdateStateMachineConfig
|
|
190
212
|
|
|
191
213
|
async stopAndUpdateTaskSchedule (key, rule) {
|
|
192
214
|
await this.stopTask(key)
|
|
@@ -212,7 +234,39 @@ class CronService {
|
|
|
212
234
|
setMissingPropertiesToNull: false
|
|
213
235
|
}
|
|
214
236
|
)
|
|
215
|
-
}
|
|
237
|
+
} // stopAndUpdateTaskSchedule
|
|
238
|
+
|
|
239
|
+
async findScheduledExecutions (key) {
|
|
240
|
+
const executions = await this.executionModel.find({
|
|
241
|
+
fields: [
|
|
242
|
+
'executionName',
|
|
243
|
+
'executionOptions',
|
|
244
|
+
'status',
|
|
245
|
+
'created',
|
|
246
|
+
'modified'
|
|
247
|
+
],
|
|
248
|
+
where: {
|
|
249
|
+
stateMachineName: {
|
|
250
|
+
equals: this.scheduledTasks[key].stateMachineName
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
orderBy: ['-modified']
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
return executions.filter(({ executionOptions }) => {
|
|
257
|
+
executionOptions = typeof executionOptions === 'string'
|
|
258
|
+
? JSON.parse(executionOptions)
|
|
259
|
+
: executionOptions
|
|
260
|
+
|
|
261
|
+
return executionOptions.instigatingClient.domain === INSTIGATING_CLIENT_DOMAIN &&
|
|
262
|
+
executionOptions.instigatingClient.scheduleKey === key
|
|
263
|
+
})
|
|
264
|
+
} // findScheduledExecutions
|
|
265
|
+
|
|
266
|
+
createScheduledTask (key, config = {}) {
|
|
267
|
+
this.scheduledTasks[key] = config
|
|
268
|
+
return this.persistTask(key, config)
|
|
269
|
+
} // createScheduledTask
|
|
216
270
|
|
|
217
271
|
async shutdown () {
|
|
218
272
|
await nodeSchedule.gracefulShutdown()
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// const datetimeToRule = require('../../services/schedule/utils/datetime-to-rule')
|
|
2
|
+
|
|
3
|
+
class CreateScheduledTask {
|
|
4
|
+
init (resourceConfig, env) {
|
|
5
|
+
this.services = env.bootedServices
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
async run (event, context) {
|
|
9
|
+
const {
|
|
10
|
+
key,
|
|
11
|
+
stateMachineName,
|
|
12
|
+
scheduleType,
|
|
13
|
+
datetime,
|
|
14
|
+
interval
|
|
15
|
+
} = event
|
|
16
|
+
|
|
17
|
+
const stateMachineOk = this.services.schedule.checkIfStateMachineExists(stateMachineName)
|
|
18
|
+
if (!stateMachineOk) {
|
|
19
|
+
return context.sendTaskSuccess()
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let input = typeof event.input === 'object'
|
|
23
|
+
? event.input
|
|
24
|
+
: {}
|
|
25
|
+
|
|
26
|
+
if (typeof event.input === 'string') {
|
|
27
|
+
try {
|
|
28
|
+
input = JSON.parse(event.input)
|
|
29
|
+
} catch (err) {
|
|
30
|
+
console.log('Issue with input', event.input)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// const rule = scheduleType === 'interval'
|
|
35
|
+
// ? interval
|
|
36
|
+
// : datetimeToRule(new Date(datetime))
|
|
37
|
+
|
|
38
|
+
const config = {
|
|
39
|
+
stateMachineName,
|
|
40
|
+
input,
|
|
41
|
+
sendResponse: 'COMPLETE',
|
|
42
|
+
scheduleType,
|
|
43
|
+
interval,
|
|
44
|
+
datetime,
|
|
45
|
+
startOnBoot: false // todo
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
await this.services.schedule.createScheduledTask(key, config)
|
|
49
|
+
// await this.services.schedule.stopAndUpdateTaskSchedule(key, rule)
|
|
50
|
+
// await this.services.schedule.stopAndUpdateStateMachineConfig(key, stateMachineName, input)
|
|
51
|
+
|
|
52
|
+
return context.sendTaskSuccess()
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = CreateScheduledTask
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
class FindScheduledExecutions {
|
|
2
|
+
init (resourceConfig, env) {
|
|
3
|
+
this.services = env.bootedServices
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
async run (key, context) {
|
|
7
|
+
const executions = await this.services.schedule.findScheduledExecutions(key)
|
|
8
|
+
return context.sendTaskSuccess(executions)
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
module.exports = FindScheduledExecutions
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
class StartScheduledTask {
|
|
2
|
+
init (resourceConfig, env) {
|
|
3
|
+
this.services = env.bootedServices
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
async run (key, context) {
|
|
7
|
+
await this.services.schedule.startTask(key)
|
|
8
|
+
return context.sendTaskSuccess()
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
module.exports = StartScheduledTask
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
class StopScheduledTask {
|
|
2
|
+
init (resourceConfig, env) {
|
|
3
|
+
this.services = env.bootedServices
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
async run (key, context) {
|
|
7
|
+
await this.services.schedule.stopTask(key)
|
|
8
|
+
return context.sendTaskSuccess()
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
module.exports = StopScheduledTask
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
class UpdateScheduledStateMachineConfig {
|
|
2
|
+
init (resourceConfig, env) {
|
|
3
|
+
this.services = env.bootedServices
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
async run (event, context) {
|
|
7
|
+
const {
|
|
8
|
+
key,
|
|
9
|
+
stateMachineName
|
|
10
|
+
} = event
|
|
11
|
+
|
|
12
|
+
const stateMachineOk = this.services.schedule.checkIfStateMachineExists(stateMachineName)
|
|
13
|
+
if (!stateMachineOk) {
|
|
14
|
+
return context.sendTaskSuccess()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let input = typeof event.input === 'object'
|
|
18
|
+
? event.input
|
|
19
|
+
: {}
|
|
20
|
+
|
|
21
|
+
if (typeof event.input === 'string') {
|
|
22
|
+
try {
|
|
23
|
+
input = JSON.parse(event.input)
|
|
24
|
+
} catch (err) {
|
|
25
|
+
console.log('Issue with input', event.input)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
await this.services.schedule.stopAndUpdateStateMachineConfig(key, stateMachineName, input)
|
|
30
|
+
|
|
31
|
+
return context.sendTaskSuccess()
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = UpdateScheduledStateMachineConfig
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"UpdateScheduledTask": {
|
|
3
|
+
"Type": "Task",
|
|
4
|
+
"Parameters": {
|
|
5
|
+
"key.$": "$.key",
|
|
6
|
+
"scheduleType.$": "$.scheduleType",
|
|
7
|
+
"datetime.$": "$.datetime",
|
|
8
|
+
"interval.$": "$.interval"
|
|
9
|
+
},
|
|
10
|
+
"Resource": "module:updateScheduledTask",
|
|
11
|
+
"End": true
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const datetimeToRule = require('../../services/schedule/utils/datetime-to-rule')
|
|
2
|
+
|
|
3
|
+
class UpdateScheduledTask {
|
|
4
|
+
init (resourceConfig, env) {
|
|
5
|
+
this.services = env.bootedServices
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
async run (event, context) {
|
|
9
|
+
const {
|
|
10
|
+
key,
|
|
11
|
+
scheduleType,
|
|
12
|
+
datetime,
|
|
13
|
+
interval
|
|
14
|
+
} = event
|
|
15
|
+
|
|
16
|
+
const rule = scheduleType === 'interval'
|
|
17
|
+
? interval
|
|
18
|
+
: datetimeToRule(new Date(datetime))
|
|
19
|
+
|
|
20
|
+
await this.services.schedule.stopAndUpdateTaskSchedule(key, rule)
|
|
21
|
+
|
|
22
|
+
return context.sendTaskSuccess()
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = UpdateScheduledTask
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wmfs/tymly-schedule-plugin",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Provides state machine scheduling for the Tymly framework",
|
|
5
5
|
"homepage": "https://github.com/wmfs/tymly-schedule-plugin#readme",
|
|
6
6
|
"author": "West Midlands Fire Service",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"@semantic-release/git": "10.0.1",
|
|
31
31
|
"@wmfs/tymly": "1.235.1",
|
|
32
32
|
"@wmfs/tymly-pg-plugin": "1.268.0",
|
|
33
|
+
"@wmfs/tymly-test-helpers": "1.16.0",
|
|
33
34
|
"chai": "4.3.6",
|
|
34
35
|
"codecov": "3.8.3",
|
|
35
36
|
"conventional-changelog-metahub": "4.0.1",
|
package/plugin.json
CHANGED
package/test/schedule-tests.js
CHANGED
|
@@ -18,9 +18,7 @@ describe('Tymly schedule tests', function () {
|
|
|
18
18
|
|
|
19
19
|
let tymlyService
|
|
20
20
|
let scheduleService
|
|
21
|
-
// let statebox
|
|
22
21
|
let catStatsModel
|
|
23
|
-
// let executionsModel
|
|
24
22
|
let taskModel
|
|
25
23
|
let client
|
|
26
24
|
|
|
@@ -34,17 +32,16 @@ describe('Tymly schedule tests', function () {
|
|
|
34
32
|
],
|
|
35
33
|
pluginPaths: [
|
|
36
34
|
path.resolve(__dirname, '..'),
|
|
37
|
-
require.resolve('@wmfs/tymly-pg-plugin')
|
|
35
|
+
require.resolve('@wmfs/tymly-pg-plugin'),
|
|
36
|
+
require.resolve('@wmfs/tymly-test-helpers/plugins/mock-users-plugin')
|
|
38
37
|
]
|
|
39
38
|
}
|
|
40
39
|
)
|
|
41
40
|
|
|
42
41
|
tymlyService = tymlyServices.tymly
|
|
43
42
|
scheduleService = tymlyServices.schedule
|
|
44
|
-
// statebox = tymlyServices.statebox
|
|
45
43
|
taskModel = tymlyServices.storage.models.schedule_task
|
|
46
44
|
catStatsModel = tymlyServices.storage.models.tymlyTest_catStats
|
|
47
|
-
// executionsModel = tymlyServices.storage.models.tymly_execution
|
|
48
45
|
client = tymlyServices.storage.client
|
|
49
46
|
|
|
50
47
|
const catStats = await catStatsModel.find({})
|
|
@@ -74,9 +71,8 @@ describe('Tymly schedule tests', function () {
|
|
|
74
71
|
expect(tasks[0].datetime).to.eql(null)
|
|
75
72
|
expect(tasks[0].status).to.eql('STOPPED')
|
|
76
73
|
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
lastRunCount = totalRunCount
|
|
74
|
+
const executions = await scheduleService.findScheduledExecutions(scheduleKey)
|
|
75
|
+
lastRunCount = executions.length
|
|
80
76
|
|
|
81
77
|
// Waited 10 seconds and runs every 2 seconds so can be 5 or 6
|
|
82
78
|
expect(lastRunCount).to.be.greaterThanOrEqual(5)
|
|
@@ -96,7 +92,8 @@ describe('Tymly schedule tests', function () {
|
|
|
96
92
|
expect(tasks[0].datetime).to.eql(null)
|
|
97
93
|
expect(tasks[0].status).to.eql('STOPPED')
|
|
98
94
|
|
|
99
|
-
|
|
95
|
+
const executions = await scheduleService.findScheduledExecutions(scheduleKey)
|
|
96
|
+
expect(executions.length).to.eql(lastRunCount)
|
|
100
97
|
|
|
101
98
|
const catStats = await catStatsModel.find({})
|
|
102
99
|
expect(catStats.length).to.eql(lastRunCount)
|
|
@@ -131,9 +128,11 @@ describe('Tymly schedule tests', function () {
|
|
|
131
128
|
expect(tasks[0].interval).to.eql(null)
|
|
132
129
|
expect(tasks[0].datetime).to.not.eql(null)
|
|
133
130
|
expect(tasks[0].scheduleType).to.eql('datetime')
|
|
134
|
-
expect(tasks[0].totalRunCount).to.eql(lastRunCount)
|
|
135
131
|
expect(tasks[0].status).to.eql('STARTED')
|
|
136
132
|
|
|
133
|
+
const executions = await scheduleService.findScheduledExecutions(scheduleKey)
|
|
134
|
+
expect(executions.length).to.eql(lastRunCount)
|
|
135
|
+
|
|
137
136
|
const catStats = await catStatsModel.find({})
|
|
138
137
|
expect(catStats.length).to.eql(lastRunCount)
|
|
139
138
|
})
|
|
@@ -145,7 +144,8 @@ describe('Tymly schedule tests', function () {
|
|
|
145
144
|
expect(tasks.length).to.eql(1)
|
|
146
145
|
expect(tasks[0].status).to.eql('STARTED')
|
|
147
146
|
|
|
148
|
-
|
|
147
|
+
const executions = await scheduleService.findScheduledExecutions(scheduleKey)
|
|
148
|
+
expect(executions.length).to.eql(lastRunCount)
|
|
149
149
|
|
|
150
150
|
const catStats = await catStatsModel.find({})
|
|
151
151
|
expect(catStats.length).to.eql(lastRunCount)
|
|
@@ -163,7 +163,8 @@ describe('Tymly schedule tests', function () {
|
|
|
163
163
|
],
|
|
164
164
|
pluginPaths: [
|
|
165
165
|
path.resolve(__dirname, '..'),
|
|
166
|
-
require.resolve('@wmfs/tymly-pg-plugin')
|
|
166
|
+
require.resolve('@wmfs/tymly-pg-plugin'),
|
|
167
|
+
require.resolve('@wmfs/tymly-test-helpers/plugins/mock-users-plugin')
|
|
167
168
|
]
|
|
168
169
|
}
|
|
169
170
|
)
|
|
@@ -182,8 +183,10 @@ describe('Tymly schedule tests', function () {
|
|
|
182
183
|
expect(tasks[0].stateMachineName).to.eql('tymlyTest_sendCatUpdate')
|
|
183
184
|
expect(tasks[0].scheduleType).to.eql('datetime')
|
|
184
185
|
expect(tasks[0].interval).to.eql(null)
|
|
185
|
-
expect(tasks[0].status).to.eql('
|
|
186
|
-
|
|
186
|
+
expect(tasks[0].status).to.eql('STOPPED')
|
|
187
|
+
|
|
188
|
+
const executions = await scheduleService.findScheduledExecutions(scheduleKey)
|
|
189
|
+
expect(executions.length).to.eql(lastRunCount)
|
|
187
190
|
})
|
|
188
191
|
|
|
189
192
|
it('clean up data', async () => {
|