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.
Files changed (67) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/LICENSE.md +3 -4
  3. package/README.md +2 -0
  4. package/audit-ci.jsonc +2 -27
  5. package/config/default.json +1 -0
  6. package/docker/mock-proxy/README.md +21 -0
  7. package/docker/mock-proxy/src/config.ts +7 -0
  8. package/docs/Proxy/Discovery.md +20 -0
  9. package/docs/Proxy/FXAPI_POC_payer_conversion_RECEIVE.plantuml +577 -0
  10. package/docs/Proxy/FXAPI_POC_payer_conversion_SEND.plantuml +1423 -0
  11. package/docs/Proxy/P2P.md +11 -0
  12. package/docs/Proxy/Proxy pattern - Happy path.plantuml +98 -0
  13. package/docs/Proxy/Proxy pattern - Lazy Discovery - No Oracles.plantuml +105 -0
  14. package/docs/Proxy/Proxy pattern - Lazy Discovery - No Oracles.png +0 -0
  15. package/docs/Proxy/Proxy pattern - Lazy Discovery - Oracles.plantuml +130 -0
  16. package/docs/Proxy/Proxy pattern - Lazy Discovery - Oracles.png +0 -0
  17. package/docs/Proxy/Proxy pattern - Lazy Discovery Identifier Cache Invalid.plantuml +72 -0
  18. package/docs/Proxy/Proxy pattern - Lazy Discovery Identifier Cache Invalid.png +0 -0
  19. package/docs/Proxy/Proxy pattern - P2P.plantuml +186 -0
  20. package/docs/Proxy/Proxy pattern - P2P.png +0 -0
  21. package/docs/Proxy/Proxy pattern - Unhappy path.plantuml +103 -0
  22. package/docs/Proxy/Proxy pattern - Unhappy path.png +0 -0
  23. package/docs/Proxy/Proxy pattern - happy path.png +0 -0
  24. package/docs/Proxy/Readme.md +39 -0
  25. package/docs/Proxy/SettingUpProxys.plantuml +31 -0
  26. package/docs/Proxy/SettingUpProxys.png +0 -0
  27. package/package.json +33 -18
  28. package/src/constants.js +1 -1
  29. package/src/domain/oracle/oracle.js +63 -4
  30. package/src/domain/participants/participants.js +246 -129
  31. package/src/domain/parties/getPartiesByTypeAndID.js +29 -8
  32. package/src/domain/parties/parties.js +33 -4
  33. package/src/domain/timeout/index.js +12 -1
  34. package/src/handlers/monitoring/index.js +1 -1
  35. package/src/interface/api-swagger-iso20022-parties.yaml +7 -6
  36. package/src/interface/api-swagger.yaml +7 -6
  37. package/src/lib/config.js +2 -1
  38. package/src/lib/db.js +2 -1
  39. package/src/models/currency/currency.js +10 -1
  40. package/src/models/endpointType/endpointType.js +10 -1
  41. package/src/models/oracle/facade.js +42 -16
  42. package/src/models/oracle/oracleEndpoint.js +65 -10
  43. package/src/models/oracle/oracleEndpointCached.js +29 -9
  44. package/src/models/participantEndpoint/facade.js +40 -4
  45. package/src/models/partyIdType/partyIdType.js +10 -1
  46. package/src/plugins.js +8 -21
  47. package/src/server.js +11 -0
  48. package/test/fixtures/index.js +29 -6
  49. package/test/unit/api/health.test.js +3 -0
  50. package/test/unit/api/participants/participants.test.js +5 -7
  51. package/test/unit/api/participants/{Type}/{ID}/{SubId}.test.js +0 -3
  52. package/test/unit/api/participants/{Type}/{ID}.test.js +0 -3
  53. package/test/unit/api/participants.test.js +36 -3
  54. package/test/unit/domain/oracle/oracle.test.js +8 -0
  55. package/test/unit/domain/participants/participants.test.js +83 -48
  56. package/test/unit/domain/parties/parties.test.js +10 -2
  57. package/test/unit/domain/timeout/index.test.js +8 -0
  58. package/test/unit/lib/config.test.js +7 -0
  59. package/test/unit/mocks.js +16 -11
  60. package/test/unit/models/oracle/oracleEndpointCached.test.js +32 -0
  61. package/test/unit/models/participantEndpoint/facade.test.js +4 -2
  62. package/test/unit/plugins.test.js +2 -2
  63. package/src/lib/requestLogger.js +0 -54
  64. package/src/metrics/handler.js +0 -33
  65. package/src/metrics/plugin.js +0 -52
  66. package/src/metrics/routes.js +0 -43
  67. 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(err)
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(err)
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(err)
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(err)
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(err)
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(err)
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(err)
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(err)
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(err)
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(err)
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(err)
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(err)
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(err)
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
- throw ErrorHandler.Factory.reformatFSPIOPError(err)
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
- throw ErrorHandler.Factory.reformatFSPIOPError(err)
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
- throw ErrorHandler.Factory.reformatFSPIOPError(err)
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
- throw ErrorHandler.Factory.reformatFSPIOPError(err)
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
- throw ErrorHandler.Factory.reformatFSPIOPError(err)
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.ext([
143
- {
144
- type: 'onRequest',
145
- method: (request, h) => {
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)
@@ -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: 'application/vnd.interoperability.parties+json;version=1.1'
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: 'application/vnd.interoperability.participants+json;version=1'
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
- beforeEach(async () => {
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
- afterEach(async () => {
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
- await server.stop()
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 = {