From 03147755761f8c3c56514a13c1fc83a1bc867ee3 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Tue, 19 Nov 2019 17:59:33 -0500 Subject: [PATCH 01/32] Move a REST endpoint and the GQL endpoint to NP routing. --- x-pack/legacy/plugins/uptime/index.ts | 2 +- .../lib/adapters/framework/adapter_types.ts | 15 ++-- .../framework/kibana_framework_adapter.ts | 72 ++++++++++++------ .../server/rest_api/create_route_with_auth.ts | 18 ++--- .../plugins/uptime/server/rest_api/index.ts | 2 - .../uptime/server/rest_api/pings/get_all.ts | 75 ++++++++++++------- .../rest_api/snapshot/get_snapshot_count.ts | 39 +++++----- .../plugins/uptime/server/rest_api/types.ts | 4 +- 8 files changed, 137 insertions(+), 90 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/index.ts b/x-pack/legacy/plugins/uptime/index.ts index 690807cc91e27..3cd0ffb1a2942 100644 --- a/x-pack/legacy/plugins/uptime/index.ts +++ b/x-pack/legacy/plugins/uptime/index.ts @@ -41,7 +41,7 @@ export const uptime = (kibana: any) => plugin(initializerContext).setup( { - route: (arg: any) => server.route(arg), + route: server.newPlatform.setup.core.http.createRouter(), }, { elasticsearch, diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts index df2723283f88c..10fa9b836028a 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts @@ -8,8 +8,9 @@ import { GraphQLOptions } from 'apollo-server-core'; import { GraphQLSchema } from 'graphql'; import { Lifecycle, ResponseToolkit } from 'hapi'; import { RouteOptions } from 'hapi'; -import { SavedObjectsLegacyService } from 'src/core/server'; +import { SavedObjectsLegacyService, RequestHandler, RouteMethod, IRouter } from 'src/core/server'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; +import { ObjectType } from '@kbn/config-schema'; export interface UMFrameworkRequest { user: string; @@ -22,17 +23,19 @@ export interface UMFrameworkRequest { export type UMFrameworkResponse = Lifecycle.ReturnValue; export interface UMFrameworkRouteOptions< - RouteRequest extends UMFrameworkRequest, - RouteResponse extends UMFrameworkResponse + P extends ObjectType, + Q extends ObjectType, + B extends ObjectType > { path: string; method: string; - handler: (req: Request, h: ResponseToolkit) => any; + handler: RequestHandler; config?: any; + validate: any; } export interface UptimeCoreSetup { - route: any; + route: IRouter; } export interface UptimeCorePlugins { @@ -58,7 +61,7 @@ export interface UMHapiGraphQLPluginOptions { export interface UMBackendFrameworkAdapter { registerRoute( - route: UMFrameworkRouteOptions + route: UMFrameworkRouteOptions ): void; registerGraphQLEndpoint(routePath: string, schema: GraphQLSchema): void; getSavedObjectsClient(): any; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts index c166530ca6428..01cf84a3eb520 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -5,8 +5,9 @@ */ import { GraphQLSchema } from 'graphql'; -import { Request, ResponseToolkit } from 'hapi'; +import { schema as kbnSchema } from '@kbn/config-schema'; import { runHttpQuery } from 'apollo-server-core'; +import { ObjectType } from '@kbn/config-schema'; import { UptimeCorePlugins, UptimeCoreSetup } from './adapter_types'; import { UMBackendFrameworkAdapter, @@ -14,7 +15,6 @@ import { UMFrameworkResponse, UMFrameworkRouteOptions, } from './adapter_types'; -import { DEFAULT_GRAPHQL_PATH } from '../../../graphql'; export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapter { constructor( @@ -28,8 +28,25 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte public registerRoute< RouteRequest extends UMFrameworkRequest, RouteResponse extends UMFrameworkResponse - >(route: UMFrameworkRouteOptions) { - this.server.route(route); + >({ + handler, + method, + path, + validate, + }: UMFrameworkRouteOptions) { + switch (method) { + case 'GET': + this.server.route.get( + { + path, + validate, + }, + handler + ); + break; + default: + throw new Error(`Handler for method ${method} is not defined`); + } } public registerGraphQLEndpoint(routePath: string, schema: GraphQLSchema): void { @@ -43,37 +60,44 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte tags: ['access:uptime'], }, }; - this.server.route({ - options: options.route, - handler: async (request: Request, h: ResponseToolkit) => { + this.server.route.post( + { + path: routePath, + validate: { + body: kbnSchema.object({ + operationName: kbnSchema.string(), + query: kbnSchema.string(), + variables: kbnSchema.recordOf(kbnSchema.string(), kbnSchema.any()), + }), + }, + }, + async (context, request, resp): Promise => { try { - const { method } = request; - const query = - method === 'post' - ? (request.payload as Record) - : (request.query as Record); + const query = request.body as Record; const graphQLResponse = await runHttpQuery([request], { - method: method.toUpperCase(), + method: 'POST', options: options.graphQLOptions, query, }); - return h.response(graphQLResponse).type('application/json'); + return resp.ok({ + body: graphQLResponse, + headers: { + 'content-type': 'application/json', + }, + }); } catch (error) { if (error.isGraphQLError === true) { - return h - .response(error.message) - .code(error.statusCode) - .type('application/json'); + return resp.internalError({ + body: { message: error.message }, + headers: { 'content-type': 'application/json' }, + }); } - return h.response(error).type('application/json'); + return resp.internalError(); } - }, - method: ['get', 'post'], - path: options.path || DEFAULT_GRAPHQL_PATH, - vhost: undefined, - }); + } + ); } public getSavedObjectsClient() { diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts b/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts index 727ed78624a48..eb3932c367709 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import Boom from 'boom'; import { UMServerLibs } from '../lib/lib'; import { UMRestApiRouteCreator, UMServerRoute } from './types'; @@ -13,17 +12,18 @@ export const createRouteWithAuth = ( routeCreator: UMRestApiRouteCreator ): UMServerRoute => { const restRoute = routeCreator(libs); - const { handler, method, path, options } = restRoute; - const authHandler = async (request: any, h: any) => { - if (libs.auth.requestIsValid(request)) { - return await handler(request, h); - } - return Boom.badRequest(); - }; + const { handler, method, path, options, ...rest } = restRoute; + // const authHandler = async (request: any, h: any) => { + // if (libs.auth.requestIsValid(request)) { + // return await handler(request, h); + // } + // return Boom.badRequest(); + // }; return { method, path, options, - handler: authHandler, + handler, // : authHandler, + ...rest, }; }; diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/index.ts b/x-pack/legacy/plugins/uptime/server/rest_api/index.ts index 889f8a820b2f3..2810982fb0c6c 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/index.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/index.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { createIsValidRoute } from './auth'; import { createGetAllRoute } from './pings'; import { createGetIndexPatternRoute } from './index_pattern'; import { createLogMonitorPageRoute, createLogOverviewPageRoute } from './telemetry'; @@ -19,7 +18,6 @@ export const restApiRoutes: UMRestApiRouteCreator[] = [ createGetIndexPatternRoute, createGetMonitorDetailsRoute, createGetSnapshotCount, - createIsValidRoute, createLogMonitorPageRoute, createLogOverviewPageRoute, ]; diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts b/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts index 70f9a5c061191..cf0a4cec44e92 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts @@ -4,36 +4,55 @@ * you may not use this file except in compliance with the Elastic License. */ -import Joi from 'joi'; -import { PingResults } from '../../../common/graphql/types'; +import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../lib/lib'; +import { UMRestApiRouteCreator } from '../types'; -export const createGetAllRoute = (libs: UMServerLibs) => ({ - method: 'GET', - path: '/api/uptime/pings', - options: { +export const createGetAllRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => { + return { + method: 'GET', + path: '/api/uptime/pings', validate: { - query: Joi.object({ - dateRangeStart: Joi.number().required(), - dateRangeEnd: Joi.number().required(), - monitorId: Joi.string(), - size: Joi.number(), - sort: Joi.string(), - status: Joi.string(), + query: schema.object({ + dateRangeStart: schema.string(), + dateRangeEnd: schema.string(), + location: schema.maybe(schema.string()), + monitorId: schema.maybe(schema.string()), + size: schema.maybe(schema.number()), + sort: schema.maybe(schema.string()), + status: schema.maybe(schema.string()), }), }, - tags: ['access:uptime'], - }, - handler: async (request: any): Promise => { - const { size, sort, dateRangeStart, dateRangeEnd, monitorId, status } = request.query; - return await libs.pings.getAll( - request, - dateRangeStart, - dateRangeEnd, - monitorId, - status, - sort, - size - ); - }, -}); + options: { + tags: ['access:uptime'], + }, + handler: async (context, request, resp): Promise => { + const { + size, + sort, + dateRangeStart, + dateRangeEnd, + location, + monitorId, + status, + } = request.query; + + const result = await libs.pings.getAll( + request, + dateRangeStart, + dateRangeEnd, + monitorId, + status, + sort, + size, + location + ); + + return resp.ok({ + body: { + ...result, + }, + }); + }, + }; +}; diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts b/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts index ddca622005d63..5f5ce03d2cd7f 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts @@ -7,29 +7,30 @@ import Joi from 'joi'; import { UMServerLibs } from '../../lib/lib'; import { Snapshot } from '../../../common/runtime_types'; +import { UMRestApiRouteCreator } from '../types'; -export const createGetSnapshotCount = (libs: UMServerLibs) => ({ +export const createGetSnapshotCount: UMRestApiRouteCreator = (libs: UMServerLibs) => ({ method: 'GET', path: '/api/uptime/snapshot/count', - options: { - validate: { - query: Joi.object({ - dateRangeStart: Joi.string().required(), - dateRangeEnd: Joi.string().required(), - filters: Joi.string(), - statusFilter: Joi.string(), - }), - }, - tags: ['access:uptime'], + validate: { + query: Joi.object({ + dateRangeStart: Joi.string().required(), + dateRangeEnd: Joi.string().required(), + filters: Joi.string(), + statusFilter: Joi.string(), + }), }, - handler: async (request: any): Promise => { + tags: ['access:uptime'], + handler: async (_context: any, request: any, response: any): Promise => { const { dateRangeStart, dateRangeEnd, filters, statusFilter } = request.query; - return await libs.monitorStates.getSnapshotCount( - request, - dateRangeStart, - dateRangeEnd, - filters, - statusFilter - ); + return response.ok({ + body: await libs.monitorStates.getSnapshotCount( + request, + dateRangeStart, + dateRangeEnd, + filters, + statusFilter + ), + }); }, }); diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts b/x-pack/legacy/plugins/uptime/server/rest_api/types.ts index acbc50828f874..68672b9651386 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/types.ts @@ -4,13 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ +import { ObjectType } from '@kbn/config-schema'; +import { RequestHandler } from 'kibana/server'; import { UMServerLibs } from '../lib/lib'; export interface UMServerRoute { method: string; path: string; options?: any; - handler: (request: any, h?: any) => any; + handler: RequestHandler; } export type UMRestApiRouteCreator = (libs: UMServerLibs) => UMServerRoute; From 1dd6ea894668117472e4d53663766e6c53a34e61 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 20 Nov 2019 12:31:40 -0500 Subject: [PATCH 02/32] Delete obsolete REST endpoint. --- .../plugins/uptime/server/rest_api/auth/index.ts | 7 ------- .../uptime/server/rest_api/auth/is_valid.ts | 16 ---------------- 2 files changed, 23 deletions(-) delete mode 100644 x-pack/legacy/plugins/uptime/server/rest_api/auth/index.ts delete mode 100644 x-pack/legacy/plugins/uptime/server/rest_api/auth/is_valid.ts diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/auth/index.ts b/x-pack/legacy/plugins/uptime/server/rest_api/auth/index.ts deleted file mode 100644 index 242d9bf73a946..0000000000000 --- a/x-pack/legacy/plugins/uptime/server/rest_api/auth/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * 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 { createIsValidRoute } from './is_valid'; diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/auth/is_valid.ts b/x-pack/legacy/plugins/uptime/server/rest_api/auth/is_valid.ts deleted file mode 100644 index 15024f7c5f497..0000000000000 --- a/x-pack/legacy/plugins/uptime/server/rest_api/auth/is_valid.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 { UMServerLibs } from '../../lib/lib'; - -export const createIsValidRoute = (libs: UMServerLibs) => ({ - method: 'GET', - path: '/api/uptime/is_valid', - handler: async (request: any): Promise => await libs.auth.requestIsValid(request), - options: { - tags: ['access:uptime'], - }, -}); From a05594d64621fe0ce915b3567cdd2cbca0e3c5b7 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 20 Nov 2019 12:35:15 -0500 Subject: [PATCH 03/32] Update remaining REST routes to work with NP router. --- .../auth/__tests__/xpack_auth_adapter.test.ts | 56 ------------- .../server/lib/adapters/auth/adapter_types.ts | 32 -------- .../uptime/server/lib/adapters/auth/index.ts | 8 -- .../lib/adapters/auth/xpack_auth_adapter.ts | 40 --------- .../framework/kibana_framework_adapter.ts | 9 ++ .../uptime/server/lib/compose/kibana.ts | 7 +- .../plugins/uptime/server/lib/domains/auth.ts | 39 +++------ .../uptime/server/lib/domains/index.ts | 2 +- .../legacy/plugins/uptime/server/lib/lib.ts | 4 +- .../server/rest_api/create_route_with_auth.ts | 24 ++++-- .../plugins/uptime/server/rest_api/index.ts | 1 + .../index_pattern/get_index_pattern.ts | 18 +++- .../uptime/server/rest_api/pings/get_all.ts | 82 ++++++++----------- .../rest_api/telemetry/log_monitor_page.ts | 8 +- .../rest_api/telemetry/log_overview_page.ts | 8 +- .../plugins/uptime/server/rest_api/types.ts | 8 +- 16 files changed, 105 insertions(+), 241 deletions(-) delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/adapters/auth/__tests__/xpack_auth_adapter.test.ts delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/adapters/auth/adapter_types.ts delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/adapters/auth/index.ts delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/adapters/auth/xpack_auth_adapter.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/__tests__/xpack_auth_adapter.test.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/__tests__/xpack_auth_adapter.test.ts deleted file mode 100644 index 7dff7a02e0dc7..0000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/__tests__/xpack_auth_adapter.test.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 { UMAuthContainer, UMXPackLicenseStatus } from '../adapter_types'; -import { UMXPackAuthAdapter } from '../xpack_auth_adapter'; - -const setupXPack = (licenseStatus: UMXPackLicenseStatus) => ({ - info: { - feature: (pluginId: string) => ({ - registerLicenseCheckResultsGenerator: ( - licenseCheckResultsHandler: (status: UMXPackLicenseStatus) => void - ) => { - licenseCheckResultsHandler(licenseStatus); - }, - }), - }, - status: { - once: (status: string, registerLicenseCheck: () => void) => { - registerLicenseCheck(); - }, - }, -}); - -describe('X-PackAuthAdapter class', () => { - let xpack: UMAuthContainer; - - beforeEach(() => { - xpack = setupXPack({ - license: { - isActive: () => true, - getType: () => 'platinum', - }, - }); - }); - - it('returns the license type', () => { - const adapter = new UMXPackAuthAdapter(xpack); - expect(adapter.getLicenseType()).toBe('platinum'); - expect(adapter.licenseIsActive()).toBe(true); - }); - - it('returns null and false for undefined license values', () => { - xpack = setupXPack({ - license: { - getType: () => undefined, - isActive: () => undefined, - }, - }); - const adapter = new UMXPackAuthAdapter(xpack); - expect(adapter.licenseIsActive()).toBe(false); - expect(adapter.getLicenseType()).toBeNull(); - }); -}); diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/adapter_types.ts deleted file mode 100644 index 016e623d7745d..0000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/adapter_types.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 interface UMAuthContainer { - info: { - feature: ( - pluginId: string - ) => { - registerLicenseCheckResultsGenerator: ( - licenseCheckResultsHandler: (info: UMXPackLicenseStatus) => void - ) => void; - }; - }; - status: { - once: (status: string, registerLicenseCheck: () => void) => void; - }; -} - -export interface UMXPackLicenseStatus { - license: { - isActive: () => boolean | undefined; - getType: () => string | undefined; - }; -} - -export interface UMAuthAdapter { - getLicenseType(): string | null; - licenseIsActive(): boolean; -} diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/index.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/index.ts deleted file mode 100644 index baa31ef752daa..0000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * 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 { UMAuthAdapter, UMAuthContainer } from './adapter_types'; -export { UMXPackAuthAdapter } from './xpack_auth_adapter'; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/xpack_auth_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/xpack_auth_adapter.ts deleted file mode 100644 index 3393cfd5fa758..0000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/xpack_auth_adapter.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 '../../../../common/constants'; -import { UMAuthAdapter, UMAuthContainer, UMXPackLicenseStatus } from './adapter_types'; - -// look at index-management for guidance, subscribe to licensecheckerresultsgenerator -// then check the license status -export class UMXPackAuthAdapter implements UMAuthAdapter { - private xpackLicenseStatus: { - isActive: boolean | undefined | null; - licenseType: string | undefined | null; - }; - - constructor(private readonly xpack: UMAuthContainer) { - this.xpack = xpack; - this.xpackLicenseStatus = { - isActive: null, - licenseType: null, - }; - this.xpack.status.once('green', this.registerLicenseCheck); - } - - public getLicenseType = (): string | null => this.xpackLicenseStatus.licenseType || null; - - public licenseIsActive = (): boolean => this.xpackLicenseStatus.isActive || false; - - private registerLicenseCheck = (): void => - this.xpack.info.feature(PLUGIN.ID).registerLicenseCheckResultsGenerator(this.updateLicenseInfo); - - private updateLicenseInfo = (xpackLicenseStatus: UMXPackLicenseStatus): void => { - this.xpackLicenseStatus = { - isActive: xpackLicenseStatus.license.isActive(), - licenseType: xpackLicenseStatus.license.getType(), - }; - }; -} diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts index 01cf84a3eb520..4242522004d74 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -44,6 +44,15 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte handler ); break; + case 'POST': + this.server.route.post( + { + path, + validate, + }, + handler + ); + break; default: throw new Error(`Handler for method ${method} is not defined`); } diff --git a/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts b/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts index 1c9999fbf6451..7027a30bfce17 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts @@ -4,24 +4,21 @@ * you may not use this file except in compliance with the Elastic License. */ -import { UMXPackAuthAdapter } from '../adapters/auth'; import { UMKibanaDatabaseAdapter } from '../adapters/database/kibana_database_adapter'; import { UMKibanaBackendFrameworkAdapter } from '../adapters/framework'; import { ElasticsearchMonitorsAdapter } from '../adapters/monitors'; import { ElasticsearchPingsAdapter } from '../adapters/pings'; -import { UMAuthDomain } from '../domains'; +import { authDomain } from '../domains'; import { UMDomainLibs, UMServerLibs } from '../lib'; import { ElasticsearchMonitorStatesAdapter } from '../adapters/monitor_states'; import { UMKibanaSavedObjectsAdapter } from '../adapters/saved_objects/kibana_saved_objects_adapter'; import { UptimeCorePlugins, UptimeCoreSetup } from '../adapters/framework'; export function compose(server: UptimeCoreSetup, plugins: UptimeCorePlugins): UMServerLibs { - const { elasticsearch, savedObjects, xpack } = plugins; + const { elasticsearch, savedObjects } = plugins; const framework = new UMKibanaBackendFrameworkAdapter(server, plugins); const database = new UMKibanaDatabaseAdapter(elasticsearch); - const authDomain = new UMAuthDomain(new UMXPackAuthAdapter(xpack), {}); - const domainLibs: UMDomainLibs = { auth: authDomain, monitors: new ElasticsearchMonitorsAdapter(database), diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/auth.ts b/x-pack/legacy/plugins/uptime/server/lib/domains/auth.ts index 62d17f121779f..e7edc6913ab07 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/auth.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/domains/auth.ts @@ -5,36 +5,19 @@ */ import Boom from 'boom'; -import { get } from 'lodash'; -import { UMAuthAdapter } from '../adapters/auth/adapter_types'; +import { RequestHandlerContext } from 'kibana/server'; -const supportedLicenses = ['basic', 'standard', 'gold', 'platinum', 'trial']; +export type UMLicenseCheck = (context: RequestHandlerContext) => boolean; -export class UMAuthDomain { - constructor(private readonly adapter: UMAuthAdapter, libs: {}) { - this.adapter = adapter; +export const authDomain: UMLicenseCheck = ({ licensing: { license } }) => { + if (license === null) { + throw Boom.badRequest('Missing license information'); } - - public requestIsValid(request: any): boolean { - const license = this.adapter.getLicenseType(); - if (license === null) { - throw Boom.badRequest('Missing license information'); - } - if (!supportedLicenses.some(licenseType => licenseType === license)) { - throw Boom.forbidden('License not supported'); - } - if (this.adapter.licenseIsActive() === false) { - throw Boom.forbidden('License not active'); - } - - return this.checkRequest(request); + if (!license.isOneOf(['basic', 'standard', 'gold', 'platinum', 'trial'])) { + throw Boom.forbidden('License not supported'); } - - private checkRequest(request: any): boolean { - const authenticated = get(request, 'auth.isAuthenticated', null); - if (authenticated === null) { - throw Boom.forbidden('Missing authentication'); - } - return authenticated; + if (license.isActive === false) { + throw Boom.forbidden('License not active'); } -} + return true; +}; diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/index.ts b/x-pack/legacy/plugins/uptime/server/lib/domains/index.ts index 5be591708fab1..b2d7503a6a192 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/index.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/domains/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { UMAuthDomain } from './auth'; +export { authDomain, UMLicenseCheck } from './auth'; diff --git a/x-pack/legacy/plugins/uptime/server/lib/lib.ts b/x-pack/legacy/plugins/uptime/server/lib/lib.ts index 217195488677e..9a6a8217d1278 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/lib.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/lib.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { UMAuthDomain } from './domains'; import { DatabaseAdapter, UMBackendFrameworkAdapter, @@ -13,9 +12,10 @@ import { UMPingsAdapter, UMSavedObjectsAdapter, } from './adapters'; +import { UMLicenseCheck } from './domains'; export interface UMDomainLibs { - auth: UMAuthDomain; + auth: UMLicenseCheck; monitors: UMMonitorsAdapter; monitorStates: UMMonitorStatesAdapter; pings: UMPingsAdapter; diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts b/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts index eb3932c367709..26ae3b454cfb8 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts @@ -4,26 +4,32 @@ * you may not use this file except in compliance with the Elastic License. */ +import { RequestHandler } from 'kibana/server'; +import { ObjectType } from '@kbn/config-schema'; import { UMServerLibs } from '../lib/lib'; -import { UMRestApiRouteCreator, UMServerRoute } from './types'; +import { UMRestApiRouteCreator, UMRouteDefinition } from './types'; export const createRouteWithAuth = ( libs: UMServerLibs, routeCreator: UMRestApiRouteCreator -): UMServerRoute => { +): UMRouteDefinition => { const restRoute = routeCreator(libs); const { handler, method, path, options, ...rest } = restRoute; - // const authHandler = async (request: any, h: any) => { - // if (libs.auth.requestIsValid(request)) { - // return await handler(request, h); - // } - // return Boom.badRequest(); - // }; + const authHandler: RequestHandler = async ( + context, + request, + response + ) => { + if (libs.auth(context)) { + return await handler(context, request, response); + } + return response.badRequest(); + }; return { method, path, options, - handler, // : authHandler, + handler: authHandler, ...rest, }; }; diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/index.ts b/x-pack/legacy/plugins/uptime/server/rest_api/index.ts index 2810982fb0c6c..9d1d8c38ad9da 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/index.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/index.ts @@ -20,4 +20,5 @@ export const restApiRoutes: UMRestApiRouteCreator[] = [ createGetSnapshotCount, createLogMonitorPageRoute, createLogOverviewPageRoute, + createGetMonitorDetailsRoute, ]; diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts b/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts index 3cdd71fda3e43..b78fb8376cf6b 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts @@ -5,12 +5,22 @@ */ import { UMServerLibs } from '../../lib/lib'; +import { UMRestApiRouteCreator } from '../types'; -export const createGetIndexPatternRoute = (libs: UMServerLibs) => ({ +export const createGetIndexPatternRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => ({ method: 'GET', path: '/api/uptime/index_pattern', - tags: ['access:uptime'], - handler: async (): Promise => { - return await libs.savedObjects.getUptimeIndexPattern(); + validate: false, + options: { + tags: ['access:uptime'], + }, + handler: async (_context, _request, response): Promise => { + try { + return response.ok({ + ...(await libs.savedObjects.getUptimeIndexPattern()), + }); + } catch (e) { + return response.internalError({ body: { message: e.message } }); + } }, }); diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts b/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts index cf0a4cec44e92..e2bdbca9fbfa0 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts @@ -8,51 +8,41 @@ import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../lib/lib'; import { UMRestApiRouteCreator } from '../types'; -export const createGetAllRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => { - return { - method: 'GET', - path: '/api/uptime/pings', - validate: { - query: schema.object({ - dateRangeStart: schema.string(), - dateRangeEnd: schema.string(), - location: schema.maybe(schema.string()), - monitorId: schema.maybe(schema.string()), - size: schema.maybe(schema.number()), - sort: schema.maybe(schema.string()), - status: schema.maybe(schema.string()), - }), - }, - options: { - tags: ['access:uptime'], - }, - handler: async (context, request, resp): Promise => { - const { - size, - sort, - dateRangeStart, - dateRangeEnd, - location, - monitorId, - status, - } = request.query; +export const createGetAllRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => ({ + method: 'GET', + path: '/api/uptime/pings', + validate: { + query: schema.object({ + dateRangeStart: schema.string(), + dateRangeEnd: schema.string(), + location: schema.maybe(schema.string()), + monitorId: schema.maybe(schema.string()), + size: schema.maybe(schema.number()), + sort: schema.maybe(schema.string()), + status: schema.maybe(schema.string()), + }), + }, + options: { + tags: ['access:uptime'], + }, + handler: async (_context, request, response): Promise => { + const { size, sort, dateRangeStart, dateRangeEnd, location, monitorId, status } = request.query; - const result = await libs.pings.getAll( - request, - dateRangeStart, - dateRangeEnd, - monitorId, - status, - sort, - size, - location - ); + const result = await libs.pings.getAll( + request, + dateRangeStart, + dateRangeEnd, + monitorId, + status, + sort, + size, + location + ); - return resp.ok({ - body: { - ...result, - }, - }); - }, - }; -}; + return response.ok({ + body: { + ...result, + }, + }); + }, +}); diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_monitor_page.ts b/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_monitor_page.ts index 34c689be6e521..f3e926493143b 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_monitor_page.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_monitor_page.ts @@ -5,13 +5,15 @@ */ import { KibanaTelemetryAdapter } from '../../lib/adapters/telemetry'; +import { UMRestApiRouteCreator } from '../types'; -export const createLogMonitorPageRoute = () => ({ +export const createLogMonitorPageRoute: UMRestApiRouteCreator = () => ({ method: 'POST', path: '/api/uptime/logMonitor', - handler: async (request: any, h: any): Promise => { + validate: false, + handler: async (_context, _request, response): Promise => { await KibanaTelemetryAdapter.countMonitor(); - return h.response().code(200); + return response.ok(); }, options: { tags: ['access:uptime'], diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_overview_page.ts b/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_overview_page.ts index bd7e7d85637e7..277ef2235fb69 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_overview_page.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_overview_page.ts @@ -5,13 +5,15 @@ */ import { KibanaTelemetryAdapter } from '../../lib/adapters/telemetry'; +import { UMRestApiRouteCreator } from '../types'; -export const createLogOverviewPageRoute = () => ({ +export const createLogOverviewPageRoute: UMRestApiRouteCreator = () => ({ method: 'POST', path: '/api/uptime/logOverview', - handler: async (request: any, h: any): Promise => { + validate: false, + handler: async (_context, _request, response): Promise => { await KibanaTelemetryAdapter.countOverview(); - return h.response().code(200); + return response.ok(); }, options: { tags: ['access:uptime'], diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts b/x-pack/legacy/plugins/uptime/server/rest_api/types.ts index 68672b9651386..d9a675b3c4cba 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/types.ts @@ -5,14 +5,14 @@ */ import { ObjectType } from '@kbn/config-schema'; -import { RequestHandler } from 'kibana/server'; +import { RequestHandler, RouteConfig } from 'kibana/server'; import { UMServerLibs } from '../lib/lib'; export interface UMServerRoute { method: string; - path: string; - options?: any; handler: RequestHandler; } -export type UMRestApiRouteCreator = (libs: UMServerLibs) => UMServerRoute; +export type UMRouteDefinition = UMServerRoute & RouteConfig; + +export type UMRestApiRouteCreator = (libs: UMServerLibs) => UMRouteDefinition; From 74bb6f0ebcf8cdaa34dea75ad5ddfeb3e1ede407 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 20 Nov 2019 23:12:54 -0500 Subject: [PATCH 04/32] Remove obsolete code, update some unit tests. --- .../lib/adapters/framework/adapter_types.ts | 34 +--------- .../framework/kibana_framework_adapter.ts | 19 +----- .../uptime/server/lib/adapters/index.ts | 1 - .../__tests__/__snapshots__/auth.test.ts.snap | 8 +-- .../server/lib/domains/__tests__/auth.test.ts | 62 +++++++------------ .../plugins/uptime/server/rest_api/types.ts | 4 +- 6 files changed, 33 insertions(+), 95 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts index 10fa9b836028a..e67f4fa59531c 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts @@ -4,23 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { GraphQLOptions } from 'apollo-server-core'; import { GraphQLSchema } from 'graphql'; -import { Lifecycle, ResponseToolkit } from 'hapi'; -import { RouteOptions } from 'hapi'; -import { SavedObjectsLegacyService, RequestHandler, RouteMethod, IRouter } from 'src/core/server'; +import { SavedObjectsLegacyService, RequestHandler, IRouter } from 'src/core/server'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { ObjectType } from '@kbn/config-schema'; - -export interface UMFrameworkRequest { - user: string; - headers: Record; - payload: Record; - params: Record; - query: Record; -} - -export type UMFrameworkResponse = Lifecycle.ReturnValue; +import { UMRouteDefinition } from '../../../rest_api'; export interface UMFrameworkRouteOptions< P extends ObjectType, @@ -45,24 +33,8 @@ export interface UptimeCorePlugins { xpack: any; } -export type UMFrameworkRouteHandler = ( - request: UMFrameworkRequest, - h: ResponseToolkit -) => void; - -export type HapiOptionsFunction = (req: Request) => GraphQLOptions | Promise; - -export interface UMHapiGraphQLPluginOptions { - path: string; - vhost?: string; - route?: RouteOptions; - graphQLOptions: GraphQLOptions | HapiOptionsFunction; -} - export interface UMBackendFrameworkAdapter { - registerRoute( - route: UMFrameworkRouteOptions - ): void; + registerRoute(route: UMRouteDefinition): void; registerGraphQLEndpoint(routePath: string, schema: GraphQLSchema): void; getSavedObjectsClient(): any; } diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts index 4242522004d74..915d795f4855d 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -7,14 +7,9 @@ import { GraphQLSchema } from 'graphql'; import { schema as kbnSchema } from '@kbn/config-schema'; import { runHttpQuery } from 'apollo-server-core'; -import { ObjectType } from '@kbn/config-schema'; import { UptimeCorePlugins, UptimeCoreSetup } from './adapter_types'; -import { - UMBackendFrameworkAdapter, - UMFrameworkRequest, - UMFrameworkResponse, - UMFrameworkRouteOptions, -} from './adapter_types'; +import { UMBackendFrameworkAdapter } from './adapter_types'; +import { UMRouteDefinition } from '../../../rest_api'; export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapter { constructor( @@ -25,15 +20,7 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte this.plugins = plugins; } - public registerRoute< - RouteRequest extends UMFrameworkRequest, - RouteResponse extends UMFrameworkResponse - >({ - handler, - method, - path, - validate, - }: UMFrameworkRouteOptions) { + public registerRoute({ handler, method, path, validate }: UMRouteDefinition) { switch (method) { case 'GET': this.server.route.get( diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/index.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/index.ts index a09f80ae3b40a..2a88df91adc29 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/index.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/index.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -export * from './auth'; export * from './database'; export * from './framework'; export * from './monitor_states'; diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/auth.test.ts.snap b/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/auth.test.ts.snap index 3a959d5af7933..d7454d0d9066c 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/auth.test.ts.snap +++ b/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/auth.test.ts.snap @@ -1,9 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Auth domain lib throws for inactive license 1`] = `"this.adapter.getLicenseType is not a function"`; +exports[`authDomain throws for inactive license 1`] = `"License not active"`; -exports[`Auth domain lib throws for null license 1`] = `"Missing license information"`; +exports[`authDomain throws for null license 1`] = `"Missing license information"`; -exports[`Auth domain lib throws for unsupported license type 1`] = `"License not supported"`; - -exports[`Auth domain lib throws if request is not authenticated 1`] = `"Missing authentication"`; +exports[`authDomain throws for unsupported license type 1`] = `"License not supported"`; diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/auth.test.ts b/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/auth.test.ts index 5d9de84a6ebbc..4b6b313009188 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/auth.test.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/auth.test.ts @@ -4,56 +4,38 @@ * you may not use this file except in compliance with the Elastic License. */ -import { UMAuthDomain } from '../auth'; +import { authDomain } from '../auth'; +import { RequestHandlerContext } from 'kibana/server'; -describe('Auth domain lib', () => { - let domain: UMAuthDomain; - let mockAdapter: any; - let mockGetLicenseType: jest.Mock; - let mockLicenseIsActive: jest.Mock; - - beforeEach(() => { - mockAdapter = jest.fn(); - mockGetLicenseType = jest.fn(); - mockLicenseIsActive = jest.fn(); - domain = new UMAuthDomain(mockAdapter, {}); - }); - - afterEach(() => { - jest.clearAllMocks(); - }); +describe('authDomain', () => { + let mockContext: RequestHandlerContext; + const isOneOf = jest.fn(); it('throws for null license', () => { - mockGetLicenseType.mockReturnValue(null); - mockAdapter.getLicenseType = mockGetLicenseType; - expect(() => domain.requestIsValid({})).toThrowErrorMatchingSnapshot(); + // @ts-ignore there's a null check in this function + mockContext = { licensing: { license: null } }; + expect(() => authDomain(mockContext)).toThrowErrorMatchingSnapshot(); }); it('throws for unsupported license type', () => { - mockGetLicenseType.mockReturnValue('oss'); - mockAdapter.getLicenseType = mockGetLicenseType; - expect(() => domain.requestIsValid({})).toThrowErrorMatchingSnapshot(); + isOneOf.mockReturnValue(false); + expect(() => + // @ts-ignore it needs to throw if the license is not supported + authDomain({ licensing: { license: { isOneOf } } }) + ).toThrowErrorMatchingSnapshot(); }); it('throws for inactive license', () => { - mockLicenseIsActive.mockReturnValue(false); - mockAdapter.licenseIsActive = mockLicenseIsActive; - expect(() => domain.requestIsValid({})).toThrowErrorMatchingSnapshot(); - }); - - it('throws if request is not authenticated', () => { - mockGetLicenseType.mockReturnValue('basic'); - mockLicenseIsActive.mockReturnValue(true); - mockAdapter.getLicenseType = mockGetLicenseType; - mockAdapter.licenseIsActive = mockLicenseIsActive; - expect(() => domain.requestIsValid({})).toThrowErrorMatchingSnapshot(); + isOneOf.mockReturnValue(true); + expect(() => + // @ts-ignore it needs to throw if !isActive + authDomain({ licensing: { license: { isActive: false, isOneOf } } }) + ).toThrowErrorMatchingSnapshot(); }); - it('accepts request if authenticated', () => { - mockGetLicenseType.mockReturnValue('basic'); - mockLicenseIsActive.mockReturnValue(true); - mockAdapter.getLicenseType = mockGetLicenseType; - mockAdapter.licenseIsActive = mockLicenseIsActive; - expect(domain.requestIsValid({ auth: { isAuthenticated: true } })).toEqual(true); + it('returns true for a valid license', () => { + isOneOf.mockReturnValue(true); + // @ts-ignore license type needs to be non-null + expect(authDomain({ licensing: { license: { isActive: true, isOneOf } } })).toBe(true); }); }); diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts b/x-pack/legacy/plugins/uptime/server/rest_api/types.ts index d9a675b3c4cba..4991cda99aff7 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/types.ts @@ -5,7 +5,7 @@ */ import { ObjectType } from '@kbn/config-schema'; -import { RequestHandler, RouteConfig } from 'kibana/server'; +import { RequestHandler, RouteConfig, RouteMethod } from 'kibana/server'; import { UMServerLibs } from '../lib/lib'; export interface UMServerRoute { @@ -13,6 +13,6 @@ export interface UMServerRoute { handler: RequestHandler; } -export type UMRouteDefinition = UMServerRoute & RouteConfig; +export type UMRouteDefinition = UMServerRoute & RouteConfig; export type UMRestApiRouteCreator = (libs: UMServerLibs) => UMRouteDefinition; From b2730e551584bd5a52161496ba75146ce68a5844 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Thu, 21 Nov 2019 13:12:07 -0500 Subject: [PATCH 05/32] Simplify route creation. --- .../framework/kibana_framework_adapter.ts | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts index 915d795f4855d..a46a7e11bd738 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -20,25 +20,18 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte this.plugins = plugins; } - public registerRoute({ handler, method, path, validate }: UMRouteDefinition) { + public registerRoute({ handler, method, options, path, validate }: UMRouteDefinition) { + const routeDefinition = { + path, + validate, + options, + }; switch (method) { case 'GET': - this.server.route.get( - { - path, - validate, - }, - handler - ); + this.server.route.get(routeDefinition, handler); break; case 'POST': - this.server.route.post( - { - path, - validate, - }, - handler - ); + this.server.route.post(routeDefinition, handler); break; default: throw new Error(`Handler for method ${method} is not defined`); @@ -61,11 +54,14 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte path: routePath, validate: { body: kbnSchema.object({ - operationName: kbnSchema.string(), + operationName: kbnSchema.nullable(kbnSchema.string()), query: kbnSchema.string(), variables: kbnSchema.recordOf(kbnSchema.string(), kbnSchema.any()), }), }, + options: { + tags: ['access:uptime'], + }, }, async (context, request, resp): Promise => { try { From c36e42a45e3abbe981ab73950f5e117da2d0d6c6 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Thu, 21 Nov 2019 15:17:40 -0500 Subject: [PATCH 06/32] Remove tests of API decommissioned API endpoint. --- .../apis/uptime/feature_controls.ts | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/x-pack/test/api_integration/apis/uptime/feature_controls.ts b/x-pack/test/api_integration/apis/uptime/feature_controls.ts index 1dd9d5ff798c4..7a5e887bbdd9e 100644 --- a/x-pack/test/api_integration/apis/uptime/feature_controls.ts +++ b/x-pack/test/api_integration/apis/uptime/feature_controls.ts @@ -47,17 +47,6 @@ export default function featureControlsTests({ getService }: FtrProviderContext) .catch((error: any) => ({ error, response: undefined })); }; - const executeIsValidRequest = async (username: string, password: string, spaceId?: string) => { - const basePath = spaceId ? `/s/${spaceId}` : ''; - - return await supertest - .get(`${basePath}/api/uptime/is_valid`) - .auth(username, password) - .set('kbn-xsrf', 'foo') - .then((response: any) => ({ error: undefined, response })) - .catch((error: any) => ({ error, response: undefined })); - }; - const executePingsRequest = async (username: string, password: string, spaceId?: string) => { const basePath = spaceId ? `/s/${spaceId}` : ''; @@ -97,9 +86,6 @@ export default function featureControlsTests({ getService }: FtrProviderContext) const graphQLResult = await executeGraphQLQuery(username, password); expect404(graphQLResult); - const isValidResult = await executeIsValidRequest(username, password); - expect404(isValidResult); - const pingsResult = await executePingsRequest(username, password); expect404(pingsResult); } finally { @@ -139,9 +125,6 @@ export default function featureControlsTests({ getService }: FtrProviderContext) const graphQLResult = await executeGraphQLQuery(username, password); expectResponse(graphQLResult); - const isValidResult = await executeIsValidRequest(username, password); - expectResponse(isValidResult); - const pingsResult = await executePingsRequest(username, password); expectResponse(pingsResult); } finally { @@ -184,9 +167,6 @@ export default function featureControlsTests({ getService }: FtrProviderContext) const graphQLResult = await executeGraphQLQuery(username, password); expect404(graphQLResult); - const isValidResult = await executeIsValidRequest(username, password); - expect404(isValidResult); - const pingsResult = await executePingsRequest(username, password); expect404(pingsResult); } finally { @@ -256,9 +236,6 @@ export default function featureControlsTests({ getService }: FtrProviderContext) const graphQLResult = await executeGraphQLQuery(username, password, space1Id); expectResponse(graphQLResult); - const isValidResult = await executeIsValidRequest(username, password, space1Id); - expectResponse(isValidResult); - const pingsResult = await executePingsRequest(username, password, space1Id); expectResponse(pingsResult); }); @@ -267,9 +244,6 @@ export default function featureControlsTests({ getService }: FtrProviderContext) const graphQLResult = await executeGraphQLQuery(username, password); expect404(graphQLResult); - const isValidResult = await executeIsValidRequest(username, password); - expect404(isValidResult); - const pingsResult = await executePingsRequest(username, password); expect404(pingsResult); }); From 92aee58c8a0e65c7682e64a9b8b2acda31969a13 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Thu, 21 Nov 2019 15:47:03 -0500 Subject: [PATCH 07/32] Rename domain check. --- .../plugins/uptime/server/lib/compose/kibana.ts | 4 ++-- .../__tests__/__snapshots__/auth.test.ts.snap | 7 ------- .../__tests__/__snapshots__/license.test.ts.snap | 7 +++++++ .../__tests__/{auth.test.ts => license.test.ts} | 12 ++++++------ .../plugins/uptime/server/lib/domains/index.ts | 2 +- .../server/lib/domains/{auth.ts => license.ts} | 2 +- x-pack/legacy/plugins/uptime/server/lib/lib.ts | 2 +- .../uptime/server/rest_api/create_route_with_auth.ts | 2 +- 8 files changed, 19 insertions(+), 19 deletions(-) delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/auth.test.ts.snap create mode 100644 x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/license.test.ts.snap rename x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/{auth.test.ts => license.test.ts} (73%) rename x-pack/legacy/plugins/uptime/server/lib/domains/{auth.ts => license.ts} (90%) diff --git a/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts b/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts index 7027a30bfce17..a7c370e03490b 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts @@ -8,7 +8,7 @@ import { UMKibanaDatabaseAdapter } from '../adapters/database/kibana_database_ad import { UMKibanaBackendFrameworkAdapter } from '../adapters/framework'; import { ElasticsearchMonitorsAdapter } from '../adapters/monitors'; import { ElasticsearchPingsAdapter } from '../adapters/pings'; -import { authDomain } from '../domains'; +import { licenseCheck } from '../domains'; import { UMDomainLibs, UMServerLibs } from '../lib'; import { ElasticsearchMonitorStatesAdapter } from '../adapters/monitor_states'; import { UMKibanaSavedObjectsAdapter } from '../adapters/saved_objects/kibana_saved_objects_adapter'; @@ -20,7 +20,7 @@ export function compose(server: UptimeCoreSetup, plugins: UptimeCorePlugins): UM const database = new UMKibanaDatabaseAdapter(elasticsearch); const domainLibs: UMDomainLibs = { - auth: authDomain, + license: licenseCheck, monitors: new ElasticsearchMonitorsAdapter(database), monitorStates: new ElasticsearchMonitorStatesAdapter(database), pings: new ElasticsearchPingsAdapter(database), diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/auth.test.ts.snap b/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/auth.test.ts.snap deleted file mode 100644 index d7454d0d9066c..0000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/auth.test.ts.snap +++ /dev/null @@ -1,7 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`authDomain throws for inactive license 1`] = `"License not active"`; - -exports[`authDomain throws for null license 1`] = `"Missing license information"`; - -exports[`authDomain throws for unsupported license type 1`] = `"License not supported"`; diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/license.test.ts.snap b/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/license.test.ts.snap new file mode 100644 index 0000000000000..07d437112e888 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/license.test.ts.snap @@ -0,0 +1,7 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`license check throws for inactive license 1`] = `"License not active"`; + +exports[`license check throws for null license 1`] = `"Missing license information"`; + +exports[`license check throws for unsupported license type 1`] = `"License not supported"`; diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/auth.test.ts b/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/license.test.ts similarity index 73% rename from x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/auth.test.ts rename to x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/license.test.ts index 4b6b313009188..73e70cb78626d 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/auth.test.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/license.test.ts @@ -4,24 +4,24 @@ * you may not use this file except in compliance with the Elastic License. */ -import { authDomain } from '../auth'; +import { licenseCheck } from '../license'; import { RequestHandlerContext } from 'kibana/server'; -describe('authDomain', () => { +describe('license check', () => { let mockContext: RequestHandlerContext; const isOneOf = jest.fn(); it('throws for null license', () => { // @ts-ignore there's a null check in this function mockContext = { licensing: { license: null } }; - expect(() => authDomain(mockContext)).toThrowErrorMatchingSnapshot(); + expect(() => licenseCheck(mockContext)).toThrowErrorMatchingSnapshot(); }); it('throws for unsupported license type', () => { isOneOf.mockReturnValue(false); expect(() => // @ts-ignore it needs to throw if the license is not supported - authDomain({ licensing: { license: { isOneOf } } }) + licenseCheck({ licensing: { license: { isOneOf } } }) ).toThrowErrorMatchingSnapshot(); }); @@ -29,13 +29,13 @@ describe('authDomain', () => { isOneOf.mockReturnValue(true); expect(() => // @ts-ignore it needs to throw if !isActive - authDomain({ licensing: { license: { isActive: false, isOneOf } } }) + licenseCheck({ licensing: { license: { isActive: false, isOneOf } } }) ).toThrowErrorMatchingSnapshot(); }); it('returns true for a valid license', () => { isOneOf.mockReturnValue(true); // @ts-ignore license type needs to be non-null - expect(authDomain({ licensing: { license: { isActive: true, isOneOf } } })).toBe(true); + expect(licenseCheck({ licensing: { license: { isActive: true, isOneOf } } })).toBe(true); }); }); diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/index.ts b/x-pack/legacy/plugins/uptime/server/lib/domains/index.ts index b2d7503a6a192..6a35b9b41020b 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/index.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/domains/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { authDomain, UMLicenseCheck } from './auth'; +export { licenseCheck, UMLicenseCheck } from './license'; diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/auth.ts b/x-pack/legacy/plugins/uptime/server/lib/domains/license.ts similarity index 90% rename from x-pack/legacy/plugins/uptime/server/lib/domains/auth.ts rename to x-pack/legacy/plugins/uptime/server/lib/domains/license.ts index e7edc6913ab07..22bb30d42387d 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/auth.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/domains/license.ts @@ -9,7 +9,7 @@ import { RequestHandlerContext } from 'kibana/server'; export type UMLicenseCheck = (context: RequestHandlerContext) => boolean; -export const authDomain: UMLicenseCheck = ({ licensing: { license } }) => { +export const licenseCheck: UMLicenseCheck = ({ licensing: { license } }) => { if (license === null) { throw Boom.badRequest('Missing license information'); } diff --git a/x-pack/legacy/plugins/uptime/server/lib/lib.ts b/x-pack/legacy/plugins/uptime/server/lib/lib.ts index 9a6a8217d1278..e68a6dd18ef5f 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/lib.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/lib.ts @@ -15,7 +15,7 @@ import { import { UMLicenseCheck } from './domains'; export interface UMDomainLibs { - auth: UMLicenseCheck; + license: UMLicenseCheck; monitors: UMMonitorsAdapter; monitorStates: UMMonitorStatesAdapter; pings: UMPingsAdapter; diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts b/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts index 26ae3b454cfb8..7fbae1d2091fe 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts @@ -20,7 +20,7 @@ export const createRouteWithAuth = ( request, response ) => { - if (libs.auth(context)) { + if (libs.license(context)) { return await handler(context, request, response); } return response.badRequest(); From 49d8cf26a4f8e0d628f16c3935067bab9fd4ecc5 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Mon, 25 Nov 2019 13:21:30 -0500 Subject: [PATCH 08/32] Make return shape of index pattern endpoint correspond to required NP resp body. --- .../uptime/server/rest_api/index_pattern/get_index_pattern.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts b/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts index b78fb8376cf6b..55f0af57ed847 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts @@ -17,7 +17,9 @@ export const createGetIndexPatternRoute: UMRestApiRouteCreator = (libs: UMServer handler: async (_context, _request, response): Promise => { try { return response.ok({ - ...(await libs.savedObjects.getUptimeIndexPattern()), + body: { + ...(await libs.savedObjects.getUptimeIndexPattern()), + }, }); } catch (e) { return response.internalError({ body: { message: e.message } }); From bb35540172b5912958440a99bc6ab1d2fbb1c4e9 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Mon, 25 Nov 2019 13:24:50 -0500 Subject: [PATCH 09/32] Move validate to appropriate level of route definition object for monitor details endpoint. --- .../rest_api/monitors/monitors_details.ts | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts b/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts index 1440b55c1c137..00860248ff153 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts @@ -3,23 +3,27 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import Joi from 'joi'; + +import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../lib/lib'; -import { MonitorDetails } from '../../../common/runtime_types/monitor/monitor_details'; +import { UMRestApiRouteCreator } from '../types'; -export const createGetMonitorDetailsRoute = (libs: UMServerLibs) => ({ +export const createGetMonitorDetailsRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => ({ method: 'GET', path: '/api/uptime/monitor/details', + validate: { + query: schema.object({ + monitorId: schema.maybe(schema.string()), + }), + }, options: { - validate: { - query: Joi.object({ - monitorId: Joi.string(), - }), - }, tags: ['access:uptime'], }, - handler: async (request: any): Promise => { + handler: async (_context, request, response): Promise => { const { monitorId } = request.query; - return await libs.monitors.getMonitorDetails(request, monitorId); + + return response.ok({ + body: { ...(await libs.monitors.getMonitorDetails(request, monitorId)) }, + }); }, }); From 789d23254421921e5105cb3cc07207f1871fa5ca Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Mon, 2 Dec 2019 13:15:13 -0500 Subject: [PATCH 10/32] Update snapshot count route. --- .../plugins/uptime/server/rest_api/index.ts | 1 - .../rest_api/snapshot/get_snapshot_count.ts | 36 ++++++++++--------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/index.ts b/x-pack/legacy/plugins/uptime/server/rest_api/index.ts index 9d1d8c38ad9da..2810982fb0c6c 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/index.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/index.ts @@ -20,5 +20,4 @@ export const restApiRoutes: UMRestApiRouteCreator[] = [ createGetSnapshotCount, createLogMonitorPageRoute, createLogOverviewPageRoute, - createGetMonitorDetailsRoute, ]; diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts b/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts index 5f5ce03d2cd7f..9b2b26f52699e 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts @@ -4,33 +4,37 @@ * you may not use this file except in compliance with the Elastic License. */ -import Joi from 'joi'; +import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../lib/lib'; -import { Snapshot } from '../../../common/runtime_types'; import { UMRestApiRouteCreator } from '../types'; export const createGetSnapshotCount: UMRestApiRouteCreator = (libs: UMServerLibs) => ({ method: 'GET', path: '/api/uptime/snapshot/count', validate: { - query: Joi.object({ - dateRangeStart: Joi.string().required(), - dateRangeEnd: Joi.string().required(), - filters: Joi.string(), - statusFilter: Joi.string(), + query: schema.object({ + dateRangeStart: schema.string(), + dateRangeEnd: schema.string(), + filters: schema.maybe(schema.string()), + statusFilter: schema.maybe(schema.string()), }), }, - tags: ['access:uptime'], - handler: async (_context: any, request: any, response: any): Promise => { + options: { + tags: ['access:uptime'], + }, + handler: async (_context, request, response): Promise => { const { dateRangeStart, dateRangeEnd, filters, statusFilter } = request.query; + const result = await libs.monitorStates.getSnapshotCount( + request, + dateRangeStart, + dateRangeEnd, + filters, + statusFilter + ); return response.ok({ - body: await libs.monitorStates.getSnapshotCount( - request, - dateRangeStart, - dateRangeEnd, - filters, - statusFilter - ), + body: { + ...result, + }, }); }, }); From a4047afdfee7f390bdcbb54e90edbc7357093b0f Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Mon, 2 Dec 2019 18:08:26 -0500 Subject: [PATCH 11/32] Fix broken lint rule. --- x-pack/legacy/plugins/uptime/server/rest_api/types.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts b/x-pack/legacy/plugins/uptime/server/rest_api/types.ts index 4991cda99aff7..b4d7e438f51be 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/types.ts @@ -13,6 +13,7 @@ export interface UMServerRoute { handler: RequestHandler; } -export type UMRouteDefinition = UMServerRoute & RouteConfig; +export type UMRouteDefinition = UMServerRoute & + RouteConfig; export type UMRestApiRouteCreator = (libs: UMServerLibs) => UMRouteDefinition; From 7221e8a3f6701c146165c6ffd7e584310ba02946 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Tue, 19 Nov 2019 17:59:33 -0500 Subject: [PATCH 12/32] Move a REST endpoint and the GQL endpoint to NP routing. --- .../server/lib/adapters/framework/kibana_framework_adapter.ts | 2 +- x-pack/legacy/plugins/uptime/server/rest_api/types.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts index a46a7e11bd738..a532ec1fd3362 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -54,7 +54,7 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte path: routePath, validate: { body: kbnSchema.object({ - operationName: kbnSchema.nullable(kbnSchema.string()), + operationName: kbnSchema.string(), query: kbnSchema.string(), variables: kbnSchema.recordOf(kbnSchema.string(), kbnSchema.any()), }), diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts b/x-pack/legacy/plugins/uptime/server/rest_api/types.ts index b4d7e438f51be..262eea15ea4a2 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/types.ts @@ -10,6 +10,8 @@ import { UMServerLibs } from '../lib/lib'; export interface UMServerRoute { method: string; + path: string; + options?: any; handler: RequestHandler; } From 64fe3873ca8c042769f526d274b1893e65d2cdec Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 20 Nov 2019 12:35:15 -0500 Subject: [PATCH 13/32] Update remaining REST routes to work with NP router. --- .../lib/adapters/framework/kibana_framework_adapter.ts | 9 +++++++++ x-pack/legacy/plugins/uptime/server/rest_api/types.ts | 2 -- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts index a532ec1fd3362..9887db2fd30c2 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -33,6 +33,15 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte case 'POST': this.server.route.post(routeDefinition, handler); break; + case 'POST': + this.server.route.post( + { + path, + validate, + }, + handler + ); + break; default: throw new Error(`Handler for method ${method} is not defined`); } diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts b/x-pack/legacy/plugins/uptime/server/rest_api/types.ts index 262eea15ea4a2..b4d7e438f51be 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/types.ts @@ -10,8 +10,6 @@ import { UMServerLibs } from '../lib/lib'; export interface UMServerRoute { method: string; - path: string; - options?: any; handler: RequestHandler; } From 43a1c83d5c9f50b0848eab64ec74e10c3848408c Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Thu, 21 Nov 2019 18:39:59 -0500 Subject: [PATCH 14/32] Refactor query functions to accept new es client from request contexts. --- x-pack/legacy/plugins/uptime/index.ts | 1 - .../lib/adapters/database/adapter_types.ts | 8 --- .../database/kibana_database_adapter.ts | 32 ---------- .../lib/adapters/framework/adapter_types.ts | 17 +++++- .../adapters/monitor_states/adapter_types.ts | 38 ++++++------ .../elasticsearch_monitor_states_adapter.ts | 59 +++++++------------ .../lib/adapters/monitor_states/index.ts | 2 +- .../search/enrich_monitor_groups.ts | 4 +- .../search/find_potential_matches.ts | 2 +- .../search/refine_potential_matches.ts | 4 +- .../lib/adapters/monitors/adapter_types.ts | 32 ++++++---- .../elasticsearch_monitors_adapter.ts | 51 ++++------------ 12 files changed, 99 insertions(+), 151 deletions(-) delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/adapters/database/kibana_database_adapter.ts diff --git a/x-pack/legacy/plugins/uptime/index.ts b/x-pack/legacy/plugins/uptime/index.ts index 3cd0ffb1a2942..40624d3a9579d 100644 --- a/x-pack/legacy/plugins/uptime/index.ts +++ b/x-pack/legacy/plugins/uptime/index.ts @@ -44,7 +44,6 @@ export const uptime = (kibana: any) => route: server.newPlatform.setup.core.http.createRouter(), }, { - elasticsearch, savedObjects, usageCollection, xpack: xpack_main, diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/database/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/database/adapter_types.ts index ace86cf946043..412bc7abcdacb 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/database/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/database/adapter_types.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { CountParams, CountResponse } from 'elasticsearch'; - export interface HistogramQueryResult { key: number; doc_count: number; @@ -27,9 +25,3 @@ export interface UMESHistogramBucket { x: number; x0: number; } - -export interface DatabaseAdapter { - count(request: any, params: CountParams): Promise; - search(request: any, params: any): Promise; - head(request: any, params: any): Promise; -} diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/database/kibana_database_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/database/kibana_database_adapter.ts deleted file mode 100644 index 4b2523503fc8f..0000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/database/kibana_database_adapter.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 { DatabaseAdapter } from './adapter_types'; - -interface KibanaElasticsearchPlugin { - getCluster: (clusterName: 'admin' | 'data') => any; - callWithRequest: (request: any, action: string, params: any) => any; -} - -export class UMKibanaDatabaseAdapter implements DatabaseAdapter { - private elasticsearch: KibanaElasticsearchPlugin; - - constructor(kbnElasticsearch: KibanaElasticsearchPlugin) { - this.elasticsearch = kbnElasticsearch.getCluster('data'); - } - - public async search(request: any, params: any): Promise { - return this.elasticsearch.callWithRequest(request, 'search', params); - } - - public async count(request: any, params: any): Promise { - return this.elasticsearch.callWithRequest(request, 'count', params); - } - - public async head(request: any, params: { index: string }): Promise { - return this.elasticsearch.callWithRequest(request, 'indices.exists', params); - } -} diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts index e67f4fa59531c..f8f1343184be9 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts @@ -5,8 +5,13 @@ */ import { GraphQLSchema } from 'graphql'; -import { SavedObjectsLegacyService, RequestHandler, IRouter } from 'src/core/server'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; +import { + SavedObjectsLegacyService, + RequestHandler, + IRouter, + CallAPIOptions, +} from 'src/core/server'; import { ObjectType } from '@kbn/config-schema'; import { UMRouteDefinition } from '../../../rest_api'; @@ -22,12 +27,20 @@ export interface UMFrameworkRouteOptions< validate: any; } +export type UMElasticsearchQueryFn = ( + callAsCurrentUser: ( + endpoint: string, + clientParams: Record, + options?: CallAPIOptions + ) => Promise, + params: P +) => Promise | T; + export interface UptimeCoreSetup { route: IRouter; } export interface UptimeCorePlugins { - elasticsearch: any; savedObjects: SavedObjectsLegacyService; usageCollection: UsageCollectionSetup; xpack: any; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/adapter_types.ts index 57b1744f5d324..9dec7834811c8 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/adapter_types.ts @@ -6,28 +6,25 @@ import { MonitorSummary, - StatesIndexStatus, CursorDirection, SortOrder, + StatesIndexStatus, } from '../../../../common/graphql/types'; +import { UMElasticsearchQueryFn } from '../framework'; +import { Snapshot } from '../../../../common/runtime_types'; + +export interface MonitorStatesParams { + dateRangeStart: string; + dateRangeEnd: string; + pagination?: CursorPagination; + filters?: string | null; + statusFilter?: string | null; +} export interface UMMonitorStatesAdapter { - getMonitorStates( - request: any, - dateRangeStart: string, - dateRangeEnd: string, - pagination?: CursorPagination, - filters?: string | null, - statusFilter?: string | null - ): Promise; - statesIndexExists(request: any): Promise; - getSnapshotCount( - request: any, - dateRangeStart: string, - dateRangeEnd: string, - filters?: string, - statusFilter?: string - ): Promise; + getMonitorStates: UMElasticsearchQueryFn; + getSnapshotCount: UMElasticsearchQueryFn; + statesIndexExists: UMElasticsearchQueryFn; } export interface CursorPagination { @@ -42,6 +39,13 @@ export interface GetMonitorStatesResult { prevPagePagination: string | null; } +export interface GetSnapshotCountParams { + dateRangeStart: string; + dateRangeEnd: string; + filters?: string | null; + statusFilter?: string | null; +} + export interface LegacyMonitorStatesQueryResult { result: any; statusFilter?: any; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/elasticsearch_monitor_states_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/elasticsearch_monitor_states_adapter.ts index c3593854fa53f..c3a41d2280a40 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/elasticsearch_monitor_states_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/elasticsearch_monitor_states_adapter.ts @@ -4,18 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ -import { DatabaseAdapter } from '../database'; -import { UMMonitorStatesAdapter, GetMonitorStatesResult, CursorPagination } from './adapter_types'; -import { StatesIndexStatus } from '../../../../common/graphql/types'; +import { UMMonitorStatesAdapter, CursorPagination } from './adapter_types'; import { INDEX_NAMES, CONTEXT_DEFAULTS } from '../../../../common/constants'; import { fetchPage } from './search'; import { MonitorGroupIterator } from './search/monitor_group_iterator'; -import { Snapshot } from '../../../../common/runtime_types'; import { getSnapshotCountHelper } from './get_snapshot_helper'; export interface QueryContext { - database: any; - request: any; + count: (query: Record) => Promise; + search: (query: Record) => Promise; dateRangeStart: string; dateRangeEnd: string; pagination: CursorPagination; @@ -24,25 +21,19 @@ export interface QueryContext { statusFilter?: string; } -export class ElasticsearchMonitorStatesAdapter implements UMMonitorStatesAdapter { - constructor(private readonly database: DatabaseAdapter) { - this.database = database; - } - +export const elasticsearchMonitorStatesAdapter: UMMonitorStatesAdapter = { // Gets a page of monitor states. - public async getMonitorStates( - request: any, - dateRangeStart: string, - dateRangeEnd: string, - pagination: CursorPagination = CONTEXT_DEFAULTS.CURSOR_PAGINATION, - filters?: string | null, - statusFilter?: string - ): Promise { + getMonitorStates: async ( + callAsCurrentUser, + { dateRangeStart, dateRangeEnd, pagination, filters, statusFilter } + ) => { + pagination = pagination || CONTEXT_DEFAULTS.CURSOR_PAGINATION; + statusFilter = statusFilter === null ? undefined : statusFilter; const size = 10; const queryContext: QueryContext = { - database: this.database, - request, + count: (query: Record): Promise => callAsCurrentUser('count', query), + search: (query: Record): Promise => callAsCurrentUser('search', query), dateRangeStart, dateRangeEnd, pagination, @@ -58,42 +49,36 @@ export class ElasticsearchMonitorStatesAdapter implements UMMonitorStatesAdapter nextPagePagination: jsonifyPagination(page.nextPagePagination), prevPagePagination: jsonifyPagination(page.prevPagePagination), }; - } + }, - public async getSnapshotCount( - request: any, - dateRangeStart: string, - dateRangeEnd: string, - filters?: string, - statusFilter?: string - ): Promise { + getSnapshotCount: async (callEs, { dateRangeStart, dateRangeEnd, filters, statusFilter }) => { const context: QueryContext = { - database: this.database, - request, + count: query => callEs('count', query), + search: query => callEs('search', query), dateRangeStart, dateRangeEnd, pagination: CONTEXT_DEFAULTS.CURSOR_PAGINATION, filterClause: filters && filters !== '' ? JSON.parse(filters) : null, size: CONTEXT_DEFAULTS.MAX_MONITORS_FOR_SNAPSHOT_COUNT, - statusFilter, + statusFilter: statusFilter || undefined, }; return getSnapshotCountHelper(new MonitorGroupIterator(context)); - } + }, - public async statesIndexExists(request: any): Promise { + statesIndexExists: async callEs => { // TODO: adapt this to the states index in future release const { _shards: { total }, count, - } = await this.database.count(request, { index: INDEX_NAMES.HEARTBEAT }); + } = await callEs('count', { index: INDEX_NAMES.HEARTBEAT }); return { indexExists: total > 0, docCount: { count, }, }; - } -} + }, +}; // To simplify the handling of the group of pagination vars they're passed back to the client as a string const jsonifyPagination = (p: any): string | null => { diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/index.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/index.ts index f23cacce7bbbe..a3fc71ad48cb3 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/index.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/index.ts @@ -5,4 +5,4 @@ */ export * from './adapter_types'; -export { ElasticsearchMonitorStatesAdapter } from './elasticsearch_monitor_states_adapter'; +export { elasticsearchMonitorStatesAdapter } from './elasticsearch_monitor_states_adapter'; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/enrich_monitor_groups.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/enrich_monitor_groups.ts index 6b594d8b49118..093e105635c2c 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/enrich_monitor_groups.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/enrich_monitor_groups.ts @@ -243,7 +243,7 @@ export const enrichMonitorGroups: MonitorEnricher = async ( }, }; - const items = await queryContext.database.search(queryContext.request, params); + const items = await queryContext.search(params); const monitorBuckets = get(items, 'aggregations.monitors.buckets', []); @@ -345,7 +345,7 @@ const getHistogramForMonitors = async ( }, }, }; - const result = await queryContext.database.search(queryContext.request, params); + const result = await queryContext.search(params); const buckets: any[] = get(result, 'aggregations.by_id.buckets', []); return buckets.reduce((map: { [key: string]: any }, item: any) => { diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/find_potential_matches.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/find_potential_matches.ts index 002dc2862fa1b..8f5e26b75f56c 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/find_potential_matches.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/find_potential_matches.ts @@ -62,7 +62,7 @@ const query = async (queryContext: QueryContext, searchAfter: any, size: number) body, }; - return await queryContext.database.search(queryContext.request, params); + return await queryContext.search(params); }; const queryBody = (queryContext: QueryContext, searchAfter: any, size: number) => { diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/refine_potential_matches.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/refine_potential_matches.ts index 3bdd6fe616f18..b0060cbee17bb 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/refine_potential_matches.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/refine_potential_matches.ts @@ -95,7 +95,7 @@ const fullyMatchingIds = async ( export const mostRecentCheckGroups = async ( queryContext: QueryContext, potentialMatchMonitorIDs: string[] -) => { +): Promise => { const params = { index: INDEX_NAMES.HEARTBEAT, body: { @@ -134,5 +134,5 @@ export const mostRecentCheckGroups = async ( }, }; - return await queryContext.database.search(queryContext.request, params); + return await queryContext.search(params); }; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/adapter_types.ts index f6ac587b0ceec..8dc55531f99a8 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/adapter_types.ts @@ -5,16 +5,28 @@ */ import { MonitorChart, MonitorPageTitle } from '../../../../common/graphql/types'; +import { UMElasticsearchQueryFn } from '../framework'; +import { MonitorDetails } from '../../../../common/runtime_types'; + +export interface GetMonitorChartsDataParams { + monitorId: string; + dateRangeStart: string; + dateRangeEnd: string; + location?: string | null; +} + +export interface GetFilterBarParams { + dateRangeStart: string; + dateRangeEnd: string; +} + +export interface GetMonitorDetailsParams { + monitorId: string; +} export interface UMMonitorsAdapter { - getMonitorChartsData( - request: any, - monitorId: string, - dateRangeStart: string, - dateRangeEnd: string, - location?: string | null - ): Promise; - getFilterBar(request: any, dateRangeStart: string, dateRangeEnd: string): Promise; - getMonitorPageTitle(request: any, monitorId: string): Promise; - getMonitorDetails(request: any, monitorId: string): Promise; + getMonitorChartsData: UMElasticsearchQueryFn; + getFilterBar: UMElasticsearchQueryFn; + getMonitorPageTitle: UMElasticsearchQueryFn; + getMonitorDetails: UMElasticsearchQueryFn; } diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts index ef0837a043172..612ecf2c3c4f4 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts @@ -6,17 +6,9 @@ import { get } from 'lodash'; import { INDEX_NAMES } from '../../../../common/constants'; -import { - FilterBar, - MonitorChart, - MonitorPageTitle, - Ping, - LocationDurationLine, -} from '../../../../common/graphql/types'; +import { MonitorChart, Ping, LocationDurationLine } from '../../../../common/graphql/types'; import { getHistogramIntervalFormatted } from '../../helper'; -import { DatabaseAdapter } from '../database'; import { UMMonitorsAdapter } from './adapter_types'; -import { MonitorDetails, Error } from '../../../../common/runtime_types'; const formatStatusBuckets = (time: any, buckets: any, docCount: any) => { let up = null; @@ -38,11 +30,7 @@ const formatStatusBuckets = (time: any, buckets: any, docCount: any) => { }; }; -export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter { - constructor(private readonly database: DatabaseAdapter) { - this.database = database; - } - +export const elasticsearchMonitorsAdapter: UMMonitorsAdapter = { /** * Fetches data used to populate monitor charts * @param request Kibana request @@ -50,13 +38,7 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter { * @param dateRangeStart timestamp bounds * @param dateRangeEnd timestamp bounds */ - public async getMonitorChartsData( - request: any, - monitorId: string, - dateRangeStart: string, - dateRangeEnd: string, - location?: string | null - ): Promise { + getMonitorChartsData: async (callEs, { dateRangeStart, dateRangeEnd, monitorId, location }) => { const params = { index: INDEX_NAMES.HEARTBEAT, body: { @@ -96,7 +78,7 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter { }, }; - const result = await this.database.search(request, params); + const result = await callEs('search', params); const dateHistogramBuckets = get(result, 'aggregations.timeseries.buckets', []); /** @@ -182,7 +164,7 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter { }); return monitorChartsData; - } + }, /** * Fetch options for the filter bar. @@ -190,11 +172,7 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter { * @param dateRangeStart timestamp bounds * @param dateRangeEnd timestamp bounds */ - public async getFilterBar( - request: any, - dateRangeStart: string, - dateRangeEnd: string - ): Promise { + getFilterBar: async (callEs, { dateRangeStart, dateRangeEnd }) => { const fields: { [key: string]: string } = { ids: 'monitor.id', schemes: 'monitor.type', @@ -220,24 +198,21 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter { }, {}), }, }; - const { aggregations } = await this.database.search(request, params); + const { aggregations } = await callEs('search', params); return Object.keys(fields).reduce((acc: { [key: string]: any[] }, field) => { const bucketName = fields[field]; acc[field] = aggregations[bucketName].buckets.map((b: { key: string | number }) => b.key); return acc; }, {}); - } + }, /** * Fetch data for the monitor page title. * @param request Kibana server request * @param monitorId the ID to query */ - public async getMonitorPageTitle( - request: any, - monitorId: string - ): Promise { + getMonitorPageTitle: async (callEs, { monitorId }) => { const params = { index: INDEX_NAMES.HEARTBEAT, body: { @@ -261,7 +236,7 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter { }, }; - const result = await this.database.search(request, params); + const result = await callEs('search', params); const pageTitle: Ping | null = get(result, 'hits.hits[0]._source', null); if (pageTitle === null) { return null; @@ -271,9 +246,9 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter { url: get(pageTitle, 'url.full', null), name: get(pageTitle, 'monitor.name', null), }; - } + }, - public async getMonitorDetails(request: any, monitorId: string): Promise { + getMonitorDetails: async (callEs, { monitorId }) => { const params = { index: INDEX_NAMES.HEARTBEAT, body: { @@ -306,7 +281,7 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter { }, }; - const result = await this.database.search(request, params); + const result = await callEs('search', params); const monitorError: Error | undefined = get(result, 'hits.hits[0]._source.error', undefined); From 6eb1bf3c982de6ca3b9a04025fd70afe1f1e35a7 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Thu, 21 Nov 2019 18:41:50 -0500 Subject: [PATCH 15/32] WIP updating framework adapter. --- x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts b/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts index a7c370e03490b..eda8dad18ab7b 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts @@ -4,25 +4,23 @@ * you may not use this file except in compliance with the Elastic License. */ -import { UMKibanaDatabaseAdapter } from '../adapters/database/kibana_database_adapter'; import { UMKibanaBackendFrameworkAdapter } from '../adapters/framework'; import { ElasticsearchMonitorsAdapter } from '../adapters/monitors'; import { ElasticsearchPingsAdapter } from '../adapters/pings'; import { licenseCheck } from '../domains'; import { UMDomainLibs, UMServerLibs } from '../lib'; -import { ElasticsearchMonitorStatesAdapter } from '../adapters/monitor_states'; +import { elasticsearchMonitorStatesAdapter } from '../adapters/monitor_states'; import { UMKibanaSavedObjectsAdapter } from '../adapters/saved_objects/kibana_saved_objects_adapter'; import { UptimeCorePlugins, UptimeCoreSetup } from '../adapters/framework'; export function compose(server: UptimeCoreSetup, plugins: UptimeCorePlugins): UMServerLibs { - const { elasticsearch, savedObjects } = plugins; + const { savedObjects } = plugins; const framework = new UMKibanaBackendFrameworkAdapter(server, plugins); - const database = new UMKibanaDatabaseAdapter(elasticsearch); const domainLibs: UMDomainLibs = { license: licenseCheck, monitors: new ElasticsearchMonitorsAdapter(database), - monitorStates: new ElasticsearchMonitorStatesAdapter(database), + monitorStates: elasticsearchMonitorStatesAdapter, pings: new ElasticsearchPingsAdapter(database), savedObjects: new UMKibanaSavedObjectsAdapter(savedObjects, elasticsearch), }; From 29900710df88728a620ae38b2d97f99699287682 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Fri, 22 Nov 2019 13:31:50 -0500 Subject: [PATCH 16/32] Refactor remaining routes/resolvers to remove usage of legacy Elasticsearch client. --- .../graphql/monitor_states/resolvers.ts | 19 ++-- .../server/graphql/monitors/resolvers.ts | 47 ++++---- .../uptime/server/graphql/pings/resolvers.ts | 15 ++- .../plugins/uptime/server/graphql/types.ts | 12 +- .../lib/adapters/database/adapter_types.ts | 27 ----- .../server/lib/adapters/database/index.ts | 7 -- .../lib/adapters/framework/adapter_types.ts | 7 +- .../framework/kibana_framework_adapter.ts | 46 ++++---- .../lib/adapters/monitors/adapter_types.ts | 16 +++ .../elasticsearch_monitors_adapter.ts | 18 --- .../server/lib/adapters/monitors/index.ts | 2 +- .../lib/adapters/pings/adapter_types.ts | 106 +++++++++++++----- .../pings/elasticsearch_pings_adapter.ts | 98 ++++------------ .../uptime/server/lib/adapters/pings/index.ts | 2 +- .../lib/adapters/saved_objects/index.ts | 2 +- .../kibana_saved_objects_adapter.ts | 21 +--- .../lib/adapters/saved_objects/types.ts | 4 +- .../uptime/server/lib/compose/kibana.ts | 16 ++- .../legacy/plugins/uptime/server/lib/lib.ts | 2 - .../server/rest_api/create_route_with_auth.ts | 4 +- .../index_pattern/get_index_pattern.ts | 10 +- .../uptime/server/rest_api/pings/get_all.ts | 19 +++- 22 files changed, 235 insertions(+), 265 deletions(-) delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/adapters/database/adapter_types.ts delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/adapters/database/index.ts diff --git a/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/resolvers.ts b/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/resolvers.ts index 8fbf3529dbe24..6d210e8635754 100644 --- a/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/resolvers.ts +++ b/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/resolvers.ts @@ -39,9 +39,9 @@ export const createMonitorStatesResolvers: CreateUMGraphQLResolvers = ( return { Query: { async getMonitorStates( - resolver, + _resolver, { dateRangeStart, dateRangeEnd, filters, pagination, statusFilter }, - { req } + { callAsCurrentUser } ): Promise { const decodedPagination = pagination ? JSON.parse(decodeURIComponent(pagination)) @@ -50,15 +50,14 @@ export const createMonitorStatesResolvers: CreateUMGraphQLResolvers = ( totalSummaryCount, { summaries, nextPagePagination, prevPagePagination }, ] = await Promise.all([ - libs.pings.getDocCount(req), - libs.monitorStates.getMonitorStates( - req, + libs.pings.getDocCount(callAsCurrentUser, undefined), + libs.monitorStates.getMonitorStates(callAsCurrentUser, { dateRangeStart, dateRangeEnd, - decodedPagination, + pagination: decodedPagination, filters, - statusFilter - ), + statusFilter, + }), ]); return { summaries, @@ -67,8 +66,8 @@ export const createMonitorStatesResolvers: CreateUMGraphQLResolvers = ( totalSummaryCount, }; }, - async getStatesIndexStatus(resolver, {}, { req }): Promise { - return await libs.monitorStates.statesIndexExists(req); + async getStatesIndexStatus(_resolver, {}, { callAsCurrentUser }): Promise { + return await libs.monitorStates.statesIndexExists(callAsCurrentUser, undefined); }, }, }; diff --git a/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts b/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts index 415afc87e201e..e0a8e4f10ba7c 100644 --- a/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts +++ b/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts @@ -71,54 +71,55 @@ export const createMonitorsResolvers: CreateUMGraphQLResolvers = ( } => ({ Query: { async getSnapshotHistogram( - resolver, + _resolver, { dateRangeStart, dateRangeEnd, filters, monitorId, statusFilter }, - { req } + { callAsCurrentUser } ): Promise { - return await libs.pings.getPingHistogram( - req, + return await libs.pings.getPingHistogram(callAsCurrentUser, { dateRangeStart, dateRangeEnd, filters, monitorId, - statusFilter - ); + statusFilter, + }); }, async getMonitorChartsData( - resolver, + _resolver, { monitorId, dateRangeStart, dateRangeEnd, location }, - { req } + { callAsCurrentUser } ): Promise { - return await libs.monitors.getMonitorChartsData( - req, + return await libs.monitors.getMonitorChartsData(callAsCurrentUser, { monitorId, dateRangeStart, dateRangeEnd, - location - ); + location, + }); }, async getLatestMonitors( - resolver, + _resolver, { dateRangeStart, dateRangeEnd, monitorId, location }, - { req } + { callAsCurrentUser } ): Promise { - return await libs.pings.getLatestMonitorDocs( - req, + return await libs.pings.getLatestMonitorDocs(callAsCurrentUser, { dateRangeStart, dateRangeEnd, monitorId, - location - ); + location, + }); }, - async getFilterBar(resolver, { dateRangeStart, dateRangeEnd }, { req }): Promise { - return await libs.monitors.getFilterBar(req, dateRangeStart, dateRangeEnd); + async getFilterBar( + _resolver, + { dateRangeStart, dateRangeEnd }, + { callAsCurrentUser } + ): Promise { + return await libs.monitors.getFilterBar(callAsCurrentUser, { dateRangeStart, dateRangeEnd }); }, async getMonitorPageTitle( - resolver: any, + _resolver: any, { monitorId }, - { req } + { callAsCurrentUser } ): Promise { - return await libs.monitors.getMonitorPageTitle(req, monitorId); + return await libs.monitors.getMonitorPageTitle(callAsCurrentUser, { monitorId }); }, }, }); diff --git a/x-pack/legacy/plugins/uptime/server/graphql/pings/resolvers.ts b/x-pack/legacy/plugins/uptime/server/graphql/pings/resolvers.ts index 066080cec353f..c3cc1b4278035 100644 --- a/x-pack/legacy/plugins/uptime/server/graphql/pings/resolvers.ts +++ b/x-pack/legacy/plugins/uptime/server/graphql/pings/resolvers.ts @@ -34,23 +34,22 @@ export const createPingsResolvers: CreateUMGraphQLResolvers = ( } => ({ Query: { async allPings( - resolver, + _resolver, { monitorId, sort, size, status, dateRangeStart, dateRangeEnd, location }, - { req } + { callAsCurrentUser } ): Promise { - return await libs.pings.getAll( - req, + return await libs.pings.getAll(callAsCurrentUser, { dateRangeStart, dateRangeEnd, monitorId, status, sort, size, - location - ); + location, + }); }, - async getDocCount(resolver, args, { req }): Promise { - return libs.pings.getDocCount(req); + async getDocCount(_resolver, _args, { callAsCurrentUser }): Promise { + return libs.pings.getDocCount(callAsCurrentUser, undefined); }, }, }); diff --git a/x-pack/legacy/plugins/uptime/server/graphql/types.ts b/x-pack/legacy/plugins/uptime/server/graphql/types.ts index cb7634ff42b4c..f987446261b2d 100644 --- a/x-pack/legacy/plugins/uptime/server/graphql/types.ts +++ b/x-pack/legacy/plugins/uptime/server/graphql/types.ts @@ -4,12 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Request } from 'hapi'; +import { RequestHandlerContext, CallAPIOptions } from 'kibana/server'; import { UMServerLibs } from '../lib/lib'; -export interface UMContext { - req: Request; -} +export type UMContext = RequestHandlerContext & { + callAsCurrentUser: ( + endpoint: string, + clientParams?: Record, + options?: CallAPIOptions | undefined + ) => Promise; +}; export interface UMGraphQLResolver { Query?: any; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/database/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/database/adapter_types.ts deleted file mode 100644 index 412bc7abcdacb..0000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/database/adapter_types.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 interface HistogramQueryResult { - key: number; - doc_count: number; - bucket_total: { - value: number; - }; - down: { - bucket_count: { - value: number; - }; - }; -} - -export interface UMESBucket { - key: number; -} - -export interface UMESHistogramBucket { - x: number; - x0: number; -} diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/database/index.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/database/index.ts deleted file mode 100644 index 4e09b5d0e9e2d..0000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/database/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * 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 './adapter_types'; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts index f8f1343184be9..7f579bc0b19d4 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts @@ -11,6 +11,7 @@ import { RequestHandler, IRouter, CallAPIOptions, + SavedObjectsClientContract, } from 'src/core/server'; import { ObjectType } from '@kbn/config-schema'; import { UMRouteDefinition } from '../../../rest_api'; @@ -36,6 +37,11 @@ export type UMElasticsearchQueryFn = ( params: P ) => Promise | T; +export type UMSavedObjectsQueryFn = ( + client: SavedObjectsClientContract, + params: P +) => Promise | T; + export interface UptimeCoreSetup { route: IRouter; } @@ -49,5 +55,4 @@ export interface UptimeCorePlugins { export interface UMBackendFrameworkAdapter { registerRoute(route: UMRouteDefinition): void; registerGraphQLEndpoint(routePath: string, schema: GraphQLSchema): void; - getSavedObjectsClient(): any; } diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts index 9887db2fd30c2..7e7bc9f7098c8 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -7,17 +7,13 @@ import { GraphQLSchema } from 'graphql'; import { schema as kbnSchema } from '@kbn/config-schema'; import { runHttpQuery } from 'apollo-server-core'; -import { UptimeCorePlugins, UptimeCoreSetup } from './adapter_types'; +import { UptimeCoreSetup } from './adapter_types'; import { UMBackendFrameworkAdapter } from './adapter_types'; import { UMRouteDefinition } from '../../../rest_api'; export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapter { - constructor( - private readonly server: UptimeCoreSetup, - private readonly plugins: UptimeCorePlugins - ) { + constructor(private readonly server: UptimeCoreSetup) { this.server = server; - this.plugins = plugins; } public registerRoute({ handler, method, options, path, validate }: UMRouteDefinition) { @@ -48,16 +44,6 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte } public registerGraphQLEndpoint(routePath: string, schema: GraphQLSchema): void { - const options = { - graphQLOptions: (req: any) => ({ - context: { req }, - schema, - }), - path: routePath, - route: { - tags: ['access:uptime'], - }, - }; this.server.route.post( { path: routePath, @@ -73,6 +59,26 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte }, }, async (context, request, resp): Promise => { + const { + core: { + elasticsearch: { + dataClient: { callAsCurrentUser }, + }, + }, + } = context; + const options = { + graphQLOptions: (req: any) => { + const c = { ...context, callAsCurrentUser }; + return { + context: c, + schema, + }; + }, + path: routePath, + route: { + tags: ['access:uptime'], + }, + }; try { const query = request.body as Record; @@ -100,12 +106,4 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte } ); } - - public getSavedObjectsClient() { - const { elasticsearch, savedObjects } = this.plugins; - const { SavedObjectsClient, getSavedObjectsRepository } = savedObjects; - const { callWithInternalUser } = elasticsearch.getCluster('admin'); - const internalRepository = getSavedObjectsRepository(callWithInternalUser); - return new SavedObjectsClient(internalRepository); - } } diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/adapter_types.ts index 8dc55531f99a8..ab792b866d58a 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/adapter_types.ts @@ -9,14 +9,19 @@ import { UMElasticsearchQueryFn } from '../framework'; import { MonitorDetails } from '../../../../common/runtime_types'; export interface GetMonitorChartsDataParams { + /** @member monitorId ID value for the selected monitor */ monitorId: string; + /** @member dateRangeStart timestamp bounds */ dateRangeStart: string; + /** @member dateRangeEnd timestamp bounds */ dateRangeEnd: string; + /** @member location optional location value for use in filtering*/ location?: string | null; } export interface GetFilterBarParams { dateRangeStart: string; + /** @member dateRangeEnd timestamp bounds */ dateRangeEnd: string; } @@ -24,9 +29,20 @@ export interface GetMonitorDetailsParams { monitorId: string; } +export interface GetMonitorPageTitleParams { + /** @member monitorId the ID to query */ + monitorId: string; +} + export interface UMMonitorsAdapter { + /** + * Fetches data used to populate monitor charts + */ getMonitorChartsData: UMElasticsearchQueryFn; getFilterBar: UMElasticsearchQueryFn; + /** + * Fetch data for the monitor page title. + */ getMonitorPageTitle: UMElasticsearchQueryFn; getMonitorDetails: UMElasticsearchQueryFn; } diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts index 612ecf2c3c4f4..498da74d81ce7 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts @@ -31,13 +31,6 @@ const formatStatusBuckets = (time: any, buckets: any, docCount: any) => { }; export const elasticsearchMonitorsAdapter: UMMonitorsAdapter = { - /** - * Fetches data used to populate monitor charts - * @param request Kibana request - * @param monitorId ID value for the selected monitor - * @param dateRangeStart timestamp bounds - * @param dateRangeEnd timestamp bounds - */ getMonitorChartsData: async (callEs, { dateRangeStart, dateRangeEnd, monitorId, location }) => { const params = { index: INDEX_NAMES.HEARTBEAT, @@ -166,12 +159,6 @@ export const elasticsearchMonitorsAdapter: UMMonitorsAdapter = { return monitorChartsData; }, - /** - * Fetch options for the filter bar. - * @param request Kibana request object - * @param dateRangeStart timestamp bounds - * @param dateRangeEnd timestamp bounds - */ getFilterBar: async (callEs, { dateRangeStart, dateRangeEnd }) => { const fields: { [key: string]: string } = { ids: 'monitor.id', @@ -207,11 +194,6 @@ export const elasticsearchMonitorsAdapter: UMMonitorsAdapter = { }, {}); }, - /** - * Fetch data for the monitor page title. - * @param request Kibana server request - * @param monitorId the ID to query - */ getMonitorPageTitle: async (callEs, { monitorId }) => { const params = { index: INDEX_NAMES.HEARTBEAT, diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/index.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/index.ts index e1cb06aa95dce..d02068a11e8d8 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/index.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/index.ts @@ -5,4 +5,4 @@ */ export * from './adapter_types'; -export { ElasticsearchMonitorsAdapter } from './elasticsearch_monitors_adapter'; +export { elasticsearchMonitorsAdapter } from './elasticsearch_monitors_adapter'; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/adapter_types.ts index 1e0cf7ec40646..fe87a606d9492 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/adapter_types.ts @@ -6,35 +6,83 @@ import { DocCount, Ping, PingResults } from '../../../../common/graphql/types'; import { HistogramResult } from '../../../../common/domain_types'; +import { UMElasticsearchQueryFn } from '../framework'; +export interface GetAllParams { + /** @member dateRangeStart timestamp bounds */ + dateRangeStart: string; + + /** @member dateRangeEnd timestamp bounds */ + dateRangeEnd: string; + + /** @member monitorId optional limit by monitorId */ + monitorId?: string | null; + + /** @member status optional limit by check statuses */ + status?: string | null; + + /** @member sort optional sort by timestamp */ + sort?: string | null; + + /** @member size optional limit query size */ + size?: number | null; + + /** @member location optional location value for use in filtering*/ + location?: string | null; +} + +export interface GetLatestMonitorDocsParams { + /** @member dateRangeStart timestamp bounds */ + dateRangeStart: string; + + /** @member dateRangeEnd timestamp bounds */ + dateRangeEnd: string; + + /** @member monitorId optional limit to monitorId */ + monitorId?: string | null; + + /** @member location optional location value for use in filtering*/ + location?: string | null; +} + +export interface GetPingHistogramParams { + /** @member dateRangeStart timestamp bounds */ + dateRangeStart: string; + /** @member dateRangeEnd timestamp bounds */ + dateRangeEnd: string; + /** @member filters user-defined filters */ + filters?: string | null; + /** @member monitorId optional limit to monitorId */ + monitorId?: string | null; + /** @member statusFilter special filter targeting the latest status of each monitor */ + statusFilter?: string | null; +} + +/** + * Count the number of documents in heartbeat indices + */ export interface UMPingsAdapter { - getAll( - request: any, - dateRangeStart: string, - dateRangeEnd: string, - monitorId?: string | null, - status?: string | null, - sort?: string | null, - size?: number | null, - location?: string | null - ): Promise; - - getLatestMonitorDocs( - request: any, - dateRangeStart: string, - dateRangeEnd: string, - monitorId?: string | null, - location?: string | null - ): Promise; - - getPingHistogram( - request: any, - dateRangeStart: string, - dateRangeEnd: string, - filters?: string | null, - monitorId?: string | null, - statusFilter?: string | null - ): Promise; - - getDocCount(request: any): Promise; + getAll: UMElasticsearchQueryFn; + + getLatestMonitorDocs: UMElasticsearchQueryFn; + + getPingHistogram: UMElasticsearchQueryFn; + + /** + * Gets data used for a composite histogram for the currently-running monitors. + */ + getDocCount: UMElasticsearchQueryFn; +} + +export interface HistogramQueryResult { + key: number; + doc_count: number; + bucket_total: { + value: number; + }; + down: { + bucket_count: { + value: number; + }; + }; } diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts index 6c71d91794003..220b7f548ba1d 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts @@ -6,40 +6,16 @@ import { get } from 'lodash'; import { INDEX_NAMES } from '../../../../common/constants'; -import { DocCount, HttpBody, Ping, PingResults } from '../../../../common/graphql/types'; +import { HttpBody, Ping, PingResults } from '../../../../common/graphql/types'; import { parseFilterQuery, getFilterClause, getHistogramIntervalFormatted } from '../../helper'; -import { DatabaseAdapter, HistogramQueryResult } from '../database'; -import { UMPingsAdapter } from './adapter_types'; +import { UMPingsAdapter, HistogramQueryResult } from './adapter_types'; import { getHistogramInterval } from '../../helper/get_histogram_interval'; -import { HistogramResult } from '../../../../common/domain_types'; -export class ElasticsearchPingsAdapter implements UMPingsAdapter { - private database: DatabaseAdapter; - - constructor(database: DatabaseAdapter) { - this.database = database; - } - - /** - * Fetches ping documents from ES - * @param request Kibana server request - * @param dateRangeStart timestamp bounds - * @param dateRangeEnd timestamp bounds - * @param monitorId optional limit by monitorId - * @param status optional limit by check statuses - * @param sort optional sort by timestamp - * @param size optional limit query size - */ - public async getAll( - request: any, - dateRangeStart: string, - dateRangeEnd: string, - monitorId?: string | null, - status?: string | null, - sort: string | null = 'desc', - size?: number | null, - location?: string | null - ): Promise { +export const elasticsearchPingsAdapter: UMPingsAdapter = { + getAll: async ( + callEs, + { dateRangeStart, dateRangeEnd, monitorId, status, sort, size, location } + ) => { const sortParam = { sort: [{ '@timestamp': { order: sort } }] }; const sizeParam = size ? { size } : undefined; const filter: any[] = [{ range: { '@timestamp': { gte: dateRangeStart, lte: dateRangeEnd } } }]; @@ -79,7 +55,7 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter { const { hits: { hits, total }, aggregations: aggs, - } = await this.database.search(request, params); + } = await callEs('search', params); const locations = get(aggs, 'locations', { buckets: [{ key: 'N/A', doc_count: 0 }] }); @@ -104,22 +80,9 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter { }; return results; - } + }, - /** - * Fetch data to populate monitor status bar. - * @param request Kibana server request - * @param dateRangeStart timestamp bounds - * @param dateRangeEnd timestamp bounds - * @param monitorId optional limit to monitorId - */ - public async getLatestMonitorDocs( - request: any, - dateRangeStart: string, - dateRangeEnd: string, - monitorId?: string | null, - location?: string | null - ): Promise { + getLatestMonitorDocs: async (callEs, { dateRangeStart, dateRangeEnd, monitorId, location }) => { // TODO: Write tests for this function const params = { index: INDEX_NAMES.HEARTBEAT, @@ -162,10 +125,9 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter { }, }; - const result = await this.database.search(request, params); + const result = await callEs('search', params); const buckets: any[] = get(result, 'aggregations.by_id.buckets', []); - // @ts-ignore TODO fix destructuring implicit any return buckets.map( ({ latest: { @@ -179,24 +141,12 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter { }; } ); - } + }, - /** - * Gets data used for a composite histogram for the currently-running monitors. - * @param request Kibana server request - * @param dateRangeStart timestamp bounds - * @param dateRangeEnd timestamp bounds - * @param filters user-defined filters - * @param statusFilter special filter targeting the latest status of each monitor - */ - public async getPingHistogram( - request: any, - dateRangeStart: string, - dateRangeEnd: string, - filters?: string | null, - monitorId?: string | null, - statusFilter?: string | null - ): Promise { + getPingHistogram: async ( + callEs, + { dateRangeStart, dateRangeEnd, filters, monitorId, statusFilter } + ) => { const boolFilters = parseFilterQuery(filters); const additionaFilters = []; if (monitorId) { @@ -245,7 +195,7 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter { }, }; - const result = await this.database.search(request, params); + const result = await callEs('search', params); const buckets: HistogramQueryResult[] = get(result, 'aggregations.timeseries.buckets', []); const histogram = buckets.map(bucket => { const x: number = get(bucket, 'key'); @@ -262,15 +212,11 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter { histogram, interval, }; - } + }, - /** - * Count the number of documents in heartbeat indices - * @param request Kibana server request - */ - public async getDocCount(request: any): Promise { - const { count } = await this.database.count(request, { index: INDEX_NAMES.HEARTBEAT }); + getDocCount: async callEs => { + const { count } = await callEs('count', { index: INDEX_NAMES.HEARTBEAT }); return { count }; - } -} + }, +}; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/index.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/index.ts index eee6aa279dd39..6d93785e01527 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/index.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/index.ts @@ -5,4 +5,4 @@ */ export * from './adapter_types'; -export { ElasticsearchPingsAdapter } from './elasticsearch_pings_adapter'; +export { elasticsearchPingsAdapter } from './elasticsearch_pings_adapter'; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/saved_objects/index.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/saved_objects/index.ts index 86154d0ab80a4..bd86daba1bcb6 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/saved_objects/index.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/saved_objects/index.ts @@ -4,5 +4,5 @@ * you may not use this file except in compliance with the Elastic License. */ -export { UMKibanaSavedObjectsAdapter } from './kibana_saved_objects_adapter'; +export { savedObjectsAdapter } from './kibana_saved_objects_adapter'; export { UMSavedObjectsAdapter } from './types'; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/saved_objects/kibana_saved_objects_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/saved_objects/kibana_saved_objects_adapter.ts index 1f10c2f7aeed1..7628c5bac0660 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/saved_objects/kibana_saved_objects_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/saved_objects/kibana_saved_objects_adapter.ts @@ -4,24 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ -import { SavedObjectsLegacyService } from 'src/core/server'; import { UMSavedObjectsAdapter } from './types'; import uptimeIndexPattern from './heartbeat_index_pattern.json'; -export class UMKibanaSavedObjectsAdapter implements UMSavedObjectsAdapter { - private readonly savedObjectsClient: any; - constructor(savedObjects: SavedObjectsLegacyService, elasticsearch: any) { - const { SavedObjectsClient, getSavedObjectsRepository } = savedObjects; - const { callWithInternalUser } = elasticsearch.getCluster('admin'); - const internalRepository = getSavedObjectsRepository(callWithInternalUser); - this.savedObjectsClient = new SavedObjectsClient(internalRepository); - } - - public async getUptimeIndexPattern(): Promise { +export const savedObjectsAdapter: UMSavedObjectsAdapter = { + getUptimeIndexPattern: async client => { try { - return await this.savedObjectsClient.get('index-pattern', uptimeIndexPattern.id); + return await client.get('index-pattern', uptimeIndexPattern.id); } catch (error) { - return await this.savedObjectsClient.create( + return await client.create( 'index-pattern', { ...uptimeIndexPattern.attributes, @@ -30,5 +21,5 @@ export class UMKibanaSavedObjectsAdapter implements UMSavedObjectsAdapter { { id: uptimeIndexPattern.id, overwrite: false } ); } - } -} + }, +}; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/saved_objects/types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/saved_objects/types.ts index 4d11bd9f6053a..0fef1e1428e97 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/saved_objects/types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/saved_objects/types.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { UMSavedObjectsQueryFn } from '../framework'; + export interface UMSavedObjectsAdapter { - getUptimeIndexPattern: () => Promise; + getUptimeIndexPattern: UMSavedObjectsQueryFn; } diff --git a/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts b/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts index eda8dad18ab7b..cc11bf90da5f3 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts @@ -5,29 +5,27 @@ */ import { UMKibanaBackendFrameworkAdapter } from '../adapters/framework'; -import { ElasticsearchMonitorsAdapter } from '../adapters/monitors'; -import { ElasticsearchPingsAdapter } from '../adapters/pings'; +import { elasticsearchMonitorsAdapter } from '../adapters/monitors'; +import { elasticsearchPingsAdapter } from '../adapters/pings'; import { licenseCheck } from '../domains'; import { UMDomainLibs, UMServerLibs } from '../lib'; import { elasticsearchMonitorStatesAdapter } from '../adapters/monitor_states'; -import { UMKibanaSavedObjectsAdapter } from '../adapters/saved_objects/kibana_saved_objects_adapter'; +import { savedObjectsAdapter } from '../adapters/saved_objects'; import { UptimeCorePlugins, UptimeCoreSetup } from '../adapters/framework'; export function compose(server: UptimeCoreSetup, plugins: UptimeCorePlugins): UMServerLibs { - const { savedObjects } = plugins; - const framework = new UMKibanaBackendFrameworkAdapter(server, plugins); + const framework = new UMKibanaBackendFrameworkAdapter(server); const domainLibs: UMDomainLibs = { license: licenseCheck, - monitors: new ElasticsearchMonitorsAdapter(database), + monitors: elasticsearchMonitorsAdapter, monitorStates: elasticsearchMonitorStatesAdapter, - pings: new ElasticsearchPingsAdapter(database), - savedObjects: new UMKibanaSavedObjectsAdapter(savedObjects, elasticsearch), + pings: elasticsearchPingsAdapter, + savedObjects: savedObjectsAdapter, }; return { framework, - database, ...domainLibs, }; } diff --git a/x-pack/legacy/plugins/uptime/server/lib/lib.ts b/x-pack/legacy/plugins/uptime/server/lib/lib.ts index e68a6dd18ef5f..da87c3ebfe301 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/lib.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/lib.ts @@ -5,7 +5,6 @@ */ import { - DatabaseAdapter, UMBackendFrameworkAdapter, UMMonitorsAdapter, UMMonitorStatesAdapter, @@ -24,5 +23,4 @@ export interface UMDomainLibs { export interface UMServerLibs extends UMDomainLibs { framework: UMBackendFrameworkAdapter; - database?: DatabaseAdapter; } diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts b/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts index 7fbae1d2091fe..175a349dbb809 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts @@ -15,7 +15,7 @@ export const createRouteWithAuth = ( ): UMRouteDefinition => { const restRoute = routeCreator(libs); const { handler, method, path, options, ...rest } = restRoute; - const authHandler: RequestHandler = async ( + const licenseCheckHandler: RequestHandler = async ( context, request, response @@ -29,7 +29,7 @@ export const createRouteWithAuth = ( method, path, options, - handler: authHandler, + handler: licenseCheckHandler, ...rest, }; }; diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts b/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts index 55f0af57ed847..6dd62932cc306 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts @@ -14,7 +14,15 @@ export const createGetIndexPatternRoute: UMRestApiRouteCreator = (libs: UMServer options: { tags: ['access:uptime'], }, - handler: async (_context, _request, response): Promise => { + handler: async ( + { + core: { + savedObjects: { client }, + }, + }, + _request, + response + ): Promise => { try { return response.ok({ body: { diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts b/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts index e2bdbca9fbfa0..817aca5f6a379 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts @@ -25,19 +25,28 @@ export const createGetAllRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => options: { tags: ['access:uptime'], }, - handler: async (_context, request, response): Promise => { + handler: async ( + { + core: { + elasticsearch: { + dataClient: { callAsInternalUser }, + }, + }, + }, + request, + response + ): Promise => { const { size, sort, dateRangeStart, dateRangeEnd, location, monitorId, status } = request.query; - const result = await libs.pings.getAll( - request, + const result = await libs.pings.getAll(callAsInternalUser, { dateRangeStart, dateRangeEnd, monitorId, status, sort, size, - location - ); + location, + }); return response.ok({ body: { From df4d4b748ba6d9a15e514e837abb3b0f21e47eee Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Fri, 22 Nov 2019 14:41:35 -0500 Subject: [PATCH 17/32] Fix broken unit tests. --- ...lasticsearch_monitors_adapter.test.ts.snap | 4 +- .../elasticsearch_monitors_adapter.test.ts | 57 ++-- .../elasticsearch_pings_adapter.test.ts | 258 ++++++++---------- .../pings/elasticsearch_pings_adapter.ts | 3 +- 4 files changed, 141 insertions(+), 181 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/__tests__/__snapshots__/elasticsearch_monitors_adapter.test.ts.snap b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/__tests__/__snapshots__/elasticsearch_monitors_adapter.test.ts.snap index 99349f42d5750..7f0eb86dae751 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/__tests__/__snapshots__/elasticsearch_monitors_adapter.test.ts.snap +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/__tests__/__snapshots__/elasticsearch_monitors_adapter.test.ts.snap @@ -2,7 +2,7 @@ exports[`ElasticsearchMonitorsAdapter getMonitorChartsData will provide expected filters when a location is specified 1`] = ` Array [ - Object {}, + "search", Object { "body": Object { "aggs": Object { @@ -74,7 +74,7 @@ Array [ exports[`ElasticsearchMonitorsAdapter getMonitorChartsData will run expected parameters when no location is specified 1`] = ` Array [ - Object {}, + "search", Object { "body": Object { "aggs": Object { diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/__tests__/elasticsearch_monitors_adapter.test.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/__tests__/elasticsearch_monitors_adapter.test.ts index b21fb982bfb3b..548fdea8a801c 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/__tests__/elasticsearch_monitors_adapter.test.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/__tests__/elasticsearch_monitors_adapter.test.ts @@ -5,38 +5,21 @@ */ import { get, set } from 'lodash'; -import { ElasticsearchMonitorsAdapter } from '../elasticsearch_monitors_adapter'; -import { CountParams, CountResponse } from 'elasticsearch'; +import { elasticsearchMonitorsAdapter as adapter } from '../elasticsearch_monitors_adapter'; import mockChartsData from './monitor_charts_mock.json'; import { assertCloseTo } from '../../../helper'; // FIXME: there are many untested functions in this adapter. They should be tested. describe('ElasticsearchMonitorsAdapter', () => { - let defaultCountResponse: CountResponse; - - beforeEach(() => { - defaultCountResponse = { - count: 0, - _shards: { - total: 0, - successful: 0, - failed: 0, - skipped: 0, - }, - }; - }); - it('getMonitorChartsData will run expected parameters when no location is specified', async () => { expect.assertions(3); const searchMock = jest.fn(); const search = searchMock.bind({}); - const database = { - search, - count: async (request: any, params: CountParams) => defaultCountResponse, - head: async (request: any, params: any) => null, - }; - const adapter = new ElasticsearchMonitorsAdapter(database); - await adapter.getMonitorChartsData({}, 'fooID', 'now-15m', 'now'); + await adapter.getMonitorChartsData(search, { + monitorId: 'fooID', + dateRangeStart: 'now-15m', + dateRangeEnd: 'now', + }); expect(searchMock).toHaveBeenCalledTimes(1); // protect against possible rounding errors polluting the snapshot comparison const fixedInterval = parseInt( @@ -66,13 +49,12 @@ describe('ElasticsearchMonitorsAdapter', () => { expect.assertions(3); const searchMock = jest.fn(); const search = searchMock.bind({}); - const database = { - search, - count: async (request: any, params: CountParams) => defaultCountResponse, - head: async (request: any, params: any) => null, - }; - const adapter = new ElasticsearchMonitorsAdapter(database); - await adapter.getMonitorChartsData({}, 'fooID', 'now-15m', 'now', 'Philadelphia'); + await adapter.getMonitorChartsData(search, { + monitorId: 'fooID', + dateRangeStart: 'now-15m', + dateRangeEnd: 'now', + location: 'Philadelphia', + }); expect(searchMock).toHaveBeenCalledTimes(1); // protect against possible rounding errors polluting the snapshot comparison const fixedInterval = parseInt( @@ -101,12 +83,13 @@ describe('ElasticsearchMonitorsAdapter', () => { it('inserts empty buckets for missing data', async () => { const searchMock = jest.fn(); searchMock.mockReturnValue(mockChartsData); - const database = { - search: searchMock, - count: jest.fn(), - head: jest.fn(), - }; - const adapter = new ElasticsearchMonitorsAdapter(database); - expect(await adapter.getMonitorChartsData({}, 'id', 'now-15m', 'now')).toMatchSnapshot(); + const search = searchMock.bind({}); + expect( + await adapter.getMonitorChartsData(search, { + monitorId: 'id', + dateRangeStart: 'now-15m', + dateRangeEnd: 'now', + }) + ).toMatchSnapshot(); }); }); diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts index 7b3c72f535401..69edc28f2050d 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts @@ -5,14 +5,10 @@ */ import { set } from 'lodash'; -import { DatabaseAdapter } from '../../database'; -import { ElasticsearchPingsAdapter } from '../elasticsearch_pings_adapter'; +import { elasticsearchPingsAdapter as adapter } from '../elasticsearch_pings_adapter'; import { assertCloseTo } from '../../../helper'; describe('ElasticsearchPingsAdapter class', () => { - let database: DatabaseAdapter; - let adapter: ElasticsearchPingsAdapter; - let serverRequest: any; let mockHits: any[]; let mockEsSearchResult: any; let mockEsCountResult: any; @@ -77,22 +73,13 @@ describe('ElasticsearchPingsAdapter class', () => { mockEsCountResult = { count: mockHits.length, }; - database = { - search: async (request: any, params: any) => mockEsSearchResult, - count: async (request: any, params: any) => mockEsCountResult, - head: async (request: any, params: any) => null, - }; - adapter = new ElasticsearchPingsAdapter(database); - serverRequest = { - requestArgs: 'hello', - }; }); describe('getPingHistogram', () => { it('returns a single bucket if array has 1', async () => { expect.assertions(2); - const search = jest.fn(); - search.mockReturnValue({ + const mockEsClient = jest.fn(); + mockEsClient.mockReturnValue({ aggregations: { timeseries: { buckets: [ @@ -109,43 +96,39 @@ describe('ElasticsearchPingsAdapter class', () => { }, }, }); - const pingDatabase = { - search, - count: jest.fn(), - head: async (request: any, params: any) => null, - }; - const pingAdapter = new ElasticsearchPingsAdapter(pingDatabase); - const result = await pingAdapter.getPingHistogram(serverRequest, 'now-15m', 'now', null); + const result = await adapter.getPingHistogram(mockEsClient, { + dateRangeStart: 'now-15m', + dateRangeEnd: 'now', + filters: null, + }); assertCloseTo(result.interval, 36000, 100); result.interval = 36000; - expect(pingDatabase.search).toHaveBeenCalledTimes(1); + expect(mockEsClient).toHaveBeenCalledTimes(1); expect(result).toMatchSnapshot(); }); it('returns expected result for no status filter', async () => { expect.assertions(2); - const search = jest.fn(); + const mockEsClient = jest.fn(); - search.mockReturnValue(standardMockResponse); + mockEsClient.mockReturnValue(standardMockResponse); - const pingDatabase = { - search, - count: jest.fn(), - head: async (request: any, params: any) => null, - }; - const pingAdapter = new ElasticsearchPingsAdapter(pingDatabase); - const result = await pingAdapter.getPingHistogram(serverRequest, 'now-15m', 'now', null); + const result = await adapter.getPingHistogram(mockEsClient, { + dateRangeStart: 'now-15m', + dateRangeEnd: 'now', + filters: null, + }); assertCloseTo(result.interval, 36000, 100); result.interval = 36000; - expect(pingDatabase.search).toHaveBeenCalledTimes(1); + expect(mockEsClient).toHaveBeenCalledTimes(1); expect(result).toMatchSnapshot(); }); it('handles status + additional user queries', async () => { expect.assertions(2); - const search = jest.fn(); - search.mockReturnValue({ + const mockEsClient = jest.fn(); + mockEsClient.mockReturnValue({ aggregations: { timeseries: { buckets: [ @@ -188,31 +171,24 @@ describe('ElasticsearchPingsAdapter class', () => { ], }, }; - const pingDatabase = { - search, - count: jest.fn(), - head: async (request: any, params: any) => null, - }; - const pingAdapter = new ElasticsearchPingsAdapter(pingDatabase); - const result = await pingAdapter.getPingHistogram( - serverRequest, - '1234', - '5678', - JSON.stringify(searchFilter), - undefined, - 'down' - ); + const result = await adapter.getPingHistogram(mockEsClient, { + dateRangeStart: '1234', + dateRangeEnd: '5678', + filters: JSON.stringify(searchFilter), + monitorId: undefined, + statusFilter: 'down', + }); assertCloseTo(result.interval, 5609564928000, 1000); result.interval = 5609564928000; - expect(pingDatabase.search).toHaveBeenCalledTimes(1); + expect(mockEsClient).toHaveBeenCalledTimes(1); expect(result).toMatchSnapshot(); }); it('handles simple_text_query without issues', async () => { expect.assertions(2); - const search = jest.fn(); - search.mockReturnValue({ + const mockEsClient = jest.fn(); + mockEsClient.mockReturnValue({ aggregations: { timeseries: { buckets: [ @@ -247,89 +223,68 @@ describe('ElasticsearchPingsAdapter class', () => { }, }, }); - const searchFilter = `{"bool":{"must":[{"simple_query_string":{"query":"http"}}]}}`; - const pingDatabase = { - search, - count: jest.fn(), - head: async (request: any, params: any) => null, - }; - const pingAdapter = new ElasticsearchPingsAdapter(pingDatabase); - const result = await pingAdapter.getPingHistogram( - serverRequest, - 'now-15m', - 'now', - searchFilter - ); + const filters = `{"bool":{"must":[{"simple_query_string":{"query":"http"}}]}}`; + const result = await adapter.getPingHistogram(mockEsClient, { + dateRangeStart: 'now-15m', + dateRangeEnd: 'now', + filters, + }); assertCloseTo(result.interval, 36000, 100); result.interval = 36000; - expect(pingDatabase.search).toHaveBeenCalledTimes(1); + expect(mockEsClient).toHaveBeenCalledTimes(1); expect(result).toMatchSnapshot(); }); it('returns a down-filtered array for when filtered by down status', async () => { expect.assertions(2); - const search = jest.fn(); - search.mockReturnValue(standardMockResponse); - const pingDatabase = { - search, - count: jest.fn(), - head: async (request: any, params: any) => null, - }; - const pingAdapter = new ElasticsearchPingsAdapter(pingDatabase); - const result = await pingAdapter.getPingHistogram( - serverRequest, - '1234', - '5678', - '', - undefined, - 'down' - ); + const mockEsClient = jest.fn(); + mockEsClient.mockReturnValue(standardMockResponse); + const result = await adapter.getPingHistogram(mockEsClient, { + dateRangeStart: '1234', + dateRangeEnd: '5678', + filters: '', + monitorId: undefined, + statusFilter: 'down', + }); assertCloseTo(result.interval, 5609564928000, 1000); result.interval = 5609564928000; - expect(pingDatabase.search).toHaveBeenCalledTimes(1); + expect(mockEsClient).toHaveBeenCalledTimes(1); expect(result).toMatchSnapshot(); }); it('returns a down-filtered array for when filtered by up status', async () => { expect.assertions(2); - const search = jest.fn(); + const mockEsClient = jest.fn(); - search.mockReturnValue(standardMockResponse); + mockEsClient.mockReturnValue(standardMockResponse); - const pingDatabase = { - search, - count: jest.fn(), - head: async (request: any, params: any) => null, - }; - const pingAdapter = new ElasticsearchPingsAdapter(pingDatabase); - const result = await pingAdapter.getPingHistogram( - serverRequest, - '1234', - '5678', - '', - undefined, - 'up' - ); - - expect(pingDatabase.search).toHaveBeenCalledTimes(1); + const result = await adapter.getPingHistogram(mockEsClient, { + dateRangeStart: '1234', + dateRangeEnd: '5678', + filters: '', + monitorId: undefined, + statusFilter: 'up', + }); + + expect(mockEsClient).toHaveBeenCalledTimes(1); expect(result).toMatchSnapshot(); }); }); describe('getDocCount', () => { it('returns data in appropriate shape', async () => { - const { count } = await adapter.getDocCount(serverRequest); + const mockEsClient = jest.fn(); + mockEsClient.mockReturnValue(mockEsCountResult); + const { count } = await adapter.getDocCount(mockEsClient, undefined); expect(count).toEqual(3); }); }); describe('getAll', () => { - let getAllSearchMock: (request: any, params: any) => Promise; let expectedGetAllParams: any; beforeEach(() => { - getAllSearchMock = jest.fn(async (request: any, params: any) => mockEsSearchResult); expectedGetAllParams = { index: 'heartbeat-8*', body: { @@ -354,15 +309,14 @@ describe('ElasticsearchPingsAdapter class', () => { }); it('returns data in the appropriate shape', async () => { - const result = await adapter.getAll( - serverRequest, - 'now-1h', - 'now', - undefined, - undefined, - 'asc', - 12 - ); + const mockEsClient = jest.fn(); + mockEsClient.mockReturnValue(mockEsSearchResult); + const result = await adapter.getAll(mockEsClient, { + dateRangeStart: 'now-1h', + dateRangeEnd: 'now', + sort: 'asc', + size: 12, + }); const count = 3; expect(result.total).toBe(count); @@ -372,57 +326,82 @@ describe('ElasticsearchPingsAdapter class', () => { expect(pings[0].timestamp).toBe('2018-10-30T18:51:59.792Z'); expect(pings[1].timestamp).toBe('2018-10-30T18:53:59.792Z'); expect(pings[2].timestamp).toBe('2018-10-30T18:55:59.792Z'); + expect(mockEsClient).toHaveBeenCalledTimes(1); }); it('creates appropriate sort and size parameters', async () => { - database.search = getAllSearchMock; - await adapter.getAll(serverRequest, 'now-1h', 'now', undefined, undefined, 'asc', 12); + const mockEsClient = jest.fn(); + mockEsClient.mockReturnValue(mockEsSearchResult); + await adapter.getAll(mockEsClient, { + dateRangeStart: 'now-1h', + dateRangeEnd: 'now', + sort: 'asc', + size: 12, + }); set(expectedGetAllParams, 'body.sort[0]', { '@timestamp': { order: 'asc' } }); - expect(database.search).toHaveBeenCalledTimes(1); - expect(database.search).toHaveBeenCalledWith(serverRequest, expectedGetAllParams); + expect(mockEsClient).toHaveBeenCalledTimes(1); + expect(mockEsClient).toHaveBeenCalledWith('search', expectedGetAllParams); }); it('omits the sort param when no sort passed', async () => { - database.search = getAllSearchMock; - await adapter.getAll(serverRequest, 'now-1h', 'now', undefined, undefined, undefined, 12); + const mockEsClient = jest.fn(); + mockEsClient.mockReturnValue(mockEsSearchResult); + await adapter.getAll(mockEsClient, { + dateRangeStart: 'now-1h', + dateRangeEnd: 'now', + size: 12, + }); - expect(database.search).toHaveBeenCalledWith(serverRequest, expectedGetAllParams); + expect(mockEsClient).toHaveBeenCalledWith('search', expectedGetAllParams); }); it('omits the size param when no size passed', async () => { - database.search = getAllSearchMock; - await adapter.getAll(serverRequest, 'now-1h', 'now', undefined, undefined, 'desc'); + const mockEsClient = jest.fn(); + mockEsClient.mockReturnValue(mockEsSearchResult); + await adapter.getAll(mockEsClient, { + dateRangeStart: 'now-1h', + dateRangeEnd: 'now', + sort: 'desc', + }); delete expectedGetAllParams.body.size; set(expectedGetAllParams, 'body.sort[0].@timestamp.order', 'desc'); - expect(database.search).toHaveBeenCalledWith(serverRequest, expectedGetAllParams); + expect(mockEsClient).toHaveBeenCalledWith('search', expectedGetAllParams); }); it('adds a filter for monitor ID', async () => { - database.search = getAllSearchMock; - await adapter.getAll(serverRequest, 'now-1h', 'now', 'testmonitorid'); + const mockEsClient = jest.fn(); + mockEsClient.mockReturnValue(mockEsSearchResult); + await adapter.getAll(mockEsClient, { + dateRangeStart: 'now-1h', + dateRangeEnd: 'now', + monitorId: 'testmonitorid', + }); delete expectedGetAllParams.body.size; expectedGetAllParams.body.query.bool.filter.push({ term: { 'monitor.id': 'testmonitorid' } }); - expect(database.search).toHaveBeenCalledWith(serverRequest, expectedGetAllParams); + expect(mockEsClient).toHaveBeenCalledWith('search', expectedGetAllParams); }); it('adds a filter for monitor status', async () => { - database.search = getAllSearchMock; - await adapter.getAll(serverRequest, 'now-1h', 'now', undefined, 'down'); + const mockEsClient = jest.fn(); + mockEsClient.mockReturnValue(mockEsSearchResult); + await adapter.getAll(mockEsClient, { + dateRangeStart: 'now-1h', + dateRangeEnd: 'now', + status: 'down', + }); delete expectedGetAllParams.body.size; expectedGetAllParams.body.query.bool.filter.push({ term: { 'monitor.status': 'down' } }); - expect(database.search).toHaveBeenCalledWith(serverRequest, expectedGetAllParams); + expect(mockEsClient).toHaveBeenCalledWith('search', expectedGetAllParams); }); }); describe('getLatestMonitorDocs', () => { - let getLatestSearchMock: (request: any, params: any) => Promise; let expectedGetLatestSearchParams: any; beforeEach(() => { - getLatestSearchMock = jest.fn(async (request: any, params: any) => mockEsSearchResult); expectedGetLatestSearchParams = { index: 'heartbeat-8*', body: { @@ -491,19 +470,18 @@ describe('ElasticsearchPingsAdapter class', () => { }); it('returns data in expected shape', async () => { - database.search = getLatestSearchMock; - const result = await adapter.getLatestMonitorDocs( - serverRequest, - 'now-1h', - 'now', - 'testmonitor' - ); + const mockEsClient = jest.fn(async (request: any, params: any) => mockEsSearchResult); + const result = await adapter.getLatestMonitorDocs(mockEsClient, { + dateRangeStart: 'now-1h', + dateRangeEnd: 'now', + monitorId: 'testmonitor', + }); expect(result).toHaveLength(1); expect(result[0].timestamp).toBe(123456); expect(result[0].monitor).not.toBeFalsy(); // @ts-ignore monitor will be defined expect(result[0].monitor.id).toBe('testmonitor'); - expect(database.search).toHaveBeenCalledWith(serverRequest, expectedGetLatestSearchParams); + expect(mockEsClient).toHaveBeenCalledWith('search', expectedGetLatestSearchParams); }); }); }); diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts index 220b7f548ba1d..021dcd286ff17 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts @@ -16,7 +16,7 @@ export const elasticsearchPingsAdapter: UMPingsAdapter = { callEs, { dateRangeStart, dateRangeEnd, monitorId, status, sort, size, location } ) => { - const sortParam = { sort: [{ '@timestamp': { order: sort } }] }; + const sortParam = { sort: [{ '@timestamp': { order: sort ?? 'desc' } }] }; const sizeParam = size ? { size } : undefined; const filter: any[] = [{ range: { '@timestamp': { gte: dateRangeStart, lte: dateRangeEnd } } }]; if (monitorId) { @@ -83,7 +83,6 @@ export const elasticsearchPingsAdapter: UMPingsAdapter = { }, getLatestMonitorDocs: async (callEs, { dateRangeStart, dateRangeEnd, monitorId, location }) => { - // TODO: Write tests for this function const params = { index: INDEX_NAMES.HEARTBEAT, body: { From 888ba2b1229e6482b1186b2865b2a405bdf48aaf Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Fri, 22 Nov 2019 16:29:10 -0500 Subject: [PATCH 18/32] Fix incorrect user usage for a REST endpoint. --- x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts b/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts index 817aca5f6a379..b7271c4bfdc6f 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts @@ -29,7 +29,7 @@ export const createGetAllRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => { core: { elasticsearch: { - dataClient: { callAsInternalUser }, + dataClient: { callAsCurrentUser }, }, }, }, @@ -38,7 +38,7 @@ export const createGetAllRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => ): Promise => { const { size, sort, dateRangeStart, dateRangeEnd, location, monitorId, status } = request.query; - const result = await libs.pings.getAll(callAsInternalUser, { + const result = await libs.pings.getAll(callAsCurrentUser, { dateRangeStart, dateRangeEnd, monitorId, From 536127039c7ad0baa3505bf77e346a9ca6d8201c Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Fri, 22 Nov 2019 16:35:57 -0500 Subject: [PATCH 19/32] Fix some broken imports and types. --- x-pack/legacy/plugins/uptime/server/lib/adapters/index.ts | 1 - .../adapters/monitor_states/search/__tests__/test_helpers.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/index.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/index.ts index 2a88df91adc29..f5ff3b8c62ba9 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/index.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/index.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -export * from './database'; export * from './framework'; export * from './monitor_states'; export * from './monitors'; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/__tests__/test_helpers.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/__tests__/test_helpers.ts index 0c3572604879e..d6fe5f82e735d 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/__tests__/test_helpers.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/__tests__/test_helpers.ts @@ -24,12 +24,12 @@ export const nextPagination = (key: any): CursorPagination => { }; export const simpleQueryContext = (): QueryContext => { return { - database: undefined, + count: _query => new Promise(r => ({})), + search: _query => new Promise(r => ({})), dateRangeEnd: '', dateRangeStart: '', filterClause: undefined, pagination: nextPagination('something'), - request: undefined, size: 0, statusFilter: '', }; From cafa4dee5cffeb36525817c8199a1748ab6065cc Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 20 Nov 2019 12:35:15 -0500 Subject: [PATCH 20/32] Update remaining REST routes to work with NP router. --- .../lib/adapters/framework/kibana_framework_adapter.ts | 9 +++++++++ x-pack/legacy/plugins/uptime/server/rest_api/index.ts | 1 + 2 files changed, 10 insertions(+) diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts index 7e7bc9f7098c8..30f2c064fca9c 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -38,6 +38,15 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte handler ); break; + case 'POST': + this.server.route.post( + { + path, + validate, + }, + handler + ); + break; default: throw new Error(`Handler for method ${method} is not defined`); } diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/index.ts b/x-pack/legacy/plugins/uptime/server/rest_api/index.ts index 2810982fb0c6c..9d1d8c38ad9da 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/index.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/index.ts @@ -20,4 +20,5 @@ export const restApiRoutes: UMRestApiRouteCreator[] = [ createGetSnapshotCount, createLogMonitorPageRoute, createLogOverviewPageRoute, + createGetMonitorDetailsRoute, ]; From 5a11ec03d6e02dffad7af8832a5ea23972658dd4 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Tue, 26 Nov 2019 09:28:49 -0500 Subject: [PATCH 21/32] Port monitor details REST endpoint to NP. --- .../server/rest_api/monitors/monitors_details.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts b/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts index 00860248ff153..f640f341e2edb 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts @@ -19,11 +19,21 @@ export const createGetMonitorDetailsRoute: UMRestApiRouteCreator = (libs: UMServ options: { tags: ['access:uptime'], }, - handler: async (_context, request, response): Promise => { + handler: async ( + { + core: { + elasticsearch: { + dataClient: { callAsCurrentUser }, + }, + }, + }, + request, + response + ): Promise => { const { monitorId } = request.query; return response.ok({ - body: { ...(await libs.monitors.getMonitorDetails(request, monitorId)) }, + body: { ...(await libs.monitors.getMonitorDetails(callAsCurrentUser, monitorId)) }, }); }, }); From cb5fe053f225cfdbadaac9d2d701f7dbf0834b53 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Tue, 3 Dec 2019 10:45:57 -0500 Subject: [PATCH 22/32] Remove some merge errors. --- x-pack/legacy/plugins/uptime/index.ts | 2 +- .../framework/kibana_framework_adapter.ts | 2 +- .../plugins/uptime/server/rest_api/index.ts | 1 - .../index_pattern/get_index_pattern.ts | 2 +- .../rest_api/snapshot/get_snapshot_count.ts | 19 ++++++++++++++----- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/index.ts b/x-pack/legacy/plugins/uptime/index.ts index 40624d3a9579d..abff51c4c18a9 100644 --- a/x-pack/legacy/plugins/uptime/index.ts +++ b/x-pack/legacy/plugins/uptime/index.ts @@ -36,7 +36,7 @@ export const uptime = (kibana: any) => init(server: KibanaServer) { const initializerContext = {} as PluginInitializerContext; const { savedObjects } = server; - const { elasticsearch, xpack_main } = server.plugins; + const { xpack_main } = server.plugins; const { usageCollection } = server.newPlatform.setup.plugins; plugin(initializerContext).setup( diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts index 30f2c064fca9c..fd1b89e88d989 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -58,7 +58,7 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte path: routePath, validate: { body: kbnSchema.object({ - operationName: kbnSchema.string(), + operationName: kbnSchema.nullable(kbnSchema.string()), query: kbnSchema.string(), variables: kbnSchema.recordOf(kbnSchema.string(), kbnSchema.any()), }), diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/index.ts b/x-pack/legacy/plugins/uptime/server/rest_api/index.ts index 9d1d8c38ad9da..2810982fb0c6c 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/index.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/index.ts @@ -20,5 +20,4 @@ export const restApiRoutes: UMRestApiRouteCreator[] = [ createGetSnapshotCount, createLogMonitorPageRoute, createLogOverviewPageRoute, - createGetMonitorDetailsRoute, ]; diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts b/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts index 6dd62932cc306..2f0aea75c5e61 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts @@ -26,7 +26,7 @@ export const createGetIndexPatternRoute: UMRestApiRouteCreator = (libs: UMServer try { return response.ok({ body: { - ...(await libs.savedObjects.getUptimeIndexPattern()), + ...(await libs.savedObjects.getUptimeIndexPattern(client, undefined)), }, }); } catch (e) { diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts b/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts index 9b2b26f52699e..d1256ecbce664 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts @@ -22,15 +22,24 @@ export const createGetSnapshotCount: UMRestApiRouteCreator = (libs: UMServerLibs options: { tags: ['access:uptime'], }, - handler: async (_context, request, response): Promise => { + handler: async ( + { + core: { + elasticsearch: { + dataClient: { callAsCurrentUser }, + }, + }, + }, + request, + response + ): Promise => { const { dateRangeStart, dateRangeEnd, filters, statusFilter } = request.query; - const result = await libs.monitorStates.getSnapshotCount( - request, + const result = await libs.monitorStates.getSnapshotCount(callAsCurrentUser, { dateRangeStart, dateRangeEnd, filters, - statusFilter - ); + statusFilter, + }); return response.ok({ body: { ...result, From 025b3e063940805650a57ea495cdc7890da87b3f Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Fri, 6 Dec 2019 10:03:53 -0500 Subject: [PATCH 23/32] Update adapters to take a single options parameter. --- .../lib/adapters/framework/adapter_types.ts | 17 +++++---- .../adapters/monitor_states/adapter_types.ts | 6 +-- .../elasticsearch_monitor_states_adapter.ts | 26 +++++++------ .../lib/adapters/monitors/adapter_types.ts | 8 ++-- .../elasticsearch_monitors_adapter.ts | 16 ++++---- .../lib/adapters/pings/adapter_types.ts | 8 ++-- .../pings/elasticsearch_pings_adapter.ts | 38 ++++++++++++------- .../rest_api/monitors/monitors_details.ts | 4 +- .../uptime/server/rest_api/pings/get_all.ts | 5 ++- .../rest_api/snapshot/get_snapshot_count.ts | 3 +- 10 files changed, 75 insertions(+), 56 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts index 7f579bc0b19d4..a20c7166d95c4 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts @@ -28,14 +28,15 @@ export interface UMFrameworkRouteOptions< validate: any; } -export type UMElasticsearchQueryFn = ( - callAsCurrentUser: ( - endpoint: string, - clientParams: Record, - options?: CallAPIOptions - ) => Promise, - params: P -) => Promise | T; +type CallElasticsearchAsCurrentUser = ( + endpoint: string, + clientParams: Record, + options?: CallAPIOptions +) => Promise; + +export type UMElasticsearchQueryFn = ( + params: { callES: CallElasticsearchAsCurrentUser } & P +) => Promise | R; export type UMSavedObjectsQueryFn = ( client: SavedObjectsClientContract, diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/adapter_types.ts index 9dec7834811c8..71e9644c2adee 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/adapter_types.ts @@ -22,9 +22,9 @@ export interface MonitorStatesParams { } export interface UMMonitorStatesAdapter { - getMonitorStates: UMElasticsearchQueryFn; - getSnapshotCount: UMElasticsearchQueryFn; - statesIndexExists: UMElasticsearchQueryFn; + getMonitorStates: UMElasticsearchQueryFn; + getSnapshotCount: UMElasticsearchQueryFn; + statesIndexExists: UMElasticsearchQueryFn<{}, StatesIndexStatus>; } export interface CursorPagination { diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/elasticsearch_monitor_states_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/elasticsearch_monitor_states_adapter.ts index c3a41d2280a40..f5ee081538a98 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/elasticsearch_monitor_states_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/elasticsearch_monitor_states_adapter.ts @@ -23,17 +23,21 @@ export interface QueryContext { export const elasticsearchMonitorStatesAdapter: UMMonitorStatesAdapter = { // Gets a page of monitor states. - getMonitorStates: async ( - callAsCurrentUser, - { dateRangeStart, dateRangeEnd, pagination, filters, statusFilter } - ) => { + getMonitorStates: async ({ + callES, + dateRangeStart, + dateRangeEnd, + pagination, + filters, + statusFilter, + }) => { pagination = pagination || CONTEXT_DEFAULTS.CURSOR_PAGINATION; statusFilter = statusFilter === null ? undefined : statusFilter; const size = 10; const queryContext: QueryContext = { - count: (query: Record): Promise => callAsCurrentUser('count', query), - search: (query: Record): Promise => callAsCurrentUser('search', query), + count: (query: Record): Promise => callES('count', query), + search: (query: Record): Promise => callES('search', query), dateRangeStart, dateRangeEnd, pagination, @@ -51,10 +55,10 @@ export const elasticsearchMonitorStatesAdapter: UMMonitorStatesAdapter = { }; }, - getSnapshotCount: async (callEs, { dateRangeStart, dateRangeEnd, filters, statusFilter }) => { + getSnapshotCount: async ({ callES, dateRangeStart, dateRangeEnd, filters, statusFilter }) => { const context: QueryContext = { - count: query => callEs('count', query), - search: query => callEs('search', query), + count: query => callES('count', query), + search: query => callES('search', query), dateRangeStart, dateRangeEnd, pagination: CONTEXT_DEFAULTS.CURSOR_PAGINATION, @@ -65,12 +69,12 @@ export const elasticsearchMonitorStatesAdapter: UMMonitorStatesAdapter = { return getSnapshotCountHelper(new MonitorGroupIterator(context)); }, - statesIndexExists: async callEs => { + statesIndexExists: async ({ callES }) => { // TODO: adapt this to the states index in future release const { _shards: { total }, count, - } = await callEs('count', { index: INDEX_NAMES.HEARTBEAT }); + } = await callES('count', { index: INDEX_NAMES.HEARTBEAT }); return { indexExists: total > 0, docCount: { diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/adapter_types.ts index ab792b866d58a..bc81b5367a5d0 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/adapter_types.ts @@ -38,11 +38,11 @@ export interface UMMonitorsAdapter { /** * Fetches data used to populate monitor charts */ - getMonitorChartsData: UMElasticsearchQueryFn; - getFilterBar: UMElasticsearchQueryFn; + getMonitorChartsData: UMElasticsearchQueryFn; + getFilterBar: UMElasticsearchQueryFn; /** * Fetch data for the monitor page title. */ - getMonitorPageTitle: UMElasticsearchQueryFn; - getMonitorDetails: UMElasticsearchQueryFn; + getMonitorPageTitle: UMElasticsearchQueryFn<{ monitorId: string }, MonitorPageTitle | null>; + getMonitorDetails: UMElasticsearchQueryFn; } diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts index 1eeefd6f93472..fcc1a581ab96c 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts @@ -32,7 +32,7 @@ const formatStatusBuckets = (time: any, buckets: any, docCount: any) => { }; export const elasticsearchMonitorsAdapter: UMMonitorsAdapter = { - getMonitorChartsData: async (callEs, { dateRangeStart, dateRangeEnd, monitorId, location }) => { + getMonitorChartsData: async ({ callES, dateRangeStart, dateRangeEnd, monitorId, location }) => { const params = { index: INDEX_NAMES.HEARTBEAT, body: { @@ -72,7 +72,7 @@ export const elasticsearchMonitorsAdapter: UMMonitorsAdapter = { }, }; - const result = await callEs('search', params); + const result = await callES('search', params); const dateHistogramBuckets = get(result, 'aggregations.timeseries.buckets', []); /** @@ -160,7 +160,7 @@ export const elasticsearchMonitorsAdapter: UMMonitorsAdapter = { return monitorChartsData; }, - getFilterBar: async (callEs, { dateRangeStart, dateRangeEnd }) => { + getFilterBar: async ({ callES, dateRangeStart, dateRangeEnd }) => { const fields: { [key: string]: string } = { ids: 'monitor.id', schemes: 'monitor.type', @@ -186,7 +186,7 @@ export const elasticsearchMonitorsAdapter: UMMonitorsAdapter = { }, {}), }, }; - const { aggregations } = await callEs('search', params); + const { aggregations } = await callES('search', params); return Object.keys(fields).reduce((acc: { [key: string]: any[] }, field) => { const bucketName = fields[field]; @@ -195,7 +195,7 @@ export const elasticsearchMonitorsAdapter: UMMonitorsAdapter = { }, {}); }, - getMonitorPageTitle: async (callEs, { monitorId }) => { + getMonitorPageTitle: async ({ callES, monitorId }) => { const params = { index: INDEX_NAMES.HEARTBEAT, body: { @@ -219,7 +219,7 @@ export const elasticsearchMonitorsAdapter: UMMonitorsAdapter = { }, }; - const result = await callEs('search', params); + const result = await callES('search', params); const pageTitle: Ping | null = get(result, 'hits.hits[0]._source', null); if (pageTitle === null) { return null; @@ -231,7 +231,7 @@ export const elasticsearchMonitorsAdapter: UMMonitorsAdapter = { }; }, - getMonitorDetails: async (callEs, { monitorId }) => { + getMonitorDetails: async ({ callES, monitorId }) => { const params = { index: INDEX_NAMES.HEARTBEAT, body: { @@ -265,7 +265,7 @@ export const elasticsearchMonitorsAdapter: UMMonitorsAdapter = { }, }; - const result = await callEs('search', params); + const result = await callES('search', params); const data = result.hits.hits[0]?._source; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/adapter_types.ts index fe87a606d9492..81df1c7c0f631 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/adapter_types.ts @@ -62,16 +62,16 @@ export interface GetPingHistogramParams { * Count the number of documents in heartbeat indices */ export interface UMPingsAdapter { - getAll: UMElasticsearchQueryFn; + getAll: UMElasticsearchQueryFn; - getLatestMonitorDocs: UMElasticsearchQueryFn; + getLatestMonitorDocs: UMElasticsearchQueryFn; - getPingHistogram: UMElasticsearchQueryFn; + getPingHistogram: UMElasticsearchQueryFn; /** * Gets data used for a composite histogram for the currently-running monitors. */ - getDocCount: UMElasticsearchQueryFn; + getDocCount: UMElasticsearchQueryFn<{}, DocCount>; } export interface HistogramQueryResult { diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts index 021dcd286ff17..6862bed8d2bdd 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts @@ -12,10 +12,16 @@ import { UMPingsAdapter, HistogramQueryResult } from './adapter_types'; import { getHistogramInterval } from '../../helper/get_histogram_interval'; export const elasticsearchPingsAdapter: UMPingsAdapter = { - getAll: async ( - callEs, - { dateRangeStart, dateRangeEnd, monitorId, status, sort, size, location } - ) => { + getAll: async ({ + callES, + dateRangeStart, + dateRangeEnd, + monitorId, + status, + sort, + size, + location, + }) => { const sortParam = { sort: [{ '@timestamp': { order: sort ?? 'desc' } }] }; const sizeParam = size ? { size } : undefined; const filter: any[] = [{ range: { '@timestamp': { gte: dateRangeStart, lte: dateRangeEnd } } }]; @@ -55,7 +61,7 @@ export const elasticsearchPingsAdapter: UMPingsAdapter = { const { hits: { hits, total }, aggregations: aggs, - } = await callEs('search', params); + } = await callES('search', params); const locations = get(aggs, 'locations', { buckets: [{ key: 'N/A', doc_count: 0 }] }); @@ -82,7 +88,7 @@ export const elasticsearchPingsAdapter: UMPingsAdapter = { return results; }, - getLatestMonitorDocs: async (callEs, { dateRangeStart, dateRangeEnd, monitorId, location }) => { + getLatestMonitorDocs: async ({ callES, dateRangeStart, dateRangeEnd, monitorId, location }) => { const params = { index: INDEX_NAMES.HEARTBEAT, body: { @@ -124,7 +130,7 @@ export const elasticsearchPingsAdapter: UMPingsAdapter = { }, }; - const result = await callEs('search', params); + const result = await callES('search', params); const buckets: any[] = get(result, 'aggregations.by_id.buckets', []); return buckets.map( @@ -142,10 +148,14 @@ export const elasticsearchPingsAdapter: UMPingsAdapter = { ); }, - getPingHistogram: async ( - callEs, - { dateRangeStart, dateRangeEnd, filters, monitorId, statusFilter } - ) => { + getPingHistogram: async ({ + callES, + dateRangeStart, + dateRangeEnd, + filters, + monitorId, + statusFilter, + }) => { const boolFilters = parseFilterQuery(filters); const additionaFilters = []; if (monitorId) { @@ -194,7 +204,7 @@ export const elasticsearchPingsAdapter: UMPingsAdapter = { }, }; - const result = await callEs('search', params); + const result = await callES('search', params); const buckets: HistogramQueryResult[] = get(result, 'aggregations.timeseries.buckets', []); const histogram = buckets.map(bucket => { const x: number = get(bucket, 'key'); @@ -213,8 +223,8 @@ export const elasticsearchPingsAdapter: UMPingsAdapter = { }; }, - getDocCount: async callEs => { - const { count } = await callEs('count', { index: INDEX_NAMES.HEARTBEAT }); + getDocCount: async ({ callES }) => { + const { count } = await callES('count', { index: INDEX_NAMES.HEARTBEAT }); return { count }; }, diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts b/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts index f640f341e2edb..a5cc37dc604c8 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts @@ -33,7 +33,9 @@ export const createGetMonitorDetailsRoute: UMRestApiRouteCreator = (libs: UMServ const { monitorId } = request.query; return response.ok({ - body: { ...(await libs.monitors.getMonitorDetails(callAsCurrentUser, monitorId)) }, + body: { + ...(await libs.monitors.getMonitorDetails({ callES: callAsCurrentUser, monitorId })), + }, }); }, }); diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts b/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts index b7271c4bfdc6f..3d3ba2ef13c62 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts @@ -36,9 +36,10 @@ export const createGetAllRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => request, response ): Promise => { - const { size, sort, dateRangeStart, dateRangeEnd, location, monitorId, status } = request.query; + const { dateRangeStart, dateRangeEnd, location, monitorId, size, sort, status } = request.query; - const result = await libs.pings.getAll(callAsCurrentUser, { + const result = await libs.pings.getAll({ + callES: callAsCurrentUser, dateRangeStart, dateRangeEnd, monitorId, diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts b/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts index d1256ecbce664..16add5a82ce5c 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts @@ -34,7 +34,8 @@ export const createGetSnapshotCount: UMRestApiRouteCreator = (libs: UMServerLibs response ): Promise => { const { dateRangeStart, dateRangeEnd, filters, statusFilter } = request.query; - const result = await libs.monitorStates.getSnapshotCount(callAsCurrentUser, { + const result = await libs.monitorStates.getSnapshotCount({ + callES: callAsCurrentUser, dateRangeStart, dateRangeEnd, filters, From e6e7f1ce2b82644ddd999d1cb15538bcfa9c31f9 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Fri, 6 Dec 2019 10:44:24 -0500 Subject: [PATCH 24/32] Update broken test files. --- .../elasticsearch_monitors_adapter.test.ts | 9 ++-- .../elasticsearch_pings_adapter.test.ts | 41 ++++++++++++------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/__tests__/elasticsearch_monitors_adapter.test.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/__tests__/elasticsearch_monitors_adapter.test.ts index 548fdea8a801c..e3e81fe360718 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/__tests__/elasticsearch_monitors_adapter.test.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/__tests__/elasticsearch_monitors_adapter.test.ts @@ -15,7 +15,8 @@ describe('ElasticsearchMonitorsAdapter', () => { expect.assertions(3); const searchMock = jest.fn(); const search = searchMock.bind({}); - await adapter.getMonitorChartsData(search, { + await adapter.getMonitorChartsData({ + callES: search, monitorId: 'fooID', dateRangeStart: 'now-15m', dateRangeEnd: 'now', @@ -49,7 +50,8 @@ describe('ElasticsearchMonitorsAdapter', () => { expect.assertions(3); const searchMock = jest.fn(); const search = searchMock.bind({}); - await adapter.getMonitorChartsData(search, { + await adapter.getMonitorChartsData({ + callES: search, monitorId: 'fooID', dateRangeStart: 'now-15m', dateRangeEnd: 'now', @@ -85,7 +87,8 @@ describe('ElasticsearchMonitorsAdapter', () => { searchMock.mockReturnValue(mockChartsData); const search = searchMock.bind({}); expect( - await adapter.getMonitorChartsData(search, { + await adapter.getMonitorChartsData({ + callES: search, monitorId: 'id', dateRangeStart: 'now-15m', dateRangeEnd: 'now', diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts index 69edc28f2050d..4fdf82b72f27e 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts @@ -96,7 +96,8 @@ describe('ElasticsearchPingsAdapter class', () => { }, }, }); - const result = await adapter.getPingHistogram(mockEsClient, { + const result = await adapter.getPingHistogram({ + callES: mockEsClient, dateRangeStart: 'now-15m', dateRangeEnd: 'now', filters: null, @@ -113,7 +114,8 @@ describe('ElasticsearchPingsAdapter class', () => { mockEsClient.mockReturnValue(standardMockResponse); - const result = await adapter.getPingHistogram(mockEsClient, { + const result = await adapter.getPingHistogram({ + callES: mockEsClient, dateRangeStart: 'now-15m', dateRangeEnd: 'now', filters: null, @@ -171,7 +173,8 @@ describe('ElasticsearchPingsAdapter class', () => { ], }, }; - const result = await adapter.getPingHistogram(mockEsClient, { + const result = await adapter.getPingHistogram({ + callES: mockEsClient, dateRangeStart: '1234', dateRangeEnd: '5678', filters: JSON.stringify(searchFilter), @@ -224,7 +227,8 @@ describe('ElasticsearchPingsAdapter class', () => { }, }); const filters = `{"bool":{"must":[{"simple_query_string":{"query":"http"}}]}}`; - const result = await adapter.getPingHistogram(mockEsClient, { + const result = await adapter.getPingHistogram({ + callES: mockEsClient, dateRangeStart: 'now-15m', dateRangeEnd: 'now', filters, @@ -240,7 +244,8 @@ describe('ElasticsearchPingsAdapter class', () => { expect.assertions(2); const mockEsClient = jest.fn(); mockEsClient.mockReturnValue(standardMockResponse); - const result = await adapter.getPingHistogram(mockEsClient, { + const result = await adapter.getPingHistogram({ + callES: mockEsClient, dateRangeStart: '1234', dateRangeEnd: '5678', filters: '', @@ -260,7 +265,8 @@ describe('ElasticsearchPingsAdapter class', () => { mockEsClient.mockReturnValue(standardMockResponse); - const result = await adapter.getPingHistogram(mockEsClient, { + const result = await adapter.getPingHistogram({ + callES: mockEsClient, dateRangeStart: '1234', dateRangeEnd: '5678', filters: '', @@ -277,7 +283,7 @@ describe('ElasticsearchPingsAdapter class', () => { it('returns data in appropriate shape', async () => { const mockEsClient = jest.fn(); mockEsClient.mockReturnValue(mockEsCountResult); - const { count } = await adapter.getDocCount(mockEsClient, undefined); + const { count } = await adapter.getDocCount({ callES: mockEsClient }); expect(count).toEqual(3); }); }); @@ -311,7 +317,8 @@ describe('ElasticsearchPingsAdapter class', () => { it('returns data in the appropriate shape', async () => { const mockEsClient = jest.fn(); mockEsClient.mockReturnValue(mockEsSearchResult); - const result = await adapter.getAll(mockEsClient, { + const result = await adapter.getAll({ + callES: mockEsClient, dateRangeStart: 'now-1h', dateRangeEnd: 'now', sort: 'asc', @@ -332,7 +339,8 @@ describe('ElasticsearchPingsAdapter class', () => { it('creates appropriate sort and size parameters', async () => { const mockEsClient = jest.fn(); mockEsClient.mockReturnValue(mockEsSearchResult); - await adapter.getAll(mockEsClient, { + await adapter.getAll({ + callES: mockEsClient, dateRangeStart: 'now-1h', dateRangeEnd: 'now', sort: 'asc', @@ -347,7 +355,8 @@ describe('ElasticsearchPingsAdapter class', () => { it('omits the sort param when no sort passed', async () => { const mockEsClient = jest.fn(); mockEsClient.mockReturnValue(mockEsSearchResult); - await adapter.getAll(mockEsClient, { + await adapter.getAll({ + callES: mockEsClient, dateRangeStart: 'now-1h', dateRangeEnd: 'now', size: 12, @@ -359,7 +368,8 @@ describe('ElasticsearchPingsAdapter class', () => { it('omits the size param when no size passed', async () => { const mockEsClient = jest.fn(); mockEsClient.mockReturnValue(mockEsSearchResult); - await adapter.getAll(mockEsClient, { + await adapter.getAll({ + callES: mockEsClient, dateRangeStart: 'now-1h', dateRangeEnd: 'now', sort: 'desc', @@ -373,7 +383,8 @@ describe('ElasticsearchPingsAdapter class', () => { it('adds a filter for monitor ID', async () => { const mockEsClient = jest.fn(); mockEsClient.mockReturnValue(mockEsSearchResult); - await adapter.getAll(mockEsClient, { + await adapter.getAll({ + callES: mockEsClient, dateRangeStart: 'now-1h', dateRangeEnd: 'now', monitorId: 'testmonitorid', @@ -387,7 +398,8 @@ describe('ElasticsearchPingsAdapter class', () => { it('adds a filter for monitor status', async () => { const mockEsClient = jest.fn(); mockEsClient.mockReturnValue(mockEsSearchResult); - await adapter.getAll(mockEsClient, { + await adapter.getAll({ + callES: mockEsClient, dateRangeStart: 'now-1h', dateRangeEnd: 'now', status: 'down', @@ -471,7 +483,8 @@ describe('ElasticsearchPingsAdapter class', () => { it('returns data in expected shape', async () => { const mockEsClient = jest.fn(async (request: any, params: any) => mockEsSearchResult); - const result = await adapter.getLatestMonitorDocs(mockEsClient, { + const result = await adapter.getLatestMonitorDocs({ + callES: mockEsClient, dateRangeStart: 'now-1h', dateRangeEnd: 'now', monitorId: 'testmonitor', From 72e214830d35519ebeff7622369fe1a570bab50d Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Fri, 6 Dec 2019 10:45:23 -0500 Subject: [PATCH 25/32] Resolve typescript warnings. --- .../pings/__tests__/elasticsearch_pings_adapter.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts index 4fdf82b72f27e..bd1c182e938a3 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/__tests__/elasticsearch_pings_adapter.test.ts @@ -482,7 +482,7 @@ describe('ElasticsearchPingsAdapter class', () => { }); it('returns data in expected shape', async () => { - const mockEsClient = jest.fn(async (request: any, params: any) => mockEsSearchResult); + const mockEsClient = jest.fn(async (_request: any, _params: any) => mockEsSearchResult); const result = await adapter.getLatestMonitorDocs({ callES: mockEsClient, dateRangeStart: 'now-1h', From 786a714af53ed9872552bcb351ebb62a67b615c5 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Fri, 6 Dec 2019 10:46:17 -0500 Subject: [PATCH 26/32] Update resolver types. --- .../server/graphql/monitor_states/resolvers.ts | 7 ++++--- .../uptime/server/graphql/monitors/resolvers.ts | 17 ++++++++++++----- .../uptime/server/graphql/pings/resolvers.ts | 5 +++-- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/resolvers.ts b/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/resolvers.ts index 6d210e8635754..a7cf57ababb71 100644 --- a/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/resolvers.ts +++ b/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/resolvers.ts @@ -50,8 +50,9 @@ export const createMonitorStatesResolvers: CreateUMGraphQLResolvers = ( totalSummaryCount, { summaries, nextPagePagination, prevPagePagination }, ] = await Promise.all([ - libs.pings.getDocCount(callAsCurrentUser, undefined), - libs.monitorStates.getMonitorStates(callAsCurrentUser, { + libs.pings.getDocCount({ callES: callAsCurrentUser }), + libs.monitorStates.getMonitorStates({ + callES: callAsCurrentUser, dateRangeStart, dateRangeEnd, pagination: decodedPagination, @@ -67,7 +68,7 @@ export const createMonitorStatesResolvers: CreateUMGraphQLResolvers = ( }; }, async getStatesIndexStatus(_resolver, {}, { callAsCurrentUser }): Promise { - return await libs.monitorStates.statesIndexExists(callAsCurrentUser, undefined); + return await libs.monitorStates.statesIndexExists({ callES: callAsCurrentUser }); }, }, }; diff --git a/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts b/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts index e0a8e4f10ba7c..2b015a23cef6c 100644 --- a/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts +++ b/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts @@ -75,7 +75,8 @@ export const createMonitorsResolvers: CreateUMGraphQLResolvers = ( { dateRangeStart, dateRangeEnd, filters, monitorId, statusFilter }, { callAsCurrentUser } ): Promise { - return await libs.pings.getPingHistogram(callAsCurrentUser, { + return await libs.pings.getPingHistogram({ + callES: callAsCurrentUser, dateRangeStart, dateRangeEnd, filters, @@ -88,7 +89,8 @@ export const createMonitorsResolvers: CreateUMGraphQLResolvers = ( { monitorId, dateRangeStart, dateRangeEnd, location }, { callAsCurrentUser } ): Promise { - return await libs.monitors.getMonitorChartsData(callAsCurrentUser, { + return await libs.monitors.getMonitorChartsData({ + callES: callAsCurrentUser, monitorId, dateRangeStart, dateRangeEnd, @@ -100,7 +102,8 @@ export const createMonitorsResolvers: CreateUMGraphQLResolvers = ( { dateRangeStart, dateRangeEnd, monitorId, location }, { callAsCurrentUser } ): Promise { - return await libs.pings.getLatestMonitorDocs(callAsCurrentUser, { + return await libs.pings.getLatestMonitorDocs({ + callES: callAsCurrentUser, dateRangeStart, dateRangeEnd, monitorId, @@ -112,14 +115,18 @@ export const createMonitorsResolvers: CreateUMGraphQLResolvers = ( { dateRangeStart, dateRangeEnd }, { callAsCurrentUser } ): Promise { - return await libs.monitors.getFilterBar(callAsCurrentUser, { dateRangeStart, dateRangeEnd }); + return await libs.monitors.getFilterBar({ + callES: callAsCurrentUser, + dateRangeStart, + dateRangeEnd, + }); }, async getMonitorPageTitle( _resolver: any, { monitorId }, { callAsCurrentUser } ): Promise { - return await libs.monitors.getMonitorPageTitle(callAsCurrentUser, { monitorId }); + return await libs.monitors.getMonitorPageTitle({ callES: callAsCurrentUser, monitorId }); }, }, }); diff --git a/x-pack/legacy/plugins/uptime/server/graphql/pings/resolvers.ts b/x-pack/legacy/plugins/uptime/server/graphql/pings/resolvers.ts index c3cc1b4278035..6a1ce508a7420 100644 --- a/x-pack/legacy/plugins/uptime/server/graphql/pings/resolvers.ts +++ b/x-pack/legacy/plugins/uptime/server/graphql/pings/resolvers.ts @@ -38,7 +38,8 @@ export const createPingsResolvers: CreateUMGraphQLResolvers = ( { monitorId, sort, size, status, dateRangeStart, dateRangeEnd, location }, { callAsCurrentUser } ): Promise { - return await libs.pings.getAll(callAsCurrentUser, { + return await libs.pings.getAll({ + callES: callAsCurrentUser, dateRangeStart, dateRangeEnd, monitorId, @@ -49,7 +50,7 @@ export const createPingsResolvers: CreateUMGraphQLResolvers = ( }); }, async getDocCount(_resolver, _args, { callAsCurrentUser }): Promise { - return libs.pings.getDocCount(callAsCurrentUser, undefined); + return libs.pings.getDocCount({ callES: callAsCurrentUser }); }, }, }); From 2300e8195b6e172656c8b87639196d3f074eade6 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Mon, 9 Dec 2019 16:46:27 -0500 Subject: [PATCH 27/32] Change GraphQL interface name for es client. --- .../graphql/monitor_states/resolvers.ts | 10 +++++----- .../server/graphql/monitors/resolvers.ts | 20 +++++++++---------- .../uptime/server/graphql/pings/resolvers.ts | 8 ++++---- .../plugins/uptime/server/graphql/types.ts | 2 +- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/resolvers.ts b/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/resolvers.ts index a7cf57ababb71..759b1c8eca95c 100644 --- a/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/resolvers.ts +++ b/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/resolvers.ts @@ -41,7 +41,7 @@ export const createMonitorStatesResolvers: CreateUMGraphQLResolvers = ( async getMonitorStates( _resolver, { dateRangeStart, dateRangeEnd, filters, pagination, statusFilter }, - { callAsCurrentUser } + { APICaller } ): Promise { const decodedPagination = pagination ? JSON.parse(decodeURIComponent(pagination)) @@ -50,9 +50,9 @@ export const createMonitorStatesResolvers: CreateUMGraphQLResolvers = ( totalSummaryCount, { summaries, nextPagePagination, prevPagePagination }, ] = await Promise.all([ - libs.pings.getDocCount({ callES: callAsCurrentUser }), + libs.pings.getDocCount({ callES: APICaller }), libs.monitorStates.getMonitorStates({ - callES: callAsCurrentUser, + callES: APICaller, dateRangeStart, dateRangeEnd, pagination: decodedPagination, @@ -67,8 +67,8 @@ export const createMonitorStatesResolvers: CreateUMGraphQLResolvers = ( totalSummaryCount, }; }, - async getStatesIndexStatus(_resolver, {}, { callAsCurrentUser }): Promise { - return await libs.monitorStates.statesIndexExists({ callES: callAsCurrentUser }); + async getStatesIndexStatus(_resolver, {}, { APICaller }): Promise { + return await libs.monitorStates.statesIndexExists({ callES: APICaller }); }, }, }; diff --git a/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts b/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts index 2b015a23cef6c..8b685d8e08a2b 100644 --- a/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts +++ b/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts @@ -73,10 +73,10 @@ export const createMonitorsResolvers: CreateUMGraphQLResolvers = ( async getSnapshotHistogram( _resolver, { dateRangeStart, dateRangeEnd, filters, monitorId, statusFilter }, - { callAsCurrentUser } + { APICaller } ): Promise { return await libs.pings.getPingHistogram({ - callES: callAsCurrentUser, + callES: APICaller, dateRangeStart, dateRangeEnd, filters, @@ -87,10 +87,10 @@ export const createMonitorsResolvers: CreateUMGraphQLResolvers = ( async getMonitorChartsData( _resolver, { monitorId, dateRangeStart, dateRangeEnd, location }, - { callAsCurrentUser } + { APICaller } ): Promise { return await libs.monitors.getMonitorChartsData({ - callES: callAsCurrentUser, + callES: APICaller, monitorId, dateRangeStart, dateRangeEnd, @@ -100,10 +100,10 @@ export const createMonitorsResolvers: CreateUMGraphQLResolvers = ( async getLatestMonitors( _resolver, { dateRangeStart, dateRangeEnd, monitorId, location }, - { callAsCurrentUser } + { APICaller } ): Promise { return await libs.pings.getLatestMonitorDocs({ - callES: callAsCurrentUser, + callES: APICaller, dateRangeStart, dateRangeEnd, monitorId, @@ -113,10 +113,10 @@ export const createMonitorsResolvers: CreateUMGraphQLResolvers = ( async getFilterBar( _resolver, { dateRangeStart, dateRangeEnd }, - { callAsCurrentUser } + { APICaller } ): Promise { return await libs.monitors.getFilterBar({ - callES: callAsCurrentUser, + callES: APICaller, dateRangeStart, dateRangeEnd, }); @@ -124,9 +124,9 @@ export const createMonitorsResolvers: CreateUMGraphQLResolvers = ( async getMonitorPageTitle( _resolver: any, { monitorId }, - { callAsCurrentUser } + { APICaller } ): Promise { - return await libs.monitors.getMonitorPageTitle({ callES: callAsCurrentUser, monitorId }); + return await libs.monitors.getMonitorPageTitle({ callES: APICaller, monitorId }); }, }, }); diff --git a/x-pack/legacy/plugins/uptime/server/graphql/pings/resolvers.ts b/x-pack/legacy/plugins/uptime/server/graphql/pings/resolvers.ts index 6a1ce508a7420..373e1467433a2 100644 --- a/x-pack/legacy/plugins/uptime/server/graphql/pings/resolvers.ts +++ b/x-pack/legacy/plugins/uptime/server/graphql/pings/resolvers.ts @@ -36,10 +36,10 @@ export const createPingsResolvers: CreateUMGraphQLResolvers = ( async allPings( _resolver, { monitorId, sort, size, status, dateRangeStart, dateRangeEnd, location }, - { callAsCurrentUser } + { APICaller } ): Promise { return await libs.pings.getAll({ - callES: callAsCurrentUser, + callES: APICaller, dateRangeStart, dateRangeEnd, monitorId, @@ -49,8 +49,8 @@ export const createPingsResolvers: CreateUMGraphQLResolvers = ( location, }); }, - async getDocCount(_resolver, _args, { callAsCurrentUser }): Promise { - return libs.pings.getDocCount({ callES: callAsCurrentUser }); + async getDocCount(_resolver, _args, { APICaller }): Promise { + return libs.pings.getDocCount({ callES: APICaller }); }, }, }); diff --git a/x-pack/legacy/plugins/uptime/server/graphql/types.ts b/x-pack/legacy/plugins/uptime/server/graphql/types.ts index f987446261b2d..529ab41a62b3b 100644 --- a/x-pack/legacy/plugins/uptime/server/graphql/types.ts +++ b/x-pack/legacy/plugins/uptime/server/graphql/types.ts @@ -8,7 +8,7 @@ import { RequestHandlerContext, CallAPIOptions } from 'kibana/server'; import { UMServerLibs } from '../lib/lib'; export type UMContext = RequestHandlerContext & { - callAsCurrentUser: ( + APICaller: ( endpoint: string, clientParams?: Record, options?: CallAPIOptions | undefined From d7601be47cc7e0d74c107f5072965e850bece977 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Mon, 9 Dec 2019 16:47:10 -0500 Subject: [PATCH 28/32] Delete unused code and fix incorrect type. --- .../framework/kibana_framework_adapter.ts | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts index 0ecafea151026..1888e85267659 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -29,24 +29,6 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte case 'POST': this.server.route.post(routeDefinition, handler); break; - case 'POST': - this.server.route.post( - { - path, - validate, - }, - handler - ); - break; - case 'POST': - this.server.route.post( - { - path, - validate, - }, - handler - ); - break; default: throw new Error(`Handler for method ${method} is not defined`); } @@ -78,7 +60,7 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte const options = { graphQLOptions: (_req: any) => { return { - context: { ...context, callAsCurrentUser }, + context: { ...context, APICaller: callAsCurrentUser }, schema, }; }, From 17a6adca661f790cda025214f0bf4d6423eb5a71 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Mon, 9 Dec 2019 16:55:45 -0500 Subject: [PATCH 29/32] Rename type for REST endpoint creators. --- .../uptime/server/lib/adapters/framework/adapter_types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts index a20c7166d95c4..665e44e51ac87 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts @@ -28,14 +28,14 @@ export interface UMFrameworkRouteOptions< validate: any; } -type CallElasticsearchAsCurrentUser = ( +type APICaller = ( endpoint: string, clientParams: Record, options?: CallAPIOptions ) => Promise; export type UMElasticsearchQueryFn = ( - params: { callES: CallElasticsearchAsCurrentUser } & P + params: { callES: APICaller } & P ) => Promise | R; export type UMSavedObjectsQueryFn = ( From ac4e2e9a62eb7d8069d60cd3c7b5eaa9126d3344 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Mon, 9 Dec 2019 16:56:15 -0500 Subject: [PATCH 30/32] Nest message values in body object for invalid response messages. --- .../plugins/uptime/server/rest_api/create_route_with_auth.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts b/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts index 18e2c7b7d15e7..35c4ba9a5c1ef 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts @@ -28,9 +28,9 @@ export const createRouteWithAuth = ( case 400: return response.badRequest({ body: { message } }); case 401: - return response.unauthorized({ body: message }); + return response.unauthorized({ body: { message } }); case 403: - return response.forbidden({ body: message }); + return response.forbidden({ body: { message } }); default: return response.internalError(); } From c0d518714978ce6abea8887de953709f378b5691 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Thu, 12 Dec 2019 13:04:09 -0500 Subject: [PATCH 31/32] Reorganize a file and clean up some types. --- .../server/graphql/monitor_states/resolvers.ts | 5 ++++- .../lib/adapters/monitor_states/adapter_types.ts | 16 ++++++++-------- .../elasticsearch_monitor_states_adapter.ts | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/resolvers.ts b/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/resolvers.ts index 759b1c8eca95c..8ddb07b3093d0 100644 --- a/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/resolvers.ts +++ b/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/resolvers.ts @@ -57,7 +57,10 @@ export const createMonitorStatesResolvers: CreateUMGraphQLResolvers = ( dateRangeEnd, pagination: decodedPagination, filters, - statusFilter, + // this is added to make typescript happy, + // this sort of reassignment used to be further downstream but I've moved it here + // because this code is going to be decomissioned soon + statusFilter: statusFilter || undefined, }), ]); return { diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/adapter_types.ts index 71e9644c2adee..4104a9287a28d 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/adapter_types.ts @@ -18,7 +18,14 @@ export interface MonitorStatesParams { dateRangeEnd: string; pagination?: CursorPagination; filters?: string | null; - statusFilter?: string | null; + statusFilter?: string; +} + +export interface GetSnapshotCountParams { + dateRangeStart: string; + dateRangeEnd: string; + filters?: string | null; + statusFilter?: string; } export interface UMMonitorStatesAdapter { @@ -39,13 +46,6 @@ export interface GetMonitorStatesResult { prevPagePagination: string | null; } -export interface GetSnapshotCountParams { - dateRangeStart: string; - dateRangeEnd: string; - filters?: string | null; - statusFilter?: string | null; -} - export interface LegacyMonitorStatesQueryResult { result: any; statusFilter?: any; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/elasticsearch_monitor_states_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/elasticsearch_monitor_states_adapter.ts index f5ee081538a98..d264da2e7ec0c 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/elasticsearch_monitor_states_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/elasticsearch_monitor_states_adapter.ts @@ -64,7 +64,7 @@ export const elasticsearchMonitorStatesAdapter: UMMonitorStatesAdapter = { pagination: CONTEXT_DEFAULTS.CURSOR_PAGINATION, filterClause: filters && filters !== '' ? JSON.parse(filters) : null, size: CONTEXT_DEFAULTS.MAX_MONITORS_FOR_SNAPSHOT_COUNT, - statusFilter: statusFilter || undefined, + statusFilter, }; return getSnapshotCountHelper(new MonitorGroupIterator(context)); }, From c745fb816e23fb0fd2f38c221905a232210943a8 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Tue, 17 Dec 2019 09:06:07 -0500 Subject: [PATCH 32/32] Add wrapper function to reduce boilerplate route code. --- .../lib/adapters/framework/adapter_types.ts | 4 +- .../framework/kibana_framework_adapter.ts | 4 +- .../server/rest_api/create_route_with_auth.ts | 16 ++-- .../plugins/uptime/server/rest_api/index.ts | 5 +- .../index_pattern/get_index_pattern.ts | 14 +--- .../rest_api/monitors/monitor_locations.ts | 18 +--- .../rest_api/monitors/monitors_details.ts | 18 +--- .../uptime/server/rest_api/pings/get_all.ts | 18 +--- .../rest_api/snapshot/get_snapshot_count.ts | 18 +--- .../rest_api/telemetry/log_monitor_page.ts | 6 +- .../rest_api/telemetry/log_overview_page.ts | 6 +- .../plugins/uptime/server/rest_api/types.ts | 82 +++++++++++++++++-- .../server/rest_api/uptime_route_wrapper.ts | 18 ++++ .../plugins/uptime/server/uptime_server.ts | 6 +- 14 files changed, 136 insertions(+), 97 deletions(-) create mode 100644 x-pack/legacy/plugins/uptime/server/rest_api/uptime_route_wrapper.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts index 665e44e51ac87..b490bf17e292c 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts @@ -14,7 +14,7 @@ import { SavedObjectsClientContract, } from 'src/core/server'; import { ObjectType } from '@kbn/config-schema'; -import { UMRouteDefinition } from '../../../rest_api'; +import { UMKibanaRoute } from '../../../rest_api'; export interface UMFrameworkRouteOptions< P extends ObjectType, @@ -54,6 +54,6 @@ export interface UptimeCorePlugins { } export interface UMBackendFrameworkAdapter { - registerRoute(route: UMRouteDefinition): void; + registerRoute(route: UMKibanaRoute): void; registerGraphQLEndpoint(routePath: string, schema: GraphQLSchema): void; } diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts index 1888e85267659..7ac3db9d0f3d7 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -9,14 +9,14 @@ import { schema as kbnSchema } from '@kbn/config-schema'; import { runHttpQuery } from 'apollo-server-core'; import { UptimeCoreSetup } from './adapter_types'; import { UMBackendFrameworkAdapter } from './adapter_types'; -import { UMRouteDefinition } from '../../../rest_api'; +import { UMKibanaRoute } from '../../../rest_api'; export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapter { constructor(private readonly server: UptimeCoreSetup) { this.server = server; } - public registerRoute({ handler, method, options, path, validate }: UMRouteDefinition) { + public registerRoute({ handler, method, options, path, validate }: UMKibanaRoute) { const routeDefinition = { path, validate, diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts b/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts index 35c4ba9a5c1ef..41527d76432cb 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts @@ -4,25 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RequestHandler } from 'kibana/server'; -import { ObjectType } from '@kbn/config-schema'; import { UMServerLibs } from '../lib/lib'; -import { UMRestApiRouteCreator, UMRouteDefinition } from './types'; +import { UptimeRoute, UMRestApiRouteFactory, UMRouteHandler } from './types'; export const createRouteWithAuth = ( libs: UMServerLibs, - routeCreator: UMRestApiRouteCreator -): UMRouteDefinition => { + routeCreator: UMRestApiRouteFactory +): UptimeRoute => { const restRoute = routeCreator(libs); const { handler, method, path, options, ...rest } = restRoute; - const licenseCheckHandler: RequestHandler = async ( - context, - request, - response - ) => { + const licenseCheckHandler: UMRouteHandler = async (customParams, context, request, response) => { const { statusCode, message } = libs.license(context.licensing.license); if (statusCode === 200) { - return await handler(context, request, response); + return await handler(customParams, context, request, response); } switch (statusCode) { case 400: diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/index.ts b/x-pack/legacy/plugins/uptime/server/rest_api/index.ts index f18b9e8e44c36..4ab225076eff2 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/index.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/index.ts @@ -8,12 +8,13 @@ import { createGetAllRoute } from './pings'; import { createGetIndexPatternRoute } from './index_pattern'; import { createLogMonitorPageRoute, createLogOverviewPageRoute } from './telemetry'; import { createGetSnapshotCount } from './snapshot'; -import { UMRestApiRouteCreator } from './types'; +import { UMRestApiRouteFactory } from './types'; import { createGetMonitorDetailsRoute, createGetMonitorLocationsRoute } from './monitors'; export * from './types'; export { createRouteWithAuth } from './create_route_with_auth'; -export const restApiRoutes: UMRestApiRouteCreator[] = [ +export { uptimeRouteWrapper } from './uptime_route_wrapper'; +export const restApiRoutes: UMRestApiRouteFactory[] = [ createGetAllRoute, createGetIndexPatternRoute, createGetMonitorDetailsRoute, diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts b/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts index 2f0aea75c5e61..f061307807a42 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts @@ -5,24 +5,16 @@ */ import { UMServerLibs } from '../../lib/lib'; -import { UMRestApiRouteCreator } from '../types'; +import { UMRestApiRouteFactory } from '../types'; -export const createGetIndexPatternRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => ({ +export const createGetIndexPatternRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ method: 'GET', path: '/api/uptime/index_pattern', validate: false, options: { tags: ['access:uptime'], }, - handler: async ( - { - core: { - savedObjects: { client }, - }, - }, - _request, - response - ): Promise => { + handler: async ({ savedObjectsClient: client }, _context, _request, response): Promise => { try { return response.ok({ body: { diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitor_locations.ts b/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitor_locations.ts index 1a189061e9dd4..b2356ae0a88bf 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitor_locations.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitor_locations.ts @@ -6,9 +6,9 @@ import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../lib/lib'; -import { UMRestApiRouteCreator } from '../types'; +import { UMRestApiRouteFactory } from '../types'; -export const createGetMonitorLocationsRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => ({ +export const createGetMonitorLocationsRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ method: 'GET', path: '/api/uptime/monitor/locations', validate: { @@ -21,23 +21,13 @@ export const createGetMonitorLocationsRoute: UMRestApiRouteCreator = (libs: UMSe options: { tags: ['access:uptime'], }, - handler: async ( - { - core: { - elasticsearch: { - dataClient: { callAsCurrentUser }, - }, - }, - }, - request, - response - ): Promise => { + handler: async ({ callES }, _context, request, response): Promise => { const { monitorId, dateStart, dateEnd } = request.query; return response.ok({ body: { ...(await libs.monitors.getMonitorLocations({ - callES: callAsCurrentUser, + callES, monitorId, dateStart, dateEnd, diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts b/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts index a5cc37dc604c8..a57e5ec469c59 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts @@ -6,9 +6,9 @@ import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../lib/lib'; -import { UMRestApiRouteCreator } from '../types'; +import { UMRestApiRouteFactory } from '../types'; -export const createGetMonitorDetailsRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => ({ +export const createGetMonitorDetailsRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ method: 'GET', path: '/api/uptime/monitor/details', validate: { @@ -19,22 +19,12 @@ export const createGetMonitorDetailsRoute: UMRestApiRouteCreator = (libs: UMServ options: { tags: ['access:uptime'], }, - handler: async ( - { - core: { - elasticsearch: { - dataClient: { callAsCurrentUser }, - }, - }, - }, - request, - response - ): Promise => { + handler: async ({ callES }, _context, request, response): Promise => { const { monitorId } = request.query; return response.ok({ body: { - ...(await libs.monitors.getMonitorDetails({ callES: callAsCurrentUser, monitorId })), + ...(await libs.monitors.getMonitorDetails({ callES, monitorId })), }, }); }, diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts b/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts index 3d3ba2ef13c62..824035954ea28 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts @@ -6,9 +6,9 @@ import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../lib/lib'; -import { UMRestApiRouteCreator } from '../types'; +import { UMRestApiRouteFactory } from '../types'; -export const createGetAllRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => ({ +export const createGetAllRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ method: 'GET', path: '/api/uptime/pings', validate: { @@ -25,21 +25,11 @@ export const createGetAllRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => options: { tags: ['access:uptime'], }, - handler: async ( - { - core: { - elasticsearch: { - dataClient: { callAsCurrentUser }, - }, - }, - }, - request, - response - ): Promise => { + handler: async ({ callES }, _context, request, response): Promise => { const { dateRangeStart, dateRangeEnd, location, monitorId, size, sort, status } = request.query; const result = await libs.pings.getAll({ - callES: callAsCurrentUser, + callES, dateRangeStart, dateRangeEnd, monitorId, diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts b/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts index 16add5a82ce5c..986ac797d63b6 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts @@ -6,9 +6,9 @@ import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../lib/lib'; -import { UMRestApiRouteCreator } from '../types'; +import { UMRestApiRouteFactory } from '../types'; -export const createGetSnapshotCount: UMRestApiRouteCreator = (libs: UMServerLibs) => ({ +export const createGetSnapshotCount: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ method: 'GET', path: '/api/uptime/snapshot/count', validate: { @@ -22,20 +22,10 @@ export const createGetSnapshotCount: UMRestApiRouteCreator = (libs: UMServerLibs options: { tags: ['access:uptime'], }, - handler: async ( - { - core: { - elasticsearch: { - dataClient: { callAsCurrentUser }, - }, - }, - }, - request, - response - ): Promise => { + handler: async ({ callES }, _context, request, response): Promise => { const { dateRangeStart, dateRangeEnd, filters, statusFilter } = request.query; const result = await libs.monitorStates.getSnapshotCount({ - callES: callAsCurrentUser, + callES, dateRangeStart, dateRangeEnd, filters, diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_monitor_page.ts b/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_monitor_page.ts index f3e926493143b..fca1e6c8d5d46 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_monitor_page.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_monitor_page.ts @@ -5,13 +5,13 @@ */ import { KibanaTelemetryAdapter } from '../../lib/adapters/telemetry'; -import { UMRestApiRouteCreator } from '../types'; +import { UMRestApiRouteFactory } from '../types'; -export const createLogMonitorPageRoute: UMRestApiRouteCreator = () => ({ +export const createLogMonitorPageRoute: UMRestApiRouteFactory = () => ({ method: 'POST', path: '/api/uptime/logMonitor', validate: false, - handler: async (_context, _request, response): Promise => { + handler: async (_customParams, _context, _request, response): Promise => { await KibanaTelemetryAdapter.countMonitor(); return response.ok(); }, diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_overview_page.ts b/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_overview_page.ts index 277ef2235fb69..37ed2e5ff5c2c 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_overview_page.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_overview_page.ts @@ -5,13 +5,13 @@ */ import { KibanaTelemetryAdapter } from '../../lib/adapters/telemetry'; -import { UMRestApiRouteCreator } from '../types'; +import { UMRestApiRouteFactory } from '../types'; -export const createLogOverviewPageRoute: UMRestApiRouteCreator = () => ({ +export const createLogOverviewPageRoute: UMRestApiRouteFactory = () => ({ method: 'POST', path: '/api/uptime/logOverview', validate: false, - handler: async (_context, _request, response): Promise => { + handler: async (_customParams, _context, _request, response): Promise => { await KibanaTelemetryAdapter.countOverview(); return response.ok(); }, diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts b/x-pack/legacy/plugins/uptime/server/rest_api/types.ts index b4d7e438f51be..e0c8ba4a286cf 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/types.ts @@ -5,15 +5,87 @@ */ import { ObjectType } from '@kbn/config-schema'; -import { RequestHandler, RouteConfig, RouteMethod } from 'kibana/server'; +import { + RequestHandler, + RouteConfig, + RouteMethod, + CallAPIOptions, + SavedObjectsClient, + RequestHandlerContext, + KibanaRequest, + KibanaResponseFactory, + IKibanaResponse, +} from 'kibana/server'; import { UMServerLibs } from '../lib/lib'; -export interface UMServerRoute { +/** + * Defines the basic properties employed by Uptime routes. + */ +export interface UMServerRoute { method: string; - handler: RequestHandler; + handler: T; } -export type UMRouteDefinition = UMServerRoute & +/** + * Merges basic uptime route properties with the route config type + * provided by Kibana core. + */ +export type UMRouteDefinition = UMServerRoute & RouteConfig; -export type UMRestApiRouteCreator = (libs: UMServerLibs) => UMRouteDefinition; +/** + * This type represents an Uptime route definition that corresponds to the contract + * provided by the Kibana platform. Route objects must conform to this type in order + * to successfully interact with the Kibana platform. + */ +export type UMKibanaRoute = UMRouteDefinition>; + +/** + * This is an abstraction over the default Kibana route type. This allows us to use custom + * arguments in our route handlers and impelement custom middleware. + */ +export type UptimeRoute = UMRouteDefinition; + +/** + * Functions of this type accept custom lib functions and outputs a route object. + */ +export type UMRestApiRouteFactory = (libs: UMServerLibs) => UptimeRoute; + +/** + * Functions of this type accept our internal route format and output a route + * object that the Kibana platform can consume. + */ +export type UMKibanaRouteWrapper = (uptimeRoute: UptimeRoute) => UMKibanaRoute; + +/** + * This type can store custom parameters used by the internal Uptime route handlers. + */ +export interface UMRouteParams { + callES: ( + endpoint: string, + clientParams?: Record, + options?: CallAPIOptions | undefined + ) => Promise; + savedObjectsClient: Pick< + SavedObjectsClient, + | 'errors' + | 'create' + | 'bulkCreate' + | 'delete' + | 'find' + | 'bulkGet' + | 'get' + | 'update' + | 'bulkUpdate' + >; +} + +/** + * This is the contract we specify internally for route handling. + */ +export type UMRouteHandler = ( + params: UMRouteParams, + context: RequestHandlerContext, + request: KibanaRequest, Record, Record>, + response: KibanaResponseFactory +) => IKibanaResponse | Promise>; diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/uptime_route_wrapper.ts b/x-pack/legacy/plugins/uptime/server/rest_api/uptime_route_wrapper.ts new file mode 100644 index 0000000000000..fb874edebee60 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/server/rest_api/uptime_route_wrapper.ts @@ -0,0 +1,18 @@ +/* + * 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 { UMKibanaRouteWrapper } from './types'; + +export const uptimeRouteWrapper: UMKibanaRouteWrapper = uptimeRoute => { + return { + ...uptimeRoute, + handler: async (context, request, response) => { + const { callAsCurrentUser: callES } = context.core.elasticsearch.dataClient; + const { client: savedObjectsClient } = context.core.savedObjects; + return await uptimeRoute.handler({ callES, savedObjectsClient }, context, request, response); + }, + }; +}; diff --git a/x-pack/legacy/plugins/uptime/server/uptime_server.ts b/x-pack/legacy/plugins/uptime/server/uptime_server.ts index a8058453f2166..4dfa1373db8d9 100644 --- a/x-pack/legacy/plugins/uptime/server/uptime_server.ts +++ b/x-pack/legacy/plugins/uptime/server/uptime_server.ts @@ -7,10 +7,12 @@ import { makeExecutableSchema } from 'graphql-tools'; import { DEFAULT_GRAPHQL_PATH, resolvers, typeDefs } from './graphql'; import { UMServerLibs } from './lib/lib'; -import { createRouteWithAuth, restApiRoutes } from './rest_api'; +import { createRouteWithAuth, restApiRoutes, uptimeRouteWrapper } from './rest_api'; export const initUptimeServer = (libs: UMServerLibs) => { - restApiRoutes.forEach(route => libs.framework.registerRoute(createRouteWithAuth(libs, route))); + restApiRoutes.forEach(route => + libs.framework.registerRoute(uptimeRouteWrapper(createRouteWithAuth(libs, route))) + ); const graphQLSchema = makeExecutableSchema({ resolvers: resolvers.map(createResolversFn => createResolversFn(libs)),