@mojaloop/sdk-scheme-adapter 24.13.0 → 24.14.0-snapshot.0
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/.yarn/cache/{@mojaloop-central-services-shared-npm-18.34.0-98deaad7cb-660f407a57.zip → @mojaloop-central-services-shared-npm-18.34.1-fc3be8e73c-f7ad2f9394.zip} +0 -0
- package/.yarn/cache/{@mojaloop-inter-scheme-proxy-cache-lib-npm-2.7.0-84455815f8-7748014a4c.zip → @mojaloop-inter-scheme-proxy-cache-lib-npm-2.9.0-cb33cd6786-fd3f20e6a7.zip} +0 -0
- package/.yarn/cache/@typescript-eslint-eslint-plugin-npm-8.46.0-e6114965b4-415afd894a.zip +0 -0
- package/.yarn/cache/@typescript-eslint-parser-npm-8.46.0-c44629050a-6838fde776.zip +0 -0
- package/.yarn/cache/@typescript-eslint-project-service-npm-8.46.0-85a4b9bb9c-de11af23ae.zip +0 -0
- package/.yarn/cache/@typescript-eslint-scope-manager-npm-8.46.0-fd8edaba78-ed85abd08c.zip +0 -0
- package/.yarn/cache/@typescript-eslint-tsconfig-utils-npm-8.46.0-8919c1f746-e78a66a854.zip +0 -0
- package/.yarn/cache/@typescript-eslint-type-utils-npm-8.46.0-dbfff922bb-5405b71b91.zip +0 -0
- package/.yarn/cache/@typescript-eslint-types-npm-8.46.0-b013400d3e-0118b0dd59.zip +0 -0
- package/.yarn/cache/@typescript-eslint-typescript-estree-npm-8.46.0-0b10d4388a-61053bd0c3.zip +0 -0
- package/.yarn/cache/@typescript-eslint-utils-npm-8.46.0-a7d3832f43-4e0da60de3.zip +0 -0
- package/.yarn/cache/@typescript-eslint-visitor-keys-npm-8.46.0-7d793afea5-37e6145b6a.zip +0 -0
- package/.yarn/install-state.gz +0 -0
- package/.yarn/releases/{yarn-4.10.2.cjs → yarn-4.10.3.cjs} +126 -126
- package/.yarnrc.yml +1 -1
- package/CLAUDE.md +186 -0
- package/_cc/learn-project.md +74 -0
- package/_cc/specs/story-CSI-1864.md +45 -0
- package/modules/api-svc/package.json +2 -2
- package/modules/api-svc/src/ControlAgent/index.js +45 -12
- package/modules/api-svc/src/config.js +1 -0
- package/modules/api-svc/src/index.js +243 -188
- package/modules/api-svc/src/lib/cache.js +3 -1
- package/modules/api-svc/test/unit/index.configPolling.test.js +229 -0
- package/modules/api-svc/test/unit/lib/model/InboundPingModel.test.js +2 -2
- package/modules/outbound-command-event-handler/package.json +4 -4
- package/modules/outbound-domain-event-handler/package.json +3 -3
- package/modules/private-shared-lib/package.json +4 -4
- package/package.json +4 -4
- package/{sbom-v24.12.0.csv → sbom-v24.13.0.csv} +220 -231
|
@@ -53,7 +53,7 @@ const { SDKStateEnum } = require('./lib/model/common');
|
|
|
53
53
|
const { createAuthClient } = require('./lib/utils');
|
|
54
54
|
const { logger } = require('./lib/logger');
|
|
55
55
|
|
|
56
|
-
const PING_INTERVAL_MS =
|
|
56
|
+
const PING_INTERVAL_MS = 30_000;
|
|
57
57
|
|
|
58
58
|
const createCache = (config) => new Cache({
|
|
59
59
|
logger,
|
|
@@ -203,6 +203,71 @@ class Server extends EventEmitter {
|
|
|
203
203
|
return isOutboundDifferent || isJwsSigningKeyDifferent;
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
+
/**
|
|
207
|
+
* Starts periodic polling of Management API for configuration updates.
|
|
208
|
+
* Only runs if PM4ML enabled and a polling interval configured.
|
|
209
|
+
*/
|
|
210
|
+
_startConfigPolling() {
|
|
211
|
+
if (!this.conf.pm4mlEnabled || !this.conf.control.mgmtAPIPollIntervalMs) {
|
|
212
|
+
this.logger.info('No failsafe config polling configured');
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
this.logger.info('starting failsafe config polling from Management API...', { intervalMs: this.conf.control.mgmtAPIPollIntervalMs });
|
|
217
|
+
|
|
218
|
+
this._configPollInterval = setInterval(
|
|
219
|
+
() => this._pollConfigFromMgmtAPI(),
|
|
220
|
+
this.conf.control.mgmtAPIPollIntervalMs
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
// Unref so it doesn't prevent process exit
|
|
224
|
+
this._configPollInterval.unref();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Polls Management API for configuration updates.
|
|
229
|
+
* Reuses the existing persistent WebSocket client (this.controlClient).
|
|
230
|
+
* Skips polling if:
|
|
231
|
+
* - Another config update is in progress
|
|
232
|
+
* - WebSocket client is not connected
|
|
233
|
+
*/
|
|
234
|
+
async _pollConfigFromMgmtAPI() {
|
|
235
|
+
// Race condition prevention: skip if restart in progress
|
|
236
|
+
if (this._configUpdateInProgress) {
|
|
237
|
+
this.logger.info('config updating already in progress, skipping poll');
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// WebSocket readyState: 0=CONNECTING, 1=OPEN, 2=CLOSING, 3=CLOSED
|
|
242
|
+
if (this.controlClient?.readyState !== 1) {
|
|
243
|
+
this.logger.warn('Control client not ready (not OPEN), skipping poll', { readyState: this.controlClient?.readyState });
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
try {
|
|
248
|
+
const newConfig = await this.controlClient.getUpdatedConfig();
|
|
249
|
+
if (!newConfig) {
|
|
250
|
+
this.logger.warn('No config received from polling');
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
this.logger.info('polling config from Management API is done, restarting server...');
|
|
254
|
+
|
|
255
|
+
const mergedConfig = _.merge({}, this.conf, newConfig);
|
|
256
|
+
await this.restart(mergedConfig, { source: 'polling' });
|
|
257
|
+
} catch (err) {
|
|
258
|
+
this.logger.error('error in polling config from Management API: ', err);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/** Stops the config polling interval. */
|
|
263
|
+
_stopConfigPolling() {
|
|
264
|
+
if (this._configPollInterval) {
|
|
265
|
+
this.logger.verbose('stopping config polling');
|
|
266
|
+
clearInterval(this._configPollInterval);
|
|
267
|
+
this._configPollInterval = null;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
206
271
|
async start() {
|
|
207
272
|
await this.cache.connect();
|
|
208
273
|
await this.oidc.auth.start();
|
|
@@ -213,12 +278,7 @@ class Server extends EventEmitter {
|
|
|
213
278
|
// management protocol messages e.g configuration changes, certificate updates etc.
|
|
214
279
|
if (this.conf.pm4mlEnabled) {
|
|
215
280
|
const RESTART_INTERVAL_MS = 10000;
|
|
216
|
-
this.controlClient = await ControlAgent.
|
|
217
|
-
address: this.conf.control.mgmtAPIWsUrl,
|
|
218
|
-
port: this.conf.control.mgmtAPIWsPort,
|
|
219
|
-
logger: this.logger,
|
|
220
|
-
appConfig: this.conf,
|
|
221
|
-
});
|
|
281
|
+
this.controlClient = await ControlAgent.createConnectedControlAgentWs(this.conf, this.logger);
|
|
222
282
|
this.controlClient.on(ControlAgent.EVENT.RECONFIGURE, this.restart.bind(this));
|
|
223
283
|
|
|
224
284
|
const schedulePing = () => {
|
|
@@ -247,6 +307,7 @@ class Server extends EventEmitter {
|
|
|
247
307
|
});
|
|
248
308
|
|
|
249
309
|
schedulePing();
|
|
310
|
+
this._startConfigPolling();
|
|
250
311
|
}
|
|
251
312
|
|
|
252
313
|
await Promise.all([
|
|
@@ -260,190 +321,200 @@ class Server extends EventEmitter {
|
|
|
260
321
|
]);
|
|
261
322
|
}
|
|
262
323
|
|
|
263
|
-
async restart(newConf) {
|
|
324
|
+
async restart(newConf, options = {}) {
|
|
325
|
+
const source = options.source || 'websocket'; // Track source of restart call - websocket or polling
|
|
326
|
+
|
|
327
|
+
// Race condition prevention
|
|
328
|
+
if (this._configUpdateInProgress) {
|
|
329
|
+
this.logger.info('Restart already in progress, skipping', { source });
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
|
|
264
333
|
const restartActionsTaken = {};
|
|
265
|
-
this.logger.
|
|
334
|
+
this.logger.debug('Server is restarting...', { source });
|
|
335
|
+
this._configUpdateInProgress = true;
|
|
266
336
|
|
|
267
|
-
|
|
268
|
-
|
|
337
|
+
try {
|
|
338
|
+
let oldCache;
|
|
339
|
+
const updateCache = !_.isEqual(this.conf.cacheUrl, newConf.cacheUrl)
|
|
269
340
|
|| !_.isEqual(this.conf.enableTestFeatures, newConf.enableTestFeatures);
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
341
|
+
if (updateCache) {
|
|
342
|
+
oldCache = this.cache;
|
|
343
|
+
await this.cache.disconnect();
|
|
344
|
+
this.cache = createCache(newConf);
|
|
345
|
+
await this.cache.connect();
|
|
346
|
+
restartActionsTaken.updateCache = true;
|
|
347
|
+
}
|
|
277
348
|
|
|
278
|
-
|
|
349
|
+
const updateOIDC = !_.isEqual(this.conf.oidc, newConf.oidc)
|
|
279
350
|
|| !_.isEqual(this.conf.outbound.tls, newConf.outbound.tls);
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
351
|
+
if (updateOIDC) {
|
|
352
|
+
this.oidc.auth.stop();
|
|
353
|
+
this.oidc = createAuthClient(newConf, this.logger);
|
|
354
|
+
this.oidc.auth.on('error', (msg) => {
|
|
355
|
+
this.emit('error', 'OIDC auth error in InboundApi', msg);
|
|
356
|
+
});
|
|
357
|
+
await this.oidc.auth.start();
|
|
358
|
+
restartActionsTaken.updateOIDC = true;
|
|
359
|
+
}
|
|
289
360
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
361
|
+
this.logger.isDebugEnabled && this.logger.push({ oldConf: this.conf.inbound, newConf: newConf.inbound }).debug('Inbound server configuration');
|
|
362
|
+
const updateInboundServer = this._shouldUpdateInboundServer(newConf);
|
|
363
|
+
if (updateInboundServer) {
|
|
364
|
+
const stopStartLabel = 'InboundServer stop/start duration';
|
|
365
|
+
// eslint-disable-next-line no-console
|
|
366
|
+
console.time(stopStartLabel); // todo: remove console.time
|
|
367
|
+
await this.inboundServer.stop();
|
|
368
|
+
|
|
369
|
+
this.mojaloopSharedAgents = this._createMojaloopSharedAgents(newConf);
|
|
370
|
+
this.inboundServer = new InboundServer(
|
|
371
|
+
newConf,
|
|
372
|
+
this.logger,
|
|
373
|
+
this.cache,
|
|
374
|
+
this.oidc,
|
|
375
|
+
this.mojaloopSharedAgents,
|
|
376
|
+
);
|
|
377
|
+
this.inboundServer.on('error', (...args) => {
|
|
378
|
+
const errMessage = 'Unhandled error in Inbound Server';
|
|
379
|
+
this.logger.push({ args }).error(errMessage);
|
|
380
|
+
this.emit('error', errMessage);
|
|
381
|
+
});
|
|
382
|
+
await this.inboundServer.start();
|
|
383
|
+
// eslint-disable-next-line no-console
|
|
384
|
+
console.timeEnd(stopStartLabel);
|
|
385
|
+
restartActionsTaken.updateInboundServer = true;
|
|
386
|
+
}
|
|
316
387
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
388
|
+
this.logger.isDebugEnabled && this.logger.push({ oldConf: this.conf.outbound, newConf: newConf.outbound }).debug('Outbound server configuration');
|
|
389
|
+
const updateOutboundServer = this._shouldUpdateOutboundServer(newConf);
|
|
390
|
+
if (updateOutboundServer) {
|
|
391
|
+
const stopStartLabel = 'OutboundServer stop/start duration';
|
|
392
|
+
// eslint-disable-next-line no-console
|
|
393
|
+
console.time(stopStartLabel);
|
|
394
|
+
await this.outboundServer.stop();
|
|
395
|
+
|
|
396
|
+
this.mojaloopSharedAgents = this._createMojaloopSharedAgents(newConf);
|
|
397
|
+
this.outboundServer = new OutboundServer(
|
|
398
|
+
newConf,
|
|
399
|
+
this.logger,
|
|
400
|
+
this.cache,
|
|
401
|
+
this.metricsClient,
|
|
402
|
+
this.oidc,
|
|
403
|
+
this.mojaloopSharedAgents,
|
|
404
|
+
);
|
|
405
|
+
this.outboundServer.on('error', (...args) => {
|
|
406
|
+
const errMessage = 'Unhandled error in Outbound Server';
|
|
407
|
+
this.logger.push({ args }).error(errMessage);
|
|
408
|
+
this.emit('error', errMessage);
|
|
409
|
+
});
|
|
410
|
+
await this.outboundServer.start();
|
|
411
|
+
// eslint-disable-next-line no-console
|
|
412
|
+
console.timeEnd(stopStartLabel);
|
|
413
|
+
restartActionsTaken.updateOutboundServer = true;
|
|
414
|
+
}
|
|
344
415
|
|
|
345
|
-
|
|
416
|
+
const updateFspiopEventHandler = !_.isEqual(this.conf.outbound, newConf.outbound)
|
|
346
417
|
&& this.conf.fspiopEventHandler.enabled;
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
logger: this.logger,
|
|
352
|
-
cache: this.cache,
|
|
353
|
-
oidc: this.oidc,
|
|
354
|
-
});
|
|
355
|
-
await this.fspiopEventHandler.start();
|
|
356
|
-
restartActionsTaken.updateFspiopEventHandler = true;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
const updateControlClient = !_.isEqual(this.conf.control, newConf.control);
|
|
360
|
-
if (updateControlClient) {
|
|
361
|
-
await this.controlClient?.stop();
|
|
362
|
-
if (this.conf.pm4mlEnabled) {
|
|
363
|
-
const RESTART_INTERVAL_MS = 10000;
|
|
364
|
-
|
|
365
|
-
const schedulePing = () => {
|
|
366
|
-
clearTimeout(this.pingTimeout);
|
|
367
|
-
this.pingTimeout = setTimeout(() => {
|
|
368
|
-
this.logger.error('Ping timeout, possible broken connection. Restarting server...');
|
|
369
|
-
this.restart(_.merge({}, newConf, {
|
|
370
|
-
control: { stopped: Date.now() }
|
|
371
|
-
}));
|
|
372
|
-
}, PING_INTERVAL_MS + this.conf.control.mgmtAPILatencyAssumption);
|
|
373
|
-
};
|
|
374
|
-
|
|
375
|
-
schedulePing();
|
|
376
|
-
|
|
377
|
-
this.controlClient = await ControlAgent.Client.Create({
|
|
378
|
-
address: newConf.control.mgmtAPIWsUrl,
|
|
379
|
-
port: newConf.control.mgmtAPIWsPort,
|
|
418
|
+
if (updateFspiopEventHandler) {
|
|
419
|
+
await this.fspiopEventHandler.stop();
|
|
420
|
+
this.fspiopEventHandler = new FSPIOPEventHandler({
|
|
421
|
+
config: newConf,
|
|
380
422
|
logger: this.logger,
|
|
381
|
-
|
|
423
|
+
cache: this.cache,
|
|
424
|
+
oidc: this.oidc,
|
|
382
425
|
});
|
|
383
|
-
|
|
384
|
-
|
|
426
|
+
await this.fspiopEventHandler.start();
|
|
427
|
+
restartActionsTaken.updateFspiopEventHandler = true;
|
|
428
|
+
}
|
|
385
429
|
|
|
430
|
+
const updateControlClient = !_.isEqual(this.conf.control, newConf.control);
|
|
431
|
+
if (updateControlClient) {
|
|
432
|
+
await this.controlClient?.stop();
|
|
433
|
+
if (this.conf.pm4mlEnabled) {
|
|
434
|
+
const RESTART_INTERVAL_MS = 10000;
|
|
435
|
+
|
|
436
|
+
const schedulePing = () => {
|
|
437
|
+
clearTimeout(this.pingTimeout);
|
|
438
|
+
this.pingTimeout = setTimeout(() => {
|
|
439
|
+
this.logger.error('Ping timeout, possible broken connection. Restarting server...');
|
|
440
|
+
this.restart(_.merge({}, newConf, {
|
|
441
|
+
control: { stopped: Date.now() }
|
|
442
|
+
}));
|
|
443
|
+
}, PING_INTERVAL_MS + this.conf.control.mgmtAPILatencyAssumption);
|
|
444
|
+
};
|
|
386
445
|
|
|
387
|
-
this.controlClient.on('ping', () => {
|
|
388
|
-
this.logger.debug('Received ping from control server');
|
|
389
446
|
schedulePing();
|
|
390
|
-
});
|
|
391
447
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
this.
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
448
|
+
this.controlClient = await ControlAgent.createConnectedControlAgentWs(newConf, this.logger);
|
|
449
|
+
this.controlClient.on(ControlAgent.EVENT.RECONFIGURE, this.restart.bind(this));
|
|
450
|
+
|
|
451
|
+
this.controlClient.on('ping', () => {
|
|
452
|
+
this.logger.debug('Received ping from control server');
|
|
453
|
+
schedulePing();
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
this.controlClient.on('close', () => {
|
|
457
|
+
clearTimeout(this.pingTimeout);
|
|
458
|
+
setTimeout(() => {
|
|
459
|
+
this.logger.debug('Control client closed. Restarting server...');
|
|
460
|
+
this.restart(_.merge({}, newConf, {
|
|
461
|
+
control: { stopped: Date.now() }
|
|
462
|
+
}));
|
|
463
|
+
}, RESTART_INTERVAL_MS);
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
restartActionsTaken.updateControlClient = true;
|
|
467
|
+
}
|
|
403
468
|
}
|
|
404
|
-
}
|
|
405
469
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
470
|
+
const updateOAuthTestServer = !_.isEqual(newConf.oauthTestServer, this.conf.oauthTestServer);
|
|
471
|
+
if (updateOAuthTestServer) {
|
|
472
|
+
await this.oauthTestServer?.stop();
|
|
473
|
+
if (this.conf.oauthTestServer.enabled) {
|
|
474
|
+
this.oauthTestServer = new OAuthTestServer({
|
|
475
|
+
clientKey: newConf.oauthTestServer.clientKey,
|
|
476
|
+
clientSecret: newConf.oauthTestServer.clientSecret,
|
|
477
|
+
port: newConf.oauthTestServer.listenPort,
|
|
478
|
+
logger: this.logger,
|
|
479
|
+
});
|
|
480
|
+
await this.oauthTestServer.start();
|
|
481
|
+
restartActionsTaken.updateOAuthTestServer = true;
|
|
482
|
+
}
|
|
418
483
|
}
|
|
419
|
-
}
|
|
420
484
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
485
|
+
const updateTestServer = !_.isEqual(newConf.test.port, this.conf.test.port);
|
|
486
|
+
if (updateTestServer) {
|
|
487
|
+
await this.testServer?.stop();
|
|
488
|
+
if (this.conf.enableTestFeatures) {
|
|
489
|
+
this.testServer = new TestServer({
|
|
490
|
+
port: newConf.test.port,
|
|
491
|
+
logger: this.logger,
|
|
492
|
+
cache: this.cache,
|
|
493
|
+
});
|
|
494
|
+
await this.testServer.start();
|
|
495
|
+
restartActionsTaken.updateTestServer = true;
|
|
496
|
+
}
|
|
432
497
|
}
|
|
433
|
-
}
|
|
434
498
|
|
|
435
|
-
|
|
499
|
+
this.conf = newConf;
|
|
436
500
|
|
|
437
|
-
|
|
501
|
+
await oldCache?.disconnect();
|
|
438
502
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
503
|
+
if (Object.keys(restartActionsTaken).length > 0) {
|
|
504
|
+
this.logger.info('Server is restarted', { restartActionsTaken, source });
|
|
505
|
+
} else {
|
|
506
|
+
this.logger.verbose('Server not restarted, no config changes detected', { source });
|
|
507
|
+
}
|
|
508
|
+
} catch (err) {
|
|
509
|
+
this.logger.error('error in Server restart: ', err);
|
|
510
|
+
} finally {
|
|
511
|
+
this._configUpdateInProgress = false;
|
|
443
512
|
}
|
|
444
513
|
}
|
|
445
514
|
|
|
446
515
|
stop() {
|
|
516
|
+
this._stopConfigPolling();
|
|
517
|
+
|
|
447
518
|
clearTimeout(this.pingTimeout);
|
|
448
519
|
this.oidc.auth.stop();
|
|
449
520
|
this.controlClient?.removeAllListeners();
|
|
@@ -452,10 +523,10 @@ class Server extends EventEmitter {
|
|
|
452
523
|
this.cache.disconnect(),
|
|
453
524
|
this.inboundServer.stop(),
|
|
454
525
|
this.outboundServer.stop(),
|
|
526
|
+
this.metricsServer.stop(),
|
|
455
527
|
this.oauthTestServer?.stop(),
|
|
456
528
|
this.testServer?.stop(),
|
|
457
529
|
this.controlClient?.stop(),
|
|
458
|
-
this.metricsServer.stop(),
|
|
459
530
|
this.backendEventHandler?.stop(),
|
|
460
531
|
this.fspiopEventHandler?.stop(),
|
|
461
532
|
]);
|
|
@@ -493,35 +564,19 @@ class Server extends EventEmitter {
|
|
|
493
564
|
}
|
|
494
565
|
}
|
|
495
566
|
|
|
496
|
-
/*
|
|
497
|
-
* Call the Connector Manager in Management API to get the updated config
|
|
498
|
-
*/
|
|
499
|
-
async function _GetUpdatedConfigFromMgmtAPI(conf, logger, client) {
|
|
500
|
-
logger.isInfoEnabled && logger.info(`Getting updated config from Management API at ${conf.control.mgmtAPIWsUrl}:${conf.control.mgmtAPIWsPort}...`);
|
|
501
|
-
const clientSendResponse = await client.send(ControlAgent.build.CONFIGURATION.READ());
|
|
502
|
-
logger.isDebugEnabled && logger.debug('client send returned:: ', clientSendResponse);
|
|
503
|
-
const responseRead = await client.receive();
|
|
504
|
-
logger.isDebugEnabled && logger.debug('client receive returned:: ', responseRead);
|
|
505
|
-
return responseRead.data;
|
|
506
|
-
}
|
|
507
|
-
|
|
508
567
|
async function start(config) {
|
|
509
568
|
if (config.pm4mlEnabled) {
|
|
510
|
-
const controlClient = await ControlAgent.
|
|
511
|
-
|
|
512
|
-
address: config.control.mgmtAPIWsUrl,
|
|
513
|
-
port: config.control.mgmtAPIWsPort,
|
|
514
|
-
logger,
|
|
515
|
-
});
|
|
516
|
-
const updatedConfigFromMgmtAPI = await _GetUpdatedConfigFromMgmtAPI(config, logger, controlClient);
|
|
517
|
-
logger.isInfoEnabled && logger.push({ updatedConfigFromMgmtAPIKeys: Object.keys(updatedConfigFromMgmtAPI) }).info('updatedConfigFromMgmtAPI keys:');
|
|
569
|
+
const controlClient = await ControlAgent.createConnectedControlAgentWs(config, logger);
|
|
570
|
+
const updatedConfigFromMgmtAPI = await controlClient.getUpdatedConfig();
|
|
518
571
|
_.merge(config, updatedConfigFromMgmtAPI);
|
|
519
572
|
controlClient.terminate();
|
|
573
|
+
// todo: - clarify, why do we need to terminate the client? (use .stop() method?)
|
|
574
|
+
// - can we use persistent ws controlClient from Server? (why do we need to establish a brand new ws connection here?)
|
|
520
575
|
}
|
|
521
576
|
|
|
522
577
|
const svr = new Server(config, logger);
|
|
523
578
|
svr.on('error', (err) => {
|
|
524
|
-
logger.
|
|
579
|
+
logger.error('Unhandled server error: ', err);
|
|
525
580
|
process.exit(2);
|
|
526
581
|
});
|
|
527
582
|
|
|
@@ -533,11 +588,11 @@ async function start(config) {
|
|
|
533
588
|
});
|
|
534
589
|
|
|
535
590
|
await svr.start().catch(err => {
|
|
536
|
-
logger.
|
|
591
|
+
logger.error('Error starting server: ', err);
|
|
537
592
|
process.exit(1);
|
|
538
593
|
});
|
|
539
594
|
|
|
540
|
-
logger.info('SDK server is started
|
|
595
|
+
logger.info('SDK server is started', { name, version });
|
|
541
596
|
}
|
|
542
597
|
|
|
543
598
|
if (require.main === module) {
|
|
@@ -98,7 +98,9 @@ class Cache {
|
|
|
98
98
|
break;
|
|
99
99
|
}
|
|
100
100
|
this._connectionState = CONN_ST.CONNECTING;
|
|
101
|
-
this._inProgressConnection = Promise.all([
|
|
101
|
+
this._inProgressConnection = Promise.all([
|
|
102
|
+
this._getClient(), this._getClient()
|
|
103
|
+
]);
|
|
102
104
|
[this._client, this._subscriptionClient] = await this._inProgressConnection;
|
|
103
105
|
|
|
104
106
|
if (this._config.enableTestFeatures) {
|