kuzzle-device-manager 0.4.13 → 2.0.0-rc3

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 (102) hide show
  1. package/index.d.ts +1 -0
  2. package/index.js +6 -1
  3. package/lib/DeviceManagerPlugin.d.ts +33 -65
  4. package/lib/DeviceManagerPlugin.js +142 -131
  5. package/lib/controllers/AssetController.d.ts +20 -5
  6. package/lib/controllers/AssetController.js +78 -23
  7. package/lib/controllers/DecodersController.d.ts +16 -0
  8. package/lib/controllers/DecodersController.js +27 -0
  9. package/lib/controllers/DeviceController.d.ts +25 -22
  10. package/lib/controllers/DeviceController.js +150 -109
  11. package/lib/controllers/index.d.ts +1 -1
  12. package/lib/controllers/index.js +6 -2
  13. package/lib/core-classes/AssetService.d.ts +31 -0
  14. package/lib/core-classes/AssetService.js +82 -0
  15. package/lib/core-classes/Decoder.d.ts +14 -59
  16. package/lib/core-classes/Decoder.js +16 -86
  17. package/lib/core-classes/DeviceManagerEngine.d.ts +11 -9
  18. package/lib/core-classes/DeviceManagerEngine.js +20 -32
  19. package/lib/core-classes/DeviceService.d.ts +81 -24
  20. package/lib/core-classes/DeviceService.js +178 -220
  21. package/lib/core-classes/PayloadService.d.ts +39 -26
  22. package/lib/core-classes/PayloadService.js +132 -124
  23. package/lib/core-classes/index.d.ts +5 -4
  24. package/lib/core-classes/index.js +10 -5
  25. package/lib/core-classes/{CustomMappings/AssetMappingsManager.d.ts → registers/AssetsRegister.d.ts} +8 -9
  26. package/lib/core-classes/{CustomMappings/AssetMappingsManager.js → registers/AssetsRegister.js} +17 -28
  27. package/lib/core-classes/registers/DecodersRegister.d.ts +46 -0
  28. package/lib/core-classes/registers/DecodersRegister.js +167 -0
  29. package/lib/core-classes/registers/DevicesRegister.d.ts +20 -0
  30. package/lib/core-classes/registers/DevicesRegister.js +37 -0
  31. package/lib/core-classes/registers/MeasuresRegister.d.ts +29 -0
  32. package/lib/core-classes/registers/MeasuresRegister.js +53 -0
  33. package/lib/mappings/assetsMappings.d.ts +36 -0
  34. package/lib/mappings/assetsMappings.js +36 -0
  35. package/lib/mappings/deviceMappings.d.ts +44 -0
  36. package/lib/mappings/deviceMappings.js +42 -0
  37. package/lib/mappings/index.d.ts +4 -0
  38. package/lib/mappings/index.js +21 -0
  39. package/lib/mappings/measuresMappings.d.ts +53 -0
  40. package/lib/mappings/measuresMappings.js +48 -0
  41. package/lib/mappings/payloadsMappings.d.ts +18 -0
  42. package/lib/mappings/payloadsMappings.js +16 -0
  43. package/lib/measures/BatteryMeasure.d.ts +7 -0
  44. package/lib/measures/BatteryMeasure.js +12 -0
  45. package/lib/measures/HumidityMeasure.d.ts +7 -0
  46. package/lib/measures/HumidityMeasure.js +12 -0
  47. package/lib/measures/MovementMeasure.d.ts +7 -0
  48. package/lib/measures/MovementMeasure.js +12 -0
  49. package/lib/measures/PositionMeasure.d.ts +12 -0
  50. package/lib/measures/PositionMeasure.js +16 -0
  51. package/lib/measures/TemperatureMeasure.d.ts +7 -0
  52. package/lib/measures/TemperatureMeasure.js +12 -0
  53. package/lib/measures/index.d.ts +5 -0
  54. package/lib/measures/index.js +22 -0
  55. package/lib/models/BaseAsset.d.ts +1 -48
  56. package/lib/models/BaseAsset.js +5 -43
  57. package/lib/models/Config.d.ts +1 -13
  58. package/lib/models/Device.d.ts +5 -96
  59. package/lib/models/Device.js +5 -73
  60. package/lib/models/index.d.ts +0 -1
  61. package/lib/models/index.js +5 -2
  62. package/lib/types/BaseAssetContent.d.ts +8 -3
  63. package/lib/types/DecodedPayload.d.ts +42 -0
  64. package/lib/types/{AssetsHistoryContent.js → DecodedPayload.js} +1 -1
  65. package/lib/types/DecoderContent.d.ts +4 -0
  66. package/lib/types/DecoderContent.js +3 -0
  67. package/lib/types/DeviceContent.d.ts +12 -44
  68. package/lib/types/DeviceManagerConfiguration.d.ts +40 -0
  69. package/lib/types/DeviceManagerConfiguration.js +3 -0
  70. package/lib/types/index.d.ts +7 -2
  71. package/lib/types/index.js +12 -3
  72. package/lib/types/measures/MeasureContent.d.ts +56 -0
  73. package/lib/types/measures/MeasureContent.js +3 -0
  74. package/lib/types/measures/MeasureDefinition.d.ts +40 -0
  75. package/lib/types/measures/MeasureDefinition.js +3 -0
  76. package/lib/types/measures/Measurement.d.ts +19 -0
  77. package/lib/types/{Measure.js → measures/Measurement.js} +1 -1
  78. package/lib/utils/index.d.ts +1 -1
  79. package/lib/utils/index.js +6 -2
  80. package/lib/utils/writeMany.d.ts +13 -0
  81. package/lib/utils/writeMany.js +37 -0
  82. package/package.json +14 -18
  83. package/lib/controllers/CRUDController.d.ts +0 -34
  84. package/lib/controllers/CRUDController.js +0 -65
  85. package/lib/core-classes/BatchProcessing/BatchController.d.ts +0 -34
  86. package/lib/core-classes/BatchProcessing/BatchController.js +0 -115
  87. package/lib/core-classes/BatchProcessing/BatchWriter.d.ts +0 -110
  88. package/lib/core-classes/BatchProcessing/BatchWriter.js +0 -264
  89. package/lib/core-classes/BatchProcessing/InstrumentablePromise.d.ts +0 -6
  90. package/lib/core-classes/BatchProcessing/InstrumentablePromise.js +0 -13
  91. package/lib/core-classes/BatchProcessing/index.d.ts +0 -3
  92. package/lib/core-classes/BatchProcessing/index.js +0 -16
  93. package/lib/core-classes/CustomMappings/DeviceMappingsManager.d.ts +0 -43
  94. package/lib/core-classes/CustomMappings/DeviceMappingsManager.js +0 -71
  95. package/lib/core-classes/MigrationService.d.ts +0 -13
  96. package/lib/core-classes/MigrationService.js +0 -49
  97. package/lib/models/Catalog.d.ts +0 -55
  98. package/lib/models/Catalog.js +0 -38
  99. package/lib/types/AssetsHistoryContent.d.ts +0 -9
  100. package/lib/types/Measure.d.ts +0 -54
  101. package/lib/utils/events.d.ts +0 -8
  102. package/lib/utils/events.js +0 -17
@@ -1,264 +1,222 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.DeviceService = void 0;
4
7
  const kuzzle_1 = require("kuzzle");
8
+ const uuid_1 = require("uuid");
9
+ const lodash_1 = __importDefault(require("lodash"));
10
+ const models_1 = require("../models");
11
+ const utils_1 = require("../utils/");
5
12
  class DeviceService {
6
- constructor(plugin, decoders) {
13
+ constructor(plugin) {
7
14
  this.config = plugin.config;
8
15
  this.context = plugin.context;
9
- this.decoders = decoders;
10
16
  }
11
17
  get sdk() {
12
18
  return this.context.accessors.sdk;
13
19
  }
14
- async mAttach(devices, bulkData, { strict, options }) {
15
- const attachedDevices = devices.filter(device => device._source.tenantId);
16
- if (strict && attachedDevices.length > 0) {
17
- const ids = attachedDevices.map(device => device._id).join(',');
18
- throw new kuzzle_1.BadRequestError(`These devices "${ids}" are already attached to a tenant`);
20
+ /**
21
+ * Create a new device.
22
+ *
23
+ * If the engineId is not the administration one, then the device will be
24
+ * automatically attached to the one provided.
25
+ *
26
+ * If an assetId is provided, then the device will be linked to this asset.
27
+ *
28
+ * @param engineId If it's not the admin engine, then the device will be attached to this one
29
+ * @param deviceContent Content of the device to create
30
+ */
31
+ async create(engineId, deviceContent, assetId, { refresh }) {
32
+ const deviceId = models_1.Device.id(deviceContent.model, deviceContent.reference);
33
+ const device = await this.sdk.document.create(this.config.adminIndex, 'devices', deviceContent, deviceId, { refresh });
34
+ if (this.config.adminIndex === engineId) {
35
+ return device;
19
36
  }
20
- const documents = this.buildBulkDevices(bulkData);
21
- const results = {
22
- errors: [],
23
- successes: [],
24
- };
25
- for (let i = 0; i < documents.length; i++) {
26
- const document = documents[i];
27
- const tenantExists = await this.tenantExists(document.tenantId);
28
- if (strict && !tenantExists) {
29
- throw new kuzzle_1.BadRequestError(`Tenant "${document.tenantId}" does not have a device-manager engine`);
30
- }
31
- else if (!strict && !tenantExists) {
32
- results.errors.push(`Tenant "${document.tenantId}" does not have a device-manager engine`);
33
- continue;
34
- }
35
- const deviceDocuments = this.formatDevicesContent(devices, document);
36
- const { errors, successes } = await this.writeToDatabase(deviceDocuments, async (deviceDocuments) => {
37
- const updated = await this.sdk.document.mUpdate(this.config.adminIndex, 'devices', deviceDocuments, { strict, refresh: options.refresh });
38
- await this.sdk.document.mCreate(document.tenantId, 'devices', deviceDocuments, { strict, refresh: options.refresh });
39
- return {
40
- successes: results.successes.concat(updated.successes),
41
- errors: results.errors.concat(updated.errors)
42
- };
43
- });
44
- results.successes.concat(successes);
45
- results.errors.concat(errors);
37
+ const attachedDevice = await this.attachEngine({ deviceId, engineId }, { refresh, strict: true });
38
+ if (!assetId) {
39
+ return attachedDevice;
46
40
  }
47
- return results;
41
+ const { device: linkedDevice } = await this.linkAsset({ assetId, deviceId }, { refresh });
42
+ return linkedDevice;
48
43
  }
49
- async mDetach(devices, bulkData, { strict, options }) {
50
- const detachedDevices = devices.filter(device => {
51
- return !device._source.tenantId || device._source.tenantId === null;
52
- });
53
- if (strict && detachedDevices.length > 0) {
54
- const ids = detachedDevices.map(device => device._id).join(',');
55
- throw new kuzzle_1.BadRequestError(`Devices "${ids}" are not attached to a tenant`);
44
+ async attachEngine(attachRequest, { refresh, strict }) {
45
+ const device = await this.getDevice(attachRequest.deviceId);
46
+ if (strict && device._source.engineId) {
47
+ throw new kuzzle_1.BadRequestError(`Device "${device._id}" is already attached to an engine.`);
56
48
  }
57
- const linkedAssets = devices.filter(device => device._source.assetId);
58
- if (strict && linkedAssets.length > 0) {
59
- const ids = linkedAssets.map(device => device._id).join(',');
60
- throw new kuzzle_1.BadRequestError(`Devices "${ids}" are still linked to an asset`);
49
+ if (!await this.tenantExists(attachRequest.engineId)) {
50
+ throw new kuzzle_1.BadRequestError(`Engine "${attachRequest.engineId}" does not exists.`);
61
51
  }
62
- const builder = bulkData.map(data => {
63
- const { deviceId } = data;
64
- const device = devices.find(s => s._id === deviceId);
65
- return { tenantId: device._source.tenantId, deviceId };
52
+ device._source.engineId = attachRequest.engineId;
53
+ const response = await global.app.trigger('device-manager:device:attach-engine:before', {
54
+ device,
55
+ engineId: attachRequest.engineId,
66
56
  });
67
- const documents = this.buildBulkDevices(builder);
68
- const results = {
69
- errors: [],
70
- successes: [],
71
- };
72
- for (let i = 0; i < documents.length; i++) {
73
- const document = documents[i];
74
- const devicesContent = devices.filter(({ _id }) => document.deviceIds.includes(_id));
75
- const deviceDocuments = devicesContent.map(device => {
76
- return { _id: device._id, body: { tenantId: null } };
77
- });
78
- const { errors, successes } = await this.writeToDatabase(deviceDocuments, async (deviceDocuments) => {
79
- const updated = await this.sdk.document.mUpdate(this.config.adminIndex, 'devices', deviceDocuments, { strict, refresh: options.refresh });
80
- await this.sdk.document.mDelete(document.tenantId, 'devices', deviceDocuments.map(device => device._id), { strict, refresh: options.refresh });
81
- return {
82
- successes: results.successes.concat(updated.successes),
83
- errors: results.errors.concat(updated.errors)
84
- };
85
- });
86
- results.successes.concat(successes);
87
- results.errors.concat(errors);
57
+ await Promise.all([
58
+ this.sdk.document.update(this.config.adminIndex, 'devices', response.device._id, { engineId: response.device._source.engineId }, { refresh }),
59
+ this.sdk.document.createOrReplace(response.device._source.engineId, 'devices', response.device._id, response.device._source, { refresh }),
60
+ ]);
61
+ await global.app.trigger('device-manager:device:attach-engine:after', {
62
+ device,
63
+ engineId: attachRequest.engineId,
64
+ });
65
+ return device;
66
+ }
67
+ async detachEngine(deviceId, { refresh, strict }) {
68
+ const device = await this.getDevice(deviceId);
69
+ const engineId = device._source.engineId;
70
+ if (strict && !engineId) {
71
+ throw new kuzzle_1.BadRequestError(`Device "${device._id}" is not attached to an engine.`);
88
72
  }
89
- return results;
73
+ if (device._source.assetId) {
74
+ throw new kuzzle_1.BadRequestError(`Device "${device._id}" is still linked to an asset.`);
75
+ }
76
+ const response = await global.app.trigger('device-manager:device:detach-engine:before', {
77
+ device,
78
+ engineId,
79
+ });
80
+ await Promise.all([
81
+ this.sdk.document.update(this.config.adminIndex, 'devices', device._id, { engineId: null }, { refresh }),
82
+ this.sdk.document.delete(response.engineId, 'devices', device._id, { refresh }),
83
+ ]);
84
+ await global.app.trigger('device-manager:device:detach-engine:after', {
85
+ device,
86
+ engineId,
87
+ });
88
+ return device;
90
89
  }
91
- async mLink(devices, bulkData, { strict, options }) {
92
- const detachedDevices = devices.filter(device => {
93
- return !device._source.tenantId || device._source.tenantId === null;
90
+ /**
91
+ * Link a device to an asset and copy device measures into the asset.
92
+ *
93
+ * Each measures will be given a distinct name when copied into the asset
94
+ */
95
+ async linkAsset(linkRequest, { refresh }) {
96
+ const device = await this.getDevice(linkRequest.deviceId);
97
+ const engineId = device._source.engineId;
98
+ if (!engineId) {
99
+ throw new kuzzle_1.BadRequestError(`Device "${device._id}" is not attached to an engine.`);
100
+ }
101
+ if (device._source.assetId) {
102
+ throw new kuzzle_1.BadRequestError(`Device "${device._id}" is already linked to an asset.`);
103
+ }
104
+ const asset = await this.getAsset(linkRequest.assetId, engineId);
105
+ if (!lodash_1.default.isArray(asset._source.measures)) {
106
+ throw new kuzzle_1.BadRequestError(`Asset "${linkRequest.assetId}" measures property is not an array.`);
107
+ }
108
+ // Copy device measures and assign measures names
109
+ const measures = (device._source.measures || []).map(measure => {
110
+ const name = lodash_1.default.get(linkRequest, `measuresNames.${measure.type}`, measure.type);
111
+ return { ...measure, name };
94
112
  });
95
- if (strict && detachedDevices.length > 0) {
96
- const ids = detachedDevices.map(device => device._id).join(',');
97
- throw new kuzzle_1.PreconditionError(`Devices "${ids}" are not attached to a tenant`);
113
+ const newMeasuresNames = measures.map(m => m.name);
114
+ const duplicateMeasure = asset._source.measures.find(m => newMeasuresNames.includes(m.name));
115
+ if (duplicateMeasure) {
116
+ throw new kuzzle_1.BadRequestError(`Duplicate measure name "${duplicateMeasure.name}"`);
117
+ }
118
+ // Keep previous asset measures of different types
119
+ for (const previousMeasure of asset._source.measures) {
120
+ if (!measures.find(m => m.name === previousMeasure.name)) {
121
+ measures.push(previousMeasure);
122
+ }
123
+ }
124
+ asset._source.measures = measures;
125
+ device._source.assetId = linkRequest.assetId;
126
+ const response = await global.app.trigger('device-manager:device:link-asset:before', { asset, device });
127
+ await Promise.all([
128
+ this.sdk.document.update(this.config.adminIndex, 'devices', device._id, { assetId: response.device._source.assetId }, { refresh }),
129
+ this.sdk.document.update(engineId, 'devices', device._id, { assetId: response.device._source.assetId }, { refresh }),
130
+ this.sdk.document.update(engineId, 'assets', asset._id, { measures: response.asset._source.measures }, { refresh }),
131
+ ]);
132
+ await global.app.trigger('device-manager:device:link-asset:after', { asset, device });
133
+ return { asset, device };
134
+ }
135
+ async unlinkAsset(deviceId, { refresh, strict }) {
136
+ const device = await this.getDevice(deviceId);
137
+ const engineId = device._source.engineId;
138
+ if (strict && !engineId) {
139
+ throw new kuzzle_1.BadRequestError(`Device "${device._id}" is not attached to an engine.`);
140
+ }
141
+ if (!device._source.assetId) {
142
+ throw new kuzzle_1.BadRequestError(`Device "${device._id}" is not linked to an asset.`);
98
143
  }
99
- const builder = bulkData.map(data => {
100
- const { deviceId, assetId } = data;
101
- const device = devices.find(s => s._id === deviceId);
102
- return { tenantId: device._source.tenantId, deviceId, assetId };
144
+ const asset = await this.getAsset(device._source.assetId, engineId);
145
+ // @todo should be done by measure name and not type
146
+ asset._source.measures = asset._source.measures.filter(m => {
147
+ return !device._source.measures.find(dm => dm.type === m.type);
103
148
  });
104
- const documents = this.buildBulkDevices(builder);
149
+ device._source.assetId = null;
150
+ const response = await global.app.trigger('device-manager:device:unlink-asset:before', { asset, device });
151
+ await Promise.all([
152
+ this.sdk.document.update(this.config.adminIndex, 'devices', device._id, { assetId: null }, { refresh }),
153
+ this.sdk.document.update(engineId, 'devices', device._id, { assetId: null }, { refresh }),
154
+ this.sdk.document.update(engineId, 'assets', asset._id, { measures: response.asset._source.measures }, { refresh }),
155
+ ]);
156
+ await global.app.trigger('device-manager:device:unlink-asset:before', { asset, device });
157
+ return { asset, device };
158
+ }
159
+ async importDevices(devices, { refresh, strict }) {
105
160
  const results = {
106
161
  errors: [],
107
162
  successes: [],
108
163
  };
109
- for (let i = 0; i < documents.length; i++) {
110
- const document = documents[i];
111
- const existingAssets = await this.sdk.document.mGet(document.tenantId, 'assets', document.assetIds);
112
- if (strict && existingAssets.errors.length > 0) {
113
- throw new kuzzle_1.NotFoundError(`Assets "${existingAssets.errors}" do not exist`);
114
- }
115
- const devicesContent = devices.filter(({ _id }) => document.deviceIds.includes(_id));
116
- const deviceDocuments = [];
117
- const assetDocuments = [];
118
- for (const device of devicesContent) {
119
- const decoder = this.decoders.get(device._source.model);
120
- const measures = await decoder.copyToAsset(device);
121
- const { assetId } = bulkData.find(data => data.deviceId === device._id);
122
- deviceDocuments.push({ _id: device._id, body: { assetId } });
123
- assetDocuments.push({ _id: assetId, body: { measures } });
124
- }
125
- const updatedDevice = await this.writeToDatabase(deviceDocuments, async (deviceDocuments) => {
126
- const updated = await this.sdk.document.mUpdate(this.config.adminIndex, 'devices', deviceDocuments, { strict, refresh: options.refresh });
127
- await this.sdk.document.mUpdate(document.tenantId, 'devices', deviceDocuments, { strict, refresh: options.refresh });
128
- return {
129
- successes: results.successes.concat(updated.successes),
130
- errors: results.errors.concat(updated.errors)
131
- };
132
- });
133
- const updatedAssets = await this.writeToDatabase(assetDocuments, async (assetDocuments) => {
134
- const updated = await this.sdk.document.mUpdate(document.tenantId, 'assets', assetDocuments, { strict, refresh: options.refresh });
135
- return {
136
- successes: results.successes.concat(updated.successes),
137
- errors: results.errors.concat(updated.errors)
138
- };
139
- });
140
- results.successes.concat(updatedDevice.successes, updatedAssets.successes);
141
- results.errors.concat(updatedDevice.errors, updatedDevice.errors);
142
- }
164
+ const deviceDocuments = devices
165
+ .map((device) => ({ _id: device._id || (0, uuid_1.v4)(), body: lodash_1.default.omit(device, ['_id']) }));
166
+ await (0, utils_1.writeToDatabase)(deviceDocuments, async (result) => {
167
+ const created = await this.sdk.document.mCreate('device-manager', 'devices', result, { refresh, strict });
168
+ return {
169
+ errors: results.errors.concat(created.errors),
170
+ successes: results.successes.concat(created.successes)
171
+ };
172
+ });
143
173
  return results;
144
174
  }
145
- async mUnlink(devices, { strict, options }) {
146
- const unlinkedDevices = devices.filter(device => !device._source.assetId);
147
- if (strict && unlinkedDevices.length > 0) {
148
- const ids = unlinkedDevices.map(d => d._id);
149
- throw new kuzzle_1.BadRequestError(`Devices "${ids}" are not linked to an asset`);
150
- }
151
- const builder = devices.map(device => {
152
- const { _id, _source } = device;
153
- return { tenantId: _source.tenantId, deviceId: _id, assetId: _source.assetId };
154
- });
155
- const documents = this.buildBulkDevices(builder);
175
+ async importCatalog(catalog, { refresh, strict }) {
156
176
  const results = {
157
177
  errors: [],
158
178
  successes: [],
159
179
  };
160
- for (let i = 0; i < documents.length; i++) {
161
- const document = documents[i];
162
- const devicesContent = devices.filter(({ _id }) => document.deviceIds.includes(_id));
163
- const deviceDocuments = [];
164
- const assetDocuments = [];
165
- for (const device of devicesContent) {
166
- deviceDocuments.push({ _id: device._id, body: { assetId: null } });
167
- const measures = await this.eraseAssetMeasure(document.tenantId, device);
168
- assetDocuments.push({ _id: device._source.assetId, body: { measures } });
169
- }
170
- const updatedDevice = await this.writeToDatabase(deviceDocuments, async (deviceDocuments) => {
171
- const updated = await this.sdk.document.mUpdate(this.config.adminIndex, 'devices', deviceDocuments, { strict, refresh: options.refresh });
172
- await this.sdk.document.mUpdate(document.tenantId, 'devices', deviceDocuments, { strict, refresh: options.refresh });
173
- return {
174
- successes: results.successes.concat(updated.successes),
175
- errors: results.errors.concat(updated.errors)
176
- };
177
- });
178
- const updatedAssets = await this.writeToDatabase(assetDocuments, async (assetDocuments) => {
179
- const updated = await this.sdk.document.mUpdate(document.tenantId, 'assets', assetDocuments, { strict, refresh: options.refresh });
180
- return {
181
- successes: results.successes.concat(updated.successes),
182
- errors: results.errors.concat(updated.errors)
183
- };
184
- });
185
- results.successes.concat(updatedDevice.successes, updatedAssets.successes);
186
- results.errors.concat(updatedDevice.errors, updatedDevice.errors);
180
+ const withoutIds = catalog.filter(content => !content.deviceId);
181
+ if (withoutIds.length > 0) {
182
+ throw new kuzzle_1.BadRequestError(`${withoutIds.length} Devices do not have an ID`);
187
183
  }
184
+ const catalogDocuments = catalog
185
+ .map((catalogContent) => ({
186
+ _id: `catalog--${catalogContent.deviceId}`,
187
+ body: {
188
+ catalog: {
189
+ authorized: catalogContent.authorized === 'false' ? false : true,
190
+ deviceId: catalogContent.deviceId,
191
+ },
192
+ type: 'catalog'
193
+ }
194
+ }));
195
+ await (0, utils_1.writeToDatabase)(catalogDocuments, async (result) => {
196
+ const created = await this.sdk.document.mCreate(this.config.adminIndex, this.config.adminCollections.config.name, result, { refresh, strict });
197
+ return {
198
+ errors: results.errors.concat(created.errors),
199
+ successes: results.successes.concat(created.successes)
200
+ };
201
+ });
188
202
  return results;
189
203
  }
190
- async eraseAssetMeasure(tenantId, device) {
191
- const { _source: { measures } } = await this.sdk.document.get(tenantId, 'assets', device._source.assetId);
192
- for (const [measureName] of Object.entries(device._source.measures)) {
193
- if (measures[measureName]) {
194
- measures[measureName] = undefined;
195
- }
196
- }
197
- return measures;
204
+ async getAsset(assetId, engineId) {
205
+ const document = await this.sdk.document.get(engineId, 'assets', assetId);
206
+ return new models_1.BaseAsset(document._source, document._id);
198
207
  }
199
- async tenantExists(tenantId) {
208
+ async getDevice(deviceId) {
209
+ const document = await this.sdk.document.get(this.config.adminIndex, 'devices', deviceId);
210
+ return new models_1.Device(document._source, document._id);
211
+ }
212
+ async tenantExists(engineId) {
200
213
  const { result: tenantExists } = await this.sdk.query({
201
- controller: 'device-manager/engine',
202
214
  action: 'exists',
203
- index: tenantId,
215
+ controller: 'device-manager/engine',
216
+ index: engineId,
204
217
  });
205
218
  return tenantExists;
206
219
  }
207
- buildBulkDevices(bulkData) {
208
- const documents = [];
209
- for (let i = 0; i < bulkData.length; i++) {
210
- const { tenantId, deviceId, assetId } = bulkData[i];
211
- const document = documents.find(doc => doc.tenantId === tenantId);
212
- if (document) {
213
- document.deviceIds.push(deviceId);
214
- document.assetIds.push(assetId);
215
- }
216
- else {
217
- documents.push({ tenantId, deviceIds: [deviceId], assetIds: [assetId] });
218
- }
219
- }
220
- return documents;
221
- }
222
- formatDevicesContent(devices, document) {
223
- const devicesContent = devices.filter(device => document.deviceIds.includes(device._id));
224
- const devicesDocuments = devicesContent.map(device => {
225
- device._source.tenantId = document.tenantId;
226
- return { _id: device._id, body: device._source };
227
- });
228
- return devicesDocuments;
229
- }
230
- async writeToDatabase(deviceDocuments, writer) {
231
- const results = {
232
- errors: [],
233
- successes: [],
234
- };
235
- const limit = global.kuzzle.config.limits.documentsWriteCount;
236
- if (deviceDocuments.length <= limit) {
237
- const { successes, errors } = await writer(deviceDocuments);
238
- results.successes.push(successes);
239
- results.errors.push(errors);
240
- return results;
241
- }
242
- const writeMany = async (start, end) => {
243
- const devices = deviceDocuments.slice(start, end);
244
- const { successes, errors } = await writer(devices);
245
- results.successes.push(successes);
246
- results.errors.push(errors);
247
- };
248
- let offset = 0;
249
- let offsetLimit = limit;
250
- let done = false;
251
- while (!done) {
252
- await writeMany(offset, offsetLimit);
253
- offset += limit;
254
- offsetLimit += limit;
255
- if (offsetLimit >= deviceDocuments.length) {
256
- done = true;
257
- await writeMany(offset, deviceDocuments.length);
258
- }
259
- }
260
- return results;
261
- }
262
220
  }
263
221
  exports.DeviceService = DeviceService;
264
222
  //# sourceMappingURL=DeviceService.js.map
@@ -1,43 +1,56 @@
1
- import { KuzzleRequest, EmbeddedSDK, Plugin } from 'kuzzle';
1
+ import { KuzzleRequest } from 'kuzzle';
2
2
  import { Decoder } from './Decoder';
3
- import { BatchWriter } from './BatchProcessing';
4
- export declare type PayloadHandler = (request: KuzzleRequest, decoder: Decoder) => Promise<any>;
3
+ import { DeviceContent } from '../types';
4
+ import { MeasuresRegister } from './registers/MeasuresRegister';
5
+ import { DeviceManagerPlugin } from '../DeviceManagerPlugin';
5
6
  export declare class PayloadService {
6
7
  private config;
7
8
  private context;
8
- private batchController;
9
- get sdk(): EmbeddedSDK;
10
- constructor(plugin: Plugin, batchWriter: BatchWriter);
9
+ private measuresRegister;
10
+ private batch;
11
+ private get sdk();
12
+ private get app();
13
+ constructor(plugin: DeviceManagerPlugin, measuresRegister: MeasuresRegister);
11
14
  process(request: KuzzleRequest, decoder: Decoder, { refresh }?: {
12
15
  refresh?: any;
13
- }): Promise<any>;
16
+ }): Promise<{
17
+ asset: any;
18
+ device: {
19
+ _id: string;
20
+ _source: DeviceContent;
21
+ };
22
+ engineId: string;
23
+ } | {
24
+ valid: boolean;
25
+ }>;
26
+ private provisionning;
27
+ /**
28
+ * Register a new device by creating the document in admin index
29
+ * @todo add before/afterRegister events
30
+ */
14
31
  private register;
15
32
  /**
16
- * Device provisioning strategy.
17
- *
18
- * If autoProvisionning is on, device is automatically registered, otherwise
19
- * we request the admin provisioning catalog to ensure this device is allowed
20
- * to register.
33
+ * Updates the device with the new measures:
34
+ * - in admin index
35
+ * - in engine index
36
+ * - in linked asset
37
+ * - historize measures in engine index
21
38
  *
22
- * After registration, we look at the admin provisioning catalog entry to:
23
- * - attach the device to a tenant
24
- * - link the device to an asset of this tenant
25
- *
26
- * Then we look into the tenant provisioning catalog entry to:
27
- * - link the device to an asset of this tenant
39
+ * @todo add before/afterUpdate events
28
40
  */
29
- private deviceProvisionning;
41
+ private update;
30
42
  /**
31
- * Get the device entry from the provisioning catalog in corresponding index
43
+ * Updates a device with the new measures
44
+ *
45
+ * @returns Updated device
32
46
  */
33
- private getCatalogEntry;
34
- private update;
47
+ private updateDevice;
35
48
  /**
36
- * Propagate the measures inside the asset document.
49
+ * Save measures in engine "measures" collection
37
50
  */
38
- private propagateToAsset;
51
+ private historizeMeasures;
39
52
  /**
40
- * Creates an history entry for an asset
53
+ * Propagate the measures inside the linked asset document.
41
54
  */
42
- private historizeAsset;
55
+ private propagateToAsset;
43
56
  }