kuzzle 2.14.16 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/api/controllers/adminController.js +5 -0
- package/lib/api/controllers/documentController.js +1 -5
- package/lib/api/controllers/serverController.js +24 -4
- package/lib/api/funnel.js +19 -0
- package/lib/{config → api}/httpRoutes.js +30 -14
- package/lib/api/openApiGenerator.d.ts +6 -0
- package/lib/api/openApiGenerator.js +167 -126
- package/lib/api/openapi/documents/document.d.ts +21 -0
- package/lib/api/openapi/documents/document.js +57 -0
- package/lib/api/openapi/tools.d.ts +2 -0
- package/lib/api/openapi/tools.js +10 -0
- package/lib/api/request/kuzzleRequest.d.ts +30 -32
- package/lib/api/request/kuzzleRequest.js +30 -102
- package/lib/api/request/requestContext.d.ts +17 -22
- package/lib/api/request/requestContext.js +44 -109
- package/lib/api/request/requestInput.d.ts +19 -22
- package/lib/api/request/requestInput.js +115 -173
- package/lib/api/request/requestResponse.d.ts +12 -8
- package/lib/api/request/requestResponse.js +35 -29
- package/lib/cluster/idCardHandler.d.ts +140 -0
- package/lib/cluster/idCardHandler.js +218 -214
- package/lib/cluster/node.js +11 -0
- package/lib/cluster/protobuf/sync.proto +4 -0
- package/lib/cluster/subscriber.js +9 -12
- package/lib/cluster/workers/IDCardRenewer.js +13 -7
- package/lib/config/default.config.js +1 -1
- package/lib/core/network/router.js +33 -0
- package/lib/core/plugin/pluginsManager.js +3 -1
- package/lib/core/realtime/hotelClerk.d.ts +7 -0
- package/lib/core/realtime/hotelClerk.js +14 -0
- package/lib/core/realtime/notifier.js +16 -18
- package/lib/core/storage/clientAdapter.js +11 -5
- package/lib/core/storage/indexCache.d.ts +55 -0
- package/lib/core/storage/indexCache.js +97 -130
- package/lib/kuzzle/kuzzle.js +11 -7
- package/lib/service/storage/elasticsearch.js +14 -9
- package/package-lock.json +286 -260
- package/package.json +18 -17
|
@@ -15,14 +15,15 @@ class IDCardRenewer {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
async init (config) {
|
|
18
|
-
if (!this.disposed) {
|
|
19
|
-
return; // Already
|
|
18
|
+
if (! this.disposed) {
|
|
19
|
+
return; // Already initialized
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
this.disposed = false;
|
|
23
23
|
this.nodeIdKey = config.nodeIdKey;
|
|
24
24
|
this.refreshDelay = config.refreshDelay || 2000;
|
|
25
|
-
|
|
25
|
+
this.refreshMultiplier = config.refreshMultiplier;
|
|
26
|
+
|
|
26
27
|
/**
|
|
27
28
|
* Since we do not have access to the Kuzzle Context we can't use kuzzle.ask('core:cache:internal:*',...),
|
|
28
29
|
* so we need to have an instance of Redis similar to the one used in the Cache Engine
|
|
@@ -48,6 +49,9 @@ class IDCardRenewer {
|
|
|
48
49
|
this.renewIDCard.bind(this),
|
|
49
50
|
this.refreshDelay);
|
|
50
51
|
}
|
|
52
|
+
|
|
53
|
+
// Notify that the worker is running and updating the ID Card
|
|
54
|
+
this.parentPort.postMessage({ initialized: true });
|
|
51
55
|
}
|
|
52
56
|
|
|
53
57
|
async initRedis (config, name) {
|
|
@@ -63,7 +67,7 @@ class IDCardRenewer {
|
|
|
63
67
|
try {
|
|
64
68
|
const refreshed = await this.redis.commands.pexpire(
|
|
65
69
|
this.nodeIdKey,
|
|
66
|
-
this.refreshDelay *
|
|
70
|
+
this.refreshDelay * this.refreshMultiplier);
|
|
67
71
|
// Unable to refresh the key in time before it expires
|
|
68
72
|
// => this node is too slow, we need to remove it from the cluster
|
|
69
73
|
if (refreshed === 0) {
|
|
@@ -99,7 +103,8 @@ class IDCardRenewer {
|
|
|
99
103
|
|
|
100
104
|
if (!isMainThread) {
|
|
101
105
|
const idCardRenewer = new IDCardRenewer();
|
|
102
|
-
|
|
106
|
+
|
|
107
|
+
parentPort.on('message', async message => {
|
|
103
108
|
if (message.action === 'start') {
|
|
104
109
|
// Simulate basic global Kuzzle Context
|
|
105
110
|
global.kuzzle = { ...message.kuzzle };
|
|
@@ -111,11 +116,12 @@ if (!isMainThread) {
|
|
|
111
116
|
};
|
|
112
117
|
// Should never throw
|
|
113
118
|
await idCardRenewer.init(message);
|
|
114
|
-
}
|
|
119
|
+
}
|
|
120
|
+
else if (message.action === 'dispose') {
|
|
115
121
|
// Should never throw
|
|
116
122
|
await idCardRenewer.dispose();
|
|
117
123
|
}
|
|
118
|
-
});
|
|
124
|
+
});
|
|
119
125
|
}
|
|
120
126
|
|
|
121
127
|
module.exports = { IDCardRenewer };
|
|
@@ -46,7 +46,7 @@ module.exports = {
|
|
|
46
46
|
(see https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS)
|
|
47
47
|
*/
|
|
48
48
|
http: {
|
|
49
|
-
routes: require('
|
|
49
|
+
routes: require('./../api/httpRoutes'),
|
|
50
50
|
accessControlAllowOrigin: '*',
|
|
51
51
|
accessControlAllowOriginUseRegExp: false,
|
|
52
52
|
accessControlAllowMethods: 'GET,POST,PUT,PATCH,DELETE,OPTIONS,HEAD',
|
|
@@ -138,6 +138,39 @@ class Router {
|
|
|
138
138
|
this._executeFromHttp(route.verb, request, cb);
|
|
139
139
|
});
|
|
140
140
|
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Returns inner metrics from the router
|
|
144
|
+
* @returns {Object}
|
|
145
|
+
*/
|
|
146
|
+
global.kuzzle.onAsk(
|
|
147
|
+
'core:network:router:metrics',
|
|
148
|
+
() => this.metrics());
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Returns the metrics of the router
|
|
153
|
+
* @returns {Object}
|
|
154
|
+
*/
|
|
155
|
+
metrics () {
|
|
156
|
+
const connectionsByProtocol = {};
|
|
157
|
+
|
|
158
|
+
for (const connection of this.connections.values()) {
|
|
159
|
+
const protocol = connection.connection.protocol.toLowerCase();
|
|
160
|
+
if (protocol === 'internal') {
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (connectionsByProtocol[protocol] === undefined) {
|
|
165
|
+
connectionsByProtocol[protocol] = 0;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
connectionsByProtocol[protocol]++;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return {
|
|
172
|
+
connections: connectionsByProtocol,
|
|
173
|
+
};
|
|
141
174
|
}
|
|
142
175
|
|
|
143
176
|
/**
|
|
@@ -118,6 +118,13 @@ export declare class HotelClerk {
|
|
|
118
118
|
*
|
|
119
119
|
*/
|
|
120
120
|
unsubscribe(connectionId: string, roomId: string, notify?: boolean): Promise<void>;
|
|
121
|
+
/**
|
|
122
|
+
* Returns inner metrics from the HotelClerk
|
|
123
|
+
*/
|
|
124
|
+
metrics(): {
|
|
125
|
+
rooms: number;
|
|
126
|
+
subscriptions: number;
|
|
127
|
+
};
|
|
121
128
|
/**
|
|
122
129
|
* Deletes a room if no user has subscribed to it, and removes it also from the
|
|
123
130
|
* real-time engine
|
|
@@ -136,6 +136,11 @@ class HotelClerk {
|
|
|
136
136
|
global.kuzzle.onAsk('core:realtime:unsubscribe', (connectionId, roomId, notify) => {
|
|
137
137
|
return this.unsubscribe(connectionId, roomId, notify);
|
|
138
138
|
});
|
|
139
|
+
/**
|
|
140
|
+
* Returns inner metrics from the HotelClerk
|
|
141
|
+
* @return {{rooms: number, subscriptions: number}}
|
|
142
|
+
*/
|
|
143
|
+
global.kuzzle.onAsk('core:realtime:hotelClerk:metrics', () => this.metrics());
|
|
139
144
|
/**
|
|
140
145
|
* Clear the hotel clerk and properly disconnect connections.
|
|
141
146
|
*/
|
|
@@ -410,6 +415,15 @@ class HotelClerk {
|
|
|
410
415
|
subscription,
|
|
411
416
|
});
|
|
412
417
|
}
|
|
418
|
+
/**
|
|
419
|
+
* Returns inner metrics from the HotelClerk
|
|
420
|
+
*/
|
|
421
|
+
metrics() {
|
|
422
|
+
return {
|
|
423
|
+
rooms: this.roomsCount,
|
|
424
|
+
subscriptions: this.subscriptions.size,
|
|
425
|
+
};
|
|
426
|
+
}
|
|
413
427
|
/**
|
|
414
428
|
* Deletes a room if no user has subscribed to it, and removes it also from the
|
|
415
429
|
* real-time engine
|
|
@@ -249,9 +249,7 @@ class NotifierController {
|
|
|
249
249
|
if (cache !== null) {
|
|
250
250
|
const stopListening = difference(JSON.parse(cache), rooms);
|
|
251
251
|
|
|
252
|
-
await this.notifyDocument(stopListening, request, 'out', 'replace',
|
|
253
|
-
_id: document._id,
|
|
254
|
-
});
|
|
252
|
+
await this.notifyDocument(stopListening, request, 'out', 'replace', document);
|
|
255
253
|
}
|
|
256
254
|
|
|
257
255
|
return rooms;
|
|
@@ -281,25 +279,29 @@ class NotifierController {
|
|
|
281
279
|
: [];
|
|
282
280
|
|
|
283
281
|
const result = await Bluebird.map(documents, (doc, index) => {
|
|
284
|
-
switch(action) {
|
|
282
|
+
switch (action) {
|
|
285
283
|
case actionEnum.CREATE:
|
|
286
284
|
return this.notifyDocumentCreate(request, doc);
|
|
285
|
+
|
|
287
286
|
case actionEnum.DELETE:
|
|
288
287
|
return this.notifyDocumentDelete(request, doc);
|
|
288
|
+
|
|
289
289
|
case actionEnum.REPLACE:
|
|
290
290
|
return this.notifyDocumentReplace(request, doc, cache[index]);
|
|
291
|
+
|
|
291
292
|
case actionEnum.UPDATE:
|
|
292
293
|
return this.notifyDocumentUpdate(request, doc, cache[index]);
|
|
294
|
+
|
|
293
295
|
case actionEnum.UPSERT:
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
296
|
+
return doc.created
|
|
297
|
+
? this.notifyDocumentCreate(request, doc)
|
|
298
|
+
: this.notifyDocumentUpdate(request, doc, cache[index]);
|
|
299
|
+
|
|
298
300
|
case actionEnum.WRITE:
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
301
|
+
return doc.created
|
|
302
|
+
? this.notifyDocumentCreate(request, doc)
|
|
303
|
+
: this.notifyDocumentReplace(request, doc, cache[index]);
|
|
304
|
+
|
|
303
305
|
default:
|
|
304
306
|
throw kerror.get('core', 'fatal', 'assertion_failed', `unknown notify action "${doc.action}"`);
|
|
305
307
|
}
|
|
@@ -342,9 +344,7 @@ class NotifierController {
|
|
|
342
344
|
if (cache !== null) {
|
|
343
345
|
const stopListening = difference(JSON.parse(cache), rooms);
|
|
344
346
|
|
|
345
|
-
await this.notifyDocument(stopListening, request, 'out', 'update',
|
|
346
|
-
_id: document._id,
|
|
347
|
-
});
|
|
347
|
+
await this.notifyDocument(stopListening, request, 'out', 'update', document);
|
|
348
348
|
}
|
|
349
349
|
|
|
350
350
|
return rooms;
|
|
@@ -361,9 +361,7 @@ class NotifierController {
|
|
|
361
361
|
const rooms = this._test(request, document._source, document._id);
|
|
362
362
|
|
|
363
363
|
if (rooms.length > 0) {
|
|
364
|
-
await this.notifyDocument(rooms, request, 'out', 'delete',
|
|
365
|
-
_id: document._id,
|
|
366
|
-
});
|
|
364
|
+
await this.notifyDocument(rooms, request, 'out', 'delete', document);
|
|
367
365
|
}
|
|
368
366
|
|
|
369
367
|
return [];
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
'use strict';
|
|
23
23
|
|
|
24
24
|
const Elasticsearch = require('../../service/storage/elasticsearch');
|
|
25
|
-
const IndexCache = require('./indexCache');
|
|
25
|
+
const { IndexCache } = require('./indexCache');
|
|
26
26
|
const { isPlainObject } = require('../../util/safeObject');
|
|
27
27
|
const kerror = require('../../kerror');
|
|
28
28
|
const { Mutex } = require('../../util/mutex');
|
|
@@ -42,7 +42,7 @@ class ClientAdapter {
|
|
|
42
42
|
global.kuzzle.config.services.storageEngine,
|
|
43
43
|
scope);
|
|
44
44
|
this.scope = scope;
|
|
45
|
-
this.cache = new IndexCache(
|
|
45
|
+
this.cache = new IndexCache();
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
async init () {
|
|
@@ -57,6 +57,13 @@ class ClientAdapter {
|
|
|
57
57
|
|
|
58
58
|
// Global store events registration
|
|
59
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Manually refresh the index cache (e.g. after alias creation)
|
|
62
|
+
*/
|
|
63
|
+
global.kuzzle.onAsk(
|
|
64
|
+
`core:storage:${this.scope}:cache:refresh`,
|
|
65
|
+
() => this.populateCache());
|
|
66
|
+
|
|
60
67
|
/**
|
|
61
68
|
* Return information about the instantiated ES service
|
|
62
69
|
* @returns {Promise.<Object>}
|
|
@@ -77,7 +84,6 @@ class ClientAdapter {
|
|
|
77
84
|
}
|
|
78
85
|
|
|
79
86
|
async createIndex (index, { indexCacheOnly=false, propagate=true } = {}) {
|
|
80
|
-
|
|
81
87
|
if (this.cache.hasIndex(index)) {
|
|
82
88
|
throw servicesError.get('index_already_exists', this.scope, index);
|
|
83
89
|
}
|
|
@@ -264,7 +270,7 @@ class ClientAdapter {
|
|
|
264
270
|
`core:storage:${this.scope}:collection:update`,
|
|
265
271
|
(index, collection, changes) => {
|
|
266
272
|
this.cache.assertCollectionExists(index, collection);
|
|
267
|
-
this.client.updateCollection(index, collection, changes);
|
|
273
|
+
return this.client.updateCollection(index, collection, changes);
|
|
268
274
|
});
|
|
269
275
|
}
|
|
270
276
|
|
|
@@ -856,7 +862,7 @@ class ClientAdapter {
|
|
|
856
862
|
* @returns {Promise}
|
|
857
863
|
*/
|
|
858
864
|
async loadMappings (
|
|
859
|
-
fixtures = {},
|
|
865
|
+
fixtures = {},
|
|
860
866
|
options = {
|
|
861
867
|
indexCacheOnly: false,
|
|
862
868
|
propagate: true,
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export declare class IndexCache {
|
|
2
|
+
/**
|
|
3
|
+
* Index map: each entry holds a set of collection names
|
|
4
|
+
*
|
|
5
|
+
* Map<index, Set<collection>>
|
|
6
|
+
*/
|
|
7
|
+
private indexes;
|
|
8
|
+
constructor();
|
|
9
|
+
/**
|
|
10
|
+
* Cache a new index
|
|
11
|
+
*
|
|
12
|
+
* @return true if an index was added, false if there is no modification
|
|
13
|
+
*/
|
|
14
|
+
addIndex(index: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Cache a new collection
|
|
17
|
+
*/
|
|
18
|
+
addCollection(index: string, collection: string): void;
|
|
19
|
+
/**
|
|
20
|
+
* Check an index existence
|
|
21
|
+
*/
|
|
22
|
+
hasIndex(index: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Check a collection existence
|
|
25
|
+
*/
|
|
26
|
+
hasCollection(index: string, collection: string): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Return the list of cached indexes
|
|
29
|
+
*/
|
|
30
|
+
listIndexes(): string[];
|
|
31
|
+
/**
|
|
32
|
+
* Return the list of an index collections
|
|
33
|
+
*
|
|
34
|
+
* @throws If the provided index does not exist
|
|
35
|
+
*/
|
|
36
|
+
listCollections(index: string): string[];
|
|
37
|
+
/**
|
|
38
|
+
* Remove an index from the cache
|
|
39
|
+
*/
|
|
40
|
+
removeIndex(index: string): void;
|
|
41
|
+
/**
|
|
42
|
+
* Remove a collection from the cache
|
|
43
|
+
*/
|
|
44
|
+
removeCollection(index: string, collection: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* Assert that the provided index exists
|
|
47
|
+
*
|
|
48
|
+
* @throws If the index does not exist
|
|
49
|
+
*/
|
|
50
|
+
assertIndexExists(index: string): void;
|
|
51
|
+
/**
|
|
52
|
+
* Assert that the provided index and collection exist
|
|
53
|
+
*/
|
|
54
|
+
assertCollectionExists(index: string, collection: string): void;
|
|
55
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/*
|
|
2
3
|
* Kuzzle, a backend software, self-hostable and ready to use
|
|
3
4
|
* to power modern apps
|
|
@@ -18,142 +19,108 @@
|
|
|
18
19
|
* See the License for the specific language governing permissions and
|
|
19
20
|
* limitations under the License.
|
|
20
21
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.IndexCache = void 0;
|
|
27
|
+
const kerror_1 = __importDefault(require("../../kerror"));
|
|
28
|
+
const storageError = kerror_1.default.wrap('services', 'storage');
|
|
26
29
|
class IndexCache {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
constructor() {
|
|
31
|
+
/**
|
|
32
|
+
* Index map: each entry holds a set of collection names
|
|
33
|
+
*
|
|
34
|
+
* Map<index, Set<collection>>
|
|
35
|
+
*/
|
|
36
|
+
this.indexes = new Map();
|
|
37
|
+
this.indexes = new Map();
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Cache a new index
|
|
41
|
+
*
|
|
42
|
+
* @return true if an index was added, false if there is no modification
|
|
43
|
+
*/
|
|
44
|
+
addIndex(index) {
|
|
45
|
+
if (this.indexes.has(index)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
this.indexes.set(index, new Set());
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Cache a new collection
|
|
53
|
+
*/
|
|
54
|
+
addCollection(index, collection) {
|
|
55
|
+
this.addIndex(index);
|
|
56
|
+
const collections = this.indexes.get(index);
|
|
57
|
+
collections.add(collection);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Check an index existence
|
|
61
|
+
*/
|
|
62
|
+
hasIndex(index) {
|
|
63
|
+
return this.indexes.has(index);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Check a collection existence
|
|
67
|
+
*/
|
|
68
|
+
hasCollection(index, collection) {
|
|
69
|
+
const collections = this.indexes.get(index);
|
|
70
|
+
if (!collections) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
return collections.has(collection);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Return the list of cached indexes
|
|
77
|
+
*/
|
|
78
|
+
listIndexes() {
|
|
79
|
+
return Array.from(this.indexes.keys());
|
|
80
|
+
}
|
|
33
81
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
82
|
+
* Return the list of an index collections
|
|
83
|
+
*
|
|
84
|
+
* @throws If the provided index does not exist
|
|
36
85
|
*/
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Cache a new index
|
|
42
|
-
* @param {string} index
|
|
43
|
-
* @return {boolean} true if an index was added, false if there is no
|
|
44
|
-
* modification
|
|
45
|
-
*/
|
|
46
|
-
addIndex (index) {
|
|
47
|
-
if (this.indexes.has(index)) {
|
|
48
|
-
return false;
|
|
86
|
+
listCollections(index) {
|
|
87
|
+
this.assertIndexExists(index);
|
|
88
|
+
return Array.from(this.indexes.get(index));
|
|
49
89
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Cache a new collection
|
|
58
|
-
* @param {string} index
|
|
59
|
-
* @param {string} collection
|
|
60
|
-
*/
|
|
61
|
-
addCollection (index, collection) {
|
|
62
|
-
this.addIndex(index);
|
|
63
|
-
const collections = this.indexes.get(index);
|
|
64
|
-
|
|
65
|
-
collections.add(collection);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Check an index existence
|
|
70
|
-
* @param {string} index
|
|
71
|
-
* @returns {boolean}
|
|
72
|
-
*/
|
|
73
|
-
hasIndex (index) {
|
|
74
|
-
return this.indexes.has(index);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Check a collection existence
|
|
79
|
-
* @param {string} index
|
|
80
|
-
* @param {string} collection
|
|
81
|
-
* @returns {boolean}
|
|
82
|
-
*/
|
|
83
|
-
hasCollection (index, collection) {
|
|
84
|
-
const collections = this.indexes.get(index);
|
|
85
|
-
|
|
86
|
-
if (!collections) {
|
|
87
|
-
return false;
|
|
90
|
+
/**
|
|
91
|
+
* Remove an index from the cache
|
|
92
|
+
*/
|
|
93
|
+
removeIndex(index) {
|
|
94
|
+
this.indexes.delete(index);
|
|
88
95
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
listIndexes () {
|
|
98
|
-
return Array.from(this.indexes.keys());
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Return the list of an index' collections
|
|
103
|
-
* @param {string} index
|
|
104
|
-
* @returns {string[]}
|
|
105
|
-
* @throws If the provided index does not exist
|
|
106
|
-
*/
|
|
107
|
-
listCollections (index) {
|
|
108
|
-
this.assertIndexExists(index);
|
|
109
|
-
|
|
110
|
-
return Array.from(this.indexes.get(index));
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Remove an index from the cache
|
|
115
|
-
* @param {string} index
|
|
116
|
-
*/
|
|
117
|
-
removeIndex (index) {
|
|
118
|
-
this.indexes.delete(index);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Remove a collection from the cache
|
|
123
|
-
* @param {string} index
|
|
124
|
-
* @param {string} collection
|
|
125
|
-
*/
|
|
126
|
-
removeCollection (index, collection) {
|
|
127
|
-
const collections = this.indexes.get(index);
|
|
128
|
-
|
|
129
|
-
if (collections) {
|
|
130
|
-
collections.delete(collection);
|
|
96
|
+
/**
|
|
97
|
+
* Remove a collection from the cache
|
|
98
|
+
*/
|
|
99
|
+
removeCollection(index, collection) {
|
|
100
|
+
const collections = this.indexes.get(index);
|
|
101
|
+
if (collections) {
|
|
102
|
+
collections.delete(collection);
|
|
103
|
+
}
|
|
131
104
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
throw kerror.get('unknown_index', index);
|
|
105
|
+
/**
|
|
106
|
+
* Assert that the provided index exists
|
|
107
|
+
*
|
|
108
|
+
* @throws If the index does not exist
|
|
109
|
+
*/
|
|
110
|
+
assertIndexExists(index) {
|
|
111
|
+
if (!this.indexes.has(index)) {
|
|
112
|
+
throw storageError.get('unknown_index', index);
|
|
113
|
+
}
|
|
142
114
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
this.assertIndexExists(index);
|
|
152
|
-
|
|
153
|
-
if (!this.indexes.get(index).has(collection)) {
|
|
154
|
-
throw kerror.get('unknown_collection', index, collection);
|
|
115
|
+
/**
|
|
116
|
+
* Assert that the provided index and collection exist
|
|
117
|
+
*/
|
|
118
|
+
assertCollectionExists(index, collection) {
|
|
119
|
+
this.assertIndexExists(index);
|
|
120
|
+
if (!this.indexes.get(index).has(collection)) {
|
|
121
|
+
throw storageError.get('unknown_collection', index, collection);
|
|
122
|
+
}
|
|
155
123
|
}
|
|
156
|
-
}
|
|
157
124
|
}
|
|
158
|
-
|
|
159
|
-
|
|
125
|
+
exports.IndexCache = IndexCache;
|
|
126
|
+
//# sourceMappingURL=indexCache.js.map
|
package/lib/kuzzle/kuzzle.js
CHANGED
|
@@ -28,7 +28,7 @@ const murmurhash_native_1 = require("murmurhash-native");
|
|
|
28
28
|
const json_stable_stringify_1 = __importDefault(require("json-stable-stringify"));
|
|
29
29
|
const koncorde_1 = require("koncorde");
|
|
30
30
|
const bluebird_1 = __importDefault(require("bluebird"));
|
|
31
|
-
const
|
|
31
|
+
const node_segfault_handler_1 = __importDefault(require("node-segfault-handler"));
|
|
32
32
|
const lodash_1 = __importDefault(require("lodash"));
|
|
33
33
|
const kuzzleStateEnum_1 = __importDefault(require("./kuzzleStateEnum"));
|
|
34
34
|
const kuzzleEventEmitter_1 = __importDefault(require("./event/kuzzleEventEmitter"));
|
|
@@ -54,21 +54,25 @@ const realtime_1 = __importDefault(require("../core/realtime"));
|
|
|
54
54
|
const cluster_1 = __importDefault(require("../cluster"));
|
|
55
55
|
const package_json_1 = require("../../package.json");
|
|
56
56
|
const BACKEND_IMPORT_KEY = 'backend:init:import';
|
|
57
|
-
|
|
57
|
+
Reflect.defineProperty(global, '_kuzzle', {
|
|
58
|
+
value: null,
|
|
59
|
+
writable: true,
|
|
60
|
+
});
|
|
61
|
+
/* eslint-disable dot-notation */
|
|
58
62
|
Reflect.defineProperty(global, 'kuzzle', {
|
|
59
63
|
configurable: true,
|
|
60
64
|
enumerable: false,
|
|
61
65
|
get() {
|
|
62
|
-
if (_kuzzle === null) {
|
|
66
|
+
if (global['_kuzzle'] === null) {
|
|
63
67
|
throw new Error('Kuzzle instance not found. Did you try to use a live-only feature before starting your application?');
|
|
64
68
|
}
|
|
65
|
-
return _kuzzle;
|
|
69
|
+
return global['_kuzzle'];
|
|
66
70
|
},
|
|
67
71
|
set(value) {
|
|
68
|
-
if (_kuzzle !== null) {
|
|
72
|
+
if (global['_kuzzle'] !== null) {
|
|
69
73
|
throw new Error('Cannot build a Kuzzle instance: another one already exists');
|
|
70
74
|
}
|
|
71
|
-
_kuzzle = value;
|
|
75
|
+
global['_kuzzle'] = value;
|
|
72
76
|
},
|
|
73
77
|
});
|
|
74
78
|
class Kuzzle extends kuzzleEventEmitter_1.default {
|
|
@@ -444,7 +448,7 @@ class Kuzzle extends kuzzleEventEmitter_1.default {
|
|
|
444
448
|
this.shutdown();
|
|
445
449
|
});
|
|
446
450
|
}
|
|
447
|
-
|
|
451
|
+
node_segfault_handler_1.default.registerHandler();
|
|
448
452
|
}
|
|
449
453
|
async dumpAndExit(suffix) {
|
|
450
454
|
if (this.config.dump.enabled) {
|
|
@@ -128,12 +128,11 @@ class ElasticSearch extends Service {
|
|
|
128
128
|
'_source_includes'
|
|
129
129
|
];
|
|
130
130
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
];
|
|
136
|
-
|
|
131
|
+
/**
|
|
132
|
+
* Only allow stored-scripts in queries
|
|
133
|
+
*/
|
|
134
|
+
this.scriptKeys = ['script', '_script'];
|
|
135
|
+
this.scriptAllowedArgs = ['id', 'params'];
|
|
137
136
|
|
|
138
137
|
this.maxScrollDuration = this._loadMsConfig('maxScrollDuration');
|
|
139
138
|
|
|
@@ -2979,14 +2978,20 @@ class ElasticSearch extends Service {
|
|
|
2979
2978
|
}
|
|
2980
2979
|
|
|
2981
2980
|
/**
|
|
2982
|
-
* Throw if
|
|
2981
|
+
* Throw if a script is used in the query.
|
|
2982
|
+
*
|
|
2983
|
+
* Only Stored Scripts are accepted
|
|
2983
2984
|
*
|
|
2984
2985
|
* @param {Object} object
|
|
2985
2986
|
*/
|
|
2986
|
-
_scriptCheck(object) {
|
|
2987
|
+
_scriptCheck (object) {
|
|
2987
2988
|
for (const [key, value] of Object.entries(object)) {
|
|
2988
2989
|
if (this.scriptKeys.includes(key)) {
|
|
2989
|
-
|
|
2990
|
+
for (const scriptArg of Object.keys(value)) {
|
|
2991
|
+
if (! this.scriptAllowedArgs.includes(scriptArg)) {
|
|
2992
|
+
throw kerror.get('invalid_query_keyword', `${key}.${scriptArg}`);
|
|
2993
|
+
}
|
|
2994
|
+
}
|
|
2990
2995
|
}
|
|
2991
2996
|
// Every object must be checked here, even the ones nested into an array
|
|
2992
2997
|
else if (typeof value === 'object' && value !== null) {
|