mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[ResponseOps][MaintenanceWindow] Introduce pagination for MW find API (#197172)
Fixes: https://github.com/elastic/kibana/issues/193076 This PR introduce pagination for our MW find API. How to test: Use postman/insomnia/curl. Do not forget to add this header: `x-elastic-internal-origin: Kibana`, because this endpoint in internal. Basically you need to do something like this: ``` GET http://localhost:5601/top/internal/alerting/rules/maintenance_window/_find?page=3&per_page=3 ``` Try different page and per_page combination. Try without them. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
fd615c72e6
commit
6645e74707
24 changed files with 455 additions and 33 deletions
|
@ -5,6 +5,20 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export type { FindMaintenanceWindowsResponse } from './types/latest';
|
||||
export {
|
||||
findMaintenanceWindowsRequestQuerySchema,
|
||||
findMaintenanceWindowsResponseBodySchema,
|
||||
} from './schemas/latest';
|
||||
export type {
|
||||
FindMaintenanceWindowsRequestQuery,
|
||||
FindMaintenanceWindowsResponse,
|
||||
} from './types/latest';
|
||||
|
||||
export type { FindMaintenanceWindowsResponse as FindMaintenanceWindowsResponseV1 } from './types/v1';
|
||||
export {
|
||||
findMaintenanceWindowsRequestQuerySchema as findMaintenanceWindowsRequestQuerySchemaV1,
|
||||
findMaintenanceWindowsResponseBodySchema as findMaintenanceWindowsResponseBodySchemaV1,
|
||||
} from './schemas/v1';
|
||||
export type {
|
||||
FindMaintenanceWindowsRequestQuery as FindMaintenanceWindowsRequestQueryV1,
|
||||
FindMaintenanceWindowsResponse as FindMaintenanceWindowsResponseV1,
|
||||
} from './types/v1';
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export * from './v1';
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { maintenanceWindowResponseSchemaV1 } from '../../../response';
|
||||
|
||||
const MAX_DOCS = 10000;
|
||||
|
||||
export const findMaintenanceWindowsRequestQuerySchema = schema.object(
|
||||
{
|
||||
page: schema.maybe(
|
||||
schema.number({
|
||||
defaultValue: 1,
|
||||
min: 1,
|
||||
max: MAX_DOCS,
|
||||
meta: {
|
||||
description: 'The page number to return.',
|
||||
},
|
||||
})
|
||||
),
|
||||
per_page: schema.maybe(
|
||||
schema.number({
|
||||
defaultValue: 20,
|
||||
min: 0,
|
||||
max: 100,
|
||||
meta: {
|
||||
description: 'The number of maintenance windows to return per page.',
|
||||
},
|
||||
})
|
||||
),
|
||||
},
|
||||
{
|
||||
validate: (params) => {
|
||||
const pageAsNumber = params.page ?? 0;
|
||||
const perPageAsNumber = params.per_page ?? 0;
|
||||
|
||||
if (Math.max(pageAsNumber, pageAsNumber * perPageAsNumber) > MAX_DOCS) {
|
||||
return `The number of documents is too high. Paginating through more than ${MAX_DOCS} documents is not possible.`;
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
export const findMaintenanceWindowsResponseBodySchema = schema.object({
|
||||
page: schema.number(),
|
||||
per_page: schema.number(),
|
||||
total: schema.number(),
|
||||
data: schema.arrayOf(maintenanceWindowResponseSchemaV1),
|
||||
});
|
|
@ -5,4 +5,4 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export type { FindMaintenanceWindowsResponse } from './v1';
|
||||
export * from './v1';
|
||||
|
|
|
@ -5,11 +5,15 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { MaintenanceWindowResponseV1 } from '../../../response';
|
||||
import { TypeOf } from '@kbn/config-schema';
|
||||
import {
|
||||
findMaintenanceWindowsResponseBodySchema,
|
||||
findMaintenanceWindowsRequestQuerySchema,
|
||||
} from '..';
|
||||
|
||||
export interface FindMaintenanceWindowsResponse {
|
||||
body: {
|
||||
data: MaintenanceWindowResponseV1[];
|
||||
total: number;
|
||||
};
|
||||
}
|
||||
export type FindMaintenanceWindowsResponse = TypeOf<
|
||||
typeof findMaintenanceWindowsResponseBodySchema
|
||||
>;
|
||||
export type FindMaintenanceWindowsRequestQuery = TypeOf<
|
||||
typeof findMaintenanceWindowsRequestQuerySchema
|
||||
>;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { maintenanceWindowStatusV1 } from '..';
|
||||
import { maintenanceWindowStatus as maintenanceWindowStatusV1 } from '../constants/v1';
|
||||
import { maintenanceWindowCategoryIdsSchemaV1 } from '../../shared';
|
||||
import { rRuleResponseSchemaV1 } from '../../../r_rule';
|
||||
import { alertsFilterQuerySchemaV1 } from '../../../alerts_filter_query';
|
||||
|
|
|
@ -16,7 +16,7 @@ export async function findMaintenanceWindows({
|
|||
}: {
|
||||
http: HttpSetup;
|
||||
}): Promise<MaintenanceWindow[]> {
|
||||
const res = await http.get<FindMaintenanceWindowsResponse['body']>(
|
||||
const res = await http.get<FindMaintenanceWindowsResponse>(
|
||||
`${INTERNAL_BASE_ALERTING_API_PATH}/rules/maintenance_window/_find`
|
||||
);
|
||||
return res.data.map((mw) => transformMaintenanceWindowResponse(mw));
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE,
|
||||
} from '../../../../../common';
|
||||
import { getMockMaintenanceWindow } from '../../../../data/maintenance_window/test_helpers';
|
||||
import { findMaintenanceWindowsParamsSchema } from './schemas';
|
||||
|
||||
const savedObjectsClient = savedObjectsClientMock.create();
|
||||
const uiSettings = uiSettingsServiceMock.createClient();
|
||||
|
@ -37,8 +38,47 @@ describe('MaintenanceWindowClient - find', () => {
|
|||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('throws an error if page is string', async () => {
|
||||
savedObjectsClient.find.mockResolvedValueOnce({
|
||||
saved_objects: [
|
||||
{
|
||||
attributes: getMockMaintenanceWindow({ expirationDate: new Date().toISOString() }),
|
||||
id: 'test-1',
|
||||
},
|
||||
{
|
||||
attributes: getMockMaintenanceWindow({ expirationDate: new Date().toISOString() }),
|
||||
id: 'test-2',
|
||||
},
|
||||
],
|
||||
page: 1,
|
||||
per_page: 5,
|
||||
} as unknown as SavedObjectsFindResponse);
|
||||
|
||||
await expect(
|
||||
// @ts-expect-error: testing validation of strings
|
||||
findMaintenanceWindows(mockContext, { page: 'dfsd', perPage: 10 })
|
||||
).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||
'"Error validating find maintenance windows data - [page]: expected value of type [number] but got [string]"'
|
||||
);
|
||||
});
|
||||
|
||||
it('throws an error if savedObjectsClient.find will throw an error', async () => {
|
||||
jest.useFakeTimers().setSystemTime(new Date('2023-02-26T00:00:00.000Z'));
|
||||
|
||||
savedObjectsClient.find.mockImplementation(() => {
|
||||
throw new Error('something went wrong!');
|
||||
});
|
||||
|
||||
await expect(
|
||||
findMaintenanceWindows(mockContext, { page: 1, perPage: 10 })
|
||||
).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||
'"Failed to find maintenance window, Error: Error: something went wrong!: something went wrong!"'
|
||||
);
|
||||
});
|
||||
|
||||
it('should find maintenance windows', async () => {
|
||||
jest.useFakeTimers().setSystemTime(new Date('2023-02-26T00:00:00.000Z'));
|
||||
const spy = jest.spyOn(findMaintenanceWindowsParamsSchema, 'validate');
|
||||
|
||||
savedObjectsClient.find.mockResolvedValueOnce({
|
||||
saved_objects: [
|
||||
|
@ -51,10 +91,13 @@ describe('MaintenanceWindowClient - find', () => {
|
|||
id: 'test-2',
|
||||
},
|
||||
],
|
||||
page: 1,
|
||||
per_page: 5,
|
||||
} as unknown as SavedObjectsFindResponse);
|
||||
|
||||
const result = await findMaintenanceWindows(mockContext);
|
||||
const result = await findMaintenanceWindows(mockContext, {});
|
||||
|
||||
expect(spy).toHaveBeenCalledWith({});
|
||||
expect(savedObjectsClient.find).toHaveBeenLastCalledWith({
|
||||
type: MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE,
|
||||
});
|
||||
|
@ -62,5 +105,7 @@ describe('MaintenanceWindowClient - find', () => {
|
|||
expect(result.data.length).toEqual(2);
|
||||
expect(result.data[0].id).toEqual('test-1');
|
||||
expect(result.data[1].id).toEqual('test-2');
|
||||
expect(result.page).toEqual(1);
|
||||
expect(result.perPage).toEqual(5);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,17 +9,35 @@ import Boom from '@hapi/boom';
|
|||
import { MaintenanceWindowClientContext } from '../../../../../common';
|
||||
import { transformMaintenanceWindowAttributesToMaintenanceWindow } from '../../transforms';
|
||||
import { findMaintenanceWindowSo } from '../../../../data/maintenance_window';
|
||||
import type { FindMaintenanceWindowsResult } from './types';
|
||||
import type { FindMaintenanceWindowsResult, FindMaintenanceWindowsParams } from './types';
|
||||
import { findMaintenanceWindowsParamsSchema } from './schemas';
|
||||
|
||||
export async function findMaintenanceWindows(
|
||||
context: MaintenanceWindowClientContext
|
||||
context: MaintenanceWindowClientContext,
|
||||
params?: FindMaintenanceWindowsParams
|
||||
): Promise<FindMaintenanceWindowsResult> {
|
||||
const { savedObjectsClient, logger } = context;
|
||||
|
||||
try {
|
||||
const result = await findMaintenanceWindowSo({ savedObjectsClient });
|
||||
if (params) {
|
||||
findMaintenanceWindowsParamsSchema.validate(params);
|
||||
}
|
||||
} catch (error) {
|
||||
throw Boom.badRequest(`Error validating find maintenance windows data - ${error.message}`);
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await findMaintenanceWindowSo({
|
||||
savedObjectsClient,
|
||||
...(params
|
||||
? { savedObjectsFindOptions: { page: params.page, perPage: params.perPage } }
|
||||
: {}),
|
||||
});
|
||||
|
||||
return {
|
||||
page: result.page,
|
||||
perPage: result.per_page,
|
||||
total: result.total,
|
||||
data: result.saved_objects.map((so) =>
|
||||
transformMaintenanceWindowAttributesToMaintenanceWindow({
|
||||
attributes: so.attributes,
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
|
||||
export const findMaintenanceWindowsParamsSchema = schema.object({
|
||||
perPage: schema.maybe(schema.number()),
|
||||
page: schema.maybe(schema.number()),
|
||||
});
|
|
@ -9,5 +9,8 @@ import { schema } from '@kbn/config-schema';
|
|||
import { maintenanceWindowSchema } from '../../../schemas';
|
||||
|
||||
export const findMaintenanceWindowsResultSchema = schema.object({
|
||||
page: schema.number(),
|
||||
perPage: schema.number(),
|
||||
data: schema.arrayOf(maintenanceWindowSchema),
|
||||
total: schema.number(),
|
||||
});
|
||||
|
|
|
@ -6,3 +6,4 @@
|
|||
*/
|
||||
|
||||
export { findMaintenanceWindowsResultSchema } from './find_maintenance_windows_result_schema';
|
||||
export { findMaintenanceWindowsParamsSchema } from './find_maintenance_window_params_schema';
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { TypeOf } from '@kbn/config-schema';
|
||||
import { findMaintenanceWindowsParamsSchema } from '../schemas';
|
||||
|
||||
export type FindMaintenanceWindowsParams = TypeOf<typeof findMaintenanceWindowsParamsSchema>;
|
|
@ -6,3 +6,4 @@
|
|||
*/
|
||||
|
||||
export type { FindMaintenanceWindowsResult } from './find_maintenance_window_result';
|
||||
export type { FindMaintenanceWindowsParams } from './find_maintenance_window_params';
|
||||
|
|
|
@ -24,7 +24,7 @@ export const findMaintenanceWindowSo = <MaintenanceWindowAggregation = Record<st
|
|||
const { savedObjectsClient, savedObjectsFindOptions } = params;
|
||||
|
||||
return savedObjectsClient.find<MaintenanceWindowAttributes, MaintenanceWindowAggregation>({
|
||||
...savedObjectsFindOptions,
|
||||
...(savedObjectsFindOptions ? savedObjectsFindOptions : {}),
|
||||
type: MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE,
|
||||
});
|
||||
};
|
||||
|
|
|
@ -13,7 +13,10 @@ import type { GetMaintenanceWindowParams } from '../application/maintenance_wind
|
|||
import { updateMaintenanceWindow } from '../application/maintenance_window/methods/update/update_maintenance_window';
|
||||
import type { UpdateMaintenanceWindowParams } from '../application/maintenance_window/methods/update/types';
|
||||
import { findMaintenanceWindows } from '../application/maintenance_window/methods/find/find_maintenance_windows';
|
||||
import type { FindMaintenanceWindowsResult } from '../application/maintenance_window/methods/find/types';
|
||||
import type {
|
||||
FindMaintenanceWindowsResult,
|
||||
FindMaintenanceWindowsParams,
|
||||
} from '../application/maintenance_window/methods/find/types';
|
||||
import { deleteMaintenanceWindow } from '../application/maintenance_window/methods/delete/delete_maintenance_window';
|
||||
import type { DeleteMaintenanceWindowParams } from '../application/maintenance_window/methods/delete/types';
|
||||
import { archiveMaintenanceWindow } from '../application/maintenance_window/methods/archive/archive_maintenance_window';
|
||||
|
@ -75,7 +78,8 @@ export class MaintenanceWindowClient {
|
|||
getMaintenanceWindow(this.context, params);
|
||||
public update = (params: UpdateMaintenanceWindowParams): Promise<MaintenanceWindow> =>
|
||||
updateMaintenanceWindow(this.context, params);
|
||||
public find = (): Promise<FindMaintenanceWindowsResult> => findMaintenanceWindows(this.context);
|
||||
public find = (params?: FindMaintenanceWindowsParams): Promise<FindMaintenanceWindowsResult> =>
|
||||
findMaintenanceWindows(this.context, params);
|
||||
public delete = (params: DeleteMaintenanceWindowParams): Promise<{}> =>
|
||||
deleteMaintenanceWindow(this.context, params);
|
||||
public archive = (params: ArchiveMaintenanceWindowParams): Promise<MaintenanceWindow> =>
|
||||
|
|
|
@ -22,6 +22,9 @@ jest.mock('../../../../lib/license_api_access', () => ({
|
|||
}));
|
||||
|
||||
const mockMaintenanceWindows = {
|
||||
page: 1,
|
||||
perPage: 3,
|
||||
total: 2,
|
||||
data: [
|
||||
{
|
||||
...getMockMaintenanceWindow(),
|
||||
|
@ -67,11 +70,54 @@ describe('findMaintenanceWindowsRoute', () => {
|
|||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(maintenanceWindowClient.find).toHaveBeenCalled();
|
||||
expect(maintenanceWindowClient.find).toHaveBeenCalledWith({});
|
||||
expect(res.ok).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
data: mockMaintenanceWindows.data.map((data) => rewriteMaintenanceWindowRes(data)),
|
||||
total: 2,
|
||||
page: 1,
|
||||
per_page: 3,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('should find the maintenance windows with query', async () => {
|
||||
const licenseState = licenseStateMock.create();
|
||||
const router = httpServiceMock.createRouter();
|
||||
|
||||
findMaintenanceWindowsRoute(router, licenseState);
|
||||
|
||||
maintenanceWindowClient.find.mockResolvedValueOnce(mockMaintenanceWindows);
|
||||
const [config, handler] = router.get.mock.calls[0];
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ maintenanceWindowClient },
|
||||
{
|
||||
query: {
|
||||
page: 1,
|
||||
per_page: 3,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
expect(config.path).toEqual('/internal/alerting/rules/maintenance_window/_find');
|
||||
expect(config.options).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"access": "internal",
|
||||
"tags": Array [
|
||||
"access:read-maintenance-window",
|
||||
],
|
||||
}
|
||||
`);
|
||||
|
||||
await handler(context, req, res);
|
||||
|
||||
expect(maintenanceWindowClient.find).toHaveBeenCalledWith({ page: 1, perPage: 3 });
|
||||
expect(res.ok).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
data: mockMaintenanceWindows.data.map((data) => rewriteMaintenanceWindowRes(data)),
|
||||
total: 2,
|
||||
page: 1,
|
||||
per_page: 3,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
|
@ -15,7 +15,15 @@ import {
|
|||
import { MAINTENANCE_WINDOW_API_PRIVILEGES } from '../../../../../common';
|
||||
import type { FindMaintenanceWindowsResult } from '../../../../application/maintenance_window/methods/find/types';
|
||||
import type { FindMaintenanceWindowsResponseV1 } from '../../../../../common/routes/maintenance_window/apis/find';
|
||||
import { transformMaintenanceWindowToResponseV1 } from '../../transforms';
|
||||
import {
|
||||
findMaintenanceWindowsRequestQuerySchemaV1,
|
||||
findMaintenanceWindowsResponseBodySchemaV1,
|
||||
type FindMaintenanceWindowsRequestQueryV1,
|
||||
} from '../../../../../common/routes/maintenance_window/apis/find';
|
||||
import {
|
||||
transformFindMaintenanceWindowParamsV1,
|
||||
transformFindMaintenanceWindowResponseV1,
|
||||
} from './transforms';
|
||||
|
||||
export const findMaintenanceWindowsRoute = (
|
||||
router: IRouter<AlertingRequestHandlerContext>,
|
||||
|
@ -24,7 +32,23 @@ export const findMaintenanceWindowsRoute = (
|
|||
router.get(
|
||||
{
|
||||
path: `${INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH}/_find`,
|
||||
validate: {},
|
||||
validate: {
|
||||
request: {
|
||||
query: findMaintenanceWindowsRequestQuerySchemaV1,
|
||||
},
|
||||
response: {
|
||||
200: {
|
||||
body: () => findMaintenanceWindowsResponseBodySchemaV1,
|
||||
description: 'Indicates a successful call.',
|
||||
},
|
||||
400: {
|
||||
description: 'Indicates an invalid schema or parameters.',
|
||||
},
|
||||
403: {
|
||||
description: 'Indicates that this call is forbidden.',
|
||||
},
|
||||
},
|
||||
},
|
||||
options: {
|
||||
access: 'internal',
|
||||
tags: [`access:${MAINTENANCE_WINDOW_API_PRIVILEGES.READ_MAINTENANCE_WINDOW}`],
|
||||
|
@ -34,20 +58,17 @@ export const findMaintenanceWindowsRoute = (
|
|||
verifyAccessAndContext(licenseState, async function (context, req, res) {
|
||||
licenseState.ensureLicenseForMaintenanceWindow();
|
||||
|
||||
const query: FindMaintenanceWindowsRequestQueryV1 = req.query || {};
|
||||
const maintenanceWindowClient = (await context.alerting).getMaintenanceWindowClient();
|
||||
|
||||
const result: FindMaintenanceWindowsResult = await maintenanceWindowClient.find();
|
||||
const options = transformFindMaintenanceWindowParamsV1(query);
|
||||
const findResult: FindMaintenanceWindowsResult = await maintenanceWindowClient.find(
|
||||
options
|
||||
);
|
||||
const responseBody: FindMaintenanceWindowsResponseV1 =
|
||||
transformFindMaintenanceWindowResponseV1(findResult);
|
||||
|
||||
const response: FindMaintenanceWindowsResponseV1 = {
|
||||
body: {
|
||||
data: result.data.map((maintenanceWindow) =>
|
||||
transformMaintenanceWindowToResponseV1(maintenanceWindow)
|
||||
),
|
||||
total: result.data.length,
|
||||
},
|
||||
};
|
||||
|
||||
return res.ok(response);
|
||||
return res.ok({ body: responseBody });
|
||||
})
|
||||
)
|
||||
);
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export { transformFindMaintenanceWindowParams } from './transform_find_maintenance_window_params/latest';
|
||||
export { transformFindMaintenanceWindowResponse } from './transform_find_maintenance_window_to_response/latest';
|
||||
|
||||
export { transformFindMaintenanceWindowParams as transformFindMaintenanceWindowParamsV1 } from './transform_find_maintenance_window_params/v1';
|
||||
export { transformFindMaintenanceWindowResponse as transformFindMaintenanceWindowResponseV1 } from './transform_find_maintenance_window_to_response/v1';
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export * from './v1';
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { FindMaintenanceWindowsRequestQuery } from '../../../../../../../common/routes/maintenance_window/apis/find';
|
||||
import { FindMaintenanceWindowsParams } from '../../../../../../application/maintenance_window/methods/find/types';
|
||||
|
||||
export const transformFindMaintenanceWindowParams = (
|
||||
params: FindMaintenanceWindowsRequestQuery
|
||||
): FindMaintenanceWindowsParams => ({
|
||||
...(params.page ? { page: params.page } : {}),
|
||||
...(params.per_page ? { perPage: params.per_page } : {}),
|
||||
});
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export * from './v1';
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { transformMaintenanceWindowToResponseV1 } from '../../../../transforms';
|
||||
import type { FindMaintenanceWindowsResponseV1 } from '../../../../../../../common/routes/maintenance_window/apis/find';
|
||||
import type { MaintenanceWindow } from '../../../../../../application/maintenance_window/types';
|
||||
import type { FindMaintenanceWindowsResult } from '../../../../../../application/maintenance_window/methods/find/types';
|
||||
|
||||
export const transformFindMaintenanceWindowResponse = (
|
||||
result: FindMaintenanceWindowsResult
|
||||
): FindMaintenanceWindowsResponseV1 => {
|
||||
return {
|
||||
page: result.page,
|
||||
per_page: result.perPage,
|
||||
total: result.total,
|
||||
data: result.data.map((maintenanceWindow: MaintenanceWindow) =>
|
||||
transformMaintenanceWindowToResponseV1(maintenanceWindow)
|
||||
),
|
||||
};
|
||||
};
|
|
@ -90,6 +90,118 @@ export default function findMaintenanceWindowTests({ getService }: FtrProviderCo
|
|||
throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`);
|
||||
}
|
||||
});
|
||||
|
||||
it('should handle find maintenance window request with pagination', async () => {
|
||||
const { body: createdMaintenanceWindow1 } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/internal/alerting/rules/maintenance_window`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send(createParams);
|
||||
|
||||
const { body: createdMaintenanceWindow2 } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/internal/alerting/rules/maintenance_window`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({ ...createParams, title: 'test-maintenance-window2' });
|
||||
|
||||
objectRemover.add(
|
||||
space.id,
|
||||
createdMaintenanceWindow1.id,
|
||||
'rules/maintenance_window',
|
||||
'alerting',
|
||||
true
|
||||
);
|
||||
objectRemover.add(
|
||||
space.id,
|
||||
createdMaintenanceWindow2.id,
|
||||
'rules/maintenance_window',
|
||||
'alerting',
|
||||
true
|
||||
);
|
||||
|
||||
const response = await supertestWithoutAuth
|
||||
.get(
|
||||
`${getUrlPrefix(
|
||||
space.id
|
||||
)}/internal/alerting/rules/maintenance_window/_find?page=1&per_page=1`
|
||||
)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.auth(user.username, user.password)
|
||||
.send({});
|
||||
|
||||
switch (scenario.id) {
|
||||
case 'no_kibana_privileges at space1':
|
||||
case 'space_1_all at space2':
|
||||
case 'space_1_all_with_restricted_fixture at space1':
|
||||
case 'space_1_all_alerts_none_actions at space1':
|
||||
expect(response.statusCode).to.eql(403);
|
||||
expect(response.body).to.eql({
|
||||
error: 'Forbidden',
|
||||
message: 'Forbidden',
|
||||
statusCode: 403,
|
||||
});
|
||||
break;
|
||||
case 'global_read at space1':
|
||||
case 'superuser at space1':
|
||||
case 'space_1_all at space1':
|
||||
expect(response.body.total).to.eql(2);
|
||||
expect(response.statusCode).to.eql(200);
|
||||
expect(response.body.data[0].id).to.eql(createdMaintenanceWindow1.id);
|
||||
expect(response.body.data[0].title).to.eql('test-maintenance-window');
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`);
|
||||
}
|
||||
});
|
||||
|
||||
it('throw an error for find maintenance window request with pagination if docs count more 10k', async () => {
|
||||
const { body: createdMaintenanceWindow1 } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/internal/alerting/rules/maintenance_window`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send(createParams);
|
||||
|
||||
objectRemover.add(
|
||||
space.id,
|
||||
createdMaintenanceWindow1.id,
|
||||
'rules/maintenance_window',
|
||||
'alerting',
|
||||
true
|
||||
);
|
||||
|
||||
const response = await supertestWithoutAuth
|
||||
.get(
|
||||
`${getUrlPrefix(
|
||||
space.id
|
||||
)}/internal/alerting/rules/maintenance_window/_find?page=101&per_page=100`
|
||||
)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.auth(user.username, user.password)
|
||||
.send({});
|
||||
|
||||
switch (scenario.id) {
|
||||
case 'no_kibana_privileges at space1':
|
||||
case 'space_1_all at space2':
|
||||
case 'space_1_all_with_restricted_fixture at space1':
|
||||
case 'space_1_all_alerts_none_actions at space1':
|
||||
expect(response.statusCode).to.eql(403);
|
||||
expect(response.body).to.eql({
|
||||
error: 'Forbidden',
|
||||
message: 'Forbidden',
|
||||
statusCode: 403,
|
||||
});
|
||||
break;
|
||||
case 'global_read at space1':
|
||||
case 'superuser at space1':
|
||||
case 'space_1_all at space1':
|
||||
expect(response.body).to.eql({
|
||||
statusCode: 400,
|
||||
error: 'Bad Request',
|
||||
message:
|
||||
'[request query]: The number of documents is too high. Paginating through more than 10000 documents is not possible.',
|
||||
});
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue