Skip to content

Commit be656bb

Browse files
authored
Merge pull request #270 from kuzzleio/2.1.2-proposal
# [2.1.2](https://github.com/kuzzleio/kuzzle-device-manager/releases/tag/2.1.2) (2023-02-20) #### Bug fixes - [ [#269](#269) ] Add lang search parameter in ApiAssetSearchRequest type ([tdislay](https://github.com/tdislay)) - [ [#268](#268) ] Fix adding of computed mesure in ingestion pipeline ([Aschen](https://github.com/Aschen)) - [ [#266](#266) ] Fix type of assetId and engineId ([Aschen](https://github.com/Aschen)) #### Enhancements - [ [#267](#267) ] Support nested metadata diff for asset history ([Aschen](https://github.com/Aschen)) ---
2 parents 2283bee + a0856f8 commit be656bb

File tree

19 files changed

+310
-44
lines changed

19 files changed

+310
-44
lines changed

features/fixtures/application/assets/Container.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ export interface ContainerMetadata extends Metadata {
1818

1919
export type ContainerMeasurements = {
2020
temperatureExt: TemperatureMeasurement;
21+
temperatureInt: TemperatureMeasurement;
2122
position: PositionMeasurement;
23+
temperatureWeather: TemperatureMeasurement;
2224
};
2325

2426
export interface ContainerAssetContent
@@ -31,10 +33,17 @@ export const containerAssetDefinition: AssetModelDefinition = {
3133
{ name: "temperatureExt", type: "temperature" },
3234
{ name: "temperatureInt", type: "temperature" },
3335
{ name: "position", type: "position" },
36+
{ name: "temperatureWeather", type: "temperature" },
3437
],
3538
metadataMappings: {
3639
weight: { type: "integer" },
3740
height: { type: "integer" },
41+
trailer: {
42+
properties: {
43+
weight: { type: "integer" },
44+
capacity: { type: "integer" },
45+
},
46+
},
3847
},
3948
defaultMetadata: {
4049
height: 20,

features/fixtures/application/tests/pipes.ts

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import {
88
EventMeasureProcessBefore,
99
AssetContent,
1010
DeviceContent,
11+
TemperatureMeasurement,
1112
} from "../../../../index";
13+
import { ContainerAssetContent } from "../assets/Container";
1214

1315
function checkEventWithDocument(app: Backend, event: string) {
1416
app.pipe.register(event, async (payload) => {
@@ -28,7 +30,7 @@ export function registerTestPipes(app: Backend) {
2830
device,
2931
measures,
3032
}: {
31-
asset: KDocument<AssetContent>;
33+
asset: KDocument<ContainerAssetContent>;
3234
device: KDocument<DeviceContent>;
3335
measures: MeasureContent[];
3436
}) => {
@@ -92,10 +94,44 @@ export function registerTestPipes(app: Backend) {
9294
}
9395
}
9496

95-
if (
96-
device._source.metadata.color === "test-metadata-history-with-measure"
97-
) {
97+
const color = device._source.metadata.color;
98+
99+
if (color === "test-metadata-history-with-measure") {
98100
asset._source.metadata.weight = 42042;
101+
asset._source.metadata.trailer.capacity = 2048;
102+
}
103+
104+
if (color === "test-create-new-asset-measure") {
105+
const measure: MeasureContent<TemperatureMeasurement> = {
106+
measuredAt: Date.now(),
107+
asset: {
108+
_id: asset._id,
109+
measureName: "temperatureWeather",
110+
metadata: asset._source.metadata,
111+
model: asset._source.model,
112+
reference: asset._source.reference,
113+
},
114+
origin: {
115+
type: "computed",
116+
_id: "rule-weather-api",
117+
measureName: "temperatureWeather",
118+
payloadUuids: ["uuid"],
119+
},
120+
type: "temperature",
121+
values: {
122+
temperature: 21.21,
123+
},
124+
};
125+
126+
measures.push(measure);
127+
128+
asset._source.measures.temperatureWeather = {
129+
name: measure.asset.measureName,
130+
measuredAt: measure.measuredAt,
131+
payloadUuids: measure.origin.payloadUuids,
132+
type: measure.type,
133+
values: measure.values,
134+
};
99135
}
100136

101137
return { asset, device, measures };

features/fixtures/fixtures.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ const assetAyseLinked1 = {
6262
metadata: {
6363
weight: 10,
6464
height: 11,
65+
trailer: {
66+
weight: 128,
67+
capacity: 1024,
68+
},
6569
},
6670
linkedDevices: [
6771
{

lib/core/DeviceManagerPlugin.ts

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {
2828
ModelModule,
2929
modelsMappings,
3030
} from "../modules/model";
31-
import { lock } from "../modules/shared";
31+
import { keepStack, lock } from "../modules/shared";
3232

3333
import { DeviceManagerConfiguration } from "./DeviceManagerConfiguration";
3434
import { DeviceManagerEngine } from "./DeviceManagerEngine";
@@ -330,8 +330,11 @@ export class DeviceManagerPlugin extends Plugin {
330330
await this.adminConfigManager
331331
.createCollection(this.config.adminIndex)
332332
.catch((error) => {
333-
throw new PluginImplementationError(
334-
`Cannot create admin "config" collection: ${error}`
333+
throw keepStack(
334+
error,
335+
new PluginImplementationError(
336+
`Cannot create admin "config" collection: ${error}`
337+
)
335338
);
336339
});
337340

@@ -340,25 +343,34 @@ export class DeviceManagerPlugin extends Plugin {
340343
mappings: modelsMappings,
341344
})
342345
.catch((error) => {
343-
throw new PluginImplementationError(
344-
`Cannot create admin "models" collection: ${error}`
346+
throw keepStack(
347+
error,
348+
new PluginImplementationError(
349+
`Cannot create admin "models" collection: ${error}`
350+
)
345351
);
346352
});
347353
await this.modelsRegister.loadModels();
348354

349355
await this.deviceManagerEngine
350356
.createDevicesCollection(this.config.adminIndex)
351357
.catch((error) => {
352-
throw new PluginImplementationError(
353-
`Cannot create admin "devices" collection: ${error}`
358+
throw keepStack(
359+
error,
360+
new PluginImplementationError(
361+
`Cannot create admin "devices" collection: ${error}`
362+
)
354363
);
355364
});
356365

357366
await this.sdk.collection
358367
.create(this.config.adminIndex, "payloads", this.getPayloadsMappings())
359368
.catch((error) => {
360-
throw new PluginImplementationError(
361-
`Cannot create admin "payloads" collection: ${error}`
369+
throw keepStack(
370+
error,
371+
new PluginImplementationError(
372+
`Cannot create admin "payloads" collection: ${error}`
373+
)
362374
);
363375
});
364376

lib/modules/asset/types/AssetApi.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ export interface ApiAssetSearchRequest extends AssetsControllerRequest {
6666

6767
scrollTTL?: string;
6868

69+
lang?: "koncorde" | "elasticsearch";
70+
6971
body: JSONObject;
7072
}
7173
export type ApiAssetSearchResult = SearchResult<KHit<AssetContent>>;

lib/modules/decoder/PayloadService.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Backend, KuzzleRequest, PluginContext } from "kuzzle";
1+
import { Backend, BadRequestError, KuzzleRequest, PluginContext } from "kuzzle";
22
import { JSONObject, KDocument } from "kuzzle-sdk";
33
import { v4 as uuidv4 } from "uuid";
44

@@ -81,6 +81,10 @@ export class PayloadService {
8181

8282
decodedPayload = await decoder.decode(decodedPayload, payload, request);
8383

84+
if (decodedPayload.references.length === 0) {
85+
throw new BadRequestError("No measurement has been decoded");
86+
}
87+
8488
const devices = await this.retrieveDevices(
8589
decoder.deviceModel,
8690
decodedPayload.references,

lib/modules/device/DeviceService.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ export class DeviceService {
8787
let device: KDocument<DeviceContent> = {
8888
_id: DeviceSerializer.id(model, reference),
8989
_source: {
90+
assetId: null,
91+
engineId: null,
9092
measures: {},
9193
metadata,
9294
model,

lib/modules/device/types/DeviceContent.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ export interface DeviceContent<
1212
/**
1313
* Linked asset unique identifier
1414
*/
15-
assetId?: string;
15+
assetId: string | null;
1616

1717
/**
1818
*/
19-
engineId?: string;
19+
engineId: string;
2020
}

lib/modules/measure/MeasureService.ts

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
AssetHistoryEventMeasure,
2020
AssetHistoryEventMetadata,
2121
} from "../asset";
22-
import { Metadata, lock, ask, onAsk } from "../shared";
22+
import { Metadata, lock, ask, onAsk, keepStack, objectDiff } from "../shared";
2323
import { AssetSerializer } from "../asset";
2424

2525
import {
@@ -145,8 +145,11 @@ export class MeasureService {
145145
device._source
146146
)
147147
.catch((error) => {
148-
throw new BadRequestError(
149-
`Cannot update device "${device._id}": ${error.message}`
148+
throw keepStack(
149+
error,
150+
new BadRequestError(
151+
`Cannot update device "${device._id}": ${error.message}`
152+
)
150153
);
151154
})
152155
);
@@ -161,8 +164,11 @@ export class MeasureService {
161164
device._source
162165
)
163166
.catch((error) => {
164-
throw new BadRequestError(
165-
`Cannot update engine device "${device._id}": ${error.message}`
167+
throw keepStack(
168+
error,
169+
new BadRequestError(
170+
`Cannot update engine device "${device._id}": ${error.message}`
171+
)
166172
);
167173
})
168174
);
@@ -200,19 +206,19 @@ export class MeasureService {
200206
measure: {
201207
// Filter measures who are not in the asset device link
202208
names: measures
203-
.filter((m) => Boolean(m.asset.measureName))
204-
.map((m) => m.asset.measureName),
209+
.filter((m) => Boolean(m.asset?.measureName))
210+
.map((m) => m.asset?.measureName),
205211
},
206212
name: "measure",
207213
};
208214

209-
const metadataDiff = this.compareMetadata(
215+
const changes = objectDiff(
210216
originalAssetMetadata,
211217
updatedAsset._source.metadata
212218
);
213-
if (metadataDiff.length !== 0) {
219+
if (changes.length !== 0) {
214220
(event as unknown as AssetHistoryEventMetadata).metadata = {
215-
names: metadataDiff,
221+
names: changes,
216222
};
217223
}
218224

@@ -222,8 +228,11 @@ export class MeasureService {
222228
);
223229
})
224230
.catch((error) => {
225-
throw new BadRequestError(
226-
`Cannot update asset "${asset._id}": ${error.message}`
231+
throw keepStack(
232+
error,
233+
new BadRequestError(
234+
`Cannot update asset "${asset._id}": ${error.message}`
235+
)
227236
);
228237
})
229238
);
@@ -257,18 +266,6 @@ export class MeasureService {
257266
});
258267
}
259268

260-
private compareMetadata(before: JSONObject, after: JSONObject): string[] {
261-
const names: string[] = [];
262-
263-
for (const [key, value] of Object.entries(before)) {
264-
if (after[key] !== value) {
265-
names.push(key);
266-
}
267-
}
268-
269-
return names;
270-
}
271-
272269
private updateDeviceMeasures(
273270
device: KDocument<DeviceContent>,
274271
measurements: MeasureContent[]

lib/modules/measure/types/MeasureContent.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ export type MeasureOriginDevice = {
3838
};
3939

4040
export type MeasureOriginComputed = {
41+
/**
42+
* Computed measures are not automatically added into the asset and device
43+
* documents at the end of the ingestion pipeline.
44+
*/
4145
type: "computed";
4246

4347
/**

0 commit comments

Comments
 (0)