account-lookup-service 15.5.0-iso.0
Sign up to get free protection for your applications and to get access to all the features.
- package/.circleci/config.yml +11 -0
- package/.ncurc.yaml +6 -0
- package/.nvmrc +1 -0
- package/.nycrc.yml +20 -0
- package/.versionrc +15 -0
- package/CHANGELOG.md +330 -0
- package/CODEOWNERS +38 -0
- package/Dockerfile +45 -0
- package/LICENSE.md +10 -0
- package/README.md +252 -0
- package/audit-ci.jsonc +32 -0
- package/audit-resolve.json +161 -0
- package/config/default.json +109 -0
- package/config/knexfile.js +21 -0
- package/docker/account-lookup-service/default.json +106 -0
- package/docker/account-lookup-service/make-default-json.sh +5 -0
- package/docker/account-lookup-service/override.json +15 -0
- package/docker/central-ledger/default.json +458 -0
- package/docker/config-modifier/account-lookup-service.js +31 -0
- package/docker/kafka/consumer.properties +26 -0
- package/docker/kafka/producer.properties +45 -0
- package/docker/kafka/server.properties +143 -0
- package/docker/kafka/tools-log4j.properties +21 -0
- package/docker/mock-proxy/Dockerfile +15 -0
- package/docker/mock-proxy/package-lock.json +4986 -0
- package/docker/mock-proxy/package.json +24 -0
- package/docker/mock-proxy/src/config.ts +14 -0
- package/docker/mock-proxy/src/server.ts +94 -0
- package/docker/mock-proxy/src/utils.ts +29 -0
- package/docker/mock-proxy/tsconfig.json +24 -0
- package/docker/sql-init/01_permissions.sql +2 -0
- package/docker/sql-init-central-ledger/01_permissions.sql +2 -0
- package/docker/wait-for/wait-for-account-lookup-service.sh +10 -0
- package/docker/wait-for/wait-for-central-ledger.sh +11 -0
- package/docker/wait-for/wait-for-kafka.sh +7 -0
- package/docker/wait-for/wait-for-ml-api-adapter.sh +9 -0
- package/docker/wait-for/wait-for-mockserver.sh +20 -0
- package/docker/wait-for/wait-for-mysql-als.sh +14 -0
- package/docker/wait-for/wait-for-mysql-central-ledger.sh +11 -0
- package/docker/wait-for/wait-for-mysql.sh +11 -0
- package/docker/wait-for/wait-for-objstore.sh +12 -0
- package/docker/wait-for/wait-for.env +18 -0
- package/docker/wait-for/wait-for.sh +81 -0
- package/docker-compose.integration.yml +29 -0
- package/docker-compose.yml +243 -0
- package/jest-int.config.js +8 -0
- package/jest.config.js +16 -0
- package/jsdoc.json +38 -0
- package/migrations/01_currency.js +42 -0
- package/migrations/02_endpointType.js +43 -0
- package/migrations/03_endpointType-indexes.js +37 -0
- package/migrations/04_partyIdType.js +43 -0
- package/migrations/05_partyIdType-indexes.js +38 -0
- package/migrations/08_oracleEndpoint.js +51 -0
- package/migrations/09_oracleEndpoint-indexes.js +41 -0
- package/migrations/10_oracleEndpoint-remove-constraints.js +38 -0
- package/package.json +180 -0
- package/scripts/_wait4_all.js +143 -0
- package/scripts/test-functional.sh +76 -0
- package/secrets/jwsSigningKey.key +27 -0
- package/seeds/currency.js +765 -0
- package/seeds/endpointType.js +65 -0
- package/seeds/partyIdType.js +79 -0
- package/src/api/endpointcache.js +67 -0
- package/src/api/health.js +66 -0
- package/src/api/index.js +85 -0
- package/src/api/oracles/{ID}.js +100 -0
- package/src/api/oracles.js +96 -0
- package/src/api/participants/{ID}/error.js +44 -0
- package/src/api/participants/{ID}.js +44 -0
- package/src/api/participants/{Type}/{ID}/error.js +74 -0
- package/src/api/participants/{Type}/{ID}/{SubId}/error.js +68 -0
- package/src/api/participants/{Type}/{ID}/{SubId}.js +113 -0
- package/src/api/participants/{Type}/{ID}.js +133 -0
- package/src/api/participants.js +63 -0
- package/src/api/parties/{Type}/{ID}/error.js +66 -0
- package/src/api/parties/{Type}/{ID}/{SubId}/error.js +56 -0
- package/src/api/parties/{Type}/{ID}/{SubId}.js +77 -0
- package/src/api/parties/{Type}/{ID}.js +98 -0
- package/src/api/routes.js +294 -0
- package/src/constants.js +16 -0
- package/src/domain/oracle/index.js +33 -0
- package/src/domain/oracle/oracle.js +234 -0
- package/src/domain/participants/index.js +35 -0
- package/src/domain/participants/participants.js +560 -0
- package/src/domain/parties/getPartiesByTypeAndID.js +239 -0
- package/src/domain/parties/index.js +32 -0
- package/src/domain/parties/parties.js +215 -0
- package/src/domain/parties/utils.js +84 -0
- package/src/domain/timeout/dto.js +48 -0
- package/src/domain/timeout/index.js +104 -0
- package/src/handlers/TimeoutHandler.js +94 -0
- package/src/handlers/index.js +70 -0
- package/src/handlers/monitoring/index.js +51 -0
- package/src/handlers/monitoring/plugins/health.js +61 -0
- package/src/handlers/monitoring/plugins/metrics.js +48 -0
- package/src/handlers/register.js +102 -0
- package/src/index.js +66 -0
- package/src/interface/admin-swagger.yaml +804 -0
- package/src/interface/admin_swagger.json +959 -0
- package/src/interface/api-swagger-iso20022-parties.yaml +1734 -0
- package/src/interface/api-swagger.yaml +1733 -0
- package/src/interface/api_swagger.json +3046 -0
- package/src/interface/fspiop-rest-v2.0-ISO20022_parties.yaml +2256 -0
- package/src/interface/thirdparty/admin-swagger.yaml +808 -0
- package/src/interface/thirdparty/admin_swagger.json +961 -0
- package/src/interface/thirdparty/api-swagger.yaml +1739 -0
- package/src/interface/thirdparty/api_swagger.json +3142 -0
- package/src/lib/argv.js +39 -0
- package/src/lib/cache.js +126 -0
- package/src/lib/config.js +183 -0
- package/src/lib/db.js +26 -0
- package/src/lib/headers.js +53 -0
- package/src/lib/healthCheck/subServiceHealth.js +84 -0
- package/src/lib/index.js +11 -0
- package/src/lib/migrator.js +17 -0
- package/src/lib/requestLogger.js +54 -0
- package/src/lib/util.js +66 -0
- package/src/metrics/handler.js +33 -0
- package/src/metrics/plugin.js +52 -0
- package/src/metrics/routes.js +43 -0
- package/src/models/currency/currency.js +48 -0
- package/src/models/currency/index.js +32 -0
- package/src/models/endpointType/endpointType.js +48 -0
- package/src/models/endpointType/index.js +32 -0
- package/src/models/misc/migrationLock.js +49 -0
- package/src/models/oracle/facade.js +341 -0
- package/src/models/oracle/index.js +41 -0
- package/src/models/oracle/oracleEndpoint.js +192 -0
- package/src/models/oracle/oracleEndpointCached.js +108 -0
- package/src/models/participantEndpoint/facade.js +238 -0
- package/src/models/partyIdType/index.js +32 -0
- package/src/models/partyIdType/partyIdType.js +41 -0
- package/src/plugins.js +139 -0
- package/src/server.js +199 -0
- package/test/fixtures/index.js +131 -0
- package/test/fixtures/iso.js +110 -0
- package/test/integration/.env +8 -0
- package/test/integration/api/parties.test.js +137 -0
- package/test/integration/constants.js +20 -0
- package/test/integration/domain/oracle/index.test.js +324 -0
- package/test/integration/domain/timeout/index.test.js +75 -0
- package/test/integration/env.sh +15 -0
- package/test/integration/example.test.js +12 -0
- package/test/integration/models/currency/currency.test.js +68 -0
- package/test/integration/plugins.test.js +62 -0
- package/test/integration/prepareTestParticipants.js +30 -0
- package/test/integration/setup.js +5 -0
- package/test/integration-config.json +81 -0
- package/test/integration-runner.sh +108 -0
- package/test/unit/api/health.test.js +142 -0
- package/test/unit/api/oracles/{ID}.test.js +264 -0
- package/test/unit/api/oracles.test.js +173 -0
- package/test/unit/api/participants/participants.test.js +117 -0
- package/test/unit/api/participants/{Type}/{ID}/error.test.js +155 -0
- package/test/unit/api/participants/{Type}/{ID}/{SubId}/error.test.js +131 -0
- package/test/unit/api/participants/{Type}/{ID}/{SubId}.test.js +377 -0
- package/test/unit/api/participants/{Type}/{ID}.test.js +383 -0
- package/test/unit/api/participants.test.js +108 -0
- package/test/unit/api/parties/endpointcache.test.js +83 -0
- package/test/unit/api/parties/parties.test.js +102 -0
- package/test/unit/api/parties/{Type}/{ID}/error.test.js +145 -0
- package/test/unit/api/parties/{Type}/{ID}/{SubId}/error.test.js +141 -0
- package/test/unit/api/parties/{Type}/{ID}/{SubId}.test.js +241 -0
- package/test/unit/api/parties/{Type}/{ID}.test.js +240 -0
- package/test/unit/domain/oracle/oracle.test.js +505 -0
- package/test/unit/domain/participants/participants.test.js +1724 -0
- package/test/unit/domain/parties/parties.test.js +940 -0
- package/test/unit/domain/timeout/dto.test.js +28 -0
- package/test/unit/domain/timeout/index.test.js +81 -0
- package/test/unit/handlers/TimeoutHandler.test.js +125 -0
- package/test/unit/handlers/index.test.js +56 -0
- package/test/unit/handlers/register.test.js +90 -0
- package/test/unit/index.test.js +139 -0
- package/test/unit/iso20022/partiesValidation.test.js +129 -0
- package/test/unit/lib/TransformFacades.test.js +18 -0
- package/test/unit/lib/argv.test.js +40 -0
- package/test/unit/lib/cache.test.js +172 -0
- package/test/unit/lib/config.test.js +108 -0
- package/test/unit/lib/healthCheck/subServiceHealth.test.js +89 -0
- package/test/unit/lib/migrator.test.js +52 -0
- package/test/unit/lib/requestLogger.test.js +115 -0
- package/test/unit/lib/util.test.js +68 -0
- package/test/unit/mocks.js +66 -0
- package/test/unit/models/currency/currency.test.js +91 -0
- package/test/unit/models/endpointType/endpointType.test.js +69 -0
- package/test/unit/models/misc/migrationLock.test.js +96 -0
- package/test/unit/models/oracle/facade.test.js +546 -0
- package/test/unit/models/oracle/oracleEndpoint.test.js +409 -0
- package/test/unit/models/oracle/oracleEndpointCached.test.js +153 -0
- package/test/unit/models/participantEndpoint/facade.test.js +295 -0
- package/test/unit/models/partyIdType/partyIdType.test.js +88 -0
- package/test/unit/plugins.test.js +89 -0
- package/test/unit/setup.js +7 -0
- package/test/util/apiClients/AlsApiClient.js +44 -0
- package/test/util/apiClients/BasicApiClient.js +34 -0
- package/test/util/apiClients/ProxyApiClient.js +25 -0
- package/test/util/apiClients/index.js +7 -0
- package/test/util/helper.js +332 -0
- package/test/util/index.js +11 -0
- package/test/util/mockgen.js +43 -0
- package/test/util/onboarding.js +132 -0
- package/test/util/scripts/addAlsDb.sh +33 -0
- package/test/util/scripts/configureMockServer.sh +35 -0
- package/test/util/scripts/env.sh +19 -0
- package/test/util/scripts/populateTestData.sh +62 -0
- package/test/util/scripts/startMockCentralServer.sh +45 -0
- package/test/util/scripts/startMockOracleServer.sh +45 -0
- package/test/util/testConfig.js +44 -0
@@ -0,0 +1,104 @@
|
|
1
|
+
/*****
|
2
|
+
License
|
3
|
+
--------------
|
4
|
+
Copyright © 2020-2024 Mojaloop Foundation
|
5
|
+
|
6
|
+
The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0
|
7
|
+
(the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0).
|
8
|
+
|
9
|
+
You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
10
|
+
|
11
|
+
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](http://www.apache.org/licenses/LICENSE-2.0).
|
12
|
+
|
13
|
+
Contributors
|
14
|
+
--------------
|
15
|
+
This is the official list of the Mojaloop project contributors for this file.
|
16
|
+
Names of the original copyright holders (individuals or organizations)
|
17
|
+
should be listed with a '*' in the first column. People who have
|
18
|
+
contributed from an organization can be listed under the organization
|
19
|
+
that actually holds the copyright for their contributions (see the
|
20
|
+
Gates Foundation organization for an example). Those individuals should have
|
21
|
+
their names indented and be marked with a '-'. Email address can be added
|
22
|
+
optionally within square brackets <email>.
|
23
|
+
|
24
|
+
* Gates Foundation
|
25
|
+
- Name Surname <name.surname@gatesfoundation.com>
|
26
|
+
|
27
|
+
* INFITX
|
28
|
+
- Steven Oderayi <steven.oderayi@infitx.com>
|
29
|
+
|
30
|
+
--------------
|
31
|
+
******/
|
32
|
+
'use strict'
|
33
|
+
|
34
|
+
const {
|
35
|
+
Factory: { createFSPIOPError, reformatFSPIOPError },
|
36
|
+
Enums: { FSPIOPErrorCodes }
|
37
|
+
} = require('@mojaloop/central-services-error-handling')
|
38
|
+
const {
|
39
|
+
EventStateMetadata,
|
40
|
+
EventStatusType,
|
41
|
+
AuditEventAction
|
42
|
+
} = require('@mojaloop/event-sdk')
|
43
|
+
const Metrics = require('@mojaloop/central-services-metrics')
|
44
|
+
|
45
|
+
const Participant = require('../../models/participantEndpoint/facade')
|
46
|
+
const { ERROR_MESSAGES } = require('../../constants')
|
47
|
+
const { timeoutCallbackDto } = require('./dto')
|
48
|
+
const { logger } = require('../../lib')
|
49
|
+
|
50
|
+
const timeoutInterschemePartiesLookups = async ({ proxyCache, batchSize }) => {
|
51
|
+
return proxyCache.processExpiredAlsKeys(sendTimeoutCallback, batchSize)
|
52
|
+
}
|
53
|
+
|
54
|
+
const sendTimeoutCallback = async (cacheKey) => {
|
55
|
+
const histTimerEnd = Metrics.getHistogram(
|
56
|
+
'eg_timeoutInterschemePartiesLookups',
|
57
|
+
'Egress - Interscheme parties lookup timeout callback',
|
58
|
+
['success']
|
59
|
+
).startTimer()
|
60
|
+
|
61
|
+
const [, destination, partyType, partyId] = cacheKey.split(':')
|
62
|
+
const { errorInformation, params, headers, endpointType, span } = await timeoutCallbackDto({ destination, partyId, partyType })
|
63
|
+
logger.debug('sendTimeoutCallback details:', { destination, partyType, partyId, cacheKey })
|
64
|
+
|
65
|
+
try {
|
66
|
+
await validateParticipant(destination)
|
67
|
+
await span.audit({ headers, errorInformation }, AuditEventAction.start)
|
68
|
+
await Participant.sendErrorToParticipant(destination, endpointType, errorInformation, headers, params, undefined, span)
|
69
|
+
histTimerEnd({ success: true })
|
70
|
+
} catch (err) {
|
71
|
+
logger.warn('error in sendTimeoutCallback: ', err)
|
72
|
+
histTimerEnd({ success: false })
|
73
|
+
const fspiopError = reformatFSPIOPError(err)
|
74
|
+
await finishSpan(span, fspiopError)
|
75
|
+
throw fspiopError
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
const validateParticipant = async (fspId) => {
|
80
|
+
const participant = await Participant.validateParticipant(fspId)
|
81
|
+
if (!participant) {
|
82
|
+
const errMessage = ERROR_MESSAGES.partyDestinationFspNotFound
|
83
|
+
logger.error(`error in validateParticipant: ${errMessage}`)
|
84
|
+
throw createFSPIOPError(FSPIOPErrorCodes.DESTINATION_FSP_ERROR, errMessage)
|
85
|
+
}
|
86
|
+
return participant
|
87
|
+
}
|
88
|
+
|
89
|
+
const finishSpan = async (span, err) => {
|
90
|
+
if (!span.isFinished) {
|
91
|
+
const state = new EventStateMetadata(
|
92
|
+
EventStatusType.failed,
|
93
|
+
err.apiErrorCode.code,
|
94
|
+
err.apiErrorCode.message
|
95
|
+
)
|
96
|
+
await span.error(err, state)
|
97
|
+
await span.finish(err.message, state)
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
module.exports = {
|
102
|
+
timeoutInterschemePartiesLookups,
|
103
|
+
sendTimeoutCallback // Exposed for testing
|
104
|
+
}
|
@@ -0,0 +1,94 @@
|
|
1
|
+
/*****
|
2
|
+
License
|
3
|
+
--------------
|
4
|
+
Copyright © 2020-2024 Mojaloop Foundation
|
5
|
+
|
6
|
+
The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0
|
7
|
+
(the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0).
|
8
|
+
|
9
|
+
You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
10
|
+
|
11
|
+
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](http://www.apache.org/licenses/LICENSE-2.0).
|
12
|
+
|
13
|
+
Contributors
|
14
|
+
--------------
|
15
|
+
This is the official list of the Mojaloop project contributors for this file.
|
16
|
+
Names of the original copyright holders (individuals or organizations)
|
17
|
+
should be listed with a '*' in the first column. People who have
|
18
|
+
contributed from an organization can be listed under the organization
|
19
|
+
that actually holds the copyright for their contributions (see the
|
20
|
+
Gates Foundation organization for an example). Those individuals should have
|
21
|
+
their names indented and be marked with a '-'. Email address can be added
|
22
|
+
optionally within square brackets <email>.
|
23
|
+
|
24
|
+
* Gates Foundation
|
25
|
+
- Name Surname <name.surname@gatesfoundation.com>
|
26
|
+
|
27
|
+
* INFITX
|
28
|
+
- Steven Oderayi <steven.oderayi@infitx.com>
|
29
|
+
--------------
|
30
|
+
******/
|
31
|
+
'use strict'
|
32
|
+
|
33
|
+
const CronJob = require('cron').CronJob
|
34
|
+
const ErrorHandler = require('@mojaloop/central-services-error-handling')
|
35
|
+
const TimeoutService = require('../domain/timeout')
|
36
|
+
const Config = require('../lib/config')
|
37
|
+
|
38
|
+
let timeoutJob
|
39
|
+
let isRegistered
|
40
|
+
let isRunning
|
41
|
+
|
42
|
+
const timeout = async (options) => {
|
43
|
+
if (isRunning) return
|
44
|
+
|
45
|
+
const { logger } = options
|
46
|
+
|
47
|
+
try {
|
48
|
+
isRunning = true
|
49
|
+
logger.debug('Timeout handler triggered')
|
50
|
+
await TimeoutService.timeoutInterschemePartiesLookups(options)
|
51
|
+
} catch (err) {
|
52
|
+
logger.error('error in timeout: ', err)
|
53
|
+
} finally {
|
54
|
+
isRunning = false
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
const register = async (options) => {
|
59
|
+
if (Config.HANDLERS_TIMEOUT_DISABLED) return false
|
60
|
+
|
61
|
+
const { logger } = options
|
62
|
+
|
63
|
+
try {
|
64
|
+
if (isRegistered) {
|
65
|
+
await stop()
|
66
|
+
}
|
67
|
+
timeoutJob = CronJob.from({
|
68
|
+
start: false,
|
69
|
+
onTick: () => timeout(options),
|
70
|
+
cronTime: Config.HANDLERS_TIMEOUT_TIMEXP,
|
71
|
+
timeZone: Config.HANDLERS_TIMEOUT_TIMEZONE
|
72
|
+
})
|
73
|
+
timeoutJob.start()
|
74
|
+
isRegistered = true
|
75
|
+
logger.info('Timeout handler registered')
|
76
|
+
return true
|
77
|
+
} catch (err) {
|
78
|
+
logger.error('error in register:', err)
|
79
|
+
throw ErrorHandler.Factory.reformatFSPIOPError(err)
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
const stop = async () => {
|
84
|
+
if (isRegistered) {
|
85
|
+
await timeoutJob.stop()
|
86
|
+
isRegistered = undefined
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
module.exports = {
|
91
|
+
timeout,
|
92
|
+
register,
|
93
|
+
stop
|
94
|
+
}
|
@@ -0,0 +1,70 @@
|
|
1
|
+
/*****
|
2
|
+
License
|
3
|
+
--------------
|
4
|
+
Copyright © 2020-2024 Mojaloop Foundation
|
5
|
+
|
6
|
+
The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0
|
7
|
+
(the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0).
|
8
|
+
|
9
|
+
You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
10
|
+
|
11
|
+
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](http://www.apache.org/licenses/LICENSE-2.0).
|
12
|
+
|
13
|
+
Contributors
|
14
|
+
--------------
|
15
|
+
This is the official list of the Mojaloop project contributors for this file.
|
16
|
+
Names of the original copyright holders (individuals or organizations)
|
17
|
+
should be listed with a '*' in the first column. People who have
|
18
|
+
contributed from an organization can be listed under the organization
|
19
|
+
that actually holds the copyright for their contributions (see the
|
20
|
+
Gates Foundation organization for an example). Those individuals should have
|
21
|
+
their names indented and be marked with a '-'. Email address can be added
|
22
|
+
optionally within square brackets <email>.
|
23
|
+
|
24
|
+
* Gates Foundation
|
25
|
+
- Name Surname <name.surname@gatesfoundation.com>
|
26
|
+
|
27
|
+
* INFITX
|
28
|
+
- Steven Oderayi <steven.oderayi@infitx.com>
|
29
|
+
--------------
|
30
|
+
******/
|
31
|
+
'use strict'
|
32
|
+
|
33
|
+
const { Command } = require('commander')
|
34
|
+
const Package = require('../../package.json')
|
35
|
+
const Server = require('../server')
|
36
|
+
const { HANDLER_TYPES } = require('../constants')
|
37
|
+
const Config = require('../lib/config')
|
38
|
+
const logger = require('../lib').loggerFactory('ALS-timeout-handler')
|
39
|
+
|
40
|
+
const Program = new Command()
|
41
|
+
|
42
|
+
Program
|
43
|
+
.version(Package.version)
|
44
|
+
.description('CLI to manage Handlers')
|
45
|
+
|
46
|
+
Program.command('handlers')
|
47
|
+
.alias('h')
|
48
|
+
.description('Start specified handler(s)')
|
49
|
+
.option('--timeout', 'Start the Timeout Handler')
|
50
|
+
.action(async (args) => {
|
51
|
+
const handlers = []
|
52
|
+
|
53
|
+
if (args.timeout) {
|
54
|
+
logger.debug('CLI: Executing --timeout')
|
55
|
+
handlers.push(HANDLER_TYPES.TIMEOUT)
|
56
|
+
}
|
57
|
+
|
58
|
+
if (handlers.length === 0) {
|
59
|
+
logger.debug('CLI: No handlers specified')
|
60
|
+
return
|
61
|
+
}
|
62
|
+
|
63
|
+
module.exports = await Server.initializeHandlers(handlers, Config, logger)
|
64
|
+
})
|
65
|
+
|
66
|
+
if (Array.isArray(process.argv) && process.argv.length > 2) {
|
67
|
+
Program.parse(process.argv)
|
68
|
+
} else {
|
69
|
+
Program.help()
|
70
|
+
}
|
@@ -0,0 +1,51 @@
|
|
1
|
+
/*****
|
2
|
+
LICENSE
|
3
|
+
|
4
|
+
Copyright © 2020 Mojaloop Foundation
|
5
|
+
|
6
|
+
The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0
|
7
|
+
(the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0).
|
8
|
+
|
9
|
+
You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
10
|
+
|
11
|
+
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,
|
12
|
+
either express or implied. See the License for the specific language governing permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0).
|
13
|
+
|
14
|
+
* Infitx
|
15
|
+
- Steven Oderayi <steven.oderayi@infitx.com>
|
16
|
+
--------------
|
17
|
+
******/
|
18
|
+
const Hapi = require('@hapi/hapi')
|
19
|
+
const Metrics = require('@mojaloop/central-services-metrics')
|
20
|
+
const { plugin: HealthPlugin } = require('./plugins/health')
|
21
|
+
const { plugin: MetricsPlugin } = require('./plugins/metrics')
|
22
|
+
const { logger } = require('../../lib')
|
23
|
+
|
24
|
+
let server
|
25
|
+
|
26
|
+
const create = async ({ port, metricsConfig }) => {
|
27
|
+
Metrics.setup(metricsConfig)
|
28
|
+
server = new Hapi.Server({ port })
|
29
|
+
await server.register([HealthPlugin, MetricsPlugin])
|
30
|
+
}
|
31
|
+
|
32
|
+
const start = async ({ enabled, port, metricsConfig, proxyCache }) => {
|
33
|
+
if (!enabled) return
|
34
|
+
if (!server) await create({ port, metricsConfig })
|
35
|
+
server.app.proxyCache = proxyCache
|
36
|
+
await server.start()
|
37
|
+
logger.info(`Monitoring server running at: ${server.info.uri}`)
|
38
|
+
}
|
39
|
+
|
40
|
+
const stop = async () => {
|
41
|
+
await Promise.all([
|
42
|
+
server?.stop(),
|
43
|
+
server.app.proxyCache?.disconnect()
|
44
|
+
])
|
45
|
+
server = null
|
46
|
+
}
|
47
|
+
|
48
|
+
module.exports = {
|
49
|
+
start,
|
50
|
+
stop
|
51
|
+
}
|
@@ -0,0 +1,61 @@
|
|
1
|
+
/*****
|
2
|
+
LICENSE
|
3
|
+
|
4
|
+
Copyright © 2020 Mojaloop Foundation
|
5
|
+
|
6
|
+
The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0
|
7
|
+
(the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0).
|
8
|
+
|
9
|
+
You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
10
|
+
|
11
|
+
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,
|
12
|
+
either express or implied. See the License for the specific language governing permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0).
|
13
|
+
|
14
|
+
* Infitx
|
15
|
+
- Steven Oderayi <steven.oderayi@infitx.com>
|
16
|
+
--------------
|
17
|
+
******/
|
18
|
+
|
19
|
+
'use strict'
|
20
|
+
|
21
|
+
const { HealthCheck } = require('@mojaloop/central-services-shared').HealthCheck
|
22
|
+
const { defaultHealthHandler } = require('@mojaloop/central-services-health')
|
23
|
+
const packageJson = require('../../../../package.json')
|
24
|
+
const { getProxyCacheHealth } = require('../../../lib/healthCheck/subServiceHealth')
|
25
|
+
|
26
|
+
let healthCheck
|
27
|
+
|
28
|
+
const createHealthCheck = ({ proxyCache }) => {
|
29
|
+
return new HealthCheck(packageJson, [
|
30
|
+
() => getProxyCacheHealth(proxyCache)
|
31
|
+
])
|
32
|
+
}
|
33
|
+
|
34
|
+
const handler = {
|
35
|
+
get: (request, reply) => {
|
36
|
+
const proxyCache = request.server.app.proxyCache
|
37
|
+
healthCheck = healthCheck || createHealthCheck({ proxyCache })
|
38
|
+
return defaultHealthHandler(healthCheck)(request, reply)
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
const routes = [
|
43
|
+
{
|
44
|
+
method: 'GET',
|
45
|
+
path: '/health',
|
46
|
+
handler: handler.get
|
47
|
+
}
|
48
|
+
]
|
49
|
+
|
50
|
+
const plugin = {
|
51
|
+
name: 'Health',
|
52
|
+
register (server) {
|
53
|
+
server.route(routes)
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
module.exports = {
|
58
|
+
plugin,
|
59
|
+
handler,
|
60
|
+
createHealthCheck
|
61
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
/*****
|
2
|
+
LICENSE
|
3
|
+
|
4
|
+
Copyright © 2020 Mojaloop Foundation
|
5
|
+
|
6
|
+
The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0
|
7
|
+
(the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0).
|
8
|
+
|
9
|
+
You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
10
|
+
|
11
|
+
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,
|
12
|
+
either express or implied. See the License for the specific language governing permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0).
|
13
|
+
|
14
|
+
* Infitx
|
15
|
+
- Steven Oderayi <steven.oderayi@infitx.com>
|
16
|
+
--------------
|
17
|
+
******/
|
18
|
+
|
19
|
+
'use strict'
|
20
|
+
|
21
|
+
const HTTPENUM = require('@mojaloop/central-services-shared').Enum.Http
|
22
|
+
const Metrics = require('@mojaloop/central-services-metrics')
|
23
|
+
|
24
|
+
const handler = {
|
25
|
+
get: async (_request, reply) => {
|
26
|
+
return reply.response(await Metrics.getMetricsForPrometheus()).code(HTTPENUM.ReturnCodes.OK.CODE)
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
const routes = [
|
31
|
+
{
|
32
|
+
method: 'GET',
|
33
|
+
path: '/metrics',
|
34
|
+
handler: handler.get
|
35
|
+
}
|
36
|
+
]
|
37
|
+
|
38
|
+
const plugin = {
|
39
|
+
name: 'Metrics',
|
40
|
+
register (server) {
|
41
|
+
server.route(routes)
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
module.exports = {
|
46
|
+
plugin,
|
47
|
+
handler
|
48
|
+
}
|
@@ -0,0 +1,102 @@
|
|
1
|
+
/*****
|
2
|
+
License
|
3
|
+
--------------
|
4
|
+
Copyright © 2020-2024 Mojaloop Foundation
|
5
|
+
|
6
|
+
The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0
|
7
|
+
(the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0).
|
8
|
+
|
9
|
+
You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
10
|
+
|
11
|
+
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](http://www.apache.org/licenses/LICENSE-2.0).
|
12
|
+
|
13
|
+
Contributors
|
14
|
+
--------------
|
15
|
+
This is the official list of the Mojaloop project contributors for this file.
|
16
|
+
Names of the original copyright holders (individuals or organizations)
|
17
|
+
should be listed with a '*' in the first column. People who have
|
18
|
+
contributed from an organization can be listed under the organization
|
19
|
+
that actually holds the copyright for their contributions (see the
|
20
|
+
Gates Foundation organization for an example). Those individuals should have
|
21
|
+
their names indented and be marked with a '-'. Email address can be added
|
22
|
+
optionally within square brackets <email>.
|
23
|
+
|
24
|
+
* Gates Foundation
|
25
|
+
- Name Surname <name.surname@gatesfoundation.com>
|
26
|
+
|
27
|
+
* INFITX
|
28
|
+
- Steven Oderayi <steven.oderayi@infitx.com>
|
29
|
+
--------------
|
30
|
+
******/
|
31
|
+
'use strict'
|
32
|
+
|
33
|
+
const Metrics = require('@mojaloop/central-services-metrics')
|
34
|
+
const { Endpoints, Participants } = require('@mojaloop/central-services-shared').Util
|
35
|
+
const TimeoutHandler = require('./TimeoutHandler')
|
36
|
+
const { HANDLER_TYPES } = require('../constants')
|
37
|
+
const Config = require('../lib/config')
|
38
|
+
const Util = require('../lib/util')
|
39
|
+
const Monitoring = require('./monitoring')
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Register handlers
|
43
|
+
*
|
44
|
+
* @param {*} handlers Array of handlers names
|
45
|
+
* @param {*} options { proxyCache: ProxyCache, batchSize: number, logger: Logger }
|
46
|
+
*/
|
47
|
+
const registerHandlers = async (handlers, options) => {
|
48
|
+
const { logger } = options
|
49
|
+
await init(options)
|
50
|
+
handlers.forEach(handler => {
|
51
|
+
switch (handler) {
|
52
|
+
case HANDLER_TYPES.TIMEOUT:
|
53
|
+
logger.debug('Registering Timeout Handler')
|
54
|
+
TimeoutHandler.register(options)
|
55
|
+
break
|
56
|
+
default:
|
57
|
+
logger.warn(`Handler ${handler} not found`)
|
58
|
+
break
|
59
|
+
}
|
60
|
+
})
|
61
|
+
}
|
62
|
+
|
63
|
+
/**
|
64
|
+
* Register all handlers
|
65
|
+
*
|
66
|
+
* @param {*} options { proxyCache: ProxyCache, batchSize: number }
|
67
|
+
*/
|
68
|
+
|
69
|
+
const registerAllHandlers = async (options) => {
|
70
|
+
options.logger.debug('Registering all handlers')
|
71
|
+
await init(options)
|
72
|
+
TimeoutHandler.register(options)
|
73
|
+
}
|
74
|
+
|
75
|
+
const stopAllHandlers = async (options) => {
|
76
|
+
options.logger.debug('Stopping all handlers')
|
77
|
+
await Promise.all([
|
78
|
+
TimeoutHandler.stop(),
|
79
|
+
Monitoring.stop()
|
80
|
+
])
|
81
|
+
}
|
82
|
+
|
83
|
+
const init = async (options) => {
|
84
|
+
options.logger.debug('Initializing caches and metrics')
|
85
|
+
!Config.INSTRUMENTATION_METRICS_DISABLED && Metrics.setup(Config.INSTRUMENTATION_METRICS_CONFIG)
|
86
|
+
await Promise.all([
|
87
|
+
Participants.initializeCache(Config.CENTRAL_SHARED_PARTICIPANT_CACHE_CONFIG, Util.hubNameConfig),
|
88
|
+
Endpoints.initializeCache(Config.CENTRAL_SHARED_ENDPOINT_CACHE_CONFIG, Util.hubNameConfig),
|
89
|
+
Monitoring.start({
|
90
|
+
enabled: !Config.INSTRUMENTATION_METRICS_DISABLED,
|
91
|
+
port: Config.HANDLERS_MONITORING_PORT,
|
92
|
+
metricsConfig: Config.INSTRUMENTATION_METRICS_CONFIG,
|
93
|
+
proxyCache: options.proxyCache
|
94
|
+
})
|
95
|
+
])
|
96
|
+
}
|
97
|
+
|
98
|
+
module.exports = {
|
99
|
+
registerHandlers,
|
100
|
+
registerAllHandlers,
|
101
|
+
stopAllHandlers
|
102
|
+
}
|
package/src/index.js
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
/*****
|
2
|
+
License
|
3
|
+
--------------
|
4
|
+
Copyright © 2017 Bill & Melinda Gates Foundation
|
5
|
+
The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
|
6
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
8
|
+
Contributors
|
9
|
+
--------------
|
10
|
+
This is the official list of the Mojaloop project contributors for this file.
|
11
|
+
Names of the original copyright holders (individuals or organizations)
|
12
|
+
should be listed with a '*' in the first column. People who have
|
13
|
+
contributed from an organization can be listed under the organization
|
14
|
+
that actually holds the copyright for their contributions (see the
|
15
|
+
Gates Foundation organization for an example). Those individuals should have
|
16
|
+
their names indented and be marked with a '-'. Email address can be added
|
17
|
+
optionally within square brackets <email>.
|
18
|
+
* Gates Foundation
|
19
|
+
|
20
|
+
* Rajiv Mothilal <rajiv.mothilal@modusbox.com>
|
21
|
+
|
22
|
+
--------------
|
23
|
+
******/
|
24
|
+
|
25
|
+
'use strict'
|
26
|
+
|
27
|
+
const Server = require('./server')
|
28
|
+
const PJson = require('../package.json')
|
29
|
+
const { Command } = require('commander')
|
30
|
+
const Config = require('./lib/config')
|
31
|
+
const Logger = require('@mojaloop/central-services-logger')
|
32
|
+
const argv = require('./lib/argv').getArgs()
|
33
|
+
|
34
|
+
const Program = new Command()
|
35
|
+
|
36
|
+
Program
|
37
|
+
.version(PJson.version)
|
38
|
+
.description('CLI to manage Servers')
|
39
|
+
|
40
|
+
Program.command('server') // sub-command name, coffeeType = type, required
|
41
|
+
.alias('s') // alternative sub-command is `o`
|
42
|
+
.description('Start the ALS services. Use options to specify server type of none to run both') // command description
|
43
|
+
.option('--api', 'Start the api server')
|
44
|
+
.option('--admin', 'Start the admin server')
|
45
|
+
|
46
|
+
// function to execute when command is uses
|
47
|
+
.action(async (args) => {
|
48
|
+
if (args.api) {
|
49
|
+
Logger.isDebugEnabled && Logger.debug('CLI: Executing --api')
|
50
|
+
module.exports = Server.initializeApi(Config)
|
51
|
+
} else if (args.admin) {
|
52
|
+
Logger.isDebugEnabled && Logger.debug('CLI: Executing --admin')
|
53
|
+
module.exports = Server.initializeAdmin(Config)
|
54
|
+
} else {
|
55
|
+
module.exports = Server.initializeAdmin(Config)
|
56
|
+
module.exports = Server.initializeApi(Config)
|
57
|
+
}
|
58
|
+
})
|
59
|
+
|
60
|
+
if (Array.isArray(argv) && argv.length > 1) {
|
61
|
+
// parse command line vars
|
62
|
+
Program.parse(argv)
|
63
|
+
} else {
|
64
|
+
// display default help
|
65
|
+
Program.help()
|
66
|
+
}
|