diff --git a/src/core_plugins/task_manager/index.ts b/src/core_plugins/task_manager/index.ts deleted file mode 100644 index f1a4d57fe22b8..0000000000000 --- a/src/core_plugins/task_manager/index.ts +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import Joi from 'joi'; -import { - Logger, - TaskDefinition, - TaskDictionary, - TaskManager, - TaskPool, - TaskStore, - validateTaskDefinition, -} from './task_pool'; -import { SanitizedTaskDefinition } from './task_pool/task'; - -// tslint:disable-next-line:no-default-export -export default function taskManager(kibana: any) { - return new kibana.Plugin({ - id: 'taskManager', - - configPrefix: 'task_manager', - - require: ['kibana', 'elasticsearch'], - - config() { - return Joi.object({ - enabled: Joi.boolean().default(true), - max_attempts: Joi.number() - .description( - 'The maximum number of times a task will be attempted before being abandoned as failed' - ) - .default(3), - poll_interval: Joi.number() - .description('How often, in milliseconds, the task manager will look for more work.') - .default(3000), - index: Joi.string() - .description('The name of the index used to store task information.') - .default('.kibana_task_manager'), - num_workers: Joi.number() - .description( - 'The maximum number of tasks that this Kibana instance will run simultaneously.' - ) - .default(10), - }).default(); - }, - - async init(server: any) { - const config = server.config(); - const logger = new Logger((...args) => server.log(...args)); - const callCluster = server.plugins.elasticsearch.getCluster('admin').callWithInternalUser; - const numWorkers = config.get('task_manager.num_workers'); - const store = new TaskStore({ - index: config.get('task_manager.index'), - callCluster, - maxAttempts: config.get('task_manager.max_attempts'), - }); - - logger.debug('Initializing the task manager index'); - await store.init(); - - const definitions = extractTaskDefinitions( - numWorkers, - this.kbnServer.uiExports.taskDefinitions - ); - - const pool = new TaskPool({ - logger, - callCluster, - numWorkers, - store, - definitions, - pollInterval: config.get('task_manager.poll_interval'), - kbnServer: this.kbnServer, - }); - - pool.start(); - - server.decorate( - 'server', - 'taskManager', - new TaskManager({ - store, - pool, - }) - ); - }, - }); -} - -// TODO, move this to a file and properly test it, validate the taskDefinition via Joi or something -function extractTaskDefinitions( - numWorkers: number, - taskDefinitions: TaskDictionary = {} -): TaskDictionary { - return Object.keys(taskDefinitions).reduce( - (acc, type) => { - const rawDefinition = taskDefinitions[type]; - rawDefinition.type = type; - const definition = Joi.attempt(rawDefinition, validateTaskDefinition) as TaskDefinition; - const workersOccupied = Math.min(numWorkers, definition.workersOccupied || 1); - - acc[type] = { - ...definition, - workersOccupied, - }; - - return acc; - }, - {} as TaskDictionary - ); -} diff --git a/src/server/config/schema.js b/src/server/config/schema.js index 6fa09a400cc09..d386921453c24 100644 --- a/src/server/config/schema.js +++ b/src/server/config/schema.js @@ -238,9 +238,26 @@ export default () => Joi.object({ }), profile: Joi.boolean().default(false) }).default(), + status: Joi.object({ allowAnonymous: Joi.boolean().default(false) }).default(), + + taskManager: Joi.object({ + max_attempts: Joi.number() + .description('The maximum number of times a task will be attempted before being abandoned as failed') + .default(3), + poll_interval: Joi.number() + .description('How often, in milliseconds, the task manager will look for more work.') + .default(3000), + index: Joi.string() + .description('The name of the index used to store task information.') + .default('.kibana_task_manager'), + num_workers: Joi.number() + .description('The maximum number of tasks that this Kibana instance will run simultaneously.') + .default(10), + }).default(), + map: Joi.object({ includeElasticMapsService: Joi.boolean().default(true), tilemap: tilemapSchema, diff --git a/src/server/kbn_server.js b/src/server/kbn_server.js index 7279a8f407b11..95c7f08cfaa25 100644 --- a/src/server/kbn_server.js +++ b/src/server/kbn_server.js @@ -36,6 +36,7 @@ import * as Plugins from './plugins'; import { indexPatternsMixin } from './index_patterns'; import { savedObjectsMixin } from './saved_objects'; import { sampleDataMixin } from './sample_data'; +import { taskManagerMixin } from './task_manager'; import { kibanaIndexMappingsMixin } from './mappings'; import { urlShorteningMixin } from './url_shortening'; import { serverExtensionsMixin } from './server_extensions'; @@ -96,6 +97,9 @@ export default class KbnServer { // setup routes for installing/uninstalling sample data sets sampleDataMixin, + // task manager service + taskManagerMixin, + // setup routes for short urls urlShorteningMixin, diff --git a/src/core_plugins/task_manager/README.md b/src/server/task_manager/README.md similarity index 100% rename from src/core_plugins/task_manager/README.md rename to src/server/task_manager/README.md diff --git a/src/server/task_manager/client_wrapper.ts b/src/server/task_manager/client_wrapper.ts new file mode 100644 index 0000000000000..8cba5931232ac --- /dev/null +++ b/src/server/task_manager/client_wrapper.ts @@ -0,0 +1,40 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { TaskManager } from './task_pool'; +import { TaskInstance } from './task_pool/task'; + +export class TaskManagerClientWrapper { + private client: TaskManager | null; + + constructor() { + this.client = null; + } + + public setClient(client: TaskManager) { + this.client = client; + } + + public schedule(task: TaskInstance) { + if (this.client == null) { + throw new Error('Task Manager Client has not been set properly!'); + } + this.client.schedule(task); + } +} diff --git a/src/server/task_manager/index.ts b/src/server/task_manager/index.ts new file mode 100644 index 0000000000000..8e3b365e62343 --- /dev/null +++ b/src/server/task_manager/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { taskManagerMixin } from './task_manager_mixin'; diff --git a/src/core_plugins/task_manager/package.json b/src/server/task_manager/package.json similarity index 100% rename from src/core_plugins/task_manager/package.json rename to src/server/task_manager/package.json diff --git a/src/server/task_manager/task_manager_mixin.ts b/src/server/task_manager/task_manager_mixin.ts new file mode 100644 index 0000000000000..d9e5a395a0bca --- /dev/null +++ b/src/server/task_manager/task_manager_mixin.ts @@ -0,0 +1,89 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Joi from 'joi'; +import { TaskManagerClientWrapper } from './client_wrapper'; +import { + Logger, + TaskDefinition, + TaskDictionary, + TaskManager, + TaskPool, + TaskStore, + validateTaskDefinition, +} from './task_pool'; +import { SanitizedTaskDefinition } from './task_pool/task'; + +export async function taskManagerMixin(kbnServer: any, server: any, config: any) { + const logger = new Logger((...args) => server.log(...args)); + const numWorkers = config.get('taskManager.num_workers'); + const definitions = extractTaskDefinitions(numWorkers, kbnServer.uiExports.taskDefinitions); + + server.decorate('server', 'taskManager', new TaskManagerClientWrapper()); + + kbnServer.afterPluginsInit(async () => { + const callCluster = server.plugins.elasticsearch.getCluster('admin').callWithInternalUser; + const store = new TaskStore({ + index: config.get('taskManager.index'), + callCluster, + maxAttempts: config.get('taskManager.max_attempts'), + }); + + logger.debug('Initializing the task manager index'); + await store.init(); + + const pool = new TaskPool({ + logger, + callCluster, + numWorkers, + store, + definitions, + pollInterval: config.get('taskManager.poll_interval'), + kbnServer, + }); + + pool.start(); + + const client = new TaskManager({ store, pool }); + server.taskManager.setClient(client); + }); +} + +// TODO, move this to a file and properly test it, validate the taskDefinition via Joi or something +function extractTaskDefinitions( + numWorkers: number, + taskDefinitions: TaskDictionary = {} +): TaskDictionary { + return Object.keys(taskDefinitions).reduce( + (acc, type) => { + const rawDefinition = taskDefinitions[type]; + rawDefinition.type = type; + const definition = Joi.attempt(rawDefinition, validateTaskDefinition) as TaskDefinition; + const workersOccupied = Math.min(numWorkers, definition.workersOccupied || 1); + + acc[type] = { + ...definition, + workersOccupied, + }; + + return acc; + }, + {} as TaskDictionary + ); +} diff --git a/src/core_plugins/task_manager/task_pool/index.ts b/src/server/task_manager/task_pool/index.ts similarity index 100% rename from src/core_plugins/task_manager/task_pool/index.ts rename to src/server/task_manager/task_pool/index.ts diff --git a/src/core_plugins/task_manager/task_pool/logger.ts b/src/server/task_manager/task_pool/logger.ts similarity index 100% rename from src/core_plugins/task_manager/task_pool/logger.ts rename to src/server/task_manager/task_pool/logger.ts diff --git a/src/core_plugins/task_manager/task_pool/task.ts b/src/server/task_manager/task_pool/task.ts similarity index 100% rename from src/core_plugins/task_manager/task_pool/task.ts rename to src/server/task_manager/task_pool/task.ts diff --git a/src/core_plugins/task_manager/task_pool/task_intervals.test.ts b/src/server/task_manager/task_pool/task_intervals.test.ts similarity index 100% rename from src/core_plugins/task_manager/task_pool/task_intervals.test.ts rename to src/server/task_manager/task_pool/task_intervals.test.ts diff --git a/src/core_plugins/task_manager/task_pool/task_intervals.ts b/src/server/task_manager/task_pool/task_intervals.ts similarity index 100% rename from src/core_plugins/task_manager/task_pool/task_intervals.ts rename to src/server/task_manager/task_pool/task_intervals.ts diff --git a/src/core_plugins/task_manager/task_pool/task_manager.ts b/src/server/task_manager/task_pool/task_manager.ts similarity index 100% rename from src/core_plugins/task_manager/task_pool/task_manager.ts rename to src/server/task_manager/task_pool/task_manager.ts diff --git a/src/core_plugins/task_manager/task_pool/task_pool.ts b/src/server/task_manager/task_pool/task_pool.ts similarity index 100% rename from src/core_plugins/task_manager/task_pool/task_pool.ts rename to src/server/task_manager/task_pool/task_pool.ts diff --git a/src/core_plugins/task_manager/task_pool/task_runner.ts b/src/server/task_manager/task_pool/task_runner.ts similarity index 99% rename from src/core_plugins/task_manager/task_pool/task_runner.ts rename to src/server/task_manager/task_pool/task_runner.ts index be54640ff3ba5..11bf4a76bb8d6 100644 --- a/src/core_plugins/task_manager/task_pool/task_runner.ts +++ b/src/server/task_manager/task_pool/task_runner.ts @@ -22,6 +22,7 @@ import { intervalFromNow } from './task_intervals'; import { TaskStore } from './task_store'; interface Logger { + info: (msg: string) => void; debug: (msg: string) => void; warning: (msg: string) => void; } diff --git a/src/core_plugins/task_manager/task_pool/task_store.ts b/src/server/task_manager/task_pool/task_store.ts similarity index 100% rename from src/core_plugins/task_manager/task_pool/task_store.ts rename to src/server/task_manager/task_pool/task_store.ts diff --git a/src/core_plugins/task_manager/cancellable/README.md b/src/utils/cancellable/README.md similarity index 100% rename from src/core_plugins/task_manager/cancellable/README.md rename to src/utils/cancellable/README.md diff --git a/src/core_plugins/task_manager/cancellable/cancellable.test.ts b/src/utils/cancellable/cancellable.test.ts similarity index 100% rename from src/core_plugins/task_manager/cancellable/cancellable.test.ts rename to src/utils/cancellable/cancellable.test.ts diff --git a/src/core_plugins/task_manager/cancellable/cancellable.ts b/src/utils/cancellable/cancellable.ts similarity index 100% rename from src/core_plugins/task_manager/cancellable/cancellable.ts rename to src/utils/cancellable/cancellable.ts diff --git a/src/core_plugins/task_manager/cancellable/cancellable_state.ts b/src/utils/cancellable/cancellable_state.ts similarity index 100% rename from src/core_plugins/task_manager/cancellable/cancellable_state.ts rename to src/utils/cancellable/cancellable_state.ts diff --git a/src/utils/index.js b/src/utils/index.js index f79690b4392ea..f0d77f3125e81 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -20,6 +20,7 @@ export { BinderBase } from './binder'; export { BinderFor } from './binder_for'; export { deepCloneWithBuffers } from './deep_clone_with_buffers'; +export { Cancellable } from './cancellable/cancellable'; export { fromRoot } from './from_root'; export { pkg } from './package_json'; export { unset } from './unset'; diff --git a/x-pack/index.js b/x-pack/index.js index 59f33832388cb..a98af06dde131 100644 --- a/x-pack/index.js +++ b/x-pack/index.js @@ -44,6 +44,6 @@ module.exports = function (kibana) { indexManagement(kibana), consoleExtensions(kibana), notifications(kibana), - kueryAutocomplete(kibana), + kueryAutocomplete(kibana) ]; };