account-lookup-service 17.8.0-snapshot.11 → 17.8.0-snapshot.13
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/package.json +4 -4
- package/src/domain/parties/services/BasePartiesService.js +26 -3
- package/src/domain/parties/services/PutPartiesErrorService.js +1 -24
- package/src/domain/parties/services/PutPartiesService.js +1 -21
- package/src/domain/parties/services/TimeoutPartiesService.js +1 -1
- package/test/unit/domain/parties/parties.test.js +5 -5
- package/test/unit/domain/parties/services/BasePartiesService.test.js +2 -1
- package/test/unit/domain/parties/services/GetPartiesService.test.js +29 -9
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "account-lookup-service",
|
3
3
|
"description": "Account Lookup Service is used to validate Party and Participant lookups.",
|
4
|
-
"version": "17.8.0-snapshot.
|
4
|
+
"version": "17.8.0-snapshot.13",
|
5
5
|
"license": "Apache-2.0",
|
6
6
|
"author": "ModusBox",
|
7
7
|
"contributors": [
|
@@ -92,14 +92,14 @@
|
|
92
92
|
"@hapi/vision": "7.0.3",
|
93
93
|
"@mojaloop/central-services-error-handling": "13.0.7",
|
94
94
|
"@mojaloop/central-services-health": "15.0.4",
|
95
|
-
"@mojaloop/central-services-logger": "11.8.
|
95
|
+
"@mojaloop/central-services-logger": "11.8.1",
|
96
96
|
"@mojaloop/central-services-metrics": "12.5.0",
|
97
|
-
"@mojaloop/central-services-shared": "18.23.
|
97
|
+
"@mojaloop/central-services-shared": "18.23.2",
|
98
98
|
"@mojaloop/central-services-stream": "11.5.2",
|
99
99
|
"@mojaloop/database-lib": "11.1.4",
|
100
100
|
"@mojaloop/event-sdk": "14.4.0",
|
101
101
|
"@mojaloop/inter-scheme-proxy-cache-lib": "2.4.0",
|
102
|
-
"@mojaloop/ml-schema-transformer-lib": "2.7.
|
102
|
+
"@mojaloop/ml-schema-transformer-lib": "2.7.1",
|
103
103
|
"@mojaloop/sdk-standard-components": "19.11.3-snapshot.0",
|
104
104
|
"@now-ims/hapi-now-auth": "2.1.0",
|
105
105
|
"ajv": "8.17.1",
|
@@ -30,6 +30,7 @@ const { Enum } = require('@mojaloop/central-services-shared')
|
|
30
30
|
const { decodePayload } = require('@mojaloop/central-services-shared').Util.StreamingProtocol
|
31
31
|
const { initStepState } = require('../../../lib/util')
|
32
32
|
const { createCallbackHeaders } = require('../../../lib/headers')
|
33
|
+
const { ERROR_MESSAGES } = require('../../../constants')
|
33
34
|
|
34
35
|
const { FspEndpointTypes, FspEndpointTemplates } = Enum.EndPoints
|
35
36
|
const { Headers, RestMethods } = Enum.Http
|
@@ -100,16 +101,17 @@ class BasePartiesService {
|
|
100
101
|
get state () { return this.#state }
|
101
102
|
|
102
103
|
async handleError (error) {
|
103
|
-
const {
|
104
|
+
const { params } = this.inputs
|
104
105
|
const log = this.log.child({ method: 'handleError' })
|
105
106
|
try {
|
106
107
|
log.error('error in processing parties request: ', error)
|
107
108
|
const fspiopError = ErrorHandler.Factory.reformatFSPIOPError(error)
|
108
|
-
const
|
109
|
+
const callbackHeaders = BasePartiesService.createErrorCallbackHeaders(this.inputs.headers, params)
|
110
|
+
const errorInfo = await this.deps.partiesUtils.makePutPartiesErrorPayload(this.deps.config, fspiopError, callbackHeaders, params)
|
109
111
|
|
110
112
|
await this.sendErrorCallback({
|
111
113
|
errorInfo,
|
112
|
-
headers:
|
114
|
+
headers: callbackHeaders,
|
113
115
|
params
|
114
116
|
})
|
115
117
|
log.info('handleError in done')
|
@@ -126,6 +128,27 @@ class BasePartiesService {
|
|
126
128
|
return this.deps.participant.validateParticipant(participantId)
|
127
129
|
}
|
128
130
|
|
131
|
+
async identifyDestinationForCallback () {
|
132
|
+
this.stepInProgress('identifyDestinationForCallback')
|
133
|
+
const { destination } = this.state
|
134
|
+
|
135
|
+
const schemeParticipant = await this.validateParticipant(destination)
|
136
|
+
if (schemeParticipant) {
|
137
|
+
this.state.requester = destination
|
138
|
+
return
|
139
|
+
}
|
140
|
+
|
141
|
+
const proxyName = this.state.proxyEnabled && await this.deps.proxyCache.lookupProxyByDfspId(destination)
|
142
|
+
if (proxyName) {
|
143
|
+
this.state.requester = proxyName
|
144
|
+
return
|
145
|
+
}
|
146
|
+
|
147
|
+
const errMessage = ERROR_MESSAGES.partyDestinationFspNotFound
|
148
|
+
this.log.warn(`${errMessage} and no proxy`, { destination })
|
149
|
+
throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_FSP_ERROR, errMessage)
|
150
|
+
}
|
151
|
+
|
129
152
|
async sendErrorCallback ({ errorInfo, headers, params }) {
|
130
153
|
this.stepInProgress('sendErrorCallback')
|
131
154
|
const sendTo = this.state.requester || this.state.source
|
@@ -25,8 +25,6 @@
|
|
25
25
|
--------------
|
26
26
|
******/
|
27
27
|
|
28
|
-
const ErrorHandler = require('@mojaloop/central-services-error-handling')
|
29
|
-
const { ERROR_MESSAGES } = require('../../../constants')
|
30
28
|
const BasePartiesService = require('./BasePartiesService')
|
31
29
|
|
32
30
|
class PutPartiesErrorService extends BasePartiesService {
|
@@ -51,7 +49,7 @@ class PutPartiesErrorService extends BasePartiesService {
|
|
51
49
|
}
|
52
50
|
}
|
53
51
|
|
54
|
-
await this.
|
52
|
+
await this.identifyDestinationForCallback()
|
55
53
|
await this.sendErrorCallbackToParticipant()
|
56
54
|
this.log.info('putPartiesByTypeAndID is done')
|
57
55
|
}
|
@@ -72,27 +70,6 @@ class PutPartiesErrorService extends BasePartiesService {
|
|
72
70
|
return isLast
|
73
71
|
}
|
74
72
|
|
75
|
-
async identifyDestinationForErrorCallback () {
|
76
|
-
this.stepInProgress('identifyDestinationForErrorCallback')
|
77
|
-
const { destination } = this.state
|
78
|
-
const schemeParticipant = await super.validateParticipant(destination)
|
79
|
-
if (schemeParticipant) {
|
80
|
-
this.state.requester = destination
|
81
|
-
return
|
82
|
-
}
|
83
|
-
|
84
|
-
this.stepInProgress('lookupProxyDestination-4')
|
85
|
-
const proxyName = this.state.proxyEnabled && await this.deps.proxyCache.lookupProxyByDfspId(destination)
|
86
|
-
if (proxyName) {
|
87
|
-
this.state.requester = proxyName
|
88
|
-
return
|
89
|
-
}
|
90
|
-
|
91
|
-
const errMessage = ERROR_MESSAGES.partyDestinationFspNotFound
|
92
|
-
this.log.warn(errMessage, { destination })
|
93
|
-
throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_FSP_ERROR, errMessage)
|
94
|
-
}
|
95
|
-
|
96
73
|
async sendErrorCallbackToParticipant () {
|
97
74
|
const { headers, params, dataUri } = this.inputs
|
98
75
|
const errorInfo = PutPartiesErrorService.decodeDataUriPayload(dataUri)
|
@@ -25,7 +25,6 @@
|
|
25
25
|
--------------
|
26
26
|
******/
|
27
27
|
|
28
|
-
const ErrorHandler = require('@mojaloop/central-services-error-handling')
|
29
28
|
const { ERROR_MESSAGES } = require('../../../constants')
|
30
29
|
const BasePartiesService = require('./BasePartiesService')
|
31
30
|
|
@@ -40,7 +39,7 @@ class PutPartiesService extends BasePartiesService {
|
|
40
39
|
if (proxy) {
|
41
40
|
await this.checkProxySuccessResponse()
|
42
41
|
}
|
43
|
-
await this.
|
42
|
+
await this.identifyDestinationForCallback()
|
44
43
|
await this.sendSuccessCallback()
|
45
44
|
}
|
46
45
|
|
@@ -85,25 +84,6 @@ class PutPartiesService extends BasePartiesService {
|
|
85
84
|
}
|
86
85
|
}
|
87
86
|
|
88
|
-
async identifyDestinationForSuccessCallback () {
|
89
|
-
const { destination } = this.state
|
90
|
-
this.stepInProgress('identifyDestinationForSuccessCallback')
|
91
|
-
const destinationParticipant = await super.validateParticipant(destination)
|
92
|
-
if (destinationParticipant) {
|
93
|
-
this.state.requester = destinationParticipant.name
|
94
|
-
return
|
95
|
-
}
|
96
|
-
|
97
|
-
const proxyName = this.state.proxyEnabled && await this.deps.proxyCache.lookupProxyByDfspId(destination)
|
98
|
-
if (!proxyName) {
|
99
|
-
const errMessage = ERROR_MESSAGES.partyDestinationFspNotFound
|
100
|
-
this.log.warn(`${errMessage} and no proxy`, { destination })
|
101
|
-
throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_FSP_ERROR, errMessage)
|
102
|
-
}
|
103
|
-
|
104
|
-
this.state.requester = proxyName
|
105
|
-
}
|
106
|
-
|
107
87
|
async sendSuccessCallback () {
|
108
88
|
const { headers, params, dataUri } = this.inputs
|
109
89
|
const sendTo = this.state.requester
|
@@ -52,7 +52,7 @@ class TimeoutPartiesService extends PutPartiesErrorService {
|
|
52
52
|
const { errorInfo, headers, params } = await this.prepareErrorInformation()
|
53
53
|
this.#spanAuditStart(errorInfo)
|
54
54
|
|
55
|
-
await this.
|
55
|
+
await this.identifyDestinationForCallback()
|
56
56
|
return super.sendErrorCallback({ errorInfo, headers, params })
|
57
57
|
}
|
58
58
|
|
@@ -587,20 +587,20 @@ describe('Parties Tests', () => {
|
|
587
587
|
it('successfully sends the callback to the participant', async () => {
|
588
588
|
expect.hasAssertions()
|
589
589
|
// Arrange
|
590
|
-
participant.validateParticipant = sandbox.stub().resolves({
|
591
|
-
name: 'fsp1'
|
592
|
-
})
|
590
|
+
participant.validateParticipant = sandbox.stub().resolves({})
|
593
591
|
participant.sendRequest = sandbox.stub().resolves()
|
594
592
|
const payload = JSON.stringify({ testPayload: true })
|
595
593
|
const dataUri = encodePayload(payload, 'application/json')
|
594
|
+
const destination = 'destFsp'
|
595
|
+
const headers = fixtures.partiesCallHeadersDto({ destination })
|
596
596
|
|
597
597
|
// Act
|
598
|
-
await partiesDomain.putPartiesByTypeAndID(
|
598
|
+
await partiesDomain.putPartiesByTypeAndID(headers, Helper.putByTypeIdRequest.params, 'put', payload, dataUri, null, proxyCache)
|
599
599
|
|
600
600
|
// Assert
|
601
601
|
expect(participant.sendRequest.callCount).toBe(1)
|
602
602
|
const sendRequestCallArgs = participant.sendRequest.getCall(0).args
|
603
|
-
expect(sendRequestCallArgs[1]).
|
603
|
+
expect(sendRequestCallArgs[1]).toBe(destination)
|
604
604
|
participant.sendRequest.reset()
|
605
605
|
})
|
606
606
|
|
@@ -54,7 +54,8 @@ describe('BasePartiesService Tests -->', () => {
|
|
54
54
|
expect(sentTo).toBe(source)
|
55
55
|
expect(payload.Rpt.Rsn.Cd).toBe('2001')
|
56
56
|
expect(payload.Rpt.OrgnlId).toBe(`${params.Type}/${params.ID}`)
|
57
|
-
expect(payload.Assgnmt.
|
57
|
+
expect(payload.Assgnmt.Assgne.Agt.FinInstnId.Othr.Id).toBe(source)
|
58
|
+
expect(payload.Assgnmt.Assgnr.Agt.FinInstnId.Othr.Id).toBe(config.HUB_NAME)
|
58
59
|
})
|
59
60
|
|
60
61
|
test('should remove proxy getParties timeout cache key', async () => {
|
@@ -199,15 +199,18 @@ describe('GetPartiesService Tests -->', () => {
|
|
199
199
|
expect(participantMock.sendRequest.mock.lastCall[1]).toBe(proxyOk)
|
200
200
|
})
|
201
201
|
|
202
|
-
|
203
|
-
expect.assertions(1)
|
202
|
+
const throwDelayedErrorOnNthCall = (N, delay = 1000, error = new Error('Nth call Delayed Error')) => {
|
204
203
|
let count = 0
|
205
|
-
|
204
|
+
return async () => {
|
206
205
|
count++
|
207
|
-
if (count !==
|
208
|
-
await sleep(1000)
|
209
|
-
throw
|
210
|
-
}
|
206
|
+
if (count !== N) return {}
|
207
|
+
await sleep(1000)
|
208
|
+
throw error
|
209
|
+
}
|
210
|
+
}
|
211
|
+
|
212
|
+
const prepareGetPartiesServiceForDelayedProxyError = () => {
|
213
|
+
participantMock.sendRequest = jest.fn(throwDelayedErrorOnNthCall(2)) // throw error on 2nd proxy call
|
211
214
|
const proxies = createProxiesUtilMock({
|
212
215
|
getAllProxiesNames: jest.fn().mockResolvedValue(['proxy1', 'proxy2'])
|
213
216
|
})
|
@@ -215,14 +218,31 @@ describe('GetPartiesService Tests -->', () => {
|
|
215
218
|
receivedErrorResponse: jest.fn().mockResolvedValue(true) // failed proxy request is last in inter-scheme discovery flow
|
216
219
|
})
|
217
220
|
const deps = createMockDeps({ proxies, proxyCache })
|
218
|
-
|
219
221
|
const headers = fixtures.partiesCallHeadersDto({ destination: '' })
|
220
222
|
const params = fixtures.partiesParamsDto()
|
221
|
-
|
223
|
+
|
224
|
+
return new GetPartiesService(deps, { headers, params })
|
225
|
+
}
|
226
|
+
|
227
|
+
test('should throw an error if proxyRequest failed after delay, and other proxies have already replied', async () => {
|
228
|
+
expect.assertions(1)
|
229
|
+
const service = prepareGetPartiesServiceForDelayedProxyError()
|
230
|
+
const { headers } = service.inputs
|
222
231
|
|
223
232
|
await expect(service.triggerInterSchemeDiscoveryFlow(headers))
|
224
233
|
.rejects.toThrow(ERROR_MESSAGES.noSuccessfulProxyDiscoveryResponses)
|
225
234
|
})
|
235
|
+
|
236
|
+
test('should send error callback in ISO format if proxyRequest failed after delay, and other proxies have already replied', async () => {
|
237
|
+
const service = prepareGetPartiesServiceForDelayedProxyError()
|
238
|
+
const { headers } = service.inputs
|
239
|
+
service.deps.config.API_TYPE = API_TYPES.iso20022
|
240
|
+
|
241
|
+
await service.triggerInterSchemeDiscoveryFlow(headers)
|
242
|
+
.catch(err => service.handleError(err))
|
243
|
+
expect(participantMock.sendErrorToParticipant).toHaveBeenCalledTimes(1)
|
244
|
+
expect(participantMock.sendErrorToParticipant.mock.lastCall[2].Rpt.Rsn.Cd).toBe('3200')
|
245
|
+
})
|
226
246
|
})
|
227
247
|
|
228
248
|
describe('setProxyGetPartiesTimeout Tests', () => {
|