Skip to content

Commit

Permalink
fix: Settle only configured settlement models while running CGS handl…
Browse files Browse the repository at this point in the history
…er (#344)

* fix:settle only configured models

* updates for transferSettlement facade and model

* made transferSettlement handler print stack trace

* updated loggers for transferSettlement::processMsgFulfil

* added error check for missing settlement models

* fix: fixed minor issues and tests

Co-authored-by: Miguel de Barros <[email protected]>
  • Loading branch information
shashi165 and mdebarros authored Feb 14, 2021
1 parent 74a2b2c commit 5bf0b97
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 15 deletions.
33 changes: 24 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "central-settlement",
"description": "Central settlements hosted by a scheme to record and make settlements.",
"version": "12.0.2",
"version": "12.0.3",
"license": "Apache-2.0",
"private": false,
"author": "ModusBox",
Expand Down Expand Up @@ -63,7 +63,7 @@
"chai-subset": "1.6.0",
"jest": "26.6.3",
"jest-junit": "12.0.0",
"eslint": "7.19.0",
"eslint": "7.20.0",
"faucet": "0.0.1",
"get-port": "5.1.1",
"node-fetch": "2.6.1",
Expand Down
15 changes: 14 additions & 1 deletion src/domain/transferSettlement/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,26 @@

const ErrorHandler = require('@mojaloop/central-services-error-handling')
const TransferSettlementModel = require('../../models/transferSettlement')
const Logger = require('@mojaloop/central-services-logger')

module.exports = {
processMsgFulfil: async function (transferEventId, transferEventStateStatus, trx) {
Logger.debug(`transferSettlement::processMsgFulfil(transferEventId=${transferEventId}, transferEventStateStatus=${transferEventStateStatus}) - start`)
try {
await TransferSettlementModel.updateStateChange(transferEventId, transferEventStateStatus, trx)
// TODO: Refactor to use ENUM for settlementGranularityName = 'GROSS' function input param
// Get the 'GROSS' settlement model by transfer
const grossSettlementModel = await TransferSettlementModel.getSettlementModelByTransferId(transferEventId, 'GROSS')
Logger.debug(`transferSettlement::processMsgFulfil - result grossSettlementModel=${JSON.stringify(grossSettlementModel)}`)
Logger.debug(`transferSettlement::processMsgFulfil - grossSettlementModel.length=${grossSettlementModel.length}`)
if (grossSettlementModel.length > 0) {
Logger.debug(`transferSettlement::processMsgFulfil - updateStateChange(transferEventId=${transferEventId}, transferEventStateStatus=${transferEventStateStatus}) - start`)
await TransferSettlementModel.updateStateChange(transferEventId, transferEventStateStatus, trx)
Logger.debug('transferSettlement::processMsgFulfil - updateStateChange - end')
}
Logger.debug('transferSettlement::processMsgFulfil - end')
return true
} catch (err) {
Logger.debug('transferSettlement::processMsgFulfil - error!', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/transferSettlement/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ async function processTransferSettlement (error, messages) {
return true
}
} catch (err) {
Logger.error(`${Utility.breadcrumb(LOG_LOCATION)}::${err.message}--0`)
Logger.error(`${Utility.breadcrumb(LOG_LOCATION)}::${err.message}--0`, err)
return true
}
}
Expand Down
22 changes: 21 additions & 1 deletion src/models/transferSettlement/facade.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ async function insertLedgerEntry (ledgerEntry, transferId, trx = null) {
.where('PC.currencyId', ledgerEntry.currency)
.transacting(trx)

if (!Array.isArray(recordsToInsert) || recordsToInsert.length === 0) {
throw new Error(`No settlement model defined for transferId: ${transferId} and ledgerEntry: ${JSON.stringify(ledgerEntry)}`)
}

await knex('transferParticipant')
.insert(recordsToInsert)
.transacting(trx)
Expand Down Expand Up @@ -296,10 +300,26 @@ async function updateTransferSettlement (transferId, status, trx = null) {
}
}

async function getSettlementModelByTransferId (transferId, settlementGranularityName) {
Logger.info(Utility.breadcrumb(location, { method: 'getSettlementModelByTransferId' }))
const knex = await Db.getKnex()
return knex('settlementModel')
.join('participantCurrency AS pc', function () {
this.on('pc.currencyId', 'settlementModel.currencyId')
.andOn('pc.ledgerAccountTypeId', 'settlementModel.ledgerAccountTypeId')
})
.join('transferParticipant AS tp', 'tp.participantCurrencyId', 'pc.participantCurrencyId')
.join('settlementGranularity AS g', 'g.settlementGranularityId', 'settlementModel.settlementGranularityId')
.where('tp.transferId', transferId)
.where('g.name', settlementGranularityName)
.where('settlementModel.isActive', 1)
.select('settlementModel.*')
}
const Facade = {
insertLedgerEntry,
insertLedgerEntries,
updateTransferSettlement
updateTransferSettlement,
getSettlementModelByTransferId
}

module.exports = Facade
3 changes: 2 additions & 1 deletion src/models/transferSettlement/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ const Facade = require('./facade')
module.exports = {
updateStateChange: Facade.updateTransferSettlement,
getTransactionObject: Facade.getTransactionRequest,
insertLedgerEntries: Facade.insertLedgerEntries
insertLedgerEntries: Facade.insertLedgerEntries,
getSettlementModelByTransferId: Facade.getSettlementModelByTransferId
}
16 changes: 16 additions & 0 deletions test/unit/domain/transferSettlement/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Test('TransferSettlementService', async (transferSettlementServiceTest) => {
await processFulfilTest.test('process a fulfil message', async test => {
try {
TransferFulfilModel.updateStateChange = sandbox.stub().returns()
TransferFulfilModel.getSettlementModelByTransferId = sandbox.stub().returns([{ name: 'CGS' }])
await TransferFulfilService.processMsgFulfil(transferEventId, transferEventStateStatus)
test.ok(TransferFulfilModel.updateStateChange.withArgs(transferEventId, transferEventStateStatus).calledOnce, 'TransferFulfilModel.updateStateChange with args ... called once')
test.end()
Expand All @@ -61,9 +62,24 @@ Test('TransferSettlementService', async (transferSettlementServiceTest) => {
}
})

await processFulfilTest.test('process a fulfil message with no matching settlement model', async test => {
try {
TransferFulfilModel.updateStateChange = sandbox.stub().returns()
TransferFulfilModel.getSettlementModelByTransferId = sandbox.stub().returns([])
await TransferFulfilService.processMsgFulfil(transferEventId, transferEventStateStatus)
test.ok(TransferFulfilModel.updateStateChange.notCalled, 'TransferFulfilModel.updateStateChange is not called')
test.end()
} catch (err) {
Logger.error(`processFulfilTest failed with error - ${err}`)
test.fail()
test.end()
}
})

await processFulfilTest.test('throw an exception', async test => {
try {
TransferFulfilModel.updateStateChange = sandbox.stub().throws(new Error('Error occurred'))
TransferFulfilModel.getSettlementModelByTransferId = sandbox.stub().returns([{ name: 'CGS' }])
await TransferFulfilService.processMsgFulfil(transferEventId, transferEventStateStatus)
test.fail()
test.end()
Expand Down
90 changes: 90 additions & 0 deletions test/unit/models/transferSettlement/facade.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,46 @@ Test('TransferSettlement facade', async (transferSettlementTest) => {
}
})

await transferSettlementTest.test('insertLedgerEntry throw error, when nothing to insert', async (test) => {
try {
sandbox.stub(Db, 'getKnex')

knexStub.transacting.onCall(0).resolves(null)
knexStub.transacting.onCall(1).resolves(1)
knexStub.transacting.onCall(2).resolves(1)
knexStub.transacting.onCall(3).resolves(1)

knexStub.transacting.onCall(4).resolves([{
transferStateChangeId: 4581
}])
knexStub.transacting.onCall(5).resolves([
{
participantPositionId: 130,
value: 39.37,
reservedValue: 0
},
{
participantPositionId: 129,
value: -39.37,
reservedValue: 0
}
])
knexStub.transacting.onCall(6).resolves(1)
const knexFunc = sandbox.stub().returns(knexStub)
Object.assign(knexFunc, knexStub)
Db.getKnex.returns(knexFunc)

const transferId = '42a874d4-82a4-4471-a3fc-3dfeb6f7cb93'
await Model.insertLedgerEntry(ledgerEntry, transferId, trxStub)
test.fail('should throw an error')

test.end()
} catch (err) {
test.ok(err instanceof Error)
test.end()
}
})

await transferSettlementTest.test('insertLedgerEntry when participantPosition records are not updated correctly', async (test) => {
try {
sandbox.stub(Db, 'getKnex')
Expand Down Expand Up @@ -519,5 +559,55 @@ Test('TransferSettlement facade', async (transferSettlementTest) => {
}
})

await transferSettlementTest.test('getSettlementModelByTransferId should', async (test) => {
try {
const transferId = '154cbf04-bac7-444d-aa66-76f66126d7f5'
const settlementGranularityName = 'GROSS'
const settlementModelResult = {
settlementModelId: 1,
name: 'CGS',
isActive: 1,
settlementGranularityId: 1,
settlementInterchangeId: 1,
settlementDelayId: 1,
currencyId: 'USD',
ledgerAccountTypeId: 1
}

sandbox.stub(Db, 'getKnex')

const context = sandbox.stub()
context.on = sandbox.stub().returns({
andOn: sandbox.stub()
})
const join1Stub = sandbox.stub().callsArgOn(1, context)

const knexStub = sandbox.stub()
Db.getKnex.returns(knexStub)
knexStub.returns({
join: join1Stub.returns({
join: sandbox.stub().returns({
join: sandbox.stub().returns({
where: sandbox.stub().returns({
where: sandbox.stub().returns({
where: sandbox.stub().returns({
select: sandbox.stub().returns(settlementModelResult)
})
})
})
})
})
})
})
const result = await Model.getSettlementModelByTransferId(transferId, settlementGranularityName)
test.deepEqual(result, settlementModelResult, 'results match')
test.end()
} catch (err) {
Logger.error(`getSettlementModelByTransferId failed with error - ${err}`)
test.fail()
test.end()
}
})

await transferSettlementTest.end()
})

0 comments on commit 5bf0b97

Please sign in to comment.