diff --git a/API.paw b/API.paw index f21e6ff8dc772307f7c744f914c05151ecbaef76..1a6987ce4a100f1b51b1ca50c332af3fc3fb11e1 100644 Binary files a/API.paw and b/API.paw differ diff --git a/src/controller/ComponentController.ts b/src/controller/ComponentController.ts index b6f260a83712415bdcef3561ec462c263e6b46dd..f55d82abf0be80e1d7a30d0b50208fdeeca183d6 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 5a6bbb508a1d9f276fc38755173105e4c13b53cd..c71f8567ffcc933bfbd586f58c6a11ebc97250a2 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 3a5e3c0b4132b8455d0b30a6a1e59a7c61aa6619..83c21ffbf7fe18b68352c0e36065be150b540eeb 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 034b592acf74969348a228630b5596eb028fab93..18426757f0a12bfd26e8b081ff2706e0104dacfa 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 1c3cf9bf23667f7a8544b1e14f6ffa1297b7c03b..9af10c3d4976279478162ac9ccc64dad9fc1ae54 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);