account-lookup-service 17.7.1 → 17.8.0-snapshot.7
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 +0 -7
- package/package.json +8 -5
- package/src/constants.js +34 -2
- package/src/domain/parties/deps.js +11 -4
- package/src/domain/parties/getPartiesByTypeAndID.js +9 -13
- package/src/domain/parties/partiesUtils.js +4 -34
- package/src/domain/parties/putParties.js +26 -71
- package/src/domain/parties/services/BasePartiesService.js +143 -15
- package/src/domain/parties/services/GetPartiesService.js +194 -164
- package/src/domain/parties/services/PutPartiesErrorService.js +51 -27
- package/src/domain/parties/services/PutPartiesService.js +51 -33
- package/src/domain/parties/services/TimeoutPartiesService.js +84 -0
- package/src/domain/parties/services/index.js +3 -1
- package/src/domain/timeout/createSpan.js +55 -0
- package/src/domain/timeout/index.js +27 -36
- package/src/handlers/TimeoutHandler.js +2 -2
- package/src/lib/util.js +11 -3
- package/test/fixtures/index.js +46 -0
- package/test/integration/domain/timeout/index.test.js +83 -28
- package/test/unit/domain/parties/parties.test.js +26 -18
- package/test/unit/domain/parties/partiesUtils.test.js +51 -0
- package/test/unit/domain/parties/services/BasePartiesService.test.js +71 -0
- package/test/unit/domain/parties/services/GetPartiesService.test.js +245 -0
- package/test/unit/domain/parties/services/PutPartiesErrorService.test.js +50 -0
- package/test/unit/domain/parties/services/TimeoutPartiesService.test.js +72 -0
- package/test/unit/domain/parties/services/deps.js +51 -0
- package/test/unit/domain/timeout/index.test.js +17 -12
- package/test/util/apiClients/BasicApiClient.js +33 -6
- package/test/util/apiClients/ProxyApiClient.js +46 -1
- package/test/util/index.js +5 -6
- package/test/util/mockDeps.js +72 -0
- package/src/domain/timeout/dto.js +0 -54
- package/test/unit/domain/parties/utils.test.js +0 -60
- package/test/unit/domain/timeout/dto.test.js +0 -24
@@ -25,207 +25,135 @@
|
|
25
25
|
--------------
|
26
26
|
******/
|
27
27
|
|
28
|
-
const ErrorHandler = require('@mojaloop/central-services-error-handling')
|
29
28
|
const { ERROR_MESSAGES } = require('../../../constants')
|
30
|
-
const { createCallbackHeaders } = require('../../../lib/headers')
|
31
29
|
const BasePartiesService = require('./BasePartiesService')
|
32
30
|
|
33
|
-
const {
|
34
|
-
FspEndpointTypes, FspEndpointTemplates,
|
35
|
-
Headers, RestMethods
|
36
|
-
} = BasePartiesService.enums()
|
37
|
-
|
31
|
+
const { FspEndpointTypes, RestMethods } = BasePartiesService.enums()
|
38
32
|
const proxyCacheTtlSec = 40 // todo: make configurable
|
39
33
|
|
40
34
|
class GetPartiesService extends BasePartiesService {
|
41
|
-
async handleRequest (
|
42
|
-
const source =
|
43
|
-
const proxy = headers[Headers.FSPIOP.PROXY]
|
44
|
-
const destination = headers[Headers.FSPIOP.DESTINATION]
|
35
|
+
async handleRequest () {
|
36
|
+
const { destination, source, proxy } = this.state
|
45
37
|
// see https://github.com/mojaloop/design-authority/issues/79
|
46
38
|
// the requester has specified a destination routing header. We should respect that and forward the request directly to the destination
|
47
39
|
// without consulting any oracles.
|
48
|
-
this.log.info('handling getParties request', { source, destination, proxy })
|
49
|
-
|
50
|
-
const requester = await this.validateRequester({ source, proxy })
|
51
|
-
results.requester = requester
|
40
|
+
this.log.info('handling getParties request...', { source, destination, proxy })
|
41
|
+
this.state.requester = await this.validateRequester()
|
52
42
|
|
53
43
|
if (destination) {
|
54
|
-
await this.forwardRequestToDestination(
|
44
|
+
await this.forwardRequestToDestination()
|
55
45
|
return
|
56
46
|
}
|
57
|
-
const response = await this.sendOracleDiscoveryRequest({ headers, params, query })
|
58
47
|
|
48
|
+
const response = await this.sendOracleDiscoveryRequest()
|
59
49
|
if (Array.isArray(response?.data?.partyList) && response.data.partyList.length > 0) {
|
60
|
-
const
|
61
|
-
|
62
|
-
return
|
50
|
+
const isDone = await this.processOraclePartyListResponse(response)
|
51
|
+
if (isDone) return
|
63
52
|
}
|
64
53
|
|
65
|
-
this.log.info('
|
66
|
-
const
|
67
|
-
|
68
|
-
|
69
|
-
await this.triggerSendToProxiesFlow({ proxyNames, headers, params, source })
|
70
|
-
return
|
54
|
+
this.log.info('no forwarded requests for oracle partyList')
|
55
|
+
const fspiopError = await this.triggerInterSchemeDiscoveryFlow(this.inputs.headers)
|
56
|
+
if (fspiopError) {
|
57
|
+
this.state.fspiopError = fspiopError // todo: think, if we need this
|
71
58
|
}
|
72
|
-
|
73
|
-
results.fspiopError = await this.sendPartyNotFoundErrorCallback({ requester, headers, params })
|
74
59
|
}
|
75
60
|
|
76
|
-
async validateRequester (
|
77
|
-
this.
|
61
|
+
async validateRequester () {
|
62
|
+
const { source, proxy, proxyEnabled } = this.state
|
78
63
|
const log = this.log.child({ source, proxy, method: 'validateRequester' })
|
64
|
+
this.stepInProgress('validateRequester-0')
|
79
65
|
|
80
|
-
const
|
81
|
-
if (
|
82
|
-
log.debug('source is in scheme')
|
66
|
+
const schemeSource = await this.validateParticipant(source)
|
67
|
+
if (schemeSource) {
|
68
|
+
log.debug('source participant is in scheme')
|
83
69
|
return source
|
84
70
|
}
|
85
71
|
|
86
|
-
if (!
|
87
|
-
|
88
|
-
log.warn(errMessage)
|
89
|
-
throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ID_NOT_FOUND, errMessage)
|
72
|
+
if (!proxyEnabled || !proxy) {
|
73
|
+
throw super.createFspiopIdNotFoundError(ERROR_MESSAGES.sourceFspNotFound, log)
|
90
74
|
}
|
91
75
|
|
92
|
-
const
|
93
|
-
if (!
|
94
|
-
|
95
|
-
log.warn(errMessage)
|
96
|
-
throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ID_NOT_FOUND, errMessage)
|
76
|
+
const schemeProxy = await this.validateParticipant(proxy)
|
77
|
+
if (!schemeProxy) {
|
78
|
+
throw super.createFspiopIdNotFoundError(ERROR_MESSAGES.partyProxyNotFound, log)
|
97
79
|
}
|
98
80
|
|
99
81
|
const isCached = await this.deps.proxyCache.addDfspIdToProxyMapping(source, proxy)
|
100
82
|
if (!isCached) {
|
101
|
-
|
102
|
-
log.warn(errMessage)
|
103
|
-
throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ID_NOT_FOUND, errMessage)
|
83
|
+
throw super.createFspiopIdNotFoundError('failed to addDfspIdToProxyMapping', log)
|
104
84
|
}
|
105
85
|
|
106
|
-
log.info('source is added to proxyMapping cache
|
86
|
+
log.info('source is added to proxyMapping cache')
|
107
87
|
return proxy
|
108
88
|
}
|
109
89
|
|
110
|
-
async forwardRequestToDestination (
|
111
|
-
this.
|
90
|
+
async forwardRequestToDestination () {
|
91
|
+
const { headers, params } = this.inputs
|
92
|
+
const { destination } = this.state
|
112
93
|
const log = this.log.child({ method: 'forwardRequestToDestination' })
|
113
94
|
let sendTo = destination
|
114
95
|
|
115
|
-
const
|
116
|
-
if (!
|
117
|
-
this.
|
118
|
-
const proxyId = this.proxyEnabled && await this.deps.proxyCache.lookupProxyByDfspId(destination)
|
96
|
+
const schemeParticipant = await this.validateParticipant(destination)
|
97
|
+
if (!schemeParticipant) {
|
98
|
+
this.stepInProgress('lookupProxyDestination-2')
|
99
|
+
const proxyId = this.state.proxyEnabled && await this.deps.proxyCache.lookupProxyByDfspId(destination)
|
119
100
|
|
120
101
|
if (!proxyId) {
|
121
|
-
log.warn('
|
122
|
-
|
123
|
-
|
102
|
+
log.warn('destination participant is not in scheme, and no dfsp-to-proxy mapping', { destination })
|
103
|
+
await super.sendDeleteOracleRequest(headers, params)
|
104
|
+
await this.triggerInterSchemeDiscoveryFlow(GetPartiesService.headersWithoutDestination(headers))
|
105
|
+
return
|
124
106
|
}
|
125
107
|
sendTo = proxyId
|
126
108
|
}
|
127
|
-
|
109
|
+
|
128
110
|
await this.#forwardGetPartiesRequest({ sendTo, headers, params })
|
129
111
|
log.info('discovery getPartiesByTypeAndID request was sent', { sendTo })
|
130
112
|
}
|
131
113
|
|
132
|
-
|
133
|
-
|
134
|
-
this.
|
135
|
-
|
136
|
-
let filteredResponsePartyList
|
137
|
-
|
138
|
-
switch (callbackEndpointType) {
|
139
|
-
case FspEndpointTypes.FSPIOP_CALLBACK_URL_PARTIES_GET:
|
140
|
-
filteredResponsePartyList = response.data.partyList.filter(party => party.partySubIdOrType == null) // Filter records that DON'T contain a partySubIdOrType
|
141
|
-
break
|
142
|
-
case FspEndpointTypes.FSPIOP_CALLBACK_URL_PARTIES_SUB_ID_GET:
|
143
|
-
filteredResponsePartyList = response.data.partyList.filter(party => party.partySubIdOrType === params.SubId) // Filter records that match partySubIdOrType
|
144
|
-
break
|
145
|
-
default:
|
146
|
-
filteredResponsePartyList = response // Fallback to providing the standard list
|
147
|
-
}
|
148
|
-
|
149
|
-
if (!Array.isArray(filteredResponsePartyList) || !filteredResponsePartyList.length) {
|
150
|
-
const errMessage = 'Requested FSP/Party not found'
|
151
|
-
this.log.warn(errMessage)
|
152
|
-
throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ID_NOT_FOUND, errMessage)
|
153
|
-
}
|
154
|
-
|
155
|
-
return filteredResponsePartyList
|
114
|
+
async sendOracleDiscoveryRequest () {
|
115
|
+
this.stepInProgress('#sendOracleDiscoveryRequest')
|
116
|
+
const { headers, params, query } = this.inputs
|
117
|
+
return this.deps.oracle.oracleRequest(headers, RestMethods.GET, params, query, undefined, this.deps.cache)
|
156
118
|
}
|
157
119
|
|
158
|
-
async
|
159
|
-
|
120
|
+
async processOraclePartyListResponse (response) {
|
121
|
+
this.stepInProgress('processOraclePartyList')
|
122
|
+
const partyList = this.#filterOraclePartyList(response)
|
160
123
|
|
161
|
-
let sentCount = 0
|
162
|
-
|
163
|
-
const
|
164
|
-
|
165
|
-
|
166
|
-
clonedHeaders[Headers.FSPIOP.DESTINATION] = fspId
|
167
|
-
}
|
168
|
-
this.deps.stepState.inProgress('validateParticipant-6')
|
169
|
-
const schemeParticipant = await this.validateParticipant(fspId)
|
170
|
-
if (schemeParticipant) {
|
171
|
-
sentCount++
|
172
|
-
log.info('participant is in scheme', { fspId })
|
173
|
-
return this.#forwardGetPartiesRequest({
|
174
|
-
sendTo: fspId,
|
175
|
-
headers: clonedHeaders,
|
176
|
-
params
|
177
|
-
})
|
178
|
-
}
|
124
|
+
let sentCount = 0
|
125
|
+
await Promise.all(partyList.map(async party => {
|
126
|
+
const isSent = await this.#processSingleOracleParty(party)
|
127
|
+
if (isSent) sentCount++
|
128
|
+
}))
|
179
129
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
const proxyName = await this.deps.proxyCache.lookupProxyByDfspId(fspId)
|
185
|
-
if (!proxyName) {
|
186
|
-
log.warn('no proxyMapping for participant! TODO: Delete reference in oracle...', { fspId })
|
187
|
-
// todo: delete reference in oracle
|
188
|
-
} else {
|
189
|
-
sentCount++
|
190
|
-
log.info('participant is NOT in scheme, use proxy name', { fspId, proxyName })
|
191
|
-
return this.#forwardGetPartiesRequest({
|
192
|
-
sendTo: proxyName,
|
193
|
-
headers: clonedHeaders,
|
194
|
-
params
|
195
|
-
})
|
196
|
-
}
|
197
|
-
}
|
198
|
-
})
|
199
|
-
await Promise.all(sending)
|
200
|
-
log.verbose('processOraclePartyList is done', { sentCount })
|
201
|
-
// todo: think what if sentCount === 0 here
|
130
|
+
const isDone = sentCount > 0
|
131
|
+
this.log.verbose('processOraclePartyList is done', { isDone, sentCount })
|
132
|
+
// if NOT isDone, need to trigger interScheme discovery flow
|
133
|
+
return isDone
|
202
134
|
}
|
203
135
|
|
204
|
-
async
|
205
|
-
this.
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
}
|
136
|
+
async triggerInterSchemeDiscoveryFlow (headers) {
|
137
|
+
const { params } = this.inputs
|
138
|
+
const { proxy, source } = this.state
|
139
|
+
const log = this.log.child({ method: 'triggerInterSchemeDiscoveryFlow' })
|
140
|
+
log.verbose('triggerInterSchemeDiscoveryFlow start...', { proxy, source })
|
210
141
|
|
211
|
-
const proxyNames = await this
|
212
|
-
|
213
|
-
|
214
|
-
|
142
|
+
const proxyNames = await this.#getFilteredProxyList(proxy)
|
143
|
+
if (!proxyNames.length) {
|
144
|
+
return this.#sendPartyNotFoundErrorCallback(headers)
|
145
|
+
}
|
215
146
|
|
216
|
-
|
217
|
-
const log = this.log.child({ method: 'triggerSendToProxiesFlow' })
|
218
|
-
this.deps.stepState.inProgress('setSendToProxiesList-10')
|
147
|
+
this.stepInProgress('setSendToProxiesList-10')
|
219
148
|
const alsReq = this.deps.partiesUtils.alsRequestDto(source, params)
|
220
|
-
log.
|
149
|
+
log.verbose('starting setSendToProxiesList flow: ', { proxyNames, alsReq, proxyCacheTtlSec })
|
221
150
|
|
222
151
|
const isCached = await this.deps.proxyCache.setSendToProxiesList(alsReq, proxyNames, proxyCacheTtlSec)
|
223
152
|
if (!isCached) {
|
224
|
-
|
225
|
-
throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ID_NOT_FOUND, ERROR_MESSAGES.failedToCacheSendToProxiesList)
|
153
|
+
throw super.createFspiopIdNotFoundError(ERROR_MESSAGES.failedToCacheSendToProxiesList, log)
|
226
154
|
}
|
227
155
|
|
228
|
-
this.
|
156
|
+
this.stepInProgress('sendingProxyRequests')
|
229
157
|
const sending = proxyNames.map(
|
230
158
|
sendTo => this.#forwardGetPartiesRequest({ sendTo, headers, params })
|
231
159
|
.then(({ status, data } = {}) => ({ status, data }))
|
@@ -234,48 +162,150 @@ class GetPartiesService extends BasePartiesService {
|
|
234
162
|
const isOk = results.some(result => result.status === 'fulfilled')
|
235
163
|
// If, at least, one request is sent to proxy, we treat the whole flow as successful.
|
236
164
|
// Failed requests should be handled by TTL expired/timeout handler
|
237
|
-
// todo:
|
238
|
-
log.info('
|
239
|
-
this.
|
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
|
+
|
240
169
|
if (!isOk) {
|
241
|
-
|
242
|
-
throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ID_NOT_FOUND, ERROR_MESSAGES.proxyConnectionError)
|
170
|
+
throw super.createFspiopIdNotFoundError(ERROR_MESSAGES.proxyConnectionError, log)
|
243
171
|
}
|
244
172
|
}
|
245
173
|
|
246
|
-
|
247
|
-
this.
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
const
|
174
|
+
isLocalSource () {
|
175
|
+
const isLocal = this.state.source === this.state.requester
|
176
|
+
this.log.debug(`isLocalSource: ${isLocal}`)
|
177
|
+
return isLocal
|
178
|
+
}
|
179
|
+
|
180
|
+
#filterOraclePartyList (response) {
|
181
|
+
// Oracle's API is a standard rest-style end-point Thus a GET /party on the oracle will return all participant-party records.
|
182
|
+
// We must filter the results based on the callbackEndpointType to make sure we remove records containing partySubIdOrType when we are in FSPIOP_CALLBACK_URL_PARTIES_GET mode:
|
183
|
+
this.stepInProgress('filterOraclePartyList')
|
184
|
+
const { params } = this.inputs
|
185
|
+
const callbackEndpointType = this.deps.partiesUtils.getPartyCbType(params.SubId)
|
186
|
+
let filteredPartyList
|
187
|
+
|
188
|
+
switch (callbackEndpointType) {
|
189
|
+
case FspEndpointTypes.FSPIOP_CALLBACK_URL_PARTIES_GET:
|
190
|
+
filteredPartyList = response.data.partyList.filter(party => party.partySubIdOrType == null) // Filter records that DON'T contain a partySubIdOrType
|
191
|
+
break
|
192
|
+
case FspEndpointTypes.FSPIOP_CALLBACK_URL_PARTIES_SUB_ID_GET:
|
193
|
+
filteredPartyList = response.data.partyList.filter(party => party.partySubIdOrType === params.SubId) // Filter records that match partySubIdOrType
|
194
|
+
break
|
195
|
+
default:
|
196
|
+
filteredPartyList = response // Fallback to providing the standard list
|
197
|
+
}
|
198
|
+
|
199
|
+
if (!Array.isArray(filteredPartyList) || !filteredPartyList.length) {
|
200
|
+
throw super.createFspiopIdNotFoundError(ERROR_MESSAGES.emptyFilteredPartyList)
|
201
|
+
}
|
202
|
+
|
203
|
+
return filteredPartyList
|
204
|
+
}
|
205
|
+
|
206
|
+
/** @returns {Promise<boolean>} - is request forwarded to participant */
|
207
|
+
async #processSingleOracleParty (party) {
|
208
|
+
const { headers, params } = this.inputs
|
209
|
+
const { fspId } = party
|
210
|
+
|
211
|
+
const schemeParticipant = await this.validateParticipant(fspId)
|
212
|
+
if (schemeParticipant) {
|
213
|
+
this.log.info('participant is in scheme, so forwarding to it...', { fspId })
|
214
|
+
await this.#forwardGetPartiesRequest({
|
215
|
+
sendTo: fspId,
|
216
|
+
headers: GetPartiesService.overrideDestinationHeader(headers, fspId),
|
217
|
+
params
|
218
|
+
})
|
219
|
+
return true
|
220
|
+
}
|
221
|
+
|
222
|
+
if (this.state.proxyEnabled) {
|
223
|
+
const proxyName = await this.deps.proxyCache.lookupProxyByDfspId(fspId)
|
224
|
+
if (!proxyName) {
|
225
|
+
this.log.warn('no proxyMapping for external DFSP! Deleting reference in oracle...', { fspId })
|
226
|
+
await super.sendDeleteOracleRequest(headers, params)
|
227
|
+
// todo: check if it won't delete all parties
|
228
|
+
return false
|
229
|
+
}
|
230
|
+
|
231
|
+
// Coz there's no destination header, it means we're inside initial inter-scheme discovery phase.
|
232
|
+
// So we should proceed only if source is in scheme (local participant)
|
233
|
+
const isLocalSource = this.isLocalSource()
|
234
|
+
if (isLocalSource) {
|
235
|
+
this.log.info('participant is NOT in scheme, but source is. So forwarding to proxy...', { fspId, proxyName })
|
236
|
+
await this.#forwardGetPartiesRequest({ // todo: add timeout if sendTo is proxy
|
237
|
+
sendTo: proxyName,
|
238
|
+
headers: GetPartiesService.overrideDestinationHeader(headers, fspId),
|
239
|
+
params
|
240
|
+
})
|
241
|
+
return true
|
242
|
+
}
|
243
|
+
}
|
244
|
+
return false
|
245
|
+
}
|
246
|
+
|
247
|
+
async #sendPartyNotFoundErrorCallback (headers) {
|
248
|
+
const { params } = this.inputs
|
249
|
+
const callbackHeaders = GetPartiesService.createErrorCallbackHeaders(headers, params)
|
250
|
+
const fspiopError = super.createFspiopIdNotFoundError('No proxy found to start inter-scheme discovery flow')
|
251
|
+
const errorInfo = await this.deps.partiesUtils.makePutPartiesErrorPayload(
|
252
|
+
this.deps.config, fspiopError, callbackHeaders, params
|
253
|
+
)
|
257
254
|
|
258
255
|
await this.sendErrorCallback({
|
259
|
-
|
260
|
-
errorInfo: fspiopError.toApiErrorObject(this.deps.config.ERROR_HANDLING),
|
256
|
+
errorInfo,
|
261
257
|
headers: callbackHeaders,
|
262
258
|
params
|
263
259
|
})
|
264
260
|
return fspiopError
|
265
261
|
}
|
266
262
|
|
267
|
-
async sendOracleDiscoveryRequest ({ headers, params, query }) {
|
268
|
-
this.deps.stepState.inProgress('oracleRequest-4')
|
269
|
-
return this.deps.oracle.oracleRequest(headers, RestMethods.GET, params, query, undefined, this.deps.cache)
|
270
|
-
}
|
271
|
-
|
272
263
|
async #forwardGetPartiesRequest ({ sendTo, headers, params }) {
|
273
|
-
this.
|
264
|
+
this.stepInProgress('#forwardGetPartiesRequest')
|
274
265
|
const callbackEndpointType = this.deps.partiesUtils.getPartyCbType(params.SubId)
|
275
266
|
const options = this.deps.partiesUtils.partiesRequestOptionsDto(params)
|
276
267
|
|
277
|
-
|
268
|
+
const sentResult = await this.deps.participant.sendRequest(
|
269
|
+
headers, sendTo, callbackEndpointType, RestMethods.GET, undefined, options, this.deps.childSpan
|
270
|
+
)
|
271
|
+
await this.#setProxyGetPartiesTimeout(sendTo)
|
272
|
+
return sentResult
|
273
|
+
}
|
274
|
+
|
275
|
+
async #getFilteredProxyList (proxy) {
|
276
|
+
this.stepInProgress('#getFilteredProxyList')
|
277
|
+
if (!this.state.proxyEnabled) {
|
278
|
+
this.log.warn('proxyCache is not enabled')
|
279
|
+
return []
|
280
|
+
}
|
281
|
+
|
282
|
+
const proxyNames = await this.deps.proxies.getAllProxiesNames(this.deps.config.SWITCH_ENDPOINT)
|
283
|
+
this.log.debug('getAllProxiesNames is done', { proxyNames })
|
284
|
+
return proxyNames.filter(name => name !== proxy)
|
285
|
+
}
|
286
|
+
|
287
|
+
async #setProxyGetPartiesTimeout (sendTo) {
|
288
|
+
const isLocalSource = this.isLocalSource()
|
289
|
+
const isSentToProxy = this.state.destination !== sendTo
|
290
|
+
this.log.verbose('isLocalSource and isSentToProxy: ', { isLocalSource, isSentToProxy, sendTo })
|
291
|
+
|
292
|
+
if (isSentToProxy && isLocalSource) {
|
293
|
+
this.stepInProgress('#setProxyGetPartiesTimeout')
|
294
|
+
const alsReq = this.deps.partiesUtils.alsRequestDto(this.state.source, this.inputs.params)
|
295
|
+
const isSet = await this.deps.proxyCache.setProxyGetPartiesTimeout(alsReq, sendTo)
|
296
|
+
this.log.info('#setProxyGetPartiesTimeout is done', { isSet })
|
297
|
+
return isSet
|
298
|
+
}
|
278
299
|
}
|
279
300
|
}
|
280
301
|
|
281
302
|
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
|
@@ -30,49 +30,73 @@ const { ERROR_MESSAGES } = require('../../../constants')
|
|
30
30
|
const BasePartiesService = require('./BasePartiesService')
|
31
31
|
|
32
32
|
class PutPartiesErrorService extends BasePartiesService {
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
33
|
+
/** @returns {Promise<true | undefined>} - If true, need to trigger inter-scheme discovery. */
|
34
|
+
async handleRequest () {
|
35
|
+
if (this.state.proxyEnabled && this.state.proxy) {
|
36
|
+
const alsReq = this.deps.partiesUtils.alsRequestDto(this.state.destination, this.inputs.params) // or source?
|
37
|
+
const isPending = await this.deps.proxyCache.isPendingCallback(alsReq)
|
38
|
+
|
39
|
+
if (!isPending) {
|
40
|
+
// not initial inter-scheme discovery case. Cleanup oracle and trigger inter-scheme discovery
|
41
|
+
this.log.warn('Need to cleanup oracle and trigger new inter-scheme discovery flow')
|
42
|
+
await this.cleanupOracle()
|
43
|
+
await this.removeProxyGetPartiesTimeoutCache(alsReq)
|
44
|
+
return true // need to trigger inter-scheme discovery
|
45
|
+
}
|
46
|
+
|
47
|
+
const isLast = await this.checkLastProxyCallback(alsReq)
|
48
|
+
if (!isLast) {
|
49
|
+
this.log.verbose('putPartiesErrorByTypeAndID proxy callback was processed')
|
50
|
+
return
|
51
|
+
}
|
44
52
|
}
|
45
|
-
|
53
|
+
|
54
|
+
await this.identifyDestinationForErrorCallback()
|
55
|
+
await this.sendErrorCallbackToParticipant()
|
56
|
+
this.log.info('putPartiesByTypeAndID is done')
|
46
57
|
}
|
47
58
|
|
48
|
-
async
|
49
|
-
this.
|
50
|
-
const
|
59
|
+
async cleanupOracle () {
|
60
|
+
this.stepInProgress('cleanupOracle')
|
61
|
+
const { headers, params, payload } = this.inputs
|
62
|
+
this.log.info('cleanupOracle due to error callback...', { payload })
|
63
|
+
const swappedHeaders = this.deps.partiesUtils.swapSourceDestinationHeaders(headers)
|
64
|
+
await super.sendDeleteOracleRequest(swappedHeaders, params)
|
65
|
+
}
|
66
|
+
|
67
|
+
async checkLastProxyCallback (alsReq) {
|
68
|
+
this.stepInProgress('checkLastProxyCallback')
|
69
|
+
const { proxy } = this.state
|
51
70
|
const isLast = await this.deps.proxyCache.receivedErrorResponse(alsReq, proxy)
|
52
71
|
this.log.info(`got${isLast ? '' : 'NOT'} last error callback from proxy`, { proxy, alsReq, isLast })
|
53
72
|
return isLast
|
54
73
|
}
|
55
74
|
|
56
|
-
async identifyDestinationForErrorCallback (
|
57
|
-
this.
|
58
|
-
const
|
59
|
-
|
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
|
+
}
|
60
83
|
|
61
|
-
this.
|
62
|
-
const proxyName = this.proxyEnabled && await this.deps.proxyCache.lookupProxyByDfspId(destination)
|
63
|
-
if (proxyName)
|
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
|
+
}
|
64
90
|
|
65
91
|
const errMessage = ERROR_MESSAGES.partyDestinationFspNotFound
|
66
92
|
this.log.warn(errMessage, { destination })
|
67
93
|
throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.DESTINATION_FSP_ERROR, errMessage)
|
68
94
|
}
|
69
95
|
|
70
|
-
async sendErrorCallbackToParticipant (
|
71
|
-
this.
|
96
|
+
async sendErrorCallbackToParticipant () {
|
97
|
+
const { headers, params, dataUri } = this.inputs
|
72
98
|
const errorInfo = PutPartiesErrorService.decodeDataUriPayload(dataUri)
|
73
|
-
return super.sendErrorCallback({
|
74
|
-
sendTo, errorInfo, headers, params
|
75
|
-
})
|
99
|
+
return super.sendErrorCallback({ errorInfo, headers, params })
|
76
100
|
}
|
77
101
|
}
|
78
102
|
|