@things-factory/integration-base 7.0.0-alpha.6 → 7.0.0-alpha.7
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/connector/oracle-connector.js +113 -17
- package/dist-server/engine/connector/oracle-connector.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/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/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 +6 -1
- package/dist-server/service/scenario-instance/scenario-instance-type.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- 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/openapi/unstable/scenario.yaml +100 -100
- package/openapi/unstable.yaml +11 -11
- package/package.json +7 -7
- package/server/controllers/index.ts +1 -0
- package/server/controllers/scenario-controller.ts +116 -0
- package/server/engine/connector/oracle-connector.ts +132 -22
- package/server/engine/task/oracle-procedure.ts +1 -16
- 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/scenario-instance/scenario-instance-mutation.ts +10 -121
- package/server/service/scenario-instance/scenario-instance-type.ts +11 -8
@@ -4,9 +4,8 @@ import { ConnectionManager } from '../connection-manager'
|
|
4
4
|
import { Connector } from '../types'
|
5
5
|
import { InputConnection } from '../../service/connection/connection-type'
|
6
6
|
|
7
|
-
|
8
7
|
try {
|
9
|
-
var
|
8
|
+
var oracledb = require('oracledb')
|
10
9
|
} catch (err) {
|
11
10
|
logger.error('oracledb module loading failed')
|
12
11
|
}
|
@@ -18,42 +17,132 @@ export class OracleConnector implements Connector {
|
|
18
17
|
ConnectionManager.logger.info('oracle-connector connections are ready')
|
19
18
|
}
|
20
19
|
|
21
|
-
async
|
20
|
+
async recreatePool(connection: InputConnection) {
|
22
21
|
const {
|
22
|
+
name,
|
23
23
|
endpoint,
|
24
|
-
params: { user, password, database }
|
24
|
+
params: { user, password, database, poolMin, poolMax, poolIncrement },
|
25
|
+
domain
|
25
26
|
} = connection
|
26
27
|
|
27
|
-
if (!
|
28
|
+
if (!oracledb) {
|
28
29
|
throw new Error('oracledb module loading failed')
|
29
30
|
}
|
30
31
|
|
31
|
-
|
32
|
-
|
32
|
+
const poolAlias = `${domain.name}-${name}`
|
33
|
+
await oracledb.getPool(poolAlias).close(10)
|
34
|
+
await oracledb.createPool({
|
33
35
|
user,
|
34
36
|
password,
|
35
|
-
|
37
|
+
// when oracle not using default port must add connection string with port like localhost:port
|
38
|
+
connectString: `${endpoint.trim()}/${database}`,
|
39
|
+
poolMin,
|
40
|
+
poolMax,
|
41
|
+
poolIncrement,
|
42
|
+
poolAlias
|
36
43
|
})
|
37
44
|
|
45
|
+
ConnectionManager.logger.info(`Oracle Database(${connection.name}:${database}) at ${endpoint} recreated.`)
|
46
|
+
}
|
47
|
+
|
48
|
+
async connect(connection: InputConnection) {
|
49
|
+
const {
|
50
|
+
name,
|
51
|
+
endpoint,
|
52
|
+
params: { user, password, database, poolMin, poolMax, poolIncrement },
|
53
|
+
domain
|
54
|
+
} = connection
|
55
|
+
|
56
|
+
if (!oracledb) {
|
57
|
+
throw new Error('oracledb module loading failed')
|
58
|
+
}
|
59
|
+
|
60
|
+
const poolAlias = `${domain.name}-${name}`
|
61
|
+
|
62
|
+
var enableStatistics = true
|
63
|
+
const pool = await oracledb.createPool({
|
64
|
+
user,
|
65
|
+
password,
|
66
|
+
// when oracle not using default port must add connection string with port like localhost:port
|
67
|
+
connectString: `${endpoint.trim()}/${database}`,
|
68
|
+
poolMin,
|
69
|
+
poolMax,
|
70
|
+
poolIncrement,
|
71
|
+
poolAlias,
|
72
|
+
enableStatistics
|
73
|
+
})
|
74
|
+
|
38
75
|
ConnectionManager.addConnectionInstance(connection, {
|
39
76
|
query: async (query, params) => {
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
77
|
+
let dbConnection: any = {}
|
78
|
+
let taskResult: any = {}
|
79
|
+
try {
|
80
|
+
dbConnection = await oracledb.getConnection(poolAlias)
|
81
|
+
|
82
|
+
taskResult = (
|
83
|
+
await dbConnection.execute(query, params, {
|
84
|
+
outFormat: oracledb.OBJECT
|
85
|
+
})
|
86
|
+
).rows
|
87
|
+
} catch (e) {
|
88
|
+
if (e.name === 'Error' && e.message.includes('NJS-040')) {
|
89
|
+
await this.recreatePool(connection)
|
90
|
+
}
|
91
|
+
throw e
|
92
|
+
}
|
93
|
+
finally {
|
94
|
+
await dbConnection.close()
|
95
|
+
}
|
96
|
+
return taskResult
|
97
|
+
|
45
98
|
},
|
46
99
|
execute: async (procedure, params) => {
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
100
|
+
let dbConnection: any = {}
|
101
|
+
let taskResult: any = {}
|
102
|
+
try {
|
103
|
+
// TODO: need to check if this is available when procedure string is a common query.
|
104
|
+
procedure = `BEGIN
|
105
|
+
${procedure}
|
106
|
+
END;`
|
107
|
+
dbConnection = await oracledb.getConnection(poolAlias)
|
108
|
+
|
109
|
+
// console.log('\n************* stat after get ****************')
|
110
|
+
// await oracledb.getPool(poolAlias).logStatistics()
|
111
|
+
|
112
|
+
const result = await dbConnection.execute(procedure, params, {
|
113
|
+
outFormat: oracledb.OBJECT
|
114
|
+
})
|
115
|
+
|
116
|
+
let paramKeys = Object.keys(params)
|
117
|
+
|
118
|
+
for (const paramKey of paramKeys) {
|
119
|
+
if (params[paramKey].dir === oracledb?.BIND_OUT) {
|
120
|
+
if (params[paramKey].type === oracledb?.CURSOR) {
|
121
|
+
const resultSetTemp = result.outBinds[paramKey]
|
122
|
+
taskResult[paramKey] = await resultSetTemp.getRows()
|
123
|
+
await resultSetTemp.close()
|
124
|
+
} else {
|
125
|
+
taskResult[paramKey] = result.outBinds[paramKey]
|
126
|
+
}
|
127
|
+
}
|
128
|
+
}
|
129
|
+
} catch (e) {
|
130
|
+
if (e.name === 'Error' && e.message.includes('NJS-040')) {
|
131
|
+
await this.recreatePool(connection)
|
132
|
+
}
|
133
|
+
throw e
|
134
|
+
}
|
135
|
+
finally {
|
136
|
+
await dbConnection.close()
|
137
|
+
|
138
|
+
// console.log('\n************* stat after close ****************')
|
139
|
+
// await oracledb.getPool(poolAlias).logStatistics()
|
140
|
+
}
|
141
|
+
return taskResult
|
55
142
|
},
|
56
|
-
close:
|
143
|
+
close: async () => {
|
144
|
+
await oracledb.getPool(poolAlias).close(10)
|
145
|
+
}
|
57
146
|
})
|
58
147
|
|
59
148
|
ConnectionManager.logger.info(`Oracle Database(${connection.name}:${database}) at ${endpoint} connected.`)
|
@@ -89,6 +178,27 @@ export class OracleConnector implements Connector {
|
|
89
178
|
name: 'database',
|
90
179
|
placeholder: 'SID',
|
91
180
|
label: 'database'
|
181
|
+
},
|
182
|
+
{
|
183
|
+
type: 'number',
|
184
|
+
name: 'poolMin',
|
185
|
+
placeholder: 'minimum connection-pool size',
|
186
|
+
label: 'pool-min',
|
187
|
+
value: 0
|
188
|
+
},
|
189
|
+
{
|
190
|
+
type: 'number',
|
191
|
+
name: 'poolMax',
|
192
|
+
placeholder: 'maximum connection-pool size',
|
193
|
+
label: 'pool-max',
|
194
|
+
value: 4
|
195
|
+
},
|
196
|
+
{
|
197
|
+
type: 'number',
|
198
|
+
name: 'poolIncrement',
|
199
|
+
placeholder: 'connection incremental size',
|
200
|
+
label: 'pool-increment',
|
201
|
+
value: 1
|
92
202
|
}
|
93
203
|
]
|
94
204
|
}
|
@@ -97,23 +97,8 @@ async function OracleProcedure(step: InputStep, context: Context) {
|
|
97
97
|
|
98
98
|
const result = await dbconnection.execute(code, procedureParameters)
|
99
99
|
|
100
|
-
var taskResult = {}
|
101
|
-
let paramKeys = Object.keys(procedureParameters)
|
102
|
-
|
103
|
-
for (const paramKey of paramKeys) {
|
104
|
-
if (procedureParameters[paramKey].dir === oracledb?.BIND_OUT) {
|
105
|
-
if (procedureParameters[paramKey].type === oracledb?.CURSOR) {
|
106
|
-
const resultSetTemp = result.outBinds[paramKey]
|
107
|
-
taskResult[paramKey] = await resultSetTemp.getRows()
|
108
|
-
await resultSetTemp.close()
|
109
|
-
} else {
|
110
|
-
taskResult[paramKey] = result.outBinds[paramKey]
|
111
|
-
}
|
112
|
-
}
|
113
|
-
}
|
114
|
-
|
115
100
|
return {
|
116
|
-
data:
|
101
|
+
data: result
|
117
102
|
}
|
118
103
|
}
|
119
104
|
|
package/server/index.ts
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
import gql from 'graphql-tag'
|
2
2
|
|
3
3
|
import { restfulApiRouter as router } from '@things-factory/api'
|
4
|
-
import { ScenarioInstanceStatus } from '../../service/scenario-instance/scenario-instance-type'
|
5
4
|
|
6
5
|
const debug = require('debug')('things-factory:integration-base:restful:unstable:run-scenario')
|
7
6
|
|
@@ -12,7 +12,7 @@ router.post('/unstable/start-scenario/:scenarioName', async (context, next) => {
|
|
12
12
|
|
13
13
|
context.body = await client.mutate({
|
14
14
|
mutation: gql`
|
15
|
-
mutation($instanceName: String, $scenarioName: String!, $variables: Object) {
|
15
|
+
mutation ($instanceName: String, $scenarioName: String!, $variables: Object) {
|
16
16
|
startScenario(instanceName: $instanceName, scenarioName: $scenarioName, variables: $variables) {
|
17
17
|
instanceName
|
18
18
|
scenarioName
|
@@ -11,7 +11,7 @@ router.post('/unstable/stop-scenario/:instanceName', async (context, next) => {
|
|
11
11
|
|
12
12
|
context.body = await client.mutate({
|
13
13
|
mutation: gql`
|
14
|
-
mutation($instanceName: String!) {
|
14
|
+
mutation ($instanceName: String!) {
|
15
15
|
stopScenario(instanceName: $instanceName) {
|
16
16
|
instanceName
|
17
17
|
scenarioName
|
@@ -1,35 +1,14 @@
|
|
1
1
|
import { Arg, Ctx, Mutation, Resolver } from 'type-graphql'
|
2
2
|
|
3
|
-
import {
|
3
|
+
import { ScalarObject } from '@things-factory/shell'
|
4
4
|
|
5
|
-
import { ScenarioEngine } from '../../engine'
|
6
|
-
import { Scenario } from '../scenario/scenario'
|
7
5
|
import { ScenarioInstance } from './scenario-instance-type'
|
8
|
-
import { PrivilegeObject, User, checkPermission } from '@things-factory/auth-base'
|
9
|
-
import { Step } from '../step/step-type'
|
10
6
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
): Promise<{ name: string; steps: Step[]; domain: Domain; privilege?: PrivilegeObject }> {
|
17
|
-
var repository = getRepository(Scenario)
|
18
|
-
|
19
|
-
var scenario = await repository.findOne({
|
20
|
-
where: { domain: { id: domain.id }, name: scenarioName },
|
21
|
-
relations: ['domain', 'steps', 'creator', 'updater']
|
22
|
-
})
|
23
|
-
|
24
|
-
if (!scenario && domain.parentId) {
|
25
|
-
scenario = await repository.findOne({
|
26
|
-
where: { domain: { id: domain.parentId }, name: scenarioName },
|
27
|
-
relations: ['domain', 'steps', 'creator', 'updater']
|
28
|
-
})
|
29
|
-
}
|
30
|
-
|
31
|
-
return scenario as any
|
32
|
-
}
|
7
|
+
import {
|
8
|
+
runScenario as controllerRunScenario,
|
9
|
+
startScenario as controllerStartScenario,
|
10
|
+
stopScenario as controllerStopScenario
|
11
|
+
} from '../../controllers/scenario-controller'
|
33
12
|
|
34
13
|
@Resolver(ScenarioInstance)
|
35
14
|
export class ScenarioInstanceMutation {
|
@@ -42,42 +21,7 @@ export class ScenarioInstanceMutation {
|
|
42
21
|
@Arg('variables', type => ScalarObject, { nullable: true }) variables: any,
|
43
22
|
@Ctx() context: ResolverContext
|
44
23
|
): Promise<ScenarioInstance> {
|
45
|
-
|
46
|
-
|
47
|
-
debug('runScenario', scenarioName, instanceName, variables)
|
48
|
-
|
49
|
-
var scenario = await findScenario(scenarioName, domain)
|
50
|
-
|
51
|
-
if (!scenario) {
|
52
|
-
throw new Error(
|
53
|
-
context.t('error.scenario not found', {
|
54
|
-
scenario: scenarioName
|
55
|
-
})
|
56
|
-
)
|
57
|
-
}
|
58
|
-
|
59
|
-
if (!(await checkPermission(scenario.privilege, user, domain, unsafeIP, prohibitedPrivileges))) {
|
60
|
-
const { category, privilege } = scenario.privilege || {}
|
61
|
-
throw new Error(
|
62
|
-
`Unauthorized! ${
|
63
|
-
category && privilege ? category + ':' + privilege + ' privilege' : 'ownership granted'
|
64
|
-
} required`
|
65
|
-
)
|
66
|
-
}
|
67
|
-
|
68
|
-
/* 시나리오 인스턴스를 생성한다. */
|
69
|
-
instanceName = instanceName || scenarioName + '-' + String(Date.now())
|
70
|
-
var instance = new ScenarioInstance(instanceName, scenario, {
|
71
|
-
domain,
|
72
|
-
user,
|
73
|
-
lng,
|
74
|
-
variables,
|
75
|
-
client: GraphqlLocalClient.client
|
76
|
-
})
|
77
|
-
|
78
|
-
await instance.run()
|
79
|
-
|
80
|
-
return instance
|
24
|
+
return await controllerRunScenario(instanceName, scenarioName, variables, context)
|
81
25
|
}
|
82
26
|
|
83
27
|
@Mutation(returns => ScenarioInstance, { description: 'To start new scenario instance' })
|
@@ -87,66 +31,11 @@ export class ScenarioInstanceMutation {
|
|
87
31
|
@Arg('variables', type => ScalarObject, { nullable: true }) variables: any,
|
88
32
|
@Ctx() context: ResolverContext
|
89
33
|
): Promise<ScenarioInstance> {
|
90
|
-
|
91
|
-
|
92
|
-
debug('startScenario', instanceName, scenarioName, variables)
|
93
|
-
|
94
|
-
var scenario = await findScenario(scenarioName, domain)
|
95
|
-
|
96
|
-
if (!scenario) {
|
97
|
-
throw new Error(
|
98
|
-
context.t('error.scenario not found', {
|
99
|
-
scenario: scenarioName
|
100
|
-
})
|
101
|
-
)
|
102
|
-
}
|
103
|
-
|
104
|
-
if (!(await checkPermission(scenario.privilege, user, domain, unsafeIP, prohibitedPrivileges))) {
|
105
|
-
const { category, privilege } = scenario.privilege || {}
|
106
|
-
throw new Error(
|
107
|
-
`Unauthorized! ${
|
108
|
-
category && privilege ? category + ':' + privilege + ' privilege' : 'ownership granted'
|
109
|
-
} required`
|
110
|
-
)
|
111
|
-
}
|
112
|
-
|
113
|
-
instanceName = instanceName || scenarioName
|
114
|
-
return await ScenarioEngine.load(instanceName, scenario, { domain, user, lng, variables })
|
34
|
+
return await controllerStartScenario(instanceName, scenarioName, variables, context)
|
115
35
|
}
|
116
36
|
|
117
37
|
@Mutation(returns => ScenarioInstance, { nullable: true, description: 'To start new scenario instance' })
|
118
|
-
async stopScenario(
|
119
|
-
|
120
|
-
@Ctx() context: ResolverContext
|
121
|
-
): Promise<ScenarioInstance | undefined> {
|
122
|
-
const { domain, user, unsafeIP, prohibitedPrivileges } = context.state
|
123
|
-
|
124
|
-
debug('stopScenario', instanceName)
|
125
|
-
|
126
|
-
var scenarioInstance = ScenarioEngine.getScenarioInstance(domain, instanceName)
|
127
|
-
|
128
|
-
if (!scenarioInstance) {
|
129
|
-
debug('stopScenario', `ScenarioInstance(${instanceName}) Not Found.`)
|
130
|
-
throw new Error(
|
131
|
-
context.t('error.scenario instance not found', {
|
132
|
-
instance: instanceName
|
133
|
-
})
|
134
|
-
)
|
135
|
-
}
|
136
|
-
|
137
|
-
var scenario = await findScenario(scenarioInstance.scenarioName, domain)
|
138
|
-
|
139
|
-
if (!(await checkPermission(scenario.privilege, user, domain, unsafeIP, prohibitedPrivileges))) {
|
140
|
-
const { category, privilege } = scenario.privilege || {}
|
141
|
-
throw new Error(
|
142
|
-
`Unauthorized! ${
|
143
|
-
category && privilege ? category + ':' + privilege + ' privilege' : 'ownership granted'
|
144
|
-
} required`
|
145
|
-
)
|
146
|
-
}
|
147
|
-
|
148
|
-
await ScenarioEngine.unload(domain, instanceName)
|
149
|
-
|
150
|
-
return scenarioInstance
|
38
|
+
async stopScenario(@Arg('instanceName', { nullable: true }) instanceName: string, @Ctx() context: ResolverContext): Promise<ScenarioInstance | undefined> {
|
39
|
+
return await controllerStopScenario(instanceName, context)
|
151
40
|
}
|
152
41
|
}
|
@@ -125,7 +125,7 @@ export class ScenarioInstance {
|
|
125
125
|
timestamp: Date
|
126
126
|
|
127
127
|
@Field({ nullable: true })
|
128
|
-
|
128
|
+
public message: string
|
129
129
|
|
130
130
|
private steps: Step[]
|
131
131
|
private rounds: number = 0
|
@@ -267,10 +267,7 @@ export class ScenarioInstance {
|
|
267
267
|
this.context.logger.error(ex.message ? ex.message : ex)
|
268
268
|
|
269
269
|
debug('failed to run ', `[ Domain: ${domain.name}, Scenario: ${scenarioName} ]\n`, ex)
|
270
|
-
this.setState(
|
271
|
-
ScenarioInstanceStatus.HALTED,
|
272
|
-
typeof message == 'object' ? JSON.stringify(message, null, 2) : message
|
273
|
-
)
|
270
|
+
this.setState(ScenarioInstanceStatus.HALTED, typeof message == 'object' ? JSON.stringify(message, null, 2) : message)
|
274
271
|
|
275
272
|
throw ex
|
276
273
|
}
|
@@ -376,9 +373,9 @@ export class ScenarioInstance {
|
|
376
373
|
return
|
377
374
|
}
|
378
375
|
|
379
|
-
this.message = `${this.instanceName}:[state changed] ${ScenarioInstanceStatus[this.getState()]} => ${
|
380
|
-
|
381
|
-
}
|
376
|
+
this.message = `${this.instanceName}:[state changed] ${ScenarioInstanceStatus[this.getState()]} => ${ScenarioInstanceStatus[state]}${
|
377
|
+
message ? ' caused by ' + util.inspect(message, false, 2, true) : ''
|
378
|
+
}`
|
382
379
|
|
383
380
|
this.context.state = state
|
384
381
|
|
@@ -421,6 +418,12 @@ export class ScenarioInstance {
|
|
421
418
|
if (this.disposer) {
|
422
419
|
await this.disposer.call(this)
|
423
420
|
}
|
421
|
+
|
422
|
+
// {{ CHECKPOINT 본 인스턴스를 위해서 생성된 logger를 닫는다.
|
423
|
+
if (this.context?.logger) {
|
424
|
+
this.context.logger.close()
|
425
|
+
}
|
426
|
+
// }}
|
424
427
|
}
|
425
428
|
|
426
429
|
async process(step, context): Promise<{ next: string; state: ScenarioInstanceStatus; data: object }> {
|