@things-factory/integration-base 7.0.0-alpha.9 → 7.0.1-alpha.1

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.
Files changed (50) hide show
  1. package/dist-server/engine/connection-manager.js +37 -6
  2. package/dist-server/engine/connection-manager.js.map +1 -1
  3. package/dist-server/engine/connector/graphql-connector.js +6 -6
  4. package/dist-server/engine/connector/graphql-connector.js.map +1 -1
  5. package/dist-server/engine/connector/operato-connector.js +19 -22
  6. package/dist-server/engine/connector/operato-connector.js.map +1 -1
  7. package/dist-server/engine/connector/proxy-connector.js +44 -0
  8. package/dist-server/engine/connector/proxy-connector.js.map +1 -0
  9. package/dist-server/engine/edge-client.js +38 -0
  10. package/dist-server/engine/edge-client.js.map +1 -0
  11. package/dist-server/engine/index.js +1 -0
  12. package/dist-server/engine/index.js.map +1 -1
  13. package/dist-server/engine/task/script.js +1 -0
  14. package/dist-server/engine/task/script.js.map +1 -1
  15. package/dist-server/engine/types.js.map +1 -1
  16. package/dist-server/service/connection/connection-mutation.js +4 -8
  17. package/dist-server/service/connection/connection-mutation.js.map +1 -1
  18. package/dist-server/service/connection/connection-query.js +17 -14
  19. package/dist-server/service/connection/connection-query.js.map +1 -1
  20. package/dist-server/service/connection/connection-subscription.js +1 -1
  21. package/dist-server/service/connection/connection-subscription.js.map +1 -1
  22. package/dist-server/service/connection/connection-type.js +32 -8
  23. package/dist-server/service/connection/connection-type.js.map +1 -1
  24. package/dist-server/service/scenario-instance/scenario-instance-type.js +12 -4
  25. package/dist-server/service/scenario-instance/scenario-instance-type.js.map +1 -1
  26. package/dist-server/tsconfig.tsbuildinfo +1 -1
  27. package/helps/integration/concept/script-internal-variables.ja.md +21 -1
  28. package/helps/integration/concept/script-internal-variables.ko.md +17 -0
  29. package/helps/integration/concept/script-internal-variables.md +18 -0
  30. package/helps/integration/concept/script-internal-variables.ms.md +19 -1
  31. package/helps/integration/concept/script-internal-variables.zh.md +18 -0
  32. package/helps/integration/task/script.ja.md +1 -1
  33. package/helps/integration/task/script.ko.md +1 -1
  34. package/helps/integration/task/script.md +1 -1
  35. package/helps/integration/task/script.ms.md +1 -1
  36. package/helps/integration/task/script.zh.md +1 -1
  37. package/package.json +10 -10
  38. package/server/engine/connection-manager.ts +49 -7
  39. package/server/engine/connector/graphql-connector.ts +8 -10
  40. package/server/engine/connector/operato-connector.ts +22 -32
  41. package/server/engine/connector/proxy-connector.ts +53 -0
  42. package/server/engine/edge-client.ts +45 -0
  43. package/server/engine/index.ts +1 -0
  44. package/server/engine/task/script.ts +1 -0
  45. package/server/engine/types.ts +45 -46
  46. package/server/service/connection/connection-mutation.ts +9 -29
  47. package/server/service/connection/connection-query.ts +13 -12
  48. package/server/service/connection/connection-subscription.ts +1 -1
  49. package/server/service/connection/connection-type.ts +53 -41
  50. package/server/service/scenario-instance/scenario-instance-type.ts +13 -5
@@ -0,0 +1,45 @@
1
+ import { Connection } from '../service/connection/connection-type'
2
+ import { Step } from '../service/step/step-type'
3
+ import { Context, TaskHandler } from './types'
4
+
5
+ export type EdgeClient = {
6
+ handler: TaskHandler
7
+ syncConnections(connections: Connection[], context?: ResolverContext): Promise<any>
8
+ connectConnections(connections: Connection[], context?: ResolverContext): Promise<any>
9
+ disconnectConnections(connections: Connection[], context?: ResolverContext): Promise<any>
10
+ }
11
+
12
+ var edgeClient: EdgeClient = {
13
+ async handler(step: Step, scenarioContext: Context) {
14
+ throw 'edgeClient not supported'
15
+ },
16
+ async syncConnections(connections: Connection[], context: ResolverContext): Promise<any> {
17
+ throw 'edgeClient not supported'
18
+ },
19
+ async connectConnections(connections: Connection[], context: ResolverContext): Promise<any> {
20
+ throw 'edgeClient not supported'
21
+ },
22
+ async disconnectConnections(connections: Connection[], context: ResolverContext): Promise<any> {
23
+ throw 'edgeClient not supported'
24
+ }
25
+ }
26
+
27
+ export async function handler(step: Step, scenarioContext: Context) {
28
+ return await edgeClient.handler(step, scenarioContext)
29
+ }
30
+
31
+ export async function syncConnections(connections: Connection[], context?: ResolverContext): Promise<any> {
32
+ return await edgeClient.syncConnections(connections, context)
33
+ }
34
+
35
+ export async function connectConnections(connections: Connection[], context?: ResolverContext): Promise<any> {
36
+ return await edgeClient.connectConnections(connections, context)
37
+ }
38
+
39
+ export async function disconnectConnections(connections: Connection[], context?: ResolverContext): Promise<any> {
40
+ return await edgeClient.disconnectConnections(connections, context)
41
+ }
42
+
43
+ export function setEdgeClient(edge: EdgeClient) {
44
+ edgeClient = edge
45
+ }
@@ -5,5 +5,6 @@ export * from './connection-manager'
5
5
  export * from './scenario-engine'
6
6
  export * from './task-registry'
7
7
  export * from './analyzer/analyze-integration'
8
+ export * from './edge-client'
8
9
 
9
10
  export { Connector } from './types'
@@ -19,6 +19,7 @@ async function Script(step: InputStep, context: Context) {
19
19
  domain,
20
20
  user,
21
21
  lng,
22
+ logger,
22
23
  data,
23
24
  variables
24
25
  }
@@ -13,79 +13,79 @@ export interface Connector {
13
13
  }
14
14
 
15
15
  export type Context = {
16
- /**
17
- * Represents the domain context.
18
- */
16
+ /**
17
+ * Represents the domain context.
18
+ */
19
19
  domain: Domain
20
20
 
21
- /**
22
- * User information.
23
- */
21
+ /**
22
+ * User information.
23
+ */
24
24
  user: User
25
25
 
26
- /**
27
- * Language code, for example 'en', 'ko'.
28
- */
26
+ /**
27
+ * Language code, for example 'en', 'ko'.
28
+ */
29
29
  lng: string
30
30
 
31
- /**
32
- * Flag to indicate if the IP is unsafe, can be undefined.
33
- */
31
+ /**
32
+ * Flag to indicate if the IP is unsafe, can be undefined.
33
+ */
34
34
  unsafeIP: boolean | undefined
35
35
 
36
- /**
37
- * List of prohibited privileges, can be undefined.
38
- */
36
+ /**
37
+ * List of prohibited privileges, can be undefined.
38
+ */
39
39
  prohibitedPrivileges: { category: string; privilege: string }[] | undefined
40
40
 
41
- /**
42
- * Logger for logging purposes.
43
- */
41
+ /**
42
+ * Logger for logging purposes.
43
+ */
44
44
  logger: any
45
45
 
46
- /**
47
- * Function to publish events or messages.
48
- */
46
+ /**
47
+ * Function to publish events or messages.
48
+ */
49
49
  publish: Function
50
50
 
51
- /**
52
- * Function to load resources or data.
53
- */
51
+ /**
52
+ * Function to load resources or data.
53
+ */
54
54
  load: Function
55
55
 
56
- /**
57
- * Current status of the scenario instance.
58
- */
56
+ /**
57
+ * Current status of the scenario instance.
58
+ */
59
59
  state: ScenarioInstanceStatus
60
60
 
61
- /**
62
- * General data storage object.
63
- */
61
+ /**
62
+ * General data storage object.
63
+ */
64
64
  data: any
65
65
 
66
- /**
67
- * Variables related to the context.
68
- */
66
+ /**
67
+ * Variables related to the context.
68
+ */
69
69
  variables: Object
70
70
 
71
- /**
72
- * Local GraphQL client object.
73
- */
71
+ /**
72
+ * Local GraphQL client object.
73
+ */
74
74
  client: any /* graphql local client */
75
75
 
76
- /**
77
- * Root object, can be used for various purposes.
78
- */
76
+ /**
77
+ * Root object, can be used for various purposes.
78
+ */
79
79
  root: Object
80
80
 
81
- /**
82
- * Array of function closures.
83
- */
81
+ /**
82
+ * Array of function closures.
83
+ */
84
84
  closures: Function[]
85
85
 
86
- /**
87
- * Function to check the state.
88
- */
86
+ /**
87
+ * Function to check the state.
88
+ */
89
89
  checkState: Function
90
90
 
91
91
  /**
@@ -104,7 +104,6 @@ export type Context = {
104
104
  __csv_resources?: any
105
105
  }
106
106
 
107
-
108
107
  export type TaskHandler = (
109
108
  step: Step,
110
109
  context: Context
@@ -10,10 +10,7 @@ import { Connection, ConnectionPatch, ConnectionStatus, NewConnection } from './
10
10
  export class ConnectionMutation {
11
11
  @Directive('@transaction')
12
12
  @Mutation(returns => Connection, { description: 'To create new connection' })
13
- async createConnection(
14
- @Arg('connection') connection: NewConnection,
15
- @Ctx() context: ResolverContext
16
- ): Promise<Connection> {
13
+ async createConnection(@Arg('connection') connection: NewConnection, @Ctx() context: ResolverContext): Promise<Connection> {
17
14
  const { domain, user, tx } = context.state
18
15
 
19
16
  return await tx.getRepository(Connection).save({
@@ -26,11 +23,7 @@ export class ConnectionMutation {
26
23
 
27
24
  @Directive('@transaction')
28
25
  @Mutation(returns => Connection, { description: 'To modify connection information' })
29
- async updateConnection(
30
- @Arg('name') name: string,
31
- @Arg('patch') patch: ConnectionPatch,
32
- @Ctx() context: ResolverContext
33
- ): Promise<Connection> {
26
+ async updateConnection(@Arg('name') name: string, @Arg('patch') patch: ConnectionPatch, @Ctx() context: ResolverContext): Promise<Connection> {
34
27
  const { domain, user, tx } = context.state
35
28
 
36
29
  const repository = tx.getRepository(Connection)
@@ -47,10 +40,7 @@ export class ConnectionMutation {
47
40
 
48
41
  @Directive('@transaction')
49
42
  @Mutation(returns => [Connection], { description: "To modify multiple connections' information" })
50
- async updateMultipleConnection(
51
- @Arg('patches', type => [ConnectionPatch]) patches: ConnectionPatch[],
52
- @Ctx() context: ResolverContext
53
- ): Promise<Connection[]> {
43
+ async updateMultipleConnection(@Arg('patches', type => [ConnectionPatch]) patches: ConnectionPatch[], @Ctx() context: ResolverContext): Promise<Connection[]> {
54
44
  const { domain, user, tx } = context.state
55
45
 
56
46
  let results = []
@@ -102,10 +92,7 @@ export class ConnectionMutation {
102
92
 
103
93
  @Directive('@transaction')
104
94
  @Mutation(returns => Boolean, { description: 'To delete multiple connections' })
105
- async deleteConnections(
106
- @Arg('names', type => [String]) names: string[],
107
- @Ctx() context: ResolverContext
108
- ): Promise<boolean> {
95
+ async deleteConnections(@Arg('names', type => [String]) names: string[], @Ctx() context: ResolverContext): Promise<boolean> {
109
96
  const { domain, tx } = context.state
110
97
 
111
98
  await tx.getRepository(Connection).delete({
@@ -122,7 +109,7 @@ export class ConnectionMutation {
122
109
  var repository = getRepository(Connection)
123
110
  var connection = await repository.findOne({
124
111
  where: { domain: { id: domain.id }, name },
125
- relations: ['domain']
112
+ relations: ['domain', 'edge']
126
113
  })
127
114
 
128
115
  await connection.connect()
@@ -130,9 +117,7 @@ export class ConnectionMutation {
130
117
 
131
118
  return {
132
119
  ...connection,
133
- state: ConnectionManager.getConnectionInstance(connection)
134
- ? ConnectionStatus.CONNECTED
135
- : ConnectionStatus.DISCONNECTED
120
+ state: ConnectionManager.getConnectionInstance(connection) ? ConnectionStatus.CONNECTED : ConnectionStatus.DISCONNECTED
136
121
  } as Connection
137
122
  }
138
123
 
@@ -143,7 +128,7 @@ export class ConnectionMutation {
143
128
  var repository = getRepository(Connection)
144
129
  var connection = await repository.findOne({
145
130
  where: { domain: { id: domain.id }, name },
146
- relations: ['domain']
131
+ relations: ['domain', 'edge']
147
132
  })
148
133
 
149
134
  await connection.disconnect()
@@ -151,19 +136,14 @@ export class ConnectionMutation {
151
136
 
152
137
  return {
153
138
  ...connection,
154
- state: ConnectionManager.getConnectionInstance(connection)
155
- ? ConnectionStatus.CONNECTED
156
- : ConnectionStatus.DISCONNECTED
139
+ state: ConnectionManager.getConnectionInstance(connection) ? ConnectionStatus.CONNECTED : ConnectionStatus.DISCONNECTED
157
140
  }
158
141
  }
159
142
 
160
143
  @Directive('@transaction')
161
144
  // @Directive('@privilege(category: "connection", privilege: "mutation", domainOwnerGranted: true)')
162
145
  @Mutation(returns => Boolean, { description: 'To import multiple connections' })
163
- async importConnections(
164
- @Arg('connections', type => [ConnectionPatch]) connections: Connection[],
165
- @Ctx() context: ResolverContext
166
- ): Promise<boolean> {
146
+ async importConnections(@Arg('connections', type => [ConnectionPatch]) connections: Connection[], @Ctx() context: ResolverContext): Promise<boolean> {
167
147
  const { tx, domain, user } = context.state
168
148
 
169
149
  const repository = tx.getRepository(Connection)
@@ -1,6 +1,6 @@
1
1
  import { Arg, Args, Ctx, FieldResolver, Query, Resolver, Root } from 'type-graphql'
2
2
 
3
- import { User } from '@things-factory/auth-base'
3
+ import { Appliance, User } from '@things-factory/auth-base'
4
4
  import { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'
5
5
 
6
6
  import { ConnectionManager } from '../../engine/connection-manager'
@@ -19,9 +19,7 @@ export class ConnectionQuery {
19
19
 
20
20
  return {
21
21
  ...connection,
22
- state: ConnectionManager.getConnectionInstance(connection)
23
- ? ConnectionStatus.CONNECTED
24
- : ConnectionStatus.DISCONNECTED
22
+ state: ConnectionManager.getConnectionInstance(connection) ? ConnectionStatus.CONNECTED : ConnectionStatus.DISCONNECTED
25
23
  } as Connection
26
24
  }
27
25
 
@@ -40,9 +38,7 @@ export class ConnectionQuery {
40
38
  const [items, total] = await queryBuilder.leftJoinAndSelect('connection.domain', 'domain').getManyAndCount()
41
39
 
42
40
  items.forEach(connection => {
43
- connection['state'] = ConnectionManager.getConnectionInstance(connection)
44
- ? ConnectionStatus.CONNECTED
45
- : ConnectionStatus.DISCONNECTED
41
+ connection['state'] = ConnectionManager.getConnectionInstance(connection) ? ConnectionStatus.CONNECTED : ConnectionStatus.DISCONNECTED
46
42
  })
47
43
 
48
44
  return { items, total }
@@ -52,26 +48,31 @@ export class ConnectionQuery {
52
48
  fetchConnectionState(@Arg('name') name: string, @Ctx() context: ResolverContext): ConnectionState {
53
49
  const { domain } = context.state
54
50
 
55
- var connection = ConnectionManager.getConnectionInstanceByName(domain, name)
51
+ const connection = ConnectionManager.getConnectionInstanceEntityByName(domain, name)
56
52
 
57
53
  return {
58
- name,
54
+ ...connection,
59
55
  state: connection ? ConnectionStatus.CONNECTED : ConnectionStatus.DISCONNECTED
60
56
  }
61
57
  }
62
58
 
59
+ @FieldResolver(type => Domain)
60
+ async edge(@Root() connection: Connection) {
61
+ return connection.edgeId && (await getRepository(Appliance).findOneBy({ id: connection.edgeId }))
62
+ }
63
+
63
64
  @FieldResolver(type => Domain)
64
65
  async domain(@Root() connection: Connection) {
65
- return connection.domain || (await getRepository(Domain).findOneBy({ id: connection.domainId }))
66
+ return connection.domain || (connection.domainId && (await getRepository(Domain).findOneBy({ id: connection.domainId })))
66
67
  }
67
68
 
68
69
  @FieldResolver(type => User)
69
70
  async updater(@Root() connection: Connection): Promise<User> {
70
- return await getRepository(User).findOneBy({ id: connection.updaterId })
71
+ return connection.updaterId && (await getRepository(User).findOneBy({ id: connection.updaterId }))
71
72
  }
72
73
 
73
74
  @FieldResolver(type => User)
74
75
  async creator(@Root() connection: Connection): Promise<User> {
75
- return await getRepository(User).findOneBy({ id: connection.creatorId })
76
+ return connection.creatorId && (await getRepository(User).findOneBy({ id: connection.creatorId }))
76
77
  }
77
78
  }
@@ -33,7 +33,7 @@ export class ConnectionSubscription {
33
33
 
34
34
  var connections = await getRepository(Connection).find({
35
35
  where,
36
- relations: ['domain']
36
+ relations: ['domain', 'edge']
37
37
  })
38
38
 
39
39
  connections.forEach(connection => {
@@ -1,20 +1,12 @@
1
1
  import { Field, ID, InputType, Int, ObjectType, registerEnumType } from 'type-graphql'
2
- import {
3
- Column,
4
- CreateDateColumn,
5
- Entity,
6
- Index,
7
- ManyToOne,
8
- PrimaryGeneratedColumn,
9
- RelationId,
10
- UpdateDateColumn
11
- } from 'typeorm'
12
-
13
- import { User } from '@things-factory/auth-base'
2
+ import { Column, CreateDateColumn, Entity, Index, ManyToOne, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'
3
+
4
+ import { User, Appliance } from '@things-factory/auth-base'
14
5
  import { logger } from '@things-factory/env'
15
- import { Domain } from '@things-factory/shell'
6
+ import { Domain, ObjectRef } from '@things-factory/shell'
16
7
 
17
8
  import { ConnectionManager } from '../../engine'
9
+ import { ProxyConnector } from '../../engine/connector/proxy-connector'
18
10
 
19
11
  export enum ConnectionStatus {
20
12
  CONNECTED = 'CONNECTED',
@@ -30,34 +22,34 @@ registerEnumType(ConnectionStatus, {
30
22
  @Index('ix_connection_0', (connection: Connection) => [connection.domain, connection.name], { unique: true })
31
23
  @ObjectType()
32
24
  export class Connection {
33
- /**
25
+ /**
34
26
  * Unique identifier for the connection, generated in UUID format.
35
27
  */
36
28
  @PrimaryGeneratedColumn('uuid')
37
29
  @Field(type => ID)
38
30
  readonly id: string
39
31
 
40
- /**
32
+ /**
41
33
  * Many-to-One relationship with the Domain entity.
42
34
  */
43
35
  @ManyToOne(type => Domain)
44
36
  @Field({ nullable: true })
45
37
  domain: Domain
46
38
 
47
- /**
39
+ /**
48
40
  * Stores the ID of the associated Domain.
49
41
  */
50
42
  @RelationId((connection: Connection) => connection.domain)
51
43
  domainId: string
52
44
 
53
- /**
45
+ /**
54
46
  * The name of the connection.
55
47
  */
56
48
  @Column()
57
49
  @Field()
58
50
  name: string
59
51
 
60
- /**
52
+ /**
61
53
  * Optional description for the connection.
62
54
  */
63
55
  @Column({
@@ -66,72 +58,81 @@ export class Connection {
66
58
  @Field({ nullable: true })
67
59
  description: string
68
60
 
69
- /**
61
+ /**
70
62
  * The type of the connection.
71
63
  */
72
64
  @Column()
73
65
  @Field({ nullable: true })
74
66
  type: string
75
67
 
76
- /**
68
+ /**
69
+ * Many-to-One relationship with the Appliance entity which delegate the connection. Optional field.
70
+ */
71
+ @ManyToOne(type => Appliance, { nullable: true })
72
+ @Field({ nullable: true })
73
+ edge: Appliance
74
+
75
+ /**
76
+ * Stores the ID of the Appliance who delegate the connection.
77
+ */
78
+ @RelationId((connection: Connection) => connection.edge)
79
+ edgeId: string
80
+
81
+ /**
77
82
  * The endpoint for the connection.
78
83
  */
79
84
  @Column()
80
85
  @Field({ nullable: true })
81
86
  endpoint: string
82
87
 
83
- /**
88
+ /**
84
89
  * Indicates the active status of the connection.
85
90
  */
86
- @Column({
87
- nullable: true
88
- })
91
+ @Column({ nullable: true })
89
92
  @Field({ nullable: true })
90
93
  active: boolean
91
94
 
92
- /**
95
+ /**
93
96
  * The status of the connection, using the ConnectionStatus type.
94
97
  */
95
98
  @Field({ nullable: true })
96
99
  state: ConnectionStatus
97
100
 
98
- /**
101
+ /**
99
102
  * Additional parameters for the connection, stored as a JSON string.
100
103
  */
101
- @Column({
102
- nullable: true
103
- })
104
+ @Column({ nullable: true })
104
105
  @Field({ nullable: true })
105
106
  params: string
106
107
 
107
- /**
108
+ /**
108
109
  * The date and time when the connection was created.
109
110
  */
110
111
  @CreateDateColumn()
111
112
  @Field({ nullable: true })
112
113
  createdAt: Date
113
114
 
114
- /**
115
+ /**
115
116
  * The date and time when the connection was last updated.
116
117
  */
117
118
  @UpdateDateColumn()
118
119
  @Field({ nullable: true })
119
120
  updatedAt: Date
120
121
 
121
- /**
122
+ /**
122
123
  * Many-to-One relationship with the User entity who created the connection. Optional field.
123
124
  */
124
125
  @ManyToOne(type => User, { nullable: true })
125
126
  @Field({ nullable: true })
126
127
  creator: User
127
128
 
128
- /**
129
+ /**
129
130
  * Stores the ID of the User who created the connection.
130
131
  */
131
132
  @RelationId((connection: Connection) => connection.creator)
132
133
  creatorId: string
133
134
 
134
- /**
135
+ /**
135
136
  * Many-to-One relationship with the User entity who last updated the connection.
136
137
  * Optional field.
137
138
  */
@@ -141,17 +142,18 @@ export class Connection {
141
142
 
142
143
  /**
143
144
  * Stores the ID of the User who last updated the connection.
144
- *
145
+ *
145
146
  */
146
147
  @RelationId((connection: Connection) => connection.updater)
147
148
  updaterId: string
148
149
 
149
150
  /**
150
151
  * Asynchronous method to establish the connection.
151
- *
152
+ *
152
153
  */
153
154
  async connect() {
154
- var connector = ConnectionManager.getConnector(this.type)
155
+ const { type, edge } = this
156
+ const connector = edge ? ProxyConnector.instance : ConnectionManager.getConnector(type)
155
157
  var params = {}
156
158
 
157
159
  try {
@@ -168,11 +170,12 @@ export class Connection {
168
170
 
169
171
  /**
170
172
  * @brief Asynchronous method to disconnect the connection.
171
- *
173
+ *
172
174
  */
173
175
  async disconnect() {
174
176
  try {
175
- var connector = ConnectionManager.getConnector(this.type)
177
+ const { type, edge } = this
178
+ const connector = edge ? ProxyConnector.instance : ConnectionManager.getConnector(type)
176
179
  await connector.disconnect(this)
177
180
  } finally {
178
181
  }
@@ -182,10 +185,10 @@ export class Connection {
182
185
  /**
183
186
  * Connection의 params의 원 타입과 사용 시에 타입 불일치로 인해 임시적으로 생성한 타입으로
184
187
  * 추후, 타입 일치를 통해서 제거할 예정임.
185
- *
188
+ *
186
189
  */
187
190
  export interface InputConnection extends Connection {
188
- params: any;
191
+ params: any
189
192
  }
190
193
 
191
194
  @ObjectType()
@@ -205,6 +208,9 @@ export class ConnectionState {
205
208
  @Field({ nullable: true })
206
209
  type?: string
207
210
 
211
+ @Field(type => Appliance, { nullable: true })
212
+ edge?: Appliance
213
+
208
214
  @Field({ nullable: true })
209
215
  state?: ConnectionStatus
210
216
 
@@ -223,6 +229,9 @@ export class NewConnection {
223
229
  @Field({ nullable: true })
224
230
  type?: string
225
231
 
232
+ @Field(type => ObjectRef, { nullable: true })
233
+ edge?: Appliance
234
+
226
235
  @Field({ nullable: true })
227
236
  endpoint?: string
228
237
 
@@ -244,6 +253,9 @@ export class ConnectionPatch {
244
253
  @Field({ nullable: true })
245
254
  type?: string
246
255
 
256
+ @Field(type => ObjectRef, { nullable: true })
257
+ edge?: Appliance
258
+
247
259
  @Field({ nullable: true })
248
260
  endpoint?: string
249
261
 
@@ -10,9 +10,11 @@ import { Domain, pubsub, PubSubLogTransport, ScalarObject } from '@things-factor
10
10
  import { User } from '@things-factory/auth-base'
11
11
  import { sleep } from '@things-factory/utils'
12
12
 
13
+ import { ConnectionManager } from '../../engine/connection-manager'
13
14
  import { TaskRegistry } from '../../engine'
14
15
  import { Context } from '../../engine/types'
15
16
  import { Step } from '../step/step-type'
17
+ import { handler as edgeHandler } from '../../engine/edge-client'
16
18
 
17
19
  const debug = require('debug')('things-factory:integration-base:scenario-instance')
18
20
  const { combine, timestamp, splat, printf } = format
@@ -440,12 +442,18 @@ export class ScenarioInstance {
440
442
  }
441
443
  step.params = step.params || {}
442
444
 
443
- var handler = TaskRegistry.getTaskHandler(step.task)
444
- if (!handler) {
445
- throw new Error(`no task handler for step '${step.name}'(${step.id})`)
446
- }
445
+ const connection = step.connection && ConnectionManager.getConnectionInstanceEntityByName(this.domain, step.connection)
446
+
447
+ if (!connection || !connection.edgeId) {
448
+ var handler = TaskRegistry.getTaskHandler(step.task)
449
+ if (!handler) {
450
+ throw new Error(`no task handler for step '${step.name}'(${step.id})`)
451
+ }
447
452
 
448
- var retval: any = await handler(step, context)
453
+ var retval: any = await handler(step, context)
454
+ } else {
455
+ var retval: any = await edgeHandler(step, context)
456
+ }
449
457
 
450
458
  if (step.log) {
451
459
  var { data } = retval || {}