kuzzle-device-manager 2.8.0-dev.4 → 2.8.0-dev.6

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.
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AssetsGroupsService = void 0;
4
+ const plugin_1 = require("../plugin");
5
+ const shared_1 = require("../shared");
6
+ const kuzzle_plugin_commons_1 = require("kuzzle-plugin-commons");
7
+ class AssetsGroupsService extends shared_1.BaseService {
8
+ constructor(plugin) {
9
+ super(plugin);
10
+ }
11
+ async create(_id, engineId, metadata, model, name, parent, request) {
12
+ if (parent !== null) {
13
+ const parentGroup = await this.sdk.document.get(engineId, plugin_1.InternalCollection.ASSETS_GROUPS, parent);
14
+ const children = parentGroup._source.children ?? [];
15
+ children.push(_id);
16
+ await this.sdk.document.update(engineId, plugin_1.InternalCollection.ASSETS_GROUPS, parent, {
17
+ children,
18
+ lastUpdate: Date.now(),
19
+ });
20
+ }
21
+ const groupMetadata = {};
22
+ if (model !== null) {
23
+ const groupModel = await (0, kuzzle_plugin_commons_1.ask)("ask:device-manager:model:group:get", { model });
24
+ for (const metadataName of Object.keys(groupModel.group.metadataMappings)) {
25
+ if (metadata[metadataName]) {
26
+ groupMetadata[metadataName] = metadata[metadataName];
27
+ }
28
+ else if (groupModel.group.defaultMetadata[metadataName]) {
29
+ groupMetadata[metadataName] =
30
+ groupModel.group.defaultMetadata[metadataName];
31
+ }
32
+ else {
33
+ groupMetadata[metadataName] = null;
34
+ }
35
+ }
36
+ }
37
+ const group = {
38
+ _id,
39
+ _source: {
40
+ children: [],
41
+ lastUpdate: Date.now(),
42
+ metadata: { ...groupMetadata },
43
+ model,
44
+ name,
45
+ parent,
46
+ },
47
+ };
48
+ return this.createDocument(request, group, {
49
+ collection: plugin_1.InternalCollection.ASSETS_GROUPS,
50
+ engineId,
51
+ });
52
+ }
53
+ async get(engineId, _id, request) {
54
+ return this.getDocument(request, _id, {
55
+ collection: plugin_1.InternalCollection.ASSETS_GROUPS,
56
+ engineId,
57
+ });
58
+ }
59
+ async update(request, _id, engineId, updateContent) {
60
+ const updatedGroup = await this.updateDocument(request, {
61
+ _id,
62
+ _source: updateContent,
63
+ }, { collection: plugin_1.InternalCollection.ASSETS_GROUPS, engineId }, { source: true, triggerEvents: true });
64
+ return updatedGroup;
65
+ }
66
+ async delete(_id, engineId, request) {
67
+ const { _source: assetGroup } = await this.get(engineId, _id, request);
68
+ if (assetGroup.parent !== null) {
69
+ const { _source: parentGroup } = await this.get(engineId, assetGroup.parent, request);
70
+ await this.update(request, assetGroup.parent, engineId, {
71
+ children: parentGroup.children.filter((children) => children !== _id),
72
+ lastUpdate: Date.now(),
73
+ });
74
+ }
75
+ await this.sdk.document.mUpdate(engineId, plugin_1.InternalCollection.ASSETS_GROUPS, assetGroup.children.map((childrenId) => ({
76
+ _id: childrenId,
77
+ body: {
78
+ lastUpdate: Date.now(),
79
+ parent: null,
80
+ },
81
+ })), { strict: true });
82
+ const { hits: assets } = await this.sdk.document.search(engineId, plugin_1.InternalCollection.ASSETS, { query: { equals: { "groups.id": _id } } }, { lang: "koncorde" });
83
+ await this.sdk.document.mUpdate(engineId, plugin_1.InternalCollection.ASSETS, assets.map((asset) => ({
84
+ _id: asset._id,
85
+ body: {
86
+ groups: asset._source.groups.filter(({ id: groupId }) => groupId !== _id),
87
+ },
88
+ })), { strict: true });
89
+ return this.deleteDocument(request, _id, {
90
+ collection: plugin_1.InternalCollection.ASSETS_GROUPS,
91
+ engineId,
92
+ });
93
+ }
94
+ async search(engineId, searchParams, request) {
95
+ return this.searchDocument(request, searchParams, {
96
+ collection: plugin_1.InternalCollection.ASSETS_GROUPS,
97
+ engineId,
98
+ });
99
+ }
100
+ async addAsset(engineId, _id, assetIds, request) {
101
+ const assetGroup = await this.get(engineId, _id, request);
102
+ const assets = [];
103
+ for (const assetId of assetIds) {
104
+ const assetContent = (await this.getDocument(request, assetId, {
105
+ collection: plugin_1.InternalCollection.ASSETS,
106
+ engineId,
107
+ }))._source;
108
+ if (!Array.isArray(assetContent.groups)) {
109
+ assetContent.groups = [];
110
+ }
111
+ if (assetGroup._source.parent !== null) {
112
+ assetContent.groups.push({
113
+ date: Date.now(),
114
+ id: assetGroup._source.parent,
115
+ });
116
+ }
117
+ assetContent.groups.push({
118
+ date: Date.now(),
119
+ id: _id,
120
+ });
121
+ assets.push({
122
+ _id: assetId,
123
+ body: assetContent,
124
+ });
125
+ }
126
+ const assetsGroupsUpdate = await this.update(request, _id, engineId, {
127
+ lastUpdate: Date.now(),
128
+ });
129
+ const update = await this.sdk.document.mReplace(engineId, plugin_1.InternalCollection.ASSETS, assets, { triggerEvents: true });
130
+ return {
131
+ ...update,
132
+ assetsGroups: assetsGroupsUpdate,
133
+ };
134
+ }
135
+ async removeAsset(engineId, _id, assetIds, request) {
136
+ const { _source: AssetGroupContent } = await this.get(engineId, _id, request);
137
+ const removedGroups = AssetGroupContent.children;
138
+ removedGroups.push(_id);
139
+ const assets = [];
140
+ for (const assetId of assetIds) {
141
+ const assetContent = (await this.getDocument(request, assetId, {
142
+ collection: plugin_1.InternalCollection.ASSETS,
143
+ engineId,
144
+ }))._source;
145
+ if (!Array.isArray(assetContent.groups)) {
146
+ continue;
147
+ }
148
+ assetContent.groups = assetContent.groups.filter(({ id: groupId }) => !removedGroups.includes(groupId));
149
+ assets.push({
150
+ _id: assetId,
151
+ body: assetContent,
152
+ });
153
+ }
154
+ const assetsGroupsUpdate = await this.update(request, _id, engineId, {
155
+ lastUpdate: Date.now(),
156
+ });
157
+ const update = await this.sdk.document.mReplace(engineId, plugin_1.InternalCollection.ASSETS, assets, { triggerEvents: true });
158
+ return {
159
+ ...update,
160
+ assetsGroups: assetsGroupsUpdate,
161
+ };
162
+ }
163
+ }
164
+ exports.AssetsGroupsService = AssetsGroupsService;
165
+ //# sourceMappingURL=AssetsGroupsService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssetsGroupsService.js","sourceRoot":"","sources":["../../../../lib/modules/asset/AssetsGroupsService.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,7 @@ import { DeviceContent } from "./types/DeviceContent";
9
9
  export declare class DeviceService extends DigitalTwinService {
10
10
  constructor(plugin: DeviceManagerPlugin);
11
11
  registerAskEvents(): void;
12
+ private _create;
12
13
  /**
13
14
  * Create a new device.
14
15
  *
@@ -30,6 +31,15 @@ export declare class DeviceService extends DigitalTwinService {
30
31
  update(engineId: string, deviceId: string, metadata: Metadata, request: KuzzleRequest): Promise<KDocument<DeviceContent>>;
31
32
  delete(engineId: string, deviceId: string, request: KuzzleRequest): Promise<void>;
32
33
  search(engineId: string, searchParams: SearchParams, request: KuzzleRequest): Promise<SearchResult<KHit<DeviceContent>>>;
34
+ /**
35
+ * Internal logic to attach the device to an engine
36
+ *
37
+ * @param engineId Engine id to attach to
38
+ * @param deviceId Device id to attach
39
+ * @param options.refresh Wait for ES indexation
40
+ * @param options.strict If true, throw if an operation isn't possible
41
+ */
42
+ private _attachEngine;
33
43
  /**
34
44
  * Attach the device to an engine
35
45
  *
@@ -67,7 +77,14 @@ export declare class DeviceService extends DigitalTwinService {
67
77
  */
68
78
  private generateMissingAssetMeasureNames;
69
79
  /**
70
- * Unlink a device of an asset
80
+ * Internal logic of unlink a device of an asset
81
+ *
82
+ * @param {string} deviceId Id of the device
83
+ * @param {KuzzleRequest} request kuzzle request
84
+ */
85
+ private _unlinkAsset;
86
+ /**
87
+ * Unlink a device of an asset with lock
71
88
  *
72
89
  * @param {string} deviceId Id of the device
73
90
  * @param {KuzzleRequest} request kuzzle request
@@ -33,16 +33,10 @@ class DeviceService extends shared_1.DigitalTwinService {
33
33
  await this.attachEngine(engineId, deviceId, request);
34
34
  });
35
35
  }
36
- /**
37
- * Create a new device.
38
- *
39
- * @todo creating a device in the "device-manager" index should be a separate
40
- * method since in this case "engineId" is not really an engine ID but still
41
- * required as an argument (in part to check the tenant rights)
42
- */
43
- async create(model, reference, metadata, request) {
36
+ async _create(deviceId, model, reference, metadata, request) {
37
+ var _a;
44
38
  let device = {
45
- _id: DeviceSerializer_1.DeviceSerializer.id(model, reference),
39
+ _id: deviceId,
46
40
  _source: {
47
41
  assetId: null,
48
42
  engineId: null,
@@ -53,38 +47,46 @@ class DeviceService extends shared_1.DigitalTwinService {
53
47
  reference,
54
48
  },
55
49
  };
56
- return (0, shared_1.lock)(`device:create:${device._id}`, async () => {
57
- var _a;
58
- const deviceModel = await this.getDeviceModel(model);
59
- const engineId = request.getString("engineId");
60
- for (const metadataName of Object.keys(deviceModel.device.metadataMappings)) {
61
- (_a = device._source.metadata)[metadataName] || (_a[metadataName] = null);
62
- }
63
- for (const [metadataName, metadataValue] of Object.entries(deviceModel.device.defaultMetadata)) {
64
- lodash_1.default.set(device._source.metadata, metadataName, metadataValue);
65
- }
66
- const refreshableCollections = [];
67
- const { _source } = await this.createDocument(request, device, {
68
- collection: plugin_1.InternalCollection.DEVICES,
69
- engineId: this.config.adminIndex,
70
- });
71
- device._source = _source;
50
+ const deviceModel = await this.getDeviceModel(model);
51
+ const engineId = request.getString("engineId");
52
+ for (const metadataName of Object.keys(deviceModel.device.metadataMappings)) {
53
+ (_a = device._source.metadata)[metadataName] || (_a[metadataName] = null);
54
+ }
55
+ for (const [metadataName, metadataValue] of Object.entries(deviceModel.device.defaultMetadata)) {
56
+ lodash_1.default.set(device._source.metadata, metadataName, metadataValue);
57
+ }
58
+ const refreshableCollections = [];
59
+ const { _source } = await this.createDocument(request, device, {
60
+ collection: plugin_1.InternalCollection.DEVICES,
61
+ engineId: this.config.adminIndex,
62
+ });
63
+ device._source = _source;
64
+ refreshableCollections.push({
65
+ collection: plugin_1.InternalCollection.DEVICES,
66
+ index: this.config.adminIndex,
67
+ });
68
+ if (engineId && engineId !== this.config.adminIndex) {
69
+ device = await this._attachEngine(engineId, device._id, request);
72
70
  refreshableCollections.push({
73
71
  collection: plugin_1.InternalCollection.DEVICES,
74
- index: this.config.adminIndex,
72
+ index: engineId,
75
73
  });
76
- if (engineId && engineId !== this.config.adminIndex) {
77
- device = await this.attachEngine(engineId, device._id, request);
78
- refreshableCollections.push({
79
- collection: plugin_1.InternalCollection.DEVICES,
80
- index: engineId,
81
- });
82
- }
83
- if (request.getRefresh() === "wait_for") {
84
- await Promise.all(refreshableCollections.map(({ index, collection }) => this.sdk.collection.refresh(index, collection)));
85
- }
86
- return device;
87
- });
74
+ }
75
+ if (request.getRefresh() === "wait_for") {
76
+ await Promise.all(refreshableCollections.map(({ index, collection }) => this.sdk.collection.refresh(index, collection)));
77
+ }
78
+ return device;
79
+ }
80
+ /**
81
+ * Create a new device.
82
+ *
83
+ * @todo creating a device in the "device-manager" index should be a separate
84
+ * method since in this case "engineId" is not really an engine ID but still
85
+ * required as an argument (in part to check the tenant rights)
86
+ */
87
+ async create(model, reference, metadata, request) {
88
+ const deviceId = DeviceSerializer_1.DeviceSerializer.id(model, reference);
89
+ return (0, shared_1.lock)(`device:${deviceId}`, async () => this._create(deviceId, model, reference, metadata, request));
88
90
  }
89
91
  async get(engineId, deviceId, request) {
90
92
  return this.getDocument(request, deviceId, {
@@ -99,29 +101,31 @@ class DeviceService extends shared_1.DigitalTwinService {
99
101
  * Replace a device metadata
100
102
  */
101
103
  async replaceMetadata(engineId, deviceId, metadata, request) {
102
- const device = await this.get(engineId, deviceId, request);
103
- for (const key in metadata) {
104
- if (key in device._source.metadata) {
105
- device._source.metadata[key] = metadata[key];
104
+ return (0, shared_1.lock)(`device:${deviceId}`, async () => {
105
+ const device = await this.get(engineId, deviceId, request);
106
+ for (const key in metadata) {
107
+ if (key in device._source.metadata) {
108
+ device._source.metadata[key] = metadata[key];
109
+ }
106
110
  }
107
- }
108
- const updatedPayload = await this.app.trigger("device-manager:device:update:before", { device: device, metadata });
109
- const updatedDevice = await this.sdk.document.replace(engineId, plugin_1.InternalCollection.DEVICES, deviceId, updatedPayload.device._source);
110
- await this.app.trigger("device-manager:device:update:after", {
111
- device: updatedDevice,
112
- metadata: updatedPayload.metadata,
111
+ const updatedPayload = await this.app.trigger("device-manager:device:update:before", { device: device, metadata });
112
+ const updatedDevice = await this.sdk.document.replace(engineId, plugin_1.InternalCollection.DEVICES, deviceId, updatedPayload.device._source);
113
+ await this.app.trigger("device-manager:device:update:after", {
114
+ device: updatedDevice,
115
+ metadata: updatedPayload.metadata,
116
+ });
117
+ return updatedDevice;
113
118
  });
114
- return updatedDevice;
115
119
  }
116
120
  /**
117
121
  * Update or Create an device metadata
118
122
  */
119
123
  async upsert(engineId, model, reference, metadata, request) {
120
- const deviceId = `${model}-${reference}`;
121
- return (0, shared_1.lock)(`device:${engineId}:${deviceId}`, async () => {
124
+ const deviceId = DeviceSerializer_1.DeviceSerializer.id(model, reference);
125
+ return (0, shared_1.lock)(`device:${deviceId}`, async () => {
122
126
  const adminIndexDevice = await this.get(this.config.adminIndex, deviceId, request).catch(() => null);
123
127
  if (!adminIndexDevice) {
124
- return this.create(model, reference, metadata, request);
128
+ return this._create(deviceId, model, reference, metadata, request);
125
129
  }
126
130
  if (adminIndexDevice._source.engineId &&
127
131
  adminIndexDevice._source.engineId !== engineId) {
@@ -129,7 +133,7 @@ class DeviceService extends shared_1.DigitalTwinService {
129
133
  }
130
134
  const engineDevice = await this.get(engineId, deviceId, request).catch(() => null);
131
135
  if (!engineDevice) {
132
- await this.attachEngine(engineId, deviceId, request);
136
+ await this._attachEngine(engineId, deviceId, request);
133
137
  }
134
138
  const updatedPayload = await this.app.trigger("device-manager:device:update:before", { device: adminIndexDevice, metadata });
135
139
  const updatedDevice = await this.updateDocument(request, {
@@ -147,7 +151,7 @@ class DeviceService extends shared_1.DigitalTwinService {
147
151
  });
148
152
  }
149
153
  async update(engineId, deviceId, metadata, request) {
150
- return (0, shared_1.lock)(`device:update:${deviceId}`, async () => {
154
+ return (0, shared_1.lock)(`device:${deviceId}`, async () => {
151
155
  const device = await this.get(engineId, deviceId, request);
152
156
  const updatedPayload = await this.app.trigger("device-manager:device:update:before", { device, metadata });
153
157
  const updatedDevice = await this.updateDocument(request, {
@@ -162,7 +166,7 @@ class DeviceService extends shared_1.DigitalTwinService {
162
166
  });
163
167
  }
164
168
  async delete(engineId, deviceId, request) {
165
- return (0, shared_1.lock)(`device:delete:${deviceId}`, async () => {
169
+ return (0, shared_1.lock)(`device:${deviceId}`, async () => {
166
170
  const device = await this.get(engineId, deviceId, request);
167
171
  const promises = [];
168
172
  if (device._source.assetId) {
@@ -211,6 +215,40 @@ class DeviceService extends shared_1.DigitalTwinService {
211
215
  engineId,
212
216
  });
213
217
  }
218
+ /**
219
+ * Internal logic to attach the device to an engine
220
+ *
221
+ * @param engineId Engine id to attach to
222
+ * @param deviceId Device id to attach
223
+ * @param options.refresh Wait for ES indexation
224
+ * @param options.strict If true, throw if an operation isn't possible
225
+ */
226
+ async _attachEngine(engineId, deviceId, request) {
227
+ const device = await this.getInternalDevices(deviceId);
228
+ if (device._source.engineId) {
229
+ throw new kuzzle_1.BadRequestError(`Device "${device._id}" is already attached to an engine.`);
230
+ }
231
+ await this.checkEngineExists(engineId);
232
+ device._source.engineId = engineId;
233
+ await this.updateDocument(request, device, {
234
+ collection: plugin_1.InternalCollection.DEVICES,
235
+ engineId: this.config.adminIndex,
236
+ });
237
+ // Make sure the device is cleaned when attached to tenant
238
+ device._source.lastMeasuredAt = null;
239
+ device._source.measures = {};
240
+ const updatedDevice = await this.createDocument(request, device, {
241
+ collection: plugin_1.InternalCollection.DEVICES,
242
+ engineId,
243
+ });
244
+ if (request.getRefresh() === "wait_for") {
245
+ await Promise.all([
246
+ this.sdk.collection.refresh(this.config.adminIndex, plugin_1.InternalCollection.DEVICES),
247
+ this.sdk.collection.refresh(device._source.engineId, plugin_1.InternalCollection.DEVICES),
248
+ ]);
249
+ }
250
+ return updatedDevice;
251
+ }
214
252
  /**
215
253
  * Attach the device to an engine
216
254
  *
@@ -220,32 +258,7 @@ class DeviceService extends shared_1.DigitalTwinService {
220
258
  * @param options.strict If true, throw if an operation isn't possible
221
259
  */
222
260
  async attachEngine(engineId, deviceId, request) {
223
- return (0, shared_1.lock)(`device:attachEngine:${deviceId}`, async () => {
224
- const device = await this.getInternalDevices(deviceId);
225
- if (device._source.engineId) {
226
- throw new kuzzle_1.BadRequestError(`Device "${device._id}" is already attached to an engine.`);
227
- }
228
- await this.checkEngineExists(engineId);
229
- device._source.engineId = engineId;
230
- await this.updateDocument(request, device, {
231
- collection: plugin_1.InternalCollection.DEVICES,
232
- engineId: this.config.adminIndex,
233
- });
234
- // Make sure the device is cleaned when attached to tenant
235
- device._source.lastMeasuredAt = null;
236
- device._source.measures = {};
237
- const updatedDevice = await this.createDocument(request, device, {
238
- collection: plugin_1.InternalCollection.DEVICES,
239
- engineId,
240
- });
241
- if (request.getRefresh() === "wait_for") {
242
- await Promise.all([
243
- this.sdk.collection.refresh(this.config.adminIndex, plugin_1.InternalCollection.DEVICES),
244
- this.sdk.collection.refresh(device._source.engineId, plugin_1.InternalCollection.DEVICES),
245
- ]);
246
- }
247
- return updatedDevice;
248
- });
261
+ return (0, shared_1.lock)(`device:${deviceId}`, async () => this._attachEngine(engineId, deviceId, request));
249
262
  }
250
263
  /**
251
264
  * Detach a device from its attached engine
@@ -254,7 +267,7 @@ class DeviceService extends shared_1.DigitalTwinService {
254
267
  * @param {KuzzleRequest} request kuzzle request
255
268
  */
256
269
  async detachEngine(deviceId, request) {
257
- return (0, shared_1.lock)(`device:detachEngine:${deviceId}`, async () => {
270
+ return (0, shared_1.lock)(`device:${deviceId}`, async () => {
258
271
  const device = await this.getInternalDevices(deviceId);
259
272
  this.checkAttachedToEngine(device);
260
273
  if (device._source.assetId) {
@@ -283,7 +296,7 @@ class DeviceService extends shared_1.DigitalTwinService {
283
296
  * Link a device to an asset.
284
297
  */
285
298
  async linkAsset(engineId, deviceId, assetId, measureNames, implicitMeasuresLinking, request) {
286
- return (0, shared_1.lock)(`device:linkAsset:${deviceId}`, async () => {
299
+ return (0, shared_1.lock)(`device:${deviceId}`, async () => {
287
300
  const device = await this.getInternalDevices(deviceId);
288
301
  const engine = await this.getEngine(engineId);
289
302
  this.checkAttachedToEngine(device);
@@ -424,61 +437,68 @@ class DeviceService extends shared_1.DigitalTwinService {
424
437
  }
425
438
  }
426
439
  /**
427
- * Unlink a device of an asset
440
+ * Internal logic of unlink a device of an asset
428
441
  *
429
442
  * @param {string} deviceId Id of the device
430
443
  * @param {KuzzleRequest} request kuzzle request
431
444
  */
432
- async unlinkAsset(deviceId, request) {
433
- return (0, shared_1.lock)(`device:unlinkAsset:${deviceId}`, async () => {
434
- const device = await this.getInternalDevices(deviceId);
435
- const engineId = device._source.engineId;
436
- this.checkAttachedToEngine(device);
437
- if (!device._source.assetId) {
438
- throw new kuzzle_1.BadRequestError(`Device "${device._id}" is not linked to an asset.`);
439
- }
440
- const asset = await this.sdk.document.get(engineId, plugin_1.InternalCollection.ASSETS, device._source.assetId);
441
- const linkedDevices = asset._source.linkedDevices.filter((link) => link._id !== device._id);
442
- const [updatedDevice, , updatedAsset] = await Promise.all([
443
- this.updateDocument(request, { _id: device._id, _source: { assetId: null } }, {
444
- collection: plugin_1.InternalCollection.DEVICES,
445
- engineId: this.config.adminIndex,
446
- }, { source: true }),
447
- this.updateDocument(request, { _id: device._id, _source: { assetId: null } }, {
448
- collection: plugin_1.InternalCollection.DEVICES,
449
- engineId,
450
- }),
451
- this.updateDocument(request, { _id: asset._id, _source: { linkedDevices } }, {
452
- collection: plugin_1.InternalCollection.ASSETS,
453
- engineId,
454
- }, { source: true }),
455
- ]);
456
- const event = {
457
- name: "unlink",
458
- unlink: {
459
- deviceId,
460
- },
461
- };
462
- await (0, kuzzle_plugin_commons_1.ask)("ask:device-manager:asset:history:add", {
445
+ async _unlinkAsset(deviceId, request) {
446
+ const device = await this.getInternalDevices(deviceId);
447
+ const engineId = device._source.engineId;
448
+ this.checkAttachedToEngine(device);
449
+ if (!device._source.assetId) {
450
+ throw new kuzzle_1.BadRequestError(`Device "${device._id}" is not linked to an asset.`);
451
+ }
452
+ const asset = await this.sdk.document.get(engineId, plugin_1.InternalCollection.ASSETS, device._source.assetId);
453
+ const linkedDevices = asset._source.linkedDevices.filter((link) => link._id !== device._id);
454
+ const [updatedDevice, , updatedAsset] = await Promise.all([
455
+ this.updateDocument(request, { _id: device._id, _source: { assetId: null } }, {
456
+ collection: plugin_1.InternalCollection.DEVICES,
457
+ engineId: this.config.adminIndex,
458
+ }, { source: true }),
459
+ this.updateDocument(request, { _id: device._id, _source: { assetId: null } }, {
460
+ collection: plugin_1.InternalCollection.DEVICES,
463
461
  engineId,
464
- histories: [
465
- {
466
- asset: updatedAsset._source,
467
- event,
468
- id: updatedAsset._id,
469
- timestamp: Date.now(),
470
- },
471
- ],
472
- });
473
- if (request.getRefresh() === "wait_for") {
474
- await Promise.all([
475
- this.sdk.collection.refresh(this.config.adminIndex, plugin_1.InternalCollection.DEVICES),
476
- this.sdk.collection.refresh(engineId, plugin_1.InternalCollection.DEVICES),
477
- this.sdk.collection.refresh(engineId, plugin_1.InternalCollection.ASSETS),
478
- ]);
479
- }
480
- return { asset: updatedAsset, device: updatedDevice };
462
+ }),
463
+ this.updateDocument(request, { _id: asset._id, _source: { linkedDevices } }, {
464
+ collection: plugin_1.InternalCollection.ASSETS,
465
+ engineId,
466
+ }, { source: true }),
467
+ ]);
468
+ const event = {
469
+ name: "unlink",
470
+ unlink: {
471
+ deviceId,
472
+ },
473
+ };
474
+ await (0, kuzzle_plugin_commons_1.ask)("ask:device-manager:asset:history:add", {
475
+ engineId,
476
+ histories: [
477
+ {
478
+ asset: updatedAsset._source,
479
+ event,
480
+ id: updatedAsset._id,
481
+ timestamp: Date.now(),
482
+ },
483
+ ],
481
484
  });
485
+ if (request.getRefresh() === "wait_for") {
486
+ await Promise.all([
487
+ this.sdk.collection.refresh(this.config.adminIndex, plugin_1.InternalCollection.DEVICES),
488
+ this.sdk.collection.refresh(engineId, plugin_1.InternalCollection.DEVICES),
489
+ this.sdk.collection.refresh(engineId, plugin_1.InternalCollection.ASSETS),
490
+ ]);
491
+ }
492
+ return { asset: updatedAsset, device: updatedDevice };
493
+ }
494
+ /**
495
+ * Unlink a device of an asset with lock
496
+ *
497
+ * @param {string} deviceId Id of the device
498
+ * @param {KuzzleRequest} request kuzzle request
499
+ */
500
+ async unlinkAsset(deviceId, request) {
501
+ return (0, shared_1.lock)(`device:${deviceId}`, async () => this._unlinkAsset(deviceId, request));
482
502
  }
483
503
  async checkEngineExists(engineId) {
484
504
  const { result: { exists }, } = await this.sdk.query({