Skip to content

Commit

Permalink
chore(binding-coap): use ts strict checking
Browse files Browse the repository at this point in the history
  • Loading branch information
JKRhb committed Aug 11, 2023
1 parent ef86533 commit 07ad566
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 79 deletions.
7 changes: 3 additions & 4 deletions packages/binding-coap/src/coap-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ export default class CoapClient implements ProtocolClient {
debug(`CoapClient received Content-Format: ${res.headers["Content-Format"]}`);

// FIXME does not work with blockwise because of node-coap
let contentType = res.headers["Content-Format"] as string;
if (!contentType) contentType = form.contentType;
const contentType = (res.headers["Content-Format"] as string) ?? form.contentType;

resolve(new Content(contentType, Readable.from(res.payload)));
});
Expand Down Expand Up @@ -226,8 +225,8 @@ export default class CoapClient implements ProtocolClient {
try {
const block2OptionValue = blockSizeToOptionValue(blockSize);
req.setOption(optionName, block2OptionValue);
} catch (e) {
warn(e.toString());
} catch (error) {
warn(`${error}`);
}
}

Expand Down
76 changes: 45 additions & 31 deletions packages/binding-coap/src/coap-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export default class CoapServer implements ProtocolServer {
private readonly port: number;
private readonly address?: string;

private mdnsIntroducer: MdnsIntroducer;
private mdnsIntroducer?: MdnsIntroducer;

private readonly server: Server = createServer(
{ reuseAddr: false },
Expand Down Expand Up @@ -461,7 +461,7 @@ export default class CoapServer implements ProtocolServer {
affordanceKey: string,
req: IncomingMessage,
res: OutgoingMessage,
contentType?: string
contentType: string
) {
const property = thing.properties[affordanceKey];

Expand All @@ -475,7 +475,7 @@ export default class CoapServer implements ProtocolServer {
if (req.headers.Observe == null) {
this.handleReadProperty(property, req, contentType, thing, res, affordanceKey);
} else {
this.handleObserveProperty(req, thing, res, affordanceKey);
this.handleObserveProperty(property, req, contentType, thing, res, affordanceKey);
}
break;
case "PUT":
Expand All @@ -502,31 +502,42 @@ export default class CoapServer implements ProtocolServer {
try {
const interactionOptions = this.createInteractionOptions(
property.forms,
property.uriVariables,
thing,
req,
contentType
contentType,
property.uriVariables
);
const content = await thing.handleReadProperty(affordanceKey, interactionOptions);
this.streamContentResponse(res, content);
} catch (err) {
error(`CoapServer on port ${this.getPort()} got internal error on read '${req.url}': ${err.message}`);
this.sendResponse(res, "5.00", err.message);
const errorMessage = `${err}`;
error(`CoapServer on port ${this.getPort()} got internal error on read '${req.url}': ${errorMessage}`);
this.sendResponse(res, "5.00", errorMessage);
}
}

private async handleObserveProperty(
property: PropertyElement,
req: IncomingMessage,
contentType: string,
thing: ExposedThing,
res: OutgoingMessage,
affordanceKey: string
) {
const interactionOptions = this.createInteractionOptions(
property.forms,
thing,
req,
contentType,
property.uriVariables
);

const listener = this.createContentListener(req, res, this.PROPERTY_DIR, affordanceKey);

try {
await thing.handleObserveProperty(affordanceKey, listener, null);
await thing.handleObserveProperty(affordanceKey, listener, interactionOptions);
} catch (error) {
warn(error.toString());
warn(`${error}`);
}

res.end();
Expand All @@ -535,10 +546,10 @@ export default class CoapServer implements ProtocolServer {
if (err) {
error(`CoapServer on port ${this.port} failed on observe with: ${err.message}`);
}
thing.handleUnobserveProperty(affordanceKey, listener, null);
thing.handleUnobserveProperty(affordanceKey, listener, interactionOptions);
});

setTimeout(() => thing.handleUnobserveProperty(affordanceKey, listener, null), 60 * 60 * 1000);
setTimeout(() => thing.handleUnobserveProperty(affordanceKey, listener, interactionOptions), 60 * 60 * 1000);
}

private createContentListener(
Expand All @@ -562,12 +573,13 @@ export default class CoapServer implements ProtocolServer {
debug(`CoapServer on port ${this.getPort()} failed '${affordanceKey}' subscription`);
this.sendResponse(res, code, "Subscription to event failed");
} else {
const errorMessage = `${err}`;
debug(
`CoapServer on port ${this.getPort()} got internal error on observe '${req.url}': ${
err.message
}`
`CoapServer on port ${this.getPort()} got internal error on observe '${
req.url
}': ${errorMessage}`
);
this.sendResponse(res, code, err.message);
this.sendResponse(res, code, errorMessage);
}
}
};
Expand All @@ -584,10 +596,10 @@ export default class CoapServer implements ProtocolServer {
try {
const interactionOptions = this.createInteractionOptions(
property.forms,
property.uriVariables,
thing,
req,
contentType
contentType,
property.uriVariables
);
await thing.handleWriteProperty(
affordanceKey,
Expand All @@ -596,8 +608,9 @@ export default class CoapServer implements ProtocolServer {
);
this.sendChangedResponse(res);
} catch (err) {
error(`CoapServer on port ${this.getPort()} got internal error on write '${req.url}': ${err.message}`);
this.sendResponse(res, "5.00", err.message);
const errorMessage = `${err}`;
error(`CoapServer on port ${this.getPort()} got internal error on write '${req.url}': ${errorMessage}`);
this.sendResponse(res, "5.00", errorMessage);
}
}

Expand All @@ -606,7 +619,7 @@ export default class CoapServer implements ProtocolServer {
affordanceKey: string,
req: IncomingMessage,
res: OutgoingMessage,
contentType?: string
contentType: string
) {
const action = thing.actions[affordanceKey];

Expand All @@ -622,10 +635,10 @@ export default class CoapServer implements ProtocolServer {

const interactionOptions = this.createInteractionOptions(
action.forms,
action.uriVariables,
thing,
req,
contentType
contentType,
action.uriVariables
);
try {
const output = await thing.handleInvokeAction(
Expand All @@ -638,18 +651,19 @@ export default class CoapServer implements ProtocolServer {
} else {
this.sendChangedResponse(res);
}
} catch (err) {
error(`CoapServer on port ${this.getPort()} got internal error on invoke '${req.url}': ${err.message}`);
this.sendResponse(res, "5.00", err.message);
} catch (errror) {
const errorMessage = `${error}`;
error(`CoapServer on port ${this.getPort()} got internal error on invoke '${req.url}': ${errorMessage}`);
this.sendResponse(res, "5.00", errorMessage);
}
}

private createInteractionOptions(
forms: TD.Form[],
affordanceUriVariables: { [k: string]: DataSchema },
thing: ExposedThing,
req: IncomingMessage,
contentType: string
contentType: string,
affordanceUriVariables?: { [k: string]: DataSchema }
) {
const options: AugmentedInteractionOptions = {
formIndex: ProtocolHelpers.findRequestMatchingFormIndex(forms, this.scheme, req.url, contentType),
Expand All @@ -667,7 +681,7 @@ export default class CoapServer implements ProtocolServer {
affordanceKey: string,
req: IncomingMessage,
res: OutgoingMessage,
contentType?: string
contentType: string
) {
const event = thing.events[affordanceKey];

Expand Down Expand Up @@ -698,18 +712,18 @@ export default class CoapServer implements ProtocolServer {

const interactionOptions = this.createInteractionOptions(
event.forms,
event.uriVariables,
thing,
req,
contentType
contentType,
event.uriVariables
);

const listener = this.createContentListener(req, res, this.EVENT_DIR, affordanceKey);

try {
await thing.handleSubscribeEvent(affordanceKey, listener, interactionOptions);
} catch (error) {
warn(error.toString());
warn(`${error}`);
}

res.end();
Expand Down
38 changes: 21 additions & 17 deletions packages/binding-coap/src/coaps-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import * as TD from "@node-wot/td-tools";

import { Subscription } from "rxjs/Subscription";

import { ProtocolClient, Content, createLoggers } from "@node-wot/core";
import { ProtocolClient, Content, createLoggers, ContentSerdes } from "@node-wot/core";
import { CoapForm, CoapMethodName, isValidCoapMethod, isSupportedCoapMethod } from "./coap";
import { CoapClient as coaps, CoapResponse, RequestMethod, SecurityParameters } from "node-coap-client";
import { Readable } from "stream";
Expand All @@ -34,7 +34,7 @@ declare interface pskSecurityParameters {

export default class CoapsClient implements ProtocolClient {
// FIXME coap Agent closes socket when no messages in flight -> new socket with every request
private authorization: SecurityParameters;
private authorization?: SecurityParameters;

public toString(): string {
return "[CoapsClient]";
Expand All @@ -46,11 +46,11 @@ export default class CoapsClient implements ProtocolClient {
.then((res: CoapResponse) => {
debug(`CoapsClient received ${res.code} from ${form.href}`);

// FIXME node-coap-client does not support options
let contentType; // = res.format[...]
if (!contentType) contentType = form.contentType;
// FIXME: Add toString conversion for response Content-Format
const contentType = form.contentType ?? ContentSerdes.DEFAULT;
const body = Readable.from(res.payload ?? Buffer.alloc(0));

resolve(new Content(contentType, Readable.from(res.payload)));
resolve(new Content(contentType, body));
})
.catch((err: Error) => {
reject(err);
Expand Down Expand Up @@ -78,11 +78,11 @@ export default class CoapsClient implements ProtocolClient {
.then((res: CoapResponse) => {
debug(`CoapsClient received ${res.code} from ${form.href}`);

// FIXME node-coap-client does not support options
let contentType; // = res.format[...]
if (!contentType) contentType = form.contentType;
// FIXME: Add toString conversion for response Content-Format
const contentType = form.contentType ?? ContentSerdes.DEFAULT;
const body = Readable.from(res.payload ?? Buffer.alloc(0));

resolve(new Content(contentType, Readable.from(res.payload)));
resolve(new Content(contentType, body));
})
.catch((err: Error) => {
reject(err);
Expand Down Expand Up @@ -112,11 +112,13 @@ export default class CoapsClient implements ProtocolClient {
): Promise<Subscription> {
return new Promise<Subscription>((resolve, reject) => {
const requestUri = new URL(form.href.replace(/$coaps/, "https"));
coaps.setSecurityParams(requestUri.hostname, this.authorization);
if (this.authorization != null) {
coaps.setSecurityParams(requestUri.hostname, this.authorization);
}

const callback = (resp: CoapResponse) => {
if (resp.payload != null) {
next(new Content(form?.contentType, Readable.from(resp.payload)));
next(new Content(form?.contentType ?? ContentSerdes.DEFAULT, Readable.from(resp.payload)));
}
};

Expand All @@ -126,12 +128,12 @@ export default class CoapsClient implements ProtocolClient {
resolve(
new Subscription(() => {
coaps.stopObserving(form.href);
complete();
complete?.();
})
);
})
.catch((err) => {
error(err);
error?.(err);
reject(err);
});
});
Expand All @@ -153,7 +155,7 @@ export default class CoapsClient implements ProtocolClient {

const security: TD.SecurityScheme = metadata[0];

if (security.scheme === "psk") {
if (security.scheme === "psk" && credentials != null) {
this.authorization = { psk: {} };
this.authorization.psk[credentials.identity] = credentials.psk;
} else if (security.scheme === "apikey") {
Expand Down Expand Up @@ -207,7 +209,9 @@ export default class CoapsClient implements ProtocolClient {
): Promise<CoapResponse> {
// url only works with http*
const requestUri = new URL(form.href.replace(/$coaps/, "https"));
coaps.setSecurityParams(requestUri.hostname, this.authorization);
if (this.authorization != null) {
coaps.setSecurityParams(requestUri.hostname, this.authorization);
}

let method;

Expand All @@ -221,7 +225,7 @@ export default class CoapsClient implements ProtocolClient {

debug(`CoapsClient sending ${method} to ${form.href}`);

const body = content.body ? await content.toBuffer() : undefined;
const body = await content?.toBuffer();

const req = coaps.request(
form.href /* string */,
Expand Down
7 changes: 4 additions & 3 deletions packages/binding-coap/test/coap-client-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { expect } from "chai";
import CoapServer from "../src/coap-server";
import CoapClient from "../src/coap-client";
import { CoapForm } from "../src/coap";
import Servient from "@node-wot/core";

const port1 = 31833;
const port2 = 31834;
Expand Down Expand Up @@ -56,7 +57,7 @@ class CoapClientTest {

const coapServer = new CoapServer(port1);

await coapServer.start(null);
await coapServer.start(new Servient());
expect(coapServer.getPort()).to.equal(port1);

/*
Expand Down Expand Up @@ -102,7 +103,7 @@ class CoapClientTest {

@test async "should re-use port"() {
const coapServer = new CoapServer(port2, "localhost");
await coapServer.start(null);
await coapServer.start(new Servient());
const coapClient = new CoapClient(coapServer);
await coapClient.readResource({
href: `coap://localhost:${port2}/`,
Expand All @@ -113,7 +114,7 @@ class CoapClientTest {

@test(timeout(5000)) async "subscribe test"() {
const coapServer = new CoapServer(port2, "localhost");
await coapServer.start(null);
await coapServer.start(new Servient());
const coapClient = new CoapClient(coapServer);
const form: CoapForm = {
href: `coap://127.0.0.1:${port2}`,
Expand Down
Loading

0 comments on commit 07ad566

Please sign in to comment.