account-lookup-service 17.8.0-snapshot.7 → 17.8.0-snapshot.8
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
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.8",
|
5
5
|
"license": "Apache-2.0",
|
6
6
|
"author": "ModusBox",
|
7
7
|
"contributors": [
|
@@ -46,12 +46,10 @@ class GetPartiesService extends BasePartiesService {
|
|
46
46
|
}
|
47
47
|
|
48
48
|
const response = await this.sendOracleDiscoveryRequest()
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
}
|
49
|
+
const isSent = await this.processOraclePartyListResponse(response)
|
50
|
+
this.log.info(`getParties request is ${isSent ? '' : 'NOT '}forwarded to oracle lookup DFSP`)
|
51
|
+
if (isSent) return
|
53
52
|
|
54
|
-
this.log.info('no forwarded requests for oracle partyList')
|
55
53
|
const fspiopError = await this.triggerInterSchemeDiscoveryFlow(this.inputs.headers)
|
56
54
|
if (fspiopError) {
|
57
55
|
this.state.fspiopError = fspiopError // todo: think, if we need this
|
@@ -118,6 +116,11 @@ class GetPartiesService extends BasePartiesService {
|
|
118
116
|
}
|
119
117
|
|
120
118
|
async processOraclePartyListResponse (response) {
|
119
|
+
if (!Array.isArray(response?.data?.partyList) || response.data.partyList.length === 0) {
|
120
|
+
this.log.verbose('oracle partyList is empty')
|
121
|
+
return false
|
122
|
+
}
|
123
|
+
|
121
124
|
this.stepInProgress('processOraclePartyList')
|
122
125
|
const partyList = this.#filterOraclePartyList(response)
|
123
126
|
|
@@ -127,48 +130,31 @@ class GetPartiesService extends BasePartiesService {
|
|
127
130
|
if (isSent) sentCount++
|
128
131
|
}))
|
129
132
|
|
130
|
-
const
|
131
|
-
this.log.verbose('processOraclePartyList is done', {
|
132
|
-
// if NOT
|
133
|
-
return
|
133
|
+
const isSent = sentCount > 0
|
134
|
+
this.log.verbose('processOraclePartyList is done', { isSent, sentCount })
|
135
|
+
// if NOT isSent, need to trigger interScheme discovery flow
|
136
|
+
return isSent
|
134
137
|
}
|
135
138
|
|
136
139
|
async triggerInterSchemeDiscoveryFlow (headers) {
|
137
140
|
const { params } = this.inputs
|
138
141
|
const { proxy, source } = this.state
|
139
|
-
const log = this.log.child({
|
140
|
-
log.verbose('triggerInterSchemeDiscoveryFlow start...', { proxy
|
142
|
+
const log = this.log.child({ source })
|
143
|
+
log.verbose('triggerInterSchemeDiscoveryFlow start...', { proxy })
|
141
144
|
|
142
145
|
const proxyNames = await this.#getFilteredProxyList(proxy)
|
143
146
|
if (!proxyNames.length) {
|
144
147
|
return this.#sendPartyNotFoundErrorCallback(headers)
|
145
148
|
}
|
146
149
|
|
147
|
-
this
|
148
|
-
const
|
149
|
-
|
150
|
-
|
151
|
-
const isCached = await this.deps.proxyCache.setSendToProxiesList(alsReq, proxyNames, proxyCacheTtlSec)
|
152
|
-
if (!isCached) {
|
153
|
-
throw super.createFspiopIdNotFoundError(ERROR_MESSAGES.failedToCacheSendToProxiesList, log)
|
154
|
-
}
|
155
|
-
|
156
|
-
this.stepInProgress('sendingProxyRequests')
|
157
|
-
const sending = proxyNames.map(
|
158
|
-
sendTo => this.#forwardGetPartiesRequest({ sendTo, headers, params })
|
159
|
-
.then(({ status, data } = {}) => ({ status, data }))
|
160
|
-
)
|
161
|
-
const results = await Promise.allSettled(sending)
|
162
|
-
const isOk = results.some(result => result.status === 'fulfilled')
|
163
|
-
// If, at least, one request is sent to proxy, we treat the whole flow as successful.
|
164
|
-
// Failed requests should be handled by TTL expired/timeout handler
|
165
|
-
// todo: If forwarding request to proxy failed, remove the proxy from setSendToProxiesList
|
166
|
-
log.info('triggerInterSchemeDiscoveryFlow is done:', { isOk, results, proxyNames, alsReq })
|
167
|
-
this.stepInProgress('allSent-12')
|
168
|
-
|
169
|
-
if (!isOk) {
|
150
|
+
const alsReq = await this.#setProxyListToCache(proxyNames, source, params)
|
151
|
+
const sentList = await this.#sendOutProxyRequests({ proxyNames, alsReq, headers, params })
|
152
|
+
if (sentList.length === 0) {
|
170
153
|
throw super.createFspiopIdNotFoundError(ERROR_MESSAGES.proxyConnectionError, log)
|
171
154
|
}
|
155
|
+
|
156
|
+
log.info('triggerInterSchemeDiscoveryFlow is done:', { sentList, alsReq })
|
157
|
+
return sentList
|
172
158
|
}
|
173
159
|
|
174
160
|
isLocalSource () {
|
@@ -269,9 +255,29 @@ class GetPartiesService extends BasePartiesService {
|
|
269
255
|
headers, sendTo, callbackEndpointType, RestMethods.GET, undefined, options, this.deps.childSpan
|
270
256
|
)
|
271
257
|
await this.#setProxyGetPartiesTimeout(sendTo)
|
258
|
+
this.log.debug('#forwardGetPartiesRequest is done:', { sendTo, sentResult })
|
272
259
|
return sentResult
|
273
260
|
}
|
274
261
|
|
262
|
+
async #sendOutProxyRequests ({ proxyNames, alsReq, headers, params }) {
|
263
|
+
this.stepInProgress('#sendOutProxyRequests')
|
264
|
+
const sentList = []
|
265
|
+
|
266
|
+
const sendProxyRequest = (sendTo) => this.#forwardGetPartiesRequest({ sendTo, headers, params })
|
267
|
+
.then(() => { sentList.push(sendTo) })
|
268
|
+
.catch(err => {
|
269
|
+
this.log.error(`error in sending request to proxy ${sendTo}: `, err)
|
270
|
+
return this.deps.proxyCache.receivedErrorResponse(alsReq, sendTo)
|
271
|
+
})
|
272
|
+
.catch(err => {
|
273
|
+
this.log.error(`failed to remove proxy ${sendTo} from proxyCache: `, err)
|
274
|
+
})
|
275
|
+
await Promise.all(proxyNames.map(sendProxyRequest))
|
276
|
+
|
277
|
+
this.log.verbose('#sendOutProxyRequests is done:', { sentList, proxyNames })
|
278
|
+
return sentList
|
279
|
+
}
|
280
|
+
|
275
281
|
async #getFilteredProxyList (proxy) {
|
276
282
|
this.stepInProgress('#getFilteredProxyList')
|
277
283
|
if (!this.state.proxyEnabled) {
|
@@ -284,6 +290,18 @@ class GetPartiesService extends BasePartiesService {
|
|
284
290
|
return proxyNames.filter(name => name !== proxy)
|
285
291
|
}
|
286
292
|
|
293
|
+
async #setProxyListToCache (proxyNames, source, params) {
|
294
|
+
this.stepInProgress('#setProxyListToCache')
|
295
|
+
const alsReq = this.deps.partiesUtils.alsRequestDto(source, params)
|
296
|
+
|
297
|
+
const isCached = await this.deps.proxyCache.setSendToProxiesList(alsReq, proxyNames, proxyCacheTtlSec)
|
298
|
+
if (!isCached) {
|
299
|
+
throw super.createFspiopIdNotFoundError(ERROR_MESSAGES.failedToCacheSendToProxiesList)
|
300
|
+
}
|
301
|
+
this.log.verbose('#setProxyListToCache is done: ', { alsReq, proxyNames, proxyCacheTtlSec })
|
302
|
+
return alsReq
|
303
|
+
}
|
304
|
+
|
287
305
|
async #setProxyGetPartiesTimeout (sendTo) {
|
288
306
|
const isLocalSource = this.isLocalSource()
|
289
307
|
const isSentToProxy = this.state.destination !== sendTo
|
@@ -300,12 +318,3 @@ class GetPartiesService extends BasePartiesService {
|
|
300
318
|
}
|
301
319
|
|
302
320
|
module.exports = GetPartiesService
|
303
|
-
|
304
|
-
// As Payee DFSP Scheme Oracle identifies direct participant.
|
305
|
-
// As Payer DFSP Scheme oracle identifies interscheme participant.
|
306
|
-
|
307
|
-
// zm-dfsp --> ZM
|
308
|
-
// region-dfsp --> Region
|
309
|
-
// mw-dfsp --> MW (mw-party-123)
|
310
|
-
|
311
|
-
// 1. region-dfsp gets info about mw-party-123
|
@@ -68,7 +68,7 @@ class PutPartiesErrorService extends BasePartiesService {
|
|
68
68
|
this.stepInProgress('checkLastProxyCallback')
|
69
69
|
const { proxy } = this.state
|
70
70
|
const isLast = await this.deps.proxyCache.receivedErrorResponse(alsReq, proxy)
|
71
|
-
this.log.info(`got${isLast ? '' : 'NOT'}
|
71
|
+
this.log.info(`got ${isLast ? '' : 'NOT '}last inter-scheme error callback from a proxy`, { proxy, alsReq, isLast })
|
72
72
|
return isLast
|
73
73
|
}
|
74
74
|
|
@@ -25,10 +25,16 @@
|
|
25
25
|
--------------
|
26
26
|
******/
|
27
27
|
|
28
|
-
const {
|
28
|
+
const {
|
29
|
+
createMockDeps,
|
30
|
+
createProxyCacheMock,
|
31
|
+
createProxiesUtilMock,
|
32
|
+
oracleMock,
|
33
|
+
participantMock
|
34
|
+
} = require('./deps')
|
29
35
|
// ↑ should be first require to mock external deps ↑
|
30
36
|
const { GetPartiesService } = require('#src/domain/parties/services/index')
|
31
|
-
const { API_TYPES } = require('#src/constants')
|
37
|
+
const { API_TYPES, ERROR_MESSAGES } = require('#src/constants')
|
32
38
|
const fixtures = require('#test/fixtures/index')
|
33
39
|
|
34
40
|
const { RestMethods, Headers } = GetPartiesService.enums()
|
@@ -154,6 +160,45 @@ describe('GetPartiesService Tests -->', () => {
|
|
154
160
|
})
|
155
161
|
})
|
156
162
|
|
163
|
+
describe('triggerInterSchemeDiscoveryFlow Tests', () => {
|
164
|
+
test('should remove proxy from proxyCache if sending request to it fails', async () => {
|
165
|
+
expect.assertions(2)
|
166
|
+
participantMock.sendRequest = jest.fn().mockRejectedValue(new Error('Proxy error'))
|
167
|
+
const proxies = createProxiesUtilMock({
|
168
|
+
getAllProxiesNames: jest.fn().mockResolvedValue(['proxy-1'])
|
169
|
+
})
|
170
|
+
const deps = createMockDeps({ proxies })
|
171
|
+
|
172
|
+
const headers = fixtures.partiesCallHeadersDto({ destination: '' })
|
173
|
+
const params = fixtures.partiesParamsDto()
|
174
|
+
const service = new GetPartiesService(deps, { headers, params })
|
175
|
+
|
176
|
+
await expect(service.triggerInterSchemeDiscoveryFlow(headers))
|
177
|
+
.rejects.toThrow(ERROR_MESSAGES.proxyConnectionError)
|
178
|
+
expect(deps.proxyCache.receivedErrorResponse).toHaveBeenCalledTimes(1)
|
179
|
+
})
|
180
|
+
|
181
|
+
test('should NOT throw an error if at least one request is sent to a proxy', async () => {
|
182
|
+
participantMock.sendRequest = jest.fn()
|
183
|
+
.mockRejectedValueOnce(new Error('Proxy error'))
|
184
|
+
.mockResolvedValueOnce({})
|
185
|
+
const proxyOk = 'proxyOk'
|
186
|
+
const proxies = createProxiesUtilMock({
|
187
|
+
getAllProxiesNames: jest.fn().mockResolvedValue(['proxyErr', proxyOk])
|
188
|
+
})
|
189
|
+
const deps = createMockDeps({ proxies })
|
190
|
+
|
191
|
+
const headers = fixtures.partiesCallHeadersDto({ destination: '' })
|
192
|
+
const params = fixtures.partiesParamsDto()
|
193
|
+
const service = new GetPartiesService(deps, { headers, params })
|
194
|
+
|
195
|
+
const sentList = await service.triggerInterSchemeDiscoveryFlow(headers)
|
196
|
+
expect(sentList).toEqual([proxyOk])
|
197
|
+
expect(deps.proxyCache.receivedErrorResponse).toHaveBeenCalledTimes(1)
|
198
|
+
expect(participantMock.sendRequest.mock.lastCall[1]).toBe(proxyOk)
|
199
|
+
})
|
200
|
+
})
|
201
|
+
|
157
202
|
describe('setProxyGetPartiesTimeout Tests', () => {
|
158
203
|
test('should set getParties timeout for local source and external destination', async () => {
|
159
204
|
participantMock.validateParticipant = jest.fn()
|