ml-testing-toolkit 18.13.0
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/.dockerignore +10 -0
- package/.grype.yaml +16 -0
- package/.ncurc.yaml +9 -0
- package/.nvmrc +1 -0
- package/.versionrc.js +16 -0
- package/CHANGELOG.md +504 -0
- package/CODEOWNERS +30 -0
- package/Dockerfile +42 -0
- package/Dockerfile-newman +13 -0
- package/LICENSE.md +9 -0
- package/README.md +119 -0
- package/assets/diagrams/architectural/architectural-diagram.svg +3 -0
- package/assets/diagrams/flow/flow-diagram.svg +3 -0
- package/assets/images/Sample-Response-Failure.png +0 -0
- package/assets/images/Screenshot 2020-04-16 at 22.58.04.png +0 -0
- package/assets/images/TLS-Enabled-on-Environment.png +0 -0
- package/assets/images/adapter-mutual-tls-enabled.png +0 -0
- package/assets/images/add-additional-input-values.png +0 -0
- package/assets/images/add-condition-button.png +0 -0
- package/assets/images/add-new-assertion.png +0 -0
- package/assets/images/add-new-input-value.png +0 -0
- package/assets/images/add-new-input-variable.png +0 -0
- package/assets/images/additional-transfers.png +0 -0
- package/assets/images/api-provisioning-add-new-api-confirmation.png +0 -0
- package/assets/images/api-provisioning-file-input-window.png +0 -0
- package/assets/images/api-provisioning-list-apis-view.png +0 -0
- package/assets/images/api-provisioning-menu-item.png +0 -0
- package/assets/images/apply_and_restart.jpg +0 -0
- package/assets/images/assess-request-or-response.png +0 -0
- package/assets/images/assess-response-equation-save.png +0 -0
- package/assets/images/assess-response-equation.png +0 -0
- package/assets/images/assess-response-status.png +0 -0
- package/assets/images/building-new-rules-file.png +0 -0
- package/assets/images/callback-rules-screen.png +0 -0
- package/assets/images/configurable-parameter-assertion.png +0 -0
- package/assets/images/configurable-parameter-currency.png +0 -0
- package/assets/images/configurable-parameter.png +0 -0
- package/assets/images/connection-manager-ui-opening.png +0 -0
- package/assets/images/create-inbound-user-simulator.png +0 -0
- package/assets/images/creating-new-rule-file.png +0 -0
- package/assets/images/dfsp-client-cacert.png +0 -0
- package/assets/images/dfsp-client-submit.png +0 -0
- package/assets/images/dfsp-client.png +0 -0
- package/assets/images/dfsp-p2p-happy-path.png +0 -0
- package/assets/images/dfsp-server-cacert.png +0 -0
- package/assets/images/dfsp-server-cert.png +0 -0
- package/assets/images/download-report.png +0 -0
- package/assets/images/drive_have_not_been_shared.jpg +0 -0
- package/assets/images/event-response-options.png +0 -0
- package/assets/images/expand-monitoring-messages.png +0 -0
- package/assets/images/fixed-response-sample.png +0 -0
- package/assets/images/header-selection.png +0 -0
- package/assets/images/heap_error_windows.jpg +0 -0
- package/assets/images/hosted-mode-docker-compose-intro.png +0 -0
- package/assets/images/hub-client-cert.png +0 -0
- package/assets/images/import-template.png +0 -0
- package/assets/images/inbound-requests-environment.png +0 -0
- package/assets/images/inbound-requests-scripts.png +0 -0
- package/assets/images/jws-certificate-submit.png +0 -0
- package/assets/images/jws-certificate.png +0 -0
- package/assets/images/jws-certs-keys.png +0 -0
- package/assets/images/jws-hub-certs-keys.png +0 -0
- package/assets/images/local-enable-jws-publickey.png +0 -0
- package/assets/images/local-mutual-tls-enabled.png +0 -0
- package/assets/images/local_drives_to_be_available.jpg +0 -0
- package/assets/images/mcm-environment-opening.png +0 -0
- package/assets/images/menu-items.png +0 -0
- package/assets/images/mock-response-sample.png +0 -0
- package/assets/images/monitoring-initial-state.png +0 -0
- package/assets/images/monitoring-messages.png +0 -0
- package/assets/images/new-empty-assertion.png +0 -0
- package/assets/images/opened-imported-template.png +0 -0
- package/assets/images/opening-default-settings.png +0 -0
- package/assets/images/opening-sync-response-rules.png +0 -0
- package/assets/images/opening-view.png +0 -0
- package/assets/images/outbound-display-opening-hub.png +0 -0
- package/assets/images/outbound-display-opening.png +0 -0
- package/assets/images/override-with-environment-variable.png +0 -0
- package/assets/images/populate-with-sample-body.png +0 -0
- package/assets/images/resource-selection.png +0 -0
- package/assets/images/rule-builder-select-api.png +0 -0
- package/assets/images/sample-condition-add-configurable-params.png +0 -0
- package/assets/images/sample-condition.png +0 -0
- package/assets/images/sample-editor.png +0 -0
- package/assets/images/sample-request.png +0 -0
- package/assets/images/sample-test-assertion.png +0 -0
- package/assets/images/send-transfer.png +0 -0
- package/assets/images/sending-single-test-case-1.png +0 -0
- package/assets/images/sending-single-test-case-2.png +0 -0
- package/assets/images/sending-test-cases.png +0 -0
- package/assets/images/server-certificates-submitted.png +0 -0
- package/assets/images/simulator-response.png +0 -0
- package/assets/images/simulator-scheme-adapter-endpoint.png +0 -0
- package/assets/images/summarized-view-of-rule.png +0 -0
- package/assets/images/template-window.png +0 -0
- package/assets/images/test-case-editor-console-log.png +0 -0
- package/assets/images/test-case-editor-environment-state.png +0 -0
- package/assets/images/test-case-editor-scripts.png +0 -0
- package/assets/images/test-case-editor.png +0 -0
- package/assets/images/testcase-definition-download.png +0 -0
- package/assets/images/testcase-definition-edit-meta-info.png +0 -0
- package/assets/images/testing-toolkit-mojaloop-testing-toolkit-endpoint.png +0 -0
- package/assets/images/tls-hub-certs-keys.png +0 -0
- package/assets/images/tls-jws-enabled-on-environment.png +0 -0
- package/assets/images/updated-sample-body-data.png +0 -0
- package/assets/images/using-configurable-parameter.png +0 -0
- package/assets/images/validation-rules-screen.png +0 -0
- package/assets/images/view-response.png +0 -0
- package/audit-ci.jsonc +7 -0
- package/connection-manager/docker-compose.yml +55 -0
- package/database/docker-compose.yml +16 -0
- package/docker/hosted-mode/docker-compose.yaml +107 -0
- package/docker/hosted-mode/keycloak/keycloak-realm.json +2298 -0
- package/docker/hosted-mode/mongo-init.sh +1 -0
- package/docker/hosted-mode-tls/docker-compose.yaml +171 -0
- package/docker/hosted-mode-tls/keycloak/keycloak-realm.json +2298 -0
- package/docker/hosted-mode-tls/mongo-init.sh +1 -0
- package/docker-compose.yml +62 -0
- package/documents/Mojaloop-Testing-Toolkit.md +296 -0
- package/documents/RULES_ENGINE.md +403 -0
- package/documents/User-Guide-API-Provisioning.md +121 -0
- package/documents/User-Guide-CLI.md +218 -0
- package/documents/User-Guide-Connection-Manager.md +282 -0
- package/documents/User-Guide-Frequently-Asked-Questions.md +39 -0
- package/documents/User-Guide-Hosted-Mode-Docker-Compose.md +110 -0
- package/documents/User-Guide-Installation.md +163 -0
- package/documents/User-Guide-Mojaloop-Testing-Toolkit.md +642 -0
- package/documents/User-Guide-OAuth-Server-Deployment.md +283 -0
- package/documents/User-Guide-Onboarding-DFSP.md +197 -0
- package/documents/User-Guide-Onboarding-HUB.md +191 -0
- package/documents/User-Guide.md +53 -0
- package/examples/collections/dfsp/p2p_failed_tests.json +7161 -0
- package/examples/collections/dfsp/p2p_fx_happy_path.json +502 -0
- package/examples/collections/dfsp/p2p_happy_path.json +350 -0
- package/examples/collections/dfsp/p2p_happy_path_extended.json +6106 -0
- package/examples/collections/dfsp/p2p_happy_path_jws.json +511 -0
- package/examples/collections/dfsp/p2p_payee_assertions_websocket.json +441 -0
- package/examples/collections/dfsp/sample.json +5029 -0
- package/examples/collections/dfsp/transaction_request_service.json +240 -0
- package/examples/collections/fxp/FXP.json +264 -0
- package/examples/collections/fxp/SDK_backend.json +98 -0
- package/examples/collections/fxp/SDK_outbound.json +163 -0
- package/examples/collections/hub/hub_01_p2p_happy_path/hub_p2p_receive_quote.json +400 -0
- package/examples/collections/hub/hub_01_p2p_happy_path/hub_p2p_send_quote.json +395 -0
- package/examples/collections/hub/hub_02_block_transfer/hub_block_transfer.json +393 -0
- package/examples/collections/hub/hub_03_funds_in_out/hub_funds_in.json +224 -0
- package/examples/collections/hub/hub_03_funds_in_out/hub_funds_out.json +780 -0
- package/examples/collections/hub/hub_04_settlements/hub_settlements.json +3138 -0
- package/examples/collections/hub/hub_05_transfer_negative_scenarios/hub_transfer_negative_payee_abort.json +475 -0
- package/examples/collections/hub/hub_05_transfer_negative_scenarios/hub_transfer_negative_payee_invalid_fulfillment.json +370 -0
- package/examples/collections/hub/hub_05_transfer_negative_scenarios/hub_transfer_negative_transfer_timeout.json +262 -0
- package/examples/collections/hub/hub_06_transaction_requests_service/hub_trs_authorizations.json +117 -0
- package/examples/collections/hub/hub_06_transaction_requests_service/hub_trs_error_framework.json +591 -0
- package/examples/collections/hub/hub_06_transaction_requests_service/hub_trs_received_state.json +379 -0
- package/examples/collections/hub/hub_06_transaction_requests_service/hub_trs_reject_state.json +361 -0
- package/examples/collections/hub/hub_07_quoting_service.json +525 -0
- package/examples/collections/hub/hub_08_participant_inactive_stop_transfers.json +706 -0
- package/examples/collections/hub/hub_09_duplicate_handling_transfers.json +1377 -0
- package/examples/collections/hub/hub_10_on_us_transfers.json +245 -0
- package/examples/collections/hub/hub_11_accented_and_spl_chars.json +629 -0
- package/examples/collections/hub/hub_12_fspiop_version_1.1.json +646 -0
- package/examples/collections/hub/hub_13_bulk_transfers.json +1857 -0
- package/examples/collections/iso20022/self_referencing_iso20022.json +926 -0
- package/examples/collections/provisioning/testingtoolkitdfsp.json +904 -0
- package/examples/environments/dfsp_local_environment.json +46 -0
- package/examples/environments/hub_local_environment.json +57 -0
- package/jest.config.js +17 -0
- package/package.json +199 -0
- package/sbom-v18.12.4.csv +1553 -0
- package/secrets/keygen.sh +5 -0
- package/secrets/privatekey.pem +27 -0
- package/secrets/publickey.cer +21 -0
- package/secrets/tls/01.pem +132 -0
- package/secrets/tls/createSecrets.sh +20 -0
- package/secrets/tls/hub_client.csr +32 -0
- package/secrets/tls/hub_client_cacert.pem +35 -0
- package/secrets/tls/hub_client_cakey.pem +52 -0
- package/secrets/tls/hub_client_key.key +52 -0
- package/secrets/tls/hub_server.csr +31 -0
- package/secrets/tls/hub_server_cacert.pem +35 -0
- package/secrets/tls/hub_server_cakey.pem +52 -0
- package/secrets/tls/hub_server_cert.pem +132 -0
- package/secrets/tls/hub_server_key.key +52 -0
- package/secrets/tls/index.txt +1 -0
- package/secrets/tls/index.txt.attr +1 -0
- package/secrets/tls/openssl-client.cnf +36 -0
- package/secrets/tls/openssl-clientca.cnf +71 -0
- package/secrets/tls/openssl-server.cnf +39 -0
- package/secrets/tls/openssl-serverca.cnf +71 -0
- package/secrets/tls/serial.txt +1 -0
- package/spec_files/api_definitions/als_admin_1.1/api_spec.yaml +804 -0
- package/spec_files/api_definitions/central_admin_1.0/api_spec.yaml +1850 -0
- package/spec_files/api_definitions/central_admin_1.0/response_map.json +96 -0
- package/spec_files/api_definitions/central_admin_old_9.3/api_spec.yaml +2467 -0
- package/spec_files/api_definitions/central_admin_old_9.3/response_map.json +96 -0
- package/spec_files/api_definitions/fspiop_1.0/api_spec.yaml +4187 -0
- package/spec_files/api_definitions/fspiop_1.0/callback_map.json +568 -0
- package/spec_files/api_definitions/fspiop_1.0/mockRef.json +79 -0
- package/spec_files/api_definitions/fspiop_1.0/trigger_templates/transaction_request_followup.json +126 -0
- package/spec_files/api_definitions/fspiop_1.0/trigger_templates/transaction_request_followup_quotes_only.json +97 -0
- package/spec_files/api_definitions/fspiop_1.1/api_spec.yaml +3778 -0
- package/spec_files/api_definitions/fspiop_1.1/callback_map.json +568 -0
- package/spec_files/api_definitions/fspiop_1.1/mockRef.json +79 -0
- package/spec_files/api_definitions/fspiop_1.1/trigger_templates/transaction_request_followup.json +125 -0
- package/spec_files/api_definitions/fspiop_2.0/api_spec.yaml +4839 -0
- package/spec_files/api_definitions/fspiop_2.0/callback_map.json +716 -0
- package/spec_files/api_definitions/fspiop_2.0/mockRef.json +79 -0
- package/spec_files/api_definitions/fspiop_2.0/trigger_templates/transaction_request_followup.json +125 -0
- package/spec_files/api_definitions/fspiop_2.0_iso20022/api_spec.yaml +8331 -0
- package/spec_files/api_definitions/fspiop_2.0_iso20022/callback_map.json +508 -0
- package/spec_files/api_definitions/fspiop_2.0_iso20022/mockRef.json +66 -0
- package/spec_files/api_definitions/fx-api_2.0/api_spec.yaml +1768 -0
- package/spec_files/api_definitions/fx-api_2.0/callback_map.json +188 -0
- package/spec_files/api_definitions/fx-api_2.0/mockRef.json +83 -0
- package/spec_files/api_definitions/mojaloop_sdk_outbound_scheme_adapter_1.0/api_spec.yaml +2612 -0
- package/spec_files/api_definitions/mojaloop_sdk_outbound_scheme_adapter_1.0/mockRef.json +22 -0
- package/spec_files/api_definitions/mojaloop_sdk_outbound_scheme_adapter_1.0/response_map.json +35 -0
- package/spec_files/api_definitions/mojaloop_simulator_0.1/api_spec.yaml +225 -0
- package/spec_files/api_definitions/mojaloop_simulator_sim_1.4/api_spec.yaml +1087 -0
- package/spec_files/api_definitions/mojaloop_simulator_sim_1.4/mockRef.json +75 -0
- package/spec_files/api_definitions/mojaloop_simulator_sim_1.4/response_map.json +55 -0
- package/spec_files/api_definitions/payment_manager_1.4/api_spec.yaml +1389 -0
- package/spec_files/api_definitions/sdk-scheme-adapter-backend-v2_1_0-openapi3-snippets_2.1/api_spec.yaml +2834 -0
- package/spec_files/api_definitions/sdk-scheme-adapter-outbound-v2_1_0-openapi3-snippets_2.1/api_spec.yaml +3449 -0
- package/spec_files/api_definitions/settlements_1.0/api_spec.yaml +983 -0
- package/spec_files/api_definitions/settlements_1.0/mockRef.json +38 -0
- package/spec_files/api_definitions/settlements_1.0/response_map.json +34 -0
- package/spec_files/api_definitions/settlements_2.0/api_spec.yaml +1001 -0
- package/spec_files/api_definitions/settlements_2.0/mockRef.json +38 -0
- package/spec_files/api_definitions/settlements_2.0/response_map.json +34 -0
- package/spec_files/api_definitions/thirdparty_sdk_outbound_0.1/api_spec.yaml +2139 -0
- package/spec_files/reports/templates/newman/html_template.html +1202 -0
- package/spec_files/reports/templates/newman/pdf_template.html +790 -0
- package/spec_files/reports/templates/testcase_definition/table_view.html +1602 -0
- package/spec_files/rules_callback/config.json +3 -0
- package/spec_files/rules_callback/default.json +2698 -0
- package/spec_files/rules_callback/p2p-limit.json +129 -0
- package/spec_files/rules_forward/config.json +3 -0
- package/spec_files/rules_forward/default.json +482 -0
- package/spec_files/rules_response/config.json +3 -0
- package/spec_files/rules_response/default.json +295 -0
- package/spec_files/rules_validation/config.json +3 -0
- package/spec_files/rules_validation/default.json +1 -0
- package/spec_files/rules_validation/p2p-limit.json +55 -0
- package/spec_files/system_config.json +175 -0
- package/spec_files/user_config.json +109 -0
- package/src/index.js +67 -0
- package/src/lib/MyEventEmitter.js +54 -0
- package/src/lib/api-management.js +143 -0
- package/src/lib/api-routes/config.js +83 -0
- package/src/lib/api-routes/history.js +139 -0
- package/src/lib/api-routes/keycloak.js +54 -0
- package/src/lib/api-routes/longpolling.js +70 -0
- package/src/lib/api-routes/oauth2.js +149 -0
- package/src/lib/api-routes/objectstore.js +53 -0
- package/src/lib/api-routes/openapi.js +224 -0
- package/src/lib/api-routes/outbound.js +134 -0
- package/src/lib/api-routes/reports.js +72 -0
- package/src/lib/api-routes/rules.js +356 -0
- package/src/lib/api-routes/samples.js +92 -0
- package/src/lib/api-routes/server-logs.js +44 -0
- package/src/lib/api-routes/settings.js +71 -0
- package/src/lib/api-server.js +135 -0
- package/src/lib/arrayStore.js +101 -0
- package/src/lib/callbackHandler.js +201 -0
- package/src/lib/config.js +177 -0
- package/src/lib/configuration-providers/mb-connection-manager.js +625 -0
- package/src/lib/db/adapters/dbAdapter.js +184 -0
- package/src/lib/db/dfspMockUsers.js +64 -0
- package/src/lib/db/models/mongoDBWrapper.js +78 -0
- package/src/lib/eventListenerClient/inboundEventListener.js +176 -0
- package/src/lib/fileAdapter.js +57 -0
- package/src/lib/httpAgentStore.js +135 -0
- package/src/lib/importExport.js +186 -0
- package/src/lib/jws/JwsSigning.js +141 -0
- package/src/lib/loadSamples.js +128 -0
- package/src/lib/logger.js +20 -0
- package/src/lib/longpollingEmitter.js +56 -0
- package/src/lib/metrics.js +51 -0
- package/src/lib/mocking/custom-functions/generic.js +57 -0
- package/src/lib/mocking/middleware-functions/ilpModel.js +238 -0
- package/src/lib/mocking/middleware-functions/quotesAssociation.js +75 -0
- package/src/lib/mocking/middleware-functions/transactionRequestsService.js +78 -0
- package/src/lib/mocking/openApiDefinitionsModel.js +64 -0
- package/src/lib/mocking/openApiMockHandler.js +466 -0
- package/src/lib/mocking/openApiRulesEngine.js +492 -0
- package/src/lib/mocking/openApiVersionTools.js +136 -0
- package/src/lib/mocking/transformers/fspiopToISO20022.js +230 -0
- package/src/lib/mocking/transformers/index.js +41 -0
- package/src/lib/notificationEmitter.js +64 -0
- package/src/lib/oauth/KeycloakHelper.js +220 -0
- package/src/lib/oauth/LoginService.js +133 -0
- package/src/lib/oauth/OAuthHelper.js +181 -0
- package/src/lib/oauth/OAuthValidator.js +118 -0
- package/src/lib/oauth/Wso2Client.js +64 -0
- package/src/lib/objectStore/inMemoryImpl.js +50 -0
- package/src/lib/objectStore/objectStoreInterface.js +51 -0
- package/src/lib/objectStore.js +122 -0
- package/src/lib/report-generator/generator.js +126 -0
- package/src/lib/report-generator/helpers.js +154 -0
- package/src/lib/requestLogger.js +190 -0
- package/src/lib/resources/wso2carbon-publickey.cert +20 -0
- package/src/lib/rulesEngine.js +95 -0
- package/src/lib/rulesEngineModel.js +463 -0
- package/src/lib/scripting-engines/postman-sandbox.js +142 -0
- package/src/lib/scripting-engines/vm-javascript-sandbox.js +294 -0
- package/src/lib/server-logs/adapters/elastic-search.js +102 -0
- package/src/lib/server-logs/adapters/grafana.js +0 -0
- package/src/lib/server-logs/index.js +75 -0
- package/src/lib/socket-server.js +55 -0
- package/src/lib/storageAdapter.js +109 -0
- package/src/lib/test-outbound/TestCaseRunner.js +173 -0
- package/src/lib/test-outbound/getTracing.js +19 -0
- package/src/lib/test-outbound/outbound-initiator.js +1107 -0
- package/src/lib/uniqueIdGenerator.js +35 -0
- package/src/lib/utils.js +89 -0
- package/src/lib/utilsInternal.js +56 -0
- package/src/lib/webSocketClient/WebSocketClientManager.js +197 -0
- package/src/server.js +218 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/*****
|
|
2
|
+
License
|
|
3
|
+
--------------
|
|
4
|
+
Copyright © 2020-2025 Mojaloop Foundation
|
|
5
|
+
The Mojaloop files are made available by the Mojaloop 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
|
+
Mojaloop Foundation 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
|
+
* Mojaloop Foundation
|
|
23
|
+
- Name Surname <name.surname@mojaloop.io>
|
|
24
|
+
|
|
25
|
+
* ModusBox
|
|
26
|
+
* Georgi Logodazhki <georgi.logodazhki@modusbox.com> (Original Author)
|
|
27
|
+
--------------
|
|
28
|
+
******/
|
|
29
|
+
|
|
30
|
+
const { rmdirAsync } = require('./utils')
|
|
31
|
+
const AdmZip = require('adm-zip')
|
|
32
|
+
const Config = require('./config')
|
|
33
|
+
const { Engine } = require('json-rules-engine')
|
|
34
|
+
const CONFIG_FILE_NAME = 'config.json'
|
|
35
|
+
const storageAdapter = require('./storageAdapter')
|
|
36
|
+
|
|
37
|
+
const exportSpecFiles = async (ruleTypes, user) => {
|
|
38
|
+
const zip = new AdmZip()
|
|
39
|
+
|
|
40
|
+
for (const index in ruleTypes) {
|
|
41
|
+
const ruleType = ruleTypes[index]
|
|
42
|
+
if (user) {
|
|
43
|
+
if (ruleType.endsWith('.json')) {
|
|
44
|
+
const filename = `spec_files/${ruleType}`
|
|
45
|
+
const document = await storageAdapter.read(filename, user)
|
|
46
|
+
zip.addFile(filename, Buffer.from(JSON.stringify(document.data)))
|
|
47
|
+
} else {
|
|
48
|
+
const filename = `spec_files/${ruleType}/`
|
|
49
|
+
const documents = await storageAdapter.read(filename, user)
|
|
50
|
+
for (const index in documents) {
|
|
51
|
+
const id = filename + documents[index]
|
|
52
|
+
const document = await storageAdapter.read(id, user)
|
|
53
|
+
zip.addFile(id, Buffer.from(JSON.stringify(document.data)))
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
if (ruleType.endsWith('.json')) {
|
|
58
|
+
const filename = `spec_files/${ruleType}`
|
|
59
|
+
zip.addLocalFile(filename)
|
|
60
|
+
} else {
|
|
61
|
+
const filename = `spec_files/${ruleType}/`
|
|
62
|
+
zip.addLocalFolder(filename, ruleType)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
namePrefix: ruleTypes.length > 1 ? 'spec_files' : ruleTypes[0],
|
|
68
|
+
buffer: zip.toBuffer()
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const validateRules = (entryName, ruleType, ruleVersion, rules) => {
|
|
73
|
+
const engine = new Engine()
|
|
74
|
+
rules.forEach(rule => {
|
|
75
|
+
if (rule.type !== ruleType) {
|
|
76
|
+
throw new Error(`validation error: rule ${rule.ruleId} in ${entryName} should be of type ${ruleType}`)
|
|
77
|
+
}
|
|
78
|
+
if (rule.version > ruleVersion) {
|
|
79
|
+
throw new Error(`validation error: rule ${rule.ruleId} in ${entryName} version should at most ${ruleVersion}`)
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
engine.addRule(rule)
|
|
83
|
+
} catch (err) {
|
|
84
|
+
throw new Error(`validation error: rule ${rule.ruleId} in ${entryName} is not valid: ${err.message}`)
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const validateInputData = (zipEntries, options) => {
|
|
90
|
+
const entries = []
|
|
91
|
+
zipEntries.forEach((zipEntry) => {
|
|
92
|
+
const entryName = zipEntry.entryName
|
|
93
|
+
const entryData = JSON.parse(zipEntry.getData().toString('utf-8'))
|
|
94
|
+
entries.push({
|
|
95
|
+
name: entryName,
|
|
96
|
+
data: entryData
|
|
97
|
+
})
|
|
98
|
+
const element = entryName.split('/')[0]
|
|
99
|
+
if (options.includes(element)) {
|
|
100
|
+
switch (element) {
|
|
101
|
+
case 'rules_response': {
|
|
102
|
+
if (entryName !== `rules_response/${CONFIG_FILE_NAME}`) {
|
|
103
|
+
validateRules(entryName, 'response', Config.getSystemConfig().CONFIG_VERSIONS.response, entryData)
|
|
104
|
+
}
|
|
105
|
+
break
|
|
106
|
+
}
|
|
107
|
+
case 'rules_validation': {
|
|
108
|
+
if (entryName !== `rules_validation/${CONFIG_FILE_NAME}`) {
|
|
109
|
+
validateRules(entryName, 'validation', Config.getSystemConfig().CONFIG_VERSIONS.validation, entryData)
|
|
110
|
+
}
|
|
111
|
+
break
|
|
112
|
+
}
|
|
113
|
+
case 'rules_callback': {
|
|
114
|
+
if (entryName !== `rules_callback/${CONFIG_FILE_NAME}`) {
|
|
115
|
+
validateRules(entryName, 'callback', Config.getSystemConfig().CONFIG_VERSIONS.callback, entryData)
|
|
116
|
+
}
|
|
117
|
+
break
|
|
118
|
+
}
|
|
119
|
+
case 'user_config.json': {
|
|
120
|
+
const userSettingsVersion = Config.getSystemConfig().CONFIG_VERSIONS.userSettings
|
|
121
|
+
if (entryData.VERSION > userSettingsVersion) {
|
|
122
|
+
throw new Error(`validation error: user_config.json version ${entryData.VERSION} not supproted be at most ${userSettingsVersion}`)
|
|
123
|
+
}
|
|
124
|
+
break
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
return entries
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const extractData = async (zip, options, entries, user) => {
|
|
133
|
+
for (const index in options) {
|
|
134
|
+
if (user) {
|
|
135
|
+
for (const index in entries) {
|
|
136
|
+
const id = entries[index].name
|
|
137
|
+
const data = entries[index].data
|
|
138
|
+
await storageAdapter.upsert(id, data, user)
|
|
139
|
+
}
|
|
140
|
+
} else {
|
|
141
|
+
const option = options[index]
|
|
142
|
+
if (option === 'user_config.json') {
|
|
143
|
+
zip.extractEntryTo(option, 'spec_files', false, true)
|
|
144
|
+
} else {
|
|
145
|
+
let deleted = false
|
|
146
|
+
for (const index in entries) {
|
|
147
|
+
const entry = entries[index].name
|
|
148
|
+
if (entry.startsWith(option)) {
|
|
149
|
+
if (!deleted) {
|
|
150
|
+
await rmdirAsync(`spec_files/${option}`, { recursive: true })
|
|
151
|
+
deleted = true
|
|
152
|
+
}
|
|
153
|
+
zip.extractEntryTo(entry, `spec_files/${option}`, false)
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const importSpecFiles = async (data, options, user) => {
|
|
162
|
+
const zip = new AdmZip(Buffer.from(data))
|
|
163
|
+
const entries = validateInputData(zip.getEntries(), options)
|
|
164
|
+
await extractData(zip, options, entries, user)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const exportSpecFile = async (filepath, user) => {
|
|
168
|
+
const filename = `spec_files/${filepath}`
|
|
169
|
+
const document = await storageAdapter.read(filename, user)
|
|
170
|
+
const documentBuffer = Buffer.from(JSON.stringify(document.data))
|
|
171
|
+
return {
|
|
172
|
+
buffer: documentBuffer
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const importSpecFile = async (data, filePath, user) => {
|
|
177
|
+
const dataBuffer = JSON.parse(Buffer.from(data).toString())
|
|
178
|
+
await storageAdapter.upsert(`spec_files/${filePath}`, dataBuffer, user)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
module.exports = {
|
|
182
|
+
exportSpecFiles,
|
|
183
|
+
importSpecFiles,
|
|
184
|
+
exportSpecFile,
|
|
185
|
+
importSpecFile
|
|
186
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/*****
|
|
2
|
+
License
|
|
3
|
+
--------------
|
|
4
|
+
Copyright © 2020-2025 Mojaloop Foundation
|
|
5
|
+
The Mojaloop files are made available by the Mojaloop 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
|
+
Mojaloop Foundation 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
|
+
* Mojaloop Foundation
|
|
23
|
+
- Name Surname <name.surname@mojaloop.io>
|
|
24
|
+
|
|
25
|
+
* ModusBox
|
|
26
|
+
* Vijaya Kumar Guthi <vijaya.guthi@modusbox.com> (Original Author)
|
|
27
|
+
--------------
|
|
28
|
+
******/
|
|
29
|
+
|
|
30
|
+
// const config = {}
|
|
31
|
+
|
|
32
|
+
const Config = require('../config')
|
|
33
|
+
const { Jws } = require('@mojaloop/sdk-standard-components')
|
|
34
|
+
const ConnectionProvider = require('../configuration-providers/mb-connection-manager')
|
|
35
|
+
const atob = require('atob')
|
|
36
|
+
|
|
37
|
+
const validate = async (req) => {
|
|
38
|
+
const userConfig = await Config.getUserConfig()
|
|
39
|
+
if (userConfig.VALIDATE_INBOUND_JWS) {
|
|
40
|
+
if (req.method === 'get') {
|
|
41
|
+
return false
|
|
42
|
+
}
|
|
43
|
+
if (req.method === 'put' && req.path.startsWith('/parties/') && !userConfig.VALIDATE_INBOUND_PUT_PARTIES_JWS) {
|
|
44
|
+
return false
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const certificate = await ConnectionProvider.getUserDfspJWSCerts(req.headers['fspiop-source'])
|
|
48
|
+
return validateWithCert(req.headers, req.payload, certificate)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const validateWithCert = (headers, body, certificate) => {
|
|
53
|
+
const reqOpts = {
|
|
54
|
+
headers,
|
|
55
|
+
body,
|
|
56
|
+
resolveWithFullResponse: true,
|
|
57
|
+
simple: false
|
|
58
|
+
}
|
|
59
|
+
const keys = {}
|
|
60
|
+
keys[headers['fspiop-source']] = certificate
|
|
61
|
+
|
|
62
|
+
const jwsValidator = new Jws.validator({ // eslint-disable-line
|
|
63
|
+
validationKeys: keys
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
jwsValidator.validate(reqOpts)
|
|
68
|
+
return true
|
|
69
|
+
} catch (err) {
|
|
70
|
+
throw new Error(err.toString())
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const validateProtectedHeaders = (headers) => {
|
|
75
|
+
if (!headers['fspiop-signature']) {
|
|
76
|
+
throw new Error('fspiop-signature is missing in the headers')
|
|
77
|
+
}
|
|
78
|
+
const { protectedHeader } = JSON.parse(headers['fspiop-signature'])
|
|
79
|
+
const decodedProtectedHeader = JSON.parse(atob(protectedHeader))
|
|
80
|
+
const jwsValidator = new Jws.validator({ // eslint-disable-line
|
|
81
|
+
validationKeys: []
|
|
82
|
+
})
|
|
83
|
+
jwsValidator._validateProtectedHeader(headers, decodedProtectedHeader)
|
|
84
|
+
return true
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const sign = async (req) => {
|
|
88
|
+
const userConfig = await Config.getUserConfig()
|
|
89
|
+
if (userConfig.JWS_SIGN) {
|
|
90
|
+
if (req.method === 'get') {
|
|
91
|
+
return false
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (req.method === 'put' && req.path.startsWith('/parties/') && !userConfig.JWS_SIGN_PUT_PARTIES) {
|
|
95
|
+
return false
|
|
96
|
+
}
|
|
97
|
+
const jwsSigningKey = await ConnectionProvider.getTestingToolkitDfspJWSPrivateKey()
|
|
98
|
+
return signWithKey(req, jwsSigningKey)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const signWithKey = (req, jwsSigningKey) => {
|
|
103
|
+
const jwsSigner = new Jws.signer({ // eslint-disable-line
|
|
104
|
+
signingKey: jwsSigningKey
|
|
105
|
+
})
|
|
106
|
+
const reqOpts = {
|
|
107
|
+
method: req.method,
|
|
108
|
+
uri: req.url,
|
|
109
|
+
headers: req.headers,
|
|
110
|
+
body: JSON.stringify(req.data),
|
|
111
|
+
agent: 'testingtoolkit',
|
|
112
|
+
resolveWithFullResponse: true,
|
|
113
|
+
simple: false
|
|
114
|
+
}
|
|
115
|
+
if (reqOpts.headers['FSPIOP-Source']) {
|
|
116
|
+
reqOpts.headers['fspiop-source'] = reqOpts.headers['FSPIOP-Source']
|
|
117
|
+
delete reqOpts.headers['FSPIOP-Source']
|
|
118
|
+
}
|
|
119
|
+
if (reqOpts.headers['FSPIOP-Destination']) {
|
|
120
|
+
reqOpts.headers['fspiop-destination'] = reqOpts.headers['FSPIOP-Destination']
|
|
121
|
+
delete reqOpts.headers['FSPIOP-Destination']
|
|
122
|
+
}
|
|
123
|
+
delete reqOpts.headers['FSPIOP-Signature']
|
|
124
|
+
delete reqOpts.headers['FSPIOP-URI']
|
|
125
|
+
delete reqOpts.headers['FSPIOP-HTTP-Method']
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
jwsSigner.sign(reqOpts)
|
|
129
|
+
return true
|
|
130
|
+
} catch (err) {
|
|
131
|
+
throw new Error(err.toString())
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
module.exports = {
|
|
136
|
+
validate,
|
|
137
|
+
validateWithCert,
|
|
138
|
+
validateProtectedHeaders,
|
|
139
|
+
sign,
|
|
140
|
+
signWithKey
|
|
141
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/*****
|
|
2
|
+
License
|
|
3
|
+
--------------
|
|
4
|
+
Copyright © 2020-2025 Mojaloop Foundation
|
|
5
|
+
The Mojaloop files are made available by the Mojaloop 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
|
+
Mojaloop Foundation 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
|
+
* Mojaloop Foundation
|
|
23
|
+
- Name Surname <name.surname@mojaloop.io>
|
|
24
|
+
|
|
25
|
+
* ModusBox
|
|
26
|
+
* Georgi Logodazhki <georgi.logodazhki@modusbox.com> (Original Author)
|
|
27
|
+
--------------
|
|
28
|
+
******/
|
|
29
|
+
const { readFileAsync, readRecursiveAsync, fileStatAsync } = require('./utils')
|
|
30
|
+
const fs = require('fs')
|
|
31
|
+
|
|
32
|
+
// load collections or environments
|
|
33
|
+
const getCollectionsOrEnvironments = async (exampleType, type) => {
|
|
34
|
+
const data = await readRecursiveAsync(`examples/${exampleType}/${type || ''}`)
|
|
35
|
+
return data.filter(filename => filename.endsWith('.json'))
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// load collections or environments with file sizes
|
|
39
|
+
const getCollectionsOrEnvironmentsWithFileSize = async (exampleType, type) => {
|
|
40
|
+
const dir = `examples/${exampleType}/${type || ''}`
|
|
41
|
+
const data = await readRecursiveAsync(dir)
|
|
42
|
+
const jsonFileList = data.filter(filename => filename.endsWith('.json'))
|
|
43
|
+
const jsonFileListWithFileSize = jsonFileList.map(file => {
|
|
44
|
+
return {
|
|
45
|
+
name: file,
|
|
46
|
+
size: fs.statSync(file).size
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
return jsonFileListWithFileSize
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// load samples content
|
|
53
|
+
const getSample = async (queryParams) => {
|
|
54
|
+
const collections = []
|
|
55
|
+
if (queryParams.collections) {
|
|
56
|
+
for (const i in queryParams.collections) {
|
|
57
|
+
const collection = await readFileAsync(queryParams.collections[i], 'utf8')
|
|
58
|
+
collections.push(JSON.parse(collection))
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const sample = {
|
|
62
|
+
name: null,
|
|
63
|
+
options: null,
|
|
64
|
+
inputValues: null,
|
|
65
|
+
test_cases: null
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (queryParams.environment) {
|
|
69
|
+
const envContent = JSON.parse(await readFileAsync(queryParams.environment, 'utf8'))
|
|
70
|
+
sample.inputValues = envContent.inputValues
|
|
71
|
+
sample.options = envContent.options
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (collections.length > 1) {
|
|
75
|
+
sample.name = 'multi'
|
|
76
|
+
sample.test_cases = []
|
|
77
|
+
let index = 1
|
|
78
|
+
collections.forEach(collection => {
|
|
79
|
+
collection.test_cases.forEach(testCase => {
|
|
80
|
+
const { id, ...remainingTestCaseProps } = testCase
|
|
81
|
+
sample.test_cases.push({
|
|
82
|
+
id: index++,
|
|
83
|
+
...remainingTestCaseProps
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
})
|
|
87
|
+
} else if (collections.length === 1) {
|
|
88
|
+
sample.name = collections[0].name
|
|
89
|
+
sample.test_cases = collections[0].test_cases
|
|
90
|
+
}
|
|
91
|
+
return sample
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// load samples content
|
|
95
|
+
const getSampleWithFolderWise = async (queryParams) => {
|
|
96
|
+
const collections = []
|
|
97
|
+
if (queryParams.collections) {
|
|
98
|
+
for (const i in queryParams.collections) {
|
|
99
|
+
const fileContent = await readFileAsync(queryParams.collections[i], 'utf8')
|
|
100
|
+
const fileStat = await fileStatAsync(queryParams.collections[i])
|
|
101
|
+
// collections.push(JSON.parse(collection))
|
|
102
|
+
collections.push({
|
|
103
|
+
name: queryParams.collections[i],
|
|
104
|
+
path: queryParams.collections[i],
|
|
105
|
+
size: fileStat.size,
|
|
106
|
+
modified: fileStat.mtime,
|
|
107
|
+
content: JSON.parse(fileContent)
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
let environment = {}
|
|
113
|
+
if (queryParams.environment) {
|
|
114
|
+
environment = JSON.parse(await readFileAsync(queryParams.environment, 'utf8')).inputValues
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
collections,
|
|
119
|
+
environment
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
module.exports = {
|
|
124
|
+
getCollectionsOrEnvironments,
|
|
125
|
+
getCollectionsOrEnvironmentsWithFileSize,
|
|
126
|
+
getSample,
|
|
127
|
+
getSampleWithFolderWise
|
|
128
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const { loggerFactory, LOG_LEVELS } = require('@mojaloop/sdk-standard-components').Logger
|
|
2
|
+
const { hostname } = require('node:os')
|
|
3
|
+
|
|
4
|
+
const createLogger = (conf = {}) => {
|
|
5
|
+
const {
|
|
6
|
+
context = {
|
|
7
|
+
hostname: hostname()
|
|
8
|
+
},
|
|
9
|
+
isJsonOutput = false
|
|
10
|
+
} = conf
|
|
11
|
+
|
|
12
|
+
return loggerFactory({ context, isJsonOutput })
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const logger = createLogger() // global logger
|
|
16
|
+
|
|
17
|
+
module.exports = {
|
|
18
|
+
logger,
|
|
19
|
+
LOG_LEVELS
|
|
20
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/*****
|
|
2
|
+
License
|
|
3
|
+
--------------
|
|
4
|
+
Copyright © 2020-2025 Mojaloop Foundation
|
|
5
|
+
The Mojaloop files are made available by the Mojaloop 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
|
+
Mojaloop Foundation 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
|
+
* Mojaloop Foundation
|
|
23
|
+
- Name Surname <name.surname@mojaloop.io>
|
|
24
|
+
|
|
25
|
+
* ModusBox
|
|
26
|
+
* Georgi Logodazhki <georgi.logodazhki@modusbox.com> (Original Author)
|
|
27
|
+
--------------
|
|
28
|
+
******/
|
|
29
|
+
|
|
30
|
+
const MyEventEmitter = require('./MyEventEmitter')
|
|
31
|
+
const objectStore = require('./objectStore')
|
|
32
|
+
|
|
33
|
+
const LONGPOLLING_TIMEOUT = 5000
|
|
34
|
+
|
|
35
|
+
const setAssertionStoreEmitter = (storedObject, eventPath, res, user) => {
|
|
36
|
+
let emitterType
|
|
37
|
+
switch (storedObject) {
|
|
38
|
+
case 'requests': emitterType = 'assertionRequest'; break
|
|
39
|
+
case 'callbacks': emitterType = 'assertionCallback'; break
|
|
40
|
+
}
|
|
41
|
+
const emitter = MyEventEmitter.getEmitter(emitterType, user)
|
|
42
|
+
const timer = setTimeout(() => {
|
|
43
|
+
emitter.removeAllListeners(eventPath)
|
|
44
|
+
res.status(500).json({ error: 'Timed out' })
|
|
45
|
+
}, LONGPOLLING_TIMEOUT)
|
|
46
|
+
|
|
47
|
+
emitter.once(eventPath, (data) => {
|
|
48
|
+
clearTimeout(timer)
|
|
49
|
+
objectStore.popObject(storedObject, eventPath, user)
|
|
50
|
+
res.status(200).json(data)
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
module.exports = {
|
|
55
|
+
setAssertionStoreEmitter
|
|
56
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const Metrics = require('@mojaloop/central-services-metrics')
|
|
2
|
+
|
|
3
|
+
module.exports = function metricsMiddleware (config = {}) {
|
|
4
|
+
Metrics.getDefaultRegister().clear()
|
|
5
|
+
Metrics.setup({
|
|
6
|
+
timeout: 5000,
|
|
7
|
+
defaultLabels: {},
|
|
8
|
+
...config
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
const client = Metrics.getClient()
|
|
12
|
+
const assertSuccess = new client.Counter({
|
|
13
|
+
name: 'assert_success_total',
|
|
14
|
+
help: 'Successful assertions',
|
|
15
|
+
labelNames: ['request', 'test']
|
|
16
|
+
})
|
|
17
|
+
const assertFail = new client.Counter({
|
|
18
|
+
name: 'assert_fail_total',
|
|
19
|
+
help: 'Failed assertions',
|
|
20
|
+
labelNames: ['request', 'test']
|
|
21
|
+
})
|
|
22
|
+
const testSuccess = new client.Counter({
|
|
23
|
+
name: 'test_success_total',
|
|
24
|
+
help: 'Successful tests',
|
|
25
|
+
labelNames: ['template']
|
|
26
|
+
})
|
|
27
|
+
const testFail = new client.Counter({
|
|
28
|
+
name: 'test_fail_total',
|
|
29
|
+
help: 'Failed tests',
|
|
30
|
+
labelNames: ['template']
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const metrics = {
|
|
34
|
+
assertSuccess: { add (value, labels) { assertSuccess.inc(labels, value) } },
|
|
35
|
+
assertFail: { add (value, labels) { assertFail.inc(labels, value) } },
|
|
36
|
+
testSuccess: { add (value, labels) { testSuccess.inc(labels, value) } },
|
|
37
|
+
testFail: { add (value, labels) { testFail.inc(labels, value) } }
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return (req, res, next) => {
|
|
41
|
+
if (req.url === '/metrics') {
|
|
42
|
+
res.set('Content-Type', 'text/plain; version=0.0.4')
|
|
43
|
+
Metrics.getMetricsForPrometheus().then(metrics => {
|
|
44
|
+
res.send(metrics)
|
|
45
|
+
})
|
|
46
|
+
} else {
|
|
47
|
+
req.metrics = metrics
|
|
48
|
+
next()
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/*****
|
|
2
|
+
License
|
|
3
|
+
--------------
|
|
4
|
+
Copyright © 2020-2025 Mojaloop Foundation
|
|
5
|
+
The Mojaloop files are made available by the Mojaloop 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
|
+
Mojaloop Foundation 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
|
+
* Mojaloop Foundation
|
|
23
|
+
- Name Surname <name.surname@mojaloop.io>
|
|
24
|
+
|
|
25
|
+
* ModusBox
|
|
26
|
+
* Vijaya Kumar Guthi <vijaya.guthi@modusbox.com> (Original Author)
|
|
27
|
+
--------------
|
|
28
|
+
******/
|
|
29
|
+
|
|
30
|
+
const { monotonicFactory } = require('ulidx')
|
|
31
|
+
|
|
32
|
+
const generateUUID = () => {
|
|
33
|
+
const uuid = require('uuid')
|
|
34
|
+
return uuid.v4()
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const curDate = () => {
|
|
38
|
+
return (new Date()).toUTCString()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const curDateISO = () => {
|
|
42
|
+
return (new Date()).toISOString()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const generateULID = monotonicFactory()
|
|
46
|
+
|
|
47
|
+
const generateID = (options) => {
|
|
48
|
+
return options.generateIDType === 'uuid' ? generateUUID() : generateULID()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = {
|
|
52
|
+
generateUUID,
|
|
53
|
+
generateULID,
|
|
54
|
+
generateID,
|
|
55
|
+
curDate,
|
|
56
|
+
curDateISO
|
|
57
|
+
}
|