From 230dd66e43c14ff3897e4712bd99f026e9ac5f54 Mon Sep 17 00:00:00 2001 From: Jonas Schlabertz <jonas@schlabertz.de> Date: Tue, 21 Jun 2022 11:45:41 +0200 Subject: [PATCH] Adds API Endpoint to retrieve the currently active ComponentInformation instance of a Component. --- API.paw | Bin 28758 -> 30281 bytes src/controller/ComponentController.ts | 33 ++++++++++++++++++++++++++ src/entity/Component.ts | 3 ++- src/entity/ComponentInformation.ts | 16 +++++++++++++ src/index.ts | 3 +-- src/router/ComponentRouter.ts | 1 + 6 files changed, 53 insertions(+), 3 deletions(-) diff --git a/API.paw b/API.paw index f21e6ff8dc772307f7c744f914c05151ecbaef76..1a6987ce4a100f1b51b1ca50c332af3fc3fb11e1 100644 GIT binary patch delta 13860 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 delta 12834 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 diff --git a/src/controller/ComponentController.ts b/src/controller/ComponentController.ts index b6f260a..f55d82a 100644 --- a/src/controller/ComponentController.ts +++ b/src/controller/ComponentController.ts @@ -43,6 +43,7 @@ export default class ComponentController extends BaseController { Component.findById(request.params.componentId, this.componentRepository, mementoDate).then(async (component) => { if(component) { const componentJsonLd = component.toJSONLD(); + this.setMementoHeaderIfNecessary(mementoDate, response); this.setJSONLDResponseType(response); response.send(componentJsonLd); } else { @@ -58,6 +59,38 @@ export default class ComponentController extends BaseController { }); } + getComponentInformation = async (request: Request, response: Response) => { + if(request.params.componentId == Component.rootId) { + // Let's just pretend that the dummy root node does not exist. + // It won't have valid context information anyway and is only intended + // for internal use. + response.status(404); + this.setJSONLDResponseType(response); + response.send(new APIError("Component not found.")); + return; + } + + const mementoDate: Date | undefined = this.getMementoDate(request); + + ComponentInformation.findCurrentVersionForComponent(request.params.componentId, this.componentInformationRepository, mementoDate).then(async (information) => { + if(information) { + const informationJsonLD = information.toJSONLD(); + this.setMementoHeaderIfNecessary(mementoDate, response); + this.setJSONLDResponseType(response); + response.send(informationJsonLD); + } else { + response.status(404); + this.setMementoHeaderIfNecessary(mementoDate, response); + this.setJSONLDResponseType(response); + response.send(new APIError("Information not found.")); + } + }).catch((error) => { + logger.error(`Error while retrieving information for component: ${JSON.stringify(error)}`); + response.status(500); + response.send(new APIError(JSON.stringify(error))); + }); + } + find = async(request: Request, response: Response) => { const filter = request.query.filter?.toString(); diff --git a/src/entity/Component.ts b/src/entity/Component.ts index 5a6bbb5..c71f856 100644 --- a/src/entity/Component.ts +++ b/src/entity/Component.ts @@ -193,7 +193,8 @@ export default class Component { "@type": "Component", "identifier": { "@id": `${config.baseURL}/component/${this.id.toString()}`}, "dateCreated": this.dateCreated.toISOString(), - "license": this.license + "license": this.license, + "currentInformation": { "@id": `${config.baseURL}/component/${this.id.toString()}/information` } }; if (this.isComponentOf) { diff --git a/src/entity/ComponentInformation.ts b/src/entity/ComponentInformation.ts index 3a5e3c0..83c21ff 100644 --- a/src/entity/ComponentInformation.ts +++ b/src/entity/ComponentInformation.ts @@ -109,6 +109,22 @@ export default class ComponentInformation { }); } + static findCurrentVersionForComponent(componentId: string, repository: Repository<ComponentInformation>, mementoDate?: Date): Promise<ComponentInformation | undefined> { + const date: Date = mementoDate ?? new Date(); + + return repository + .createQueryBuilder("componentInformation") + .leftJoinAndSelect("componentInformation.component", "component") + .leftJoinAndSelect("componentInformation.nextVersion", "nextVersion") + .where("componentInformation.component = :componentId", { componentId }) + .andWhere("componentInformation.dateCreated <= :date1::timestamptz", { date1: date }) + .andWhere("coalesce(\"nextVersion\".\"dateCreated\", 'Infinity') > :date2::timestamptz", { date2: date }) + .leftJoinAndSelect("componentInformation.type", "metadataType") + .leftJoinAndSelect("componentInformation.measurementTargets", "measurementTargets") + .leftJoinAndSelect("componentInformation.previousVersion", "previousVersion") + .getOne(); + } + static find(filter: string | undefined, from: Date | undefined, to: Date | undefined, metadataTypeFilter: string | undefined, pageSize: number, page: number, repository: Repository<ComponentInformation>): Promise<ComponentInformation[]> { let baseQuery = repository .createQueryBuilder("componentInformation") diff --git a/src/index.ts b/src/index.ts index 034b592..1842675 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,8 +14,6 @@ declare module "http" { } } -// StartUp Routine - // Signal handlers process.on("SIGINT", () => { logger.info("Received SIGINT"); @@ -26,6 +24,7 @@ process.on("SIGINT", () => { }); }); +// StartUp Routine dbService.then((connection) => { if (connection.isConnected) { mqttService.then((mqttClient) => { diff --git a/src/router/ComponentRouter.ts b/src/router/ComponentRouter.ts index 1c3cf9b..9af10c3 100644 --- a/src/router/ComponentRouter.ts +++ b/src/router/ComponentRouter.ts @@ -19,6 +19,7 @@ class ComponentRouter extends GenericRouter { // Component find routes this.expressRouter.get("/root", this.componentController.findRoots); this.expressRouter.get("/:componentId", checkSchema(getComponentSchema), ValidationErrorMiddleware, this.componentController.getComponent); + this.expressRouter.get("/:componentId/information", checkSchema(getComponentSchema), ValidationErrorMiddleware, this.componentController.getComponentInformation); this.expressRouter.get("/", checkSchema(findComponentSchema), ValidationErrorMiddleware, this.componentController.find); this.expressRouter.post("/", checkSchema(createComponentSchema), ValidationErrorMiddleware, this.componentController.createComponent); -- GitLab