@mojaloop/sdk-scheme-adapter 12.2.1 → 12.3.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/.env.example +1 -1
- package/CHANGELOG.md +22 -0
- package/audit-resolve.json +71 -1
- package/package.json +4 -1
- package/src/ControlAgent/index.js +2 -3
- package/src/ControlServer/index.js +2 -2
- package/src/InboundServer/index.js +7 -7
- package/src/InboundServer/middlewares.js +2 -2
- package/src/OutboundServer/handlers.js +3 -0
- package/src/OutboundServer/index.js +10 -11
- package/src/config.js +31 -14
- package/src/index.js +198 -10
- package/src/lib/cache.js +110 -52
- package/src/lib/metrics.js +148 -0
- package/src/lib/model/AccountsModel.js +4 -1
- package/src/lib/model/Async2SyncModel.js +4 -1
- package/src/lib/model/InboundTransfersModel.js +4 -1
- package/src/lib/model/OutboundBulkQuotesModel.js +4 -1
- package/src/lib/model/OutboundBulkTransfersModel.js +4 -1
- package/src/lib/model/OutboundRequestToPayModel.js +4 -1
- package/src/lib/model/OutboundRequestToPayTransferModel.js +4 -1
- package/src/lib/model/OutboundTransfersModel.js +61 -1
- package/src/lib/model/ProxyModel/index.js +4 -2
- package/src/lib/validate.js +2 -2
- package/test/__mocks__/redis.js +4 -0
- package/test/config/integration.env +5 -0
- package/test/unit/ControlServer/index.js +3 -3
- package/test/unit/InboundServer.test.js +1 -1
- package/test/unit/api/utils.js +4 -1
- package/test/unit/config.test.js +3 -3
- package/test/unit/data/defaultConfig.json +23 -7
- package/test/unit/index.test.js +95 -4
- package/test/unit/lib/model/OutboundTransfersModel.test.js +37 -1
- package/test/unit/lib/model/data/defaultConfig.json +24 -9
- package/src/lib/api/index.js +0 -12
- package/src/lib/randomphrase/index.js +0 -21
- package/src/lib/randomphrase/words.json +0 -3397
package/test/unit/index.test.js
CHANGED
|
@@ -10,13 +10,18 @@
|
|
|
10
10
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
|
-
const { Logger } = require('@mojaloop/sdk-standard-components');
|
|
14
|
-
const defaultConfig = require('./data/defaultConfig');
|
|
15
|
-
|
|
16
13
|
jest.mock('dotenv', () => ({
|
|
17
14
|
config: jest.fn()
|
|
18
15
|
}));
|
|
19
16
|
|
|
17
|
+
const promClient = require('prom-client');
|
|
18
|
+
const defaultConfig = require('./data/defaultConfig.json');
|
|
19
|
+
const { Logger } = require('@mojaloop/sdk-standard-components');
|
|
20
|
+
const { MetricsClient } = require('~/lib/metrics');
|
|
21
|
+
|
|
22
|
+
const TestControlServer = require('./ControlServer');
|
|
23
|
+
|
|
24
|
+
|
|
20
25
|
process.env.PEER_ENDPOINT = '172.17.0.3:4000';
|
|
21
26
|
process.env.BACKEND_ENDPOINT = '172.17.0.5:4000';
|
|
22
27
|
process.env.CACHE_HOST = '172.17.0.2';
|
|
@@ -26,6 +31,10 @@ process.env.MGMT_API_WS_URL = '0.0.0.0';
|
|
|
26
31
|
const index = require('~/index.js');
|
|
27
32
|
|
|
28
33
|
describe('index.js', () => {
|
|
34
|
+
beforeEach(() => {
|
|
35
|
+
promClient.register.clear();
|
|
36
|
+
});
|
|
37
|
+
|
|
29
38
|
test('WSO2 error events in OutboundServer propagate to top-level server', () => {
|
|
30
39
|
const logger = new Logger.Logger({ stringify: () => '' });
|
|
31
40
|
const svr = new index.Server(defaultConfig, logger);
|
|
@@ -50,7 +59,89 @@ describe('index.js', () => {
|
|
|
50
59
|
expect(typeof(index.OutboundServerMiddleware)).toBe('object');
|
|
51
60
|
expect(typeof(index.Router)).toBe('function');
|
|
52
61
|
expect(typeof(index.Validate)).toBe('function');
|
|
53
|
-
expect(typeof(index.RandomPhrase)).toBe('function');
|
|
54
62
|
expect(typeof(index.Cache)).toBe('function');
|
|
55
63
|
});
|
|
56
64
|
});
|
|
65
|
+
|
|
66
|
+
describe('Server', () => {
|
|
67
|
+
let server, controlServer, conf, logger;
|
|
68
|
+
|
|
69
|
+
beforeEach(async () => {
|
|
70
|
+
promClient.register.clear();
|
|
71
|
+
logger = new Logger.Logger({ stringify: () => '' });
|
|
72
|
+
conf = JSON.parse(JSON.stringify(defaultConfig));
|
|
73
|
+
conf.enableTestFeatures = true;
|
|
74
|
+
conf.pm4mlEnabled = true;
|
|
75
|
+
conf.control.mgmtAPIWsUrl = 'localhost';
|
|
76
|
+
conf.control.mgmtAPIWsPort = 4005;
|
|
77
|
+
conf.control.port = conf.control.mgmtAPIWsPort;
|
|
78
|
+
controlServer = new TestControlServer.Server({ logger, appConfig: conf });
|
|
79
|
+
server = new index.Server(conf, logger);
|
|
80
|
+
await server.start();
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
afterEach(async () => {
|
|
84
|
+
await controlServer.stop();
|
|
85
|
+
await server.stop();
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
describe('is reconfigured correctly by the control client', () => {
|
|
89
|
+
let newConf;
|
|
90
|
+
beforeEach(async () => {
|
|
91
|
+
// not every server restarts on every config change, we'll make sure they all restart
|
|
92
|
+
newConf = { ...conf, logIndent: conf.logIndent + 1, control: { ...conf.control, rubbish: 'data' }, test: { trash: 'data' } };
|
|
93
|
+
// Just in case, we'll assert the new configuration is different to the old one
|
|
94
|
+
expect(newConf).not.toEqual(conf);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('reconfigures and restarts constituent servers when triggered by control client', async () => {
|
|
98
|
+
const [restartInbound, restartOutbound, restartControl, restartOAuthTest, restartTest] =
|
|
99
|
+
Array.from({ length: 5 }).map(() => jest.fn());
|
|
100
|
+
server.inboundServer.reconfigure = jest.fn(() => restartInbound);
|
|
101
|
+
server.outboundServer.reconfigure = jest.fn(() => restartOutbound);
|
|
102
|
+
server.testServer.reconfigure = jest.fn(() => restartTest);
|
|
103
|
+
server.oauthTestServer.reconfigure = jest.fn(() => restartOAuthTest);
|
|
104
|
+
server.controlClient.reconfigure = jest.fn(() => restartControl);
|
|
105
|
+
|
|
106
|
+
await controlServer.broadcastConfigChange(newConf);
|
|
107
|
+
|
|
108
|
+
// We wait for the servers to get restarted
|
|
109
|
+
await new Promise((wait) => setTimeout(wait, 1000));
|
|
110
|
+
|
|
111
|
+
expect(server.inboundServer.reconfigure).toHaveBeenCalledTimes(1);
|
|
112
|
+
expect(server.inboundServer.reconfigure).toHaveBeenCalledWith(
|
|
113
|
+
newConf, expect.any(Logger.Logger), expect.any(index.Cache)
|
|
114
|
+
);
|
|
115
|
+
expect(server.outboundServer.reconfigure).toHaveBeenCalledTimes(1);
|
|
116
|
+
const metricsClient = new MetricsClient();
|
|
117
|
+
expect(server.outboundServer.reconfigure).toHaveBeenCalledWith(
|
|
118
|
+
newConf, expect.any(Logger.Logger), expect.any(index.Cache), metricsClient
|
|
119
|
+
);
|
|
120
|
+
expect(server.controlClient.reconfigure).toHaveBeenCalledTimes(1);
|
|
121
|
+
expect(server.controlClient.reconfigure).toHaveBeenCalledWith({
|
|
122
|
+
logger: expect.any(Logger.Logger),
|
|
123
|
+
port: newConf.control.port,
|
|
124
|
+
appConfig: newConf
|
|
125
|
+
});
|
|
126
|
+
expect(server.testServer.reconfigure).toHaveBeenCalledTimes(1);
|
|
127
|
+
expect(server.testServer.reconfigure).toHaveBeenCalledWith({
|
|
128
|
+
logger: expect.any(Logger.Logger),
|
|
129
|
+
cache: expect.any(index.Cache),
|
|
130
|
+
port: newConf.test.port
|
|
131
|
+
});
|
|
132
|
+
expect(server.oauthTestServer.reconfigure).toHaveBeenCalledTimes(1);
|
|
133
|
+
expect(server.oauthTestServer.reconfigure).toHaveBeenCalledWith({
|
|
134
|
+
logger: expect.any(Logger.Logger),
|
|
135
|
+
clientKey: newConf.oauthTestServer.clientKey,
|
|
136
|
+
clientSecret: newConf.oauthTestServer.clientSecret,
|
|
137
|
+
port: newConf.oauthTestServer.listenPort,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
expect(restartInbound).toHaveBeenCalledTimes(1);
|
|
141
|
+
expect(restartOutbound).toHaveBeenCalledTimes(1);
|
|
142
|
+
expect(restartTest).toHaveBeenCalledTimes(1);
|
|
143
|
+
expect(restartOAuthTest).toHaveBeenCalledTimes(1);
|
|
144
|
+
expect(restartControl).toHaveBeenCalledTimes(1);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
});
|
|
@@ -15,6 +15,7 @@ jest.mock('@mojaloop/sdk-standard-components');
|
|
|
15
15
|
jest.mock('redis');
|
|
16
16
|
|
|
17
17
|
const Cache = require('~/lib/cache');
|
|
18
|
+
const { MetricsClient } = require('~/lib/metrics');
|
|
18
19
|
const Model = require('~/lib/model').OutboundTransfersModel;
|
|
19
20
|
const PartiesModel = require('~/lib/model').PartiesModel;
|
|
20
21
|
|
|
@@ -50,6 +51,7 @@ describe('outboundModel', () => {
|
|
|
50
51
|
let config;
|
|
51
52
|
let logger;
|
|
52
53
|
let cache;
|
|
54
|
+
let metricsClient;
|
|
53
55
|
|
|
54
56
|
/**
|
|
55
57
|
*
|
|
@@ -91,6 +93,7 @@ describe('outboundModel', () => {
|
|
|
91
93
|
...config,
|
|
92
94
|
cache,
|
|
93
95
|
logger,
|
|
96
|
+
metricsClient,
|
|
94
97
|
});
|
|
95
98
|
|
|
96
99
|
await model.initialize(JSON.parse(JSON.stringify(transferRequest)));
|
|
@@ -113,6 +116,7 @@ describe('outboundModel', () => {
|
|
|
113
116
|
beforeAll(async () => {
|
|
114
117
|
logger = new Logger.Logger({ context: { app: 'outbound-model-unit-tests-cache' }, stringify: () => '' });
|
|
115
118
|
quoteResponse = JSON.parse(JSON.stringify(quoteResponseTemplate));
|
|
119
|
+
metricsClient = new MetricsClient();
|
|
116
120
|
});
|
|
117
121
|
|
|
118
122
|
beforeEach(async () => {
|
|
@@ -140,6 +144,7 @@ describe('outboundModel', () => {
|
|
|
140
144
|
const model = new Model({
|
|
141
145
|
cache,
|
|
142
146
|
logger,
|
|
147
|
+
metricsClient,
|
|
143
148
|
...config,
|
|
144
149
|
});
|
|
145
150
|
|
|
@@ -194,6 +199,7 @@ describe('outboundModel', () => {
|
|
|
194
199
|
const model = new Model({
|
|
195
200
|
cache,
|
|
196
201
|
logger,
|
|
202
|
+
metricsClient,
|
|
197
203
|
...config,
|
|
198
204
|
});
|
|
199
205
|
|
|
@@ -274,6 +280,7 @@ describe('outboundModel', () => {
|
|
|
274
280
|
const model = new Model({
|
|
275
281
|
cache,
|
|
276
282
|
logger,
|
|
283
|
+
metricsClient,
|
|
277
284
|
...config,
|
|
278
285
|
});
|
|
279
286
|
|
|
@@ -303,6 +310,7 @@ describe('outboundModel', () => {
|
|
|
303
310
|
const model = new Model({
|
|
304
311
|
cache,
|
|
305
312
|
logger,
|
|
313
|
+
metricsClient,
|
|
306
314
|
...config,
|
|
307
315
|
});
|
|
308
316
|
|
|
@@ -333,6 +341,7 @@ describe('outboundModel', () => {
|
|
|
333
341
|
const model = new Model({
|
|
334
342
|
cache,
|
|
335
343
|
logger,
|
|
344
|
+
metricsClient,
|
|
336
345
|
...config,
|
|
337
346
|
});
|
|
338
347
|
|
|
@@ -360,6 +369,7 @@ describe('outboundModel', () => {
|
|
|
360
369
|
const model = new Model({
|
|
361
370
|
cache,
|
|
362
371
|
logger,
|
|
372
|
+
metricsClient,
|
|
363
373
|
...config,
|
|
364
374
|
});
|
|
365
375
|
|
|
@@ -395,6 +405,7 @@ describe('outboundModel', () => {
|
|
|
395
405
|
let model = new Model({
|
|
396
406
|
cache,
|
|
397
407
|
logger,
|
|
408
|
+
metricsClient,
|
|
398
409
|
...config,
|
|
399
410
|
});
|
|
400
411
|
|
|
@@ -421,6 +432,7 @@ describe('outboundModel', () => {
|
|
|
421
432
|
model = new Model({
|
|
422
433
|
cache,
|
|
423
434
|
logger,
|
|
435
|
+
metricsClient,
|
|
424
436
|
...config,
|
|
425
437
|
});
|
|
426
438
|
|
|
@@ -451,6 +463,7 @@ describe('outboundModel', () => {
|
|
|
451
463
|
let model = new Model({
|
|
452
464
|
cache,
|
|
453
465
|
logger,
|
|
466
|
+
metricsClient,
|
|
454
467
|
...config,
|
|
455
468
|
});
|
|
456
469
|
|
|
@@ -477,6 +490,7 @@ describe('outboundModel', () => {
|
|
|
477
490
|
model = new Model({
|
|
478
491
|
cache,
|
|
479
492
|
logger,
|
|
493
|
+
metricsClient,
|
|
480
494
|
...config,
|
|
481
495
|
});
|
|
482
496
|
|
|
@@ -502,6 +516,7 @@ describe('outboundModel', () => {
|
|
|
502
516
|
model = new Model({
|
|
503
517
|
cache,
|
|
504
518
|
logger,
|
|
519
|
+
metricsClient,
|
|
505
520
|
...config,
|
|
506
521
|
});
|
|
507
522
|
|
|
@@ -557,6 +572,7 @@ describe('outboundModel', () => {
|
|
|
557
572
|
const model = new Model({
|
|
558
573
|
cache,
|
|
559
574
|
logger,
|
|
575
|
+
metricsClient,
|
|
560
576
|
...config,
|
|
561
577
|
});
|
|
562
578
|
|
|
@@ -608,6 +624,7 @@ describe('outboundModel', () => {
|
|
|
608
624
|
const model = new Model({
|
|
609
625
|
cache,
|
|
610
626
|
logger,
|
|
627
|
+
metricsClient,
|
|
611
628
|
...config,
|
|
612
629
|
});
|
|
613
630
|
|
|
@@ -701,6 +718,7 @@ describe('outboundModel', () => {
|
|
|
701
718
|
const model = new Model({
|
|
702
719
|
cache,
|
|
703
720
|
logger,
|
|
721
|
+
metricsClient,
|
|
704
722
|
...config,
|
|
705
723
|
});
|
|
706
724
|
|
|
@@ -763,6 +781,7 @@ describe('outboundModel', () => {
|
|
|
763
781
|
const model = new Model({
|
|
764
782
|
cache,
|
|
765
783
|
logger,
|
|
784
|
+
metricsClient,
|
|
766
785
|
...config,
|
|
767
786
|
});
|
|
768
787
|
|
|
@@ -823,6 +842,7 @@ describe('outboundModel', () => {
|
|
|
823
842
|
const model = new Model({
|
|
824
843
|
cache,
|
|
825
844
|
logger,
|
|
845
|
+
metricsClient,
|
|
826
846
|
...config,
|
|
827
847
|
});
|
|
828
848
|
|
|
@@ -849,11 +869,12 @@ describe('outboundModel', () => {
|
|
|
849
869
|
|
|
850
870
|
|
|
851
871
|
async function testTlsServer(enableTls) {
|
|
852
|
-
config.tls.enabled = enableTls;
|
|
872
|
+
config.outbound.tls.mutualTLS.enabled = enableTls;
|
|
853
873
|
|
|
854
874
|
new Model({
|
|
855
875
|
cache,
|
|
856
876
|
logger,
|
|
877
|
+
metricsClient,
|
|
857
878
|
...config
|
|
858
879
|
});
|
|
859
880
|
|
|
@@ -866,4 +887,19 @@ describe('outboundModel', () => {
|
|
|
866
887
|
|
|
867
888
|
test('Outbound server should use HTTP if outbound mTLS disabled', () =>
|
|
868
889
|
testTlsServer(false));
|
|
890
|
+
|
|
891
|
+
test('Outbound transfers model should record metrics', async () => {
|
|
892
|
+
const metrics = metricsClient._prometheusRegister.metrics();
|
|
893
|
+
expect(metrics).toBeTruthy();
|
|
894
|
+
|
|
895
|
+
expect(metrics).toEqual(expect.stringContaining('mojaloop_connector_outbound_party_lookup_request_count'));
|
|
896
|
+
expect(metrics).toEqual(expect.stringContaining('mojaloop_connector_outbound_party_lookup_response_count'));
|
|
897
|
+
expect(metrics).toEqual(expect.stringContaining('mojaloop_connector_outbound_quote_request_count'));
|
|
898
|
+
expect(metrics).toEqual(expect.stringContaining('mojaloop_connector_outbound_quote_response_count'));
|
|
899
|
+
expect(metrics).toEqual(expect.stringContaining('mojaloop_connector_outbound_transfer_prepare_count'));
|
|
900
|
+
expect(metrics).toEqual(expect.stringContaining('mojaloop_connector_outbound_transfer_fulfil_response_count'));
|
|
901
|
+
expect(metrics).toEqual(expect.stringContaining('mojaloop_connector_outbound_quote_request_latency'));
|
|
902
|
+
expect(metrics).toEqual(expect.stringContaining('mojaloop_connector_outbound_transfer_latency'));
|
|
903
|
+
expect(metrics).toEqual(expect.stringContaining('mojaloop_connector_outbound_party_lookup_latency'));
|
|
904
|
+
});
|
|
869
905
|
});
|
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
"inbound": {
|
|
3
|
+
"port": 4000,
|
|
4
|
+
"tls": {
|
|
5
|
+
"mutualTLS": { "enabled": false },
|
|
6
|
+
"creds": {
|
|
7
|
+
"ca": null,
|
|
8
|
+
"cert": null,
|
|
9
|
+
"key": null
|
|
10
|
+
}
|
|
8
11
|
}
|
|
9
12
|
},
|
|
10
|
-
"
|
|
11
|
-
|
|
13
|
+
"outbound": {
|
|
14
|
+
"port": 4001,
|
|
15
|
+
"tls": {
|
|
16
|
+
"mutualTLS": { "enabled": false },
|
|
17
|
+
"creds": {
|
|
18
|
+
"ca": null,
|
|
19
|
+
"cert": null,
|
|
20
|
+
"key": null
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
12
24
|
"peerEndpoint": "172.17.0.2:3001",
|
|
13
25
|
"backendEndpoint": "172.17.0.2:3001",
|
|
14
26
|
"alsEndpoint": "127.0.0.1:6500",
|
|
@@ -43,5 +55,8 @@
|
|
|
43
55
|
"rejectExpiredQuoteResponses": false,
|
|
44
56
|
"rejectExpiredTransferFulfils": false,
|
|
45
57
|
"rejectTransfersOnExpiredQuotes": false,
|
|
46
|
-
"logIndent": 2
|
|
58
|
+
"logIndent": 2,
|
|
59
|
+
"metrics": {
|
|
60
|
+
"port": 4004
|
|
61
|
+
}
|
|
47
62
|
}
|
package/src/lib/api/index.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**************************************************************************
|
|
2
|
-
* (C) Copyright ModusBox Inc. 2019 - All rights reserved. *
|
|
3
|
-
* *
|
|
4
|
-
* This file is made available under the terms of the license agreement *
|
|
5
|
-
* specified in the corresponding source code repository. *
|
|
6
|
-
* *
|
|
7
|
-
* ORIGINAL AUTHOR: *
|
|
8
|
-
* Matt Kingston - matt.kingston@modusbox.com *
|
|
9
|
-
**************************************************************************/
|
|
10
|
-
|
|
11
|
-
'use strict';
|
|
12
|
-
|
|
13
|
-
const words = require('./words.json');
|
|
14
|
-
|
|
15
|
-
const randomEl = arr => arr[Math.floor(Math.random() * arr.length)];
|
|
16
|
-
module.exports = (separator = '-') => [
|
|
17
|
-
randomEl(words.adjectives),
|
|
18
|
-
randomEl(words.nouns),
|
|
19
|
-
randomEl(words.adjectives),
|
|
20
|
-
randomEl(words.nouns)
|
|
21
|
-
].join(separator);
|