@alwaysai/device-agent 1.4.0 → 2.0.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.d.ts.map +1 -1
- package/lib/application-control/config.js +10 -5
- package/lib/application-control/config.js.map +1 -1
- package/lib/application-control/environment-variables.d.ts +1 -5
- package/lib/application-control/environment-variables.d.ts.map +1 -1
- package/lib/application-control/environment-variables.js +9 -26
- package/lib/application-control/environment-variables.js.map +1 -1
- package/lib/application-control/environment-variables.test.js +27 -7
- package/lib/application-control/environment-variables.test.js.map +1 -1
- package/lib/application-control/index.d.ts +4 -4
- package/lib/application-control/index.d.ts.map +1 -1
- package/lib/application-control/index.js +1 -4
- package/lib/application-control/index.js.map +1 -1
- package/lib/application-control/install.d.ts.map +1 -1
- package/lib/application-control/install.js +9 -7
- package/lib/application-control/install.js.map +1 -1
- package/lib/application-control/models.d.ts +5 -11
- package/lib/application-control/models.d.ts.map +1 -1
- package/lib/application-control/models.js +27 -64
- 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 +10 -12
- package/lib/application-control/status.js.map +1 -1
- package/lib/application-control/utils.d.ts +0 -4
- package/lib/application-control/utils.d.ts.map +1 -1
- package/lib/application-control/utils.js +3 -26
- package/lib/application-control/utils.js.map +1 -1
- package/lib/cloud-connection/bootstrap-provision.js +3 -2
- package/lib/cloud-connection/bootstrap-provision.js.map +1 -1
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts +11 -16
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
- package/lib/cloud-connection/device-agent-cloud-connection.js +295 -246
- package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
- package/lib/cloud-connection/device-agent.d.ts.map +1 -1
- package/lib/cloud-connection/device-agent.js +11 -9
- package/lib/cloud-connection/device-agent.js.map +1 -1
- package/lib/cloud-connection/live-updates-handler.d.ts +18 -27
- package/lib/cloud-connection/live-updates-handler.d.ts.map +1 -1
- package/lib/cloud-connection/live-updates-handler.js +58 -170
- package/lib/cloud-connection/live-updates-handler.js.map +1 -1
- package/lib/cloud-connection/live-updates-handler.test.js +76 -54
- package/lib/cloud-connection/live-updates-handler.test.js.map +1 -1
- package/lib/cloud-connection/passthrough-handler.d.ts +9 -4
- package/lib/cloud-connection/passthrough-handler.d.ts.map +1 -1
- package/lib/cloud-connection/passthrough-handler.js +95 -62
- package/lib/cloud-connection/passthrough-handler.js.map +1 -1
- package/lib/cloud-connection/shadow-handler.d.ts +5 -1
- package/lib/cloud-connection/shadow-handler.d.ts.map +1 -1
- package/lib/cloud-connection/shadow-handler.js +63 -31
- package/lib/cloud-connection/shadow-handler.js.map +1 -1
- package/lib/cloud-connection/shadow-handler.test.js +45 -57
- package/lib/cloud-connection/shadow-handler.test.js.map +1 -1
- package/lib/cloud-connection/shadow.d.ts.map +1 -1
- package/lib/cloud-connection/shadow.js +2 -1
- package/lib/cloud-connection/shadow.js.map +1 -1
- package/lib/cloud-connection/transaction-manager.d.ts +7 -2
- package/lib/cloud-connection/transaction-manager.d.ts.map +1 -1
- package/lib/cloud-connection/transaction-manager.js +29 -29
- package/lib/cloud-connection/transaction-manager.js.map +1 -1
- package/lib/cloud-connection/transaction-manager.test.js +105 -3
- package/lib/cloud-connection/transaction-manager.test.js.map +1 -1
- package/lib/device-control/device-control.d.ts +14 -6
- package/lib/device-control/device-control.d.ts.map +1 -1
- package/lib/device-control/device-control.js +172 -72
- 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 +57 -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 +46 -14
- package/lib/infrastructure/agent-config.d.ts.map +1 -1
- package/lib/infrastructure/agent-config.js +36 -21
- package/lib/infrastructure/agent-config.js.map +1 -1
- package/lib/infrastructure/agent-config.test.js +6 -1
- package/lib/infrastructure/agent-config.test.js.map +1 -1
- package/lib/infrastructure/config-check-utility.d.ts +6 -0
- package/lib/infrastructure/config-check-utility.d.ts.map +1 -0
- package/lib/infrastructure/config-check-utility.js +67 -0
- package/lib/infrastructure/config-check-utility.js.map +1 -0
- package/lib/infrastructure/config-check-utility.test.d.ts +2 -0
- package/lib/infrastructure/config-check-utility.test.d.ts.map +1 -0
- package/lib/infrastructure/config-check-utility.test.js +109 -0
- package/lib/infrastructure/config-check-utility.test.js.map +1 -0
- package/lib/infrastructure/device-certificate.d.ts +10 -0
- package/lib/infrastructure/device-certificate.d.ts.map +1 -0
- package/lib/infrastructure/device-certificate.js +47 -0
- package/lib/infrastructure/device-certificate.js.map +1 -0
- package/lib/infrastructure/device-certificate.test.d.ts +2 -0
- package/lib/infrastructure/device-certificate.test.d.ts.map +1 -0
- package/lib/infrastructure/device-certificate.test.js +24 -0
- package/lib/infrastructure/device-certificate.test.js.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-file.test.d.ts +2 -0
- package/lib/infrastructure/legacy-migration/legacy-file.test.d.ts.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-file.test.js +61 -0
- package/lib/infrastructure/legacy-migration/legacy-file.test.js.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-files.d.ts +75 -0
- package/lib/infrastructure/legacy-migration/legacy-files.d.ts.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-files.js +75 -0
- package/lib/infrastructure/legacy-migration/legacy-files.js.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.d.ts +6 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.d.ts.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.js +149 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.js.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.test.d.ts +2 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.test.d.ts.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.test.js +226 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.test.js.map +1 -0
- package/lib/infrastructure/require-files-present-ready.test.d.ts +2 -0
- package/lib/infrastructure/require-files-present-ready.test.d.ts.map +1 -0
- package/lib/infrastructure/require-files-present-ready.test.js +44 -0
- package/lib/infrastructure/require-files-present-ready.test.js.map +1 -0
- package/lib/infrastructure/required-config-checks.d.ts +2 -0
- package/lib/infrastructure/required-config-checks.d.ts.map +1 -0
- package/lib/infrastructure/required-config-checks.js +30 -0
- package/lib/infrastructure/required-config-checks.js.map +1 -0
- package/lib/infrastructure/tokens-and-device-cfg.d.ts.map +1 -1
- package/lib/infrastructure/tokens-and-device-cfg.js +11 -8
- package/lib/infrastructure/tokens-and-device-cfg.js.map +1 -1
- package/lib/local-connection/rabbitmq-connection.d.ts.map +1 -1
- package/lib/local-connection/rabbitmq-connection.js +21 -21
- package/lib/local-connection/rabbitmq-connection.js.map +1 -1
- package/lib/secure-tunneling/secure-tunneling.d.ts +15 -23
- package/lib/secure-tunneling/secure-tunneling.d.ts.map +1 -1
- package/lib/secure-tunneling/secure-tunneling.js +52 -47
- package/lib/secure-tunneling/secure-tunneling.js.map +1 -1
- package/lib/secure-tunneling/secure-tunneling.test.js +29 -31
- package/lib/secure-tunneling/secure-tunneling.test.js.map +1 -1
- package/lib/subcommands/app/analytics.d.ts.map +1 -1
- package/lib/subcommands/app/analytics.js +1 -2
- package/lib/subcommands/app/analytics.js.map +1 -1
- package/lib/subcommands/app/env-vars.d.ts +4 -0
- package/lib/subcommands/app/env-vars.d.ts.map +1 -1
- package/lib/subcommands/app/env-vars.js +52 -6
- package/lib/subcommands/app/env-vars.js.map +1 -1
- package/lib/subcommands/app/index.d.ts.map +1 -1
- package/lib/subcommands/app/index.js +1 -3
- package/lib/subcommands/app/index.js.map +1 -1
- package/lib/subcommands/app/models.d.ts +0 -11
- package/lib/subcommands/app/models.d.ts.map +1 -1
- package/lib/subcommands/app/models.js +2 -58
- package/lib/subcommands/app/models.js.map +1 -1
- package/lib/subcommands/app/shadow.d.ts.map +1 -1
- package/lib/subcommands/app/shadow.js +6 -5
- package/lib/subcommands/app/shadow.js.map +1 -1
- package/lib/subcommands/app/version.d.ts.map +1 -1
- package/lib/subcommands/app/version.js +2 -4
- package/lib/subcommands/app/version.js.map +1 -1
- package/lib/subcommands/config.d.ts +2 -0
- package/lib/subcommands/config.d.ts.map +1 -0
- package/lib/subcommands/config.js +39 -0
- package/lib/subcommands/config.js.map +1 -0
- package/lib/subcommands/device/clean.d.ts +1 -1
- package/lib/subcommands/device/clean.d.ts.map +1 -1
- package/lib/subcommands/device/clean.js +25 -15
- 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 +13 -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} +10 -49
- package/lib/subcommands/device/init.js.map +1 -0
- package/lib/subcommands/device/migrate.d.ts +2 -0
- package/lib/subcommands/device/migrate.d.ts.map +1 -0
- package/lib/subcommands/device/migrate.js +24 -0
- package/lib/subcommands/device/migrate.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 +25 -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/subcommands/index.d.ts +1 -1
- package/lib/subcommands/index.d.ts.map +1 -1
- package/lib/subcommands/index.js +3 -1
- package/lib/subcommands/index.js.map +1 -1
- package/lib/subcommands/rabbitmq-connection.d.ts +1 -1
- package/lib/subcommands/rabbitmq-connection.d.ts.map +1 -1
- package/lib/util/aai-error.d.ts +12 -0
- package/lib/util/aai-error.d.ts.map +1 -0
- package/lib/util/aai-error.js +11 -0
- package/lib/util/aai-error.js.map +1 -0
- package/lib/util/aws-regions.d.ts +2 -0
- package/lib/util/aws-regions.d.ts.map +1 -0
- package/lib/util/{cloud-mode-ready.js → aws-regions.js} +2 -20
- package/lib/util/aws-regions.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 +46 -0
- package/lib/util/check-for-updates.js.map +1 -0
- package/lib/util/clean-certs.d.ts.map +1 -1
- package/lib/util/clean-certs.js +5 -4
- package/lib/util/clean-certs.js.map +1 -1
- package/lib/util/directories.d.ts +4 -18
- package/lib/util/directories.d.ts.map +1 -1
- package/lib/util/directories.js +18 -32
- package/lib/util/directories.js.map +1 -1
- package/lib/util/file.d.ts +11 -0
- package/lib/util/file.d.ts.map +1 -0
- package/lib/util/file.js +127 -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/lib/util/get-device-id.d.ts.map +1 -1
- package/lib/util/get-device-id.js +7 -1
- package/lib/util/get-device-id.js.map +1 -1
- package/lib/util/http-client.js +3 -3
- package/lib/util/http-client.js.map +1 -1
- package/package.json +22 -19
- package/readme.md +15 -35
- package/src/application-control/config.ts +10 -13
- package/src/application-control/environment-variables.test.ts +28 -7
- package/src/application-control/environment-variables.ts +13 -40
- package/src/application-control/index.ts +3 -16
- package/src/application-control/install.ts +16 -10
- package/src/application-control/models.ts +40 -98
- package/src/application-control/status.ts +9 -7
- package/src/application-control/utils.ts +1 -29
- package/src/cloud-connection/bootstrap-provision.ts +7 -7
- package/src/cloud-connection/device-agent-cloud-connection.ts +647 -509
- package/src/cloud-connection/device-agent.ts +16 -7
- package/src/cloud-connection/live-updates-handler.test.ts +137 -64
- package/src/cloud-connection/live-updates-handler.ts +103 -234
- package/src/cloud-connection/passthrough-handler.ts +134 -75
- package/src/cloud-connection/shadow-handler.test.ts +45 -57
- package/src/cloud-connection/shadow-handler.ts +114 -56
- package/src/cloud-connection/shadow.ts +4 -1
- package/src/cloud-connection/transaction-manager.test.ts +127 -3
- package/src/cloud-connection/transaction-manager.ts +68 -39
- package/src/device-control/device-control.ts +179 -72
- package/src/docker/docker-compose.ts +61 -0
- package/src/index.ts +2 -6
- package/src/infrastructure/agent-config.test.ts +9 -2
- package/src/infrastructure/agent-config.ts +45 -46
- package/src/infrastructure/config-check-utility.test.ts +154 -0
- package/src/infrastructure/config-check-utility.ts +77 -0
- package/src/infrastructure/device-certificate.test.ts +40 -0
- package/src/infrastructure/device-certificate.ts +58 -0
- package/src/infrastructure/legacy-migration/legacy-file.test.ts +88 -0
- package/src/infrastructure/legacy-migration/legacy-files.ts +101 -0
- package/src/infrastructure/legacy-migration/legacy-migration.test.ts +396 -0
- package/src/infrastructure/legacy-migration/legacy-migration.ts +229 -0
- package/src/infrastructure/require-files-present-ready.test.ts +53 -0
- package/src/infrastructure/required-config-checks.ts +33 -0
- package/src/infrastructure/tokens-and-device-cfg.ts +12 -10
- package/src/local-connection/rabbitmq-connection.ts +28 -23
- package/src/secure-tunneling/secure-tunneling.test.ts +37 -39
- package/src/secure-tunneling/secure-tunneling.ts +74 -69
- package/src/subcommands/app/analytics.ts +2 -4
- package/src/subcommands/app/env-vars.ts +72 -9
- package/src/subcommands/app/index.ts +3 -11
- package/src/subcommands/app/models.ts +5 -81
- package/src/subcommands/app/shadow.ts +6 -5
- package/src/subcommands/app/version.ts +3 -4
- package/src/subcommands/config.ts +42 -0
- package/src/subcommands/device/clean.ts +32 -18
- package/src/subcommands/device/get-info.ts +49 -0
- package/src/subcommands/device/index.ts +13 -2
- package/src/subcommands/device/{device.ts → init.ts} +11 -69
- package/src/subcommands/device/migrate.ts +20 -0
- package/src/subcommands/device/refresh.ts +23 -0
- package/src/subcommands/device/restart.ts +11 -0
- package/src/subcommands/index.ts +3 -1
- package/src/util/aai-error.ts +20 -0
- package/src/util/{cloud-mode-ready.ts → aws-regions.ts} +0 -24
- package/src/util/check-for-updates.ts +53 -0
- package/src/util/clean-certs.ts +8 -4
- package/src/util/directories.ts +23 -67
- package/src/util/file.test.ts +90 -0
- package/src/util/file.ts +156 -0
- package/src/util/get-device-id.ts +7 -7
- package/src/util/http-client.ts +2 -2
- 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/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/cloud-mode-ready.d.ts +0 -3
- package/lib/util/cloud-mode-ready.d.ts.map +0 -1
- package/lib/util/cloud-mode-ready.js.map +0 -1
- package/lib/util/download-file.d.ts +0 -6
- package/lib/util/download-file.d.ts.map +0 -1
- package/lib/util/download-file.js +0 -25
- package/lib/util/download-file.js.map +0 -1
- package/lib/util/fetch-with-timeout.d.ts +0 -4
- package/lib/util/fetch-with-timeout.d.ts.map +0 -1
- package/lib/util/fetch-with-timeout.js +0 -30
- package/lib/util/fetch-with-timeout.js.map +0 -1
- package/lib/util/parsing.d.ts +0 -2
- package/lib/util/parsing.d.ts.map +0 -1
- package/lib/util/parsing.js +0 -17
- package/lib/util/parsing.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/util/download-file.ts +0 -25
- package/src/util/fetch-with-timeout.ts +0 -35
- package/src/util/parsing.ts +0 -11
- package/src/util/safe-rimraf.ts +0 -14
|
@@ -1,14 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
DeviceAgentStatusShadowUpdate,
|
|
3
|
+
PassthroughStatusValue
|
|
4
|
+
} from '@alwaysai/device-agent-schemas/lib/shadow-schema';
|
|
5
|
+
import { stringifyError } from 'alwaysai/lib/util';
|
|
6
|
+
import * as amqp from 'amqplib';
|
|
7
|
+
import { ALWAYSAI_ANALYTICS_PASSTHROUGH } from '../environment';
|
|
3
8
|
import {
|
|
4
9
|
LOCAL_CONNECTION_HOST,
|
|
5
10
|
LOCAL_CONNECTION_PORT,
|
|
6
11
|
LOCAL_CONNECTION_ROUTING_KEY
|
|
7
12
|
} from '../local-connection/constants';
|
|
8
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
setupRabbitMQContainer,
|
|
15
|
+
stopRabbitMQContainer
|
|
16
|
+
} from '../local-connection/rabbitmq-connection';
|
|
9
17
|
import { logger } from '../util/logger';
|
|
10
18
|
import sleep from '../util/sleep';
|
|
11
19
|
import { Publisher } from './publisher';
|
|
20
|
+
import { ShadowHandler } from './shadow-handler';
|
|
12
21
|
|
|
13
22
|
const messageQueue: any[] = [];
|
|
14
23
|
const ackQueue: any[] = [];
|
|
@@ -16,21 +25,90 @@ const MAX_LOCAL_CONNECTION_ATTEMPTS = 10;
|
|
|
16
25
|
|
|
17
26
|
export class PassthroughHandler {
|
|
18
27
|
public publisher: Publisher;
|
|
19
|
-
public
|
|
20
|
-
public
|
|
28
|
+
public shadowHandler: ShadowHandler;
|
|
29
|
+
public connection: amqp.Connection | undefined;
|
|
30
|
+
public channel: amqp.Channel;
|
|
21
31
|
public packetQueue;
|
|
22
32
|
|
|
23
|
-
constructor(publisher: Publisher) {
|
|
33
|
+
constructor(publisher: Publisher, shadowHandler: ShadowHandler) {
|
|
24
34
|
this.publisher = publisher;
|
|
35
|
+
this.shadowHandler = shadowHandler;
|
|
25
36
|
}
|
|
26
37
|
|
|
27
|
-
|
|
28
|
-
|
|
38
|
+
runChannel = async () => {
|
|
39
|
+
logger.debug('Beginning to consume packets');
|
|
40
|
+
await this.channel.consume(
|
|
41
|
+
this.packetQueue,
|
|
42
|
+
(msg) => {
|
|
43
|
+
// NOTE: this needs to be an arrow function and then the whole contents of processPublish are below
|
|
44
|
+
if (msg?.content !== undefined) {
|
|
45
|
+
const packet = JSON.parse(msg.content.toString());
|
|
46
|
+
messageQueue.push({ packet, msg });
|
|
47
|
+
while (messageQueue.length > 0) {
|
|
48
|
+
const entry = messageQueue.shift();
|
|
49
|
+
const { packet, msg } = entry;
|
|
50
|
+
try {
|
|
51
|
+
const parsedPacket = JSON.parse(packet);
|
|
52
|
+
if (parsedPacket?.['action']) {
|
|
53
|
+
switch (parsedPacket['action']) {
|
|
54
|
+
case 'analytics':
|
|
55
|
+
ackQueue.push(msg);
|
|
56
|
+
// FIXME: put real topic here
|
|
57
|
+
this.publisher.publishToCloudWithAck(
|
|
58
|
+
packet,
|
|
59
|
+
(errOrResp) => {
|
|
60
|
+
while (ackQueue.length > 0) {
|
|
61
|
+
const msg = ackQueue.shift();
|
|
62
|
+
if (errOrResp === true) {
|
|
63
|
+
this.channel.ack(msg); // acknowledge, allow queue to discard
|
|
64
|
+
} else if (errOrResp === false) {
|
|
65
|
+
this.channel.reject(msg, true); // reject and requeue
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
break;
|
|
71
|
+
case 'heartbeat':
|
|
72
|
+
this.channel.ack(msg);
|
|
73
|
+
logger.silly(
|
|
74
|
+
`Heartbeat package received & acknowledged: ${packet}`
|
|
75
|
+
);
|
|
76
|
+
break;
|
|
77
|
+
default:
|
|
78
|
+
this.channel.ack(msg);
|
|
79
|
+
logger.debug(
|
|
80
|
+
`Unknown 'action' package received & acknowledged: ${packet}`
|
|
81
|
+
);
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
this.channel.ack(msg);
|
|
86
|
+
logger.debug(
|
|
87
|
+
`Received & acknowledged a RabbitMQ Package of unknown structure: ${parsedPacket}`
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
} catch (e) {
|
|
91
|
+
logger.error(
|
|
92
|
+
`There was a problem parsing RabbitMQ packet!\n${stringifyError(
|
|
93
|
+
e
|
|
94
|
+
)}`
|
|
95
|
+
);
|
|
96
|
+
this.channel.ack(msg);
|
|
97
|
+
logger.debug('Problematic packet was acknowledged');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
noAck: false // When true, RabbitMQ deletes message as soon as it is consumed
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
async establishLocalConnection(): Promise<void> {
|
|
29
109
|
let connectAttempts = 0;
|
|
30
110
|
let connected = false;
|
|
31
|
-
logger.debug(
|
|
32
|
-
`Setting up alwaysAI Local Connection on host: ${LOCAL_CONNECTION_HOST} and channel key: ${LOCAL_CONNECTION_ROUTING_KEY}`
|
|
33
|
-
);
|
|
111
|
+
logger.debug(`Establishing local connection...`);
|
|
34
112
|
while (
|
|
35
113
|
connectAttempts <= MAX_LOCAL_CONNECTION_ATTEMPTS &&
|
|
36
114
|
this.connection === undefined
|
|
@@ -40,6 +118,13 @@ export class PassthroughHandler {
|
|
|
40
118
|
`amqp://${LOCAL_CONNECTION_HOST}:${LOCAL_CONNECTION_PORT}`
|
|
41
119
|
);
|
|
42
120
|
this.channel = await this.connection.createChannel();
|
|
121
|
+
this.connection.on('error', async () => {
|
|
122
|
+
logger.error(`Local connection failed. Attempting to reconnect...`);
|
|
123
|
+
await stopRabbitMQContainer();
|
|
124
|
+
this.connection = undefined;
|
|
125
|
+
await this.setup();
|
|
126
|
+
});
|
|
127
|
+
|
|
43
128
|
connected = true;
|
|
44
129
|
} catch (e) {
|
|
45
130
|
const timeTillNextAttemptMs = 1000 + 1000 * connectAttempts;
|
|
@@ -53,84 +138,58 @@ export class PassthroughHandler {
|
|
|
53
138
|
}
|
|
54
139
|
}
|
|
55
140
|
if (connected === true) {
|
|
56
|
-
this.channel.prefetch(1); // This ensures we only get one packet at a time! This appears to have prevented throttling
|
|
141
|
+
await this.channel.prefetch(1); // This ensures we only get one packet at a time! This appears to have prevented throttling
|
|
57
142
|
this.packetQueue = `${LOCAL_CONNECTION_ROUTING_KEY}`;
|
|
58
143
|
await this.channel.assertQueue(this.packetQueue, {
|
|
59
144
|
durable: true
|
|
60
145
|
});
|
|
146
|
+
logger.info(`Local connection established.`);
|
|
61
147
|
} else {
|
|
62
148
|
throw new Error(
|
|
63
149
|
'Unable to establish connection to alwaysAI Local Connection, please try restarting Device Agent.'
|
|
64
150
|
);
|
|
65
151
|
}
|
|
66
152
|
}
|
|
67
|
-
}
|
|
68
153
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
case 'analytics':
|
|
78
|
-
ackQueue.push(msg);
|
|
79
|
-
// FIXME: put real topic here
|
|
80
|
-
passthroughHandler.publisher.publishToCloudWithAck(
|
|
81
|
-
packet,
|
|
82
|
-
(errOrResp) => {
|
|
83
|
-
while (ackQueue.length > 0) {
|
|
84
|
-
const msg = ackQueue.shift();
|
|
85
|
-
if (errOrResp === true) {
|
|
86
|
-
passthroughHandler.channel.ack(msg); // acknowledge, allow queue to discard
|
|
87
|
-
} else if (errOrResp === false) {
|
|
88
|
-
passthroughHandler.channel.reject(msg, true); // reject and requeue
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
);
|
|
93
|
-
break;
|
|
94
|
-
case 'heartbeat':
|
|
95
|
-
passthroughHandler.channel.ack(msg);
|
|
96
|
-
logger.debug(
|
|
97
|
-
`Heartbeat package received & acknowledged: ${packet}`
|
|
98
|
-
);
|
|
99
|
-
break;
|
|
100
|
-
default:
|
|
101
|
-
passthroughHandler.channel.ack(msg);
|
|
102
|
-
logger.debug(
|
|
103
|
-
`Unknown 'action' package received & acknowledged: ${packet}`
|
|
104
|
-
);
|
|
105
|
-
break;
|
|
106
|
-
}
|
|
107
|
-
} else {
|
|
108
|
-
passthroughHandler.channel.ack(msg);
|
|
109
|
-
logger.debug(
|
|
110
|
-
`Received & acknowledged a RabbitMQ Package of unknown structure: ${parsedPacket}`
|
|
111
|
-
);
|
|
154
|
+
private async publishPassthroughStatusUpdate(
|
|
155
|
+
status: PassthroughStatusValue,
|
|
156
|
+
message?: string
|
|
157
|
+
) {
|
|
158
|
+
const deviceAgentPassthroughStatus: DeviceAgentStatusShadowUpdate = {
|
|
159
|
+
passthrough: {
|
|
160
|
+
status: status,
|
|
161
|
+
message: message ?? ''
|
|
112
162
|
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
163
|
+
};
|
|
164
|
+
await this.shadowHandler.updateDeviceAgentStatusShadow(
|
|
165
|
+
deviceAgentPassthroughStatus
|
|
166
|
+
);
|
|
118
167
|
}
|
|
119
|
-
}
|
|
120
168
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
169
|
+
async setup() {
|
|
170
|
+
if (ALWAYSAI_ANALYTICS_PASSTHROUGH === true) {
|
|
171
|
+
logger.debug(
|
|
172
|
+
`Setting up alwaysAI Local Connection on host: ${LOCAL_CONNECTION_HOST} and channel key: ${LOCAL_CONNECTION_ROUTING_KEY}`
|
|
173
|
+
);
|
|
174
|
+
await this.publishPassthroughStatusUpdate('starting');
|
|
175
|
+
await setupRabbitMQContainer();
|
|
176
|
+
try {
|
|
177
|
+
await this.establishLocalConnection();
|
|
178
|
+
await this.runChannel();
|
|
179
|
+
await this.publishPassthroughStatusUpdate(
|
|
180
|
+
'running',
|
|
181
|
+
`Passthrough running on host: ${LOCAL_CONNECTION_HOST} and channel key: ${LOCAL_CONNECTION_ROUTING_KEY}`
|
|
182
|
+
);
|
|
183
|
+
} catch (e) {
|
|
184
|
+
logger.error(
|
|
185
|
+
`There was a problem maintaining RabbitMQ connection!\n${stringifyError(
|
|
186
|
+
e
|
|
187
|
+
)}`
|
|
188
|
+
);
|
|
189
|
+
await this.publishPassthroughStatusUpdate('error', stringifyError(e));
|
|
130
190
|
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
noAck: false // When true, RabbitMQ deletes message as soon as it is consumed
|
|
191
|
+
} else {
|
|
192
|
+
await this.publishPassthroughStatusUpdate('disabled');
|
|
134
193
|
}
|
|
135
|
-
|
|
194
|
+
}
|
|
136
195
|
}
|
|
@@ -68,13 +68,11 @@ describe('Test Shadow Handler', () => {
|
|
|
68
68
|
|
|
69
69
|
test('handle project shadow empty delta', async () => {
|
|
70
70
|
const payload = {
|
|
71
|
-
|
|
72
|
-
[projectId1]: {}
|
|
73
|
-
}
|
|
71
|
+
[projectId1]: {}
|
|
74
72
|
};
|
|
75
73
|
|
|
76
74
|
const updates = await shadowHandler.handleProjectShadow({
|
|
77
|
-
topic: getShadowTopic(clientId, 'projects', 'update/
|
|
75
|
+
topic: getShadowTopic(clientId, 'projects', 'update/delta'),
|
|
78
76
|
payload,
|
|
79
77
|
clientToken: ''
|
|
80
78
|
});
|
|
@@ -104,16 +102,14 @@ describe('Test Shadow Handler', () => {
|
|
|
104
102
|
|
|
105
103
|
const payload = {
|
|
106
104
|
state: {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
appConfig: JSON.stringify(appCfg1)
|
|
110
|
-
}
|
|
105
|
+
[projectId1]: {
|
|
106
|
+
appConfig: JSON.stringify(appCfg1)
|
|
111
107
|
}
|
|
112
108
|
}
|
|
113
109
|
};
|
|
114
110
|
|
|
115
111
|
const updates = await shadowHandler.handleProjectShadow({
|
|
116
|
-
topic: getShadowTopic(clientId, 'projects', 'update/
|
|
112
|
+
topic: getShadowTopic(clientId, 'projects', 'update/delta'),
|
|
117
113
|
payload,
|
|
118
114
|
clientToken: ''
|
|
119
115
|
});
|
|
@@ -153,16 +149,14 @@ describe('Test Shadow Handler', () => {
|
|
|
153
149
|
|
|
154
150
|
const payload = {
|
|
155
151
|
state: {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
appConfig: JSON.stringify(appCfg1)
|
|
159
|
-
}
|
|
152
|
+
[projectId1]: {
|
|
153
|
+
appConfig: JSON.stringify(appCfg1)
|
|
160
154
|
}
|
|
161
155
|
}
|
|
162
156
|
};
|
|
163
157
|
|
|
164
158
|
const updates = await shadowHandler.handleProjectShadow({
|
|
165
|
-
topic: getShadowTopic(clientId, 'projects', 'update/
|
|
159
|
+
topic: getShadowTopic(clientId, 'projects', 'update/delta'),
|
|
166
160
|
payload,
|
|
167
161
|
clientToken: ''
|
|
168
162
|
});
|
|
@@ -220,19 +214,17 @@ describe('Test Shadow Handler', () => {
|
|
|
220
214
|
};
|
|
221
215
|
const payload = {
|
|
222
216
|
state: {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
appConfig: JSON.stringify(appCfg2)
|
|
229
|
-
}
|
|
217
|
+
[projectId1]: {
|
|
218
|
+
appConfig: JSON.stringify(appCfg1)
|
|
219
|
+
},
|
|
220
|
+
[projectId2]: {
|
|
221
|
+
appConfig: JSON.stringify(appCfg2)
|
|
230
222
|
}
|
|
231
223
|
}
|
|
232
224
|
};
|
|
233
225
|
|
|
234
226
|
const updates = await shadowHandler.handleProjectShadow({
|
|
235
|
-
topic: getShadowTopic(clientId, 'projects', 'update/
|
|
227
|
+
topic: getShadowTopic(clientId, 'projects', 'update/delta'),
|
|
236
228
|
payload,
|
|
237
229
|
clientToken: ''
|
|
238
230
|
});
|
|
@@ -281,16 +273,14 @@ describe('Test Shadow Handler', () => {
|
|
|
281
273
|
|
|
282
274
|
const payload = {
|
|
283
275
|
state: {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
appConfig: JSON.stringify(appCfg1)
|
|
287
|
-
}
|
|
276
|
+
[projectId1]: {
|
|
277
|
+
appConfig: JSON.stringify(appCfg1)
|
|
288
278
|
}
|
|
289
279
|
}
|
|
290
280
|
};
|
|
291
281
|
|
|
292
282
|
const updates = await shadowHandler.handleProjectShadow({
|
|
293
|
-
topic: getShadowTopic(clientId, 'projects', 'update/
|
|
283
|
+
topic: getShadowTopic(clientId, 'projects', 'update/delta'),
|
|
294
284
|
payload,
|
|
295
285
|
clientToken: ''
|
|
296
286
|
});
|
|
@@ -365,10 +355,8 @@ describe('Test Shadow Handler', () => {
|
|
|
365
355
|
|
|
366
356
|
const payload = {
|
|
367
357
|
state: {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
appConfig: appCfg1 // This is missing JSON.stringify() making this an unparsable object.
|
|
371
|
-
}
|
|
358
|
+
[projectId1]: {
|
|
359
|
+
appConfig: appCfg1 // This is missing JSON.stringify() making this an unparsable object.
|
|
372
360
|
}
|
|
373
361
|
}
|
|
374
362
|
};
|
|
@@ -378,7 +366,7 @@ describe('Test Shadow Handler', () => {
|
|
|
378
366
|
.mockReturnValue({} as unknown as Logger);
|
|
379
367
|
|
|
380
368
|
const updates = await shadowHandler.handleProjectShadow({
|
|
381
|
-
topic: getShadowTopic(clientId, 'projects', 'update/
|
|
369
|
+
topic: getShadowTopic(clientId, 'projects', 'update/delta'),
|
|
382
370
|
payload,
|
|
383
371
|
clientToken: ''
|
|
384
372
|
});
|
|
@@ -393,13 +381,15 @@ describe('Test Shadow Handler', () => {
|
|
|
393
381
|
describe('handle project shadow env vars', () => {
|
|
394
382
|
test('handle a response from the getAccepted from the cloud', async () => {
|
|
395
383
|
const envVars1 = {
|
|
396
|
-
|
|
384
|
+
service: {
|
|
385
|
+
VAR0: 'value0'
|
|
386
|
+
}
|
|
397
387
|
};
|
|
398
388
|
const payload = {
|
|
399
389
|
state: {
|
|
400
390
|
reported: {
|
|
401
391
|
[projectId1]: {
|
|
402
|
-
envVars:
|
|
392
|
+
envVars: JSON.stringify(envVars1)
|
|
403
393
|
}
|
|
404
394
|
}
|
|
405
395
|
}
|
|
@@ -414,22 +404,20 @@ describe('Test Shadow Handler', () => {
|
|
|
414
404
|
});
|
|
415
405
|
test('handle project shadow env vars update delta', async () => {
|
|
416
406
|
const envVars1 = {
|
|
417
|
-
|
|
407
|
+
service: {
|
|
408
|
+
VAR1: 'value1'
|
|
409
|
+
}
|
|
418
410
|
};
|
|
419
411
|
const payload = {
|
|
420
412
|
state: {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
envVars: {
|
|
424
|
-
service: envVars1
|
|
425
|
-
}
|
|
426
|
-
}
|
|
413
|
+
[projectId1]: {
|
|
414
|
+
envVars: JSON.stringify(envVars1)
|
|
427
415
|
}
|
|
428
416
|
}
|
|
429
417
|
};
|
|
430
418
|
|
|
431
419
|
const updates = await shadowHandler.handleProjectShadow({
|
|
432
|
-
topic: getShadowTopic(clientId, 'projects', 'update/
|
|
420
|
+
topic: getShadowTopic(clientId, 'projects', 'update/delta'),
|
|
433
421
|
payload,
|
|
434
422
|
clientToken: ''
|
|
435
423
|
});
|
|
@@ -438,36 +426,36 @@ describe('Test Shadow Handler', () => {
|
|
|
438
426
|
projectId: projectId1,
|
|
439
427
|
txId: expect.any(String),
|
|
440
428
|
envVarUpdate: {
|
|
441
|
-
envVars:
|
|
429
|
+
envVars: envVars1
|
|
442
430
|
}
|
|
443
431
|
});
|
|
444
432
|
});
|
|
445
433
|
|
|
446
434
|
test('handle project shadow env vars update delta for two projects', async () => {
|
|
447
435
|
const service1 = {
|
|
448
|
-
|
|
436
|
+
service: {
|
|
437
|
+
VAR1: 'value1'
|
|
438
|
+
}
|
|
449
439
|
};
|
|
450
440
|
const service2 = {
|
|
451
|
-
|
|
441
|
+
service: {
|
|
442
|
+
VAR2: 'value2'
|
|
443
|
+
}
|
|
452
444
|
};
|
|
453
445
|
|
|
454
446
|
const payload = {
|
|
455
447
|
state: {
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
},
|
|
462
|
-
[projectId2]: {
|
|
463
|
-
envVars: { service: service2 }
|
|
464
|
-
}
|
|
448
|
+
[projectId1]: {
|
|
449
|
+
envVars: JSON.stringify(service1)
|
|
450
|
+
},
|
|
451
|
+
[projectId2]: {
|
|
452
|
+
envVars: JSON.stringify(service2)
|
|
465
453
|
}
|
|
466
454
|
}
|
|
467
455
|
};
|
|
468
456
|
|
|
469
457
|
const updates = await shadowHandler.handleProjectShadow({
|
|
470
|
-
topic: getShadowTopic(clientId, 'projects', 'update/
|
|
458
|
+
topic: getShadowTopic(clientId, 'projects', 'update/delta'),
|
|
471
459
|
payload,
|
|
472
460
|
clientToken: ''
|
|
473
461
|
});
|
|
@@ -476,14 +464,14 @@ describe('Test Shadow Handler', () => {
|
|
|
476
464
|
projectId: projectId1,
|
|
477
465
|
txId: expect.any(String),
|
|
478
466
|
envVarUpdate: {
|
|
479
|
-
envVars:
|
|
467
|
+
envVars: service1
|
|
480
468
|
}
|
|
481
469
|
});
|
|
482
470
|
expect(updates[1]).toEqual({
|
|
483
471
|
projectId: projectId2,
|
|
484
472
|
txId: expect.any(String),
|
|
485
473
|
envVarUpdate: {
|
|
486
|
-
envVars:
|
|
474
|
+
envVars: service2
|
|
487
475
|
}
|
|
488
476
|
});
|
|
489
477
|
});
|