kuzzle 2.19.2 → 2.19.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/lib/api/controllers/adminController.js +94 -80
- package/lib/api/controllers/authController.js +239 -212
- package/lib/api/controllers/baseController.js +89 -51
- package/lib/api/controllers/bulkController.js +62 -49
- package/lib/api/controllers/clusterController.js +6 -8
- package/lib/api/controllers/collectionController.js +140 -129
- package/lib/api/controllers/debugController.d.ts +2 -2
- package/lib/api/controllers/debugController.js +33 -31
- package/lib/api/controllers/documentController.js +365 -274
- package/lib/api/controllers/index.js +13 -13
- package/lib/api/controllers/indexController.js +46 -50
- package/lib/api/controllers/memoryStorageController.js +410 -360
- package/lib/api/controllers/realtimeController.js +37 -36
- package/lib/api/controllers/securityController.js +553 -412
- package/lib/api/controllers/serverController.js +111 -104
- package/lib/api/documentExtractor.js +75 -68
- package/lib/api/funnel.js +411 -312
- package/lib/api/httpRoutes.js +1493 -324
- package/lib/api/openapi/OpenApiManager.d.ts +1 -1
- package/lib/api/openapi/OpenApiManager.js +22 -22
- package/lib/api/openapi/components/document/count.yaml +1 -1
- package/lib/api/openapi/components/document/create.yaml +2 -2
- package/lib/api/openapi/components/document/delete.yaml +1 -1
- package/lib/api/openapi/components/document/deleteByQuery.yaml +1 -1
- package/lib/api/openapi/components/document/exists.yaml +1 -1
- package/lib/api/openapi/components/document/get.yaml +2 -2
- package/lib/api/openapi/components/document/index.js +12 -12
- package/lib/api/openapi/components/document/replace.yaml +1 -1
- package/lib/api/openapi/components/document/scroll.yaml +1 -1
- package/lib/api/openapi/components/document/validate.yaml +1 -1
- package/lib/api/openapi/components/index.d.ts +2 -2
- package/lib/api/openapi/components/index.js +1 -1
- package/lib/api/openapi/components/security/index.js +1 -1
- package/lib/api/openapi/components/security/upsertUser.yaml +2 -3
- package/lib/api/openapi/index.d.ts +1 -1
- package/lib/api/openapi/openApiGenerator.d.ts +1 -1
- package/lib/api/openapi/openApiGenerator.js +7 -7
- package/lib/api/rateLimiter.js +12 -13
- package/lib/api/request/index.d.ts +4 -4
- package/lib/api/request/kuzzleRequest.d.ts +9 -9
- package/lib/api/request/kuzzleRequest.js +89 -87
- package/lib/api/request/requestContext.d.ts +2 -2
- package/lib/api/request/requestContext.js +17 -17
- package/lib/api/request/requestInput.d.ts +1 -1
- package/lib/api/request/requestInput.js +19 -19
- package/lib/api/request/requestResponse.d.ts +4 -4
- package/lib/api/request/requestResponse.js +31 -33
- package/lib/cluster/command.js +48 -44
- package/lib/cluster/idCardHandler.d.ts +1 -1
- package/lib/cluster/idCardHandler.js +15 -15
- package/lib/cluster/index.js +2 -2
- package/lib/cluster/node.js +301 -269
- package/lib/cluster/publisher.js +45 -46
- package/lib/cluster/state.d.ts +5 -5
- package/lib/cluster/state.js +8 -8
- package/lib/cluster/subscriber.js +163 -113
- package/lib/cluster/workers/IDCardRenewer.js +33 -32
- package/lib/config/default.config.d.ts +1 -1
- package/lib/config/default.config.js +212 -171
- package/lib/config/documentEventAliases.js +6 -6
- package/lib/config/index.js +161 -98
- package/lib/config/sdkCompatibility.json +8 -8
- package/lib/core/auth/formatProcessing.js +7 -7
- package/lib/core/auth/passportResponse.js +7 -7
- package/lib/core/auth/passportWrapper.js +34 -30
- package/lib/core/auth/tokenManager.d.ts +2 -2
- package/lib/core/auth/tokenManager.js +11 -10
- package/lib/core/backend/applicationManager.d.ts +1 -1
- package/lib/core/backend/applicationManager.js +2 -2
- package/lib/core/backend/backend.d.ts +3 -3
- package/lib/core/backend/backend.js +34 -31
- package/lib/core/backend/backendCluster.d.ts +2 -2
- package/lib/core/backend/backendCluster.js +5 -5
- package/lib/core/backend/backendConfig.d.ts +2 -2
- package/lib/core/backend/backendConfig.js +3 -3
- package/lib/core/backend/backendController.d.ts +2 -2
- package/lib/core/backend/backendController.js +9 -10
- package/lib/core/backend/backendErrors.d.ts +3 -3
- package/lib/core/backend/backendErrors.js +2 -1
- package/lib/core/backend/backendHook.d.ts +2 -2
- package/lib/core/backend/backendHook.js +5 -5
- package/lib/core/backend/backendImport.d.ts +3 -3
- package/lib/core/backend/backendImport.js +23 -23
- package/lib/core/backend/backendOpenApi.d.ts +2 -2
- package/lib/core/backend/backendOpenApi.js +16 -16
- package/lib/core/backend/backendPipe.d.ts +2 -2
- package/lib/core/backend/backendPipe.js +6 -6
- package/lib/core/backend/backendPlugin.d.ts +4 -4
- package/lib/core/backend/backendPlugin.js +14 -14
- package/lib/core/backend/backendStorage.d.ts +2 -2
- package/lib/core/backend/backendStorage.js +1 -2
- package/lib/core/backend/backendVault.d.ts +2 -2
- package/lib/core/backend/backendVault.js +3 -3
- package/lib/core/backend/index.d.ts +14 -14
- package/lib/core/backend/internalLogger.d.ts +1 -1
- package/lib/core/backend/internalLogger.js +5 -5
- package/lib/core/cache/cacheDbEnum.js +4 -4
- package/lib/core/cache/cacheEngine.js +79 -85
- package/lib/core/network/accessLogger.js +126 -120
- package/lib/core/network/clientConnection.js +5 -5
- package/lib/core/network/context.js +8 -8
- package/lib/core/network/entryPoint.js +100 -85
- package/lib/core/network/httpRouter/index.js +63 -60
- package/lib/core/network/httpRouter/routeHandler.js +18 -19
- package/lib/core/network/httpRouter/routePart.js +23 -19
- package/lib/core/network/protocolManifest.js +3 -3
- package/lib/core/network/protocols/httpMessage.js +8 -10
- package/lib/core/network/protocols/httpwsProtocol.js +305 -250
- package/lib/core/network/protocols/internalProtocol.js +27 -24
- package/lib/core/network/protocols/mqttProtocol.js +106 -96
- package/lib/core/network/protocols/protocol.js +20 -17
- package/lib/core/network/router.js +56 -46
- package/lib/core/plugin/plugin.js +151 -120
- package/lib/core/plugin/pluginContext.d.ts +7 -7
- package/lib/core/plugin/pluginContext.js +48 -44
- package/lib/core/plugin/pluginManifest.js +13 -12
- package/lib/core/plugin/pluginRepository.js +26 -27
- package/lib/core/plugin/pluginsManager.js +425 -304
- package/lib/core/plugin/privilegedContext.js +3 -3
- package/lib/core/realtime/actionEnum.js +1 -1
- package/lib/core/realtime/channel.d.ts +1 -1
- package/lib/core/realtime/channel.js +22 -22
- package/lib/core/realtime/connectionRooms.d.ts +1 -1
- package/lib/core/realtime/hotelClerk.d.ts +2 -2
- package/lib/core/realtime/hotelClerk.js +53 -50
- package/lib/core/realtime/index.js +5 -5
- package/lib/core/realtime/notification/document.js +25 -25
- package/lib/core/realtime/notification/index.js +4 -4
- package/lib/core/realtime/notification/server.js +3 -3
- package/lib/core/realtime/notification/user.js +4 -4
- package/lib/core/realtime/notifier.js +113 -75
- package/lib/core/realtime/room.d.ts +1 -1
- package/lib/core/realtime/subscription.d.ts +1 -1
- package/lib/core/realtime/subscription.js +1 -1
- package/lib/core/security/index.js +8 -8
- package/lib/core/security/profileRepository.d.ts +6 -6
- package/lib/core/security/profileRepository.js +48 -45
- package/lib/core/security/roleRepository.js +127 -115
- package/lib/core/security/securityLoader.js +70 -63
- package/lib/core/security/tokenRepository.js +132 -118
- package/lib/core/security/userRepository.js +104 -88
- package/lib/core/shared/KoncordeWrapper.d.ts +1 -1
- package/lib/core/shared/KoncordeWrapper.js +3 -1
- package/lib/core/shared/abstractManifest.js +22 -23
- package/lib/core/shared/repository.js +69 -67
- package/lib/core/shared/sdk/embeddedSdk.d.ts +2 -2
- package/lib/core/shared/sdk/embeddedSdk.js +36 -32
- package/lib/core/shared/sdk/funnelProtocol.d.ts +1 -1
- package/lib/core/shared/sdk/funnelProtocol.js +11 -11
- package/lib/core/shared/sdk/impersonatedSdk.js +19 -18
- package/lib/core/shared/store.js +127 -32
- package/lib/core/statistics/index.js +2 -2
- package/lib/core/statistics/statistics.js +99 -85
- package/lib/core/storage/clientAdapter.js +219 -136
- package/lib/core/storage/indexCache.js +3 -3
- package/lib/core/storage/storageEngine.js +10 -13
- package/lib/core/storage/storeScopeEnum.js +3 -3
- package/lib/core/validation/baseType.js +12 -10
- package/lib/core/validation/index.js +2 -2
- package/lib/core/validation/types/anything.js +4 -4
- package/lib/core/validation/types/boolean.js +7 -7
- package/lib/core/validation/types/date.js +165 -131
- package/lib/core/validation/types/email.js +18 -21
- package/lib/core/validation/types/enum.js +34 -21
- package/lib/core/validation/types/geoPoint.js +7 -7
- package/lib/core/validation/types/geoShape.js +148 -125
- package/lib/core/validation/types/integer.js +9 -9
- package/lib/core/validation/types/ipAddress.js +17 -19
- package/lib/core/validation/types/numeric.js +36 -29
- package/lib/core/validation/types/object.js +19 -19
- package/lib/core/validation/types/string.js +36 -29
- package/lib/core/validation/types/url.js +17 -19
- package/lib/core/validation/validation.js +422 -378
- package/lib/kerror/codes/1-services.json +7 -1
- package/lib/kerror/codes/4-plugin.json +2 -2
- package/lib/kerror/codes/index.js +85 -63
- package/lib/kerror/errors/badRequestError.d.ts +1 -1
- package/lib/kerror/errors/externalServiceError.d.ts +1 -1
- package/lib/kerror/errors/forbiddenError.d.ts +1 -1
- package/lib/kerror/errors/gatewayTimeoutError.d.ts +1 -1
- package/lib/kerror/errors/index.d.ts +15 -15
- package/lib/kerror/errors/internalError.d.ts +1 -1
- package/lib/kerror/errors/kuzzleError.d.ts +1 -1
- package/lib/kerror/errors/multipleErrorsError.d.ts +1 -1
- package/lib/kerror/errors/multipleErrorsError.js +1 -1
- package/lib/kerror/errors/notFoundError.d.ts +1 -1
- package/lib/kerror/errors/partialError.d.ts +1 -1
- package/lib/kerror/errors/partialError.js +1 -1
- package/lib/kerror/errors/pluginImplementationError.d.ts +1 -1
- package/lib/kerror/errors/pluginImplementationError.js +2 -1
- package/lib/kerror/errors/preconditionError.d.ts +1 -1
- package/lib/kerror/errors/serviceUnavailableError.d.ts +1 -1
- package/lib/kerror/errors/sizeLimitError.d.ts +1 -1
- package/lib/kerror/errors/tooManyRequestsError.d.ts +1 -1
- package/lib/kerror/errors/unauthorizedError.d.ts +1 -1
- package/lib/kerror/index.d.ts +3 -3
- package/lib/kerror/index.js +17 -16
- package/lib/kuzzle/dumpGenerator.js +130 -114
- package/lib/kuzzle/event/kuzzleEventEmitter.js +96 -70
- package/lib/kuzzle/event/pipeRunner.js +25 -24
- package/lib/kuzzle/event/waterfall.js +13 -15
- package/lib/kuzzle/index.js +2 -2
- package/lib/kuzzle/internalIndexHandler.js +80 -59
- package/lib/kuzzle/kuzzle.js +99 -99
- package/lib/kuzzle/kuzzleStateEnum.js +1 -1
- package/lib/kuzzle/log.js +23 -18
- package/lib/kuzzle/vault.js +34 -19
- package/lib/model/security/profile.d.ts +3 -3
- package/lib/model/security/profile.js +38 -37
- package/lib/model/security/rights.js +5 -5
- package/lib/model/security/role.d.ts +3 -3
- package/lib/model/security/role.js +25 -26
- package/lib/model/security/token.d.ts +1 -1
- package/lib/model/security/token.js +4 -4
- package/lib/model/security/user.d.ts +2 -2
- package/lib/model/security/user.js +9 -9
- package/lib/model/storage/apiKey.js +43 -33
- package/lib/model/storage/baseModel.js +49 -45
- package/lib/service/cache/redis.js +60 -55
- package/lib/service/service.js +17 -17
- package/lib/service/storage/elasticsearch.js +839 -755
- package/lib/service/storage/esWrapper.js +103 -86
- package/lib/service/storage/queryTranslator.js +52 -59
- package/lib/types/Controller.d.ts +3 -3
- package/lib/types/ControllerDefinition.d.ts +3 -3
- package/lib/types/DebugModule.d.ts +2 -2
- package/lib/types/DebugModule.js +1 -1
- package/lib/types/Global.d.ts +1 -1
- package/lib/types/HttpStream.d.ts +2 -1
- package/lib/types/HttpStream.js +7 -5
- package/lib/types/Kuzzle.d.ts +1 -1
- package/lib/types/KuzzleDocument.d.ts +1 -1
- package/lib/types/OpenApiDefinition.d.ts +1 -1
- package/lib/types/PasswordPolicy.d.ts +1 -1
- package/lib/types/Plugin.d.ts +6 -6
- package/lib/types/Plugin.js +2 -2
- package/lib/types/Policy.d.ts +1 -1
- package/lib/types/RequestPayload.d.ts +1 -1
- package/lib/types/ResponsePayload.d.ts +1 -1
- package/lib/types/Token.d.ts +1 -1
- package/lib/types/User.d.ts +1 -1
- package/lib/types/config/DumpConfiguration.d.ts +8 -8
- package/lib/types/config/HttpConfiguration.d.ts +1 -1
- package/lib/types/config/KuzzleConfiguration.d.ts +1 -1
- package/lib/types/config/LimitsConfiguration.d.ts +8 -8
- package/lib/types/config/PluginsConfiguration.d.ts +4 -4
- package/lib/types/config/SecurityConfiguration.d.ts +62 -62
- package/lib/types/config/ServerConfiguration.d.ts +55 -55
- package/lib/types/config/ServicesConfiguration.d.ts +2 -2
- package/lib/types/config/internalCache/InternalCacheRedisConfiguration.d.ts +10 -10
- package/lib/types/config/publicCache/PublicCacheRedisConfiguration.d.ts +3 -3
- package/lib/types/config/storageEngine/StorageEngineElasticsearchConfiguration.d.ts +194 -110
- package/lib/types/errors/ErrorDefinition.d.ts +1 -1
- package/lib/types/errors/ErrorDomains.d.ts +1 -1
- package/lib/types/index.d.ts +38 -38
- package/lib/types/realtime/RealtimeScope.d.ts +1 -1
- package/lib/types/realtime/RealtimeUsers.d.ts +1 -1
- package/lib/util/assertType.js +13 -11
- package/lib/util/async.d.ts +1 -0
- package/lib/util/async.js +61 -0
- package/lib/util/asyncStore.js +19 -21
- package/lib/util/bufferedPassThrough.d.ts +2 -2
- package/lib/util/bufferedPassThrough.js +4 -4
- package/lib/util/bytes.js +9 -13
- package/lib/util/crypto.js +1 -1
- package/lib/util/debug.js +5 -5
- package/lib/util/deprecate.js +24 -21
- package/lib/util/didYouMean.js +7 -7
- package/lib/util/dump-collection.d.ts +2 -2
- package/lib/util/dump-collection.js +26 -26
- package/lib/util/esRequest.d.ts +1 -0
- package/lib/util/esRequest.js +62 -0
- package/lib/util/extractFields.js +24 -25
- package/lib/util/inflector.js +5 -5
- package/lib/util/koncordeCompat.d.ts +2 -2
- package/lib/util/koncordeCompat.js +5 -5
- package/lib/util/memoize.js +3 -5
- package/lib/util/mutex.d.ts +19 -1
- package/lib/util/mutex.js +39 -12
- package/lib/util/name-generator.js +1331 -1331
- package/lib/util/promback.js +8 -10
- package/lib/util/readYamlFile.d.ts +1 -1
- package/lib/util/readYamlFile.js +1 -1
- package/lib/util/requestAssertions.js +34 -34
- package/lib/util/safeObject.js +5 -5
- package/lib/util/stackTrace.js +20 -22
- package/lib/util/wildcard.js +15 -15
- package/package.json +6 -6
- package/npm-shrinkwrap.json +0 -19422
|
@@ -48,20 +48,20 @@ const internalError_1 = require("../../kerror/errors/internalError");
|
|
|
48
48
|
const assert = __importStar(require("../../util/assertType"));
|
|
49
49
|
// private properties
|
|
50
50
|
// \u200b is a zero width space, used to masquerade console.log output
|
|
51
|
-
const _jwt =
|
|
52
|
-
const _volatile =
|
|
53
|
-
const _body =
|
|
54
|
-
const _headers =
|
|
55
|
-
const _controller =
|
|
56
|
-
const _action =
|
|
51
|
+
const _jwt = "jwt\u200b";
|
|
52
|
+
const _volatile = "volatile\u200b";
|
|
53
|
+
const _body = "body\u200b";
|
|
54
|
+
const _headers = "headers\u200b";
|
|
55
|
+
const _controller = "controller\u200b";
|
|
56
|
+
const _action = "action\u200b";
|
|
57
57
|
// any property not listed here will be copied into
|
|
58
58
|
// RequestInput.args
|
|
59
59
|
const resourceProperties = new Set([
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
"jwt",
|
|
61
|
+
"volatile",
|
|
62
|
+
"body",
|
|
63
|
+
"controller",
|
|
64
|
+
"action",
|
|
65
65
|
]);
|
|
66
66
|
/**
|
|
67
67
|
* @deprecated
|
|
@@ -118,8 +118,8 @@ class RequestInput {
|
|
|
118
118
|
* Any undefined option is set to null
|
|
119
119
|
*/
|
|
120
120
|
constructor(data) {
|
|
121
|
-
if (!data || typeof data !==
|
|
122
|
-
throw new internalError_1.InternalError(
|
|
121
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
122
|
+
throw new internalError_1.InternalError("Input request data must be a non-null object");
|
|
123
123
|
}
|
|
124
124
|
this[_jwt] = null;
|
|
125
125
|
this[_volatile] = null;
|
|
@@ -169,7 +169,7 @@ class RequestInput {
|
|
|
169
169
|
return this[_jwt];
|
|
170
170
|
}
|
|
171
171
|
set jwt(str) {
|
|
172
|
-
this[_jwt] = assert.assertString(
|
|
172
|
+
this[_jwt] = assert.assertString("jwt", str);
|
|
173
173
|
}
|
|
174
174
|
/**
|
|
175
175
|
* API controller name.
|
|
@@ -194,7 +194,7 @@ class RequestInput {
|
|
|
194
194
|
set controller(str) {
|
|
195
195
|
// can only be set once
|
|
196
196
|
if (!this[_controller]) {
|
|
197
|
-
this[_controller] = assert.assertString(
|
|
197
|
+
this[_controller] = assert.assertString("controller", str);
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
/**
|
|
@@ -220,7 +220,7 @@ class RequestInput {
|
|
|
220
220
|
set action(str) {
|
|
221
221
|
// can only be set once
|
|
222
222
|
if (!this[_action]) {
|
|
223
|
-
this[_action] = assert.assertString(
|
|
223
|
+
this[_action] = assert.assertString("action", str);
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
226
|
/**
|
|
@@ -245,7 +245,7 @@ class RequestInput {
|
|
|
245
245
|
return this[_body];
|
|
246
246
|
}
|
|
247
247
|
set body(obj) {
|
|
248
|
-
this[_body] = assert.assertObject(
|
|
248
|
+
this[_body] = assert.assertObject("body", obj);
|
|
249
249
|
}
|
|
250
250
|
/**
|
|
251
251
|
* Request headers (Http only).
|
|
@@ -256,7 +256,7 @@ class RequestInput {
|
|
|
256
256
|
return this[_headers];
|
|
257
257
|
}
|
|
258
258
|
set headers(obj) {
|
|
259
|
-
this[_headers] = assert.assertObject(
|
|
259
|
+
this[_headers] = assert.assertObject("headers", obj);
|
|
260
260
|
}
|
|
261
261
|
/**
|
|
262
262
|
* Volatile object.
|
|
@@ -279,7 +279,7 @@ class RequestInput {
|
|
|
279
279
|
return this[_volatile];
|
|
280
280
|
}
|
|
281
281
|
set volatile(obj) {
|
|
282
|
-
this[_volatile] = assert.assertObject(
|
|
282
|
+
this[_volatile] = assert.assertObject("volatile", obj);
|
|
283
283
|
}
|
|
284
284
|
}
|
|
285
285
|
exports.RequestInput = RequestInput;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { JSONObject } from
|
|
2
|
-
import { Deprecation } from
|
|
3
|
-
import { KuzzleError } from
|
|
1
|
+
import { JSONObject } from "kuzzle-sdk";
|
|
2
|
+
import { Deprecation } from "../../types";
|
|
3
|
+
import { KuzzleError } from "../../kerror/errors/kuzzleError";
|
|
4
4
|
export declare class Headers {
|
|
5
5
|
headers: JSONObject;
|
|
6
6
|
private namesMap;
|
|
@@ -94,7 +94,7 @@ export declare class RequestResponse {
|
|
|
94
94
|
configure(options?: {
|
|
95
95
|
headers?: JSONObject;
|
|
96
96
|
status?: number;
|
|
97
|
-
format?:
|
|
97
|
+
format?: "standard" | "raw";
|
|
98
98
|
}): void;
|
|
99
99
|
/**
|
|
100
100
|
* Gets a header value (case-insensitive)
|
|
@@ -47,13 +47,11 @@ exports.RequestResponse = exports.Headers = void 0;
|
|
|
47
47
|
const assert = __importStar(require("../../util/assertType"));
|
|
48
48
|
// private properties
|
|
49
49
|
// \u200b is a zero width space, used to masquerade console.log output
|
|
50
|
-
const _request =
|
|
51
|
-
const _headers =
|
|
52
|
-
const _userHeaders =
|
|
50
|
+
const _request = "request\u200b";
|
|
51
|
+
const _headers = "headers\u200b";
|
|
52
|
+
const _userHeaders = "userHeaders\u200b"; // List of headers to be sent in the response
|
|
53
53
|
// List of headers that should not be present in the body of the response
|
|
54
|
-
const restrictedHeaders = [
|
|
55
|
-
'set-cookie',
|
|
56
|
-
];
|
|
54
|
+
const restrictedHeaders = ["set-cookie"];
|
|
57
55
|
class Headers {
|
|
58
56
|
constructor() {
|
|
59
57
|
this.namesMap = new Map();
|
|
@@ -63,7 +61,7 @@ class Headers {
|
|
|
63
61
|
get: (target, name) => this.getHeader(name),
|
|
64
62
|
set: (target, name, value) => this.setHeader(name, value),
|
|
65
63
|
});
|
|
66
|
-
this.setHeader(
|
|
64
|
+
this.setHeader("X-Kuzzle-Node", global.kuzzle.id);
|
|
67
65
|
}
|
|
68
66
|
/**
|
|
69
67
|
* Gets a header value
|
|
@@ -71,17 +69,17 @@ class Headers {
|
|
|
71
69
|
* @param name Header name. Could be a string (case-insensitive) or a symbol
|
|
72
70
|
*/
|
|
73
71
|
getHeader(name) {
|
|
74
|
-
if (typeof name ===
|
|
72
|
+
if (typeof name === "symbol") {
|
|
75
73
|
return this.headers[name];
|
|
76
74
|
}
|
|
77
|
-
assert.assertString(
|
|
75
|
+
assert.assertString("header name", name);
|
|
78
76
|
if (!name) {
|
|
79
77
|
return;
|
|
80
78
|
}
|
|
81
79
|
return this.headers[this.namesMap.get(name.toLowerCase())];
|
|
82
80
|
}
|
|
83
81
|
removeHeader(name) {
|
|
84
|
-
assert.assertString(
|
|
82
|
+
assert.assertString("header name", name);
|
|
85
83
|
if (!name) {
|
|
86
84
|
return true;
|
|
87
85
|
}
|
|
@@ -94,7 +92,7 @@ class Headers {
|
|
|
94
92
|
return true;
|
|
95
93
|
}
|
|
96
94
|
setHeader(name, value) {
|
|
97
|
-
assert.assertString(
|
|
95
|
+
assert.assertString("header name", name);
|
|
98
96
|
if (!name) {
|
|
99
97
|
return true;
|
|
100
98
|
}
|
|
@@ -108,25 +106,25 @@ class Headers {
|
|
|
108
106
|
// Common HTTP headers are overwritten when set, instead of being
|
|
109
107
|
// concatenated
|
|
110
108
|
switch (lowerCased) {
|
|
111
|
-
case
|
|
112
|
-
case
|
|
113
|
-
case
|
|
114
|
-
case
|
|
115
|
-
case
|
|
116
|
-
case
|
|
117
|
-
case
|
|
118
|
-
case
|
|
119
|
-
case
|
|
120
|
-
case
|
|
121
|
-
case
|
|
122
|
-
case
|
|
123
|
-
case
|
|
124
|
-
case
|
|
125
|
-
case
|
|
126
|
-
case
|
|
109
|
+
case "age":
|
|
110
|
+
case "authorization":
|
|
111
|
+
case "content-length":
|
|
112
|
+
case "content-type":
|
|
113
|
+
case "etag":
|
|
114
|
+
case "expires":
|
|
115
|
+
case "from":
|
|
116
|
+
case "host":
|
|
117
|
+
case "if-modified-since":
|
|
118
|
+
case "if-unmodified-since":
|
|
119
|
+
case "last-modified, location":
|
|
120
|
+
case "max-forwards":
|
|
121
|
+
case "proxy-authorization":
|
|
122
|
+
case "referer":
|
|
123
|
+
case "retry-after":
|
|
124
|
+
case "user-agent":
|
|
127
125
|
this.headers[_name] = _value;
|
|
128
126
|
break;
|
|
129
|
-
case
|
|
127
|
+
case "set-cookie":
|
|
130
128
|
if (!this.headers[_name]) {
|
|
131
129
|
this.headers[_name] = [_value];
|
|
132
130
|
}
|
|
@@ -136,7 +134,7 @@ class Headers {
|
|
|
136
134
|
break;
|
|
137
135
|
default: {
|
|
138
136
|
if (this.headers[_name]) {
|
|
139
|
-
this.headers[_name] +=
|
|
137
|
+
this.headers[_name] += ", " + _value;
|
|
140
138
|
}
|
|
141
139
|
else {
|
|
142
140
|
this.headers[_name] = _value;
|
|
@@ -271,10 +269,10 @@ class RequestResponse {
|
|
|
271
269
|
this.status = 200;
|
|
272
270
|
}
|
|
273
271
|
switch (options.format) {
|
|
274
|
-
case
|
|
272
|
+
case "raw":
|
|
275
273
|
this.raw = true;
|
|
276
274
|
break;
|
|
277
|
-
case
|
|
275
|
+
case "standard":
|
|
278
276
|
this.raw = false;
|
|
279
277
|
break;
|
|
280
278
|
}
|
|
@@ -302,7 +300,7 @@ class RequestResponse {
|
|
|
302
300
|
* Adds new multiple headers.
|
|
303
301
|
*/
|
|
304
302
|
setHeaders(headers, ifNotPresent = false) {
|
|
305
|
-
assert.assertObject(
|
|
303
|
+
assert.assertObject("headers", headers);
|
|
306
304
|
if (headers) {
|
|
307
305
|
for (const name of Object.keys(headers)) {
|
|
308
306
|
// When ifNotPresent is set to true, only set the header if no value has been defined before
|
|
@@ -334,7 +332,7 @@ class RequestResponse {
|
|
|
334
332
|
* For example "set-cookie" headers should only be visible by the browser,
|
|
335
333
|
* otherwise they may leak information about the server's cookies, since the browser will
|
|
336
334
|
* not be able to restrict them to the domain of the request.
|
|
337
|
-
|
|
335
|
+
*/
|
|
338
336
|
for (const header of restrictedHeaders) {
|
|
339
337
|
if (filteredHeaders[header] !== undefined) {
|
|
340
338
|
filteredHeaders[header] = undefined;
|
package/lib/cluster/command.js
CHANGED
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
* limitations under the License.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
"use strict";
|
|
23
23
|
|
|
24
|
-
const { Reply, Request } = require(
|
|
25
|
-
const protobuf = require(
|
|
26
|
-
const Bluebird = require(
|
|
24
|
+
const { Reply, Request } = require("zeromq");
|
|
25
|
+
const protobuf = require("protobufjs");
|
|
26
|
+
const Bluebird = require("bluebird");
|
|
27
27
|
|
|
28
28
|
/* eslint-disable sort-keys */
|
|
29
29
|
const stateEnum = Object.freeze({
|
|
@@ -33,9 +33,9 @@ const stateEnum = Object.freeze({
|
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
const topicEnum = Object.freeze({
|
|
36
|
-
FULLSTATE:
|
|
37
|
-
HANDSHAKE:
|
|
38
|
-
DISCARDED:
|
|
36
|
+
FULLSTATE: "fullstate",
|
|
37
|
+
HANDSHAKE: "handshake",
|
|
38
|
+
DISCARDED: "discarded", // 0 byte message expected
|
|
39
39
|
});
|
|
40
40
|
/* eslint-enable sort-keys */
|
|
41
41
|
|
|
@@ -45,7 +45,7 @@ class ClusterCommand {
|
|
|
45
45
|
* @constructor
|
|
46
46
|
* @param {ClusterNode} localNode
|
|
47
47
|
*/
|
|
48
|
-
constructor
|
|
48
|
+
constructor(localNode) {
|
|
49
49
|
this.node = localNode;
|
|
50
50
|
this.server = null;
|
|
51
51
|
this.protoroot = null;
|
|
@@ -53,14 +53,14 @@ class ClusterCommand {
|
|
|
53
53
|
this.state = stateEnum.INITIALIZING;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
async init
|
|
56
|
+
async init() {
|
|
57
57
|
this.protoroot = await protobuf.load(`${__dirname}/protobuf/command.proto`);
|
|
58
58
|
await this.serve();
|
|
59
59
|
|
|
60
60
|
this.listen();
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
async serve
|
|
63
|
+
async serve() {
|
|
64
64
|
this.server = new Reply();
|
|
65
65
|
await this.server.bind(`tcp://*:${this.node.config.ports.command}`);
|
|
66
66
|
}
|
|
@@ -73,7 +73,7 @@ class ClusterCommand {
|
|
|
73
73
|
*
|
|
74
74
|
* @returns {void}
|
|
75
75
|
*/
|
|
76
|
-
async listen
|
|
76
|
+
async listen() {
|
|
77
77
|
this.state = stateEnum.RUNNING;
|
|
78
78
|
|
|
79
79
|
while (this.state === stateEnum.RUNNING) {
|
|
@@ -92,8 +92,7 @@ class ClusterCommand {
|
|
|
92
92
|
// to send some kind of response on an invalid request received
|
|
93
93
|
await this.server.send([topicEnum.DISCARDED, null]);
|
|
94
94
|
}
|
|
95
|
-
}
|
|
96
|
-
catch (e) {
|
|
95
|
+
} catch (e) {
|
|
97
96
|
if (this.state !== stateEnum.CLOSED) {
|
|
98
97
|
throw e;
|
|
99
98
|
}
|
|
@@ -105,7 +104,7 @@ class ClusterCommand {
|
|
|
105
104
|
* Closes opened sockets and marks this server as closed.
|
|
106
105
|
* @return {void}
|
|
107
106
|
*/
|
|
108
|
-
dispose
|
|
107
|
+
dispose() {
|
|
109
108
|
this.state = stateEnum.CLOSED;
|
|
110
109
|
this.server.close();
|
|
111
110
|
}
|
|
@@ -114,21 +113,21 @@ class ClusterCommand {
|
|
|
114
113
|
* Sends back the full state to the requesting node
|
|
115
114
|
* @return {void}
|
|
116
115
|
*/
|
|
117
|
-
async sendFullState
|
|
116
|
+
async sendFullState() {
|
|
118
117
|
const fullState = this.node.fullState.serialize();
|
|
119
118
|
fullState.activity = this.node.activity;
|
|
120
119
|
fullState.nodesState = [];
|
|
121
120
|
for (const [id, subscriber] of this.node.remoteNodes.entries()) {
|
|
122
121
|
fullState.nodesState.push({
|
|
123
122
|
id,
|
|
124
|
-
lastMessageId: subscriber.lastMessageId
|
|
123
|
+
lastMessageId: subscriber.lastMessageId,
|
|
125
124
|
});
|
|
126
125
|
}
|
|
127
126
|
fullState.nodesState.push({
|
|
128
127
|
id: this.node.nodeId,
|
|
129
|
-
lastMessageId: this.node.publisher.lastMessageId
|
|
128
|
+
lastMessageId: this.node.publisher.lastMessageId,
|
|
130
129
|
});
|
|
131
|
-
const protoEncode = this.protoroot.lookupType(
|
|
130
|
+
const protoEncode = this.protoroot.lookupType("FullStateResponse");
|
|
132
131
|
const buffer = protoEncode.encode(protoEncode.create(fullState)).finish();
|
|
133
132
|
|
|
134
133
|
await this.server.send([topicEnum.FULLSTATE, buffer]);
|
|
@@ -138,13 +137,15 @@ class ClusterCommand {
|
|
|
138
137
|
* Handles a handshake request from a remote node
|
|
139
138
|
* @return {void}
|
|
140
139
|
*/
|
|
141
|
-
async handleHandshake
|
|
142
|
-
const decoder = this.protoroot.lookupType(
|
|
143
|
-
const { nodeId, ip, lastMessageId } = decoder.toObject(
|
|
140
|
+
async handleHandshake(data) {
|
|
141
|
+
const decoder = this.protoroot.lookupType("HandshakeRequest");
|
|
142
|
+
const { nodeId, ip, lastMessageId } = decoder.toObject(
|
|
143
|
+
decoder.decode(data)
|
|
144
|
+
);
|
|
144
145
|
|
|
145
146
|
const added = await this.node.addNode(nodeId, ip, lastMessageId);
|
|
146
147
|
|
|
147
|
-
const encoder = this.protoroot.lookupType(
|
|
148
|
+
const encoder = this.protoroot.lookupType("HandshakeResponse");
|
|
148
149
|
const response = {
|
|
149
150
|
added,
|
|
150
151
|
lastMessageId: this.node.publisher.lastMessageId,
|
|
@@ -163,11 +164,15 @@ class ClusterCommand {
|
|
|
163
164
|
* @param {Array.<IdCard>} nodes
|
|
164
165
|
* @return {Object|null} Returns the fetched full state, or null if no node answered
|
|
165
166
|
*/
|
|
166
|
-
async getFullState
|
|
167
|
+
async getFullState(nodes) {
|
|
167
168
|
let idx = Math.floor(Math.random() * Math.floor(nodes.length));
|
|
168
169
|
let fullState = null;
|
|
169
170
|
|
|
170
|
-
for (
|
|
171
|
+
for (
|
|
172
|
+
let retries = 0;
|
|
173
|
+
fullState === null && retries < nodes.length;
|
|
174
|
+
retries++
|
|
175
|
+
) {
|
|
171
176
|
const { id, ip } = nodes[idx];
|
|
172
177
|
const req = new Request();
|
|
173
178
|
|
|
@@ -180,14 +185,14 @@ class ClusterCommand {
|
|
|
180
185
|
|
|
181
186
|
try {
|
|
182
187
|
[, fullState] = await req.receive();
|
|
183
|
-
}
|
|
184
|
-
catch (e) {
|
|
188
|
+
} catch (e) {
|
|
185
189
|
// no response from the remote node in a timely fashion... retrying
|
|
186
190
|
// with another one
|
|
187
|
-
global.kuzzle.log.warn(
|
|
191
|
+
global.kuzzle.log.warn(
|
|
192
|
+
`Unable to fetch a full state from node ${id} (no response received)`
|
|
193
|
+
);
|
|
188
194
|
idx = (idx + 1) % nodes.length;
|
|
189
|
-
}
|
|
190
|
-
finally {
|
|
195
|
+
} finally {
|
|
191
196
|
req.close();
|
|
192
197
|
}
|
|
193
198
|
}
|
|
@@ -196,7 +201,7 @@ class ClusterCommand {
|
|
|
196
201
|
return null;
|
|
197
202
|
}
|
|
198
203
|
|
|
199
|
-
const decoder = this.protoroot.lookupType(
|
|
204
|
+
const decoder = this.protoroot.lookupType("FullStateResponse");
|
|
200
205
|
|
|
201
206
|
return decoder.toObject(decoder.decode(fullState));
|
|
202
207
|
}
|
|
@@ -213,28 +218,27 @@ class ClusterCommand {
|
|
|
213
218
|
* @param {Array.<IdCard>} nodes
|
|
214
219
|
* @return {Object}
|
|
215
220
|
*/
|
|
216
|
-
async broadcastHandshake
|
|
221
|
+
async broadcastHandshake(nodes) {
|
|
217
222
|
const payload = {
|
|
218
223
|
ip: this.node.ip,
|
|
219
224
|
lastMessageId: this.node.publisher.lastMessageId,
|
|
220
225
|
nodeId: this.node.nodeId,
|
|
221
226
|
};
|
|
222
227
|
|
|
223
|
-
const encoder = this.protoroot.lookupType(
|
|
228
|
+
const encoder = this.protoroot.lookupType("HandshakeRequest");
|
|
224
229
|
const encoded = encoder.encode(encoder.create(payload)).finish();
|
|
225
230
|
|
|
226
|
-
const responses = await Bluebird.map(
|
|
227
|
-
|
|
228
|
-
|
|
231
|
+
const responses = await Bluebird.map(nodes, ({ id, ip }) =>
|
|
232
|
+
this._sendSingleHandshake(id, ip, encoded)
|
|
233
|
+
);
|
|
229
234
|
|
|
230
|
-
const decoder = this.protoroot.lookupType(
|
|
235
|
+
const decoder = this.protoroot.lookupType("HandshakeResponse");
|
|
231
236
|
const result = {};
|
|
232
237
|
|
|
233
238
|
for (let i = 0; i < nodes.length; i++) {
|
|
234
239
|
if (responses[i] === null) {
|
|
235
240
|
result[nodes[i].id] = null;
|
|
236
|
-
}
|
|
237
|
-
else {
|
|
241
|
+
} else {
|
|
238
242
|
result[nodes[i].id] = decoder.toObject(decoder.decode(responses[i]));
|
|
239
243
|
}
|
|
240
244
|
}
|
|
@@ -251,7 +255,7 @@ class ClusterCommand {
|
|
|
251
255
|
* @return {Object|null} - handshake encoded response, or null if no
|
|
252
256
|
* response was received
|
|
253
257
|
*/
|
|
254
|
-
async _sendSingleHandshake
|
|
258
|
+
async _sendSingleHandshake(id, ip, payload) {
|
|
255
259
|
const req = new Request();
|
|
256
260
|
|
|
257
261
|
req.receiveTimeout = 2000;
|
|
@@ -264,11 +268,11 @@ class ClusterCommand {
|
|
|
264
268
|
|
|
265
269
|
try {
|
|
266
270
|
[, response] = await req.receive();
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
finally {
|
|
271
|
+
} catch (e) {
|
|
272
|
+
global.kuzzle.log.warn(
|
|
273
|
+
`Couldn't complete handshake with node ${id}: no response received`
|
|
274
|
+
);
|
|
275
|
+
} finally {
|
|
272
276
|
req.close();
|
|
273
277
|
}
|
|
274
278
|
|
|
@@ -28,8 +28,8 @@ const name_generator_1 = require("../util/name-generator");
|
|
|
28
28
|
const worker_threads_1 = require("worker_threads");
|
|
29
29
|
const bluebird_1 = __importDefault(require("bluebird"));
|
|
30
30
|
require("../types");
|
|
31
|
-
const REDIS_PREFIX =
|
|
32
|
-
const REDIS_ID_CARDS_INDEX = REDIS_PREFIX +
|
|
31
|
+
const REDIS_PREFIX = "{cluster/node}/";
|
|
32
|
+
const REDIS_ID_CARDS_INDEX = REDIS_PREFIX + "id-cards-index";
|
|
33
33
|
class IdCard {
|
|
34
34
|
constructor({ id, ip, birthdate, topology }) {
|
|
35
35
|
this.id = id;
|
|
@@ -98,7 +98,7 @@ class ClusterIdCardHandler {
|
|
|
98
98
|
async createIdCard() {
|
|
99
99
|
let reserved = false;
|
|
100
100
|
do {
|
|
101
|
-
this.nodeId = name_generator_1.NameGenerator.generateRandomName({ prefix:
|
|
101
|
+
this.nodeId = name_generator_1.NameGenerator.generateRandomName({ prefix: "knode" });
|
|
102
102
|
this.nodeIdKey = `${REDIS_PREFIX}${this.nodeId}`;
|
|
103
103
|
this.idCard = new IdCard({
|
|
104
104
|
birthdate: Date.now(),
|
|
@@ -111,14 +111,14 @@ class ClusterIdCardHandler {
|
|
|
111
111
|
await this.addIdCardToIndex();
|
|
112
112
|
this.refreshWorker = this.constructWorker(`${__dirname}/workers/IDCardRenewer.js`);
|
|
113
113
|
this.refreshWorker.unref();
|
|
114
|
-
this.refreshWorker.on(
|
|
114
|
+
this.refreshWorker.on("message", async (message) => {
|
|
115
115
|
if (message.error) {
|
|
116
116
|
await this.node.evictSelf(message.error);
|
|
117
117
|
}
|
|
118
118
|
});
|
|
119
119
|
// Transfer informations to the worker
|
|
120
120
|
this.refreshWorker.postMessage({
|
|
121
|
-
action:
|
|
121
|
+
action: "start",
|
|
122
122
|
kuzzle: {
|
|
123
123
|
config: global.kuzzle.config,
|
|
124
124
|
id: global.kuzzle.id,
|
|
@@ -127,7 +127,7 @@ class ClusterIdCardHandler {
|
|
|
127
127
|
// Used to configure a redis the same way as the Cache Engine does
|
|
128
128
|
redis: {
|
|
129
129
|
config: global.kuzzle.config.services.internalCache,
|
|
130
|
-
name:
|
|
130
|
+
name: "internal_adapter",
|
|
131
131
|
},
|
|
132
132
|
refreshDelay: this.refreshDelay,
|
|
133
133
|
refreshMultiplier: this.refreshMultiplier,
|
|
@@ -155,7 +155,7 @@ class ClusterIdCardHandler {
|
|
|
155
155
|
global.kuzzle.log.error(`An error occurred while refreshing the ID card during WorkerThread startup: ${error}`);
|
|
156
156
|
}
|
|
157
157
|
}, this.refreshDelay * this.refreshMultiplier);
|
|
158
|
-
this.refreshWorker.on(
|
|
158
|
+
this.refreshWorker.on("message", ({ initialized }) => {
|
|
159
159
|
if (initialized) {
|
|
160
160
|
clearInterval(this.refreshTimer);
|
|
161
161
|
this.refreshTimer = null;
|
|
@@ -165,7 +165,7 @@ class ClusterIdCardHandler {
|
|
|
165
165
|
async dispose() {
|
|
166
166
|
this.disposed = true;
|
|
167
167
|
if (this.refreshWorker) {
|
|
168
|
-
this.refreshWorker.postMessage({ action:
|
|
168
|
+
this.refreshWorker.postMessage({ action: "dispose" });
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
171
|
/**
|
|
@@ -187,12 +187,12 @@ class ClusterIdCardHandler {
|
|
|
187
187
|
*/
|
|
188
188
|
async getRemoteIdCards() {
|
|
189
189
|
const idCards = [];
|
|
190
|
-
let keys = await global.kuzzle.ask(
|
|
191
|
-
keys = keys.filter(nodeIdKey => nodeIdKey !== this.nodeIdKey);
|
|
190
|
+
let keys = await global.kuzzle.ask("core:cache:internal:execute", "smembers", REDIS_ID_CARDS_INDEX);
|
|
191
|
+
keys = keys.filter((nodeIdKey) => nodeIdKey !== this.nodeIdKey);
|
|
192
192
|
if (keys.length === 0) {
|
|
193
193
|
return idCards;
|
|
194
194
|
}
|
|
195
|
-
const rawIdCards = await global.kuzzle.ask(
|
|
195
|
+
const rawIdCards = await global.kuzzle.ask("core:cache:internal:mget", keys);
|
|
196
196
|
const expiredIdCards = [];
|
|
197
197
|
for (let i = 0; i < keys.length; i++) {
|
|
198
198
|
// filter keys that might have expired between the key search and their
|
|
@@ -205,8 +205,8 @@ class ClusterIdCardHandler {
|
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
// Clean expired ID Card's keys in the index
|
|
208
|
-
await bluebird_1.default.map(expiredIdCards, idCardKey => {
|
|
209
|
-
return global.kuzzle.ask(
|
|
208
|
+
await bluebird_1.default.map(expiredIdCards, (idCardKey) => {
|
|
209
|
+
return global.kuzzle.ask("core:cache:internal:execute", "srem", REDIS_ID_CARDS_INDEX, idCardKey);
|
|
210
210
|
});
|
|
211
211
|
return idCards;
|
|
212
212
|
}
|
|
@@ -234,7 +234,7 @@ class ClusterIdCardHandler {
|
|
|
234
234
|
* This set is an index to retrieve ID Cards faster.
|
|
235
235
|
*/
|
|
236
236
|
async addIdCardToIndex() {
|
|
237
|
-
await global.kuzzle.ask(
|
|
237
|
+
await global.kuzzle.ask("core:cache:internal:execute", "sadd", REDIS_ID_CARDS_INDEX, this.nodeIdKey);
|
|
238
238
|
}
|
|
239
239
|
/**
|
|
240
240
|
* Saves the local node IdCard into Redis
|
|
@@ -245,7 +245,7 @@ class ClusterIdCardHandler {
|
|
|
245
245
|
if (!this.idCard) {
|
|
246
246
|
return false;
|
|
247
247
|
}
|
|
248
|
-
return await global.kuzzle.ask(
|
|
248
|
+
return await global.kuzzle.ask("core:cache:internal:store", this.nodeIdKey, JSON.stringify(this.idCard.serialize()), { onlyIfNew: creation, ttl: this.refreshDelay * this.refreshMultiplier });
|
|
249
249
|
}
|
|
250
250
|
}
|
|
251
251
|
exports.ClusterIdCardHandler = ClusterIdCardHandler;
|
package/lib/cluster/index.js
CHANGED