account-lookup-service 15.6.0-snapshot.4 → 16.1.0-iso.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/CHANGELOG.md +25 -0
- package/LICENSE.md +3 -4
- package/README.md +2 -0
- package/audit-ci.jsonc +2 -27
- package/config/default.json +1 -0
- package/docker/mock-proxy/README.md +21 -0
- package/docker/mock-proxy/src/config.ts +7 -0
- package/docs/Proxy/Discovery.md +20 -0
- package/docs/Proxy/FXAPI_POC_payer_conversion_RECEIVE.plantuml +577 -0
- package/docs/Proxy/FXAPI_POC_payer_conversion_SEND.plantuml +1423 -0
- package/docs/Proxy/P2P.md +11 -0
- package/docs/Proxy/Proxy pattern - Happy path.plantuml +98 -0
- package/docs/Proxy/Proxy pattern - Lazy Discovery - No Oracles.plantuml +105 -0
- package/docs/Proxy/Proxy pattern - Lazy Discovery - No Oracles.png +0 -0
- package/docs/Proxy/Proxy pattern - Lazy Discovery - Oracles.plantuml +130 -0
- package/docs/Proxy/Proxy pattern - Lazy Discovery - Oracles.png +0 -0
- package/docs/Proxy/Proxy pattern - Lazy Discovery Identifier Cache Invalid.plantuml +72 -0
- package/docs/Proxy/Proxy pattern - Lazy Discovery Identifier Cache Invalid.png +0 -0
- package/docs/Proxy/Proxy pattern - P2P.plantuml +186 -0
- package/docs/Proxy/Proxy pattern - P2P.png +0 -0
- package/docs/Proxy/Proxy pattern - Unhappy path.plantuml +103 -0
- package/docs/Proxy/Proxy pattern - Unhappy path.png +0 -0
- package/docs/Proxy/Proxy pattern - happy path.png +0 -0
- package/docs/Proxy/Readme.md +39 -0
- package/docs/Proxy/SettingUpProxys.plantuml +31 -0
- package/docs/Proxy/SettingUpProxys.png +0 -0
- package/package.json +33 -18
- package/src/constants.js +2 -1
- package/src/domain/oracle/oracle.js +63 -4
- package/src/domain/participants/participants.js +246 -129
- package/src/domain/parties/getPartiesByTypeAndID.js +28 -7
- package/src/domain/parties/parties.js +32 -3
- package/src/domain/timeout/index.js +12 -1
- package/src/handlers/monitoring/index.js +1 -1
- package/src/interface/api-swagger-iso20022-parties.yaml +7 -6
- package/src/interface/api-swagger.yaml +7 -6
- package/src/lib/config.js +2 -1
- package/src/lib/db.js +2 -1
- package/src/models/currency/currency.js +10 -1
- package/src/models/endpointType/endpointType.js +10 -1
- package/src/models/oracle/facade.js +42 -16
- package/src/models/oracle/oracleEndpoint.js +65 -10
- package/src/models/oracle/oracleEndpointCached.js +29 -9
- package/src/models/participantEndpoint/facade.js +40 -4
- package/src/models/partyIdType/partyIdType.js +10 -1
- package/src/plugins.js +8 -21
- package/src/server.js +11 -0
- package/test/fixtures/index.js +30 -6
- package/test/unit/api/health.test.js +3 -0
- package/test/unit/api/participants/participants.test.js +5 -7
- package/test/unit/api/participants/{Type}/{ID}/{SubId}.test.js +0 -3
- package/test/unit/api/participants/{Type}/{ID}.test.js +0 -3
- package/test/unit/api/participants.test.js +36 -3
- package/test/unit/domain/oracle/oracle.test.js +8 -0
- package/test/unit/domain/participants/participants.test.js +83 -48
- package/test/unit/domain/parties/parties.test.js +8 -0
- package/test/unit/domain/timeout/index.test.js +8 -0
- package/test/unit/lib/config.test.js +7 -0
- package/test/unit/mocks.js +16 -11
- package/test/unit/models/oracle/oracleEndpointCached.test.js +32 -0
- package/test/unit/plugins.test.js +2 -2
- package/src/lib/requestLogger.js +0 -54
- package/src/metrics/handler.js +0 -33
- package/src/metrics/plugin.js +0 -52
- package/src/metrics/routes.js +0 -43
- package/test/unit/lib/requestLogger.test.js +0 -115
@@ -34,20 +34,28 @@ const Sinon = require('sinon')
|
|
34
34
|
const Enums = require('@mojaloop/central-services-shared').Enum
|
35
35
|
const Logger = require('@mojaloop/central-services-logger')
|
36
36
|
const ErrorHandler = require('@mojaloop/central-services-error-handling')
|
37
|
+
const Metrics = require('@mojaloop/central-services-metrics')
|
37
38
|
|
38
39
|
const participantsDomain = require('../../../../src/domain/participants/participants')
|
39
40
|
const participant = require('../../../../src/models/participantEndpoint/facade')
|
40
41
|
const oracle = require('../../../../src/models/oracle/facade')
|
41
|
-
const Helper = require('../../../util/helper')
|
42
42
|
const Config = require('../../../../src/lib/config')
|
43
|
+
const { logger } = require('../../../../src/lib')
|
44
|
+
const { ERROR_MESSAGES } = require('../../../../src/constants')
|
45
|
+
const Helper = require('../../../util/helper')
|
46
|
+
const fixtures = require('../../../fixtures')
|
43
47
|
|
44
|
-
|
45
|
-
Logger.isErrorEnabled = jest.fn(() => true)
|
46
|
-
Logger.isInfoEnabled = jest.fn(() => true)
|
48
|
+
const { Headers } = Enums.Http
|
47
49
|
|
48
50
|
describe('participant Tests', () => {
|
49
51
|
describe('getParticipantsByTypeAndID', () => {
|
50
52
|
let sandbox
|
53
|
+
// Initialize Metrics for testing
|
54
|
+
Metrics.getCounter(
|
55
|
+
'errorCount',
|
56
|
+
'Error count',
|
57
|
+
['code', 'system', 'operation', 'step']
|
58
|
+
)
|
51
59
|
|
52
60
|
beforeEach(() => {
|
53
61
|
sandbox = Sinon.createSandbox()
|
@@ -185,7 +193,7 @@ describe('participant Tests', () => {
|
|
185
193
|
expect.hasAssertions()
|
186
194
|
// Arrange
|
187
195
|
participant.validateParticipant = sandbox.stub().resolves(null)
|
188
|
-
const
|
196
|
+
const logStub = sandbox.stub(logger.constructor.prototype, 'warn')
|
189
197
|
|
190
198
|
participant.sendRequest = sandbox.stub()
|
191
199
|
const args = [
|
@@ -199,8 +207,8 @@ describe('participant Tests', () => {
|
|
199
207
|
await participantsDomain.getParticipantsByTypeAndID(...args)
|
200
208
|
|
201
209
|
// Assert
|
202
|
-
const firstCallArgs =
|
203
|
-
expect(firstCallArgs[0]).toBe(
|
210
|
+
const firstCallArgs = logStub.getCall(0).args
|
211
|
+
expect(firstCallArgs[0]).toBe(ERROR_MESSAGES.sourceFspNotFound)
|
204
212
|
})
|
205
213
|
|
206
214
|
it('fails when `oracleRequest` response is empty', async () => {
|
@@ -485,9 +493,8 @@ describe('participant Tests', () => {
|
|
485
493
|
it('handles the case where `validateParticipant` returns null', async () => {
|
486
494
|
expect.hasAssertions()
|
487
495
|
// Arrange
|
496
|
+
const logStub = sandbox.stub(logger.constructor.prototype, 'error')
|
488
497
|
participant.validateParticipant = sandbox.stub().resolves(null)
|
489
|
-
sandbox.stub(Logger)
|
490
|
-
Logger.error = sandbox.stub()
|
491
498
|
participant.sendErrorToParticipant = sandbox.stub()
|
492
499
|
const headers = {
|
493
500
|
accept: 'application/vnd.interoperability.participants+json;version=1',
|
@@ -510,8 +517,7 @@ describe('participant Tests', () => {
|
|
510
517
|
await participantsDomain.putParticipantsByTypeAndID(headers, params, method, payload)
|
511
518
|
|
512
519
|
// Assert
|
513
|
-
|
514
|
-
expect(loggerFirstCallArgs[0]).toBe('Requester FSP not found')
|
520
|
+
expect(logStub.getCall(0).args[1].message).toBe(ERROR_MESSAGES.sourceFspNotFound)
|
515
521
|
})
|
516
522
|
|
517
523
|
it('handles case where type is not in `PartyAccountTypes`', async () => {
|
@@ -739,9 +745,6 @@ describe('participant Tests', () => {
|
|
739
745
|
it('handles PUT /error when SubId supplied but validateParticipant throws error', async () => {
|
740
746
|
expect.hasAssertions()
|
741
747
|
// Arrange
|
742
|
-
sandbox.stub(Logger)
|
743
|
-
Logger.info = sandbox.stub()
|
744
|
-
Logger.error = sandbox.stub()
|
745
748
|
participant.validateParticipant = sandbox.stub().throws(new Error('Validation failed'))
|
746
749
|
oracle.oracleRequest = sandbox.stub().resolves(null)
|
747
750
|
participant.sendErrorToParticipant = sandbox.stub()
|
@@ -771,15 +774,11 @@ describe('participant Tests', () => {
|
|
771
774
|
expect(participant.sendErrorToParticipant.callCount).toBe(1)
|
772
775
|
const firstCallArgs = participant.sendErrorToParticipant.getCall(0).args
|
773
776
|
expect(firstCallArgs[1]).toBe(expectedCallbackEndpointType)
|
774
|
-
expect(Logger.error.callCount).toBe(1)
|
775
777
|
})
|
776
778
|
|
777
779
|
it('handles PUT /error when `sendErrorToParticipant` throws error', async () => {
|
778
780
|
expect.hasAssertions()
|
779
781
|
// Arrange
|
780
|
-
sandbox.stub(Logger)
|
781
|
-
Logger.info = sandbox.stub()
|
782
|
-
Logger.error = sandbox.stub()
|
783
782
|
participant.validateParticipant = sandbox.stub().resolves({})
|
784
783
|
participant.sendErrorToParticipant = sandbox.stub().throws(new Error('sendErrorToParticipant failed'))
|
785
784
|
const expectedCallbackEndpointType = Enums.EndPoints.FspEndpointTypes.FSPIOP_CALLBACK_URL_PARTICIPANT_PUT_ERROR
|
@@ -809,15 +808,11 @@ describe('participant Tests', () => {
|
|
809
808
|
const secondCallArgs = participant.sendErrorToParticipant.getCall(1).args
|
810
809
|
expect(firstCallArgs[1]).toBe(expectedCallbackEndpointType)
|
811
810
|
expect(secondCallArgs[0]).toBe(Config.HUB_NAME)
|
812
|
-
expect(Logger.error.callCount).toBe(2)
|
813
811
|
})
|
814
812
|
|
815
813
|
it('handles PUT /error when SubId is supplied and `sendErrorToParticipant` throws error', async () => {
|
816
814
|
expect.hasAssertions()
|
817
815
|
// Arrange
|
818
|
-
sandbox.stub(Logger)
|
819
|
-
Logger.info = sandbox.stub()
|
820
|
-
Logger.error = sandbox.stub()
|
821
816
|
participant.validateParticipant = sandbox.stub().resolves({})
|
822
817
|
participant.sendErrorToParticipant = sandbox.stub().throws(new Error('sendErrorToParticipant failed'))
|
823
818
|
const expectedCallbackEndpointType = Enums.EndPoints.FspEndpointTypes.FSPIOP_CALLBACK_URL_PARTICIPANT_SUB_ID_PUT_ERROR
|
@@ -848,7 +843,6 @@ describe('participant Tests', () => {
|
|
848
843
|
const secondCallArgs = participant.sendErrorToParticipant.getCall(1).args
|
849
844
|
expect(firstCallArgs[1]).toBe(expectedCallbackEndpointType)
|
850
845
|
expect(secondCallArgs[0]).toBe(Config.HUB_NAME)
|
851
|
-
expect(Logger.error.callCount).toBe(2)
|
852
846
|
})
|
853
847
|
})
|
854
848
|
|
@@ -1048,9 +1042,8 @@ describe('participant Tests', () => {
|
|
1048
1042
|
it('handles the case where `validateParticipant` returns null', async () => {
|
1049
1043
|
expect.hasAssertions()
|
1050
1044
|
// Arrange
|
1045
|
+
const logStub = sandbox.stub(logger.constructor.prototype, 'error')
|
1051
1046
|
participant.validateParticipant = sandbox.stub().resolves(null)
|
1052
|
-
sandbox.stub(Logger)
|
1053
|
-
Logger.error = sandbox.stub()
|
1054
1047
|
participant.sendErrorToParticipant = sandbox.stub()
|
1055
1048
|
const headers = {
|
1056
1049
|
accept: 'application/vnd.interoperability.participants+json;version=1',
|
@@ -1072,8 +1065,7 @@ describe('participant Tests', () => {
|
|
1072
1065
|
await participantsDomain.postParticipants(headers, 'get', params, payload)
|
1073
1066
|
|
1074
1067
|
// Assert
|
1075
|
-
|
1076
|
-
expect(loggerFirstCallArgs[0]).toBe('Requester FSP not found')
|
1068
|
+
expect(logStub.getCall(0).args[0]).toBe(ERROR_MESSAGES.sourceFspNotFound)
|
1077
1069
|
})
|
1078
1070
|
|
1079
1071
|
it('handles case where type is not in `PartyAccountTypes`', async () => {
|
@@ -1202,7 +1194,7 @@ describe('participant Tests', () => {
|
|
1202
1194
|
|
1203
1195
|
const headers = {
|
1204
1196
|
accept: 'application/vnd.interoperability.participants+json;version=1',
|
1205
|
-
'fspiop-destination': Config.HUB_NAME,
|
1197
|
+
// 'fspiop-destination': Config.HUB_NAME,
|
1206
1198
|
'content-type': 'application/vnd.interoperability.participants+json;version=1.1',
|
1207
1199
|
date: '2019-05-24 08:52:19',
|
1208
1200
|
'fspiop-source': 'fsp1'
|
@@ -1318,15 +1310,23 @@ describe('participant Tests', () => {
|
|
1318
1310
|
const expected = {
|
1319
1311
|
currency: 'USD',
|
1320
1312
|
partyList: [
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
1313
|
+
{
|
1314
|
+
...ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.PARTY_NOT_FOUND, undefined, undefined, undefined, [{
|
1315
|
+
key: Enums.Accounts.PartyAccountTypes.MSISDN,
|
1316
|
+
value: undefined
|
1317
|
+
}]).toApiErrorObject(Config.ERROR_HANDLING),
|
1318
|
+
partyId: payload.partyList[1]
|
1319
|
+
},
|
1320
|
+
{
|
1321
|
+
...ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ADD_PARTY_INFO_ERROR, undefined, undefined, undefined, [{
|
1322
|
+
key: 'NOT_A_VALID_PARTY_ID',
|
1323
|
+
value: undefined
|
1324
|
+
}]).toApiErrorObject(Config.ERROR_HANDLING),
|
1325
|
+
partyId: payload.partyList[2]
|
1326
|
+
},
|
1327
|
+
{
|
1328
|
+
partyId: { currency: undefined }
|
1329
|
+
}
|
1330
1330
|
]
|
1331
1331
|
}
|
1332
1332
|
|
@@ -1342,10 +1342,10 @@ describe('participant Tests', () => {
|
|
1342
1342
|
it('handles error when `validateParticipant` fails and `sendErrorToParticipant` throws', async () => {
|
1343
1343
|
expect.hasAssertions()
|
1344
1344
|
// Arrange
|
1345
|
-
sandbox.stub(
|
1346
|
-
Logger.error = sandbox.stub()
|
1345
|
+
const logStub = sandbox.stub(logger.constructor.prototype, 'error')
|
1347
1346
|
participant.validateParticipant = sandbox.stub().resolves(null)
|
1348
|
-
|
1347
|
+
const cbError = new Error('unknown error')
|
1348
|
+
participant.sendErrorToParticipant = sandbox.stub().throws(cbError)
|
1349
1349
|
|
1350
1350
|
const headers = {
|
1351
1351
|
accept: 'application/vnd.interoperability.participants+json;version=1',
|
@@ -1368,10 +1368,8 @@ describe('participant Tests', () => {
|
|
1368
1368
|
await participantsDomain.postParticipantsBatch(headers, 'get', payload, Helper.mockSpan())
|
1369
1369
|
|
1370
1370
|
// Assert
|
1371
|
-
|
1372
|
-
|
1373
|
-
expect(firstCallArgs[0]).toBe('Requester FSP not found')
|
1374
|
-
expect(thirdCallArgs[0].message).toBe('unknown error')
|
1371
|
+
expect(logStub.getCall(0).firstArg).toBe(ERROR_MESSAGES.sourceFspNotFound)
|
1372
|
+
expect(logStub.getCall(2).lastArg).toEqual(cbError)
|
1375
1373
|
})
|
1376
1374
|
|
1377
1375
|
it('handles error when `oracleBatchRequest` returns no result', async () => {
|
@@ -1447,6 +1445,44 @@ describe('participant Tests', () => {
|
|
1447
1445
|
expect(firstCallArgs[4].partyList[1].errorInformation).toBeDefined()
|
1448
1446
|
expect(firstCallArgs[4].partyList[2].errorInformation).toBeDefined()
|
1449
1447
|
})
|
1448
|
+
|
1449
|
+
it('should not call oracle if source-header and fspId in payload are different, and no destination [CSI-938]', async () => {
|
1450
|
+
const headers = fixtures.participantsCallHeadersDto({ destination: '' })
|
1451
|
+
const payload = {
|
1452
|
+
requestId: '0e21b07e-3117-46ca-ae22-6ee370895697',
|
1453
|
+
currency: 'MWK',
|
1454
|
+
partyList: [
|
1455
|
+
{
|
1456
|
+
fspId: 'test-mwk-dfsp',
|
1457
|
+
partyIdType: 'MSISDN',
|
1458
|
+
partyIdentifier: '16665551002'
|
1459
|
+
}
|
1460
|
+
]
|
1461
|
+
}
|
1462
|
+
expect(headers.source).not.toBe(payload.partyList[0].fspId)
|
1463
|
+
expect(headers.destination).toBeUndefined()
|
1464
|
+
|
1465
|
+
participant.validateParticipant = sandbox.stub().resolves({})
|
1466
|
+
participant.sendRequest = sandbox.stub()
|
1467
|
+
participant.sendErrorToParticipant = sandbox.stub().resolves({})
|
1468
|
+
oracle.oracleBatchRequest = sandbox.stub().resolves({})
|
1469
|
+
|
1470
|
+
await participantsDomain.postParticipantsBatch(headers, 'put', payload, Helper.mockSpan())
|
1471
|
+
|
1472
|
+
expect(oracle.oracleBatchRequest.callCount).toBe(0)
|
1473
|
+
expect(participant.sendErrorToParticipant.callCount).toBe(0)
|
1474
|
+
expect(participant.sendRequest.callCount).toBe(1)
|
1475
|
+
|
1476
|
+
const { args } = participant.sendRequest.getCall(0)
|
1477
|
+
expect(args[0][Headers.FSPIOP.DESTINATION]).toBe(headers[Headers.FSPIOP.SOURCE])
|
1478
|
+
expect(args[0][Headers.FSPIOP.SOURCE]).toBe(Config.HUB_NAME)
|
1479
|
+
expect(args[1]).toBe(headers[Headers.FSPIOP.SOURCE])
|
1480
|
+
|
1481
|
+
const { partyList } = args[4]
|
1482
|
+
expect(partyList.length).toBe(1)
|
1483
|
+
expect(partyList[0].errorInformation).toBeDefined()
|
1484
|
+
expect(partyList[0].partyId).toBe(payload.partyList[0])
|
1485
|
+
})
|
1450
1486
|
})
|
1451
1487
|
|
1452
1488
|
describe('deleteParticipants', () => {
|
@@ -1602,9 +1638,8 @@ describe('participant Tests', () => {
|
|
1602
1638
|
it('handles the case where `validateParticipant` returns null', async () => {
|
1603
1639
|
expect.hasAssertions()
|
1604
1640
|
// Arrange
|
1641
|
+
const logStub = sandbox.stub(logger.constructor.prototype, 'error')
|
1605
1642
|
participant.validateParticipant = sandbox.stub().resolves(null)
|
1606
|
-
sandbox.stub(Logger)
|
1607
|
-
Logger.error = sandbox.stub()
|
1608
1643
|
participant.sendErrorToParticipant = sandbox.stub()
|
1609
1644
|
const headers = {
|
1610
1645
|
accept: 'application/vnd.interoperability.participants+json;version=1',
|
@@ -1625,8 +1660,8 @@ describe('participant Tests', () => {
|
|
1625
1660
|
await participantsDomain.deleteParticipants(headers, params, method, query)
|
1626
1661
|
|
1627
1662
|
// Assert
|
1628
|
-
|
1629
|
-
expect(
|
1663
|
+
expect(logStub.getCall(0).firstArg).toBe(ERROR_MESSAGES.sourceFspNotFound)
|
1664
|
+
// expect(logStub.getCall()]).toBe(ERROR_MESSAGES.sourceFspNotFound)
|
1630
1665
|
})
|
1631
1666
|
|
1632
1667
|
it('handles case where type is not in `PartyAccountTypes`', async () => {
|
@@ -37,6 +37,7 @@ const { createProxyCache } = require('@mojaloop/inter-scheme-proxy-cache-lib')
|
|
37
37
|
const { Enum, Util } = require('@mojaloop/central-services-shared')
|
38
38
|
const { MojaloopApiErrorCodes } = require('@mojaloop/sdk-standard-components').Errors
|
39
39
|
const Logger = require('@mojaloop/central-services-logger')
|
40
|
+
const Metrics = require('@mojaloop/central-services-metrics')
|
40
41
|
|
41
42
|
const Config = require('../../../../src/lib/config')
|
42
43
|
const Db = require('../../../../src/lib/db')
|
@@ -65,6 +66,13 @@ let sandbox
|
|
65
66
|
describe('Parties Tests', () => {
|
66
67
|
let proxyCache
|
67
68
|
|
69
|
+
// Initialize Metrics for testing
|
70
|
+
Metrics.getCounter(
|
71
|
+
'errorCount',
|
72
|
+
'Error count',
|
73
|
+
['code', 'system', 'operation', 'step']
|
74
|
+
)
|
75
|
+
|
68
76
|
beforeEach(async () => {
|
69
77
|
await Util.Endpoints.initializeCache(Config.CENTRAL_SHARED_ENDPOINT_CACHE_CONFIG, libUtil.hubNameConfig)
|
70
78
|
sandbox = Sinon.createSandbox()
|
@@ -33,8 +33,16 @@
|
|
33
33
|
|
34
34
|
const Participant = require('../../../../src/models/participantEndpoint/facade')
|
35
35
|
const TimeoutDomain = require('../../../../src/domain/timeout')
|
36
|
+
const Metrics = require('@mojaloop/central-services-metrics')
|
36
37
|
|
37
38
|
describe('Timeout Domain', () => {
|
39
|
+
// Initialize Metrics for testing
|
40
|
+
Metrics.getCounter(
|
41
|
+
'errorCount',
|
42
|
+
'Error count',
|
43
|
+
['code', 'system', 'operation', 'step']
|
44
|
+
)
|
45
|
+
|
38
46
|
beforeEach(() => {
|
39
47
|
jest.clearAllMocks()
|
40
48
|
jest.spyOn(Participant, 'validateParticipant').mockResolvedValue({})
|
@@ -105,4 +105,11 @@ describe('Config tests', () => {
|
|
105
105
|
expect(isSuccess).toBe(false)
|
106
106
|
expect(error.message).toBe('File doesn\'t exist')
|
107
107
|
})
|
108
|
+
|
109
|
+
it('should have FSPIOP_SOURCE_TO_SIGN config defined', () => {
|
110
|
+
process.env.ALS_ENDPOINT_SECURITY__JWS__JWS_SIGN = 'false' // to avoid error in config getFileContent()
|
111
|
+
const config = require(configImport)
|
112
|
+
expect(config.FSPIOP_SOURCE_TO_SIGN).toBeDefined()
|
113
|
+
expect(config.FSPIOP_SOURCE_TO_SIGN).toBe(config.HUB_NAME)
|
114
|
+
})
|
108
115
|
})
|
package/test/unit/mocks.js
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
/*****
|
2
2
|
License
|
3
3
|
--------------
|
4
|
-
Copyright ©
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
Copyright © 2020-2024 Mojaloop Foundation
|
5
|
+
|
6
|
+
The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0
|
7
|
+
(the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0).
|
8
|
+
|
9
|
+
You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
10
|
+
|
11
|
+
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](http://www.apache.org/licenses/LICENSE-2.0).
|
8
12
|
|
9
13
|
Contributors
|
10
14
|
--------------
|
@@ -16,6 +20,7 @@
|
|
16
20
|
Gates Foundation organization for an example). Those individuals should have
|
17
21
|
their names indented and be marked with a '-'. Email address can be added
|
18
22
|
optionally within square brackets <email>.
|
23
|
+
|
19
24
|
* Gates Foundation
|
20
25
|
- Name Surname <name.surname@gatesfoundation.com>
|
21
26
|
|
@@ -26,13 +31,13 @@
|
|
26
31
|
const RedisMock = require('ioredis-mock')
|
27
32
|
|
28
33
|
/*
|
29
|
-
|
30
|
-
|
34
|
+
ioredis-mock doesn't provide a status-field, so we need to override it here
|
35
|
+
*/
|
31
36
|
class MockIoRedis extends RedisMock {
|
32
37
|
connected = false
|
33
38
|
/**
|
34
|
-
|
35
|
-
|
39
|
+
@param opts RedisOptions
|
40
|
+
*/
|
36
41
|
constructor (opts) {
|
37
42
|
super(opts)
|
38
43
|
this.lazyConnect = Boolean(opts?.lazyConnect)
|
@@ -45,9 +50,9 @@ class MockIoRedis extends RedisMock {
|
|
45
50
|
|
46
51
|
class IoRedisMockCluster extends MockIoRedis {
|
47
52
|
/**
|
48
|
-
|
49
|
-
|
50
|
-
|
53
|
+
@param nodesList BasicConnectionConfig[]
|
54
|
+
@param redisOptions RedisClusterOptions
|
55
|
+
*/
|
51
56
|
constructor (nodesList, redisOptions) {
|
52
57
|
super(redisOptions)
|
53
58
|
this._nodes = []
|
@@ -58,6 +58,7 @@ describe('ParticipantCurrency cached model', () => {
|
|
58
58
|
sandbox.stub(OracleEndpointUncached, 'getOracleEndpointByTypeAndCurrency').returns(oracleEndpoints)
|
59
59
|
sandbox.stub(OracleEndpointUncached, 'getOracleEndpointByCurrency').returns(oracleEndpoints)
|
60
60
|
sandbox.stub(OracleEndpointUncached, 'getOracleEndpointByType').returns(oracleEndpoints)
|
61
|
+
sandbox.stub(OracleEndpointUncached, 'assertPendingAcquires').returns()
|
61
62
|
})
|
62
63
|
|
63
64
|
afterEach(() => {
|
@@ -150,4 +151,35 @@ describe('ParticipantCurrency cached model', () => {
|
|
150
151
|
await Model.getOracleEndpointByTypeAndCurrency('MSISDN', 'USD')
|
151
152
|
expect(cacheClient.get.called).toBeTruthy()
|
152
153
|
})
|
154
|
+
it('getOracleEndpointCached calls assertPendingAcquire when assertPendingAcquire is true', async () => {
|
155
|
+
let cache = null
|
156
|
+
const cacheClient = {
|
157
|
+
createKey: sandbox.stub().returns({}),
|
158
|
+
get: () => cache,
|
159
|
+
set: (key, x) => {
|
160
|
+
cache = { item: x } // the cache returns {item: <data>} structure
|
161
|
+
}
|
162
|
+
}
|
163
|
+
Cache.registerCacheClient.returns(cacheClient)
|
164
|
+
await Model.initialize()
|
165
|
+
|
166
|
+
await Model.getOracleEndpointByTypeAndCurrency('MSISDN', 'USD', true)
|
167
|
+
expect(OracleEndpointUncached.assertPendingAcquires.calledOnce).toBeTruthy()
|
168
|
+
})
|
169
|
+
|
170
|
+
it('getOracleEndpointCached does not call assertPendingAcquire when assertPendingAcquire is false', async () => {
|
171
|
+
let cache = null
|
172
|
+
const cacheClient = {
|
173
|
+
createKey: sandbox.stub().returns({}),
|
174
|
+
get: () => cache,
|
175
|
+
set: (key, x) => {
|
176
|
+
cache = { item: x } // the cache returns {item: <data>} structure
|
177
|
+
}
|
178
|
+
}
|
179
|
+
Cache.registerCacheClient.returns(cacheClient)
|
180
|
+
await Model.initialize()
|
181
|
+
|
182
|
+
await Model.getOracleEndpointByTypeAndCurrency('MSISDN', 'USD', false)
|
183
|
+
expect(OracleEndpointUncached.assertPendingAcquires.called).toBeFalsy()
|
184
|
+
})
|
153
185
|
})
|
@@ -64,7 +64,7 @@ describe('Plugin Tests', () => {
|
|
64
64
|
await registerPlugins(server, api)
|
65
65
|
|
66
66
|
// Assert
|
67
|
-
expect(server.register.callCount).toBe(
|
67
|
+
expect(server.register.callCount).toBe(11)
|
68
68
|
const firstCallArgs = server.register.getCall(1).args
|
69
69
|
expect(firstCallArgs[0].options.document.info.title.includes('Open API for FSP Interoperability (FSPIOP) (Implementation Friendly Version)')).toBe(true)
|
70
70
|
})
|
@@ -86,6 +86,6 @@ describe('Plugin Tests', () => {
|
|
86
86
|
await registerPlugins(server, api)
|
87
87
|
|
88
88
|
// Assert
|
89
|
-
expect(server.register.callCount).toBe(
|
89
|
+
expect(server.register.callCount).toBe(10)
|
90
90
|
})
|
91
91
|
})
|
package/src/lib/requestLogger.js
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
/*****
|
2
|
-
License
|
3
|
-
--------------
|
4
|
-
Copyright © 2017 Bill & Melinda Gates Foundation
|
5
|
-
The Mojaloop files are made available by the Bill & Melinda Gates 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
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
7
|
-
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.
|
8
|
-
Contributors
|
9
|
-
--------------
|
10
|
-
This is the official list of the Mojaloop project contributors for this file.
|
11
|
-
Names of the original copyright holders (individuals or organizations)
|
12
|
-
should be listed with a '*' in the first column. People who have
|
13
|
-
contributed from an organization can be listed under the organization
|
14
|
-
that actually holds the copyright for their contributions (see the
|
15
|
-
Gates Foundation organization for an example). Those individuals should have
|
16
|
-
their names indented and be marked with a '-'. Email address can be added
|
17
|
-
optionally within square brackets <email>.
|
18
|
-
* Gates Foundation
|
19
|
-
|
20
|
-
* Rajiv Mothilal <rajiv.mothilal@modusbox.com>
|
21
|
-
|
22
|
-
--------------
|
23
|
-
******/
|
24
|
-
|
25
|
-
'use strict'
|
26
|
-
|
27
|
-
const { logger, asyncStorage } = require('./index')
|
28
|
-
|
29
|
-
const logRequest = function (request) {
|
30
|
-
const { path, method, headers, payload, query } = request
|
31
|
-
const requestId = request.info.id = `${request.info.id}__${headers.traceid}`
|
32
|
-
asyncStorage.enterWith({ requestId })
|
33
|
-
|
34
|
-
logger.isInfoEnabled && logger.info(`[==> req] ${method.toUpperCase()} ${path}`, { headers, payload, query })
|
35
|
-
}
|
36
|
-
|
37
|
-
const logResponse = function (request) {
|
38
|
-
if (logger.isInfoEnabled) {
|
39
|
-
const { path, method, headers, payload, query, response } = request
|
40
|
-
const { received } = request.info
|
41
|
-
|
42
|
-
const statusCode = response instanceof Error
|
43
|
-
? response.output?.statusCode
|
44
|
-
: response.statusCode
|
45
|
-
const respTimeSec = ((Date.now() - received) / 1000).toFixed(3)
|
46
|
-
|
47
|
-
logger.info(`[<== ${statusCode}][${respTimeSec} s] ${method.toUpperCase()} ${path}`, { headers, payload, query })
|
48
|
-
}
|
49
|
-
}
|
50
|
-
|
51
|
-
module.exports = {
|
52
|
-
logRequest,
|
53
|
-
logResponse
|
54
|
-
}
|
package/src/metrics/handler.js
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
/*****
|
2
|
-
License
|
3
|
-
--------------
|
4
|
-
Copyright © 2017 Bill & Melinda Gates Foundation
|
5
|
-
The Mojaloop files are made available by the Bill & Melinda Gates 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
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
7
|
-
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.
|
8
|
-
Contributors
|
9
|
-
--------------
|
10
|
-
This is the official list of the Mojaloop project contributors for this file.
|
11
|
-
Names of the original copyright holders (individuals or organizations)
|
12
|
-
should be listed with a '*' in the first column. People who have
|
13
|
-
contributed from an organization can be listed under the organization
|
14
|
-
that actually holds the copyright for their contributions (see the
|
15
|
-
Gates Foundation organization for an example). Those individuals should have
|
16
|
-
their names indented and be marked with a '-'. Email address can be added
|
17
|
-
optionally within square brackets <email>.
|
18
|
-
* Gates Foundation
|
19
|
-
- Name Surname <name.surname@gatesfoundation.com>
|
20
|
-
|
21
|
-
- Pedro Barreto <pedrob@crosslaketech.com>
|
22
|
-
- Rajiv Mothilal <rajivmothilal@gmail.com>
|
23
|
-
- Shashikant Hirugade <shashikant.hirugade@modusbox.com>
|
24
|
-
--------------
|
25
|
-
******/
|
26
|
-
|
27
|
-
'use strict'
|
28
|
-
|
29
|
-
const Metrics = require('@mojaloop/central-services-metrics')
|
30
|
-
|
31
|
-
exports.metrics = async function (request, h) {
|
32
|
-
return h.response(await Metrics.getMetricsForPrometheus()).code(200)
|
33
|
-
}
|
package/src/metrics/plugin.js
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
/*****
|
2
|
-
License
|
3
|
-
--------------
|
4
|
-
Copyright © 2017 Bill & Melinda Gates Foundation
|
5
|
-
The Mojaloop files are made available by the Bill & Melinda Gates 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
|
-
Gates Foundation organization 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
|
-
* Gates Foundation
|
23
|
-
- Name Surname <name.surname@gatesfoundation.com>
|
24
|
-
|
25
|
-
* Lazola Lucas <lazola.lucas@modusbox.com>
|
26
|
-
* Rajiv Mothilal <rajiv.mothilal@modusbox.com>
|
27
|
-
* Miguel de Barros <miguel.debarros@modusbox.com>
|
28
|
-
* Shashikant Hirugade <shashikant.hirugade@modusbox.com>
|
29
|
-
|
30
|
-
--------------
|
31
|
-
|
32
|
-
******/
|
33
|
-
'use strict'
|
34
|
-
|
35
|
-
/**
|
36
|
-
* @module src/metrics/plugin
|
37
|
-
*/
|
38
|
-
|
39
|
-
/**
|
40
|
-
* @function Register Handler Routes HAPI
|
41
|
-
*
|
42
|
-
* @async
|
43
|
-
* @description Registers registers plugins on HAPI server. This retrieves all routes to be exposed from the routes.js file
|
44
|
-
* @returns {Promise} - Returns a promise: resolve if successful, or rejection if failed
|
45
|
-
*/
|
46
|
-
|
47
|
-
exports.plugin = {
|
48
|
-
name: 'handler metrics routes',
|
49
|
-
register: function (server) {
|
50
|
-
server.route(require('./routes'))
|
51
|
-
}
|
52
|
-
}
|
package/src/metrics/routes.js
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
/*****
|
2
|
-
License
|
3
|
-
--------------
|
4
|
-
Copyright © 2017 Bill & Melinda Gates Foundation
|
5
|
-
The Mojaloop files are made available by the Bill & Melinda Gates 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
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
7
|
-
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.
|
8
|
-
Contributors
|
9
|
-
--------------
|
10
|
-
This is the official list of the Mojaloop project contributors for this file.
|
11
|
-
Names of the original copyright holders (individuals or organizations)
|
12
|
-
should be listed with a '*' in the first column. People who have
|
13
|
-
contributed from an organization can be listed under the organization
|
14
|
-
that actually holds the copyright for their contributions (see the
|
15
|
-
Gates Foundation organization for an example). Those individuals should have
|
16
|
-
their names indented and be marked with a '-'. Email address can be added
|
17
|
-
optionally within square brackets <email>.
|
18
|
-
* Gates Foundation
|
19
|
-
- Name Surname <name.surname@gatesfoundation.com>
|
20
|
-
|
21
|
-
- Pedro Barreto <pedrob@crosslaketech.com>
|
22
|
-
- Rajiv Mothilal <rajivmothilal@gmail.com>
|
23
|
-
- Shashikant Hirugade <shashikant.hirugade@modusbox.com>
|
24
|
-
--------------
|
25
|
-
******/
|
26
|
-
|
27
|
-
'use strict'
|
28
|
-
|
29
|
-
const Handler = require('./handler')
|
30
|
-
const tags = ['api', 'metrics']
|
31
|
-
|
32
|
-
module.exports = [
|
33
|
-
{
|
34
|
-
method: 'GET',
|
35
|
-
path: '/metrics',
|
36
|
-
handler: Handler.metrics,
|
37
|
-
config: {
|
38
|
-
tags,
|
39
|
-
description: 'Prometheus metrics endpoint',
|
40
|
-
id: 'metrics'
|
41
|
-
}
|
42
|
-
}
|
43
|
-
]
|