Remove old search code and rename UI Setting
This commit is contained in:
parent
3de838c899
commit
17de9fa257
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { get, memoize, trimEnd } from 'lodash';
|
||||
import { get, memoize } from 'lodash';
|
||||
import { BehaviorSubject, throwError, timer, defer, from, Observable, NEVER } from 'rxjs';
|
||||
import { catchError, finalize } from 'rxjs/operators';
|
||||
import { PublicMethodsOf } from '@kbn/utility-types';
|
||||
|
@ -29,7 +29,6 @@ import {
|
|||
IKibanaSearchResponse,
|
||||
ISearchOptions,
|
||||
ISessionService,
|
||||
ES_SEARCH_STRATEGY,
|
||||
} from '../../common';
|
||||
import { SearchUsageCollector } from './collectors';
|
||||
import {
|
||||
|
@ -71,7 +70,7 @@ export class SearchInterceptor {
|
|||
* @internal
|
||||
*/
|
||||
protected application!: CoreStart['application'];
|
||||
private batchedFetch?: BatchedFunc<
|
||||
private batchedFetch!: BatchedFunc<
|
||||
{ request: IKibanaSearchRequest; strategy?: string },
|
||||
IKibanaSearchResponse
|
||||
>;
|
||||
|
@ -139,20 +138,7 @@ export class SearchInterceptor {
|
|||
signal: AbortSignal,
|
||||
strategy?: string
|
||||
): Promise<IKibanaSearchResponse> {
|
||||
if (this.batchedFetch) {
|
||||
return this.batchedFetch({ request, strategy }, signal);
|
||||
} else {
|
||||
const { id, ...searchRequest } = request;
|
||||
const path = trimEnd(`/internal/search/${strategy || ES_SEARCH_STRATEGY}/${id || ''}`, '/');
|
||||
const body = JSON.stringify(searchRequest);
|
||||
|
||||
return this.deps.http.fetch({
|
||||
method: 'POST',
|
||||
path,
|
||||
body,
|
||||
signal,
|
||||
});
|
||||
}
|
||||
return this.batchedFetch({ request, strategy }, signal);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,119 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import type { MockedKeys } from '@kbn/utility-types/jest';
|
||||
import { from } from 'rxjs';
|
||||
import { CoreSetup, RequestHandlerContext } from 'src/core/server';
|
||||
import { coreMock, httpServerMock } from '../../../../../../src/core/server/mocks';
|
||||
import { registerSearchRoute } from './search';
|
||||
import { DataPluginStart } from '../../plugin';
|
||||
|
||||
describe('Search service', () => {
|
||||
let mockCoreSetup: MockedKeys<CoreSetup<{}, DataPluginStart>>;
|
||||
|
||||
beforeEach(() => {
|
||||
mockCoreSetup = coreMock.createSetup();
|
||||
});
|
||||
|
||||
it('handler calls context.search.search with the given request and strategy', async () => {
|
||||
const response = {
|
||||
id: 'yay',
|
||||
rawResponse: {
|
||||
took: 100,
|
||||
timed_out: true,
|
||||
_shards: {
|
||||
total: 0,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
skipped: 0,
|
||||
},
|
||||
hits: {
|
||||
total: 0,
|
||||
max_score: 0,
|
||||
hits: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const mockContext = {
|
||||
search: {
|
||||
search: jest.fn().mockReturnValue(from(Promise.resolve(response))),
|
||||
},
|
||||
};
|
||||
|
||||
const mockBody = { id: undefined, params: {} };
|
||||
const mockParams = { strategy: 'foo' };
|
||||
const mockRequest = httpServerMock.createKibanaRequest({
|
||||
body: mockBody,
|
||||
params: mockParams,
|
||||
});
|
||||
const mockResponse = httpServerMock.createResponseFactory();
|
||||
|
||||
registerSearchRoute(mockCoreSetup.http.createRouter());
|
||||
|
||||
const mockRouter = mockCoreSetup.http.createRouter.mock.results[0].value;
|
||||
const handler = mockRouter.post.mock.calls[0][1];
|
||||
await handler((mockContext as unknown) as RequestHandlerContext, mockRequest, mockResponse);
|
||||
|
||||
expect(mockContext.search.search).toBeCalled();
|
||||
expect(mockContext.search.search.mock.calls[0][0]).toStrictEqual(mockBody);
|
||||
expect(mockResponse.ok).toBeCalled();
|
||||
expect(mockResponse.ok.mock.calls[0][0]).toEqual({
|
||||
body: response,
|
||||
});
|
||||
});
|
||||
|
||||
it('handler throws an error if the search throws an error', async () => {
|
||||
const rejectedValue = from(
|
||||
Promise.reject({
|
||||
message: 'oh no',
|
||||
body: {
|
||||
error: 'oops',
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
const mockContext = {
|
||||
search: {
|
||||
search: jest.fn().mockReturnValue(rejectedValue),
|
||||
},
|
||||
};
|
||||
|
||||
const mockBody = { id: undefined, params: {} };
|
||||
const mockParams = { strategy: 'foo' };
|
||||
const mockRequest = httpServerMock.createKibanaRequest({
|
||||
body: mockBody,
|
||||
params: mockParams,
|
||||
});
|
||||
const mockResponse = httpServerMock.createResponseFactory();
|
||||
|
||||
registerSearchRoute(mockCoreSetup.http.createRouter());
|
||||
|
||||
const mockRouter = mockCoreSetup.http.createRouter.mock.results[0].value;
|
||||
const handler = mockRouter.post.mock.calls[0][1];
|
||||
await handler((mockContext as unknown) as RequestHandlerContext, mockRequest, mockResponse);
|
||||
|
||||
expect(mockContext.search.search).toBeCalled();
|
||||
expect(mockContext.search.search.mock.calls[0][0]).toStrictEqual(mockBody);
|
||||
expect(mockResponse.customError).toBeCalled();
|
||||
const error: any = mockResponse.customError.mock.calls[0][0];
|
||||
expect(error.body.message).toBe('oh no');
|
||||
expect(error.body.attributes.error).toBe('oops');
|
||||
});
|
||||
});
|
|
@ -17,60 +17,10 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { first } from 'rxjs/operators';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import type { IRouter } from 'src/core/server';
|
||||
import { getRequestAbortedSignal } from '../../lib';
|
||||
|
||||
export function registerSearchRoute(router: IRouter): void {
|
||||
router.post(
|
||||
{
|
||||
path: '/internal/search/{strategy}/{id?}',
|
||||
validate: {
|
||||
params: schema.object({
|
||||
strategy: schema.string(),
|
||||
id: schema.maybe(schema.string()),
|
||||
}),
|
||||
|
||||
query: schema.object({}, { unknowns: 'allow' }),
|
||||
|
||||
body: schema.object({}, { unknowns: 'allow' }),
|
||||
},
|
||||
},
|
||||
async (context, request, res) => {
|
||||
const searchRequest = request.body;
|
||||
const { strategy, id } = request.params;
|
||||
const abortSignal = getRequestAbortedSignal(request.events.aborted$);
|
||||
|
||||
try {
|
||||
const response = await context
|
||||
.search!.search(
|
||||
{ ...searchRequest, id },
|
||||
{
|
||||
abortSignal,
|
||||
strategy,
|
||||
}
|
||||
)
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
|
||||
return res.ok({
|
||||
body: response,
|
||||
});
|
||||
} catch (err) {
|
||||
return res.customError({
|
||||
statusCode: err.statusCode || 500,
|
||||
body: {
|
||||
message: err.message,
|
||||
attributes: {
|
||||
error: err.body?.error || err.message,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
router.delete(
|
||||
{
|
||||
path: '/internal/search/{strategy}/{id}',
|
||||
|
|
|
@ -267,14 +267,13 @@ export function getUiSettings(): Record<string, UiSettingsParams<unknown>> {
|
|||
},
|
||||
[UI_SETTINGS.COURIER_BATCH_SEARCHES]: {
|
||||
name: i18n.translate('data.advancedSettings.courier.batchSearchesTitle', {
|
||||
defaultMessage: 'Batch concurrent searches',
|
||||
defaultMessage: 'Use legacy search',
|
||||
}),
|
||||
value: false,
|
||||
type: 'boolean',
|
||||
description: i18n.translate('data.advancedSettings.courier.batchSearchesText', {
|
||||
defaultMessage: `When disabled, dashboard panels will load individually, and search requests will terminate when users navigate
|
||||
away or update the query. When enabled, dashboard panels will load together when all of the data is loaded, and
|
||||
searches will not terminate.`,
|
||||
defaultMessage: `Kibana uses a new search and batching infrastructure.
|
||||
Enable this option if you prefer to fallback to the legacy synchronous behavior`,
|
||||
}),
|
||||
deprecation: {
|
||||
message: i18n.translate('data.advancedSettings.courier.batchSearchesTextDeprecation', {
|
||||
|
|
Loading…
Reference in a new issue