Moving Files and fix the Server Architecture

This commit is contained in:
Martin Karkowski 2020-11-12 17:07:05 +01:00
parent 2591e2cbfb
commit c8c721b1c9
23 changed files with 389 additions and 127 deletions

View File

@ -2,7 +2,7 @@
* @author Martin Karkowski * @author Martin Karkowski
* @email m.karkowski@zema.de * @email m.karkowski@zema.de
* @create date 2020-11-11 13:27:58 * @create date 2020-11-11 13:27:58
* @modify date 2020-11-11 15:41:24 * @modify date 2020-11-12 13:49:17
* @desc [description] * @desc [description]
*/ */
@ -39,7 +39,7 @@ const main = async function () {
['-f', '--file'], ['-f', '--file'],
{ {
help: 'File containing containing the package definitions.', help: 'File containing containing the package definitions.',
defaultValue: './config/packages.json', defaultValue: './config/settings.json',
type: 'string', type: 'string',
dest: 'file' dest: 'file'
} }

View File

@ -2,7 +2,7 @@
* @author Martin Karkowski * @author Martin Karkowski
* @email m.karkowski@zema.de * @email m.karkowski@zema.de
* @create date 2020-11-09 13:27:58 * @create date 2020-11-09 13:27:58
* @modify date 2020-11-10 16:24:52 * @modify date 2020-11-12 11:31:20
* @desc [description] * @desc [description]
*/ */
@ -109,7 +109,7 @@ const main = async function () {
} }
try { try {
await writeFile(join('dist', 'src', 'apidoc.json'), JSON.stringify(data.generalInformationModel, undefined, 4)); await writeFile(join('dist', 'lib', 'open-api', 'apidoc.json'), JSON.stringify(data.generalInformationModel, undefined, 4));
} catch(e){ } catch(e){
opts.logger.error('Failed to generate ' + join('dist', 'src', 'apidoc.json')); opts.logger.error('Failed to generate ' + join('dist', 'src', 'apidoc.json'));
console.error(e); console.error(e);

View File

@ -2,28 +2,29 @@
* @author Martin Karkowski * @author Martin Karkowski
* @email m.karkowski@zema.de * @email m.karkowski@zema.de
* @create date 2020-11-11 13:27:58 * @create date 2020-11-11 13:27:58
* @modify date 2020-11-11 16:59:09 * @modify date 2020-11-12 14:10:27
* @desc [description] * @desc [description]
*/ */
import { ArgumentParser } from 'argparse'; import { ArgumentParser } from 'argparse';
import { readFile } from 'fs/promises'; import { readFile } from 'fs/promises';
import "reflect-metadata"; import "reflect-metadata";
import { promisify } from 'util';
import { AmqpLayer } from '../communication/amqpLayer'; import { AmqpLayer } from '../communication/amqpLayer';
import { EventLayer } from '../communication/eventLayer'; import { EventLayer } from '../communication/eventLayer';
import { IoSocketClient } from '../communication/IoSocketClient'; import { IoSocketClient } from '../communication/IoSocketClient';
import { IoSocketServer } from '../communication/IoSocketServer'; import { IoSocketServer } from '../communication/IoSocketServer';
import { getLinkedDispatcher } from '../dispatcher/getLinkedDispatcher'; import { getLinkedDispatcher } from '../dispatcher/getLinkedDispatcher';
import { getPackageLoader } from '../loader/getPackageLoader'; import { getPackageLoader } from '../loader/getPackageLoader';
import { loadPackages } from '../loader/loadPackages'; import { loadFunctions, loadPackages } from '../loader/loadPackages';
import { getNopeLogger } from '../logger/getLogger'; import { getNopeLogger } from '../logger/getLogger';
import { LoggerLevels } from '../logger/nopeLogger';
import { setGlobalLoggerLevel } from '../logger/setGlobalLoggerLevel';
import { INopeDispatcher } from '../types/nope/nopeDispatcher.interface'; import { INopeDispatcher } from '../types/nope/nopeDispatcher.interface';
// Define the Main Function. // Define the Main Function.
// This function is used as cli tool. // This function is used as cli tool.
const main = async function () { export async function runNopeBackend() {
const parser = new ArgumentParser({ const parser = new ArgumentParser({
version: '1.0.0', version: '1.0.0',
@ -59,13 +60,11 @@ const main = async function () {
opts = {} as any opts = {} as any
} }
parser.addArgument( parser.addArgument(
['-f', '--file'], ['-f', '--file'],
{ {
help: 'File containing containing the package definitions.', help: 'File containing containing the package definitions.',
defaultValue: './config/packages.json', defaultValue: './config/settings.json',
type: 'string', type: 'string',
dest: 'file' dest: 'file'
} }
@ -82,7 +81,7 @@ const main = async function () {
} }
); );
parser.addArgument( parser.addArgument(
['-params', '--params'], ['-p', '--params'],
{ {
help: 'Paramas for the Channel, to connect to. The Following Defaults are used: \n' + JSON.stringify(layerDefaults, undefined, 4), help: 'Paramas for the Channel, to connect to. The Following Defaults are used: \n' + JSON.stringify(layerDefaults, undefined, 4),
defaultValue: 'not-provided', defaultValue: 'not-provided',
@ -90,8 +89,34 @@ const main = async function () {
dest: 'params' dest: 'params'
} }
); );
parser.addArgument(
['-s', '--skipLoadingConfig'],
{
help: 'Flag to prevent loading the elements defined in the settings.json.',
action: 'append', nargs: '?',
dest: 'skipLoadingConfig'
}
);
parser.addArgument(
['-l', '--log'],
{
help: 'Specify the Logger Level. Defaults to "info". Valid values are: ' + LoggerLevels.join(', '),
defaultValue: 'info',
type: 'string',
dest: 'log'
}
);
const args = parser.parseArgs(); const args = parser.parseArgs();
if (LoggerLevels.includes(args.log)){
setGlobalLoggerLevel(args.level);
}
args.skipLoadingConfig = Array.isArray(args.skipLoadingConfig);
// Define a Logger // Define a Logger
const logger = getNopeLogger('starter'); const logger = getNopeLogger('starter');
@ -112,11 +137,26 @@ const main = async function () {
} }
} }
// If required load all Packages.
if (!args.skipLoadingConfig){
// Try to load the Modules.
try {
logger.info('loading Packages')
await loadFunctions(args.file)
} catch (e) {
logger.error('Unable to load the Packages defined in ' + args.file + ' See Output for detailled information');
console.error(e)
return;
}
}
// Try to create an dispatcher: // Try to create an dispatcher:
let dispatcher: INopeDispatcher; let dispatcher: INopeDispatcher;
try { try {
dispatcher = getLinkedDispatcher({ dispatcher = getLinkedDispatcher({
communicator: new validLayers[args.channel](... opts.params) communicator: new validLayers[args.channel](... opts.params),
logger: getNopeLogger('dispatcher', 'silly')
}) })
} catch (e) { } catch (e) {
logger.error('Unable to create the Dispatcher. Please check the Provided Parameters.'); logger.error('Unable to create the Dispatcher. Please check the Provided Parameters.');
@ -126,14 +166,25 @@ const main = async function () {
await dispatcher.ready.waitFor(value => value); await dispatcher.ready.waitFor(value => value);
// Try to load the Modules. // If required load all Packages.
try { if (!args.skipLoadingConfig){
await loadPackages(getPackageLoader(dispatcher), args.file) // Try to load the Modules.
} catch (e) { try {
logger.error('Unable to load the Packages defined in ' + args.file + ' See Output for detailled information'); logger.info('loading Packages')
console.error(e) await loadPackages(getPackageLoader(dispatcher), args.file)
return; } catch (e) {
} logger.error('Unable to load the Packages defined in ' + args.file + ' See Output for detailled information');
console.error(e)
return;
}
}
// Return the Dispatcher.
return dispatcher;
} }
main().catch(e => console.error(e)); // If requested As Main => Perform the Operation.
if (require.main === module) {
runNopeBackend().catch(console.error);
}

View File

@ -0,0 +1,25 @@
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2020-11-12 11:22:27
* @modify date 2020-11-12 11:22:36
* @desc [description]
*/
import "reflect-metadata";
import { getNopeLogger } from '../logger/getLogger';
import { startOpenApiBackend } from '../open-api/startOpenApiBackend';
import { runNopeBackend } from './runNopeBackend';
// Define the Main Function.
// This function is used as cli tool.
export async function runOpenApiServer() {
const dispatcher = await runNopeBackend();
const result = await startOpenApiBackend(dispatcher, { port: 3001, logger: getNopeLogger('open-api-server', 'debug') });
}
// If requested As Main => Perform the Operation.
if (require.main === module) {
runOpenApiServer().catch(console.error);
}

View File

@ -2,22 +2,24 @@
* @author Martin Karkowski * @author Martin Karkowski
* @email m.karkowski@zema.de * @email m.karkowski@zema.de
* @create date 2020-11-04 17:36:04 * @create date 2020-11-04 17:36:04
* @modify date 2020-11-06 08:46:24 * @modify date 2020-11-12 13:23:48
* @desc [description] * @desc [description]
*/ */
import { EventEmitter } from 'events';
import { connect, Socket } from 'socket.io-client'; import { connect, Socket } from 'socket.io-client';
import { getCentralNopeLogger, getNopeLogger } from "../logger/getLogger"; import { Logger } from "winston";
import { getNopeLogger } from "../logger/getLogger";
import { NopeObservable } from '../observables/nopeObservable'; import { NopeObservable } from '../observables/nopeObservable';
import { IAvailableInstanceGeneratorsMsg, IAvailableServicesMsg, IAvailableTopicsMsg, ICommunicationInterface, IExternalEventMsg, IRequestTaskMsg, IResponseTaskMsg, ITaskCancelationMsg } from "../types/nope/nopeCommunication.interface"; import { IAvailableInstanceGeneratorsMsg, IAvailableServicesMsg, IAvailableTopicsMsg, ICommunicationInterface, IExternalEventMsg, IRequestTaskMsg, IResponseTaskMsg, ITaskCancelationMsg } from "../types/nope/nopeCommunication.interface";
import { INopeObservable } from '../types/nope/nopeObservable.interface'; import { INopeObservable } from '../types/nope/nopeObservable.interface';
import { Logger } from "winston";
export class IoSocketClient implements ICommunicationInterface { export class IoSocketClient implements ICommunicationInterface {
connected: INopeObservable<boolean>; connected: INopeObservable<boolean>;
protected _emitter: typeof Socket; protected _emitter: typeof Socket;
protected _internalEmitter: EventEmitter
protected _logger: Logger; protected _logger: Logger;
constructor(public uri: string) { constructor(public uri: string) {
@ -34,7 +36,8 @@ export class IoSocketClient implements ICommunicationInterface {
this._logger.info('connecting to: ' + uri); this._logger.info('connecting to: ' + uri);
this._emitter = connect(uri); this._emitter = connect(uri);
this._internalEmitter = new EventEmitter();
this._emitter.on('connect', (...args) => { this._emitter.on('connect', (...args) => {
// Element is connected // Element is connected
_this._logger.info('connected'); _this._logger.info('connected');
@ -48,10 +51,12 @@ export class IoSocketClient implements ICommunicationInterface {
} }
async onTaskCancelation(cb: (msg: ITaskCancelationMsg) => void) { async onTaskCancelation(cb: (msg: ITaskCancelationMsg) => void) {
this._internalEmitter.on('cancel', cb);
this._emitter.on('cancel', cb); this._emitter.on('cancel', cb);
} }
async emitTaskCancelation(msg: ITaskCancelationMsg) { async emitTaskCancelation(msg: ITaskCancelationMsg) {
this._internalEmitter.emit('cancel', msg);
this._emitter.emit('cancel', msg); this._emitter.emit('cancel', msg);
} }
@ -64,70 +69,87 @@ export class IoSocketClient implements ICommunicationInterface {
} }
async emitNewInstanceGeneratorsAvailable(generators: IAvailableInstanceGeneratorsMsg) { async emitNewInstanceGeneratorsAvailable(generators: IAvailableInstanceGeneratorsMsg) {
this._internalEmitter.emit('generators', generators);
this._emitter.emit('generators', generators); this._emitter.emit('generators', generators);
} }
async onNewInstanceGeneratorsAvailable(cb: (generators: IAvailableInstanceGeneratorsMsg) => void) { async onNewInstanceGeneratorsAvailable(cb: (generators: IAvailableInstanceGeneratorsMsg) => void) {
this._emitter.on('generators', cb) this._internalEmitter.on('generators', cb);
this._emitter.on('generators', cb);
} }
async emitRpcRequest(name: string, request: IRequestTaskMsg) { async emitRpcRequest(name: string, request: IRequestTaskMsg) {
this._internalEmitter.emit(name, request);
this._emitter.emit(name, request); this._emitter.emit(name, request);
} }
async emitRpcResult(name: string, result: IResponseTaskMsg) { async emitRpcResult(name: string, result: IResponseTaskMsg) {
this._internalEmitter.emit(name, result);
this._emitter.emit(name, result); this._emitter.emit(name, result);
} }
async onRpcResult(name: string, cb: (result: IResponseTaskMsg) => void) { async onRpcResult(name: string, cb: (result: IResponseTaskMsg) => void) {
this._internalEmitter.on(name, cb);
this._emitter.on(name, cb); this._emitter.on(name, cb);
} }
async offRpcResponse(name: string, cb: (result: IResponseTaskMsg) => void) { async offRpcResponse(name: string, cb: (result: IResponseTaskMsg) => void) {
this._internalEmitter.off(name, cb);
this._emitter.off(name, cb); this._emitter.off(name, cb);
} }
async onRpcRequest(name: string, cb: (data: IRequestTaskMsg) => void) { async onRpcRequest(name: string, cb: (data: IRequestTaskMsg) => void) {
this._internalEmitter.on(name, cb);
this._emitter.on(name, cb); this._emitter.on(name, cb);
} }
async offRpcRequest(name: string, cb: (data: IRequestTaskMsg) => void) { async offRpcRequest(name: string, cb: (data: IRequestTaskMsg) => void) {
this._internalEmitter.off(name, cb);
this._emitter.off(name, cb); this._emitter.off(name, cb);
} }
async emitNewServicesAvailable(services: IAvailableServicesMsg) { async emitNewServicesAvailable(services: IAvailableServicesMsg) {
this._internalEmitter.emit('services', services)
this._emitter.emit('services', services) this._emitter.emit('services', services)
} }
async onNewServicesAvailable(cb: (services: IAvailableServicesMsg) => void) { async onNewServicesAvailable(cb: (services: IAvailableServicesMsg) => void) {
this._internalEmitter.on('services', cb);
this._emitter.on('services', cb); this._emitter.on('services', cb);
} }
async onBonjour(cb: (dispatcher: string) => void) { async onBonjour(cb: (dispatcher: string) => void) {
this._internalEmitter.on('bonjour', cb);
this._emitter.on('bonjour', cb); this._emitter.on('bonjour', cb);
} }
async emitBonjour(dispatcher: string) { async emitBonjour(dispatcher: string) {
this._internalEmitter.emit('bonjour', dispatcher);
this._emitter.emit('bonjour', dispatcher); this._emitter.emit('bonjour', dispatcher);
} }
async emitNewTopicsAvailable(topics: IAvailableTopicsMsg) { async emitNewTopicsAvailable(topics: IAvailableTopicsMsg) {
this._internalEmitter.emit('topics', topics);
this._emitter.emit('topics', topics) this._emitter.emit('topics', topics)
} }
async onNewTopicsAvailable(cb: (topics: IAvailableTopicsMsg) => void) { async onNewTopicsAvailable(cb: (topics: IAvailableTopicsMsg) => void) {
this._emitter.on('topics', cb) this._emitter.on('topics', cb);
this._emitter.on('topics', cb);
} }
async onEvent(event: string, cb: (data: IExternalEventMsg) => void) { async onEvent(event: string, cb: (data: IExternalEventMsg) => void) {
this._emitter.on('event_' + event, cb); this._emitter.on('event_' + event, cb);
this._emitter.on('event_' + event, cb);
} }
async emitEvent(event: string, data: IExternalEventMsg) { async emitEvent(event: string, data: IExternalEventMsg) {
this._emitter.emit('event_' + event, data) this._internalEmitter.emit('event_' + event, data);
this._emitter.emit('event_' + event, data);
} }
async offEvent(event: string, cb: (data: IExternalEventMsg) => void) { async offEvent(event: string, cb: (data: IExternalEventMsg) => void) {
this._internalEmitter.off('event_' + event, cb);
this._emitter.off('event_' + event, cb); this._emitter.off('event_' + event, cb);
} }
} }

View File

@ -2,10 +2,11 @@
* @author Martin Karkowski * @author Martin Karkowski
* @email m.karkowski@zema.de * @email m.karkowski@zema.de
* @create date 2020-11-06 08:52:42 * @create date 2020-11-06 08:52:42
* @modify date 2020-11-11 16:29:07 * @modify date 2020-11-12 13:26:43
* @desc [description] * @desc [description]
*/ */
import { EventEmitter } from "events";
import { Server } from "http"; import { Server } from "http";
import * as io from 'socket.io'; import * as io from 'socket.io';
import { Logger } from "winston"; import { Logger } from "winston";
@ -24,6 +25,7 @@ export class IoSocketSeverEventEmitter {
protected _sockets: Set<io.Socket>; protected _sockets: Set<io.Socket>;
protected _funcs: Map<string, (...args: any[]) => void>; protected _funcs: Map<string, (...args: any[]) => void>;
protected _logger: Logger; protected _logger: Logger;
protected _internalEmitter: EventEmitter;
/** /**
* Creates an instance of IoSocketServer. * Creates an instance of IoSocketServer.
@ -38,6 +40,8 @@ export class IoSocketSeverEventEmitter {
this._socket = (io as any)(); this._socket = (io as any)();
} }
this._internalEmitter = new EventEmitter();
this.connected = new NopeObservable(); this.connected = new NopeObservable();
this.connected.setContent(false); this.connected.setContent(false);
@ -99,6 +103,7 @@ export class IoSocketSeverEventEmitter {
// Store the Function // Store the Function
this._funcs.set(event, cb); this._funcs.set(event, cb);
this._internalEmitter.on(event, cb);
} }
emit(event: string, data: any): void { emit(event: string, data: any): void {
@ -106,6 +111,7 @@ export class IoSocketSeverEventEmitter {
this._logger.debug('sending data on: ' + event); this._logger.debug('sending data on: ' + event);
} }
this._socket.emit(event, data); this._socket.emit(event, data);
this._internalEmitter.emit(event,data);
} }
} }

View File

@ -2,7 +2,7 @@
* @author Martin Karkowski * @author Martin Karkowski
* @email m.karkowski@zema.de * @email m.karkowski@zema.de
* @create date 2020-11-06 08:52:55 * @create date 2020-11-06 08:52:55
* @modify date 2020-11-06 09:21:34 * @modify date 2020-11-12 13:55:43
* @desc [description] * @desc [description]
*/ */
@ -34,12 +34,13 @@ export type callable<T> = {
* @param options The Options. * @param options The Options.
*/ */
export function exportFunctionToDispatcher<T>(func: T, options: IExportFunctionToDispatcherParameters) { export function exportFunctionToDispatcher<T>(func: T, options: IExportFunctionToDispatcherParameters) {
// Only add the element if it doesnt exists.
container.instance.set(options.id, { if (!container.instance.has(options.id)){
callback: async (...args) => await ((func as any)(...args)), container.instance.set(options.id, {
options, callback: async (...args) => await ((func as any)(...args)),
uri: options.id || (func as any).name options,
}); uri: options.id || (func as any).name
});
}
return func; return func;
} }

View File

@ -2,7 +2,7 @@
* @author Martin Karkowski * @author Martin Karkowski
* @email m.karkowski@zema.de * @email m.karkowski@zema.de
* @create date 2020-08-25 23:27:28 * @create date 2020-08-25 23:27:28
* @modify date 2020-11-11 16:38:47 * @modify date 2020-11-12 14:11:17
* @desc [description] * @desc [description]
*/ */
@ -16,18 +16,21 @@ import { getDispatcher } from "./getDispatcher";
* @param options * @param options
*/ */
export function getLinkedDispatcher(options: INopeRpcDispatcherOptions) { export function getLinkedDispatcher(options: INopeRpcDispatcherOptions) {
const container = getSingleton('nopeBackendDispatcher.container', () => {
return new Map<string, {
uri: string,
callback: (...args) => Promise<any>,
options: IExportFunctionToDispatcherParameters
}>()
});
// Create the Dispatcher Instance.
const dispatcher = getDispatcher(options); const dispatcher = getDispatcher(options);
// Define a Container, which contains all functions.
const container = getSingleton('nopeBackendDispatcher.container', () => {
return new Map<string, {
uri: string,
callback: (...args) => Promise<any>,
options: IExportFunctionToDispatcherParameters
}>()
});
// If the Dispatcher has been connected, register all functions. // If the Dispatcher has been connected, register all functions.
dispatcher.ready.waitFor(value => value).then(() => { dispatcher.ready.waitFor(value => value === true).then(() => {
if (dispatcher.ready.getContent()){ if (dispatcher.ready.getContent()){
// Iterate over the Functions // Iterate over the Functions
for (const [uri, settings] of container.instance.entries()) { for (const [uri, settings] of container.instance.entries()) {
@ -36,7 +39,7 @@ export function getLinkedDispatcher(options: INopeRpcDispatcherOptions) {
}); });
} }
} else { } else {
console.log('Failed') // Failed to Setup the Container.
} }
}); });

View File

@ -2,7 +2,7 @@
* @author Martin Karkowski * @author Martin Karkowski
* @email m.karkowski@zema.de * @email m.karkowski@zema.de
* @create date 2020-10-12 18:52:00 * @create date 2020-10-12 18:52:00
* @modify date 2020-11-09 09:43:40 * @modify date 2020-11-12 14:27:58
* @desc [description] * @desc [description]
*/ */
@ -141,8 +141,8 @@ export class nopeDispatcher implements INopeDispatcher {
provideInstanceGeneratorForExternalDispatchers<I extends INopeModule>(identifier: string, cb: IGenerateRemoteInstanceForOtherDispatcherCallback<I>) { provideInstanceGeneratorForExternalDispatchers<I extends INopeModule>(identifier: string, cb: IGenerateRemoteInstanceForOtherDispatcherCallback<I>) {
const _this = this; const _this = this;
if (this._logger?.isDebugEnabled()) { if (this._logger?.isSillyEnabled()) {
this._logger.debug('Adding instance generator for "' + identifier + '" to external Generators. Other Elements can now create instances of this type.'); this._logger.silly('Adding instance generator for "' + identifier + '" to external Generators. Other Elements can now create instances of this type.');
} }
const _cb = this.registerFunction(async (data: IInstanceCreationMsg) => { const _cb = this.registerFunction(async (data: IInstanceCreationMsg) => {
@ -219,8 +219,8 @@ export class nopeDispatcher implements INopeDispatcher {
unprovideInstanceGeneratorForExternalDispatchers(identifier: string) { unprovideInstanceGeneratorForExternalDispatchers(identifier: string) {
if (this._externalGenerators.has(identifier)) { if (this._externalGenerators.has(identifier)) {
if (this._logger?.isDebugEnabled()) { if (this._logger?.isSillyEnabled()) {
this._logger.debug('Removing instance generator for "' + identifier + '" from external Generators. Other Elements cant create instances of this type anymore.'); this._logger.silly('Removing instance generator for "' + identifier + '" from external Generators. Other Elements cant create instances of this type anymore.');
} }
this.unregisterFunction(this._externalGenerators.get(identifier)); this.unregisterFunction(this._externalGenerators.get(identifier));
@ -230,8 +230,8 @@ export class nopeDispatcher implements INopeDispatcher {
registerInternalInstanceGenerator<I extends INopeModule>(identifier: string, cb: IGenerateRemoteInstanceCallback<I>) { registerInternalInstanceGenerator<I extends INopeModule>(identifier: string, cb: IGenerateRemoteInstanceCallback<I>) {
if (this._logger?.isDebugEnabled()) { if (this._logger?.isSillyEnabled()) {
this._logger.debug('Adding instance generator for "' + identifier + '" as internal Generator. This Generator wont be used externally.'); this._logger.silly('Adding instance generator for "' + identifier + '" as internal Generator. This Generator wont be used externally.');
} }
this._internalGenerators.set(identifier, cb); this._internalGenerators.set(identifier, cb);
@ -239,8 +239,8 @@ export class nopeDispatcher implements INopeDispatcher {
unregisterInternalInstanceGenerator(identifier: string) { unregisterInternalInstanceGenerator(identifier: string) {
if (this._logger?.isDebugEnabled()) { if (this._logger?.isSillyEnabled()) {
this._logger.debug('Rmoving instance generator for "' + identifier + '" from internal Generator. The sytem cant create elements of this type any more.'); this._logger.silly('Rmoving instance generator for "' + identifier + '" from internal Generator. The sytem cant create elements of this type any more.');
} }
this._internalGenerators.delete(identifier); this._internalGenerators.delete(identifier);
@ -267,13 +267,13 @@ export class nopeDispatcher implements INopeDispatcher {
throw Error('Please Provide at least a "type" and "identifier" in the paremeters'); throw Error('Please Provide at least a "type" and "identifier" in the paremeters');
} }
if (this._logger?.isDebugEnabled()) { if (this._logger?.isSillyEnabled()) {
this._logger.debug('Requesting an Instance of type: "' + _defDescription.type + '" with the identifier: "' + _defDescription.identifier + '"'); this._logger.silly('Requesting an Instance of type: "' + _defDescription.type + '" with the identifier: "' + _defDescription.identifier + '"');
} }
if (this._instances.has(_description.identifier)) { if (this._instances.has(_description.identifier)) {
if (this._logger?.isDebugEnabled()) { if (this._logger?.isSillyEnabled()) {
this._logger.debug('Already created instance with the identifiert: "' + _defDescription.identifier + '" => returning this instance'); this._logger.silly('Already created instance with the identifiert: "' + _defDescription.identifier + '" => returning this instance');
} }
// Add the Dispatcher to the Element: // Add the Dispatcher to the Element:
@ -296,16 +296,16 @@ export class nopeDispatcher implements INopeDispatcher {
if (this._internalGenerators.has(_type)) { if (this._internalGenerators.has(_type)) {
if (this._logger?.isDebugEnabled()) { if (this._logger?.isSillyEnabled()) {
this._logger.debug('No instance with the identifiert: "' + _defDescription.identifier + '" found, but an internal generator is available. Using the internal one for creating the instance and requesting the "real" instance externally'); this._logger.silly('No instance with the identifiert: "' + _defDescription.identifier + '" found, but an internal generator is available. Using the internal one for creating the instance and requesting the "real" instance externally');
} }
const result = await this.performCall<IInstanceDescriptionMsg>('generateInstance_' + _description.type, [_description], { const result = await this.performCall<IInstanceDescriptionMsg>('generateInstance_' + _description.type, [_description], {
paramsHasNoCallback: true, paramsHasNoCallback: true,
}); });
if (this._logger?.isDebugEnabled()) { if (this._logger?.isSillyEnabled()) {
this._logger.debug('Received a description for the instance'); this._logger.silly('Received a description for the instance');
} }
// Create the Instance // Create the Instance
@ -470,12 +470,16 @@ export class nopeDispatcher implements INopeDispatcher {
if (this._logger?.isErrorEnabled()) { if (this._logger?.isErrorEnabled()) {
// If there is a Logger: // If there is a Logger:
this._logger.error('Dispatcher "' + this.id + '" failed with request: "' + data.taskId + '"'); this._logger.error('Dispatcher "' + this.id + '" failed with request: "' + data.taskId + '"');
this._logger.error(error); console.error(error);
this._logger.error(error);
} }
// An Error occourd => Forward the Error. // An Error occourd => Forward the Error.
const result: IResponseTaskMsg = { const result: IResponseTaskMsg = {
error, error: {
error,
msg: error.toString()
},
taskId: data.taskId, taskId: data.taskId,
type: 'response' type: 'response'
} }
@ -508,6 +512,12 @@ export class nopeDispatcher implements INopeDispatcher {
// Based on the Result of the Remote => // Based on the Result of the Remote =>
if (task && data.error) { if (task && data.error) {
if (this._logger?.isErrorEnabled()){
this._logger.error('Failed with task ' + data.taskId);
this._logger.error('Reason: ' + data.error.msg);
console.log(data.error.error);
}
task.reject(data.error); task.reject(data.error);
// Clearout the Timer // Clearout the Timer
@ -592,6 +602,10 @@ export class nopeDispatcher implements INopeDispatcher {
if (data.dispatcher !== _this.id) { if (data.dispatcher !== _this.id) {
_this._mappingOfRemoteDispatchersAndServices.set(data.dispatcher, data); _this._mappingOfRemoteDispatchersAndServices.set(data.dispatcher, data);
_this._updateExternalServices(); _this._updateExternalServices();
if (this._logger?.isSillyEnabled()) {
// If there is a Logger:
this._logger.silly('received new services');
}
} }
} catch (e) { } catch (e) {
} }
@ -603,6 +617,10 @@ export class nopeDispatcher implements INopeDispatcher {
if (data.dispatcher !== _this.id) { if (data.dispatcher !== _this.id) {
_this._mappingOfRemoteDispatchersAndTopics.set(data.dispatcher, data); _this._mappingOfRemoteDispatchersAndTopics.set(data.dispatcher, data);
_this._updateExternalEvents(); _this._updateExternalEvents();
if (this._logger?.isSillyEnabled()) {
// If there is a Logger:
this._logger.silly('received new events');
}
} }
} catch (e) { } catch (e) {
} }
@ -612,6 +630,10 @@ export class nopeDispatcher implements INopeDispatcher {
try { try {
_this._mappingOfRemoteDispatchersAndGenerators.set(data.dispatcher, data); _this._mappingOfRemoteDispatchersAndGenerators.set(data.dispatcher, data);
_this._updateExternalGenerators(); _this._updateExternalGenerators();
if (this._logger?.isSillyEnabled()) {
// If there is a Logger:
this._logger.silly('received new generators');
}
} catch (e) { } catch (e) {
} }
}) })
@ -638,6 +660,11 @@ export class nopeDispatcher implements INopeDispatcher {
_this._updateExternalServices(); _this._updateExternalServices();
_this._updateExternalGenerators(); _this._updateExternalGenerators();
_this._updateExternalEvents(); _this._updateExternalEvents();
if (this._logger?.isDebugEnabled()) {
// If there is a Logger:
this._logger.debug('a dispatcher went offline');
}
}); });
this._communicator.onTaskCancelation((event) => { this._communicator.onTaskCancelation((event) => {
@ -765,7 +792,7 @@ export class nopeDispatcher implements INopeDispatcher {
for (const dispatcherInfo of this._mappingOfRemoteDispatchersAndServices.values()) { for (const dispatcherInfo of this._mappingOfRemoteDispatchersAndServices.values()) {
dispatcherInfo.services.map(service => _this._externalProvidedServices.add(service)); dispatcherInfo.services.map(service => _this._externalProvidedServices.add(service));
} }
// Create a Comparing loop. // Create a Comparing loop.
// The Loop checks if the element doesnt exists in the known services // The Loop checks if the element doesnt exists in the known services
// before the update. // before the update.
@ -914,9 +941,9 @@ export class nopeDispatcher implements INopeDispatcher {
// Register Functions. // Register Functions.
this._communicator.onRpcRequest(_req, cb); this._communicator.onRpcRequest(_req, cb);
if (this._logger?.isDebugEnabled()) { if (this._logger?.isSillyEnabled()) {
// If there is a Logger: // If there is a Logger:
this._logger.debug('Dispatcher "' + this.id + '" listening on: "' + _req + '"'); this._logger.silly('Dispatcher "' + this.id + '" listening on: "' + _req + '"');
} }
} }
} }
@ -1014,9 +1041,9 @@ export class nopeDispatcher implements INopeDispatcher {
// Publish the Available Services. // Publish the Available Services.
this._sendAvailableServices(); this._sendAvailableServices();
if (this._logger?.isDebugEnabled()) { if (this._logger?.isSillyEnabled()) {
// If there is a Logger: // If there is a Logger:
this._logger.debug('Dispatcher "' + this.id + '" registered: "' + _id + '"'); this._logger.silly('Dispatcher "' + this.id + '" registered: "' + _id + '"');
} }
} }
@ -1042,9 +1069,9 @@ export class nopeDispatcher implements INopeDispatcher {
// Publish the Available Services. // Publish the Available Services.
this._sendAvailableServices(); this._sendAvailableServices();
if (this._logger?.isDebugEnabled()) { if (this._logger?.isSillyEnabled()) {
// If there is a Logger: // If there is a Logger:
this._logger.debug('Dispatcher "' + this.id + '" unregistered: "' + _id + '"'); this._logger.silly('Dispatcher "' + this.id + '" unregistered: "' + _id + '"');
} }
} }
@ -1061,9 +1088,9 @@ export class nopeDispatcher implements INopeDispatcher {
// Publish the Available Services. // Publish the Available Services.
this._sendAvailableProperties(); this._sendAvailableProperties();
if (this._logger?.isDebugEnabled()) { if (this._logger?.isSillyEnabled()) {
// If there is a Logger: // If there is a Logger:
this._logger.debug('Dispatcher "' + this.id + '" unregistered: "' + _id + '"'); this._logger.silly('Dispatcher "' + this.id + '" unregistered: "' + _id + '"');
} }
} }
@ -1490,13 +1517,13 @@ export class nopeDispatcher implements INopeDispatcher {
} }
if (_this._logger?.isDebugEnabled()) { if (_this._logger?.isSillyEnabled()) {
_this._logger.debug('Clearing Callbacks from ' + _taskId); _this._logger.silly('Clearing Callbacks from ' + _taskId);
} }
} }
if (_this._logger?.isDebugEnabled()) { if (_this._logger?.isSillyEnabled()) {
_this._logger.debug('Dispatcher "' + this.id + '" requesting externally Function "' + serviceName + '" with task: "' + _taskId + '"'); _this._logger.silly('Dispatcher "' + this.id + '" requesting externally Function "' + serviceName + '" with task: "' + _taskId + '"');
} }
// Define a Callback-Function, which will expect the Task. // Define a Callback-Function, which will expect the Task.
@ -1592,15 +1619,15 @@ export class nopeDispatcher implements INopeDispatcher {
if (_this._subscriptionMode === 'individual') { if (_this._subscriptionMode === 'individual') {
await _this._communicator.emitRpcRequest(_this._getServiceName(taskRequest.functionId, 'request'), taskRequest); await _this._communicator.emitRpcRequest(_this._getServiceName(taskRequest.functionId, 'request'), taskRequest);
if (_this._logger && _this._logger.isDebugEnabled()) { if (_this._logger && _this._logger.isSillyEnabled()) {
_this._logger.debug('Dispatcher "' + this.id + '" putting task "' + _taskId + '" on: "' + _this._getServiceName(taskRequest.functionId, 'request') + '"'); _this._logger.silly('Dispatcher "' + this.id + '" putting task "' + _taskId + '" on: "' + _this._getServiceName(taskRequest.functionId, 'request') + '"');
} }
} else { } else {
await _this._communicator.emitRpcRequest('request', taskRequest); await _this._communicator.emitRpcRequest('request', taskRequest);
if (_this._logger && _this._logger.isDebugEnabled()) { if (_this._logger && _this._logger.isSillyEnabled()) {
_this._logger.debug('Dispatcher "' + this.id + '" putting task "' + _taskId + '" on: "request"'); _this._logger.silly('Dispatcher "' + this.id + '" putting task "' + _taskId + '" on: "request"');
} }
} }

View File

@ -2,7 +2,7 @@
* @author Martin Karkowski * @author Martin Karkowski
* @email m.karkowski@zema.de * @email m.karkowski@zema.de
* @create date 2020-11-11 14:19:10 * @create date 2020-11-11 14:19:10
* @modify date 2020-11-11 16:12:18 * @modify date 2020-11-12 13:53:17
* @desc [description] * @desc [description]
*/ */
@ -15,7 +15,7 @@ import { IInstanceCreationMsg } from "../types/nope/nopeCommunication.interface"
import { IPackageDescription } from "../types/nope/nopePackage.interface"; import { IPackageDescription } from "../types/nope/nopePackage.interface";
import { INopePackageLoader } from "../types/nope/nopePackageLoader.interface"; import { INopePackageLoader } from "../types/nope/nopePackageLoader.interface";
export interface IConfigFile { export interface IPackageConfig {
nameOfPackage: string; nameOfPackage: string;
defaultInstances: { defaultInstances: {
options: Partial<IInstanceCreationMsg>; options: Partial<IInstanceCreationMsg>;
@ -31,6 +31,14 @@ export interface IConfigFile {
path: string; path: string;
} }
export interface IConfigFile {
functions: {
path: string,
functions: []
}[],
packages: IPackageConfig[]
}
/** /**
* List the available Packages * List the available Packages
* *
@ -65,6 +73,33 @@ export async function listPackages(dir: string = './modules') {
return ret; return ret;
} }
export async function listFunctions(dir: string = './modules') {
// Define the Return Array.
const ret = new Array<{
content: any,
path: string,
}>();
// Scan for the Package-Files
// And iterate over them.
for (const fileName of await listFiles(dir, '.functions.js')) {
// Now Try to load a Package, to test whether is is an assembly.
try {
ret.push({
content: (await import(resolve(fileName))).DESCRIPTION,
path: fileName
});
} catch (e) {
getNopeLogger('helper-list-functions').error('Failed Loading the functions in file: ' + fileName);
getNopeLogger('helper-list-functions').error(e);
}
}
return ret;
}
/** /**
* Helper Function to write a default configuration. * Helper Function to write a default configuration.
* *
@ -77,8 +112,7 @@ export async function writeDefaultConfig(
filename: string = join(resolve(process.cwd()), 'config', 'assembly.json') filename: string = join(resolve(process.cwd()), 'config', 'assembly.json')
) { ) {
// Determine all Packages // Determine all Packages
const packages = await listPackages(dir); const packages: IPackageConfig[] = (await listPackages(dir)).map(item => {
const valuesToStore: IConfigFile[] = packages.map(item => {
return { return {
nameOfPackage: item.package.nameOfPackage, nameOfPackage: item.package.nameOfPackage,
defaultInstances: item.package.defaultInstances, defaultInstances: item.package.defaultInstances,
@ -87,7 +121,18 @@ export async function writeDefaultConfig(
} }
}); });
await createFile(filename, JSON.stringify(valuesToStore, undefined, 4)); const functions = (await listFunctions(dir)).map(item => {
return {
path: item.path,
functions: Object.getOwnPropertyNames(item.content || {})
}
});
await createFile(filename, JSON.stringify({
functions,
packages
}, undefined, 4));
} }
/** /**
@ -98,7 +143,10 @@ export async function writeDefaultConfig(
* @param {string} filename * @param {string} filename
*/ */
export async function loadPackages(loader: INopePackageLoader,filename: string = join(resolve(process.cwd()), 'config', 'assembly.json')) { export async function loadPackages(loader: INopePackageLoader,filename: string = join(resolve(process.cwd()), 'config', 'assembly.json')) {
let data: IConfigFile[] = []; let data: IConfigFile = {
functions: [],
packages: []
};
try { try {
/** Load the File and Parse it. */ /** Load the File and Parse it. */
@ -126,7 +174,7 @@ export async function loadPackages(loader: INopePackageLoader,filename: string =
// Scan for the Package-Files // Scan for the Package-Files
// And iterate over them. // And iterate over them.
for (const item of data) { for (const item of data.packages) {
// Now Try to load a Package, to test whether is is an assembly. // Now Try to load a Package, to test whether is is an assembly.
try { try {
const loadedPackage = (await import(resolve(item.path))).DESCRIPTION as IPackageDescription<any>; const loadedPackage = (await import(resolve(item.path))).DESCRIPTION as IPackageDescription<any>;
@ -149,4 +197,49 @@ export async function loadPackages(loader: INopePackageLoader,filename: string =
// Generate the instances. // Generate the instances.
await loader.generateInstances() await loader.generateInstances()
}
export async function loadFunctions(filename: string = join(resolve(process.cwd()), 'config', 'assembly.json')){
let data: IConfigFile = {
functions: [],
packages: []
};
try {
/** Load the File and Parse it. */
data = JSON.parse(
await readFile(filename,{encoding: 'utf8'})
);
} catch (e) {
// Generate the Default File
await writeDefaultConfig(filename);
// Show an Hint
getNopeLogger('helper-load-packages').warn('No configuration was present. Created a new config file in ' + filename);
// Readin the newly created Data.
data = JSON.parse(await readFile(
filename, {
encoding:'utf8'
})
);
}
// Define the Return Array.
const functionPackages = new Array<any>();
// Scan for the Package-Files
// And iterate over them.
for (const item of data.functions) {
// Now Try to load a Package, to test whether is is an assembly.
try {
const loadedFunction = (await import(resolve(item.path))).DESCRIPTION as IPackageDescription<any>;
functionPackages.push(loadedFunction);
} catch (e) {
getNopeLogger('helper-load-packages').error('Failed Loading function-file at ' + item.path);
}
}
return functionPackages;
} }

View File

@ -2,7 +2,7 @@
* @author Martin Karkowski * @author Martin Karkowski
* @email m.karkowski@zema.de * @email m.karkowski@zema.de
* @create date 2018-07-01 09:10:35 * @create date 2018-07-01 09:10:35
* @modify date 2020-11-07 01:15:42 * @modify date 2020-11-12 13:17:43
* @desc [description] * @desc [description]
*/ */
@ -444,6 +444,8 @@ export class NopePackageLoader implements INopePackageLoader {
throw Error('Already loaded a Package with the name "' + element.nameOfPackage +'" !'); throw Error('Already loaded a Package with the name "' + element.nameOfPackage +'" !');
} }
this._logger.info('loading package ' + element.nameOfPackage);
// Store the Package // Store the Package
this.packages[element.nameOfPackage] = element; this.packages[element.nameOfPackage] = element;

View File

@ -5,6 +5,7 @@ import { SPLITCHAR } from "../helpers/objectMethods";
* Contains the Valid Types of the Loger. * Contains the Valid Types of the Loger.
*/ */
export type LoggerLevel = 'error' | 'warn' | 'info' | 'http' | 'verbose' | 'debug' | 'silly'; export type LoggerLevel = 'error' | 'warn' | 'info' | 'http' | 'verbose' | 'debug' | 'silly';
export const LoggerLevels = ['error' , 'warn' , 'info' , 'http' , 'verbose' , 'debug' , 'silly']
const order: {[K in LoggerLevel]: number} = { const order: {[K in LoggerLevel]: number} = {
error: 0, error: 0,

View File

@ -32,16 +32,16 @@ export function runMiddleware(app) {
new_req[i] = options[i]; new_req[i] = options[i];
} }
} else { } else {
new_req = createReq(path, options); new_req = _createReq(path, options);
} }
new_res = createRes(callback); new_res = _createRes(callback);
app(new_req, new_res); app(new_req, new_res);
}; };
/* end - APP.runMiddleware*/ /* end - APP.runMiddleware*/
}; };
function createReq(path, options) { function _createReq(path, options) {
if (!options) options = {}; if (!options) options = {};
var req = _.extend( var req = _.extend(
{ {
@ -58,7 +58,7 @@ function createReq(path, options) {
// req.connection=_req.connection // req.connection=_req.connection
return req; return req;
} }
function createRes(callback) { function _createRes(callback) {
var res: any = { var res: any = {
_removedHeader: {}, _removedHeader: {},
}; };

View File

@ -1,3 +1,11 @@
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2020-11-12 11:21:41
* @modify date 2020-11-12 11:21:43
* @desc [description]
*/
import * as bodyParser from "body-parser"; import * as bodyParser from "body-parser";
import * as cors from 'cors'; import * as cors from 'cors';
import * as express from "express"; import * as express from "express";
@ -7,8 +15,7 @@ import { assignIn } from 'lodash';
import { join } from "path"; import { join } from "path";
import "reflect-metadata"; import "reflect-metadata";
import { Logger } from 'winston'; import { Logger } from 'winston';
import { IoSocketServer } from "../lib/communication/IoSocketServer"; import { INopeDispatcher } from "../types/nope/nopeDispatcher.interface";
import { getLinkedDispatcher } from "../lib/dispatcher/getLinkedDispatcher";
import { getBackendAccesors } from './getBackendAccessors'; import { getBackendAccesors } from './getBackendAccessors';
/** /**
@ -35,9 +42,12 @@ function _genApiDoc(title: string, version: string, basePath: string, definition
/** /**
* Function to start a Open-API-Server * Function to start a Open-API-Server
* @param _dispatcher The Dispatcher, which should be used.
* @param options Options for the Server * @param options Options for the Server
*/ */
export async function startBackend(options: { export async function startOpenApiBackend(
_dispatcher: INopeDispatcher,
options: {
port?: number, port?: number,
backendPort?: number, backendPort?: number,
basePath?: string, basePath?: string,
@ -77,11 +87,7 @@ export async function startBackend(options: {
routesGlob: '**/*.{ts,js}', routesGlob: '**/*.{ts,js}',
routesIndexFileRegExp: /(?:index)?\.[tj]s$/, routesIndexFileRegExp: /(?:index)?\.[tj]s$/,
dependencies: { dependencies: {
_dispatcher: getLinkedDispatcher( _dispatcher
{
communicator: new IoSocketServer(opts.backendPort, 'generic', 'generic')
}
)
}, },
}); });

View File

@ -76,6 +76,9 @@ export async function parseModuleToOpenAPI(description: IParsableDescription, op
// 1. Specify the Mode (No Params = GET, else POST) // 1. Specify the Mode (No Params = GET, else POST)
(method as any).mode = method.schema.inputs.length > 0 ? 'POST' : 'GET'; (method as any).mode = method.schema.inputs.length > 0 ? 'POST' : 'GET';
(method as any).required = method.schema.inputs.filter(param => !param.optional).map(param => param.name);
(method as any).hasInput = method.schema.inputs.length > 0;
// Now adapt the Schema of the Method. // Now adapt the Schema of the Method.
// Iterate over the Inputs, add a Description if not provided // Iterate over the Inputs, add a Description if not provided
// And determine whehter the Parameters are required or not. // And determine whehter the Parameters are required or not.
@ -83,8 +86,6 @@ export async function parseModuleToOpenAPI(description: IParsableDescription, op
// Provide a Description. (If not provided) // Provide a Description. (If not provided)
param.description = param.description || 'Not provided'; param.description = param.description || 'Not provided';
// Open API uses "required" instead of optional => invert
param.optional = !param.optional;
if (options.sharedDefinitions){ if (options.sharedDefinitions){
param.schema.definitions = undefined; param.schema.definitions = undefined;
@ -111,6 +112,8 @@ export async function parseModuleToOpenAPI(description: IParsableDescription, op
(method as any).resultDescription = method.schema.outputs.description || 'Not Provided'; (method as any).resultDescription = method.schema.outputs.description || 'Not Provided';
// And add a Schema for the Return type. // And add a Schema for the Return type.
(method as any).parsedOutput = JSON.stringify(method.schema.outputs); (method as any).parsedOutput = JSON.stringify(method.schema.outputs);
(method as any).parsedInput = JSON.stringify(_unifySchema(method.schema.inputs, options));
(method as any).hasInput = method.schema.inputs.length > 0;
(method as any).tag = description.name; (method as any).tag = description.name;
// Determine the Filename. // Determine the Filename.
@ -134,7 +137,7 @@ export async function parseModuleToOpenAPI(description: IParsableDescription, op
for (const imp of imports){ for (const imp of imports){
const relativDir = relative(fileDir, imp.dir); const relativDir = relative(fileDir, imp.dir);
(method as any)[imp.name] = replaceAll(join(relativDir, imp.fileName), '\\', '/'); (method as any)[imp.name] = replaceAll(join(relativDir, imp.fileName), '\\', '/');
} }
// Write down the Schema: // Write down the Schema:
await createFile( await createFile(
@ -192,8 +195,6 @@ export async function parseFunctionToOpenAPI(description: IFunctionOptions, opti
// Provide a Description. (If not provided) // Provide a Description. (If not provided)
param.description = param.description || 'Not provided'; param.description = param.description || 'Not provided';
// Open API uses "required" instead of optional => invert
param.optional = !param.optional;
if (options.sharedDefinitions){ if (options.sharedDefinitions){
param.schema.definitions = undefined; param.schema.definitions = undefined;
@ -221,10 +222,14 @@ export async function parseFunctionToOpenAPI(description: IFunctionOptions, opti
// And add a Schema for the Return type. // And add a Schema for the Return type.
(_description as any).parsedOutput = JSON.stringify(_description.schema.outputs); (_description as any).parsedOutput = JSON.stringify(_description.schema.outputs);
(_description as any).tag = 'generic-services'; (_description as any).tag = 'generic-services';
(_description as any).parsedInput = JSON.stringify(_unifySchema(_description.schema.inputs, options));
(_description as any).hasInput = _description.schema.inputs.length > 0;
(_description as any).required = _description.schema.inputs.filter(param => !param.optional).map(param => param.name);
(_description as any).name = _description.id;
// Determine the Filename. // Determine the Filename.
const fileDir = join(options.outputDir, 'generic-services'); const fileDir = join(options.outputDir, 'generic-services');
const fileName = join(fileDir, _description.id+'.ts'); const fileName = join(fileDir, _description.id + '.ts');
// Determine the Import Pathes. // Determine the Import Pathes.
const imports = [ const imports = [

View File

@ -34,16 +34,15 @@ export default function (_dispatcher: INopeDispatcher) {
{{#if methodDescription}}summary: '{{methodDescription}}',{{/if}} {{#if methodDescription}}summary: '{{methodDescription}}',{{/if}}
{{#if operationId}}operationId: '{{operationId}}',{{/if}} {{#if operationId}}operationId: '{{operationId}}',{{/if}}
parameters: [ parameters: [
{{#each schema.inputs}} {{#if hasInput}}
{ {
name: '{{name}}', name: '{{name}}',
in: "body", in: "body",
description: '{{description}}', description: '{{description}}',
required: {{optional}}, required: true,
schema: {{{parsedSchema}}} schema: {{{parsedInput}}}
}
}{{#unless @last}},{{/unless}} {{/if}}
{{/each}}
], ],
responses: { responses: {
200: { 200: {

View File

@ -43,7 +43,17 @@ export default function (_dispatcher: INopeDispatcher) {
schema: {{{parsedSchema}}} schema: {{{parsedSchema}}}
}{{#unless @last}},{{/unless}} }{{#unless @last}},{{/unless}}
{{/each}} {{/each}}
schema: {
type: 'object',
properties: {
{{#each schema.inputs}}
{{name}}: {{{parsedSchema}}}{{#unless @last}},{{/unless}}
{{/each}}
},
required: [{{#each required}}element{{#unless @last}},{{/unless}}{{/each}}]
}
], ],
responses: { responses: {
200: { 200: {

View File

@ -2,7 +2,7 @@
* @author Martin Karkowski * @author Martin Karkowski
* @email m.karkowski@zema.de * @email m.karkowski@zema.de
* @create date 2020-10-12 18:31:54 * @create date 2020-10-12 18:31:54
* @modify date 2020-11-06 23:17:07 * @modify date 2020-11-12 14:26:21
* @desc [description] * @desc [description]
*/ */
@ -439,7 +439,10 @@ export type IResponseTaskMsg = {
* *
* @type {*} * @type {*}
*/ */
error?: any error?: {
error: any,
msg: string
}
} }
export type IAvailableServicesMsg = { export type IAvailableServicesMsg = {

View File

@ -2,11 +2,12 @@
* @author Martin Karkowski * @author Martin Karkowski
* @email m.karkowski@zema.de * @email m.karkowski@zema.de
* @create date 2020-11-10 16:53:43 * @create date 2020-11-10 16:53:43
* @modify date 2020-11-11 16:57:30 * @modify date 2020-11-12 14:29:57
* @desc [description] * @desc [description]
*/ */
import { IPackageDescription } from "../../../lib/types/nope/nopePackage.interface"; import { IPackageDescription } from "../../../lib/types/nope/nopePackage.interface";
import { startTask } from "./xetics.functions";
import { XeticsInterfaceClient } from "./xetics.module"; import { XeticsInterfaceClient } from "./xetics.module";
const TYPES = { const TYPES = {
@ -22,7 +23,7 @@ export const DESCRIPTION: IPackageDescription<typeof TYPES> = {
identifier: "xetics-einlegen", identifier: "xetics-einlegen",
params: [ params: [
'Einlegen', 'Einlegen',
0 1
], ],
type: XeticsInterfaceClient.prototype.constructor.name.toString() type: XeticsInterfaceClient.prototype.constructor.name.toString()
}, },
@ -33,7 +34,7 @@ export const DESCRIPTION: IPackageDescription<typeof TYPES> = {
identifier: "xetics-schrauben", identifier: "xetics-schrauben",
params: [ params: [
'Verschrauben', 'Verschrauben',
0 1
], ],
type: XeticsInterfaceClient.prototype.constructor.name.toString() type: XeticsInterfaceClient.prototype.constructor.name.toString()
}, },
@ -43,7 +44,7 @@ export const DESCRIPTION: IPackageDescription<typeof TYPES> = {
identifier: "xetics-qualitaetskontrolle", identifier: "xetics-qualitaetskontrolle",
params: [ params: [
'Qualitaetskontrolle', 'Qualitaetskontrolle',
0 1
], ],
type: XeticsInterfaceClient.prototype.constructor.name.toString() type: XeticsInterfaceClient.prototype.constructor.name.toString()
}, },
@ -53,7 +54,7 @@ export const DESCRIPTION: IPackageDescription<typeof TYPES> = {
identifier: "xetics-verpacken", identifier: "xetics-verpacken",
params: [ params: [
'Verpacken', 'Verpacken',
0 1
], ],
type: XeticsInterfaceClient.prototype.constructor.name.toString() type: XeticsInterfaceClient.prototype.constructor.name.toString()
}, },
@ -64,7 +65,7 @@ export const DESCRIPTION: IPackageDescription<typeof TYPES> = {
providedClasses: [ providedClasses: [
{ {
description: { description: {
name: XeticsInterfaceClient.constructor.name, name: XeticsInterfaceClient.prototype.constructor.name.toString(),
selector: TYPES.xeticsClient, selector: TYPES.xeticsClient,
type: XeticsInterfaceClient type: XeticsInterfaceClient
}, },
@ -73,7 +74,14 @@ export const DESCRIPTION: IPackageDescription<typeof TYPES> = {
} }
} }
], ],
providedFunctions: [], providedFunctions: [
{
function: startTask,
options: {
id: 'startTask'
}
}
],
requiredPackages: [], requiredPackages: [],
types: TYPES types: TYPES
} }

View File

@ -12,5 +12,5 @@
}, },
"tempDir": "./temp/", "tempDir": "./temp/",
"configDir": "./config", "configDir": "./config",
"modules": "./modules" "modules": "./dist/modules"
} }