Skip to content

Commit 0a6463b

Browse files
authored
feat: add initial requestThingDescription implementation (#1166)
* feat: add initial requestThingDescription implementation
1 parent 143c8a0 commit 0a6463b

13 files changed

Lines changed: 170 additions & 29 deletions

File tree

packages/binding-coap/src/coap-client.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,24 @@ export default class CoapClient implements ProtocolClient {
183183
});
184184
}
185185

186+
/**
187+
* @inheritdoc
188+
*/
189+
requestThingDescription(uri: string): Promise<Content> {
190+
const options: CoapRequestParams = this.uriToOptions(uri);
191+
const req = this.agent.request(options);
192+
193+
req.setOption("Accept", "application/td+json");
194+
return new Promise<Content>((resolve, reject) => {
195+
req.on("response", (res: IncomingMessage) => {
196+
const contentType = (res.headers["Content-Format"] as string) ?? "application/td+json";
197+
resolve(new Content(contentType, Readable.from(res.payload)));
198+
});
199+
req.on("error", (err: Error) => reject(err));
200+
req.end();
201+
});
202+
}
203+
186204
public async start(): Promise<void> {
187205
// do nothing
188206
}

packages/binding-coap/src/coaps-client.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,23 @@ export default class CoapsClient implements ProtocolClient {
139139
});
140140
}
141141

142+
/**
143+
* @inheritdoc
144+
*/
145+
public async requestThingDescription(uri: string): Promise<Content> {
146+
const response = await coaps.request(uri, "get", undefined, {
147+
// FIXME: Add accept option
148+
// Currently not supported by node-coap-client
149+
});
150+
151+
// TODO: Respect Content-Format in response.
152+
// Currently not really well supported by node-coap-client
153+
const contentType = "application/td+json";
154+
const payload = response.payload ?? Buffer.alloc(0);
155+
156+
return new Content(contentType, Readable.from(payload));
157+
}
158+
142159
public async start(): Promise<void> {
143160
// do nothing
144161
}

packages/binding-file/src/file-client.ts

Lines changed: 43 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,40 +24,48 @@ import path = require("path");
2424

2525
const { debug, warn } = createLoggers("binding-file", "file-client");
2626

27+
/**
28+
* Used to determine the Content-Type of a file from the extension in its
29+
* {@link filePath} if no explicit Content-Type is defined.
30+
*
31+
* @param filepath The file path the Content-Type is determined for.
32+
* @returns An appropriate Content-Type or `application/octet-stream` as a fallback.
33+
*/
34+
function mapFileExtensionToContentType(filepath: string) {
35+
const fileExtension = path.extname(filepath);
36+
debug(`FileClient found '${fileExtension}' extension`);
37+
switch (fileExtension) {
38+
case ".txt":
39+
case ".log":
40+
case ".ini":
41+
case ".cfg":
42+
return "text/plain";
43+
case ".json":
44+
return "application/json";
45+
case ".jsontd":
46+
return "application/td+json";
47+
case ".jsonld":
48+
return "application/ld+json";
49+
default:
50+
warn(`FileClient cannot determine media type for path '${filepath}'`);
51+
return "application/octet-stream";
52+
}
53+
}
54+
2755
export default class FileClient implements ProtocolClient {
2856
public toString(): string {
2957
return "[FileClient]";
3058
}
3159

60+
private async readFile(filepath: string, contentType?: string): Promise<Content> {
61+
const resource = fs.createReadStream(filepath);
62+
const resourceContentType = contentType ?? mapFileExtensionToContentType(filepath);
63+
return new Content(resourceContentType, resource);
64+
}
65+
3266
public async readResource(form: Form): Promise<Content> {
33-
const filepath = form.href.split("//");
34-
const resource = fs.createReadStream(filepath[1]);
35-
const extension = path.extname(filepath[1]);
36-
debug(`FileClient found '${extension}' extension`);
37-
let contentType;
38-
if (form.contentType != null) {
39-
contentType = form.contentType;
40-
} else {
41-
// *guess* contentType based on file extension
42-
contentType = "application/octet-stream";
43-
switch (extension) {
44-
case ".txt":
45-
case ".log":
46-
case ".ini":
47-
case ".cfg":
48-
contentType = "text/plain";
49-
break;
50-
case ".json":
51-
contentType = "application/json";
52-
break;
53-
case ".jsonld":
54-
contentType = "application/ld+json";
55-
break;
56-
default:
57-
warn(`FileClient cannot determine media type of '${form.href}'`);
58-
}
59-
}
60-
return new Content(contentType, resource);
67+
const filepath = new URL(form.href).pathname;
68+
return this.readFile(filepath, form.contentType);
6169
}
6270

6371
public async writeResource(form: Form, content: Content): Promise<void> {
@@ -72,6 +80,13 @@ export default class FileClient implements ProtocolClient {
7280
throw new Error("FileClient does not implement unlink");
7381
}
7482

83+
/**
84+
* @inheritdoc
85+
*/
86+
public async requestThingDescription(uri: string): Promise<Content> {
87+
return this.readFile(uri, "application/td+json");
88+
}
89+
7590
public async subscribeResource(
7691
form: Form,
7792
next: (value: Content) => void,

packages/binding-http/src/http-client-impl.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,18 @@ export default class HttpClient implements ProtocolClient {
212212
}
213213
}
214214

215+
/**
216+
* @inheritdoc
217+
*/
218+
public async requestThingDescription(uri: string): Promise<Content> {
219+
const headers: HeadersInit = {
220+
Accept: "application/td+json",
221+
};
222+
const response = await fetch(uri, { headers });
223+
const body = ProtocolHelpers.toNodeStream(response.body as Readable);
224+
return new Content(response.headers.get("content-type") ?? "application/td+json", body);
225+
}
226+
215227
public async start(): Promise<void> {
216228
// do nothing
217229
}

packages/binding-mbus/src/mbus-client.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ export default class MBusClient implements ProtocolClient {
6161
throw new Error("Method not implemented.");
6262
}
6363

64+
/**
65+
* @inheritdoc
66+
*/
67+
public async requestThingDescription(uri: string): Promise<Content> {
68+
throw new Error("Method not implemented");
69+
}
70+
6471
async start(): Promise<void> {
6572
// do nothing
6673
}

packages/binding-modbus/src/modbus-client.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,13 @@ export default class ModbusClient implements ProtocolClient {
131131
});
132132
}
133133

134+
/**
135+
* @inheritdoc
136+
*/
137+
public async requestThingDescription(uri: string): Promise<Content> {
138+
throw new Error("Method not implemented");
139+
}
140+
134141
async start(): Promise<void> {
135142
// do nothing
136143
}

packages/binding-mqtt/src/mqtt-client.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,13 @@ export default class MqttClient implements ProtocolClient {
161161
}
162162
}
163163

164+
/**
165+
* @inheritdoc
166+
*/
167+
public async requestThingDescription(uri: string): Promise<Content> {
168+
throw new Error("Method not implemented");
169+
}
170+
164171
public async start(): Promise<void> {
165172
// do nothing
166173
}

packages/binding-netconf/src/netconf-client.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,13 @@ export default class NetconfClient implements ProtocolClient {
155155
throw unimplementedError;
156156
}
157157

158+
/**
159+
* @inheritdoc
160+
*/
161+
public async requestThingDescription(uri: string): Promise<Content> {
162+
throw new Error("Method not implemented");
163+
}
164+
158165
public async start(): Promise<void> {
159166
// do nothing
160167
}

packages/binding-opcua/src/opcua-protocol-client.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,13 @@ export class OPCUAProtocolClient implements ProtocolClient {
430430
});
431431
}
432432

433+
/**
434+
* @inheritdoc
435+
*/
436+
public async requestThingDescription(uri: string): Promise<Content> {
437+
throw new Error("Method not implemented");
438+
}
439+
433440
start(): Promise<void> {
434441
debug("start: Sorry not implemented");
435442
throw new Error("Method not implemented.");

packages/binding-websockets/src/ws-client.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ export default class WebSocketClient implements ProtocolClient {
6666
throw new Error("Websocket client does not implement subscribeResource");
6767
}
6868

69+
/**
70+
* @inheritdoc
71+
*/
72+
public async requestThingDescription(uri: string): Promise<Content> {
73+
throw new Error("Method not implemented");
74+
}
75+
6976
public async start(): Promise<void> {
7077
// do nothing
7178
}

0 commit comments

Comments
 (0)