@alwaysai/device-agent 1.5.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/application-control/config.d.ts.map +1 -1
- package/lib/application-control/config.js +8 -3
- package/lib/application-control/config.js.map +1 -1
- package/lib/application-control/environment-variables.d.ts +5 -5
- package/lib/application-control/environment-variables.d.ts.map +1 -1
- package/lib/application-control/environment-variables.js +25 -38
- 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 +4 -1
- package/lib/application-control/install.d.ts.map +1 -1
- package/lib/application-control/install.js +24 -8
- package/lib/application-control/install.js.map +1 -1
- package/lib/application-control/models.d.ts +0 -11
- package/lib/application-control/models.d.ts.map +1 -1
- package/lib/application-control/models.js +5 -54
- package/lib/application-control/models.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 +12 -22
- package/lib/application-control/utils.js.map +1 -1
- package/lib/cloud-connection/base-message-handler.d.ts +27 -0
- package/lib/cloud-connection/base-message-handler.d.ts.map +1 -0
- package/lib/cloud-connection/base-message-handler.js +72 -0
- package/lib/cloud-connection/base-message-handler.js.map +1 -0
- package/lib/cloud-connection/bootstrap-provision.js +3 -2
- package/lib/cloud-connection/bootstrap-provision.js.map +1 -1
- package/lib/cloud-connection/connection-manager.d.ts +21 -0
- package/lib/cloud-connection/connection-manager.d.ts.map +1 -0
- package/lib/cloud-connection/connection-manager.js +158 -0
- package/lib/cloud-connection/connection-manager.js.map +1 -0
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts +9 -30
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
- package/lib/cloud-connection/device-agent-cloud-connection.js +69 -508
- package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
- package/lib/cloud-connection/device-agent-message-handler.d.ts +22 -0
- package/lib/cloud-connection/device-agent-message-handler.d.ts.map +1 -0
- package/lib/cloud-connection/device-agent-message-handler.js +357 -0
- package/lib/cloud-connection/device-agent-message-handler.js.map +1 -0
- 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 +19 -28
- package/lib/cloud-connection/live-updates-handler.d.ts.map +1 -1
- package/lib/cloud-connection/live-updates-handler.js +60 -172
- package/lib/cloud-connection/live-updates-handler.js.map +1 -1
- package/lib/cloud-connection/live-updates-handler.test.js +71 -165
- package/lib/cloud-connection/live-updates-handler.test.js.map +1 -1
- package/lib/cloud-connection/message-dispatcher.d.ts +10 -0
- package/lib/cloud-connection/message-dispatcher.d.ts.map +1 -0
- package/lib/cloud-connection/message-dispatcher.js +27 -0
- package/lib/cloud-connection/message-dispatcher.js.map +1 -0
- package/lib/cloud-connection/passthrough-handler.d.ts +4 -1
- package/lib/cloud-connection/passthrough-handler.d.ts.map +1 -1
- package/lib/cloud-connection/passthrough-handler.js +30 -11
- package/lib/cloud-connection/passthrough-handler.js.map +1 -1
- package/lib/cloud-connection/shadow-handler.d.ts +11 -3
- package/lib/cloud-connection/shadow-handler.d.ts.map +1 -1
- package/lib/cloud-connection/shadow-handler.js +133 -28
- 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 +12 -3
- package/lib/cloud-connection/transaction-manager.d.ts.map +1 -1
- package/lib/cloud-connection/transaction-manager.js +29 -28
- package/lib/cloud-connection/transaction-manager.js.map +1 -1
- package/lib/cloud-connection/transaction-manager.test.js +46 -5
- package/lib/cloud-connection/transaction-manager.test.js.map +1 -1
- package/lib/device-control/device-control.d.ts +8 -8
- package/lib/device-control/device-control.d.ts.map +1 -1
- package/lib/device-control/device-control.js +95 -71
- package/lib/device-control/device-control.js.map +1 -1
- package/lib/docker/docker-compose.d.ts.map +1 -1
- package/lib/docker/docker-compose.js +2 -1
- package/lib/docker/docker-compose.js.map +1 -1
- package/lib/infrastructure/agent-config.d.ts +2 -1
- package/lib/infrastructure/agent-config.d.ts.map +1 -1
- package/lib/infrastructure/agent-config.js +7 -7
- package/lib/infrastructure/agent-config.js.map +1 -1
- package/lib/infrastructure/agent-config.test.js +3 -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/jobs/job-handler.d.ts +23 -0
- package/lib/jobs/job-handler.d.ts.map +1 -0
- package/lib/jobs/job-handler.js +131 -0
- package/lib/jobs/job-handler.js.map +1 -0
- package/lib/local-connection/rabbitmq-connection.d.ts.map +1 -1
- package/lib/local-connection/rabbitmq-connection.js +14 -14
- package/lib/local-connection/rabbitmq-connection.js.map +1 -1
- package/lib/secure-tunneling/secure-tunnel-message-handler.d.ts +8 -0
- package/lib/secure-tunneling/secure-tunnel-message-handler.d.ts.map +1 -0
- package/lib/secure-tunneling/secure-tunnel-message-handler.js +42 -0
- package/lib/secure-tunneling/secure-tunnel-message-handler.js.map +1 -0
- package/lib/secure-tunneling/secure-tunneling.d.ts +9 -9
- package/lib/secure-tunneling/secure-tunneling.d.ts.map +1 -1
- package/lib/secure-tunneling/secure-tunneling.js +21 -16
- package/lib/secure-tunneling/secure-tunneling.js.map +1 -1
- package/lib/secure-tunneling/secure-tunneling.test.js +11 -13
- 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 +2 -0
- package/lib/subcommands/app/version.d.ts.map +1 -1
- package/lib/subcommands/app/version.js +16 -6
- 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 +23 -13
- package/lib/subcommands/device/clean.js.map +1 -1
- package/lib/subcommands/device/index.d.ts.map +1 -1
- package/lib/subcommands/device/index.js +3 -1
- package/lib/subcommands/device/index.js.map +1 -1
- package/lib/subcommands/device/init.js +8 -8
- package/lib/subcommands/device/init.js.map +1 -1
- 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.map +1 -1
- package/lib/subcommands/device/refresh.js +1 -0
- package/lib/subcommands/device/refresh.js.map +1 -1
- 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.map +1 -1
- package/lib/util/check-for-updates.js +5 -28
- package/lib/util/check-for-updates.js.map +1 -1
- 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 +4 -0
- package/lib/util/file.d.ts.map +1 -1
- package/lib/util/file.js +65 -4
- package/lib/util/file.js.map +1 -1
- 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 +19 -17
- package/readme.md +12 -32
- package/src/application-control/config.ts +9 -12
- package/src/application-control/environment-variables.test.ts +28 -7
- package/src/application-control/environment-variables.ts +42 -59
- package/src/application-control/index.ts +3 -16
- package/src/application-control/install.ts +39 -13
- package/src/application-control/models.ts +6 -87
- package/src/application-control/utils.ts +10 -25
- package/src/cloud-connection/base-message-handler.ts +118 -0
- package/src/cloud-connection/bootstrap-provision.ts +7 -7
- package/src/cloud-connection/connection-manager.ts +187 -0
- package/src/cloud-connection/device-agent-cloud-connection.ts +130 -723
- package/src/cloud-connection/device-agent-message-handler.ts +642 -0
- package/src/cloud-connection/device-agent.ts +16 -7
- package/src/cloud-connection/live-updates-handler.test.ts +121 -189
- package/src/cloud-connection/live-updates-handler.ts +105 -232
- package/src/cloud-connection/message-dispatcher.ts +33 -0
- package/src/cloud-connection/passthrough-handler.ts +55 -18
- package/src/cloud-connection/shadow-handler.test.ts +45 -57
- package/src/cloud-connection/shadow-handler.ts +224 -54
- package/src/cloud-connection/shadow.ts +4 -1
- package/src/cloud-connection/transaction-manager.test.ts +68 -6
- package/src/cloud-connection/transaction-manager.ts +69 -41
- package/src/device-control/device-control.ts +102 -70
- package/src/docker/docker-compose.ts +3 -2
- package/src/infrastructure/agent-config.test.ts +6 -2
- package/src/infrastructure/agent-config.ts +8 -7
- 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/jobs/job-handler.ts +146 -0
- package/src/local-connection/rabbitmq-connection.ts +22 -17
- package/src/secure-tunneling/secure-tunnel-message-handler.ts +56 -0
- package/src/secure-tunneling/secure-tunneling.test.ts +20 -22
- package/src/secure-tunneling/secure-tunneling.ts +41 -29
- 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 +23 -6
- package/src/subcommands/config.ts +42 -0
- package/src/subcommands/device/clean.ts +31 -17
- package/src/subcommands/device/index.ts +3 -1
- package/src/subcommands/device/init.ts +11 -11
- package/src/subcommands/device/migrate.ts +20 -0
- package/src/subcommands/device/refresh.ts +1 -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 +14 -30
- package/src/util/clean-certs.ts +8 -4
- package/src/util/directories.ts +23 -67
- package/src/util/file.ts +83 -3
- package/src/util/get-device-id.ts +7 -7
- package/src/util/http-client.ts +2 -2
- 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/src/util/download-file.ts +0 -25
- package/src/util/fetch-with-timeout.ts +0 -35
- package/src/util/parsing.ts +0 -11
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { logger } from '../util/logger';
|
|
2
|
-
import { microServiceHttpClient } from '../util/http-client';
|
|
3
|
-
import { requireLoggedInAndPaidPlan } from '../util/require-logged-in-and-paid-plan';
|
|
4
1
|
import {
|
|
5
2
|
DeviceTokens,
|
|
6
|
-
writeOrValidateDeviceCfgFile
|
|
7
|
-
writeTokens
|
|
3
|
+
writeOrValidateDeviceCfgFile
|
|
8
4
|
} from 'alwaysai/lib/core/device';
|
|
9
|
-
import {
|
|
5
|
+
import { getDeviceConfigPath } from 'alwaysai/lib/infrastructure';
|
|
10
6
|
import { LOCAL_AAI_CFG_DIR } from 'alwaysai/lib/paths';
|
|
7
|
+
import { JsSpawner } from 'alwaysai/lib/util';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
import { microServiceHttpClient } from '../util/http-client';
|
|
10
|
+
import { logger } from '../util/logger';
|
|
11
|
+
import { requireLoggedInAndPaidPlan } from '../util/require-logged-in-and-paid-plan';
|
|
11
12
|
|
|
12
13
|
// NOTE: This closely follows the flow of deviceCheckAndUpdateComponent in the CLI
|
|
13
14
|
export async function writeTokenAndDeviceCfg(props: { deviceUuid: string }) {
|
|
@@ -21,14 +22,15 @@ export async function writeTokenAndDeviceCfg(props: { deviceUuid: string }) {
|
|
|
21
22
|
);
|
|
22
23
|
|
|
23
24
|
const tokens: DeviceTokens = {
|
|
24
|
-
|
|
25
|
+
deviceUuid,
|
|
25
26
|
accessToken,
|
|
26
27
|
refreshToken,
|
|
27
28
|
idToken
|
|
28
29
|
};
|
|
29
|
-
const tokenSpawner = JsSpawner({
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
const tokenSpawner = JsSpawner({
|
|
31
|
+
path: join(LOCAL_AAI_CFG_DIR, getDeviceConfigPath())
|
|
32
|
+
});
|
|
33
|
+
await writeOrValidateDeviceCfgFile({ spawner: tokenSpawner, ...tokens });
|
|
32
34
|
|
|
33
35
|
logger.info('Updated tokens and certificate');
|
|
34
36
|
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { MessageHandler } from '../cloud-connection/message-dispatcher';
|
|
2
|
+
import { logger } from '../util/logger';
|
|
3
|
+
import {
|
|
4
|
+
BaseHandler,
|
|
5
|
+
HandlerContext
|
|
6
|
+
} from '../cloud-connection/base-message-handler';
|
|
7
|
+
import { DeviceAgentMessageHandler } from '../cloud-connection/device-agent-message-handler';
|
|
8
|
+
|
|
9
|
+
class JobState {
|
|
10
|
+
private static instance: JobState;
|
|
11
|
+
public jobInProgress = false;
|
|
12
|
+
|
|
13
|
+
// Singleton pattern
|
|
14
|
+
private constructor() { } // eslint-disable-line
|
|
15
|
+
|
|
16
|
+
static getInstance(): JobState {
|
|
17
|
+
if (!JobState.instance) {
|
|
18
|
+
JobState.instance = new JobState();
|
|
19
|
+
}
|
|
20
|
+
return JobState.instance;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class JobHandler extends BaseHandler implements MessageHandler {
|
|
25
|
+
private readonly msgHandler: DeviceAgentMessageHandler;
|
|
26
|
+
|
|
27
|
+
constructor(handlerContext: HandlerContext) {
|
|
28
|
+
super(handlerContext);
|
|
29
|
+
this.msgHandler = new DeviceAgentMessageHandler(
|
|
30
|
+
handlerContext,
|
|
31
|
+
this.handleJobError,
|
|
32
|
+
this.handleJobSuccess
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
private readonly state = JobState.getInstance();
|
|
36
|
+
private jobId = '';
|
|
37
|
+
|
|
38
|
+
public async handle(message: any, topic: string): Promise<void> {
|
|
39
|
+
const TOPICS = this.getJobTopic();
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
switch (topic) {
|
|
43
|
+
case TOPICS.NOTIFY_NEXT:
|
|
44
|
+
await this.notifyNext(message);
|
|
45
|
+
break;
|
|
46
|
+
case TOPICS.START_NEXT_ACCEPTED:
|
|
47
|
+
this.startNextAccepted(message);
|
|
48
|
+
break;
|
|
49
|
+
default:
|
|
50
|
+
logger.info(`No handler for topic: ${topic}`);
|
|
51
|
+
}
|
|
52
|
+
} catch (error) {
|
|
53
|
+
logger.error(`Error handling job for topic: ${topic}`, error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
getJobTopic() {
|
|
58
|
+
const TOPICS = {
|
|
59
|
+
NOTIFY_NEXT: `$aws/things/${this.clientId}/jobs/notify-next`,
|
|
60
|
+
START_NEXT: `$aws/things/${this.clientId}/jobs/start-next`,
|
|
61
|
+
START_NEXT_ACCEPTED: `$aws/things/${this.clientId}/jobs/start-next/accepted`,
|
|
62
|
+
UPDATE: `$aws/things/${this.clientId}/jobs/${this.jobId}/update`
|
|
63
|
+
};
|
|
64
|
+
return TOPICS;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private async notifyNext(message: any): Promise<void> {
|
|
68
|
+
// Triggers when a job is completed and we need to notify the next job
|
|
69
|
+
logger.info('Invoking NOTIFY_NEXT handler');
|
|
70
|
+
const TOPICS = this.getJobTopic();
|
|
71
|
+
this.publisher.publish(TOPICS.START_NEXT, JSON.stringify({}));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
private startNextAccepted(message: any): void {
|
|
75
|
+
if (this.state.jobInProgress) {
|
|
76
|
+
logger.info('Job already in progress');
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
this.state.jobInProgress = true;
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
if (message.execution) {
|
|
84
|
+
this.processJobExecution(message.execution);
|
|
85
|
+
} else {
|
|
86
|
+
this.state.jobInProgress = false;
|
|
87
|
+
}
|
|
88
|
+
} catch (error: unknown) {
|
|
89
|
+
this.handleError(error);
|
|
90
|
+
}
|
|
91
|
+
this.state.jobInProgress = false;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private processJobExecution(execution: any): void {
|
|
95
|
+
logger.info('Job in progress...');
|
|
96
|
+
const { jobDocument, jobId } = execution;
|
|
97
|
+
this.jobId = jobId;
|
|
98
|
+
this.msgHandler.handle(jobDocument);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private handleError(error: unknown): void {
|
|
102
|
+
if (error instanceof Error) {
|
|
103
|
+
logger.error(`Error starting next job`, error);
|
|
104
|
+
this.handleJobError('', error.message);
|
|
105
|
+
} else {
|
|
106
|
+
let errorMessage: string;
|
|
107
|
+
if (typeof error === 'string') {
|
|
108
|
+
errorMessage = error;
|
|
109
|
+
} else if (typeof error === 'object' && error !== null) {
|
|
110
|
+
try {
|
|
111
|
+
errorMessage = JSON.stringify(error);
|
|
112
|
+
} catch (jsonError) {
|
|
113
|
+
errorMessage = 'Unknown error (failed to stringify)';
|
|
114
|
+
}
|
|
115
|
+
} else {
|
|
116
|
+
errorMessage = 'Unknown error';
|
|
117
|
+
}
|
|
118
|
+
logger.error(`Unexpected error: ${errorMessage}`);
|
|
119
|
+
this.handleJobError('', errorMessage);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private updateJobStatus(status: string, message?: string): void {
|
|
124
|
+
const { UPDATE } = this.getJobTopic();
|
|
125
|
+
const payload = {
|
|
126
|
+
status,
|
|
127
|
+
statusDetails: {
|
|
128
|
+
message
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
this.publisher.publish(UPDATE, JSON.stringify(payload));
|
|
133
|
+
logger.info(`Marked job ${this.jobId} as ${status}`);
|
|
134
|
+
// Reset the job state
|
|
135
|
+
this.state.jobInProgress = false;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
private readonly handleJobSuccess = (txId: string): void => {
|
|
139
|
+
this.updateJobStatus('SUCCEEDED');
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
private readonly handleJobError = (_txId: string, msg: string): void => {
|
|
143
|
+
logger.error(`Unexpected error type: ${msg}`);
|
|
144
|
+
this.updateJobStatus('FAILED', `Unexpected error: ${msg}`);
|
|
145
|
+
};
|
|
146
|
+
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import sleep from '../util/sleep';
|
|
3
|
-
import { compose } from '../docker/docker-compose';
|
|
1
|
+
import { JsSpawner, stringifyError } from 'alwaysai/lib/util';
|
|
4
2
|
import * as YAML from 'yaml';
|
|
5
|
-
|
|
3
|
+
import { compose } from '../docker/docker-compose';
|
|
6
4
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
getDeviceAgentConfigPath,
|
|
6
|
+
getDeviceAgentDockerComposePath
|
|
9
7
|
} from '../util/directories';
|
|
10
|
-
import {
|
|
8
|
+
import { logger } from '../util/logger';
|
|
9
|
+
import sleep from '../util/sleep';
|
|
11
10
|
import { LOCAL_CONNECTION_PORT } from './constants';
|
|
12
11
|
|
|
13
12
|
export const rabbitMQServiceName = 'alwaysAIRabbitMQ';
|
|
@@ -16,13 +15,13 @@ export const rabbitMQContainerName = 'alwaysAIRabbitMQContainer';
|
|
|
16
15
|
export async function checkRabbitMQContainerRunning() {
|
|
17
16
|
logger.debug('Checking alwaysAI Local Connection Container status');
|
|
18
17
|
const spawner = JsSpawner();
|
|
19
|
-
if (!(await spawner.exists(
|
|
18
|
+
if (!(await spawner.exists(getDeviceAgentDockerComposePath()))) {
|
|
20
19
|
logger.warn(
|
|
21
20
|
'alwaysAI Location Connection configuration file is not present'
|
|
22
21
|
);
|
|
23
22
|
return false;
|
|
24
23
|
}
|
|
25
|
-
const containerData = await compose.ps({ cwd:
|
|
24
|
+
const containerData = await compose.ps({ cwd: getDeviceAgentConfigPath() });
|
|
26
25
|
if (containerData !== undefined) {
|
|
27
26
|
const rabbitmqService = containerData.data.services[0];
|
|
28
27
|
if (
|
|
@@ -41,8 +40,8 @@ export async function checkRabbitMQContainerRunning() {
|
|
|
41
40
|
|
|
42
41
|
export async function writeRabbitMQDockerComposeFile() {
|
|
43
42
|
const spawner = JsSpawner();
|
|
44
|
-
if (!(await spawner.exists(
|
|
45
|
-
await JsSpawner().mkdirp(
|
|
43
|
+
if (!(await spawner.exists(getDeviceAgentConfigPath()))) {
|
|
44
|
+
await JsSpawner().mkdirp(getDeviceAgentConfigPath());
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
logger.debug(
|
|
@@ -68,7 +67,7 @@ export async function writeRabbitMQDockerComposeFile() {
|
|
|
68
67
|
|
|
69
68
|
const RabbitMQDockerComposeYaml = YAML.stringify(rabbitmqDockerComposeCmd);
|
|
70
69
|
await spawner.writeFile(
|
|
71
|
-
|
|
70
|
+
getDeviceAgentDockerComposePath(),
|
|
72
71
|
RabbitMQDockerComposeYaml
|
|
73
72
|
);
|
|
74
73
|
}
|
|
@@ -79,12 +78,14 @@ export async function setupRabbitMQContainer() {
|
|
|
79
78
|
await writeRabbitMQDockerComposeFile();
|
|
80
79
|
} catch (e) {
|
|
81
80
|
logger.error(
|
|
82
|
-
`An error occurred setting up docker-compose.yaml for Device Agent pass through
|
|
81
|
+
`An error occurred setting up docker-compose.yaml for Device Agent pass through!\n${stringifyError(
|
|
82
|
+
e
|
|
83
|
+
)}`
|
|
83
84
|
);
|
|
84
85
|
}
|
|
85
86
|
try {
|
|
86
87
|
const upOut = await compose.upAll({
|
|
87
|
-
cwd:
|
|
88
|
+
cwd: getDeviceAgentConfigPath()
|
|
88
89
|
});
|
|
89
90
|
logger.debug(
|
|
90
91
|
`Docker compose up for alwaysAI Local Connection:\n${JSON.stringify(
|
|
@@ -97,14 +98,16 @@ export async function setupRabbitMQContainer() {
|
|
|
97
98
|
}
|
|
98
99
|
} catch (e) {
|
|
99
100
|
logger.error(
|
|
100
|
-
`Unable to start alwaysAI Device Agent Local Connection Container
|
|
101
|
+
`Unable to start alwaysAI Device Agent Local Connection Container!\n${stringifyError(
|
|
102
|
+
e
|
|
103
|
+
)}`
|
|
101
104
|
);
|
|
102
105
|
}
|
|
103
106
|
}
|
|
104
107
|
|
|
105
108
|
export async function stopRabbitMQContainer() {
|
|
106
109
|
try {
|
|
107
|
-
const downOut = await compose.down({ cwd:
|
|
110
|
+
const downOut = await compose.down({ cwd: getDeviceAgentConfigPath() });
|
|
108
111
|
logger.debug(`Stopping alwaysAI Local Connection container`);
|
|
109
112
|
logger.debug(
|
|
110
113
|
`Docker compose down for alwaysAI Local Connection:\n${JSON.stringify(
|
|
@@ -113,7 +116,9 @@ export async function stopRabbitMQContainer() {
|
|
|
113
116
|
);
|
|
114
117
|
} catch (e) {
|
|
115
118
|
logger.error(
|
|
116
|
-
`Unable to stop alwaysAI Device Agent Local Connection Container
|
|
119
|
+
`Unable to stop alwaysAI Device Agent Local Connection Container!\n${stringifyError(
|
|
120
|
+
e
|
|
121
|
+
)}`
|
|
117
122
|
);
|
|
118
123
|
}
|
|
119
124
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getUpdateDeltaStateFromMessage,
|
|
3
|
+
validateSecureTunnelShadowUpdate
|
|
4
|
+
} from '@alwaysai/device-agent-schemas';
|
|
5
|
+
import { MessageHandler } from '../cloud-connection/message-dispatcher';
|
|
6
|
+
import { logger } from '../util/logger';
|
|
7
|
+
import { BaseHandler } from '../cloud-connection/base-message-handler';
|
|
8
|
+
|
|
9
|
+
export class SecureTunnelMessageHandler
|
|
10
|
+
extends BaseHandler
|
|
11
|
+
implements MessageHandler<any>
|
|
12
|
+
{
|
|
13
|
+
public getNotifyTopic(): string {
|
|
14
|
+
return `$aws/things/${this.clientId}/tunnels/notify`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
public async handle(message: any, topic: string): Promise<void> {
|
|
18
|
+
const secureTunnelNotifyTopic = this.getNotifyTopic();
|
|
19
|
+
if (topic === secureTunnelNotifyTopic) {
|
|
20
|
+
await this.secureTunnelHandler.secureTunnelNotifyHandler(message);
|
|
21
|
+
} else if (
|
|
22
|
+
topic === this.shadowHandler.shadowTopics.secureTunnel.updateDelta
|
|
23
|
+
) {
|
|
24
|
+
logger.info(`Received secure tunnel update: ${JSON.stringify(message)}`);
|
|
25
|
+
await this.handleSecureTunnelMessage(message);
|
|
26
|
+
} else if (
|
|
27
|
+
topic === this.shadowHandler.shadowTopics.secureTunnel.deleteAccepted
|
|
28
|
+
) {
|
|
29
|
+
logger.info(`Received secure tunnel deleteAccepted: ${message}`);
|
|
30
|
+
await this.secureTunnelHandler.destroy();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public async handleSecureTunnelMessage(payload: any): Promise<void> {
|
|
35
|
+
logger.info(`Received secure tunnel update: ${JSON.stringify(payload)}`);
|
|
36
|
+
const state = getUpdateDeltaStateFromMessage(payload);
|
|
37
|
+
if (!state) {
|
|
38
|
+
logger.debug(`No state found in message: ${JSON.stringify(payload)}`);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const valid = validateSecureTunnelShadowUpdate(state);
|
|
42
|
+
if (!valid) {
|
|
43
|
+
logger.error(
|
|
44
|
+
`Error validating message: ${JSON.stringify(
|
|
45
|
+
{ payload, errors: validateSecureTunnelShadowUpdate.errors },
|
|
46
|
+
null,
|
|
47
|
+
2
|
|
48
|
+
)}`
|
|
49
|
+
);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const secureTunnelUpdate =
|
|
53
|
+
await this.secureTunnelHandler.syncShadowToDeviceState(payload);
|
|
54
|
+
await this.shadowHandler.updateSecureTunnelShadow(secureTunnelUpdate);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SecureTunnelPortInfo,
|
|
3
|
+
SecureTunnelShadowUpdate
|
|
4
|
+
} from '@alwaysai/device-agent-schemas';
|
|
1
5
|
import { AAI_DIR } from 'alwaysai/lib/paths';
|
|
6
|
+
import { downloadToFile } from '../util/file';
|
|
7
|
+
import { ChildProcess } from 'child_process';
|
|
2
8
|
import { join } from 'path';
|
|
3
9
|
import { aaiArtifactsBucketUrl } from '../urls';
|
|
4
10
|
import {
|
|
@@ -7,19 +13,12 @@ import {
|
|
|
7
13
|
SECURE_TUNNEL_BIN_NAME,
|
|
8
14
|
SECURE_TUNNEL_BIN_PATH
|
|
9
15
|
} from '../util/directories';
|
|
10
|
-
import { downloadFile } from '../util/download-file';
|
|
11
16
|
import { getArch, getDistribution, getOsVersion } from '../util/system-info';
|
|
12
17
|
import {
|
|
13
18
|
SecureTunnelHandlerSingleton,
|
|
14
19
|
SecureTunnelShadowUpdateDelta
|
|
15
20
|
} from './secure-tunneling';
|
|
16
|
-
// import { JsSpawner } from 'alwaysai/lib/util/spawner';
|
|
17
|
-
import { ChildProcess } from 'child_process';
|
|
18
21
|
import { killDetachedProcess, runDetachedProcess } from './spawner-detached';
|
|
19
|
-
import {
|
|
20
|
-
SecureTunnelPortInfo,
|
|
21
|
-
SecureTunnelShadowDescriptionReported
|
|
22
|
-
} from '@alwaysai/device-agent-schemas';
|
|
23
22
|
//-----------------------------------------------------------------------------
|
|
24
23
|
// mocks
|
|
25
24
|
//-----------------------------------------------------------------------------
|
|
@@ -50,9 +49,8 @@ jest.mock('../util/system-info', () => ({
|
|
|
50
49
|
getDistribution: jest.fn()
|
|
51
50
|
}));
|
|
52
51
|
|
|
53
|
-
jest.mock('../util/
|
|
54
|
-
|
|
55
|
-
}));
|
|
52
|
+
jest.mock('../util/file');
|
|
53
|
+
const mockDownloadToFile = jest.mocked(downloadToFile);
|
|
56
54
|
|
|
57
55
|
jest.mock('./spawner-detached', () => ({
|
|
58
56
|
runDetachedProcess: jest.fn(),
|
|
@@ -174,10 +172,11 @@ describe('SecureTunnelHandlerSingleton', () => {
|
|
|
174
172
|
|
|
175
173
|
function transformDeltaToUpdateReported(
|
|
176
174
|
deltaMsg: SecureTunnelShadowUpdateDelta
|
|
177
|
-
):
|
|
175
|
+
): SecureTunnelShadowUpdate {
|
|
178
176
|
const { version, state } = deltaMsg;
|
|
179
|
-
const reportedStateReported:
|
|
180
|
-
JSON.
|
|
177
|
+
const reportedStateReported: SecureTunnelShadowUpdate = JSON.parse(
|
|
178
|
+
JSON.stringify(state)
|
|
179
|
+
);
|
|
181
180
|
return reportedStateReported;
|
|
182
181
|
}
|
|
183
182
|
|
|
@@ -705,7 +704,7 @@ describe('SecureTunnelHandlerSingleton', () => {
|
|
|
705
704
|
expect(getDistribution).not.toHaveBeenCalled();
|
|
706
705
|
expect(mockJsSpawner.mkdirp).not.toHaveBeenCalled();
|
|
707
706
|
expect(mockJsSpawner.run).not.toHaveBeenCalled();
|
|
708
|
-
expect(
|
|
707
|
+
expect(mockDownloadToFile).not.toHaveBeenCalled();
|
|
709
708
|
expect(runDetachedProcess).toHaveBeenCalledTimes(1);
|
|
710
709
|
expect(runDetachedProcess).toHaveBeenCalledWith(
|
|
711
710
|
SECURE_TUNNEL_BIN_PATH,
|
|
@@ -782,11 +781,10 @@ describe('SecureTunnelHandlerSingleton', () => {
|
|
|
782
781
|
exe: 'chmod',
|
|
783
782
|
args: ['+x', SECURE_TUNNEL_BIN_PATH]
|
|
784
783
|
});
|
|
785
|
-
expect(
|
|
786
|
-
expect(
|
|
784
|
+
expect(mockDownloadToFile).toHaveBeenCalledTimes(1);
|
|
785
|
+
expect(mockDownloadToFile).toHaveBeenCalledWith({
|
|
787
786
|
url: expectedUrl,
|
|
788
|
-
path: SECURE_TUNNEL_BIN_PATH
|
|
789
|
-
errorMessage: `Secure Tunnel bin for ${linuxDistro} ${osVersion} ${arch} not found}`
|
|
787
|
+
path: SECURE_TUNNEL_BIN_PATH
|
|
790
788
|
});
|
|
791
789
|
expect(runDetachedProcess).toHaveBeenCalledTimes(1);
|
|
792
790
|
expect(runDetachedProcess).toHaveBeenCalledWith(
|
|
@@ -916,7 +914,7 @@ describe('SecureTunnelHandlerSingleton', () => {
|
|
|
916
914
|
expect(getOsVersion).not.toHaveBeenCalled();
|
|
917
915
|
expect(getDistribution).not.toHaveBeenCalled();
|
|
918
916
|
expect(mockJsSpawner.mkdirp).not.toHaveBeenCalled();
|
|
919
|
-
expect(
|
|
917
|
+
expect(mockDownloadToFile).not.toHaveBeenCalled();
|
|
920
918
|
expect(mockJsSpawner.run).not.toHaveBeenCalled();
|
|
921
919
|
expect(runDetachedProcess).not.toHaveBeenCalled();
|
|
922
920
|
expect(killDetachedProcess).not.toHaveBeenCalled();
|
|
@@ -1028,7 +1026,7 @@ describe('SecureTunnelHandlerSingleton', () => {
|
|
|
1028
1026
|
expect(getOsVersion).not.toHaveBeenCalled();
|
|
1029
1027
|
expect(getDistribution).not.toHaveBeenCalled();
|
|
1030
1028
|
expect(mockJsSpawner.mkdirp).not.toHaveBeenCalled();
|
|
1031
|
-
expect(
|
|
1029
|
+
expect(mockDownloadToFile).not.toHaveBeenCalled();
|
|
1032
1030
|
expect(runDetachedProcess).not.toHaveBeenCalled();
|
|
1033
1031
|
expect(killDetachedProcess).not.toHaveBeenCalled();
|
|
1034
1032
|
}
|
|
@@ -1153,7 +1151,7 @@ describe('SecureTunnelHandlerSingleton', () => {
|
|
|
1153
1151
|
expect(getOsVersion).not.toHaveBeenCalled();
|
|
1154
1152
|
expect(getDistribution).not.toHaveBeenCalled();
|
|
1155
1153
|
expect(mockJsSpawner.mkdirp).not.toHaveBeenCalled();
|
|
1156
|
-
expect(
|
|
1154
|
+
expect(mockDownloadToFile).not.toHaveBeenCalled();
|
|
1157
1155
|
expect(mockJsSpawner.run).not.toHaveBeenCalled();
|
|
1158
1156
|
expect(runDetachedProcess).toHaveBeenCalledTimes(1);
|
|
1159
1157
|
expect(runDetachedProcess).toHaveBeenCalledWith(
|
|
@@ -1228,7 +1226,7 @@ describe('SecureTunnelHandlerSingleton', () => {
|
|
|
1228
1226
|
expect(getOsVersion).not.toHaveBeenCalled();
|
|
1229
1227
|
expect(getDistribution).not.toHaveBeenCalled();
|
|
1230
1228
|
expect(mockJsSpawner.mkdirp).not.toHaveBeenCalled();
|
|
1231
|
-
expect(
|
|
1229
|
+
expect(mockDownloadToFile).not.toHaveBeenCalled();
|
|
1232
1230
|
expect(mockJsSpawner.run).not.toHaveBeenCalled();
|
|
1233
1231
|
expect(runDetachedProcess).toHaveBeenCalledTimes(0);
|
|
1234
1232
|
expect(killDetachedProcess).toHaveBeenCalledTimes(2);
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SecureTunnelPortInfo,
|
|
3
|
+
SecureTunnelShadowUpdate
|
|
4
|
+
} from '@alwaysai/device-agent-schemas';
|
|
1
5
|
import { AAI_DIR } from 'alwaysai/lib/paths';
|
|
2
|
-
import { JsSpawner } from 'alwaysai/lib/util';
|
|
6
|
+
import { JsSpawner, stringifyError } from 'alwaysai/lib/util';
|
|
3
7
|
import { ChildProcess } from 'child_process';
|
|
4
8
|
import { join } from 'path';
|
|
5
9
|
import { aaiArtifactsBucketUrl } from '../urls';
|
|
6
|
-
import { isValidAwsRegion } from '../util/
|
|
10
|
+
import { isValidAwsRegion } from '../util/aws-regions';
|
|
7
11
|
import {
|
|
8
12
|
AWS_ROOT_CERTIFICATE_FILE_PATH,
|
|
9
13
|
SECURE_TUNNEL_BIN_DIR,
|
|
10
14
|
SECURE_TUNNEL_BIN_NAME,
|
|
11
15
|
SECURE_TUNNEL_BIN_PATH
|
|
12
16
|
} from '../util/directories';
|
|
13
|
-
import { downloadFile } from '../util/download-file';
|
|
14
17
|
import { logger } from '../util/logger';
|
|
15
18
|
import { getArch, getDistribution, getOsVersion } from '../util/system-info';
|
|
16
19
|
import { killDetachedProcess, runDetachedProcess } from './spawner-detached';
|
|
17
|
-
import {
|
|
18
|
-
SecureTunnelPortInfo,
|
|
19
|
-
SecureTunnelShadowDescriptionReported
|
|
20
|
-
} from '@alwaysai/device-agent-schemas';
|
|
20
|
+
import { downloadToFile } from '../util/file';
|
|
21
21
|
|
|
22
22
|
enum SecureTunnelServiceType {
|
|
23
23
|
SSH = 'SSH',
|
|
@@ -25,18 +25,18 @@ enum SecureTunnelServiceType {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export type SecureTunnelShadowState = {
|
|
28
|
-
reported?:
|
|
29
|
-
desired?:
|
|
28
|
+
reported?: SecureTunnelShadowUpdate;
|
|
29
|
+
desired?: SecureTunnelShadowUpdate;
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
export type SecureTunnelShadowUpdateDelta = {
|
|
33
33
|
version: number;
|
|
34
34
|
timestamp: number;
|
|
35
|
-
state:
|
|
35
|
+
state: SecureTunnelShadowUpdate;
|
|
36
36
|
metadata?: any;
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
export type
|
|
39
|
+
export type SecureTunnelShadow = {
|
|
40
40
|
version: number;
|
|
41
41
|
state: SecureTunnelShadowState;
|
|
42
42
|
};
|
|
@@ -76,7 +76,7 @@ const ST_START_PORT_NUMBER = 5010;
|
|
|
76
76
|
*/
|
|
77
77
|
export class SecureTunnelHandlerSingleton {
|
|
78
78
|
private static instance: SecureTunnelHandlerSingleton;
|
|
79
|
-
private reported:
|
|
79
|
+
private reported: SecureTunnelShadowUpdate;
|
|
80
80
|
private httpProxyMap: SecureTunnelProxyMap[];
|
|
81
81
|
private localProxyInfo: SecureTunnelLocalProxyInfo;
|
|
82
82
|
|
|
@@ -146,9 +146,9 @@ export class SecureTunnelHandlerSingleton {
|
|
|
146
146
|
|
|
147
147
|
/**
|
|
148
148
|
* Returns current state of SecureTunnel shadow
|
|
149
|
-
* @returns {
|
|
149
|
+
* @returns {SecureTunnelShadowUpdate} - reported state of the SecureTunnel shadow
|
|
150
150
|
*/
|
|
151
|
-
public getSecureTunnelShadow():
|
|
151
|
+
public getSecureTunnelShadow(): SecureTunnelShadowUpdate {
|
|
152
152
|
logger.debug('-> SecureTunnelHandlerSingleton.getSecureTunnelShadow');
|
|
153
153
|
logger.debug(`reported: ${JSON.stringify(this.reported)}`);
|
|
154
154
|
logger.debug('<- SecureTunnelHandlerSingleton.getSecureTunnelShadow');
|
|
@@ -158,11 +158,11 @@ export class SecureTunnelHandlerSingleton {
|
|
|
158
158
|
/**
|
|
159
159
|
* Updates current state of SecureTunnel shadow
|
|
160
160
|
* @param {SecureTunnelShadowUpdateDelta} deltaMsg - delta message, which includes desired state of the SecureTunnel shadow
|
|
161
|
-
* @return {
|
|
161
|
+
* @return {SecureTunnelShadowUpdate} update reported message to send back to AWS IoT device shadow
|
|
162
162
|
*/
|
|
163
163
|
public async syncShadowToDeviceState(
|
|
164
164
|
deltaMsg: SecureTunnelShadowUpdateDelta
|
|
165
|
-
): Promise<
|
|
165
|
+
): Promise<SecureTunnelShadowUpdate> {
|
|
166
166
|
logger.debug('-> SecureTunnelHandlerSingleton.syncShadowToDeviceState');
|
|
167
167
|
const { version, state } = deltaMsg;
|
|
168
168
|
if (!state || typeof state.st_ports === 'undefined') {
|
|
@@ -234,8 +234,8 @@ export class SecureTunnelHandlerSingleton {
|
|
|
234
234
|
this.processNotifyMessage(message);
|
|
235
235
|
await this.downloadSecureTunnel();
|
|
236
236
|
await this.startLocalProxy();
|
|
237
|
-
} catch (
|
|
238
|
-
logger.error(
|
|
237
|
+
} catch (e) {
|
|
238
|
+
logger.error(stringifyError(e));
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
logger.info(`Local Proxy Started: ${JSON.stringify(this.localProxyInfo)}`);
|
|
@@ -324,9 +324,11 @@ export class SecureTunnelHandlerSingleton {
|
|
|
324
324
|
this.httpProxyMap[this.httpProxyMap.length - 1]
|
|
325
325
|
)}`
|
|
326
326
|
);
|
|
327
|
-
} catch (
|
|
327
|
+
} catch (e) {
|
|
328
328
|
logger.error(
|
|
329
|
-
`ERROR: starting socat for: ${portInfo.ip}:${
|
|
329
|
+
`ERROR: starting socat for: ${portInfo.ip}:${
|
|
330
|
+
portInfo.port
|
|
331
|
+
} on localhost port: ${localPort}\nerror:\n${stringifyError(e)}`
|
|
330
332
|
);
|
|
331
333
|
const lastHttpProxyMap = this.httpProxyMap.pop();
|
|
332
334
|
logger.info(`removed last proxyMap: ${JSON.stringify(lastHttpProxyMap)}`);
|
|
@@ -371,7 +373,7 @@ export class SecureTunnelHandlerSingleton {
|
|
|
371
373
|
);
|
|
372
374
|
logger.debug(`Remaining map: ${JSON.stringify(this.httpProxyMap)}`);
|
|
373
375
|
} catch (e) {
|
|
374
|
-
logger.error(
|
|
376
|
+
logger.error(`ERROR: killing socat process:\n${stringifyError(e)}`);
|
|
375
377
|
}
|
|
376
378
|
logger.debug(
|
|
377
379
|
`Removing map: ${JSON.stringify(this.httpProxyMap[itemIndex])}`
|
|
@@ -427,7 +429,7 @@ export class SecureTunnelHandlerSingleton {
|
|
|
427
429
|
]);
|
|
428
430
|
logger.debug('SUCCESS: killing local proxy process');
|
|
429
431
|
} catch (e) {
|
|
430
|
-
logger.error(
|
|
432
|
+
logger.error(`ERROR: killing local proxy process:\n${stringifyError(e)}`);
|
|
431
433
|
}
|
|
432
434
|
this.localProxyInfo = {
|
|
433
435
|
lpDstAccessKey: '',
|
|
@@ -545,11 +547,21 @@ export class SecureTunnelHandlerSingleton {
|
|
|
545
547
|
logger.info('Downloading SecureTunnel local proxy ...');
|
|
546
548
|
const url = `${aaiArtifactsBucketUrl}/securetunnel/${linuxDistro}/${osVersion}/${arch}/${SECURE_TUNNEL_BIN_NAME}`;
|
|
547
549
|
await JsSpawner().mkdirp(join(AAI_DIR, SECURE_TUNNEL_BIN_DIR));
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
550
|
+
try {
|
|
551
|
+
await downloadToFile({
|
|
552
|
+
url,
|
|
553
|
+
path: SECURE_TUNNEL_BIN_PATH
|
|
554
|
+
});
|
|
555
|
+
} catch (error) {
|
|
556
|
+
logger.error(
|
|
557
|
+
`Secure Tunnel bin for ${linuxDistro} ${osVersion} ${arch} not found}: ${stringifyError(
|
|
558
|
+
error
|
|
559
|
+
)}`
|
|
560
|
+
);
|
|
561
|
+
throw new Error(
|
|
562
|
+
`Secure Tunnel bin for ${linuxDistro} ${osVersion} ${arch} not found}`
|
|
563
|
+
);
|
|
564
|
+
}
|
|
553
565
|
|
|
554
566
|
await JsSpawner().run({
|
|
555
567
|
exe: 'chmod',
|
|
@@ -578,8 +590,8 @@ export class SecureTunnelHandlerSingleton {
|
|
|
578
590
|
}
|
|
579
591
|
|
|
580
592
|
private sortPorts(
|
|
581
|
-
desired:
|
|
582
|
-
):
|
|
593
|
+
desired: SecureTunnelShadowUpdate
|
|
594
|
+
): SecureTunnelShadowUpdate {
|
|
583
595
|
logger.debug('-> SecureTunnelHandlerSingleton.sortPorts');
|
|
584
596
|
const sortedPorts = JSON.parse(JSON.stringify(this.reported));
|
|
585
597
|
sortedPorts.st_ports.sort((a, b) => {
|
|
@@ -7,10 +7,9 @@ import {
|
|
|
7
7
|
import { readAppCfgFile } from '../../application-control';
|
|
8
8
|
import { DeviceAgentCloudConnection } from '../../cloud-connection/device-agent-cloud-connection';
|
|
9
9
|
import sleep from '../../util/sleep';
|
|
10
|
-
import { logger } from '../../util/logger';
|
|
11
10
|
import { assign, merge } from 'lodash';
|
|
12
11
|
import {
|
|
13
|
-
|
|
12
|
+
buildUpdateShadowMessage,
|
|
14
13
|
getShadowTopic
|
|
15
14
|
} from '@alwaysai/device-agent-schemas';
|
|
16
15
|
|
|
@@ -64,7 +63,6 @@ export const setAnalyticsCfgCliLeaf = CliLeaf({
|
|
|
64
63
|
}
|
|
65
64
|
) {
|
|
66
65
|
const deviceAgent = new DeviceAgentCloudConnection();
|
|
67
|
-
await deviceAgent.setupHandlers();
|
|
68
66
|
|
|
69
67
|
const newAppCfg = {
|
|
70
68
|
analytics: {
|
|
@@ -85,7 +83,7 @@ export const setAnalyticsCfgCliLeaf = CliLeaf({
|
|
|
85
83
|
deviceAgent.publisher.publish(
|
|
86
84
|
getShadowTopic(deviceAgent.getClientId(), 'projects', 'update'),
|
|
87
85
|
JSON.stringify(
|
|
88
|
-
|
|
86
|
+
buildUpdateShadowMessage({
|
|
89
87
|
clientId: 'client',
|
|
90
88
|
desired: toDesire
|
|
91
89
|
})
|