@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
|
@@ -3,27 +3,27 @@ import {
|
|
|
3
3
|
validateAppConfig
|
|
4
4
|
} from '@alwaysai/app-configuration-schemas';
|
|
5
5
|
import {
|
|
6
|
+
buildUpdateShadowMessage,
|
|
6
7
|
EnvVars,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
generateTxId,
|
|
9
|
+
getShadowTopic,
|
|
10
|
+
getUpdateDeltaStateFromMessage,
|
|
11
|
+
ProjectShadowUpdate,
|
|
12
|
+
SecureTunnelShadowUpdate,
|
|
13
|
+
validateEnvVarSchemaShadowUpdate,
|
|
14
|
+
validateProjectShadowUpdate
|
|
15
|
+
} from '@alwaysai/device-agent-schemas';
|
|
16
|
+
import {
|
|
17
|
+
buildBaseShadowMessage,
|
|
18
|
+
DeviceAgentStatusShadowUpdate,
|
|
19
|
+
ShadowProjectsUpdateAll
|
|
20
|
+
} from '@alwaysai/device-agent-schemas/lib/shadow-schema';
|
|
21
|
+
import { stringifyError } from 'alwaysai/lib/util';
|
|
22
|
+
import { getAllEnvs, readAppCfgFile, setEnv } from '../application-control';
|
|
11
23
|
import { getSystemInformation } from '../device-control/device-control';
|
|
12
24
|
import { logger } from '../util/logger';
|
|
13
25
|
import { Publisher } from './publisher';
|
|
14
26
|
import { AppConfigModels, getAppCfgModelsDiff } from './shadow';
|
|
15
|
-
import {
|
|
16
|
-
generateTxId,
|
|
17
|
-
validateProjectShadowUpdate,
|
|
18
|
-
buildBaseShadowMessage,
|
|
19
|
-
buildUpdateProjectShadowMessage,
|
|
20
|
-
buildUpdateSystemInfoShadowMessage,
|
|
21
|
-
getShadowTopic,
|
|
22
|
-
ShadowProjectsUpdateAll,
|
|
23
|
-
getDesiredFromMessage,
|
|
24
|
-
ShadowTopics,
|
|
25
|
-
ProjectShadowUpdate
|
|
26
|
-
} from '@alwaysai/device-agent-schemas';
|
|
27
27
|
|
|
28
28
|
export type AppConfigUpdate = {
|
|
29
29
|
newAppCfg: AppConfig;
|
|
@@ -107,15 +107,15 @@ export class ShadowHandler {
|
|
|
107
107
|
txId: string;
|
|
108
108
|
projectId: string;
|
|
109
109
|
}): Promise<AppConfigUpdate | null> {
|
|
110
|
-
let appCfgUpdate: any;
|
|
111
110
|
let newAppCfg: any;
|
|
112
|
-
|
|
113
111
|
// Handle errors and validation
|
|
114
112
|
try {
|
|
115
113
|
newAppCfg = JSON.parse(appConfig);
|
|
116
|
-
} catch (
|
|
114
|
+
} catch (e) {
|
|
117
115
|
logger.error(
|
|
118
|
-
`Could not parse the appConfig for transaction ${txId}!\n${
|
|
116
|
+
`Could not parse the appConfig for transaction ${txId}!\n${stringifyError(
|
|
117
|
+
e
|
|
118
|
+
)}`
|
|
119
119
|
);
|
|
120
120
|
return null;
|
|
121
121
|
}
|
|
@@ -139,14 +139,47 @@ export class ShadowHandler {
|
|
|
139
139
|
projectId
|
|
140
140
|
});
|
|
141
141
|
|
|
142
|
+
const appCfgUpdate: AppConfigUpdate = { newAppCfg };
|
|
142
143
|
if (updatedModels && Object.keys(updatedModels).length) {
|
|
143
|
-
appCfgUpdate =
|
|
144
|
-
} else {
|
|
145
|
-
appCfgUpdate = { newAppCfg };
|
|
144
|
+
appCfgUpdate.updatedModels = updatedModels;
|
|
146
145
|
}
|
|
147
146
|
return appCfgUpdate;
|
|
148
147
|
}
|
|
149
148
|
|
|
149
|
+
private async generateEnvVarsUpdate({
|
|
150
|
+
envVars,
|
|
151
|
+
txId,
|
|
152
|
+
projectId
|
|
153
|
+
}: {
|
|
154
|
+
envVars: string;
|
|
155
|
+
txId: string;
|
|
156
|
+
projectId: string;
|
|
157
|
+
}): Promise<EnvVarUpdate | null> {
|
|
158
|
+
let newEnvVars: any;
|
|
159
|
+
try {
|
|
160
|
+
newEnvVars = JSON.parse(envVars);
|
|
161
|
+
} catch (e) {
|
|
162
|
+
logger.error(
|
|
163
|
+
`Could not parse the environment variables for transaction ${txId}!\n${stringifyError(
|
|
164
|
+
e
|
|
165
|
+
)}`
|
|
166
|
+
);
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (!validateEnvVarSchemaShadowUpdate(newEnvVars)) {
|
|
171
|
+
logger.error(
|
|
172
|
+
`Received invalid environment variables update for ${projectId}!\n${JSON.stringify(
|
|
173
|
+
validateEnvVarSchemaShadowUpdate.errors,
|
|
174
|
+
null,
|
|
175
|
+
2
|
|
176
|
+
)}`
|
|
177
|
+
);
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
return { envVars: newEnvVars };
|
|
181
|
+
}
|
|
182
|
+
|
|
150
183
|
private async processProjectShadowUpdates({
|
|
151
184
|
delta
|
|
152
185
|
}: {
|
|
@@ -220,7 +253,14 @@ export class ShadowHandler {
|
|
|
220
253
|
`Found a delta for app environment variable shadow. Updating ${projectId}`
|
|
221
254
|
);
|
|
222
255
|
const envVars = projectDelta.envVars;
|
|
223
|
-
|
|
256
|
+
const envVarsUpdate = await this.generateEnvVarsUpdate({
|
|
257
|
+
envVars,
|
|
258
|
+
txId,
|
|
259
|
+
projectId
|
|
260
|
+
});
|
|
261
|
+
if (envVarsUpdate) {
|
|
262
|
+
shadowUpdate.envVarUpdate = envVarsUpdate;
|
|
263
|
+
}
|
|
224
264
|
}
|
|
225
265
|
|
|
226
266
|
return shadowUpdate.appCfgUpdate || shadowUpdate.envVarUpdate
|
|
@@ -244,24 +284,14 @@ export class ShadowHandler {
|
|
|
244
284
|
throw Error(`Topic ${topic} is not in the ${this.projectShadowTopics}`);
|
|
245
285
|
}
|
|
246
286
|
switch (topic) {
|
|
247
|
-
case this.shadowTopics.project.
|
|
248
|
-
|
|
287
|
+
case this.shadowTopics.project.updateDelta: {
|
|
288
|
+
const delta = getUpdateDeltaStateFromMessage(payload);
|
|
289
|
+
if (!delta) {
|
|
249
290
|
logger.debug(
|
|
250
|
-
`
|
|
251
|
-
{ topic, payload },
|
|
252
|
-
null,
|
|
253
|
-
2
|
|
254
|
-
)}`
|
|
255
|
-
);
|
|
256
|
-
break;
|
|
257
|
-
}
|
|
258
|
-
const desired = getDesiredFromMessage(payload);
|
|
259
|
-
if (!desired) {
|
|
260
|
-
logger.debug(
|
|
261
|
-
`No desired state found in message: ${JSON.stringify(payload)}`
|
|
291
|
+
`No delta state found in message: ${JSON.stringify(payload)}`
|
|
262
292
|
);
|
|
263
293
|
} else {
|
|
264
|
-
return await this.processProjectShadowUpdates({ delta
|
|
294
|
+
return await this.processProjectShadowUpdates({ delta });
|
|
265
295
|
}
|
|
266
296
|
break;
|
|
267
297
|
}
|
|
@@ -276,21 +306,18 @@ export class ShadowHandler {
|
|
|
276
306
|
);
|
|
277
307
|
break;
|
|
278
308
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
} else {
|
|
284
|
-
logger.info(
|
|
285
|
-
`No delta in projects.getAccepted in named shadow '${
|
|
286
|
-
topic.split('/')[5]
|
|
287
|
-
}'`
|
|
309
|
+
const delta = getUpdateDeltaStateFromMessage(payload);
|
|
310
|
+
if (!delta) {
|
|
311
|
+
logger.debug(
|
|
312
|
+
`No delta state found in message: ${JSON.stringify(payload)}`
|
|
288
313
|
);
|
|
314
|
+
} else {
|
|
315
|
+
return await this.processProjectShadowUpdates({ delta });
|
|
289
316
|
}
|
|
290
317
|
break;
|
|
291
318
|
}
|
|
292
319
|
case this.shadowTopics.project.getRejected:
|
|
293
|
-
case this.shadowTopics.project.
|
|
320
|
+
case this.shadowTopics.project.updateAccepted:
|
|
294
321
|
case this.shadowTopics.project.updateRejected: {
|
|
295
322
|
// Not handling these for now
|
|
296
323
|
break;
|
|
@@ -312,7 +339,10 @@ export class ShadowHandler {
|
|
|
312
339
|
this.publisher.publish(
|
|
313
340
|
getShadowTopic(this.clientId, 'system-info', 'update'),
|
|
314
341
|
JSON.stringify(
|
|
315
|
-
|
|
342
|
+
buildUpdateShadowMessage({
|
|
343
|
+
clientId: this.clientId,
|
|
344
|
+
reported: systemInfo
|
|
345
|
+
})
|
|
316
346
|
)
|
|
317
347
|
);
|
|
318
348
|
}
|
|
@@ -324,13 +354,13 @@ export class ShadowHandler {
|
|
|
324
354
|
const toReport: ShadowProjectsUpdateAll = {
|
|
325
355
|
[projectId]: {
|
|
326
356
|
appConfig: JSON.stringify(appCfg),
|
|
327
|
-
envVars
|
|
357
|
+
envVars: JSON.stringify(envVars)
|
|
328
358
|
}
|
|
329
359
|
};
|
|
330
360
|
this.publisher.publish(
|
|
331
361
|
getShadowTopic(this.clientId, 'projects', 'update'),
|
|
332
362
|
JSON.stringify(
|
|
333
|
-
|
|
363
|
+
buildUpdateShadowMessage({
|
|
334
364
|
clientId: this.clientId,
|
|
335
365
|
reported: toReport
|
|
336
366
|
})
|
|
@@ -346,15 +376,15 @@ export class ShadowHandler {
|
|
|
346
376
|
envVars: EnvVars;
|
|
347
377
|
}) {
|
|
348
378
|
await setEnv({ projectId, envVars });
|
|
349
|
-
|
|
379
|
+
const currentEnvs = await getAllEnvs({ projectId });
|
|
350
380
|
this.publisher.publish(
|
|
351
381
|
getShadowTopic(this.clientId, 'projects', 'update'),
|
|
352
382
|
JSON.stringify(
|
|
353
|
-
|
|
383
|
+
buildUpdateShadowMessage({
|
|
354
384
|
clientId: this.clientId,
|
|
355
385
|
reported: {
|
|
356
386
|
[projectId]: {
|
|
357
|
-
envVars
|
|
387
|
+
envVars: JSON.stringify(currentEnvs)
|
|
358
388
|
}
|
|
359
389
|
}
|
|
360
390
|
})
|
|
@@ -362,6 +392,34 @@ export class ShadowHandler {
|
|
|
362
392
|
);
|
|
363
393
|
}
|
|
364
394
|
|
|
395
|
+
public async updateSecureTunnelShadow(
|
|
396
|
+
secureTunnelShadowUpdate: SecureTunnelShadowUpdate
|
|
397
|
+
) {
|
|
398
|
+
this.publisher.publish(
|
|
399
|
+
getShadowTopic(this.clientId, 'secure-tunnel', 'update'),
|
|
400
|
+
JSON.stringify(
|
|
401
|
+
buildUpdateShadowMessage({
|
|
402
|
+
reported: secureTunnelShadowUpdate,
|
|
403
|
+
clientId: this.clientId
|
|
404
|
+
})
|
|
405
|
+
)
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
public async updateDeviceAgentStatusShadow(
|
|
410
|
+
deviceAgentStatusShadowUpdate: DeviceAgentStatusShadowUpdate
|
|
411
|
+
) {
|
|
412
|
+
this.publisher.publish(
|
|
413
|
+
getShadowTopic(this.clientId, 'device-agent-status', 'update'),
|
|
414
|
+
JSON.stringify(
|
|
415
|
+
buildUpdateShadowMessage({
|
|
416
|
+
reported: deviceAgentStatusShadowUpdate,
|
|
417
|
+
clientId: this.clientId
|
|
418
|
+
})
|
|
419
|
+
)
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
|
|
365
423
|
public getProjectShadowUpdates() {
|
|
366
424
|
this.publisher.publish(
|
|
367
425
|
getShadowTopic(this.clientId, 'projects', 'get'),
|
|
@@ -373,7 +431,7 @@ export class ShadowHandler {
|
|
|
373
431
|
this.publisher.publish(
|
|
374
432
|
getShadowTopic(this.clientId, 'projects', 'update'),
|
|
375
433
|
JSON.stringify(
|
|
376
|
-
|
|
434
|
+
buildUpdateShadowMessage({
|
|
377
435
|
clientId: this.clientId,
|
|
378
436
|
reported: { [projectId]: null },
|
|
379
437
|
desired: { [projectId]: null }
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { logger } from '../util/logger';
|
|
2
2
|
import { readAppCfgFile } from '../application-control';
|
|
3
3
|
import { AppConfig } from '@alwaysai/app-configuration-schemas';
|
|
4
|
+
import { stringifyError } from 'alwaysai/lib/util';
|
|
4
5
|
|
|
5
6
|
export type AppConfigModels = {
|
|
6
7
|
[modelId: string]: number;
|
|
@@ -43,7 +44,9 @@ export const getAppCfgModelsDiff = async ({
|
|
|
43
44
|
newScripts[scriptName] = shadowScripts[scriptName];
|
|
44
45
|
});
|
|
45
46
|
} catch (e) {
|
|
46
|
-
logger.error(
|
|
47
|
+
logger.error(
|
|
48
|
+
`Error parsing app config update for ${projectId}!\n${stringifyError(e)}`
|
|
49
|
+
);
|
|
47
50
|
}
|
|
48
51
|
|
|
49
52
|
return { scripts: newScripts, updatedModels, untouchedModels };
|
|
@@ -7,6 +7,7 @@ import { TransactionManager } from './transaction-manager';
|
|
|
7
7
|
import { v4 as uuidv4 } from 'uuid';
|
|
8
8
|
import { Publisher } from './publisher';
|
|
9
9
|
import { LiveUpdatesHandler } from './live-updates-handler';
|
|
10
|
+
import { AppConfigUpdate, ShadowUpdate } from './shadow-handler';
|
|
10
11
|
|
|
11
12
|
const mockClient = {
|
|
12
13
|
publish: jest.fn()
|
|
@@ -14,8 +15,8 @@ const mockClient = {
|
|
|
14
15
|
const clientId = 'test-client';
|
|
15
16
|
|
|
16
17
|
const mockLiveUpdatesHandler = {
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
enable: jest.fn(),
|
|
19
|
+
disable: jest.fn()
|
|
19
20
|
} as any as LiveUpdatesHandler;
|
|
20
21
|
|
|
21
22
|
describe('Test Transaction Manager', () => {
|
|
@@ -187,7 +188,7 @@ describe('Test Transaction Manager', () => {
|
|
|
187
188
|
throw new Error('Expected start transaction to fail!');
|
|
188
189
|
} catch (e) {
|
|
189
190
|
console.log(e);
|
|
190
|
-
expect(e.code).toBe(txnMgr.Errors.
|
|
191
|
+
expect(e.code).toBe(txnMgr.Errors.PROJECT_TRANSACTION_ONGOING);
|
|
191
192
|
}
|
|
192
193
|
expect(txnMgr.getTransactionFromProject(projectId)).toEqual(txId);
|
|
193
194
|
expect(txnMgr.getProjectFromTransaction(txId)).toEqual(projectId);
|
|
@@ -245,4 +246,127 @@ describe('Test Transaction Manager', () => {
|
|
|
245
246
|
|
|
246
247
|
expect(txnMgr.getProjectFromTransaction(txId)).toBeUndefined();
|
|
247
248
|
});
|
|
249
|
+
|
|
250
|
+
test('add an appCfgUpdate from txDetails', async () => {
|
|
251
|
+
const txId = generateTxId();
|
|
252
|
+
const projectId = generateRandomProjectId();
|
|
253
|
+
const cfgUpdate: ShadowUpdate = { txId: txId, projectId: projectId };
|
|
254
|
+
|
|
255
|
+
await txnMgr.runTransactionStep({
|
|
256
|
+
func: func_incomplete,
|
|
257
|
+
projectId,
|
|
258
|
+
txId,
|
|
259
|
+
start: true
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
expect(txnMgr.getAppCfgUpdateFromTxID(txId)).toEqual(undefined);
|
|
263
|
+
|
|
264
|
+
txnMgr.setAppCfgUpdateToTx(txId, cfgUpdate);
|
|
265
|
+
|
|
266
|
+
expect(txnMgr.getProjectFromTransaction(txId)).toEqual(projectId);
|
|
267
|
+
expect(txnMgr.getTransactionFromProject(projectId)).toEqual(txId);
|
|
268
|
+
expect(txnMgr.isOngoingTransaction(txId)).toBe(true);
|
|
269
|
+
expect(txnMgr.isOngoingTransactionForProjectID(projectId)).toBe(true);
|
|
270
|
+
expect(txnMgr.isAnyOngoingTransaction()).toBe(true);
|
|
271
|
+
expect(txnMgr.getAppCfgUpdateFromTxID(txId)).toEqual(cfgUpdate);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
test('update a tx while holding appCfgUpdate', async () => {
|
|
275
|
+
const txId = generateTxId();
|
|
276
|
+
const projectId = generateRandomProjectId();
|
|
277
|
+
const cfgUpdate: ShadowUpdate = { txId: txId, projectId: projectId };
|
|
278
|
+
|
|
279
|
+
await txnMgr.runTransactionStep({
|
|
280
|
+
func: func_incomplete,
|
|
281
|
+
projectId,
|
|
282
|
+
txId,
|
|
283
|
+
start: true
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
txnMgr.setAppCfgUpdateToTx(txId, cfgUpdate);
|
|
287
|
+
|
|
288
|
+
await txnMgr.runTransactionStep({
|
|
289
|
+
func: func_incomplete,
|
|
290
|
+
projectId,
|
|
291
|
+
txId,
|
|
292
|
+
start: false,
|
|
293
|
+
stepName: 'step2'
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
expect(txnMgr.getProjectFromTransaction(txId)).toEqual(projectId);
|
|
297
|
+
expect(txnMgr.getTransactionFromProject(projectId)).toEqual(txId);
|
|
298
|
+
expect(txnMgr.isOngoingTransaction(txId)).toBe(true);
|
|
299
|
+
expect(txnMgr.isOngoingTransactionForProjectID(projectId)).toBe(true);
|
|
300
|
+
expect(txnMgr.isAnyOngoingTransaction()).toBe(true);
|
|
301
|
+
expect(txnMgr.getAppCfgUpdateFromTxID(txId)).toEqual(cfgUpdate);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
test('update an appCfgUpdate to the same tx ', async () => {
|
|
305
|
+
const txId = generateTxId();
|
|
306
|
+
const projectId = generateRandomProjectId();
|
|
307
|
+
const cfgUpdate: ShadowUpdate = { txId: txId, projectId: projectId };
|
|
308
|
+
|
|
309
|
+
const ogAppCfg1: AppConfigUpdate = {
|
|
310
|
+
newAppCfg: {
|
|
311
|
+
scripts: {
|
|
312
|
+
start: 'python app.py'
|
|
313
|
+
},
|
|
314
|
+
models: {}
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
const cfgUpdate2: ShadowUpdate = {
|
|
319
|
+
txId: txId,
|
|
320
|
+
projectId: projectId,
|
|
321
|
+
appCfgUpdate: ogAppCfg1
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
await txnMgr.runTransactionStep({
|
|
325
|
+
func: func_incomplete,
|
|
326
|
+
projectId,
|
|
327
|
+
txId,
|
|
328
|
+
start: true
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
txnMgr.setAppCfgUpdateToTx(txId, cfgUpdate);
|
|
332
|
+
|
|
333
|
+
await txnMgr.runTransactionStep({
|
|
334
|
+
func: func_incomplete,
|
|
335
|
+
projectId,
|
|
336
|
+
txId,
|
|
337
|
+
start: false,
|
|
338
|
+
stepName: 'step2'
|
|
339
|
+
});
|
|
340
|
+
txnMgr.setAppCfgUpdateToTx(txId, cfgUpdate2);
|
|
341
|
+
|
|
342
|
+
expect(txnMgr.getProjectFromTransaction(txId)).toEqual(projectId);
|
|
343
|
+
expect(txnMgr.getTransactionFromProject(projectId)).toEqual(txId);
|
|
344
|
+
expect(txnMgr.isOngoingTransaction(txId)).toBe(true);
|
|
345
|
+
expect(txnMgr.isOngoingTransactionForProjectID(projectId)).toBe(true);
|
|
346
|
+
expect(txnMgr.isAnyOngoingTransaction()).toBe(true);
|
|
347
|
+
expect(txnMgr.getAppCfgUpdateFromTxID(txId)).toEqual(cfgUpdate2);
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
test('remove a tx, ensure appCfgUpdate is removed', async () => {
|
|
351
|
+
const txId = generateTxId();
|
|
352
|
+
const projectId = generateRandomProjectId();
|
|
353
|
+
const cfgUpdate: ShadowUpdate = { txId: txId, projectId: projectId };
|
|
354
|
+
|
|
355
|
+
await txnMgr.runTransactionStep({
|
|
356
|
+
func: func_incomplete,
|
|
357
|
+
projectId,
|
|
358
|
+
txId,
|
|
359
|
+
start: true
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
txnMgr.setAppCfgUpdateToTx(txId, cfgUpdate);
|
|
363
|
+
txnMgr.completeTransaction(txId);
|
|
364
|
+
|
|
365
|
+
expect(txnMgr.getProjectFromTransaction(txId)).toEqual(undefined);
|
|
366
|
+
expect(txnMgr.getTransactionFromProject(projectId)).toEqual(undefined);
|
|
367
|
+
expect(txnMgr.isOngoingTransaction(txId)).toBe(false);
|
|
368
|
+
expect(txnMgr.isOngoingTransactionForProjectID(projectId)).toBe(false);
|
|
369
|
+
expect(txnMgr.isAnyOngoingTransaction()).toBe(false);
|
|
370
|
+
expect(txnMgr.getAppCfgUpdateFromTxID(txId)).toEqual(undefined);
|
|
371
|
+
});
|
|
248
372
|
});
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
ToClientStatusResponseMessage,
|
|
3
3
|
buildToClientStatusResponseMessage,
|
|
4
4
|
keyMirrors
|
|
5
5
|
} from '@alwaysai/device-agent-schemas';
|
|
6
6
|
import { LiveUpdatesHandler } from './live-updates-handler';
|
|
7
7
|
import { Publisher } from './publisher';
|
|
8
8
|
import { logger } from '../util/logger';
|
|
9
|
-
import { keyMirror } from 'alwaysai/lib/util';
|
|
9
|
+
import { keyMirror, stringifyError } from 'alwaysai/lib/util';
|
|
10
10
|
import { CodedError } from '@carnesen/coded-error';
|
|
11
|
+
import { ShadowUpdate } from './shadow-handler';
|
|
11
12
|
|
|
12
13
|
interface TransactionDetails {
|
|
13
14
|
txId: string;
|
|
@@ -16,6 +17,7 @@ interface TransactionDetails {
|
|
|
16
17
|
start: string;
|
|
17
18
|
update?: string;
|
|
18
19
|
stop?: string;
|
|
20
|
+
appCfgUpdate?: ShadowUpdate;
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
export class TransactionManager {
|
|
@@ -24,11 +26,12 @@ export class TransactionManager {
|
|
|
24
26
|
private liveUpdatesHandler: LiveUpdatesHandler;
|
|
25
27
|
private publisher: Publisher;
|
|
26
28
|
|
|
27
|
-
private startTransaction(
|
|
29
|
+
private async startTransaction(
|
|
28
30
|
txId: string,
|
|
29
31
|
projectId: string,
|
|
32
|
+
liveUpdatesPublishFn?: () => Promise<void>,
|
|
30
33
|
stepName?: string
|
|
31
|
-
): void {
|
|
34
|
+
): Promise<void> {
|
|
32
35
|
// Check if the transaction already exists
|
|
33
36
|
if (this.detailsByTx[txId]) {
|
|
34
37
|
const txnDetails = this.detailsByTx[txId];
|
|
@@ -51,7 +54,7 @@ export class TransactionManager {
|
|
|
51
54
|
null,
|
|
52
55
|
2
|
|
53
56
|
)}`,
|
|
54
|
-
this.Errors.
|
|
57
|
+
this.Errors.PROJECT_TRANSACTION_ONGOING
|
|
55
58
|
);
|
|
56
59
|
}
|
|
57
60
|
|
|
@@ -65,10 +68,14 @@ export class TransactionManager {
|
|
|
65
68
|
this.detailsByTx[txId] = txDetails;
|
|
66
69
|
this.detailsByProject[projectId] = txDetails;
|
|
67
70
|
logger.info(`Started transaction:\n${JSON.stringify(txDetails, null, 2)}`);
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
71
|
+
|
|
72
|
+
if (liveUpdatesPublishFn) {
|
|
73
|
+
await this.liveUpdatesHandler.enable(
|
|
74
|
+
keyMirrors.toClientMessageType.status_response,
|
|
75
|
+
liveUpdatesPublishFn,
|
|
76
|
+
txId
|
|
77
|
+
);
|
|
78
|
+
}
|
|
72
79
|
}
|
|
73
80
|
|
|
74
81
|
private updateTransaction(txId: string, stepName?: string): void {
|
|
@@ -93,7 +100,7 @@ export class TransactionManager {
|
|
|
93
100
|
|
|
94
101
|
public Errors = keyMirror({
|
|
95
102
|
TRANSACTION_ONGOING: null,
|
|
96
|
-
|
|
103
|
+
PROJECT_TRANSACTION_ONGOING: null,
|
|
97
104
|
TRANSACTION_NOT_ONGOING: null
|
|
98
105
|
});
|
|
99
106
|
|
|
@@ -102,48 +109,49 @@ export class TransactionManager {
|
|
|
102
109
|
projectId: string;
|
|
103
110
|
txId: string;
|
|
104
111
|
start: boolean;
|
|
112
|
+
liveUpdatesPublishFn?: () => Promise<void>;
|
|
105
113
|
stepName?: string;
|
|
106
114
|
}) {
|
|
107
|
-
const { func, projectId, txId, start, stepName } =
|
|
115
|
+
const { func, projectId, txId, start, liveUpdatesPublishFn, stepName } =
|
|
116
|
+
props;
|
|
108
117
|
if (start) {
|
|
109
|
-
this.startTransaction(
|
|
118
|
+
await this.startTransaction(
|
|
119
|
+
txId,
|
|
120
|
+
projectId,
|
|
121
|
+
liveUpdatesPublishFn,
|
|
122
|
+
stepName
|
|
123
|
+
);
|
|
110
124
|
} else {
|
|
111
125
|
this.updateTransaction(txId, stepName);
|
|
112
126
|
}
|
|
113
127
|
try {
|
|
114
128
|
const completed = await func();
|
|
115
129
|
if (completed) {
|
|
116
|
-
this.completeTransaction(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
successStatusResponsePayload,
|
|
124
|
-
txId
|
|
130
|
+
this.completeTransaction(
|
|
131
|
+
txId,
|
|
132
|
+
buildToClientStatusResponseMessage(
|
|
133
|
+
this.publisher.getClientId(),
|
|
134
|
+
{ status: keyMirrors.statusResponse.success },
|
|
135
|
+
txId
|
|
136
|
+
)
|
|
125
137
|
);
|
|
126
|
-
this.publisher.publishToClient(message);
|
|
127
138
|
}
|
|
128
139
|
} catch (e) {
|
|
129
|
-
const message: string = e.message;
|
|
130
140
|
logger.error(
|
|
131
|
-
`Failed to execute cmd for ${projectId}
|
|
141
|
+
`Failed to execute cmd for ${projectId}!\n${stringifyError(e)}`
|
|
132
142
|
);
|
|
133
143
|
|
|
134
|
-
this.completeTransaction(
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
txId
|
|
144
|
+
this.completeTransaction(
|
|
145
|
+
txId,
|
|
146
|
+
buildToClientStatusResponseMessage(
|
|
147
|
+
this.publisher.getClientId(),
|
|
148
|
+
{
|
|
149
|
+
status: keyMirrors.statusResponse.failure,
|
|
150
|
+
message: e.message
|
|
151
|
+
},
|
|
152
|
+
txId
|
|
153
|
+
)
|
|
145
154
|
);
|
|
146
|
-
this.publisher.publishToClient(failureStatusResponseMessage);
|
|
147
155
|
}
|
|
148
156
|
}
|
|
149
157
|
|
|
@@ -169,7 +177,23 @@ export class TransactionManager {
|
|
|
169
177
|
return txnDetails?.projectId;
|
|
170
178
|
}
|
|
171
179
|
|
|
172
|
-
public
|
|
180
|
+
public getAppCfgUpdateFromTxID(txId: string): ShadowUpdate | undefined {
|
|
181
|
+
return this.detailsByTx[txId]?.appCfgUpdate;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
public setAppCfgUpdateToTx(txId: string, appCfgUpdate: ShadowUpdate) {
|
|
185
|
+
if (this.isOngoingTransaction(txId)) {
|
|
186
|
+
this.detailsByTx[txId].appCfgUpdate = appCfgUpdate;
|
|
187
|
+
} else
|
|
188
|
+
throw new Error(
|
|
189
|
+
`Could not set appCfgUpdate, the transaction ${txId} does not exist.`
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
public completeTransaction(
|
|
194
|
+
txId: string,
|
|
195
|
+
messageToPublish?: ToClientStatusResponseMessage
|
|
196
|
+
): void {
|
|
173
197
|
const txDetails = this.detailsByTx[txId];
|
|
174
198
|
if (txDetails === undefined) {
|
|
175
199
|
throw new CodedError(
|
|
@@ -184,8 +208,13 @@ export class TransactionManager {
|
|
|
184
208
|
delete this.detailsByTx[txId];
|
|
185
209
|
delete this.detailsByProject[txDetails.projectId];
|
|
186
210
|
|
|
187
|
-
|
|
211
|
+
this.liveUpdatesHandler.disable(
|
|
212
|
+
keyMirrors.toClientMessageType.status_response,
|
|
188
213
|
txId
|
|
189
|
-
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
if (messageToPublish) {
|
|
217
|
+
this.publisher.publishToClient(messageToPublish);
|
|
218
|
+
}
|
|
190
219
|
}
|
|
191
220
|
}
|