account-lookup-service 15.6.0-snapshot.4 → 16.1.0-iso.1
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 +1 -1
- package/src/domain/oracle/oracle.js +63 -4
- package/src/domain/participants/participants.js +246 -129
- package/src/domain/parties/getPartiesByTypeAndID.js +29 -8
- package/src/domain/parties/parties.js +33 -4
- 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 +29 -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 +10 -2
- 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/models/participantEndpoint/facade.test.js +4 -2
- 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
@@ -27,6 +27,10 @@
|
|
27
27
|
|
28
28
|
const Db = require('../../lib/db')
|
29
29
|
const ErrorHandler = require('@mojaloop/central-services-error-handling')
|
30
|
+
const extensions = [{
|
31
|
+
key: 'system',
|
32
|
+
value: '["db"]'
|
33
|
+
}]
|
30
34
|
|
31
35
|
const getOracleEndpointByType = async (type) => {
|
32
36
|
try {
|
@@ -43,7 +47,12 @@ const getOracleEndpointByType = async (type) => {
|
|
43
47
|
'pt.name as idType', 'oracleEndpoint.currencyId as currency', 'oracleEndpoint.isDefault')
|
44
48
|
})
|
45
49
|
} catch (err) {
|
46
|
-
throw ErrorHandler.Factory.reformatFSPIOPError(
|
50
|
+
throw ErrorHandler.Factory.reformatFSPIOPError(
|
51
|
+
err,
|
52
|
+
undefined,
|
53
|
+
undefined,
|
54
|
+
extensions
|
55
|
+
)
|
47
56
|
}
|
48
57
|
}
|
49
58
|
|
@@ -64,7 +73,12 @@ const getOracleEndpointByTypeAndCurrency = async (type, currencyId) => {
|
|
64
73
|
'pt.name as idType', 'oracleEndpoint.currencyId as currency', 'oracleEndpoint.isDefault')
|
65
74
|
})
|
66
75
|
} catch (err) {
|
67
|
-
throw ErrorHandler.Factory.reformatFSPIOPError(
|
76
|
+
throw ErrorHandler.Factory.reformatFSPIOPError(
|
77
|
+
err,
|
78
|
+
undefined,
|
79
|
+
undefined,
|
80
|
+
extensions
|
81
|
+
)
|
68
82
|
}
|
69
83
|
}
|
70
84
|
|
@@ -84,7 +98,12 @@ const getOracleEndpointByCurrency = async (currencyId) => {
|
|
84
98
|
'pt.name as idType', 'oracleEndpoint.currencyId as currency', 'oracleEndpoint.isDefault')
|
85
99
|
})
|
86
100
|
} catch (err) {
|
87
|
-
throw ErrorHandler.Factory.reformatFSPIOPError(
|
101
|
+
throw ErrorHandler.Factory.reformatFSPIOPError(
|
102
|
+
err,
|
103
|
+
undefined,
|
104
|
+
undefined,
|
105
|
+
extensions
|
106
|
+
)
|
88
107
|
}
|
89
108
|
}
|
90
109
|
|
@@ -104,7 +123,12 @@ const getOracleEndpointById = async (oracleEndpointId) => {
|
|
104
123
|
'pt.name as idType', 'oracleEndpoint.currencyId as currency', 'oracleEndpoint.isDefault')
|
105
124
|
})
|
106
125
|
} catch (err) {
|
107
|
-
throw ErrorHandler.Factory.reformatFSPIOPError(
|
126
|
+
throw ErrorHandler.Factory.reformatFSPIOPError(
|
127
|
+
err,
|
128
|
+
undefined,
|
129
|
+
undefined,
|
130
|
+
extensions
|
131
|
+
)
|
108
132
|
}
|
109
133
|
}
|
110
134
|
|
@@ -122,7 +146,12 @@ const getAllOracleEndpoint = async () => {
|
|
122
146
|
'pt.name as idType', 'oracleEndpoint.currencyId as currency', 'oracleEndpoint.isDefault')
|
123
147
|
})
|
124
148
|
} catch (err) {
|
125
|
-
throw ErrorHandler.Factory.reformatFSPIOPError(
|
149
|
+
throw ErrorHandler.Factory.reformatFSPIOPError(
|
150
|
+
err,
|
151
|
+
undefined,
|
152
|
+
undefined,
|
153
|
+
extensions
|
154
|
+
)
|
126
155
|
}
|
127
156
|
}
|
128
157
|
|
@@ -142,7 +171,12 @@ const getAllOracleEndpointsByMatchCondition = async (oracleEndpointModel, partyI
|
|
142
171
|
'oracleEndpoint.isActive', 'oracleEndpoint.partyIdTypeId', 'oracleEndpoint.endpointTypeId', 'oracleEndpoint.currencyId')
|
143
172
|
})
|
144
173
|
} catch (err) {
|
145
|
-
throw ErrorHandler.Factory.reformatFSPIOPError(
|
174
|
+
throw ErrorHandler.Factory.reformatFSPIOPError(
|
175
|
+
err,
|
176
|
+
undefined,
|
177
|
+
undefined,
|
178
|
+
extensions
|
179
|
+
)
|
146
180
|
}
|
147
181
|
}
|
148
182
|
|
@@ -150,7 +184,12 @@ const createOracleEndpoint = async (oracleEndpointModel) => {
|
|
150
184
|
try {
|
151
185
|
return await Db.from('oracleEndpoint').insert(oracleEndpointModel)
|
152
186
|
} catch (err) {
|
153
|
-
throw ErrorHandler.Factory.reformatFSPIOPError(
|
187
|
+
throw ErrorHandler.Factory.reformatFSPIOPError(
|
188
|
+
err,
|
189
|
+
undefined,
|
190
|
+
undefined,
|
191
|
+
extensions
|
192
|
+
)
|
154
193
|
}
|
155
194
|
}
|
156
195
|
|
@@ -158,7 +197,12 @@ const updateOracleEndpointById = async (id, oracleEndpointModel) => {
|
|
158
197
|
try {
|
159
198
|
return await Db.from('oracleEndpoint').update({ oracleEndpointId: id }, oracleEndpointModel)
|
160
199
|
} catch (err) {
|
161
|
-
throw ErrorHandler.Factory.reformatFSPIOPError(
|
200
|
+
throw ErrorHandler.Factory.reformatFSPIOPError(
|
201
|
+
err,
|
202
|
+
undefined,
|
203
|
+
undefined,
|
204
|
+
extensions
|
205
|
+
)
|
162
206
|
}
|
163
207
|
}
|
164
208
|
|
@@ -166,7 +210,12 @@ const setIsActiveOracleEndpoint = async (oracleType, isActive) => {
|
|
166
210
|
try {
|
167
211
|
return await Db.from('oracleEndpoint').update({ oracleType }, { isActive })
|
168
212
|
} catch (err) {
|
169
|
-
throw ErrorHandler.Factory.reformatFSPIOPError(
|
213
|
+
throw ErrorHandler.Factory.reformatFSPIOPError(
|
214
|
+
err,
|
215
|
+
undefined,
|
216
|
+
undefined,
|
217
|
+
extensions
|
218
|
+
)
|
170
219
|
}
|
171
220
|
}
|
172
221
|
|
@@ -174,11 +223,17 @@ const destroyOracleEndpointById = async (oracleEndpointId) => {
|
|
174
223
|
try {
|
175
224
|
return await Db.from('oracleEndpoint').update({ oracleEndpointId }, { isActive: false })
|
176
225
|
} catch (err) {
|
177
|
-
throw ErrorHandler.Factory.reformatFSPIOPError(
|
226
|
+
throw ErrorHandler.Factory.reformatFSPIOPError(
|
227
|
+
err,
|
228
|
+
undefined,
|
229
|
+
undefined,
|
230
|
+
extensions
|
231
|
+
)
|
178
232
|
}
|
179
233
|
}
|
180
234
|
|
181
235
|
module.exports = {
|
236
|
+
assertPendingAcquires: Db.assertPendingAcquires,
|
182
237
|
getOracleEndpointByType,
|
183
238
|
getOracleEndpointByTypeAndCurrency,
|
184
239
|
getOracleEndpointByCurrency,
|
@@ -31,6 +31,10 @@ const Metrics = require('@mojaloop/central-services-metrics')
|
|
31
31
|
const OracleEndpointUncached = require('./oracleEndpoint')
|
32
32
|
|
33
33
|
let cacheClient
|
34
|
+
const extensions = [{
|
35
|
+
key: 'system',
|
36
|
+
value: '["db","@hapi/catbox-memory"]'
|
37
|
+
}]
|
34
38
|
|
35
39
|
const getCacheKey = (params) => {
|
36
40
|
return cacheClient.createKey(`${Object.values(params).join('__')}`)
|
@@ -49,6 +53,7 @@ const getOracleEndpointCached = async (params) => {
|
|
49
53
|
const cacheKey = getCacheKey(params)
|
50
54
|
let cachedEndpoints = cacheClient.get(cacheKey)
|
51
55
|
if (!cachedEndpoints) {
|
56
|
+
if (params.assertPendingAcquire) OracleEndpointUncached.assertPendingAcquires()
|
52
57
|
// No oracleEndpoint in the cache, so fetch from participant API
|
53
58
|
let oracleEndpoints
|
54
59
|
if (partyIdType && currency) {
|
@@ -83,26 +88,41 @@ exports.initialize = async () => {
|
|
83
88
|
cacheClient = Cache.registerCacheClient(oracleEndpointCacheClientMeta)
|
84
89
|
}
|
85
90
|
|
86
|
-
exports.getOracleEndpointByTypeAndCurrency = async (partyIdType, currency) => {
|
91
|
+
exports.getOracleEndpointByTypeAndCurrency = async (partyIdType, currency, assertPendingAcquire) => {
|
87
92
|
try {
|
88
|
-
return await getOracleEndpointCached({ partyIdType, currency })
|
93
|
+
return await getOracleEndpointCached({ partyIdType, currency, assertPendingAcquire })
|
89
94
|
} catch (err) {
|
90
|
-
throw ErrorHandler.Factory.reformatFSPIOPError(
|
95
|
+
throw ErrorHandler.Factory.reformatFSPIOPError(
|
96
|
+
err,
|
97
|
+
undefined,
|
98
|
+
undefined,
|
99
|
+
extensions
|
100
|
+
)
|
91
101
|
}
|
92
102
|
}
|
93
103
|
|
94
|
-
exports.getOracleEndpointByType = async (partyIdType) => {
|
104
|
+
exports.getOracleEndpointByType = async (partyIdType, assertPendingAcquire) => {
|
95
105
|
try {
|
96
|
-
return await getOracleEndpointCached({ partyIdType })
|
106
|
+
return await getOracleEndpointCached({ partyIdType, assertPendingAcquire })
|
97
107
|
} catch (err) {
|
98
|
-
throw ErrorHandler.Factory.reformatFSPIOPError(
|
108
|
+
throw ErrorHandler.Factory.reformatFSPIOPError(
|
109
|
+
err,
|
110
|
+
undefined,
|
111
|
+
undefined,
|
112
|
+
extensions
|
113
|
+
)
|
99
114
|
}
|
100
115
|
}
|
101
116
|
|
102
|
-
exports.getOracleEndpointByCurrency = async (currency) => {
|
117
|
+
exports.getOracleEndpointByCurrency = async (currency, assertPendingAcquire) => {
|
103
118
|
try {
|
104
|
-
return await getOracleEndpointCached({ currency })
|
119
|
+
return await getOracleEndpointCached({ currency, assertPendingAcquire })
|
105
120
|
} catch (err) {
|
106
|
-
throw ErrorHandler.Factory.reformatFSPIOPError(
|
121
|
+
throw ErrorHandler.Factory.reformatFSPIOPError(
|
122
|
+
err,
|
123
|
+
undefined,
|
124
|
+
undefined,
|
125
|
+
extensions
|
126
|
+
)
|
107
127
|
}
|
108
128
|
}
|
@@ -126,7 +126,16 @@ exports.sendRequest = async (headers, requestedParticipant, endpointType, method
|
|
126
126
|
} catch (err) {
|
127
127
|
histTimerEndSendRequestToParticipant({ success: false, endpointType, participantName: requestedParticipant })
|
128
128
|
logger.warn('error in sendRequest: ', err)
|
129
|
-
|
129
|
+
const extensions = [{
|
130
|
+
key: 'system',
|
131
|
+
value: '["http"]'
|
132
|
+
}]
|
133
|
+
throw ErrorHandler.Factory.reformatFSPIOPError(
|
134
|
+
err,
|
135
|
+
undefined,
|
136
|
+
undefined,
|
137
|
+
extensions
|
138
|
+
)
|
130
139
|
}
|
131
140
|
}
|
132
141
|
|
@@ -151,7 +160,16 @@ exports.validateParticipant = async (fsp) => {
|
|
151
160
|
} catch (err) {
|
152
161
|
histTimerEnd({ success: false })
|
153
162
|
logger.warn('error in validateParticipant: ', err)
|
154
|
-
|
163
|
+
const extensions = [{
|
164
|
+
key: 'system',
|
165
|
+
value: '["http"]'
|
166
|
+
}]
|
167
|
+
throw ErrorHandler.Factory.reformatFSPIOPError(
|
168
|
+
err,
|
169
|
+
undefined,
|
170
|
+
undefined,
|
171
|
+
extensions
|
172
|
+
)
|
155
173
|
}
|
156
174
|
}
|
157
175
|
|
@@ -191,7 +209,16 @@ exports.sendErrorToParticipant = async (participantName, endpointType, errorInfo
|
|
191
209
|
} catch (err) {
|
192
210
|
histTimerEndGetParticipantEndpoint({ success: false, endpointType, participantName })
|
193
211
|
logger.warn('error in getEndpoint: ', err)
|
194
|
-
|
212
|
+
const extensions = [{
|
213
|
+
key: 'system',
|
214
|
+
value: '["http"]'
|
215
|
+
}]
|
216
|
+
throw ErrorHandler.Factory.reformatFSPIOPError(
|
217
|
+
err,
|
218
|
+
undefined,
|
219
|
+
undefined,
|
220
|
+
extensions
|
221
|
+
)
|
195
222
|
}
|
196
223
|
|
197
224
|
// Send error to participant
|
@@ -235,6 +262,15 @@ exports.sendErrorToParticipant = async (participantName, endpointType, errorInfo
|
|
235
262
|
} catch (err) {
|
236
263
|
histTimerEndSendRequestToParticipant({ success: false, endpointType, participantName })
|
237
264
|
logger.warn('error in sendErrorToParticipant: ', err)
|
238
|
-
|
265
|
+
const extensions = [{
|
266
|
+
key: 'system',
|
267
|
+
value: '["http"]'
|
268
|
+
}]
|
269
|
+
throw ErrorHandler.Factory.reformatFSPIOPError(
|
270
|
+
err,
|
271
|
+
undefined,
|
272
|
+
undefined,
|
273
|
+
extensions
|
274
|
+
)
|
239
275
|
}
|
240
276
|
}
|
@@ -32,7 +32,16 @@ const getPartyIdTypeByName = async (name) => {
|
|
32
32
|
try {
|
33
33
|
return Db.from('partyIdType').findOne({ name, isActive: true })
|
34
34
|
} catch (err) {
|
35
|
-
|
35
|
+
const extensions = [{
|
36
|
+
key: 'system',
|
37
|
+
value: '["db"]'
|
38
|
+
}]
|
39
|
+
throw ErrorHandler.Factory.reformatFSPIOPError(
|
40
|
+
err,
|
41
|
+
undefined,
|
42
|
+
undefined,
|
43
|
+
extensions
|
44
|
+
)
|
36
45
|
}
|
37
46
|
}
|
38
47
|
|
package/src/plugins.js
CHANGED
@@ -24,22 +24,22 @@
|
|
24
24
|
******/
|
25
25
|
'use strict'
|
26
26
|
|
27
|
-
const { randomUUID } = require('node:crypto')
|
28
27
|
const Inert = require('@hapi/inert')
|
29
28
|
const Vision = require('@hapi/vision')
|
30
29
|
const Blipp = require('blipp')
|
31
30
|
const ErrorHandling = require('@mojaloop/central-services-error-handling')
|
31
|
+
const MetricsPlugin = require('@mojaloop/central-services-metrics').plugin
|
32
32
|
const {
|
33
33
|
APIDocumentation,
|
34
34
|
FSPIOPHeaderValidation,
|
35
35
|
HapiEventPlugin,
|
36
36
|
HapiRawPayload,
|
37
|
-
OpenapiBackendValidator
|
37
|
+
OpenapiBackendValidator,
|
38
|
+
loggingPlugin
|
38
39
|
} = require('@mojaloop/central-services-shared').Util.Hapi
|
39
40
|
|
41
|
+
const { logger } = require('./lib')
|
40
42
|
const Config = require('./lib/config')
|
41
|
-
const MetricsPlugin = require('./metrics/plugin')
|
42
|
-
const RequestLogger = require('./lib/requestLogger')
|
43
43
|
|
44
44
|
const registerPlugins = async (server, openAPIBackend) => {
|
45
45
|
await server.register(OpenapiBackendValidator)
|
@@ -139,23 +139,10 @@ const registerPlugins = async (server, openAPIBackend) => {
|
|
139
139
|
await server.register([Blipp])
|
140
140
|
}
|
141
141
|
|
142
|
-
await server.
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
request.headers.traceid = request.headers.traceid || randomUUID()
|
147
|
-
RequestLogger.logRequest(request)
|
148
|
-
return h.continue
|
149
|
-
}
|
150
|
-
},
|
151
|
-
{
|
152
|
-
type: 'onPreResponse',
|
153
|
-
method: (request, h) => {
|
154
|
-
RequestLogger.logResponse(request)
|
155
|
-
return h.continue
|
156
|
-
}
|
157
|
-
}
|
158
|
-
])
|
142
|
+
await server.register({
|
143
|
+
plugin: loggingPlugin,
|
144
|
+
options: { log: logger }
|
145
|
+
})
|
159
146
|
}
|
160
147
|
|
161
148
|
module.exports = {
|
package/src/server.js
CHANGED
@@ -105,6 +105,14 @@ const createServer = async (port, api, routes, isAdmin, proxyCacheConfig, proxyM
|
|
105
105
|
await Plugins.registerPlugins(server, api, isAdmin)
|
106
106
|
|
107
107
|
server.route(routes)
|
108
|
+
|
109
|
+
// Initialize the error count metric
|
110
|
+
Metrics.getCounter(
|
111
|
+
'errorCount',
|
112
|
+
'Error count',
|
113
|
+
['code', 'system', 'operation', 'step']
|
114
|
+
)
|
115
|
+
|
108
116
|
// TODO: follow instructions https://github.com/anttiviljami/openapi-backend/blob/master/DOCS.md#postresponsehandler-handler
|
109
117
|
await server.start()
|
110
118
|
|
@@ -129,6 +137,9 @@ const initializeApi = async (appConfig) => {
|
|
129
137
|
} = appConfig
|
130
138
|
|
131
139
|
if (!INSTRUMENTATION_METRICS_DISABLED) {
|
140
|
+
if (INSTRUMENTATION_METRICS_CONFIG.defaultLabels) {
|
141
|
+
INSTRUMENTATION_METRICS_CONFIG.defaultLabels.serviceVersion = version
|
142
|
+
}
|
132
143
|
initializeInstrumentation(INSTRUMENTATION_METRICS_CONFIG)
|
133
144
|
}
|
134
145
|
await connectDatabase(DATABASE)
|
package/test/fixtures/index.js
CHANGED
@@ -9,14 +9,15 @@ const headersDto = ({
|
|
9
9
|
destination = 'toDfsp',
|
10
10
|
proxy = '',
|
11
11
|
date = '2024-05-24 08:52:19',
|
12
|
-
accept
|
12
|
+
accept,
|
13
|
+
contentType
|
13
14
|
} = {}) => Object.freeze({
|
14
15
|
[Headers.FSPIOP.SOURCE]: source,
|
15
16
|
...(destination && { [Headers.FSPIOP.DESTINATION]: destination }),
|
16
17
|
...(proxy && { [Headers.FSPIOP.PROXY]: proxy }),
|
17
18
|
date,
|
18
19
|
accept,
|
19
|
-
'content-type': accept
|
20
|
+
'content-type': contentType || accept
|
20
21
|
})
|
21
22
|
|
22
23
|
const protocolVersionsDto = () => ({
|
@@ -40,22 +41,28 @@ const partiesCallHeadersDto = ({
|
|
40
41
|
destination,
|
41
42
|
proxy,
|
42
43
|
date,
|
43
|
-
accept: '
|
44
|
+
accept: interopHeader('parties', '1'),
|
45
|
+
contentType: interopHeader('parties', '1.1')
|
44
46
|
})
|
45
47
|
|
46
48
|
const participantsCallHeadersDto = ({
|
47
49
|
source,
|
48
50
|
destination,
|
49
51
|
proxy,
|
50
|
-
date
|
52
|
+
date,
|
53
|
+
acceptVersion = '1',
|
54
|
+
contentTypeVersion = '1.1'
|
51
55
|
} = {}) => headersDto({
|
52
56
|
source,
|
53
57
|
destination,
|
54
58
|
proxy,
|
55
59
|
date,
|
56
|
-
accept: '
|
60
|
+
accept: interopHeader('participants', acceptVersion),
|
61
|
+
contentType: interopHeader('participants', contentTypeVersion)
|
57
62
|
})
|
58
63
|
|
64
|
+
const interopHeader = (resource, version = '1') => `application/vnd.interoperability.${resource}+json;version=${version}`
|
65
|
+
|
59
66
|
const oracleRequestResponseDto = ({
|
60
67
|
partyList = [{ fspId: 'dfspFromOracle' }]
|
61
68
|
} = {}) => ({
|
@@ -83,6 +90,20 @@ const putPartiesSuccessResponseDto = ({
|
|
83
90
|
}
|
84
91
|
})
|
85
92
|
|
93
|
+
const postParticipantsPayloadDto = ({
|
94
|
+
requestId = randomUUID(), // '01JE8SG3F4WNHY8B9876THQ344',
|
95
|
+
partyList = [{
|
96
|
+
partyIdType: 'MSISDN',
|
97
|
+
partyIdentifier: '123456',
|
98
|
+
fspId: 'fspId123'
|
99
|
+
}],
|
100
|
+
currency = 'XXX'
|
101
|
+
} = {}) => Object.freeze({
|
102
|
+
requestId,
|
103
|
+
partyList,
|
104
|
+
...(currency && { currency })
|
105
|
+
})
|
106
|
+
|
86
107
|
const errorCallbackResponseDto = ({
|
87
108
|
errorCode = '1234',
|
88
109
|
errorDescription = 'Error description',
|
@@ -124,8 +145,10 @@ module.exports = {
|
|
124
145
|
participantsCallHeadersDto,
|
125
146
|
oracleRequestResponseDto,
|
126
147
|
putPartiesSuccessResponseDto,
|
148
|
+
postParticipantsPayloadDto,
|
127
149
|
errorCallbackResponseDto,
|
128
150
|
mockAlsRequestDto,
|
129
151
|
protocolVersionsDto,
|
130
|
-
mockHapiRequestDto
|
152
|
+
mockHapiRequestDto,
|
153
|
+
interopHeader
|
131
154
|
}
|
@@ -38,6 +38,7 @@ const Sinon = require('sinon')
|
|
38
38
|
const MigrationLockModel = require('../../../src/models/misc/migrationLock')
|
39
39
|
const Logger = require('@mojaloop/central-services-logger')
|
40
40
|
const Config = require('../../../src/lib/config')
|
41
|
+
const Metrics = require('@mojaloop/central-services-metrics')
|
41
42
|
|
42
43
|
Logger.isDebugEnabled = jest.fn(() => true)
|
43
44
|
Logger.isErrorEnabled = jest.fn(() => true)
|
@@ -51,6 +52,7 @@ describe('/health', () => {
|
|
51
52
|
sandbox = Sinon.createSandbox()
|
52
53
|
sandbox.stub(Db, 'connect').returns(Promise.resolve({}))
|
53
54
|
Config.API_PORT = await getPort()
|
55
|
+
Metrics.getDefaultRegister().clear()
|
54
56
|
server = await initServer(Config)
|
55
57
|
})
|
56
58
|
|
@@ -117,6 +119,7 @@ describe('/health', () => {
|
|
117
119
|
Config.proxyMap = { proxied: 'proxy' }
|
118
120
|
let serverWithProxy
|
119
121
|
try {
|
122
|
+
Metrics.getDefaultRegister().clear()
|
120
123
|
serverWithProxy = await initServer(Config)
|
121
124
|
sandbox.stub(MigrationLockModel, 'getIsMigrationLocked').resolves(false)
|
122
125
|
const mock = await Helper.generateMockRequest('/health', 'get')
|
@@ -35,16 +35,12 @@ const Helper = require('../../../util/helper')
|
|
35
35
|
const participants = require('../../../../src/domain/participants')
|
36
36
|
const initServer = require('../../../../src/server').initializeApi
|
37
37
|
const getPort = require('get-port')
|
38
|
-
const Logger = require('@mojaloop/central-services-logger')
|
39
38
|
const Config = require('../../../../src/lib/config')
|
40
39
|
|
41
|
-
Logger.isDebugEnabled = jest.fn(() => true)
|
42
|
-
Logger.isErrorEnabled = jest.fn(() => true)
|
43
|
-
Logger.isInfoEnabled = jest.fn(() => true)
|
44
|
-
let server
|
45
|
-
let sandbox
|
46
|
-
|
47
40
|
describe('/participants', () => {
|
41
|
+
let server
|
42
|
+
let sandbox
|
43
|
+
|
48
44
|
beforeAll(async () => {
|
49
45
|
sandbox = Sinon.createSandbox()
|
50
46
|
sandbox.stub(Db, 'connect').returns(Promise.resolve({}))
|
@@ -56,6 +52,7 @@ describe('/participants', () => {
|
|
56
52
|
await server.stop()
|
57
53
|
sandbox.restore()
|
58
54
|
})
|
55
|
+
|
59
56
|
const mock = {
|
60
57
|
requestId: '3ede3c17-36aa-42f4-b6db-b0df2e42f31e',
|
61
58
|
partyList: [{
|
@@ -79,6 +76,7 @@ describe('/participants', () => {
|
|
79
76
|
],
|
80
77
|
currency: 'EUR'
|
81
78
|
}
|
79
|
+
|
82
80
|
it('postParticipantsBatch success', async () => {
|
83
81
|
// Arrange
|
84
82
|
const options = {
|
@@ -35,7 +35,6 @@ const Db = require('../../../../../../src/lib/db')
|
|
35
35
|
const oracleEndpointCached = require('../../../../../../src/models/oracle/oracleEndpointCached')
|
36
36
|
const participant = require('../../../../../../src/models/participantEndpoint/facade')
|
37
37
|
const participants = require('../../../../../../src/domain/participants')
|
38
|
-
const requestLogger = require('../../../../../../src/lib/requestLogger')
|
39
38
|
const Helper = require('../../../../../util/helper')
|
40
39
|
const initServer = require('../../../../../../src/server').initializeApi
|
41
40
|
const Logger = require('@mojaloop/central-services-logger')
|
@@ -51,8 +50,6 @@ describe('/participants/{Type}/{ID}/{SubId}', () => {
|
|
51
50
|
beforeAll(async () => {
|
52
51
|
sandbox = Sinon.createSandbox()
|
53
52
|
sandbox.stub(Db, 'connect').returns(Promise.resolve({}))
|
54
|
-
sandbox.stub(requestLogger, 'logRequest').returns({})
|
55
|
-
sandbox.stub(requestLogger, 'logResponse').returns({})
|
56
53
|
Config.API_PORT = await getPort()
|
57
54
|
server = await initServer(Config)
|
58
55
|
})
|
@@ -40,7 +40,6 @@ const Db = require('../../../../../src/lib/db')
|
|
40
40
|
const oracleEndpointCached = require('../../../../../src/models/oracle/oracleEndpointCached')
|
41
41
|
const participant = require('../../../../../src/models/participantEndpoint/facade')
|
42
42
|
const participants = require('../../../../../src/domain/participants')
|
43
|
-
const requestLogger = require('../../../../../src/lib/requestLogger')
|
44
43
|
const Helper = require('../../../../util/helper')
|
45
44
|
const initServer = require('../../../../../src/server').initializeApi
|
46
45
|
const Config = require('../../../../../src/lib/config')
|
@@ -55,8 +54,6 @@ describe('/participants/{Type}/{ID}', () => {
|
|
55
54
|
beforeAll(async () => {
|
56
55
|
sandbox = Sinon.createSandbox()
|
57
56
|
sandbox.stub(Db, 'connect').returns(Promise.resolve({}))
|
58
|
-
sandbox.stub(requestLogger, 'logRequest').returns({})
|
59
|
-
sandbox.stub(requestLogger, 'logResponse').returns({})
|
60
57
|
Config.API_PORT = await getPort()
|
61
58
|
server = await initServer(Config)
|
62
59
|
sandbox.stub(Logger)
|
@@ -36,6 +36,7 @@ const initServer = require('../../../src/server').initializeApi
|
|
36
36
|
const Helper = require('../../util/helper')
|
37
37
|
const Db = require('../../../src/lib/db')
|
38
38
|
const Config = require('../../../src/lib/config')
|
39
|
+
const fixtures = require('../../fixtures')
|
39
40
|
|
40
41
|
Logger.isDebugEnabled = jest.fn(() => true)
|
41
42
|
Logger.isErrorEnabled = jest.fn(() => true)
|
@@ -44,14 +45,14 @@ let sandbox
|
|
44
45
|
let server
|
45
46
|
|
46
47
|
describe('/participants', () => {
|
47
|
-
|
48
|
+
beforeAll(async () => {
|
48
49
|
sandbox = Sinon.createSandbox()
|
49
50
|
sandbox.stub(Db, 'connect').returns(Promise.resolve({}))
|
50
51
|
Config.API_PORT = await getPort()
|
51
52
|
server = await initServer(Config)
|
52
53
|
})
|
53
54
|
|
54
|
-
|
55
|
+
afterAll(async () => {
|
55
56
|
await server.stop()
|
56
57
|
sandbox.restore()
|
57
58
|
})
|
@@ -103,6 +104,38 @@ describe('/participants', () => {
|
|
103
104
|
|
104
105
|
// Assert
|
105
106
|
expect(response.statusCode).toBe(400)
|
106
|
-
|
107
|
+
})
|
108
|
+
|
109
|
+
it('should validate requestId in UUID format', async () => {
|
110
|
+
const reqOptions = {
|
111
|
+
method: 'post',
|
112
|
+
url: '/participants',
|
113
|
+
headers: fixtures.participantsCallHeadersDto(),
|
114
|
+
payload: fixtures.postParticipantsPayloadDto()
|
115
|
+
}
|
116
|
+
const response = await server.inject(reqOptions)
|
117
|
+
expect(response.statusCode).toBe(200)
|
118
|
+
})
|
119
|
+
|
120
|
+
it('should validate requestId in ULID format', async () => {
|
121
|
+
const reqOptions = {
|
122
|
+
method: 'post',
|
123
|
+
url: '/participants',
|
124
|
+
headers: fixtures.participantsCallHeadersDto(),
|
125
|
+
payload: fixtures.postParticipantsPayloadDto({ requestId: '01JE8SG3F4WNHY8B9876THQ344' })
|
126
|
+
}
|
127
|
+
const response = await server.inject(reqOptions)
|
128
|
+
expect(response.statusCode).toBe(200)
|
129
|
+
})
|
130
|
+
|
131
|
+
it('should fail requestId validation', async () => {
|
132
|
+
const reqOptions = {
|
133
|
+
method: 'post',
|
134
|
+
url: '/participants',
|
135
|
+
headers: fixtures.participantsCallHeadersDto(),
|
136
|
+
payload: fixtures.postParticipantsPayloadDto({ requestId: 'wrong format' })
|
137
|
+
}
|
138
|
+
const response = await server.inject(reqOptions)
|
139
|
+
expect(response.statusCode).toBe(400)
|
107
140
|
})
|
108
141
|
})
|
@@ -37,6 +37,7 @@ const partyIdType = require('../../../../src/models/partyIdType')
|
|
37
37
|
const Db = require('../../../../src/lib/db')
|
38
38
|
const oracleEndpointCached = require('../../../../src/models/oracle/oracleEndpointCached')
|
39
39
|
const Logger = require('@mojaloop/central-services-logger')
|
40
|
+
const Metrics = require('@mojaloop/central-services-metrics')
|
40
41
|
|
41
42
|
Logger.isDebugEnabled = jest.fn(() => true)
|
42
43
|
Logger.isErrorEnabled = jest.fn(() => true)
|
@@ -90,6 +91,13 @@ let sandbox
|
|
90
91
|
let SpanStub
|
91
92
|
|
92
93
|
describe('Oracle tests', () => {
|
94
|
+
// Initialize Metrics for testing
|
95
|
+
Metrics.getCounter(
|
96
|
+
'errorCount',
|
97
|
+
'Error count',
|
98
|
+
['code', 'system', 'operation', 'step']
|
99
|
+
)
|
100
|
+
|
93
101
|
beforeEach(() => {
|
94
102
|
sandbox = Sinon.createSandbox()
|
95
103
|
Db.partyIdType = {
|