Skip to content

Commit

Permalink
Better type safety for alert list API
Browse files Browse the repository at this point in the history
  • Loading branch information
madirey committed Feb 6, 2020
1 parent c4b7147 commit d513a43
Show file tree
Hide file tree
Showing 10 changed files with 47 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { AlertListData } from './types';
import { AlertListData } from '../../types';

interface ServerReturnedAlertsData {
type: 'serverReturnedAlertsData';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@

export { alertListReducer } from './reducer';
export { AlertAction } from './action';
export * from './types';
export * from '../../types';
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import { Reducer } from 'redux';
import { AlertListState } from './types';
import { AlertListState } from '../../types';
import { AppAction } from '../action';

const initialState = (): AlertListState => {
Expand All @@ -25,7 +25,7 @@ export const alertListReducer: Reducer<AlertListState, AppAction> = (
if (action.type === 'serverReturnedAlertsData') {
return {
...state,
...action.payload,
alerts: action.payload.alerts,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { AlertListState } from './types';
import { AlertListState } from '../../types';

export const alertListData = (state: AlertListState) => state.alerts;

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

import { Dispatch, MiddlewareAPI } from 'redux';
import { CoreStart } from 'kibana/public';
import { AlertListState } from './store/alerts';
import { EndpointListState } from './store/endpoint_list';
import { AppAction } from './store/action';
import { AlertResultList } from '../../../common/types';

export type MiddlewareFactory = (
coreStart: CoreStart
Expand All @@ -20,3 +20,6 @@ export interface GlobalState {
readonly endpointList: EndpointListState;
readonly alertList: AlertListState;
}

export type AlertListData = AlertResultList;
export type AlertListState = AlertResultList;
22 changes: 10 additions & 12 deletions x-pack/plugins/endpoint/server/routes/alerts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { IRouter } from 'kibana/server';
import { RequestHandler } from 'kibana/server';
import { IRouter, KibanaRequest, RequestHandler } from 'kibana/server';
import { SearchResponse } from 'elasticsearch';
import { schema, TypeOf } from '@kbn/config-schema';
import { schema } from '@kbn/config-schema';

import {
getPagingProperties,
kibanaRequestToAlertListQuery,
buildAlertListESQuery,
} from '../services/endpoint/alert_query_builders';

import { AlertData, AlertResultList } from '../../common/types';
import { EndpointAppContext } from '../types';
import { AlertRequestParams, EndpointAppContext } from '../types';

const ALERTS_ROUTE = '/api/endpoint/alerts';

Expand All @@ -25,14 +24,13 @@ export const reqSchema = schema.object({
});

export function registerAlertRoutes(router: IRouter, endpointAppContext: EndpointAppContext) {
const alertsHandler: RequestHandler<unknown, TypeOf<typeof reqSchema>> = async (
ctx,
req,
res
) => {
const alertsHandler: RequestHandler<unknown, AlertRequestParams> = async (ctx, req, res) => {
try {
const queryParams = await getPagingProperties(req, endpointAppContext);
const reqBody = await kibanaRequestToAlertListQuery(queryParams, endpointAppContext);
const queryParams = await getPagingProperties(
req as KibanaRequest<unknown, AlertRequestParams, AlertRequestParams, any>,
endpointAppContext
);
const reqBody = await buildAlertListESQuery(queryParams);
const response = (await ctx.core.elasticsearch.dataClient.callAsCurrentUser(
'search',
reqBody
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,18 @@
*/
import { httpServerMock, loggingServiceMock } from 'src/core/server/mocks';
import { EndpointConfigSchema } from '../../config';
import { getPagingProperties, kibanaRequestToAlertListQuery } from './alert_query_builders';
import { getPagingProperties, buildAlertListESQuery } from './alert_query_builders';

describe('test query builder', () => {
describe('test query builder request processing', () => {
it('should execute the correct Elasticsearch query for a default request', async () => {
const mockRequest = httpServerMock.createKibanaRequest({
body: {},
});
const mockRequest = httpServerMock.createKibanaRequest({});
const mockCtx = {
logFactory: loggingServiceMock.create(),
config: () => Promise.resolve(EndpointConfigSchema.validate({})),
};
const queryParams = await getPagingProperties(mockRequest, mockCtx);
const query = await kibanaRequestToAlertListQuery(queryParams, mockCtx);
const query = await buildAlertListESQuery(queryParams);

expect(query).toEqual({
body: {
Expand Down Expand Up @@ -51,7 +49,7 @@ describe('test query builder', () => {
config: () => Promise.resolve(EndpointConfigSchema.validate({})),
};
const queryParams = await getPagingProperties(mockRequest, mockCtx);
const query = await kibanaRequestToAlertListQuery(queryParams, mockCtx);
const query = await buildAlertListESQuery(queryParams);

expect(query).toEqual({
body: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
*/
import { KibanaRequest } from 'kibana/server';
import { EndpointAppConstants } from '../../../common/types';
import { EndpointAppContext } from '../../types';
import { EndpointAppContext, AlertRequestParams, JSONish } from '../../types';

export const kibanaRequestToAlertListQuery = async (
pagingProperties: Record<string, any>,
endpointAppContext: EndpointAppContext
): Promise<Record<string, any>> => {
export const buildAlertListESQuery = async (
pagingProperties: Record<string, number>
): Promise<JSONish> => {
const DEFAULT_TOTAL_HITS = 10000;

// Calculate minimum total hits set to indicate there's a next page
Expand Down Expand Up @@ -40,9 +39,9 @@ export const kibanaRequestToAlertListQuery = async (
};

export const getPagingProperties = async (
request: KibanaRequest<any, any, any>,
request: KibanaRequest<unknown, AlertRequestParams, AlertRequestParams>,
endpointAppContext: EndpointAppContext
): Promise<Record<string, any>> => {
): Promise<Record<string, number>> => {
const config = await endpointAppContext.config();
const pagingProperties: { page_size?: number; page_index?: number } = {};

Expand Down
18 changes: 18 additions & 0 deletions x-pack/plugins/endpoint/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,25 @@
import { LoggerFactory } from 'kibana/server';
import { EndpointConfigType } from './config';

/**
* A JSON-like structure.
*/
export interface JSONish {
[key: string]: number | string | null | undefined | JSONish | JSONish[];
}

/**
* The context for Endpoint apps.
*/
export interface EndpointAppContext {
logFactory: LoggerFactory;
config(): Promise<EndpointConfigType>;
}

/**
* Request params for alert queries.
*/
export interface AlertRequestParams {
page_index?: number;
page_size?: number;
}

0 comments on commit d513a43

Please sign in to comment.