diff --git a/x-pack/plugins/apm/index.ts b/x-pack/plugins/apm/index.ts index 97fd04fd0aca..533071dde482 100644 --- a/x-pack/plugins/apm/index.ts +++ b/x-pack/plugins/apm/index.ts @@ -7,13 +7,9 @@ import { i18n } from '@kbn/i18n'; import { Server } from 'hapi'; import { resolve } from 'path'; +import { CoreSetup, PluginInitializerContext } from 'src/core/server/index.js'; import mappings from './mappings.json'; -import { makeApmUsageCollector } from './server/lib/apm_telemetry'; -import { initErrorsApi } from './server/routes/errors'; -import { initMetricsApi } from './server/routes/metrics'; -import { initServicesApi } from './server/routes/services'; -import { initTracesApi } from './server/routes/traces'; -import { initTransactionGroupsApi } from './server/routes/transaction_groups'; +import { plugin } from './server/new-platform/index'; // TODO: get proper types export function apm(kibana: any) { @@ -73,13 +69,14 @@ export function apm(kibana: any) { }, // TODO: get proper types - init(server: any) { - initTransactionGroupsApi(server); - initTracesApi(server); - initServicesApi(server); - initErrorsApi(server); - initMetricsApi(server); - makeApmUsageCollector(server); + init(server: Server) { + const initializerContext = {} as PluginInitializerContext; + const core = { + http: { + server + } + } as CoreSetup; + plugin(initializerContext).setup(core); } }); } diff --git a/x-pack/plugins/apm/public/index.tsx b/x-pack/plugins/apm/public/index.tsx index ff5b7b679e2d..4e3e044366b6 100644 --- a/x-pack/plugins/apm/public/index.tsx +++ b/x-pack/plugins/apm/public/index.tsx @@ -6,9 +6,8 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import { Provider } from 'react-redux'; -import { Router } from 'react-router-dom'; import 'react-vis/dist/style.css'; +import { CoreSetup } from 'src/core/public'; import 'ui/autoload/all'; import 'ui/autoload/styles'; import chrome from 'ui/chrome'; @@ -17,11 +16,10 @@ import { I18nContext } from 'ui/i18n'; import { uiModules } from 'ui/modules'; import 'uiExports/autocompleteProviders'; import { GlobalHelpExtension } from './components/app/GlobalHelpExtension'; -import { Main } from './components/app/Main'; -import { history } from './components/shared/Links/url_helpers'; -import { LocationProvider } from './context/LocationContext'; // @ts-ignore import configureStore from './store/config/configureStore'; +import { plugin } from './new-platform'; +import { REACT_APP_ROOT_ID } from './new-platform/plugin'; import './style/global_overrides.css'; import template from './templates/index.html'; @@ -32,34 +30,26 @@ chrome.helpExtension.set(domElement => { ReactDOM.unmountComponentAtNode(domElement); }; }); -const REACT_APP_ROOT_ID = 'react-apm-root'; - -type PromiseResolver = (value?: {} | PromiseLike<{}> | undefined) => void; // @ts-ignore chrome.setRootTemplate(template); -const store = configureStore(); -const checkForRoot = (resolve: PromiseResolver) => { - const ready = !!document.getElementById(REACT_APP_ROOT_ID); - if (ready) { - resolve(); - } else { - setTimeout(() => checkForRoot(resolve), 10); - } -}; -const waitForRoot = new Promise(resolve => checkForRoot(resolve)); -waitForRoot.then(() => { - ReactDOM.render( - - - - -
- - - - , - document.getElementById(REACT_APP_ROOT_ID) - ); +const checkForRoot = () => { + return new Promise(resolve => { + const ready = !!document.getElementById(REACT_APP_ROOT_ID); + if (ready) { + resolve(); + } else { + setTimeout(() => resolve(checkForRoot()), 10); + } + }); +}; + +checkForRoot().then(() => { + const core = { + i18n: { + Context: I18nContext + } + } as CoreSetup; + plugin().setup(core); }); diff --git a/x-pack/plugins/apm/public/new-platform/index.tsx b/x-pack/plugins/apm/public/new-platform/index.tsx new file mode 100644 index 000000000000..cb4cc2a845a4 --- /dev/null +++ b/x-pack/plugins/apm/public/new-platform/index.tsx @@ -0,0 +1,11 @@ +/* + * 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 { Plugin } from './plugin'; + +export function plugin() { + return new Plugin(); +} diff --git a/x-pack/plugins/apm/public/new-platform/plugin.tsx b/x-pack/plugins/apm/public/new-platform/plugin.tsx new file mode 100644 index 000000000000..1049148d50d0 --- /dev/null +++ b/x-pack/plugins/apm/public/new-platform/plugin.tsx @@ -0,0 +1,37 @@ +/* + * 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 React from 'react'; +import ReactDOM from 'react-dom'; +import { Provider } from 'react-redux'; +import { Router } from 'react-router-dom'; +import { CoreSetup } from 'src/core/public'; +import { Main } from '../components/app/Main'; +import { history } from '../components/shared/Links/url_helpers'; +import { LocationProvider } from '../context/LocationContext'; +// @ts-ignore +import configureStore from '../store/config/configureStore'; + +export const REACT_APP_ROOT_ID = 'react-apm-root'; + +export class Plugin { + public setup(core: CoreSetup) { + const { i18n } = core; + const store = configureStore(); + ReactDOM.render( + + + + +
+ + + + , + document.getElementById(REACT_APP_ROOT_ID) + ); + } +} diff --git a/x-pack/plugins/apm/server/lib/apm_telemetry/make_apm_usage_collector.ts b/x-pack/plugins/apm/server/lib/apm_telemetry/make_apm_usage_collector.ts index 15c30f4337c2..8f03bd0b5fbb 100644 --- a/x-pack/plugins/apm/server/lib/apm_telemetry/make_apm_usage_collector.ts +++ b/x-pack/plugins/apm/server/lib/apm_telemetry/make_apm_usage_collector.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Server } from 'hapi'; +import { CoreSetup } from 'src/core/server'; import { APM_TELEMETRY_DOC_ID, createApmTelementry, @@ -12,16 +12,22 @@ import { } from './apm_telemetry'; // TODO this type should be defined by the platform -interface KibanaHapiServer extends Server { - usage: { - collectorSet: { - makeUsageCollector: (options: unknown) => unknown; - register: (options: unknown) => unknown; +export interface CoreSetupWithUsageCollector extends CoreSetup { + http: CoreSetup['http'] & { + server: { + usage: { + collectorSet: { + makeUsageCollector: (options: unknown) => unknown; + register: (options: unknown) => unknown; + }; + }; }; }; } -export function makeApmUsageCollector(server: KibanaHapiServer): void { +export function makeApmUsageCollector(core: CoreSetupWithUsageCollector) { + const { server } = core.http; + const apmUsageCollector = server.usage.collectorSet.makeUsageCollector({ type: 'apm', fetch: async () => { diff --git a/x-pack/plugins/apm/server/new-platform/index.ts b/x-pack/plugins/apm/server/new-platform/index.ts new file mode 100644 index 000000000000..8ad0cbbb811f --- /dev/null +++ b/x-pack/plugins/apm/server/new-platform/index.ts @@ -0,0 +1,12 @@ +/* + * 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 { PluginInitializerContext } from 'src/core/server'; +import { Plugin } from './plugin'; + +export function plugin(initializerContext: PluginInitializerContext) { + return new Plugin(); +} diff --git a/x-pack/plugins/apm/server/new-platform/plugin.ts b/x-pack/plugins/apm/server/new-platform/plugin.ts new file mode 100644 index 000000000000..4ad969703391 --- /dev/null +++ b/x-pack/plugins/apm/server/new-platform/plugin.ts @@ -0,0 +1,25 @@ +/* + * 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 { CoreSetup } from 'src/core/server'; +import { makeApmUsageCollector } from '../lib/apm_telemetry'; +import { CoreSetupWithUsageCollector } from '../lib/apm_telemetry/make_apm_usage_collector'; +import { initErrorsApi } from '../routes/errors'; +import { initMetricsApi } from '../routes/metrics'; +import { initServicesApi } from '../routes/services'; +import { initTracesApi } from '../routes/traces'; +import { initTransactionGroupsApi } from '../routes/transaction_groups'; + +export class Plugin { + public setup(core: CoreSetup) { + initTransactionGroupsApi(core); + initTracesApi(core); + initServicesApi(core); + initErrorsApi(core); + initMetricsApi(core); + makeApmUsageCollector(core as CoreSetupWithUsageCollector); + } +} diff --git a/x-pack/plugins/apm/server/routes/__test__/routeFailures.test.ts b/x-pack/plugins/apm/server/routes/__test__/routeFailures.test.ts index c7aed10c4c1c..4db63a4ce588 100644 --- a/x-pack/plugins/apm/server/routes/__test__/routeFailures.test.ts +++ b/x-pack/plugins/apm/server/routes/__test__/routeFailures.test.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Server } from 'hapi'; import { flatten } from 'lodash'; +import { CoreSetup } from 'src/core/server'; import { initErrorsApi } from '../errors'; import { initServicesApi } from '../services'; import { initTracesApi } from '../traces'; @@ -13,9 +13,14 @@ import { initTracesApi } from '../traces'; describe('route handlers should fail with a Boom error', () => { let consoleErrorSpy: any; - async function testRouteFailures(init: (server: Server) => void) { + async function testRouteFailures(init: (core: CoreSetup) => void) { const mockServer = { route: jest.fn() }; - init((mockServer as unknown) as Server); + const mockCore = ({ + http: { + server: mockServer + } + } as unknown) as CoreSetup; + init(mockCore); expect(mockServer.route).toHaveBeenCalled(); const mockCluster = { diff --git a/x-pack/plugins/apm/server/routes/errors.ts b/x-pack/plugins/apm/server/routes/errors.ts index b8a30c007be5..e4f855f298e9 100644 --- a/x-pack/plugins/apm/server/routes/errors.ts +++ b/x-pack/plugins/apm/server/routes/errors.ts @@ -5,9 +5,9 @@ */ import Boom from 'boom'; -import { Server } from 'hapi'; import Joi from 'joi'; import { Legacy } from 'kibana'; +import { CoreSetup } from 'src/core/server'; import { getDistribution } from '../lib/errors/distribution/get_distribution'; import { getErrorGroup } from '../lib/errors/get_error_group'; import { getErrorGroups } from '../lib/errors/get_error_groups'; @@ -21,7 +21,8 @@ const defaultErrorHandler = (err: Error) => { throw Boom.boomify(err, { statusCode: 400 }); }; -export function initErrorsApi(server: Server) { +export function initErrorsApi(core: CoreSetup) { + const { server } = core.http; server.route({ method: 'GET', path: ROOT, diff --git a/x-pack/plugins/apm/server/routes/metrics.ts b/x-pack/plugins/apm/server/routes/metrics.ts index 76ba0a40077e..c94defca8a5f 100644 --- a/x-pack/plugins/apm/server/routes/metrics.ts +++ b/x-pack/plugins/apm/server/routes/metrics.ts @@ -5,7 +5,7 @@ */ import Boom from 'boom'; -import { Server } from 'hapi'; +import { CoreSetup } from 'src/core/server'; import { withDefaultValidators } from '../lib/helpers/input_validation'; import { setupRequest } from '../lib/helpers/setup_request'; import { getAllMetricsChartData } from '../lib/metrics/get_all_metrics_chart_data'; @@ -16,7 +16,8 @@ const defaultErrorHandler = (err: Error) => { throw Boom.boomify(err, { statusCode: 400 }); }; -export function initMetricsApi(server: Server) { +export function initMetricsApi(core: CoreSetup) { + const { server } = core.http; server.route({ method: 'GET', path: `/api/apm/services/{serviceName}/metrics/charts`, diff --git a/x-pack/plugins/apm/server/routes/services.ts b/x-pack/plugins/apm/server/routes/services.ts index 07255d41cc88..345dda5da68c 100644 --- a/x-pack/plugins/apm/server/routes/services.ts +++ b/x-pack/plugins/apm/server/routes/services.ts @@ -5,7 +5,7 @@ */ import Boom from 'boom'; -import { Server } from 'hapi'; +import { CoreSetup } from 'src/core/server'; import { AgentName } from '../../typings/es_schemas/ui/fields/Agent'; import { createApmTelementry, storeApmTelemetry } from '../lib/apm_telemetry'; import { withDefaultValidators } from '../lib/helpers/input_validation'; @@ -20,7 +20,8 @@ const defaultErrorHandler = (err: Error) => { throw Boom.boomify(err, { statusCode: 400 }); }; -export function initServicesApi(server: Server) { +export function initServicesApi(core: CoreSetup) { + const { server } = core.http; server.route({ method: 'GET', path: ROOT, diff --git a/x-pack/plugins/apm/server/routes/traces.ts b/x-pack/plugins/apm/server/routes/traces.ts index 81dbf741f925..112c79110d37 100644 --- a/x-pack/plugins/apm/server/routes/traces.ts +++ b/x-pack/plugins/apm/server/routes/traces.ts @@ -5,7 +5,8 @@ */ import Boom from 'boom'; -import { Server } from 'hapi'; + +import { CoreSetup } from 'src/core/server'; import { withDefaultValidators } from '../lib/helpers/input_validation'; import { setupRequest } from '../lib/helpers/setup_request'; import { getTopTraces } from '../lib/traces/get_top_traces'; @@ -18,7 +19,9 @@ const defaultErrorHandler = (err: Error) => { throw Boom.boomify(err, { statusCode: 400 }); }; -export function initTracesApi(server: Server) { +export function initTracesApi(core: CoreSetup) { + const { server } = core.http; + // Get trace list server.route({ method: 'GET', diff --git a/x-pack/plugins/apm/server/routes/transaction_groups.ts b/x-pack/plugins/apm/server/routes/transaction_groups.ts index 74b8f3dc6b58..71edd0ba3867 100644 --- a/x-pack/plugins/apm/server/routes/transaction_groups.ts +++ b/x-pack/plugins/apm/server/routes/transaction_groups.ts @@ -5,8 +5,8 @@ */ import Boom from 'boom'; -import { Server } from 'hapi'; import Joi from 'joi'; +import { CoreSetup } from 'src/core/server'; import { withDefaultValidators } from '../lib/helpers/input_validation'; import { setupRequest } from '../lib/helpers/setup_request'; import { getChartsData } from '../lib/transactions/charts'; @@ -19,7 +19,9 @@ const defaultErrorHandler = (err: Error) => { throw Boom.boomify(err, { statusCode: 400 }); }; -export function initTransactionGroupsApi(server: Server) { +export function initTransactionGroupsApi(core: CoreSetup) { + const { server } = core.http; + server.route({ method: 'GET', path: