@mojaloop/sdk-scheme-adapter 11.18.8
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.
- package/.env.example +140 -0
- package/.eslintignore +2 -0
- package/.eslintrc.json +30 -0
- package/.nvmrc +1 -0
- package/.versionrc +15 -0
- package/CHANGELOG.md +118 -0
- package/InboundServer/api.yaml +3594 -0
- package/InboundServer/api_template.yaml +69 -0
- package/InboundServer/handlers.js +940 -0
- package/InboundServer/index.js +205 -0
- package/InboundServer/middlewares.js +426 -0
- package/OAuthTestServer/index.js +66 -0
- package/OAuthTestServer/model.js +70 -0
- package/OutboundServer/api.yaml +2732 -0
- package/OutboundServer/api_interfaces/index.d.ts +117 -0
- package/OutboundServer/api_interfaces/openapi.d.ts +1475 -0
- package/OutboundServer/api_template/components/parameters/bulkQuoteId.yaml +9 -0
- package/OutboundServer/api_template/components/parameters/bulkTransferId.yaml +9 -0
- package/OutboundServer/api_template/components/parameters/requestToPayTransactionId.yaml +9 -0
- package/OutboundServer/api_template/components/parameters/transferId.yaml +9 -0
- package/OutboundServer/api_template/components/responses/accountsCreationCompleted.yaml +5 -0
- package/OutboundServer/api_template/components/responses/accountsCreationError.yaml +5 -0
- package/OutboundServer/api_template/components/responses/accountsCreationTimeout.yaml +5 -0
- package/OutboundServer/api_template/components/responses/authorizationPostSuccess.yaml +5 -0
- package/OutboundServer/api_template/components/responses/authorizationsServerError.yaml +5 -0
- package/OutboundServer/api_template/components/responses/bulkQuoteBadRequest.yaml +5 -0
- package/OutboundServer/api_template/components/responses/bulkQuoteServerError.yaml +5 -0
- package/OutboundServer/api_template/components/responses/bulkQuoteSuccess.yaml +5 -0
- package/OutboundServer/api_template/components/responses/bulkQuoteTimeout.yaml +5 -0
- package/OutboundServer/api_template/components/responses/bulkTransferBadRequest.yaml +5 -0
- package/OutboundServer/api_template/components/responses/bulkTransferServerError.yaml +5 -0
- package/OutboundServer/api_template/components/responses/bulkTransferSuccess.yaml +5 -0
- package/OutboundServer/api_template/components/responses/bulkTransferTimeout.yaml +5 -0
- package/OutboundServer/api_template/components/responses/partiesByIdError404.yaml +9 -0
- package/OutboundServer/api_template/components/responses/partiesByIdSuccess.yaml +5 -0
- package/OutboundServer/api_template/components/responses/quotesPostSuccess.yaml +5 -0
- package/OutboundServer/api_template/components/responses/quotesServerError.yaml +5 -0
- package/OutboundServer/api_template/components/responses/requestToPaySuccess.yaml +5 -0
- package/OutboundServer/api_template/components/responses/requestToPayTransferBadRequest.yaml +5 -0
- package/OutboundServer/api_template/components/responses/requestToPayTransferSuccess.yaml +5 -0
- package/OutboundServer/api_template/components/responses/simpleTransfersPostSuccess.yaml +5 -0
- package/OutboundServer/api_template/components/responses/simpleTransfersServerError.yaml +5 -0
- package/OutboundServer/api_template/components/responses/transferBadRequest.yaml +5 -0
- package/OutboundServer/api_template/components/responses/transferServerError.yaml +5 -0
- package/OutboundServer/api_template/components/responses/transferSuccess.yaml +5 -0
- package/OutboundServer/api_template/components/responses/transferTimeout.yaml +5 -0
- package/OutboundServer/api_template/components/schemas/accountCreationStatus.yaml +18 -0
- package/OutboundServer/api_template/components/schemas/accountsCreationState.yaml +4 -0
- package/OutboundServer/api_template/components/schemas/accountsRequest.yaml +20 -0
- package/OutboundServer/api_template/components/schemas/accountsResponse.yaml +15 -0
- package/OutboundServer/api_template/components/schemas/async2SyncCurrentState.yaml +5 -0
- package/OutboundServer/api_template/components/schemas/authorizationsPostRequest.yaml +15 -0
- package/OutboundServer/api_template/components/schemas/authorizationsPostResponse.yaml +19 -0
- package/OutboundServer/api_template/components/schemas/bulkQuoteErrorResponse.yaml +8 -0
- package/OutboundServer/api_template/components/schemas/bulkQuoteRequest.yaml +26 -0
- package/OutboundServer/api_template/components/schemas/bulkQuoteResponse.yaml +21 -0
- package/OutboundServer/api_template/components/schemas/bulkQuoteStatus.yaml +4 -0
- package/OutboundServer/api_template/components/schemas/bulkQuoteStatusResponse.yaml +17 -0
- package/OutboundServer/api_template/components/schemas/bulkTransferErrorResponse.yaml +8 -0
- package/OutboundServer/api_template/components/schemas/bulkTransferRequest.yaml +26 -0
- package/OutboundServer/api_template/components/schemas/bulkTransferResponse.yaml +16 -0
- package/OutboundServer/api_template/components/schemas/bulkTransferStatus.yaml +4 -0
- package/OutboundServer/api_template/components/schemas/bulkTransferStatusResponse.yaml +17 -0
- package/OutboundServer/api_template/components/schemas/errorAccountsResponse.yaml +8 -0
- package/OutboundServer/api_template/components/schemas/errorAuthorizationsResponse.yaml +3 -0
- package/OutboundServer/api_template/components/schemas/errorQuotesResponse.yaml +9 -0
- package/OutboundServer/api_template/components/schemas/errorResponse.yaml +8 -0
- package/OutboundServer/api_template/components/schemas/errorSimpleTransfersResponse.yaml +3 -0
- package/OutboundServer/api_template/components/schemas/errorTransferResponse.yaml +8 -0
- package/OutboundServer/api_template/components/schemas/extensionListEmptiable.yaml +6 -0
- package/OutboundServer/api_template/components/schemas/individualQuote.yaml +32 -0
- package/OutboundServer/api_template/components/schemas/individualQuoteResult.yaml +28 -0
- package/OutboundServer/api_template/components/schemas/individualTransfer.yaml +32 -0
- package/OutboundServer/api_template/components/schemas/individualTransferFulfilment.yaml +13 -0
- package/OutboundServer/api_template/components/schemas/individualTransferResult.yaml +41 -0
- package/OutboundServer/api_template/components/schemas/mojaloopError.yaml +5 -0
- package/OutboundServer/api_template/components/schemas/mojaloopTransactionRequestState.yaml +2 -0
- package/OutboundServer/api_template/components/schemas/partiesByIdResponse.yaml +13 -0
- package/OutboundServer/api_template/components/schemas/quote.yaml +3 -0
- package/OutboundServer/api_template/components/schemas/quoteError.yaml +16 -0
- package/OutboundServer/api_template/components/schemas/quotesPostRequest.yaml +13 -0
- package/OutboundServer/api_template/components/schemas/quotesPostResponse.yaml +48 -0
- package/OutboundServer/api_template/components/schemas/requestToPayRequest.yaml +39 -0
- package/OutboundServer/api_template/components/schemas/requestToPayResponse.yaml +41 -0
- package/OutboundServer/api_template/components/schemas/requestToPayTransferRequest.yaml +42 -0
- package/OutboundServer/api_template/components/schemas/requestToPayTransferResponse.yaml +58 -0
- package/OutboundServer/api_template/components/schemas/simpleTransferServerError.yaml +5 -0
- package/OutboundServer/api_template/components/schemas/simpleTransfersPostRequest.yaml +12 -0
- package/OutboundServer/api_template/components/schemas/simpleTransfersPostResponse.yaml +11 -0
- package/OutboundServer/api_template/components/schemas/transactionType.yaml +4 -0
- package/OutboundServer/api_template/components/schemas/transferContinuationAcceptOTP.yaml +9 -0
- package/OutboundServer/api_template/components/schemas/transferContinuationAcceptParty.yaml +8 -0
- package/OutboundServer/api_template/components/schemas/transferContinuationAcceptQuote.yaml +9 -0
- package/OutboundServer/api_template/components/schemas/transferError.yaml +16 -0
- package/OutboundServer/api_template/components/schemas/transferFulfilment.yaml +3 -0
- package/OutboundServer/api_template/components/schemas/transferParty.yaml +40 -0
- package/OutboundServer/api_template/components/schemas/transferRequest.yaml +37 -0
- package/OutboundServer/api_template/components/schemas/transferResponse.yaml +58 -0
- package/OutboundServer/api_template/components/schemas/transferStatus.yaml +6 -0
- package/OutboundServer/api_template/components/schemas/transferStatusResponse.yaml +13 -0
- package/OutboundServer/api_template/health.yaml +12 -0
- package/OutboundServer/api_template/openapi.yaml +55 -0
- package/OutboundServer/api_template/paths/accounts.yaml +26 -0
- package/OutboundServer/api_template/paths/authorizations.yaml +19 -0
- package/OutboundServer/api_template/paths/bulkQuotes.yaml +23 -0
- package/OutboundServer/api_template/paths/bulkQuotes_bulkQuoteId.yaml +24 -0
- package/OutboundServer/api_template/paths/bulkTransfers.yaml +23 -0
- package/OutboundServer/api_template/paths/bulkTransfers_bulkTransferId.yaml +24 -0
- package/OutboundServer/api_template/paths/parties_Type_ID.yaml +20 -0
- package/OutboundServer/api_template/paths/parties_Type_ID_SubId.yaml +22 -0
- package/OutboundServer/api_template/paths/quotes.yaml +20 -0
- package/OutboundServer/api_template/paths/requestToPay.yaml +22 -0
- package/OutboundServer/api_template/paths/requestToPayTransfer.yaml +57 -0
- package/OutboundServer/api_template/paths/requestToPayTransfer_requestToPayTransactionId.yaml +34 -0
- package/OutboundServer/api_template/paths/simpleTransfers.yaml +19 -0
- package/OutboundServer/api_template/paths/transfers.yaml +55 -0
- package/OutboundServer/api_template/paths/transfers_transferId.yaml +58 -0
- package/OutboundServer/handlers.js +622 -0
- package/OutboundServer/index.js +137 -0
- package/OutboundServer/middlewares.js +67 -0
- package/TestServer/api.yaml +62 -0
- package/TestServer/handlers.js +63 -0
- package/TestServer/index.js +215 -0
- package/audit-resolve.json +65 -0
- package/babel.config.js +3 -0
- package/config.js +158 -0
- package/index.d.ts +1 -0
- package/index.js +149 -0
- package/jest.config.js +15 -0
- package/lib/api/index.js +12 -0
- package/lib/cache.js +352 -0
- package/lib/check.js +25 -0
- package/lib/model/AccountsModel.js +396 -0
- package/lib/model/Async2SyncModel.js +283 -0
- package/lib/model/AuthorizationsModel.js +86 -0
- package/lib/model/InboundTransfersModel.js +730 -0
- package/lib/model/OutboundBulkQuotesModel.js +485 -0
- package/lib/model/OutboundBulkTransfersModel.js +479 -0
- package/lib/model/OutboundRequestToPayModel.js +517 -0
- package/lib/model/OutboundRequestToPayTransferModel.js +893 -0
- package/lib/model/OutboundTransfersModel.js +823 -0
- package/lib/model/PartiesModel.js +70 -0
- package/lib/model/ProxyModel/MatchRules/Expression.js +48 -0
- package/lib/model/ProxyModel/MatchRules/Headers.js +65 -0
- package/lib/model/ProxyModel/MatchRules/MatchRule.js +27 -0
- package/lib/model/ProxyModel/MatchRules/Path.js +36 -0
- package/lib/model/ProxyModel/MatchRules/Query.js +65 -0
- package/lib/model/ProxyModel/MatchRules/index.js +19 -0
- package/lib/model/ProxyModel/Route.js +82 -0
- package/lib/model/ProxyModel/configSchema.json +118 -0
- package/lib/model/ProxyModel/index.js +138 -0
- package/lib/model/QuotesModel.js +94 -0
- package/lib/model/TransfersModel.js +81 -0
- package/lib/model/common/BackendError.js +26 -0
- package/lib/model/common/PersistentStateMachine.js +93 -0
- package/lib/model/common/index.js +18 -0
- package/lib/model/index.js +43 -0
- package/lib/model/lib/deferredJob.js +113 -0
- package/lib/model/lib/index.js +9 -0
- package/lib/model/lib/requests/backendRequests.js +227 -0
- package/lib/model/lib/requests/common.js +76 -0
- package/lib/model/lib/requests/index.js +19 -0
- package/lib/model/lib/shared.js +468 -0
- package/lib/randomphrase/index.js +21 -0
- package/lib/randomphrase/words.json +3397 -0
- package/lib/router.js +28 -0
- package/lib/validate.js +205 -0
- package/package.json +102 -0
- package/test/__mocks__/@mojaloop/sdk-standard-components.js +152 -0
- package/test/__mocks__/javascript-state-machine.js +21 -0
- package/test/__mocks__/redis.js +49 -0
- package/test/__mocks__/uuidv4.js +16 -0
- package/test/config/integration.env +136 -0
- package/test/integration/lib/Outbound/authorizations.test.js +58 -0
- package/test/integration/lib/Outbound/data/authorizationsPostRequest.json +43 -0
- package/test/integration/lib/Outbound/data/quotesPostRequest.json +52 -0
- package/test/integration/lib/Outbound/data/transfersPostRequest.json +24 -0
- package/test/integration/lib/Outbound/parties.test.js +28 -0
- package/test/integration/lib/Outbound/quotes.test.js +58 -0
- package/test/integration/lib/Outbound/simpleTransfers.test.js +67 -0
- package/test/integration/lib/cache.test.js +80 -0
- package/test/integration/testEnv.js +7 -0
- package/test/unit/InboundServer.test.js +443 -0
- package/test/unit/TestServer.test.js +394 -0
- package/test/unit/api/accounts/accounts.test.js +128 -0
- package/test/unit/api/accounts/data/postAccountsBody.json +7 -0
- package/test/unit/api/accounts/data/postAccountsErrorMojaloopResponse.json +25 -0
- package/test/unit/api/accounts/data/postAccountsErrorTimeoutResponse.json +19 -0
- package/test/unit/api/accounts/data/postAccountsSuccessResponse.json +17 -0
- package/test/unit/api/accounts/data/postAccountsSuccessResponseWithError1.json +21 -0
- package/test/unit/api/accounts/data/postAccountsSuccessResponseWithError2.json +21 -0
- package/test/unit/api/accounts/utils.js +65 -0
- package/test/unit/api/proxy/data/proxyConfig.yaml +82 -0
- package/test/unit/api/proxy/data/requestBody.json +22 -0
- package/test/unit/api/proxy/data/requestHeaders.json +5 -0
- package/test/unit/api/proxy/data/requestQuery.json +6 -0
- package/test/unit/api/proxy/data/responseBody.json +21 -0
- package/test/unit/api/proxy/data/responseHeaders.json +5 -0
- package/test/unit/api/proxy/proxy.test.js +220 -0
- package/test/unit/api/proxy/utils.js +79 -0
- package/test/unit/api/transfers/data/getTransfersCommittedResponse.json +21 -0
- package/test/unit/api/transfers/data/getTransfersErrorNotFound.json +17 -0
- package/test/unit/api/transfers/data/postQuotesBody.json +52 -0
- package/test/unit/api/transfers/data/postTransfersBadBody.json +17 -0
- package/test/unit/api/transfers/data/postTransfersBody.json +24 -0
- package/test/unit/api/transfers/data/postTransfersErrorMojaloopResponse.json +53 -0
- package/test/unit/api/transfers/data/postTransfersErrorTimeoutResponse.json +47 -0
- package/test/unit/api/transfers/data/postTransfersSimpleBody.json +26 -0
- package/test/unit/api/transfers/data/postTransfersSuccessResponse.json +101 -0
- package/test/unit/api/transfers/data/putPartiesBody.json +20 -0
- package/test/unit/api/transfers/data/putQuotesBody.json +37 -0
- package/test/unit/api/transfers/data/putTransfersBody.json +17 -0
- package/test/unit/api/transfers/transfers.test.js +191 -0
- package/test/unit/api/transfers/utils.js +183 -0
- package/test/unit/api/utils.js +75 -0
- package/test/unit/config.test.js +119 -0
- package/test/unit/data/commonHttpHeaders.json +6 -0
- package/test/unit/data/defaultConfig.json +58 -0
- package/test/unit/data/postQuotesBody.json +52 -0
- package/test/unit/data/putParticipantsBody.json +12 -0
- package/test/unit/data/putPartiesBody.json +20 -0
- package/test/unit/data/testFile.json +29 -0
- package/test/unit/data/testFile.yaml +14 -0
- package/test/unit/inboundApi/data/mockArguments.json +117 -0
- package/test/unit/inboundApi/data/mockTransactionRequest.json +42 -0
- package/test/unit/inboundApi/handlers.test.js +799 -0
- package/test/unit/index.test.js +55 -0
- package/test/unit/lib/cache.test.js +146 -0
- package/test/unit/lib/model/AccountsModel.test.js +121 -0
- package/test/unit/lib/model/AuthorizationsModel.test.js +460 -0
- package/test/unit/lib/model/InboundTransfersModel.test.js +628 -0
- package/test/unit/lib/model/OutboundBulkQuotesModel.test.js +249 -0
- package/test/unit/lib/model/OutboundBulkTransfersModel.test.js +244 -0
- package/test/unit/lib/model/OutboundRequestToPayModel.test.js +166 -0
- package/test/unit/lib/model/OutboundRequestToPayTransferModel.test.js +245 -0
- package/test/unit/lib/model/OutboundTransfersModel.test.js +836 -0
- package/test/unit/lib/model/PartiesModel.test.js +468 -0
- package/test/unit/lib/model/QuotesModel.test.js +470 -0
- package/test/unit/lib/model/TransfersModel.test.js +474 -0
- package/test/unit/lib/model/common/PersistentStateMachine.test.js +179 -0
- package/test/unit/lib/model/data/authorizationsResponse.json +13 -0
- package/test/unit/lib/model/data/bulkQuoteRequest.json +27 -0
- package/test/unit/lib/model/data/bulkQuoteResponse.json +35 -0
- package/test/unit/lib/model/data/bulkTransferFulfil.json +13 -0
- package/test/unit/lib/model/data/bulkTransferRequest.json +29 -0
- package/test/unit/lib/model/data/defaultConfig.json +47 -0
- package/test/unit/lib/model/data/getBulkTransfersBackendResponse.json +42 -0
- package/test/unit/lib/model/data/getBulkTransfersMojaloopResponse.json +22 -0
- package/test/unit/lib/model/data/getTransfersBackendResponse.json +34 -0
- package/test/unit/lib/model/data/getTransfersMojaloopResponse.json +17 -0
- package/test/unit/lib/model/data/mockArguments.json +131 -0
- package/test/unit/lib/model/data/mockTxnRequestsArguments.json +63 -0
- package/test/unit/lib/model/data/notificationToPayee.json +10 -0
- package/test/unit/lib/model/data/payeeParty.json +16 -0
- package/test/unit/lib/model/data/putAuthorizationsResponse.json +10 -0
- package/test/unit/lib/model/data/putQuotesResponse.json +33 -0
- package/test/unit/lib/model/data/putTransfersResponse.json +5 -0
- package/test/unit/lib/model/data/quoteResponse.json +31 -0
- package/test/unit/lib/model/data/requestToPayRequest.json +20 -0
- package/test/unit/lib/model/data/requestToPayTransferRequest.json +27 -0
- package/test/unit/lib/model/data/transactionRequestResponse.json +18 -0
- package/test/unit/lib/model/data/transferFulfil.json +8 -0
- package/test/unit/lib/model/data/transferRequest.json +26 -0
- package/test/unit/lib/model/mockedLibRequests.js +74 -0
- package/test/unit/mockLogger.js +39 -0
- package/test/unit/outboundApi/data/bulkQuoteRequest.json +28 -0
- package/test/unit/outboundApi/data/bulkTransferRequest.json +28 -0
- package/test/unit/outboundApi/data/mockBulkQuoteError.json +45 -0
- package/test/unit/outboundApi/data/mockBulkTransferError.json +48 -0
- package/test/unit/outboundApi/data/mockError.json +41 -0
- package/test/unit/outboundApi/data/mockGetPartiesError.json +4 -0
- package/test/unit/outboundApi/data/mockRequestToPayError.json +32 -0
- package/test/unit/outboundApi/data/mockRequestToPayTransferError.json +39 -0
- package/test/unit/outboundApi/data/requestToPay.json +21 -0
- package/test/unit/outboundApi/data/requestToPayTransferRequest.json +20 -0
- package/test/unit/outboundApi/data/transferRequest.json +21 -0
- package/test/unit/outboundApi/handlers.test.js +986 -0
package/lib/check.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**************************************************************************
|
|
2
|
+
* (C) Copyright ModusBox Inc. 2020 - All rights reserved. *
|
|
3
|
+
* *
|
|
4
|
+
* This file is made available under the terms of the license agreement *
|
|
5
|
+
* specified in the corresponding source code repository. *
|
|
6
|
+
* *
|
|
7
|
+
* ORIGINAL AUTHOR: *
|
|
8
|
+
* Matt Kingston - matt.kingston@modusbox.com *
|
|
9
|
+
**************************************************************************/
|
|
10
|
+
|
|
11
|
+
// This module maps all methods on Node assert to non-throwing "check" functions which return true
|
|
12
|
+
// if the assertion succeeded and false otherwise
|
|
13
|
+
|
|
14
|
+
const assert = require('assert').strict;
|
|
15
|
+
|
|
16
|
+
module.exports = Object.fromEntries(
|
|
17
|
+
Object.entries(assert).map(([k, f]) => [k, (...args) => {
|
|
18
|
+
try {
|
|
19
|
+
f.bind(assert)(...args);
|
|
20
|
+
return true;
|
|
21
|
+
} catch (err) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}])
|
|
25
|
+
);
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
/**************************************************************************
|
|
2
|
+
* (C) Copyright ModusBox Inc. 2019 - All rights reserved. *
|
|
3
|
+
* *
|
|
4
|
+
* This file is made available under the terms of the license agreement *
|
|
5
|
+
* specified in the corresponding source code repository. *
|
|
6
|
+
* *
|
|
7
|
+
* ORIGINAL AUTHOR: *
|
|
8
|
+
* Yevhen Kyriukha - yevhen.kyriukha@modusbox.com *
|
|
9
|
+
**************************************************************************/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
const util = require('util');
|
|
14
|
+
const { uuid } = require('uuidv4');
|
|
15
|
+
const StateMachine = require('javascript-state-machine');
|
|
16
|
+
const { MojaloopRequests, Errors } = require('@mojaloop/sdk-standard-components');
|
|
17
|
+
const { BackendError } = require('./common');
|
|
18
|
+
|
|
19
|
+
const stateEnum = {
|
|
20
|
+
'ERROR_OCCURRED': 'ERROR_OCCURRED',
|
|
21
|
+
'COMPLETED': 'COMPLETED',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Models the state machine and operations required for performing an outbound transfer
|
|
27
|
+
*/
|
|
28
|
+
class AccountsModel {
|
|
29
|
+
constructor(config) {
|
|
30
|
+
this._cache = config.cache;
|
|
31
|
+
this._logger = config.logger;
|
|
32
|
+
this._requestProcessingTimeoutSeconds = config.requestProcessingTimeoutSeconds;
|
|
33
|
+
this._dfspId = config.dfspId;
|
|
34
|
+
|
|
35
|
+
this._requests = new MojaloopRequests({
|
|
36
|
+
logger: this._logger,
|
|
37
|
+
peerEndpoint: config.alsEndpoint,
|
|
38
|
+
dfspId: config.dfspId,
|
|
39
|
+
tls: config.tls,
|
|
40
|
+
jwsSign: config.jwsSign,
|
|
41
|
+
jwsSigningKey: config.jwsSigningKey,
|
|
42
|
+
wso2: config.wso2,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Initializes the internal state machine object
|
|
49
|
+
*/
|
|
50
|
+
_initStateMachine (initState) {
|
|
51
|
+
this._stateMachine = new StateMachine({
|
|
52
|
+
init: initState,
|
|
53
|
+
transitions: [
|
|
54
|
+
{ name: 'createAccounts', from: 'start', to: 'succeeded' },
|
|
55
|
+
{ name: 'error', from: '*', to: 'errored' },
|
|
56
|
+
],
|
|
57
|
+
methods: {
|
|
58
|
+
onTransition: this._handleTransition.bind(this),
|
|
59
|
+
onAfterTransition: this._afterTransition.bind(this),
|
|
60
|
+
onPendingTransition: (transition, from, to) => {
|
|
61
|
+
// allow transitions to 'error' state while other transitions are in progress
|
|
62
|
+
if(transition !== 'error') {
|
|
63
|
+
throw new BackendError(`Transition requested while another transition is in progress: ${transition} from: ${from} to: ${to}`, 500);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
return this._stateMachine[initState];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Updates the internal state representation to reflect that of the state machine itself
|
|
75
|
+
*/
|
|
76
|
+
_afterTransition() {
|
|
77
|
+
this._logger.log(`State machine transitioned: ${this._data.currentState} -> ${this._stateMachine.state}`);
|
|
78
|
+
this._data.currentState = this._stateMachine.state;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Initializes the accounts model
|
|
84
|
+
*
|
|
85
|
+
* @param data {object} - The outbound API POST /accounts request body
|
|
86
|
+
*/
|
|
87
|
+
async initialize(data) {
|
|
88
|
+
this._data = data;
|
|
89
|
+
|
|
90
|
+
// add a modelId if one is not present e.g. on first submission
|
|
91
|
+
if(!this._data.hasOwnProperty('modelId')) {
|
|
92
|
+
this._data.modelId = uuid();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// initialize the transfer state machine to its starting state
|
|
96
|
+
if(!this._data.hasOwnProperty('currentState')) {
|
|
97
|
+
this._data.currentState = 'start';
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if(!this._data.hasOwnProperty('response')) {
|
|
101
|
+
this._data.response = [];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
this._initStateMachine(this._data.currentState);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Handles state machine transitions
|
|
110
|
+
*/
|
|
111
|
+
async _handleTransition(lifecycle, ...args) {
|
|
112
|
+
this._logger.log(`Request ${this._data.requestId} is transitioning from ${lifecycle.from} to ${lifecycle.to} in response to ${lifecycle.transition}`);
|
|
113
|
+
|
|
114
|
+
switch(lifecycle.transition) {
|
|
115
|
+
case 'init':
|
|
116
|
+
return;
|
|
117
|
+
|
|
118
|
+
case 'createAccounts':
|
|
119
|
+
return this._createAccounts();
|
|
120
|
+
|
|
121
|
+
case 'error':
|
|
122
|
+
this._logger.log(`State machine is erroring with error: ${util.inspect(args)}`);
|
|
123
|
+
this._data.lastError = args[0] || new BackendError('unspecified error', 500);
|
|
124
|
+
break;
|
|
125
|
+
|
|
126
|
+
default:
|
|
127
|
+
this._logger.log(`Unhandled state transition for request ${this._data.requestId}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
async _executeCreateAccountsRequest(request) {
|
|
133
|
+
// eslint-disable-next-line no-async-promise-executor
|
|
134
|
+
return new Promise(async (resolve, reject) => {
|
|
135
|
+
const requestKey = `ac_${request.requestId}`;
|
|
136
|
+
|
|
137
|
+
const subId = await this._cache.subscribe(requestKey, async (cn, msg, subId) => {
|
|
138
|
+
try {
|
|
139
|
+
let error;
|
|
140
|
+
let message = JSON.parse(msg);
|
|
141
|
+
|
|
142
|
+
if (message.type === 'accountsCreationErrorResponse') {
|
|
143
|
+
error = new BackendError(`Got an error response creating accounts: ${util.inspect(message.data)}`, 500);
|
|
144
|
+
error.mojaloopError = message.data;
|
|
145
|
+
} else if (message.type !== 'accountsCreationSuccessfulResponse') {
|
|
146
|
+
this._logger.push({ message }).log(
|
|
147
|
+
`Ignoring cache notification for request ${requestKey}. ` +
|
|
148
|
+
`Unknown message type ${message.type}.`
|
|
149
|
+
);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// cancel the timeout handler
|
|
154
|
+
clearTimeout(timeout);
|
|
155
|
+
|
|
156
|
+
// stop listening for account creation response messages.
|
|
157
|
+
// no need to await for the unsubscribe to complete.
|
|
158
|
+
// we dont really care if the unsubscribe fails but we should log it regardless
|
|
159
|
+
this._cache.unsubscribe(requestKey, subId).catch(e => {
|
|
160
|
+
this._logger.log(`Error unsubscribing (in callback) ${requestKey} ${subId}: ${e.stack || util.inspect(e)}`);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
if (error) {
|
|
164
|
+
return reject(error);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const response = message.data;
|
|
168
|
+
this._logger.push({ response }).log('Account creation response received');
|
|
169
|
+
return resolve(response);
|
|
170
|
+
}
|
|
171
|
+
catch(err) {
|
|
172
|
+
return reject(err);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// set up a timeout for the request
|
|
177
|
+
const timeout = setTimeout(() => {
|
|
178
|
+
const err = new BackendError(`Timeout waiting for response to account creation request ${request.requestId}`, 504);
|
|
179
|
+
|
|
180
|
+
// we dont really care if the unsubscribe fails but we should log it regardless
|
|
181
|
+
this._cache.unsubscribe(requestKey, subId).catch(e => {
|
|
182
|
+
this._logger.log(`Error unsubscribing (in timeout handler) ${requestKey} ${subId}: ${e.stack || util.inspect(e)}`);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
return reject(err);
|
|
186
|
+
}, this._requestProcessingTimeoutSeconds * 1000);
|
|
187
|
+
|
|
188
|
+
// now we have a timeout handler and a cache subscriber hooked up we can fire off
|
|
189
|
+
// a POST /participants request to the switch
|
|
190
|
+
try {
|
|
191
|
+
const res = await this._requests.postParticipants(request);
|
|
192
|
+
this._logger.push({ res }).log('Account creation request sent to peer');
|
|
193
|
+
}
|
|
194
|
+
catch(err) {
|
|
195
|
+
// cancel the timout and unsubscribe before rejecting the promise
|
|
196
|
+
clearTimeout(timeout);
|
|
197
|
+
|
|
198
|
+
// we dont really care if the unsubscribe fails but we should log it regardless
|
|
199
|
+
this._cache.unsubscribe(requestKey, subId).catch(e => {
|
|
200
|
+
this._logger.log(`Error unsubscribing (in error handler) ${requestKey} ${subId}: ${e.stack || util.inspect(e)}`);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
return reject(err);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
async _createAccounts() {
|
|
210
|
+
const requests = this._buildRequests();
|
|
211
|
+
for await (let request of requests) {
|
|
212
|
+
const response = await this._executeCreateAccountsRequest(request);
|
|
213
|
+
this._data.response.push(...this._buildClientResponse(response));
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
_buildClientResponse(response) {
|
|
218
|
+
return response.partyList.map(party => ({
|
|
219
|
+
idType: party.partyId.partyIdType,
|
|
220
|
+
idValue: party.partyId.partyIdentifier,
|
|
221
|
+
idSubValue: party.partyId.partySubIdOrType,
|
|
222
|
+
...!response.currency && {
|
|
223
|
+
error: {
|
|
224
|
+
statusCode: Errors.MojaloopApiErrorCodes.CLIENT_ERROR.code,
|
|
225
|
+
message: 'Provided currency not supported',
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
...party.errorInformation && {
|
|
229
|
+
error: {
|
|
230
|
+
statusCode: party.errorInformation.errorCode,
|
|
231
|
+
message: party.errorInformation.errorDescription,
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
}));
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Builds accounts creation requests payload from current state
|
|
240
|
+
*
|
|
241
|
+
* @returns {Array} - the account creation requests
|
|
242
|
+
*/
|
|
243
|
+
_buildRequests() {
|
|
244
|
+
const MAX_ITEMS_PER_REQUEST = 10000; // As per API Spec 6.2.2.2 (partyList field)
|
|
245
|
+
|
|
246
|
+
const requests = [];
|
|
247
|
+
for (let account of this._data.accounts) {
|
|
248
|
+
let request = requests.find(req =>
|
|
249
|
+
req.currency === account.currency && (req.partyList.length < MAX_ITEMS_PER_REQUEST));
|
|
250
|
+
if (!request) {
|
|
251
|
+
request = {
|
|
252
|
+
requestId: uuid(),
|
|
253
|
+
partyList: [],
|
|
254
|
+
currency: account.currency,
|
|
255
|
+
};
|
|
256
|
+
requests.push(request);
|
|
257
|
+
}
|
|
258
|
+
request.partyList.push({
|
|
259
|
+
partyIdType: account.idType,
|
|
260
|
+
partyIdentifier: account.idValue,
|
|
261
|
+
partySubIdOrType: account.idSubValue,
|
|
262
|
+
fspId: this._dfspId,
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
return requests;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Returns an object representing the final state of the transfer suitable for the outbound API
|
|
270
|
+
*
|
|
271
|
+
* @returns {object} - Response representing the result of the transfer process
|
|
272
|
+
*/
|
|
273
|
+
getResponse() {
|
|
274
|
+
// we want to project some of our internal state into a more useful
|
|
275
|
+
// representation to return to the SDK API consumer
|
|
276
|
+
const resp = { ...this._data };
|
|
277
|
+
|
|
278
|
+
switch(this._data.currentState) {
|
|
279
|
+
case 'succeeded':
|
|
280
|
+
resp.currentState = stateEnum.COMPLETED;
|
|
281
|
+
break;
|
|
282
|
+
|
|
283
|
+
case 'errored':
|
|
284
|
+
resp.currentState = stateEnum.ERROR_OCCURRED;
|
|
285
|
+
break;
|
|
286
|
+
|
|
287
|
+
default:
|
|
288
|
+
this._logger.log(
|
|
289
|
+
`Account model response being returned from an unexpected state: ${this._data.currentState}. ` +
|
|
290
|
+
'Returning ERROR_OCCURRED state'
|
|
291
|
+
);
|
|
292
|
+
resp.currentState = stateEnum.ERROR_OCCURRED;
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return resp;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Persists the model state to cache for reinitialisation at a later point
|
|
302
|
+
*/
|
|
303
|
+
async _save() {
|
|
304
|
+
try {
|
|
305
|
+
this._data.currentState = this._stateMachine.state;
|
|
306
|
+
const res = await this._cache.set(`accountModel_${this._data.modelId}`, this._data);
|
|
307
|
+
this._logger.push({ res }).log('Persisted account model in cache');
|
|
308
|
+
}
|
|
309
|
+
catch(err) {
|
|
310
|
+
this._logger.push({ err }).log('Error saving account model');
|
|
311
|
+
throw err;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Loads an accounts model from cache for resumption of the accounts management process
|
|
318
|
+
*
|
|
319
|
+
* @param modelId {string} - UUID of the model to load from cache
|
|
320
|
+
*/
|
|
321
|
+
async load(modelId) {
|
|
322
|
+
try {
|
|
323
|
+
const data = await this._cache.get(`accountModel_${modelId}`);
|
|
324
|
+
if(!data) {
|
|
325
|
+
throw new BackendError(`No cached data found for account model with id: ${modelId}`, 500);
|
|
326
|
+
}
|
|
327
|
+
await this.initialize(data);
|
|
328
|
+
this._logger.push({ cache: this._data }).log('Account model loaded from cached state');
|
|
329
|
+
}
|
|
330
|
+
catch(err) {
|
|
331
|
+
this._logger.push({ err }).log('Error loading account model');
|
|
332
|
+
throw err;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Returns a promise that resolves when the state machine has reached a terminal state
|
|
339
|
+
*/
|
|
340
|
+
async run() {
|
|
341
|
+
try {
|
|
342
|
+
// run transitions based on incoming state
|
|
343
|
+
switch(this._data.currentState) {
|
|
344
|
+
case 'start': {
|
|
345
|
+
await this._stateMachine.createAccounts();
|
|
346
|
+
const accounts = this._data.response;
|
|
347
|
+
const failCount = accounts.filter((account) => account.error).length;
|
|
348
|
+
const successCount = this._data.response.length - failCount;
|
|
349
|
+
this._logger.log(`Accounts created: ${successCount} succeeded, ${failCount} failed`);
|
|
350
|
+
// if (failCount > 0) {
|
|
351
|
+
// throw new BackendError(`Failed to create ${failCount} account(s)`, 500);
|
|
352
|
+
// }
|
|
353
|
+
break;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
case 'succeeded':
|
|
357
|
+
// all steps complete so return
|
|
358
|
+
this._logger.log('Accounts creation completed');
|
|
359
|
+
await this._save();
|
|
360
|
+
return this.getResponse();
|
|
361
|
+
|
|
362
|
+
case 'errored':
|
|
363
|
+
// stopped in errored state
|
|
364
|
+
this._logger.log('State machine in errored state');
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// now call ourslves recursively to deal with the next transition
|
|
369
|
+
this._logger.log(
|
|
370
|
+
`Account model state machine transition completed in state: ${this._stateMachine.state}. ` +
|
|
371
|
+
'Handling next transition.'
|
|
372
|
+
);
|
|
373
|
+
return this.run();
|
|
374
|
+
}
|
|
375
|
+
catch(err) {
|
|
376
|
+
this._logger.log(`Error running account model: ${util.inspect(err)}`);
|
|
377
|
+
|
|
378
|
+
// as this function is recursive, we dont want to error the state machine multiple times
|
|
379
|
+
if(this._data.currentState !== 'errored') {
|
|
380
|
+
// err should not have a executionState property here!
|
|
381
|
+
if(err.executionState) {
|
|
382
|
+
this._logger.log(`State machine is broken: ${util.inspect(err)}`);
|
|
383
|
+
}
|
|
384
|
+
// transition to errored state
|
|
385
|
+
await this._stateMachine.error(err);
|
|
386
|
+
|
|
387
|
+
// avoid circular ref between executionState.lastError and err
|
|
388
|
+
err.executionState = JSON.parse(JSON.stringify(this.getResponse()));
|
|
389
|
+
}
|
|
390
|
+
throw err;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
module.exports = AccountsModel;
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**************************************************************************
|
|
2
|
+
* (C) Copyright ModusBox Inc. 2021 - All rights reserved. *
|
|
3
|
+
* *
|
|
4
|
+
* This file is made available under the terms of the license agreement *
|
|
5
|
+
* specified in the corresponding source code repository. *
|
|
6
|
+
* *
|
|
7
|
+
* ORIGINAL AUTHOR: *
|
|
8
|
+
* Paweł Marzec - pawel.marzec@modusbox.com *
|
|
9
|
+
**************************************************************************/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
const util = require('util');
|
|
13
|
+
|
|
14
|
+
const PSM = require('./common').PersistentStateMachine;
|
|
15
|
+
const MojaloopRequests = require('@mojaloop/sdk-standard-components').MojaloopRequests;
|
|
16
|
+
const deferredJob = require('./lib').deferredJob;
|
|
17
|
+
|
|
18
|
+
function generate({
|
|
19
|
+
/**
|
|
20
|
+
* @name channelNameMethod
|
|
21
|
+
* @description generates the pub/sub channel name
|
|
22
|
+
* @param {object} args - the arguments passed as object, same as passed to `run, triggerDeferredJob, generateKey` method
|
|
23
|
+
* @returns {string} - the pub/sub channel name
|
|
24
|
+
*/
|
|
25
|
+
channelNameMethod,
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @name requestActionMethod
|
|
29
|
+
* @description invokes the call to switch
|
|
30
|
+
* @param {object} requests - MojaloopRequests instance
|
|
31
|
+
* @param {array} args - the arguments passed as object to `run` method
|
|
32
|
+
*/
|
|
33
|
+
requestActionMethod,
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @name argsValidationMethod
|
|
37
|
+
* @description makes validation of args object, invoked in `run, triggerDeferredJob, generateKey` methods to ensure everything is going well
|
|
38
|
+
* @param {object} requests - MojaloopRequests instance
|
|
39
|
+
* @param {array} args - the arguments passed as object to `run` method
|
|
40
|
+
*/
|
|
41
|
+
argsValidationMethod,
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @name reformatMessageMethod
|
|
45
|
+
* @description reformats message received from PUB/SUB channel, it is optional method, if not specified identify function is used by default
|
|
46
|
+
* @param {object} message - message received
|
|
47
|
+
* @returns {object} - reformatted message
|
|
48
|
+
*/
|
|
49
|
+
reformatMessageMethod,
|
|
50
|
+
|
|
51
|
+
// the name of the model, used for logging
|
|
52
|
+
modelName
|
|
53
|
+
}) {
|
|
54
|
+
|
|
55
|
+
// don't reformat message if method not specified
|
|
56
|
+
const reformatMessage = reformatMessageMethod || ((m) => m);
|
|
57
|
+
|
|
58
|
+
const specStateMachine = {
|
|
59
|
+
init: 'start',
|
|
60
|
+
transitions: [
|
|
61
|
+
{ name: 'init', from: 'none', to: 'start' },
|
|
62
|
+
{ name: 'requestAction', from: 'start', to: 'succeeded' },
|
|
63
|
+
{ name: 'error', from: '*', to: 'errored' },
|
|
64
|
+
],
|
|
65
|
+
methods: {
|
|
66
|
+
// workflow methods
|
|
67
|
+
run,
|
|
68
|
+
getResponse,
|
|
69
|
+
|
|
70
|
+
// specific transitions handlers methods
|
|
71
|
+
onRequestAction
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @name run
|
|
77
|
+
* @description run the workflow logic
|
|
78
|
+
* @param {arguments} args - arguments
|
|
79
|
+
* @returns {Object} - the http response payload
|
|
80
|
+
*/
|
|
81
|
+
async function run(args) {
|
|
82
|
+
// input validation, it should throws if any of args is invalid
|
|
83
|
+
argsValidationMethod(args);
|
|
84
|
+
|
|
85
|
+
const { data, logger } = this.context;
|
|
86
|
+
try {
|
|
87
|
+
// run transitions based on incoming state
|
|
88
|
+
switch (data.currentState) {
|
|
89
|
+
case 'start':
|
|
90
|
+
// the first transition is requestAction
|
|
91
|
+
await this.requestAction(args);
|
|
92
|
+
// don't await to finish the save
|
|
93
|
+
this.saveToCache();
|
|
94
|
+
|
|
95
|
+
// eslint-disable-next-line no-fallthrough
|
|
96
|
+
case 'succeeded':
|
|
97
|
+
// all steps complete so return
|
|
98
|
+
logger.log('Action called successfully');
|
|
99
|
+
return this.getResponse();
|
|
100
|
+
|
|
101
|
+
case 'errored':
|
|
102
|
+
// stopped in errored state
|
|
103
|
+
logger.log('State machine in errored state');
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
} catch (err) {
|
|
107
|
+
logger.log(`Error running ${modelName} model: ${util.inspect(err)}`);
|
|
108
|
+
|
|
109
|
+
// as this function is recursive, we don't want to error the state machine multiple times
|
|
110
|
+
if (data.currentState !== 'errored') {
|
|
111
|
+
// err should not have a requestActionState property here!
|
|
112
|
+
if (err.requestActionState) {
|
|
113
|
+
logger.log('State machine is broken');
|
|
114
|
+
}
|
|
115
|
+
// transition to errored state
|
|
116
|
+
await this.error(err);
|
|
117
|
+
|
|
118
|
+
// avoid circular ref between requestActionState.lastError and err
|
|
119
|
+
err.requestActionState = JSON.parse(JSON.stringify(this.getResponse()));
|
|
120
|
+
}
|
|
121
|
+
throw err;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const mapCurrentState = {
|
|
126
|
+
start: 'WAITING_FOR_ACTION',
|
|
127
|
+
succeeded: 'COMPLETED',
|
|
128
|
+
errored: 'ERROR_OCCURRED'
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @name getResponse
|
|
133
|
+
* @description returns the http response payload depending on which state machine is
|
|
134
|
+
* @returns {Object} - the http response payload
|
|
135
|
+
*/
|
|
136
|
+
function getResponse() {
|
|
137
|
+
const { data, logger } = this.context;
|
|
138
|
+
let resp = { ...data };
|
|
139
|
+
|
|
140
|
+
// project some of our internal state into a more useful
|
|
141
|
+
// representation to return to the SDK API consumer
|
|
142
|
+
resp.currentState = mapCurrentState[data.currentState];
|
|
143
|
+
|
|
144
|
+
// handle unexpected state
|
|
145
|
+
if (!resp.currentState) {
|
|
146
|
+
logger.error(`${modelName} model response being returned from an unexpected state: ${data.currentState}. Returning ERROR_OCCURRED state`);
|
|
147
|
+
resp.currentState = mapCurrentState.errored;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return resp;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* @name onRequestAction
|
|
154
|
+
* @description generates the pub/sub channel name
|
|
155
|
+
* @param {object} args - the arguments passed as object
|
|
156
|
+
* @returns {string} - the pub/sub channel name
|
|
157
|
+
*/
|
|
158
|
+
async function onRequestAction(fsm, args) {
|
|
159
|
+
const { cache, logger } = this.context;
|
|
160
|
+
const { requests, config } = this.handlersContext;
|
|
161
|
+
logger.push({ args }).log('onRequestAction - arguments');
|
|
162
|
+
|
|
163
|
+
return deferredJob(cache, channelNameMethod(args))
|
|
164
|
+
.init(async (channel) => {
|
|
165
|
+
const res = await requestActionMethod(requests, args);
|
|
166
|
+
logger.push({ res, channel, args }).log('RequestAction call sent to peer, listening on response');
|
|
167
|
+
return res;
|
|
168
|
+
})
|
|
169
|
+
.job((message) => {
|
|
170
|
+
this.context.data = {
|
|
171
|
+
...reformatMessage(message),
|
|
172
|
+
currentState: this.state
|
|
173
|
+
};
|
|
174
|
+
logger.push({ message }).log('requestActionMethod message received');
|
|
175
|
+
})
|
|
176
|
+
.wait(config.requestProcessingTimeoutSeconds * 1000);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
*
|
|
182
|
+
* @param {object} cache - the cache instance used to publish message
|
|
183
|
+
* @param {object} message - the message used to trigger deferred job
|
|
184
|
+
* @param {object} args - args passed to channelNameMethod
|
|
185
|
+
* @returns {Promise} - the promise which resolves when deferred job is invoked
|
|
186
|
+
*/
|
|
187
|
+
async function triggerDeferredJob({ cache, message, args }) {
|
|
188
|
+
// input validation, it should throws if any of args is invalid
|
|
189
|
+
argsValidationMethod(args);
|
|
190
|
+
|
|
191
|
+
const cn = channelNameMethod(args);
|
|
192
|
+
return deferredJob(cache, cn).trigger(message);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* @name generateKey
|
|
197
|
+
* @description generates the cache key used to store state machine
|
|
198
|
+
* @param {object} args - args passed to channelNameMethod
|
|
199
|
+
|
|
200
|
+
* @returns {string} - the cache key
|
|
201
|
+
*/
|
|
202
|
+
function generateKey(args) {
|
|
203
|
+
// input validation, it should throws if any of args is invalid
|
|
204
|
+
argsValidationMethod(args);
|
|
205
|
+
|
|
206
|
+
return `key-${channelNameMethod(args)}`;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* @name injectHandlersContext
|
|
212
|
+
* @description injects the config into state machine data, so it will be accessible to on transition notification handlers via `this.handlersContext`
|
|
213
|
+
* @param {Object} config - config to be injected into state machine data
|
|
214
|
+
* @returns {Object} - the altered specStateMachine
|
|
215
|
+
*/
|
|
216
|
+
function injectHandlersContext(config) {
|
|
217
|
+
return {
|
|
218
|
+
...specStateMachine,
|
|
219
|
+
data: {
|
|
220
|
+
handlersContext: {
|
|
221
|
+
modelName,
|
|
222
|
+
config: { ...config }, // injects config property
|
|
223
|
+
requests: new MojaloopRequests({
|
|
224
|
+
logger: config.logger,
|
|
225
|
+
peerEndpoint: config.peerEndpoint,
|
|
226
|
+
alsEndpoint: config.alsEndpoint,
|
|
227
|
+
quotesEndpoint: config.quotesEndpoint,
|
|
228
|
+
transfersEndpoint: config.transfersEndpoint,
|
|
229
|
+
transactionRequestsEndpoint: config.transactionRequestsEndpoint,
|
|
230
|
+
dfspId: config.dfspId,
|
|
231
|
+
tls: config.tls,
|
|
232
|
+
jwsSign: config.jwsSign,
|
|
233
|
+
jwsSignPutParties: config.jwsSignPutParties,
|
|
234
|
+
jwsSigningKey: config.jwsSigningKey,
|
|
235
|
+
wso2Auth: config.wso2Auth
|
|
236
|
+
})
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* @name create
|
|
245
|
+
* @description creates a new instance of state machine specified in specStateMachine ^
|
|
246
|
+
* @param {Object} data - payload data
|
|
247
|
+
* @param {String} key - the cache key where state machine will store the payload data after each transition
|
|
248
|
+
* @param {Object} config - the additional configuration for transition handlers
|
|
249
|
+
*/
|
|
250
|
+
async function create(data, key, config) {
|
|
251
|
+
const spec = injectHandlersContext(config, specStateMachine);
|
|
252
|
+
return PSM.create(data, config.cache, key, config.logger, spec);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* @name loadFromCache
|
|
258
|
+
* @description loads state machine from cache by given key and specify the additional config for transition handlers
|
|
259
|
+
* @param {String} key - the cache key used to retrieve the state machine from cache
|
|
260
|
+
* @param {Object} config - the additional configuration for transition handlers
|
|
261
|
+
*/
|
|
262
|
+
async function loadFromCache(key, config) {
|
|
263
|
+
const customCreate = async (data, _cache, key) => create(data, key, config);
|
|
264
|
+
return PSM.loadFromCache(config.cache, key, config.logger, specStateMachine, customCreate);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
return {
|
|
269
|
+
channelName: channelNameMethod,
|
|
270
|
+
triggerDeferredJob,
|
|
271
|
+
create,
|
|
272
|
+
generateKey,
|
|
273
|
+
loadFromCache,
|
|
274
|
+
|
|
275
|
+
// exports for testing purposes
|
|
276
|
+
mapCurrentState
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
module.exports = {
|
|
281
|
+
generate
|
|
282
|
+
};
|
|
283
|
+
|