@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
@@ -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 { JsSpawner } from 'alwaysai/lib/util';
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
- deviceId: deviceUuid,
25
+ deviceUuid,
25
26
  accessToken,
26
27
  refreshToken,
27
28
  idToken
28
29
  };
29
- const tokenSpawner = JsSpawner({ path: LOCAL_AAI_CFG_DIR });
30
- await writeTokens({ spawner: tokenSpawner, tokens });
31
- await writeOrValidateDeviceCfgFile({ spawner: tokenSpawner, deviceUuid });
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 { logger } from '../util/logger';
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
- DEVICE_AGENT_CFG_PATH,
8
- DEVICE_AGENT_DOCKER_COMPOSE_PATH
5
+ getDeviceAgentConfigPath,
6
+ getDeviceAgentDockerComposePath
9
7
  } from '../util/directories';
10
- import { JsSpawner } from 'alwaysai/lib/util';
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(DEVICE_AGENT_DOCKER_COMPOSE_PATH))) {
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: DEVICE_AGENT_CFG_PATH });
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(DEVICE_AGENT_CFG_PATH))) {
45
- await JsSpawner().mkdirp(DEVICE_AGENT_CFG_PATH);
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
- DEVICE_AGENT_DOCKER_COMPOSE_PATH,
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:\n{e.message}`
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: DEVICE_AGENT_CFG_PATH
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:\n${e}`
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: DEVICE_AGENT_CFG_PATH });
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:\n${e.message}`
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/download-file', () => ({
54
- downloadFile: jest.fn()
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
- ): SecureTunnelShadowDescriptionReported {
175
+ ): SecureTunnelShadowUpdate {
178
176
  const { version, state } = deltaMsg;
179
- const reportedStateReported: SecureTunnelShadowDescriptionReported =
180
- JSON.parse(JSON.stringify(state));
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(downloadFile).not.toHaveBeenCalled();
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(downloadFile).toHaveBeenCalledTimes(1);
786
- expect(downloadFile).toHaveBeenCalledWith({
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(downloadFile).not.toHaveBeenCalled();
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(downloadFile).not.toHaveBeenCalled();
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(downloadFile).not.toHaveBeenCalled();
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(downloadFile).not.toHaveBeenCalled();
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/cloud-mode-ready';
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?: SecureTunnelShadowDescriptionReported;
29
- desired?: SecureTunnelShadowDescriptionReported;
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: SecureTunnelShadowDescriptionReported;
35
+ state: SecureTunnelShadowUpdate;
36
36
  metadata?: any;
37
37
  };
38
38
 
39
- export type SecureTunnelShadowUpdate = {
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: SecureTunnelShadowDescriptionReported;
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 {SecureTunnelShadowDescriptionReported} - reported state of the SecureTunnel shadow
149
+ * @returns {SecureTunnelShadowUpdate} - reported state of the SecureTunnel shadow
150
150
  */
151
- public getSecureTunnelShadow(): SecureTunnelShadowDescriptionReported {
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 {SecureTunnelShadowDescriptionReported} update reported message to send back to AWS IoT device shadow
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<SecureTunnelShadowDescriptionReported> {
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 (error) {
238
- logger.error(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 (error) {
327
+ } catch (e) {
328
328
  logger.error(
329
- `ERROR: starting socat for: ${portInfo.ip}:${portInfo.port} on localhost port: ${localPort}, error: ${error}`
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('ERROR: killing socat process:', e);
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('ERROR: killing local proxy process:', e);
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
- await downloadFile({
549
- url,
550
- path: SECURE_TUNNEL_BIN_PATH,
551
- errorMessage: `Secure Tunnel bin for ${linuxDistro} ${osVersion} ${arch} not found}`
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: SecureTunnelShadowDescriptionReported
582
- ): SecureTunnelShadowDescriptionReported {
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
- buildUpdateProjectShadowMessage,
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
- buildUpdateProjectShadowMessage({
86
+ buildUpdateShadowMessage({
89
87
  clientId: 'client',
90
88
  desired: toDesire
91
89
  })