Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to list all registered decoders by the plugin #114

Merged
merged 9 commits into from
Oct 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@ index.js.map
# Doc
doc/framework
frontmatter-errors.json

.vscode
2 changes: 1 addition & 1 deletion doc/1/classes/decoder/constructor/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { Decoder } from 'kuzzle-plugin-device-manager';

class KarakoyDecoder extends Decoder {
constructor () {
super('Karakoy');
super("Karakoy", ["temperature"]);
}

// This method must be implemented
Expand Down
68 changes: 68 additions & 0 deletions doc/1/controllers/decoder/list-decoders/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
code: true
type: page
title: list
description: List available registered decoders
---

# List

List available registered decoders.

---

## Query Syntax

### HTTP

```http
URL: http://localhost:7512/_/device-manager/decoders/_list
Method: GET
```

### Other protocols

```js
{
"controller": "device-manager/decoders",
"action": "list",
}
```

### Kourou

```bash
kourou device-manager/decoders:list
```
---

## Response

```js
{
"action": "list",
"controller": "device-manager/decoders",
"error": null,
"node": "knode-nine-hydra-22631",
"requestId": "d888a8e1-2f80-4849-99d0-86ea70fe91e4",
"result": {
"decoders": [
{
"deviceModel": "DummyTemp",
"deviceMeasures": [
"temperature"
]
},
{
"deviceModel": "DummyTempPosition",
"deviceMeasures": [
"temperature",
"position"
]
}
]
},
"status": 200,
"volatile": null
}
```
4 changes: 2 additions & 2 deletions doc/1/guides/decoders/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const deviceManager = new DeviceManagerPlugin();

class KarakoyDecoder extends Decoder {
constructor () {
super("Karakoy");
super("Karakoy", ["temperature"]);
}

async decode (payload: JSONObject, request: KuzzleRequest): Promise<DeviceContent> {
Expand Down Expand Up @@ -74,7 +74,7 @@ You can specify a custom API action and custom HTTP routes by defining the `acti
```js
class KarakoyDecoder extends Decoder {
constructor () {
super("Karakoy");
super("Karakoy", ["temperature"]);

// Generated API action: "device-manager/payload:karakoy-v1"
this.action = 'karakoy-v1';
Expand Down
6 changes: 6 additions & 0 deletions features/DecodersController.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Feature: Device Manager decoders controller

Scenario: List all registered decoders
When When I successfully execute the action "device-manager/decoders":"list"
Then I should receive a result matching:
| decoders | [{"deviceModel":"DummyTemp","deviceMeasures":["temperature"]},{"deviceModel":"DummyTempPosition","deviceMeasures":["temperature","position"]}] |
2 changes: 1 addition & 1 deletion features/fixtures/application/decoders/DummyTempDecoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { JSONObject, KuzzleRequest, PreconditionError } from 'kuzzle';

export class DummyTempDecoder extends Decoder {
constructor () {
super('DummyTemp');
super('DummyTemp', ["temperature"]);

this.payloadsMappings = {
deviceEUI: { type: 'keyword' }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { JSONObject, KuzzleRequest, PreconditionError } from 'kuzzle';

export class DummyTempPositionDecoder extends Decoder {
constructor () {
super('DummyTempPosition');
super('DummyTempPosition', ["temperature", "position"]);
}

async validate (payload: JSONObject, request: KuzzleRequest) {
Expand Down
7 changes: 7 additions & 0 deletions lib/DeviceManagerPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { EngineController } from 'kuzzle-plugin-commons';
import {
AssetController,
DeviceController,
DecodersController
} from './controllers';
import {
DeviceManagerEngine,
Expand All @@ -26,6 +27,7 @@ import {
PayloadHandler,
AssetMappingsManager,
DeviceMappingsManager,
DecodersService
} from './core-classes';
import {
assetsMappings,
Expand Down Expand Up @@ -86,10 +88,12 @@ export class DeviceManagerPlugin extends Plugin {
private assetController: AssetController;
private deviceController: DeviceController;
private engineController: EngineController;
private decodersController: DecodersController;

private payloadService: PayloadService;
private deviceManagerEngine: DeviceManagerEngine;
private deviceService: DeviceService;
private decodersService: DecodersService;
private migrationService: MigrationService;

private batchWriter: BatchWriter;
Expand Down Expand Up @@ -195,15 +199,18 @@ export class DeviceManagerPlugin extends Plugin {

this.payloadService = new PayloadService(this, this.batchWriter);
this.deviceService = new DeviceService(this, this.decoders);
this.decodersService = new DecodersService(this, this.decoders);
this.migrationService = new MigrationService('device-manager', this);
this.deviceManagerEngine = new DeviceManagerEngine(this, this.assetMappings, this.deviceMappings);

this.assetController = new AssetController(this);
this.deviceController = new DeviceController(this, this.deviceService);
this.decodersController = new DecodersController(this, this.decodersService);
this.engineController = new EngineController('device-manager', this, this.deviceManagerEngine);

this.api['device-manager/asset'] = this.assetController.definition;
this.api['device-manager/device'] = this.deviceController.definition;
this.api['device-manager/decoders'] = this.decodersController.definition;

this.pipes = {
'device-manager/device:beforeUpdate': this.pipeCheckEngine.bind(this),
Expand Down
40 changes: 40 additions & 0 deletions lib/controllers/DecodersController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {
EmbeddedSDK,
Plugin,
} from 'kuzzle';

import { CRUDController } from './CRUDController';
import { DecodersService } from '../core-classes';

export class DecodersController extends CRUDController {
private decodersService: DecodersService;

get sdk(): EmbeddedSDK {
return this.context.accessors.sdk;
}

constructor(plugin: Plugin, decodersService: DecodersService) {
super(plugin, 'decoders');

this.decodersService = decodersService;

this.definition = {
actions: {
list: {
handler: this.list.bind(this),
http: [{ verb: 'get', path: 'device-manager/decoders' }]
}
}
};
}

/**
* List all available decoders
*/
async list () {
const decoders = await this.decodersService.list();

return { decoders };
}

}
2 changes: 1 addition & 1 deletion lib/controllers/DeviceController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export class DeviceController extends CRUDController {
prunePayloads: {
handler: this.prunePayloads.bind(this),
http: [{ verb: 'delete', path: 'device-manager/devices/_prunePayloads' }]
},
}
}
};
}
Expand Down
1 change: 1 addition & 0 deletions lib/controllers/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './AssetController';
export * from './CRUDController';
export * from './DeviceController';
export * from './DecodersController';
23 changes: 19 additions & 4 deletions lib/core-classes/Decoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import {
HttpRoute,
PreconditionError,
} from 'kuzzle';
import _ from 'lodash';

import has from 'lodash/has';

import { Device, BaseAsset } from '../models';

import { AssetDeviceMeasures, DeviceContent } from '../types';
import { DeviceContent, DecoderContent, AssetDeviceMeasures } from '../types';

/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/no-empty-function */
Expand All @@ -26,6 +27,11 @@ export abstract class Decoder {
*/
deviceModel: string;

/**
* Array of device measure type
*/
deviceMeasures: string[];

/**
* Custom name for the associated API action in the "payload" controller
*/
Expand Down Expand Up @@ -62,9 +68,11 @@ export abstract class Decoder {

/**
* @param deviceModel Device model for this decoder
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments should be updated as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but this hasn't changed 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was talking about the constructor now takes 2 params instead of one

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes, i didn't understud it that way ! i'll change that with the last Nitpiking you added

* @param deviceMeasures Devices measure types for this decoder
*/
constructor (deviceModel: string) {
constructor (deviceModel: string, deviceMeasures: string[]) {
this.deviceModel = deviceModel;
this.deviceMeasures = deviceMeasures;
}

/**
Expand Down Expand Up @@ -199,11 +207,18 @@ export abstract class Decoder {
*/
ensureProperties (payload: JSONObject, paths: string[]): void | never {
for (const path of paths) {
if (! _.has(payload, path)) {
if (! has(payload, path)) {
throw new PreconditionError(`Missing property "${path}" in payload`);
}
}
}

serialize(): DecoderContent {
return {
deviceModel: this.deviceModel,
deviceMeasures: this.deviceMeasures
}
}
}

/* eslint-enable @typescript-eslint/no-unused-vars */
Expand Down
31 changes: 31 additions & 0 deletions lib/core-classes/DecodersService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { PluginContext, EmbeddedSDK, Plugin } from "kuzzle";

import { Decoder } from "./Decoder";
import { DeviceManagerConfig } from "../DeviceManagerPlugin";
import { DecoderContent } from '../types/decoders/DecodersContent';

export class DecodersService {
private config: DeviceManagerConfig;
private context: PluginContext;

private decoders: Map<string, Decoder>;

get sdk(): EmbeddedSDK {
return this.context.accessors.sdk;
}

constructor(plugin: Plugin, decoders: Map<string, Decoder>) {
this.config = plugin.config as any;
this.context = plugin.context;

this.decoders = decoders;
}

async list(): Promise<DecoderContent[]> {
const decoders = Array
.from(this.decoders.values())
.map(decoder => decoder.serialize())

return decoders;
}
}
2 changes: 2 additions & 0 deletions lib/core-classes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export * from './BatchProcessing';

export * from './Decoder';

export * from './DecodersService';

export * from './CustomMappings/AssetMappingsManager';

export * from './CustomMappings/DeviceMappingsManager';
4 changes: 4 additions & 0 deletions lib/types/decoders/DecodersContent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface DecoderContent {
deviceModel: string
deviceMeasures: string[]
}
4 changes: 4 additions & 0 deletions lib/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ export * from './asset/AssetContentBase';

export * from './asset/AssetDeviceMeasures';

export * from './asset/AssetContentBase';

export * from './asset/AssetHistoryContent';

export * from './asset/AssetMeasureOrigin';

export * from './device/DeviceContent';

export * from './device/DeviceMeasures';

export * from './decoders/DecodersContent';