Skip to content

Commit

Permalink
[Uptime] Migrate Uptime server routing to new platform (#51125)
Browse files Browse the repository at this point in the history
* Move a REST endpoint and the GQL endpoint to NP routing.

* Delete obsolete REST endpoint.

* Update remaining REST routes to work with NP router.

* Remove obsolete code, update some unit tests.

* Simplify route creation.

* Remove tests of API decommissioned API endpoint.

* Rename domain check.

* Make return shape of index pattern endpoint correspond to required NP resp body.

* Move validate to appropriate level of route definition object for monitor details endpoint.

* Update snapshot count route.

* Fix broken lint rule.

* Remove usages of Boom.

* Fix license router creation.
  • Loading branch information
justinkambic committed Dec 5, 2019
1 parent 14a9f6c commit dcb7439
Show file tree
Hide file tree
Showing 29 changed files with 278 additions and 436 deletions.
2 changes: 1 addition & 1 deletion x-pack/legacy/plugins/uptime/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,26 @@
* 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 } from 'src/core/server';
import { SavedObjectsLegacyService, RequestHandler, IRouter } from 'src/core/server';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';

export interface UMFrameworkRequest {
user: string;
headers: Record<string, any>;
payload: Record<string, any>;
params: Record<string, any>;
query: Record<string, any>;
}

export type UMFrameworkResponse = Lifecycle.ReturnValue;
import { ObjectType } from '@kbn/config-schema';
import { UMRouteDefinition } from '../../../rest_api';

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<P, Q, B>;
config?: any;
validate: any;
}

export interface UptimeCoreSetup {
route: any;
route: IRouter;
}

export interface UptimeCorePlugins {
Expand All @@ -42,24 +33,8 @@ export interface UptimeCorePlugins {
xpack: any;
}

export type UMFrameworkRouteHandler<RouteRequest extends UMFrameworkRequest> = (
request: UMFrameworkRequest,
h: ResponseToolkit
) => void;

export type HapiOptionsFunction = (req: Request) => GraphQLOptions | Promise<GraphQLOptions>;

export interface UMHapiGraphQLPluginOptions {
path: string;
vhost?: string;
route?: RouteOptions;
graphQLOptions: GraphQLOptions | HapiOptionsFunction;
}

export interface UMBackendFrameworkAdapter {
registerRoute<RouteRequest extends UMFrameworkRequest, RouteResponse extends UMFrameworkResponse>(
route: UMFrameworkRouteOptions<RouteRequest, RouteResponse>
): void;
registerRoute(route: UMRouteDefinition): void;
registerGraphQLEndpoint(routePath: string, schema: GraphQLSchema): void;
getSavedObjectsClient(): any;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,11 @@
*/

import { GraphQLSchema } from 'graphql';
import { Request, ResponseToolkit } from 'hapi';
import { schema as kbnSchema } from '@kbn/config-schema';
import { runHttpQuery } from 'apollo-server-core';
import { UptimeCorePlugins, UptimeCoreSetup } from './adapter_types';
import {
UMBackendFrameworkAdapter,
UMFrameworkRequest,
UMFrameworkResponse,
UMFrameworkRouteOptions,
} from './adapter_types';
import { DEFAULT_GRAPHQL_PATH } from '../../../graphql';
import { UMBackendFrameworkAdapter } from './adapter_types';
import { UMRouteDefinition } from '../../../rest_api';

export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapter {
constructor(
Expand All @@ -25,11 +20,22 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte
this.plugins = plugins;
}

public registerRoute<
RouteRequest extends UMFrameworkRequest,
RouteResponse extends UMFrameworkResponse
>(route: UMFrameworkRouteOptions<RouteRequest, RouteResponse>) {
this.server.route(route);
public registerRoute({ handler, method, options, path, validate }: UMRouteDefinition) {
const routeDefinition = {
path,
validate,
options,
};
switch (method) {
case 'GET':
this.server.route.get(routeDefinition, handler);
break;
case 'POST':
this.server.route.post(routeDefinition, handler);
break;
default:
throw new Error(`Handler for method ${method} is not defined`);
}
}

public registerGraphQLEndpoint(routePath: string, schema: GraphQLSchema): void {
Expand All @@ -43,37 +49,47 @@ 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.nullable(kbnSchema.string()),
query: kbnSchema.string(),
variables: kbnSchema.recordOf(kbnSchema.string(), kbnSchema.any()),
}),
},
options: {
tags: ['access:uptime'],
},
},
async (context, request, resp): Promise<any> => {
try {
const { method } = request;
const query =
method === 'post'
? (request.payload as Record<string, any>)
: (request.query as Record<string, any>);
const query = request.body as Record<string, any>;

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() {
Expand Down
1 change: 0 additions & 1 deletion x-pack/legacy/plugins/uptime/server/lib/adapters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
9 changes: 3 additions & 6 deletions x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,23 @@
* 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 { 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 { 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,
license: licenseCheck,
monitors: new ElasticsearchMonitorsAdapter(database),
monitorStates: new ElasticsearchMonitorStatesAdapter(database),
pings: new ElasticsearchPingsAdapter(database),
Expand Down

This file was deleted.

Loading

0 comments on commit dcb7439

Please sign in to comment.