|
8 | 8 | /* eslint-disable max-classes-per-file */
|
9 | 9 |
|
10 | 10 | import { SavedObject } from '@kbn/core/server';
|
11 |
| -import { KibanaRequest, Logger } from '@kbn/core/server'; |
| 11 | +import { Logger } from '@kbn/core/server'; |
12 | 12 | import {
|
13 | 13 | ConcreteTaskInstance,
|
14 | 14 | TaskManagerSetupContract,
|
15 | 15 | TaskManagerStartContract,
|
16 | 16 | TaskInstance,
|
17 | 17 | } from '@kbn/task-manager-plugin/server';
|
| 18 | +import { Subject } from 'rxjs'; |
18 | 19 | import { sendErrorTelemetryEvents } from '../routes/telemetry/monitor_upgrade_sender';
|
19 | 20 | import { UptimeServerSetup } from '../legacy_uptime/lib/adapters';
|
20 | 21 | import { installSyntheticsIndexTemplates } from '../routes/synthetics_service/install_index_templates';
|
@@ -170,7 +171,7 @@ export class SyntheticsService {
|
170 | 171 |
|
171 | 172 | if (service.isAllowed) {
|
172 | 173 | service.setupIndexTemplates();
|
173 |
| - service.syncErrors = await service.pushConfigs(); |
| 174 | + await service.pushConfigs(); |
174 | 175 | }
|
175 | 176 | } catch (e) {
|
176 | 177 | sendErrorTelemetryEvents(service.logger, service.server.telemetry, {
|
@@ -306,65 +307,44 @@ export class SyntheticsService {
|
306 | 307 | }
|
307 | 308 | }
|
308 | 309 |
|
309 |
| - async pushConfigs(configs?: HeartbeatConfig[], isEdit?: boolean) { |
310 |
| - const monitorConfigs = configs ?? (await this.getMonitorConfigs()); |
311 |
| - const monitors = this.formatConfigs(monitorConfigs); |
312 |
| - |
313 |
| - if (monitors.length === 0) { |
314 |
| - this.logger.debug('No monitor found which can be pushed to service.'); |
315 |
| - return null; |
316 |
| - } |
317 |
| - |
318 |
| - this.apiKey = await this.getApiKey(); |
319 |
| - |
320 |
| - if (!this.apiKey) { |
321 |
| - return null; |
322 |
| - } |
| 310 | + async pushConfigs() { |
| 311 | + const service = this; |
| 312 | + const subject = new Subject<SyntheticsMonitorWithId[]>(); |
323 | 313 |
|
324 |
| - const data = { |
325 |
| - monitors, |
326 |
| - output: await this.getOutput(this.apiKey), |
327 |
| - isEdit: !!isEdit, |
328 |
| - }; |
| 314 | + subject.subscribe(async (monitorConfigs) => { |
| 315 | + const monitors = this.formatConfigs(monitorConfigs); |
329 | 316 |
|
330 |
| - this.logger.debug(`${monitors.length} monitors will be pushed to synthetics service.`); |
| 317 | + if (monitors.length === 0) { |
| 318 | + this.logger.debug('No monitor found which can be pushed to service.'); |
| 319 | + return null; |
| 320 | + } |
331 | 321 |
|
332 |
| - try { |
333 |
| - this.syncErrors = await this.apiClient.put(data); |
334 |
| - return this.syncErrors; |
335 |
| - } catch (e) { |
336 |
| - this.logger.error(e); |
337 |
| - throw e; |
338 |
| - } |
339 |
| - } |
| 322 | + this.apiKey = await this.getApiKey(); |
340 | 323 |
|
341 |
| - async runOnceConfigs(configs?: HeartbeatConfig[]) { |
342 |
| - const monitors = this.formatConfigs(configs || (await this.getMonitorConfigs())); |
343 |
| - if (monitors.length === 0) { |
344 |
| - return; |
345 |
| - } |
| 324 | + if (!this.apiKey) { |
| 325 | + return null; |
| 326 | + } |
346 | 327 |
|
347 |
| - this.apiKey = await this.getApiKey(); |
| 328 | + const data = { |
| 329 | + monitors, |
| 330 | + output: await this.getOutput(this.apiKey), |
| 331 | + }; |
348 | 332 |
|
349 |
| - if (!this.apiKey) { |
350 |
| - return null; |
351 |
| - } |
| 333 | + this.logger.debug(`${monitors.length} monitors will be pushed to synthetics service.`); |
352 | 334 |
|
353 |
| - const data = { |
354 |
| - monitors, |
355 |
| - output: await this.getOutput(this.apiKey), |
356 |
| - }; |
| 335 | + try { |
| 336 | + service.syncErrors = await this.apiClient.put(data); |
| 337 | + } catch (e) { |
| 338 | + this.logger.error(e); |
| 339 | + throw e; |
| 340 | + } |
| 341 | + }); |
357 | 342 |
|
358 |
| - try { |
359 |
| - return await this.apiClient.runOnce(data); |
360 |
| - } catch (e) { |
361 |
| - this.logger.error(e); |
362 |
| - throw e; |
363 |
| - } |
| 343 | + await this.getMonitorConfigs(subject); |
364 | 344 | }
|
365 | 345 |
|
366 |
| - async triggerConfigs(request?: KibanaRequest, configs?: HeartbeatConfig[]) { |
367 |
| - const monitors = this.formatConfigs(configs || (await this.getMonitorConfigs())); |
| 346 | + async runOnceConfigs(configs: HeartbeatConfig[]) { |
| 347 | + const monitors = this.formatConfigs(configs); |
368 | 348 | if (monitors.length === 0) {
|
369 | 349 | return;
|
370 | 350 | }
|
@@ -401,81 +381,92 @@ export class SyntheticsService {
|
401 | 381 | };
|
402 | 382 | const result = await this.apiClient.delete(data);
|
403 | 383 | if (this.syncErrors && this.syncErrors?.length > 0) {
|
404 |
| - this.syncErrors = await this.pushConfigs(); |
| 384 | + await this.pushConfigs(); |
405 | 385 | }
|
406 | 386 | return result;
|
407 | 387 | }
|
408 | 388 |
|
409 | 389 | async deleteAllConfigs() {
|
410 |
| - const configs = await this.getMonitorConfigs(); |
411 |
| - return await this.deleteConfigs(configs); |
| 390 | + const subject = new Subject<SyntheticsMonitorWithId[]>(); |
| 391 | + |
| 392 | + subject.subscribe(async (monitors) => { |
| 393 | + await this.deleteConfigs(monitors); |
| 394 | + }); |
| 395 | + |
| 396 | + await this.getMonitorConfigs(subject); |
412 | 397 | }
|
413 | 398 |
|
414 |
| - async getMonitorConfigs() { |
415 |
| - const savedObjectsClient = this.server.savedObjectsClient; |
| 399 | + async getMonitorConfigs(subject: Subject<SyntheticsMonitorWithId[]>) { |
| 400 | + const soClient = this.server.savedObjectsClient; |
416 | 401 | const encryptedClient = this.server.encryptedSavedObjects.getClient();
|
417 | 402 |
|
418 |
| - if (!savedObjectsClient?.find) { |
| 403 | + if (!soClient?.find) { |
419 | 404 | return [] as SyntheticsMonitorWithId[];
|
420 | 405 | }
|
421 | 406 |
|
422 |
| - const { saved_objects: encryptedMonitors } = await savedObjectsClient.find<SyntheticsMonitor>({ |
| 407 | + const finder = soClient.createPointInTimeFinder({ |
423 | 408 | type: syntheticsMonitorType,
|
| 409 | + perPage: 500, |
424 | 410 | namespaces: ['*'],
|
425 |
| - perPage: 10000, |
426 | 411 | });
|
427 | 412 |
|
428 | 413 | const start = performance.now();
|
429 | 414 |
|
430 |
| - const monitors: Array<SavedObject<SyntheticsMonitorWithSecrets>> = ( |
431 |
| - await Promise.all( |
432 |
| - encryptedMonitors.map( |
433 |
| - (monitor) => |
434 |
| - new Promise((resolve) => { |
435 |
| - encryptedClient |
436 |
| - .getDecryptedAsInternalUser<SyntheticsMonitorWithSecrets>( |
437 |
| - syntheticsMonitor.name, |
438 |
| - monitor.id, |
439 |
| - { |
440 |
| - namespace: monitor.namespaces?.[0], |
441 |
| - } |
442 |
| - ) |
443 |
| - .then((decryptedMonitor) => resolve(decryptedMonitor)) |
444 |
| - .catch((e) => { |
445 |
| - this.logger.error(e); |
446 |
| - sendErrorTelemetryEvents(this.logger, this.server.telemetry, { |
447 |
| - reason: 'Failed to decrypt monitor', |
448 |
| - message: e?.message, |
449 |
| - type: 'runTaskError', |
450 |
| - code: e?.code, |
451 |
| - status: e.status, |
452 |
| - kibanaVersion: this.server.kibanaVersion, |
| 415 | + for await (const result of finder.find()) { |
| 416 | + const encryptedMonitors = result.saved_objects; |
| 417 | + |
| 418 | + const monitors: Array<SavedObject<SyntheticsMonitorWithSecrets>> = ( |
| 419 | + await Promise.all( |
| 420 | + encryptedMonitors.map( |
| 421 | + (monitor) => |
| 422 | + new Promise((resolve) => { |
| 423 | + encryptedClient |
| 424 | + .getDecryptedAsInternalUser<SyntheticsMonitorWithSecrets>( |
| 425 | + syntheticsMonitor.name, |
| 426 | + monitor.id, |
| 427 | + { |
| 428 | + namespace: monitor.namespaces?.[0], |
| 429 | + } |
| 430 | + ) |
| 431 | + .then((decryptedMonitor) => resolve(decryptedMonitor)) |
| 432 | + .catch((e) => { |
| 433 | + this.logger.error(e); |
| 434 | + sendErrorTelemetryEvents(this.logger, this.server.telemetry, { |
| 435 | + reason: 'Failed to decrypt monitor', |
| 436 | + message: e?.message, |
| 437 | + type: 'runTaskError', |
| 438 | + code: e?.code, |
| 439 | + status: e.status, |
| 440 | + kibanaVersion: this.server.kibanaVersion, |
| 441 | + }); |
| 442 | + resolve(null); |
453 | 443 | });
|
454 |
| - resolve(null); |
455 |
| - }); |
456 |
| - }) |
| 444 | + }) |
| 445 | + ) |
457 | 446 | )
|
458 |
| - ) |
459 |
| - ).filter((monitor) => monitor !== null) as Array<SavedObject<SyntheticsMonitorWithSecrets>>; |
460 |
| - |
461 |
| - const end = performance.now(); |
462 |
| - const duration = end - start; |
| 447 | + ).filter((monitor) => monitor !== null) as Array<SavedObject<SyntheticsMonitorWithSecrets>>; |
463 | 448 |
|
464 |
| - this.logger.debug(`Decrypted ${monitors.length} monitors. Took ${duration} milliseconds`, { |
465 |
| - event: { |
466 |
| - duration, |
467 |
| - }, |
468 |
| - monitors: monitors.length, |
469 |
| - }); |
| 449 | + const end = performance.now(); |
| 450 | + const duration = end - start; |
470 | 451 |
|
471 |
| - return (monitors ?? []).map((monitor) => { |
472 |
| - const attributes = monitor.attributes as unknown as MonitorFields; |
473 |
| - return formatHeartbeatRequest({ |
474 |
| - monitor: normalizeSecrets(monitor).attributes, |
475 |
| - monitorId: monitor.id, |
476 |
| - customHeartbeatId: attributes[ConfigKey.CUSTOM_HEARTBEAT_ID], |
| 452 | + this.logger.debug(`Decrypted ${monitors.length} monitors. Took ${duration} milliseconds`, { |
| 453 | + event: { |
| 454 | + duration, |
| 455 | + }, |
| 456 | + monitors: monitors.length, |
477 | 457 | });
|
478 |
| - }); |
| 458 | + |
| 459 | + subject.next( |
| 460 | + (monitors ?? []).map((monitor) => { |
| 461 | + const attributes = monitor.attributes as unknown as MonitorFields; |
| 462 | + return formatHeartbeatRequest({ |
| 463 | + monitor: normalizeSecrets(monitor).attributes, |
| 464 | + monitorId: monitor.id, |
| 465 | + customHeartbeatId: attributes[ConfigKey.CUSTOM_HEARTBEAT_ID], |
| 466 | + }); |
| 467 | + }) |
| 468 | + ); |
| 469 | + } |
479 | 470 | }
|
480 | 471 |
|
481 | 472 | formatConfigs(configs: SyntheticsMonitorWithId[]) {
|
|
0 commit comments