@things-factory/integration-base 8.0.0-beta.1 → 8.0.0-beta.2
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/package.json +10 -10
- package/server/controllers/index.ts +0 -2
- package/server/controllers/publish-data.ts +0 -29
- package/server/controllers/scenario-controller.ts +0 -156
- package/server/engine/analyzer/analyze-integration.ts +0 -115
- package/server/engine/connection-manager.ts +0 -239
- package/server/engine/connector/echo-back-connector.ts +0 -51
- package/server/engine/connector/echo-back-server.ts +0 -72
- package/server/engine/connector/graphql-connector.ts +0 -126
- package/server/engine/connector/headless-connector.ts +0 -341
- package/server/engine/connector/http-connector.ts +0 -65
- package/server/engine/connector/index.ts +0 -13
- package/server/engine/connector/mqtt-connector.ts +0 -78
- package/server/engine/connector/mssql-connector.ts +0 -152
- package/server/engine/connector/mysql-connector.ts +0 -94
- package/server/engine/connector/operato-connector.ts +0 -264
- package/server/engine/connector/oracle-connector.ts +0 -218
- package/server/engine/connector/postgresql-connector.ts +0 -152
- package/server/engine/connector/proxy-connector.ts +0 -53
- package/server/engine/connector/socket-server.ts +0 -86
- package/server/engine/connector/sqlite-connector.ts +0 -69
- package/server/engine/edge-client.ts +0 -45
- package/server/engine/index.ts +0 -11
- package/server/engine/pending-queue.ts +0 -97
- package/server/engine/resource-pool/headless-pool.ts +0 -136
- package/server/engine/resource-pool/index.ts +0 -1
- package/server/engine/scenario-engine.ts +0 -106
- package/server/engine/task/book-up-scenario.ts +0 -73
- package/server/engine/task/csv-readline.ts +0 -127
- package/server/engine/task/data-accessor.ts +0 -36
- package/server/engine/task/data-mapper.ts +0 -47
- package/server/engine/task/database-query.ts +0 -56
- package/server/engine/task/echo-receive.ts +0 -21
- package/server/engine/task/echo-send.ts +0 -32
- package/server/engine/task/empty-check.ts +0 -38
- package/server/engine/task/end.ts +0 -18
- package/server/engine/task/floating-point.ts +0 -71
- package/server/engine/task/goto.ts +0 -27
- package/server/engine/task/graphql-mutate.ts +0 -79
- package/server/engine/task/graphql-query.ts +0 -78
- package/server/engine/task/headless-post.ts +0 -128
- package/server/engine/task/headless-scrap.ts +0 -83
- package/server/engine/task/http-get.ts +0 -117
- package/server/engine/task/http-post.ts +0 -148
- package/server/engine/task/index.ts +0 -45
- package/server/engine/task/jsonata.ts +0 -45
- package/server/engine/task/local-graphql-mutate.ts +0 -100
- package/server/engine/task/local-graphql-query.ts +0 -100
- package/server/engine/task/log.ts +0 -78
- package/server/engine/task/mqtt-publish.ts +0 -45
- package/server/engine/task/mqtt-subscribe.ts +0 -139
- package/server/engine/task/mssql-procedure.ts +0 -128
- package/server/engine/task/oracle-procedure.ts +0 -124
- package/server/engine/task/pick-pending-scenario.ts +0 -80
- package/server/engine/task/publish.ts +0 -40
- package/server/engine/task/random.ts +0 -53
- package/server/engine/task/reset-pending-queue.ts +0 -17
- package/server/engine/task/script.ts +0 -63
- package/server/engine/task/set-domain.ts +0 -37
- package/server/engine/task/sleep.ts +0 -34
- package/server/engine/task/socket-listener.ts +0 -96
- package/server/engine/task/state-group-read.ts +0 -69
- package/server/engine/task/state-read.ts +0 -56
- package/server/engine/task/state-write.ts +0 -65
- package/server/engine/task/stop-scenario.ts +0 -44
- package/server/engine/task/sub-scenario.ts +0 -57
- package/server/engine/task/switch-goto.ts +0 -43
- package/server/engine/task/switch-range-goto.ts +0 -53
- package/server/engine/task/switch-range-scenario.ts +0 -79
- package/server/engine/task/switch-range-set.ts +0 -48
- package/server/engine/task/switch-scenario.ts +0 -67
- package/server/engine/task/switch-set.ts +0 -37
- package/server/engine/task/throw.ts +0 -27
- package/server/engine/task/utils/headless-pool-for-scenario.ts +0 -71
- package/server/engine/task/utils/substitute.ts +0 -44
- package/server/engine/task/variables.ts +0 -17
- package/server/engine/task-registry.ts +0 -23
- package/server/engine/types.ts +0 -114
- package/server/index.ts +0 -20
- package/server/migrations/index.ts +0 -9
- package/server/restful/index.ts +0 -1
- package/server/restful/unstable/index.ts +0 -7
- package/server/restful/unstable/run-scenario.ts +0 -51
- package/server/restful/unstable/scenario-instance.ts +0 -52
- package/server/restful/unstable/scenario-instances.ts +0 -80
- package/server/restful/unstable/scenario.ts +0 -41
- package/server/restful/unstable/scenarios.ts +0 -69
- package/server/restful/unstable/start-scenario.ts +0 -33
- package/server/restful/unstable/stop-scenario.ts +0 -30
- package/server/routers/scenario-schedule-callback-router.ts +0 -69
- package/server/routers/scenario-view-router.ts +0 -46
- package/server/routes.ts +0 -30
- package/server/service/analysis/analysis-query.ts +0 -13
- package/server/service/analysis/index.ts +0 -3
- package/server/service/connection/connection-mutation.ts +0 -190
- package/server/service/connection/connection-query.ts +0 -87
- package/server/service/connection/connection-subscription.ts +0 -104
- package/server/service/connection/connection-type.ts +0 -288
- package/server/service/connection/index.ts +0 -7
- package/server/service/connector/connector-query.ts +0 -62
- package/server/service/connector/connector-type.ts +0 -29
- package/server/service/connector/index.ts +0 -4
- package/server/service/index.ts +0 -52
- package/server/service/payload-log/index.ts +0 -7
- package/server/service/payload-log/payload-log-mutation.ts +0 -151
- package/server/service/payload-log/payload-log-query.ts +0 -49
- package/server/service/payload-log/payload-log-type.ts +0 -36
- package/server/service/payload-log/payload-log.ts +0 -100
- package/server/service/property-spec.ts +0 -24
- package/server/service/scenario/index.ts +0 -6
- package/server/service/scenario/scenario-mutation.ts +0 -396
- package/server/service/scenario/scenario-query.ts +0 -109
- package/server/service/scenario/scenario-type.ts +0 -78
- package/server/service/scenario/scenario.ts +0 -124
- package/server/service/scenario-flow/scenario-flow.ts +0 -17
- package/server/service/scenario-instance/index.ts +0 -6
- package/server/service/scenario-instance/scenario-instance-mutation.ts +0 -44
- package/server/service/scenario-instance/scenario-instance-query.ts +0 -42
- package/server/service/scenario-instance/scenario-instance-subscription.ts +0 -118
- package/server/service/scenario-instance/scenario-instance-type.ts +0 -563
- package/server/service/scenario-queue/index.ts +0 -4
- package/server/service/scenario-queue/scenario-queue-subscription.ts +0 -55
- package/server/service/scenario-queue/scenario-queue-type.ts +0 -27
- package/server/service/state-register/data-resolver.ts +0 -56
- package/server/service/state-register/index.ts +0 -8
- package/server/service/state-register/state-register-mutation.ts +0 -166
- package/server/service/state-register/state-register-query.ts +0 -80
- package/server/service/state-register/state-register-type.ts +0 -80
- package/server/service/state-register/state-register.ts +0 -113
- package/server/service/step/index.ts +0 -6
- package/server/service/step/step-mutation.ts +0 -52
- package/server/service/step/step-query.ts +0 -55
- package/server/service/step/step-type.ts +0 -215
- package/server/service/task-type/index.ts +0 -4
- package/server/service/task-type/task-type-query.ts +0 -95
- package/server/service/task-type/task-type-type.ts +0 -29
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@things-factory/integration-base",
|
3
|
-
"version": "8.0.0-beta.
|
3
|
+
"version": "8.0.0-beta.2",
|
4
4
|
"main": "dist-server/index.js",
|
5
5
|
"browser": "client/index.js",
|
6
6
|
"things-factory": true,
|
@@ -27,14 +27,14 @@
|
|
27
27
|
"dependencies": {
|
28
28
|
"@apollo/client": "^3.6.9",
|
29
29
|
"@operato/moment-timezone-es": "^8.0.0-beta",
|
30
|
-
"@things-factory/api": "^8.0.0-beta.
|
31
|
-
"@things-factory/auth-base": "^8.0.0-beta.
|
32
|
-
"@things-factory/cache-service": "^8.0.0-beta.
|
33
|
-
"@things-factory/env": "^8.0.0-beta.
|
34
|
-
"@things-factory/oauth2-client": "^8.0.0-beta.
|
35
|
-
"@things-factory/scheduler-client": "^8.0.0-beta.
|
36
|
-
"@things-factory/shell": "^8.0.0-beta.
|
37
|
-
"@things-factory/utils": "^8.0.0-beta.
|
30
|
+
"@things-factory/api": "^8.0.0-beta.2",
|
31
|
+
"@things-factory/auth-base": "^8.0.0-beta.2",
|
32
|
+
"@things-factory/cache-service": "^8.0.0-beta.2",
|
33
|
+
"@things-factory/env": "^8.0.0-beta.2",
|
34
|
+
"@things-factory/oauth2-client": "^8.0.0-beta.2",
|
35
|
+
"@things-factory/scheduler-client": "^8.0.0-beta.2",
|
36
|
+
"@things-factory/shell": "^8.0.0-beta.2",
|
37
|
+
"@things-factory/utils": "^8.0.0-beta.2",
|
38
38
|
"async-mqtt": "^2.5.0",
|
39
39
|
"chance": "^1.1.11",
|
40
40
|
"cross-fetch": "^3.0.4",
|
@@ -45,5 +45,5 @@
|
|
45
45
|
"readline": "^1.3.0",
|
46
46
|
"ses": "^1.5.0"
|
47
47
|
},
|
48
|
-
"gitHead": "
|
48
|
+
"gitHead": "f03431a09435511b2595515658f9cb8f78ba4ebb"
|
49
49
|
}
|
@@ -1,29 +0,0 @@
|
|
1
|
-
import { Domain, getRepository, pubsub } from '@things-factory/shell'
|
2
|
-
import { User } from '@things-factory/auth-base'
|
3
|
-
|
4
|
-
import { StateRegister } from '../service/state-register/state-register'
|
5
|
-
|
6
|
-
export async function publishData(tag: string, data: any, { domain, user }: { domain: Domain; user: User }) {
|
7
|
-
const repository = getRepository(StateRegister)
|
8
|
-
|
9
|
-
const stateRegister = await repository.findOne({
|
10
|
-
where: { domain: { id: domain?.id }, name: tag }
|
11
|
-
})
|
12
|
-
|
13
|
-
if (stateRegister) {
|
14
|
-
await repository.save({
|
15
|
-
...stateRegister,
|
16
|
-
state: data,
|
17
|
-
writer: user,
|
18
|
-
wroteAt: new Date()
|
19
|
-
})
|
20
|
-
}
|
21
|
-
|
22
|
-
pubsub.publish('data', {
|
23
|
-
data: {
|
24
|
-
domain,
|
25
|
-
tag,
|
26
|
-
data
|
27
|
-
}
|
28
|
-
})
|
29
|
-
}
|
@@ -1,156 +0,0 @@
|
|
1
|
-
import { getRepository, Domain, GraphqlLocalClient } from '@things-factory/shell'
|
2
|
-
import { checkUserHasRole } from '@things-factory/auth-base'
|
3
|
-
import { cacheService } from '@things-factory/cache-service'
|
4
|
-
|
5
|
-
import { ScenarioEngine } from '../engine/scenario-engine'
|
6
|
-
import { Scenario } from '../service/scenario/scenario'
|
7
|
-
import { ScenarioInstance, ScenarioInstanceRunResult } from '../service/scenario-instance/scenario-instance-type'
|
8
|
-
import { Step } from '../service/step/step-type'
|
9
|
-
|
10
|
-
const debug = require('debug')('things-factory:integration-base:controller:run-scenario')
|
11
|
-
|
12
|
-
async function findScenario(
|
13
|
-
scenarioName: string,
|
14
|
-
domain: Domain
|
15
|
-
): Promise<{
|
16
|
-
id: string
|
17
|
-
ttl: number
|
18
|
-
name: string
|
19
|
-
steps: Step[]
|
20
|
-
domain: Domain
|
21
|
-
}> {
|
22
|
-
var repository = getRepository(Scenario)
|
23
|
-
|
24
|
-
var scenario = await repository.findOne({
|
25
|
-
where: { domain: { id: domain.id }, name: scenarioName },
|
26
|
-
relations: ['domain', 'steps', 'role', 'creator', 'updater']
|
27
|
-
})
|
28
|
-
|
29
|
-
if (!scenario && domain.parentId) {
|
30
|
-
scenario = await repository.findOne({
|
31
|
-
where: { domain: { id: domain.parentId }, name: scenarioName },
|
32
|
-
relations: ['domain', 'steps', 'role', 'creator', 'updater']
|
33
|
-
})
|
34
|
-
}
|
35
|
-
|
36
|
-
return scenario as any
|
37
|
-
}
|
38
|
-
|
39
|
-
export async function checkHasRole(scenario: Partial<Scenario>, context: ResolverContext): Promise<void> {
|
40
|
-
const { domain, user } = context.state
|
41
|
-
if (!(await checkUserHasRole(scenario.roleId, domain, user))) {
|
42
|
-
throw new Error(
|
43
|
-
context.t('error.scenario run unauthorized', {
|
44
|
-
scenario: scenario.name
|
45
|
-
})
|
46
|
-
)
|
47
|
-
}
|
48
|
-
}
|
49
|
-
|
50
|
-
export async function runScenario(
|
51
|
-
instanceName: string,
|
52
|
-
scenarioName: string,
|
53
|
-
variables: any,
|
54
|
-
context: ResolverContext
|
55
|
-
): Promise<ScenarioInstanceRunResult> {
|
56
|
-
const { domain, user, lng } = context.state
|
57
|
-
|
58
|
-
debug('runScenario', scenarioName, instanceName, variables)
|
59
|
-
|
60
|
-
var scenario = await findScenario(scenarioName, domain)
|
61
|
-
|
62
|
-
if (!scenario) {
|
63
|
-
throw new Error(
|
64
|
-
context.t('error.scenario not found', {
|
65
|
-
scenario: scenarioName
|
66
|
-
})
|
67
|
-
)
|
68
|
-
}
|
69
|
-
|
70
|
-
await checkHasRole(scenario, context)
|
71
|
-
|
72
|
-
if (scenario.ttl > 0) {
|
73
|
-
const cachedValue = await cacheService.getFromCache(scenario.id, { domain: domain.id, variables: variables || {} })
|
74
|
-
if (cachedValue) {
|
75
|
-
return cachedValue.value
|
76
|
-
}
|
77
|
-
}
|
78
|
-
|
79
|
-
/* 시나리오 인스턴스를 생성한다. */
|
80
|
-
instanceName = instanceName || scenarioName + '-' + String(Date.now())
|
81
|
-
var instance = new ScenarioInstance(instanceName, scenario, {
|
82
|
-
domain,
|
83
|
-
user,
|
84
|
-
lng,
|
85
|
-
variables,
|
86
|
-
client: GraphqlLocalClient.client
|
87
|
-
})
|
88
|
-
|
89
|
-
try {
|
90
|
-
return await instance.run()
|
91
|
-
} catch (err) {
|
92
|
-
console.error(err)
|
93
|
-
|
94
|
-
throw new Error(
|
95
|
-
context.t('error.scenario run error', {
|
96
|
-
scenario: scenarioName
|
97
|
-
})
|
98
|
-
)
|
99
|
-
}
|
100
|
-
}
|
101
|
-
|
102
|
-
export async function startScenario(
|
103
|
-
instanceName: string,
|
104
|
-
scenarioName: string,
|
105
|
-
variables: any,
|
106
|
-
context: ResolverContext
|
107
|
-
): Promise<ScenarioInstance> {
|
108
|
-
const { domain, user, lng } = context.state
|
109
|
-
|
110
|
-
debug('startScenario', instanceName, scenarioName, variables)
|
111
|
-
|
112
|
-
var scenario = await findScenario(scenarioName, domain)
|
113
|
-
|
114
|
-
if (!scenario) {
|
115
|
-
throw new Error(
|
116
|
-
context.t('error.scenario not found', {
|
117
|
-
scenario: scenarioName
|
118
|
-
})
|
119
|
-
)
|
120
|
-
}
|
121
|
-
|
122
|
-
await checkHasRole(scenario, context)
|
123
|
-
|
124
|
-
instanceName = instanceName || scenarioName
|
125
|
-
return await ScenarioEngine.load(instanceName, scenario, { domain, user, lng, variables })
|
126
|
-
}
|
127
|
-
|
128
|
-
export async function stopScenario(
|
129
|
-
instanceName: string,
|
130
|
-
context: ResolverContext
|
131
|
-
): Promise<ScenarioInstance | undefined> {
|
132
|
-
const { domain, user, unsafeIP, prohibitedPrivileges } = context.state
|
133
|
-
|
134
|
-
debug('stopScenario', instanceName)
|
135
|
-
|
136
|
-
runScenario
|
137
|
-
|
138
|
-
var scenarioInstance = ScenarioEngine.getScenarioInstance(domain, instanceName)
|
139
|
-
|
140
|
-
if (!scenarioInstance) {
|
141
|
-
debug('stopScenario', `ScenarioInstance(${instanceName}) Not Found.`)
|
142
|
-
throw new Error(
|
143
|
-
context.t('error.scenario instance not found', {
|
144
|
-
instance: instanceName
|
145
|
-
})
|
146
|
-
)
|
147
|
-
}
|
148
|
-
|
149
|
-
var scenario = await findScenario(scenarioInstance.scenarioName, domain)
|
150
|
-
|
151
|
-
await checkHasRole(scenario, context)
|
152
|
-
|
153
|
-
await ScenarioEngine.unload(domain, instanceName)
|
154
|
-
|
155
|
-
return scenarioInstance
|
156
|
-
}
|
@@ -1,115 +0,0 @@
|
|
1
|
-
import uniq from 'lodash/uniq'
|
2
|
-
|
3
|
-
import { Domain, getRepository } from '@things-factory/shell'
|
4
|
-
import { Scenario } from '../../service/scenario/scenario'
|
5
|
-
import { Connection } from '../../service/connection/connection-type'
|
6
|
-
|
7
|
-
export async function analyzeIntegration(domain: Domain) {
|
8
|
-
const tagNames = []
|
9
|
-
|
10
|
-
const model = {
|
11
|
-
nodes: [],
|
12
|
-
relationships: []
|
13
|
-
}
|
14
|
-
|
15
|
-
var id = 0
|
16
|
-
|
17
|
-
const scenarios = await getRepository(Scenario).find({
|
18
|
-
where: { domain: { id: domain.id } },
|
19
|
-
relations: ['steps']
|
20
|
-
})
|
21
|
-
|
22
|
-
const connections = await getRepository(Connection).find({
|
23
|
-
where: { domain: { id: domain.id } }
|
24
|
-
})
|
25
|
-
|
26
|
-
model.nodes = model.nodes.concat(
|
27
|
-
scenarios.map(scenario => {
|
28
|
-
return {
|
29
|
-
id: scenario.id,
|
30
|
-
labels: ['Scenario'],
|
31
|
-
text: scenario.name,
|
32
|
-
icon: 'settings',
|
33
|
-
properties: {
|
34
|
-
name: scenario.name,
|
35
|
-
description: scenario.description
|
36
|
-
}
|
37
|
-
}
|
38
|
-
})
|
39
|
-
)
|
40
|
-
|
41
|
-
model.nodes = model.nodes.concat(
|
42
|
-
connections.map(connection => {
|
43
|
-
return {
|
44
|
-
id: connection.id,
|
45
|
-
labels: ['Connection'],
|
46
|
-
text: connection.name,
|
47
|
-
icon: 'link',
|
48
|
-
properties: {
|
49
|
-
name: connection.name,
|
50
|
-
description: connection.description
|
51
|
-
}
|
52
|
-
}
|
53
|
-
})
|
54
|
-
)
|
55
|
-
|
56
|
-
scenarios.forEach(scenario => {
|
57
|
-
const connectionNames = uniq(scenario.steps.map(step => step.connection).filter(Boolean))
|
58
|
-
const connectionList = connectionNames
|
59
|
-
.map(connectionName => connections.find(connection => connection.name == connectionName))
|
60
|
-
.filter(Boolean)
|
61
|
-
|
62
|
-
const relationships = connectionList.map(connection => {
|
63
|
-
return {
|
64
|
-
id: ++id,
|
65
|
-
type: 'using',
|
66
|
-
startNode: scenario.id,
|
67
|
-
endNode: connection.id,
|
68
|
-
properties: {}
|
69
|
-
}
|
70
|
-
})
|
71
|
-
|
72
|
-
model.relationships = model.relationships.concat(relationships)
|
73
|
-
})
|
74
|
-
|
75
|
-
scenarios.forEach(scenario => {
|
76
|
-
const tags = uniq(
|
77
|
-
scenario.steps
|
78
|
-
.filter(step => !step.connection && step.task == 'publish')
|
79
|
-
.map(step => JSON.parse(step.params)?.tag)
|
80
|
-
.filter(Boolean)
|
81
|
-
)
|
82
|
-
|
83
|
-
for (const tag of tags) {
|
84
|
-
if (tagNames.includes(tag)) {
|
85
|
-
continue
|
86
|
-
}
|
87
|
-
|
88
|
-
model.nodes.push({
|
89
|
-
id: `tag-${tag}`,
|
90
|
-
labels: ['Tag'],
|
91
|
-
text: tag,
|
92
|
-
icon: 'label',
|
93
|
-
properties: {
|
94
|
-
tag
|
95
|
-
}
|
96
|
-
})
|
97
|
-
|
98
|
-
tagNames.push(tag)
|
99
|
-
}
|
100
|
-
|
101
|
-
const relationships = tags.map(tag => {
|
102
|
-
return {
|
103
|
-
id: ++id,
|
104
|
-
type: 'publish',
|
105
|
-
startNode: scenario.id,
|
106
|
-
endNode: `tag-${tag}`,
|
107
|
-
properties: {}
|
108
|
-
}
|
109
|
-
})
|
110
|
-
|
111
|
-
model.relationships = model.relationships.concat(relationships)
|
112
|
-
})
|
113
|
-
|
114
|
-
return model
|
115
|
-
}
|
@@ -1,239 +0,0 @@
|
|
1
|
-
import moment from 'moment-timezone'
|
2
|
-
import { createLogger, format, transports } from 'winston'
|
3
|
-
|
4
|
-
import { Domain, getRepository, pubsub, PubSubLogTransport } from '@things-factory/shell'
|
5
|
-
|
6
|
-
import { Connection, ConnectionStatus } from '../service'
|
7
|
-
import { Connector } from './types'
|
8
|
-
import { ProxyConnector } from './connector/proxy-connector'
|
9
|
-
|
10
|
-
const { combine, splat, printf, errors } = format
|
11
|
-
const debug = require('debug')('things-factory:integration-base:connections')
|
12
|
-
|
13
|
-
function getSystemTimeZone() {
|
14
|
-
try {
|
15
|
-
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone
|
16
|
-
if (!timeZone) {
|
17
|
-
throw new Error('Unable to resolve timeZone')
|
18
|
-
}
|
19
|
-
return timeZone
|
20
|
-
} catch (e) {
|
21
|
-
console.warn('Failed to get system timeZone, falling back to UTC.', e)
|
22
|
-
return 'UTC'
|
23
|
-
}
|
24
|
-
}
|
25
|
-
|
26
|
-
const SYSTEM_TZ = getSystemTimeZone()
|
27
|
-
const systemTimestamp = format((info, opts: { tz?: string }) => {
|
28
|
-
if (opts.tz) info.timestamp = moment().tz(opts.tz).format()
|
29
|
-
return info
|
30
|
-
})
|
31
|
-
|
32
|
-
export class ConnectionManager {
|
33
|
-
private static connectors: { [propName: string]: Connector } = {}
|
34
|
-
private static connections: { [domainId: string]: { [name: string]: any } } = {}
|
35
|
-
private static entities = {}
|
36
|
-
private static logFormat = printf(({ level, message, timestamp, stack }) => {
|
37
|
-
return `${timestamp} ${level}: ${stack || message}`
|
38
|
-
})
|
39
|
-
|
40
|
-
public static logger = createLogger({
|
41
|
-
format: combine(errors({ stack: true }), systemTimestamp({ tz: SYSTEM_TZ }), splat(), ConnectionManager.logFormat),
|
42
|
-
transports: [
|
43
|
-
new (transports as any).DailyRotateFile({
|
44
|
-
filename: `logs/connections-%DATE%.log`,
|
45
|
-
datePattern: 'YYYY-MM-DD-HH',
|
46
|
-
zippedArchive: false,
|
47
|
-
maxSize: '20m',
|
48
|
-
maxFiles: '14d',
|
49
|
-
level: 'info'
|
50
|
-
}),
|
51
|
-
new PubSubLogTransport({
|
52
|
-
topic: 'connection-log'
|
53
|
-
})
|
54
|
-
]
|
55
|
-
})
|
56
|
-
|
57
|
-
static async ready() {
|
58
|
-
const CONNECTIONS = (
|
59
|
-
await getRepository(Connection).find({
|
60
|
-
where: { active: true },
|
61
|
-
relations: ['domain', 'edge', 'creator', 'updater']
|
62
|
-
})
|
63
|
-
).map(connection => {
|
64
|
-
var params = {}
|
65
|
-
try {
|
66
|
-
params = JSON.parse(connection.params || '{}')
|
67
|
-
} catch (ex) {
|
68
|
-
ConnectionManager.logger.error(`connection '${connection.name}' params should be JSON format`, ex)
|
69
|
-
}
|
70
|
-
|
71
|
-
return {
|
72
|
-
...connection,
|
73
|
-
params
|
74
|
-
}
|
75
|
-
})
|
76
|
-
|
77
|
-
ConnectionManager.logger.info('Initializing ConnectionManager...')
|
78
|
-
|
79
|
-
return await Promise.all(
|
80
|
-
[...Object.keys(ConnectionManager.connectors), 'proxy-connector'].map(type => {
|
81
|
-
const connector = type == 'proxy-connector' ? ProxyConnector.instance : ConnectionManager.getConnector(type)
|
82
|
-
|
83
|
-
ConnectionManager.logger.info(`Connector '${type}' started to ready`)
|
84
|
-
|
85
|
-
return connector
|
86
|
-
.ready(
|
87
|
-
CONNECTIONS.filter(connection => {
|
88
|
-
if (type == 'proxy-connector') {
|
89
|
-
return !!connection.edge
|
90
|
-
} else {
|
91
|
-
return !connection.edge && connection.type == type
|
92
|
-
}
|
93
|
-
}) as any
|
94
|
-
)
|
95
|
-
.catch(error => {
|
96
|
-
ConnectionManager.logger.error(error)
|
97
|
-
})
|
98
|
-
.then(() => {
|
99
|
-
ConnectionManager.logger.info(`All connector for '${type}' ready`)
|
100
|
-
})
|
101
|
-
})
|
102
|
-
).then(() => {
|
103
|
-
ConnectionManager.logger.info('ConnectionManager initialization done:')
|
104
|
-
Object.keys(ConnectionManager.connections).forEach(key => {
|
105
|
-
var connections = ConnectionManager.connections[key]
|
106
|
-
ConnectionManager.logger.info('For domain(%s) : %s', key, JSON.stringify(Object.keys(connections)))
|
107
|
-
})
|
108
|
-
})
|
109
|
-
}
|
110
|
-
|
111
|
-
static registerConnector(type: string, connector: Connector) {
|
112
|
-
ConnectionManager.connectors[type] = connector
|
113
|
-
}
|
114
|
-
|
115
|
-
static getConnector(type: string): Connector {
|
116
|
-
return ConnectionManager.connectors[type]
|
117
|
-
}
|
118
|
-
|
119
|
-
static getConnectors(): { [connectorName: string]: Connector } {
|
120
|
-
return {
|
121
|
-
...ConnectionManager.connectors
|
122
|
-
}
|
123
|
-
}
|
124
|
-
|
125
|
-
static unregisterConnector(type: string) {
|
126
|
-
delete ConnectionManager.connectors[type]
|
127
|
-
}
|
128
|
-
|
129
|
-
static getConnections() {
|
130
|
-
return ConnectionManager.connections
|
131
|
-
}
|
132
|
-
|
133
|
-
static getEntities() {
|
134
|
-
return ConnectionManager.entities
|
135
|
-
}
|
136
|
-
|
137
|
-
static getConnectionInstance(connection: Connection): any {
|
138
|
-
const { domain, name } = connection
|
139
|
-
return ConnectionManager.connections[domain.id]?.[name]
|
140
|
-
}
|
141
|
-
|
142
|
-
static getConnectionInstanceByName(domain: Domain, name: string) {
|
143
|
-
const connections = ConnectionManager.connections[domain.id]
|
144
|
-
const connection = connections?.[name]
|
145
|
-
|
146
|
-
if (!connection) {
|
147
|
-
throw `The connection with the given name(${name}) cannot be found`
|
148
|
-
}
|
149
|
-
|
150
|
-
return connection
|
151
|
-
}
|
152
|
-
|
153
|
-
static getConnectionInstanceEntityByName(domain: Domain, name: string): any {
|
154
|
-
const connection = ConnectionManager.entities[domain.id]?.[name]
|
155
|
-
if (connection) {
|
156
|
-
return connection
|
157
|
-
}
|
158
|
-
|
159
|
-
if (domain.parentId) {
|
160
|
-
return ConnectionManager.entities[domain.id]?.[name]
|
161
|
-
}
|
162
|
-
}
|
163
|
-
|
164
|
-
static getConnectionInstances(domain: Domain): { [connectionName: string]: any } {
|
165
|
-
const connections = ConnectionManager.connections[domain.id]
|
166
|
-
const parentConnections = domain.parentId && ConnectionManager.connections[domain.parentId]
|
167
|
-
|
168
|
-
return {
|
169
|
-
...parentConnections,
|
170
|
-
...connections
|
171
|
-
}
|
172
|
-
}
|
173
|
-
|
174
|
-
static getConnectionInstanceEntities(domain: Domain): { [connectionName: string]: any } {
|
175
|
-
const connections = ConnectionManager.entities[domain.id]
|
176
|
-
|
177
|
-
return {
|
178
|
-
...connections
|
179
|
-
}
|
180
|
-
}
|
181
|
-
|
182
|
-
static addConnectionInstance(connection: Connection, instance: any) {
|
183
|
-
const { domain, name } = connection
|
184
|
-
|
185
|
-
var connections = ConnectionManager.connections[domain.id]
|
186
|
-
if (!connections) {
|
187
|
-
connections = ConnectionManager.connections[domain.id] = {}
|
188
|
-
}
|
189
|
-
|
190
|
-
var entities = ConnectionManager.entities[domain.id]
|
191
|
-
if (!entities) {
|
192
|
-
entities = ConnectionManager.entities[domain.id] = {}
|
193
|
-
}
|
194
|
-
|
195
|
-
connections[name] = instance
|
196
|
-
entities[name] = connection
|
197
|
-
|
198
|
-
ConnectionManager.publishState(connection, ConnectionStatus.CONNECTED)
|
199
|
-
debug('add-connection', domain.subdomain, name)
|
200
|
-
}
|
201
|
-
|
202
|
-
static removeConnectionInstance(connection: Connection): any {
|
203
|
-
const { domain, name } = connection
|
204
|
-
var connections = ConnectionManager.connections[domain.id]
|
205
|
-
var entities = ConnectionManager.entities[domain.id]
|
206
|
-
|
207
|
-
var instance = connections?.[name]
|
208
|
-
|
209
|
-
if (!connections || !instance) {
|
210
|
-
debug('remove-connection', `'${name}' connection not found in domain '${domain.subdomain}'`)
|
211
|
-
return
|
212
|
-
}
|
213
|
-
|
214
|
-
delete connections[name]
|
215
|
-
delete entities[name]
|
216
|
-
|
217
|
-
ConnectionManager.publishState(connection, ConnectionStatus.DISCONNECTED)
|
218
|
-
debug('remove-connection', `'${name}' connection is removed from domain '${domain.subdomain}'`)
|
219
|
-
|
220
|
-
return instance
|
221
|
-
}
|
222
|
-
|
223
|
-
private static async publishState(connection: Connection, state) {
|
224
|
-
const { domain, id, name, description, type, edge } = connection
|
225
|
-
|
226
|
-
pubsub.publish('connection-state', {
|
227
|
-
connectionState: {
|
228
|
-
domain,
|
229
|
-
id,
|
230
|
-
name,
|
231
|
-
description,
|
232
|
-
type,
|
233
|
-
edge,
|
234
|
-
state,
|
235
|
-
timestamp: new Date()
|
236
|
-
}
|
237
|
-
})
|
238
|
-
}
|
239
|
-
}
|
@@ -1,51 +0,0 @@
|
|
1
|
-
import net from 'net'
|
2
|
-
import PromiseSocket from 'promise-socket'
|
3
|
-
|
4
|
-
import { Connector } from '../types'
|
5
|
-
import { ConnectionManager } from '../connection-manager'
|
6
|
-
import { InputConnection } from '../../service/connection/connection-type'
|
7
|
-
|
8
|
-
export class EchoBack implements Connector {
|
9
|
-
async ready(connectionConfigs) {
|
10
|
-
await Promise.all(connectionConfigs.map(this.connect.bind(this)))
|
11
|
-
|
12
|
-
ConnectionManager.logger.info('echo-back connections are ready')
|
13
|
-
}
|
14
|
-
|
15
|
-
async connect(connection: InputConnection) {
|
16
|
-
let socket = new PromiseSocket(new net.Socket())
|
17
|
-
let [host, port = 8124] = connection.endpoint.split(':')
|
18
|
-
|
19
|
-
try {
|
20
|
-
await socket.connect(Number(port), host)
|
21
|
-
ConnectionManager.addConnectionInstance(connection, socket)
|
22
|
-
|
23
|
-
ConnectionManager.logger.info(
|
24
|
-
`echo-back-connector connection(${connection.name}:${connection.endpoint}) is connected`
|
25
|
-
)
|
26
|
-
} catch (e) {
|
27
|
-
ConnectionManager.logger.error(
|
28
|
-
`echo-back-connector connection(${connection.name}:${connection.endpoint}) is not connected.`,
|
29
|
-
e
|
30
|
-
)
|
31
|
-
}
|
32
|
-
}
|
33
|
-
|
34
|
-
async disconnect(connection: InputConnection) {
|
35
|
-
let socket = ConnectionManager.removeConnectionInstance(connection)
|
36
|
-
|
37
|
-
await socket.destroy()
|
38
|
-
|
39
|
-
ConnectionManager.logger.info(`echo-back-connector connection(${connection.name}) is disconnected`)
|
40
|
-
}
|
41
|
-
|
42
|
-
get parameterSpec() {
|
43
|
-
return []
|
44
|
-
}
|
45
|
-
|
46
|
-
get taskPrefixes() {
|
47
|
-
return ['echo']
|
48
|
-
}
|
49
|
-
}
|
50
|
-
|
51
|
-
ConnectionManager.registerConnector('echo-back', new EchoBack())
|
@@ -1,72 +0,0 @@
|
|
1
|
-
import net from 'net'
|
2
|
-
import PromiseSocket from 'promise-socket'
|
3
|
-
|
4
|
-
import { Connector } from '../types'
|
5
|
-
import { ConnectionManager } from '../connection-manager'
|
6
|
-
import { InputConnection } from '../../service/connection/connection-type'
|
7
|
-
|
8
|
-
export class EchoBack implements Connector {
|
9
|
-
async ready(connectionConfigs: InputConnection[]) {
|
10
|
-
await Promise.all(connectionConfigs.map(this.connect.bind(this)))
|
11
|
-
|
12
|
-
ConnectionManager.logger.info('echo-back-servers are ready')
|
13
|
-
}
|
14
|
-
|
15
|
-
async connect(config: InputConnection): Promise<void> {
|
16
|
-
var [host = '0.0.0.0', port = 8124] = config.endpoint.split(':')
|
17
|
-
|
18
|
-
return new Promise((resolve, reject) => {
|
19
|
-
var server = net.createServer(socket => {
|
20
|
-
socket.on('data', function (data) {
|
21
|
-
socket.write(data.toString())
|
22
|
-
})
|
23
|
-
|
24
|
-
socket.on('error', function (err) {
|
25
|
-
ConnectionManager.logger.error(err)
|
26
|
-
reject(err)
|
27
|
-
})
|
28
|
-
})
|
29
|
-
|
30
|
-
server.listen(port, async () => {
|
31
|
-
ConnectionManager.logger.info(`Echo-back server listening on ${host}:${port}`)
|
32
|
-
|
33
|
-
/* default client connection */
|
34
|
-
let socket = new net.Socket()
|
35
|
-
socket.on('error', console.error)
|
36
|
-
|
37
|
-
try {
|
38
|
-
let promiseSocket = new PromiseSocket(socket)
|
39
|
-
await promiseSocket.connect(Number(port), 'localhost')
|
40
|
-
promiseSocket['__server__'] = server
|
41
|
-
|
42
|
-
ConnectionManager.addConnectionInstance(config, promiseSocket)
|
43
|
-
|
44
|
-
ConnectionManager.logger.info(`echo-back-server connection(${config.name}:${config.endpoint}) is connected`)
|
45
|
-
|
46
|
-
resolve()
|
47
|
-
} catch (err) {
|
48
|
-
ConnectionManager.logger.error(
|
49
|
-
`echo-back-server connection(${config.name}:${config.endpoint}) is connected.\ncause: ${err}`
|
50
|
-
)
|
51
|
-
reject(err)
|
52
|
-
}
|
53
|
-
})
|
54
|
-
})
|
55
|
-
}
|
56
|
-
|
57
|
-
async disconnect(connection: InputConnection) {
|
58
|
-
let socket = ConnectionManager.removeConnectionInstance(connection)
|
59
|
-
var server = socket['__server__']
|
60
|
-
|
61
|
-
await socket.destroy()
|
62
|
-
server && (await server.close())
|
63
|
-
|
64
|
-
ConnectionManager.logger.info(`echo-back-server connection(${connection.name}) is disconnected`)
|
65
|
-
}
|
66
|
-
|
67
|
-
get parameterSpec() {
|
68
|
-
return []
|
69
|
-
}
|
70
|
-
}
|
71
|
-
|
72
|
-
ConnectionManager.registerConnector('echo-back-server', new EchoBack())
|