@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
|
@@ -0,0 +1,148 @@
|
|
|
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
|
+
* James Bush - james.bush@modusbox.com *
|
|
9
|
+
**************************************************************************/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
const http = require('http');
|
|
14
|
+
const Koa = require('koa');
|
|
15
|
+
const koaBody = require('koa-body');
|
|
16
|
+
const PrometheusClient = require('prom-client');
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A utility class that abstracts the underlying metrics implementation (Prometheus)
|
|
21
|
+
* from the consumer. This may be premature if Prometheus is never swapped out...but
|
|
22
|
+
* who can tell what the Universe will bring us.
|
|
23
|
+
*
|
|
24
|
+
* This object exposes methods for getting different types of measurement construct
|
|
25
|
+
* in order for consuming code to record metrics. The constructs are quite tightly
|
|
26
|
+
* coupled to Prometheus view of metrics, although that is fairly abstract so the
|
|
27
|
+
* risk appears low that this will cause conflicts in future.
|
|
28
|
+
*
|
|
29
|
+
* The metrics client is intended to be used as a singleton in a process and keeps a
|
|
30
|
+
* 'per name' cache of metrics to avoid duplicates. Not sure if this is strictly
|
|
31
|
+
* necessary but I dont have time to dig into the prom-client code to see what
|
|
32
|
+
* happens if you create the same metric twice.
|
|
33
|
+
*/
|
|
34
|
+
class MetricsClient {
|
|
35
|
+
constructor() {
|
|
36
|
+
this._prometheusRegister = PrometheusClient.register;
|
|
37
|
+
this._metrics = {};
|
|
38
|
+
|
|
39
|
+
this._counterPrefix = 'cntr_';
|
|
40
|
+
this._histogramPrefix = 'hist_';
|
|
41
|
+
this._gaugePrefix = 'gage_';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
getHistogram(name, description, buckets) {
|
|
46
|
+
const metricName = `${this._histogramPrefix}${name}`;
|
|
47
|
+
|
|
48
|
+
let conf = {
|
|
49
|
+
name: name,
|
|
50
|
+
help: description,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
if(buckets) {
|
|
54
|
+
conf.buckets = buckets;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if(!this._metrics[metricName]) {
|
|
58
|
+
this._metrics[metricName] = new PrometheusClient.Histogram(conf);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return this._metrics[metricName];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
getCounter(name, description) {
|
|
66
|
+
const metricName = `${this._counterPrefix}${name}`;
|
|
67
|
+
|
|
68
|
+
if(!this._metrics[metricName]) {
|
|
69
|
+
this._metrics[metricName] = new PrometheusClient.Counter({
|
|
70
|
+
name: name,
|
|
71
|
+
help: description
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return this._metrics[metricName];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
getGauge(name, description) {
|
|
80
|
+
const metricName = `${this._counterPrefix}${name}`;
|
|
81
|
+
|
|
82
|
+
if(!this._metrics[metricName]) {
|
|
83
|
+
this._metrics[metricName] = new PrometheusClient.Gauge({
|
|
84
|
+
name: name,
|
|
85
|
+
help: description
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return this._metrics[metricName];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Exposes an HTTP endpoint for metrics to be scraped by some external daemon
|
|
96
|
+
*/
|
|
97
|
+
class MetricsServer {
|
|
98
|
+
/**
|
|
99
|
+
* @param {number} port metrics server listen port
|
|
100
|
+
* @param {Logger} logger Logger
|
|
101
|
+
* @param {Object} prometheusClient Prometheus client instance
|
|
102
|
+
*/
|
|
103
|
+
constructor({ port, logger }) {
|
|
104
|
+
this._port = port;
|
|
105
|
+
this._logger = logger;
|
|
106
|
+
this._prometheusClient = PrometheusClient;
|
|
107
|
+
this._prometheusRegister = PrometheusClient.register;
|
|
108
|
+
this._api = this.setupApi();
|
|
109
|
+
this._server = http.createServer(this._api.callback());
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async start() {
|
|
113
|
+
if (this._server.listening) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
this._prometheusClient.collectDefaultMetrics({
|
|
117
|
+
prefix: 'mojaloop_connector_default_'
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
await new Promise((resolve) => this._server.listen(this._port, resolve));
|
|
121
|
+
this._logger.push({ port: this._port }).log('Serving Metrics');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async stop() {
|
|
125
|
+
await new Promise(resolve => this._server.close(resolve));
|
|
126
|
+
this._logger.log('Metrics Server shut down complete');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
setupApi() {
|
|
130
|
+
const result = new Koa();
|
|
131
|
+
|
|
132
|
+
result.use(koaBody());
|
|
133
|
+
result.use(async ctx => {
|
|
134
|
+
this._logger.log('Metrics request received');
|
|
135
|
+
|
|
136
|
+
ctx.response.set('Content-Type', this._prometheusRegister.contentType);
|
|
137
|
+
ctx.response.body = this._prometheusRegister.metrics();
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
module.exports = {
|
|
146
|
+
MetricsServer,
|
|
147
|
+
MetricsClient
|
|
148
|
+
};
|
|
@@ -36,7 +36,10 @@ class AccountsModel {
|
|
|
36
36
|
logger: this._logger,
|
|
37
37
|
peerEndpoint: config.alsEndpoint,
|
|
38
38
|
dfspId: config.dfspId,
|
|
39
|
-
tls:
|
|
39
|
+
tls: {
|
|
40
|
+
enabled: config.outbound.tls.mutualTLS.enabled,
|
|
41
|
+
creds: config.outbound.tls.creds,
|
|
42
|
+
},
|
|
40
43
|
jwsSign: config.jwsSign,
|
|
41
44
|
jwsSigningKey: config.jwsSigningKey,
|
|
42
45
|
wso2: config.wso2,
|
|
@@ -228,7 +228,10 @@ function generate({
|
|
|
228
228
|
transfersEndpoint: config.transfersEndpoint,
|
|
229
229
|
transactionRequestsEndpoint: config.transactionRequestsEndpoint,
|
|
230
230
|
dfspId: config.dfspId,
|
|
231
|
-
tls:
|
|
231
|
+
tls: {
|
|
232
|
+
enabled: config.outbound.tls.mutualTLS.enabled,
|
|
233
|
+
creds: config.outbound.tls.creds,
|
|
234
|
+
},
|
|
232
235
|
jwsSign: config.jwsSign,
|
|
233
236
|
jwsSignPutParties: config.jwsSignPutParties,
|
|
234
237
|
jwsSigningKey: config.jwsSigningKey,
|
|
@@ -46,7 +46,10 @@ class InboundTransfersModel {
|
|
|
46
46
|
transactionRequestsEndpoint: config.transactionRequestsEndpoint,
|
|
47
47
|
bulkQuotesEndpoint: config.bulkQuotesEndpoint,
|
|
48
48
|
dfspId: config.dfspId,
|
|
49
|
-
tls:
|
|
49
|
+
tls: {
|
|
50
|
+
enabled: config.outbound.tls.mutualTLS.enabled,
|
|
51
|
+
creds: config.outbound.tls.creds,
|
|
52
|
+
},
|
|
50
53
|
jwsSign: config.jwsSign,
|
|
51
54
|
jwsSigningKey: config.jwsSigningKey,
|
|
52
55
|
wso2: config.wso2,
|
|
@@ -40,7 +40,10 @@ class OutboundBulkQuotesModel {
|
|
|
40
40
|
peerEndpoint: config.peerEndpoint,
|
|
41
41
|
bulkQuotesEndpoint: config.bulkQuotesEndpoint,
|
|
42
42
|
dfspId: config.dfspId,
|
|
43
|
-
tls:
|
|
43
|
+
tls: {
|
|
44
|
+
enabled: config.outbound.tls.mutualTLS.enabled,
|
|
45
|
+
creds: config.outbound.tls.creds,
|
|
46
|
+
},
|
|
44
47
|
jwsSign: config.jwsSign,
|
|
45
48
|
jwsSigningKey: config.jwsSigningKey,
|
|
46
49
|
wso2: config.wso2,
|
|
@@ -38,7 +38,10 @@ class OutboundBulkTransfersModel {
|
|
|
38
38
|
peerEndpoint: config.peerEndpoint,
|
|
39
39
|
bulkTransfersEndpoint: config.bulkTransfersEndpoint,
|
|
40
40
|
dfspId: config.dfspId,
|
|
41
|
-
tls:
|
|
41
|
+
tls: {
|
|
42
|
+
enabled: config.outbound.tls.mutualTLS.enabled,
|
|
43
|
+
creds: config.outbound.tls.creds,
|
|
44
|
+
},
|
|
42
45
|
jwsSign: config.jwsSign,
|
|
43
46
|
jwsSignPutParties: config.jwsSignPutParties,
|
|
44
47
|
jwsSigningKey: config.jwsSigningKey,
|
|
@@ -39,7 +39,10 @@ class OutboundRequestToPayModel {
|
|
|
39
39
|
peerEndpoint: config.peerEndpoint,
|
|
40
40
|
alsEndpoint: config.alsEndpoint,
|
|
41
41
|
dfspId: config.dfspId,
|
|
42
|
-
tls:
|
|
42
|
+
tls: {
|
|
43
|
+
enabled: config.outbound.tls.mutualTLS.enabled,
|
|
44
|
+
creds: config.outbound.tls.creds,
|
|
45
|
+
},
|
|
43
46
|
jwsSign: config.jwsSign,
|
|
44
47
|
jwsSignPutParties: config.jwsSignPutParties,
|
|
45
48
|
jwsSigningKey: config.jwsSigningKey,
|
|
@@ -52,7 +52,10 @@ class OutboundRequestToPayTransferModel {
|
|
|
52
52
|
authorizationsEndpoint: config.authorizationsEndpoint,
|
|
53
53
|
transfersEndpoint: config.transfersEndpoint,
|
|
54
54
|
dfspId: config.dfspId,
|
|
55
|
-
tls:
|
|
55
|
+
tls: {
|
|
56
|
+
enabled: config.outbound.tls.mutualTLS.enabled,
|
|
57
|
+
creds: config.outbound.tls.creds,
|
|
58
|
+
},
|
|
56
59
|
jwsSign: config.jwsSign,
|
|
57
60
|
jwsSignPutParties: config.jwsSignPutParties,
|
|
58
61
|
jwsSigningKey: config.jwsSigningKey,
|
|
@@ -51,7 +51,10 @@ class OutboundTransfersModel {
|
|
|
51
51
|
transfersEndpoint: config.transfersEndpoint,
|
|
52
52
|
transactionRequestsEndpoint: config.transactionRequestsEndpoint,
|
|
53
53
|
dfspId: config.dfspId,
|
|
54
|
-
tls:
|
|
54
|
+
tls: {
|
|
55
|
+
enabled: config.outbound.tls.mutualTLS.enabled,
|
|
56
|
+
creds: config.outbound.tls.creds,
|
|
57
|
+
},
|
|
55
58
|
jwsSign: config.jwsSign,
|
|
56
59
|
jwsSignPutParties: config.jwsSignPutParties,
|
|
57
60
|
jwsSigningKey: config.jwsSigningKey,
|
|
@@ -63,6 +66,36 @@ class OutboundTransfersModel {
|
|
|
63
66
|
secret: config.ilpSecret,
|
|
64
67
|
logger: this._logger,
|
|
65
68
|
});
|
|
69
|
+
|
|
70
|
+
this.metrics = {
|
|
71
|
+
partyLookupRequests: config.metricsClient.getCounter(
|
|
72
|
+
'mojaloop_connector_outbound_party_lookup_request_count',
|
|
73
|
+
'Count of outbound party lookup requests sent'),
|
|
74
|
+
partyLookupResponses: config.metricsClient.getCounter(
|
|
75
|
+
'mojaloop_connector_outbound_party_lookup_response_count',
|
|
76
|
+
'Count of responses received to outbound party lookups'),
|
|
77
|
+
quoteRequests: config.metricsClient.getCounter(
|
|
78
|
+
'mojaloop_connector_outbound_quote_request_count',
|
|
79
|
+
'Count of outbound quote requests sent'),
|
|
80
|
+
quoteResponses: config.metricsClient.getCounter(
|
|
81
|
+
'mojaloop_connector_outbound_quote_response_count',
|
|
82
|
+
'Count of responses received to outbound quote requests'),
|
|
83
|
+
transferPrepares: config.metricsClient.getCounter(
|
|
84
|
+
'mojaloop_connector_outbound_transfer_prepare_count',
|
|
85
|
+
'Count of outbound transfer prepare requests sent'),
|
|
86
|
+
transferFulfils: config.metricsClient.getCounter(
|
|
87
|
+
'mojaloop_connector_outbound_transfer_fulfil_response_count',
|
|
88
|
+
'Count of responses received to outbound transfer prepares'),
|
|
89
|
+
partyLookupLatency: config.metricsClient.getHistogram(
|
|
90
|
+
'mojaloop_connector_outbound_party_lookup_latency',
|
|
91
|
+
'Time taken for a response to a party lookup request to be received'),
|
|
92
|
+
quoteRequestLatency: config.metricsClient.getHistogram(
|
|
93
|
+
'mojaloop_connector_outbound_quote_request_latency',
|
|
94
|
+
'Time taken for a response to a quote request to be received'),
|
|
95
|
+
transferLatency: config.metricsClient.getHistogram(
|
|
96
|
+
'mojaloop_connector_outbound_transfer_latency',
|
|
97
|
+
'Time taken for a response to a transfer prepare to be received')
|
|
98
|
+
};
|
|
66
99
|
}
|
|
67
100
|
|
|
68
101
|
|
|
@@ -182,9 +215,16 @@ class OutboundTransfersModel {
|
|
|
182
215
|
subId: this.data.to.idSubValue
|
|
183
216
|
});
|
|
184
217
|
|
|
218
|
+
let latencyTimerDone;
|
|
219
|
+
|
|
185
220
|
// hook up a subscriber to handle response messages
|
|
186
221
|
const subId = await this._cache.subscribe(payeeKey, (cn, msg, subId) => {
|
|
187
222
|
try {
|
|
223
|
+
if(latencyTimerDone) {
|
|
224
|
+
latencyTimerDone();
|
|
225
|
+
}
|
|
226
|
+
this.metrics.partyLookupResponses.inc();
|
|
227
|
+
|
|
188
228
|
let payee = JSON.parse(msg);
|
|
189
229
|
|
|
190
230
|
if(payee.errorInformation) {
|
|
@@ -276,8 +316,10 @@ class OutboundTransfersModel {
|
|
|
276
316
|
// now we have a timeout handler and a cache subscriber hooked up we can fire off
|
|
277
317
|
// a GET /parties request to the switch
|
|
278
318
|
try {
|
|
319
|
+
latencyTimerDone = this.metrics.partyLookupLatency.startTimer();
|
|
279
320
|
const res = await this._requests.getParties(this.data.to.idType, this.data.to.idValue,
|
|
280
321
|
this.data.to.idSubValue, this.data.to.fspId);
|
|
322
|
+
this.metrics.partyLookupRequests.inc();
|
|
281
323
|
this._logger.push({ peer: res }).log('Party lookup sent to peer');
|
|
282
324
|
}
|
|
283
325
|
catch(err) {
|
|
@@ -309,10 +351,16 @@ class OutboundTransfersModel {
|
|
|
309
351
|
|
|
310
352
|
// listen for events on the quoteId
|
|
311
353
|
const quoteKey = `qt_${quote.quoteId}`;
|
|
354
|
+
let latencyTimerDone;
|
|
312
355
|
|
|
313
356
|
// hook up a subscriber to handle response messages
|
|
314
357
|
const subId = await this._cache.subscribe(quoteKey, (cn, msg, subId) => {
|
|
315
358
|
try {
|
|
359
|
+
if(latencyTimerDone) {
|
|
360
|
+
latencyTimerDone();
|
|
361
|
+
}
|
|
362
|
+
this.metrics.quoteResponses.inc();
|
|
363
|
+
|
|
316
364
|
let error;
|
|
317
365
|
let message = JSON.parse(msg);
|
|
318
366
|
|
|
@@ -377,7 +425,9 @@ class OutboundTransfersModel {
|
|
|
377
425
|
// now we have a timeout handler and a cache subscriber hooked up we can fire off
|
|
378
426
|
// a POST /quotes request to the switch
|
|
379
427
|
try {
|
|
428
|
+
latencyTimerDone = this.metrics.quoteRequestLatency.startTimer();
|
|
380
429
|
const res = await this._requests.postQuotes(quote, this.data.to.fspId);
|
|
430
|
+
this.metrics.quoteRequests.inc();
|
|
381
431
|
this._logger.push({ res }).log('Quote request sent to peer');
|
|
382
432
|
}
|
|
383
433
|
catch(err) {
|
|
@@ -456,12 +506,20 @@ class OutboundTransfersModel {
|
|
|
456
506
|
// listen for events on the transferId
|
|
457
507
|
const transferKey = `tf_${this.data.transferId}`;
|
|
458
508
|
|
|
509
|
+
let latencyTimerDone;
|
|
510
|
+
|
|
459
511
|
const subId = await this._cache.subscribe(transferKey, async (cn, msg, subId) => {
|
|
460
512
|
try {
|
|
461
513
|
let error;
|
|
462
514
|
let message = JSON.parse(msg);
|
|
463
515
|
|
|
516
|
+
if(latencyTimerDone) {
|
|
517
|
+
latencyTimerDone();
|
|
518
|
+
}
|
|
519
|
+
|
|
464
520
|
if (message.type === 'transferFulfil') {
|
|
521
|
+
this.metrics.transferFulfils.inc();
|
|
522
|
+
|
|
465
523
|
if (this._rejectExpiredTransferFulfils) {
|
|
466
524
|
const now = new Date().toISOString();
|
|
467
525
|
if (now > prepare.expiration) {
|
|
@@ -520,7 +578,9 @@ class OutboundTransfersModel {
|
|
|
520
578
|
// now we have a timeout handler and a cache subscriber hooked up we can fire off
|
|
521
579
|
// a POST /transfers request to the switch
|
|
522
580
|
try {
|
|
581
|
+
latencyTimerDone = this.metrics.transferLatency.startTimer();
|
|
523
582
|
const res = await this._requests.postTransfers(prepare, this.data.quoteResponseSource);
|
|
583
|
+
this.metrics.transferPrepares.inc();
|
|
524
584
|
this._logger.push({ res }).log('Transfer prepare sent to peer');
|
|
525
585
|
}
|
|
526
586
|
catch(err) {
|
|
@@ -35,8 +35,10 @@ class ProxyModel {
|
|
|
35
35
|
this._requests = new MojaloopRequests({
|
|
36
36
|
logger: this._logger,
|
|
37
37
|
peerEndpoint: config.peerEndpoint,
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
tls: {
|
|
39
|
+
enabled: config.outbound.tls.mutualTLS.enabled,
|
|
40
|
+
creds: config.outbound.tls.creds,
|
|
41
|
+
},
|
|
40
42
|
jwsSign: config.jwsSign,
|
|
41
43
|
jwsSigningKey: config.jwsSigningKey,
|
|
42
44
|
wso2Auth: config.wso2Auth
|
package/src/lib/validate.js
CHANGED
|
@@ -24,7 +24,7 @@ const { Errors } = require('@mojaloop/sdk-standard-components');
|
|
|
24
24
|
const Ajv = require('ajv');
|
|
25
25
|
const ajv = new Ajv({ allErrors: true, coerceTypes: true, strict: false });
|
|
26
26
|
|
|
27
|
-
const httpMethods = ['get', 'head', 'post', 'put', 'delete', '
|
|
27
|
+
const httpMethods = ['get', 'head', 'post', 'put', 'delete', 'connect', 'options', 'trace', 'patch'];
|
|
28
28
|
|
|
29
29
|
// Create a json schema in the format we've chosen to use
|
|
30
30
|
const createSchema = (pathValue, methodValue) => {
|
|
@@ -186,7 +186,7 @@ class Validator {
|
|
|
186
186
|
|
|
187
187
|
if(firstError.keyword === 'required') {
|
|
188
188
|
// this is a missing required property; there is a specific mojaloop api spec error code for this
|
|
189
|
-
err = new Errors.MojaloopFSPIOPError(firstError, util.format('Request failed validation',
|
|
189
|
+
err = new Errors.MojaloopFSPIOPError(firstError, util.format('Request failed validation',
|
|
190
190
|
validationResult), null, Errors.MojaloopApiErrorCodes.MISSING_ELEMENT);
|
|
191
191
|
|
|
192
192
|
// overwrite the defaul error message with something more useful
|
package/test/__mocks__/redis.js
CHANGED
|
@@ -132,6 +132,11 @@ TRANSFERS_ENDPOINT=ml-testing-toolkit:5000
|
|
|
132
132
|
# The fulfilment will be generated from the provided ILP packet, and must hash to the provided condition.
|
|
133
133
|
ALLOW_TRANSFER_WITHOUT_QUOTE=false
|
|
134
134
|
|
|
135
|
+
# To enable request for notification on fulfiled transfer
|
|
136
|
+
RESERVE_NOTIFICATION=true
|
|
137
|
+
# resources API versions should be string in format: "resourceOneName=1.0,resourceTwoName=1.1"
|
|
138
|
+
RESOURCE_VERSIONS="transfers=1.1,participants=1.1"
|
|
139
|
+
|
|
135
140
|
# Management API websocket connection settings.
|
|
136
141
|
# The Management API uses this for exchanging connector management messages.
|
|
137
142
|
MGMT_API_WS_URL=127.0.0.1
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
const ws = require('ws');
|
|
13
13
|
const jsonPatch = require('fast-json-patch');
|
|
14
|
-
const
|
|
14
|
+
const { generateSlug } = require('random-word-slugs');
|
|
15
15
|
const { getInternalEventEmitter, INTERNAL_EVENTS } = require('./events');
|
|
16
16
|
|
|
17
17
|
const ControlServerEventEmitter = getInternalEventEmitter();
|
|
@@ -58,7 +58,7 @@ const deserialise = (msg) => {
|
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
|
|
61
|
-
const buildMsg = (verb, msg, data, id =
|
|
61
|
+
const buildMsg = (verb, msg, data, id = generateSlug(4)) => serialise({
|
|
62
62
|
verb,
|
|
63
63
|
msg,
|
|
64
64
|
data,
|
|
@@ -197,7 +197,7 @@ class Server extends ws.Server {
|
|
|
197
197
|
* @param {object} params Updated configuration
|
|
198
198
|
*/
|
|
199
199
|
async broadcastConfigChange(updatedConfig) {
|
|
200
|
-
const updateConfMsg = build.CONFIGURATION.PATCH({}, updatedConfig,
|
|
200
|
+
const updateConfMsg = build.CONFIGURATION.PATCH({}, updatedConfig, generateSlug(4));
|
|
201
201
|
const errorLogger = (socket, message) => (err) =>
|
|
202
202
|
this._logger
|
|
203
203
|
.push({ message, ip: this._clientData.get(socket).ip, err })
|
|
@@ -334,7 +334,7 @@ describe('Inbound Server', () => {
|
|
|
334
334
|
});
|
|
335
335
|
|
|
336
336
|
async function testTlsServer(enableTls) {
|
|
337
|
-
defConfig.mutualTLS.
|
|
337
|
+
defConfig.inbound.tls.mutualTLS.enabled = enableTls;
|
|
338
338
|
const logger = new Logger.Logger({ stringify: () => '' });
|
|
339
339
|
const cache = new Cache({ ...defConfig.cacheConfig, logger: logger.push({ component: 'cache' }) });
|
|
340
340
|
const server = new InboundServer(defConfig, logger, cache);
|
package/test/unit/api/utils.js
CHANGED
|
@@ -6,6 +6,7 @@ const Validate = require('~/lib/validate');
|
|
|
6
6
|
|
|
7
7
|
const InboundServer = require('~/InboundServer');
|
|
8
8
|
const OutboundServer = require('~/OutboundServer');
|
|
9
|
+
const { MetricsClient } = require('~/lib/metrics');
|
|
9
10
|
const { Logger } = require('@mojaloop/sdk-standard-components');
|
|
10
11
|
const Cache = require('~/lib/cache');
|
|
11
12
|
|
|
@@ -47,7 +48,9 @@ const createTestServers = async (config) => {
|
|
|
47
48
|
});
|
|
48
49
|
await cache.connect();
|
|
49
50
|
defConfig.requestProcessingTimeoutSeconds = 2;
|
|
50
|
-
const
|
|
51
|
+
const metricsClient = new MetricsClient();
|
|
52
|
+
metricsClient._prometheusRegister.clear();
|
|
53
|
+
const serverOutbound = new OutboundServer(defConfig, logger, cache, metricsClient);
|
|
51
54
|
await serverOutbound.start();
|
|
52
55
|
const reqOutbound = supertest(serverOutbound._server);
|
|
53
56
|
|
package/test/unit/config.test.js
CHANGED
|
@@ -68,7 +68,7 @@ describe('config', () => {
|
|
|
68
68
|
fs.writeFileSync(cert, certContent);
|
|
69
69
|
process.env.IN_SERVER_CERT_PATH = cert;
|
|
70
70
|
const config = require('~/config');
|
|
71
|
-
const content = config.
|
|
71
|
+
const content = config.inbound.tls.creds.cert.toString();
|
|
72
72
|
expect(content).toBe(certContent);
|
|
73
73
|
});
|
|
74
74
|
|
|
@@ -84,7 +84,7 @@ describe('config', () => {
|
|
|
84
84
|
certs.forEach((cert, index) => fs.writeFileSync(cert, certContent[index]));
|
|
85
85
|
process.env.IN_CA_CERT_PATH = certs.join(',');
|
|
86
86
|
const config = require('~/config');
|
|
87
|
-
const content = config.
|
|
87
|
+
const content = config.inbound.tls.creds.ca.map(ca => ca.toString());
|
|
88
88
|
expect(content).toStrictEqual(certContent);
|
|
89
89
|
});
|
|
90
90
|
|
|
@@ -114,7 +114,7 @@ describe('config', () => {
|
|
|
114
114
|
|
|
115
115
|
it('should throw an err if the resource string is not correctly formed', () => {
|
|
116
116
|
const parseResourceVersion = require('~/config').__parseResourceVersion;
|
|
117
|
-
expect(() => parseResourceVersion('resourceOneName=1.0;resourceTwoName=1.1')).toThrowError(new Error('Resource versions format should be in format: "
|
|
117
|
+
expect(() => parseResourceVersion('resourceOneName=1.0;resourceTwoName=1.1')).toThrowError(new Error('Resource versions format should be in format: "resourceOneName=1.0,resourceTwoName=1.1"'));
|
|
118
118
|
});
|
|
119
119
|
|
|
120
120
|
});
|
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
"control": {},
|
|
3
|
+
"test": {
|
|
4
|
+
"tls": {
|
|
5
|
+
"mutualTLS": { "enabled": false },
|
|
5
6
|
"creds": {
|
|
6
7
|
"ca": null,
|
|
7
8
|
"cert": null,
|
|
8
9
|
"key": null
|
|
9
10
|
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"inbound": {
|
|
14
|
+
"tls": {
|
|
15
|
+
"mutualTLS": { "enabled": false },
|
|
16
|
+
"creds": {
|
|
17
|
+
"ca": null,
|
|
18
|
+
"cert": null,
|
|
19
|
+
"key": null
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"outbound": {
|
|
24
|
+
"tls": {
|
|
25
|
+
"mutualTLS": { "enabled": false },
|
|
13
26
|
"creds": {
|
|
14
27
|
"ca": null,
|
|
15
28
|
"cert": null,
|
|
@@ -54,5 +67,8 @@
|
|
|
54
67
|
"rejectExpiredQuoteResponses": false,
|
|
55
68
|
"rejectExpiredTransferFulfils": false,
|
|
56
69
|
"rejectTransfersOnExpiredQuotes": false,
|
|
57
|
-
"logIndent": 2
|
|
70
|
+
"logIndent": 2,
|
|
71
|
+
"metrics": {
|
|
72
|
+
"port": 4004
|
|
73
|
+
}
|
|
58
74
|
}
|