@alwaysai/device-agent 1.3.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/lib/application-control/config.js +2 -2
  2. package/lib/application-control/config.js.map +1 -1
  3. package/lib/application-control/environment-variables.d.ts.map +1 -1
  4. package/lib/application-control/environment-variables.js +9 -4
  5. package/lib/application-control/environment-variables.js.map +1 -1
  6. package/lib/application-control/environment-variables.test.js +1 -1
  7. package/lib/application-control/environment-variables.test.js.map +1 -1
  8. package/lib/application-control/install.d.ts.map +1 -1
  9. package/lib/application-control/install.js +7 -2
  10. package/lib/application-control/install.js.map +1 -1
  11. package/lib/application-control/models.d.ts +5 -0
  12. package/lib/application-control/models.d.ts.map +1 -1
  13. package/lib/application-control/models.js +28 -14
  14. package/lib/application-control/models.js.map +1 -1
  15. package/lib/application-control/status.d.ts.map +1 -1
  16. package/lib/application-control/status.js +14 -17
  17. package/lib/application-control/status.js.map +1 -1
  18. package/lib/application-control/utils.js +2 -2
  19. package/lib/application-control/utils.js.map +1 -1
  20. package/lib/cloud-connection/device-agent-cloud-connection.d.ts +5 -5
  21. package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
  22. package/lib/cloud-connection/device-agent-cloud-connection.js +140 -105
  23. package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
  24. package/lib/cloud-connection/live-updates-handler.d.ts +4 -2
  25. package/lib/cloud-connection/live-updates-handler.d.ts.map +1 -1
  26. package/lib/cloud-connection/live-updates-handler.js +46 -25
  27. package/lib/cloud-connection/live-updates-handler.js.map +1 -1
  28. package/lib/cloud-connection/live-updates-handler.test.js +132 -16
  29. package/lib/cloud-connection/live-updates-handler.test.js.map +1 -1
  30. package/lib/cloud-connection/messages.d.ts.map +1 -1
  31. package/lib/cloud-connection/messages.js +3 -4
  32. package/lib/cloud-connection/messages.js.map +1 -1
  33. package/lib/cloud-connection/passthrough-handler.d.ts +5 -3
  34. package/lib/cloud-connection/passthrough-handler.d.ts.map +1 -1
  35. package/lib/cloud-connection/passthrough-handler.js +76 -62
  36. package/lib/cloud-connection/passthrough-handler.js.map +1 -1
  37. package/lib/cloud-connection/shadow-handler.d.ts +16 -21
  38. package/lib/cloud-connection/shadow-handler.d.ts.map +1 -1
  39. package/lib/cloud-connection/shadow-handler.js +162 -108
  40. package/lib/cloud-connection/shadow-handler.js.map +1 -1
  41. package/lib/cloud-connection/shadow-handler.test.js +100 -83
  42. package/lib/cloud-connection/shadow-handler.test.js.map +1 -1
  43. package/lib/cloud-connection/transaction-manager.d.ts +3 -0
  44. package/lib/cloud-connection/transaction-manager.d.ts.map +1 -1
  45. package/lib/cloud-connection/transaction-manager.js +11 -0
  46. package/lib/cloud-connection/transaction-manager.js.map +1 -1
  47. package/lib/cloud-connection/transaction-manager.test.js +102 -0
  48. package/lib/cloud-connection/transaction-manager.test.js.map +1 -1
  49. package/lib/device-control/device-control.d.ts +16 -15
  50. package/lib/device-control/device-control.d.ts.map +1 -1
  51. package/lib/device-control/device-control.js +117 -18
  52. package/lib/device-control/device-control.js.map +1 -1
  53. package/lib/docker/docker-compose.d.ts +14 -0
  54. package/lib/docker/docker-compose.d.ts.map +1 -0
  55. package/lib/docker/docker-compose.js +56 -0
  56. package/lib/docker/docker-compose.js.map +1 -0
  57. package/lib/index.js +2 -5
  58. package/lib/index.js.map +1 -1
  59. package/lib/infrastructure/agent-config.d.ts +45 -14
  60. package/lib/infrastructure/agent-config.d.ts.map +1 -1
  61. package/lib/infrastructure/agent-config.js +30 -15
  62. package/lib/infrastructure/agent-config.js.map +1 -1
  63. package/lib/infrastructure/agent-config.test.js +3 -0
  64. package/lib/infrastructure/agent-config.test.js.map +1 -1
  65. package/lib/local-connection/rabbitmq-connection.js +11 -11
  66. package/lib/local-connection/rabbitmq-connection.js.map +1 -1
  67. package/lib/secure-tunneling/secure-tunneling.d.ts +97 -0
  68. package/lib/secure-tunneling/secure-tunneling.d.ts.map +1 -0
  69. package/lib/secure-tunneling/secure-tunneling.js +435 -0
  70. package/lib/secure-tunneling/secure-tunneling.js.map +1 -0
  71. package/lib/secure-tunneling/secure-tunneling.test.d.ts +2 -0
  72. package/lib/secure-tunneling/secure-tunneling.test.d.ts.map +1 -0
  73. package/lib/secure-tunneling/secure-tunneling.test.js +1070 -0
  74. package/lib/secure-tunneling/secure-tunneling.test.js.map +1 -0
  75. package/lib/secure-tunneling/spawner-detached.d.ts +6 -0
  76. package/lib/secure-tunneling/spawner-detached.d.ts.map +1 -0
  77. package/lib/secure-tunneling/spawner-detached.js +107 -0
  78. package/lib/secure-tunneling/spawner-detached.js.map +1 -0
  79. package/lib/subcommands/app/analytics.d.ts.map +1 -1
  80. package/lib/subcommands/app/analytics.js +9 -13
  81. package/lib/subcommands/app/analytics.js.map +1 -1
  82. package/lib/subcommands/app/env-vars.d.ts.map +1 -1
  83. package/lib/subcommands/app/env-vars.js +11 -16
  84. package/lib/subcommands/app/env-vars.js.map +1 -1
  85. package/lib/subcommands/app/models.d.ts.map +1 -1
  86. package/lib/subcommands/app/models.js +12 -16
  87. package/lib/subcommands/app/models.js.map +1 -1
  88. package/lib/subcommands/device/clean.d.ts.map +1 -1
  89. package/lib/subcommands/device/clean.js +8 -6
  90. package/lib/subcommands/device/clean.js.map +1 -1
  91. package/lib/subcommands/device/get-info.d.ts +2 -0
  92. package/lib/subcommands/device/get-info.d.ts.map +1 -0
  93. package/lib/subcommands/device/get-info.js +36 -0
  94. package/lib/subcommands/device/get-info.js.map +1 -0
  95. package/lib/subcommands/device/index.d.ts.map +1 -1
  96. package/lib/subcommands/device/index.js +11 -2
  97. package/lib/subcommands/device/index.js.map +1 -1
  98. package/lib/subcommands/device/init.d.ts +5 -0
  99. package/lib/subcommands/device/init.d.ts.map +1 -0
  100. package/lib/subcommands/device/{device.js → init.js} +5 -36
  101. package/lib/subcommands/device/init.js.map +1 -0
  102. package/lib/subcommands/device/refresh.d.ts +2 -0
  103. package/lib/subcommands/device/refresh.d.ts.map +1 -0
  104. package/lib/subcommands/device/refresh.js +24 -0
  105. package/lib/subcommands/device/refresh.js.map +1 -0
  106. package/lib/subcommands/device/restart.d.ts +2 -0
  107. package/lib/subcommands/device/restart.d.ts.map +1 -0
  108. package/lib/subcommands/device/restart.js +14 -0
  109. package/lib/subcommands/device/restart.js.map +1 -0
  110. package/lib/util/check-for-updates.d.ts +3 -0
  111. package/lib/util/check-for-updates.d.ts.map +1 -0
  112. package/lib/util/check-for-updates.js +69 -0
  113. package/lib/util/check-for-updates.js.map +1 -0
  114. package/lib/util/cloud-mode-ready.d.ts +1 -0
  115. package/lib/util/cloud-mode-ready.d.ts.map +1 -1
  116. package/lib/util/cloud-mode-ready.js +36 -1
  117. package/lib/util/cloud-mode-ready.js.map +1 -1
  118. package/lib/util/file.d.ts +7 -0
  119. package/lib/util/file.d.ts.map +1 -0
  120. package/lib/util/file.js +66 -0
  121. package/lib/util/file.js.map +1 -0
  122. package/lib/util/file.test.d.ts +2 -0
  123. package/lib/util/file.test.d.ts.map +1 -0
  124. package/lib/util/file.test.js +87 -0
  125. package/lib/util/file.test.js.map +1 -0
  126. package/package.json +8 -7
  127. package/readme.md +3 -3
  128. package/src/application-control/config.ts +1 -1
  129. package/src/application-control/environment-variables.test.ts +1 -1
  130. package/src/application-control/environment-variables.ts +9 -6
  131. package/src/application-control/install.ts +8 -3
  132. package/src/application-control/models.ts +47 -19
  133. package/src/application-control/status.ts +16 -14
  134. package/src/application-control/utils.ts +1 -1
  135. package/src/cloud-connection/device-agent-cloud-connection.ts +202 -148
  136. package/src/cloud-connection/live-updates-handler.test.ts +161 -20
  137. package/src/cloud-connection/live-updates-handler.ts +63 -31
  138. package/src/cloud-connection/messages.ts +3 -4
  139. package/src/cloud-connection/passthrough-handler.ts +98 -76
  140. package/src/cloud-connection/shadow-handler.test.ts +101 -84
  141. package/src/cloud-connection/shadow-handler.ts +287 -133
  142. package/src/cloud-connection/transaction-manager.test.ts +124 -0
  143. package/src/cloud-connection/transaction-manager.ts +15 -0
  144. package/src/device-control/device-control.ts +125 -23
  145. package/src/docker/docker-compose.ts +60 -0
  146. package/src/index.ts +2 -6
  147. package/src/infrastructure/agent-config.test.ts +3 -0
  148. package/src/infrastructure/agent-config.ts +38 -40
  149. package/src/local-connection/rabbitmq-connection.ts +8 -8
  150. package/src/secure-tunneling/secure-tunneling.test.ts +1239 -0
  151. package/src/secure-tunneling/secure-tunneling.ts +599 -0
  152. package/src/secure-tunneling/spawner-detached.ts +123 -0
  153. package/src/subcommands/app/analytics.ts +16 -13
  154. package/src/subcommands/app/env-vars.ts +18 -16
  155. package/src/subcommands/app/models.ts +20 -16
  156. package/src/subcommands/device/clean.ts +5 -2
  157. package/src/subcommands/device/get-info.ts +49 -0
  158. package/src/subcommands/device/index.ts +11 -2
  159. package/src/subcommands/device/{device.ts → init.ts} +5 -47
  160. package/src/subcommands/device/refresh.ts +22 -0
  161. package/src/subcommands/device/restart.ts +11 -0
  162. package/src/util/check-for-updates.ts +69 -0
  163. package/src/util/cloud-mode-ready.ts +36 -0
  164. package/src/util/file.test.ts +90 -0
  165. package/src/util/file.ts +76 -0
  166. package/lib/docker/docker-compose-cmd.d.ts +0 -5
  167. package/lib/docker/docker-compose-cmd.d.ts.map +0 -1
  168. package/lib/docker/docker-compose-cmd.js +0 -16
  169. package/lib/docker/docker-compose-cmd.js.map +0 -1
  170. package/lib/secure-tunneling/index.d.ts +0 -5
  171. package/lib/secure-tunneling/index.d.ts.map +0 -1
  172. package/lib/secure-tunneling/index.js +0 -64
  173. package/lib/secure-tunneling/index.js.map +0 -1
  174. package/lib/subcommands/device/device.d.ts +0 -7
  175. package/lib/subcommands/device/device.d.ts.map +0 -1
  176. package/lib/subcommands/device/device.js.map +0 -1
  177. package/lib/util/safe-rimraf.d.ts +0 -2
  178. package/lib/util/safe-rimraf.d.ts.map +0 -1
  179. package/lib/util/safe-rimraf.js +0 -16
  180. package/lib/util/safe-rimraf.js.map +0 -1
  181. package/src/docker/docker-compose-cmd.ts +0 -15
  182. package/src/secure-tunneling/index.ts +0 -74
  183. package/src/util/safe-rimraf.ts +0 -14
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.runChannel = exports.PassthroughHandler = void 0;
4
- // eslint-disable-next-line
5
- const amqp = require('amqplib');
3
+ exports.PassthroughHandler = void 0;
4
+ const amqp = require("amqplib");
6
5
  const constants_1 = require("../local-connection/constants");
7
6
  const rabbitmq_connection_1 = require("../local-connection/rabbitmq-connection");
8
7
  const logger_1 = require("../util/logger");
@@ -12,18 +11,78 @@ const ackQueue = [];
12
11
  const MAX_LOCAL_CONNECTION_ATTEMPTS = 10;
13
12
  class PassthroughHandler {
14
13
  constructor(publisher) {
14
+ this.runChannel = async () => {
15
+ logger_1.logger.debug('Beginning to consume packets');
16
+ await this.channel.consume(this.packetQueue, (msg) => {
17
+ // NOTE: this needs to be an arrow function and then the whole contents of processPublish are below
18
+ if ((msg === null || msg === void 0 ? void 0 : msg.content) !== undefined) {
19
+ const packet = JSON.parse(msg.content.toString());
20
+ messageQueue.push({ packet, msg });
21
+ while (messageQueue.length > 0) {
22
+ const entry = messageQueue.shift();
23
+ const { packet, msg } = entry;
24
+ try {
25
+ const parsedPacket = JSON.parse(packet);
26
+ if (parsedPacket === null || parsedPacket === void 0 ? void 0 : parsedPacket['action']) {
27
+ switch (parsedPacket['action']) {
28
+ case 'analytics':
29
+ ackQueue.push(msg);
30
+ // FIXME: put real topic here
31
+ this.publisher.publishToCloudWithAck(packet, (errOrResp) => {
32
+ while (ackQueue.length > 0) {
33
+ const msg = ackQueue.shift();
34
+ if (errOrResp === true) {
35
+ this.channel.ack(msg); // acknowledge, allow queue to discard
36
+ }
37
+ else if (errOrResp === false) {
38
+ this.channel.reject(msg, true); // reject and requeue
39
+ }
40
+ }
41
+ });
42
+ break;
43
+ case 'heartbeat':
44
+ this.channel.ack(msg);
45
+ logger_1.logger.silly(`Heartbeat package received & acknowledged: ${packet}`);
46
+ break;
47
+ default:
48
+ this.channel.ack(msg);
49
+ logger_1.logger.debug(`Unknown 'action' package received & acknowledged: ${packet}`);
50
+ break;
51
+ }
52
+ }
53
+ else {
54
+ this.channel.ack(msg);
55
+ logger_1.logger.debug(`Received & acknowledged a RabbitMQ Package of unknown structure: ${parsedPacket}`);
56
+ }
57
+ }
58
+ catch (e) {
59
+ logger_1.logger.error(`There was a problem parsing RabbitMQ packet ${e}`);
60
+ this.channel.ack(msg);
61
+ logger_1.logger.debug(`Problematic packet was acknowledged`);
62
+ }
63
+ }
64
+ }
65
+ }, {
66
+ noAck: false // When true, RabbitMQ deletes message as soon as it is consumed
67
+ });
68
+ };
15
69
  this.publisher = publisher;
16
70
  }
17
- async setup() {
18
- await (0, rabbitmq_connection_1.setupRabbitMQContainer)();
71
+ async establishLocalConnection() {
19
72
  let connectAttempts = 0;
20
73
  let connected = false;
21
- logger_1.logger.debug(`Setting up alwaysAI Local Connection on host: ${constants_1.LOCAL_CONNECTION_HOST} and channel key: ${constants_1.LOCAL_CONNECTION_ROUTING_KEY}`);
74
+ logger_1.logger.debug(`Establishing local connection...`);
22
75
  while (connectAttempts <= MAX_LOCAL_CONNECTION_ATTEMPTS &&
23
76
  this.connection === undefined) {
24
77
  try {
25
78
  this.connection = await amqp.connect(`amqp://${constants_1.LOCAL_CONNECTION_HOST}:${constants_1.LOCAL_CONNECTION_PORT}`);
26
79
  this.channel = await this.connection.createChannel();
80
+ this.connection.on('error', async () => {
81
+ logger_1.logger.error(`Local connection failed. Attempting to reconnect...`);
82
+ await (0, rabbitmq_connection_1.stopRabbitMQContainer)();
83
+ this.connection = undefined;
84
+ await this.setup();
85
+ });
27
86
  connected = true;
28
87
  }
29
88
  catch (e) {
@@ -34,74 +93,29 @@ class PassthroughHandler {
34
93
  }
35
94
  }
36
95
  if (connected === true) {
37
- this.channel.prefetch(1); // This ensures we only get one packet at a time! This appears to have prevented throttling
96
+ await this.channel.prefetch(1); // This ensures we only get one packet at a time! This appears to have prevented throttling
38
97
  this.packetQueue = `${constants_1.LOCAL_CONNECTION_ROUTING_KEY}`;
39
98
  await this.channel.assertQueue(this.packetQueue, {
40
99
  durable: true
41
100
  });
101
+ logger_1.logger.info(`Local connection established.`);
42
102
  }
43
103
  else {
44
104
  throw new Error('Unable to establish connection to alwaysAI Local Connection, please try restarting Device Agent.');
45
105
  }
46
106
  }
47
- }
48
- exports.PassthroughHandler = PassthroughHandler;
49
- function processPublish(passthroughHandler) {
50
- while (messageQueue.length > 0) {
51
- const entry = messageQueue.shift();
52
- const { packet, msg } = entry;
107
+ async setup() {
108
+ logger_1.logger.debug(`Setting up alwaysAI Local Connection on host: ${constants_1.LOCAL_CONNECTION_HOST} and channel key: ${constants_1.LOCAL_CONNECTION_ROUTING_KEY}`);
109
+ await (0, rabbitmq_connection_1.setupRabbitMQContainer)();
53
110
  try {
54
- const parsedPacket = JSON.parse(packet);
55
- if (parsedPacket && parsedPacket['action']) {
56
- switch (parsedPacket['action']) {
57
- case 'analytics':
58
- ackQueue.push(msg);
59
- // FIXME: put real topic here
60
- passthroughHandler.publisher.publishToCloudWithAck(packet, (errOrResp) => {
61
- while (ackQueue.length > 0) {
62
- const msg = ackQueue.shift();
63
- if (errOrResp === true) {
64
- passthroughHandler.channel.ack(msg); // acknowledge, allow queue to discard
65
- }
66
- else if (errOrResp === false) {
67
- passthroughHandler.channel.reject(msg, true); // reject and requeue
68
- }
69
- }
70
- });
71
- break;
72
- case 'heartbeat':
73
- passthroughHandler.channel.ack(msg);
74
- logger_1.logger.debug(`Heartbeat package received & acknowledged: ${packet}`);
75
- break;
76
- default:
77
- passthroughHandler.channel.ack(msg);
78
- logger_1.logger.debug(`Unknown 'action' package received & acknowledged: ${packet}`);
79
- break;
80
- }
81
- }
82
- else {
83
- passthroughHandler.channel.ack(msg);
84
- logger_1.logger.debug(`Received & acknowledged a RabbitMQ Package of unknown structure: ${parsedPacket}`);
85
- }
111
+ await this.establishLocalConnection();
112
+ await this.runChannel();
86
113
  }
87
- catch (e) {
88
- logger_1.logger.error(`There was a problem parsing RabbitMQ packet ${e}`);
89
- passthroughHandler.channel.ack(msg);
90
- logger_1.logger.debug(`Problematic packet was acknowledged`);
114
+ catch (error) {
115
+ logger_1.logger.error(`There was a problem maintaining RabbitMQ connection: ${error}`);
116
+ throw new Error(`There was a problem maintaining RabbitMQ connection: ${error}`);
91
117
  }
92
118
  }
93
119
  }
94
- async function runChannel(passthroughHandler) {
95
- logger_1.logger.debug('Beginning to consume packets');
96
- passthroughHandler.channel.consume(passthroughHandler.packetQueue, function (msg) {
97
- if (msg.content !== undefined) {
98
- const packet = JSON.parse(msg.content.toString());
99
- messageQueue.push({ packet, msg });
100
- processPublish(passthroughHandler);
101
- }
102
- }, {
103
- noAck: false // When true, RabbitMQ deletes message as soon as it is consumed
104
- });
105
- }
106
- exports.runChannel = runChannel;
120
+ exports.PassthroughHandler = PassthroughHandler;
107
121
  //# sourceMappingURL=passthrough-handler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"passthrough-handler.js","sourceRoot":"","sources":["../../src/cloud-connection/passthrough-handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"passthrough-handler.js","sourceRoot":"","sources":["../../src/cloud-connection/passthrough-handler.ts"],"names":[],"mappings":"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"}
@@ -2,21 +2,7 @@ import { AppConfig } from '@alwaysai/app-configuration-schemas';
2
2
  import { EnvVars } from '../application-control';
3
3
  import { Publisher } from './publisher';
4
4
  import { AppConfigModels } from './shadow';
5
- export interface ShadowTopics {
6
- projects: {
7
- get: string;
8
- getAccepted: string;
9
- getRejected: string;
10
- update: string;
11
- updateDelta: string;
12
- updateAccepted: string;
13
- updateRejected: string;
14
- delete: string;
15
- };
16
- systemInfo: {
17
- update: string;
18
- };
19
- }
5
+ import { SecureTunnelShadowDescriptionReported } from '@alwaysai/device-agent-schemas';
20
6
  export declare type AppConfigUpdate = {
21
7
  newAppCfg: AppConfig;
22
8
  updatedModels?: AppConfigModels;
@@ -33,18 +19,27 @@ export declare type ShadowUpdate = {
33
19
  export declare class ShadowHandler {
34
20
  private clientId;
35
21
  private publisher;
36
- readonly shadowPrefix: string;
37
- readonly shadowTopics: ShadowTopics;
22
+ projectShadowTopics: string[];
23
+ readonly shadowTopics: {
24
+ [key: string]: any;
25
+ };
38
26
  constructor(clientId: string, publisher: Publisher);
39
- private handleNamedShadowUpdate;
40
- handleShadowTopic({ topic, payload, clientToken }: {
27
+ private generateAppConfigUpdate;
28
+ private processProjectShadowUpdates;
29
+ private processProjectShadowUpdate;
30
+ handleProjectShadow({ topic, payload, clientToken }: {
41
31
  topic: string;
42
32
  payload: any;
43
33
  clientToken: string;
44
34
  }): Promise<ShadowUpdate[]>;
45
35
  updateSystemInfoShadow(): Promise<void>;
46
36
  updateProjectShadow(projectId: string): Promise<void>;
47
- getShadowUpdates(): void;
48
- clearAppConfig(projectId: string): void;
37
+ updateProjectEnvVars({ projectId, envVars }: {
38
+ projectId: string;
39
+ envVars: EnvVars;
40
+ }): Promise<void>;
41
+ updateSecureTunnelShadow(secureTunnelShadowUpdate: SecureTunnelShadowDescriptionReported): Promise<void>;
42
+ getProjectShadowUpdates(): void;
43
+ clearProjectShadow(projectId: string): void;
49
44
  }
50
45
  //# sourceMappingURL=shadow-handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shadow-handler.d.ts","sourceRoot":"","sources":["../../src/cloud-connection/shadow-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EAEV,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,OAAO,EAA8B,MAAM,wBAAwB,CAAC;AAE7E,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,eAAe,EAAuB,MAAM,UAAU,CAAC;AAIhE,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE;QACR,GAAG,EAAE,MAAM,CAAC;QACZ,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;QACvB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,UAAU,EAAE;QACV,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,oBAAY,eAAe,GAAG;IAC5B,SAAS,EAAE,SAAS,CAAC;IACrB,aAAa,CAAC,EAAE,eAAe,CAAC;CACjC,CAAC;AAEF,oBAAY,YAAY,GAAG;IACzB,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,oBAAY,YAAY,GAAG;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAEF,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAY;IAC7B,SAAgB,YAAY,EAAE,MAAM,CAAC;IACrC,SAAgB,YAAY,EAAE,YAAY,CAAC;gBAE/B,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS;YAqBpC,uBAAuB;IAsExB,iBAAiB,CAAC,EAC7B,KAAK,EACL,OAAO,EACP,WAAW,EACZ,EAAE;QACD,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,GAAG,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAqCd,sBAAsB;IAYtB,mBAAmB,CAAC,SAAS,EAAE,MAAM;IAmB3C,gBAAgB;IAQhB,cAAc,CAAC,SAAS,EAAE,MAAM;CAiBxC"}
1
+ {"version":3,"file":"shadow-handler.d.ts","sourceRoot":"","sources":["../../src/cloud-connection/shadow-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EAEV,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,OAAO,EAIR,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,eAAe,EAAuB,MAAM,UAAU,CAAC;AAChE,OAAO,EAWL,qCAAqC,EACtC,MAAM,gCAAgC,CAAC;AAExC,oBAAY,eAAe,GAAG;IAC5B,SAAS,EAAE,SAAS,CAAC;IACrB,aAAa,CAAC,EAAE,eAAe,CAAC;CACjC,CAAC;AAEF,oBAAY,YAAY,GAAG;IACzB,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,oBAAY,YAAY,GAAG;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAEF,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAY;IACtB,mBAAmB,EAAE,MAAM,EAAE,CAAM;IAC1C,SAAgB,YAAY,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;gBACzC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS;YAoDpC,uBAAuB;YA8CvB,2BAA2B;YAkC3B,0BAA0B;IAiD3B,mBAAmB,CAAC,EAC/B,KAAK,EACL,OAAO,EACP,WAAW,EACZ,EAAE;QACD,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,GAAG,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAqEd,sBAAsB;IAUtB,mBAAmB,CAAC,SAAS,EAAE,MAAM;IAqBrC,oBAAoB,CAAC,EAChC,SAAS,EACT,OAAO,EACR,EAAE;QACD,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,OAAO,CAAC;KAClB;IAkBY,wBAAwB,CACnC,wBAAwB,EAAE,qCAAqC;IAa1D,uBAAuB;IAOvB,kBAAkB,CAAC,SAAS,EAAE,MAAM;CAY5C"}
@@ -3,157 +3,211 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ShadowHandler = void 0;
4
4
  const app_configuration_schemas_1 = require("@alwaysai/app-configuration-schemas");
5
5
  const application_control_1 = require("../application-control");
6
+ const device_control_1 = require("../device-control/device-control");
6
7
  const logger_1 = require("../util/logger");
7
8
  const shadow_1 = require("./shadow");
8
- const device_control_1 = require("../device-control/device-control");
9
9
  const device_agent_schemas_1 = require("@alwaysai/device-agent-schemas");
10
10
  class ShadowHandler {
11
11
  constructor(clientId, publisher) {
12
+ this.projectShadowTopics = [];
12
13
  this.clientId = clientId;
13
14
  this.publisher = publisher;
14
- this.shadowPrefix = `$aws/things/${this.clientId}/shadow/name/`;
15
15
  this.shadowTopics = {
16
- projects: {
17
- get: `${this.shadowPrefix}projects/get`,
18
- getAccepted: `${this.shadowPrefix}projects/get/accepted`,
19
- getRejected: `${this.shadowPrefix}projects/get/rejected`,
20
- update: `${this.shadowPrefix}projects/update`,
21
- updateDelta: `${this.shadowPrefix}projects/update/delta`,
22
- updateAccepted: `${this.shadowPrefix}projects/update/accepted`,
23
- updateRejected: `${this.shadowPrefix}projects/update/rejected`,
24
- delete: `${this.shadowPrefix}projects/delete`
16
+ project: {
17
+ get: (0, device_agent_schemas_1.getShadowTopic)(clientId, 'projects', 'get'),
18
+ getAccepted: (0, device_agent_schemas_1.getShadowTopic)(clientId, 'projects', 'get/accepted'),
19
+ getRejected: (0, device_agent_schemas_1.getShadowTopic)(clientId, 'projects', 'get/rejected'),
20
+ update: (0, device_agent_schemas_1.getShadowTopic)(clientId, 'projects', 'update'),
21
+ updateDelta: (0, device_agent_schemas_1.getShadowTopic)(clientId, 'projects', 'update/delta'),
22
+ updateAccepted: (0, device_agent_schemas_1.getShadowTopic)(clientId, 'projects', 'update/accepted'),
23
+ updateRejected: (0, device_agent_schemas_1.getShadowTopic)(clientId, 'projects', 'update/rejected')
25
24
  },
26
25
  systemInfo: {
27
- update: `${this.shadowPrefix}system-info/update`
26
+ update: (0, device_agent_schemas_1.getShadowTopic)(clientId, 'system-info', 'update')
27
+ },
28
+ secureTunnel: {
29
+ get: (0, device_agent_schemas_1.getShadowTopic)(clientId, 'secure-tunnel', 'get'),
30
+ getAccepted: (0, device_agent_schemas_1.getShadowTopic)(clientId, 'secure-tunnel', 'get/accepted'),
31
+ getRejected: (0, device_agent_schemas_1.getShadowTopic)(clientId, 'secure-tunnel', 'get/rejected'),
32
+ update: (0, device_agent_schemas_1.getShadowTopic)(clientId, 'secure-tunnel', 'update'),
33
+ updateDelta: (0, device_agent_schemas_1.getShadowTopic)(clientId, 'secure-tunnel', 'update/delta'),
34
+ updateAccepted: (0, device_agent_schemas_1.getShadowTopic)(clientId, 'secure-tunnel', 'update/accepted'),
35
+ updateRejected: (0, device_agent_schemas_1.getShadowTopic)(clientId, 'secure-tunnel', 'update/rejected'),
36
+ delete: (0, device_agent_schemas_1.getShadowTopic)(clientId, 'secure-tunnel', 'delete'),
37
+ deleteAccepted: (0, device_agent_schemas_1.getShadowTopic)(clientId, 'secure-tunnel', 'delete/accepted'),
38
+ deleteRejected: (0, device_agent_schemas_1.getShadowTopic)(clientId, 'secure-tunnel', 'delete/rejected')
28
39
  }
29
40
  };
41
+ this.projectShadowTopics.push(this.shadowTopics.project.getAccepted);
42
+ this.projectShadowTopics.push(this.shadowTopics.project.getRejected);
43
+ this.projectShadowTopics.push(this.shadowTopics.project.updateDelta);
44
+ this.projectShadowTopics.push(this.shadowTopics.project.updateAccepted);
45
+ this.projectShadowTopics.push(this.shadowTopics.project.updateRejected);
30
46
  }
31
- async handleNamedShadowUpdate({ delta }) {
32
- const updates = [];
33
- const deltaKeys = Object.keys(delta);
34
- for (const projectId of deltaKeys) {
35
- const projectShadow = delta[projectId];
36
- // For incoming shadow updates, there will be no TxID, so it needs to be generated here.
37
- const txId = (0, device_agent_schemas_1.generateTxId)();
38
- const shadowUpdate = { projectId, txId };
39
- if (projectShadow.appConfig) {
40
- let newAppCfg;
41
- try {
42
- newAppCfg = JSON.parse(projectShadow.appConfig);
43
- }
44
- catch (error) {
45
- logger_1.logger.error(`Could not parse the appConfig for transaction ${txId}!\n${error}`);
46
- continue;
47
- }
48
- if (!(0, app_configuration_schemas_1.validateAppConfig)(newAppCfg)) {
49
- // FIXME: Raise an exception to be handled at higher layer
50
- logger_1.logger.error(`Received invalid app config for ${projectId}!\n${JSON.stringify(app_configuration_schemas_1.validateAppConfig.errors, null, 2)}`);
47
+ async generateAppConfigUpdate({ appConfig, txId, projectId }) {
48
+ let newAppCfg;
49
+ // Handle errors and validation
50
+ try {
51
+ newAppCfg = JSON.parse(appConfig);
52
+ }
53
+ catch (error) {
54
+ logger_1.logger.error(`Could not parse the appConfig for transaction ${txId}!\n${error}`);
55
+ return null;
56
+ }
57
+ if (!(0, app_configuration_schemas_1.validateAppConfig)(newAppCfg)) {
58
+ // FIXME: Raise an exception to be handled at higher layer
59
+ logger_1.logger.error(`Received invalid app config for ${projectId}!\n${JSON.stringify(app_configuration_schemas_1.validateAppConfig.errors, null, 2)}`);
60
+ return null;
61
+ }
62
+ // If all ok, return the AppConfigUpdate
63
+ logger_1.logger.info(`Found a delta for app config shadow. Updating ${projectId}`);
64
+ const { updatedModels } = await (0, shadow_1.getAppCfgModelsDiff)({
65
+ newAppCfg,
66
+ projectId
67
+ });
68
+ const appCfgUpdate = { newAppCfg };
69
+ if (updatedModels && Object.keys(updatedModels).length) {
70
+ appCfgUpdate.updatedModels = updatedModels;
71
+ }
72
+ return appCfgUpdate;
73
+ }
74
+ async processProjectShadowUpdates({ delta }) {
75
+ const shadowUpdatesPromises = [];
76
+ for (const [projectId, projectDelta] of Object.entries(delta)) {
77
+ if (projectDelta) {
78
+ const valid = (0, device_agent_schemas_1.validateProjectShadowUpdate)(projectDelta);
79
+ if (!valid) {
80
+ logger_1.logger.error(`Error validating shadow update: ${JSON.stringify({ projectDelta, errors: device_agent_schemas_1.validateProjectShadowUpdate.errors }, null, 2)}`);
51
81
  continue;
52
82
  }
53
- const { updatedModels } = await (0, shadow_1.getAppCfgModelsDiff)({
54
- newAppCfg,
55
- projectId
56
- });
57
- if (updatedModels && Object.keys(updatedModels).length) {
58
- shadowUpdate.appCfgUpdate = { newAppCfg, updatedModels };
59
- }
60
- else {
61
- shadowUpdate.appCfgUpdate = { newAppCfg };
62
- }
63
- }
64
- else {
65
- logger_1.logger.info(`Ignoring app config shadow update for ${projectId} due to no delta`);
83
+ shadowUpdatesPromises.push(this.processProjectShadowUpdate({
84
+ projectId,
85
+ projectDelta
86
+ }));
66
87
  }
67
- if (projectShadow.envVars) {
68
- const envVars = projectShadow.envVars;
69
- shadowUpdate.envVarUpdate = { envVars };
70
- }
71
- else {
72
- logger_1.logger.info(`Ignoring app environment variable shadow update for ${projectId} due to no delta`);
73
- }
74
- if (shadowUpdate.appCfgUpdate || shadowUpdate.envVarUpdate) {
75
- updates.push(shadowUpdate);
88
+ }
89
+ return (await Promise.all(shadowUpdatesPromises)).filter((promise) => promise !== null);
90
+ }
91
+ async processProjectShadowUpdate({ projectId, projectDelta }) {
92
+ const txId = (0, device_agent_schemas_1.generateTxId)();
93
+ const shadowUpdate = { projectId, txId };
94
+ // Handle appConfig Updates
95
+ if (!projectDelta.appConfig) {
96
+ logger_1.logger.info(`Ignoring app config shadow update for ${projectId} due to no delta`);
97
+ }
98
+ else {
99
+ logger_1.logger.info(`Found a delta for app config shadow. Updating ${projectId}`);
100
+ const appConfig = projectDelta.appConfig;
101
+ const appCfgUpdate = await this.generateAppConfigUpdate({
102
+ appConfig,
103
+ txId,
104
+ projectId
105
+ });
106
+ if (appCfgUpdate) {
107
+ shadowUpdate.appCfgUpdate = appCfgUpdate;
76
108
  }
77
109
  }
78
- return updates;
110
+ // Handle envVars Updates
111
+ if (!projectDelta.envVars) {
112
+ logger_1.logger.info(`Ignoring app environment variable shadow update for ${projectId} due to no delta`);
113
+ }
114
+ else {
115
+ logger_1.logger.info(`Found a delta for app environment variable shadow. Updating ${projectId}`);
116
+ const envVars = projectDelta.envVars;
117
+ shadowUpdate.envVarUpdate = { envVars };
118
+ }
119
+ return shadowUpdate.appCfgUpdate || shadowUpdate.envVarUpdate
120
+ ? shadowUpdate
121
+ : null;
79
122
  }
80
123
  // Public interface
81
- async handleShadowTopic({ topic, payload, clientToken }) {
124
+ async handleProjectShadow({ topic, payload, clientToken }) {
82
125
  // TODO: make use a function like the other topic getters
83
- const shadowName = topic.split('/')[5];
126
+ if (!this.projectShadowTopics.includes(topic)) {
127
+ throw Error(`Topic ${topic} is not in the ${this.projectShadowTopics}`);
128
+ }
84
129
  switch (topic) {
85
- case this.shadowTopics.projects.updateAccepted:
130
+ case this.shadowTopics.project.updateAccepted: {
86
131
  if (clientToken === this.clientId) {
87
- logger_1.logger.debug(`Ignoring delta caused by Device Agent: ${JSON.stringify({ topic, payload }, null, 2)}`);
132
+ logger_1.logger.debug(`Ignoring message as it was caused by Device Agent itself: ${JSON.stringify({ topic, payload }, null, 2)}`);
88
133
  break;
89
134
  }
90
- return await this.handleNamedShadowUpdate({ delta: payload.desired });
91
- case this.shadowTopics.projects.getAccepted:
92
- if (payload['delta']) {
93
- return await this.handleNamedShadowUpdate({
94
- delta: payload['delta']
135
+ const desired = (0, device_agent_schemas_1.getDesiredFromMessage)(payload);
136
+ if (!desired) {
137
+ logger_1.logger.debug(`No desired state found in message: ${JSON.stringify(payload)}`);
138
+ }
139
+ else {
140
+ return await this.processProjectShadowUpdates({ delta: desired });
141
+ }
142
+ break;
143
+ }
144
+ case this.shadowTopics.project.getAccepted: {
145
+ if (clientToken !== this.clientId) {
146
+ logger_1.logger.debug(`Ignoring message as it was caused by Device Agent itself: ${JSON.stringify({ topic, payload }, null, 2)}`);
147
+ break;
148
+ }
149
+ if (payload.state.delta) {
150
+ return await this.processProjectShadowUpdates({
151
+ delta: payload.state.delta
95
152
  });
96
153
  }
97
154
  else {
98
- logger_1.logger.info(`No delta updates in named shadow '${shadowName}'`);
155
+ logger_1.logger.info(`No delta in projects.getAccepted in named shadow '${topic.split('/')[5]}'`);
99
156
  }
100
157
  break;
158
+ }
159
+ case this.shadowTopics.project.getRejected:
160
+ case this.shadowTopics.project.updateDelta:
161
+ case this.shadowTopics.project.updateRejected: {
162
+ // Not handling these for now
163
+ break;
164
+ }
101
165
  default:
102
- logger_1.logger.info(`Ignoring shadow message: ${JSON.stringify({ topic, payload }, null, 2)}`);
166
+ logger_1.logger.info(`Did not match a correct topic. Ignoring shadow message: ${JSON.stringify({ topic, payload }, null, 2)}`);
103
167
  }
104
168
  return [];
105
169
  }
106
170
  async updateSystemInfoShadow() {
107
171
  const systemInfo = await (0, device_control_1.getSystemInformation)();
108
- const packet = {
109
- state: {
110
- reported: systemInfo
111
- },
112
- clientToken: this.clientId
113
- };
114
- const topic = this.shadowTopics.systemInfo.update;
115
- this.publisher.publish(topic, JSON.stringify(packet));
172
+ this.publisher.publish((0, device_agent_schemas_1.getShadowTopic)(this.clientId, 'system-info', 'update'), JSON.stringify((0, device_agent_schemas_1.buildUpdateSystemInfoShadowMessage)(this.clientId, systemInfo)));
116
173
  }
117
174
  async updateProjectShadow(projectId) {
118
175
  const appCfg = await (0, application_control_1.readAppCfgFile)({ projectId });
119
176
  const envVars = await (0, application_control_1.getAllEnvs)({ projectId });
120
- const packet = {
121
- state: {
122
- reported: {
123
- [projectId]: {
124
- appConfig: JSON.stringify(appCfg),
125
- envVars
126
- }
127
- }
128
- },
129
- clientToken: this.clientId
130
- };
131
- const topic = this.shadowTopics.projects.update;
132
- this.publisher.publish(topic, JSON.stringify(packet));
133
- }
134
- getShadowUpdates() {
135
- const topic = this.shadowTopics.projects.get;
136
- const packet = {
137
- clientToken: this.clientId
177
+ const toReport = {
178
+ [projectId]: {
179
+ appConfig: JSON.stringify(appCfg),
180
+ envVars
181
+ }
138
182
  };
139
- this.publisher.publish(topic, JSON.stringify(packet));
183
+ this.publisher.publish((0, device_agent_schemas_1.getShadowTopic)(this.clientId, 'projects', 'update'), JSON.stringify((0, device_agent_schemas_1.buildUpdateProjectShadowMessage)({
184
+ clientId: this.clientId,
185
+ reported: toReport
186
+ })));
140
187
  }
141
- clearAppConfig(projectId) {
142
- const topic = this.shadowTopics.projects.update;
143
- // TODO: We should actually send only desired and handle the delta
144
- // to update reported
145
- const packet = {
146
- state: {
147
- desired: {
148
- [projectId]: null
149
- },
150
- reported: {
151
- [projectId]: null
188
+ async updateProjectEnvVars({ projectId, envVars }) {
189
+ await (0, application_control_1.setEnv)({ projectId, envVars });
190
+ this.publisher.publish((0, device_agent_schemas_1.getShadowTopic)(this.clientId, 'projects', 'update'), JSON.stringify((0, device_agent_schemas_1.buildUpdateProjectShadowMessage)({
191
+ clientId: this.clientId,
192
+ reported: {
193
+ [projectId]: {
194
+ envVars
152
195
  }
153
- },
154
- clientToken: this.clientId
155
- };
156
- this.publisher.publish(topic, JSON.stringify(packet));
196
+ }
197
+ })));
198
+ }
199
+ async updateSecureTunnelShadow(secureTunnelShadowUpdate) {
200
+ this.publisher.publish((0, device_agent_schemas_1.getShadowTopic)(this.clientId, 'secure-tunnel', 'update'), JSON.stringify((0, device_agent_schemas_1.buildUpdateSecureTunnelShadowMessage)(secureTunnelShadowUpdate, this.clientId)));
201
+ }
202
+ getProjectShadowUpdates() {
203
+ this.publisher.publish((0, device_agent_schemas_1.getShadowTopic)(this.clientId, 'projects', 'get'), JSON.stringify((0, device_agent_schemas_1.buildBaseShadowMessage)(this.clientId)));
204
+ }
205
+ clearProjectShadow(projectId) {
206
+ this.publisher.publish((0, device_agent_schemas_1.getShadowTopic)(this.clientId, 'projects', 'update'), JSON.stringify((0, device_agent_schemas_1.buildUpdateProjectShadowMessage)({
207
+ clientId: this.clientId,
208
+ reported: { [projectId]: null },
209
+ desired: { [projectId]: null }
210
+ })));
157
211
  }
158
212
  }
159
213
  exports.ShadowHandler = ShadowHandler;