@hahnpro/flow-sdk 4.20.4 → 4.20.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/FlowApplication.d.ts +3 -6
- package/dist/FlowApplication.js +107 -94
- package/dist/FlowElement.js +4 -3
- package/dist/RpcClient.d.ts +4 -2
- package/dist/RpcClient.js +9 -9
- package/dist/TestModule.js +6 -6
- package/dist/extra-validators.js +1 -1
- package/dist/index.js +10 -10
- package/dist/rpc_server.py +6 -35
- package/dist/unit-utils.js +1 -1
- package/dist/utils.d.ts +4 -0
- package/dist/utils.js +12 -3
- package/package.json +12 -12
|
@@ -20,6 +20,7 @@ export declare class FlowApplication {
|
|
|
20
20
|
private properties;
|
|
21
21
|
private _rpcClient;
|
|
22
22
|
constructor(modules: ClassType<any>[], flow: Flow, logger?: Logger, amqpConnection?: AmqpConnection, skipApi?: boolean);
|
|
23
|
+
private init;
|
|
23
24
|
private setQueueMetrics;
|
|
24
25
|
private updateMetrics;
|
|
25
26
|
subscribe: (streamId: string, observer: PartialObserver<FlowEvent>) => import("rxjs").Subscription;
|
|
@@ -29,10 +30,10 @@ export declare class FlowApplication {
|
|
|
29
30
|
onMessage: (event: CloudEvent<any>) => Promise<Nack | undefined>;
|
|
30
31
|
/**
|
|
31
32
|
* Publish a flow event to the amqp flowlogs exchange.
|
|
32
|
-
* If the
|
|
33
|
+
* If the event size exceeds the limit it will be truncated
|
|
33
34
|
*/
|
|
34
35
|
publishEvent: (event: FlowEvent) => Promise<void>;
|
|
35
|
-
|
|
36
|
+
rpcClient(): Promise<RpcClient>;
|
|
36
37
|
/**
|
|
37
38
|
* Calls onDestroy lifecycle method on all flow elements,
|
|
38
39
|
* closes amqp connection after allowing logs to be processed and published
|
|
@@ -44,10 +45,6 @@ export declare class FlowApplication {
|
|
|
44
45
|
* A new subject will be created if one doesn't exist yet.
|
|
45
46
|
*/
|
|
46
47
|
private getOutputStream;
|
|
47
|
-
/**
|
|
48
|
-
* Truncates an object or string to the specified max length and depth
|
|
49
|
-
*/
|
|
50
|
-
private truncate;
|
|
51
48
|
}
|
|
52
49
|
export interface Context extends FlowElementContext {
|
|
53
50
|
app?: FlowApplication;
|
package/dist/FlowApplication.js
CHANGED
|
@@ -3,11 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.FlowApplication = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
require("reflect-metadata");
|
|
6
|
-
const object_sizeof_1 =
|
|
6
|
+
const object_sizeof_1 = tslib_1.__importDefault(require("object-sizeof"));
|
|
7
7
|
const perf_hooks_1 = require("perf_hooks");
|
|
8
8
|
const rxjs_1 = require("rxjs");
|
|
9
9
|
const operators_1 = require("rxjs/operators");
|
|
10
|
-
const util_1 = require("util");
|
|
11
10
|
const uuid_1 = require("uuid");
|
|
12
11
|
const hpc_api_1 = require("@hahnpro/hpc-api");
|
|
13
12
|
const amqp_1 = require("./amqp");
|
|
@@ -18,8 +17,7 @@ const MAX_EVENT_SIZE_BYTES = +process.env.MAX_EVENT_SIZE_BYTES || 512 * 1024;
|
|
|
18
17
|
const WARN_EVENT_PROCESSING_SEC = +process.env.WARN_EVENT_PROCESSING_SEC || 60;
|
|
19
18
|
const WARN_EVENT_QUEUE_SIZE = +process.env.WARN_EVENT_QUEUE_SIZE || 100;
|
|
20
19
|
class FlowApplication {
|
|
21
|
-
constructor(modules, flow, logger, amqpConnection, skipApi) {
|
|
22
|
-
var _a, _b, _c;
|
|
20
|
+
constructor(modules, flow, logger, amqpConnection, skipApi = false) {
|
|
23
21
|
this.amqpConnection = amqpConnection;
|
|
24
22
|
this.declarations = {};
|
|
25
23
|
this.elements = {};
|
|
@@ -152,7 +150,7 @@ class FlowApplication {
|
|
|
152
150
|
try {
|
|
153
151
|
const message = event.format();
|
|
154
152
|
if ((0, object_sizeof_1.default)(message) > MAX_EVENT_SIZE_BYTES) {
|
|
155
|
-
message.data =
|
|
153
|
+
message.data = (0, utils_1.truncate)(message.data);
|
|
156
154
|
}
|
|
157
155
|
return this.amqpConnection.publish('flowlogs', '', message);
|
|
158
156
|
}
|
|
@@ -174,111 +172,131 @@ class FlowApplication {
|
|
|
174
172
|
this.logger.log('Flow Deployment is terminating');
|
|
175
173
|
this.destroy(0);
|
|
176
174
|
});
|
|
175
|
+
this.init(flow, modules, logger, skipApi);
|
|
176
|
+
}
|
|
177
|
+
async init(flow, modules, logger, skipApi) {
|
|
178
|
+
this.context = Object.assign({}, flow.context);
|
|
179
|
+
this.properties = flow.properties || {};
|
|
177
180
|
try {
|
|
178
|
-
if (skipApi
|
|
181
|
+
if (!skipApi) {
|
|
179
182
|
this.api = new hpc_api_1.API();
|
|
180
183
|
}
|
|
181
184
|
}
|
|
182
185
|
catch (err) {
|
|
183
186
|
this.logger.error((err === null || err === void 0 ? void 0 : err.message) || err);
|
|
184
187
|
}
|
|
185
|
-
|
|
186
|
-
this.
|
|
187
|
-
this.
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
188
|
+
const logErrorAndExit = (err) => {
|
|
189
|
+
this.logger.error(new Error(err));
|
|
190
|
+
this.destroy(1);
|
|
191
|
+
};
|
|
192
|
+
if (this.amqpConnection) {
|
|
193
|
+
try {
|
|
194
|
+
await this.amqpConnection.managedChannel.assertExchange('deployment', 'direct', { durable: true });
|
|
195
|
+
await this.amqpConnection.managedChannel.assertExchange('flowlogs', 'fanout', { durable: true });
|
|
196
|
+
}
|
|
197
|
+
catch (e) {
|
|
198
|
+
logErrorAndExit(`Could not assert exchanges: ${e}`);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
try {
|
|
202
|
+
await this.amqpConnection.createSubscriber((msg) => this.onMessage(msg), {
|
|
203
|
+
exchange: 'deployment',
|
|
204
|
+
routingKey: this.context.deploymentId,
|
|
205
|
+
queueOptions: { durable: false, exclusive: true },
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
catch (err) {
|
|
209
|
+
logErrorAndExit(`Could not subscribe to deployment exchange: ${err}`);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
for (const module of modules) {
|
|
214
|
+
const moduleName = Reflect.getMetadata('module:name', module);
|
|
215
|
+
const moduleDeclarations = Reflect.getMetadata('module:declarations', module);
|
|
216
|
+
if (!moduleName || !moduleDeclarations || !Array.isArray(moduleDeclarations)) {
|
|
217
|
+
logErrorAndExit(`FlowModule (${module.name}) metadata is missing or invalid`);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
for (const declaration of moduleDeclarations) {
|
|
221
|
+
const functionFqn = Reflect.getMetadata('element:functionFqn', declaration);
|
|
222
|
+
if (!functionFqn) {
|
|
223
|
+
logErrorAndExit(`FlowFunction (${declaration.name}) metadata is missing or invalid`);
|
|
224
|
+
return;
|
|
200
225
|
}
|
|
226
|
+
this.declarations[`${moduleName}.${functionFqn}`] = declaration;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
for (const element of flow.elements) {
|
|
230
|
+
const { id, name, properties, module, functionFqn } = element;
|
|
231
|
+
try {
|
|
232
|
+
const context = Object.assign(Object.assign({}, this.context), { id, name, logger, app: this });
|
|
233
|
+
this.elements[id] = new this.declarations[`${module}.${functionFqn}`](context, properties);
|
|
234
|
+
}
|
|
235
|
+
catch (err) {
|
|
236
|
+
logErrorAndExit(`Could not create FlowElement for ${module}.${functionFqn}`);
|
|
237
|
+
return;
|
|
201
238
|
}
|
|
202
|
-
|
|
203
|
-
|
|
239
|
+
}
|
|
240
|
+
for (const connection of flow.connections) {
|
|
241
|
+
const { source, target, sourceStream = 'default', targetStream = 'default' } = connection;
|
|
242
|
+
if (!source || !target) {
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
const sourceStreamId = `${source}.${sourceStream}`;
|
|
246
|
+
const targetStreamId = `${target}.${targetStream}`;
|
|
247
|
+
const element = this.elements[target];
|
|
248
|
+
if (!element || !element.constructor) {
|
|
249
|
+
logErrorAndExit(`${target} has not been initialized`);
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
const streamHandler = Reflect.getMetadata(`stream:${targetStream}`, element.constructor);
|
|
253
|
+
if (!streamHandler || !element[streamHandler]) {
|
|
254
|
+
logErrorAndExit(`${target} does not implement a handler for ${targetStream}`);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
const streamOptions = Reflect.getMetadata(`stream:options:${targetStream}`, element.constructor) || {};
|
|
258
|
+
const concurrent = streamOptions.concurrent || 1;
|
|
259
|
+
const outputStream = this.getOutputStream(sourceStreamId);
|
|
260
|
+
outputStream
|
|
261
|
+
.pipe((0, operators_1.tap)(() => this.setQueueMetrics(targetStreamId)), (0, operators_1.mergeMap)(async (event) => {
|
|
262
|
+
this.performanceMap.set(event.getId(), perf_hooks_1.performance.eventLoopUtilization());
|
|
204
263
|
try {
|
|
205
|
-
|
|
206
|
-
this.elements[id] = new this.declarations[`${module}.${functionFqn}`](context, properties);
|
|
264
|
+
await element[streamHandler](event);
|
|
207
265
|
}
|
|
208
266
|
catch (err) {
|
|
209
|
-
throw new Error(`Could not create FlowElement for ${module}.${functionFqn}`);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
for (const connection of flow.connections) {
|
|
213
|
-
const { source, target, sourceStream = 'default', targetStream = 'default' } = connection;
|
|
214
|
-
if (!source || !target) {
|
|
215
|
-
continue;
|
|
216
|
-
}
|
|
217
|
-
const sourceStreamId = `${source}.${sourceStream}`;
|
|
218
|
-
const targetStreamId = `${target}.${targetStream}`;
|
|
219
|
-
const element = this.elements[target];
|
|
220
|
-
if (!element || !element.constructor) {
|
|
221
|
-
throw new Error(target + ' has not been initialized');
|
|
222
|
-
}
|
|
223
|
-
const streamHandler = Reflect.getMetadata(`stream:${targetStream}`, element.constructor);
|
|
224
|
-
if (!streamHandler || !element[streamHandler]) {
|
|
225
|
-
throw new Error(`${target} does not implement a handler for ${targetStream}`);
|
|
226
|
-
}
|
|
227
|
-
const streamOptions = Reflect.getMetadata(`stream:options:${targetStream}`, element.constructor) || {};
|
|
228
|
-
const concurrent = streamOptions.concurrent || 1;
|
|
229
|
-
const outputStream = this.getOutputStream(sourceStreamId);
|
|
230
|
-
outputStream
|
|
231
|
-
.pipe((0, operators_1.tap)(() => this.setQueueMetrics(targetStreamId)), (0, operators_1.mergeMap)(async (event) => {
|
|
232
|
-
this.performanceMap.set(event.getId(), perf_hooks_1.performance.eventLoopUtilization());
|
|
233
267
|
try {
|
|
234
|
-
|
|
268
|
+
element.handleApiError(err);
|
|
235
269
|
}
|
|
236
|
-
catch (
|
|
237
|
-
|
|
238
|
-
element.handleApiError(err);
|
|
239
|
-
}
|
|
240
|
-
catch (e) {
|
|
241
|
-
this.logger.error(err);
|
|
242
|
-
}
|
|
270
|
+
catch (e) {
|
|
271
|
+
this.logger.error(err);
|
|
243
272
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
}
|
|
273
|
+
}
|
|
274
|
+
return event;
|
|
275
|
+
}, concurrent), (0, operators_1.tap)((event) => {
|
|
276
|
+
this.updateMetrics(targetStreamId);
|
|
277
|
+
let elu = this.performanceMap.get(event.getId());
|
|
278
|
+
if (elu) {
|
|
279
|
+
this.performanceMap.delete(event.getId());
|
|
280
|
+
elu = perf_hooks_1.performance.eventLoopUtilization(elu);
|
|
281
|
+
if (elu.utilization > 0.7 && elu.active > 1000) {
|
|
282
|
+
this.logger.warn(`High event loop utilization detected for ${targetStreamId} with event ${event.getId()}! Handler has been active for ${Number(elu.active).toFixed(2)}ms with a utilization of ${Number(elu.utilization * 100).toFixed(2)}%. Consider refactoring or move tasks to a worker thread.`);
|
|
254
283
|
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
(_c = (_b = (_a = this.amqpConnection) === null || _a === void 0 ? void 0 : _a.managedChannel.assertExchange('deployment', 'direct', { durable: true })) === null || _b === void 0 ? void 0 : _b.then(() => this.amqpConnection.managedChannel.assertExchange('flowlogs', 'fanout', { durable: true }))) === null || _c === void 0 ? void 0 : _c.then(() => this.amqpConnection.createSubscriber((msg) => this.onMessage(msg), {
|
|
259
|
-
exchange: 'deployment',
|
|
260
|
-
routingKey: this.context.deploymentId,
|
|
261
|
-
queueOptions: { durable: false, exclusive: true },
|
|
262
|
-
})).catch((error) => {
|
|
263
|
-
this.logger.error('could not assert Exchange!\nError:\n' + error.toString());
|
|
264
|
-
});
|
|
265
|
-
this.logger.log('Flow Deployment is running');
|
|
266
|
-
}
|
|
267
|
-
catch (err) {
|
|
268
|
-
this.logger.error(err);
|
|
269
|
-
this.destroy(1);
|
|
284
|
+
}
|
|
285
|
+
}))
|
|
286
|
+
.subscribe();
|
|
270
287
|
}
|
|
288
|
+
this.logger.log('Flow Deployment is running');
|
|
271
289
|
}
|
|
272
290
|
getProperties() {
|
|
273
291
|
return this.properties;
|
|
274
292
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
if (!((_a = this.amqpConnection) === null || _a === void 0 ? void 0 : _a.managedConnection)) {
|
|
293
|
+
async rpcClient() {
|
|
294
|
+
if (!this.amqpConnection) {
|
|
278
295
|
throw new Error('No AMQP connection available');
|
|
279
296
|
}
|
|
280
297
|
if (!this._rpcClient) {
|
|
281
|
-
this._rpcClient = new RpcClient_1.RpcClient(this.amqpConnection
|
|
298
|
+
this._rpcClient = new RpcClient_1.RpcClient(this.amqpConnection);
|
|
299
|
+
await this._rpcClient.init();
|
|
282
300
|
}
|
|
283
301
|
return this._rpcClient;
|
|
284
302
|
}
|
|
@@ -301,7 +319,9 @@ class FlowApplication {
|
|
|
301
319
|
console.error(err);
|
|
302
320
|
}
|
|
303
321
|
finally {
|
|
304
|
-
process.
|
|
322
|
+
if (process.env.JEST_WORKER_ID == undefined || process.env.NODE_ENV !== 'test') {
|
|
323
|
+
process.exit(exitCode);
|
|
324
|
+
}
|
|
305
325
|
}
|
|
306
326
|
}
|
|
307
327
|
getOutputStream(id) {
|
|
@@ -312,12 +332,5 @@ class FlowApplication {
|
|
|
312
332
|
}
|
|
313
333
|
return stream;
|
|
314
334
|
}
|
|
315
|
-
truncate(msg, depth = 4, maxStringLength = 1000) {
|
|
316
|
-
let truncated = (0, util_1.inspect)(msg, { depth, maxStringLength });
|
|
317
|
-
if (truncated.startsWith("'") && truncated.endsWith("'")) {
|
|
318
|
-
truncated = truncated.substring(1, truncated.length - 1);
|
|
319
|
-
}
|
|
320
|
-
return truncated;
|
|
321
|
-
}
|
|
322
335
|
}
|
|
323
336
|
exports.FlowApplication = FlowApplication;
|
package/dist/FlowElement.js
CHANGED
|
@@ -9,9 +9,10 @@ const FlowEvent_1 = require("./FlowEvent");
|
|
|
9
9
|
const FlowLogger_1 = require("./FlowLogger");
|
|
10
10
|
const utils_1 = require("./utils");
|
|
11
11
|
class FlowElement {
|
|
12
|
-
constructor(_a, properties, propertiesClassType, whitelist
|
|
12
|
+
constructor(_a, properties, propertiesClassType, whitelist) {
|
|
13
13
|
var _b, _c;
|
|
14
|
-
var { app, logger } = _a, metadata =
|
|
14
|
+
var { app, logger } = _a, metadata = tslib_1.__rest(_a, ["app", "logger"]);
|
|
15
|
+
if (whitelist === void 0) { whitelist = false; }
|
|
15
16
|
this.propertiesClassType = propertiesClassType;
|
|
16
17
|
this.whitelist = whitelist;
|
|
17
18
|
this.stopPropagateStream = new Map();
|
|
@@ -92,7 +93,7 @@ class FlowElement {
|
|
|
92
93
|
async callRpcFunction(functionName, ...args) {
|
|
93
94
|
var _a, _b;
|
|
94
95
|
try {
|
|
95
|
-
return (_b = (_a = this.app) === null || _a === void 0 ? void 0 : _a.rpcClient) === null || _b === void 0 ? void 0 : _b.callFunction(this.rpcRoutingKey, functionName, ...args);
|
|
96
|
+
return (_b = (await ((_a = this.app) === null || _a === void 0 ? void 0 : _a.rpcClient()))) === null || _b === void 0 ? void 0 : _b.callFunction(this.rpcRoutingKey, functionName, ...args);
|
|
96
97
|
}
|
|
97
98
|
catch (err) {
|
|
98
99
|
this.logger.error(err);
|
package/dist/RpcClient.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AmqpConnection } from './amqp';
|
|
2
2
|
export declare class RpcClient {
|
|
3
|
+
private amqpConnection;
|
|
3
4
|
private channel;
|
|
4
5
|
private openRequests;
|
|
5
|
-
constructor(
|
|
6
|
+
constructor(amqpConnection: AmqpConnection);
|
|
7
|
+
init(): Promise<void>;
|
|
6
8
|
private onMessage;
|
|
7
9
|
callFunction: (routingKey: string, functionName: string, ...args: any[]) => Promise<unknown>;
|
|
8
10
|
declareFunction: (routingKey: string, name: string) => (...args: any[]) => Promise<unknown>;
|
package/dist/RpcClient.js
CHANGED
|
@@ -3,7 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.RpcClient = void 0;
|
|
4
4
|
const uuid_1 = require("uuid");
|
|
5
5
|
class RpcClient {
|
|
6
|
-
constructor(
|
|
6
|
+
constructor(amqpConnection) {
|
|
7
|
+
this.amqpConnection = amqpConnection;
|
|
7
8
|
this.openRequests = new Map();
|
|
8
9
|
this.onMessage = (msg) => {
|
|
9
10
|
if (this.openRequests.has(msg.properties.correlationId)) {
|
|
@@ -49,16 +50,15 @@ class RpcClient {
|
|
|
49
50
|
this.declareFunction = (routingKey, name) => {
|
|
50
51
|
return (...args) => this.callFunction(routingKey, name, ...args);
|
|
51
52
|
};
|
|
52
|
-
if (!
|
|
53
|
+
if (!amqpConnection) {
|
|
53
54
|
throw new Error('currently no amqp connection available');
|
|
54
55
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
});
|
|
56
|
+
}
|
|
57
|
+
async init() {
|
|
58
|
+
this.channel = this.amqpConnection.managedConnection.createChannel({ json: true });
|
|
59
|
+
await this.channel.waitForConnect();
|
|
60
|
+
await this.channel.assertExchange('rpc_direct_exchange', 'direct', { durable: false });
|
|
61
|
+
await this.channel.consume('amq.rabbitmq.reply-to', this.onMessage, { noAck: true });
|
|
62
62
|
}
|
|
63
63
|
close() {
|
|
64
64
|
return this.channel.close();
|
package/dist/TestModule.js
CHANGED
|
@@ -10,18 +10,18 @@ let TestTrigger = class TestTrigger extends FlowElement_1.FlowTask {
|
|
|
10
10
|
return this.emitOutput(event.getData());
|
|
11
11
|
}
|
|
12
12
|
};
|
|
13
|
-
|
|
13
|
+
tslib_1.__decorate([
|
|
14
14
|
(0, FlowElement_1.InputStream)('default'),
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
tslib_1.__metadata("design:type", Function),
|
|
16
|
+
tslib_1.__metadata("design:paramtypes", [FlowEvent_1.FlowEvent]),
|
|
17
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
18
18
|
], TestTrigger.prototype, "onDefault", null);
|
|
19
|
-
TestTrigger =
|
|
19
|
+
TestTrigger = tslib_1.__decorate([
|
|
20
20
|
(0, FlowElement_1.FlowFunction)('test.task.Trigger')
|
|
21
21
|
], TestTrigger);
|
|
22
22
|
let TestModule = class TestModule {
|
|
23
23
|
};
|
|
24
|
-
TestModule =
|
|
24
|
+
TestModule = tslib_1.__decorate([
|
|
25
25
|
(0, FlowModule_1.FlowModule)({ name: 'test', declarations: [TestTrigger] })
|
|
26
26
|
], TestModule);
|
|
27
27
|
exports.TestModule = TestModule;
|
package/dist/extra-validators.js
CHANGED
|
@@ -24,7 +24,7 @@ let IsNotSiblingOfConstraint = class IsNotSiblingOfConstraint {
|
|
|
24
24
|
return args.constraints.filter((prop) => (0, class_validator_1.isDefined)(args.object[prop]));
|
|
25
25
|
}
|
|
26
26
|
};
|
|
27
|
-
IsNotSiblingOfConstraint =
|
|
27
|
+
IsNotSiblingOfConstraint = tslib_1.__decorate([
|
|
28
28
|
(0, class_validator_1.ValidatorConstraint)({ async: false })
|
|
29
29
|
], IsNotSiblingOfConstraint);
|
|
30
30
|
function IsNotSiblingOf(props, validationOptions) {
|
package/dist/index.js
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.IncompatableWith = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
5
|
+
tslib_1.__exportStar(require("@hahnpro/hpc-api"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./flow.interface"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./utils"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./FlowApplication"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./FlowElement"), exports);
|
|
10
|
+
tslib_1.__exportStar(require("./FlowEvent"), exports);
|
|
11
|
+
tslib_1.__exportStar(require("./FlowLogger"), exports);
|
|
12
|
+
tslib_1.__exportStar(require("./FlowModule"), exports);
|
|
13
|
+
tslib_1.__exportStar(require("./TestModule"), exports);
|
|
14
|
+
tslib_1.__exportStar(require("./unit-decorators"), exports);
|
|
15
15
|
var extra_validators_1 = require("./extra-validators");
|
|
16
16
|
Object.defineProperty(exports, "IncompatableWith", { enumerable: true, get: function () { return extra_validators_1.IncompatableWith; } });
|
package/dist/rpc_server.py
CHANGED
|
@@ -5,41 +5,12 @@ from functools import partial, wraps
|
|
|
5
5
|
from aio_pika import IncomingMessage, Exchange, Message, connect_robust, ExchangeType
|
|
6
6
|
import os
|
|
7
7
|
|
|
8
|
-
user = ""
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
password = ""
|
|
15
|
-
try:
|
|
16
|
-
password = os.environ["RABBIT_PASSWORD"]
|
|
17
|
-
except:
|
|
18
|
-
password = "guest"
|
|
19
|
-
|
|
20
|
-
host = ""
|
|
21
|
-
try:
|
|
22
|
-
host = os.environ["RABBIT_HOST"]
|
|
23
|
-
except:
|
|
24
|
-
host = "localhost"
|
|
25
|
-
|
|
26
|
-
port = ""
|
|
27
|
-
try:
|
|
28
|
-
port = os.environ["RABBIT_PORT"]
|
|
29
|
-
except:
|
|
30
|
-
port = "5672"
|
|
31
|
-
|
|
32
|
-
vhost = ""
|
|
33
|
-
try:
|
|
34
|
-
vhost = os.environ["RABBIT_VHOST"]
|
|
35
|
-
except:
|
|
36
|
-
vhost = ""
|
|
37
|
-
|
|
38
|
-
routingKey = ""
|
|
39
|
-
try:
|
|
40
|
-
routingKey = os.environ["RPC_ROUTING_KEY"]
|
|
41
|
-
except:
|
|
42
|
-
routingKey = "rpc"
|
|
8
|
+
user = os.getenv("RABBIT_USER", "guest")
|
|
9
|
+
password = os.getenv("RABBIT_PASSWORD", "guest")
|
|
10
|
+
host = os.getenv("RABBIT_HOST", "localhost")
|
|
11
|
+
port = os.getenv("RABBIT_PORT", "5672")
|
|
12
|
+
vhost = os.getenv("RABBIT_VHOST", "")
|
|
13
|
+
routingKey = os.getenv("RPC_ROUTING_KEY", "rpc")
|
|
43
14
|
|
|
44
15
|
remoteProcedures = {}
|
|
45
16
|
|
package/dist/unit-utils.js
CHANGED
|
@@ -29,7 +29,7 @@ let UnitArgsValidator = class UnitArgsValidator {
|
|
|
29
29
|
return `${args.property} must be a number conforming to the specified constraints`;
|
|
30
30
|
}
|
|
31
31
|
};
|
|
32
|
-
UnitArgsValidator =
|
|
32
|
+
UnitArgsValidator = tslib_1.__decorate([
|
|
33
33
|
(0, class_validator_1.ValidatorConstraint)({ async: false })
|
|
34
34
|
], UnitArgsValidator);
|
|
35
35
|
const prefixes = [
|
package/dist/utils.d.ts
CHANGED
|
@@ -6,3 +6,7 @@ export declare function delay(ms: number): Promise<void>;
|
|
|
6
6
|
export declare function deleteFiles(dir: string, ...filenames: string[]): Promise<void>;
|
|
7
7
|
export declare function handleApiError(error: any, logger: FlowLogger): void;
|
|
8
8
|
export declare function runPyScript(scriptPath: string, data: any): Promise<any>;
|
|
9
|
+
/**
|
|
10
|
+
* Truncates an object or string to the specified max length and depth
|
|
11
|
+
*/
|
|
12
|
+
export declare function truncate(msg: any, depth?: number, maxStringLength?: number): string;
|
package/dist/utils.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.runPyScript = exports.handleApiError = exports.deleteFiles = exports.delay = exports.toArray = exports.getCircularReplacer = exports.fillTemplate = void 0;
|
|
3
|
+
exports.truncate = exports.runPyScript = exports.handleApiError = exports.deleteFiles = exports.delay = exports.toArray = exports.getCircularReplacer = exports.fillTemplate = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const fs_1 = require("fs");
|
|
6
|
-
const isPlainObject_1 =
|
|
6
|
+
const isPlainObject_1 = tslib_1.__importDefault(require("lodash/isPlainObject"));
|
|
7
7
|
const path_1 = require("path");
|
|
8
8
|
const python_shell_1 = require("python-shell");
|
|
9
|
-
const string_interp_1 =
|
|
9
|
+
const string_interp_1 = tslib_1.__importDefault(require("string-interp"));
|
|
10
|
+
const util_1 = require("util");
|
|
10
11
|
function fillTemplate(value, ...templateVariables) {
|
|
11
12
|
if ((0, isPlainObject_1.default)(value)) {
|
|
12
13
|
for (const key of Object.keys(value)) {
|
|
@@ -104,3 +105,11 @@ function runPyScript(scriptPath, data) {
|
|
|
104
105
|
});
|
|
105
106
|
}
|
|
106
107
|
exports.runPyScript = runPyScript;
|
|
108
|
+
function truncate(msg, depth = 4, maxStringLength = 1000) {
|
|
109
|
+
let truncated = (0, util_1.inspect)(msg, { depth, maxStringLength });
|
|
110
|
+
if (truncated.startsWith("'") && truncated.endsWith("'")) {
|
|
111
|
+
truncated = truncated.substring(1, truncated.length - 1);
|
|
112
|
+
}
|
|
113
|
+
return truncated;
|
|
114
|
+
}
|
|
115
|
+
exports.truncate = truncate;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hahnpro/flow-sdk",
|
|
3
|
-
"version": "4.20.
|
|
3
|
+
"version": "4.20.7",
|
|
4
4
|
"description": "SDK for building Flow Modules",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -24,31 +24,31 @@
|
|
|
24
24
|
"access": "public"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@hahnpro/hpc-api": "2.1.
|
|
27
|
+
"@hahnpro/hpc-api": "2.1.1",
|
|
28
28
|
"amqp-connection-manager": "^3.9.0",
|
|
29
29
|
"amqplib": "^0.8.0",
|
|
30
30
|
"class-transformer": "0.5.1",
|
|
31
31
|
"class-validator": "~0.13.2",
|
|
32
|
-
"cloudevents": "^5.3.
|
|
32
|
+
"cloudevents": "^5.3.2",
|
|
33
33
|
"lodash": "^4.17.21",
|
|
34
|
-
"object-sizeof": "^1.6.
|
|
34
|
+
"object-sizeof": "^1.6.3",
|
|
35
35
|
"python-shell": "^3.0.1",
|
|
36
36
|
"reflect-metadata": "^0.1.13",
|
|
37
|
-
"rxjs": "^7.5.
|
|
37
|
+
"rxjs": "^7.5.5",
|
|
38
38
|
"string-interp": "^0.3.6",
|
|
39
39
|
"uuid": "^8.3.2"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@golevelup/nestjs-rabbitmq": "^2.
|
|
43
|
-
"@nestjs/common": "^8.
|
|
42
|
+
"@golevelup/nestjs-rabbitmq": "^2.2.0",
|
|
43
|
+
"@nestjs/common": "^8.4.0",
|
|
44
44
|
"@types/amqp-connection-manager": "^2.0.12",
|
|
45
45
|
"@types/amqplib": "^0.8.2",
|
|
46
|
-
"@types/jest": "^27.4.
|
|
47
|
-
"@types/lodash": "^4.14.
|
|
48
|
-
"@types/node": "^16.11.
|
|
46
|
+
"@types/jest": "^27.4.1",
|
|
47
|
+
"@types/lodash": "^4.14.179",
|
|
48
|
+
"@types/node": "^16.11.26",
|
|
49
49
|
"class-validator-jsonschema": "^3.1.0",
|
|
50
|
-
"jest": "^27.
|
|
51
|
-
"typescript": "^4.
|
|
50
|
+
"jest": "^27.5.1",
|
|
51
|
+
"typescript": "^4.6.2"
|
|
52
52
|
},
|
|
53
53
|
"engines": {
|
|
54
54
|
"node": "^14.13.1 || >=16.0.0"
|