@things-factory/integration-base 7.0.0-alpha.1 → 7.0.0-alpha.21
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/dist-server/controllers/index.js +5 -0
- package/dist-server/controllers/index.js.map +1 -0
- package/dist-server/controllers/scenario-controller.js +87 -0
- package/dist-server/controllers/scenario-controller.js.map +1 -0
- package/dist-server/engine/connection-manager.js +37 -6
- package/dist-server/engine/connection-manager.js.map +1 -1
- package/dist-server/engine/connector/graphql-connector.js +6 -6
- package/dist-server/engine/connector/graphql-connector.js.map +1 -1
- package/dist-server/engine/connector/operato-connector.js +19 -22
- package/dist-server/engine/connector/operato-connector.js.map +1 -1
- package/dist-server/engine/connector/oracle-connector.js +113 -17
- package/dist-server/engine/connector/oracle-connector.js.map +1 -1
- package/dist-server/engine/connector/proxy-connector.js +44 -0
- package/dist-server/engine/connector/proxy-connector.js.map +1 -0
- package/dist-server/engine/edge-client.js +38 -0
- package/dist-server/engine/edge-client.js.map +1 -0
- package/dist-server/engine/index.js +1 -0
- package/dist-server/engine/index.js.map +1 -1
- package/dist-server/engine/task/oracle-procedure.js +1 -15
- package/dist-server/engine/task/oracle-procedure.js.map +1 -1
- package/dist-server/engine/task/script.js +1 -0
- package/dist-server/engine/task/script.js.map +1 -1
- package/dist-server/engine/task/utils/headless-pool-for-scenario.js +1 -1
- package/dist-server/engine/task/utils/headless-pool-for-scenario.js.map +1 -1
- package/dist-server/engine/types.js.map +1 -1
- package/dist-server/index.js +1 -0
- package/dist-server/index.js.map +1 -1
- package/dist-server/restful/unstable/run-scenario.js.map +1 -1
- package/dist-server/restful/unstable/start-scenario.js +1 -1
- package/dist-server/restful/unstable/start-scenario.js.map +1 -1
- package/dist-server/restful/unstable/stop-scenario.js +1 -1
- package/dist-server/restful/unstable/stop-scenario.js.map +1 -1
- package/dist-server/service/connection/connection-mutation.js +4 -8
- package/dist-server/service/connection/connection-mutation.js.map +1 -1
- package/dist-server/service/connection/connection-query.js +17 -14
- package/dist-server/service/connection/connection-query.js.map +1 -1
- package/dist-server/service/connection/connection-subscription.js +2 -2
- package/dist-server/service/connection/connection-subscription.js.map +1 -1
- package/dist-server/service/connection/connection-type.js +32 -8
- package/dist-server/service/connection/connection-type.js.map +1 -1
- package/dist-server/service/scenario-instance/scenario-instance-mutation.js +4 -71
- package/dist-server/service/scenario-instance/scenario-instance-mutation.js.map +1 -1
- package/dist-server/service/scenario-instance/scenario-instance-type.js +18 -5
- package/dist-server/service/scenario-instance/scenario-instance-type.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/helps/integration/concept/script-internal-variables.ja.md +21 -1
- package/helps/integration/concept/script-internal-variables.ko.md +17 -0
- package/helps/integration/concept/script-internal-variables.md +18 -0
- package/helps/integration/concept/script-internal-variables.ms.md +19 -1
- package/helps/integration/concept/script-internal-variables.zh.md +18 -0
- package/helps/integration/connector/oracle-connector.ja.md +90 -0
- package/helps/integration/connector/oracle-connector.ko.md +87 -0
- package/helps/integration/connector/oracle-connector.md +46 -25
- package/helps/integration/connector/oracle-connector.ms.md +87 -0
- package/helps/integration/connector/oracle-connector.zh.md +87 -0
- package/helps/integration/task/script.ja.md +1 -1
- package/helps/integration/task/script.ko.md +1 -1
- package/helps/integration/task/script.md +1 -1
- package/helps/integration/task/script.ms.md +1 -1
- package/helps/integration/task/script.zh.md +1 -1
- package/openapi/unstable/scenario.yaml +100 -100
- package/openapi/unstable.yaml +11 -11
- package/package.json +7 -11
- package/server/controllers/index.ts +1 -0
- package/server/controllers/scenario-controller.ts +116 -0
- package/server/engine/connection-manager.ts +49 -7
- package/server/engine/connector/graphql-connector.ts +8 -10
- package/server/engine/connector/operato-connector.ts +22 -32
- package/server/engine/connector/oracle-connector.ts +132 -22
- package/server/engine/connector/proxy-connector.ts +53 -0
- package/server/engine/edge-client.ts +45 -0
- package/server/engine/index.ts +1 -0
- package/server/engine/task/oracle-procedure.ts +1 -16
- package/server/engine/task/script.ts +1 -0
- package/server/engine/task/utils/headless-pool-for-scenario.ts +1 -1
- package/server/engine/types.ts +45 -46
- package/server/index.ts +1 -0
- package/server/restful/unstable/run-scenario.ts +0 -1
- package/server/restful/unstable/start-scenario.ts +1 -1
- package/server/restful/unstable/stop-scenario.ts +1 -1
- package/server/service/connection/connection-mutation.ts +9 -29
- package/server/service/connection/connection-query.ts +13 -12
- package/server/service/connection/connection-subscription.ts +2 -2
- package/server/service/connection/connection-type.ts +53 -41
- package/server/service/scenario-instance/scenario-instance-mutation.ts +10 -121
- package/server/service/scenario-instance/scenario-instance-type.ts +24 -13
@@ -2,9 +2,9 @@ paths:
|
|
2
2
|
/scenario/{scenarioId}:
|
3
3
|
get:
|
4
4
|
tags:
|
5
|
-
-
|
6
|
-
description:
|
7
|
-
operationId:
|
5
|
+
- integration
|
6
|
+
description: Use this call to get information for single integration scenario.
|
7
|
+
operationId: scenario
|
8
8
|
parameters:
|
9
9
|
- in: header
|
10
10
|
name: x-things-factory-domain
|
@@ -12,28 +12,28 @@ paths:
|
|
12
12
|
type: string
|
13
13
|
required: false
|
14
14
|
description: things-factory subdomain name
|
15
|
-
- in:
|
16
|
-
name:
|
15
|
+
- in: path
|
16
|
+
name: scenarioId
|
17
17
|
required: true
|
18
|
-
type:
|
18
|
+
type: string
|
19
19
|
responses:
|
20
20
|
'200':
|
21
|
-
description:
|
21
|
+
description: OK
|
22
22
|
'400':
|
23
|
-
description:
|
23
|
+
description: Bad request is sent
|
24
24
|
'401':
|
25
|
-
description:
|
25
|
+
description: Authentication Error
|
26
26
|
'404':
|
27
|
-
description:
|
27
|
+
description: Resource not found
|
28
28
|
'500':
|
29
|
-
description:
|
29
|
+
description: Server error
|
30
30
|
|
31
31
|
/scenarios:
|
32
32
|
get:
|
33
33
|
tags:
|
34
|
-
-
|
35
|
-
description:
|
36
|
-
operationId:
|
34
|
+
- integration
|
35
|
+
description: Use this API to get a list of integration scenarios.
|
36
|
+
operationId: scenarios
|
37
37
|
parameters:
|
38
38
|
- in: header
|
39
39
|
name: x-things-factory-domain
|
@@ -41,34 +41,34 @@ paths:
|
|
41
41
|
type: string
|
42
42
|
required: false
|
43
43
|
description: things-factory subdomain name
|
44
|
-
- in:
|
45
|
-
name:
|
46
|
-
description:
|
47
|
-
type:
|
48
|
-
format:
|
49
|
-
- in:
|
50
|
-
name:
|
51
|
-
description:
|
52
|
-
type:
|
53
|
-
format:
|
44
|
+
- in: query
|
45
|
+
name: page
|
46
|
+
description: This integer value is used to specify the maximum number of entries to return in a single "page" of data. Max entries per page is 100.
|
47
|
+
type: integer
|
48
|
+
format: uint32
|
49
|
+
- in: query
|
50
|
+
name: offset
|
51
|
+
description: Specifies the starting entry of data to return in the current call. Default is 1. if data is more than one page, the offset can be some entry to start next call.
|
52
|
+
type: integer
|
53
|
+
format: uint32
|
54
54
|
responses:
|
55
55
|
'200':
|
56
|
-
description:
|
56
|
+
description: OK
|
57
57
|
'400':
|
58
|
-
description:
|
58
|
+
description: Bad request is sent
|
59
59
|
'401':
|
60
|
-
description:
|
60
|
+
description: Authentication Error
|
61
61
|
'404':
|
62
|
-
description:
|
62
|
+
description: Resource not found
|
63
63
|
'500':
|
64
|
-
description:
|
64
|
+
description: Server error
|
65
65
|
|
66
66
|
/scenario-instance/{instanceName}:
|
67
67
|
get:
|
68
68
|
tags:
|
69
|
-
-
|
70
|
-
description:
|
71
|
-
operationId:
|
69
|
+
- integration
|
70
|
+
description: Use this call to get information for single integration scenario instance.
|
71
|
+
operationId: scenarioInstance
|
72
72
|
parameters:
|
73
73
|
- in: header
|
74
74
|
name: x-things-factory-domain
|
@@ -76,28 +76,28 @@ paths:
|
|
76
76
|
type: string
|
77
77
|
required: false
|
78
78
|
description: things-factory subdomain name
|
79
|
-
- in:
|
80
|
-
name:
|
79
|
+
- in: path
|
80
|
+
name: instanceName
|
81
81
|
required: true
|
82
|
-
type:
|
82
|
+
type: string
|
83
83
|
responses:
|
84
84
|
'200':
|
85
|
-
description:
|
85
|
+
description: OK
|
86
86
|
'400':
|
87
|
-
description:
|
87
|
+
description: Bad request is sent
|
88
88
|
'401':
|
89
|
-
description:
|
89
|
+
description: Authentication Error
|
90
90
|
'404':
|
91
|
-
description:
|
91
|
+
description: Resource not found
|
92
92
|
'500':
|
93
|
-
description:
|
93
|
+
description: Server error
|
94
94
|
|
95
95
|
/scenario-instances:
|
96
96
|
get:
|
97
97
|
tags:
|
98
|
-
-
|
99
|
-
description:
|
100
|
-
operationId:
|
98
|
+
- integration
|
99
|
+
description: Use this API to get a list of integration scenario instances.
|
100
|
+
operationId: scenarioInstances
|
101
101
|
parameters:
|
102
102
|
- in: header
|
103
103
|
name: x-things-factory-domain
|
@@ -105,34 +105,34 @@ paths:
|
|
105
105
|
type: string
|
106
106
|
required: false
|
107
107
|
description: things-factory subdomain name
|
108
|
-
- in:
|
109
|
-
name:
|
110
|
-
description:
|
111
|
-
type:
|
112
|
-
format:
|
113
|
-
- in:
|
114
|
-
name:
|
115
|
-
description:
|
116
|
-
type:
|
117
|
-
format:
|
108
|
+
- in: query
|
109
|
+
name: page
|
110
|
+
description: This integer value is used to specify the maximum number of entries to return in a single "page" of data. Max entries per page is 100.
|
111
|
+
type: integer
|
112
|
+
format: uint32
|
113
|
+
- in: query
|
114
|
+
name: offset
|
115
|
+
description: Specifies the starting entry of data to return in the current call. Default is 1. if data is more than one page, the offset can be some entry to start next call.
|
116
|
+
type: integer
|
117
|
+
format: uint32
|
118
118
|
responses:
|
119
119
|
'200':
|
120
|
-
description:
|
120
|
+
description: OK
|
121
121
|
'400':
|
122
|
-
description:
|
122
|
+
description: Bad request is sent
|
123
123
|
'401':
|
124
|
-
description:
|
124
|
+
description: Authentication Error
|
125
125
|
'404':
|
126
|
-
description:
|
126
|
+
description: Resource not found
|
127
127
|
'500':
|
128
|
-
description:
|
128
|
+
description: Server error
|
129
129
|
|
130
130
|
/run-scenario/{scenarioName}:
|
131
131
|
post:
|
132
132
|
tags:
|
133
|
-
-
|
134
|
-
description:
|
135
|
-
operationId:
|
133
|
+
- integration
|
134
|
+
description: Use this call to run scenario as standalone.
|
135
|
+
operationId: runScenario
|
136
136
|
requestBody:
|
137
137
|
content:
|
138
138
|
application/json:
|
@@ -140,11 +140,11 @@ paths:
|
|
140
140
|
type: object
|
141
141
|
properties:
|
142
142
|
instanceName:
|
143
|
-
type:
|
144
|
-
description:
|
143
|
+
type: string
|
144
|
+
description: Scenario Instance Name to identify new scenario instance to run
|
145
145
|
variables:
|
146
|
-
type:
|
147
|
-
description:
|
146
|
+
type: object
|
147
|
+
description: Input parameters for the new scenario instance to run
|
148
148
|
parameters:
|
149
149
|
- in: header
|
150
150
|
name: x-things-factory-domain
|
@@ -152,28 +152,28 @@ paths:
|
|
152
152
|
type: string
|
153
153
|
required: false
|
154
154
|
description: things-factory subdomain name
|
155
|
-
- in:
|
156
|
-
name:
|
155
|
+
- in: path
|
156
|
+
name: scenarioName
|
157
157
|
required: true
|
158
|
-
type:
|
158
|
+
type: string
|
159
159
|
responses:
|
160
160
|
'200':
|
161
|
-
description:
|
161
|
+
description: OK
|
162
162
|
'400':
|
163
|
-
description:
|
163
|
+
description: Bad request is sent
|
164
164
|
'401':
|
165
|
-
description:
|
165
|
+
description: Authentication Error
|
166
166
|
'404':
|
167
|
-
description:
|
167
|
+
description: Resource not found
|
168
168
|
'500':
|
169
|
-
description:
|
169
|
+
description: Server error
|
170
170
|
|
171
171
|
/start-scenario/{scenarioName}:
|
172
172
|
post:
|
173
173
|
tags:
|
174
|
-
-
|
175
|
-
description:
|
176
|
-
operationId:
|
174
|
+
- integration
|
175
|
+
description: Use this call to start scenario as a given instance name.
|
176
|
+
operationId: startScenario
|
177
177
|
requestBody:
|
178
178
|
content:
|
179
179
|
application/json:
|
@@ -181,11 +181,11 @@ paths:
|
|
181
181
|
type: object
|
182
182
|
properties:
|
183
183
|
instanceName:
|
184
|
-
type:
|
185
|
-
description:
|
184
|
+
type: string
|
185
|
+
description: Scenario Instance Name to identify new scenario instance to start
|
186
186
|
variables:
|
187
|
-
type:
|
188
|
-
description:
|
187
|
+
type: object
|
188
|
+
description: Input parameters for the new scenario instance to start
|
189
189
|
parameters:
|
190
190
|
- in: header
|
191
191
|
name: x-things-factory-domain
|
@@ -193,28 +193,28 @@ paths:
|
|
193
193
|
type: string
|
194
194
|
required: false
|
195
195
|
description: things-factory subdomain name
|
196
|
-
- in:
|
197
|
-
name:
|
196
|
+
- in: path
|
197
|
+
name: scenarioName
|
198
198
|
required: true
|
199
|
-
type:
|
199
|
+
type: string
|
200
200
|
responses:
|
201
201
|
'200':
|
202
|
-
description:
|
202
|
+
description: OK
|
203
203
|
'400':
|
204
|
-
description:
|
204
|
+
description: Bad request is sent
|
205
205
|
'401':
|
206
|
-
description:
|
206
|
+
description: Authentication Error
|
207
207
|
'404':
|
208
|
-
description:
|
208
|
+
description: Resource not found
|
209
209
|
'500':
|
210
|
-
description:
|
210
|
+
description: Server error
|
211
211
|
|
212
212
|
/stop-scenario/{instanceName}:
|
213
213
|
post:
|
214
214
|
tags:
|
215
|
-
-
|
216
|
-
description:
|
217
|
-
operationId:
|
215
|
+
- integration
|
216
|
+
description: Use this call to stop scenario running as a given instance name.
|
217
|
+
operationId: stopScenario
|
218
218
|
parameters:
|
219
219
|
- in: header
|
220
220
|
name: x-things-factory-domain
|
@@ -222,19 +222,19 @@ paths:
|
|
222
222
|
type: string
|
223
223
|
required: false
|
224
224
|
description: things-factory subdomain name
|
225
|
-
- in:
|
226
|
-
name:
|
225
|
+
- in: path
|
226
|
+
name: instanceName
|
227
227
|
required: true
|
228
|
-
type:
|
229
|
-
description:
|
228
|
+
type: string
|
229
|
+
description: scenario instance name to be stopped
|
230
230
|
responses:
|
231
231
|
'200':
|
232
|
-
description:
|
232
|
+
description: OK
|
233
233
|
'400':
|
234
|
-
description:
|
234
|
+
description: Bad request is sent
|
235
235
|
'401':
|
236
|
-
description:
|
236
|
+
description: Authentication Error
|
237
237
|
'404':
|
238
|
-
description:
|
238
|
+
description: Resource not found
|
239
239
|
'500':
|
240
|
-
description:
|
240
|
+
description: Server error
|
package/openapi/unstable.yaml
CHANGED
@@ -3,22 +3,22 @@ info:
|
|
3
3
|
description: >
|
4
4
|
For the latest release information please check our [release notes](https://developer.myoperato.com/release_notes).
|
5
5
|
The Integration API exposes integrations endpoint and related functions.
|
6
|
-
version:
|
7
|
-
title:
|
8
|
-
termsOfService:
|
6
|
+
version: unstable
|
7
|
+
title: Integration
|
8
|
+
termsOfService: https://myoperato.com/terms/
|
9
9
|
contact:
|
10
|
-
email:
|
10
|
+
email: heartyoh@hatiolab.com
|
11
11
|
license:
|
12
12
|
name: MIT
|
13
13
|
url: http://mit-license.org/
|
14
14
|
tags:
|
15
|
-
- name:
|
16
|
-
description:
|
15
|
+
- name: integration
|
16
|
+
description: API to integrate with other systems
|
17
17
|
schemes:
|
18
|
-
-
|
19
|
-
-
|
18
|
+
- https
|
19
|
+
- http
|
20
20
|
servers:
|
21
|
-
- url:
|
21
|
+
- url: /api/unstable/
|
22
22
|
|
23
23
|
components:
|
24
24
|
securitySchemes:
|
@@ -37,5 +37,5 @@ responses:
|
|
37
37
|
description: Unauthorized
|
38
38
|
|
39
39
|
externalDocs:
|
40
|
-
description:
|
41
|
-
url:
|
40
|
+
description: Find out about our release notes
|
41
|
+
url: https://developer.myoperato.com/release_notes
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@things-factory/integration-base",
|
3
|
-
"version": "7.0.0-alpha.
|
3
|
+
"version": "7.0.0-alpha.21",
|
4
4
|
"main": "dist-server/index.js",
|
5
5
|
"browser": "client/index.js",
|
6
6
|
"things-factory": true,
|
@@ -26,26 +26,22 @@
|
|
26
26
|
},
|
27
27
|
"dependencies": {
|
28
28
|
"@apollo/client": "^3.6.9",
|
29
|
-
"@things-factory/api": "^7.0.0-alpha.
|
30
|
-
"@things-factory/auth-base": "^7.0.0-alpha.
|
29
|
+
"@things-factory/api": "^7.0.0-alpha.21",
|
30
|
+
"@things-factory/auth-base": "^7.0.0-alpha.21",
|
31
31
|
"@things-factory/env": "^7.0.0-alpha.0",
|
32
|
-
"@things-factory/oauth2-client": "^7.0.0-alpha.
|
33
|
-
"@things-factory/scheduler-client": "^7.0.0-alpha.
|
34
|
-
"@things-factory/shell": "^7.0.0-alpha.
|
32
|
+
"@things-factory/oauth2-client": "^7.0.0-alpha.21",
|
33
|
+
"@things-factory/scheduler-client": "^7.0.0-alpha.21",
|
34
|
+
"@things-factory/shell": "^7.0.0-alpha.21",
|
35
35
|
"@things-factory/utils": "^7.0.0-alpha.0",
|
36
36
|
"async-mqtt": "^2.5.0",
|
37
37
|
"chance": "^1.1.11",
|
38
38
|
"cross-fetch": "^3.0.4",
|
39
39
|
"ieee754": "^1.2.1",
|
40
40
|
"moment-timezone": "^0.5.40",
|
41
|
-
"mssql": "^8.1.2",
|
42
41
|
"node-fetch": "^2.6.0",
|
43
42
|
"promise-socket": "^7.0.0",
|
44
43
|
"readline": "^1.3.0",
|
45
44
|
"vm2": "3.9.11"
|
46
45
|
},
|
47
|
-
"
|
48
|
-
"@types/cron": "^2.0.1"
|
49
|
-
},
|
50
|
-
"gitHead": "778315d165d7f15e147583a45d5079c3d7cbce38"
|
46
|
+
"gitHead": "6dff39aa0d60f0fcf760cca9b8453626f222fa57"
|
51
47
|
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './scenario-controller'
|
@@ -0,0 +1,116 @@
|
|
1
|
+
import { getRepository, Domain, GraphqlLocalClient } from '@things-factory/shell'
|
2
|
+
import { PrivilegeObject, checkPermission } from '@things-factory/auth-base'
|
3
|
+
|
4
|
+
import { ScenarioEngine } from '../engine/scenario-engine'
|
5
|
+
import { Scenario } from '../service/scenario/scenario'
|
6
|
+
import { ScenarioInstance } from '../service/scenario-instance/scenario-instance-type'
|
7
|
+
import { Step } from '../service/step/step-type'
|
8
|
+
|
9
|
+
const debug = require('debug')('things-factory:integration-base:controller:run-scenario')
|
10
|
+
|
11
|
+
async function findScenario(scenarioName: string, domain: Domain): Promise<{ name: string; steps: Step[]; domain: Domain; privilege?: PrivilegeObject }> {
|
12
|
+
var repository = getRepository(Scenario)
|
13
|
+
|
14
|
+
var scenario = await repository.findOne({
|
15
|
+
where: { domain: { id: domain.id }, name: scenarioName },
|
16
|
+
relations: ['domain', 'steps', 'creator', 'updater']
|
17
|
+
})
|
18
|
+
|
19
|
+
if (!scenario && domain.parentId) {
|
20
|
+
scenario = await repository.findOne({
|
21
|
+
where: { domain: { id: domain.parentId }, name: scenarioName },
|
22
|
+
relations: ['domain', 'steps', 'creator', 'updater']
|
23
|
+
})
|
24
|
+
}
|
25
|
+
|
26
|
+
return scenario as any
|
27
|
+
}
|
28
|
+
|
29
|
+
export async function runScenario(instanceName: string, scenarioName: string, variables: any, context: ResolverContext): Promise<ScenarioInstance> {
|
30
|
+
const { domain, user, lng, unsafeIP, prohibitedPrivileges } = context.state
|
31
|
+
|
32
|
+
debug('runScenario', scenarioName, instanceName, variables)
|
33
|
+
|
34
|
+
var scenario = await findScenario(scenarioName, domain)
|
35
|
+
|
36
|
+
if (!scenario) {
|
37
|
+
throw new Error(
|
38
|
+
context.t('error.scenario not found', {
|
39
|
+
scenario: scenarioName
|
40
|
+
})
|
41
|
+
)
|
42
|
+
}
|
43
|
+
|
44
|
+
if (!(await checkPermission(scenario.privilege, user, domain, unsafeIP, prohibitedPrivileges))) {
|
45
|
+
const { category, privilege } = scenario.privilege || {}
|
46
|
+
throw new Error(`Unauthorized! ${category && privilege ? category + ':' + privilege + ' privilege' : 'ownership granted'} required`)
|
47
|
+
}
|
48
|
+
|
49
|
+
/* 시나리오 인스턴스를 생성한다. */
|
50
|
+
instanceName = instanceName || scenarioName + '-' + String(Date.now())
|
51
|
+
var instance = new ScenarioInstance(instanceName, scenario, {
|
52
|
+
domain,
|
53
|
+
user,
|
54
|
+
lng,
|
55
|
+
variables,
|
56
|
+
client: GraphqlLocalClient.client
|
57
|
+
})
|
58
|
+
|
59
|
+
await instance.run()
|
60
|
+
|
61
|
+
return instance
|
62
|
+
}
|
63
|
+
|
64
|
+
export async function startScenario(instanceName: string, scenarioName: string, variables: any, context: ResolverContext): Promise<ScenarioInstance> {
|
65
|
+
const { domain, user, lng, unsafeIP, prohibitedPrivileges } = context.state
|
66
|
+
|
67
|
+
debug('startScenario', instanceName, scenarioName, variables)
|
68
|
+
|
69
|
+
var scenario = await findScenario(scenarioName, domain)
|
70
|
+
|
71
|
+
if (!scenario) {
|
72
|
+
throw new Error(
|
73
|
+
context.t('error.scenario not found', {
|
74
|
+
scenario: scenarioName
|
75
|
+
})
|
76
|
+
)
|
77
|
+
}
|
78
|
+
|
79
|
+
if (!(await checkPermission(scenario.privilege, user, domain, unsafeIP, prohibitedPrivileges))) {
|
80
|
+
const { category, privilege } = scenario.privilege || {}
|
81
|
+
throw new Error(`Unauthorized! ${category && privilege ? category + ':' + privilege + ' privilege' : 'ownership granted'} required`)
|
82
|
+
}
|
83
|
+
|
84
|
+
instanceName = instanceName || scenarioName
|
85
|
+
return await ScenarioEngine.load(instanceName, scenario, { domain, user, lng, variables })
|
86
|
+
}
|
87
|
+
|
88
|
+
export async function stopScenario(instanceName: string, context: ResolverContext): Promise<ScenarioInstance | undefined> {
|
89
|
+
const { domain, user, unsafeIP, prohibitedPrivileges } = context.state
|
90
|
+
|
91
|
+
debug('stopScenario', instanceName)
|
92
|
+
|
93
|
+
runScenario
|
94
|
+
|
95
|
+
var scenarioInstance = ScenarioEngine.getScenarioInstance(domain, instanceName)
|
96
|
+
|
97
|
+
if (!scenarioInstance) {
|
98
|
+
debug('stopScenario', `ScenarioInstance(${instanceName}) Not Found.`)
|
99
|
+
throw new Error(
|
100
|
+
context.t('error.scenario instance not found', {
|
101
|
+
instance: instanceName
|
102
|
+
})
|
103
|
+
)
|
104
|
+
}
|
105
|
+
|
106
|
+
var scenario = await findScenario(scenarioInstance.scenarioName, domain)
|
107
|
+
|
108
|
+
if (!(await checkPermission(scenario.privilege, user, domain, unsafeIP, prohibitedPrivileges))) {
|
109
|
+
const { category, privilege } = scenario.privilege || {}
|
110
|
+
throw new Error(`Unauthorized! ${category && privilege ? category + ':' + privilege + ' privilege' : 'ownership granted'} required`)
|
111
|
+
}
|
112
|
+
|
113
|
+
await ScenarioEngine.unload(domain, instanceName)
|
114
|
+
|
115
|
+
return scenarioInstance
|
116
|
+
}
|
@@ -5,6 +5,7 @@ import { Domain, getRepository, pubsub, PubSubLogTransport } from '@things-facto
|
|
5
5
|
|
6
6
|
import { Connection, ConnectionStatus } from '../service'
|
7
7
|
import { Connector } from './types'
|
8
|
+
import { ProxyConnector } from './connector/proxy-connector'
|
8
9
|
|
9
10
|
const { combine, timestamp, splat, printf } = format
|
10
11
|
const debug = require('debug')('things-factory:integration-base:connections')
|
@@ -17,7 +18,8 @@ const systemTimestamp = format((info, opts) => {
|
|
17
18
|
|
18
19
|
export class ConnectionManager {
|
19
20
|
private static connectors: { [propName: string]: Connector } = {}
|
20
|
-
private static connections = {}
|
21
|
+
private static connections: { [domainId: string]: { [name: string]: any } } = {}
|
22
|
+
private static entities = {}
|
21
23
|
private static logFormat = printf(({ level, message, timestamp }) => {
|
22
24
|
return `${timestamp} ${level}: ${message}`
|
23
25
|
})
|
@@ -43,7 +45,7 @@ export class ConnectionManager {
|
|
43
45
|
const CONNECTIONS = (
|
44
46
|
await getRepository(Connection).find({
|
45
47
|
where: { active: true },
|
46
|
-
relations: ['domain', 'creator', 'updater']
|
48
|
+
relations: ['domain', 'edge', 'creator', 'updater']
|
47
49
|
})
|
48
50
|
).map(connection => {
|
49
51
|
var params = {}
|
@@ -63,12 +65,21 @@ export class ConnectionManager {
|
|
63
65
|
ConnectionManager.logger.info('Initializing ConnectionManager...')
|
64
66
|
|
65
67
|
return await Promise.all(
|
66
|
-
Object.keys(ConnectionManager.connectors).map(type => {
|
67
|
-
|
68
|
+
[...Object.keys(ConnectionManager.connectors), 'proxy-connector'].map(type => {
|
69
|
+
const connector = 'proxy-connector' ? ProxyConnector.instance : ConnectionManager.getConnector(type)
|
70
|
+
|
68
71
|
ConnectionManager.logger.info(`Connector '${type}' started to ready`)
|
69
72
|
|
70
73
|
return connector
|
71
|
-
.ready(
|
74
|
+
.ready(
|
75
|
+
CONNECTIONS.filter(connection => {
|
76
|
+
if (type == 'proxy-connector') {
|
77
|
+
return !!connection.edge
|
78
|
+
} else {
|
79
|
+
return !connection.edge && connection.type == type
|
80
|
+
}
|
81
|
+
}) as any
|
82
|
+
)
|
72
83
|
.catch(error => {
|
73
84
|
ConnectionManager.logger.error(error.message)
|
74
85
|
})
|
@@ -103,6 +114,14 @@ export class ConnectionManager {
|
|
103
114
|
delete ConnectionManager.connectors[type]
|
104
115
|
}
|
105
116
|
|
117
|
+
static getConnections() {
|
118
|
+
return ConnectionManager.connections
|
119
|
+
}
|
120
|
+
|
121
|
+
static getEntities() {
|
122
|
+
return ConnectionManager.entities
|
123
|
+
}
|
124
|
+
|
106
125
|
static getConnectionInstance(connection: Connection): any {
|
107
126
|
const { domain, name } = connection
|
108
127
|
return ConnectionManager.connections[domain.id]?.[name]
|
@@ -119,6 +138,11 @@ export class ConnectionManager {
|
|
119
138
|
return connection
|
120
139
|
}
|
121
140
|
|
141
|
+
static getConnectionInstanceEntityByName(domain: Domain, name: string): any {
|
142
|
+
const entities = ConnectionManager.entities[domain.id]
|
143
|
+
return entities?.[name]
|
144
|
+
}
|
145
|
+
|
122
146
|
static getConnectionInstances(domain: Domain): { [connectionName: string]: any } {
|
123
147
|
const connections = ConnectionManager.connections[domain.id]
|
124
148
|
|
@@ -127,6 +151,14 @@ export class ConnectionManager {
|
|
127
151
|
}
|
128
152
|
}
|
129
153
|
|
154
|
+
static getConnectionInstanceEntities(domain: Domain): { [connectionName: string]: any } {
|
155
|
+
const connections = ConnectionManager.entities[domain.id]
|
156
|
+
|
157
|
+
return {
|
158
|
+
...connections
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
130
162
|
static addConnectionInstance(connection: Connection, instance: any) {
|
131
163
|
const { domain, name } = connection
|
132
164
|
|
@@ -135,7 +167,13 @@ export class ConnectionManager {
|
|
135
167
|
connections = ConnectionManager.connections[domain.id] = {}
|
136
168
|
}
|
137
169
|
|
170
|
+
var entities = ConnectionManager.entities[domain.id]
|
171
|
+
if (!entities) {
|
172
|
+
entities = ConnectionManager.entities[domain.id] = {}
|
173
|
+
}
|
174
|
+
|
138
175
|
connections[name] = instance
|
176
|
+
entities[name] = connection
|
139
177
|
|
140
178
|
ConnectionManager.publishState(connection, ConnectionStatus.CONNECTED)
|
141
179
|
debug('add-connection', domain.subdomain, name)
|
@@ -144,6 +182,8 @@ export class ConnectionManager {
|
|
144
182
|
static removeConnectionInstance(connection: Connection): any {
|
145
183
|
const { domain, name } = connection
|
146
184
|
var connections = ConnectionManager.connections[domain.id]
|
185
|
+
var entities = ConnectionManager.entities[domain.id]
|
186
|
+
|
147
187
|
var instance = connections?.[name]
|
148
188
|
|
149
189
|
if (!connections || !instance) {
|
@@ -152,6 +192,7 @@ export class ConnectionManager {
|
|
152
192
|
}
|
153
193
|
|
154
194
|
delete connections[name]
|
195
|
+
delete entities[name]
|
155
196
|
|
156
197
|
ConnectionManager.publishState(connection, ConnectionStatus.DISCONNECTED)
|
157
198
|
debug('remove-connection', `'${name}' connection is removed from domain '${domain.subdomain}'`)
|
@@ -159,8 +200,8 @@ export class ConnectionManager {
|
|
159
200
|
return instance
|
160
201
|
}
|
161
202
|
|
162
|
-
static publishState(connection: Connection, state) {
|
163
|
-
const { domain, id, name, description, type } = connection
|
203
|
+
private static async publishState(connection: Connection, state) {
|
204
|
+
const { domain, id, name, description, type, edge } = connection
|
164
205
|
|
165
206
|
pubsub.publish('connection-state', {
|
166
207
|
connectionState: {
|
@@ -169,6 +210,7 @@ export class ConnectionManager {
|
|
169
210
|
name,
|
170
211
|
description,
|
171
212
|
type,
|
213
|
+
edge,
|
172
214
|
state,
|
173
215
|
timestamp: new Date()
|
174
216
|
}
|