@restorecommerce/chassis-srv 0.3.2 → 0.3.6
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/CHANGELOG.md +17 -0
- package/lib/cache/index.js +22 -3
- package/lib/cache/index.js.map +1 -1
- package/lib/command-interface/index.js +481 -493
- package/lib/command-interface/index.js.map +1 -1
- package/lib/config/index.js +6 -15
- package/lib/config/index.js.map +1 -1
- package/lib/database/index.d.ts +2 -4
- package/lib/database/index.js +4 -13
- package/lib/database/index.js.map +1 -1
- package/lib/database/provider/arango/base.js +314 -322
- package/lib/database/provider/arango/base.js.map +1 -1
- package/lib/database/provider/arango/common.js +70 -57
- package/lib/database/provider/arango/common.js.map +1 -1
- package/lib/database/provider/arango/graph.d.ts +4 -8
- package/lib/database/provider/arango/graph.js +335 -466
- package/lib/database/provider/arango/graph.js.map +1 -1
- package/lib/database/provider/arango/index.js +34 -21
- package/lib/database/provider/arango/index.js.map +1 -1
- package/lib/database/provider/arango/interface.d.ts +70 -0
- package/lib/database/provider/arango/interface.js +46 -0
- package/lib/database/provider/arango/interface.js.map +1 -0
- package/lib/database/provider/arango/utils.d.ts +77 -0
- package/lib/database/provider/arango/utils.js +587 -0
- package/lib/database/provider/arango/utils.js.map +1 -0
- package/lib/database/provider/nedb/index.js +203 -206
- package/lib/database/provider/nedb/index.js.map +1 -1
- package/lib/health/index.js +36 -42
- package/lib/health/index.js.map +1 -1
- package/lib/index.d.ts +4 -0
- package/lib/index.js +27 -6
- package/lib/index.js.map +1 -1
- package/lib/microservice/endpoint.js +33 -23
- package/lib/microservice/endpoint.js.map +1 -1
- package/lib/microservice/server.js +115 -106
- package/lib/microservice/server.js.map +1 -1
- package/lib/microservice/transport/provider/grpc/index.js +58 -52
- package/lib/microservice/transport/provider/grpc/index.js.map +1 -1
- package/lib/microservice/transport/provider/grpc/reflection.js +101 -93
- package/lib/microservice/transport/provider/grpc/reflection.js.map +1 -1
- package/lib/offsets/index.d.ts +1 -1
- package/lib/offsets/index.js +46 -39
- package/lib/offsets/index.js.map +1 -1
- package/package.json +27 -27
- package/test.js +56 -0
- package/tsconfig.json +13 -6
- package/setupTopics.js +0 -32
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
10
20
|
};
|
|
11
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
22
|
exports.CommandInterface = void 0;
|
|
13
|
-
const _ = require("lodash");
|
|
14
|
-
const database = require("./../database");
|
|
15
|
-
const async = require("async");
|
|
23
|
+
const _ = __importStar(require("lodash"));
|
|
24
|
+
const database = __importStar(require("./../database"));
|
|
25
|
+
const async = __importStar(require("async"));
|
|
16
26
|
// For some reason this is required
|
|
17
27
|
const crypto = require('crypto');
|
|
18
28
|
const ServingStatus = {
|
|
@@ -114,33 +124,31 @@ class CommandInterface {
|
|
|
114
124
|
* @param call
|
|
115
125
|
* @param context
|
|
116
126
|
*/
|
|
117
|
-
command(call, context) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
};
|
|
126
|
-
return this.encodeMsg(result);
|
|
127
|
-
}
|
|
128
|
-
const name = call.name || call.request.name;
|
|
129
|
-
if (_.isNil(this.commands[name])) {
|
|
130
|
-
const result = {
|
|
131
|
-
error: {
|
|
132
|
-
code: 400,
|
|
133
|
-
message: `Command name ${name} does not exist`
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
return this.encodeMsg(result);
|
|
137
|
-
}
|
|
138
|
-
const payload = call.payload ? this.decodeMsg(call.payload) :
|
|
139
|
-
(call.request.payload ? this.decodeMsg(call.request.payload) : null);
|
|
140
|
-
// calling operation bound to the command name
|
|
141
|
-
const result = yield this.commands[name].apply(this, [payload]);
|
|
127
|
+
async command(call, context) {
|
|
128
|
+
if (_.isNil(call.request) && _.isNil(call.name)) {
|
|
129
|
+
const result = {
|
|
130
|
+
error: {
|
|
131
|
+
code: 400,
|
|
132
|
+
message: 'No command name provided',
|
|
133
|
+
}
|
|
134
|
+
};
|
|
142
135
|
return this.encodeMsg(result);
|
|
143
|
-
}
|
|
136
|
+
}
|
|
137
|
+
const name = call.name || call.request.name;
|
|
138
|
+
if (_.isNil(this.commands[name])) {
|
|
139
|
+
const result = {
|
|
140
|
+
error: {
|
|
141
|
+
code: 400,
|
|
142
|
+
message: `Command name ${name} does not exist`
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
return this.encodeMsg(result);
|
|
146
|
+
}
|
|
147
|
+
const payload = call.payload ? this.decodeMsg(call.payload) :
|
|
148
|
+
(call.request.payload ? this.decodeMsg(call.request.payload) : null);
|
|
149
|
+
// calling operation bound to the command name
|
|
150
|
+
const result = await this.commands[name].apply(this, [payload]);
|
|
151
|
+
return this.encodeMsg(result);
|
|
144
152
|
}
|
|
145
153
|
/**
|
|
146
154
|
* Reconfigure service
|
|
@@ -162,200 +170,198 @@ class CommandInterface {
|
|
|
162
170
|
* ArangoDB database collections, using the chassis-srv database provider.
|
|
163
171
|
* @param topics list of Kafka topics to be restored
|
|
164
172
|
*/
|
|
165
|
-
restore(payload) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
+
async restore(payload) {
|
|
174
|
+
if (_.isEmpty(payload) || _.isEmpty(payload.data)) {
|
|
175
|
+
// throw new errors.InvalidArgument('Invalid payload for restore command');
|
|
176
|
+
return {
|
|
177
|
+
error: {
|
|
178
|
+
code: 400,
|
|
179
|
+
message: 'Invalid payload for restore command'
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
const restoreData = payload.data || [];
|
|
184
|
+
// the Kafka config should contains a key-value pair, mapping
|
|
185
|
+
// a label with the topic's name
|
|
186
|
+
const kafkaEventsCfg = this.config.get('events:kafka');
|
|
187
|
+
const kafkaCfg = this.config.get('events:kafka:topics');
|
|
188
|
+
if (_.isNil(kafkaCfg) || kafkaCfg.length == 0) {
|
|
189
|
+
return {
|
|
190
|
+
error: {
|
|
191
|
+
code: 500,
|
|
192
|
+
message: 'Kafka topics config not available'
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
const topicLabels = _.keys(kafkaCfg).filter((elem, index) => {
|
|
197
|
+
return elem.includes('.resource');
|
|
198
|
+
}).map((elem) => {
|
|
199
|
+
return elem.replace('.resource', '');
|
|
200
|
+
});
|
|
201
|
+
const restoreSetup = {};
|
|
202
|
+
const restoreEventSetup = {};
|
|
203
|
+
restoreData.forEach((data) => {
|
|
204
|
+
const ignoreOffset = (data.ignore_offset || []).filter((offset) => {
|
|
205
|
+
const isNumber = Number(offset) != NaN;
|
|
206
|
+
if (!isNumber) {
|
|
207
|
+
this.logger.warn(`Invalid value for "ignore_offset" parameter in restore: ${offset}`);
|
|
208
|
+
}
|
|
209
|
+
return isNumber;
|
|
210
|
+
});
|
|
211
|
+
restoreSetup[data.entity] = {
|
|
212
|
+
baseOffset: Number(data.base_offset) || 0,
|
|
213
|
+
ignoreOffset
|
|
214
|
+
};
|
|
215
|
+
});
|
|
216
|
+
const restoreCollections = _.keys(restoreSetup);
|
|
217
|
+
try {
|
|
218
|
+
const dbCfgs = this.config.get('database');
|
|
219
|
+
const dbCfgNames = _.keys(dbCfgs);
|
|
220
|
+
for (let i = 0; i < dbCfgNames.length; i += 1) {
|
|
221
|
+
const dbCfgName = dbCfgNames[i];
|
|
222
|
+
const dbCfg = dbCfgs[dbCfgName];
|
|
223
|
+
const collections = dbCfg.collections;
|
|
224
|
+
let graphName, edgeConfigDefs;
|
|
225
|
+
if (this.config.get('graph')) {
|
|
226
|
+
graphName = this.config.get('graph:graphName');
|
|
227
|
+
edgeConfigDefs = this.config.get('graph:edgeDefinitions');
|
|
228
|
+
}
|
|
229
|
+
const db = await database.get(dbCfg, this.logger, graphName, edgeConfigDefs);
|
|
230
|
+
if (_.isNil(collections)) {
|
|
231
|
+
this.logger.warn('No collections found on DB config');
|
|
232
|
+
return {};
|
|
233
|
+
}
|
|
234
|
+
let intersection = _.intersection(restoreCollections, collections);
|
|
235
|
+
if (intersection.length > 0) {
|
|
236
|
+
intersection = _.intersection(intersection, topicLabels);
|
|
237
|
+
for (let resource of intersection) {
|
|
238
|
+
const topicName = kafkaCfg[`${resource}.resource`].topic;
|
|
239
|
+
restoreEventSetup[topicName] = {
|
|
240
|
+
topic: await this.kafkaEvents.topic(topicName),
|
|
241
|
+
events: this.makeResourcesRestoreSetup(db, resource),
|
|
242
|
+
baseOffset: restoreSetup[resource].baseOffset,
|
|
243
|
+
ignoreOffset: restoreSetup[resource].ignoreOffset
|
|
244
|
+
};
|
|
173
245
|
}
|
|
174
|
-
}
|
|
246
|
+
}
|
|
175
247
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
// a label with the topic's name
|
|
179
|
-
const kafkaEventsCfg = this.config.get('events:kafka');
|
|
180
|
-
const kafkaCfg = this.config.get('events:kafka:topics');
|
|
181
|
-
if (_.isNil(kafkaCfg) || kafkaCfg.length == 0) {
|
|
182
|
-
return {
|
|
183
|
-
error: {
|
|
184
|
-
code: 500,
|
|
185
|
-
message: 'Kafka topics config not available'
|
|
186
|
-
}
|
|
187
|
-
};
|
|
248
|
+
if (_.isEmpty(restoreEventSetup)) {
|
|
249
|
+
this.logger.warn('No data was setup for the restore process.');
|
|
188
250
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
restoreSetup[data.entity] = {
|
|
205
|
-
baseOffset: Number(data.base_offset) || 0,
|
|
206
|
-
ignoreOffset
|
|
207
|
-
};
|
|
208
|
-
});
|
|
209
|
-
const restoreCollections = _.keys(restoreSetup);
|
|
210
|
-
try {
|
|
211
|
-
const dbCfgs = this.config.get('database');
|
|
212
|
-
const dbCfgNames = _.keys(dbCfgs);
|
|
213
|
-
for (let i = 0; i < dbCfgNames.length; i += 1) {
|
|
214
|
-
const dbCfgName = dbCfgNames[i];
|
|
215
|
-
const dbCfg = dbCfgs[dbCfgName];
|
|
216
|
-
const collections = dbCfg.collections;
|
|
217
|
-
let graphName, edgeConfigDefs;
|
|
218
|
-
if (this.config.get('graph')) {
|
|
219
|
-
graphName = this.config.get('graph:graphName');
|
|
220
|
-
edgeConfigDefs = this.config.get('graph:edgeDefinitions');
|
|
221
|
-
}
|
|
222
|
-
const db = yield database.get(dbCfg, this.logger, graphName, edgeConfigDefs);
|
|
223
|
-
if (_.isNil(collections)) {
|
|
224
|
-
this.logger.warn('No collections found on DB config');
|
|
225
|
-
return {};
|
|
226
|
-
}
|
|
227
|
-
let intersection = _.intersection(restoreCollections, collections);
|
|
228
|
-
if (intersection.length > 0) {
|
|
229
|
-
intersection = _.intersection(intersection, topicLabels);
|
|
230
|
-
for (let resource of intersection) {
|
|
231
|
-
const topicName = kafkaCfg[`${resource}.resource`].topic;
|
|
232
|
-
restoreEventSetup[topicName] = {
|
|
233
|
-
topic: yield this.kafkaEvents.topic(topicName),
|
|
234
|
-
events: this.makeResourcesRestoreSetup(db, resource),
|
|
235
|
-
baseOffset: restoreSetup[resource].baseOffset,
|
|
236
|
-
ignoreOffset: restoreSetup[resource].ignoreOffset
|
|
237
|
-
};
|
|
238
|
-
}
|
|
251
|
+
else {
|
|
252
|
+
const that = this;
|
|
253
|
+
// Start the restore process
|
|
254
|
+
this.logger.warn('restoring data');
|
|
255
|
+
for (let topicName in restoreEventSetup) {
|
|
256
|
+
const topicSetup = restoreEventSetup[topicName];
|
|
257
|
+
const restoreTopic = topicSetup.topic;
|
|
258
|
+
const topicEvents = topicSetup.events;
|
|
259
|
+
// saving listeners for potentially subscribed events on this topic,
|
|
260
|
+
// so they don't get called during the restore process
|
|
261
|
+
const previousEvents = _.cloneDeep(restoreTopic.subscribed);
|
|
262
|
+
const listenersBackup = new Map();
|
|
263
|
+
for (let event of previousEvents) {
|
|
264
|
+
listenersBackup.set(event, restoreTopic.emitter.listeners(event));
|
|
265
|
+
await restoreTopic.removeAllListeners(event);
|
|
239
266
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
this.
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
const ignoreOffsets = topicSetup.ignoreOffset;
|
|
264
|
-
const eventNames = _.keys(topicEvents);
|
|
265
|
-
this.logger.debug(`topic ${topicName} has current offset ${targetOffset}`);
|
|
266
|
-
const restoreGroupId = kafkaEventsCfg.groupId + '-restore-' + crypto.randomBytes(32).toString('hex');
|
|
267
|
-
const consumer = this.kafkaEvents.provider.client.consumer({
|
|
268
|
-
groupId: restoreGroupId
|
|
267
|
+
// const eventNames = _.keys(restoreTopic.events);
|
|
268
|
+
const baseOffset = topicSetup.baseOffset;
|
|
269
|
+
const targetOffset = (await restoreTopic.$offset(-1)) - 1;
|
|
270
|
+
const ignoreOffsets = topicSetup.ignoreOffset;
|
|
271
|
+
const eventNames = _.keys(topicEvents);
|
|
272
|
+
this.logger.debug(`topic ${topicName} has current offset ${targetOffset}`);
|
|
273
|
+
const restoreGroupId = kafkaEventsCfg.groupId + '-restore-' + crypto.randomBytes(32).toString('hex');
|
|
274
|
+
const consumer = this.kafkaEvents.provider.client.consumer({
|
|
275
|
+
groupId: restoreGroupId
|
|
276
|
+
});
|
|
277
|
+
const drainEvent = (message, done) => {
|
|
278
|
+
const msg = message.value;
|
|
279
|
+
const eventName = message.key.toString();
|
|
280
|
+
const context = _.pick(message, ['offset', 'partition', 'topic']);
|
|
281
|
+
const eventListener = topicEvents[message.key];
|
|
282
|
+
// decode protobuf
|
|
283
|
+
let decodedMsg = that.kafkaEvents.provider.decodeObject(kafkaEventsCfg, eventName, msg);
|
|
284
|
+
decodedMsg = _.pick(decodedMsg, _.keys(decodedMsg)); // preventing protobuf.js special fields
|
|
285
|
+
eventListener(decodedMsg, context, that.config.get(), eventName).then(() => {
|
|
286
|
+
done();
|
|
287
|
+
}).catch((err) => {
|
|
288
|
+
that.logger.error(`Exception caught invoking restore listener for event ${eventName}:`, err);
|
|
289
|
+
done(err);
|
|
269
290
|
});
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
let
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
that.logger.error(`Exception caught invoking restore listener for event ${eventName}:`, err);
|
|
282
|
-
done(err);
|
|
283
|
-
});
|
|
284
|
-
if (message.offset >= targetOffset) {
|
|
285
|
-
for (let event of eventNames) {
|
|
286
|
-
restoreTopic.removeAllListeners(event).then(() => { }).catch((err) => {
|
|
287
|
-
that.logger.error('Error removing listeners after restore', err);
|
|
291
|
+
if (message.offset >= targetOffset) {
|
|
292
|
+
for (let event of eventNames) {
|
|
293
|
+
restoreTopic.removeAllListeners(event).then(() => { }).catch((err) => {
|
|
294
|
+
that.logger.error('Error removing listeners after restore', err);
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
for (let event of previousEvents) {
|
|
298
|
+
const listeners = listenersBackup.get(event);
|
|
299
|
+
for (let listener of listeners) {
|
|
300
|
+
restoreTopic.on(event, listener).then(() => { }).catch((err) => {
|
|
301
|
+
that.logger.error('Error subscribing to listeners after restore', err);
|
|
288
302
|
});
|
|
289
303
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
that.
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
that.commandTopic.emit('restoreResponse', {
|
|
306
|
-
services: _.keys(that.service),
|
|
307
|
-
payload: that.encodeMsg(msg)
|
|
308
|
-
}).then(() => {
|
|
309
|
-
that.logger.info('Restore response emitted');
|
|
310
|
-
}).catch((err) => {
|
|
311
|
-
that.logger.error('Error emitting command response', err);
|
|
312
|
-
});
|
|
313
|
-
that.logger.info('restore process done');
|
|
314
|
-
}).catch(err => {
|
|
315
|
-
that.logger.error('Error deleting restore kafka group:', err);
|
|
304
|
+
}
|
|
305
|
+
consumer.stop().then(() => consumer.disconnect()).then(() => {
|
|
306
|
+
this.kafkaEvents.provider.admin.deleteGroups([restoreGroupId]).then(() => {
|
|
307
|
+
that.logger.debug('restore kafka group deleted');
|
|
308
|
+
const msg = {
|
|
309
|
+
topic: topicName,
|
|
310
|
+
offset: message.offset
|
|
311
|
+
};
|
|
312
|
+
that.commandTopic.emit('restoreResponse', {
|
|
313
|
+
services: _.keys(that.service),
|
|
314
|
+
payload: that.encodeMsg(msg)
|
|
315
|
+
}).then(() => {
|
|
316
|
+
that.logger.info('Restore response emitted');
|
|
317
|
+
}).catch((err) => {
|
|
318
|
+
that.logger.error('Error emitting command response', err);
|
|
316
319
|
});
|
|
320
|
+
that.logger.info('restore process done');
|
|
317
321
|
}).catch(err => {
|
|
318
|
-
that.logger.error('Error
|
|
322
|
+
that.logger.error('Error deleting restore kafka group:', err);
|
|
319
323
|
});
|
|
324
|
+
}).catch(err => {
|
|
325
|
+
that.logger.error('Error stopping consumer:', err);
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
const asyncQueue = that.startToReceiveRestoreMessages(restoreTopic, drainEvent);
|
|
330
|
+
await consumer.connect().catch(err => {
|
|
331
|
+
that.logger.error(`error connecting consumer:`, err);
|
|
332
|
+
throw err;
|
|
333
|
+
});
|
|
334
|
+
await consumer.subscribe({
|
|
335
|
+
topic: topicName,
|
|
336
|
+
});
|
|
337
|
+
await consumer.run({
|
|
338
|
+
eachMessage: async (payload) => {
|
|
339
|
+
if (payload.message.key.toString() in topicEvents && !_.includes(ignoreOffsets, parseInt(payload.message.offset))) {
|
|
340
|
+
asyncQueue.push(payload.message);
|
|
341
|
+
that.logger.debug(`received message ${payload.message.offset}/${targetOffset}`);
|
|
320
342
|
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
topic: topicName,
|
|
329
|
-
});
|
|
330
|
-
yield consumer.run({
|
|
331
|
-
eachMessage: (payload) => __awaiter(this, void 0, void 0, function* () {
|
|
332
|
-
if (payload.message.key.toString() in topicEvents && !_.includes(ignoreOffsets, parseInt(payload.message.offset))) {
|
|
333
|
-
asyncQueue.push(payload.message);
|
|
334
|
-
that.logger.debug(`received message ${payload.message.offset}/${targetOffset}`);
|
|
335
|
-
}
|
|
336
|
-
})
|
|
337
|
-
});
|
|
338
|
-
yield consumer.seek({
|
|
339
|
-
topic: topicName,
|
|
340
|
-
partition: 0,
|
|
341
|
-
offset: baseOffset.toString(10)
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
this.logger.debug('waiting until all messages are processed');
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
await consumer.seek({
|
|
346
|
+
topic: topicName,
|
|
347
|
+
partition: 0,
|
|
348
|
+
offset: baseOffset.toString(10)
|
|
349
|
+
});
|
|
345
350
|
}
|
|
351
|
+
this.logger.debug('waiting until all messages are processed');
|
|
346
352
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
})
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
}
|
|
353
|
+
}
|
|
354
|
+
catch (err) {
|
|
355
|
+
console.log('Err is...........', err);
|
|
356
|
+
this.logger.error('Error occurred while restoring the system', err.message);
|
|
357
|
+
await this.commandTopic.emit('restoreResponse', {
|
|
358
|
+
services: _.keys(this.service),
|
|
359
|
+
payload: this.encodeMsg({
|
|
360
|
+
error: err.message
|
|
361
|
+
})
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
return {};
|
|
359
365
|
}
|
|
360
366
|
startToReceiveRestoreMessages(restoreTopic, drainEvent) {
|
|
361
367
|
const asyncQueue = async.queue((msg, done) => {
|
|
@@ -382,202 +388,192 @@ class CommandInterface {
|
|
|
382
388
|
* Reset system data related to a service. Default implementation truncates
|
|
383
389
|
* a set of ArangoDB instances, using the chassis-srv database provider.
|
|
384
390
|
*/
|
|
385
|
-
reset() {
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
break;
|
|
407
|
-
}
|
|
391
|
+
async reset() {
|
|
392
|
+
this.logger.info('reset process started');
|
|
393
|
+
if (this.health.status !== ServingStatus.NOT_SERVING) {
|
|
394
|
+
this.logger.warn('reset process starting while server is serving');
|
|
395
|
+
}
|
|
396
|
+
let errorMsg = null;
|
|
397
|
+
try {
|
|
398
|
+
const dbCfgs = this.config.get('database');
|
|
399
|
+
const dbCfgNames = _.keys(dbCfgs);
|
|
400
|
+
for (let i = 0; i < dbCfgNames.length; i += 1) {
|
|
401
|
+
const dbCfgName = dbCfgNames[i];
|
|
402
|
+
const dbCfg = dbCfgs[dbCfgName];
|
|
403
|
+
const db = await database.get(dbCfg, this.logger);
|
|
404
|
+
switch (dbCfg.provider) {
|
|
405
|
+
case 'arango':
|
|
406
|
+
await db.truncate();
|
|
407
|
+
this.logger.info(`arangodb ${dbCfg.database} truncated`);
|
|
408
|
+
break;
|
|
409
|
+
default:
|
|
410
|
+
this.logger.error(`unsupported database provider ${dbCfg.provider} in database config ${dbCfgName}`);
|
|
411
|
+
break;
|
|
408
412
|
}
|
|
409
413
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
});
|
|
427
|
-
}
|
|
428
|
-
yield this.commandTopic.emit('resetResponse', eventObject);
|
|
429
|
-
this.logger.info('reset process ended');
|
|
430
|
-
if (errorMsg) {
|
|
431
|
-
return {
|
|
432
|
-
error: errorMsg
|
|
433
|
-
};
|
|
434
|
-
}
|
|
435
|
-
return {
|
|
414
|
+
}
|
|
415
|
+
catch (err) {
|
|
416
|
+
this.logger.error('Unexpected error while resetting the system', err.message);
|
|
417
|
+
errorMsg = err.message;
|
|
418
|
+
}
|
|
419
|
+
const eventObject = {
|
|
420
|
+
services: _.keys(this.service),
|
|
421
|
+
payload: null
|
|
422
|
+
};
|
|
423
|
+
if (errorMsg) {
|
|
424
|
+
eventObject.payload = this.encodeMsg({
|
|
425
|
+
error: errorMsg
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
eventObject.payload = this.encodeMsg({
|
|
436
430
|
status: 'Reset concluded successfully'
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
await this.commandTopic.emit('resetResponse', eventObject);
|
|
434
|
+
this.logger.info('reset process ended');
|
|
435
|
+
if (errorMsg) {
|
|
436
|
+
return {
|
|
437
|
+
error: errorMsg
|
|
437
438
|
};
|
|
438
|
-
}
|
|
439
|
+
}
|
|
440
|
+
return {
|
|
441
|
+
status: 'Reset concluded successfully'
|
|
442
|
+
};
|
|
439
443
|
}
|
|
440
444
|
/**
|
|
441
445
|
* Check the service status
|
|
442
446
|
* @param call List of services to be checked
|
|
443
447
|
* @param context
|
|
444
448
|
*/
|
|
445
|
-
check(payload) {
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
message: 'Invalid payload for restore command'
|
|
452
|
-
}
|
|
453
|
-
};
|
|
454
|
-
}
|
|
455
|
-
const serviceName = payload.service;
|
|
456
|
-
if (_.isNil(serviceName) || _.size(serviceName) === 0) {
|
|
457
|
-
yield this.commandTopic.emit('healthCheckResponse', {
|
|
458
|
-
services: _.keys(this.service),
|
|
459
|
-
payload: this.encodeMsg({
|
|
460
|
-
status: this.health.status,
|
|
461
|
-
})
|
|
462
|
-
});
|
|
463
|
-
return {
|
|
464
|
-
status: this.health.status,
|
|
465
|
-
};
|
|
466
|
-
}
|
|
467
|
-
const service = this.service[serviceName];
|
|
468
|
-
if (_.isNil(service)) {
|
|
469
|
-
const errorMsg = 'Service ' + serviceName + ' does not exist';
|
|
470
|
-
this.logger.warn(errorMsg);
|
|
471
|
-
return {
|
|
472
|
-
error: {
|
|
473
|
-
code: 404,
|
|
474
|
-
message: errorMsg
|
|
475
|
-
}
|
|
476
|
-
};
|
|
477
|
-
}
|
|
478
|
-
let status = ServingStatus.UNKNOWN;
|
|
479
|
-
// If one transports serves the service, set it to SERVING
|
|
480
|
-
_.forEach(service.transport, (transportStatus) => {
|
|
481
|
-
if (transportStatus === ServingStatus.SERVING) {
|
|
482
|
-
status = transportStatus;
|
|
449
|
+
async check(payload) {
|
|
450
|
+
if (_.isNil(payload)) {
|
|
451
|
+
return {
|
|
452
|
+
error: {
|
|
453
|
+
code: 400,
|
|
454
|
+
message: 'Invalid payload for restore command'
|
|
483
455
|
}
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
const serviceName = payload.service;
|
|
459
|
+
if (_.isNil(serviceName) || _.size(serviceName) === 0) {
|
|
460
|
+
await this.commandTopic.emit('healthCheckResponse', {
|
|
461
|
+
services: _.keys(this.service),
|
|
487
462
|
payload: this.encodeMsg({
|
|
488
|
-
status,
|
|
463
|
+
status: this.health.status,
|
|
489
464
|
})
|
|
490
465
|
});
|
|
491
466
|
return {
|
|
492
|
-
status,
|
|
467
|
+
status: this.health.status,
|
|
493
468
|
};
|
|
469
|
+
}
|
|
470
|
+
const service = this.service[serviceName];
|
|
471
|
+
if (_.isNil(service)) {
|
|
472
|
+
const errorMsg = 'Service ' + serviceName + ' does not exist';
|
|
473
|
+
this.logger.warn(errorMsg);
|
|
474
|
+
return {
|
|
475
|
+
error: {
|
|
476
|
+
code: 404,
|
|
477
|
+
message: errorMsg
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
let status = ServingStatus.UNKNOWN;
|
|
482
|
+
// If one transports serves the service, set it to SERVING
|
|
483
|
+
_.forEach(service.transport, (transportStatus) => {
|
|
484
|
+
if (transportStatus === ServingStatus.SERVING) {
|
|
485
|
+
status = transportStatus;
|
|
486
|
+
}
|
|
494
487
|
});
|
|
488
|
+
await this.commandTopic.emit('healthCheckResponse', {
|
|
489
|
+
services: [serviceName],
|
|
490
|
+
payload: this.encodeMsg({
|
|
491
|
+
status,
|
|
492
|
+
})
|
|
493
|
+
});
|
|
494
|
+
return {
|
|
495
|
+
status,
|
|
496
|
+
};
|
|
495
497
|
}
|
|
496
498
|
/**
|
|
497
499
|
* Retrieve current NPM package and Node version of service
|
|
498
500
|
*/
|
|
499
|
-
version() {
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
payload: this.encodeMsg(response)
|
|
508
|
-
});
|
|
509
|
-
return response;
|
|
501
|
+
async version() {
|
|
502
|
+
const response = {
|
|
503
|
+
nodejs: process.version,
|
|
504
|
+
version: process.env.npm_package_version,
|
|
505
|
+
};
|
|
506
|
+
await this.commandTopic.emit('versionResponse', {
|
|
507
|
+
services: _.keys(this.service),
|
|
508
|
+
payload: this.encodeMsg(response)
|
|
510
509
|
});
|
|
510
|
+
return response;
|
|
511
511
|
}
|
|
512
512
|
/**
|
|
513
513
|
* Update config for acs-client to disable it
|
|
514
514
|
* @param payload JSON object containing key value pairs for configuration
|
|
515
515
|
*/
|
|
516
|
-
configUpdate(payload) {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
message: 'Invalid payload for configUpdate command'
|
|
523
|
-
}
|
|
524
|
-
};
|
|
525
|
-
}
|
|
526
|
-
let response;
|
|
527
|
-
try {
|
|
528
|
-
let configProperties = Object.keys(payload);
|
|
529
|
-
for (let key of configProperties) {
|
|
530
|
-
this.config.set(key, payload[key]);
|
|
516
|
+
async configUpdate(payload) {
|
|
517
|
+
if (_.isNil(payload)) {
|
|
518
|
+
return {
|
|
519
|
+
error: {
|
|
520
|
+
code: 400,
|
|
521
|
+
message: 'Invalid payload for configUpdate command'
|
|
531
522
|
}
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
}
|
|
540
|
-
catch (error) {
|
|
541
|
-
this.logger.error('Error executing configUpdate Command', { message: error.message });
|
|
542
|
-
response = error.message;
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
let response;
|
|
526
|
+
try {
|
|
527
|
+
let configProperties = Object.keys(payload);
|
|
528
|
+
for (let key of configProperties) {
|
|
529
|
+
this.config.set(key, payload[key]);
|
|
543
530
|
}
|
|
544
|
-
|
|
545
|
-
|
|
531
|
+
response = {
|
|
532
|
+
status: 'Configuration updated successfully'
|
|
533
|
+
};
|
|
534
|
+
await this.commandTopic.emit('configUpdateResponse', {
|
|
535
|
+
services: _.keys(this.service),
|
|
536
|
+
payload: this.encodeMsg(response)
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
catch (error) {
|
|
540
|
+
this.logger.error('Error executing configUpdate Command', { message: error.message });
|
|
541
|
+
response = error.message;
|
|
542
|
+
}
|
|
543
|
+
return response;
|
|
546
544
|
}
|
|
547
545
|
/**
|
|
548
546
|
* Sets provided authentication apiKey on configuration
|
|
549
547
|
* @param payload JSON object containing key value pairs for authentication apiKey
|
|
550
548
|
*/
|
|
551
|
-
setApiKey(payload) {
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
message: 'Invalid payload for setApiKey command'
|
|
558
|
-
}
|
|
559
|
-
};
|
|
560
|
-
}
|
|
561
|
-
let response;
|
|
562
|
-
try {
|
|
563
|
-
let configProperties = Object.keys(payload);
|
|
564
|
-
for (let key of configProperties) {
|
|
565
|
-
this.config.set(key, payload[key]);
|
|
549
|
+
async setApiKey(payload) {
|
|
550
|
+
if (_.isNil(payload)) {
|
|
551
|
+
return {
|
|
552
|
+
error: {
|
|
553
|
+
code: 400,
|
|
554
|
+
message: 'Invalid payload for setApiKey command'
|
|
566
555
|
}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
}
|
|
575
|
-
catch (err) {
|
|
576
|
-
this.logger.error('Error executing setApiKey Command', { message: err.message });
|
|
577
|
-
response = err.message;
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
let response;
|
|
559
|
+
try {
|
|
560
|
+
let configProperties = Object.keys(payload);
|
|
561
|
+
for (let key of configProperties) {
|
|
562
|
+
this.config.set(key, payload[key]);
|
|
578
563
|
}
|
|
579
|
-
|
|
580
|
-
|
|
564
|
+
response = {
|
|
565
|
+
status: 'ApiKey set successfully'
|
|
566
|
+
};
|
|
567
|
+
await this.commandTopic.emit('setApiKeyResponse', {
|
|
568
|
+
services: _.keys(this.service),
|
|
569
|
+
payload: this.encodeMsg(response)
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
catch (err) {
|
|
573
|
+
this.logger.error('Error executing setApiKey Command', { message: err.message });
|
|
574
|
+
response = err.message;
|
|
575
|
+
}
|
|
576
|
+
return response;
|
|
581
577
|
}
|
|
582
578
|
/**
|
|
583
579
|
* Flush the cache based on DB index and prefix passed, if no dbIndex is passed
|
|
@@ -585,112 +581,110 @@ class CommandInterface {
|
|
|
585
581
|
*
|
|
586
582
|
* @param prefix An optional prefix to flush instead of entire cache
|
|
587
583
|
*/
|
|
588
|
-
flushCache(payload) {
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
584
|
+
async flushCache(payload) {
|
|
585
|
+
let flushCachePayload;
|
|
586
|
+
if (payload && payload.data) {
|
|
587
|
+
flushCachePayload = payload.data;
|
|
588
|
+
}
|
|
589
|
+
let dbIndex, pattern, response;
|
|
590
|
+
if (flushCachePayload) {
|
|
591
|
+
dbIndex = flushCachePayload.db_index;
|
|
592
|
+
pattern = flushCachePayload.pattern;
|
|
593
|
+
}
|
|
594
|
+
if (dbIndex === undefined || !dbIndex) {
|
|
595
|
+
dbIndex = 0;
|
|
596
|
+
}
|
|
597
|
+
// select the particular dbIndex
|
|
598
|
+
await this.redisClient.select(dbIndex);
|
|
599
|
+
try {
|
|
600
|
+
if (pattern != undefined) {
|
|
601
|
+
let flushPattern = '*' + pattern + '*';
|
|
602
|
+
this.logger.debug('Flushing cache wiht pattern', { dbIndex, flushPattern });
|
|
603
|
+
let stream, pipeline;
|
|
604
|
+
try {
|
|
605
|
+
stream = this.redisClient.scanStream({ match: flushPattern, count: 100 });
|
|
606
|
+
pipeline = this.redisClient.pipeline();
|
|
607
|
+
}
|
|
608
|
+
catch (err) {
|
|
609
|
+
this.logger.error('Error creating stream / pipeline in Redis', { message: err.message });
|
|
610
|
+
response = err.message;
|
|
611
|
+
}
|
|
612
|
+
let localKeys = [];
|
|
613
|
+
if (stream && pipeline) {
|
|
614
|
+
await new Promise((resolve, reject) => {
|
|
615
|
+
stream.on('data', (resultKeys) => {
|
|
616
|
+
this.logger.info('Data Received:', localKeys.length);
|
|
617
|
+
for (let i = 0; i < resultKeys.length; i++) {
|
|
618
|
+
localKeys.push(resultKeys[i]);
|
|
619
|
+
pipeline.del(resultKeys[i]);
|
|
620
|
+
}
|
|
621
|
+
if (localKeys.length > 100) {
|
|
622
|
+
pipeline.exec(() => { this.logger.info('one batch delete complete'); });
|
|
623
|
+
localKeys = [];
|
|
624
|
+
pipeline = this.redisClient.pipeline();
|
|
625
|
+
}
|
|
626
|
+
});
|
|
627
|
+
stream.on('end', () => {
|
|
628
|
+
pipeline.exec(() => { this.logger.info('final batch delete complete'); });
|
|
629
|
+
response = {
|
|
630
|
+
status: 'Successfully flushed cache pattern'
|
|
631
|
+
};
|
|
632
|
+
resolve(response);
|
|
633
|
+
});
|
|
634
|
+
stream.on('error', (err) => {
|
|
635
|
+
this.logger.error('error', err);
|
|
636
|
+
response = err.message;
|
|
637
|
+
resolve(err);
|
|
638
|
+
});
|
|
639
|
+
});
|
|
640
|
+
}
|
|
601
641
|
}
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
642
|
+
else {
|
|
643
|
+
this.logger.debug('Flushing cache', { dbIndex });
|
|
644
|
+
await new Promise((resolve, reject) => {
|
|
645
|
+
if (dbIndex || dbIndex === 0) {
|
|
646
|
+
// Flush all keys in the given dbIndex (flushDB)
|
|
647
|
+
this.redisClient.flushdb(async (err, reply) => {
|
|
648
|
+
if (err) {
|
|
649
|
+
this.logger.error('Failed flushing cache with DB index', { err, dbIndex });
|
|
650
|
+
return reject();
|
|
651
|
+
}
|
|
652
|
+
if (reply) {
|
|
653
|
+
this.logger.debug('Successfully flushed cache with DB index', { dbIndex });
|
|
654
|
+
response = {
|
|
655
|
+
status: `Successfully flushed cache with DB index ${dbIndex}`
|
|
656
|
+
};
|
|
657
|
+
return resolve(response);
|
|
658
|
+
}
|
|
659
|
+
});
|
|
616
660
|
}
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
this.logger.
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
if (localKeys.length > 100) {
|
|
627
|
-
pipeline.exec(() => { this.logger.info('one batch delete complete'); });
|
|
628
|
-
localKeys = [];
|
|
629
|
-
pipeline = this.redisClient.pipeline();
|
|
630
|
-
}
|
|
631
|
-
});
|
|
632
|
-
stream.on('end', () => {
|
|
633
|
-
pipeline.exec(() => { this.logger.info('final batch delete complete'); });
|
|
661
|
+
else {
|
|
662
|
+
// Flush Complete Redis Cache (flushAll)
|
|
663
|
+
this.redisClient.flushall(async (err, reply) => {
|
|
664
|
+
if (err) {
|
|
665
|
+
this.logger.error('Failed flushing complete cache', { err });
|
|
666
|
+
return reject();
|
|
667
|
+
}
|
|
668
|
+
if (reply) {
|
|
669
|
+
this.logger.debug('Successfully flushed complete cache');
|
|
634
670
|
response = {
|
|
635
|
-
status: 'Successfully flushed cache
|
|
671
|
+
status: 'Successfully flushed complete cache'
|
|
636
672
|
};
|
|
637
|
-
resolve(response);
|
|
638
|
-
}
|
|
639
|
-
stream.on('error', (err) => {
|
|
640
|
-
this.logger.error('error', err);
|
|
641
|
-
response = err.message;
|
|
642
|
-
resolve(err);
|
|
643
|
-
});
|
|
673
|
+
return resolve(response);
|
|
674
|
+
}
|
|
644
675
|
});
|
|
645
676
|
}
|
|
646
|
-
}
|
|
647
|
-
else {
|
|
648
|
-
this.logger.debug('Flushing cache', { dbIndex });
|
|
649
|
-
yield new Promise((resolve, reject) => {
|
|
650
|
-
if (dbIndex || dbIndex === 0) {
|
|
651
|
-
// Flush all keys in the given dbIndex (flushDB)
|
|
652
|
-
this.redisClient.flushdb((err, reply) => __awaiter(this, void 0, void 0, function* () {
|
|
653
|
-
if (err) {
|
|
654
|
-
this.logger.error('Failed flushing cache with DB index', { err, dbIndex });
|
|
655
|
-
return reject();
|
|
656
|
-
}
|
|
657
|
-
if (reply) {
|
|
658
|
-
this.logger.debug('Successfully flushed cache with DB index', { dbIndex });
|
|
659
|
-
response = {
|
|
660
|
-
status: `Successfully flushed cache with DB index ${dbIndex}`
|
|
661
|
-
};
|
|
662
|
-
return resolve(response);
|
|
663
|
-
}
|
|
664
|
-
}));
|
|
665
|
-
}
|
|
666
|
-
else {
|
|
667
|
-
// Flush Complete Redis Cache (flushAll)
|
|
668
|
-
this.redisClient.flushall((err, reply) => __awaiter(this, void 0, void 0, function* () {
|
|
669
|
-
if (err) {
|
|
670
|
-
this.logger.error('Failed flushing complete cache', { err });
|
|
671
|
-
return reject();
|
|
672
|
-
}
|
|
673
|
-
if (reply) {
|
|
674
|
-
this.logger.debug('Successfully flushed complete cache');
|
|
675
|
-
response = {
|
|
676
|
-
status: 'Successfully flushed complete cache'
|
|
677
|
-
};
|
|
678
|
-
return resolve(response);
|
|
679
|
-
}
|
|
680
|
-
}));
|
|
681
|
-
}
|
|
682
|
-
});
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
catch (err) {
|
|
686
|
-
response = err.message;
|
|
677
|
+
});
|
|
687
678
|
}
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
679
|
+
}
|
|
680
|
+
catch (err) {
|
|
681
|
+
response = err.message;
|
|
682
|
+
}
|
|
683
|
+
await this.commandTopic.emit('flushCacheResponse', {
|
|
684
|
+
services: _.keys(this.service),
|
|
685
|
+
payload: this.encodeMsg(response)
|
|
693
686
|
});
|
|
687
|
+
return response;
|
|
694
688
|
}
|
|
695
689
|
// Helper functions
|
|
696
690
|
/**
|
|
@@ -701,25 +695,19 @@ class CommandInterface {
|
|
|
701
695
|
makeResourcesRestoreSetup(db, resource) {
|
|
702
696
|
const that = this;
|
|
703
697
|
return {
|
|
704
|
-
[`${resource}Created`]: function restoreCreated(message, ctx, config, eventName) {
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
return {};
|
|
709
|
-
});
|
|
698
|
+
[`${resource}Created`]: async function restoreCreated(message, ctx, config, eventName) {
|
|
699
|
+
that.decodeBufferField(message, resource);
|
|
700
|
+
await db.insert(`${resource}s`, message);
|
|
701
|
+
return {};
|
|
710
702
|
},
|
|
711
|
-
[`${resource}Modified`]: function restoreModified(message, ctx, config, eventName) {
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
return {};
|
|
716
|
-
});
|
|
703
|
+
[`${resource}Modified`]: async function restoreModified(message, ctx, config, eventName) {
|
|
704
|
+
that.decodeBufferField(message, resource);
|
|
705
|
+
await db.update(`${resource}s`, { id: message.id }, _.omitBy(message, _.isNil));
|
|
706
|
+
return {};
|
|
717
707
|
},
|
|
718
|
-
[`${resource}Deleted`]: function restoreDeleted(message, ctx, config, eventName) {
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
return {};
|
|
722
|
-
});
|
|
708
|
+
[`${resource}Deleted`]: async function restoreDeleted(message, ctx, config, eventName) {
|
|
709
|
+
await db.delete(`${resource}s`, { id: message.id });
|
|
710
|
+
return {};
|
|
723
711
|
}
|
|
724
712
|
};
|
|
725
713
|
}
|