@alwaysai/device-agent 1.5.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.
Files changed (273) 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 +1 -5
  5. package/lib/application-control/environment-variables.d.ts.map +1 -1
  6. package/lib/application-control/environment-variables.js +9 -26
  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.map +1 -1
  15. package/lib/application-control/install.js +8 -7
  16. package/lib/application-control/install.js.map +1 -1
  17. package/lib/application-control/models.d.ts +0 -11
  18. package/lib/application-control/models.d.ts.map +1 -1
  19. package/lib/application-control/models.js +5 -54
  20. package/lib/application-control/models.js.map +1 -1
  21. package/lib/application-control/utils.d.ts +0 -4
  22. package/lib/application-control/utils.d.ts.map +1 -1
  23. package/lib/application-control/utils.js +1 -24
  24. package/lib/application-control/utils.js.map +1 -1
  25. package/lib/cloud-connection/bootstrap-provision.js +3 -2
  26. package/lib/cloud-connection/bootstrap-provision.js.map +1 -1
  27. package/lib/cloud-connection/device-agent-cloud-connection.d.ts +10 -15
  28. package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
  29. package/lib/cloud-connection/device-agent-cloud-connection.js +279 -250
  30. package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
  31. package/lib/cloud-connection/device-agent.d.ts.map +1 -1
  32. package/lib/cloud-connection/device-agent.js +11 -9
  33. package/lib/cloud-connection/device-agent.js.map +1 -1
  34. package/lib/cloud-connection/live-updates-handler.d.ts +18 -28
  35. package/lib/cloud-connection/live-updates-handler.d.ts.map +1 -1
  36. package/lib/cloud-connection/live-updates-handler.js +54 -169
  37. package/lib/cloud-connection/live-updates-handler.js.map +1 -1
  38. package/lib/cloud-connection/live-updates-handler.test.js +71 -165
  39. package/lib/cloud-connection/live-updates-handler.test.js.map +1 -1
  40. package/lib/cloud-connection/passthrough-handler.d.ts +4 -1
  41. package/lib/cloud-connection/passthrough-handler.d.ts.map +1 -1
  42. package/lib/cloud-connection/passthrough-handler.js +30 -11
  43. package/lib/cloud-connection/passthrough-handler.js.map +1 -1
  44. package/lib/cloud-connection/shadow-handler.d.ts +5 -3
  45. package/lib/cloud-connection/shadow-handler.d.ts.map +1 -1
  46. package/lib/cloud-connection/shadow-handler.js +59 -27
  47. package/lib/cloud-connection/shadow-handler.js.map +1 -1
  48. package/lib/cloud-connection/shadow-handler.test.js +45 -57
  49. package/lib/cloud-connection/shadow-handler.test.js.map +1 -1
  50. package/lib/cloud-connection/shadow.d.ts.map +1 -1
  51. package/lib/cloud-connection/shadow.js +2 -1
  52. package/lib/cloud-connection/shadow.js.map +1 -1
  53. package/lib/cloud-connection/transaction-manager.d.ts +4 -2
  54. package/lib/cloud-connection/transaction-manager.d.ts.map +1 -1
  55. package/lib/cloud-connection/transaction-manager.js +18 -29
  56. package/lib/cloud-connection/transaction-manager.js.map +1 -1
  57. package/lib/cloud-connection/transaction-manager.test.js +3 -3
  58. package/lib/cloud-connection/transaction-manager.test.js.map +1 -1
  59. package/lib/device-control/device-control.d.ts +8 -8
  60. package/lib/device-control/device-control.d.ts.map +1 -1
  61. package/lib/device-control/device-control.js +95 -71
  62. package/lib/device-control/device-control.js.map +1 -1
  63. package/lib/docker/docker-compose.d.ts.map +1 -1
  64. package/lib/docker/docker-compose.js +2 -1
  65. package/lib/docker/docker-compose.js.map +1 -1
  66. package/lib/infrastructure/agent-config.d.ts +2 -1
  67. package/lib/infrastructure/agent-config.d.ts.map +1 -1
  68. package/lib/infrastructure/agent-config.js +7 -7
  69. package/lib/infrastructure/agent-config.js.map +1 -1
  70. package/lib/infrastructure/agent-config.test.js +3 -1
  71. package/lib/infrastructure/agent-config.test.js.map +1 -1
  72. package/lib/infrastructure/config-check-utility.d.ts +6 -0
  73. package/lib/infrastructure/config-check-utility.d.ts.map +1 -0
  74. package/lib/infrastructure/config-check-utility.js +67 -0
  75. package/lib/infrastructure/config-check-utility.js.map +1 -0
  76. package/lib/infrastructure/config-check-utility.test.d.ts +2 -0
  77. package/lib/infrastructure/config-check-utility.test.d.ts.map +1 -0
  78. package/lib/infrastructure/config-check-utility.test.js +109 -0
  79. package/lib/infrastructure/config-check-utility.test.js.map +1 -0
  80. package/lib/infrastructure/device-certificate.d.ts +10 -0
  81. package/lib/infrastructure/device-certificate.d.ts.map +1 -0
  82. package/lib/infrastructure/device-certificate.js +47 -0
  83. package/lib/infrastructure/device-certificate.js.map +1 -0
  84. package/lib/infrastructure/device-certificate.test.d.ts +2 -0
  85. package/lib/infrastructure/device-certificate.test.d.ts.map +1 -0
  86. package/lib/infrastructure/device-certificate.test.js +24 -0
  87. package/lib/infrastructure/device-certificate.test.js.map +1 -0
  88. package/lib/infrastructure/legacy-migration/legacy-file.test.d.ts +2 -0
  89. package/lib/infrastructure/legacy-migration/legacy-file.test.d.ts.map +1 -0
  90. package/lib/infrastructure/legacy-migration/legacy-file.test.js +61 -0
  91. package/lib/infrastructure/legacy-migration/legacy-file.test.js.map +1 -0
  92. package/lib/infrastructure/legacy-migration/legacy-files.d.ts +75 -0
  93. package/lib/infrastructure/legacy-migration/legacy-files.d.ts.map +1 -0
  94. package/lib/infrastructure/legacy-migration/legacy-files.js +75 -0
  95. package/lib/infrastructure/legacy-migration/legacy-files.js.map +1 -0
  96. package/lib/infrastructure/legacy-migration/legacy-migration.d.ts +6 -0
  97. package/lib/infrastructure/legacy-migration/legacy-migration.d.ts.map +1 -0
  98. package/lib/infrastructure/legacy-migration/legacy-migration.js +149 -0
  99. package/lib/infrastructure/legacy-migration/legacy-migration.js.map +1 -0
  100. package/lib/infrastructure/legacy-migration/legacy-migration.test.d.ts +2 -0
  101. package/lib/infrastructure/legacy-migration/legacy-migration.test.d.ts.map +1 -0
  102. package/lib/infrastructure/legacy-migration/legacy-migration.test.js +226 -0
  103. package/lib/infrastructure/legacy-migration/legacy-migration.test.js.map +1 -0
  104. package/lib/infrastructure/require-files-present-ready.test.d.ts +2 -0
  105. package/lib/infrastructure/require-files-present-ready.test.d.ts.map +1 -0
  106. package/lib/infrastructure/require-files-present-ready.test.js +44 -0
  107. package/lib/infrastructure/require-files-present-ready.test.js.map +1 -0
  108. package/lib/infrastructure/required-config-checks.d.ts +2 -0
  109. package/lib/infrastructure/required-config-checks.d.ts.map +1 -0
  110. package/lib/infrastructure/required-config-checks.js +30 -0
  111. package/lib/infrastructure/required-config-checks.js.map +1 -0
  112. package/lib/infrastructure/tokens-and-device-cfg.d.ts.map +1 -1
  113. package/lib/infrastructure/tokens-and-device-cfg.js +11 -8
  114. package/lib/infrastructure/tokens-and-device-cfg.js.map +1 -1
  115. package/lib/local-connection/rabbitmq-connection.d.ts.map +1 -1
  116. package/lib/local-connection/rabbitmq-connection.js +14 -14
  117. package/lib/local-connection/rabbitmq-connection.js.map +1 -1
  118. package/lib/secure-tunneling/secure-tunneling.d.ts +9 -9
  119. package/lib/secure-tunneling/secure-tunneling.d.ts.map +1 -1
  120. package/lib/secure-tunneling/secure-tunneling.js +21 -16
  121. package/lib/secure-tunneling/secure-tunneling.js.map +1 -1
  122. package/lib/secure-tunneling/secure-tunneling.test.js +11 -13
  123. package/lib/secure-tunneling/secure-tunneling.test.js.map +1 -1
  124. package/lib/subcommands/app/analytics.d.ts.map +1 -1
  125. package/lib/subcommands/app/analytics.js +1 -2
  126. package/lib/subcommands/app/analytics.js.map +1 -1
  127. package/lib/subcommands/app/env-vars.d.ts +4 -0
  128. package/lib/subcommands/app/env-vars.d.ts.map +1 -1
  129. package/lib/subcommands/app/env-vars.js +52 -6
  130. package/lib/subcommands/app/env-vars.js.map +1 -1
  131. package/lib/subcommands/app/index.d.ts.map +1 -1
  132. package/lib/subcommands/app/index.js +1 -3
  133. package/lib/subcommands/app/index.js.map +1 -1
  134. package/lib/subcommands/app/models.d.ts +0 -11
  135. package/lib/subcommands/app/models.d.ts.map +1 -1
  136. package/lib/subcommands/app/models.js +2 -58
  137. package/lib/subcommands/app/models.js.map +1 -1
  138. package/lib/subcommands/app/shadow.d.ts.map +1 -1
  139. package/lib/subcommands/app/shadow.js +6 -5
  140. package/lib/subcommands/app/shadow.js.map +1 -1
  141. package/lib/subcommands/app/version.d.ts.map +1 -1
  142. package/lib/subcommands/app/version.js +2 -4
  143. package/lib/subcommands/app/version.js.map +1 -1
  144. package/lib/subcommands/config.d.ts +2 -0
  145. package/lib/subcommands/config.d.ts.map +1 -0
  146. package/lib/subcommands/config.js +39 -0
  147. package/lib/subcommands/config.js.map +1 -0
  148. package/lib/subcommands/device/clean.d.ts +1 -1
  149. package/lib/subcommands/device/clean.d.ts.map +1 -1
  150. package/lib/subcommands/device/clean.js +23 -13
  151. package/lib/subcommands/device/clean.js.map +1 -1
  152. package/lib/subcommands/device/index.d.ts.map +1 -1
  153. package/lib/subcommands/device/index.js +3 -1
  154. package/lib/subcommands/device/index.js.map +1 -1
  155. package/lib/subcommands/device/init.js +8 -8
  156. package/lib/subcommands/device/init.js.map +1 -1
  157. package/lib/subcommands/device/migrate.d.ts +2 -0
  158. package/lib/subcommands/device/migrate.d.ts.map +1 -0
  159. package/lib/subcommands/device/migrate.js +24 -0
  160. package/lib/subcommands/device/migrate.js.map +1 -0
  161. package/lib/subcommands/device/refresh.d.ts.map +1 -1
  162. package/lib/subcommands/device/refresh.js +1 -0
  163. package/lib/subcommands/device/refresh.js.map +1 -1
  164. package/lib/subcommands/index.d.ts +1 -1
  165. package/lib/subcommands/index.d.ts.map +1 -1
  166. package/lib/subcommands/index.js +3 -1
  167. package/lib/subcommands/index.js.map +1 -1
  168. package/lib/subcommands/rabbitmq-connection.d.ts +1 -1
  169. package/lib/subcommands/rabbitmq-connection.d.ts.map +1 -1
  170. package/lib/util/aai-error.d.ts +12 -0
  171. package/lib/util/aai-error.d.ts.map +1 -0
  172. package/lib/util/aai-error.js +11 -0
  173. package/lib/util/aai-error.js.map +1 -0
  174. package/lib/util/aws-regions.d.ts +2 -0
  175. package/lib/util/aws-regions.d.ts.map +1 -0
  176. package/lib/util/{cloud-mode-ready.js → aws-regions.js} +2 -20
  177. package/lib/util/aws-regions.js.map +1 -0
  178. package/lib/util/check-for-updates.d.ts.map +1 -1
  179. package/lib/util/check-for-updates.js +5 -28
  180. package/lib/util/check-for-updates.js.map +1 -1
  181. package/lib/util/clean-certs.d.ts.map +1 -1
  182. package/lib/util/clean-certs.js +5 -4
  183. package/lib/util/clean-certs.js.map +1 -1
  184. package/lib/util/directories.d.ts +4 -18
  185. package/lib/util/directories.d.ts.map +1 -1
  186. package/lib/util/directories.js +18 -32
  187. package/lib/util/directories.js.map +1 -1
  188. package/lib/util/file.d.ts +4 -0
  189. package/lib/util/file.d.ts.map +1 -1
  190. package/lib/util/file.js +65 -4
  191. package/lib/util/file.js.map +1 -1
  192. package/lib/util/get-device-id.d.ts.map +1 -1
  193. package/lib/util/get-device-id.js +7 -1
  194. package/lib/util/get-device-id.js.map +1 -1
  195. package/lib/util/http-client.js +3 -3
  196. package/lib/util/http-client.js.map +1 -1
  197. package/package.json +19 -17
  198. package/readme.md +12 -32
  199. package/src/application-control/config.ts +9 -12
  200. package/src/application-control/environment-variables.test.ts +28 -7
  201. package/src/application-control/environment-variables.ts +13 -40
  202. package/src/application-control/index.ts +3 -16
  203. package/src/application-control/install.ts +15 -10
  204. package/src/application-control/models.ts +6 -87
  205. package/src/application-control/utils.ts +0 -28
  206. package/src/cloud-connection/bootstrap-provision.ts +7 -7
  207. package/src/cloud-connection/device-agent-cloud-connection.ts +639 -525
  208. package/src/cloud-connection/device-agent.ts +16 -7
  209. package/src/cloud-connection/live-updates-handler.test.ts +121 -189
  210. package/src/cloud-connection/live-updates-handler.ts +99 -234
  211. package/src/cloud-connection/passthrough-handler.ts +55 -18
  212. package/src/cloud-connection/shadow-handler.test.ts +45 -57
  213. package/src/cloud-connection/shadow-handler.ts +103 -57
  214. package/src/cloud-connection/shadow.ts +4 -1
  215. package/src/cloud-connection/transaction-manager.test.ts +3 -3
  216. package/src/cloud-connection/transaction-manager.ts +53 -39
  217. package/src/device-control/device-control.ts +102 -70
  218. package/src/docker/docker-compose.ts +3 -2
  219. package/src/infrastructure/agent-config.test.ts +6 -2
  220. package/src/infrastructure/agent-config.ts +8 -7
  221. package/src/infrastructure/config-check-utility.test.ts +154 -0
  222. package/src/infrastructure/config-check-utility.ts +77 -0
  223. package/src/infrastructure/device-certificate.test.ts +40 -0
  224. package/src/infrastructure/device-certificate.ts +58 -0
  225. package/src/infrastructure/legacy-migration/legacy-file.test.ts +88 -0
  226. package/src/infrastructure/legacy-migration/legacy-files.ts +101 -0
  227. package/src/infrastructure/legacy-migration/legacy-migration.test.ts +396 -0
  228. package/src/infrastructure/legacy-migration/legacy-migration.ts +229 -0
  229. package/src/infrastructure/require-files-present-ready.test.ts +53 -0
  230. package/src/infrastructure/required-config-checks.ts +33 -0
  231. package/src/infrastructure/tokens-and-device-cfg.ts +12 -10
  232. package/src/local-connection/rabbitmq-connection.ts +22 -17
  233. package/src/secure-tunneling/secure-tunneling.test.ts +20 -22
  234. package/src/secure-tunneling/secure-tunneling.ts +41 -29
  235. package/src/subcommands/app/analytics.ts +2 -4
  236. package/src/subcommands/app/env-vars.ts +72 -9
  237. package/src/subcommands/app/index.ts +3 -11
  238. package/src/subcommands/app/models.ts +5 -81
  239. package/src/subcommands/app/shadow.ts +6 -5
  240. package/src/subcommands/app/version.ts +3 -4
  241. package/src/subcommands/config.ts +42 -0
  242. package/src/subcommands/device/clean.ts +31 -17
  243. package/src/subcommands/device/index.ts +3 -1
  244. package/src/subcommands/device/init.ts +11 -11
  245. package/src/subcommands/device/migrate.ts +20 -0
  246. package/src/subcommands/device/refresh.ts +1 -0
  247. package/src/subcommands/index.ts +3 -1
  248. package/src/util/aai-error.ts +20 -0
  249. package/src/util/{cloud-mode-ready.ts → aws-regions.ts} +0 -24
  250. package/src/util/check-for-updates.ts +14 -30
  251. package/src/util/clean-certs.ts +8 -4
  252. package/src/util/directories.ts +23 -67
  253. package/src/util/file.ts +83 -3
  254. package/src/util/get-device-id.ts +7 -7
  255. package/src/util/http-client.ts +2 -2
  256. package/lib/util/cloud-mode-ready.d.ts +0 -3
  257. package/lib/util/cloud-mode-ready.d.ts.map +0 -1
  258. package/lib/util/cloud-mode-ready.js.map +0 -1
  259. package/lib/util/download-file.d.ts +0 -6
  260. package/lib/util/download-file.d.ts.map +0 -1
  261. package/lib/util/download-file.js +0 -25
  262. package/lib/util/download-file.js.map +0 -1
  263. package/lib/util/fetch-with-timeout.d.ts +0 -4
  264. package/lib/util/fetch-with-timeout.d.ts.map +0 -1
  265. package/lib/util/fetch-with-timeout.js +0 -30
  266. package/lib/util/fetch-with-timeout.js.map +0 -1
  267. package/lib/util/parsing.d.ts +0 -2
  268. package/lib/util/parsing.d.ts.map +0 -1
  269. package/lib/util/parsing.js +0 -17
  270. package/lib/util/parsing.js.map +0 -1
  271. package/src/util/download-file.ts +0 -25
  272. package/src/util/fetch-with-timeout.ts +0 -35
  273. package/src/util/parsing.ts +0 -11
@@ -68,13 +68,11 @@ describe('Test Shadow Handler', () => {
68
68
 
69
69
  test('handle project shadow empty delta', async () => {
70
70
  const payload = {
71
- desired: {
72
- [projectId1]: {}
73
- }
71
+ [projectId1]: {}
74
72
  };
75
73
 
76
74
  const updates = await shadowHandler.handleProjectShadow({
77
- topic: getShadowTopic(clientId, 'projects', 'update/accepted'),
75
+ topic: getShadowTopic(clientId, 'projects', 'update/delta'),
78
76
  payload,
79
77
  clientToken: ''
80
78
  });
@@ -104,16 +102,14 @@ describe('Test Shadow Handler', () => {
104
102
 
105
103
  const payload = {
106
104
  state: {
107
- desired: {
108
- [projectId1]: {
109
- appConfig: JSON.stringify(appCfg1)
110
- }
105
+ [projectId1]: {
106
+ appConfig: JSON.stringify(appCfg1)
111
107
  }
112
108
  }
113
109
  };
114
110
 
115
111
  const updates = await shadowHandler.handleProjectShadow({
116
- topic: getShadowTopic(clientId, 'projects', 'update/accepted'),
112
+ topic: getShadowTopic(clientId, 'projects', 'update/delta'),
117
113
  payload,
118
114
  clientToken: ''
119
115
  });
@@ -153,16 +149,14 @@ describe('Test Shadow Handler', () => {
153
149
 
154
150
  const payload = {
155
151
  state: {
156
- desired: {
157
- [projectId1]: {
158
- appConfig: JSON.stringify(appCfg1)
159
- }
152
+ [projectId1]: {
153
+ appConfig: JSON.stringify(appCfg1)
160
154
  }
161
155
  }
162
156
  };
163
157
 
164
158
  const updates = await shadowHandler.handleProjectShadow({
165
- topic: getShadowTopic(clientId, 'projects', 'update/accepted'),
159
+ topic: getShadowTopic(clientId, 'projects', 'update/delta'),
166
160
  payload,
167
161
  clientToken: ''
168
162
  });
@@ -220,19 +214,17 @@ describe('Test Shadow Handler', () => {
220
214
  };
221
215
  const payload = {
222
216
  state: {
223
- desired: {
224
- [projectId1]: {
225
- appConfig: JSON.stringify(appCfg1)
226
- },
227
- [projectId2]: {
228
- appConfig: JSON.stringify(appCfg2)
229
- }
217
+ [projectId1]: {
218
+ appConfig: JSON.stringify(appCfg1)
219
+ },
220
+ [projectId2]: {
221
+ appConfig: JSON.stringify(appCfg2)
230
222
  }
231
223
  }
232
224
  };
233
225
 
234
226
  const updates = await shadowHandler.handleProjectShadow({
235
- topic: getShadowTopic(clientId, 'projects', 'update/accepted'),
227
+ topic: getShadowTopic(clientId, 'projects', 'update/delta'),
236
228
  payload,
237
229
  clientToken: ''
238
230
  });
@@ -281,16 +273,14 @@ describe('Test Shadow Handler', () => {
281
273
 
282
274
  const payload = {
283
275
  state: {
284
- desired: {
285
- [projectId1]: {
286
- appConfig: JSON.stringify(appCfg1)
287
- }
276
+ [projectId1]: {
277
+ appConfig: JSON.stringify(appCfg1)
288
278
  }
289
279
  }
290
280
  };
291
281
 
292
282
  const updates = await shadowHandler.handleProjectShadow({
293
- topic: getShadowTopic(clientId, 'projects', 'update/accepted'),
283
+ topic: getShadowTopic(clientId, 'projects', 'update/delta'),
294
284
  payload,
295
285
  clientToken: ''
296
286
  });
@@ -365,10 +355,8 @@ describe('Test Shadow Handler', () => {
365
355
 
366
356
  const payload = {
367
357
  state: {
368
- desired: {
369
- [projectId1]: {
370
- appConfig: appCfg1 // This is missing JSON.stringify() making this an unparsable object.
371
- }
358
+ [projectId1]: {
359
+ appConfig: appCfg1 // This is missing JSON.stringify() making this an unparsable object.
372
360
  }
373
361
  }
374
362
  };
@@ -378,7 +366,7 @@ describe('Test Shadow Handler', () => {
378
366
  .mockReturnValue({} as unknown as Logger);
379
367
 
380
368
  const updates = await shadowHandler.handleProjectShadow({
381
- topic: getShadowTopic(clientId, 'projects', 'update/accepted'),
369
+ topic: getShadowTopic(clientId, 'projects', 'update/delta'),
382
370
  payload,
383
371
  clientToken: ''
384
372
  });
@@ -393,13 +381,15 @@ describe('Test Shadow Handler', () => {
393
381
  describe('handle project shadow env vars', () => {
394
382
  test('handle a response from the getAccepted from the cloud', async () => {
395
383
  const envVars1 = {
396
- VAR0: 'value0'
384
+ service: {
385
+ VAR0: 'value0'
386
+ }
397
387
  };
398
388
  const payload = {
399
389
  state: {
400
390
  reported: {
401
391
  [projectId1]: {
402
- envVars: { service: envVars1 }
392
+ envVars: JSON.stringify(envVars1)
403
393
  }
404
394
  }
405
395
  }
@@ -414,22 +404,20 @@ describe('Test Shadow Handler', () => {
414
404
  });
415
405
  test('handle project shadow env vars update delta', async () => {
416
406
  const envVars1 = {
417
- VAR1: 'value1'
407
+ service: {
408
+ VAR1: 'value1'
409
+ }
418
410
  };
419
411
  const payload = {
420
412
  state: {
421
- desired: {
422
- [projectId1]: {
423
- envVars: {
424
- service: envVars1
425
- }
426
- }
413
+ [projectId1]: {
414
+ envVars: JSON.stringify(envVars1)
427
415
  }
428
416
  }
429
417
  };
430
418
 
431
419
  const updates = await shadowHandler.handleProjectShadow({
432
- topic: getShadowTopic(clientId, 'projects', 'update/accepted'),
420
+ topic: getShadowTopic(clientId, 'projects', 'update/delta'),
433
421
  payload,
434
422
  clientToken: ''
435
423
  });
@@ -438,36 +426,36 @@ describe('Test Shadow Handler', () => {
438
426
  projectId: projectId1,
439
427
  txId: expect.any(String),
440
428
  envVarUpdate: {
441
- envVars: { service: envVars1 }
429
+ envVars: envVars1
442
430
  }
443
431
  });
444
432
  });
445
433
 
446
434
  test('handle project shadow env vars update delta for two projects', async () => {
447
435
  const service1 = {
448
- VAR1: 'value1'
436
+ service: {
437
+ VAR1: 'value1'
438
+ }
449
439
  };
450
440
  const service2 = {
451
- VAR2: 'value2'
441
+ service: {
442
+ VAR2: 'value2'
443
+ }
452
444
  };
453
445
 
454
446
  const payload = {
455
447
  state: {
456
- desired: {
457
- [projectId1]: {
458
- envVars: {
459
- service: service1
460
- }
461
- },
462
- [projectId2]: {
463
- envVars: { service: service2 }
464
- }
448
+ [projectId1]: {
449
+ envVars: JSON.stringify(service1)
450
+ },
451
+ [projectId2]: {
452
+ envVars: JSON.stringify(service2)
465
453
  }
466
454
  }
467
455
  };
468
456
 
469
457
  const updates = await shadowHandler.handleProjectShadow({
470
- topic: getShadowTopic(clientId, 'projects', 'update/accepted'),
458
+ topic: getShadowTopic(clientId, 'projects', 'update/delta'),
471
459
  payload,
472
460
  clientToken: ''
473
461
  });
@@ -476,14 +464,14 @@ describe('Test Shadow Handler', () => {
476
464
  projectId: projectId1,
477
465
  txId: expect.any(String),
478
466
  envVarUpdate: {
479
- envVars: { service: service1 }
467
+ envVars: service1
480
468
  }
481
469
  });
482
470
  expect(updates[1]).toEqual({
483
471
  projectId: projectId2,
484
472
  txId: expect.any(String),
485
473
  envVarUpdate: {
486
- envVars: { service: service2 }
474
+ envVars: service2
487
475
  }
488
476
  });
489
477
  });
@@ -3,28 +3,27 @@ import {
3
3
  validateAppConfig
4
4
  } from '@alwaysai/app-configuration-schemas';
5
5
  import {
6
+ buildUpdateShadowMessage,
6
7
  EnvVars,
7
- getAllEnvs,
8
- readAppCfgFile,
9
- setEnv
10
- } from '../application-control';
11
- import { getSystemInformation } from '../device-control/device-control';
12
- import { logger } from '../util/logger';
13
- import { Publisher } from './publisher';
14
- import { AppConfigModels, getAppCfgModelsDiff } from './shadow';
15
- import {
16
8
  generateTxId,
17
- validateProjectShadowUpdate,
18
- buildBaseShadowMessage,
19
- buildUpdateProjectShadowMessage,
20
- buildUpdateSystemInfoShadowMessage,
21
9
  getShadowTopic,
22
- ShadowProjectsUpdateAll,
23
- getDesiredFromMessage,
10
+ getUpdateDeltaStateFromMessage,
24
11
  ProjectShadowUpdate,
25
- buildUpdateSecureTunnelShadowMessage,
26
- SecureTunnelShadowDescriptionReported
12
+ SecureTunnelShadowUpdate,
13
+ validateEnvVarSchemaShadowUpdate,
14
+ validateProjectShadowUpdate
27
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';
23
+ import { getSystemInformation } from '../device-control/device-control';
24
+ import { logger } from '../util/logger';
25
+ import { Publisher } from './publisher';
26
+ import { AppConfigModels, getAppCfgModelsDiff } from './shadow';
28
27
 
29
28
  export type AppConfigUpdate = {
30
29
  newAppCfg: AppConfig;
@@ -112,9 +111,11 @@ export class ShadowHandler {
112
111
  // Handle errors and validation
113
112
  try {
114
113
  newAppCfg = JSON.parse(appConfig);
115
- } catch (error) {
114
+ } catch (e) {
116
115
  logger.error(
117
- `Could not parse the appConfig for transaction ${txId}!\n${error}`
116
+ `Could not parse the appConfig for transaction ${txId}!\n${stringifyError(
117
+ e
118
+ )}`
118
119
  );
119
120
  return null;
120
121
  }
@@ -145,6 +146,40 @@ export class ShadowHandler {
145
146
  return appCfgUpdate;
146
147
  }
147
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
+
148
183
  private async processProjectShadowUpdates({
149
184
  delta
150
185
  }: {
@@ -218,7 +253,14 @@ export class ShadowHandler {
218
253
  `Found a delta for app environment variable shadow. Updating ${projectId}`
219
254
  );
220
255
  const envVars = projectDelta.envVars;
221
- shadowUpdate.envVarUpdate = { envVars };
256
+ const envVarsUpdate = await this.generateEnvVarsUpdate({
257
+ envVars,
258
+ txId,
259
+ projectId
260
+ });
261
+ if (envVarsUpdate) {
262
+ shadowUpdate.envVarUpdate = envVarsUpdate;
263
+ }
222
264
  }
223
265
 
224
266
  return shadowUpdate.appCfgUpdate || shadowUpdate.envVarUpdate
@@ -242,24 +284,14 @@ export class ShadowHandler {
242
284
  throw Error(`Topic ${topic} is not in the ${this.projectShadowTopics}`);
243
285
  }
244
286
  switch (topic) {
245
- case this.shadowTopics.project.updateAccepted: {
246
- if (clientToken === this.clientId) {
247
- logger.debug(
248
- `Ignoring message as it was caused by Device Agent itself: ${JSON.stringify(
249
- { topic, payload },
250
- null,
251
- 2
252
- )}`
253
- );
254
- break;
255
- }
256
- const desired = getDesiredFromMessage(payload);
257
- if (!desired) {
287
+ case this.shadowTopics.project.updateDelta: {
288
+ const delta = getUpdateDeltaStateFromMessage(payload);
289
+ if (!delta) {
258
290
  logger.debug(
259
- `No desired state found in message: ${JSON.stringify(payload)}`
291
+ `No delta state found in message: ${JSON.stringify(payload)}`
260
292
  );
261
293
  } else {
262
- return await this.processProjectShadowUpdates({ delta: desired });
294
+ return await this.processProjectShadowUpdates({ delta });
263
295
  }
264
296
  break;
265
297
  }
@@ -274,21 +306,18 @@ export class ShadowHandler {
274
306
  );
275
307
  break;
276
308
  }
277
- if (payload.state.delta) {
278
- return await this.processProjectShadowUpdates({
279
- delta: payload.state.delta
280
- });
281
- } else {
282
- logger.info(
283
- `No delta in projects.getAccepted in named shadow '${
284
- topic.split('/')[5]
285
- }'`
309
+ const delta = getUpdateDeltaStateFromMessage(payload);
310
+ if (!delta) {
311
+ logger.debug(
312
+ `No delta state found in message: ${JSON.stringify(payload)}`
286
313
  );
314
+ } else {
315
+ return await this.processProjectShadowUpdates({ delta });
287
316
  }
288
317
  break;
289
318
  }
290
319
  case this.shadowTopics.project.getRejected:
291
- case this.shadowTopics.project.updateDelta:
320
+ case this.shadowTopics.project.updateAccepted:
292
321
  case this.shadowTopics.project.updateRejected: {
293
322
  // Not handling these for now
294
323
  break;
@@ -310,7 +339,10 @@ export class ShadowHandler {
310
339
  this.publisher.publish(
311
340
  getShadowTopic(this.clientId, 'system-info', 'update'),
312
341
  JSON.stringify(
313
- buildUpdateSystemInfoShadowMessage(this.clientId, systemInfo)
342
+ buildUpdateShadowMessage({
343
+ clientId: this.clientId,
344
+ reported: systemInfo
345
+ })
314
346
  )
315
347
  );
316
348
  }
@@ -322,13 +354,13 @@ export class ShadowHandler {
322
354
  const toReport: ShadowProjectsUpdateAll = {
323
355
  [projectId]: {
324
356
  appConfig: JSON.stringify(appCfg),
325
- envVars
357
+ envVars: JSON.stringify(envVars)
326
358
  }
327
359
  };
328
360
  this.publisher.publish(
329
361
  getShadowTopic(this.clientId, 'projects', 'update'),
330
362
  JSON.stringify(
331
- buildUpdateProjectShadowMessage({
363
+ buildUpdateShadowMessage({
332
364
  clientId: this.clientId,
333
365
  reported: toReport
334
366
  })
@@ -344,15 +376,15 @@ export class ShadowHandler {
344
376
  envVars: EnvVars;
345
377
  }) {
346
378
  await setEnv({ projectId, envVars });
347
-
379
+ const currentEnvs = await getAllEnvs({ projectId });
348
380
  this.publisher.publish(
349
381
  getShadowTopic(this.clientId, 'projects', 'update'),
350
382
  JSON.stringify(
351
- buildUpdateProjectShadowMessage({
383
+ buildUpdateShadowMessage({
352
384
  clientId: this.clientId,
353
385
  reported: {
354
386
  [projectId]: {
355
- envVars
387
+ envVars: JSON.stringify(currentEnvs)
356
388
  }
357
389
  }
358
390
  })
@@ -361,15 +393,29 @@ export class ShadowHandler {
361
393
  }
362
394
 
363
395
  public async updateSecureTunnelShadow(
364
- secureTunnelShadowUpdate: SecureTunnelShadowDescriptionReported
396
+ secureTunnelShadowUpdate: SecureTunnelShadowUpdate
365
397
  ) {
366
398
  this.publisher.publish(
367
399
  getShadowTopic(this.clientId, 'secure-tunnel', 'update'),
368
400
  JSON.stringify(
369
- buildUpdateSecureTunnelShadowMessage(
370
- secureTunnelShadowUpdate,
371
- this.clientId
372
- )
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
+ })
373
419
  )
374
420
  );
375
421
  }
@@ -385,7 +431,7 @@ export class ShadowHandler {
385
431
  this.publisher.publish(
386
432
  getShadowTopic(this.clientId, 'projects', 'update'),
387
433
  JSON.stringify(
388
- buildUpdateProjectShadowMessage({
434
+ buildUpdateShadowMessage({
389
435
  clientId: this.clientId,
390
436
  reported: { [projectId]: null },
391
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(`Error parsing app config update: ${e.message}`);
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 };
@@ -15,8 +15,8 @@ const mockClient = {
15
15
  const clientId = 'test-client';
16
16
 
17
17
  const mockLiveUpdatesHandler = {
18
- enableTransactionStatus: jest.fn(),
19
- disableTransactionStatus: jest.fn()
18
+ enable: jest.fn(),
19
+ disable: jest.fn()
20
20
  } as any as LiveUpdatesHandler;
21
21
 
22
22
  describe('Test Transaction Manager', () => {
@@ -188,7 +188,7 @@ describe('Test Transaction Manager', () => {
188
188
  throw new Error('Expected start transaction to fail!');
189
189
  } catch (e) {
190
190
  console.log(e);
191
- expect(e.code).toBe(txnMgr.Errors.PROJECT_ONGOING);
191
+ expect(e.code).toBe(txnMgr.Errors.PROJECT_TRANSACTION_ONGOING);
192
192
  }
193
193
  expect(txnMgr.getTransactionFromProject(projectId)).toEqual(txId);
194
194
  expect(txnMgr.getProjectFromTransaction(txId)).toEqual(projectId);