Skip to content

Commit

Permalink
improve logging and adjust tests
Browse files Browse the repository at this point in the history
  • Loading branch information
holomekc committed Dec 4, 2023
1 parent 178ab65 commit 6718ec8
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 54 deletions.
65 changes: 35 additions & 30 deletions src/api/abstract-bshc-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { BshbError } from "../error/bshb-error";
import { BshbErrorType } from "../error/bshb-error-type";
import { BshbCallOptions } from "../bshb-call-options";
import { BshbUtils } from "../bshb-utils";
import * as util from "util";
import * as http from "http";

/**
* This class provides a simple call for all defined clients
Expand Down Expand Up @@ -101,8 +103,6 @@ export abstract class AbstractBshcClient {
requestOptions.headers["Systempassword"] = Buffer.from(options.systemPassword).toString("base64");
}

this.logger.fine("requestOptions: ", requestOptions);

let postData: string | undefined = undefined;
if (data) {
if (typeof data === "string") {
Expand All @@ -113,27 +113,18 @@ export abstract class AbstractBshcClient {
requestOptions.headers["Content-Length"] = postData.length;
}

this.logger.fine("");
this.logger.fine(
"call:\n" +
requestOptions.method +
" | " +
requestOptions.hostname +
":" +
requestOptions.port +
requestOptions.path
this.logger.debug(
`
Request: (${requestOptions.method}) ${requestOptions.hostname}:${requestOptions.port}${requestOptions.path}
Headers:
${util.inspect(requestOptions.headers, { colors: true })}
Body:
${util.inspect(data, { colors: true, depth: 10 })}
`
);
this.logger.fine("headers:\n", requestOptions.headers);
this.logger.fine("body:\n", postData ? postData : "");
this.logger.fine("");

return new Observable<BshbResponse<T>>((observer) => {
const req = https.request(requestOptions, (res) => {
this.logger.fine("");
this.logger.fine("response information:");
this.logger.fine("status:", res.statusCode);
this.logger.fine("headers:", res.headers);

const chunks: any[] = [];

res
Expand All @@ -147,31 +138,34 @@ export abstract class AbstractBshcClient {
dataString = data.toString("utf-8");
}

this.logger.fine("content: ", dataString);
this.logger.fine("");

try {
let parsedData = undefined;
if (dataString) {
parsedData = JSON.parse(dataString);
}

if (res.statusCode && res.statusCode >= 300) {
this.logResponse(requestOptions, res, dataString);

this.handleError(
observer,
BshbErrorType.ERROR,
`call to BSHC failed with HTTP status=${res.statusCode}`
);
} else {
let parsedData = undefined;
if (dataString) {
parsedData = JSON.parse(dataString);
}

this.logResponse(requestOptions, res, parsedData);

observer.next(new BshbResponse<T>(res, parsedData));
}
} catch (e) {
this.logResponse(requestOptions, res, dataString);
observer.error(new BshbError("error during parsing response from BSHC", BshbErrorType.PARSING, e));
} finally {
observer.complete();
}
})
.on("error", (err) => {
this.logResponse(requestOptions, res, undefined);
this.handleError(observer, BshbErrorType.ERROR, err);
});
});
Expand All @@ -197,17 +191,28 @@ export abstract class AbstractBshcClient {
}

private handleError<T>(observer: Subscriber<BshbResponse<T>>, errorType: BshbErrorType, errorDetails: any): void {
this.logger.error("error during call to BSHC: ", errorDetails);
this.logger.error("Error during call to BSHC: ", errorDetails);
try {
if (errorDetails instanceof Error) {
observer.error(new BshbError("error during call to BSHC: ", errorType, errorDetails));
observer.error(new BshbError("Error during call to BSHC: ", errorType, errorDetails));
} else if (typeof errorDetails === "string") {
observer.error(new BshbError(errorDetails, errorType));
} else {
observer.error(new BshbError("error during call to BSHC", errorType));
observer.error(new BshbError("Error during call to BSHC", errorType));
}
} finally {
observer.complete();
}
}

private logResponse(requestOptions: RequestOptions, res: http.IncomingMessage, data?: any) {
this.logger.debug(`
Response: (${requestOptions.method}) ${requestOptions.hostname}:${requestOptions.port}${requestOptions.path}
Status: ${util.inspect(res.statusCode, { colors: true })}
Headers:
${util.inspect(res.headers, { colors: true })}
Content:
${typeof data === "object" ? util.inspect(data, { colors: true }) : data}
`);
}
}
3 changes: 1 addition & 2 deletions src/api/pairing-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ export class PairingClient extends AbstractBshcClient {
token: string;
}>
> {
const clientData = new BoschClientData(name, identifier, certificate);
const postData = JSON.stringify(clientData);
const postData = new BoschClientData(name, identifier, certificate);

return new Observable<BshbResponse<{ url: string; token: string }>>((subscriber) => {
this.simpleCall<{ url: string; token: string }>(
Expand Down
27 changes: 10 additions & 17 deletions test/bosch-smart-home-bridge.spec.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,37 @@
import { expect } from "chai";
import { BshbUtils } from "../src/bshb-utils";
import { BoschSmartHomeBridge, BoschSmartHomeBridgeBuilder } from "../src";
import { createBshcRouter } from "./bshc-mock";
import { BoschSmartHomeBridge, BoschSmartHomeBridgeBuilder, BshbUtils } from "../src";
import { DefaultTestLogger, resetBshcAdminRouter, resetBshcRouter } from "./bshc-mock";
import { Router } from "express";

describe("BoschSmartHomeBridge", () => {
let bshb: BoschSmartHomeBridge;
let bshc: Router;
let bshcAdmin: Router;
before(() => {
const certResult = BshbUtils.generateClientCertificate();
bshb = BoschSmartHomeBridgeBuilder.builder()
.withHost("127.0.0.1")
.withClientCert(certResult.cert)
.withClientPrivateKey(certResult.private)
.withIgnoreCertificateCheck(true)
/*.withLogger(
new (class implements Logger {
fine(message?: any, ...optionalParams: any[]): void {}
debug(message?: any, ...optionalParams: any[]): void {}
info(message?: any, ...optionalParams: any[]): void {}
warn(message?: any, ...optionalParams: any[]): void {}
error(message?: any, ...optionalParams: any[]): void {}
})()
)*/
.withLogger(new DefaultTestLogger())
.build();
});

beforeEach(() => {
bshc = createBshcRouter();
bshc = resetBshcRouter();
bshcAdmin = resetBshcAdminRouter();
});

it("test not paired", (done) => {
bshc.get("/smarthome/rooms", (req, res) => {
res.statusCode = 401;
res.json({});
});
bshcAdmin.post("/smarthome/clients", (req, res) => {
res.statusCode = 401;
res.json({});
});

const identifier = BshbUtils.generateIdentifier();

Expand Down
69 changes: 64 additions & 5 deletions test/bshc-mock.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,86 @@
import express, { Router } from "express";
import express from "express";
import bodyParser from "body-parser";
import { BshbUtils } from "../src";
import { BshbUtils, Logger } from "../src";
import https from "https";

const bshc = express();
let bshcRouter: Router;
export const createBshcRouter = () => {
let bshcRouter = express.Router();
export const resetBshcRouter = () => {
bshcRouter = express.Router();
return bshcRouter;
};

let bshcAdminRouter = express.Router();
export const resetBshcAdminRouter = () => {
bshcAdminRouter = express.Router();
return bshcAdminRouter;
};
const bshcAdmin = express();

bshc.use(bodyParser.json());
bshc.use((req, res, next) => {
console.log(`@${req.method} ${req.path}`);
bshcRouter(req, res, next);
next();
});

bshcAdmin.use(bodyParser.json());
bshcAdmin.use((req, res, next) => {
bshcAdminRouter(req, res, next);
next();
});

const certResult = BshbUtils.generateClientCertificate();

const server = https.createServer({ key: certResult.private, cert: certResult.cert }, bshc);
const adminServer = https.createServer({ key: certResult.private, cert: certResult.cert }, bshcAdmin);

server.listen(8444, () => {});
adminServer.listen(8443, () => {});

export class DefaultTestLogger implements Logger {
fine(message?: any, ...optionalParams: any[]): void {
DefaultTestLogger.log("debug", message, ...optionalParams);
}

debug(message?: any, ...optionalParams: any[]): void {
DefaultTestLogger.log("debug", message, ...optionalParams);
}

info(message?: any, ...optionalParams: any[]): void {
DefaultTestLogger.log("info", message, ...optionalParams);
}

warn(message?: any, ...optionalParams: any[]): void {
DefaultTestLogger.log("warn", message, ...optionalParams);
}

error(message?: any, ...optionalParams: any[]): void {
DefaultTestLogger.log("error", message, ...optionalParams);
}

private static log(msgType: "debug" | "info" | "warn" | "error", message?: any, ...optionalParams: any[]) {
if (optionalParams[0] && optionalParams[0].ca) {
optionalParams = [
{
path: optionalParams[0].path,
method: optionalParams[0].method,
headers: optionalParams[0].headers,
body: optionalParams[0].body,
},
];
}
if (message) {
if (optionalParams.length > 0) {
console[msgType](message, optionalParams);
} else {
console[msgType](message);
}
} else {
if (optionalParams.length > 0) {
console[msgType](optionalParams);
} else {
console[msgType]();
}
}
}
}

0 comments on commit 6718ec8

Please sign in to comment.