kuzzle 2.49.1 → 2.50.0-beta.3
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/dist/bin/check-node-version.js +11 -0
- package/dist/bin/copy-protobuf.js +17 -0
- package/dist/lib/api/controllers/adminController.d.ts +51 -0
- package/dist/lib/api/controllers/adminController.js +191 -0
- package/{lib → dist/lib}/api/controllers/authController.d.ts +20 -40
- package/{lib → dist/lib}/api/controllers/authController.js +23 -24
- package/dist/lib/api/controllers/bulkController.d.ts +46 -0
- package/dist/lib/api/controllers/bulkController.js +132 -0
- package/dist/lib/api/controllers/clusterController.d.ts +6 -0
- package/{lib → dist/lib}/api/controllers/clusterController.js +7 -11
- package/dist/lib/api/controllers/collectionController.d.ts +136 -0
- package/dist/lib/api/controllers/collectionController.js +356 -0
- package/dist/lib/api/controllers/documentController.d.ts +181 -0
- package/dist/lib/api/controllers/documentController.js +768 -0
- package/dist/lib/api/controllers/index.d.ts +12 -0
- package/{lib → dist/lib}/api/controllers/index.js +13 -14
- package/dist/lib/api/controllers/indexController.d.ts +65 -0
- package/dist/lib/api/controllers/indexController.js +139 -0
- package/dist/lib/api/controllers/memoryStorageController.d.ts +8 -0
- package/dist/lib/api/controllers/memoryStorageController.js +867 -0
- package/dist/lib/api/controllers/realtimeController.d.ts +47 -0
- package/dist/lib/api/controllers/realtimeController.js +128 -0
- package/dist/lib/api/controllers/securityController.d.ts +423 -0
- package/dist/lib/api/controllers/securityController.js +1139 -0
- package/dist/lib/api/controllers/serverController.d.ts +82 -0
- package/dist/lib/api/controllers/serverController.js +321 -0
- package/dist/lib/api/documentExtractor.d.ts +9 -0
- package/dist/lib/api/documentExtractor.js +274 -0
- package/dist/lib/api/funnel.d.ts +183 -0
- package/dist/lib/api/funnel.js +821 -0
- package/dist/lib/api/httpRoutes.d.ts +17 -0
- package/dist/lib/api/httpRoutes.js +1496 -0
- package/dist/lib/api/rateLimiter.d.ts +18 -0
- package/dist/lib/api/rateLimiter.js +74 -0
- package/{lib → dist/lib}/api/request/kuzzleRequest.d.ts +2 -2
- package/{lib → dist/lib}/api/request/requestContext.d.ts +2 -1
- package/dist/lib/cluster/command.d.ts +73 -0
- package/dist/lib/cluster/command.js +236 -0
- package/dist/lib/cluster/index.d.ts +2 -0
- package/{lib → dist/lib}/cluster/index.js +1 -2
- package/dist/lib/cluster/node.d.ts +278 -0
- package/dist/lib/cluster/node.js +876 -0
- package/dist/lib/cluster/publisher.d.ts +188 -0
- package/dist/lib/cluster/publisher.js +347 -0
- package/dist/lib/cluster/subscriber.d.ts +269 -0
- package/dist/lib/cluster/subscriber.js +555 -0
- package/dist/lib/cluster/workers/IDCardRenewer.d.ts +13 -0
- package/dist/lib/cluster/workers/IDCardRenewer.js +120 -0
- package/{lib → dist/lib}/config/documentEventAliases.d.ts +1 -2
- package/dist/lib/config/index.d.ts +5 -0
- package/dist/lib/config/index.js +244 -0
- package/dist/lib/config/sdkCompatibility.json +9 -0
- package/dist/lib/core/auth/formatProcessing.d.ts +30 -0
- package/dist/lib/core/auth/formatProcessing.js +55 -0
- package/dist/lib/core/auth/passportResponse.d.ts +15 -0
- package/{lib → dist/lib}/core/auth/passportResponse.js +24 -30
- package/dist/lib/core/auth/passportWrapper.d.ts +28 -0
- package/dist/lib/core/auth/passportWrapper.js +126 -0
- package/{lib → dist/lib}/core/backend/backendConfig.js +2 -2
- package/{lib → dist/lib}/core/backend/backendErrors.js +9 -12
- package/dist/lib/core/cache/cacheEngine.d.ts +15 -0
- package/dist/lib/core/cache/cacheEngine.js +205 -0
- package/dist/lib/core/network/accessLogger.d.ts +29 -0
- package/dist/lib/core/network/accessLogger.js +250 -0
- package/dist/lib/core/network/clientConnection.d.ts +15 -0
- package/{lib → dist/lib}/core/network/clientConnection.js +17 -24
- package/dist/lib/core/network/context.d.ts +42 -0
- package/dist/lib/core/network/context.js +57 -0
- package/dist/lib/core/network/entryPoint.d.ts +62 -0
- package/dist/lib/core/network/entryPoint.js +261 -0
- package/dist/lib/core/network/httpRouter/index.d.ts +85 -0
- package/dist/lib/core/network/httpRouter/index.js +258 -0
- package/dist/lib/core/network/httpRouter/routeHandler.d.ts +46 -0
- package/dist/lib/core/network/httpRouter/routeHandler.js +101 -0
- package/dist/lib/core/network/httpRouter/routePart.d.ts +35 -0
- package/dist/lib/core/network/httpRouter/routePart.js +117 -0
- package/dist/lib/core/network/protocolManifest.d.ts +6 -0
- package/{lib → dist/lib}/core/network/protocolManifest.js +5 -9
- package/dist/lib/core/network/protocols/httpMessage.d.ts +22 -0
- package/dist/lib/core/network/protocols/httpMessage.js +62 -0
- package/dist/lib/core/network/protocols/httpwsProtocol.d.ts +171 -0
- package/dist/lib/core/network/protocols/httpwsProtocol.js +921 -0
- package/dist/lib/core/network/protocols/internalProtocol.d.ts +27 -0
- package/dist/lib/core/network/protocols/internalProtocol.js +82 -0
- package/dist/lib/core/network/protocols/mqttProtocol.d.ts +39 -0
- package/dist/lib/core/network/protocols/mqttProtocol.js +219 -0
- package/dist/lib/core/network/protocols/protocol.d.ts +26 -0
- package/dist/lib/core/network/protocols/protocol.js +74 -0
- package/dist/lib/core/network/router.d.ts +49 -0
- package/dist/lib/core/network/router.js +193 -0
- package/dist/lib/core/plugin/plugin.d.ts +56 -0
- package/dist/lib/core/plugin/plugin.js +282 -0
- package/{lib → dist/lib}/core/plugin/pluginContext.js +2 -2
- package/dist/lib/core/plugin/pluginManifest.d.ts +5 -0
- package/{lib → dist/lib}/core/plugin/pluginManifest.js +16 -27
- package/dist/lib/core/plugin/pluginRepository.d.ts +53 -0
- package/dist/lib/core/plugin/pluginRepository.js +112 -0
- package/dist/lib/core/plugin/pluginsManager.d.ts +190 -0
- package/dist/lib/core/plugin/pluginsManager.js +817 -0
- package/dist/lib/core/plugin/privilegedContext.d.ts +14 -0
- package/{lib → dist/lib}/core/plugin/privilegedContext.js +10 -14
- package/dist/lib/core/realtime/actionEnum.d.ts +25 -0
- package/{lib → dist/lib}/core/realtime/actionEnum.js +7 -10
- package/dist/lib/core/realtime/index.d.ts +8 -0
- package/{lib → dist/lib}/core/realtime/index.js +9 -13
- package/dist/lib/core/realtime/notification/document.d.ts +34 -0
- package/dist/lib/core/realtime/notification/document.js +98 -0
- package/dist/lib/core/realtime/notification/index.d.ts +3 -0
- package/{lib → dist/lib}/core/realtime/notification/index.js +4 -5
- package/dist/lib/core/realtime/notification/server.d.ts +17 -0
- package/{lib → dist/lib}/core/realtime/notification/server.js +8 -10
- package/dist/lib/core/realtime/notification/user.d.ts +29 -0
- package/dist/lib/core/realtime/notification/user.js +66 -0
- package/dist/lib/core/realtime/notifier.d.ts +171 -0
- package/dist/lib/core/realtime/notifier.js +405 -0
- package/dist/lib/core/security/index.d.ts +14 -0
- package/{lib → dist/lib}/core/security/index.js +15 -19
- package/dist/lib/core/security/roleRepository.d.ts +143 -0
- package/dist/lib/core/security/roleRepository.js +445 -0
- package/dist/lib/core/security/securityLoader.d.ts +24 -0
- package/dist/lib/core/security/securityLoader.js +125 -0
- package/{lib → dist/lib}/core/security/tokenRepository.js +1 -1
- package/dist/lib/core/security/userRepository.d.ts +81 -0
- package/dist/lib/core/security/userRepository.js +346 -0
- package/dist/lib/core/shared/abstractManifest.d.ts +27 -0
- package/dist/lib/core/shared/abstractManifest.js +85 -0
- package/dist/lib/core/shared/sdk/impersonatedSdk.d.ts +7 -0
- package/dist/lib/core/shared/sdk/impersonatedSdk.js +80 -0
- package/{lib → dist/lib}/core/shared/store.d.ts +2 -2
- package/dist/lib/core/statistics/statistics.d.ts +94 -0
- package/dist/lib/core/statistics/statistics.js +287 -0
- package/dist/lib/core/storage/clientAdapter.d.ts +62 -0
- package/dist/lib/core/storage/clientAdapter.js +756 -0
- package/dist/lib/core/storage/storageEngine.d.ts +13 -0
- package/dist/lib/core/storage/storageEngine.js +52 -0
- package/dist/lib/core/validation/baseType.d.ts +35 -0
- package/dist/lib/core/validation/baseType.js +70 -0
- package/dist/lib/core/validation/types/anything.d.ts +10 -0
- package/{lib → dist/lib}/core/validation/types/anything.js +7 -10
- package/dist/lib/core/validation/types/boolean.d.ts +16 -0
- package/{lib → dist/lib}/core/validation/types/boolean.js +18 -23
- package/dist/lib/core/validation/types/date.d.ts +17 -0
- package/dist/lib/core/validation/types/date.js +215 -0
- package/dist/lib/core/validation/types/email.d.ts +17 -0
- package/dist/lib/core/validation/types/email.js +80 -0
- package/dist/lib/core/validation/types/enum.d.ts +17 -0
- package/dist/lib/core/validation/types/enum.js +70 -0
- package/dist/lib/core/validation/types/geoPoint.d.ts +17 -0
- package/{lib → dist/lib}/core/validation/types/geoPoint.js +19 -24
- package/dist/lib/core/validation/types/geoShape.d.ts +31 -0
- package/dist/lib/core/validation/types/geoShape.js +280 -0
- package/dist/lib/core/validation/types/integer.d.ts +7 -0
- package/{lib → dist/lib}/core/validation/types/integer.js +21 -27
- package/dist/lib/core/validation/types/ipAddress.d.ts +17 -0
- package/dist/lib/core/validation/types/ipAddress.js +73 -0
- package/dist/lib/core/validation/types/numeric.d.ts +17 -0
- package/dist/lib/core/validation/types/numeric.js +84 -0
- package/dist/lib/core/validation/types/object.d.ts +24 -0
- package/dist/lib/core/validation/types/object.js +74 -0
- package/dist/lib/core/validation/types/string.d.ts +17 -0
- package/dist/lib/core/validation/types/string.js +85 -0
- package/dist/lib/core/validation/types/url.d.ts +17 -0
- package/dist/lib/core/validation/types/url.js +73 -0
- package/dist/lib/core/validation/validation.d.ts +113 -0
- package/dist/lib/core/validation/validation.js +692 -0
- package/dist/lib/kerror/codes/0-core.json +194 -0
- package/dist/lib/kerror/codes/1-services.json +351 -0
- package/dist/lib/kerror/codes/2-api.json +195 -0
- package/dist/lib/kerror/codes/3-network.json +151 -0
- package/dist/lib/kerror/codes/4-plugin.json +498 -0
- package/dist/lib/kerror/codes/5-validation.json +158 -0
- package/dist/lib/kerror/codes/6-protocol.json +28 -0
- package/dist/lib/kerror/codes/7-security.json +283 -0
- package/dist/lib/kerror/codes/8-cluster.json +16 -0
- package/dist/lib/kerror/codes/index.d.ts +24 -0
- package/dist/lib/kerror/codes/index.js +140 -0
- package/{lib → dist/lib}/kerror/index.d.ts +5 -5
- package/{lib → dist/lib}/kuzzle/Logger.d.ts +6 -0
- package/{lib → dist/lib}/kuzzle/Logger.js +26 -5
- package/dist/lib/kuzzle/dumpGenerator.d.ts +14 -0
- package/dist/lib/kuzzle/dumpGenerator.js +180 -0
- package/dist/lib/kuzzle/event/pipeRunner.d.ts +30 -0
- package/dist/lib/kuzzle/event/pipeRunner.js +119 -0
- package/dist/lib/kuzzle/event/waterfall.d.ts +2 -0
- package/dist/lib/kuzzle/event/waterfall.js +90 -0
- package/dist/lib/kuzzle/internalIndexHandler.d.ts +186 -0
- package/dist/lib/kuzzle/internalIndexHandler.js +174 -0
- package/{lib → dist/lib}/kuzzle/kuzzle.d.ts +6 -7
- package/{lib → dist/lib}/kuzzle/kuzzle.js +5 -2
- package/dist/lib/kuzzle/kuzzleStateEnum.d.ts +20 -0
- package/{lib → dist/lib}/kuzzle/kuzzleStateEnum.js +5 -8
- package/dist/lib/kuzzle/vault.d.ts +2 -0
- package/dist/lib/kuzzle/vault.js +63 -0
- package/dist/lib/model/security/rights.d.ts +8 -0
- package/{lib → dist/lib}/model/security/rights.js +4 -8
- package/{lib → dist/lib}/model/security/role.d.ts +1 -1
- package/{lib → dist/lib}/model/security/user.d.ts +1 -0
- package/dist/lib/model/storage/apiKey.d.ts +49 -0
- package/dist/lib/model/storage/apiKey.js +126 -0
- package/dist/lib/model/storage/baseModel.d.ts +100 -0
- package/dist/lib/model/storage/baseModel.js +211 -0
- package/dist/lib/service/cache/redis.d.ts +74 -0
- package/dist/lib/service/cache/redis.js +237 -0
- package/dist/lib/service/service.d.ts +30 -0
- package/dist/lib/service/service.js +74 -0
- package/{lib → dist/lib}/service/storage/7/elasticsearch.d.ts +2 -2
- package/{lib → dist/lib}/service/storage/7/elasticsearch.js +23 -25
- package/dist/lib/service/storage/7/esWrapper.d.ts +19 -0
- package/dist/lib/service/storage/7/esWrapper.js +245 -0
- package/{lib → dist/lib}/service/storage/8/elasticsearch.js +23 -25
- package/dist/lib/service/storage/8/esWrapper.d.ts +19 -0
- package/dist/lib/service/storage/8/esWrapper.js +245 -0
- package/{lib → dist/lib}/types/Plugin.d.ts +1 -1
- package/{lib/types → dist/lib/types/controllers}/Controller.d.ts +2 -2
- package/{lib/types → dist/lib/types/controllers}/ControllerDefinition.d.ts +1 -1
- package/dist/lib/types/controllers/adminControlller.type.d.ts +5 -0
- package/dist/lib/types/controllers/adminControlller.type.js +3 -0
- package/dist/lib/types/controllers/authController.type.d.ts +5 -0
- package/dist/lib/types/controllers/authController.type.js +3 -0
- package/dist/lib/types/core/auth/formatProcessing.type.d.ts +7 -0
- package/dist/lib/types/core/auth/formatProcessing.type.js +3 -0
- package/{lib → dist/lib}/types/index.d.ts +3 -3
- package/{lib → dist/lib}/types/index.js +3 -3
- package/dist/lib/util/assertType.d.ts +41 -0
- package/{lib → dist/lib}/util/assertType.js +38 -56
- package/dist/lib/util/asyncStore.d.ts +38 -0
- package/dist/lib/util/asyncStore.js +70 -0
- package/dist/lib/util/bytes.d.ts +2 -0
- package/dist/lib/util/bytes.js +33 -0
- package/dist/lib/util/debug.d.ts +2 -0
- package/{lib → dist/lib}/util/debug.js +15 -23
- package/dist/lib/util/deprecate.d.ts +1 -0
- package/dist/lib/util/deprecate.js +64 -0
- package/dist/lib/util/didYouMean.d.ts +2 -0
- package/{lib → dist/lib}/util/didYouMean.js +9 -15
- package/dist/lib/util/extractFields.d.ts +17 -0
- package/{lib → dist/lib}/util/extractFields.js +18 -32
- package/dist/lib/util/memoize.d.ts +7 -0
- package/{lib → dist/lib}/util/memoize.js +14 -21
- package/dist/lib/util/promback.d.ts +13 -0
- package/dist/lib/util/promback.js +60 -0
- package/dist/lib/util/requestAssertions.d.ts +10 -0
- package/dist/lib/util/requestAssertions.js +143 -0
- package/dist/lib/util/safeObject.d.ts +3 -0
- package/{lib → dist/lib}/util/safeObject.js +7 -13
- package/dist/lib/util/stackTrace.d.ts +19 -0
- package/{lib → dist/lib}/util/stackTrace.js +35 -41
- package/dist/lib/util/wildcard.d.ts +1 -0
- package/{lib → dist/lib}/util/wildcard.js +21 -30
- package/dist/package.json +120 -0
- package/package.json +45 -58
- package/bin/start-kuzzle-server +0 -126
- package/check-node-version.js +0 -17
- package/lib/api/controllers/adminController.js +0 -229
- package/lib/api/controllers/bulkController.js +0 -210
- package/lib/api/controllers/collectionController.js +0 -502
- package/lib/api/controllers/documentController.js +0 -1156
- package/lib/api/controllers/indexController.js +0 -179
- package/lib/api/controllers/memoryStorageController.js +0 -1023
- package/lib/api/controllers/realtimeController.js +0 -155
- package/lib/api/controllers/securityController.js +0 -1571
- package/lib/api/controllers/serverController.js +0 -381
- package/lib/api/documentExtractor.js +0 -309
- package/lib/api/funnel.js +0 -1143
- package/lib/api/httpRoutes.js +0 -1547
- package/lib/api/rateLimiter.js +0 -87
- package/lib/cluster/command.js +0 -284
- package/lib/cluster/node.js +0 -1203
- package/lib/cluster/publisher.js +0 -386
- package/lib/cluster/subscriber.js +0 -776
- package/lib/cluster/workers/IDCardRenewer.js +0 -144
- package/lib/config/index.js +0 -351
- package/lib/config/sdkCompatibility.json +0 -9
- package/lib/core/auth/formatProcessing.js +0 -66
- package/lib/core/auth/passportWrapper.js +0 -126
- package/lib/core/cache/cacheEngine.js +0 -278
- package/lib/core/network/accessLogger.js +0 -322
- package/lib/core/network/context.js +0 -80
- package/lib/core/network/entryPoint.js +0 -358
- package/lib/core/network/httpRouter/index.js +0 -316
- package/lib/core/network/httpRouter/routeHandler.js +0 -111
- package/lib/core/network/httpRouter/routePart.js +0 -147
- package/lib/core/network/protocols/httpMessage.js +0 -69
- package/lib/core/network/protocols/httpwsProtocol.js +0 -1254
- package/lib/core/network/protocols/internalProtocol.js +0 -109
- package/lib/core/network/protocols/mqttProtocol.js +0 -291
- package/lib/core/network/protocols/protocol.js +0 -102
- package/lib/core/network/router.js +0 -255
- package/lib/core/plugin/plugin.js +0 -436
- package/lib/core/plugin/pluginRepository.js +0 -132
- package/lib/core/plugin/pluginsManager.js +0 -1244
- package/lib/core/realtime/notification/document.js +0 -108
- package/lib/core/realtime/notification/user.js +0 -70
- package/lib/core/realtime/notifier.js +0 -541
- package/lib/core/security/README.md +0 -223
- package/lib/core/security/roleRepository.js +0 -569
- package/lib/core/security/securityLoader.js +0 -174
- package/lib/core/security/userRepository.js +0 -446
- package/lib/core/shared/README.md +0 -3
- package/lib/core/shared/abstractManifest.js +0 -102
- package/lib/core/shared/sdk/impersonatedSdk.js +0 -94
- package/lib/core/statistics/index.js +0 -24
- package/lib/core/statistics/statistics.js +0 -373
- package/lib/core/storage/clientAdapter.js +0 -1045
- package/lib/core/storage/storageEngine.js +0 -63
- package/lib/core/validation/baseType.js +0 -80
- package/lib/core/validation/index.js +0 -24
- package/lib/core/validation/types/date.js +0 -284
- package/lib/core/validation/types/email.js +0 -92
- package/lib/core/validation/types/enum.js +0 -100
- package/lib/core/validation/types/geoShape.js +0 -370
- package/lib/core/validation/types/ipAddress.js +0 -83
- package/lib/core/validation/types/numeric.js +0 -108
- package/lib/core/validation/types/object.js +0 -88
- package/lib/core/validation/types/string.js +0 -110
- package/lib/core/validation/types/url.js +0 -83
- package/lib/core/validation/validation.js +0 -1180
- package/lib/kerror/codes/0-core.json +0 -194
- package/lib/kerror/codes/1-services.json +0 -351
- package/lib/kerror/codes/2-api.json +0 -195
- package/lib/kerror/codes/3-network.json +0 -151
- package/lib/kerror/codes/4-plugin.json +0 -498
- package/lib/kerror/codes/5-validation.json +0 -158
- package/lib/kerror/codes/6-protocol.json +0 -28
- package/lib/kerror/codes/7-security.json +0 -283
- package/lib/kerror/codes/8-cluster.json +0 -16
- package/lib/kerror/codes/index.js +0 -208
- package/lib/kuzzle/dumpGenerator.js +0 -259
- package/lib/kuzzle/event/pipeRunner.js +0 -144
- package/lib/kuzzle/event/waterfall.js +0 -101
- package/lib/kuzzle/internalIndexHandler.js +0 -234
- package/lib/kuzzle/vault.js +0 -89
- package/lib/model/storage/apiKey.js +0 -158
- package/lib/model/storage/baseModel.js +0 -275
- package/lib/service/cache/redis.js +0 -282
- package/lib/service/service.js +0 -84
- package/lib/service/storage/7/esWrapper.js +0 -303
- package/lib/service/storage/8/esWrapper.js +0 -303
- package/lib/util/asyncStore.js +0 -112
- package/lib/util/bytes.js +0 -36
- package/lib/util/deprecate.js +0 -82
- package/lib/util/promback.js +0 -66
- package/lib/util/readYamlFile.d.ts +0 -2
- package/lib/util/readYamlFile.js +0 -10
- package/lib/util/requestAssertions.js +0 -157
- /package/{index.d.ts → dist/index.d.ts} +0 -0
- /package/{index.js → dist/index.js} +0 -0
- /package/{lib → dist/lib}/api/controllers/baseController.d.ts +0 -0
- /package/{lib → dist/lib}/api/controllers/baseController.js +0 -0
- /package/{lib → dist/lib}/api/controllers/debugController.d.ts +0 -0
- /package/{lib → dist/lib}/api/controllers/debugController.js +0 -0
- /package/{lib → dist/lib}/api/openapi/OpenApiManager.d.ts +0 -0
- /package/{lib → dist/lib}/api/openapi/OpenApiManager.js +0 -0
- /package/{lib → dist/lib}/api/openapi/index.d.ts +0 -0
- /package/{lib → dist/lib}/api/openapi/index.js +0 -0
- /package/{lib → dist/lib}/api/openapi/openApiGenerator.d.ts +0 -0
- /package/{lib → dist/lib}/api/openapi/openApiGenerator.js +0 -0
- /package/{lib → dist/lib}/api/request/index.d.ts +0 -0
- /package/{lib → dist/lib}/api/request/index.js +0 -0
- /package/{lib → dist/lib}/api/request/kuzzleRequest.js +0 -0
- /package/{lib → dist/lib}/api/request/requestContext.js +0 -0
- /package/{lib → dist/lib}/api/request/requestInput.d.ts +0 -0
- /package/{lib → dist/lib}/api/request/requestInput.js +0 -0
- /package/{lib → dist/lib}/api/request/requestResponse.d.ts +0 -0
- /package/{lib → dist/lib}/api/request/requestResponse.js +0 -0
- /package/{lib → dist/lib}/cluster/idCardHandler.d.ts +0 -0
- /package/{lib → dist/lib}/cluster/idCardHandler.js +0 -0
- /package/{lib → dist/lib}/cluster/protobuf/command.proto +0 -0
- /package/{lib → dist/lib}/cluster/protobuf/sync.proto +0 -0
- /package/{lib → dist/lib}/cluster/state.d.ts +0 -0
- /package/{lib → dist/lib}/cluster/state.js +0 -0
- /package/{lib → dist/lib}/config/default.config.d.ts +0 -0
- /package/{lib → dist/lib}/config/default.config.js +0 -0
- /package/{lib → dist/lib}/config/documentEventAliases.js +0 -0
- /package/{lib → dist/lib}/core/auth/tokenManager.d.ts +0 -0
- /package/{lib → dist/lib}/core/auth/tokenManager.js +0 -0
- /package/{lib → dist/lib}/core/backend/applicationManager.d.ts +0 -0
- /package/{lib → dist/lib}/core/backend/applicationManager.js +0 -0
- /package/{lib → dist/lib}/core/backend/backend.d.ts +0 -0
- /package/{lib → dist/lib}/core/backend/backend.js +0 -0
- /package/{lib → dist/lib}/core/backend/backendCluster.d.ts +0 -0
- /package/{lib → dist/lib}/core/backend/backendCluster.js +0 -0
- /package/{lib → dist/lib}/core/backend/backendConfig.d.ts +0 -0
- /package/{lib → dist/lib}/core/backend/backendController.d.ts +0 -0
- /package/{lib → dist/lib}/core/backend/backendController.js +0 -0
- /package/{lib → dist/lib}/core/backend/backendErrors.d.ts +0 -0
- /package/{lib → dist/lib}/core/backend/backendHook.d.ts +0 -0
- /package/{lib → dist/lib}/core/backend/backendHook.js +0 -0
- /package/{lib → dist/lib}/core/backend/backendImport.d.ts +0 -0
- /package/{lib → dist/lib}/core/backend/backendImport.js +0 -0
- /package/{lib → dist/lib}/core/backend/backendOpenApi.d.ts +0 -0
- /package/{lib → dist/lib}/core/backend/backendOpenApi.js +0 -0
- /package/{lib → dist/lib}/core/backend/backendPipe.d.ts +0 -0
- /package/{lib → dist/lib}/core/backend/backendPipe.js +0 -0
- /package/{lib → dist/lib}/core/backend/backendPlugin.d.ts +0 -0
- /package/{lib → dist/lib}/core/backend/backendPlugin.js +0 -0
- /package/{lib → dist/lib}/core/backend/backendStorage.d.ts +0 -0
- /package/{lib → dist/lib}/core/backend/backendStorage.js +0 -0
- /package/{lib → dist/lib}/core/backend/backendSubscription.d.ts +0 -0
- /package/{lib → dist/lib}/core/backend/backendSubscription.js +0 -0
- /package/{lib → dist/lib}/core/backend/backendVault.d.ts +0 -0
- /package/{lib → dist/lib}/core/backend/backendVault.js +0 -0
- /package/{lib → dist/lib}/core/backend/index.d.ts +0 -0
- /package/{lib → dist/lib}/core/backend/index.js +0 -0
- /package/{lib → dist/lib}/core/backend/internalLogger.d.ts +0 -0
- /package/{lib → dist/lib}/core/backend/internalLogger.js +0 -0
- /package/{lib → dist/lib}/core/cache/cacheDbEnum.d.ts +0 -0
- /package/{lib → dist/lib}/core/cache/cacheDbEnum.js +0 -0
- /package/{lib → dist/lib}/core/debug/kuzzleDebugger.d.ts +0 -0
- /package/{lib → dist/lib}/core/debug/kuzzleDebugger.js +0 -0
- /package/{lib → dist/lib}/core/plugin/pluginContext.d.ts +0 -0
- /package/{lib → dist/lib}/core/realtime/channel.d.ts +0 -0
- /package/{lib → dist/lib}/core/realtime/channel.js +0 -0
- /package/{lib → dist/lib}/core/realtime/connectionRooms.d.ts +0 -0
- /package/{lib → dist/lib}/core/realtime/connectionRooms.js +0 -0
- /package/{lib → dist/lib}/core/realtime/hotelClerk.d.ts +0 -0
- /package/{lib → dist/lib}/core/realtime/hotelClerk.js +0 -0
- /package/{lib → dist/lib}/core/realtime/room.d.ts +0 -0
- /package/{lib → dist/lib}/core/realtime/room.js +0 -0
- /package/{lib → dist/lib}/core/realtime/subscription.d.ts +0 -0
- /package/{lib → dist/lib}/core/realtime/subscription.js +0 -0
- /package/{lib → dist/lib}/core/security/profileRepository.d.ts +0 -0
- /package/{lib → dist/lib}/core/security/profileRepository.js +0 -0
- /package/{lib → dist/lib}/core/security/tokenRepository.d.ts +0 -0
- /package/{lib → dist/lib}/core/shared/KoncordeWrapper.d.ts +0 -0
- /package/{lib → dist/lib}/core/shared/KoncordeWrapper.js +0 -0
- /package/{lib → dist/lib}/core/shared/ObjectRepository.d.ts +0 -0
- /package/{lib → dist/lib}/core/shared/ObjectRepository.js +0 -0
- /package/{lib → dist/lib}/core/shared/sdk/embeddedSdk.d.ts +0 -0
- /package/{lib → dist/lib}/core/shared/sdk/embeddedSdk.js +0 -0
- /package/{lib → dist/lib}/core/shared/sdk/funnelProtocol.d.ts +0 -0
- /package/{lib → dist/lib}/core/shared/sdk/funnelProtocol.js +0 -0
- /package/{lib → dist/lib}/core/shared/store.js +0 -0
- /package/{lib → dist/lib}/core/storage/indexCache.d.ts +0 -0
- /package/{lib → dist/lib}/core/storage/indexCache.js +0 -0
- /package/{lib → dist/lib}/core/storage/storeScopeEnum.d.ts +0 -0
- /package/{lib → dist/lib}/core/storage/storeScopeEnum.js +0 -0
- /package/{lib → dist/lib}/kerror/errors/badRequestError.d.ts +0 -0
- /package/{lib → dist/lib}/kerror/errors/badRequestError.js +0 -0
- /package/{lib → dist/lib}/kerror/errors/externalServiceError.d.ts +0 -0
- /package/{lib → dist/lib}/kerror/errors/externalServiceError.js +0 -0
- /package/{lib → dist/lib}/kerror/errors/forbiddenError.d.ts +0 -0
- /package/{lib → dist/lib}/kerror/errors/forbiddenError.js +0 -0
- /package/{lib → dist/lib}/kerror/errors/gatewayTimeoutError.d.ts +0 -0
- /package/{lib → dist/lib}/kerror/errors/gatewayTimeoutError.js +0 -0
- /package/{lib → dist/lib}/kerror/errors/index.d.ts +0 -0
- /package/{lib → dist/lib}/kerror/errors/index.js +0 -0
- /package/{lib → dist/lib}/kerror/errors/internalError.d.ts +0 -0
- /package/{lib → dist/lib}/kerror/errors/internalError.js +0 -0
- /package/{lib → dist/lib}/kerror/errors/kuzzleError.d.ts +0 -0
- /package/{lib → dist/lib}/kerror/errors/kuzzleError.js +0 -0
- /package/{lib → dist/lib}/kerror/errors/multipleErrorsError.d.ts +0 -0
- /package/{lib → dist/lib}/kerror/errors/multipleErrorsError.js +0 -0
- /package/{lib → dist/lib}/kerror/errors/notFoundError.d.ts +0 -0
- /package/{lib → dist/lib}/kerror/errors/notFoundError.js +0 -0
- /package/{lib → dist/lib}/kerror/errors/partialError.d.ts +0 -0
- /package/{lib → dist/lib}/kerror/errors/partialError.js +0 -0
- /package/{lib → dist/lib}/kerror/errors/pluginImplementationError.d.ts +0 -0
- /package/{lib → dist/lib}/kerror/errors/pluginImplementationError.js +0 -0
- /package/{lib → dist/lib}/kerror/errors/preconditionError.d.ts +0 -0
- /package/{lib → dist/lib}/kerror/errors/preconditionError.js +0 -0
- /package/{lib → dist/lib}/kerror/errors/serviceUnavailableError.d.ts +0 -0
- /package/{lib → dist/lib}/kerror/errors/serviceUnavailableError.js +0 -0
- /package/{lib → dist/lib}/kerror/errors/sizeLimitError.d.ts +0 -0
- /package/{lib → dist/lib}/kerror/errors/sizeLimitError.js +0 -0
- /package/{lib → dist/lib}/kerror/errors/tooManyRequestsError.d.ts +0 -0
- /package/{lib → dist/lib}/kerror/errors/tooManyRequestsError.js +0 -0
- /package/{lib → dist/lib}/kerror/errors/unauthorizedError.d.ts +0 -0
- /package/{lib → dist/lib}/kerror/errors/unauthorizedError.js +0 -0
- /package/{lib → dist/lib}/kerror/index.js +0 -0
- /package/{lib → dist/lib}/kuzzle/event/KuzzleEventEmitter.d.ts +0 -0
- /package/{lib → dist/lib}/kuzzle/event/KuzzleEventEmitter.js +0 -0
- /package/{lib → dist/lib}/kuzzle/index.d.ts +0 -0
- /package/{lib → dist/lib}/kuzzle/index.js +0 -0
- /package/{lib → dist/lib}/model/security/profile.d.ts +0 -0
- /package/{lib → dist/lib}/model/security/profile.js +0 -0
- /package/{lib → dist/lib}/model/security/role.js +0 -0
- /package/{lib → dist/lib}/model/security/token.d.ts +0 -0
- /package/{lib → dist/lib}/model/security/token.js +0 -0
- /package/{lib → dist/lib}/model/security/user.js +0 -0
- /package/{lib → dist/lib}/service/storage/8/elasticsearch.d.ts +0 -0
- /package/{lib → dist/lib}/service/storage/Elasticsearch.d.ts +0 -0
- /package/{lib → dist/lib}/service/storage/Elasticsearch.js +0 -0
- /package/{lib → dist/lib}/service/storage/commons/queryTranslator.d.ts +0 -0
- /package/{lib → dist/lib}/service/storage/commons/queryTranslator.js +0 -0
- /package/{lib → dist/lib}/types/ClientConnection.d.ts +0 -0
- /package/{lib → dist/lib}/types/ClientConnection.js +0 -0
- /package/{lib → dist/lib}/types/Deprecation.d.ts +0 -0
- /package/{lib → dist/lib}/types/Deprecation.js +0 -0
- /package/{lib → dist/lib}/types/EventHandler.d.ts +0 -0
- /package/{lib → dist/lib}/types/EventHandler.js +0 -0
- /package/{lib → dist/lib}/types/Global.d.ts +0 -0
- /package/{lib → dist/lib}/types/Global.js +0 -0
- /package/{lib → dist/lib}/types/HttpMessage.d.ts +0 -0
- /package/{lib → dist/lib}/types/HttpMessage.js +0 -0
- /package/{lib → dist/lib}/types/HttpStream.d.ts +0 -0
- /package/{lib → dist/lib}/types/HttpStream.js +0 -0
- /package/{lib → dist/lib}/types/Kuzzle.d.ts +0 -0
- /package/{lib → dist/lib}/types/Kuzzle.js +0 -0
- /package/{lib → dist/lib}/types/KuzzleDocument.d.ts +0 -0
- /package/{lib → dist/lib}/types/KuzzleDocument.js +0 -0
- /package/{lib → dist/lib}/types/OpenApiDefinition.d.ts +0 -0
- /package/{lib → dist/lib}/types/OpenApiDefinition.js +0 -0
- /package/{lib → dist/lib}/types/PasswordPolicy.d.ts +0 -0
- /package/{lib → dist/lib}/types/PasswordPolicy.js +0 -0
- /package/{lib → dist/lib}/types/Plugin.js +0 -0
- /package/{lib → dist/lib}/types/PluginManifest.d.ts +0 -0
- /package/{lib → dist/lib}/types/PluginManifest.js +0 -0
- /package/{lib → dist/lib}/types/Policy.d.ts +0 -0
- /package/{lib → dist/lib}/types/Policy.js +0 -0
- /package/{lib → dist/lib}/types/PolicyRestrictions.d.ts +0 -0
- /package/{lib → dist/lib}/types/PolicyRestrictions.js +0 -0
- /package/{lib → dist/lib}/types/ProfileDefinition.d.ts +0 -0
- /package/{lib → dist/lib}/types/ProfileDefinition.js +0 -0
- /package/{lib → dist/lib}/types/RoleDefinition.d.ts +0 -0
- /package/{lib → dist/lib}/types/RoleDefinition.js +0 -0
- /package/{lib → dist/lib}/types/StrategyDefinition.d.ts +0 -0
- /package/{lib → dist/lib}/types/StrategyDefinition.js +0 -0
- /package/{lib → dist/lib}/types/Target.d.ts +0 -0
- /package/{lib → dist/lib}/types/Target.js +0 -0
- /package/{lib → dist/lib}/types/Token.d.ts +0 -0
- /package/{lib → dist/lib}/types/Token.js +0 -0
- /package/{lib → dist/lib}/types/User.d.ts +0 -0
- /package/{lib → dist/lib}/types/User.js +0 -0
- /package/{lib → dist/lib}/types/config/DumpConfiguration.d.ts +0 -0
- /package/{lib → dist/lib}/types/config/DumpConfiguration.js +0 -0
- /package/{lib → dist/lib}/types/config/HttpConfiguration.d.ts +0 -0
- /package/{lib → dist/lib}/types/config/HttpConfiguration.js +0 -0
- /package/{lib → dist/lib}/types/config/KuzzleConfiguration.d.ts +0 -0
- /package/{lib → dist/lib}/types/config/KuzzleConfiguration.js +0 -0
- /package/{lib → dist/lib}/types/config/LimitsConfiguration.d.ts +0 -0
- /package/{lib → dist/lib}/types/config/LimitsConfiguration.js +0 -0
- /package/{lib → dist/lib}/types/config/PluginsConfiguration.d.ts +0 -0
- /package/{lib → dist/lib}/types/config/PluginsConfiguration.js +0 -0
- /package/{lib → dist/lib}/types/config/SecurityConfiguration.d.ts +0 -0
- /package/{lib → dist/lib}/types/config/SecurityConfiguration.js +0 -0
- /package/{lib → dist/lib}/types/config/ServerConfiguration.d.ts +0 -0
- /package/{lib → dist/lib}/types/config/ServerConfiguration.js +0 -0
- /package/{lib → dist/lib}/types/config/ServicesConfiguration.d.ts +0 -0
- /package/{lib → dist/lib}/types/config/ServicesConfiguration.js +0 -0
- /package/{lib → dist/lib}/types/config/internalCache/InternalCacheRedisConfiguration.d.ts +0 -0
- /package/{lib → dist/lib}/types/config/internalCache/InternalCacheRedisConfiguration.js +0 -0
- /package/{lib → dist/lib}/types/config/publicCache/PublicCacheRedisConfiguration.d.ts +0 -0
- /package/{lib → dist/lib}/types/config/publicCache/PublicCacheRedisConfiguration.js +0 -0
- /package/{lib → dist/lib}/types/config/storageEngine/StorageEngineElasticsearchConfiguration.d.ts +0 -0
- /package/{lib → dist/lib}/types/config/storageEngine/StorageEngineElasticsearchConfiguration.js +0 -0
- /package/{lib/types → dist/lib/types/controllers}/Controller.js +0 -0
- /package/{lib/types → dist/lib/types/controllers}/ControllerDefinition.js +0 -0
- /package/{lib/types → dist/lib/types/controllers}/ControllerRights.d.ts +0 -0
- /package/{lib/types → dist/lib/types/controllers}/ControllerRights.js +0 -0
- /package/{lib → dist/lib}/types/errors/ErrorDefinition.d.ts +0 -0
- /package/{lib → dist/lib}/types/errors/ErrorDefinition.js +0 -0
- /package/{lib → dist/lib}/types/errors/ErrorDomains.d.ts +0 -0
- /package/{lib → dist/lib}/types/errors/ErrorDomains.js +0 -0
- /package/{lib → dist/lib}/types/events/EventGenericDocument.d.ts +0 -0
- /package/{lib → dist/lib}/types/events/EventGenericDocument.js +0 -0
- /package/{lib → dist/lib}/types/events/EventProtocol.d.ts +0 -0
- /package/{lib → dist/lib}/types/events/EventProtocol.js +0 -0
- /package/{lib → dist/lib}/types/realtime/RealtimeScope.d.ts +0 -0
- /package/{lib → dist/lib}/types/realtime/RealtimeScope.js +0 -0
- /package/{lib → dist/lib}/types/realtime/RealtimeUsers.d.ts +0 -0
- /package/{lib → dist/lib}/types/realtime/RealtimeUsers.js +0 -0
- /package/{lib → dist/lib}/types/realtime/RoomList.d.ts +0 -0
- /package/{lib → dist/lib}/types/realtime/RoomList.js +0 -0
- /package/{lib → dist/lib}/types/shared/StoreCollectionsDefinition.d.ts +0 -0
- /package/{lib → dist/lib}/types/shared/StoreCollectionsDefinition.js +0 -0
- /package/{lib → dist/lib}/types/storage/7/Elasticsearch.d.ts +0 -0
- /package/{lib → dist/lib}/types/storage/7/Elasticsearch.js +0 -0
- /package/{lib → dist/lib}/types/storage/8/Elasticsearch.d.ts +0 -0
- /package/{lib → dist/lib}/types/storage/8/Elasticsearch.js +0 -0
- /package/{lib → dist/lib}/util/Inflector.d.ts +0 -0
- /package/{lib → dist/lib}/util/Inflector.js +0 -0
- /package/{lib → dist/lib}/util/array.d.ts +0 -0
- /package/{lib → dist/lib}/util/array.js +0 -0
- /package/{lib → dist/lib}/util/async.d.ts +0 -0
- /package/{lib → dist/lib}/util/async.js +0 -0
- /package/{lib → dist/lib}/util/bufferedPassThrough.d.ts +0 -0
- /package/{lib → dist/lib}/util/bufferedPassThrough.js +0 -0
- /package/{lib → dist/lib}/util/crypto.d.ts +0 -0
- /package/{lib → dist/lib}/util/crypto.js +0 -0
- /package/{lib → dist/lib}/util/dump-collection.d.ts +0 -0
- /package/{lib → dist/lib}/util/dump-collection.js +0 -0
- /package/{lib → dist/lib}/util/esRequest.d.ts +0 -0
- /package/{lib → dist/lib}/util/esRequest.js +0 -0
- /package/{lib → dist/lib}/util/koncordeCompat.d.ts +0 -0
- /package/{lib → dist/lib}/util/koncordeCompat.js +0 -0
- /package/{lib → dist/lib}/util/mutex.d.ts +0 -0
- /package/{lib → dist/lib}/util/mutex.js +0 -0
- /package/{lib → dist/lib}/util/name-generator.d.ts +0 -0
- /package/{lib → dist/lib}/util/name-generator.js +0 -0
- /package/{lib → dist/lib}/util/time.d.ts +0 -0
- /package/{lib → dist/lib}/util/time.js +0 -0
|
@@ -0,0 +1,876 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Kuzzle, a backend software, self-hostable and ready to use
|
|
3
|
+
* to power modern apps
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2015-2022 Kuzzle
|
|
6
|
+
* mailto: support AT kuzzle.io
|
|
7
|
+
* website: http://kuzzle.io
|
|
8
|
+
*
|
|
9
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
10
|
+
* you may not use this file except in compliance with the License.
|
|
11
|
+
* You may obtain a copy of the License at
|
|
12
|
+
*
|
|
13
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
14
|
+
*
|
|
15
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
16
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
17
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18
|
+
* See the License for the specific language governing permissions and
|
|
19
|
+
* limitations under the License.
|
|
20
|
+
*/
|
|
21
|
+
"use strict";
|
|
22
|
+
const os = require("os");
|
|
23
|
+
const net = require("net");
|
|
24
|
+
const assert = require("assert");
|
|
25
|
+
const Bluebird = require("bluebird");
|
|
26
|
+
const EventEmitter = require("eventemitter3");
|
|
27
|
+
const _ = require("lodash");
|
|
28
|
+
const debug = require("../util/debug")("kuzzle:cluster:sync");
|
|
29
|
+
const { Mutex } = require("../util/mutex");
|
|
30
|
+
const { ClusterIdCardHandler } = require("./idCardHandler");
|
|
31
|
+
const ClusterPublisher = require("./publisher");
|
|
32
|
+
const ClusterSubscriber = require("./subscriber");
|
|
33
|
+
const ClusterState = require("./state");
|
|
34
|
+
const ClusterCommand = require("./command");
|
|
35
|
+
const kuzzleStateEnum = require("../kuzzle/kuzzleStateEnum");
|
|
36
|
+
const { fromKoncordeIndex } = require("../util/koncordeCompat");
|
|
37
|
+
/**
|
|
38
|
+
* Test an IP address and determine if it's in the public or private range.
|
|
39
|
+
*
|
|
40
|
+
* @param {String} ip
|
|
41
|
+
* @return {Boolean}
|
|
42
|
+
*/
|
|
43
|
+
function isPrivateIP(ip) {
|
|
44
|
+
if (net.isIPv6(ip)) {
|
|
45
|
+
const prefix = ip.split(":")[0];
|
|
46
|
+
return ((prefix.startsWith("fd") && prefix.length === 4) || prefix === "fe80");
|
|
47
|
+
}
|
|
48
|
+
// IPv4
|
|
49
|
+
const exploded = ip.split(".").map((s) => Number.parseInt(s));
|
|
50
|
+
return (exploded[0] === 10 ||
|
|
51
|
+
(exploded[0] === 172 && exploded[1] >= 16 && exploded[1] <= 31) ||
|
|
52
|
+
(exploded[0] === 192 && exploded[1] === 168));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Some IPv4 addresses are reserved for internal uses only, and cannot be
|
|
56
|
+
* reached from other machines. We need to detect and filter them
|
|
57
|
+
* @param {String} ip
|
|
58
|
+
* @return {Boolean}
|
|
59
|
+
*/
|
|
60
|
+
function isInternalIP(ip) {
|
|
61
|
+
// To my knowledge, there aren't any reserved, non-loopback and non-routable
|
|
62
|
+
// IPv6 addresses
|
|
63
|
+
if (net.isIPv6(ip)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
const exploded = ip.split(".").map((s) => Number.parseInt(s));
|
|
67
|
+
// 127.x.x: loopback addresses are already flagged as "internal" by
|
|
68
|
+
// os.networkInterfaces.
|
|
69
|
+
return (exploded[0] === 127 ||
|
|
70
|
+
// 169.254.x.x addresses are APIPA addresses: temporary and non-routable.
|
|
71
|
+
// We need to remove them from the accepted list of IP addresses
|
|
72
|
+
// (this is a "just in case" scenario: APIPA addresses are obsolete and
|
|
73
|
+
// should not be used anymore, but we never know...)
|
|
74
|
+
(exploded[0] === 169 && exploded[1] === 254));
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Return the first IP address matching the provided configuration
|
|
78
|
+
* @param {Object} [options]
|
|
79
|
+
* @param {String} [options.family] IP family (IPv4 or IPv6)
|
|
80
|
+
* @param {String} [options.interface] Network interface/IP/MAC to use
|
|
81
|
+
* @param {String} [options.ip] Used to target public or private addresses
|
|
82
|
+
* @return {String|null}
|
|
83
|
+
*/
|
|
84
|
+
function getIP({ family = "IPv4", interface: netInterface, ip } = {}) {
|
|
85
|
+
const mustBePrivate = ip === "private";
|
|
86
|
+
let interfaces = [];
|
|
87
|
+
for (const [key, value] of Object.entries(os.networkInterfaces())) {
|
|
88
|
+
for (const _interface of value) {
|
|
89
|
+
interfaces.push({
|
|
90
|
+
interface: key,
|
|
91
|
+
..._interface,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
debug("Found interfaces %o", interfaces);
|
|
96
|
+
interfaces = interfaces.filter((n) => {
|
|
97
|
+
return (!n.internal &&
|
|
98
|
+
!isInternalIP(n.address) &&
|
|
99
|
+
n.family === family &&
|
|
100
|
+
(!ip || mustBePrivate === isPrivateIP(n.address)));
|
|
101
|
+
});
|
|
102
|
+
debug("Filtered interfaces %o", interfaces);
|
|
103
|
+
if (interfaces.length === 0) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
// take the first IP from the list if no interface has been defined
|
|
107
|
+
if (!netInterface) {
|
|
108
|
+
return interfaces[0].address;
|
|
109
|
+
}
|
|
110
|
+
for (const i of interfaces) {
|
|
111
|
+
if ([i.interface, i.address, i.mac].includes(netInterface)) {
|
|
112
|
+
return i.address;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* @typedef {nodeActivityEnum}
|
|
119
|
+
*/
|
|
120
|
+
const nodeActivityEnum = Object.freeze({
|
|
121
|
+
ADDED: 1,
|
|
122
|
+
EVICTED: 2,
|
|
123
|
+
});
|
|
124
|
+
// Handles the node logic: discovery, eviction, heartbeat, ...
|
|
125
|
+
// Dependencies: core:cache module must be started
|
|
126
|
+
class ClusterNode {
|
|
127
|
+
constructor() {
|
|
128
|
+
this.config = global.kuzzle.config.cluster;
|
|
129
|
+
this.logger = global.kuzzle.log.child("cluster:node");
|
|
130
|
+
this.heartbeatDelay = this.config.heartbeat;
|
|
131
|
+
const family = this.config.ipv6 ? "IPv6" : "IPv4";
|
|
132
|
+
this.ip = getIP({
|
|
133
|
+
family,
|
|
134
|
+
interface: this.config.interface,
|
|
135
|
+
ip: this.config.ip,
|
|
136
|
+
});
|
|
137
|
+
debug("Found IP address: %s with config %o", this.ip, this.config);
|
|
138
|
+
assert(this.ip !== null, `[CLUSTER] No suitable IP address found with the provided configuration (family: ${family}, interface: ${this.config.interface}, ip: ${this.config.ip})`);
|
|
139
|
+
this.nodeId = null;
|
|
140
|
+
this.heartbeatTimer = null;
|
|
141
|
+
this.idCardHandler = new ClusterIdCardHandler(this);
|
|
142
|
+
this.publisher = new ClusterPublisher(this);
|
|
143
|
+
this.fullState = new ClusterState();
|
|
144
|
+
this.command = new ClusterCommand(this);
|
|
145
|
+
this.eventEmitter = new EventEmitter();
|
|
146
|
+
/**
|
|
147
|
+
* Links remote node IDs with their subscriber counterpart
|
|
148
|
+
* @type {Map.<string, ClusterSubscriber>}
|
|
149
|
+
*/
|
|
150
|
+
this.remoteNodes = new Map();
|
|
151
|
+
/**
|
|
152
|
+
* Cluster nodes activity, used to keep track of nodes being added or
|
|
153
|
+
* removed, to give more insights to cluster statuses
|
|
154
|
+
*/
|
|
155
|
+
this.activityMaxLength = this.config.activityDepth;
|
|
156
|
+
this.activity = [];
|
|
157
|
+
}
|
|
158
|
+
get syncAddress() {
|
|
159
|
+
return `tcp://${this.ip}:${this.config.ports.sync}`;
|
|
160
|
+
}
|
|
161
|
+
async init() {
|
|
162
|
+
// The publisher needs to be created and initialized before the handshake:
|
|
163
|
+
// other nodes we'll connect to during the handshake will start to subscribe
|
|
164
|
+
// to this node right away
|
|
165
|
+
await this.publisher.init();
|
|
166
|
+
// This also needs to be started before the handshake, as this class handles
|
|
167
|
+
// direct requests to other nodes (needed to request for the full state
|
|
168
|
+
// and to introduce oneself to other nodes)
|
|
169
|
+
await this.command.init();
|
|
170
|
+
global.kuzzle.onPipe("kuzzle:shutdown", () => this.shutdown());
|
|
171
|
+
await this.handshake();
|
|
172
|
+
this.registerEvents();
|
|
173
|
+
this.registerAskEvents();
|
|
174
|
+
if (this.countActiveNodes() < this.config.minimumNodes) {
|
|
175
|
+
this.logger.info("[CLUSTER] Not enough nodes active. Waiting for other nodes to join the cluster...");
|
|
176
|
+
while (this.countActiveNodes() < this.config.minimumNodes) {
|
|
177
|
+
await Bluebird.delay(100);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return this.nodeId;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Shutdown event: clears all timers, sends a termination status to other
|
|
184
|
+
* nodes, and removes entries from the cache
|
|
185
|
+
*/
|
|
186
|
+
async shutdown() {
|
|
187
|
+
clearInterval(this.heartbeatTimer);
|
|
188
|
+
await this.idCardHandler.dispose();
|
|
189
|
+
for (const subscriber of this.remoteNodes.values()) {
|
|
190
|
+
subscriber.dispose();
|
|
191
|
+
}
|
|
192
|
+
this.publisher.sendNodeShutdown(this.nodeId);
|
|
193
|
+
await this.publisher.dispose();
|
|
194
|
+
this.command.dispose();
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Notify other nodes to not evict this node
|
|
198
|
+
*
|
|
199
|
+
* @param {bool} evictionPrevented
|
|
200
|
+
*/
|
|
201
|
+
preventEviction(evictionPrevented) {
|
|
202
|
+
this.publisher.sendNodePreventEviction(evictionPrevented);
|
|
203
|
+
// This node is subscribed to the other node and might not receive their heartbeat while debugging
|
|
204
|
+
// so this node should not have the responsability of evicting others when his own eviction is prevented
|
|
205
|
+
// when debugging.
|
|
206
|
+
// Otherwise when recovering from a debug session, all the other nodes will be evicted.
|
|
207
|
+
for (const subscriber of this.remoteNodes.values()) {
|
|
208
|
+
subscriber.handleNodePreventEviction({
|
|
209
|
+
evictionPrevented,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Adds a new remote node, and subscribes to it.
|
|
215
|
+
* @param {string} id - remote node ID
|
|
216
|
+
* @param {string} ip - remote node IP address
|
|
217
|
+
* @param {number} lastMessageId - remote node last message ID
|
|
218
|
+
* @return {boolean} false if the node was already known, true otherwise
|
|
219
|
+
*/
|
|
220
|
+
async addNode(id, ip, lastMessageId) {
|
|
221
|
+
if (this.remoteNodes.has(id)) {
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
const subscriber = new ClusterSubscriber(this, id, ip);
|
|
225
|
+
this.remoteNodes.set(id, subscriber);
|
|
226
|
+
await subscriber.init();
|
|
227
|
+
await subscriber.sync(lastMessageId);
|
|
228
|
+
await this.idCardHandler.addNode(id);
|
|
229
|
+
this.logger.info(`[CLUSTER] Node "${id}" joined the cluster`);
|
|
230
|
+
this.trackActivity(id, ip, nodeActivityEnum.ADDED);
|
|
231
|
+
if (global.kuzzle.state === kuzzleStateEnum.NOT_ENOUGH_NODES &&
|
|
232
|
+
this.countActiveNodes() >= this.config.minimumNodes) {
|
|
233
|
+
global.kuzzle.state = kuzzleStateEnum.RUNNING;
|
|
234
|
+
this.logger.warn(`[CLUSTER] Minimum number of nodes reached (${this.countActiveNodes()}). This node is now accepting requests again.`);
|
|
235
|
+
}
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Evicts this node from the cluster.
|
|
240
|
+
*
|
|
241
|
+
* @param {String} reason
|
|
242
|
+
* @param {Error} [error]
|
|
243
|
+
* @return {void}
|
|
244
|
+
*/
|
|
245
|
+
async evictSelf(reason, error = null) {
|
|
246
|
+
this.logger.error(`[CLUSTER] ${reason}`);
|
|
247
|
+
if (error) {
|
|
248
|
+
this.logger.error(error.stack);
|
|
249
|
+
}
|
|
250
|
+
this.publisher.sendNodeEvicted(this.nodeId, this.nodeId, reason);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Evicts a remote from the list
|
|
254
|
+
* @param {string} nodeId - remote node ID
|
|
255
|
+
* @param {Object} [options]
|
|
256
|
+
* @param {boolean} [options.broadcast] - broadcast the eviction to the cluster
|
|
257
|
+
* @param {string} [options.reason] - reason of eviction
|
|
258
|
+
*/
|
|
259
|
+
async evictNode(nodeId, { broadcast = false, reason = "" }) {
|
|
260
|
+
const subscriber = this.remoteNodes.get(nodeId);
|
|
261
|
+
if (!subscriber) {
|
|
262
|
+
this.logger.warn(`[CLUSTER] Node "${nodeId}" with no subscriber evicted. Reason: ${reason}`);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
this.logger.warn(`[CLUSTER] Node "${nodeId}" evicted. Reason: ${reason}`);
|
|
266
|
+
this.trackActivity(nodeId, subscriber.remoteNodeIP, nodeActivityEnum.EVICTED, reason);
|
|
267
|
+
await this.idCardHandler.removeNode(nodeId);
|
|
268
|
+
this.remoteNodes.delete(nodeId);
|
|
269
|
+
this.fullState.removeNode(nodeId);
|
|
270
|
+
subscriber.dispose();
|
|
271
|
+
if (broadcast) {
|
|
272
|
+
this.publisher.sendNodeEvicted(this.nodeId, nodeId, reason);
|
|
273
|
+
}
|
|
274
|
+
if (this.countActiveNodes() < this.config.minimumNodes) {
|
|
275
|
+
global.kuzzle.state = kuzzleStateEnum.NOT_ENOUGH_NODES;
|
|
276
|
+
this.logger.warn(`[CLUSTER] Not enough nodes active (expected: ${this.config.minimumNodes}, active: ${this.countActiveNodes()}). Deactivating node until new ones are added.`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Verifies the consistency of the cluster by comparing our own known
|
|
281
|
+
* topology with the one kept in other nodes ID cards
|
|
282
|
+
*
|
|
283
|
+
* /!\ Do not wait for this method: it's meant to run as a background check.
|
|
284
|
+
* It'll never throw, and it'll never generate unhandled rejections.
|
|
285
|
+
*/
|
|
286
|
+
async enforceClusterConsistency() {
|
|
287
|
+
// Delay the check to 1 heartbeat round, to allow all nodes to update
|
|
288
|
+
// their ID cards
|
|
289
|
+
await Bluebird.delay(this.heartbeatDelay);
|
|
290
|
+
try {
|
|
291
|
+
const idCards = await this.idCardHandler.getRemoteIdCards();
|
|
292
|
+
idCards.push(this.idCardHandler.idCard);
|
|
293
|
+
let splits = [];
|
|
294
|
+
for (const idCard of idCards) {
|
|
295
|
+
let topology = Array.from(idCard.topology);
|
|
296
|
+
topology.push(idCard.id);
|
|
297
|
+
if (topology.length !== idCards.length) {
|
|
298
|
+
topology = topology.sort();
|
|
299
|
+
const found = splits.some((split) => {
|
|
300
|
+
if (split.length !== topology.length) {
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
return split.every((id, index) => id === topology[index]);
|
|
304
|
+
});
|
|
305
|
+
if (!found) {
|
|
306
|
+
splits.push(topology);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
// No split detected, the cluster is consistent
|
|
311
|
+
if (splits.length === 0) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
// There is at least 1 cluster split detected.
|
|
315
|
+
//
|
|
316
|
+
// First we elect the smallest split possible.
|
|
317
|
+
// If multiple splits are eligibles, we choose amongst them the split
|
|
318
|
+
// containing the youngest isolated node (isolated = the node is in this
|
|
319
|
+
// split alone, and in no other splits). If no split is eligible using
|
|
320
|
+
// this method, we fall back to the smallest split containing the youngest
|
|
321
|
+
// node (isolated or not).
|
|
322
|
+
//
|
|
323
|
+
// The goal of this process is to force at least 1 node to kill itself,
|
|
324
|
+
// with all nodes concluding on their own on the same list of nodes to
|
|
325
|
+
// shut down.
|
|
326
|
+
// First remove every non existing node from topologies
|
|
327
|
+
splits = splits.map((topology) => topology.filter((nodeId) => idCards.find((card) => card.id === nodeId)));
|
|
328
|
+
splits = splits.sort((a, b) => a.length - b.length);
|
|
329
|
+
const eligibleSplits = splits.filter((split) => split.length === splits[0].length);
|
|
330
|
+
let candidates;
|
|
331
|
+
if (eligibleSplits.length === 1) {
|
|
332
|
+
candidates = eligibleSplits[0];
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
// Beware: search isolated nodes in ALL the splits, not only the
|
|
336
|
+
// smallest ones
|
|
337
|
+
let isolatedNodes = _.xor(...splits);
|
|
338
|
+
const eligibleNodes = _.uniq(_.flatten(eligibleSplits));
|
|
339
|
+
isolatedNodes = _.intersection(isolatedNodes, eligibleNodes);
|
|
340
|
+
const isIsolated = isolatedNodes.length > 0;
|
|
341
|
+
// safety measure: this should never happen
|
|
342
|
+
if (isolatedNodes.length === 0) {
|
|
343
|
+
isolatedNodes = eligibleNodes;
|
|
344
|
+
}
|
|
345
|
+
let youngestNode;
|
|
346
|
+
for (let i = 0; i < isolatedNodes.length; i++) {
|
|
347
|
+
const idCard = idCards.find((card) => card.id === isolatedNodes[i]);
|
|
348
|
+
if (!youngestNode || idCard.birthdate > youngestNode.birthdate) {
|
|
349
|
+
youngestNode = idCard;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
if (isIsolated) {
|
|
353
|
+
for (let i = 0; !candidates && i < eligibleSplits.length; i++) {
|
|
354
|
+
if (eligibleSplits[i].includes(youngestNode.id)) {
|
|
355
|
+
candidates = _.intersection(eligibleSplits[i], isolatedNodes);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
candidates = [youngestNode.id];
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
if (candidates.includes(this.nodeId)) {
|
|
364
|
+
this.logger.error("[CLUSTER] Network split detected. This node is outside the cluster: shutting down.");
|
|
365
|
+
global.kuzzle.shutdown();
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
catch (err) {
|
|
370
|
+
this.logger.error("[CLUSTER] Unexpected exception caught during a cluster consistency check. Shutting down...");
|
|
371
|
+
this.logger.error(err.stack);
|
|
372
|
+
global.kuzzle.shutdown();
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Discovers other active nodes from the cluster and, if other nodes exist,
|
|
377
|
+
* starts a handshake procedure to sync this node and to make it able to
|
|
378
|
+
* handle new client requests
|
|
379
|
+
*
|
|
380
|
+
* @return {void}
|
|
381
|
+
*/
|
|
382
|
+
async handshake() {
|
|
383
|
+
const handshakeTimeout = setTimeout(() => {
|
|
384
|
+
this.logger.error(`[CLUSTER] Failed to join the cluster: timed out (joinTimeout: ${this.config.joinTimeout}ms)`);
|
|
385
|
+
global.kuzzle.shutdown();
|
|
386
|
+
}, this.config.joinTimeout);
|
|
387
|
+
const mutex = new Mutex("clusterHandshake", {
|
|
388
|
+
timeout: this.config.joinTimeout,
|
|
389
|
+
});
|
|
390
|
+
try {
|
|
391
|
+
await mutex.lock();
|
|
392
|
+
// Create the ID Key AFTER the handshake mutex is actually locked,
|
|
393
|
+
// to prevent race conditions (other nodes attempting to connect to this
|
|
394
|
+
// node while it's still initializing)
|
|
395
|
+
await this.idCardHandler.createIdCard();
|
|
396
|
+
debug("[CLUSTER] ID Card created");
|
|
397
|
+
this.nodeId = this.idCardHandler.nodeId;
|
|
398
|
+
await this.startHeartbeat();
|
|
399
|
+
debug("[CLUSTER] Start heartbeat");
|
|
400
|
+
let retried = false;
|
|
401
|
+
let fullState = null;
|
|
402
|
+
let nodes;
|
|
403
|
+
debug("[CLUSTER] Start retrieving full state..");
|
|
404
|
+
do {
|
|
405
|
+
nodes = await this.idCardHandler.getRemoteIdCards();
|
|
406
|
+
debug("[CLUSTER] %s remote nodes discovered", nodes.length);
|
|
407
|
+
// No other nodes detected = no handshake required
|
|
408
|
+
if (nodes.length === 0) {
|
|
409
|
+
this.trackActivity(this.nodeId, this.ip, nodeActivityEnum.ADDED);
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
// Verify that no other node share the same IP address as this one
|
|
413
|
+
const duplicate = nodes.filter((node) => node.ip === this.ip);
|
|
414
|
+
if (duplicate.length > 0) {
|
|
415
|
+
this.logger.error(`[CLUSTER] Another node share the same IP address as this one (${this.ip}): ${duplicate[0].id}. Shutting down.`);
|
|
416
|
+
global.kuzzle.shutdown();
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
// Subscribe to remote nodes and start buffering sync messages
|
|
420
|
+
await Bluebird.map(nodes, ({ id, ip }) => {
|
|
421
|
+
const subscriber = new ClusterSubscriber(this, id, ip);
|
|
422
|
+
this.remoteNodes.set(id, subscriber);
|
|
423
|
+
return subscriber.init();
|
|
424
|
+
});
|
|
425
|
+
debug("[CLUSTER] Successfully subscribed to nodes");
|
|
426
|
+
fullState = await this.command.getFullState(nodes);
|
|
427
|
+
// Uh oh... no node was able to give us the full state.
|
|
428
|
+
// We must retry later, to check if the redis keys have expired. If they
|
|
429
|
+
// are still there and we still aren't able to fetch a full state, this
|
|
430
|
+
// means we're probably facing a network split, and we must then shut
|
|
431
|
+
// down.
|
|
432
|
+
if (fullState === null) {
|
|
433
|
+
if (retried) {
|
|
434
|
+
this.logger.error("[CLUSTER] Could not connect to discovered cluster nodes (network split detected). Shutting down.");
|
|
435
|
+
global.kuzzle.shutdown();
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
// Disposes all subscribers
|
|
439
|
+
for (const subscriber of this.remoteNodes.values()) {
|
|
440
|
+
subscriber.dispose();
|
|
441
|
+
}
|
|
442
|
+
this.remoteNodes.clear();
|
|
443
|
+
// Waits for a redis heartbeat round
|
|
444
|
+
retried = true;
|
|
445
|
+
const retryDelay = this.heartbeatDelay * 1.5;
|
|
446
|
+
this.logger.warn(`[CLUSTER] Unable to connect to discovered cluster nodes. Retrying in ${retryDelay}ms...`);
|
|
447
|
+
await Bluebird.delay(retryDelay);
|
|
448
|
+
}
|
|
449
|
+
} while (fullState === null);
|
|
450
|
+
debug("[CLUSTER] Fullstate retrieved, loading into node..");
|
|
451
|
+
await this.fullState.loadFullState(fullState);
|
|
452
|
+
this.activity = fullState.activity ? fullState.activity : this.activity;
|
|
453
|
+
debug("[CLUSTER] Fullstate loaded.");
|
|
454
|
+
const handshakeResponses = await this.command.broadcastHandshake(nodes);
|
|
455
|
+
debug("[CLUSTER] Successful handshakes with other nodes.");
|
|
456
|
+
// Update subscribers: start synchronizing, or unsubscribes from nodes who
|
|
457
|
+
// didn't respond
|
|
458
|
+
for (const [nodeId, handshakeData] of Object.entries(handshakeResponses)) {
|
|
459
|
+
const subscriber = this.remoteNodes.get(nodeId);
|
|
460
|
+
if (handshakeData === null) {
|
|
461
|
+
subscriber.dispose();
|
|
462
|
+
this.remoteNodes.delete(nodeId);
|
|
463
|
+
}
|
|
464
|
+
else {
|
|
465
|
+
await this.idCardHandler.addNode(nodeId);
|
|
466
|
+
const nodesStates = fullState.nodesState || [];
|
|
467
|
+
const nodeStatus = nodesStates.find((node) => node.id === nodeId);
|
|
468
|
+
subscriber.sync(nodeStatus ? nodeStatus.lastMessageId : handshakeData.lastMessageId);
|
|
469
|
+
this.logger.info(`[CLUSTER] Successfully completed the handshake with node ${nodeId}`);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
this.logger.info("[CLUSTER] Successfully joined the cluster.");
|
|
473
|
+
this.trackActivity(this.nodeId, this.ip, nodeActivityEnum.ADDED);
|
|
474
|
+
}
|
|
475
|
+
finally {
|
|
476
|
+
clearTimeout(handshakeTimeout);
|
|
477
|
+
await mutex.unlock();
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
countActiveNodes() {
|
|
481
|
+
return this.remoteNodes.size + 1;
|
|
482
|
+
}
|
|
483
|
+
startHeartbeat() {
|
|
484
|
+
this.heartbeatTimer = setInterval(() => {
|
|
485
|
+
this.publisher.sendHeartbeat(this.syncAddress);
|
|
486
|
+
}, this.heartbeatDelay);
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Cluster activity tracking
|
|
490
|
+
*
|
|
491
|
+
* @param {string} id
|
|
492
|
+
* @param {string} ip
|
|
493
|
+
* @param {nodeActivityEnum} event
|
|
494
|
+
* @param {string} [reason]
|
|
495
|
+
*/
|
|
496
|
+
trackActivity(id, ip, event, reason) {
|
|
497
|
+
if (this.activity.length > this.activityMaxLength) {
|
|
498
|
+
this.activity.shift();
|
|
499
|
+
}
|
|
500
|
+
this.activity.push({
|
|
501
|
+
address: ip,
|
|
502
|
+
date: new Date().toISOString(),
|
|
503
|
+
event,
|
|
504
|
+
id,
|
|
505
|
+
reason,
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Returns the full status of the cluster
|
|
510
|
+
* @return {Object}
|
|
511
|
+
*/
|
|
512
|
+
async getStatus() {
|
|
513
|
+
const status = {
|
|
514
|
+
activeNodes: 0,
|
|
515
|
+
activity: this.activity.map(({ address, date, event, id, reason }) => ({
|
|
516
|
+
address,
|
|
517
|
+
date,
|
|
518
|
+
event: event === nodeActivityEnum.ADDED ? "joined" : "evicted",
|
|
519
|
+
id,
|
|
520
|
+
reason,
|
|
521
|
+
})),
|
|
522
|
+
nodes: [],
|
|
523
|
+
};
|
|
524
|
+
const idCards = await this.idCardHandler.getRemoteIdCards();
|
|
525
|
+
idCards.push(this.idCardHandler.idCard);
|
|
526
|
+
for (const idCard of idCards) {
|
|
527
|
+
status.nodes.push({
|
|
528
|
+
address: idCard.ip,
|
|
529
|
+
birthdate: new Date(idCard.birthdate).toISOString(),
|
|
530
|
+
id: idCard.id,
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
status.activeNodes = status.nodes.length;
|
|
534
|
+
return status;
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Registers ask events
|
|
538
|
+
*/
|
|
539
|
+
registerAskEvents() {
|
|
540
|
+
global.kuzzle.onAsk("cluster:node:preventEviction", (state) => {
|
|
541
|
+
this.preventEviction(state);
|
|
542
|
+
});
|
|
543
|
+
/**
|
|
544
|
+
* Removes a room from the full state, and only for this node.
|
|
545
|
+
* Removes the room from Koncorde if, and only if, no other node uses it.
|
|
546
|
+
*
|
|
547
|
+
* @param {string} roomId
|
|
548
|
+
* @return {void}
|
|
549
|
+
*/
|
|
550
|
+
global.kuzzle.onAsk("cluster:realtime:room:remove", (roomId) => this.removeRealtimeRoom(roomId));
|
|
551
|
+
/**
|
|
552
|
+
* Returns the total number of subscribers on all nodes for the provided
|
|
553
|
+
* room
|
|
554
|
+
*
|
|
555
|
+
* @param {string} roomId
|
|
556
|
+
* @returns {Number}
|
|
557
|
+
*/
|
|
558
|
+
global.kuzzle.onAsk("cluster:realtime:room:count", (roomId) => this.countRealtimeSubscribers(roomId));
|
|
559
|
+
/**
|
|
560
|
+
* Returns the list of existing rooms in the cluster
|
|
561
|
+
*
|
|
562
|
+
* @returns {Object}
|
|
563
|
+
*/
|
|
564
|
+
global.kuzzle.onAsk("cluster:realtime:room:list", () => this.fullState.listRealtimeRooms());
|
|
565
|
+
/**
|
|
566
|
+
* Returns the requested room. Used to create a room on the fly on this node
|
|
567
|
+
* if it exists only on remote nodes (e.g. for the realtime:join API action)
|
|
568
|
+
*
|
|
569
|
+
* @param {string} roomId
|
|
570
|
+
* @returns {NormalizedFilter}
|
|
571
|
+
*/
|
|
572
|
+
global.kuzzle.onAsk("cluster:realtime:filters:get", (roomId) => this.fullState.getNormalizedFilters(roomId));
|
|
573
|
+
/**
|
|
574
|
+
* Broadcasts an event to other nodes
|
|
575
|
+
*
|
|
576
|
+
* @param {string} event name
|
|
577
|
+
* @param {Object} payload - event payload
|
|
578
|
+
*/
|
|
579
|
+
global.kuzzle.onAsk("cluster:event:broadcast", (event, payload) => this.broadcast(event, payload));
|
|
580
|
+
/**
|
|
581
|
+
* Listens to a cluster-wide event
|
|
582
|
+
*
|
|
583
|
+
* @param {string} event name
|
|
584
|
+
* @param {Function} fn - event listener
|
|
585
|
+
*/
|
|
586
|
+
global.kuzzle.onAsk("cluster:event:on", (event, fn) => this.eventEmitter.on(event, fn));
|
|
587
|
+
/**
|
|
588
|
+
* Listens to a cluster-wide event once.
|
|
589
|
+
*
|
|
590
|
+
* @param {string} event name
|
|
591
|
+
* @param {Function} fn - event listener
|
|
592
|
+
*/
|
|
593
|
+
global.kuzzle.onAsk("cluster:event:once", (event, fn) => this.eventEmitter.once(event, fn));
|
|
594
|
+
/**
|
|
595
|
+
* Removes a listener from an event
|
|
596
|
+
*
|
|
597
|
+
* @param {string} event name
|
|
598
|
+
* @param {Function} fn - event listener
|
|
599
|
+
*/
|
|
600
|
+
global.kuzzle.onAsk("cluster:event:off", (event, fn) => this.eventEmitter.removeListener(event, fn));
|
|
601
|
+
/**
|
|
602
|
+
* Removes all listeners from an event
|
|
603
|
+
*
|
|
604
|
+
* @param {string} event name
|
|
605
|
+
*/
|
|
606
|
+
global.kuzzle.onAsk("cluster:event:removeAllListeners", (event) => this.eventEmitter.removeAllListeners(event));
|
|
607
|
+
/**
|
|
608
|
+
* Returns the full status of the cluster
|
|
609
|
+
*/
|
|
610
|
+
global.kuzzle.onAsk("cluster:status:get", () => this.getStatus());
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Starts listening to events to trigger sync messages on state changes.
|
|
614
|
+
*
|
|
615
|
+
* @return {void}
|
|
616
|
+
*/
|
|
617
|
+
registerEvents() {
|
|
618
|
+
global.kuzzle.on("admin:afterRefreshIndexCache", () => this.onIndexCacheRefreshed());
|
|
619
|
+
global.kuzzle.onCall("core:realtime:room:create:after", (payload) => this.onNewRealtimeRoom(payload));
|
|
620
|
+
global.kuzzle.onCall("core:realtime:subscribe:after", (roomId) => this.onNewSubscription(roomId));
|
|
621
|
+
global.kuzzle.onCall("core:realtime:unsubscribe:after", (roomId) => this.onUnsubscription(roomId));
|
|
622
|
+
global.kuzzle.on("core:notify:document", ({ notification, rooms }) => {
|
|
623
|
+
this.onDocumentNotification(rooms, notification);
|
|
624
|
+
});
|
|
625
|
+
global.kuzzle.on("core:notify:user", ({ notification, room }) => this.onUserNotification(room, notification));
|
|
626
|
+
global.kuzzle.on("core:auth:strategyAdded", ({ name, pluginName, strategy }) => {
|
|
627
|
+
this.onAuthStrategyAdded(name, pluginName, strategy);
|
|
628
|
+
});
|
|
629
|
+
global.kuzzle.on("core:auth:strategyRemoved", ({ name, pluginName }) => this.onAuthStrategyRemoved(name, pluginName));
|
|
630
|
+
global.kuzzle.on("admin:afterDump", (request) => {
|
|
631
|
+
const suffix = request.getString("suffix", "manual-api-action");
|
|
632
|
+
return this.onDumpRequest(suffix);
|
|
633
|
+
});
|
|
634
|
+
global.kuzzle.on("admin:afterResetSecurity", () => this.onSecurityReset());
|
|
635
|
+
global.kuzzle.on("admin:afterShutdown", () => this.onShutdown());
|
|
636
|
+
global.kuzzle.on("collection:afterDeleteSpecifications", () => this.onValidatorsChanged());
|
|
637
|
+
global.kuzzle.on("collection:afterUpdateSpecifications", () => this.onValidatorsChanged());
|
|
638
|
+
// Profile change events
|
|
639
|
+
global.kuzzle.on("core:security:profile:create", ({ args: [profileId] }) => this.onProfileChanged(profileId));
|
|
640
|
+
global.kuzzle.on("core:security:profile:createOrReplace", ({ args: [profileId] }) => this.onProfileChanged(profileId));
|
|
641
|
+
global.kuzzle.on("core:security:profile:update", ({ args: [profileId] }) => this.onProfileChanged(profileId));
|
|
642
|
+
global.kuzzle.on("core:security:profile:delete", ({ args: [profileId] }) => this.onProfileChanged(profileId));
|
|
643
|
+
// Role change events
|
|
644
|
+
global.kuzzle.on("core:security:role:create", ({ args: [roleId] }) => this.onRoleChanged(roleId));
|
|
645
|
+
global.kuzzle.on("core:security:role:createOrReplace", ({ args: [roleId] }) => this.onRoleChanged(roleId));
|
|
646
|
+
global.kuzzle.on("core:security:role:update", ({ args: [roleId] }) => this.onRoleChanged(roleId));
|
|
647
|
+
global.kuzzle.on("core:security:role:delete", ({ args: [roleId] }) => this.onRoleChanged(roleId));
|
|
648
|
+
// Index cache change events
|
|
649
|
+
global.kuzzle.on("core:storage:index:create:after", ({ index, scope }) => this.onIndexAdded(scope, index));
|
|
650
|
+
global.kuzzle.on("core:storage:index:delete:after", ({ index, scope }) => this.onIndexesRemoved(scope, [index]));
|
|
651
|
+
global.kuzzle.on("core:storage:index:mDelete:after", ({ indexes, scope }) => this.onIndexesRemoved(scope, indexes));
|
|
652
|
+
global.kuzzle.on("core:storage:collection:create:after", ({ collection, index, scope }) => {
|
|
653
|
+
this.onCollectionAdded(scope, index, collection);
|
|
654
|
+
});
|
|
655
|
+
global.kuzzle.on("core:storage:collection:delete:after", ({ collection, index, scope }) => {
|
|
656
|
+
this.onCollectionRemoved(scope, index, collection);
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* Triggered whenever a realtime room is created on this node
|
|
661
|
+
*
|
|
662
|
+
* @param {NormalizedFilter} payload
|
|
663
|
+
* @return {void}
|
|
664
|
+
*/
|
|
665
|
+
onNewRealtimeRoom(payload) {
|
|
666
|
+
const roomMessageId = this.publisher.sendNewRealtimeRoom(payload);
|
|
667
|
+
debug("[%s] Broadcasting new realtime room %s (message: %d)", this.nodeId, payload.id, roomMessageId);
|
|
668
|
+
const icpair = fromKoncordeIndex(payload.index);
|
|
669
|
+
this.fullState.addRealtimeRoom(payload.id, icpair.index, icpair.collection, payload.filter, {
|
|
670
|
+
messageId: roomMessageId,
|
|
671
|
+
nodeId: this.nodeId,
|
|
672
|
+
subscribers: 0,
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Triggered on a new realtime subscription
|
|
677
|
+
*
|
|
678
|
+
* @param {string} roomId
|
|
679
|
+
* @return {void}
|
|
680
|
+
*/
|
|
681
|
+
onNewSubscription(roomId) {
|
|
682
|
+
const subMessageId = this.publisher.sendSubscription(roomId);
|
|
683
|
+
debug("[%s] Broadcasting new realtime subscription on room %s (message: %d)", this.nodeId, roomId, subMessageId);
|
|
684
|
+
this.fullState.addRealtimeSubscription(roomId, this.nodeId, subMessageId);
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* Triggered when a realtime room is removed from this node.
|
|
688
|
+
*
|
|
689
|
+
* @param {string} roomId
|
|
690
|
+
* @return {void}
|
|
691
|
+
*/
|
|
692
|
+
removeRealtimeRoom(roomId) {
|
|
693
|
+
const messageId = this.publisher.sendRemoveRealtimeRoom(roomId);
|
|
694
|
+
debug("[%s] Broadcasted the removal of room %s (message: %d)", this.nodeId, roomId, messageId);
|
|
695
|
+
this.fullState.removeRealtimeRoom(roomId, this.nodeId);
|
|
696
|
+
}
|
|
697
|
+
/**
|
|
698
|
+
* Broadcasts an event to other nodes
|
|
699
|
+
*
|
|
700
|
+
* @param {string} event name
|
|
701
|
+
* @param {Object} payload - event payload
|
|
702
|
+
*/
|
|
703
|
+
broadcast(event, payload) {
|
|
704
|
+
const messageId = this.publisher.sendClusterWideEvent(event, payload);
|
|
705
|
+
debug('[%s] Emitted cluster-wide event "%s" (message: %d)', this.nodeId, event, messageId);
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* Triggered when a user unsubscribes from a room
|
|
709
|
+
*
|
|
710
|
+
* @param {string} roomId
|
|
711
|
+
* @return {void}
|
|
712
|
+
*/
|
|
713
|
+
onUnsubscription(roomId) {
|
|
714
|
+
const messageId = this.publisher.sendUnsubscription(roomId);
|
|
715
|
+
debug("[%s] Broadcasting realtime unsubscription on room %s (message: %d)", this.nodeId, roomId, messageId);
|
|
716
|
+
this.fullState.removeRealtimeSubscription(roomId, this.nodeId, messageId);
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Triggered when a document notification must be propagated
|
|
720
|
+
*
|
|
721
|
+
* @param {Array.<string>} rooms - list of rooms to notify
|
|
722
|
+
* @param {DocumentNotification} notification
|
|
723
|
+
* @return {void}
|
|
724
|
+
*/
|
|
725
|
+
onDocumentNotification(rooms, notification) {
|
|
726
|
+
this.publisher.sendDocumentNotification(rooms, notification);
|
|
727
|
+
}
|
|
728
|
+
/**
|
|
729
|
+
* Triggered when a user notification must be propagated
|
|
730
|
+
*
|
|
731
|
+
* @param {string} room
|
|
732
|
+
* @param {UserNotification} notification
|
|
733
|
+
* @return {void}
|
|
734
|
+
*/
|
|
735
|
+
onUserNotification(room, notification) {
|
|
736
|
+
this.publisher.sendUserNotification(room, notification);
|
|
737
|
+
}
|
|
738
|
+
/**
|
|
739
|
+
* Triggered when a new authentication strategy has been dynamically added
|
|
740
|
+
*
|
|
741
|
+
* @param {string} strategyName
|
|
742
|
+
* @param {string} pluginName
|
|
743
|
+
* @param {Object} strategyObject
|
|
744
|
+
* @return {void}
|
|
745
|
+
*/
|
|
746
|
+
onAuthStrategyAdded(strategyName, pluginName, strategyObject) {
|
|
747
|
+
this.publisher.sendNewAuthStrategy(strategyName, pluginName, strategyObject);
|
|
748
|
+
this.fullState.addAuthStrategy({
|
|
749
|
+
pluginName,
|
|
750
|
+
strategy: strategyObject,
|
|
751
|
+
strategyName,
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
/**
|
|
755
|
+
* Triggered when an authentication strategy has been dynamically removed
|
|
756
|
+
*
|
|
757
|
+
* @param {string} strategyName
|
|
758
|
+
* @param {string} pluginName
|
|
759
|
+
* @return {void}
|
|
760
|
+
*/
|
|
761
|
+
onAuthStrategyRemoved(strategyName, pluginName) {
|
|
762
|
+
this.publisher.sendRemoveAuthStrategy(strategyName, pluginName);
|
|
763
|
+
this.fullState.removeAuthStrategy(strategyName);
|
|
764
|
+
}
|
|
765
|
+
/**
|
|
766
|
+
* Triggered when a dump has been requested
|
|
767
|
+
*
|
|
768
|
+
* @param {string} suffix
|
|
769
|
+
* @return {void}
|
|
770
|
+
*/
|
|
771
|
+
onDumpRequest(suffix) {
|
|
772
|
+
this.publisher.sendDumpRequest(suffix);
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* Triggered when security rights have been reset
|
|
776
|
+
*
|
|
777
|
+
* @return {void}
|
|
778
|
+
*/
|
|
779
|
+
onSecurityReset() {
|
|
780
|
+
this.publisher.send("ResetSecurity", {});
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* Triggered when a document validator has changed
|
|
784
|
+
*
|
|
785
|
+
* @return {void}
|
|
786
|
+
*/
|
|
787
|
+
onValidatorsChanged() {
|
|
788
|
+
this.publisher.send("RefreshValidators", {});
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
* Triggered when a profile has changed
|
|
792
|
+
*
|
|
793
|
+
* @param {string} profileId
|
|
794
|
+
* @return {void}
|
|
795
|
+
*/
|
|
796
|
+
onProfileChanged(profileId) {
|
|
797
|
+
this.publisher.send("InvalidateProfile", { profileId });
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* Triggered when a role has changed
|
|
801
|
+
*
|
|
802
|
+
* @param {string} roleId
|
|
803
|
+
* @return {void}
|
|
804
|
+
*/
|
|
805
|
+
onRoleChanged(roleId) {
|
|
806
|
+
this.publisher.send("InvalidateRole", { roleId });
|
|
807
|
+
}
|
|
808
|
+
/**
|
|
809
|
+
* Triggered when an index has been added to the index cache
|
|
810
|
+
*
|
|
811
|
+
* @param {storeScopeEnum} scope
|
|
812
|
+
* @param {string} index
|
|
813
|
+
* @return {void}
|
|
814
|
+
*/
|
|
815
|
+
onIndexAdded(scope, index) {
|
|
816
|
+
this.publisher.sendAddIndex(scope, index);
|
|
817
|
+
}
|
|
818
|
+
/**
|
|
819
|
+
* Triggered when a collection has been added to the index cache
|
|
820
|
+
*
|
|
821
|
+
* @param {storeScopeEnum} scope
|
|
822
|
+
* @param {string} index
|
|
823
|
+
* @param {string} collection
|
|
824
|
+
* @return {void}
|
|
825
|
+
*/
|
|
826
|
+
onCollectionAdded(scope, index, collection) {
|
|
827
|
+
this.publisher.sendAddCollection(scope, index, collection);
|
|
828
|
+
}
|
|
829
|
+
/**
|
|
830
|
+
* Triggered when index have been removed from the index cache
|
|
831
|
+
*
|
|
832
|
+
* @param {storeScopeEnum} scope
|
|
833
|
+
* @param {Array.<string>} indexes
|
|
834
|
+
* @return {void}
|
|
835
|
+
*/
|
|
836
|
+
onIndexesRemoved(scope, indexes) {
|
|
837
|
+
this.publisher.sendRemoveIndexes(scope, indexes);
|
|
838
|
+
}
|
|
839
|
+
/**
|
|
840
|
+
* Triggered when a collection has been removed from the index cache
|
|
841
|
+
*
|
|
842
|
+
* @param {storeScopeEnum} scope
|
|
843
|
+
* @param {string} index
|
|
844
|
+
* @param {string} collection
|
|
845
|
+
* @return {void}
|
|
846
|
+
*/
|
|
847
|
+
onCollectionRemoved(scope, index, collection) {
|
|
848
|
+
this.publisher.sendRemoveCollection(scope, index, collection);
|
|
849
|
+
}
|
|
850
|
+
/**
|
|
851
|
+
* Triggered when a cluster-wide shutdown has been initiated
|
|
852
|
+
*
|
|
853
|
+
* @return {void}
|
|
854
|
+
*/
|
|
855
|
+
onShutdown() {
|
|
856
|
+
this.publisher.send("Shutdown", {});
|
|
857
|
+
}
|
|
858
|
+
/**
|
|
859
|
+
* Triggered when the index cache has been manually refreshed
|
|
860
|
+
*/
|
|
861
|
+
onIndexCacheRefreshed() {
|
|
862
|
+
this.publisher.send("RefreshIndexCache", {});
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* Returns the total number of subscribers on the cluster for the provided
|
|
866
|
+
* room
|
|
867
|
+
*
|
|
868
|
+
* @param {string} roomId
|
|
869
|
+
* @return {void}
|
|
870
|
+
*/
|
|
871
|
+
async countRealtimeSubscribers(roomId) {
|
|
872
|
+
return this.fullState.countRealtimeSubscriptions(roomId);
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
module.exports = ClusterNode;
|
|
876
|
+
//# sourceMappingURL=node.js.map
|