@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.
Files changed (305) hide show
  1. package/lib/application-control/config.d.ts.map +1 -1
  2. package/lib/application-control/config.js +8 -3
  3. package/lib/application-control/config.js.map +1 -1
  4. package/lib/application-control/environment-variables.d.ts +5 -5
  5. package/lib/application-control/environment-variables.d.ts.map +1 -1
  6. package/lib/application-control/environment-variables.js +25 -38
  7. package/lib/application-control/environment-variables.js.map +1 -1
  8. package/lib/application-control/environment-variables.test.js +27 -7
  9. package/lib/application-control/environment-variables.test.js.map +1 -1
  10. package/lib/application-control/index.d.ts +4 -4
  11. package/lib/application-control/index.d.ts.map +1 -1
  12. package/lib/application-control/index.js +1 -4
  13. package/lib/application-control/index.js.map +1 -1
  14. package/lib/application-control/install.d.ts +4 -1
  15. package/lib/application-control/install.d.ts.map +1 -1
  16. package/lib/application-control/install.js +24 -8
  17. package/lib/application-control/install.js.map +1 -1
  18. package/lib/application-control/models.d.ts +0 -11
  19. package/lib/application-control/models.d.ts.map +1 -1
  20. package/lib/application-control/models.js +5 -54
  21. package/lib/application-control/models.js.map +1 -1
  22. package/lib/application-control/utils.d.ts +0 -4
  23. package/lib/application-control/utils.d.ts.map +1 -1
  24. package/lib/application-control/utils.js +12 -22
  25. package/lib/application-control/utils.js.map +1 -1
  26. package/lib/cloud-connection/base-message-handler.d.ts +27 -0
  27. package/lib/cloud-connection/base-message-handler.d.ts.map +1 -0
  28. package/lib/cloud-connection/base-message-handler.js +72 -0
  29. package/lib/cloud-connection/base-message-handler.js.map +1 -0
  30. package/lib/cloud-connection/bootstrap-provision.js +3 -2
  31. package/lib/cloud-connection/bootstrap-provision.js.map +1 -1
  32. package/lib/cloud-connection/connection-manager.d.ts +21 -0
  33. package/lib/cloud-connection/connection-manager.d.ts.map +1 -0
  34. package/lib/cloud-connection/connection-manager.js +158 -0
  35. package/lib/cloud-connection/connection-manager.js.map +1 -0
  36. package/lib/cloud-connection/device-agent-cloud-connection.d.ts +9 -30
  37. package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
  38. package/lib/cloud-connection/device-agent-cloud-connection.js +69 -508
  39. package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
  40. package/lib/cloud-connection/device-agent-message-handler.d.ts +22 -0
  41. package/lib/cloud-connection/device-agent-message-handler.d.ts.map +1 -0
  42. package/lib/cloud-connection/device-agent-message-handler.js +357 -0
  43. package/lib/cloud-connection/device-agent-message-handler.js.map +1 -0
  44. package/lib/cloud-connection/device-agent.d.ts.map +1 -1
  45. package/lib/cloud-connection/device-agent.js +11 -9
  46. package/lib/cloud-connection/device-agent.js.map +1 -1
  47. package/lib/cloud-connection/live-updates-handler.d.ts +19 -28
  48. package/lib/cloud-connection/live-updates-handler.d.ts.map +1 -1
  49. package/lib/cloud-connection/live-updates-handler.js +60 -172
  50. package/lib/cloud-connection/live-updates-handler.js.map +1 -1
  51. package/lib/cloud-connection/live-updates-handler.test.js +71 -165
  52. package/lib/cloud-connection/live-updates-handler.test.js.map +1 -1
  53. package/lib/cloud-connection/message-dispatcher.d.ts +10 -0
  54. package/lib/cloud-connection/message-dispatcher.d.ts.map +1 -0
  55. package/lib/cloud-connection/message-dispatcher.js +27 -0
  56. package/lib/cloud-connection/message-dispatcher.js.map +1 -0
  57. package/lib/cloud-connection/passthrough-handler.d.ts +4 -1
  58. package/lib/cloud-connection/passthrough-handler.d.ts.map +1 -1
  59. package/lib/cloud-connection/passthrough-handler.js +30 -11
  60. package/lib/cloud-connection/passthrough-handler.js.map +1 -1
  61. package/lib/cloud-connection/shadow-handler.d.ts +11 -3
  62. package/lib/cloud-connection/shadow-handler.d.ts.map +1 -1
  63. package/lib/cloud-connection/shadow-handler.js +133 -28
  64. package/lib/cloud-connection/shadow-handler.js.map +1 -1
  65. package/lib/cloud-connection/shadow-handler.test.js +45 -57
  66. package/lib/cloud-connection/shadow-handler.test.js.map +1 -1
  67. package/lib/cloud-connection/shadow.d.ts.map +1 -1
  68. package/lib/cloud-connection/shadow.js +2 -1
  69. package/lib/cloud-connection/shadow.js.map +1 -1
  70. package/lib/cloud-connection/transaction-manager.d.ts +12 -3
  71. package/lib/cloud-connection/transaction-manager.d.ts.map +1 -1
  72. package/lib/cloud-connection/transaction-manager.js +29 -28
  73. package/lib/cloud-connection/transaction-manager.js.map +1 -1
  74. package/lib/cloud-connection/transaction-manager.test.js +46 -5
  75. package/lib/cloud-connection/transaction-manager.test.js.map +1 -1
  76. package/lib/device-control/device-control.d.ts +8 -8
  77. package/lib/device-control/device-control.d.ts.map +1 -1
  78. package/lib/device-control/device-control.js +95 -71
  79. package/lib/device-control/device-control.js.map +1 -1
  80. package/lib/docker/docker-compose.d.ts.map +1 -1
  81. package/lib/docker/docker-compose.js +2 -1
  82. package/lib/docker/docker-compose.js.map +1 -1
  83. package/lib/infrastructure/agent-config.d.ts +2 -1
  84. package/lib/infrastructure/agent-config.d.ts.map +1 -1
  85. package/lib/infrastructure/agent-config.js +7 -7
  86. package/lib/infrastructure/agent-config.js.map +1 -1
  87. package/lib/infrastructure/agent-config.test.js +3 -1
  88. package/lib/infrastructure/agent-config.test.js.map +1 -1
  89. package/lib/infrastructure/config-check-utility.d.ts +6 -0
  90. package/lib/infrastructure/config-check-utility.d.ts.map +1 -0
  91. package/lib/infrastructure/config-check-utility.js +67 -0
  92. package/lib/infrastructure/config-check-utility.js.map +1 -0
  93. package/lib/infrastructure/config-check-utility.test.d.ts +2 -0
  94. package/lib/infrastructure/config-check-utility.test.d.ts.map +1 -0
  95. package/lib/infrastructure/config-check-utility.test.js +109 -0
  96. package/lib/infrastructure/config-check-utility.test.js.map +1 -0
  97. package/lib/infrastructure/device-certificate.d.ts +10 -0
  98. package/lib/infrastructure/device-certificate.d.ts.map +1 -0
  99. package/lib/infrastructure/device-certificate.js +47 -0
  100. package/lib/infrastructure/device-certificate.js.map +1 -0
  101. package/lib/infrastructure/device-certificate.test.d.ts +2 -0
  102. package/lib/infrastructure/device-certificate.test.d.ts.map +1 -0
  103. package/lib/infrastructure/device-certificate.test.js +24 -0
  104. package/lib/infrastructure/device-certificate.test.js.map +1 -0
  105. package/lib/infrastructure/legacy-migration/legacy-file.test.d.ts +2 -0
  106. package/lib/infrastructure/legacy-migration/legacy-file.test.d.ts.map +1 -0
  107. package/lib/infrastructure/legacy-migration/legacy-file.test.js +61 -0
  108. package/lib/infrastructure/legacy-migration/legacy-file.test.js.map +1 -0
  109. package/lib/infrastructure/legacy-migration/legacy-files.d.ts +75 -0
  110. package/lib/infrastructure/legacy-migration/legacy-files.d.ts.map +1 -0
  111. package/lib/infrastructure/legacy-migration/legacy-files.js +75 -0
  112. package/lib/infrastructure/legacy-migration/legacy-files.js.map +1 -0
  113. package/lib/infrastructure/legacy-migration/legacy-migration.d.ts +6 -0
  114. package/lib/infrastructure/legacy-migration/legacy-migration.d.ts.map +1 -0
  115. package/lib/infrastructure/legacy-migration/legacy-migration.js +149 -0
  116. package/lib/infrastructure/legacy-migration/legacy-migration.js.map +1 -0
  117. package/lib/infrastructure/legacy-migration/legacy-migration.test.d.ts +2 -0
  118. package/lib/infrastructure/legacy-migration/legacy-migration.test.d.ts.map +1 -0
  119. package/lib/infrastructure/legacy-migration/legacy-migration.test.js +226 -0
  120. package/lib/infrastructure/legacy-migration/legacy-migration.test.js.map +1 -0
  121. package/lib/infrastructure/require-files-present-ready.test.d.ts +2 -0
  122. package/lib/infrastructure/require-files-present-ready.test.d.ts.map +1 -0
  123. package/lib/infrastructure/require-files-present-ready.test.js +44 -0
  124. package/lib/infrastructure/require-files-present-ready.test.js.map +1 -0
  125. package/lib/infrastructure/required-config-checks.d.ts +2 -0
  126. package/lib/infrastructure/required-config-checks.d.ts.map +1 -0
  127. package/lib/infrastructure/required-config-checks.js +30 -0
  128. package/lib/infrastructure/required-config-checks.js.map +1 -0
  129. package/lib/infrastructure/tokens-and-device-cfg.d.ts.map +1 -1
  130. package/lib/infrastructure/tokens-and-device-cfg.js +11 -8
  131. package/lib/infrastructure/tokens-and-device-cfg.js.map +1 -1
  132. package/lib/jobs/job-handler.d.ts +23 -0
  133. package/lib/jobs/job-handler.d.ts.map +1 -0
  134. package/lib/jobs/job-handler.js +131 -0
  135. package/lib/jobs/job-handler.js.map +1 -0
  136. package/lib/local-connection/rabbitmq-connection.d.ts.map +1 -1
  137. package/lib/local-connection/rabbitmq-connection.js +14 -14
  138. package/lib/local-connection/rabbitmq-connection.js.map +1 -1
  139. package/lib/secure-tunneling/secure-tunnel-message-handler.d.ts +8 -0
  140. package/lib/secure-tunneling/secure-tunnel-message-handler.d.ts.map +1 -0
  141. package/lib/secure-tunneling/secure-tunnel-message-handler.js +42 -0
  142. package/lib/secure-tunneling/secure-tunnel-message-handler.js.map +1 -0
  143. package/lib/secure-tunneling/secure-tunneling.d.ts +9 -9
  144. package/lib/secure-tunneling/secure-tunneling.d.ts.map +1 -1
  145. package/lib/secure-tunneling/secure-tunneling.js +21 -16
  146. package/lib/secure-tunneling/secure-tunneling.js.map +1 -1
  147. package/lib/secure-tunneling/secure-tunneling.test.js +11 -13
  148. package/lib/secure-tunneling/secure-tunneling.test.js.map +1 -1
  149. package/lib/subcommands/app/analytics.d.ts.map +1 -1
  150. package/lib/subcommands/app/analytics.js +1 -2
  151. package/lib/subcommands/app/analytics.js.map +1 -1
  152. package/lib/subcommands/app/env-vars.d.ts +4 -0
  153. package/lib/subcommands/app/env-vars.d.ts.map +1 -1
  154. package/lib/subcommands/app/env-vars.js +52 -6
  155. package/lib/subcommands/app/env-vars.js.map +1 -1
  156. package/lib/subcommands/app/index.d.ts.map +1 -1
  157. package/lib/subcommands/app/index.js +1 -3
  158. package/lib/subcommands/app/index.js.map +1 -1
  159. package/lib/subcommands/app/models.d.ts +0 -11
  160. package/lib/subcommands/app/models.d.ts.map +1 -1
  161. package/lib/subcommands/app/models.js +2 -58
  162. package/lib/subcommands/app/models.js.map +1 -1
  163. package/lib/subcommands/app/shadow.d.ts.map +1 -1
  164. package/lib/subcommands/app/shadow.js +6 -5
  165. package/lib/subcommands/app/shadow.js.map +1 -1
  166. package/lib/subcommands/app/version.d.ts +2 -0
  167. package/lib/subcommands/app/version.d.ts.map +1 -1
  168. package/lib/subcommands/app/version.js +16 -6
  169. package/lib/subcommands/app/version.js.map +1 -1
  170. package/lib/subcommands/config.d.ts +2 -0
  171. package/lib/subcommands/config.d.ts.map +1 -0
  172. package/lib/subcommands/config.js +39 -0
  173. package/lib/subcommands/config.js.map +1 -0
  174. package/lib/subcommands/device/clean.d.ts +1 -1
  175. package/lib/subcommands/device/clean.d.ts.map +1 -1
  176. package/lib/subcommands/device/clean.js +23 -13
  177. package/lib/subcommands/device/clean.js.map +1 -1
  178. package/lib/subcommands/device/index.d.ts.map +1 -1
  179. package/lib/subcommands/device/index.js +3 -1
  180. package/lib/subcommands/device/index.js.map +1 -1
  181. package/lib/subcommands/device/init.js +8 -8
  182. package/lib/subcommands/device/init.js.map +1 -1
  183. package/lib/subcommands/device/migrate.d.ts +2 -0
  184. package/lib/subcommands/device/migrate.d.ts.map +1 -0
  185. package/lib/subcommands/device/migrate.js +24 -0
  186. package/lib/subcommands/device/migrate.js.map +1 -0
  187. package/lib/subcommands/device/refresh.d.ts.map +1 -1
  188. package/lib/subcommands/device/refresh.js +1 -0
  189. package/lib/subcommands/device/refresh.js.map +1 -1
  190. package/lib/subcommands/index.d.ts +1 -1
  191. package/lib/subcommands/index.d.ts.map +1 -1
  192. package/lib/subcommands/index.js +3 -1
  193. package/lib/subcommands/index.js.map +1 -1
  194. package/lib/subcommands/rabbitmq-connection.d.ts +1 -1
  195. package/lib/subcommands/rabbitmq-connection.d.ts.map +1 -1
  196. package/lib/util/aai-error.d.ts +12 -0
  197. package/lib/util/aai-error.d.ts.map +1 -0
  198. package/lib/util/aai-error.js +11 -0
  199. package/lib/util/aai-error.js.map +1 -0
  200. package/lib/util/aws-regions.d.ts +2 -0
  201. package/lib/util/aws-regions.d.ts.map +1 -0
  202. package/lib/util/{cloud-mode-ready.js → aws-regions.js} +2 -20
  203. package/lib/util/aws-regions.js.map +1 -0
  204. package/lib/util/check-for-updates.d.ts.map +1 -1
  205. package/lib/util/check-for-updates.js +5 -28
  206. package/lib/util/check-for-updates.js.map +1 -1
  207. package/lib/util/clean-certs.d.ts.map +1 -1
  208. package/lib/util/clean-certs.js +5 -4
  209. package/lib/util/clean-certs.js.map +1 -1
  210. package/lib/util/directories.d.ts +4 -18
  211. package/lib/util/directories.d.ts.map +1 -1
  212. package/lib/util/directories.js +18 -32
  213. package/lib/util/directories.js.map +1 -1
  214. package/lib/util/file.d.ts +4 -0
  215. package/lib/util/file.d.ts.map +1 -1
  216. package/lib/util/file.js +65 -4
  217. package/lib/util/file.js.map +1 -1
  218. package/lib/util/get-device-id.d.ts.map +1 -1
  219. package/lib/util/get-device-id.js +7 -1
  220. package/lib/util/get-device-id.js.map +1 -1
  221. package/lib/util/http-client.js +3 -3
  222. package/lib/util/http-client.js.map +1 -1
  223. package/package.json +19 -17
  224. package/readme.md +12 -32
  225. package/src/application-control/config.ts +9 -12
  226. package/src/application-control/environment-variables.test.ts +28 -7
  227. package/src/application-control/environment-variables.ts +42 -59
  228. package/src/application-control/index.ts +3 -16
  229. package/src/application-control/install.ts +39 -13
  230. package/src/application-control/models.ts +6 -87
  231. package/src/application-control/utils.ts +10 -25
  232. package/src/cloud-connection/base-message-handler.ts +118 -0
  233. package/src/cloud-connection/bootstrap-provision.ts +7 -7
  234. package/src/cloud-connection/connection-manager.ts +187 -0
  235. package/src/cloud-connection/device-agent-cloud-connection.ts +130 -723
  236. package/src/cloud-connection/device-agent-message-handler.ts +642 -0
  237. package/src/cloud-connection/device-agent.ts +16 -7
  238. package/src/cloud-connection/live-updates-handler.test.ts +121 -189
  239. package/src/cloud-connection/live-updates-handler.ts +105 -232
  240. package/src/cloud-connection/message-dispatcher.ts +33 -0
  241. package/src/cloud-connection/passthrough-handler.ts +55 -18
  242. package/src/cloud-connection/shadow-handler.test.ts +45 -57
  243. package/src/cloud-connection/shadow-handler.ts +224 -54
  244. package/src/cloud-connection/shadow.ts +4 -1
  245. package/src/cloud-connection/transaction-manager.test.ts +68 -6
  246. package/src/cloud-connection/transaction-manager.ts +69 -41
  247. package/src/device-control/device-control.ts +102 -70
  248. package/src/docker/docker-compose.ts +3 -2
  249. package/src/infrastructure/agent-config.test.ts +6 -2
  250. package/src/infrastructure/agent-config.ts +8 -7
  251. package/src/infrastructure/config-check-utility.test.ts +154 -0
  252. package/src/infrastructure/config-check-utility.ts +77 -0
  253. package/src/infrastructure/device-certificate.test.ts +40 -0
  254. package/src/infrastructure/device-certificate.ts +58 -0
  255. package/src/infrastructure/legacy-migration/legacy-file.test.ts +88 -0
  256. package/src/infrastructure/legacy-migration/legacy-files.ts +101 -0
  257. package/src/infrastructure/legacy-migration/legacy-migration.test.ts +396 -0
  258. package/src/infrastructure/legacy-migration/legacy-migration.ts +229 -0
  259. package/src/infrastructure/require-files-present-ready.test.ts +53 -0
  260. package/src/infrastructure/required-config-checks.ts +33 -0
  261. package/src/infrastructure/tokens-and-device-cfg.ts +12 -10
  262. package/src/jobs/job-handler.ts +146 -0
  263. package/src/local-connection/rabbitmq-connection.ts +22 -17
  264. package/src/secure-tunneling/secure-tunnel-message-handler.ts +56 -0
  265. package/src/secure-tunneling/secure-tunneling.test.ts +20 -22
  266. package/src/secure-tunneling/secure-tunneling.ts +41 -29
  267. package/src/subcommands/app/analytics.ts +2 -4
  268. package/src/subcommands/app/env-vars.ts +72 -9
  269. package/src/subcommands/app/index.ts +3 -11
  270. package/src/subcommands/app/models.ts +5 -81
  271. package/src/subcommands/app/shadow.ts +6 -5
  272. package/src/subcommands/app/version.ts +23 -6
  273. package/src/subcommands/config.ts +42 -0
  274. package/src/subcommands/device/clean.ts +31 -17
  275. package/src/subcommands/device/index.ts +3 -1
  276. package/src/subcommands/device/init.ts +11 -11
  277. package/src/subcommands/device/migrate.ts +20 -0
  278. package/src/subcommands/device/refresh.ts +1 -0
  279. package/src/subcommands/index.ts +3 -1
  280. package/src/util/aai-error.ts +20 -0
  281. package/src/util/{cloud-mode-ready.ts → aws-regions.ts} +0 -24
  282. package/src/util/check-for-updates.ts +14 -30
  283. package/src/util/clean-certs.ts +8 -4
  284. package/src/util/directories.ts +23 -67
  285. package/src/util/file.ts +83 -3
  286. package/src/util/get-device-id.ts +7 -7
  287. package/src/util/http-client.ts +2 -2
  288. package/lib/util/cloud-mode-ready.d.ts +0 -3
  289. package/lib/util/cloud-mode-ready.d.ts.map +0 -1
  290. package/lib/util/cloud-mode-ready.js.map +0 -1
  291. package/lib/util/download-file.d.ts +0 -6
  292. package/lib/util/download-file.d.ts.map +0 -1
  293. package/lib/util/download-file.js +0 -25
  294. package/lib/util/download-file.js.map +0 -1
  295. package/lib/util/fetch-with-timeout.d.ts +0 -4
  296. package/lib/util/fetch-with-timeout.d.ts.map +0 -1
  297. package/lib/util/fetch-with-timeout.js +0 -30
  298. package/lib/util/fetch-with-timeout.js.map +0 -1
  299. package/lib/util/parsing.d.ts +0 -2
  300. package/lib/util/parsing.d.ts.map +0 -1
  301. package/lib/util/parsing.js +0 -17
  302. package/lib/util/parsing.js.map +0 -1
  303. package/src/util/download-file.ts +0 -25
  304. package/src/util/fetch-with-timeout.ts +0 -35
  305. package/src/util/parsing.ts +0 -11
@@ -0,0 +1,642 @@
1
+ import {
2
+ keyMirrors,
3
+ AppStateControlMessage,
4
+ buildToClientStatusResponseMessage,
5
+ AppStateControlPayload,
6
+ AppVersionControlMessage,
7
+ AppVersionControlInstallPayload,
8
+ AppVersionControlUninstallPayload,
9
+ SignedUrlsRequestPayload,
10
+ buildSignedUrlsRequestMessage,
11
+ ToCloudMessage,
12
+ LiveStateUpdatesToggleMessage,
13
+ buildDeviceStatsMessage,
14
+ buildAppStateMessage,
15
+ buildAppLogsMessage,
16
+ AppInstallResponsePayload,
17
+ ModelsInstallResponsePayload,
18
+ ToDeviceStatusResponseMessage,
19
+ DeviceActionPayload,
20
+ validateToDeviceAgentMessage,
21
+ ToDeviceAgentMessage,
22
+ EnvVars,
23
+ validateEnvVarSchemaShadowUpdate
24
+ } from '@alwaysai/device-agent-schemas';
25
+ import {
26
+ AppInstallResponseMessage,
27
+ ModelsInstallResponseMessage
28
+ } from '@alwaysai/device-agent-schemas/lib/app-action-schema';
29
+ import { DeviceActionMessage } from '@alwaysai/device-agent-schemas/lib/device-action-schema';
30
+ import { logger, stringifyError } from 'alwaysai/lib/util';
31
+ import {
32
+ startApp,
33
+ stopApp,
34
+ restartApp,
35
+ getAppLogs,
36
+ installApp,
37
+ updateModelsWithPresignedUrls
38
+ } from '../application-control';
39
+ import { reboot } from '../device-control/device-control';
40
+ import { MessageDispatcher, MessageHandler } from './message-dispatcher';
41
+ import { getDeviceStatsPayload, getAppStatePayload } from './messages';
42
+ import { BaseHandler, HandlerContext } from './base-message-handler';
43
+ import { ErrorFunction, SuccessFunction } from './transaction-manager';
44
+ import {
45
+ AppConfig,
46
+ validateAppConfig
47
+ } from '@alwaysai/app-configuration-schemas';
48
+
49
+ export type AppContent = {
50
+ projectId: string;
51
+ appCfg?: AppConfig;
52
+ envVars?: EnvVars;
53
+ };
54
+
55
+ export type AppContentUpdate = {
56
+ appCfg?: string;
57
+ envVars?: string;
58
+ };
59
+ export class DeviceAgentMessageHandler
60
+ extends MessageDispatcher<ToDeviceAgentMessage>
61
+ implements MessageHandler<any>
62
+ {
63
+ private readonly handlerContext: HandlerContext;
64
+ private readonly errorFn?: ErrorFunction;
65
+ private readonly successFn?: SuccessFunction;
66
+
67
+ constructor(
68
+ handlerContext: HandlerContext,
69
+ errorFn?: ErrorFunction,
70
+ successFn?: SuccessFunction
71
+ ) {
72
+ super();
73
+ this.handlerContext = handlerContext;
74
+ this.errorFn = errorFn;
75
+ this.successFn = successFn;
76
+
77
+ const handlerMapping: {
78
+ [key: string]: new (
79
+ context: HandlerContext,
80
+ errorFn?: ErrorFunction,
81
+ successFn?: SuccessFunction
82
+ ) => MessageHandler<ToDeviceAgentMessage>;
83
+ } = {
84
+ [keyMirrors.toDeviceAgentMessageType.app_state_control]:
85
+ AppStateMessageHandler,
86
+ [keyMirrors.toDeviceAgentMessageType.live_state_updates]:
87
+ LiveStateUpdatesMessageHandler,
88
+ [keyMirrors.toDeviceAgentMessageType.app_version_control]:
89
+ AppVersionControlMessageHandler,
90
+ [keyMirrors.toDeviceAgentMessageType.app_install_response]:
91
+ AppInstallResponseMessageHandler,
92
+ [keyMirrors.toDeviceAgentMessageType.models_install_response]:
93
+ ModelsInstallResponseMessageHandler,
94
+ [keyMirrors.toDeviceAgentMessageType.status_response]:
95
+ StatusResponseMessageHandler,
96
+ [keyMirrors.toDeviceAgentMessageType.device_action]:
97
+ DeviceActionMessageHandler
98
+ };
99
+
100
+ Object.entries(handlerMapping).forEach(([keyMirror, HandlerClass]) => {
101
+ this.registerHandler(
102
+ keyMirror,
103
+ new HandlerClass(this.handlerContext, this.errorFn, this.successFn)
104
+ );
105
+ });
106
+ }
107
+
108
+ public handle(message: any, topic?: string): void {
109
+ const valid = validateToDeviceAgentMessage(message);
110
+ if (!valid) {
111
+ logger.error(
112
+ `Error validating message: ${JSON.stringify(
113
+ { topic, message, errors: validateToDeviceAgentMessage.errors },
114
+ null,
115
+ 2
116
+ )}`
117
+ );
118
+ if (this.errorFn) {
119
+ this.errorFn(
120
+ '',
121
+ `Error validating message: ${JSON.stringify(
122
+ { topic, message, errors: validateToDeviceAgentMessage.errors },
123
+ null,
124
+ 2
125
+ )}`
126
+ );
127
+ }
128
+ return;
129
+ }
130
+ this.dispatch(message.messageType, message);
131
+ }
132
+ }
133
+
134
+ class AppStateMessageHandler
135
+ extends BaseHandler
136
+ implements MessageHandler<AppStateControlMessage>
137
+ {
138
+ public async handle(message: AppStateControlMessage): Promise<void> {
139
+ const payload = message.payload;
140
+ const projectId = payload.projectId;
141
+ const txId = message.txId;
142
+ try {
143
+ await this.txnMgr.runTransactionStep({
144
+ func: () => this.handleAppStateControl(message.payload),
145
+ projectId,
146
+ txId,
147
+ start: true,
148
+ liveUpdatesPublishFn: async () =>
149
+ this.publisher.publishToClient(
150
+ buildToClientStatusResponseMessage(
151
+ this.clientId,
152
+ { status: keyMirrors.statusResponse.in_progress },
153
+ txId
154
+ ),
155
+ logger.silly
156
+ ),
157
+ stepName: payload.baseCommand,
158
+ errorFn: this.errorFn,
159
+ successFn: this.successFn
160
+ });
161
+ } catch (e) {
162
+ logger.error(
163
+ `Error processing application state control request for ${projectId}!\n${stringifyError(
164
+ e
165
+ )}`
166
+ );
167
+ }
168
+ }
169
+
170
+ private handleAppStateControl = async (
171
+ payload: AppStateControlPayload
172
+ ): Promise<boolean> => {
173
+ const { baseCommand, projectId } = payload;
174
+ switch (baseCommand) {
175
+ case keyMirrors.appStateControl.start:
176
+ await startApp({ projectId });
177
+ break;
178
+ case keyMirrors.appStateControl.stop:
179
+ await stopApp({ projectId });
180
+ break;
181
+ case keyMirrors.appStateControl.restart:
182
+ await restartApp({ projectId });
183
+ break;
184
+ }
185
+ return true;
186
+ };
187
+ }
188
+
189
+ class AppVersionControlMessageHandler
190
+ extends BaseHandler
191
+ implements MessageHandler<AppVersionControlMessage>
192
+ {
193
+ public async handle(message: AppVersionControlMessage): Promise<void> {
194
+ const payload = message.payload;
195
+ const projectId = payload.projectId;
196
+ const txId = message.txId;
197
+ try {
198
+ await this.txnMgr.runTransactionStep({
199
+ func: () => this.handleAppVersionControl(payload, txId),
200
+ projectId,
201
+ txId,
202
+ start: true,
203
+ liveUpdatesPublishFn: async () =>
204
+ this.publisher.publishToClient(
205
+ buildToClientStatusResponseMessage(
206
+ this.clientId,
207
+ { status: keyMirrors.statusResponse.in_progress },
208
+ txId
209
+ ),
210
+ logger.silly
211
+ ),
212
+ stepName: payload.baseCommand,
213
+ errorFn: this.errorFn,
214
+ successFn: this.successFn
215
+ });
216
+ } catch (e) {
217
+ logger.error(
218
+ `Error processing application install request for ${projectId}!\n${stringifyError(
219
+ e
220
+ )}`
221
+ );
222
+ }
223
+ }
224
+
225
+ private handleAppVersionControl = async (
226
+ payload:
227
+ | AppVersionControlInstallPayload
228
+ | AppVersionControlUninstallPayload,
229
+ txId: string
230
+ ): Promise<boolean> => {
231
+ switch (payload.baseCommand) {
232
+ case keyMirrors.appVersionControl.install: {
233
+ const { projectId, appReleaseHash, appCfg, envVars } = payload;
234
+ const appContentUpdate: AppContentUpdate = {
235
+ appCfg,
236
+ envVars
237
+ };
238
+ const appContent = await this.processAppContentUpdate(
239
+ projectId,
240
+ appContentUpdate
241
+ );
242
+ if (appContent) {
243
+ this.txnMgr.setAppContentToTx(txId, appContent);
244
+ }
245
+
246
+ const signedUrlsRequestPayload: SignedUrlsRequestPayload = {
247
+ signedUrlsRequest: {
248
+ projectId,
249
+ appReleaseHash
250
+ }
251
+ };
252
+ const message = buildSignedUrlsRequestMessage(
253
+ this.clientId,
254
+ signedUrlsRequestPayload,
255
+ txId
256
+ );
257
+ await this.publishCloudRequest(message);
258
+ return false;
259
+ }
260
+ case keyMirrors.appVersionControl.uninstall: {
261
+ const { projectId } = payload;
262
+ await this.atomicApplicationUninstall(projectId);
263
+ return true;
264
+ }
265
+ default:
266
+ logger.warn(
267
+ `Ignore App Version Control packet: ${JSON.stringify(
268
+ payload,
269
+ null,
270
+ 2
271
+ )}`
272
+ );
273
+ return true;
274
+ }
275
+ };
276
+
277
+ private async publishCloudRequest(message: ToCloudMessage) {
278
+ this.publisher.publishToCloud(message);
279
+ }
280
+
281
+ private async processAppContentUpdate(
282
+ projectId: string,
283
+ appContentUpdate: AppContentUpdate
284
+ ): Promise<AppContent | null> {
285
+ const appContent: AppContent = { projectId };
286
+ // appCfg
287
+ if (!appContentUpdate.appCfg) {
288
+ logger.info(`No appCfgUpdate for ${projectId}`);
289
+ } else {
290
+ // Handle errors and validation
291
+ try {
292
+ const appCfgUpdate = JSON.parse(appContentUpdate.appCfg);
293
+ if (!validateAppConfig(appCfgUpdate)) {
294
+ logger.error(
295
+ `Received invalid app config for ${projectId}!\n${JSON.stringify(
296
+ validateAppConfig.errors,
297
+ null,
298
+ 2
299
+ )}`
300
+ );
301
+ throw new Error(
302
+ `Received invalid app config for ${projectId}!\n${JSON.stringify(
303
+ validateAppConfig.errors,
304
+ null,
305
+ 2
306
+ )}`
307
+ );
308
+ } else {
309
+ appContent.appCfg = appCfgUpdate;
310
+ }
311
+ } catch (e) {
312
+ logger.error(
313
+ `Could not parse the appConfig for transaction!\n${stringifyError(e)}`
314
+ );
315
+ }
316
+ }
317
+
318
+ // envVars
319
+ if (!appContentUpdate.envVars) {
320
+ logger.info(`No envVars for ${projectId}`);
321
+ } else {
322
+ try {
323
+ const envvarsUpdate = JSON.parse(appContentUpdate.envVars);
324
+ if (!validateEnvVarSchemaShadowUpdate(envvarsUpdate)) {
325
+ logger.error(
326
+ `Received invalid environment variables update for ${projectId}!\n${JSON.stringify(
327
+ validateEnvVarSchemaShadowUpdate.errors,
328
+ null,
329
+ 2
330
+ )}`
331
+ );
332
+ throw new Error(
333
+ `Received invalid environment variables update for${projectId}!\n${JSON.stringify(
334
+ validateEnvVarSchemaShadowUpdate.errors,
335
+ null,
336
+ 2
337
+ )}`
338
+ );
339
+ } else {
340
+ appContent.envVars = envvarsUpdate;
341
+ }
342
+ } catch (e) {
343
+ // throw here
344
+ logger.error(
345
+ `Could not parse the environment variables for transaction!\n${stringifyError(
346
+ e
347
+ )}`
348
+ );
349
+ }
350
+ }
351
+
352
+ return appContent.appCfg || appContent.envVars ? appContent : null;
353
+ }
354
+ }
355
+
356
+ class LiveStateUpdatesMessageHandler
357
+ extends BaseHandler
358
+ implements MessageHandler<LiveStateUpdatesToggleMessage>
359
+ {
360
+ public async handle(message: LiveStateUpdatesToggleMessage): Promise<void> {
361
+ const { deviceStats, appState, appLogs } = message.payload;
362
+ const txId = message.txId;
363
+
364
+ if (deviceStats !== undefined) {
365
+ if (deviceStats) {
366
+ await this.liveUpdatesHandler.enable(
367
+ keyMirrors.toClientMessageType.device_stats,
368
+ async () =>
369
+ this.publisher.publishToClient(
370
+ buildDeviceStatsMessage(
371
+ this.clientId,
372
+ await getDeviceStatsPayload(),
373
+ txId
374
+ ),
375
+ logger.silly
376
+ )
377
+ );
378
+ } else {
379
+ this.liveUpdatesHandler.disable(
380
+ keyMirrors.toClientMessageType.device_stats
381
+ );
382
+ }
383
+ }
384
+
385
+ if (appState !== undefined) {
386
+ if (appState) {
387
+ await this.liveUpdatesHandler.enable(
388
+ keyMirrors.toClientMessageType.app_state,
389
+ async () =>
390
+ this.publisher.publishToClient(
391
+ buildAppStateMessage(
392
+ this.clientId,
393
+ await getAppStatePayload(),
394
+ txId
395
+ ),
396
+ logger.silly
397
+ )
398
+ );
399
+ } else {
400
+ this.liveUpdatesHandler.disable(
401
+ keyMirrors.toClientMessageType.app_state
402
+ );
403
+ }
404
+ }
405
+
406
+ if (appLogs !== undefined) {
407
+ if (appLogs.toggle) {
408
+ await this.liveUpdatesHandler.startStream(
409
+ appLogs.projectId,
410
+ async () =>
411
+ await getAppLogs({
412
+ projectId: appLogs.projectId,
413
+ args: ['--tail', '100', '--no-log-prefix']
414
+ }),
415
+ async (logChunk: string) =>
416
+ this.publisher.publishToClient(
417
+ buildAppLogsMessage(
418
+ this.clientId,
419
+ {
420
+ projectId: appLogs.projectId,
421
+ logChunk
422
+ },
423
+ txId
424
+ ),
425
+ logger.silly
426
+ )
427
+ );
428
+ } else {
429
+ this.liveUpdatesHandler.stopStream(appLogs.projectId);
430
+ }
431
+ }
432
+ }
433
+ }
434
+
435
+ class AppInstallResponseMessageHandler
436
+ extends BaseHandler
437
+ implements MessageHandler<AppInstallResponseMessage>
438
+ {
439
+ public async handle(message: AppInstallResponseMessage): Promise<void> {
440
+ const payload = message.payload;
441
+ const txId = message.txId;
442
+ const { projectId } = payload.appInstallResponse;
443
+ const start = !this.txnMgr.isOngoingTransactionForProjectID(projectId);
444
+
445
+ if (!start && txId !== this.txnMgr.getTransactionFromProject(projectId)) {
446
+ throw new Error(
447
+ `App install response received a message for a transaction ID ${txId} that is not currently underway (${this.txnMgr.getTransactionFromProject(
448
+ projectId
449
+ )})!`
450
+ );
451
+ }
452
+ const appContent = this.txnMgr.getAppContentFromTxId(txId);
453
+ await this.txnMgr.runTransactionStep({
454
+ func: () =>
455
+ this.handleAppInstallCloudResponsePayload(payload, appContent),
456
+ projectId,
457
+ txId,
458
+ start,
459
+ stepName: message.messageType,
460
+ errorFn: this.errorFn,
461
+ successFn: this.successFn
462
+ });
463
+ }
464
+
465
+ private handleAppInstallCloudResponsePayload = async (
466
+ payload: AppInstallResponsePayload,
467
+ appContent?: AppContent
468
+ ): Promise<boolean> => {
469
+ const {
470
+ projectId,
471
+ appReleaseHash,
472
+ appInstallPayload,
473
+ modelsInstallPayload
474
+ } = payload.appInstallResponse;
475
+ const signedUrlsPayload = {
476
+ appInstallPayload,
477
+ modelsInstallPayload
478
+ };
479
+ await this.atomicApplicationUpdate(async () => {
480
+ this.shadowHandler.clearProjectShadow(projectId);
481
+ await installApp({
482
+ projectId,
483
+ appReleaseHash,
484
+ signedUrlsPayload,
485
+ appCfg: appContent?.appCfg,
486
+ envVars: appContent?.envVars
487
+ });
488
+ }, projectId);
489
+ return true;
490
+ };
491
+ }
492
+
493
+ class ModelsInstallResponseMessageHandler
494
+ extends BaseHandler
495
+ implements MessageHandler<ModelsInstallResponseMessage>
496
+ {
497
+ public async handle(message: ModelsInstallResponseMessage): Promise<void> {
498
+ const payload = message.payload;
499
+ const txId = message.txId;
500
+ const { projectId } = payload.modelsInstallResponse;
501
+ if (txId !== this.txnMgr.getTransactionFromProject(projectId)) {
502
+ throw new Error(
503
+ `Model install response received a message for a transaction ID ${txId} that is not currently underway (${this.txnMgr.getTransactionFromProject(
504
+ projectId
505
+ )})!`
506
+ );
507
+ }
508
+ await this.txnMgr.runTransactionStep({
509
+ func: () => this.handleModelsInstallCloudResponsePayload(payload, txId),
510
+ projectId,
511
+ txId,
512
+ start: false,
513
+ stepName: message.messageType,
514
+ errorFn: this.errorFn,
515
+ successFn: this.successFn
516
+ });
517
+ }
518
+
519
+ private handleModelsInstallCloudResponsePayload = async (
520
+ payload: ModelsInstallResponsePayload,
521
+ txId: string
522
+ ): Promise<boolean> => {
523
+ const projectId = payload.modelsInstallResponse.projectId;
524
+
525
+ const update = this.txnMgr.getAppCfgUpdateFromTxID(txId);
526
+ if (update === undefined) {
527
+ throw new Error(
528
+ 'Unknown error while updating models via application config! No config present for model update.'
529
+ );
530
+ }
531
+ const { appCfgUpdate, envVarUpdate } = update;
532
+ if (appCfgUpdate) {
533
+ await this.atomicApplicationUpdate(
534
+ async () =>
535
+ await updateModelsWithPresignedUrls({
536
+ projectId,
537
+ modelInstallPayloads: payload.modelsInstallResponse.newModels,
538
+ newAppCfg: appCfgUpdate.newAppCfg
539
+ }),
540
+ projectId
541
+ );
542
+ }
543
+
544
+ if (envVarUpdate) {
545
+ await this.atomicApplicationUpdate(
546
+ async () =>
547
+ await this.shadowHandler.updateProjectEnvVars({
548
+ projectId,
549
+ envVars: envVarUpdate.envVars
550
+ }),
551
+ projectId,
552
+ true
553
+ );
554
+ }
555
+ return true;
556
+ };
557
+ }
558
+
559
+ class StatusResponseMessageHandler
560
+ extends BaseHandler
561
+ implements MessageHandler<ToDeviceStatusResponseMessage>
562
+ {
563
+ public async handle(message: ToDeviceStatusResponseMessage): Promise<void> {
564
+ const txId = message.txId;
565
+ const { failure } = keyMirrors.statusResponse;
566
+ if (message.payload.status === failure) {
567
+ this.txnMgr.completeTransaction(txId);
568
+ const msg = buildToClientStatusResponseMessage(
569
+ this.clientId,
570
+ {
571
+ status: keyMirrors.statusResponse.failure,
572
+ message: message.payload.message
573
+ },
574
+ txId
575
+ );
576
+ this.publisher.publishToClient(msg);
577
+ }
578
+ }
579
+ }
580
+
581
+ class DeviceActionMessageHandler
582
+ extends BaseHandler
583
+ implements MessageHandler<DeviceActionMessage>
584
+ {
585
+ public async handle(message: DeviceActionMessage): Promise<void> {
586
+ const txId = message.txId;
587
+ try {
588
+ this.publisher.publishToClient(
589
+ buildToClientStatusResponseMessage(
590
+ this.clientId,
591
+ {
592
+ status: keyMirrors.statusResponse.in_progress
593
+ },
594
+ txId
595
+ )
596
+ );
597
+
598
+ await this.handleDeviceAction(message.payload);
599
+
600
+ this.publisher.publishToClient(
601
+ buildToClientStatusResponseMessage(
602
+ this.clientId,
603
+ {
604
+ status: keyMirrors.statusResponse.success
605
+ },
606
+ txId
607
+ )
608
+ );
609
+ } catch (e) {
610
+ logger.error(
611
+ `There was a problem performing device action '${
612
+ message.payload.action
613
+ }'!\n${stringifyError(e)}`
614
+ );
615
+ this.publisher.publishToClient(
616
+ buildToClientStatusResponseMessage(
617
+ this.clientId,
618
+ {
619
+ status: keyMirrors.statusResponse.failure,
620
+ message: e.message
621
+ },
622
+ txId
623
+ )
624
+ );
625
+ }
626
+ }
627
+
628
+ private async handleDeviceAction(payload: DeviceActionPayload) {
629
+ const { system_restart } = keyMirrors.deviceAction;
630
+ switch (payload.action) {
631
+ case system_restart: {
632
+ await reboot();
633
+ break;
634
+ }
635
+ default: {
636
+ logger.info(
637
+ `Unrecognized device action requested: '${payload.action}'.`
638
+ );
639
+ }
640
+ }
641
+ }
642
+ }
@@ -1,16 +1,20 @@
1
1
  // eslint-disable-next-line
2
2
  const awsIot = require('aws-iot-device-sdk');
3
+ import { getTargetHardwareUuid } from 'alwaysai/lib/core/app';
3
4
  import {
5
+ DEVICE_CERTIFICATE_FILE_NAME,
6
+ DEVICE_CERTIFICATE_ID_FILE_NAME,
4
7
  DEVICE_PRIVATE_KEY_FILE_NAME,
8
+ LOCAL_CERT_AND_KEY_DIR
9
+ } from 'alwaysai/lib/infrastructure';
10
+ import { JsSpawner } from 'alwaysai/lib/util';
11
+ import {
5
12
  CERTIFICATE_OWNERSHIP_TOKEN_FILE_NAME,
6
- DEVICE_ID_FILE_NAME,
7
- DEVICE_CERTIFICATE_FILE_NAME
8
- } from '../util/directories';
13
+ getBootstrapCertificateDirectoryPath
14
+ } from '../infrastructure/device-certificate';
9
15
  import { getDeviceUuid } from '../util/get-device-id';
10
- import { JsSpawner } from 'alwaysai/lib/util';
11
16
  import { logger } from '../util/logger';
12
- import { getTargetHardwareUuid } from 'alwaysai/lib/core/app';
13
- import { LOCAL_CERT_AND_KEY_DIR } from 'alwaysai/lib/paths';
17
+
14
18
  // eslint-disable-next-line
15
19
  const process = require('process');
16
20
 
@@ -85,7 +89,10 @@ export class BootstrapAgent extends DeviceAgent {
85
89
 
86
90
  await certSpawner.writeFile(DEVICE_PRIVATE_KEY_FILE_NAME, privateKey);
87
91
 
88
- await certSpawner.writeFile(DEVICE_ID_FILE_NAME, certificateId);
92
+ await certSpawner.writeFile(
93
+ DEVICE_CERTIFICATE_ID_FILE_NAME,
94
+ certificateId
95
+ );
89
96
 
90
97
  await certSpawner.writeFile(
91
98
  CERTIFICATE_OWNERSHIP_TOKEN_FILE_NAME,
@@ -111,6 +118,8 @@ export class BootstrapAgent extends DeviceAgent {
111
118
  }
112
119
  case '$aws/provisioning-templates/FleetProvisionTemplate/provision/json/accepted': {
113
120
  logger.info('Device agent provisioning: success');
121
+ const spawner = JsSpawner();
122
+ await spawner.rimraf(getBootstrapCertificateDirectoryPath());
114
123
  process.exit();
115
124
  }
116
125
  }