@mojaloop/central-ledger 17.7.8 → 17.8.0-orb.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 (147) hide show
  1. package/.ncurc.yaml +3 -1
  2. package/.nvmrc +1 -1
  3. package/.nycrc.yml +16 -1
  4. package/Dockerfile +9 -10
  5. package/README.md +39 -9
  6. package/audit-ci.jsonc +15 -2
  7. package/config/default.json +17 -1
  8. package/docker/central-ledger/default.json +9 -0
  9. package/docker/config-modifier/configs/central-ledger.js +25 -0
  10. package/docker/env.sh +15 -0
  11. package/docker/kafka/scripts/provision.sh +4 -1
  12. package/docker/ml-api-adapter/default.json +4 -1
  13. package/docker-compose.yml +90 -2
  14. package/documentation/db/erd-transfer-timeout.png +0 -0
  15. package/documentation/db/erd-transfer-timeout.txt +81 -0
  16. package/documentation/fx-implementation/README.md +48 -0
  17. package/documentation/fx-implementation/assets/fx-position-movements.drawio.svg +4 -0
  18. package/documentation/fx-implementation/assets/test-scenario.drawio.svg +4 -0
  19. package/documentation/sequence-diagrams/Handler - FX timeout.plantuml +123 -0
  20. package/documentation/sequence-diagrams/Handler - FX timeout.png +0 -0
  21. package/documentation/sequence-diagrams/Handler - timeout.plantuml +81 -0
  22. package/documentation/sequence-diagrams/Handler - timeout.png +0 -0
  23. package/documentation/state-diagrams/transfer-ML-spec-states-diagram.png +0 -0
  24. package/documentation/state-diagrams/transfer-internal-states-diagram.png +0 -0
  25. package/documentation/state-diagrams/transfer-internal-states.plantuml +75 -0
  26. package/documentation/state-diagrams/transfer-states.plantuml +13 -0
  27. package/migrations/310204_transferParticipant-participantId.js +52 -0
  28. package/migrations/310403_participantPositionChange-participantCurrencyId.js +47 -0
  29. package/migrations/310404_participantPositionChange-change.js +46 -0
  30. package/migrations/600010_fxTransferType.js +43 -0
  31. package/migrations/600011_fxTransferType-indexes.js +38 -0
  32. package/migrations/600012_fxParticipantCurrencyType.js +43 -0
  33. package/migrations/600013_fxParticipantCurrencyType-indexes.js +38 -0
  34. package/migrations/600100_fxTransferDuplicateCheck.js +42 -0
  35. package/migrations/600110_fxTransferErrorDuplicateCheck.js.js +17 -0
  36. package/migrations/600200_fxTransfer.js +51 -0
  37. package/migrations/600201_fxTransfer-indexes.js +40 -0
  38. package/migrations/600400_fxTransferStateChange.js +46 -0
  39. package/migrations/600401_fxTransferStateChange-indexes.js +40 -0
  40. package/migrations/600501_fxWatchList.js +46 -0
  41. package/migrations/600502_fxWatchList-indexes.js +40 -0
  42. package/migrations/600600_fxTransferFulfilmentDuplicateCheck.js +43 -0
  43. package/migrations/600601_fxTransferFulfilmentDuplicateCheck-indexes.js +38 -0
  44. package/migrations/600700_fxTransferFulfilment.js +47 -0
  45. package/migrations/600701_fxTransferFulfilment-indexes.js +43 -0
  46. package/migrations/600800_fxTransferExtension.js +47 -0
  47. package/migrations/601400_fxTransferTimeout.js +43 -0
  48. package/migrations/601401_fxTransferTimeout-indexes.js +37 -0
  49. package/migrations/601500_fxTransferError.js +44 -0
  50. package/migrations/601501_fxTransferError-indexes.js +37 -0
  51. package/migrations/610200_fxTransferParticipant.js +52 -0
  52. package/migrations/610201_fxTransferParticipant-indexes.js +44 -0
  53. package/migrations/610202_fxTransferParticipant-participantId.js +52 -0
  54. package/migrations/610403_participantPositionChange-fxTransfer.js +46 -0
  55. package/migrations/910101_feature904DataMigration.js +46 -52
  56. package/migrations/910102_feature949DataMigration.js +219 -225
  57. package/migrations/950104_settlementModel-settlementAccountTypeId.js +15 -20
  58. package/migrations/950108_participantProxy.js +18 -0
  59. package/migrations/950109_fxQuote.js +19 -0
  60. package/migrations/950110_fxQuoteResponse.js +25 -0
  61. package/migrations/950111_fxQuoteError.js +23 -0
  62. package/migrations/950113_fxQuoteDuplicateCheck.js +18 -0
  63. package/migrations/950114_fxQuoteResponseDuplicateCheck.js +21 -0
  64. package/migrations/950115_fxQuoteConversionTerms.js +36 -0
  65. package/migrations/950116_fxQuoteConversionTermsExtension.js +21 -0
  66. package/migrations/950117_fxQuoteResponseConversionTerms.js +39 -0
  67. package/migrations/950118_fxQuoteResponseConversionTermsExtension.js +21 -0
  68. package/migrations/950119_fxCharge.js +27 -0
  69. package/migrations/960100_create_externalParticipant.js +47 -0
  70. package/migrations/960110_alter_transferParticipant__addFiled_externalParticipantId.js +50 -0
  71. package/migrations/960111_alter_fxTransferParticipant__addFiled_externalParticipantId.js +50 -0
  72. package/package.json +27 -20
  73. package/seeds/endpointType.js +18 -0
  74. package/seeds/fxParticipantCurrencyType.js +45 -0
  75. package/seeds/fxTransferType.js +45 -0
  76. package/seeds/participant.js +2 -1
  77. package/seeds/transferParticipantRoleType.js +9 -0
  78. package/seeds/transferState.js +10 -0
  79. package/src/api/interface/swagger.json +23 -30
  80. package/src/api/participants/handler.js +6 -2
  81. package/src/api/participants/routes.js +8 -7
  82. package/src/api/root/handler.js +15 -5
  83. package/src/domain/fx/cyril.js +466 -0
  84. package/src/domain/fx/index.js +107 -0
  85. package/src/domain/participant/index.js +108 -1
  86. package/src/domain/position/abort.js +215 -0
  87. package/src/domain/position/binProcessor.js +361 -99
  88. package/src/domain/position/fulfil.js +252 -111
  89. package/src/domain/position/fx-fulfil.js +138 -0
  90. package/src/domain/position/fx-prepare.js +280 -0
  91. package/src/domain/position/fx-timeout-reserved.js +159 -0
  92. package/src/domain/position/index.js +1 -0
  93. package/src/domain/position/prepare.js +69 -49
  94. package/src/domain/position/timeout-reserved.js +162 -0
  95. package/src/domain/timeout/index.js +26 -2
  96. package/src/domain/transfer/index.js +22 -5
  97. package/src/domain/transfer/transform.js +19 -6
  98. package/src/handlers/admin/handler.js +0 -2
  99. package/src/handlers/bulk/fulfil/handler.js +5 -5
  100. package/src/handlers/bulk/get/handler.js +5 -5
  101. package/src/handlers/bulk/prepare/handler.js +9 -9
  102. package/src/handlers/bulk/processing/handler.js +8 -7
  103. package/src/handlers/bulk/shared/validator.js +1 -1
  104. package/src/handlers/positions/handler.js +23 -10
  105. package/src/handlers/positions/handlerBatch.js +54 -26
  106. package/src/handlers/register.js +2 -1
  107. package/src/handlers/timeouts/handler.js +212 -68
  108. package/src/handlers/transfers/FxFulfilService.js +387 -0
  109. package/src/handlers/transfers/createRemittanceEntity.js +106 -0
  110. package/src/handlers/transfers/dto.js +53 -0
  111. package/src/handlers/transfers/handler.js +609 -571
  112. package/src/handlers/transfers/prepare.js +572 -0
  113. package/src/handlers/transfers/validator.js +75 -14
  114. package/src/lib/cache.js +1 -1
  115. package/src/lib/config.js +6 -3
  116. package/src/lib/healthCheck/subServiceHealth.js +12 -2
  117. package/src/lib/proxyCache.js +131 -0
  118. package/src/models/bulkTransfer/facade.js +58 -82
  119. package/src/models/fxTransfer/duplicateCheck.js +153 -0
  120. package/src/models/fxTransfer/fxTransfer.js +578 -0
  121. package/src/models/fxTransfer/fxTransferError.js +53 -0
  122. package/src/models/fxTransfer/fxTransferExtension.js +41 -0
  123. package/src/models/fxTransfer/fxTransferTimeout.js +68 -0
  124. package/src/models/fxTransfer/index.js +15 -0
  125. package/src/models/fxTransfer/stateChange.js +47 -0
  126. package/src/models/fxTransfer/watchList.js +49 -0
  127. package/src/models/ledgerAccountType/ledgerAccountType.js +8 -32
  128. package/src/models/misc/segment.js +0 -1
  129. package/src/models/participant/externalParticipant.js +96 -0
  130. package/src/models/participant/externalParticipantCached.js +148 -0
  131. package/src/models/participant/facade.js +192 -123
  132. package/src/models/participant/participant.js +2 -1
  133. package/src/models/participant/participantCurrency.js +1 -1
  134. package/src/models/participant/participantPosition.js +2 -8
  135. package/src/models/position/batch.js +90 -1
  136. package/src/models/position/facade.js +5 -5
  137. package/src/models/position/participantPositionChanges.js +68 -0
  138. package/src/models/settlement/settlementModel.js +5 -23
  139. package/src/models/transfer/facade.js +806 -447
  140. package/src/shared/constants.js +52 -0
  141. package/src/shared/fspiopErrorFactory.js +131 -0
  142. package/src/shared/logger/index.js +8 -0
  143. package/src/shared/loggingPlugin.js +43 -0
  144. package/src/shared/plugins.js +6 -0
  145. package/src/shared/setup.js +10 -0
  146. package/test-integration.Dockerfile +1 -1
  147. package/test.Dockerfile +1 -1
@@ -35,20 +35,206 @@ that actually holds the copyright for their contributions (see the
35
35
  */
36
36
 
37
37
  const CronJob = require('cron').CronJob
38
- const Config = require('../../lib/config')
39
- const TimeoutService = require('../../domain/timeout')
40
38
  const Enum = require('@mojaloop/central-services-shared').Enum
41
- const Kafka = require('@mojaloop/central-services-shared').Util.Kafka
42
- const Producer = require('@mojaloop/central-services-stream').Util.Producer
43
39
  const Utility = require('@mojaloop/central-services-shared').Util
40
+ const Producer = require('@mojaloop/central-services-stream').Util.Producer
44
41
  const ErrorHandler = require('@mojaloop/central-services-error-handling')
45
42
  const EventSdk = require('@mojaloop/event-sdk')
46
- const resourceVersions = require('@mojaloop/central-services-shared').Util.resourceVersions
47
- const Logger = require('@mojaloop/central-services-logger')
43
+
44
+ const Config = require('../../lib/config')
45
+ const TimeoutService = require('../../domain/timeout')
46
+ const { logger } = require('../../shared/logger')
47
+
48
+ const { Kafka, resourceVersions } = Utility
49
+ const { Action, Type } = Enum.Events.Event
50
+
48
51
  let timeoutJob
49
52
  let isRegistered
50
53
  let running = false
51
54
 
55
+ /**
56
+ * Processes timedOut transfers
57
+ *
58
+ * @param {TimedOutTransfer[]} transferTimeoutList
59
+ * @returns {Promise<void>}
60
+ */
61
+ const _processTimedOutTransfers = async (transferTimeoutList) => {
62
+ const fspiopError = ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.TRANSFER_EXPIRED).toApiErrorObject(Config.ERROR_HANDLING)
63
+ if (!Array.isArray(transferTimeoutList)) {
64
+ transferTimeoutList = [
65
+ { ...transferTimeoutList }
66
+ ]
67
+ }
68
+
69
+ for (const TT of transferTimeoutList) {
70
+ const span = EventSdk.Tracer.createSpan('cl_transfer_timeout')
71
+ try {
72
+ const state = Utility.StreamingProtocol.createEventState(Enum.Events.EventStatus.FAILURE.status, fspiopError.errorInformation.errorCode, fspiopError.errorInformation.errorDescription)
73
+ const metadata = Utility.StreamingProtocol.createMetadataWithCorrelatedEvent(TT.transferId, Enum.Kafka.Topics.NOTIFICATION, Action.TIMEOUT_RECEIVED, state)
74
+ const destination = TT.externalPayerName || TT.payerFsp
75
+ const source = TT.externalPayeeName || TT.payeeFsp
76
+ const headers = Utility.Http.SwitchDefaultHeaders(destination, Enum.Http.HeaderResources.TRANSFERS, Config.HUB_NAME, resourceVersions[Enum.Http.HeaderResources.TRANSFERS].contentVersion)
77
+ const message = Utility.StreamingProtocol.createMessage(TT.transferId, destination, source, metadata, headers, fspiopError, { id: TT.transferId }, `application/vnd.interoperability.${Enum.Http.HeaderResources.TRANSFERS}+json;version=${resourceVersions[Enum.Http.HeaderResources.TRANSFERS].contentVersion}`)
78
+
79
+ span.setTags(Utility.EventFramework.getTransferSpanTags({ payload: message.content.payload, headers }, Type.TRANSFER, Action.TIMEOUT_RECEIVED))
80
+ await span.audit({
81
+ state,
82
+ metadata,
83
+ headers,
84
+ message
85
+ }, EventSdk.AuditEventAction.start)
86
+
87
+ if (TT.bulkTransferId === null) { // regular transfer
88
+ if (TT.transferStateId === Enum.Transfers.TransferInternalState.EXPIRED_PREPARED) {
89
+ message.from = Config.HUB_NAME
90
+ // event & type set above when `const metadata` is initialized to NOTIFICATION / TIMEOUT_RECEIVED
91
+ await Kafka.produceGeneralMessage(
92
+ Config.KAFKA_CONFIG,
93
+ Producer,
94
+ Enum.Kafka.Topics.NOTIFICATION,
95
+ Action.TIMEOUT_RECEIVED,
96
+ message,
97
+ state,
98
+ null,
99
+ span
100
+ )
101
+ } else if (TT.transferStateId === Enum.Transfers.TransferInternalState.RESERVED_TIMEOUT) {
102
+ message.metadata.event.type = Type.POSITION
103
+ message.metadata.event.action = Action.TIMEOUT_RESERVED
104
+ // Key position timeouts with payer account id
105
+ await Kafka.produceGeneralMessage(
106
+ Config.KAFKA_CONFIG,
107
+ Producer,
108
+ Enum.Kafka.Topics.POSITION,
109
+ Action.TIMEOUT_RESERVED,
110
+ message,
111
+ state,
112
+ TT.effectedParticipantCurrencyId?.toString(),
113
+ span,
114
+ Config.KAFKA_CONFIG.EVENT_TYPE_ACTION_TOPIC_MAP?.POSITION?.TIMEOUT_RESERVED
115
+ )
116
+ }
117
+ } else { // individual transfer from a bulk
118
+ if (TT.transferStateId === Enum.Transfers.TransferInternalState.EXPIRED_PREPARED) {
119
+ message.from = Config.HUB_NAME
120
+ message.metadata.event.type = Type.BULK_PROCESSING
121
+ message.metadata.event.action = Action.BULK_TIMEOUT_RECEIVED
122
+ await Kafka.produceGeneralMessage(
123
+ Config.KAFKA_CONFIG,
124
+ Producer,
125
+ Enum.Kafka.Topics.BULK_PROCESSING,
126
+ Action.BULK_TIMEOUT_RECEIVED,
127
+ message,
128
+ state,
129
+ null,
130
+ span
131
+ )
132
+ } else if (TT.transferStateId === Enum.Transfers.TransferInternalState.RESERVED_TIMEOUT) {
133
+ message.metadata.event.type = Type.POSITION
134
+ message.metadata.event.action = Action.BULK_TIMEOUT_RESERVED
135
+ // Key position timeouts with payer account id
136
+ await Kafka.produceGeneralMessage(
137
+ Config.KAFKA_CONFIG,
138
+ Producer,
139
+ Enum.Kafka.Topics.POSITION,
140
+ Action.BULK_TIMEOUT_RESERVED,
141
+ message,
142
+ state,
143
+ TT.payerParticipantCurrencyId?.toString(),
144
+ span
145
+ )
146
+ }
147
+ }
148
+ } catch (err) {
149
+ logger.error('error in _processTimedOutTransfers:', err)
150
+ const fspiopError = ErrorHandler.Factory.reformatFSPIOPError(err)
151
+ const state = new EventSdk.EventStateMetadata(EventSdk.EventStatusType.failed, fspiopError.apiErrorCode.code, fspiopError.apiErrorCode.message)
152
+ await span.error(fspiopError, state)
153
+ await span.finish(fspiopError.message, state)
154
+ throw fspiopError
155
+ } finally {
156
+ if (!span.isFinished) {
157
+ await span.finish()
158
+ }
159
+ }
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Processes timedOut fxTransfers
165
+ *
166
+ * @param {TimedOutFxTransfer[]} fxTransferTimeoutList
167
+ * @returns {Promise<void>}
168
+ */
169
+ const _processFxTimedOutTransfers = async (fxTransferTimeoutList) => {
170
+ const fspiopError = ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.TRANSFER_EXPIRED).toApiErrorObject(Config.ERROR_HANDLING)
171
+ if (!Array.isArray(fxTransferTimeoutList)) {
172
+ fxTransferTimeoutList = [
173
+ { ...fxTransferTimeoutList }
174
+ ]
175
+ }
176
+ for (const fTT of fxTransferTimeoutList) {
177
+ const span = EventSdk.Tracer.createSpan('cl_fx_transfer_timeout')
178
+ try {
179
+ const state = Utility.StreamingProtocol.createEventState(Enum.Events.EventStatus.FAILURE.status, fspiopError.errorInformation.errorCode, fspiopError.errorInformation.errorDescription)
180
+ const metadata = Utility.StreamingProtocol.createMetadataWithCorrelatedEvent(fTT.commitRequestId, Enum.Kafka.Topics.NOTIFICATION, Action.TIMEOUT_RECEIVED, state)
181
+ const destination = fTT.externalInitiatingFspName || fTT.initiatingFsp
182
+ const source = fTT.externalCounterPartyFspName || fTT.counterPartyFsp
183
+ const headers = Utility.Http.SwitchDefaultHeaders(destination, Enum.Http.HeaderResources.FX_TRANSFERS, Config.HUB_NAME, resourceVersions[Enum.Http.HeaderResources.FX_TRANSFERS].contentVersion)
184
+ const message = Utility.StreamingProtocol.createMessage(fTT.commitRequestId, destination, source, metadata, headers, fspiopError, { id: fTT.commitRequestId }, `application/vnd.interoperability.${Enum.Http.HeaderResources.FX_TRANSFERS}+json;version=${resourceVersions[Enum.Http.HeaderResources.FX_TRANSFERS].contentVersion}`)
185
+
186
+ span.setTags(Utility.EventFramework.getTransferSpanTags({ payload: message.content.payload, headers }, Type.FX_TRANSFER, Action.TIMEOUT_RECEIVED))
187
+ await span.audit({
188
+ state,
189
+ metadata,
190
+ headers,
191
+ message
192
+ }, EventSdk.AuditEventAction.start)
193
+
194
+ if (fTT.transferStateId === Enum.Transfers.TransferInternalState.EXPIRED_PREPARED) {
195
+ message.from = Config.HUB_NAME
196
+ // event & type set above when `const metadata` is initialized to NOTIFICATION / TIMEOUT_RECEIVED
197
+ await Kafka.produceGeneralMessage(
198
+ Config.KAFKA_CONFIG,
199
+ Producer,
200
+ Enum.Kafka.Topics.NOTIFICATION,
201
+ Action.FX_TIMEOUT_RESERVED,
202
+ message,
203
+ state,
204
+ null,
205
+ span
206
+ )
207
+ } else if (fTT.transferStateId === Enum.Transfers.TransferInternalState.RESERVED_TIMEOUT) {
208
+ message.metadata.event.type = Type.POSITION
209
+ message.metadata.event.action = Action.FX_TIMEOUT_RESERVED
210
+ // Key position timeouts with payer account id
211
+ await Kafka.produceGeneralMessage(
212
+ Config.KAFKA_CONFIG,
213
+ Producer,
214
+ Enum.Kafka.Topics.POSITION,
215
+ Action.FX_TIMEOUT_RESERVED,
216
+ message,
217
+ state,
218
+ fTT.effectedParticipantCurrencyId?.toString(),
219
+ span,
220
+ Config.KAFKA_CONFIG.EVENT_TYPE_ACTION_TOPIC_MAP?.POSITION?.FX_TIMEOUT_RESERVED
221
+ )
222
+ }
223
+ } catch (err) {
224
+ logger.error('error in _processFxTimedOutTransfers:', err)
225
+ const fspiopError = ErrorHandler.Factory.reformatFSPIOPError(err)
226
+ const state = new EventSdk.EventStateMetadata(EventSdk.EventStatusType.failed, fspiopError.apiErrorCode.code, fspiopError.apiErrorCode.message)
227
+ await span.error(fspiopError, state)
228
+ await span.finish(fspiopError.message, state)
229
+ throw fspiopError
230
+ } finally {
231
+ if (!span.isFinished) {
232
+ await span.finish()
233
+ }
234
+ }
235
+ }
236
+ }
237
+
52
238
  /**
53
239
  * @function TransferTimeoutHandler
54
240
  *
@@ -70,73 +256,31 @@ const timeout = async () => {
70
256
  const segmentId = timeoutSegment ? timeoutSegment.segmentId : 0
71
257
  const cleanup = await TimeoutService.cleanupTransferTimeout()
72
258
  const latestTransferStateChange = await TimeoutService.getLatestTransferStateChange()
259
+
260
+ const fxTimeoutSegment = await TimeoutService.getFxTimeoutSegment()
73
261
  const intervalMax = (latestTransferStateChange && parseInt(latestTransferStateChange.transferStateChangeId)) || 0
74
- const result = await TimeoutService.timeoutExpireReserved(segmentId, intervalMin, intervalMax)
75
- const fspiopError = ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.TRANSFER_EXPIRED).toApiErrorObject(Config.ERROR_HANDLING)
76
- if (!Array.isArray(result)) {
77
- result[0] = result
78
- }
79
- for (let i = 0; i < result.length; i++) {
80
- const span = EventSdk.Tracer.createSpan('cl_transfer_timeout')
81
- try {
82
- const state = Utility.StreamingProtocol.createEventState(Enum.Events.EventStatus.FAILURE.status, fspiopError.errorInformation.errorCode, fspiopError.errorInformation.errorDescription)
83
- const metadata = Utility.StreamingProtocol.createMetadataWithCorrelatedEvent(result[i].transferId, Enum.Kafka.Topics.NOTIFICATION, Enum.Events.Event.Action.TIMEOUT_RECEIVED, state)
84
- const headers = Utility.Http.SwitchDefaultHeaders(result[i].payerFsp, Enum.Http.HeaderResources.TRANSFERS, Enum.Http.Headers.FSPIOP.SWITCH.value, resourceVersions[Enum.Http.HeaderResources.TRANSFERS].contentVersion)
85
- const message = Utility.StreamingProtocol.createMessage(result[i].transferId, result[i].payeeFsp, result[i].payerFsp, metadata, headers, fspiopError, { id: result[i].transferId }, `application/vnd.interoperability.${Enum.Http.HeaderResources.TRANSFERS}+json;version=${resourceVersions[Enum.Http.HeaderResources.TRANSFERS].contentVersion}`)
86
- span.setTags(Utility.EventFramework.getTransferSpanTags({ payload: message.content.payload, headers }, Enum.Events.Event.Type.TRANSFER, Enum.Events.Event.Action.TIMEOUT_RECEIVED))
87
- await span.audit({
88
- state,
89
- metadata,
90
- headers,
91
- message
92
- }, EventSdk.AuditEventAction.start)
93
- if (result[i].bulkTransferId === null) { // regular transfer
94
- if (result[i].transferStateId === Enum.Transfers.TransferInternalState.EXPIRED_PREPARED) {
95
- message.to = message.from
96
- message.from = Enum.Http.Headers.FSPIOP.SWITCH.value
97
- // event & type set above when `const metadata` is initialized to NOTIFICATION / TIMEOUT_RECEIVED
98
- await Kafka.produceGeneralMessage(Config.KAFKA_CONFIG, Producer, Enum.Kafka.Topics.NOTIFICATION, Enum.Events.Event.Action.TIMEOUT_RECEIVED, message, state, null, span)
99
- } else if (result[i].transferStateId === Enum.Transfers.TransferInternalState.RESERVED_TIMEOUT) {
100
- message.metadata.event.type = Enum.Events.Event.Type.POSITION
101
- message.metadata.event.action = Enum.Events.Event.Action.TIMEOUT_RESERVED
102
- // Key position timeouts with payer account id
103
- await Kafka.produceGeneralMessage(Config.KAFKA_CONFIG, Producer, Enum.Kafka.Topics.POSITION, Enum.Events.Event.Action.TIMEOUT_RESERVED, message, state, result[i].payerParticipantCurrencyId?.toString(), span)
104
- }
105
- } else { // individual transfer from a bulk
106
- if (result[i].transferStateId === Enum.Transfers.TransferInternalState.EXPIRED_PREPARED) {
107
- message.to = message.from
108
- message.from = Enum.Http.Headers.FSPIOP.SWITCH.value
109
- message.metadata.event.type = Enum.Events.Event.Type.BULK_PROCESSING
110
- message.metadata.event.action = Enum.Events.Event.Action.BULK_TIMEOUT_RECEIVED
111
- await Kafka.produceGeneralMessage(Config.KAFKA_CONFIG, Producer, Enum.Kafka.Topics.BULK_PROCESSING, Enum.Events.Event.Action.BULK_TIMEOUT_RECEIVED, message, state, null, span)
112
- } else if (result[i].transferStateId === Enum.Transfers.TransferInternalState.RESERVED_TIMEOUT) {
113
- message.metadata.event.type = Enum.Events.Event.Type.POSITION
114
- message.metadata.event.action = Enum.Events.Event.Action.BULK_TIMEOUT_RESERVED
115
- // Key position timeouts with payer account id
116
- await Kafka.produceGeneralMessage(Config.KAFKA_CONFIG, Producer, Enum.Kafka.Topics.POSITION, Enum.Events.Event.Action.BULK_TIMEOUT_RESERVED, message, state, result[i].payerParticipantCurrencyId?.toString(), span)
117
- }
118
- }
119
- } catch (err) {
120
- Logger.isErrorEnabled && Logger.error(err)
121
- const fspiopError = ErrorHandler.Factory.reformatFSPIOPError(err)
122
- const state = new EventSdk.EventStateMetadata(EventSdk.EventStatusType.failed, fspiopError.apiErrorCode.code, fspiopError.apiErrorCode.message)
123
- await span.error(fspiopError, state)
124
- await span.finish(fspiopError.message, state)
125
- throw fspiopError
126
- } finally {
127
- if (!span.isFinished) {
128
- await span.finish()
129
- }
130
- }
131
- }
262
+ const fxIntervalMin = fxTimeoutSegment ? fxTimeoutSegment.value : 0
263
+ const fxSegmentId = fxTimeoutSegment ? fxTimeoutSegment.segmentId : 0
264
+ const fxCleanup = await TimeoutService.cleanupFxTransferTimeout()
265
+ const latestFxTransferStateChange = await TimeoutService.getLatestFxTransferStateChange()
266
+ const fxIntervalMax = (latestFxTransferStateChange && parseInt(latestFxTransferStateChange.fxTransferStateChangeId)) || 0
267
+
268
+ const { transferTimeoutList, fxTransferTimeoutList } = await TimeoutService.timeoutExpireReserved(segmentId, intervalMin, intervalMax, fxSegmentId, fxIntervalMin, fxIntervalMax)
269
+ transferTimeoutList && await _processTimedOutTransfers(transferTimeoutList)
270
+ fxTransferTimeoutList && await _processFxTimedOutTransfers(fxTransferTimeoutList)
271
+
132
272
  return {
133
273
  intervalMin,
134
274
  cleanup,
135
275
  intervalMax,
136
- result
276
+ fxIntervalMin,
277
+ fxCleanup,
278
+ fxIntervalMax,
279
+ transferTimeoutList,
280
+ fxTransferTimeoutList
137
281
  }
138
282
  } catch (err) {
139
- Logger.isErrorEnabled && Logger.error(err)
283
+ logger.error('error in timeout:', err)
140
284
  throw ErrorHandler.Factory.reformatFSPIOPError(err)
141
285
  } finally {
142
286
  running = false
@@ -192,7 +336,7 @@ const registerTimeoutHandler = async () => {
192
336
  await timeoutJob.start()
193
337
  return true
194
338
  } catch (err) {
195
- Logger.isErrorEnabled && Logger.error(err)
339
+ logger.error('error in registerTimeoutHandler:', err)
196
340
  throw ErrorHandler.Factory.reformatFSPIOPError(err)
197
341
  }
198
342
  }
@@ -212,7 +356,7 @@ const registerAllHandlers = async () => {
212
356
  }
213
357
  return true
214
358
  } catch (err) {
215
- Logger.isErrorEnabled && Logger.error(err)
359
+ logger.error('error in registerAllHandlers:', err)
216
360
  throw ErrorHandler.Factory.reformatFSPIOPError(err)
217
361
  }
218
362
  }