From 886cbeebaa249a5f0f8492234e341ade73ab64a2 Mon Sep 17 00:00:00 2001 From: Gidi Meir Morris Date: Mon, 27 Apr 2020 15:24:37 +0100 Subject: [PATCH] Revert "removed legacy task manager" This reverts commit a43d410d8a8c9d98ca550b1d54767b7c90165429. --- x-pack/index.js | 2 + x-pack/legacy/plugins/apm/index.ts | 8 ++- x-pack/legacy/plugins/task_manager/index.ts | 7 +++ .../plugins/task_manager/server/index.ts | 57 +++++++++++++++++ .../plugins/task_manager/server/legacy.ts | 58 +++++++++++++++++ x-pack/plugins/actions/server/plugin.ts | 14 ++--- x-pack/plugins/alerting/server/plugin.ts | 14 ++--- .../apm/server/lib/apm_telemetry/index.ts | 30 ++++----- .../server/create_task_manager.test.ts | 62 +++++++++++++++++++ .../server/create_task_manager.ts | 42 +++++++++++++ x-pack/plugins/task_manager/server/mocks.ts | 1 + x-pack/plugins/task_manager/server/plugin.ts | 62 +++++++++---------- .../task_manager/server/task_manager.mock.ts | 1 + .../sample_task_plugin/server/index.ts | 4 +- x-pack/typings/hapi.d.ts | 4 +- 15 files changed, 299 insertions(+), 67 deletions(-) create mode 100644 x-pack/legacy/plugins/task_manager/index.ts create mode 100644 x-pack/legacy/plugins/task_manager/server/index.ts create mode 100644 x-pack/legacy/plugins/task_manager/server/legacy.ts create mode 100644 x-pack/plugins/task_manager/server/create_task_manager.test.ts create mode 100644 x-pack/plugins/task_manager/server/create_task_manager.ts diff --git a/x-pack/index.js b/x-pack/index.js index 57b2a843b315b..64975bdc631cf 100644 --- a/x-pack/index.js +++ b/x-pack/index.js @@ -17,6 +17,7 @@ import { indexManagement } from './legacy/plugins/index_management'; import { spaces } from './legacy/plugins/spaces'; import { canvas } from './legacy/plugins/canvas'; import { infra } from './legacy/plugins/infra'; +import { taskManager } from './legacy/plugins/task_manager'; import { rollup } from './legacy/plugins/rollup'; import { siem } from './legacy/plugins/siem'; import { remoteClusters } from './legacy/plugins/remote_clusters'; @@ -40,6 +41,7 @@ module.exports = function(kibana) { canvas(kibana), indexManagement(kibana), infra(kibana), + taskManager(kibana), rollup(kibana), siem(kibana), remoteClusters(kibana), diff --git a/x-pack/legacy/plugins/apm/index.ts b/x-pack/legacy/plugins/apm/index.ts index 408530670cd95..d2383acd45eba 100644 --- a/x-pack/legacy/plugins/apm/index.ts +++ b/x-pack/legacy/plugins/apm/index.ts @@ -14,7 +14,13 @@ import mappings from './mappings.json'; export const apm: LegacyPluginInitializer = kibana => { return new kibana.Plugin({ - require: ['kibana', 'elasticsearch', 'xpack_main', 'apm_oss'], + require: [ + 'kibana', + 'elasticsearch', + 'xpack_main', + 'apm_oss', + 'task_manager' + ], id: 'apm', configPrefix: 'xpack.apm', publicDir: resolve(__dirname, 'public'), diff --git a/x-pack/legacy/plugins/task_manager/index.ts b/x-pack/legacy/plugins/task_manager/index.ts new file mode 100644 index 0000000000000..276d1ea3accea --- /dev/null +++ b/x-pack/legacy/plugins/task_manager/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export * from './server/'; diff --git a/x-pack/legacy/plugins/task_manager/server/index.ts b/x-pack/legacy/plugins/task_manager/server/index.ts new file mode 100644 index 0000000000000..af6aa69f68176 --- /dev/null +++ b/x-pack/legacy/plugins/task_manager/server/index.ts @@ -0,0 +1,57 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Root } from 'joi'; +import { Legacy } from 'kibana'; + +import { createLegacyApi, getTaskManagerSetup } from './legacy'; +export { LegacyTaskManagerApi, getTaskManagerSetup, getTaskManagerStart } from './legacy'; + +// Once all plugins are migrated to NP, this can be removed +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { TaskManager } from '../../../../plugins/task_manager/server/task_manager'; + +export function taskManager(kibana: any) { + return new kibana.Plugin({ + id: 'task_manager', + require: ['kibana', 'elasticsearch', 'xpack_main'], + configPrefix: 'xpack.task_manager', + config(Joi: Root) { + return Joi.object({ + enabled: Joi.boolean().default(true), + index: Joi.string() + .description('The name of the index used to store task information.') + .default('.kibana_task_manager') + .invalid(['.tasks']), + }) + .unknown(true) + .default(); + }, + init(server: Legacy.Server) { + /* + * We must expose the New Platform Task Manager Plugin via the legacy Api + * as removing it now would be a breaking change - we'll remove this in v8.0.0 + */ + server.expose( + createLegacyApi( + getTaskManagerSetup(server)! + .registerLegacyAPI() + .then((taskManagerPlugin: TaskManager) => { + // we can't tell the Kibana Platform Task Manager plugin to + // to wait to `start` as that happens before legacy plugins + // instead we will start the internal Task Manager plugin when + // all legacy plugins have finished initializing + // Once all plugins are migrated to NP, this can be removed + this.kbnServer.afterPluginsInit(() => { + taskManagerPlugin.start(); + }); + return taskManagerPlugin; + }) + ) + ); + }, + }); +} diff --git a/x-pack/legacy/plugins/task_manager/server/legacy.ts b/x-pack/legacy/plugins/task_manager/server/legacy.ts new file mode 100644 index 0000000000000..cd2047b757e61 --- /dev/null +++ b/x-pack/legacy/plugins/task_manager/server/legacy.ts @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Server } from 'src/legacy/server/kbn_server'; +import { + TaskManagerSetupContract, + TaskManagerStartContract, +} from '../../../../plugins/task_manager/server'; + +import { Middleware } from '../../../../plugins/task_manager/server/lib/middleware.js'; +import { + TaskDictionary, + TaskInstanceWithDeprecatedFields, + TaskInstanceWithId, + TaskDefinition, +} from '../../../../plugins/task_manager/server/task.js'; +import { SearchOpts } from '../../../../plugins/task_manager/server/task_store.js'; + +// Once all plugins are migrated to NP and we can remove Legacy TaskManager in version 8.0.0, +// this can be removed +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { TaskManager } from '../../../../plugins/task_manager/server/task_manager'; + +export type LegacyTaskManagerApi = Pick< + TaskManagerSetupContract, + 'addMiddleware' | 'registerTaskDefinitions' +> & + TaskManagerStartContract; + +export function getTaskManagerSetup(server: Server): TaskManagerSetupContract | undefined { + return server?.newPlatform?.setup?.plugins?.taskManager as TaskManagerSetupContract; +} + +export function getTaskManagerStart(server: Server): TaskManagerStartContract | undefined { + return server?.newPlatform?.start?.plugins?.taskManager as TaskManagerStartContract; +} + +export function createLegacyApi(legacyTaskManager: Promise): LegacyTaskManagerApi { + return { + addMiddleware: (middleware: Middleware) => { + legacyTaskManager.then((tm: TaskManager) => tm.addMiddleware(middleware)); + }, + registerTaskDefinitions: (taskDefinitions: TaskDictionary) => { + legacyTaskManager.then((tm: TaskManager) => tm.registerTaskDefinitions(taskDefinitions)); + }, + fetch: (opts: SearchOpts) => legacyTaskManager.then((tm: TaskManager) => tm.fetch(opts)), + get: (id: string) => legacyTaskManager.then((tm: TaskManager) => tm.get(id)), + remove: (id: string) => legacyTaskManager.then((tm: TaskManager) => tm.remove(id)), + schedule: (taskInstance: TaskInstanceWithDeprecatedFields, options?: any) => + legacyTaskManager.then((tm: TaskManager) => tm.schedule(taskInstance, options)), + runNow: (taskId: string) => legacyTaskManager.then((tm: TaskManager) => tm.runNow(taskId)), + ensureScheduled: (taskInstance: TaskInstanceWithId, options?: any) => + legacyTaskManager.then((tm: TaskManager) => tm.ensureScheduled(taskInstance, options)), + }; +} diff --git a/x-pack/plugins/actions/server/plugin.ts b/x-pack/plugins/actions/server/plugin.ts index b0ff315ac0765..b12e289fcbcf7 100644 --- a/x-pack/plugins/actions/server/plugin.ts +++ b/x-pack/plugins/actions/server/plugin.ts @@ -171,15 +171,15 @@ export class ActionsPlugin implements Plugin, Plugi const usageCollection = plugins.usageCollection; if (usageCollection) { - initializeActionsTelemetry( - this.telemetryLogger, - plugins.taskManager, - core, - await this.kibanaIndex - ); - core.getStartServices().then(async ([, startPlugins]: [CoreStart, any, any]) => { registerActionsUsageCollector(usageCollection, startPlugins.taskManager); + + initializeActionsTelemetry( + this.telemetryLogger, + plugins.taskManager, + core, + await this.kibanaIndex + ); }); } diff --git a/x-pack/plugins/alerting/server/plugin.ts b/x-pack/plugins/alerting/server/plugin.ts index c80eab1373c23..f5bef134a5b96 100644 --- a/x-pack/plugins/alerting/server/plugin.ts +++ b/x-pack/plugins/alerting/server/plugin.ts @@ -148,15 +148,15 @@ export class AlertingPlugin { const usageCollection = plugins.usageCollection; if (usageCollection) { - initializeAlertingTelemetry( - this.telemetryLogger, - core, - plugins.taskManager, - await this.kibanaIndex - ); - core.getStartServices().then(async ([, startPlugins]: [CoreStart, any, any]) => { registerAlertsUsageCollector(usageCollection, startPlugins.taskManager); + + initializeAlertingTelemetry( + this.telemetryLogger, + core, + plugins.taskManager, + await this.kibanaIndex + ); }); } diff --git a/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts b/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts index c4b5dc868c37e..3eb61bb130725 100644 --- a/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts +++ b/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts @@ -38,21 +38,6 @@ export async function createApmTelemetry({ taskManager: TaskManagerSetupContract; logger: Logger; }) { - taskManager.registerTaskDefinitions({ - [APM_TELEMETRY_TASK_NAME]: { - title: 'Collect APM telemetry', - type: APM_TELEMETRY_TASK_NAME, - createTaskRunner: () => { - return { - run: async () => { - await collectAndStore(); - }, - cancel: async () => {} - }; - } - } - }); - const savedObjectsClient = await getInternalSavedObjectsClient(core); const collectAndStore = async () => { @@ -94,6 +79,21 @@ export async function createApmTelemetry({ ); }; + taskManager.registerTaskDefinitions({ + [APM_TELEMETRY_TASK_NAME]: { + title: 'Collect APM telemetry', + type: APM_TELEMETRY_TASK_NAME, + createTaskRunner: () => { + return { + run: async () => { + await collectAndStore(); + }, + cancel: async () => {} + }; + } + } + }); + const collector = usageCollector.makeUsageCollector({ type: 'apm', fetch: async () => { diff --git a/x-pack/plugins/task_manager/server/create_task_manager.test.ts b/x-pack/plugins/task_manager/server/create_task_manager.test.ts new file mode 100644 index 0000000000000..133cfcac4c046 --- /dev/null +++ b/x-pack/plugins/task_manager/server/create_task_manager.test.ts @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { createTaskManager, LegacyDeps } from './create_task_manager'; +import { mockLogger } from './test_utils'; +import { CoreSetup, SavedObjectsSerializer, UuidServiceSetup } from '../../../../src/core/server'; +import { + savedObjectsRepositoryMock, + savedObjectsTypeRegistryMock, +} from '../../../../src/core/server/mocks'; + +jest.mock('./task_manager'); + +describe('createTaskManager', () => { + const uuid: UuidServiceSetup = { + getInstanceUuid() { + return 'some-uuid'; + }, + }; + const mockCoreSetup = { + uuid, + } as CoreSetup; + + const getMockLegacyDeps = (): LegacyDeps => ({ + config: {}, + savedObjectsSerializer: new SavedObjectsSerializer(savedObjectsTypeRegistryMock.create()), + elasticsearch: { + callAsInternalUser: jest.fn(), + }, + savedObjectsRepository: savedObjectsRepositoryMock.create(), + logger: mockLogger(), + }); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + test('exposes the underlying TaskManager', async () => { + const mockLegacyDeps = getMockLegacyDeps(); + const setupResult = createTaskManager(mockCoreSetup, mockLegacyDeps); + expect(setupResult).toMatchInlineSnapshot(` + TaskManager { + "addMiddleware": [MockFunction], + "assertUninitialized": [MockFunction], + "attemptToRun": [MockFunction], + "ensureScheduled": [MockFunction], + "fetch": [MockFunction], + "get": [MockFunction], + "registerTaskDefinitions": [MockFunction], + "remove": [MockFunction], + "runNow": [MockFunction], + "schedule": [MockFunction], + "start": [MockFunction], + "stop": [MockFunction], + "waitUntilStarted": [MockFunction], + } + `); + }); +}); diff --git a/x-pack/plugins/task_manager/server/create_task_manager.ts b/x-pack/plugins/task_manager/server/create_task_manager.ts new file mode 100644 index 0000000000000..9ff97bbcc17e6 --- /dev/null +++ b/x-pack/plugins/task_manager/server/create_task_manager.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + IClusterClient, + SavedObjectsSerializer, + CoreSetup, + ISavedObjectsRepository, +} from '../../../../src/core/server'; +import { TaskManager } from './task_manager'; +import { Logger } from './types'; + +export interface LegacyDeps { + config: any; + elasticsearch: Pick; + savedObjectsRepository: ISavedObjectsRepository; + savedObjectsSerializer: SavedObjectsSerializer; + logger: Logger; +} + +export function createTaskManager( + core: CoreSetup, + { + logger, + config, + elasticsearch: { callAsInternalUser }, + savedObjectsRepository, + savedObjectsSerializer, + }: LegacyDeps +) { + return new TaskManager({ + taskManagerId: core.uuid.getInstanceUuid(), + config, + savedObjectsRepository, + serializer: savedObjectsSerializer, + callAsInternalUser, + logger, + }); +} diff --git a/x-pack/plugins/task_manager/server/mocks.ts b/x-pack/plugins/task_manager/server/mocks.ts index 4a78a0b49001b..8ec05dd1bd401 100644 --- a/x-pack/plugins/task_manager/server/mocks.ts +++ b/x-pack/plugins/task_manager/server/mocks.ts @@ -8,6 +8,7 @@ import { TaskManagerSetupContract, TaskManagerStartContract } from './plugin'; const createSetupMock = () => { const mock: jest.Mocked = { + registerLegacyAPI: jest.fn(), addMiddleware: jest.fn(), registerTaskDefinitions: jest.fn(), }; diff --git a/x-pack/plugins/task_manager/server/plugin.ts b/x-pack/plugins/task_manager/server/plugin.ts index 4295dbf912c4c..843347d26ecc5 100644 --- a/x-pack/plugins/task_manager/server/plugin.ts +++ b/x-pack/plugins/task_manager/server/plugin.ts @@ -3,19 +3,20 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { PluginInitializerContext, Plugin, CoreSetup, CoreStart } from 'src/core/server'; +import { PluginInitializerContext, Plugin, CoreSetup } from 'src/core/server'; import { Subject } from 'rxjs'; import { first } from 'rxjs/operators'; +import { once } from 'lodash'; import { TaskDictionary, TaskDefinition } from './task'; import { TaskManager } from './task_manager'; +import { createTaskManager } from './create_task_manager'; import { TaskManagerConfig } from './config'; import { Middleware } from './lib/middleware'; import { setupSavedObjects } from './saved_objects'; -export type TaskManagerSetupContract = Pick< - TaskManager, - 'addMiddleware' | 'registerTaskDefinitions' ->; +export type TaskManagerSetupContract = { + registerLegacyAPI: () => Promise; +} & Pick; export type TaskManagerStartContract = Pick< TaskManager, @@ -27,24 +28,39 @@ export class TaskManagerPlugin legacyTaskManager$: Subject = new Subject(); taskManager: Promise = this.legacyTaskManager$.pipe(first()).toPromise(); currentConfig: TaskManagerConfig; - taskManagerId?: string; - config?: TaskManagerConfig; constructor(private readonly initContext: PluginInitializerContext) { this.initContext = initContext; this.currentConfig = {} as TaskManagerConfig; } - public async setup(core: CoreSetup): Promise { - this.config = await this.initContext.config + public async setup(core: CoreSetup, plugins: any): Promise { + const logger = this.initContext.logger.get('taskManager'); + const config = await this.initContext.config .create() .pipe(first()) .toPromise(); - setupSavedObjects(core.savedObjects, this.config); - this.taskManagerId = core.uuid.getInstanceUuid(); + setupSavedObjects(core.savedObjects, config); return { + registerLegacyAPI: once(() => { + (async () => { + const [{ savedObjects, elasticsearch }] = await core.getStartServices(); + const savedObjectsRepository = savedObjects.createInternalRepository(['task']); + this.legacyTaskManager$.next( + createTaskManager(core, { + logger, + config, + elasticsearch: elasticsearch.legacy.client, + savedObjectsRepository, + savedObjectsSerializer: savedObjects.createSerializer(), + }) + ); + this.legacyTaskManager$.complete(); + })(); + return this.taskManager; + }), addMiddleware: (middleware: Middleware) => { this.taskManager.then(tm => tm.addMiddleware(middleware)); }, @@ -54,29 +70,7 @@ export class TaskManagerPlugin }; } - public start({ savedObjects, elasticsearch }: CoreStart): TaskManagerStartContract { - const logger = this.initContext.logger.get('taskManager'); - const savedObjectsRepository = savedObjects.createInternalRepository(['task']); - - this.legacyTaskManager$.next( - new TaskManager({ - taskManagerId: this.taskManagerId!, - config: this.config!, - savedObjectsRepository, - serializer: savedObjects.createSerializer(), - callAsInternalUser: elasticsearch.legacy.client.callAsInternalUser, - logger, - }) - ); - this.legacyTaskManager$.complete(); - - // we need to "drain" any calls made to the seup API - // before `starting` TaskManager. This is a legacy relic - // of the old API that should be resolved once we split - // Task manager into two services, setup and start, instead - // of the single instance of TaskManager - this.taskManager.then(tm => tm.start()); - + public start(): TaskManagerStartContract { return { fetch: (...args) => this.taskManager.then(tm => tm.fetch(...args)), get: (...args) => this.taskManager.then(tm => tm.get(...args)), diff --git a/x-pack/plugins/task_manager/server/task_manager.mock.ts b/x-pack/plugins/task_manager/server/task_manager.mock.ts index 1fc626e7d58d6..1be1a81cdeb68 100644 --- a/x-pack/plugins/task_manager/server/task_manager.mock.ts +++ b/x-pack/plugins/task_manager/server/task_manager.mock.ts @@ -11,6 +11,7 @@ export const taskManagerMock = { const mocked: jest.Mocked = { registerTaskDefinitions: jest.fn(), addMiddleware: jest.fn(), + registerLegacyAPI: jest.fn(), ...overrides, }; return mocked; diff --git a/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/index.ts b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/index.ts index 77233f463734a..55eb15d32a127 100644 --- a/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/index.ts +++ b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/index.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { PluginInitializerContext } from 'kibana/server'; import { SampleTaskManagerFixturePlugin } from './plugin'; -export const plugin = () => new SampleTaskManagerFixturePlugin(); +export const plugin = (initContext: PluginInitializerContext) => + new SampleTaskManagerFixturePlugin(initContext); diff --git a/x-pack/typings/hapi.d.ts b/x-pack/typings/hapi.d.ts index f4e8ca1103b04..872e042eb1cdb 100644 --- a/x-pack/typings/hapi.d.ts +++ b/x-pack/typings/hapi.d.ts @@ -10,7 +10,7 @@ import { XPackMainPlugin } from '../legacy/plugins/xpack_main/server/xpack_main' import { SecurityPlugin } from '../legacy/plugins/security'; import { ActionsPlugin, ActionsClient } from '../plugins/actions/server'; import { AlertingPlugin, AlertsClient } from '../plugins/alerting/server'; -import { TaskManagerStartContract } from '../plugins/task_manager/server'; +import { LegacyTaskManagerApi } from '../legacy/plugins/task_manager/server'; declare module 'hapi' { interface Request { @@ -22,6 +22,6 @@ declare module 'hapi' { security?: SecurityPlugin; actions?: ActionsPlugin; alerting?: AlertingPlugin; - task_manager?: TaskManagerStartContract; + task_manager?: LegacyTaskManagerApi; } }