Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(mojaloop/#2803): add event handlers #380

Merged
merged 6 commits into from
Sep 20, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion modules/api-svc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
"jest": "^29.0.3",
"jest-junit": "^14.0.1",
"nock": "^13.2.9",
"npm-check-updates": "^16.1.3",
"npm-check-updates": "^16.2.1",
"openapi-response-validator": "^12.0.2",
"openapi-typescript": "^5.4.1",
"redis-mock": "^0.56.3",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*****
License
--------------
Copyright © 2017 Bill & Melinda Gates Foundation
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
http://www.apache.org/licenses/LICENSE-2.0
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.
Contributors
--------------
This is the official list (alphabetical ordering) of the Mojaloop project contributors for this file.
Names of the original copyright holders (individuals or organizations)
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
Gates Foundation organization for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets <email>.
* Gates Foundation
- Name Surname <name.surname@gatesfoundation.com>
* Modusbox
- Kevin Leyow <kevin.leyow@modusbox.com>
--------------
******/

const { BulkTransfersRequestedDmEvt } = require('@mojaloop/sdk-scheme-adapter-private-shared-lib');
const { OutboundBulkTransfersModel } = require('../../lib/model');
const { BulkTransfersCallbackReceivedDmEvt } = require('@mojaloop/sdk-scheme-adapter-private-shared-lib');

module.exports.handleBulkTransfersRequestedDmEvt = async (
message,
options,
logger,
) => {
const event = BulkTransfersRequestedDmEvt.CreateFromDomainEvent(message);

try {
// use the bulk transfers model to execute asynchronous request with the switch
const model = new OutboundBulkTransfersModel({
...options.config,
cache: options.cache,
logger: logger,
wso2: options.wso2Auth,
});

await model.initialize(event.request);
const response = await model.run();

const bulkTransfersCallbackReceivedDmEvt = new BulkTransfersCallbackReceivedDmEvt({
bulkId: event.getKey(),
content: {
batchId: event.batchId,
bulkTransferId: response.bulkTransferId,
bulkTransfersResult: response,
},
timestamp: Date.now(),
headers: [],
});

await options.producer.sendDomainEvent(bulkTransfersCallbackReceivedDmEvt);
} catch (err) {
logger.push({ err }).log('Error in handleBulkTransfersRequestedDmEvt');
}
};
1 change: 1 addition & 0 deletions modules/api-svc/src/FSPIOPEventHandler/handlers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@
module.exports = {
...require('./bulk-quotes-requested'),
...require('./party-info-requested'),
...require('./bulk-transfers-requested'),
};
12 changes: 8 additions & 4 deletions modules/api-svc/src/FSPIOPEventHandler/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ const {
BC_CONFIG,
KafkaDomainEventConsumer,
KafkaDomainEventProducer,
BulkTransfersRequestedDmEvt,
PartyInfoRequestedDmEvt,
BulkQuotesRequestedDmEvt,
} = require('@mojaloop/sdk-scheme-adapter-private-shared-lib');
const {
handlePartyInfoRequestedDmEvt,
handleBulkQuotesRequestedDmEvt,
handleBulkTransfersRequestedDmEvt,
} = require('./handlers');
const {
PartyInfoRequestedDmEvt,
BulkQuotesRequestedDmEvt,
} = require('@mojaloop/sdk-scheme-adapter-private-shared-lib');

class FSPIOPEventHandler {
constructor({ config, logger, cache, wso2Auth }) {
Expand Down Expand Up @@ -94,6 +94,10 @@ class FSPIOPEventHandler {
await handleBulkQuotesRequestedDmEvt(message, this._domainEventHandlerOptions, this._logger);
break;
}
case BulkTransfersRequestedDmEvt.name: {
await handleBulkTransfersRequestedDmEvt(message, this._domainEventHandlerOptions, this._logger);
break;
}
default: {
this._logger.debug(`${message?.getName()}:${message?.getKey()} - Skipping unknown domain event`);
return;
Expand Down
111 changes: 89 additions & 22 deletions modules/api-svc/test/unit/FSPIOPEventHandler.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,35 @@ const config = require('./data/defaultConfig.json');
const {
PartyInfoRequestedDmEvt,
BulkQuotesRequestedDmEvt,
BulkTransfersRequestedDmEvt,
KafkaDomainEventConsumer,
KafkaDomainEventProducer,
} = require('@mojaloop/sdk-scheme-adapter-private-shared-lib');

const {
OutboundBulkQuotesModel,
PartiesModel,
OutboundBulkTransfersModel,
} = require('~/lib/model');

const {
KafkaDomainEventConsumer,
KafkaDomainEventProducer,
} = require('@mojaloop/sdk-scheme-adapter-private-shared-lib');

const logger = new Logger.Logger({ context: { app: 'FSPIOPEventHandler' }, stringify: () => '' });

describe('FSPIOPEventHandler', () => {
test('should handle PartyInfoRequestedDmEvt event', async () => {
const fspiopEventHandler = new FSPIOPEventHandler({
let fspiopEventHandler;

beforeEach(async () => {
fspiopEventHandler = new FSPIOPEventHandler({
config,
logger,
});
await fspiopEventHandler.start();
});

afterAll(async () => {
await fspiopEventHandler.stop();
});

test('should handle PartyInfoRequestedDmEvt event', async () => {
const request = {
partyIdType: 'PERSONAL_ID',
partyIdentifier: '16135551212',
Expand Down Expand Up @@ -99,16 +107,9 @@ describe('FSPIOPEventHandler', () => {
currentState: 'COMPLETED',
}
});

await fspiopEventHandler.stop();
});

test('should return error information for PartyInfoRequestedDmEvt event', async () => {
const fspiopEventHandler = new FSPIOPEventHandler({
config,
logger,
});
await fspiopEventHandler.start();
const request = {
partyIdType: 'PERSONAL_ID',
partyIdentifier: '16135551212',
Expand Down Expand Up @@ -180,16 +181,9 @@ describe('FSPIOPEventHandler', () => {
},
},
});

await fspiopEventHandler.stop();
});

test('should handle BulkQuotesRequestedDmEvt event', async () => {
const fspiopEventHandler = new FSPIOPEventHandler({
config,
logger,
});
await fspiopEventHandler.start();
const bulkId = 'bulk-tx-test';
const event = new BulkQuotesRequestedDmEvt({
bulkId,
Expand Down Expand Up @@ -251,8 +245,81 @@ describe('FSPIOPEventHandler', () => {
bulkQuoteId: bulkQuoteResponse.bulkQuoteId,
bulkQuotesResult: bulkQuoteResponse,
});
});

await fspiopEventHandler.stop();
test('should handle BulkTransfersRequestedDmEvt event', async () => {
const bulkTransfersRequest = {
homeTransactionId: 'home-transaction-id',
from: {
idType: 'MSISDN',
idValue: '123456'
},
individualTransfers: [
{
homeTransactionId: 'home-individual-transfer-id',
to: {
partyIdInfo: {
partyIdType: 'MSISDN',
partyIdentifier: '1'
},
},
amountType: 'SEND',
currency: 'USD',
amount: '1'
},
]
};
const bulkTransfersRequestedDmEvt = new BulkTransfersRequestedDmEvt({
bulkId: 'bulk-tx-test',
headers: [],
timestamp: Date.now(),
content: {
batchId: '61c35bae-77d0-4f7d-b894-be375b838ff6',
bulkTransfersRequest,
},
});

const bulkTransfersResult = {
bulkTransferId: '81c35bae-77d0-4f7d-b894-be375b838ff6',
currentState: 'COMPLETED',
individualTransferResults: [
{
transferId: 'individual-transfer-id',
to: {
partyIdInfo: {
partyIdType: 'MSISDN',
partyIdentifier: '1'
},
},
amountType: 'SEND',
currency: 'USD',
amount: '1'
},
]
};

const initializeSpy = jest.spyOn(OutboundBulkTransfersModel.prototype, 'initialize')
.mockImplementationOnce(async () => bulkTransfersResult);

jest.spyOn(OutboundBulkTransfersModel.prototype, 'run')
.mockImplementationOnce(async () => bulkTransfersResult);


const handler = KafkaDomainEventConsumer.mock.ctor.mock.calls[0][0];
await handler(bulkTransfersRequestedDmEvt);

// run workflow
expect(initializeSpy).toBeCalledWith(bulkTransfersRequestedDmEvt.request);

await new Promise((resolve) => setTimeout(resolve, 1500));

const sent = KafkaDomainEventProducer.mock.sendDomainEvent.mock.calls[0][0];
expect(sent._data.name).toEqual('BulkTransfersCallbackReceivedDmEvt');
expect(sent._data.content).toEqual({
batchId: '61c35bae-77d0-4f7d-b894-be375b838ff6',
bulkTransferId: '81c35bae-77d0-4f7d-b894-be375b838ff6',
bulkTransfersResult
});
});
});

10 changes: 5 additions & 5 deletions modules/outbound-command-event-handler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
},
"dependencies": {
"@mojaloop/api-snippets": "^15.0.1",
"@mojaloop/logging-bc-client-lib": "^0.1.13",
"@mojaloop/logging-bc-public-types-lib": "^0.1.10",
"@mojaloop/logging-bc-client-lib": "^0.1.14",
"@mojaloop/logging-bc-public-types-lib": "^0.1.11",
"@mojaloop/sdk-scheme-adapter-private-shared-lib": "workspace:^",
"ajv": "^8.11.0",
"convict": "^6.2.3",
Expand All @@ -60,13 +60,13 @@
"@types/supertest": "^2.0.12",
"@types/swagger-ui-express": "^4.1.3",
"@types/yamljs": "^0.2.31",
"@typescript-eslint/eslint-plugin": "^5.37.0",
"@typescript-eslint/parser": "^5.37.0",
"@typescript-eslint/eslint-plugin": "^5.38.0",
"@typescript-eslint/parser": "^5.38.0",
"copyfiles": "^2.4.1",
"eslint": "^8.23.1",
"jest": "^29.0.3",
"nodemon": "^2.0.20",
"npm-check-updates": "^16.1.3",
"npm-check-updates": "^16.2.1",
"replace": "^1.2.1",
"standard-version": "^9.5.0",
"ts-jest": "^29.0.1",
Expand Down
10 changes: 5 additions & 5 deletions modules/outbound-domain-event-handler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
"snapshot": "standard-version --no-verify --skip.changelog --prerelease snapshot --releaseCommitMessageFormat 'chore(snapshot): {{currentTag}}'"
},
"dependencies": {
"@mojaloop/logging-bc-client-lib": "^0.1.13",
"@mojaloop/logging-bc-public-types-lib": "^0.1.10",
"@mojaloop/logging-bc-client-lib": "^0.1.14",
"@mojaloop/logging-bc-public-types-lib": "^0.1.11",
"@mojaloop/sdk-scheme-adapter-private-shared-lib": "workspace:^",
"convict": "^6.2.3"
},
Expand All @@ -48,12 +48,12 @@
"@types/jest": "^29.0.3",
"@types/node": "^18.7.18",
"@types/node-cache": "^4.2.5",
"@typescript-eslint/eslint-plugin": "^5.37.0",
"@typescript-eslint/parser": "^5.37.0",
"@typescript-eslint/eslint-plugin": "^5.38.0",
"@typescript-eslint/parser": "^5.38.0",
"eslint": "^8.23.1",
"jest": "^29.0.3",
"nodemon": "^2.0.20",
"npm-check-updates": "^16.1.3",
"npm-check-updates": "^16.2.1",
"replace": "^1.2.1",
"standard-version": "^9.5.0",
"ts-jest": "^29.0.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { ILogger } from '@mojaloop/logging-bc-public-types-lib';
import {
DomainEvent,
BulkTransfersCallbackReceivedDmEvt,
ProcessBulkTransfersCallbackCmdEvt,
IProcessBulkTransfersCallbackCmdEvtData,
} from '@mojaloop/sdk-scheme-adapter-private-shared-lib';
import { IDomainEventHandlerOptions } from '../../types';

Expand All @@ -9,8 +12,28 @@ export async function handleBulkTransfersCallbackReceived(
options: IDomainEventHandlerOptions,
logger: ILogger,
): Promise<void> {
const bulkTransfersCallbackReceivedMessage
= BulkTransfersCallbackReceivedDmEvt.CreateFromDomainEvent(message);
try {
const processPartyInfoCallbackMessageData: IProcessBulkTransfersCallbackCmdEvtData = {
bulkId: bulkTransfersCallbackReceivedMessage.getKey(),
content: {
batchId: bulkTransfersCallbackReceivedMessage.batchId,
bulkTransferId: bulkTransfersCallbackReceivedMessage.bulkTransferId,
bulkTransfersResult: bulkTransfersCallbackReceivedMessage.bulkTransfersResult,
},
timestamp: Date.now(),
headers: bulkTransfersCallbackReceivedMessage.getHeaders(),
};

const processBulkTransfersCallbackMessage
= new ProcessBulkTransfersCallbackCmdEvt(processPartyInfoCallbackMessageData);

await options.commandProducer.sendCommandEvent(processBulkTransfersCallbackMessage);

logger.info(`Sent command event ${processBulkTransfersCallbackMessage.getName()}`);
console.log(processBulkTransfersCallbackMessage);
} catch (err) {
logger.info(`Failed to send command event . ${(err as Error).message}`);
logger.info(`Failed to send command event ProcessBulkTransfersCallbackCmdEvt. ${(err as Error).message}`);
kleyow marked this conversation as resolved.
Show resolved Hide resolved
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ export * from './sdk_outbound_bulk_accept_party_info_processed';
export * from './bulk-quotes-callback-received';
export * from './party-info-callback-processed';
export * from './sdk_outbound_bulk_accept_quote_processed';
export * from './bulk_transfers_callback_received';
Loading