Kinda first ready?
This commit is contained in:
@@ -3,7 +3,7 @@ import type AASInterfaceServer from "server";
|
||||
import type { Request } from "types/requests";
|
||||
import type InterfaceConnectionObject from "interfaceConnectionObject";
|
||||
import Traverser from "./helper/traverser";
|
||||
import type { AIMCMapper } from "./parser/AIMCMapper";
|
||||
import { AIMCMapper } from "./parser/AIMCMapper";
|
||||
import { AssetInterfacesDescription } from "types/aidConf";
|
||||
import AIDParser from "./parser/AIDParser";
|
||||
|
||||
@@ -13,9 +13,9 @@ type AASRegistration = {
|
||||
}
|
||||
|
||||
type AASRegistrationPrepared = AASRegistration & {
|
||||
serverInstaces?: AASInterfaceServer<any>[];
|
||||
connectorInterfaces?: InterfaceConnectionObject<any>[];
|
||||
mappingConfiguration?: AIMCMapper;
|
||||
serverInstances: AASInterfaceServer<any>[];
|
||||
connectorInterfaces: InterfaceConnectionObject<any>[];
|
||||
mappingConfiguration: AIMCMapper;
|
||||
}
|
||||
|
||||
type ServerInterfaceEntry<ConfigInterface> = {
|
||||
@@ -23,15 +23,30 @@ type ServerInterfaceEntry<ConfigInterface> = {
|
||||
config: ConfigInterface
|
||||
}
|
||||
|
||||
type InterfaceConnectionEntry<ConfigInterface> = {
|
||||
interfaceConnection: typeof InterfaceConnectionObject<ConfigInterface>,
|
||||
config: ConfigInterface
|
||||
}
|
||||
|
||||
export default class MultiMessageBroker {
|
||||
private prepared: boolean = false;
|
||||
|
||||
private aasRegistrations: AASRegistrationPrepared[] = [];
|
||||
private interfaceConnections: InterfaceConnectionEntry<any>[] = [];
|
||||
|
||||
public constructor() {}
|
||||
|
||||
public registerAAS(registration: AASRegistration): void {
|
||||
this.aasRegistrations.push(registration as AASRegistrationPrepared);
|
||||
public registerAAS<T>(registration: AASRegistration): void {
|
||||
this.aasRegistrations.push({
|
||||
...registration,
|
||||
serverInstances: [],
|
||||
connectorInterfaces: [],
|
||||
mappingConfiguration: new AIMCMapper(registration.aas)
|
||||
});
|
||||
}
|
||||
|
||||
public registerInterfaceConnection<T>(interfaceConnectionEntry: InterfaceConnectionEntry<T>): void {
|
||||
this.interfaceConnections.push(interfaceConnectionEntry);
|
||||
}
|
||||
|
||||
public prepare(): void {
|
||||
@@ -39,10 +54,10 @@ export default class MultiMessageBroker {
|
||||
|
||||
if (!Array.isArray(registration.serverInterfaces)) registration.serverInterfaces = [registration.serverInterfaces];
|
||||
|
||||
registration.serverInstaces = registration.serverInterfaces.map(serverInterface => {
|
||||
registration.serverInstances = registration.serverInterfaces.map(serverInterface => {
|
||||
try {
|
||||
// @ts-ignore
|
||||
const server = new serverInterface.serverInterface<typeof serverInterface.config>(serverInterface.config, registration.aas, this.onInterfaceRequest.bind(this));
|
||||
const server = new serverInterface.serverInterface<typeof serverInterface.config>(serverInterface.config, registration.aas, registration.mappingConfiguration, (req: Request) => this.onInterfaceRequest(req, registration));
|
||||
server.prepare();
|
||||
return server;
|
||||
} catch (e) {
|
||||
@@ -52,9 +67,17 @@ export default class MultiMessageBroker {
|
||||
}).filter(i => i !== null);
|
||||
|
||||
const interfaceDescription = AIDParser.parse(registration.aas);
|
||||
if (!interfaceDescription) continue;
|
||||
|
||||
// TODO
|
||||
// Create connectors and mapping configuration
|
||||
const endpoints = Object.values(interfaceDescription).flatMap(idEntries => idEntries.map(entry => entry.EndPointMetadata));
|
||||
const uniqueProtocols = [...new Set(endpoints.map(endpoint => new URL(endpoint.base).protocol))];
|
||||
|
||||
for (const protocol of uniqueProtocols) {
|
||||
const connectorProto = this.interfaceConnections.find(connection => connection.interfaceConnection.prototype.uriProtocol.includes(protocol))
|
||||
if (connectorProto === undefined) continue;
|
||||
// @ts-ignore
|
||||
registration.connectorInterfaces.push(new connectorProto.interfaceConnection(connectorProto.config, registration.mappingConfiguration, (response: any) => this.onConnectorEvent(response)));
|
||||
}
|
||||
}
|
||||
|
||||
this.prepared = true;
|
||||
@@ -64,17 +87,74 @@ export default class MultiMessageBroker {
|
||||
if (!this.prepared) this.prepare();
|
||||
|
||||
for (const registration of this.aasRegistrations) {
|
||||
registration.serverInstaces?.forEach(server => server?.run());
|
||||
registration.serverInstances?.forEach(server => server?.run());
|
||||
}
|
||||
}
|
||||
|
||||
private onInterfaceRequest(request: Request) {
|
||||
// TODO
|
||||
private onInterfaceRequest(request: Request, registration: AASRegistrationPrepared): any {
|
||||
|
||||
const getConnector = (target: types.Class) => {
|
||||
const mapping = registration.mappingConfiguration?.get(target);
|
||||
if (mapping === undefined) throw new ReferenceError(`No mapping found for ${(request.target as any).idShort}`);
|
||||
|
||||
const connector = registration.connectorInterfaces?.find(connector => connector.endpointMetadata.base === mapping.base);
|
||||
if (connector === undefined) throw new ReferenceError(`No connector found for ${(request.target as any).idShort}`);
|
||||
|
||||
return connector;
|
||||
}
|
||||
|
||||
switch (request.type) {
|
||||
case "READ": {
|
||||
const connector = getConnector(request.target);
|
||||
|
||||
return connector.readProperty(request.target);
|
||||
}
|
||||
case "WRITE": {
|
||||
const connector = getConnector(request.target);
|
||||
|
||||
return connector.writeProperty(request.target, request.extraData.value);
|
||||
}
|
||||
case "OBSERVE": {
|
||||
const connector = getConnector(request.target);
|
||||
|
||||
return connector.observeProperty(request.target, request.extraData.callback);
|
||||
}
|
||||
case "SUBSCRIBE": {
|
||||
const connector = getConnector(request.target);
|
||||
|
||||
return connector.subscribeEvent(request.target, request.extraData.callback);
|
||||
}
|
||||
case "UNSUBSCRIBE": {
|
||||
const connector = getConnector(request.target);
|
||||
|
||||
return connector.unsubscribeEvent(request.target);
|
||||
}
|
||||
case "CALL": {
|
||||
const connector = getConnector(request.target);
|
||||
|
||||
return connector.callActionSync(request.target, request.extraData.args);
|
||||
}
|
||||
case "CALL-ASYNC": {
|
||||
const connector = getConnector(request.target);
|
||||
|
||||
return connector.callActionAsync(request.target, request.extraData.args);
|
||||
}
|
||||
case "GET-OP-STATE": {
|
||||
const state = registration.connectorInterfaces.map(connector => connector.readAsyncActionState(request.target)).filter(state => state !== undefined)[0];
|
||||
if (state === undefined) throw new ReferenceError(`No connector found for operation handle ${request.target}`);
|
||||
return state;
|
||||
}
|
||||
case "GET-OP-RESULT": {
|
||||
const result = registration.connectorInterfaces.map(connector => connector.readAsyncActionResponse(request.target)).filter(result => result !== undefined)[0];
|
||||
if (result === undefined) throw new ReferenceError(`No connector found for operation handle ${request.target}`);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private onConnectorEvent(response: any) {
|
||||
for (const aas of this.aasRegistrations) {
|
||||
for (const server of aas.serverInstaces ?? []) {
|
||||
for (const server of aas.serverInstances ?? []) {
|
||||
server?.notify(response);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user