@mojaloop/sdk-scheme-adapter 24.2.0-csi-1210.6 → 24.2.1-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.
Files changed (48) hide show
  1. package/.yarn/cache/@hapi-hapi-npm-21.4.0-2644a983d1-4e6ccd65ba.zip +0 -0
  2. package/.yarn/cache/@hapi-statehood-npm-8.2.0-5844e85740-0ebe5fa44e.zip +0 -0
  3. package/.yarn/cache/@mojaloop-central-services-shared-npm-18.22.1-afa19f2925-27182cd5be.zip +0 -0
  4. package/.yarn/cache/{@mojaloop-event-sdk-npm-14.1.5-97dbf6c0e3-9d5836df5a.zip → @mojaloop-event-sdk-npm-14.3.0-2aa8149477-6173c7d96f.zip} +0 -0
  5. package/.yarn/cache/@mojaloop-inter-scheme-proxy-cache-lib-npm-2.3.7-87034262d3-37fe9b388c.zip +0 -0
  6. package/.yarn/cache/@mojaloop-sdk-standard-components-npm-19.10.0-snapshot.1-e9bbd7866c-90ec21d0f6.zip +0 -0
  7. package/.yarn/cache/{@types-node-npm-22.13.9-565bb4cd14-d36ae841fa.zip → @types-node-npm-22.13.10-af5336e62b-1cd6b899df.zip} +0 -0
  8. package/.yarn/cache/axios-npm-1.8.2-55671cda10-c47a43b79a.zip +0 -0
  9. package/.yarn/cache/ioredis-npm-5.6.0-2140ad9baf-b085cec251.zip +0 -0
  10. package/.yarn/install-state.gz +0 -0
  11. package/CHANGELOG.md +14 -0
  12. package/docker-compose.yml +10 -5
  13. package/modules/api-svc/package.json +5 -5
  14. package/modules/api-svc/src/config.js +4 -3
  15. package/modules/api-svc/src/index.js +60 -13
  16. package/modules/api-svc/src/lib/logger.js +47 -0
  17. package/modules/api-svc/src/lib/utils.js +1 -19
  18. package/modules/api-svc/test/integration/lib/cache.test.js +2 -7
  19. package/modules/api-svc/test/integration-pm4ml/mockServers/managementService/config.js +3 -2
  20. package/modules/api-svc/test/integration-pm4ml/mockServers/managementService/index.js +25 -24
  21. package/modules/api-svc/test/integration-pm4ml/mockServers/managementService/server.js +35 -2
  22. package/modules/api-svc/test/unit/BackendEventHandler.test.js +2 -2
  23. package/modules/api-svc/test/unit/ControlClient.test.js +5 -4
  24. package/modules/api-svc/test/unit/FSPIOPEventHandler.test.js +6 -5
  25. package/modules/api-svc/test/unit/InboundServer-iso20022.test.js +3 -3
  26. package/modules/api-svc/test/unit/InboundServer.test.js +3 -2
  27. package/modules/api-svc/test/unit/TestServer.test.js +10 -11
  28. package/modules/api-svc/test/unit/api/transfers/utils.js +2 -2
  29. package/modules/api-svc/test/unit/api/utils.js +4 -3
  30. package/modules/api-svc/test/unit/ilp.test.js +3 -2
  31. package/modules/api-svc/test/unit/inboundApi/handlers-iso20022.test.js +5 -5
  32. package/modules/api-svc/test/unit/inboundApi/handlers.test.js +28 -27
  33. package/modules/api-svc/test/unit/index.test.js +10 -13
  34. package/modules/api-svc/test/unit/lib/cache.test.js +2 -2
  35. package/modules/api-svc/test/unit/lib/model/AccountsModel.test.js +3 -2
  36. package/modules/api-svc/test/unit/lib/model/InboundTransfersModel.test.js +10 -8
  37. package/modules/api-svc/test/unit/lib/model/OutboundBulkQuotesModel.test.js +4 -4
  38. package/modules/api-svc/test/unit/lib/model/OutboundBulkTransfersModel.test.js +3 -2
  39. package/modules/api-svc/test/unit/lib/model/OutboundRequestToPayModel.test.js +5 -4
  40. package/modules/api-svc/test/unit/lib/model/OutboundRequestToPayTransferModel.test.js +4 -4
  41. package/modules/api-svc/test/unit/lib/model/OutboundTransfersISO20022.test.js +5 -6
  42. package/modules/api-svc/test/unit/lib/model/OutboundTransfersModel.test.js +4 -10
  43. package/modules/api-svc/test/unit/lib/model/lib/requests/backendRequests.test.js +3 -2
  44. package/modules/api-svc/test/unit/mockLogger.js +10 -7
  45. package/modules/outbound-command-event-handler/package.json +3 -3
  46. package/modules/outbound-domain-event-handler/package.json +2 -2
  47. package/modules/private-shared-lib/package.json +3 -3
  48. package/package.json +2 -2
Binary file
package/CHANGELOG.md CHANGED
@@ -1,4 +1,18 @@
1
1
  # Changelog: [mojaloop/sdk-scheme-adapter](https://github.com/mojaloop/sdk-scheme-adapter)
2
+ ## [24.2.0](https://github.com/mojaloop/sdk-scheme-adapter/compare/v24.1.3...v24.2.0) (2025-03-05)
3
+
4
+
5
+ ### Features
6
+
7
+ * add code to restart sdk on broken control client connection ([#555](https://github.com/mojaloop/sdk-scheme-adapter/issues/555)) ([4ce10e8](https://github.com/mojaloop/sdk-scheme-adapter/commit/4ce10e8c1385471e1cf33fc0abe923210167a099))
8
+ * **csi-1210:** added OTel header to Outbound/Inbound TransfersModel ([#552](https://github.com/mojaloop/sdk-scheme-adapter/issues/552)) ([cbbd0b7](https://github.com/mojaloop/sdk-scheme-adapter/commit/cbbd0b7e0e26eb85d04178a1e8cdb2120b9f4f6f))
9
+
10
+
11
+ ### Chore
12
+
13
+ * add better service checks to docker compose ([#556](https://github.com/mojaloop/sdk-scheme-adapter/issues/556)) ([ba0d7f0](https://github.com/mojaloop/sdk-scheme-adapter/commit/ba0d7f04ba7a138363c85edad5ba0bef0b7e5302))
14
+ * add heartbeat to test server ([#557](https://github.com/mojaloop/sdk-scheme-adapter/issues/557)) ([5d7b628](https://github.com/mojaloop/sdk-scheme-adapter/commit/5d7b6284e93c081359089f6865c726f05d2f44b9))
15
+
2
16
  ### [24.1.3](https://github.com/mojaloop/sdk-scheme-adapter/compare/v24.1.2...v24.1.3) (2025-02-25)
3
17
 
4
18
 
@@ -19,9 +19,12 @@ services:
19
19
  - "4002:4002"
20
20
  - "9229:9229"
21
21
  depends_on:
22
- - redis
23
- - ml-testing-toolkit
24
- - kafka
22
+ redis:
23
+ condition: service_healthy
24
+ ml-testing-toolkit:
25
+ condition: service_started
26
+ kafka:
27
+ condition: service_healthy
25
28
  command: yarn nx run modules-api-svc:start
26
29
  volumes:
27
30
  - ./docker/wait4:/tmp/wait4
@@ -144,7 +147,8 @@ services:
144
147
  environment:
145
148
  - KAFKA_BROKERS=kafka:29092
146
149
  depends_on:
147
- - kafka
150
+ kafka:
151
+ condition: service_healthy
148
152
  profiles:
149
153
  - debug
150
154
 
@@ -153,7 +157,8 @@ services:
153
157
  - mojaloop-net
154
158
  image: docker.io/bitnami/kafka:3.4.0
155
159
  depends_on:
156
- - kafka
160
+ kafka:
161
+ condition: service_healthy
157
162
  entrypoint: [ '/bin/sh', '-c' ]
158
163
  command: |
159
164
  "
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mojaloop/sdk-scheme-adapter-api-svc",
3
- "version": "21.0.0-snapshot.25",
3
+ "version": "21.0.0-snapshot.27",
4
4
  "description": "An adapter for connecting to Mojaloop API enabled switches.",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -68,14 +68,14 @@
68
68
  "@mojaloop/central-services-error-handling": "13.0.7",
69
69
  "@mojaloop/central-services-logger": "11.5.5",
70
70
  "@mojaloop/central-services-metrics": "12.4.5",
71
- "@mojaloop/central-services-shared": "18.21.0",
72
- "@mojaloop/event-sdk": "14.1.5",
71
+ "@mojaloop/central-services-shared": "18.22.1",
72
+ "@mojaloop/event-sdk": "14.3.0",
73
73
  "@mojaloop/logging-bc-client-lib": "0.5.8",
74
74
  "@mojaloop/ml-schema-transformer-lib": "2.5.6",
75
75
  "@mojaloop/sdk-scheme-adapter-private-shared-lib": "workspace:^",
76
- "@mojaloop/sdk-standard-components": "v19.9.0",
76
+ "@mojaloop/sdk-standard-components": "19.10.0-snapshot.1",
77
77
  "ajv": "8.17.1",
78
- "axios": "1.8.1",
78
+ "axios": "1.8.2",
79
79
  "body-parser": "1.20.3",
80
80
  "co-body": "6.2.0",
81
81
  "dotenv": "16.4.7",
@@ -30,7 +30,7 @@ require('dotenv').config();
30
30
  const fs = require('node:fs');
31
31
  const yaml = require('js-yaml');
32
32
  const { from } = require('env-var');
33
- const { Logger } = require('@mojaloop/sdk-standard-components').Logger;
33
+ const { LOG_LEVELS } = require('./lib/logger');
34
34
  const { API_TYPES, RESOURCE_VERSIONS_STRING } = require('./constants');
35
35
 
36
36
  function getFileContent (path) {
@@ -86,10 +86,11 @@ module.exports = {
86
86
  __parseResourceVersion: parseResourceVersions,
87
87
  control: {
88
88
  mgmtAPIWsUrl: env.get('MGMT_API_WS_URL').default('127.0.0.1').asString(),
89
- mgmtAPIWsPort: env.get('MGMT_API_WS_PORT').default('4005').asPortNumber()
89
+ mgmtAPIWsPort: env.get('MGMT_API_WS_PORT').default('4005').asPortNumber(),
90
+ mgmtAPILatencyAssumption: env.get('MGMT_API_LATENCY_ASSUMPTION').default('2000').asIntPositive(),
90
91
  },
91
92
  idGenerator: env.get('ID_GENERATOR').default('{"type":"ulid"}').asJsonObject(),
92
- logLevel: env.get('LOG_LEVEL').default('info').asEnum(Logger.logLevels),
93
+ logLevel: env.get('LOG_LEVEL').default('info').asEnum(LOG_LEVELS),
93
94
  inbound: {
94
95
  port: env.get('INBOUND_LISTEN_PORT').default('4000').asPortNumber(),
95
96
  tls: {
@@ -48,7 +48,8 @@ const Router = require('./lib/router');
48
48
  const Validate = require('./lib/validate');
49
49
  const Cache = require('./lib/cache');
50
50
  const { SDKStateEnum } = require('./lib/model/common');
51
- const { createAuthClient, createLogger } = require('./lib/utils');
51
+ const { createAuthClient } = require('./lib/utils');
52
+ const { createLogger } = require('./lib/logger');
52
53
 
53
54
  const LOG_ID = {
54
55
  INBOUND: { app: 'mojaloop-connector-inbound-api' },
@@ -62,6 +63,8 @@ const LOG_ID = {
62
63
  CACHE: { component: 'cache' },
63
64
  };
64
65
 
66
+ const PING_INTERVAL_MS = 30000;
67
+
65
68
  const createCache = (config, logger) => new Cache({
66
69
  cacheUrl: config.cacheUrl,
67
70
  logger: logger.push(LOG_ID.CACHE),
@@ -78,6 +81,7 @@ class Server extends EventEmitter {
78
81
  this.conf = conf;
79
82
  this.logger = logger;
80
83
  this.cache = createCache(conf, logger);
84
+ this.pingTimeout;
81
85
 
82
86
  this.metricsClient = new MetricsClient();
83
87
 
@@ -166,12 +170,33 @@ class Server extends EventEmitter {
166
170
  appConfig: this.conf,
167
171
  });
168
172
  this.controlClient.on(ControlAgent.EVENT.RECONFIGURE, this.restart.bind(this));
169
- this.controlClient.on('close', () => setTimeout(() => {
170
- this.logger.push({ currentConf: this.conf }).debug('Control client closed. Restarting server...');
171
- this.restart(_.merge({}, this.conf, {
172
- control: { stopped: Date.now() }
173
- }));
174
- }, RESTART_INTERVAL_MS));
173
+
174
+ const schedulePing = () => {
175
+ clearTimeout(this.pingTimeout);
176
+ this.pingTimeout = setTimeout(() => {
177
+ this.logger.error('Ping timeout, possible broken connection. Restarting server...');
178
+ this.restart(_.merge({}, this.conf, {
179
+ control: { stopped: Date.now() }
180
+ }));
181
+ }, PING_INTERVAL_MS + this.conf.control.mgmtAPILatencyAssumption);
182
+ };
183
+
184
+ this.controlClient.on('ping', () => {
185
+ this.logger.debug('Received ping from control server');
186
+ schedulePing();
187
+ });
188
+
189
+ this.controlClient.on('close', () => {
190
+ clearTimeout(this.pingTimeout);
191
+ setTimeout(() => {
192
+ this.logger.debug('Control client closed. Restarting server...');
193
+ this.restart(_.merge({}, this.conf, {
194
+ control: { stopped: Date.now() }
195
+ }));
196
+ }, RESTART_INTERVAL_MS);
197
+ });
198
+
199
+ schedulePing();
175
200
  }
176
201
 
177
202
  await Promise.all([
@@ -284,12 +309,33 @@ class Server extends EventEmitter {
284
309
  appConfig: newConf,
285
310
  });
286
311
  this.controlClient.on(ControlAgent.EVENT.RECONFIGURE, this.restart.bind(this));
287
- this.controlClient.on('close', () => setTimeout(() => {
288
- this.logger.push({ newConf }).debug('Control client closed. Restarting server...');
289
- this.restart(_.merge({}, newConf, {
290
- control: { stopped: Date.now() }
291
- }));
292
- }, RESTART_INTERVAL_MS));
312
+
313
+ const schedulePing = () => {
314
+ clearTimeout(this.pingTimeout);
315
+ this.pingTimeout = setTimeout(() => {
316
+ this.logger.error('Ping timeout, possible broken connection. Restarting server...');
317
+ this.restart(_.merge({}, newConf, {
318
+ control: { stopped: Date.now() }
319
+ }));
320
+ }, PING_INTERVAL_MS + this.conf.control.mgmtAPILatencyAssumption);
321
+ };
322
+
323
+ this.controlClient.on('ping', () => {
324
+ this.logger.debug('Received ping from control server');
325
+ schedulePing();
326
+ });
327
+
328
+ this.controlClient.on('close', () => {
329
+ clearTimeout(this.pingTimeout);
330
+ setTimeout(() => {
331
+ this.logger.debug('Control client closed. Restarting server...');
332
+ this.restart(_.merge({}, newConf, {
333
+ control: { stopped: Date.now() }
334
+ }));
335
+ }, RESTART_INTERVAL_MS);
336
+ });
337
+
338
+ schedulePing();
293
339
  restartActionsTaken.updateControlClient = true;
294
340
  }
295
341
  }
@@ -337,6 +383,7 @@ class Server extends EventEmitter {
337
383
  }
338
384
 
339
385
  stop() {
386
+ clearTimeout(this.pingTimeout);
340
387
  this.wso2.auth.stop();
341
388
  this.controlClient?.removeAllListeners();
342
389
  this.inboundServer.removeAllListeners();
@@ -0,0 +1,47 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2020-2025 Mojaloop Foundation
5
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10
+
11
+ Contributors
12
+ --------------
13
+ This is the official list of the Mojaloop project contributors for this file.
14
+ Names of the original copyright holders (individuals or organizations)
15
+ should be listed with a '*' in the first column. People who have
16
+ contributed from an organization can be listed under the organization
17
+ that actually holds the copyright for their contributions (see the
18
+ Mojaloop Foundation for an example). Those individuals should have
19
+ their names indented and be marked with a '-'. Email address can be added
20
+ optionally within square brackets <email>.
21
+
22
+ * Mojaloop Foundation
23
+ * Eugen Klymniuk <eugen.klymniuk@infitx.com>
24
+
25
+ --------------
26
+ ******/
27
+
28
+ const { hostname } = require('node:os');
29
+ const { loggerFactory, LOG_LEVELS } = require('@mojaloop/sdk-standard-components').Logger;
30
+
31
+ const createLogger = (conf = {}) => {
32
+ const {
33
+ context = {
34
+ // If we're running from a Mojaloop helm chart deployment, we'll have a SIM_NAME
35
+ simulator: process.env['SIM_NAME'],
36
+ hostname: hostname(),
37
+ },
38
+ isJsonOutput = false,
39
+ } = conf;
40
+
41
+ return loggerFactory({ context, isJsonOutput });
42
+ };
43
+
44
+ module.exports = {
45
+ createLogger,
46
+ LOG_LEVELS,
47
+ };
@@ -25,25 +25,8 @@
25
25
  --------------
26
26
  ******/
27
27
 
28
- const { hostname } = require('node:os');
29
28
  const { randomBytes } = require('node:crypto');
30
- const { WSO2Auth, Logger } = require('@mojaloop/sdk-standard-components');
31
-
32
- const SDK_LOGGER_HIERARCHY = Logger.Logger.logLevels.reverse();
33
-
34
- const createLogger = (conf) => new Logger.Logger({
35
- context: {
36
- // If we're running from a Mojaloop helm chart deployment, we'll have a SIM_NAME
37
- simulator: process.env['SIM_NAME'],
38
- hostname: hostname(),
39
- },
40
- opts: {
41
- // todo: should be done inside Logger code
42
- levels: SDK_LOGGER_HIERARCHY.slice(SDK_LOGGER_HIERARCHY.indexOf(conf.logLevel)),
43
- isJsonOutput: conf.isJsonOutput,
44
- },
45
- stringify: Logger.buildStringify({ isJsonOutput: conf.isJsonOutput }),
46
- });
29
+ const { WSO2Auth } = require('@mojaloop/sdk-standard-components');
47
30
 
48
31
  const createAuthClient = (conf, logger) => {
49
32
  const { wso2, outbound } = conf;
@@ -88,7 +71,6 @@ const generateTraceparent = (traceId = randomBytes(16).toString('hex')) => {
88
71
 
89
72
  module.exports = {
90
73
  createAuthClient,
91
- createLogger,
92
74
  generateTraceparent,
93
75
  transformHeadersIsoToFspiop
94
76
  };
@@ -31,7 +31,7 @@
31
31
  jest.dontMock('redis');
32
32
 
33
33
  const Cache = require('~/lib/cache');
34
- const { Logger } = require('@mojaloop/sdk-standard-components');
34
+ const { createLogger } = require('~/lib/logger');
35
35
  const env = require('../testEnv');
36
36
 
37
37
  const defaultCacheConfig = {
@@ -40,12 +40,7 @@ const defaultCacheConfig = {
40
40
  };
41
41
 
42
42
  const createCache = async (config) => {
43
- config.logger = new Logger.Logger({
44
- context: {
45
- app: 'mojaloop-sdk-inboundCache'
46
- },
47
- stringify: Logger.buildStringify({ space: 4 }),
48
- });
43
+ config.logger = createLogger({ context: { app: 'mojaloop-sdk-inboundCache' } });
49
44
  const cache = new Cache(config);
50
45
  await cache.connect();
51
46
 
@@ -26,9 +26,10 @@
26
26
  ******/
27
27
  'use strict';
28
28
 
29
- const fs = require('fs');
30
29
  require('dotenv').config();
30
+ const fs = require('fs');
31
31
  const { from } = require('env-var');
32
+ const { LOG_LEVELS } = require('../../../../src/lib/logger');
32
33
 
33
34
  function getFileContent (path) {
34
35
  if (!fs.existsSync(path)) {
@@ -43,7 +44,7 @@ const env = from(process.env, {
43
44
  });
44
45
 
45
46
  module.exports = {
46
- logLevel: env.get('LOG_LEVEL').default('info').asEnum(['trace', 'debug', 'info', 'warn', 'error', 'fatal']),
47
+ logLevel: env.get('LOG_LEVEL').default('info').asEnum(LOG_LEVELS),
47
48
  server: {
48
49
  port: env.get('SERVER_LISTEN_PORT').default('4005').asPortNumber(),
49
50
  },
@@ -1,42 +1,43 @@
1
+ const express = require('express');
2
+ const { createLogger } = require('../../../../src/lib/logger');
1
3
  const Config = require('./config');
2
4
  const ManagementService = require('./server');
3
- const { Logger } = require('@mojaloop/sdk-standard-components');
4
- const express = require('express')
5
- const app = express()
6
-
7
- const logger = new Logger.Logger({
8
- ctx: {
9
- simulator: 'test',
10
- hostname: 'test',
5
+
6
+ const app = express();
7
+
8
+ const logger = createLogger({
9
+ context: {
10
+ simulator: 'test',
11
+ hostname: 'test',
11
12
  }
12
- });
13
+ });
13
14
 
14
15
  const managementServer = new ManagementService.Server({
15
16
  port: Config.server.port,
16
- logger: logger,
17
+ logger,
17
18
  });
18
19
 
19
20
  // Test API Server
20
21
  app.use(express.json());
21
22
 
22
23
  app.get('/health', (req, res) => {
23
- res.send('OK')
24
- })
24
+ res.send('OK');
25
+ });
25
26
 
26
27
  app.post('/updateOutboundTLSConfig', (req, res) => {
27
- managementServer.updateOutboundTLSConfig(req.body);
28
- res.status(200).json({
29
- message: 'Updated configuration'
30
- })
31
- })
28
+ managementServer.updateOutboundTLSConfig(req.body);
29
+ res.status(200).json({
30
+ message: 'Updated configuration'
31
+ });
32
+ });
32
33
 
33
34
  app.post('/resetConfig', (req, res) => {
34
- managementServer.resetConfig();
35
- res.status(200).json({
36
- message: 'Reset Done'
37
- })
38
- })
35
+ managementServer.resetConfig();
36
+ res.status(200).json({
37
+ message: 'Reset Done'
38
+ });
39
+ });
39
40
 
40
41
  app.listen(Config.testAPIServer.port, () => {
41
- logger.log(`Test API Server listening on port ${Config.testAPIServer.port}`)
42
- })
42
+ logger.log(`Test API Server listening on port ${Config.testAPIServer.port}`);
43
+ });
@@ -11,7 +11,6 @@
11
11
  const ws = require('ws');
12
12
  const jsonPatch = require('fast-json-patch');
13
13
  const randomPhrase = require('./lib/randomphrase');
14
- const { Logger } = require('@mojaloop/sdk-standard-components');
15
14
 
16
15
  const INIT_CONFIG = require('./initConfig')
17
16
 
@@ -113,6 +112,7 @@ class Server extends ws.Server {
113
112
  _clientData;
114
113
  _currentConfig;
115
114
  _isConfigUpdated;
115
+ _heartbeatInterval;
116
116
 
117
117
  constructor(opts) {
118
118
  super({ clientTracking: true, port: opts.port });
@@ -134,7 +134,14 @@ class Server extends ws.Server {
134
134
  remoteAddress: req.socket.remoteAddress,
135
135
  });
136
136
  logger.log('Websocket connection received');
137
- this._clientData.set(socket, { ip: req.connection.remoteAddress, logger });
137
+ this._clientData.set(socket, { ip: req.connection.remoteAddress, logger, isAlive: true });
138
+
139
+ socket.on('pong', () => {
140
+ const clientData = this._clientData.get(socket);
141
+ if (clientData) {
142
+ clientData.isAlive = true;
143
+ }
144
+ });
138
145
 
139
146
  socket.on('close', (code, reason) => {
140
147
  logger.push({ code, reason }).log('Websocket connection closed');
@@ -144,6 +151,31 @@ class Server extends ws.Server {
144
151
  socket.on('message', this._handle(socket, logger));
145
152
  });
146
153
  this._logger.push(this.address()).log('running on');
154
+ this._startHeartbeat();
155
+ }
156
+
157
+ _startHeartbeat() {
158
+ this._heartbeatInterval = setInterval(() => {
159
+ this.clients.forEach((client) => {
160
+ const clientData = this._clientData.get(client);
161
+ if (clientData && !clientData.isAlive) {
162
+ client.terminate();
163
+ this._clientData.delete(client);
164
+ return;
165
+ }
166
+ if (clientData) {
167
+ clientData.isAlive = false;
168
+ }
169
+ client.ping();
170
+ });
171
+ }, 30000);
172
+ }
173
+
174
+ _stopHeartbeat() {
175
+ if (this._heartbeatInterval) {
176
+ clearInterval(this._heartbeatInterval);
177
+ this._heartbeatInterval = null;
178
+ }
147
179
  }
148
180
 
149
181
  _setConfig(newConfig) {
@@ -158,6 +190,7 @@ class Server extends ws.Server {
158
190
 
159
191
  // Close the server then wait for all the client sockets to close
160
192
  async stop() {
193
+ this._stopHeartbeat();
161
194
  const closing = new Promise((resolve) => this.close(resolve));
162
195
  for (const client of this.clients) {
163
196
  client.terminate();
@@ -28,7 +28,7 @@
28
28
  const { BackendEventHandler } = require('../../src/BackendEventHandler');
29
29
  const { BackendRequests } = require('../../src/lib/model/lib/requests');
30
30
  const { SDKStateEnum } = require('../../src/lib/model/common');
31
- const { Logger } = require('@mojaloop/sdk-standard-components');
31
+ const { createLogger } = require('../../src/lib/logger');
32
32
  const config = require('./data/defaultConfig.json');
33
33
  const bulkTransactionResponse = require('./lib/model/data/bulkTransactionResponse.json');
34
34
  const {
@@ -42,7 +42,7 @@ const {
42
42
  KafkaDomainEventProducer,
43
43
  } = require('@mojaloop/sdk-scheme-adapter-private-shared-lib');
44
44
 
45
- const logger = new Logger.Logger({ context: { app: 'BackendEventHandler' }, stringify: () => '' });
45
+ const logger = createLogger({ context: { app: 'BackendEventHandler' }, stringify: () => '' });
46
46
 
47
47
  describe('BackendEventHandler', () => {
48
48
  const putBulkTransactions = jest.spyOn(BackendRequests.prototype, 'putBulkTransactions').mockImplementation(async () => ({}));
@@ -24,12 +24,13 @@
24
24
 
25
25
  --------------
26
26
  ******/
27
- const ControlAgent = require('~/ControlAgent');
28
- const TestControlServer = require('./ControlServer');
29
- const { Logger } = require('@mojaloop/sdk-standard-components');
30
27
 
31
28
  jest.mock('~/lib/cache');
32
29
 
30
+ const ControlAgent = require('~/ControlAgent');
31
+ const { createLogger } = require('~/lib/logger');
32
+ const TestControlServer = require('./ControlServer');
33
+
33
34
  // TODO:
34
35
  // - diff against master to determine what else needs testing
35
36
  // - especially look for assertions in the code
@@ -59,7 +60,7 @@ describe('ControlAgent', () => {
59
60
  const changedConfig = { ...appConfig, some: 'thing' };
60
61
 
61
62
  beforeAll(async () => {
62
- logger = new Logger.Logger({ stringify: () => '' });
63
+ logger = createLogger({ stringify: () => '' });
63
64
  server = new TestControlServer.Server({ logger, appConfig });
64
65
  client = await ControlAgent.Client.Create({
65
66
  address: 'localhost',
@@ -33,10 +33,6 @@ process.env.CACHE_URL = 'redis://172.17.0.2:6379';
33
33
  process.env.MGMT_API_WS_URL = '0.0.0.0';
34
34
  process.env.SUPPORTED_CURRENCIES='USD';
35
35
 
36
- const { FSPIOPEventHandler } = require('../../src/FSPIOPEventHandler');
37
- const bulkQuoteRequest = require('../unit/lib/model/data/bulkQuoteRequest.json');
38
- const { Logger } = require('@mojaloop/sdk-standard-components');
39
- const config = require('./data/defaultConfig.json');
40
36
  const {
41
37
  PartyInfoRequestedDmEvt,
42
38
  BulkQuotesRequestedDmEvt,
@@ -45,6 +41,8 @@ const {
45
41
  KafkaDomainEventProducer,
46
42
  } = require('@mojaloop/sdk-scheme-adapter-private-shared-lib');
47
43
 
44
+ const { FSPIOPEventHandler } = require('../../src/FSPIOPEventHandler');
45
+ const { createLogger } = require('../../src/lib/logger');
48
46
  const {
49
47
  OutboundBulkQuotesModel,
50
48
  PartiesModel,
@@ -52,7 +50,10 @@ const {
52
50
  SDKStateEnum
53
51
  } = require('../../src/lib/model');
54
52
 
55
- const logger = new Logger.Logger({ context: { app: 'FSPIOPEventHandler' }, stringify: () => '' });
53
+ const bulkQuoteRequest = require('../unit/lib/model/data/bulkQuoteRequest.json');
54
+ const config = require('./data/defaultConfig.json');
55
+
56
+ const logger = createLogger({ context: { app: 'FSPIOPEventHandler' }, stringify: () => '' });
56
57
 
57
58
  describe('FSPIOPEventHandler', () => {
58
59
  let fspiopEventHandler;
@@ -37,17 +37,17 @@ jest.mock('../../src/lib/cache');
37
37
  jest.mock('../../src/lib/model/lib/requests', () => require('./lib/model/mockedLibRequests'));
38
38
 
39
39
  const supertest = require('supertest');
40
- const { Logger } = require('@mojaloop/sdk-standard-components');
41
-
42
40
  const InboundServer = require('../../src/InboundServer');
43
41
  const Cache = require('../../src/lib/cache');
44
42
  const config = require('../../src/config');
45
43
  const helpers = require('../helpers');
44
+ const { createLogger } = require('../../src/lib/logger');
45
+
46
46
  const isoBodies = require('./inboundApi/data/isoBodies');
47
47
  const commonHttpHeaders = require('./data/commonHttpHeaders');
48
48
  const transactionRequestResponse = require('./lib/model/data/transactionRequestResponse');
49
49
 
50
- const logger = new Logger.Logger();
50
+ const logger = createLogger();
51
51
 
52
52
  const createIsoHeaders = resource => ({
53
53
  ...commonHttpHeaders,
@@ -47,16 +47,17 @@ jest.mock('@mojaloop/sdk-standard-components');
47
47
  jest.mock('~/lib/cache');
48
48
  jest.mock('~/lib/model/lib/requests', () => require('./lib/model/mockedLibRequests'));
49
49
 
50
+ const { Jws } = require('@mojaloop/sdk-standard-components');
51
+ const { createLogger } = require('~/lib/logger');
50
52
  const InboundServer = require('~/InboundServer');
51
53
  const Cache = require('~/lib/cache');
52
- const { Jws, Logger } = require('@mojaloop/sdk-standard-components');
53
54
  const path = require('path');
54
55
  const fs = require('fs');
55
56
  const os = require('os');
56
57
  const http = require('http');
57
58
  const https = require('https');
58
59
 
59
- const logger = new Logger.Logger();
60
+ const logger = createLogger();
60
61
 
61
62
  describe('Inbound Server', () => {
62
63
  describe('PUT /parties', () => {