@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.
- package/lib/application-control/config.js +2 -2
- package/lib/application-control/config.js.map +1 -1
- package/lib/application-control/environment-variables.d.ts.map +1 -1
- package/lib/application-control/environment-variables.js +9 -4
- package/lib/application-control/environment-variables.js.map +1 -1
- package/lib/application-control/environment-variables.test.js +1 -1
- package/lib/application-control/environment-variables.test.js.map +1 -1
- package/lib/application-control/install.d.ts.map +1 -1
- package/lib/application-control/install.js +7 -2
- package/lib/application-control/install.js.map +1 -1
- package/lib/application-control/models.d.ts +5 -0
- package/lib/application-control/models.d.ts.map +1 -1
- package/lib/application-control/models.js +28 -14
- package/lib/application-control/models.js.map +1 -1
- package/lib/application-control/status.d.ts.map +1 -1
- package/lib/application-control/status.js +14 -17
- package/lib/application-control/status.js.map +1 -1
- package/lib/application-control/utils.js +2 -2
- package/lib/application-control/utils.js.map +1 -1
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts +5 -5
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
- package/lib/cloud-connection/device-agent-cloud-connection.js +140 -105
- package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
- package/lib/cloud-connection/live-updates-handler.d.ts +4 -2
- package/lib/cloud-connection/live-updates-handler.d.ts.map +1 -1
- package/lib/cloud-connection/live-updates-handler.js +46 -25
- package/lib/cloud-connection/live-updates-handler.js.map +1 -1
- package/lib/cloud-connection/live-updates-handler.test.js +132 -16
- package/lib/cloud-connection/live-updates-handler.test.js.map +1 -1
- package/lib/cloud-connection/messages.d.ts.map +1 -1
- package/lib/cloud-connection/messages.js +3 -4
- package/lib/cloud-connection/messages.js.map +1 -1
- package/lib/cloud-connection/passthrough-handler.d.ts +5 -3
- package/lib/cloud-connection/passthrough-handler.d.ts.map +1 -1
- package/lib/cloud-connection/passthrough-handler.js +76 -62
- package/lib/cloud-connection/passthrough-handler.js.map +1 -1
- package/lib/cloud-connection/shadow-handler.d.ts +16 -21
- package/lib/cloud-connection/shadow-handler.d.ts.map +1 -1
- package/lib/cloud-connection/shadow-handler.js +162 -108
- package/lib/cloud-connection/shadow-handler.js.map +1 -1
- package/lib/cloud-connection/shadow-handler.test.js +100 -83
- package/lib/cloud-connection/shadow-handler.test.js.map +1 -1
- package/lib/cloud-connection/transaction-manager.d.ts +3 -0
- package/lib/cloud-connection/transaction-manager.d.ts.map +1 -1
- package/lib/cloud-connection/transaction-manager.js +11 -0
- package/lib/cloud-connection/transaction-manager.js.map +1 -1
- package/lib/cloud-connection/transaction-manager.test.js +102 -0
- package/lib/cloud-connection/transaction-manager.test.js.map +1 -1
- package/lib/device-control/device-control.d.ts +16 -15
- package/lib/device-control/device-control.d.ts.map +1 -1
- package/lib/device-control/device-control.js +117 -18
- package/lib/device-control/device-control.js.map +1 -1
- package/lib/docker/docker-compose.d.ts +14 -0
- package/lib/docker/docker-compose.d.ts.map +1 -0
- package/lib/docker/docker-compose.js +56 -0
- package/lib/docker/docker-compose.js.map +1 -0
- package/lib/index.js +2 -5
- package/lib/index.js.map +1 -1
- package/lib/infrastructure/agent-config.d.ts +45 -14
- package/lib/infrastructure/agent-config.d.ts.map +1 -1
- package/lib/infrastructure/agent-config.js +30 -15
- package/lib/infrastructure/agent-config.js.map +1 -1
- package/lib/infrastructure/agent-config.test.js +3 -0
- package/lib/infrastructure/agent-config.test.js.map +1 -1
- package/lib/local-connection/rabbitmq-connection.js +11 -11
- package/lib/local-connection/rabbitmq-connection.js.map +1 -1
- package/lib/secure-tunneling/secure-tunneling.d.ts +97 -0
- package/lib/secure-tunneling/secure-tunneling.d.ts.map +1 -0
- package/lib/secure-tunneling/secure-tunneling.js +435 -0
- package/lib/secure-tunneling/secure-tunneling.js.map +1 -0
- package/lib/secure-tunneling/secure-tunneling.test.d.ts +2 -0
- package/lib/secure-tunneling/secure-tunneling.test.d.ts.map +1 -0
- package/lib/secure-tunneling/secure-tunneling.test.js +1070 -0
- package/lib/secure-tunneling/secure-tunneling.test.js.map +1 -0
- package/lib/secure-tunneling/spawner-detached.d.ts +6 -0
- package/lib/secure-tunneling/spawner-detached.d.ts.map +1 -0
- package/lib/secure-tunneling/spawner-detached.js +107 -0
- package/lib/secure-tunneling/spawner-detached.js.map +1 -0
- package/lib/subcommands/app/analytics.d.ts.map +1 -1
- package/lib/subcommands/app/analytics.js +9 -13
- package/lib/subcommands/app/analytics.js.map +1 -1
- package/lib/subcommands/app/env-vars.d.ts.map +1 -1
- package/lib/subcommands/app/env-vars.js +11 -16
- package/lib/subcommands/app/env-vars.js.map +1 -1
- package/lib/subcommands/app/models.d.ts.map +1 -1
- package/lib/subcommands/app/models.js +12 -16
- package/lib/subcommands/app/models.js.map +1 -1
- package/lib/subcommands/device/clean.d.ts.map +1 -1
- package/lib/subcommands/device/clean.js +8 -6
- package/lib/subcommands/device/clean.js.map +1 -1
- package/lib/subcommands/device/get-info.d.ts +2 -0
- package/lib/subcommands/device/get-info.d.ts.map +1 -0
- package/lib/subcommands/device/get-info.js +36 -0
- package/lib/subcommands/device/get-info.js.map +1 -0
- package/lib/subcommands/device/index.d.ts.map +1 -1
- package/lib/subcommands/device/index.js +11 -2
- package/lib/subcommands/device/index.js.map +1 -1
- package/lib/subcommands/device/init.d.ts +5 -0
- package/lib/subcommands/device/init.d.ts.map +1 -0
- package/lib/subcommands/device/{device.js → init.js} +5 -36
- package/lib/subcommands/device/init.js.map +1 -0
- package/lib/subcommands/device/refresh.d.ts +2 -0
- package/lib/subcommands/device/refresh.d.ts.map +1 -0
- package/lib/subcommands/device/refresh.js +24 -0
- package/lib/subcommands/device/refresh.js.map +1 -0
- package/lib/subcommands/device/restart.d.ts +2 -0
- package/lib/subcommands/device/restart.d.ts.map +1 -0
- package/lib/subcommands/device/restart.js +14 -0
- package/lib/subcommands/device/restart.js.map +1 -0
- package/lib/util/check-for-updates.d.ts +3 -0
- package/lib/util/check-for-updates.d.ts.map +1 -0
- package/lib/util/check-for-updates.js +69 -0
- package/lib/util/check-for-updates.js.map +1 -0
- package/lib/util/cloud-mode-ready.d.ts +1 -0
- package/lib/util/cloud-mode-ready.d.ts.map +1 -1
- package/lib/util/cloud-mode-ready.js +36 -1
- package/lib/util/cloud-mode-ready.js.map +1 -1
- package/lib/util/file.d.ts +7 -0
- package/lib/util/file.d.ts.map +1 -0
- package/lib/util/file.js +66 -0
- package/lib/util/file.js.map +1 -0
- package/lib/util/file.test.d.ts +2 -0
- package/lib/util/file.test.d.ts.map +1 -0
- package/lib/util/file.test.js +87 -0
- package/lib/util/file.test.js.map +1 -0
- package/package.json +8 -7
- package/readme.md +3 -3
- package/src/application-control/config.ts +1 -1
- package/src/application-control/environment-variables.test.ts +1 -1
- package/src/application-control/environment-variables.ts +9 -6
- package/src/application-control/install.ts +8 -3
- package/src/application-control/models.ts +47 -19
- package/src/application-control/status.ts +16 -14
- package/src/application-control/utils.ts +1 -1
- package/src/cloud-connection/device-agent-cloud-connection.ts +202 -148
- package/src/cloud-connection/live-updates-handler.test.ts +161 -20
- package/src/cloud-connection/live-updates-handler.ts +63 -31
- package/src/cloud-connection/messages.ts +3 -4
- package/src/cloud-connection/passthrough-handler.ts +98 -76
- package/src/cloud-connection/shadow-handler.test.ts +101 -84
- package/src/cloud-connection/shadow-handler.ts +287 -133
- package/src/cloud-connection/transaction-manager.test.ts +124 -0
- package/src/cloud-connection/transaction-manager.ts +15 -0
- package/src/device-control/device-control.ts +125 -23
- package/src/docker/docker-compose.ts +60 -0
- package/src/index.ts +2 -6
- package/src/infrastructure/agent-config.test.ts +3 -0
- package/src/infrastructure/agent-config.ts +38 -40
- package/src/local-connection/rabbitmq-connection.ts +8 -8
- package/src/secure-tunneling/secure-tunneling.test.ts +1239 -0
- package/src/secure-tunneling/secure-tunneling.ts +599 -0
- package/src/secure-tunneling/spawner-detached.ts +123 -0
- package/src/subcommands/app/analytics.ts +16 -13
- package/src/subcommands/app/env-vars.ts +18 -16
- package/src/subcommands/app/models.ts +20 -16
- package/src/subcommands/device/clean.ts +5 -2
- package/src/subcommands/device/get-info.ts +49 -0
- package/src/subcommands/device/index.ts +11 -2
- package/src/subcommands/device/{device.ts → init.ts} +5 -47
- package/src/subcommands/device/refresh.ts +22 -0
- package/src/subcommands/device/restart.ts +11 -0
- package/src/util/check-for-updates.ts +69 -0
- package/src/util/cloud-mode-ready.ts +36 -0
- package/src/util/file.test.ts +90 -0
- package/src/util/file.ts +76 -0
- package/lib/docker/docker-compose-cmd.d.ts +0 -5
- package/lib/docker/docker-compose-cmd.d.ts.map +0 -1
- package/lib/docker/docker-compose-cmd.js +0 -16
- package/lib/docker/docker-compose-cmd.js.map +0 -1
- package/lib/secure-tunneling/index.d.ts +0 -5
- package/lib/secure-tunneling/index.d.ts.map +0 -1
- package/lib/secure-tunneling/index.js +0 -64
- package/lib/secure-tunneling/index.js.map +0 -1
- package/lib/subcommands/device/device.d.ts +0 -7
- package/lib/subcommands/device/device.d.ts.map +0 -1
- package/lib/subcommands/device/device.js.map +0 -1
- package/lib/util/safe-rimraf.d.ts +0 -2
- package/lib/util/safe-rimraf.d.ts.map +0 -1
- package/lib/util/safe-rimraf.js +0 -16
- package/lib/util/safe-rimraf.js.map +0 -1
- package/src/docker/docker-compose-cmd.ts +0 -15
- package/src/secure-tunneling/index.ts +0 -74
- 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.
|
|
4
|
-
|
|
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
|
|
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(`
|
|
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
|
-
|
|
49
|
-
|
|
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
|
-
|
|
55
|
-
|
|
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 (
|
|
88
|
-
logger_1.logger.error(`There was a problem
|
|
89
|
-
|
|
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
|
-
|
|
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":";;;AAAA,
|
|
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
|
-
|
|
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
|
-
|
|
37
|
-
readonly shadowTopics:
|
|
22
|
+
projectShadowTopics: string[];
|
|
23
|
+
readonly shadowTopics: {
|
|
24
|
+
[key: string]: any;
|
|
25
|
+
};
|
|
38
26
|
constructor(clientId: string, publisher: Publisher);
|
|
39
|
-
private
|
|
40
|
-
|
|
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
|
-
|
|
48
|
-
|
|
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,
|
|
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
|
-
|
|
17
|
-
get:
|
|
18
|
-
getAccepted:
|
|
19
|
-
getRejected:
|
|
20
|
-
update:
|
|
21
|
-
updateDelta:
|
|
22
|
-
updateAccepted:
|
|
23
|
-
updateRejected:
|
|
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:
|
|
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
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
-
|
|
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
|
|
124
|
+
async handleProjectShadow({ topic, payload, clientToken }) {
|
|
82
125
|
// TODO: make use a function like the other topic getters
|
|
83
|
-
|
|
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.
|
|
130
|
+
case this.shadowTopics.project.updateAccepted: {
|
|
86
131
|
if (clientToken === this.clientId) {
|
|
87
|
-
logger_1.logger.debug(`Ignoring
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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(
|
|
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
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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;
|