From b8e5d92d823338694ff24e615f8585c2bc944966 Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Thu, 26 May 2022 02:15:32 +0200 Subject: [PATCH 01/25] chore!: bump tsc target to es2018 --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index f60306d3c..80c0127d3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es6", + "target": "es2018", "lib": ["dom"], "skipLibCheck": false, "module": "commonjs", From 10306847664c1b4786f1aea1ac2490db9edfb459 Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Thu, 26 May 2022 02:16:53 +0200 Subject: [PATCH 02/25] feat!: add proposal for new discovery API --- packages/core/src/wot-impl.ts | 61 ++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/packages/core/src/wot-impl.ts b/packages/core/src/wot-impl.ts index 55ac7265b..90268e26c 100644 --- a/packages/core/src/wot-impl.ts +++ b/packages/core/src/wot-impl.ts @@ -19,10 +19,58 @@ import Servient from "./servient"; import ExposedThing from "./exposed-thing"; import ConsumedThing from "./consumed-thing"; import Helpers from "./helpers"; +import { ThingDescription } from "wot-thing-description-types"; import { createLoggers } from "./logger"; const { debug } = createLoggers("core", "wot-impl"); +class ThingDiscoveryImpl implements AsyncIterable { + + filter: WoT.ThingFilter; + + active = true; + + constructor(filter: WoT.ThingFilter) { + this.filter = filter; + } + + async*[Symbol.asyncIterator](): AsyncIterator { + switch (this.filter.method) { + case "direct": { + if (!this.active) { + return; + } + + const response = await fetch(this.filter.url); + const parsedTd = await response.json(); + yield new Promise(resolve => resolve(parsedTd)); + break; + } + default: + throw Error("Only the direct discovery method has been implemented yet."); + } + } + + public stop(): void { + this.active = false; + } +} +/** + * wot-type-definitions does not contain a implementation of Discovery method enums + * so we need to create them here. Sadly, we should keep this enum in sync with + * WoT.DiscoveryMethod + */ +export enum DiscoveryMethod { + /** does not provide any restriction */ + "any", + /** for discovering Things defined in the same device */ + "local", + /** for discovery based on a service provided by a directory or repository of Things */ + "directory", + /** for discovering Things in the device's network by using a supported multicast protocol */ + "multicast", +} + export default class WoTImpl { private srv: Servient; constructor(srv: Servient) { @@ -30,17 +78,8 @@ export default class WoTImpl { } /** @inheritDoc */ - async discover(filter?: WoT.ThingFilter): Promise { - throw new Error("not implemented"); - } - - /** @inheritDoc */ - async exploreDirectory(url: string, filter?: WoT.ThingFilter): Promise { - throw new Error("not implemented"); - } - - async requestThingDescription(url: string): Promise { - throw new Error("not implemented"); + discover(filter?: WoT.ThingFilter): ThingDiscoveryImpl { + return new ThingDiscoveryImpl(filter); } /** @inheritDoc */ From 96be7f497c4bb76c6302664a9839e3ff7495522d Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Thu, 26 May 2022 03:03:49 +0200 Subject: [PATCH 03/25] fixup! feat!: add proposal for new discovery API This commit should probably be dropped --- packages/core/example/example.js | 11 +++++++++++ packages/core/src/wot-impl.ts | 6 +++--- 2 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 packages/core/example/example.js diff --git a/packages/core/example/example.js b/packages/core/example/example.js new file mode 100644 index 000000000..66c2ab044 --- /dev/null +++ b/packages/core/example/example.js @@ -0,0 +1,11 @@ +const { Servient } = require("@node-wot/core"); + +async function discover() { + const servient = new Servient(); + const wot = await servient.start(); + for await(const td of wot.discover({url: "http://plugfest.thingweb.io:8083/smart-coffee-machine", method: "direct"})) { + console.log(td); + } +} + +discover(); diff --git a/packages/core/src/wot-impl.ts b/packages/core/src/wot-impl.ts index 90268e26c..a1933b1b6 100644 --- a/packages/core/src/wot-impl.ts +++ b/packages/core/src/wot-impl.ts @@ -23,6 +23,7 @@ import { ThingDescription } from "wot-thing-description-types"; import { createLoggers } from "./logger"; const { debug } = createLoggers("core", "wot-impl"); +import fetch from "node-fetch"; class ThingDiscoveryImpl implements AsyncIterable { @@ -40,7 +41,6 @@ class ThingDiscoveryImpl implements AsyncIterable { if (!this.active) { return; } - const response = await fetch(this.filter.url); const parsedTd = await response.json(); yield new Promise(resolve => resolve(parsedTd)); @@ -78,8 +78,8 @@ export default class WoTImpl { } /** @inheritDoc */ - discover(filter?: WoT.ThingFilter): ThingDiscoveryImpl { - return new ThingDiscoveryImpl(filter); + discover(filter?: WoT.ThingFilter): WoT.ThingDiscovery { + return new ThingDiscoveryImpl(filter) as unknown as WoT.ThingDiscovery; } /** @inheritDoc */ From 7f403239548df7d60223dd98ae8242129223caf3 Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Thu, 26 May 2022 03:06:08 +0200 Subject: [PATCH 04/25] fixup! feat!: add proposal for new discovery API --- packages/core/src/wot-impl.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core/src/wot-impl.ts b/packages/core/src/wot-impl.ts index a1933b1b6..3be559653 100644 --- a/packages/core/src/wot-impl.ts +++ b/packages/core/src/wot-impl.ts @@ -43,6 +43,7 @@ class ThingDiscoveryImpl implements AsyncIterable { } const response = await fetch(this.filter.url); const parsedTd = await response.json(); + this.active = false; yield new Promise(resolve => resolve(parsedTd)); break; } From d68f9dfa6dd2565b0499f78b9b65cbec8aa3b1bb Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Thu, 26 May 2022 15:12:24 +0200 Subject: [PATCH 05/25] fixup! feat!: add proposal for new discovery API --- packages/binding-coap/src/coap-client.ts | 5 +++++ packages/binding-coap/src/coaps-client.ts | 5 +++++ packages/binding-file/src/file-client.ts | 5 +++++ packages/binding-http/src/http-client-impl.ts | 10 ++++++++++ packages/binding-mbus/src/mbus-client.ts | 5 +++++ packages/binding-modbus/src/modbus-client.ts | 5 +++++ packages/binding-mqtt/src/mqtt-client.ts | 5 +++++ .../binding-netconf/src/netconf-client.ts | 5 +++++ .../src/opcua-protocol-client.ts | 6 +++++- packages/binding-websockets/src/ws-client.ts | 5 +++++ packages/core/example/example.js | 9 ++++++++- packages/core/src/protocol-interfaces.ts | 3 +++ packages/core/src/wot-impl.ts | 19 +++++++++++-------- 13 files changed, 77 insertions(+), 10 deletions(-) diff --git a/packages/binding-coap/src/coap-client.ts b/packages/binding-coap/src/coap-client.ts index 4d0740ace..174d9a3c7 100644 --- a/packages/binding-coap/src/coap-client.ts +++ b/packages/binding-coap/src/coap-client.ts @@ -38,6 +38,7 @@ import { OutgoingMessage, ObserveReadStream, } from "coap"; +import { ThingDescription } from "wot-thing-description-types"; const { debug, warn } = createLoggers("binding-coap", "coap-client"); @@ -55,6 +56,10 @@ export default class CoapClient implements ProtocolClient { registerFormat(ContentSerdes.JSON_LD, 2100); } + discoverDirectly(uri: string): Promise { + throw new Error("Method not implemented."); + } + public toString(): string { return "[CoapClient]"; } diff --git a/packages/binding-coap/src/coaps-client.ts b/packages/binding-coap/src/coaps-client.ts index 2113c4f4f..5867c2bda 100644 --- a/packages/binding-coap/src/coaps-client.ts +++ b/packages/binding-coap/src/coaps-client.ts @@ -25,6 +25,7 @@ import { ProtocolClient, Content, createLoggers, ContentSerdes } from "@node-wot import { CoapForm, CoapMethodName, isValidCoapMethod, isSupportedCoapMethod } from "./coap"; import { CoapClient as coaps, CoapResponse, RequestMethod, SecurityParameters } from "node-coap-client"; import { Readable } from "stream"; +import { ThingDescription } from "wot-thing-description-types"; const { debug, warn, error } = createLoggers("binding-coap", "coaps-client"); @@ -235,4 +236,8 @@ export default class CoapsClient implements ProtocolClient { return req; } + + discoverDirectly(uri: string): Promise { + throw new Error("Method not implemented."); + } } diff --git a/packages/binding-file/src/file-client.ts b/packages/binding-file/src/file-client.ts index 31c3d005a..55e5fd0de 100644 --- a/packages/binding-file/src/file-client.ts +++ b/packages/binding-file/src/file-client.ts @@ -21,6 +21,7 @@ import { ProtocolClient, Content, createLoggers } from "@node-wot/core"; import { Subscription } from "rxjs/Subscription"; import fs = require("fs"); import path = require("path"); +import { ThingDescription } from "wot-typescript-definitions"; const { debug, warn } = createLoggers("binding-file", "file-client"); @@ -90,4 +91,8 @@ export default class FileClient implements ProtocolClient { } public setSecurity = (metadata: Array): boolean => false; + + discoverDirectly(uri: string): Promise { + throw new Error("Method not implemented."); + } } diff --git a/packages/binding-http/src/http-client-impl.ts b/packages/binding-http/src/http-client-impl.ts index de5c93182..eaa6c17dd 100644 --- a/packages/binding-http/src/http-client-impl.ts +++ b/packages/binding-http/src/http-client-impl.ts @@ -409,4 +409,14 @@ export default class HttpClient implements ProtocolClient { return url; } + + async discoverDirectly(uri: string): Promise { + // Note: This is still work in progress + const headers: HeadersInit = { + Accept: "application/td+json", + }; + const response = await fetch(uri, { headers }); + // TODO: Result should be validated + return await response.json(); + } } diff --git a/packages/binding-mbus/src/mbus-client.ts b/packages/binding-mbus/src/mbus-client.ts index 63a8c24cb..a68edecbe 100644 --- a/packages/binding-mbus/src/mbus-client.ts +++ b/packages/binding-mbus/src/mbus-client.ts @@ -23,6 +23,7 @@ import { SecurityScheme } from "@node-wot/td-tools"; import { MBusConnection, PropertyOperation } from "./mbus-connection"; import { Subscription } from "rxjs/Subscription"; +import { ThingDescription } from "wot-typescript-definitions"; const debug = createDebugLogger("binding-mbus", "mbus-client"); @@ -144,4 +145,8 @@ export default class MBusClient implements ProtocolClient { return result; } + + discoverDirectly(uri: string): Promise { + throw new Error("Method not implemented."); + } } diff --git a/packages/binding-modbus/src/modbus-client.ts b/packages/binding-modbus/src/modbus-client.ts index f375d227d..fbc95bdff 100644 --- a/packages/binding-modbus/src/modbus-client.ts +++ b/packages/binding-modbus/src/modbus-client.ts @@ -23,6 +23,7 @@ import { modbusFunctionToEntity } from "./utils"; import { ModbusConnection, ModbusFormWithDefaults, PropertyOperation } from "./modbus-connection"; import { Readable } from "stream"; import { Subscription } from "rxjs/Subscription"; +import { ThingDescription } from "wot-typescript-definitions"; const debug = createDebugLogger("binding-modbus", "modbus-client"); @@ -309,4 +310,8 @@ export default class ModbusClient implements ProtocolClient { return result as ModbusFormWithDefaults; } + + discoverDirectly(uri: string): Promise { + throw new Error("Method not implemented."); + } } diff --git a/packages/binding-mqtt/src/mqtt-client.ts b/packages/binding-mqtt/src/mqtt-client.ts index ef3b5d1c9..c0b352c21 100644 --- a/packages/binding-mqtt/src/mqtt-client.ts +++ b/packages/binding-mqtt/src/mqtt-client.ts @@ -25,6 +25,7 @@ import { IPublishPacket, QoS } from "mqtt"; import * as url from "url"; import { Subscription } from "rxjs/Subscription"; import { Readable } from "stream"; +import { ThingDescription } from "wot-typescript-definitions"; const { debug, warn } = createLoggers("binding-mqtt", "mqtt-client"); @@ -199,4 +200,8 @@ export default class MqttClient implements ProtocolClient { return (qos = 0); } } + + discoverDirectly(uri: string): Promise { + throw new Error("Method not implemented."); + } } diff --git a/packages/binding-netconf/src/netconf-client.ts b/packages/binding-netconf/src/netconf-client.ts index 90d8892cb..5b67840eb 100644 --- a/packages/binding-netconf/src/netconf-client.ts +++ b/packages/binding-netconf/src/netconf-client.ts @@ -23,6 +23,7 @@ import * as AsyncNodeNetcon from "./async-node-netconf"; import Url from "url-parse"; import { Readable } from "stream"; import { Subscription } from "rxjs/Subscription"; +import { ThingDescription } from "wot-typescript-definitions"; const { debug, warn } = createLoggers("binding-netconf", "netconf-client"); @@ -175,4 +176,8 @@ export default class NetconfClient implements ProtocolClient { this.credentials = credentials; return true; } + + discoverDirectly(uri: string): Promise { + throw new Error("Method not implemented."); + } } diff --git a/packages/binding-opcua/src/opcua-protocol-client.ts b/packages/binding-opcua/src/opcua-protocol-client.ts index 524564c1c..00b58b9f7 100644 --- a/packages/binding-opcua/src/opcua-protocol-client.ts +++ b/packages/binding-opcua/src/opcua-protocol-client.ts @@ -45,7 +45,7 @@ import { makeBrowsePath } from "node-opcua-service-translate-browse-path"; import { StatusCodes } from "node-opcua-status-code"; import { schemaDataValue } from "./codec"; -import { FormElementProperty } from "wot-thing-description-types"; +import { FormElementProperty, ThingDescription } from "wot-thing-description-types"; import { opcuaJsonEncodeVariant } from "node-opcua-json"; import { Argument, BrowseDescription, BrowseResult } from "node-opcua-types"; import { isGoodish2, ReferenceTypeIds } from "node-opcua"; @@ -620,4 +620,8 @@ export class OPCUAProtocolClient implements ProtocolClient { return new Content("application/json", Readable.from(JSON.stringify(body))); } + + discoverDirectly(uri: string): Promise { + throw new Error("Method not implemented."); + } } diff --git a/packages/binding-websockets/src/ws-client.ts b/packages/binding-websockets/src/ws-client.ts index cdf79dd12..12b93391b 100644 --- a/packages/binding-websockets/src/ws-client.ts +++ b/packages/binding-websockets/src/ws-client.ts @@ -20,6 +20,7 @@ import { ProtocolClient, Content, createLoggers } from "@node-wot/core"; import { Form, SecurityScheme } from "@node-wot/td-tools"; import { Subscription } from "rxjs/Subscription"; +import { ThingDescription } from "wot-thing-description-types"; const { debug, warn } = createLoggers("binding-websockets", "ws-client"); @@ -29,6 +30,10 @@ export default class WebSocketClient implements ProtocolClient { // TODO: implement and remove eslint-ignore-useless-constructor } + discoverDirectly(uri: string): Promise { + throw new Error("Method not implemented."); + } + public toString(): string { return `[WebSocketClient]`; } diff --git a/packages/core/example/example.js b/packages/core/example/example.js index 66c2ab044..c14d35caf 100644 --- a/packages/core/example/example.js +++ b/packages/core/example/example.js @@ -1,9 +1,16 @@ const { Servient } = require("@node-wot/core"); +const { HttpClientFactory } = require("@node-wot/binding-http"); +// Note: This example is just for testing/demonstration purposes and +// will eventually be moved to the examples package. async function discover() { const servient = new Servient(); + servient.addClientFactory(new HttpClientFactory()); const wot = await servient.start(); - for await(const td of wot.discover({url: "http://plugfest.thingweb.io:8083/smart-coffee-machine", method: "direct"})) { + for await (const td of wot.discover({ + url: "http://plugfest.thingweb.io:8083/smart-coffee-machine", + method: "direct", + })) { console.log(td); } } diff --git a/packages/core/src/protocol-interfaces.ts b/packages/core/src/protocol-interfaces.ts index 68ded1233..21e721dcb 100644 --- a/packages/core/src/protocol-interfaces.ts +++ b/packages/core/src/protocol-interfaces.ts @@ -20,6 +20,7 @@ import { Subscription } from "rxjs/Subscription"; import Servient from "./servient"; import ExposedThing from "./exposed-thing"; import { Content } from "./content"; +import { ThingDescription } from "wot-typescript-definitions"; export type PropertyContentMap = Map; @@ -59,6 +60,8 @@ export interface ProtocolClient { /** this client is requested to perform an "unlink" on the resource with the given URI */ unlinkResource(form: TD.Form): Promise; + discoverDirectly(uri: string): Promise; + subscribeResource( form: TD.Form, next: (content: Content) => void, diff --git a/packages/core/src/wot-impl.ts b/packages/core/src/wot-impl.ts index 3be559653..f1d1aae93 100644 --- a/packages/core/src/wot-impl.ts +++ b/packages/core/src/wot-impl.ts @@ -23,28 +23,31 @@ import { ThingDescription } from "wot-thing-description-types"; import { createLoggers } from "./logger"; const { debug } = createLoggers("core", "wot-impl"); -import fetch from "node-fetch"; class ThingDiscoveryImpl implements AsyncIterable { - filter: WoT.ThingFilter; active = true; - constructor(filter: WoT.ThingFilter) { + private servient: Servient; + + constructor(filter: WoT.ThingFilter, servient: Servient) { this.filter = filter; + this.servient = servient; } - async*[Symbol.asyncIterator](): AsyncIterator { + async *[Symbol.asyncIterator](): AsyncIterator { switch (this.filter.method) { case "direct": { if (!this.active) { return; } - const response = await fetch(this.filter.url); - const parsedTd = await response.json(); + // TODO: This needs to refactored + const uriScheme = new URL(this.filter.url).protocol.split(":")[0]; + const client = this.servient.getClientFor(uriScheme); + const thingDescription = client.discoverDirectly(this.filter.url); this.active = false; - yield new Promise(resolve => resolve(parsedTd)); + yield new Promise((resolve) => resolve(thingDescription)); break; } default: @@ -80,7 +83,7 @@ export default class WoTImpl { /** @inheritDoc */ discover(filter?: WoT.ThingFilter): WoT.ThingDiscovery { - return new ThingDiscoveryImpl(filter) as unknown as WoT.ThingDiscovery; + return new ThingDiscoveryImpl(filter, this.srv) as unknown as WoT.ThingDiscovery; } /** @inheritDoc */ From 880558eaab2ecfa4f34a57c33bf3221991738c05 Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Thu, 26 May 2022 15:26:13 +0200 Subject: [PATCH 06/25] fixup! feat!: add proposal for new discovery API --- packages/core/test/ClientTest.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/core/test/ClientTest.ts b/packages/core/test/ClientTest.ts index 56a28678a..2768ee7e6 100644 --- a/packages/core/test/ClientTest.ts +++ b/packages/core/test/ClientTest.ts @@ -169,6 +169,10 @@ class TDClient implements ProtocolClient { public toString(): string { return "TDClient"; } + + discoverDirectly(uri: string): Promise { + return Promise.reject(new Error("discoverDirectly not implemented")); + } } class TDClientFactory implements ProtocolClientFactory { @@ -239,6 +243,10 @@ class TrapClient implements ProtocolClient { } public setSecurity = (metadata: SecurityScheme[]) => false; + + discoverDirectly(uri: string): Promise { + return Promise.reject(new Error("discoverDirectly not implemented")); + } } class TrapClientFactory implements ProtocolClientFactory { @@ -306,6 +314,10 @@ class TestProtocolClient implements ProtocolClient { this.securitySchemes = securitySchemes; return true; } + + discoverDirectly(uri: string): Promise { + return Promise.reject(new Error("discoverDirectly not implemented")); + } } @suite("client flow of servient") From d1ec05f30c9742746def9f54750ad6ab0cf362e9 Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Thu, 26 May 2022 15:50:33 +0200 Subject: [PATCH 07/25] fixup! feat!: add proposal for new discovery API --- packages/core/example/example.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/example/example.js b/packages/core/example/example.js index c14d35caf..dc7e50e89 100644 --- a/packages/core/example/example.js +++ b/packages/core/example/example.js @@ -2,7 +2,7 @@ const { Servient } = require("@node-wot/core"); const { HttpClientFactory } = require("@node-wot/binding-http"); // Note: This example is just for testing/demonstration purposes and -// will eventually be moved to the examples package. +// will eventually be removed/moved to the examples package. async function discover() { const servient = new Servient(); servient.addClientFactory(new HttpClientFactory()); From 37a16206550c213dad8949a267db0eb8fc8c1fad Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Tue, 9 Aug 2022 18:09:24 +0200 Subject: [PATCH 08/25] fixup! feat!: add proposal for new discovery API --- packages/binding-coap/src/coap-client.ts | 2 +- packages/binding-coap/src/coaps-client.ts | 2 +- packages/binding-file/src/file-client.ts | 2 +- packages/binding-mbus/src/mbus-client.ts | 2 +- packages/binding-modbus/src/modbus-client.ts | 2 +- packages/binding-mqtt/src/mqtt-client.ts | 2 +- packages/binding-netconf/src/netconf-client.ts | 2 +- packages/binding-opcua/src/opcua-protocol-client.ts | 2 +- packages/binding-websockets/src/ws-client.ts | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/binding-coap/src/coap-client.ts b/packages/binding-coap/src/coap-client.ts index 174d9a3c7..339f621cb 100644 --- a/packages/binding-coap/src/coap-client.ts +++ b/packages/binding-coap/src/coap-client.ts @@ -57,7 +57,7 @@ export default class CoapClient implements ProtocolClient { } discoverDirectly(uri: string): Promise { - throw new Error("Method not implemented."); + return Promise.reject(new Error("Method not implemented.")); } public toString(): string { diff --git a/packages/binding-coap/src/coaps-client.ts b/packages/binding-coap/src/coaps-client.ts index 5867c2bda..008ef7847 100644 --- a/packages/binding-coap/src/coaps-client.ts +++ b/packages/binding-coap/src/coaps-client.ts @@ -238,6 +238,6 @@ export default class CoapsClient implements ProtocolClient { } discoverDirectly(uri: string): Promise { - throw new Error("Method not implemented."); + return Promise.reject(new Error("Method not implemented.")); } } diff --git a/packages/binding-file/src/file-client.ts b/packages/binding-file/src/file-client.ts index 55e5fd0de..c1a25af0f 100644 --- a/packages/binding-file/src/file-client.ts +++ b/packages/binding-file/src/file-client.ts @@ -93,6 +93,6 @@ export default class FileClient implements ProtocolClient { public setSecurity = (metadata: Array): boolean => false; discoverDirectly(uri: string): Promise { - throw new Error("Method not implemented."); + return Promise.reject(new Error("Method not implemented.")); } } diff --git a/packages/binding-mbus/src/mbus-client.ts b/packages/binding-mbus/src/mbus-client.ts index a68edecbe..8bfa51597 100644 --- a/packages/binding-mbus/src/mbus-client.ts +++ b/packages/binding-mbus/src/mbus-client.ts @@ -147,6 +147,6 @@ export default class MBusClient implements ProtocolClient { } discoverDirectly(uri: string): Promise { - throw new Error("Method not implemented."); + return Promise.reject(new Error("Method not implemented.")); } } diff --git a/packages/binding-modbus/src/modbus-client.ts b/packages/binding-modbus/src/modbus-client.ts index fbc95bdff..52892fb3a 100644 --- a/packages/binding-modbus/src/modbus-client.ts +++ b/packages/binding-modbus/src/modbus-client.ts @@ -312,6 +312,6 @@ export default class ModbusClient implements ProtocolClient { } discoverDirectly(uri: string): Promise { - throw new Error("Method not implemented."); + return Promise.reject(new Error("Method not implemented.")); } } diff --git a/packages/binding-mqtt/src/mqtt-client.ts b/packages/binding-mqtt/src/mqtt-client.ts index c0b352c21..7d94d2710 100644 --- a/packages/binding-mqtt/src/mqtt-client.ts +++ b/packages/binding-mqtt/src/mqtt-client.ts @@ -202,6 +202,6 @@ export default class MqttClient implements ProtocolClient { } discoverDirectly(uri: string): Promise { - throw new Error("Method not implemented."); + return Promise.reject(new Error("Method not implemented.")); } } diff --git a/packages/binding-netconf/src/netconf-client.ts b/packages/binding-netconf/src/netconf-client.ts index 5b67840eb..9973bbbc1 100644 --- a/packages/binding-netconf/src/netconf-client.ts +++ b/packages/binding-netconf/src/netconf-client.ts @@ -178,6 +178,6 @@ export default class NetconfClient implements ProtocolClient { } discoverDirectly(uri: string): Promise { - throw new Error("Method not implemented."); + return Promise.reject(new Error("Method not implemented.")); } } diff --git a/packages/binding-opcua/src/opcua-protocol-client.ts b/packages/binding-opcua/src/opcua-protocol-client.ts index 00b58b9f7..9248d9f40 100644 --- a/packages/binding-opcua/src/opcua-protocol-client.ts +++ b/packages/binding-opcua/src/opcua-protocol-client.ts @@ -622,6 +622,6 @@ export class OPCUAProtocolClient implements ProtocolClient { } discoverDirectly(uri: string): Promise { - throw new Error("Method not implemented."); + return Promise.reject(new Error("Method not implemented.")); } } diff --git a/packages/binding-websockets/src/ws-client.ts b/packages/binding-websockets/src/ws-client.ts index 12b93391b..f6400ab95 100644 --- a/packages/binding-websockets/src/ws-client.ts +++ b/packages/binding-websockets/src/ws-client.ts @@ -31,7 +31,7 @@ export default class WebSocketClient implements ProtocolClient { } discoverDirectly(uri: string): Promise { - throw new Error("Method not implemented."); + return Promise.reject(new Error("Method not implemented.")); } public toString(): string { From 6ee7d4bf52320a04a00de8f2b3a84b9b4a4458a2 Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Tue, 9 Aug 2022 18:34:47 +0200 Subject: [PATCH 09/25] fixup! feat!: add proposal for new discovery API --- packages/binding-coap/src/coap-client.ts | 19 ++++++++++++++++--- packages/binding-coap/src/coaps-client.ts | 3 +-- packages/binding-file/src/file-client.ts | 3 +-- packages/binding-http/src/http-client-impl.ts | 5 +++-- packages/binding-mbus/src/mbus-client.ts | 3 +-- packages/binding-modbus/src/modbus-client.ts | 3 +-- packages/binding-mqtt/src/mqtt-client.ts | 3 +-- .../binding-netconf/src/netconf-client.ts | 3 +-- .../src/opcua-protocol-client.ts | 4 ++-- packages/binding-websockets/src/ws-client.ts | 3 +-- packages/core/src/protocol-interfaces.ts | 2 +- packages/core/src/wot-impl.ts | 7 +++++-- 12 files changed, 34 insertions(+), 24 deletions(-) diff --git a/packages/binding-coap/src/coap-client.ts b/packages/binding-coap/src/coap-client.ts index 339f621cb..bcc9d69cc 100644 --- a/packages/binding-coap/src/coap-client.ts +++ b/packages/binding-coap/src/coap-client.ts @@ -38,7 +38,6 @@ import { OutgoingMessage, ObserveReadStream, } from "coap"; -import { ThingDescription } from "wot-thing-description-types"; const { debug, warn } = createLoggers("binding-coap", "coap-client"); @@ -56,8 +55,22 @@ export default class CoapClient implements ProtocolClient { registerFormat(ContentSerdes.JSON_LD, 2100); } - discoverDirectly(uri: string): Promise { - return Promise.reject(new Error("Method not implemented.")); + discoverDirectly(uri: string): Promise { + const options: CoapRequestParams = this.uriToOptions(uri); + const req = this.agent.request(options); + + req.setOption("Accept", "application/td+json"); + return new Promise((resolve, reject) => { + req.on("response", (res: IncomingMessage) => { + let contentType = res.headers["Content-Format"]; + if (typeof contentType !== "string") { + contentType = "application/td+json"; + } + resolve({ type: contentType, body: Readable.from(res.payload) }); + }); + req.on("error", (err: Error) => reject(err)); + req.end(); + }); } public toString(): string { diff --git a/packages/binding-coap/src/coaps-client.ts b/packages/binding-coap/src/coaps-client.ts index 008ef7847..0e47ebca3 100644 --- a/packages/binding-coap/src/coaps-client.ts +++ b/packages/binding-coap/src/coaps-client.ts @@ -25,7 +25,6 @@ import { ProtocolClient, Content, createLoggers, ContentSerdes } from "@node-wot import { CoapForm, CoapMethodName, isValidCoapMethod, isSupportedCoapMethod } from "./coap"; import { CoapClient as coaps, CoapResponse, RequestMethod, SecurityParameters } from "node-coap-client"; import { Readable } from "stream"; -import { ThingDescription } from "wot-thing-description-types"; const { debug, warn, error } = createLoggers("binding-coap", "coaps-client"); @@ -237,7 +236,7 @@ export default class CoapsClient implements ProtocolClient { return req; } - discoverDirectly(uri: string): Promise { + discoverDirectly(uri: string): Promise { return Promise.reject(new Error("Method not implemented.")); } } diff --git a/packages/binding-file/src/file-client.ts b/packages/binding-file/src/file-client.ts index c1a25af0f..c7bcaae4b 100644 --- a/packages/binding-file/src/file-client.ts +++ b/packages/binding-file/src/file-client.ts @@ -21,7 +21,6 @@ import { ProtocolClient, Content, createLoggers } from "@node-wot/core"; import { Subscription } from "rxjs/Subscription"; import fs = require("fs"); import path = require("path"); -import { ThingDescription } from "wot-typescript-definitions"; const { debug, warn } = createLoggers("binding-file", "file-client"); @@ -92,7 +91,7 @@ export default class FileClient implements ProtocolClient { public setSecurity = (metadata: Array): boolean => false; - discoverDirectly(uri: string): Promise { + discoverDirectly(uri: string): Promise { return Promise.reject(new Error("Method not implemented.")); } } diff --git a/packages/binding-http/src/http-client-impl.ts b/packages/binding-http/src/http-client-impl.ts index eaa6c17dd..45f9d3168 100644 --- a/packages/binding-http/src/http-client-impl.ts +++ b/packages/binding-http/src/http-client-impl.ts @@ -410,13 +410,14 @@ export default class HttpClient implements ProtocolClient { return url; } - async discoverDirectly(uri: string): Promise { + async discoverDirectly(uri: string): Promise { // Note: This is still work in progress const headers: HeadersInit = { Accept: "application/td+json", }; const response = await fetch(uri, { headers }); // TODO: Result should be validated - return await response.json(); + const body = ProtocolHelpers.toNodeStream(response.body as Readable); + return { type: response.headers.get("content-type"), body }; } } diff --git a/packages/binding-mbus/src/mbus-client.ts b/packages/binding-mbus/src/mbus-client.ts index 8bfa51597..b26ffc217 100644 --- a/packages/binding-mbus/src/mbus-client.ts +++ b/packages/binding-mbus/src/mbus-client.ts @@ -23,7 +23,6 @@ import { SecurityScheme } from "@node-wot/td-tools"; import { MBusConnection, PropertyOperation } from "./mbus-connection"; import { Subscription } from "rxjs/Subscription"; -import { ThingDescription } from "wot-typescript-definitions"; const debug = createDebugLogger("binding-mbus", "mbus-client"); @@ -146,7 +145,7 @@ export default class MBusClient implements ProtocolClient { return result; } - discoverDirectly(uri: string): Promise { + discoverDirectly(uri: string): Promise { return Promise.reject(new Error("Method not implemented.")); } } diff --git a/packages/binding-modbus/src/modbus-client.ts b/packages/binding-modbus/src/modbus-client.ts index 52892fb3a..4e8811da5 100644 --- a/packages/binding-modbus/src/modbus-client.ts +++ b/packages/binding-modbus/src/modbus-client.ts @@ -23,7 +23,6 @@ import { modbusFunctionToEntity } from "./utils"; import { ModbusConnection, ModbusFormWithDefaults, PropertyOperation } from "./modbus-connection"; import { Readable } from "stream"; import { Subscription } from "rxjs/Subscription"; -import { ThingDescription } from "wot-typescript-definitions"; const debug = createDebugLogger("binding-modbus", "modbus-client"); @@ -311,7 +310,7 @@ export default class ModbusClient implements ProtocolClient { return result as ModbusFormWithDefaults; } - discoverDirectly(uri: string): Promise { + discoverDirectly(uri: string): Promise { return Promise.reject(new Error("Method not implemented.")); } } diff --git a/packages/binding-mqtt/src/mqtt-client.ts b/packages/binding-mqtt/src/mqtt-client.ts index 7d94d2710..53237bb44 100644 --- a/packages/binding-mqtt/src/mqtt-client.ts +++ b/packages/binding-mqtt/src/mqtt-client.ts @@ -25,7 +25,6 @@ import { IPublishPacket, QoS } from "mqtt"; import * as url from "url"; import { Subscription } from "rxjs/Subscription"; import { Readable } from "stream"; -import { ThingDescription } from "wot-typescript-definitions"; const { debug, warn } = createLoggers("binding-mqtt", "mqtt-client"); @@ -201,7 +200,7 @@ export default class MqttClient implements ProtocolClient { } } - discoverDirectly(uri: string): Promise { + discoverDirectly(uri: string): Promise { return Promise.reject(new Error("Method not implemented.")); } } diff --git a/packages/binding-netconf/src/netconf-client.ts b/packages/binding-netconf/src/netconf-client.ts index 9973bbbc1..27b2c74dc 100644 --- a/packages/binding-netconf/src/netconf-client.ts +++ b/packages/binding-netconf/src/netconf-client.ts @@ -23,7 +23,6 @@ import * as AsyncNodeNetcon from "./async-node-netconf"; import Url from "url-parse"; import { Readable } from "stream"; import { Subscription } from "rxjs/Subscription"; -import { ThingDescription } from "wot-typescript-definitions"; const { debug, warn } = createLoggers("binding-netconf", "netconf-client"); @@ -177,7 +176,7 @@ export default class NetconfClient implements ProtocolClient { return true; } - discoverDirectly(uri: string): Promise { + discoverDirectly(uri: string): Promise { return Promise.reject(new Error("Method not implemented.")); } } diff --git a/packages/binding-opcua/src/opcua-protocol-client.ts b/packages/binding-opcua/src/opcua-protocol-client.ts index 9248d9f40..7c053c57d 100644 --- a/packages/binding-opcua/src/opcua-protocol-client.ts +++ b/packages/binding-opcua/src/opcua-protocol-client.ts @@ -45,7 +45,7 @@ import { makeBrowsePath } from "node-opcua-service-translate-browse-path"; import { StatusCodes } from "node-opcua-status-code"; import { schemaDataValue } from "./codec"; -import { FormElementProperty, ThingDescription } from "wot-thing-description-types"; +import { FormElementProperty } from "wot-thing-description-types"; import { opcuaJsonEncodeVariant } from "node-opcua-json"; import { Argument, BrowseDescription, BrowseResult } from "node-opcua-types"; import { isGoodish2, ReferenceTypeIds } from "node-opcua"; @@ -621,7 +621,7 @@ export class OPCUAProtocolClient implements ProtocolClient { return new Content("application/json", Readable.from(JSON.stringify(body))); } - discoverDirectly(uri: string): Promise { + discoverDirectly(uri: string): Promise { return Promise.reject(new Error("Method not implemented.")); } } diff --git a/packages/binding-websockets/src/ws-client.ts b/packages/binding-websockets/src/ws-client.ts index f6400ab95..7a3f4c1f6 100644 --- a/packages/binding-websockets/src/ws-client.ts +++ b/packages/binding-websockets/src/ws-client.ts @@ -20,7 +20,6 @@ import { ProtocolClient, Content, createLoggers } from "@node-wot/core"; import { Form, SecurityScheme } from "@node-wot/td-tools"; import { Subscription } from "rxjs/Subscription"; -import { ThingDescription } from "wot-thing-description-types"; const { debug, warn } = createLoggers("binding-websockets", "ws-client"); @@ -30,7 +29,7 @@ export default class WebSocketClient implements ProtocolClient { // TODO: implement and remove eslint-ignore-useless-constructor } - discoverDirectly(uri: string): Promise { + discoverDirectly(uri: string): Promise { return Promise.reject(new Error("Method not implemented.")); } diff --git a/packages/core/src/protocol-interfaces.ts b/packages/core/src/protocol-interfaces.ts index 21e721dcb..364adc403 100644 --- a/packages/core/src/protocol-interfaces.ts +++ b/packages/core/src/protocol-interfaces.ts @@ -60,7 +60,7 @@ export interface ProtocolClient { /** this client is requested to perform an "unlink" on the resource with the given URI */ unlinkResource(form: TD.Form): Promise; - discoverDirectly(uri: string): Promise; + discoverDirectly(uri: string): Promise; subscribeResource( form: TD.Form, diff --git a/packages/core/src/wot-impl.ts b/packages/core/src/wot-impl.ts index f1d1aae93..71db14f9a 100644 --- a/packages/core/src/wot-impl.ts +++ b/packages/core/src/wot-impl.ts @@ -21,6 +21,7 @@ import ConsumedThing from "./consumed-thing"; import Helpers from "./helpers"; import { ThingDescription } from "wot-thing-description-types"; import { createLoggers } from "./logger"; +import contentSerdes from "./content-serdes"; const { debug } = createLoggers("core", "wot-impl"); @@ -45,9 +46,11 @@ class ThingDiscoveryImpl implements AsyncIterable { // TODO: This needs to refactored const uriScheme = new URL(this.filter.url).protocol.split(":")[0]; const client = this.servient.getClientFor(uriScheme); - const thingDescription = client.discoverDirectly(this.filter.url); + const result = await client.discoverDirectly(this.filter.url); + // TODO: Add TD validation + const thingDescription = contentSerdes.contentToValue(result as any, {}); this.active = false; - yield new Promise((resolve) => resolve(thingDescription)); + yield new Promise((resolve) => resolve(thingDescription as ThingDescription)); break; } default: From cf5a3914ae596f49a1c4f1a386b57c8b5d82fe03 Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Tue, 9 Aug 2022 19:12:10 +0200 Subject: [PATCH 10/25] fixup! feat!: add proposal for new discovery API --- packages/core/example/example.js | 18 +++++++++++++----- packages/core/src/wot-impl.ts | 23 +++++++++++++++-------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/packages/core/example/example.js b/packages/core/example/example.js index dc7e50e89..dfcaa955d 100644 --- a/packages/core/example/example.js +++ b/packages/core/example/example.js @@ -1,17 +1,25 @@ const { Servient } = require("@node-wot/core"); const { HttpClientFactory } = require("@node-wot/binding-http"); +const { CoapClientFactory } = require("@node-wot/binding-coap"); // Note: This example is just for testing/demonstration purposes and // will eventually be removed/moved to the examples package. async function discover() { const servient = new Servient(); servient.addClientFactory(new HttpClientFactory()); + servient.addClientFactory(new CoapClientFactory()); const wot = await servient.start(); - for await (const td of wot.discover({ - url: "http://plugfest.thingweb.io:8083/smart-coffee-machine", - method: "direct", - })) { - console.log(td); + + const httpUrl = "http://plugfest.thingweb.io:8083/smart-coffee-machine"; + const coapUrl = "coap://plugfest.thingweb.io:5683/smart-coffee-machine"; + + for (const url of [httpUrl, coapUrl]) { + for await (const td of wot.discover({ + url, + method: "direct", + })) { + console.log(td); + } } } diff --git a/packages/core/src/wot-impl.ts b/packages/core/src/wot-impl.ts index 71db14f9a..f6ee8b224 100644 --- a/packages/core/src/wot-impl.ts +++ b/packages/core/src/wot-impl.ts @@ -21,7 +21,9 @@ import ConsumedThing from "./consumed-thing"; import Helpers from "./helpers"; import { ThingDescription } from "wot-thing-description-types"; import { createLoggers } from "./logger"; -import contentSerdes from "./content-serdes"; +import ContentManager from "./content-serdes"; +import { InteractionOutput } from "./interaction-output"; +import ProtocolHelpers from "./protocol-helpers"; const { debug } = createLoggers("core", "wot-impl"); @@ -40,17 +42,21 @@ class ThingDiscoveryImpl implements AsyncIterable { async *[Symbol.asyncIterator](): AsyncIterator { switch (this.filter.method) { case "direct": { - if (!this.active) { + const url = this.filter.url; + if (!this.active || url == null) { return; } - // TODO: This needs to refactored - const uriScheme = new URL(this.filter.url).protocol.split(":")[0]; + const uriScheme = new URL(url).protocol.split(":")[0]; const client = this.servient.getClientFor(uriScheme); - const result = await client.discoverDirectly(this.filter.url); + const result = await client.discoverDirectly(url); + const data = await ProtocolHelpers.readStreamFully(result.body); + // TODO: Add TD validation - const thingDescription = contentSerdes.contentToValue(result as any, {}); + // FIXME: application/td+json can't be handled at the moment + + const value = ContentManager.contentToValue({ type: "application/json", body: data }, {}); this.active = false; - yield new Promise((resolve) => resolve(thingDescription as ThingDescription)); + yield new Promise((resolve) => resolve(value as ThingDescription)); break; } default: @@ -86,7 +92,8 @@ export default class WoTImpl { /** @inheritDoc */ discover(filter?: WoT.ThingFilter): WoT.ThingDiscovery { - return new ThingDiscoveryImpl(filter, this.srv) as unknown as WoT.ThingDiscovery; + // TODO: Should filter really be nullable? + return new ThingDiscoveryImpl(filter as any, this.srv) as unknown as WoT.ThingDiscovery; } /** @inheritDoc */ From 734f86b098c0f203b42b290059fc9f6343ad3a40 Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Tue, 9 Aug 2022 19:17:37 +0200 Subject: [PATCH 11/25] fixup! feat!: add proposal for new discovery API --- packages/core/test/ClientTest.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/core/test/ClientTest.ts b/packages/core/test/ClientTest.ts index 2768ee7e6..b9dc67d1d 100644 --- a/packages/core/test/ClientTest.ts +++ b/packages/core/test/ClientTest.ts @@ -170,7 +170,7 @@ class TDClient implements ProtocolClient { return "TDClient"; } - discoverDirectly(uri: string): Promise { + discoverDirectly(uri: string): Promise { return Promise.reject(new Error("discoverDirectly not implemented")); } } @@ -244,7 +244,7 @@ class TrapClient implements ProtocolClient { public setSecurity = (metadata: SecurityScheme[]) => false; - discoverDirectly(uri: string): Promise { + discoverDirectly(uri: string): Promise { return Promise.reject(new Error("discoverDirectly not implemented")); } } @@ -315,7 +315,7 @@ class TestProtocolClient implements ProtocolClient { return true; } - discoverDirectly(uri: string): Promise { + discoverDirectly(uri: string): Promise { return Promise.reject(new Error("discoverDirectly not implemented")); } } From 04b7b2fe76c08dd1457584feb09c6957006e6a7c Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Tue, 9 Aug 2022 19:20:51 +0200 Subject: [PATCH 12/25] fixup! feat!: add proposal for new discovery API --- packages/core/src/wot-impl.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/src/wot-impl.ts b/packages/core/src/wot-impl.ts index f6ee8b224..b72b63f9c 100644 --- a/packages/core/src/wot-impl.ts +++ b/packages/core/src/wot-impl.ts @@ -22,7 +22,6 @@ import Helpers from "./helpers"; import { ThingDescription } from "wot-thing-description-types"; import { createLoggers } from "./logger"; import ContentManager from "./content-serdes"; -import { InteractionOutput } from "./interaction-output"; import ProtocolHelpers from "./protocol-helpers"; const { debug } = createLoggers("core", "wot-impl"); From 5440bea0c10c151266e13757dfc6669ce8470e72 Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Mon, 7 Nov 2022 16:10:07 +0100 Subject: [PATCH 13/25] fixup! feat!: add proposal for new discovery API --- packages/core/example/example.js | 12 ++--- packages/core/src/wot-impl.ts | 75 +++++++++++++++++--------------- 2 files changed, 48 insertions(+), 39 deletions(-) diff --git a/packages/core/example/example.js b/packages/core/example/example.js index dfcaa955d..c4bd661ba 100644 --- a/packages/core/example/example.js +++ b/packages/core/example/example.js @@ -14,11 +14,13 @@ async function discover() { const coapUrl = "coap://plugfest.thingweb.io:5683/smart-coffee-machine"; for (const url of [httpUrl, coapUrl]) { - for await (const td of wot.discover({ - url, - method: "direct", - })) { - console.log(td); + console.log(await wot.discovery.direct(url)); + } + + // Alternative approach + for (const url of [httpUrl, coapUrl]) { + for await (const result of wot.discovery.directIterator(url)) { + console.log(result); } } } diff --git a/packages/core/src/wot-impl.ts b/packages/core/src/wot-impl.ts index b72b63f9c..9c973b53b 100644 --- a/packages/core/src/wot-impl.ts +++ b/packages/core/src/wot-impl.ts @@ -26,47 +26,48 @@ import ProtocolHelpers from "./protocol-helpers"; const { debug } = createLoggers("core", "wot-impl"); -class ThingDiscoveryImpl implements AsyncIterable { - filter: WoT.ThingFilter; - - active = true; +class ThingDiscovery { private servient: Servient; - - constructor(filter: WoT.ThingFilter, servient: Servient) { - this.filter = filter; + constructor(servient: Servient) { this.servient = servient; } - async *[Symbol.asyncIterator](): AsyncIterator { - switch (this.filter.method) { - case "direct": { - const url = this.filter.url; - if (!this.active || url == null) { - return; - } - const uriScheme = new URL(url).protocol.split(":")[0]; - const client = this.servient.getClientFor(uriScheme); - const result = await client.discoverDirectly(url); - const data = await ProtocolHelpers.readStreamFully(result.body); - - // TODO: Add TD validation - // FIXME: application/td+json can't be handled at the moment - - const value = ContentManager.contentToValue({ type: "application/json", body: data }, {}); - this.active = false; - yield new Promise((resolve) => resolve(value as ThingDescription)); - break; - } - default: - throw Error("Only the direct discovery method has been implemented yet."); + async direct(url: string, filter?: WoT.ThingFilter): Promise { + const uriScheme = new URL(url).protocol.split(":")[0]; + const client = this.servient.getClientFor(uriScheme); + const result = await client.discoverDirectly(url); + const data = await ProtocolHelpers.readStreamFully(result.body); + + // TODO: Add TD validation + // FIXME: application/td+json can't be handled at the moment + + const value = ContentManager.contentToValue({ type: "application/json", body: data }, {}); + return new Promise((resolve) => resolve(value as ThingDescription)); + } + + // Alternative approach. + async *directIterator(url: string, filter?: WoT.ThingFilter): AsyncGenerator { + const uriScheme = new URL(url).protocol.split(":")[0]; + const client = this.servient.getClientFor(uriScheme); + const result = await client.discoverDirectly(url); + const data = await ProtocolHelpers.readStreamFully(result.body); + + // TODO: Add TD validation + // FIXME: application/td+json can't be handled at the moment + + const value = ContentManager.contentToValue({ type: "application/json", body: data }, {}); + + if (value instanceof Object) { + yield value as ThingDescription; } } - public stop(): void { - this.active = false; + async *directory(url: string, filter?: WoT.ThingFilter): AsyncGenerator { + // Not implemented, do nothing } } + /** * wot-type-definitions does not contain a implementation of Discovery method enums * so we need to create them here. Sadly, we should keep this enum in sync with @@ -85,14 +86,20 @@ export enum DiscoveryMethod { export default class WoTImpl { private srv: Servient; + DiscoveryMethod: typeof WoT.DiscoveryMethod; + + discovery: ThingDiscovery; + constructor(srv: Servient) { this.srv = srv; + // force casting cause tsc does not allow to use DiscoveryMethod as WoT.DiscoveryMethod even if they are the same + this.DiscoveryMethod = DiscoveryMethod as unknown as typeof WoT.DiscoveryMethod; + + this.discovery = new ThingDiscovery(srv); } - /** @inheritDoc */ discover(filter?: WoT.ThingFilter): WoT.ThingDiscovery { - // TODO: Should filter really be nullable? - return new ThingDiscoveryImpl(filter as any, this.srv) as unknown as WoT.ThingDiscovery; + throw new Error("REMOVE ME."); } /** @inheritDoc */ From db320c1daa1528e095593ea0e9f1b6018336707d Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Mon, 7 Nov 2022 16:56:38 +0100 Subject: [PATCH 14/25] fixup! feat!: add proposal for new discovery API --- packages/core/src/wot-impl.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/core/src/wot-impl.ts b/packages/core/src/wot-impl.ts index 9c973b53b..432ce829e 100644 --- a/packages/core/src/wot-impl.ts +++ b/packages/core/src/wot-impl.ts @@ -43,7 +43,11 @@ class ThingDiscovery { // FIXME: application/td+json can't be handled at the moment const value = ContentManager.contentToValue({ type: "application/json", body: data }, {}); - return new Promise((resolve) => resolve(value as ThingDescription)); + if (value instanceof Object) { + return value as ThingDescription; + } + + throw Error(`Could not parse Thing Description obtained from ${url}`); } // Alternative approach. From 74b0e3751967542d245a67a7652a11e3a5cab857 Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Mon, 7 Nov 2022 17:00:28 +0100 Subject: [PATCH 15/25] fixup! feat!: add proposal for new discovery API --- packages/binding-coap/src/coaps-client.ts | 4 ++-- packages/binding-file/src/file-client.ts | 4 ++-- packages/binding-mbus/src/mbus-client.ts | 4 ++-- packages/binding-modbus/src/modbus-client.ts | 4 ++-- packages/binding-mqtt/src/mqtt-client.ts | 4 ++-- packages/binding-netconf/src/netconf-client.ts | 4 ++-- packages/binding-opcua/src/opcua-protocol-client.ts | 4 ++-- packages/binding-websockets/src/ws-client.ts | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/binding-coap/src/coaps-client.ts b/packages/binding-coap/src/coaps-client.ts index 0e47ebca3..ea93d3318 100644 --- a/packages/binding-coap/src/coaps-client.ts +++ b/packages/binding-coap/src/coaps-client.ts @@ -236,7 +236,7 @@ export default class CoapsClient implements ProtocolClient { return req; } - discoverDirectly(uri: string): Promise { - return Promise.reject(new Error("Method not implemented.")); + async discoverDirectly(uri: string): Promise { + throw new Error("Method not implemented."); } } diff --git a/packages/binding-file/src/file-client.ts b/packages/binding-file/src/file-client.ts index c7bcaae4b..0b721adf5 100644 --- a/packages/binding-file/src/file-client.ts +++ b/packages/binding-file/src/file-client.ts @@ -91,7 +91,7 @@ export default class FileClient implements ProtocolClient { public setSecurity = (metadata: Array): boolean => false; - discoverDirectly(uri: string): Promise { - return Promise.reject(new Error("Method not implemented.")); + async discoverDirectly(uri: string): Promise { + throw new Error("Method not implemented."); } } diff --git a/packages/binding-mbus/src/mbus-client.ts b/packages/binding-mbus/src/mbus-client.ts index b26ffc217..ebd021c18 100644 --- a/packages/binding-mbus/src/mbus-client.ts +++ b/packages/binding-mbus/src/mbus-client.ts @@ -145,7 +145,7 @@ export default class MBusClient implements ProtocolClient { return result; } - discoverDirectly(uri: string): Promise { - return Promise.reject(new Error("Method not implemented.")); + async discoverDirectly(uri: string): Promise { + throw new Error("Method not implemented."); } } diff --git a/packages/binding-modbus/src/modbus-client.ts b/packages/binding-modbus/src/modbus-client.ts index 4e8811da5..207676aaa 100644 --- a/packages/binding-modbus/src/modbus-client.ts +++ b/packages/binding-modbus/src/modbus-client.ts @@ -310,7 +310,7 @@ export default class ModbusClient implements ProtocolClient { return result as ModbusFormWithDefaults; } - discoverDirectly(uri: string): Promise { - return Promise.reject(new Error("Method not implemented.")); + async discoverDirectly(uri: string): Promise { + throw new Error("Method not implemented."); } } diff --git a/packages/binding-mqtt/src/mqtt-client.ts b/packages/binding-mqtt/src/mqtt-client.ts index 53237bb44..8d7aba6b1 100644 --- a/packages/binding-mqtt/src/mqtt-client.ts +++ b/packages/binding-mqtt/src/mqtt-client.ts @@ -200,7 +200,7 @@ export default class MqttClient implements ProtocolClient { } } - discoverDirectly(uri: string): Promise { - return Promise.reject(new Error("Method not implemented.")); + async discoverDirectly(uri: string): Promise { + throw new Error("Method not implemented."); } } diff --git a/packages/binding-netconf/src/netconf-client.ts b/packages/binding-netconf/src/netconf-client.ts index 27b2c74dc..93d7cbdcf 100644 --- a/packages/binding-netconf/src/netconf-client.ts +++ b/packages/binding-netconf/src/netconf-client.ts @@ -176,7 +176,7 @@ export default class NetconfClient implements ProtocolClient { return true; } - discoverDirectly(uri: string): Promise { - return Promise.reject(new Error("Method not implemented.")); + async discoverDirectly(uri: string): Promise { + throw new Error("Method not implemented."); } } diff --git a/packages/binding-opcua/src/opcua-protocol-client.ts b/packages/binding-opcua/src/opcua-protocol-client.ts index 7c053c57d..37a1ae019 100644 --- a/packages/binding-opcua/src/opcua-protocol-client.ts +++ b/packages/binding-opcua/src/opcua-protocol-client.ts @@ -621,7 +621,7 @@ export class OPCUAProtocolClient implements ProtocolClient { return new Content("application/json", Readable.from(JSON.stringify(body))); } - discoverDirectly(uri: string): Promise { - return Promise.reject(new Error("Method not implemented.")); + async discoverDirectly(uri: string): Promise { + throw new Error("Method not implemented."); } } diff --git a/packages/binding-websockets/src/ws-client.ts b/packages/binding-websockets/src/ws-client.ts index 7a3f4c1f6..7938f35f9 100644 --- a/packages/binding-websockets/src/ws-client.ts +++ b/packages/binding-websockets/src/ws-client.ts @@ -29,8 +29,8 @@ export default class WebSocketClient implements ProtocolClient { // TODO: implement and remove eslint-ignore-useless-constructor } - discoverDirectly(uri: string): Promise { - return Promise.reject(new Error("Method not implemented.")); + async discoverDirectly(uri: string): Promise { + throw new Error("Method not implemented."); } public toString(): string { From 2207a91e87d3243527b571642b35998cc4bfad47 Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Mon, 7 Nov 2022 17:04:26 +0100 Subject: [PATCH 16/25] fixup! feat!: add proposal for new discovery API --- packages/core/test/ClientTest.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/core/test/ClientTest.ts b/packages/core/test/ClientTest.ts index b9dc67d1d..380114273 100644 --- a/packages/core/test/ClientTest.ts +++ b/packages/core/test/ClientTest.ts @@ -170,8 +170,8 @@ class TDClient implements ProtocolClient { return "TDClient"; } - discoverDirectly(uri: string): Promise { - return Promise.reject(new Error("discoverDirectly not implemented")); + async discoverDirectly(uri: string): Promise { + throw new Error("discoverDirectly not implemented."); } } @@ -244,8 +244,8 @@ class TrapClient implements ProtocolClient { public setSecurity = (metadata: SecurityScheme[]) => false; - discoverDirectly(uri: string): Promise { - return Promise.reject(new Error("discoverDirectly not implemented")); + async discoverDirectly(uri: string): Promise { + throw new Error("discoverDirectly not implemented."); } } @@ -315,8 +315,8 @@ class TestProtocolClient implements ProtocolClient { return true; } - discoverDirectly(uri: string): Promise { - return Promise.reject(new Error("discoverDirectly not implemented")); + async discoverDirectly(uri: string): Promise { + throw new Error("discoverDirectly not implemented."); } } From ad43508d8c6b10df1e8533ec66957677a761e03d Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Mon, 7 Nov 2022 17:15:32 +0100 Subject: [PATCH 17/25] fixup! feat!: add proposal for new discovery API --- packages/core/src/wot-impl.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/src/wot-impl.ts b/packages/core/src/wot-impl.ts index 432ce829e..a5fe3576c 100644 --- a/packages/core/src/wot-impl.ts +++ b/packages/core/src/wot-impl.ts @@ -27,7 +27,6 @@ import ProtocolHelpers from "./protocol-helpers"; const { debug } = createLoggers("core", "wot-impl"); class ThingDiscovery { - private servient: Servient; constructor(servient: Servient) { this.servient = servient; From b869b5ce51e648e687bf98a307bc73af70e42c80 Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Tue, 19 Sep 2023 08:19:40 +0200 Subject: [PATCH 18/25] fixup! feat!: add proposal for new discovery API --- packages/core/src/protocol-interfaces.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/src/protocol-interfaces.ts b/packages/core/src/protocol-interfaces.ts index 364adc403..5eb246866 100644 --- a/packages/core/src/protocol-interfaces.ts +++ b/packages/core/src/protocol-interfaces.ts @@ -20,7 +20,6 @@ import { Subscription } from "rxjs/Subscription"; import Servient from "./servient"; import ExposedThing from "./exposed-thing"; import { Content } from "./content"; -import { ThingDescription } from "wot-typescript-definitions"; export type PropertyContentMap = Map; From 961606ecd4d3e85d99902b0f2f202260c9448cf7 Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Tue, 19 Sep 2023 08:26:33 +0200 Subject: [PATCH 19/25] fixup! feat!: add proposal for new discovery API --- packages/binding-coap/src/coap-client.ts | 7 ++----- packages/binding-http/src/http-client-impl.ts | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/binding-coap/src/coap-client.ts b/packages/binding-coap/src/coap-client.ts index bcc9d69cc..c7156d7d6 100644 --- a/packages/binding-coap/src/coap-client.ts +++ b/packages/binding-coap/src/coap-client.ts @@ -62,11 +62,8 @@ export default class CoapClient implements ProtocolClient { req.setOption("Accept", "application/td+json"); return new Promise((resolve, reject) => { req.on("response", (res: IncomingMessage) => { - let contentType = res.headers["Content-Format"]; - if (typeof contentType !== "string") { - contentType = "application/td+json"; - } - resolve({ type: contentType, body: Readable.from(res.payload) }); + const contentType = (res.headers["Content-Format"] as string) ?? "application/td+json"; + resolve(new Content(contentType, Readable.from(res.payload))); }); req.on("error", (err: Error) => reject(err)); req.end(); diff --git a/packages/binding-http/src/http-client-impl.ts b/packages/binding-http/src/http-client-impl.ts index 45f9d3168..f489f77e0 100644 --- a/packages/binding-http/src/http-client-impl.ts +++ b/packages/binding-http/src/http-client-impl.ts @@ -418,6 +418,6 @@ export default class HttpClient implements ProtocolClient { const response = await fetch(uri, { headers }); // TODO: Result should be validated const body = ProtocolHelpers.toNodeStream(response.body as Readable); - return { type: response.headers.get("content-type"), body }; + return new Content(response.headers.get("content-type") ?? "application/td+json", body); } } From 950faa31a2e52d90a4d6a4a11c3cd6d9d6ecee7f Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Tue, 19 Sep 2023 09:15:33 +0200 Subject: [PATCH 20/25] fixup! feat!: add proposal for new discovery API --- packages/core/src/wot-impl.ts | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/core/src/wot-impl.ts b/packages/core/src/wot-impl.ts index a5fe3576c..3f51b4598 100644 --- a/packages/core/src/wot-impl.ts +++ b/packages/core/src/wot-impl.ts @@ -54,20 +54,33 @@ class ThingDiscovery { const uriScheme = new URL(url).protocol.split(":")[0]; const client = this.servient.getClientFor(uriScheme); const result = await client.discoverDirectly(url); - const data = await ProtocolHelpers.readStreamFully(result.body); // TODO: Add TD validation // FIXME: application/td+json can't be handled at the moment - const value = ContentManager.contentToValue({ type: "application/json", body: data }, {}); + const value = ContentManager.contentToValue({ type: "application/json", body: await result.toBuffer() }, {}); if (value instanceof Object) { yield value as ThingDescription; } } - async *directory(url: string, filter?: WoT.ThingFilter): AsyncGenerator { - // Not implemented, do nothing + async *exploreDirectory(url: string, filter?: WoT.ThingFilter): AsyncGenerator { + yield Promise.reject(new Error("Unimplemented")); + } + + async requestThingDescription(url: string): Promise { + const uriScheme = new URL(url).protocol.split(":")[0]; + const client = this.servient.getClientFor(uriScheme); + const result = await client.discoverDirectly(url); + + const value = ContentManager.contentToValue({ type: result.type, body: await result.toBuffer() }, {}); + + if (value instanceof Object) { + return value as ThingDescription; + } + + throw new Error("Not found."); } } From 56369833f7a0110b55b1dd48b9a89af88bba9304 Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Mon, 23 Oct 2023 12:27:44 +0200 Subject: [PATCH 21/25] fixup! feat!: add proposal for new discovery API --- packages/core/src/wot-impl.ts | 114 +++++++++++++--------------------- 1 file changed, 42 insertions(+), 72 deletions(-) diff --git a/packages/core/src/wot-impl.ts b/packages/core/src/wot-impl.ts index 3f51b4598..1d2b0fb62 100644 --- a/packages/core/src/wot-impl.ts +++ b/packages/core/src/wot-impl.ts @@ -22,100 +22,47 @@ import Helpers from "./helpers"; import { ThingDescription } from "wot-thing-description-types"; import { createLoggers } from "./logger"; import ContentManager from "./content-serdes"; -import ProtocolHelpers from "./protocol-helpers"; const { debug } = createLoggers("core", "wot-impl"); -class ThingDiscovery { - private servient: Servient; - constructor(servient: Servient) { - this.servient = servient; - } - - async direct(url: string, filter?: WoT.ThingFilter): Promise { - const uriScheme = new URL(url).protocol.split(":")[0]; - const client = this.servient.getClientFor(uriScheme); - const result = await client.discoverDirectly(url); - const data = await ProtocolHelpers.readStreamFully(result.body); +interface ThingFilter { + fragment?: object; +} - // TODO: Add TD validation - // FIXME: application/td+json can't be handled at the moment +class ThingDiscoveryProcess { + #done = false; - const value = ContentManager.contentToValue({ type: "application/json", body: data }, {}); - if (value instanceof Object) { - return value as ThingDescription; - } - - throw Error(`Could not parse Thing Description obtained from ${url}`); + get done() { + return this.#done; } - // Alternative approach. - async *directIterator(url: string, filter?: WoT.ThingFilter): AsyncGenerator { - const uriScheme = new URL(url).protocol.split(":")[0]; - const client = this.servient.getClientFor(uriScheme); - const result = await client.discoverDirectly(url); - - // TODO: Add TD validation - // FIXME: application/td+json can't be handled at the moment - - const value = ContentManager.contentToValue({ type: "application/json", body: await result.toBuffer() }, {}); + #error?: Error; - if (value instanceof Object) { - yield value as ThingDescription; - } + get error() { + return this.#error; } - async *exploreDirectory(url: string, filter?: WoT.ThingFilter): AsyncGenerator { - yield Promise.reject(new Error("Unimplemented")); - } + #filter: ThingFilter; - async requestThingDescription(url: string): Promise { - const uriScheme = new URL(url).protocol.split(":")[0]; - const client = this.servient.getClientFor(uriScheme); - const result = await client.discoverDirectly(url); - const value = ContentManager.contentToValue({ type: result.type, body: await result.toBuffer() }, {}); - if (value instanceof Object) { - return value as ThingDescription; - } + constructor(filter?: ThingFilter) { + this.#filter = filter ?? {}; + }; - throw new Error("Not found."); + stop(): void { + this.#done = true; } -} -/** - * wot-type-definitions does not contain a implementation of Discovery method enums - * so we need to create them here. Sadly, we should keep this enum in sync with - * WoT.DiscoveryMethod - */ -export enum DiscoveryMethod { - /** does not provide any restriction */ - "any", - /** for discovering Things defined in the same device */ - "local", - /** for discovery based on a service provided by a directory or repository of Things */ - "directory", - /** for discovering Things in the device's network by using a supported multicast protocol */ - "multicast", -} + // TODO: Implement AsyncIterable + // async iterable; + }; export default class WoTImpl { private srv: Servient; - DiscoveryMethod: typeof WoT.DiscoveryMethod; - - discovery: ThingDiscovery; constructor(srv: Servient) { this.srv = srv; - // force casting cause tsc does not allow to use DiscoveryMethod as WoT.DiscoveryMethod even if they are the same - this.DiscoveryMethod = DiscoveryMethod as unknown as typeof WoT.DiscoveryMethod; - - this.discovery = new ThingDiscovery(srv); - } - - discover(filter?: WoT.ThingFilter): WoT.ThingDiscovery { - throw new Error("REMOVE ME."); } /** @inheritDoc */ @@ -165,6 +112,29 @@ export default class WoTImpl { } }); } + + async discover(filter?: WoT.ThingFilter): Promise { + // TODO: Implement this function + return new ThingDiscoveryProcess(filter); + } + + async *exploreDirectory(url: string, filter?: WoT.ThingFilter): AsyncGenerator { + yield Promise.reject(new Error("Unimplemented")); + } + + async requestThingDescription(url: string): Promise { + const uriScheme = new URL(url).protocol.split(":")[0]; + const client = this.srv.getClientFor(uriScheme); + const result = await client.discoverDirectly(url); + + const value = ContentManager.contentToValue({ type: result.type, body: await result.toBuffer() }, {}); + + if (value instanceof Object) { + return value as ThingDescription; + } + + throw new Error("Not found."); + } } /** Instantiation of the WoT.DataType declaration */ From 88252f0e5bf665b132f683b29b138b8786e54a93 Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Mon, 23 Oct 2023 12:29:45 +0200 Subject: [PATCH 22/25] fixup! feat!: add proposal for new discovery API --- packages/core/src/wot-impl.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/core/src/wot-impl.ts b/packages/core/src/wot-impl.ts index 1d2b0fb62..6e2be936f 100644 --- a/packages/core/src/wot-impl.ts +++ b/packages/core/src/wot-impl.ts @@ -44,19 +44,17 @@ class ThingDiscoveryProcess { #filter: ThingFilter; - - constructor(filter?: ThingFilter) { this.#filter = filter ?? {}; - }; + } - stop(): void { + stop(): void { this.#done = true; } // TODO: Implement AsyncIterable // async iterable; - }; +} export default class WoTImpl { private srv: Servient; From 44af6199bc305b1be91369bab675574828c28a07 Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Tue, 21 Nov 2023 14:17:14 +0100 Subject: [PATCH 23/25] fixup! feat!: add proposal for new discovery API --- packages/core/src/wot-impl.ts | 65 +++++++++++++++++------------------ 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/packages/core/src/wot-impl.ts b/packages/core/src/wot-impl.ts index 6e2be936f..79d631c56 100644 --- a/packages/core/src/wot-impl.ts +++ b/packages/core/src/wot-impl.ts @@ -25,11 +25,7 @@ import ContentManager from "./content-serdes"; const { debug } = createLoggers("core", "wot-impl"); -interface ThingFilter { - fragment?: object; -} - -class ThingDiscoveryProcess { +class ThingDiscoveryProcess implements WoT.ThingDiscoveryProcess { #done = false; get done() { @@ -42,18 +38,21 @@ class ThingDiscoveryProcess { return this.#error; } - #filter: ThingFilter; + #filter: WoT.ThingFilter; - constructor(filter?: ThingFilter) { + constructor(filter?: WoT.ThingFilter) { this.#filter = filter ?? {}; } + filter?: WoT.ThingFilter | undefined; + + [Symbol.asyncIterator](): AsyncIterator { + throw new Error("Method not implemented."); + } + stop(): void { this.#done = true; } - - // TODO: Implement AsyncIterable - // async iterable; } export default class WoTImpl { @@ -63,6 +62,29 @@ export default class WoTImpl { this.srv = srv; } + async discover(filter?: WoT.ThingFilter): Promise { + // TODO: Implement this function + return new ThingDiscoveryProcess(filter); + } + + async *exploreDirectory(url: string, filter?: WoT.ThingFilter): AsyncGenerator { + yield Promise.reject(new Error("Unimplemented")); + } + + async requestThingDescription(url: string): Promise { + const uriScheme = new URL(url).protocol.split(":")[0]; + const client = this.srv.getClientFor(uriScheme); + const result = await client.discoverDirectly(url); + + const value = ContentManager.contentToValue({ type: result.type, body: await result.toBuffer() }, {}); + + if (value instanceof Object) { + return value as ThingDescription; + } + + throw new Error("Not found."); + } + /** @inheritDoc */ async consume(td: WoT.ThingDescription): Promise { try { @@ -110,29 +132,6 @@ export default class WoTImpl { } }); } - - async discover(filter?: WoT.ThingFilter): Promise { - // TODO: Implement this function - return new ThingDiscoveryProcess(filter); - } - - async *exploreDirectory(url: string, filter?: WoT.ThingFilter): AsyncGenerator { - yield Promise.reject(new Error("Unimplemented")); - } - - async requestThingDescription(url: string): Promise { - const uriScheme = new URL(url).protocol.split(":")[0]; - const client = this.srv.getClientFor(uriScheme); - const result = await client.discoverDirectly(url); - - const value = ContentManager.contentToValue({ type: result.type, body: await result.toBuffer() }, {}); - - if (value instanceof Object) { - return value as ThingDescription; - } - - throw new Error("Not found."); - } } /** Instantiation of the WoT.DataType declaration */ From 495b857c4b53780e40ce4e8d4265d921fed9afef Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Tue, 21 Nov 2023 14:19:36 +0100 Subject: [PATCH 24/25] fixup! feat!: add proposal for new discovery API --- packages/core/src/wot-impl.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/core/src/wot-impl.ts b/packages/core/src/wot-impl.ts index 79d631c56..1728260cb 100644 --- a/packages/core/src/wot-impl.ts +++ b/packages/core/src/wot-impl.ts @@ -62,15 +62,18 @@ export default class WoTImpl { this.srv = srv; } + /** @inheritDoc */ async discover(filter?: WoT.ThingFilter): Promise { // TODO: Implement this function return new ThingDiscoveryProcess(filter); } + /** @inheritDoc */ async *exploreDirectory(url: string, filter?: WoT.ThingFilter): AsyncGenerator { yield Promise.reject(new Error("Unimplemented")); } + /** @inheritDoc */ async requestThingDescription(url: string): Promise { const uriScheme = new URL(url).protocol.split(":")[0]; const client = this.srv.getClientFor(uriScheme); From ccd7751b1e42072903f52f44a38c1d926b0a3ff9 Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Tue, 21 Nov 2023 14:21:36 +0100 Subject: [PATCH 25/25] fixup! feat!: add proposal for new discovery API --- packages/core/src/wot-impl.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/src/wot-impl.ts b/packages/core/src/wot-impl.ts index 1728260cb..1b9a05339 100644 --- a/packages/core/src/wot-impl.ts +++ b/packages/core/src/wot-impl.ts @@ -69,8 +69,8 @@ export default class WoTImpl { } /** @inheritDoc */ - async *exploreDirectory(url: string, filter?: WoT.ThingFilter): AsyncGenerator { - yield Promise.reject(new Error("Unimplemented")); + async exploreDirectory(url: string, filter?: WoT.ThingFilter): Promise { + return new ThingDiscoveryProcess(filter); } /** @inheritDoc */