@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
@@ -25,7 +25,7 @@
25
25
  'use strict'
26
26
 
27
27
  const Test = require('tape')
28
- const Joi = require('@hapi/joi')
28
+ const Joi = require('joi')
29
29
  const Logger = require('@mojaloop/central-services-logger')
30
30
  const Db = require('@mojaloop/central-services-database').Db
31
31
 
@@ -0,0 +1,62 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2017 Bill & Melinda Gates Foundation
5
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+ http://www.apache.org/licenses/LICENSE-2.0
7
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
8
+ Contributors
9
+ --------------
10
+ This is the official list of the Mojaloop project contributors for this file.
11
+ Names of the original copyright holders (individuals or organizations)
12
+ should be listed with a '*' in the first column. People who have
13
+ contributed from an organization can be listed under the organization
14
+ that actually holds the copyright for their contributions (see the
15
+ Gates Foundation organization for an example). Those individuals should have
16
+ their names indented and be marked with a '-'. Email address can be added
17
+ optionally within square brackets <email>.
18
+ * Gates Foundation
19
+ - Name Surname <name.surname@gatesfoundation.com>
20
+
21
+ * ModusBox
22
+ - Georgi Georgiev <georgi.georgiev@modusbox.com>
23
+ - Valentin Genev <valentin.genev@modusbox.com>
24
+ - Nikolay Anastasov <nikolay.anastasov@modusbox.com>
25
+ - Shashikant Hirugade <shashikant.hirugade@modusbox.com>
26
+ - Rajiv Mothilal <rajiv.mothilal@modusbox.com>
27
+ --------------
28
+ ******/
29
+
30
+ 'use strict'
31
+
32
+ const Config = require('../../../src/lib/config')
33
+ const Enum = require('@mojaloop/central-services-shared').Enum
34
+ const ErrorHandler = require('@mojaloop/central-services-error-handling')
35
+ const ParticipantService = require('../../../src/domain/participant')
36
+
37
+ const testData = {
38
+ currency: 'USD'
39
+ }
40
+
41
+ exports.prepareData = async () => {
42
+ try {
43
+ const hubReconciliationAccountExists = await ParticipantService.hubAccountExists(testData.currency, Enum.Accounts.LedgerAccountType.HUB_RECONCILIATION)
44
+ if (!hubReconciliationAccountExists) {
45
+ await ParticipantService.createHubAccount(Config.HUB_ID, testData.currency, Enum.Accounts.LedgerAccountType.HUB_RECONCILIATION)
46
+ }
47
+ const hubMlnsAccountExists = await ParticipantService.hubAccountExists(testData.currency, Enum.Accounts.LedgerAccountType.HUB_MULTILATERAL_SETTLEMENT)
48
+ if (!hubMlnsAccountExists) {
49
+ await ParticipantService.createHubAccount(Config.HUB_ID, testData.currency, Enum.Accounts.LedgerAccountType.HUB_MULTILATERAL_SETTLEMENT)
50
+ }
51
+ const hubReconciliationAccountExistsZAR = await ParticipantService.hubAccountExists('ZAR', Enum.Accounts.LedgerAccountType.HUB_RECONCILIATION)
52
+ if (!hubReconciliationAccountExistsZAR) {
53
+ await ParticipantService.createHubAccount(Config.HUB_ID, 'ZAR', Enum.Accounts.LedgerAccountType.HUB_RECONCILIATION)
54
+ }
55
+ const hubMlnsAccountExistsZAR = await ParticipantService.hubAccountExists('ZAR', Enum.Accounts.LedgerAccountType.HUB_MULTILATERAL_SETTLEMENT)
56
+ if (!hubMlnsAccountExistsZAR) {
57
+ await ParticipantService.createHubAccount(Config.HUB_ID, 'ZAR', Enum.Accounts.LedgerAccountType.HUB_MULTILATERAL_SETTLEMENT)
58
+ }
59
+ } catch (err) {
60
+ throw ErrorHandler.Factory.reformatFSPIOPError(err)
61
+ }
62
+ }
@@ -51,7 +51,7 @@ exports.prepareData = async () => {
51
51
  exports.deletePreparedData = async (ilpId, transferId, payerName, payeeName) => {
52
52
  try {
53
53
  return await IlpPacketModel.destroyByTransferId({
54
- transferId: transferId
54
+ transferId
55
55
  }).then(async () => {
56
56
  return TransferPreparationModule.deletePreparedData(transferId, payerName, payeeName)
57
57
  })
@@ -0,0 +1,80 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2017 Bill & Melinda Gates Foundation
5
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+ http://www.apache.org/licenses/LICENSE-2.0
7
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
8
+ Contributors
9
+ --------------
10
+ This is the official list of the Mojaloop project contributors for this file.
11
+ Names of the original copyright holders (individuals or organizations)
12
+ should be listed with a '*' in the first column. People who have
13
+ contributed from an organization can be listed under the organization
14
+ that actually holds the copyright for their contributions (see the
15
+ Gates Foundation organization for an example). Those individuals should have
16
+ their names indented and be marked with a '-'. Email address can be added
17
+ optionally within square brackets <email>.
18
+ * Gates Foundation
19
+ - Name Surname <name.surname@gatesfoundation.com>
20
+
21
+ * Vijaya Kumar Guthi <vijaya.guthi@modusbox.com>
22
+ --------------
23
+ ******/
24
+
25
+ 'use strict'
26
+
27
+ const Uuid = require('uuid4')
28
+ const TransferService = require('../../../src/domain/transfer')
29
+ const ErrorHandler = require('@mojaloop/central-services-error-handling')
30
+ const Time = require('@mojaloop/central-services-shared').Util.Time
31
+ const Comparators = require('@mojaloop/central-services-shared').Util.Comparators
32
+ const CentralEnums = require('@mojaloop/central-services-shared').Enum
33
+ const Config = require('../../../src/lib/config')
34
+ const Enums = require('../../../src/lib/enumCached')
35
+
36
+ const recordFundsInSampleData = {
37
+ currency: 'USD',
38
+ amount: 1000.0
39
+ }
40
+
41
+ exports.recordFundsIn = async (participantName, participantCurrencyId, recordFundsInObj = {}) => {
42
+ try {
43
+ const transferId = Uuid()
44
+ const payload = {
45
+ transferId,
46
+ externalReference: 'string',
47
+ action: CentralEnums.Transfers.AdminTransferAction.RECORD_FUNDS_IN,
48
+ amount: {
49
+ amount: recordFundsInObj.amount || recordFundsInSampleData.amount,
50
+ currency: recordFundsInObj.currency || recordFundsInSampleData.currency
51
+ },
52
+ reason: 'Reason for in flow of funds',
53
+ extensionList: {}
54
+ }
55
+
56
+ const fundsInPayload = {
57
+ ...payload,
58
+ participantCurrencyId,
59
+ payee: Config.HUB_NAME,
60
+ payer: participantName
61
+ }
62
+
63
+ await Enums.initialize()
64
+ const enums = {
65
+ transferState: await Enums.getEnums('transferState'),
66
+ transferParticipantRoleType: await Enums.getEnums('transferParticipantRoleType'),
67
+ ledgerAccountType: await Enums.getEnums('ledgerAccountType'),
68
+ ledgerEntryType: await Enums.getEnums('ledgerEntryType'),
69
+ hubParticipant: await Enums.getEnums('hubParticipant')
70
+ }
71
+
72
+ const transactionTimestamp = Time.getUTCString(new Date())
73
+
74
+ await Comparators.duplicateCheckComparator(transferId, fundsInPayload, TransferService.getTransferDuplicateCheck, TransferService.saveTransferDuplicateCheck)
75
+ await TransferService.recordFundsIn(fundsInPayload, transactionTimestamp, enums)
76
+ return true
77
+ } catch (err) {
78
+ throw ErrorHandler.Factory.reformatFSPIOPError(err)
79
+ }
80
+ }
@@ -47,7 +47,12 @@ exports.prepareLimitAndInitialPosition = async (participantName, limitAndInitial
47
47
  },
48
48
  initialPosition: limitAndInitialPositionObj.initialPosition || limitAndInitialPositionSampleData.initialPosition
49
49
  }
50
- return await Model.addLimitAndInitialPosition(participantName, limitAndInitialPosition)
50
+ await Model.addLimitAndInitialPosition(participantName, limitAndInitialPosition)
51
+ return {
52
+ participantPosition: {
53
+ value: limitAndInitialPositionObj.initialPosition || limitAndInitialPositionSampleData.initialPosition
54
+ }
55
+ }
51
56
  } catch (err) {
52
57
  throw ErrorHandler.Factory.reformatFSPIOPError(err)
53
58
  }
@@ -0,0 +1,88 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2017 Bill & Melinda Gates Foundation
5
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+ http://www.apache.org/licenses/LICENSE-2.0
7
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
8
+ Contributors
9
+ --------------
10
+ This is the official list of the Mojaloop project contributors for this file.
11
+ Names of the original copyright holders (individuals or organizations)
12
+ should be listed with a '*' in the first column. People who have
13
+ contributed from an organization can be listed under the organization
14
+ that actually holds the copyright for their contributions (see the
15
+ Gates Foundation organization for an example). Those individuals should have
16
+ their names indented and be marked with a '-'. Email address can be added
17
+ optionally within square brackets <email>.
18
+ * Gates Foundation
19
+ - Name Surname <name.surname@gatesfoundation.com>
20
+
21
+ * ModusBox
22
+ - Georgi Georgiev <georgi.georgiev@modusbox.com>
23
+ - Valentin Genev <valentin.genev@modusbox.com>
24
+ - Nikolay Anastasov <nikolay.anastasov@modusbox.com>
25
+ - Shashikant Hirugade <shashikant.hirugade@modusbox.com>
26
+ - Rajiv Mothilal <rajiv.mothilal@modusbox.com>
27
+ --------------
28
+ ******/
29
+
30
+ 'use strict'
31
+
32
+ const Model = require('../../../src/domain/settlement')
33
+ const Enums = require('../../../src/lib/enumCached')
34
+ const ErrorHandler = require('@mojaloop/central-services-error-handling')
35
+ const Db = require('@mojaloop/central-services-database').Db
36
+ const Cache = require('../../../src/lib/cache')
37
+ const ParticipantCached = require('../../../src/models/participant/participantCached')
38
+ const ParticipantCurrencyCached = require('../../../src/models/participant/participantCurrencyCached')
39
+ const ParticipantLimitCached = require('../../../src/models/participant/participantLimitCached')
40
+ const SettlementModelCached = require('../../../src/models/settlement/settlementModelCached')
41
+ const Config = require('../../../src/lib/config')
42
+
43
+ const settlementModels = [
44
+ {
45
+ name: 'DEFERREDNETUSD',
46
+ settlementGranularity: 'NET',
47
+ settlementInterchange: 'MULTILATERAL',
48
+ settlementAccountType: 'SETTLEMENT',
49
+ settlementDelay: 'DEFERRED',
50
+ ledgerAccountType: 'POSITION',
51
+ autoPositionReset: true,
52
+ currency: 'USD',
53
+ requireLiquidityCheck: true
54
+ },
55
+ {
56
+ name: 'DEFERREDNET',
57
+ settlementGranularity: 'NET',
58
+ settlementInterchange: 'MULTILATERAL',
59
+ settlementAccountType: 'SETTLEMENT',
60
+ settlementDelay: 'DEFERRED',
61
+ ledgerAccountType: 'POSITION',
62
+ autoPositionReset: true,
63
+ requireLiquidityCheck: true
64
+ }
65
+ ]
66
+
67
+ exports.prepareData = async () => {
68
+ await Db.connect(Config.DATABASE)
69
+ await Enums.initialize()
70
+ await ParticipantCached.initialize()
71
+ await ParticipantCurrencyCached.initialize()
72
+ await ParticipantLimitCached.initialize()
73
+ await SettlementModelCached.initialize()
74
+ await Cache.initCache()
75
+
76
+ try {
77
+ const settlementModelUSDExists = await Model.getByName(settlementModels[0].name)
78
+ const settlementModelDefaultExists = await Model.getByName(settlementModels[0].name)
79
+ if (!settlementModelUSDExists) {
80
+ await Model.createSettlementModel(settlementModels[0])
81
+ }
82
+ if (!settlementModelDefaultExists) {
83
+ await Model.createSettlementModel(settlementModels[1])
84
+ }
85
+ } catch (err) {
86
+ throw ErrorHandler.Factory.reformatFSPIOPError(err)
87
+ }
88
+ }
@@ -0,0 +1,163 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2017 Bill & Melinda Gates Foundation
5
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10
+
11
+ Contributors
12
+ --------------
13
+ This is the official list of the Mojaloop project contributors for this file.
14
+ Names of the original copyright holders (individuals or organizations)
15
+ should be listed with a '*' in the first column. People who have
16
+ contributed from an organization can be listed under the organization
17
+ that actually holds the copyright for their contributions (see the
18
+ Gates Foundation organization for an example). Those individuals should have
19
+ their names indented and be marked with a '-'. Email address can be added
20
+ optionally within square brackets <email>.
21
+
22
+ * Gates Foundation
23
+ - Name Surname <name.surname@gatesfoundation.com>
24
+
25
+ - Lewis Daly <lewisd@crosslaketech.com>
26
+ --------------
27
+ ******/
28
+ 'use strict'
29
+
30
+ const Logger = require('@mojaloop/central-services-logger')
31
+ const Consumer = require('@mojaloop/central-services-stream').Kafka.Consumer
32
+
33
+ /**
34
+ * @class TestConsumer
35
+ * @description A Kafka consumer that listens for events from our test harness, and
36
+ * makes it easy to ensure that
37
+ */
38
+ class TestConsumer {
39
+ constructor (handlers) {
40
+ this.handlers = handlers
41
+ this.eventLog = []
42
+ this.consumers = []
43
+ }
44
+
45
+ /**
46
+ * @function startListening
47
+ * @description Start listening for Consumers
48
+ */
49
+ async startListening () {
50
+ await Promise.all(this.handlers.map(async handlerConfig => {
51
+ const handler = {
52
+ command: this.onEvent.bind(this),
53
+ topicName: handlerConfig.topicName,
54
+ config: handlerConfig.config
55
+ }
56
+ // Override the client and group ids:
57
+ handler.config.rdkafkaConf['client.id'] = 'testConsumer'
58
+ handler.config.rdkafkaConf['group.id'] = 'testConsumerGroup'
59
+
60
+ Logger.warn(`TestConsumer.startListening(): registering consumer with topicName: ${handler.topicName}`)
61
+ const topics = [handler.topicName]
62
+ const consumer = new Consumer(topics, handler.config)
63
+ await consumer.connect()
64
+ await consumer.consume(handler.command)
65
+ this.consumers.push(consumer)
66
+ }))
67
+ }
68
+
69
+ /**
70
+ * @function destroy
71
+ * @description Stop listening for the registered Consumers
72
+ * and release and open files
73
+ */
74
+ async destroy () {
75
+ Logger.warn(`TestConsumer.destroy(): destroying ${this.consumers.length} consumers`)
76
+ await Promise.all(this.consumers.map(async c => c.disconnect()))
77
+ }
78
+
79
+ /**
80
+ * @function peek
81
+ * @description Read the last event that we saw
82
+ */
83
+ peek () {
84
+ Logger.warn(`peeking at event log. EventLogLength:${this.eventLog.length}`)
85
+ return this.eventLog[0]
86
+ }
87
+
88
+ /**
89
+ * @function peekOrDie
90
+ * @description Read the last event that we saw. Throw an error if not found
91
+ */
92
+ peekOrDie () {
93
+ const peekResult = this.peek()
94
+ if (!peekResult) {
95
+ throw new Error('TestConsumer.peekOrDie(): `peek()` found no events.')
96
+ }
97
+ return peekResult
98
+ }
99
+
100
+ /**
101
+ * @function getAllEvents
102
+ * @description Get a list of all events
103
+ * @param {string} eventId
104
+ * @returns {Array<event>} A list of the events found for the eventId
105
+ */
106
+ getAllEvents () {
107
+ return this.eventLog
108
+ }
109
+
110
+ /**
111
+ * @function getEventsForFilter
112
+ * @description Get a list of all events that match a basic filter
113
+ * @param {*} filters
114
+ * @param {string} filters.action - String matching filter for `event.value.metadata.event.action`
115
+ * @param {string} filters.topicFilter - String matching filter for `event.topic`
116
+ * @param {string} filters.valueFromFilter - String matching filter for `event.value.from`
117
+ * @param {string} filters.valueToFilter - String matching filter for `event.value.to`
118
+ * @returns {Array<event>} A list of the events found for the eventId
119
+ * @throws {Error} If no events could be found for the given set of filters
120
+ */
121
+ getEventsForFilter (filters) {
122
+ const { action, topicFilter, valueFromFilter, valueToFilter } = filters
123
+
124
+ let events = this.eventLog
125
+ if (topicFilter !== undefined) {
126
+ events = events.filter(e => e.topic === topicFilter)
127
+ }
128
+
129
+ if (action !== undefined) {
130
+ events = events.filter(e => e.value.metadata.event.action === action)
131
+ }
132
+
133
+ if (valueFromFilter !== undefined) {
134
+ events = events.filter(e => e.value.from === valueFromFilter)
135
+ }
136
+
137
+ if (valueToFilter !== undefined) {
138
+ events = events.filter(e => e.value.to === valueToFilter)
139
+ }
140
+
141
+ if (events.length === 0) {
142
+ throw new Error(`No events found for given filters" ${JSON.stringify(filters)}`)
143
+ }
144
+
145
+ return events
146
+ }
147
+
148
+ /**
149
+ * @function clearEvents
150
+ * @description Clears the event queue
151
+ */
152
+ clearEvents () {
153
+ this.eventLog = []
154
+ }
155
+
156
+ onEvent (arg1, events) {
157
+ Logger.warn('TestConsumer.onEvent')
158
+ Logger.debug(`TestConsumer.onEvent - received event: ${JSON.stringify(events)}`)
159
+ this.eventLog = this.eventLog.concat(events)
160
+ }
161
+ }
162
+
163
+ module.exports = TestConsumer
@@ -98,7 +98,6 @@ exports.transferPrepare = async () => {
98
98
  const transferObj = requestBodys().messageProtocol()
99
99
  await Producer.produceMessage(transferObj, topicConfTransferPrepare, config)
100
100
  return transferObj.id
101
- // return true
102
101
  }
103
102
 
104
103
  const topicConfTransferFulfil = {
@@ -50,7 +50,7 @@ exports.prepareData = async () => {
50
50
 
51
51
  }
52
52
  const transfer = {
53
- transferId: transferId,
53
+ transferId,
54
54
  amount: payload.amount.amount,
55
55
  currencyId: payload.amount.currency,
56
56
  ilpCondition: payload.condition,
@@ -61,7 +61,7 @@ exports.prepareData = async () => {
61
61
  exports.deletePreparedData = async (transferId, payerName, payeeName) => {
62
62
  try {
63
63
  return await Model.truncate({
64
- transferId: transferId
64
+ transferId
65
65
  }).then(async () => {
66
66
  await TransferStatePreparationHelper.deletePreparedData()
67
67
  await TransferPreparationModule.deletePreparedData(transferId, payerName, payeeName)
@@ -86,7 +86,6 @@ exports.prepareData = async () => {
86
86
  })
87
87
 
88
88
  await TransferParticipantModel.saveTransferParticipant({
89
- transferParticipantId: transferDuplicateCheckResult.participantPayerResult.participant.participantId,
90
89
  transferId: transferResult.transfer.transferId,
91
90
  participantCurrencyId: transferDuplicateCheckResult.participantPayerResult.participantCurrencyId,
92
91
  transferParticipantRoleTypeId: Enum.Accounts.TransferParticipantRoleType.PAYER_DFSP,
@@ -95,7 +94,6 @@ exports.prepareData = async () => {
95
94
  })
96
95
 
97
96
  await TransferParticipantModel.saveTransferParticipant({
98
- transferParticipantId: transferDuplicateCheckResult.participantPayeeResult.participant.participantId,
99
97
  transferId: transferResult.transfer.transferId,
100
98
  participantCurrencyId: transferDuplicateCheckResult.participantPayeeResult.participantCurrencyId,
101
99
  transferParticipantRoleTypeId: Enum.Accounts.TransferParticipantRoleType.PAYEE_DFSP,
@@ -122,13 +120,13 @@ exports.prepareData = async () => {
122
120
  exports.deletePreparedData = async (transferId, payerName, payeeName) => {
123
121
  try {
124
122
  return await StateChangeModel.truncate({
125
- transferId: transferId
123
+ transferId
126
124
  }).then(async () => {
127
125
  await IlpModel.destroyByTransferId({
128
- transferId: transferId
126
+ transferId
129
127
  }).then(async () => {
130
128
  await TransferExtensionModel.destroyByTransferId({
131
- transferId: transferId
129
+ transferId
132
130
  }).then(async () => {
133
131
  // await TransferStatePreparationHelper.deletePreparedData()
134
132
  await TransferFacade.destroyByTransferId({ transferId: 'test_tr_id' }).then(async () => {
@@ -36,12 +36,18 @@ const Config = require('../../../../src/lib/config')
36
36
  const Model = require('../../../../src/models/transfer/transferStateChange')
37
37
  const HelperModule = require('../../helpers')
38
38
  const Time = require('@mojaloop/central-services-shared').Util.Time
39
+ const ParticipantCached = require('../../../../src/models/participant/participantCached')
40
+ const ParticipantCurrencyCached = require('../../../../src/models/participant/participantCurrencyCached')
41
+ const ParticipantLimitCached = require('../../../../src/models/participant/participantLimitCached')
39
42
 
40
43
  Test('Transfer State Change model test', async (stateChangeTest) => {
41
44
  let stateChangePrepareResult = {}
42
45
  await stateChangeTest.test('setup', async (assert) => {
43
46
  try {
44
47
  await Db.connect(Config.DATABASE).then(async () => {
48
+ await ParticipantCached.initialize()
49
+ await ParticipantCurrencyCached.initialize()
50
+ await ParticipantLimitCached.initialize()
45
51
  await Cache.initCache()
46
52
  assert.pass('setup OK')
47
53
  assert.end()
@@ -0,0 +1,126 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2017 Bill & Melinda Gates Foundation
5
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+ http://www.apache.org/licenses/LICENSE-2.0
7
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
8
+ Contributors
9
+ --------------
10
+ This is the official list of the Mojaloop project contributors for this file.
11
+ Names of the original copyright holders (individuals or organizations)
12
+ should be listed with a '*' in the first column. People who have
13
+ contributed from an organization can be listed under the organization
14
+ that actually holds the copyright for their contributions (see the
15
+ Gates Foundation organization for an example). Those individuals should have
16
+ their names indented and be marked with a '-'. Email address can be added
17
+ optionally within square brackets <email>.
18
+ * Gates Foundation
19
+ - Name Surname <name.surname@gatesfoundation.com>
20
+
21
+ * ModusBox
22
+ - Claudio Viola <claudio.viola@modusbox.com>
23
+ --------------
24
+ ******/
25
+ 'use strict'
26
+
27
+ const Test = require('tapes')(require('tape'))
28
+ const Sinon = require('sinon')
29
+ const Logger = require('@mojaloop/central-services-logger')
30
+ const Handler = require('../../../../src/api/ledgerAccountTypes/handler')
31
+ const LedgerAccountTypeService = require('../../../../src/domain/ledgerAccountTypes')
32
+
33
+ Test('LedgerAccountTypes', ledgerAccountTypesHandlerTest => {
34
+ let sandbox
35
+
36
+ ledgerAccountTypesHandlerTest.beforeEach(test => {
37
+ sandbox = Sinon.createSandbox()
38
+ sandbox.stub(Logger)
39
+ sandbox.stub(LedgerAccountTypeService)
40
+ test.end()
41
+ })
42
+
43
+ ledgerAccountTypesHandlerTest.afterEach(test => {
44
+ sandbox.restore()
45
+ test.end()
46
+ })
47
+
48
+ ledgerAccountTypesHandlerTest.test('Handler Test', async handlerTest => {
49
+ handlerTest.test('create should create a new ledgerAccountType model', async function (test) {
50
+ const payload = {
51
+ name: 'INTERCHANGE_FEE_SETTLEMENT',
52
+ description: 'settlement account type for interchange fees',
53
+ isActive: true,
54
+ isSettleable: true
55
+ }
56
+ LedgerAccountTypeService.getByName.returns(Promise.resolve(false))
57
+ const reply = {
58
+ response: () => {
59
+ return {
60
+ code: statusCode => {
61
+ test.equal(statusCode, 201, 'should return a 201')
62
+ test.end()
63
+ }
64
+ }
65
+ }
66
+ }
67
+ await Handler.create({ payload }, reply)
68
+ })
69
+
70
+ handlerTest.test('create should fail if the ledger Account type model exists', async function (test) {
71
+ const payload = {
72
+ name: 'INTERCHANGE_FEE_SETTLEMENT',
73
+ description: 'settlement account type for interchange fees',
74
+ isActive: true,
75
+ isSettleable: true
76
+ }
77
+ LedgerAccountTypeService.getByName.returns(Promise.resolve(true))
78
+ try {
79
+ await Handler.create({ payload })
80
+ test.fail('An error should have been thrown')
81
+ } catch (e) {
82
+ test.ok(e instanceof Error, 'should return an error')
83
+ test.equal(e.message, 'This Ledger Account Type already exists', 'should return an error with the message This Ledger Account Type already exists')
84
+ test.end()
85
+ }
86
+ })
87
+
88
+ handlerTest.test('create should fail if some error occurs', async function (test) {
89
+ const payload = {
90
+ name: 'INTERCHANGE_FEE_SETTLEMENT',
91
+ description: 'settlement account type for interchange fees',
92
+ isActive: true,
93
+ isSettleable: true
94
+ }
95
+ LedgerAccountTypeService.getByName.rejects(new Error('Something happened'))
96
+
97
+ try {
98
+ await Handler.create({ payload })
99
+ test.fail('Error not thrown')
100
+ } catch (e) {
101
+ test.ok(e instanceof Error, 'should return an instance of an error')
102
+ test.equal(e.message, 'Something happened', 'should return the error message thrown')
103
+ test.end()
104
+ }
105
+ })
106
+
107
+ handlerTest.test('getAll should return all the ledgerAccount Types models', async function (test) {
108
+ const ledgerAccountTypes = [
109
+ {
110
+ name: 'INTERCHANGE_FEE_SETTLEMENT',
111
+ description: 'settlement account type for interchange fees',
112
+ isActive: true,
113
+ isSettleable: true
114
+ }
115
+ ]
116
+ LedgerAccountTypeService.getAll.returns(Promise.resolve(ledgerAccountTypes))
117
+ const result = await Handler.getAll()
118
+ test.deepEqual(result, ledgerAccountTypes, 'should return an array of ledger account types')
119
+ test.end()
120
+ })
121
+
122
+ handlerTest.end()
123
+ })
124
+
125
+ ledgerAccountTypesHandlerTest.end()
126
+ })