diff --git a/lib/src/example_modules/httpInterfaceServer.ts b/lib/src/example_modules/httpInterfaceServer.ts index dfb91c8..af90a35 100644 --- a/lib/src/example_modules/httpInterfaceServer.ts +++ b/lib/src/example_modules/httpInterfaceServer.ts @@ -3,7 +3,7 @@ import express from "express"; import { jsonization, types } from "@aas-core-works/aas-core3.0-typescript"; import AASInterfaceServer from "../server"; import type { OnRequestCallback } from "types/requests"; -import AASHelper from "../aasHelper"; +import Traverser from "../helper/traverser"; export type Config = { bindAddress: string, @@ -53,11 +53,11 @@ export default class HTTPInterfaceServer extends AASInterfaceServer { try { // This is what the specification says const decoded = Buffer.from(id, "base64").toString("utf-8"); - let sm = AASHelper.findSMById(this.aas, decoded); + let sm = Traverser.findSMById(this.aas, decoded); if (sm === null) { // Normally, at least in BaSyx just the shortId is used, so just test if we find something like this - sm = AASHelper.findSMByIdShort(this.aas, id); + sm = Traverser.findSMByIdShort(this.aas, id); } return sm; @@ -134,7 +134,7 @@ export default class HTTPInterfaceServer extends AASInterfaceServer { switch (endingMatch) { case undefined: { if (req.method !== "GET") return res.status(501).end(); - const prop = AASHelper.getElementByIdPath(this.aas, sm, idShortPath); + const prop = Traverser.getElementByIdPath(this.aas, sm, idShortPath); // TODO //! Check if mapping and live data is available! diff --git a/lib/src/helper/fileImporter.ts b/lib/src/helper/fileImporter.ts new file mode 100644 index 0000000..6505a16 --- /dev/null +++ b/lib/src/helper/fileImporter.ts @@ -0,0 +1,34 @@ + +import { readdirSync, readFileSync } from "fs"; +import { types, jsonization } from "@aas-core-works/aas-core3.0-typescript"; + +export default class FileImporter { + public static readAASByPath(path: string): types.Environment { + if (!path.endsWith(".json")) throw new Error("File must be a JSON file"); + + const file = readFileSync(path, { encoding: "utf-8" }); + + const aas = JSON.parse(file); + const aasJson = jsonization.environmentFromJsonable(aas); + if (aasJson.error) throw aasJson.error; + + return aasJson.mustValue(); + } + + public static readAllAASFromPath(path: string): types.Environment[] { + + return FileImporter.getAllAASFilePaths(path).map(file => { + try { + return FileImporter.readAASByPath(file); + } catch (e) { + console.log(`Error while reading AAS from ${file}`, e); + return null; + } + }).filter(aas => aas !== null) as types.Environment[]; + } + + private static getAllAASFilePaths(aasPath: string): string[] { + const files = readdirSync(aasPath); + return files.filter(file => file.endsWith(".json")).map(file => `${aasPath}/${file}`); + } +} \ No newline at end of file diff --git a/lib/src/aasHelper.ts b/lib/src/helper/traverser.ts similarity index 61% rename from lib/src/aasHelper.ts rename to lib/src/helper/traverser.ts index ce845b5..717f45a 100644 --- a/lib/src/aasHelper.ts +++ b/lib/src/helper/traverser.ts @@ -1,39 +1,9 @@ -import { readdirSync, readFileSync } from "fs"; -import { types, jsonization } from "@aas-core-works/aas-core3.0-typescript"; +import { types } from "@aas-core-works/aas-core3.0-typescript"; const GLOBALLY_IDENTIFIABLES = [types.KeyTypes.GlobalReference, types.KeyTypes.AssetAdministrationShell, types.KeyTypes.ConceptDescription, types.KeyTypes.Identifiable, types.KeyTypes.Submodel] -export default class AASHelper { - - public static readAASByPath(path: string): types.Environment { - if (!path.endsWith(".json")) throw new Error("File must be a JSON file"); - - const file = readFileSync(path, { encoding: "utf-8" }); - - const aas = JSON.parse(file); - const aasJson = jsonization.environmentFromJsonable(aas); - if (aasJson.error) throw aasJson.error; - - return aasJson.mustValue(); - } - - public static readAllAASFromPath(path: string): types.Environment[] { - - return AASHelper.getAllAASFilePaths(path).map(file => { - try { - return AASHelper.readAASByPath(file); - } catch (e) { - console.log(`Error while reading AAS from ${file}`, e); - return null; - } - }).filter(aas => aas !== null) as types.Environment[]; - } - - private static getAllAASFilePaths(aasPath: string): string[] { - const files = readdirSync(aasPath); - return files.filter(file => file.endsWith(".json")).map(file => `${aasPath}/${file}`); - } +export default class Traverser { public static findAASById(environment: types.Environment, id: string): types.AssetAdministrationShell | null { if (environment.assetAdministrationShells === null) return null; @@ -61,9 +31,9 @@ export default class AASHelper { if (current === null && !GLOBALLY_IDENTIFIABLES.includes(key.type)) break; if (current === null) { - current = AASHelper.findElement(env, element => (element as any).id === key.value) + current = Traverser.findElement(env, element => (element as any).id === key.value) } else { - current = AASHelper.findElement(current, element => (element as any).idShort === key.value) + current = Traverser.findElement(current, element => (element as any).idShort === key.value) } } @@ -75,16 +45,16 @@ export default class AASHelper { for (const shortId of shortIds) { if (current === null) break; - current = AASHelper.findChildByIdShort(current, shortId); + current = Traverser.findChildByIdShort(current, shortId); } return current; } public static getElementByIdPath(env: types.Environment, submodelOrIdShort: string | types.Submodel, idShorts: string[]): types.Class | null { - const sm = typeof submodelOrIdShort === "string" ? AASHelper.findSMByIdShort(env, submodelOrIdShort) : submodelOrIdShort; + const sm = typeof submodelOrIdShort === "string" ? Traverser.findSMByIdShort(env, submodelOrIdShort) : submodelOrIdShort; if (sm === null) return null; - return AASHelper.traverseByShortIds(sm, idShorts); + return Traverser.traverseByShortIds(sm, idShorts); } public static findElement(start: types.Class, checkFunction: (element: types.Class) => boolean): types.Class | null { diff --git a/lib/src/index.ts b/lib/src/index.ts index 70d0196..28c3303 100644 --- a/lib/src/index.ts +++ b/lib/src/index.ts @@ -1,8 +1,8 @@ -import AASHelper from "./aasHelper"; import MultiMessageBroker from "./multimessageBroker"; -import HTTPInterfaceServer, { Config } from "./example_modules/httpInterfaceServer"; +import HTTPInterfaceServer from "./example_modules/httpInterfaceServer"; +import FileImporter from "helper/fileImporter"; -const aas = AASHelper.readAASByPath("../AID-AIMC-Full-Example-20230911T1608.json"); +const aas = FileImporter.readAASByPath("../AID-AIMC-Full-Example-20230911T1608.json"); const broker = new MultiMessageBroker(); broker.registerAAS({ aas, serverInterfaces: { serverInterface: HTTPInterfaceServer, config: { bindPort: 3000, bindAddress: "0.0.0.0" } } }); diff --git a/lib/src/multimessageBroker.ts b/lib/src/multimessageBroker.ts index 89c464f..0b2a37a 100644 --- a/lib/src/multimessageBroker.ts +++ b/lib/src/multimessageBroker.ts @@ -2,7 +2,7 @@ import { types } from "@aas-core-works/aas-core3.0-typescript"; import type AASInterfaceServer from "server"; import type { Request } from "types/requests"; import type InterfaceConnectionObject from "interfaceConnectionObject"; -import AASHelper from "./aasHelper"; +import Traverser from "./helper/traverser"; import type { AIMCMapper } from "./parser/AIMCMapper"; import { AssetInterfaceDescription } from "types/aidConf"; import AIDParser from "./parser/AIDParser"; diff --git a/lib/src/parser/AIDParser.ts b/lib/src/parser/AIDParser.ts index 8bdf24f..3f6530f 100644 --- a/lib/src/parser/AIDParser.ts +++ b/lib/src/parser/AIDParser.ts @@ -1,12 +1,12 @@ import * as aasCore from "@aas-core-works/aas-core3.0-typescript"; import type { AssetInterfaceDescription, EndpointMetadata, InterfaceDescription, InterfaceMetadata, InterfaceAction, InterfaceEvent, InterfaceProperty, InterfacePropertyForm } from "types/aidConf"; import { AvailableEndpoint, endpointAvailable } from "../types/common"; -import AASHelper from "../aasHelper"; +import Traverser from "../helper/traverser"; export default class AIDParser { public static parse(env: aasCore.types.Environment): AssetInterfaceDescription | null { - const sm = AASHelper.findSMByIdShort(env, "AssetInterfaceDescription"); + const sm = Traverser.findSMByIdShort(env, "AssetInterfaceDescription"); if (sm === null || sm.submodelElements === null) return null; const parsed = {} as AssetInterfaceDescription; @@ -28,11 +28,11 @@ export default class AIDParser { } private static parseAIDEntry(entry: aasCore.types.SubmodelElementCollection, endpointProtocol?: AvailableEndpoint): InterfaceDescription | null { - const title = AASHelper.findElement(entry, element => (element as any).idShort.toLocaleLowerCase() === "title"); + const title = Traverser.findElement(entry, element => (element as any).idShort.toLocaleLowerCase() === "title"); const titleString = title !== null && aasCore.types.isProperty(title) && title.value ? title.value : ""; - const ep = AASHelper.findElement(entry, element => (element as any).idShort.toLocaleLowerCase() === "endpointmetadata"); - const im = AASHelper.findElement(entry, element => (element as any).idShort.toLocaleLowerCase() === "interfacemetadata"); + const ep = Traverser.findElement(entry, element => (element as any).idShort.toLocaleLowerCase() === "endpointmetadata"); + const im = Traverser.findElement(entry, element => (element as any).idShort.toLocaleLowerCase() === "interfacemetadata"); if (ep === null || !aasCore.types.isSubmodelElementCollection(ep) || !ep.value || im === null || !aasCore.types.isSubmodelElementCollection(im) || !im.value) return null; const parsedEp = AIDParser.parseEndpointMetaData(ep, endpointProtocol); @@ -53,7 +53,7 @@ export default class AIDParser { const parsed = {} as EndpointMetadata; for (const key of ["base", "contentType"]) { - const prop = AASHelper.findElement(endpoint, element => (element as any).idShort.toLocaleLowerCase() === key.toLocaleLowerCase()); + const prop = Traverser.findElement(endpoint, element => (element as any).idShort.toLocaleLowerCase() === key.toLocaleLowerCase()); if (prop === null || !aasCore.types.isProperty(prop) || !prop.value) return null; // Mandatory else parsed[key] = prop.value; } @@ -73,7 +73,7 @@ export default class AIDParser { events: [] } as InterfaceMetadata; - const prop = AASHelper.findElement(interfaceMeta, element => (element as any).idShort.toLocaleLowerCase() === "properties"); + const prop = Traverser.findElement(interfaceMeta, element => (element as any).idShort.toLocaleLowerCase() === "properties"); if (prop === null || !aasCore.types.isSubmodelElementList(prop) || !prop.value) return null; // Mandatory for (const element of prop.value) { if (!aasCore.types.isSubmodelElementCollection(element)) continue; @@ -82,7 +82,7 @@ export default class AIDParser { parsed.properties.push(parsedProp); } - const actions = AASHelper.findElement(interfaceMeta, element => (element as any).idShort.toLocaleLowerCase() === "actions"); + const actions = Traverser.findElement(interfaceMeta, element => (element as any).idShort.toLocaleLowerCase() === "actions"); if (actions === null || !aasCore.types.isSubmodelElementList(actions) || !actions.value) return null; // Mandatory for (const element of actions.value) { if (!aasCore.types.isSubmodelElementCollection(element)) continue; @@ -106,7 +106,7 @@ export default class AIDParser { else parsed[key] = prop.value; } */ - const forms = AASHelper.findElement(prop, element => (element as any).idShort.toLocaleLowerCase() === "forms"); + const forms = Traverser.findElement(prop, element => (element as any).idShort.toLocaleLowerCase() === "forms"); if (forms === null || !aasCore.types.isSubmodelElementList(forms) || !forms.value) return null; // Mandatory for (const element of forms.value) { if (!aasCore.types.isSubmodelElementCollection(element)) continue; @@ -127,7 +127,7 @@ export default class AIDParser { const parsed = {} as any; for (const key of ["href", "contentType"]) { - const prop = AASHelper.findElement(form, element => (element as any).idShort.toLocaleLowerCase() === key.toLocaleLowerCase()); + const prop = Traverser.findElement(form, element => (element as any).idShort.toLocaleLowerCase() === key.toLocaleLowerCase()); if (prop === null || !aasCore.types.isProperty(prop) || !prop.value) return null; // Mandatory else parsed[key] = prop.value; }