@mojaloop/central-ledger 9.2.2 → 15.1.3-snapshot.2

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 (256) hide show
  1. package/.circleci/config.yml +625 -204
  2. package/.env +3 -2
  3. package/.ncurc.yaml +9 -0
  4. package/.nvmrc +1 -1
  5. package/.versionrc +15 -0
  6. package/CHANGELOG.md +353 -0
  7. package/CODEOWNERS +31 -0
  8. package/Dockerfile +20 -14
  9. package/LICENSE.md +4 -4
  10. package/Onboarding.md +0 -7
  11. package/README.md +99 -22
  12. package/audit-resolve.json +136 -1
  13. package/config/default.json +82 -27
  14. package/docker/central-ledger/default.json +68 -21
  15. package/docker/ml-api-adapter/default.json +10 -1
  16. package/docker/wait-for/wait-for-objstore.sh +1 -6
  17. package/docker/wait-for/wait-for.env +1 -1
  18. package/docker-compose.integration.yml +8 -5
  19. package/docker-compose.yml +73 -16
  20. package/migrations/310203_transferParticipant-indexes.js +38 -0
  21. package/migrations/310503_participantLimit-indexes-composite.js +38 -0
  22. package/migrations/{400401_settlementWindowStateChange-indexes.js → 400401_settlmentWindowStateChange-indexes.js} +0 -0
  23. package/migrations/401301_settlementModel-indexes.js +2 -0
  24. package/migrations/500401_quote-hotfix-2719.js +58 -0
  25. package/migrations/500501_feature-fixSubIdRef.js +53 -0
  26. package/migrations/500601_party-2480.js +63 -0
  27. package/migrations/501001_quoteExtension-quote-service-174.js +46 -0
  28. package/migrations/501002_quoteExtension-2522.js +61 -0
  29. package/migrations/800101_feature-fixSubIdRef.js +90 -0
  30. package/migrations/910102_hotfix954.js +4 -1
  31. package/migrations/940100_quotePartyIdInfoExtension.js +52 -0
  32. package/migrations/940101_quotePartyIdInfoExtension-2522.js +64 -0
  33. package/migrations/950100_settlementContentAggregation-decimal184.js +40 -0
  34. package/migrations/950101_transferParticipantStateChange.js +46 -0
  35. package/migrations/950102_settlementModel-adjustPosition.js +42 -0
  36. package/migrations/950103_dropTransferParticipantStateChange.js +47 -0
  37. package/migrations/950104_settlementModel-settlementAccountTypeId.js +79 -0
  38. package/migrations/950106_unique_settlement_model_ledger_account_currency.js +38 -0
  39. package/migrations/950107_settlementWindowContent_foreign_settlementModel.js +60 -0
  40. package/package.json +99 -81
  41. package/scripts/_wait4_all.js +146 -0
  42. package/seeds/amountType.js +4 -6
  43. package/seeds/balanceOfPayments.js +4 -6
  44. package/seeds/bulkProcessingState.js +4 -6
  45. package/seeds/bulkTransferState.js +4 -6
  46. package/seeds/currency.js +4 -6
  47. package/seeds/endpointType.js +128 -7
  48. package/seeds/ledgerAccountType.js +11 -10
  49. package/seeds/ledgerEntryType.js +5 -7
  50. package/seeds/participant.js +4 -6
  51. package/seeds/participantLimitType.js +4 -6
  52. package/seeds/partyIdentifierType.js +4 -6
  53. package/seeds/partyType.js +4 -6
  54. package/seeds/settlementDelay.js +4 -6
  55. package/seeds/settlementGranularity.js +4 -6
  56. package/seeds/settlementInterchange.js +4 -6
  57. package/seeds/settlementState.js +4 -6
  58. package/seeds/settlementWindow1State.js +4 -6
  59. package/seeds/transactionInitiator.js +4 -6
  60. package/seeds/transactionInitiatorType.js +4 -6
  61. package/seeds/transactionScenario.js +4 -6
  62. package/seeds/transferParticipantRoleType.js +4 -6
  63. package/seeds/transferState.js +9 -6
  64. package/src/api/interface/swagger.json +728 -948
  65. package/src/api/ledgerAccountTypes/handler.js +55 -0
  66. package/src/api/ledgerAccountTypes/routes.js +63 -0
  67. package/src/api/metrics/handler.js +2 -2
  68. package/src/api/metrics/routes.js +1 -1
  69. package/src/api/participants/handler.js +43 -35
  70. package/src/api/participants/routes.js +13 -13
  71. package/src/api/root/routes.js +2 -2
  72. package/src/api/settlementModels/handler.js +9 -26
  73. package/src/api/settlementModels/routes.js +4 -4
  74. package/src/api/transactions/handler.js +46 -0
  75. package/src/api/transactions/routes.js +45 -0
  76. package/src/domain/bulkTransfer/index.js +6 -5
  77. package/src/domain/ledgerAccountTypes/index.js +58 -0
  78. package/src/domain/participant/index.js +55 -4
  79. package/src/domain/position/index.js +18 -2
  80. package/src/domain/settlement/index.js +39 -6
  81. package/src/domain/transactions/index.js +61 -0
  82. package/src/domain/transfer/index.js +22 -2
  83. package/src/domain/transfer/transform.js +3 -3
  84. package/src/handlers/admin/handler.js +24 -32
  85. package/src/handlers/bulk/fulfil/handler.js +89 -56
  86. package/src/handlers/bulk/get/handler.js +203 -0
  87. package/src/handlers/bulk/index.js +4 -1
  88. package/src/handlers/bulk/prepare/handler.js +30 -29
  89. package/src/handlers/bulk/processing/handler.js +61 -32
  90. package/src/handlers/bulk/shared/validator.js +13 -1
  91. package/src/handlers/index.js +18 -9
  92. package/src/handlers/positions/handler.js +67 -46
  93. package/src/handlers/register.js +7 -7
  94. package/src/handlers/timeouts/handler.js +9 -4
  95. package/src/handlers/transfers/handler.js +408 -182
  96. package/src/handlers/transfers/validator.js +41 -11
  97. package/src/lib/cache.js +8 -34
  98. package/src/lib/config.js +5 -7
  99. package/src/lib/enum.js +22 -22
  100. package/src/lib/enumCached.js +76 -0
  101. package/src/lib/healthCheck/subServiceHealth.js +2 -2
  102. package/src/lib/requestLogger.js +9 -9
  103. package/src/lib/urlParser.js +1 -1
  104. package/src/models/bulkTransfer/bulkTransfer.js +6 -6
  105. package/src/models/bulkTransfer/bulkTransferAssociation.js +3 -3
  106. package/src/models/bulkTransfer/bulkTransferDuplicateCheck.js +4 -4
  107. package/src/models/bulkTransfer/bulkTransferExtension.js +2 -2
  108. package/src/models/bulkTransfer/bulkTransferFulfilmentDuplicateCheck.js +4 -4
  109. package/src/models/bulkTransfer/bulkTransferStateChange.js +7 -7
  110. package/src/models/bulkTransfer/facade.js +54 -3
  111. package/src/models/bulkTransfer/individualTransfer.js +2 -2
  112. package/src/models/ilpPackets/ilpPacket.js +36 -0
  113. package/src/models/ledgerAccountType/ledgerAccountType.js +139 -3
  114. package/src/models/misc/migrationLock.js +1 -1
  115. package/src/models/misc/segment.js +1 -1
  116. package/src/models/participant/facade.js +226 -76
  117. package/src/models/participant/participant.js +6 -5
  118. package/src/models/participant/participantCached.js +8 -0
  119. package/src/models/participant/participantCurrency.js +7 -7
  120. package/src/models/participant/participantCurrencyCached.js +11 -1
  121. package/src/models/participant/participantLimit.js +13 -13
  122. package/src/models/participant/participantLimitCached.js +124 -0
  123. package/src/models/participant/participantPosition.js +34 -5
  124. package/src/models/participant/participantPositionChange.js +10 -2
  125. package/src/models/position/facade.js +112 -18
  126. package/src/models/position/participantPosition.js +6 -6
  127. package/src/models/settlement/settlementModel.js +92 -17
  128. package/src/models/settlement/settlementModelCached.js +139 -0
  129. package/src/models/transfer/facade.js +97 -32
  130. package/src/models/transfer/ilpPacket.js +4 -4
  131. package/src/models/transfer/transfer.js +7 -7
  132. package/src/models/transfer/transferDuplicateCheck.js +21 -5
  133. package/src/models/transfer/transferError.js +5 -5
  134. package/src/models/transfer/transferErrorDuplicateCheck.js +4 -4
  135. package/src/models/transfer/transferExtension.js +4 -4
  136. package/src/models/transfer/transferFulfilment.js +5 -5
  137. package/src/models/transfer/transferFulfilmentDuplicateCheck.js +4 -4
  138. package/src/models/transfer/transferParticipant.js +3 -3
  139. package/src/models/transfer/transferStateChange.js +11 -11
  140. package/src/models/transfer/transferTimeout.js +5 -5
  141. package/src/schema/bulkTransfer.js +4 -4
  142. package/src/shared/plugins.js +10 -9
  143. package/src/shared/setup.js +69 -46
  144. package/test/integration/domain/participant/index.test.js +2 -0
  145. package/test/integration/handlers/handlers.test.js +605 -166
  146. package/test/integration/handlers/root.test.js +1 -1
  147. package/test/integration/helpers/hubAccounts.js +62 -0
  148. package/test/integration/helpers/ilpPacket.js +1 -1
  149. package/test/integration/helpers/participantFundsInOut.js +80 -0
  150. package/test/integration/helpers/participantLimit.js +6 -1
  151. package/test/integration/helpers/settlementModels.js +88 -0
  152. package/test/integration/helpers/testConsumer.js +163 -0
  153. package/test/integration/helpers/testProducer.js +0 -1
  154. package/test/integration/helpers/transferDuplicateCheck.js +1 -1
  155. package/test/integration/helpers/transferStateChange.js +1 -1
  156. package/test/integration/helpers/transferTestHelper.js +3 -5
  157. package/test/integration/models/transfer/transferStateChange.test.js +6 -0
  158. package/test/unit/api/ledgerAccountTypes/handler.test.js +126 -0
  159. package/test/unit/api/ledgerAccountTypes/routes.test.js +52 -0
  160. package/test/unit/api/participants/handler.test.js +75 -33
  161. package/test/unit/api/root/handler.test.js +1 -1
  162. package/test/unit/api/root/routes.test.js +2 -2
  163. package/test/unit/api/settlementModels/handler.test.js +21 -57
  164. package/test/unit/api/transactions/handler.test.js +108 -0
  165. package/test/unit/api/transactions/routes.test.js +38 -0
  166. package/test/unit/domain/ledgerAccountTypes/index.test.js +197 -0
  167. package/test/unit/domain/participant/index.test.js +115 -2
  168. package/test/unit/domain/settlement/index.test.js +199 -29
  169. package/test/unit/domain/transactions/index.test.js +128 -0
  170. package/test/unit/domain/transfer/index.test.js +1 -0
  171. package/test/unit/domain/transfer/transform.test.js +2 -0
  172. package/test/unit/handlers/admin/handler.test.js +5 -5
  173. package/test/unit/handlers/bulk/get/handler.test.js +401 -0
  174. package/test/unit/handlers/index.test.js +6 -0
  175. package/test/unit/handlers/positions/handler.test.js +26 -0
  176. package/test/unit/handlers/register.test.js +2 -0
  177. package/test/unit/handlers/transfers/handler.test.js +491 -36
  178. package/test/unit/handlers/transfers/validator.test.js +31 -31
  179. package/test/unit/lib/cache.test.js +0 -64
  180. package/test/unit/lib/cachingOfEnums.test.js +121 -0
  181. package/test/unit/lib/config.test.js +34 -0
  182. package/test/unit/lib/enum.test.js +6 -1
  183. package/test/unit/lib/enumCached.test.js +82 -0
  184. package/test/unit/lib/healthCheck/subServiceHealth.test.js +2 -0
  185. package/test/unit/lib/requestLogger.test.js +14 -12
  186. package/test/unit/models/ilpPackets/ilpPacket.test.js +89 -0
  187. package/test/unit/models/ledgerAccountType/ledgerAccountType.test.js +255 -6
  188. package/test/unit/models/misc/migrationLock.test.js +4 -0
  189. package/test/unit/models/misc/segment.test.js +5 -0
  190. package/test/unit/models/participant/facade.test.js +493 -54
  191. package/test/unit/models/participant/participant.test.js +4 -0
  192. package/test/unit/models/participant/participantCurrency.test.js +22 -9
  193. package/test/unit/models/participant/participantCurrencyCached.test.js +1 -1
  194. package/test/unit/models/participant/participantLimit.test.js +97 -0
  195. package/test/unit/models/participant/participantLimitCached.test.js +232 -0
  196. package/test/unit/models/participant/participantPosition.test.js +217 -0
  197. package/test/unit/models/participant/participantPositionChange.test.js +3 -0
  198. package/test/unit/models/position/facade.test.js +318 -29
  199. package/test/unit/models/position/participantPosition.test.js +22 -7
  200. package/test/unit/models/settlement/settlementModel.test.js +18 -37
  201. package/test/unit/models/settlement/settlementModelCached.test.js +171 -0
  202. package/test/unit/models/transfer/facade.test.js +115 -0
  203. package/test/unit/models/transfer/ilpPacket.test.js +28 -11
  204. package/test/unit/models/transfer/transfer.test.js +13 -4
  205. package/test/unit/models/transfer/transferDuplicateCheck.test.js +4 -0
  206. package/test/unit/models/transfer/transferError.test.js +5 -1
  207. package/test/unit/models/transfer/transferErrorDuplicateCheck.test.js +4 -0
  208. package/test/unit/models/transfer/transferExtension.test.js +26 -9
  209. package/test/unit/models/transfer/transferFulfilment.test.js +14 -5
  210. package/test/unit/models/transfer/transferFulfilmentDuplicateCheck.test.js +4 -0
  211. package/test/unit/models/transfer/transferParticipant.test.js +14 -5
  212. package/test/unit/models/transfer/transferStateChange.test.js +3 -0
  213. package/test/unit/models/transfer/transferTimeout.test.js +6 -0
  214. package/test/unit/seeds/amountType.test.js +6 -22
  215. package/test/unit/seeds/balanceOfPayments.test.js +6 -22
  216. package/test/unit/seeds/bulkProcessingState.test.js +84 -0
  217. package/test/unit/{lib/sidecar/nullClient.test.js → seeds/bulkTransferState.test.js} +36 -39
  218. package/test/unit/seeds/currency.test.js +6 -22
  219. package/test/unit/seeds/endpointType.test.js +6 -22
  220. package/test/unit/seeds/ledgerAccountType.test.js +5 -22
  221. package/test/unit/seeds/ledgerEntryType.test.js +6 -22
  222. package/test/unit/seeds/participant.test.js +5 -22
  223. package/test/unit/seeds/participantLimitType.test.js +6 -22
  224. package/test/unit/seeds/partyIdentifierType.test.js +6 -22
  225. package/test/unit/seeds/partyType.test.js +6 -22
  226. package/test/unit/seeds/settlementState.test.js +5 -22
  227. package/test/unit/seeds/settlementWindow1State.test.js +5 -22
  228. package/test/unit/seeds/transactionInitiator.test.js +6 -22
  229. package/test/unit/seeds/transactionInitiatorType.test.js +6 -22
  230. package/test/unit/seeds/transactionScenario.test.js +6 -22
  231. package/test/unit/seeds/transferParticipantRoleType.test.js +6 -22
  232. package/test/unit/seeds/transferState.test.js +6 -22
  233. package/test/unit/shared/plugins.test.js +31 -1
  234. package/test/unit/shared/setup.test.js +25 -36
  235. package/test/util/helpers.js +37 -2
  236. package/test/util/randomTransfers.js +1 -1
  237. package/test/util/scripts/env.sh +6 -5
  238. package/test/util/scripts/populateTestData.sh +204 -181
  239. package/test/util/scripts/populateTestDataForLegacySimulator.sh +261 -0
  240. package/test/util/scripts/restartObjStore.sh +1 -1
  241. package/test-integration.Dockerfile +15 -15
  242. package/test.Dockerfile +12 -12
  243. package/.circleci/_set_up_deploy_envs.sh +0 -47
  244. package/.dockerignore +0 -17
  245. package/.ncurc.json +0 -3
  246. package/server.sh +0 -4
  247. package/sonar-project.properties +0 -17
  248. package/src/lib/sidecar/index.js +0 -47
  249. package/src/lib/sidecar/nullClient.js +0 -18
  250. package/test/.env +0 -8
  251. package/test/integration-config.json +0 -367
  252. package/test/integration-runner.env +0 -31
  253. package/test/integration-runner.sh +0 -264
  254. package/test/spec-runner.sh +0 -132
  255. package/test/unit/lib/sidecar/index.test.js +0 -148
  256. package/test/unit/models/position/participantLimit.test.js +0 -135
@@ -41,7 +41,9 @@
41
41
  const Logger = require('@mojaloop/central-services-logger')
42
42
  const EventSdk = require('@mojaloop/event-sdk')
43
43
  const TransferService = require('../../domain/transfer')
44
+ const TransferObjectTransform = require('../../domain/transfer/transform')
44
45
  const PositionService = require('../../domain/position')
46
+ const SettlementModelCached = require('../../models/settlement/settlementModelCached')
45
47
  const Utility = require('@mojaloop/central-services-shared').Util
46
48
  const Kafka = require('@mojaloop/central-services-shared').Util.Kafka
47
49
  const Producer = require('@mojaloop/central-services-stream').Util.Producer
@@ -74,21 +76,23 @@ const fromSwitch = true
74
76
  *
75
77
  * @returns {object} - Returns a boolean: true if successful, or throws and error if failed
76
78
  */
79
+
77
80
  const positions = async (error, messages) => {
78
81
  const histTimerEnd = Metrics.getHistogram(
79
82
  'transfer_position',
80
83
  'Consume a prepare transfer message from the kafka topic and process it accordingly',
81
- ['success', 'fspId']
84
+ ['success', 'fspId', 'action']
82
85
  ).startTimer()
83
86
 
84
87
  if (error) {
85
- histTimerEnd({ success: false, fspId: Config.INSTRUMENTATION_METRICS_LABELS.fspId })
88
+ histTimerEnd({ success: false, fspId: Config.INSTRUMENTATION_METRICS_LABELS.fspId, action: 'error' })
86
89
  throw ErrorHandler.Factory.reformatFSPIOPError(error)
87
90
  }
88
91
  let message = {}
89
92
  let prepareBatch = []
90
93
  let contextFromMessage
91
94
  let span
95
+ let action
92
96
  try {
93
97
  if (Array.isArray(messages)) {
94
98
  prepareBatch = Array.from(messages)
@@ -102,87 +106,104 @@ const positions = async (error, messages) => {
102
106
  await span.audit(message, EventSdk.AuditEventAction.start)
103
107
  const payload = decodePayload(message.value.content.payload)
104
108
  const eventType = message.value.metadata.event.type
105
- const action = message.value.metadata.event.action
109
+ action = message.value.metadata.event.action
106
110
  const transferId = payload.transferId || (message.value.content.uriParams && message.value.content.uriParams.id)
107
111
  if (!transferId) {
108
112
  const fspiopError = ErrorHandler.Factory.createInternalServerFSPIOPError('transferId is null or undefined')
109
- Logger.error(fspiopError)
113
+ Logger.isErrorEnabled && Logger.error(fspiopError)
110
114
  throw fspiopError
111
115
  }
112
116
  const kafkaTopic = message.topic
113
- Logger.info(Utility.breadcrumb(location, { method: 'positions' }))
117
+ Logger.isInfoEnabled && Logger.info(Utility.breadcrumb(location, { method: 'positions' }))
114
118
 
115
- const actionLetter = action === Enum.Events.Event.Action.PREPARE ? Enum.Events.ActionLetter.prepare
116
- : (action === Enum.Events.Event.Action.COMMIT ? Enum.Events.ActionLetter.commit
117
- : (action === Enum.Events.Event.Action.REJECT ? Enum.Events.ActionLetter.reject
118
- : (action === Enum.Events.Event.Action.ABORT ? Enum.Events.ActionLetter.abort
119
- : (action === Enum.Events.Event.Action.TIMEOUT_RESERVED ? Enum.Events.ActionLetter.timeout
120
- : (action === Enum.Events.Event.Action.BULK_PREPARE ? Enum.Events.ActionLetter.bulkPrepare
121
- : (action === Enum.Events.Event.Action.BULK_COMMIT ? Enum.Events.ActionLetter.bulkCommit
122
- : (action === Enum.Events.Event.Action.BULK_TIMEOUT_RESERVED ? Enum.Events.ActionLetter.bulkTimeoutReserved
123
- : Enum.Events.ActionLetter.unknown)))))))
119
+ const actionLetter = action === Enum.Events.Event.Action.PREPARE
120
+ ? Enum.Events.ActionLetter.prepare
121
+ : (action === Enum.Events.Event.Action.RESERVE
122
+ ? Enum.Events.ActionLetter.reserve
123
+ : (action === Enum.Events.Event.Action.COMMIT
124
+ ? Enum.Events.ActionLetter.commit
125
+ : (action === Enum.Events.Event.Action.REJECT
126
+ ? Enum.Events.ActionLetter.reject
127
+ : (action === Enum.Events.Event.Action.ABORT
128
+ ? Enum.Events.ActionLetter.abort
129
+ : (action === Enum.Events.Event.Action.TIMEOUT_RESERVED
130
+ ? Enum.Events.ActionLetter.timeout
131
+ : (action === Enum.Events.Event.Action.BULK_PREPARE
132
+ ? Enum.Events.ActionLetter.bulkPrepare
133
+ : (action === Enum.Events.Event.Action.BULK_COMMIT
134
+ ? Enum.Events.ActionLetter.bulkCommit
135
+ : (action === Enum.Events.Event.Action.BULK_TIMEOUT_RESERVED
136
+ ? Enum.Events.ActionLetter.bulkTimeoutReserved
137
+ : (action === Enum.Events.Event.Action.BULK_ABORT
138
+ ? Enum.Events.ActionLetter.bulkAbort
139
+ : Enum.Events.ActionLetter.unknown)))))))))
124
140
  const params = { message, kafkaTopic, decodedPayload: payload, span, consumer: Consumer, producer: Producer }
125
141
  const eventDetail = { action }
126
- if (![Enum.Events.Event.Action.BULK_PREPARE, Enum.Events.Event.Action.BULK_COMMIT, Enum.Events.Event.Action.BULK_TIMEOUT_RESERVED].includes(action)) {
142
+ if (![Enum.Events.Event.Action.BULK_PREPARE, Enum.Events.Event.Action.BULK_COMMIT, Enum.Events.Event.Action.BULK_TIMEOUT_RESERVED, Enum.Events.Event.Action.BULK_ABORT].includes(action)) {
127
143
  eventDetail.functionality = Enum.Events.Event.Type.NOTIFICATION
128
144
  } else {
129
145
  eventDetail.functionality = Enum.Events.Event.Type.BULK_PROCESSING
130
146
  }
131
147
 
132
148
  if (eventType === Enum.Events.Event.Type.POSITION && [Enum.Events.Event.Action.PREPARE, Enum.Events.Event.Action.BULK_PREPARE].includes(action)) {
133
- Logger.info(Utility.breadcrumb(location, { path: 'prepare' }))
149
+ Logger.isInfoEnabled && Logger.info(Utility.breadcrumb(location, { path: 'prepare' }))
134
150
  const { preparedMessagesList, limitAlarms } = await PositionService.calculatePreparePositionsBatch(decodeMessages(prepareBatch))
135
151
  for (const limit of limitAlarms) {
136
152
  // Publish alarm message to KafkaTopic for the Hub to consume as it is the Hub
137
153
  // rather than the switch to manage this (the topic is an participantEndpoint)
138
- Logger.info(`Limit alarm should be sent with ${limit}`)
154
+ Logger.isInfoEnabled && Logger.info(`Limit alarm should be sent with ${limit}`)
139
155
  }
140
- for (const prepareMessage of preparedMessagesList) {
141
- const { transferState } = prepareMessage
156
+ if (Array.isArray(preparedMessagesList) && preparedMessagesList.length > 0) {
157
+ const prepareMessage = preparedMessagesList[0]
158
+ const { transferState, fspiopError } = prepareMessage
142
159
  if (transferState.transferStateId === Enum.Transfers.TransferState.RESERVED) {
143
- Logger.info(Utility.breadcrumb(location, `payer--${actionLetter}1`))
160
+ Logger.isInfoEnabled && Logger.info(Utility.breadcrumb(location, `payer--${actionLetter}1`))
144
161
  await Kafka.proceed(Config.KAFKA_CONFIG, params, { consumerCommit, eventDetail })
145
- histTimerEnd({ success: true, fspId: Config.INSTRUMENTATION_METRICS_LABELS.fspId })
162
+ histTimerEnd({ success: true, fspId: Config.INSTRUMENTATION_METRICS_LABELS.fspId, action })
146
163
  return true
147
164
  } else {
148
- Logger.info(Utility.breadcrumb(location, `payerNotifyInsufficientLiquidity--${actionLetter}2`))
149
- const fspiopError = ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.PAYER_FSP_INSUFFICIENT_LIQUIDITY)
150
- const fspiopApiError = fspiopError.toApiErrorObject(Config.ERROR_HANDLING)
165
+ Logger.isInfoEnabled && Logger.info(Utility.breadcrumb(location, `payerNotifyInsufficientLiquidity--${actionLetter}2`))
166
+ const responseFspiopError = fspiopError || ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.INTERNAL_SERVER_ERROR)
167
+ const fspiopApiError = responseFspiopError.toApiErrorObject(Config.ERROR_HANDLING)
151
168
  await TransferService.logTransferError(transferId, fspiopApiError.errorInformation.errorCode, fspiopApiError.errorInformation.errorDescription)
152
169
  await Kafka.proceed(Config.KAFKA_CONFIG, params, { consumerCommit, fspiopError: fspiopApiError, eventDetail, fromSwitch })
153
- throw fspiopError
170
+ throw responseFspiopError
154
171
  }
155
172
  }
156
- } else if (eventType === Enum.Events.Event.Type.POSITION && [Enum.Events.Event.Action.COMMIT, Enum.Events.Event.Action.BULK_COMMIT].includes(action)) {
157
- Logger.info(Utility.breadcrumb(location, { path: 'commit' }))
173
+ } else if (eventType === Enum.Events.Event.Type.POSITION && [Enum.Events.Event.Action.COMMIT, Enum.Events.Event.Action.RESERVE, Enum.Events.Event.Action.BULK_COMMIT].includes(action)) {
174
+ Logger.isInfoEnabled && Logger.info(Utility.breadcrumb(location, { path: 'commit' }))
158
175
  const transferInfo = await TransferService.getTransferInfoToChangePosition(transferId, Enum.Accounts.TransferParticipantRoleType.PAYEE_DFSP, Enum.Accounts.LedgerEntryType.PRINCIPLE_VALUE)
159
176
  if (transferInfo.transferStateId !== Enum.Transfers.TransferInternalState.RECEIVED_FULFIL) {
160
- Logger.info(Utility.breadcrumb(location, `validationFailed::notReceivedFulfilState1--${actionLetter}3`))
177
+ Logger.isInfoEnabled && Logger.info(Utility.breadcrumb(location, `validationFailed::notReceivedFulfilState1--${actionLetter}3`))
161
178
  const fspiopError = ErrorHandler.Factory.createInternalServerFSPIOPError(`Invalid State: ${transferInfo.transferStateId} - expected: ${Enum.Transfers.TransferInternalState.RECEIVED_FULFIL}`)
162
179
  await Kafka.proceed(Config.KAFKA_CONFIG, params, { consumerCommit, fspiopError: fspiopError.toApiErrorObject(Config.ERROR_HANDLING), eventDetail, fromSwitch })
163
180
  throw fspiopError
164
181
  } else {
165
- Logger.info(Utility.breadcrumb(location, `payee--${actionLetter}4`))
182
+ Logger.isInfoEnabled && Logger.info(Utility.breadcrumb(location, `payee--${actionLetter}4`))
166
183
  const isReversal = false
167
184
  const transferStateChange = {
168
185
  transferId: transferInfo.transferId,
169
186
  transferStateId: Enum.Transfers.TransferState.COMMITTED
170
187
  }
171
188
  await PositionService.changeParticipantPosition(transferInfo.participantCurrencyId, isReversal, transferInfo.amount, transferStateChange)
189
+ if (action === Enum.Events.Event.Action.RESERVE) {
190
+ const transfer = await TransferService.getById(transferInfo.transferId)
191
+ message.value.content.payload = TransferObjectTransform.toFulfil(transfer)
192
+ }
172
193
  await Kafka.proceed(Config.KAFKA_CONFIG, params, { consumerCommit, eventDetail })
173
- histTimerEnd({ success: true, fspId: Config.INSTRUMENTATION_METRICS_LABELS.fspId })
194
+ histTimerEnd({ success: true, fspId: Config.INSTRUMENTATION_METRICS_LABELS.fspId, action })
174
195
  return true
175
196
  }
176
- } else if (eventType === Enum.Events.Event.Type.POSITION && [Enum.Events.Event.Action.REJECT, Enum.Events.Event.Action.ABORT].includes(action)) {
177
- Logger.info(Utility.breadcrumb(location, { path: action }))
197
+ } else if (eventType === Enum.Events.Event.Type.POSITION && [Enum.Events.Event.Action.REJECT, Enum.Events.Event.Action.ABORT, Enum.Events.Event.Action.ABORT_VALIDATION, Enum.Events.Event.Action.BULK_ABORT].includes(action)) {
198
+ Logger.isInfoEnabled && Logger.info(Utility.breadcrumb(location, { path: action }))
178
199
  const transferInfo = await TransferService.getTransferInfoToChangePosition(transferId, Enum.Accounts.TransferParticipantRoleType.PAYER_DFSP, Enum.Accounts.LedgerEntryType.PRINCIPLE_VALUE)
179
200
  let transferStateId
180
201
 
181
202
  if (action === Enum.Events.Event.Action.REJECT) {
182
- Logger.info(Utility.breadcrumb(location, `receivedReject--${actionLetter}5`))
203
+ Logger.isInfoEnabled && Logger.info(Utility.breadcrumb(location, `receivedReject--${actionLetter}5`))
183
204
  transferStateId = Enum.Transfers.TransferInternalState.ABORTED_REJECTED
184
- } else { // action === Enum.Events.Event.Action.ABORT
185
- Logger.info(Utility.breadcrumb(location, `receivedError--${actionLetter}5`))
205
+ } else { // action === Enum.Events.Event.Action.ABORT || action === Enum.Events.Event.Action.BULK_ABORT
206
+ Logger.isInfoEnabled && Logger.info(Utility.breadcrumb(location, `receivedError--${actionLetter}5`))
186
207
  transferStateId = Enum.Transfers.TransferInternalState.ABORTED_ERROR
187
208
  }
188
209
  const isReversal = true
@@ -193,17 +214,17 @@ const positions = async (error, messages) => {
193
214
  }
194
215
  await PositionService.changeParticipantPosition(transferInfo.participantCurrencyId, isReversal, transferInfo.amount, transferStateChange)
195
216
  await Kafka.proceed(Config.KAFKA_CONFIG, params, { consumerCommit, eventDetail })
196
- histTimerEnd({ success: true, fspId: Config.INSTRUMENTATION_METRICS_LABELS.fspId })
217
+ histTimerEnd({ success: true, fspId: Config.INSTRUMENTATION_METRICS_LABELS.fspId, action })
197
218
  return true
198
219
  } else if (eventType === Enum.Events.Event.Type.POSITION && [Enum.Events.Event.Action.TIMEOUT_RESERVED, Enum.Events.Event.Action.BULK_TIMEOUT_RESERVED].includes(action)) {
199
- Logger.info(Utility.breadcrumb(location, { path: 'timeout' }))
220
+ Logger.isInfoEnabled && Logger.info(Utility.breadcrumb(location, { path: 'timeout' }))
200
221
  span.setTags({ transactionId: transferId })
201
222
  const transferInfo = await TransferService.getTransferInfoToChangePosition(transferId, Enum.Accounts.TransferParticipantRoleType.PAYER_DFSP, Enum.Accounts.LedgerEntryType.PRINCIPLE_VALUE)
202
223
  if (transferInfo.transferStateId !== Enum.Transfers.TransferInternalState.RESERVED_TIMEOUT) {
203
- Logger.info(Utility.breadcrumb(location, `validationFailed::notReceivedFulfilState2--${actionLetter}6`))
224
+ Logger.isInfoEnabled && Logger.info(Utility.breadcrumb(location, `validationFailed::notReceivedFulfilState2--${actionLetter}6`))
204
225
  throw ErrorHandler.Factory.createInternalServerFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.INTERNAL_SERVER_ERROR.message)
205
226
  } else {
206
- Logger.info(Utility.breadcrumb(location, `validationPassed2--${actionLetter}7`))
227
+ Logger.isInfoEnabled && Logger.info(Utility.breadcrumb(location, `validationPassed2--${actionLetter}7`))
207
228
  const isReversal = true
208
229
  const transferStateChange = {
209
230
  transferId: transferInfo.transferId,
@@ -211,23 +232,20 @@ const positions = async (error, messages) => {
211
232
  reason: ErrorHandler.Enums.FSPIOPErrorCodes.TRANSFER_EXPIRED.message
212
233
  }
213
234
  await PositionService.changeParticipantPosition(transferInfo.participantCurrencyId, isReversal, transferInfo.amount, transferStateChange)
214
- const fspiopError = ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.EXPIRED_ERROR, null, null, null, payload.extensionList)
215
- if (action === Enum.Events.Event.Action.TIMEOUT_RESERVED) {
216
- eventDetail.action = Enum.Events.Event.Action.ABORT
217
- }
235
+ const fspiopError = ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.TRANSFER_EXPIRED, null, null, null, payload.extensionList)
218
236
  await Kafka.proceed(Config.KAFKA_CONFIG, params, { consumerCommit, fspiopError: fspiopError.toApiErrorObject(Config.ERROR_HANDLING), eventDetail })
219
237
  throw fspiopError
220
238
  }
221
239
  } else {
222
- Logger.info(Utility.breadcrumb(location, `invalidEventTypeOrAction--${actionLetter}8`))
240
+ Logger.isInfoEnabled && Logger.info(Utility.breadcrumb(location, `invalidEventTypeOrAction--${actionLetter}8`))
223
241
  const fspiopError = ErrorHandler.Factory.createInternalServerFSPIOPError(`Invalid event action:(${action}) and/or type:(${eventType})`)
224
242
  const eventDetail = { functionality: Enum.Events.Event.Type.NOTIFICATION, action: Enum.Events.Event.Action.POSITION }
225
243
  await Kafka.proceed(Config.KAFKA_CONFIG, params, { consumerCommit, fspiopError: fspiopError.toApiErrorObject(Config.ERROR_HANDLING), eventDetail, fromSwitch })
226
244
  throw fspiopError
227
245
  }
228
246
  } catch (err) {
229
- Logger.error(`${Utility.breadcrumb(location)}::${err.message}--0`)
230
- histTimerEnd({ success: false, fspId: Config.INSTRUMENTATION_METRICS_LABELS.fspId })
247
+ Logger.isErrorEnabled && Logger.error(`${Utility.breadcrumb(location)}::${err.message}--0`)
248
+ histTimerEnd({ success: false, fspId: Config.INSTRUMENTATION_METRICS_LABELS.fspId, action })
231
249
  const fspiopError = ErrorHandler.Factory.reformatFSPIOPError(err)
232
250
  const state = new EventSdk.EventStateMetadata(EventSdk.EventStatusType.failed, fspiopError.apiErrorCode.code, fspiopError.apiErrorCode.message)
233
251
  await span.error(fspiopError, state)
@@ -250,6 +268,7 @@ const positions = async (error, messages) => {
250
268
  */
251
269
  const registerPositionHandler = async () => {
252
270
  try {
271
+ await SettlementModelCached.initialize()
253
272
  const positionHandler = {
254
273
  command: positions,
255
274
  topicName: Kafka.transformGeneralTopicName(Config.KAFKA_CONFIG.TOPIC_TEMPLATES.GENERAL_TOPIC_TEMPLATE.TEMPLATE, Enum.Events.Event.Type.POSITION, Enum.Events.Event.Action.PREPARE),
@@ -259,6 +278,7 @@ const registerPositionHandler = async () => {
259
278
  await Consumer.createHandler(positionHandler.topicName, positionHandler.config, positionHandler.command)
260
279
  return true
261
280
  } catch (err) {
281
+ Logger.isErrorEnabled && Logger.error(err)
262
282
  throw ErrorHandler.Factory.reformatFSPIOPError(err)
263
283
  }
264
284
  }
@@ -275,6 +295,7 @@ const registerAllHandlers = async () => {
275
295
  try {
276
296
  return await registerPositionHandler()
277
297
  } catch (err) {
298
+ Logger.isErrorEnabled && Logger.error(err)
278
299
  throw ErrorHandler.Factory.reformatFSPIOPError(err)
279
300
  }
280
301
  }
@@ -58,23 +58,22 @@ const ErrorHandler = require('@mojaloop/central-services-error-handling')
58
58
  const registerAllHandlers = async () => {
59
59
  try {
60
60
  const modules = await requireGlob(['./**/handler.js'])
61
- Logger.info(JSON.stringify(modules))
62
61
  for (const key in modules) {
63
- Logger.info(`Registering handler module[${key}]: ${JSON.stringify(modules[key])}`)
62
+ Logger.isInfoEnabled && Logger.info(`Registering handler module[${key}]: ${JSON.stringify(modules[key])}`)
64
63
  if (Object.prototype.hasOwnProperty.call(modules[key], 'handler')) {
65
64
  const handlerObject = modules[key]
66
- Logger.info(JSON.stringify(handlerObject.handler))
67
65
  await handlerObject.handler.registerAllHandlers()
68
66
  } else {
69
- for (const i in modules[key]) {
70
- const handlerObject = modules[key][i]
71
- Logger.info(JSON.stringify(handlerObject.handler))
67
+ for (const subKey in modules[key]) {
68
+ const handlerObject = modules[key][subKey]
69
+ Logger.isInfoEnabled && Logger.info(` ⌙ Registering sub-handler module[${key}-${subKey}]: ${JSON.stringify(handlerObject)}`)
72
70
  await handlerObject.handler.registerAllHandlers()
73
71
  }
74
72
  }
75
73
  }
76
74
  return true
77
75
  } catch (err) {
76
+ Logger.isErrorEnabled && Logger.error(err)
78
77
  throw ErrorHandler.Factory.reformatFSPIOPError(err)
79
78
  }
80
79
  }
@@ -101,6 +100,7 @@ module.exports = {
101
100
  bulk: {
102
101
  registerBulkPrepareHandler: BulkHandlers.registerBulkPrepareHandler,
103
102
  registerBulkFulfilHandler: BulkHandlers.registerBulkFulfilHandler,
104
- registerBulkProcessingHandler: BulkHandlers.registerBulkProcessingHandler
103
+ registerBulkProcessingHandler: BulkHandlers.registerBulkProcessingHandler,
104
+ registerBulkGetHandler: BulkHandlers.registerGetBulkTransferHandler
105
105
  }
106
106
  }
@@ -43,7 +43,8 @@ const Producer = require('@mojaloop/central-services-stream').Util.Producer
43
43
  const Utility = require('@mojaloop/central-services-shared').Util
44
44
  const ErrorHandler = require('@mojaloop/central-services-error-handling')
45
45
  const EventSdk = require('@mojaloop/event-sdk')
46
-
46
+ const resourceVersions = require('@mojaloop/central-services-shared').Util.resourceVersions
47
+ const Logger = require('@mojaloop/central-services-logger')
47
48
  let timeoutJob
48
49
  let isRegistered
49
50
 
@@ -77,8 +78,8 @@ const timeout = async () => {
77
78
  try {
78
79
  const state = Utility.StreamingProtocol.createEventState(Enum.Events.EventStatus.FAILURE.status, fspiopError.errorInformation.errorCode, fspiopError.errorInformation.errorDescription)
79
80
  const metadata = Utility.StreamingProtocol.createMetadataWithCorrelatedEvent(result[i].transferId, Enum.Kafka.Topics.NOTIFICATION, Enum.Events.Event.Action.TIMEOUT_RECEIVED, state)
80
- const headers = Utility.Http.SwitchDefaultHeaders(result[i].payerFsp, Enum.Http.HeaderResources.TRANSFERS, Enum.Http.Headers.FSPIOP.SWITCH.value)
81
- const message = Utility.StreamingProtocol.createMessage(result[i].transferId, result[i].payeeFsp, result[i].payerFsp, metadata, headers, fspiopError, { id: result[i].transferId }, 'application/vnd.interoperability.transfers+json;version=1.0')
81
+ const headers = Utility.Http.SwitchDefaultHeaders(result[i].payerFsp, Enum.Http.HeaderResources.TRANSFERS, Enum.Http.Headers.FSPIOP.SWITCH.value, resourceVersions[Enum.Http.HeaderResources.TRANSFERS].contentVersion)
82
+ 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}`)
82
83
  span.setTags(Utility.EventFramework.getTransferSpanTags({ payload: message.content.payload, headers }, Enum.Events.Event.Type.TRANSFER, Enum.Events.Event.Action.TIMEOUT_RECEIVED))
83
84
  await span.audit({
84
85
  state,
@@ -111,6 +112,7 @@ const timeout = async () => {
111
112
  }
112
113
  }
113
114
  } catch (err) {
115
+ Logger.isErrorEnabled && Logger.error(err)
114
116
  const fspiopError = ErrorHandler.Factory.reformatFSPIOPError(err)
115
117
  const state = new EventSdk.EventStateMetadata(EventSdk.EventStatusType.failed, fspiopError.apiErrorCode.code, fspiopError.apiErrorCode.message)
116
118
  await span.error(fspiopError, state)
@@ -129,6 +131,7 @@ const timeout = async () => {
129
131
  result
130
132
  }
131
133
  } catch (err) {
134
+ Logger.isErrorEnabled && Logger.error(err)
132
135
  throw ErrorHandler.Factory.reformatFSPIOPError(err)
133
136
  }
134
137
  }
@@ -175,13 +178,14 @@ const registerTimeoutHandler = async () => {
175
178
  cronTime: Config.HANDLERS_TIMEOUT_TIMEXP,
176
179
  onTick: timeout,
177
180
  start: false,
178
- timeZone: Config.HANDLERS_CRON_TIMEZONE
181
+ timeZone: Config.HANDLERS_TIMEOUT_TIMEZONE
179
182
  })
180
183
  isRegistered = true
181
184
 
182
185
  await timeoutJob.start()
183
186
  return true
184
187
  } catch (err) {
188
+ Logger.isErrorEnabled && Logger.error(err)
185
189
  throw ErrorHandler.Factory.reformatFSPIOPError(err)
186
190
  }
187
191
  }
@@ -201,6 +205,7 @@ const registerAllHandlers = async () => {
201
205
  }
202
206
  return true
203
207
  } catch (err) {
208
+ Logger.isErrorEnabled && Logger.error(err)
204
209
  throw ErrorHandler.Factory.reformatFSPIOPError(err)
205
210
  }
206
211
  }