diff --git a/src/plugins/data/kibana.jsonc b/src/plugins/data/kibana.jsonc index 90658599a87b..2881da532d63 100644 --- a/src/plugins/data/kibana.jsonc +++ b/src/plugins/data/kibana.jsonc @@ -28,7 +28,6 @@ ], "optionalPlugins": [ "usageCollection", - "taskManager", "security" ], "requiredBundles": [ diff --git a/src/plugins/data/server/plugin.ts b/src/plugins/data/server/plugin.ts index 70fa72b1634c..1b2b0c3c78ca 100644 --- a/src/plugins/data/server/plugin.ts +++ b/src/plugins/data/server/plugin.ts @@ -12,10 +12,6 @@ import { BfetchServerSetup } from '@kbn/bfetch-plugin/server'; import { PluginStart as DataViewsServerPluginStart } from '@kbn/data-views-plugin/server'; import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server'; import { FieldFormatsSetup, FieldFormatsStart } from '@kbn/field-formats-plugin/server'; -import type { - TaskManagerSetupContract, - TaskManagerStartContract, -} from '@kbn/task-manager-plugin/server'; import type { SecurityPluginSetup } from '@kbn/security-plugin/server'; import { ConfigSchema } from '../config'; import type { ISearchSetup, ISearchStart } from './search'; @@ -55,7 +51,6 @@ export interface DataPluginSetupDependencies { expressions: ExpressionsServerSetup; usageCollection?: UsageCollectionSetup; fieldFormats: FieldFormatsSetup; - taskManager?: TaskManagerSetupContract; security?: SecurityPluginSetup; } @@ -63,7 +58,6 @@ export interface DataPluginStartDependencies { fieldFormats: FieldFormatsStart; logger: Logger; dataViews: DataViewsServerPluginStart; - taskManager?: TaskManagerStartContract; } export class DataServerPlugin @@ -90,14 +84,7 @@ export class DataServerPlugin public setup( core: CoreSetup, - { - bfetch, - expressions, - usageCollection, - fieldFormats, - taskManager, - security, - }: DataPluginSetupDependencies + { bfetch, expressions, usageCollection, fieldFormats, security }: DataPluginSetupDependencies ) { this.scriptsService.setup(core); const querySetup = this.queryService.setup(core); @@ -110,7 +97,6 @@ export class DataServerPlugin expressions, usageCollection, security, - taskManager, }); return { @@ -120,14 +106,10 @@ export class DataServerPlugin }; } - public start( - core: CoreStart, - { fieldFormats, dataViews, taskManager }: DataPluginStartDependencies - ) { + public start(core: CoreStart, { fieldFormats, dataViews }: DataPluginStartDependencies) { const search = this.searchService.start(core, { fieldFormats, indexPatterns: dataViews, - taskManager, }); const datatableUtilities = new DatatableUtilitiesService( search.aggs, diff --git a/src/plugins/data/server/search/mocks.ts b/src/plugins/data/server/search/mocks.ts index 8630f2be1585..118d43ed14d2 100644 --- a/src/plugins/data/server/search/mocks.ts +++ b/src/plugins/data/server/search/mocks.ts @@ -17,6 +17,7 @@ export function createSearchSetupMock(): jest.Mocked { aggs: searchAggsSetupMock(), registerSearchStrategy: jest.fn(), searchSource: searchSourceMock.createSetupContract(), + enableRollups: jest.fn(), }; } diff --git a/src/plugins/data/server/search/search_service.ts b/src/plugins/data/server/search/search_service.ts index f9d1c79390fb..0387cb820f16 100644 --- a/src/plugins/data/server/search/search_service.ts +++ b/src/plugins/data/server/search/search_service.ts @@ -25,10 +25,6 @@ import { ExpressionsServerSetup } from '@kbn/expressions-plugin/server'; import { FieldFormatsStart } from '@kbn/field-formats-plugin/server'; import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server'; import { KbnServerError } from '@kbn/kibana-utils-plugin/server'; -import type { - TaskManagerSetupContract, - TaskManagerStartContract, -} from '@kbn/task-manager-plugin/server'; import type { SecurityPluginSetup } from '@kbn/security-plugin/server'; import type { DataViewsServerPluginStart } from '@kbn/data-views-plugin/server'; import type { @@ -107,7 +103,6 @@ export interface SearchServiceSetupDependencies { bfetch: BfetchServerSetup; expressions: ExpressionsServerSetup; usageCollection?: UsageCollectionSetup; - taskManager?: TaskManagerSetupContract; security?: SecurityPluginSetup; } @@ -115,7 +110,6 @@ export interface SearchServiceSetupDependencies { export interface SearchServiceStartDependencies { fieldFormats: FieldFormatsStart; indexPatterns: DataViewsServerPluginStart; - taskManager?: TaskManagerStartContract; } /** @internal */ @@ -131,6 +125,7 @@ export class SearchService implements Plugin { private sessionService: SearchSessionService; private asScoped!: ISearchStart['asScoped']; private searchAsInternalUser!: ISearchStrategy; + private rollupsEnabled: boolean = false; constructor( private initializerContext: PluginInitializerContext, @@ -145,7 +140,7 @@ export class SearchService implements Plugin { public setup( core: CoreSetup, - { bfetch, expressions, usageCollection, taskManager, security }: SearchServiceSetupDependencies + { bfetch, expressions, usageCollection, security }: SearchServiceSetupDependencies ): ISearchSetup { core.savedObjects.registerType(searchSessionSavedObjectType); const usage = usageCollection ? usageProvider(core) : undefined; @@ -261,12 +256,13 @@ export class SearchService implements Plugin { registerSearchStrategy: this.registerSearchStrategy, usage, searchSource: this.searchSourceService.setup(), + enableRollups: () => (this.rollupsEnabled = true), }; } public start( core: CoreStart, - { fieldFormats, indexPatterns, taskManager }: SearchServiceStartDependencies + { fieldFormats, indexPatterns }: SearchServiceStartDependencies ): ISearchStart { const { elasticsearch, savedObjects, uiSettings } = core; @@ -278,7 +274,7 @@ export class SearchService implements Plugin { indexPatterns, }); - this.asScoped = this.asScopedProvider(core); + this.asScoped = this.asScopedProvider(core, this.rollupsEnabled); return { aggs, searchAsInternalUser: this.searchAsInternalUser, @@ -516,7 +512,7 @@ export class SearchService implements Plugin { return deps.searchSessionsClient.extend(sessionId, expires); }; - private asScopedProvider = (core: CoreStart) => { + private asScopedProvider = (core: CoreStart, rollupsEnabled: boolean = false) => { const { elasticsearch, savedObjects, uiSettings } = core; const getSessionAsScoped = this.sessionService.asScopedProvider(core); return (request: KibanaRequest): IScopedSearchClient => { @@ -530,6 +526,7 @@ export class SearchService implements Plugin { uiSettings.asScopedToClient(savedObjectsClient) ), request, + rollupsEnabled, }; return { search: < diff --git a/src/plugins/data/server/search/strategies/ese_search/ese_search_strategy.test.ts b/src/plugins/data/server/search/strategies/ese_search/ese_search_strategy.test.ts index 070d07c07c95..627bb5fe2929 100644 --- a/src/plugins/data/server/search/strategies/ese_search/ese_search_strategy.test.ts +++ b/src/plugins/data/server/search/strategies/ese_search/ese_search_strategy.test.ts @@ -64,6 +64,7 @@ describe('ES search strategy', () => { }, }, searchSessionsClient: createSearchSessionsClientMock(), + rollupsEnabled: true, } as unknown as SearchStrategyDependencies; const mockLegacyConfig$ = new BehaviorSubject({ elasticsearch: { @@ -233,6 +234,31 @@ describe('ES search strategy', () => { expect(method).toBe('POST'); expect(path).toBe('/foo-%E7%A8%8B/_rollup_search'); }); + + it("doesn't call the rollup API if the index is a rollup type BUT rollups are disabled", async () => { + mockApiCaller.mockResolvedValueOnce(mockRollupResponse); + mockSubmitCaller.mockResolvedValueOnce(mockAsyncResponse); + + const params = { index: 'foo-程', body: { query: {} } }; + const esSearch = await enhancedEsSearchStrategyProvider( + mockLegacyConfig$, + mockSearchConfig, + mockLogger + ); + + await esSearch + .search( + { + indexType: 'rollup', + params, + }, + {}, + { ...mockDeps, rollupsEnabled: false } + ) + .toPromise(); + + expect(mockApiCaller).toBeCalledTimes(0); + }); }); describe('with sessionId', () => { diff --git a/src/plugins/data/server/search/strategies/ese_search/ese_search_strategy.ts b/src/plugins/data/server/search/strategies/ese_search/ese_search_strategy.ts index e5567b45f1e0..298933907b8b 100644 --- a/src/plugins/data/server/search/strategies/ese_search/ese_search_strategy.ts +++ b/src/plugins/data/server/search/strategies/ese_search/ese_search_strategy.ts @@ -154,7 +154,7 @@ export const enhancedEsSearchStrategyProvider = ( throw new KbnServerError('Unknown indexType', 400); } - if (request.indexType === undefined) { + if (request.indexType === undefined || !deps.rollupsEnabled) { return asyncSearch(request, options, deps); } else { return from(rollupSearch(request, options, deps)); diff --git a/src/plugins/data/server/search/types.ts b/src/plugins/data/server/search/types.ts index 50fc29334d22..8b94085c3f80 100644 --- a/src/plugins/data/server/search/types.ts +++ b/src/plugins/data/server/search/types.ts @@ -35,6 +35,7 @@ export interface SearchStrategyDependencies { uiSettingsClient: Pick; searchSessionsClient: IScopedSearchSessionsClient; request: KibanaRequest; + rollupsEnabled?: boolean; } export interface ISearchSetup { @@ -55,7 +56,7 @@ export interface ISearchSetup { * Used internally for telemetry */ usage?: SearchUsage; - + enableRollups: () => void; searchSource: ReturnType; } diff --git a/src/plugins/data/tsconfig.json b/src/plugins/data/tsconfig.json index 450c85826591..73eb71508a89 100644 --- a/src/plugins/data/tsconfig.json +++ b/src/plugins/data/tsconfig.json @@ -25,7 +25,6 @@ "@kbn/field-formats-plugin", "@kbn/data-views-plugin", "@kbn/screenshot-mode-plugin", - "@kbn/task-manager-plugin", "@kbn/security-plugin", "@kbn/expressions-plugin", "@kbn/field-types", diff --git a/src/plugins/data_views/server/data_views_service_factory.ts b/src/plugins/data_views/server/data_views_service_factory.ts index fb5ae2c5afe3..ac27ad0bc809 100644 --- a/src/plugins/data_views/server/data_views_service_factory.ts +++ b/src/plugins/data_views/server/data_views_service_factory.ts @@ -25,6 +25,7 @@ interface DataViewsServiceFactoryDeps { uiSettings: UiSettingsServiceStart; fieldFormats: FieldFormatsStart; capabilities: CoreStart['capabilities']; + rollupsEnabled: boolean; } /** @@ -38,14 +39,18 @@ export const dataViewsServiceFactory = (deps: DataViewsServiceFactoryDeps) => request?: KibanaRequest, byPassCapabilities?: boolean ) { - const { logger, uiSettings, fieldFormats, capabilities } = deps; + const { logger, uiSettings, fieldFormats, capabilities, rollupsEnabled } = deps; const uiSettingsClient = uiSettings.asScopedToClient(savedObjectsClient); const formats = await fieldFormats.fieldFormatServiceFactory(uiSettingsClient); return new DataViewsService({ uiSettings: new UiSettingsServerToCommon(uiSettingsClient), savedObjectsClient: new SavedObjectsClientWrapper(savedObjectsClient), - apiClient: new IndexPatternsApiServer(elasticsearchClient, savedObjectsClient), + apiClient: new IndexPatternsApiServer( + elasticsearchClient, + savedObjectsClient, + rollupsEnabled + ), fieldFormats: formats, onError: (error) => { logger.error(error); diff --git a/src/plugins/data_views/server/fetcher/index_patterns_fetcher.test.ts b/src/plugins/data_views/server/fetcher/index_patterns_fetcher.test.ts index f6f2d378fef7..6253c68d84fb 100644 --- a/src/plugins/data_views/server/fetcher/index_patterns_fetcher.test.ts +++ b/src/plugins/data_views/server/fetcher/index_patterns_fetcher.test.ts @@ -10,6 +10,19 @@ import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { IndexPatternsFetcher } from '.'; import { elasticsearchServiceMock } from '@kbn/core/server/mocks'; +const rollupResponse = { + foo: { + rollup_jobs: [ + { + index_pattern: 'foo', + job_id: '123', + rollup_index: 'foo', + fields: [], + }, + ], + }, +}; + describe('Index Pattern Fetcher - server', () => { let indexPatterns: IndexPatternsFetcher; let esClient: ReturnType; @@ -21,12 +34,40 @@ describe('Index Pattern Fetcher - server', () => { beforeEach(() => { jest.clearAllMocks(); esClient = elasticsearchServiceMock.createElasticsearchClient(); - indexPatterns = new IndexPatternsFetcher(esClient); + indexPatterns = new IndexPatternsFetcher(esClient, false, true); }); it('calls fieldcaps once', async () => { esClient.fieldCaps.mockResponse(response as unknown as estypes.FieldCapsResponse); - indexPatterns = new IndexPatternsFetcher(esClient, true); + indexPatterns = new IndexPatternsFetcher(esClient, true, true); await indexPatterns.getFieldsForWildcard({ pattern: patternList }); expect(esClient.fieldCaps).toHaveBeenCalledTimes(1); }); + + it('calls rollup api when given rollup data view', async () => { + esClient.fieldCaps.mockResponse(response as unknown as estypes.FieldCapsResponse); + esClient.rollup.getRollupIndexCaps.mockResponse( + rollupResponse as unknown as estypes.RollupGetRollupIndexCapsResponse + ); + indexPatterns = new IndexPatternsFetcher(esClient, true, true); + await indexPatterns.getFieldsForWildcard({ + pattern: patternList, + type: 'rollup', + rollupIndex: 'foo', + }); + expect(esClient.rollup.getRollupIndexCaps).toHaveBeenCalledTimes(1); + }); + + it("doesn't call rollup api when given rollup data view and rollups are disabled", async () => { + esClient.fieldCaps.mockResponse(response as unknown as estypes.FieldCapsResponse); + esClient.rollup.getRollupIndexCaps.mockResponse( + rollupResponse as unknown as estypes.RollupGetRollupIndexCapsResponse + ); + indexPatterns = new IndexPatternsFetcher(esClient, true, false); + await indexPatterns.getFieldsForWildcard({ + pattern: patternList, + type: 'rollup', + rollupIndex: 'foo', + }); + expect(esClient.rollup.getRollupIndexCaps).toHaveBeenCalledTimes(0); + }); }); diff --git a/src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts b/src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts index 3511cefd34d8..b1d22dc5523c 100644 --- a/src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts +++ b/src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts @@ -40,10 +40,16 @@ interface FieldSubType { export class IndexPatternsFetcher { private elasticsearchClient: ElasticsearchClient; private allowNoIndices: boolean; + private rollupsEnabled: boolean; - constructor(elasticsearchClient: ElasticsearchClient, allowNoIndices: boolean = false) { + constructor( + elasticsearchClient: ElasticsearchClient, + allowNoIndices: boolean = false, + rollupsEnabled: boolean = false + ) { this.elasticsearchClient = elasticsearchClient; this.allowNoIndices = allowNoIndices; + this.rollupsEnabled = rollupsEnabled; } /** @@ -81,7 +87,7 @@ export class IndexPatternsFetcher { fields: options.fields || ['*'], }); - if (type === 'rollup' && rollupIndex) { + if (this.rollupsEnabled && type === 'rollup' && rollupIndex) { const rollupFields: FieldDescriptor[] = []; const capabilityCheck = getCapabilitiesForRollupIndices( await this.elasticsearchClient.rollup.getRollupIndexCaps({ diff --git a/src/plugins/data_views/server/index.ts b/src/plugins/data_views/server/index.ts index 553f1a48d1d6..33e93df3be89 100644 --- a/src/plugins/data_views/server/index.ts +++ b/src/plugins/data_views/server/index.ts @@ -10,6 +10,7 @@ export { getFieldByName, findIndexPatternById } from './utils'; export type { FieldDescriptor, RollupIndexCapability } from './fetcher'; export { IndexPatternsFetcher, getCapabilitiesForRollupIndices } from './fetcher'; export type { + DataViewsServerPluginSetup, DataViewsServerPluginStart, DataViewsServerPluginSetupDependencies, DataViewsServerPluginStartDependencies, diff --git a/src/plugins/data_views/server/index_patterns_api_client.ts b/src/plugins/data_views/server/index_patterns_api_client.ts index f470e7f8ed7d..0beb1efacf9b 100644 --- a/src/plugins/data_views/server/index_patterns_api_client.ts +++ b/src/plugins/data_views/server/index_patterns_api_client.ts @@ -16,7 +16,8 @@ export class IndexPatternsApiServer implements IDataViewsApiClient { esClient: ElasticsearchClient; constructor( elasticsearchClient: ElasticsearchClient, - private readonly savedObjectsClient: SavedObjectsClientContract + private readonly savedObjectsClient: SavedObjectsClientContract, + private readonly rollupsEnabled: boolean ) { this.esClient = elasticsearchClient; } @@ -29,7 +30,11 @@ export class IndexPatternsApiServer implements IDataViewsApiClient { indexFilter, fields, }: GetFieldsOptions) { - const indexPatterns = new IndexPatternsFetcher(this.esClient, allowNoIndex); + const indexPatterns = new IndexPatternsFetcher( + this.esClient, + allowNoIndex, + this.rollupsEnabled + ); return await indexPatterns .getFieldsForWildcard({ pattern, diff --git a/src/plugins/data_views/server/plugin.ts b/src/plugins/data_views/server/plugin.ts index fab72338bdb3..c96de2e4294f 100644 --- a/src/plugins/data_views/server/plugin.ts +++ b/src/plugins/data_views/server/plugin.ts @@ -33,6 +33,7 @@ export class DataViewsServerPlugin > { private readonly logger: Logger; + private rollupsEnabled: boolean = false; constructor(initializerContext: PluginInitializerContext) { this.logger = initializerContext.logger.get('dataView'); @@ -46,7 +47,12 @@ export class DataViewsServerPlugin core.capabilities.registerProvider(capabilitiesProvider); const dataViewRestCounter = usageCollection?.createUsageCounter('dataViewsRestApi'); - registerRoutes(core.http, core.getStartServices, dataViewRestCounter); + registerRoutes( + core.http, + core.getStartServices, + () => this.rollupsEnabled, + dataViewRestCounter + ); expressions.registerFunction(getIndexPatternLoad({ getStartServices: core.getStartServices })); registerIndexPatternsUsageCollector(core.getStartServices, usageCollection); @@ -60,7 +66,9 @@ export class DataViewsServerPlugin }, }); - return {}; + return { + enableRollups: () => (this.rollupsEnabled = true), + }; } public start( @@ -72,6 +80,7 @@ export class DataViewsServerPlugin uiSettings, fieldFormats, capabilities, + rollupsEnabled: this.rollupsEnabled, }); return { diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts index 9951bedb8229..15d761935c0a 100644 --- a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts +++ b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts @@ -111,86 +111,93 @@ const validate: FullValidationConfig = { }, }; -const handler: RequestHandler<{}, IQuery, IBody> = async (context, request, response) => { - const { asCurrentUser } = (await context.core).elasticsearch.client; - const indexPatterns = new IndexPatternsFetcher(asCurrentUser); - const { - pattern, - meta_fields: metaFields, - type, - rollup_index: rollupIndex, - allow_no_index: allowNoIndex, - include_unmapped: includeUnmapped, - } = request.query; - - // not available to get request - const indexFilter = request.body?.index_filter; - - let parsedFields: string[] = []; - let parsedMetaFields: string[] = []; - try { - parsedMetaFields = parseFields(metaFields); - parsedFields = parseFields(request.query.fields ?? []); - } catch (error) { - return response.badRequest(); - } - - try { - const { fields, indices } = await indexPatterns.getFieldsForWildcard({ +const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, IBody> = + (isRollupsEnabled) => async (context, request, response) => { + const { asCurrentUser } = (await context.core).elasticsearch.client; + const indexPatterns = new IndexPatternsFetcher(asCurrentUser, undefined, isRollupsEnabled()); + const { pattern, - metaFields: parsedMetaFields, + meta_fields: metaFields, type, - rollupIndex, - fieldCapsOptions: { - allow_no_indices: allowNoIndex || false, - includeUnmapped, - }, - indexFilter, - ...(parsedFields.length > 0 ? { fields: parsedFields } : {}), - }); + rollup_index: rollupIndex, + allow_no_index: allowNoIndex, + include_unmapped: includeUnmapped, + } = request.query; - const body: { fields: FieldDescriptorRestResponse[]; indices: string[] } = { fields, indices }; + // not available to get request + const indexFilter = request.body?.index_filter; - return response.ok({ - body, - headers: { - 'content-type': 'application/json', - }, - }); - } catch (error) { - if ( - typeof error === 'object' && - !!error?.isBoom && - !!error?.output?.payload && - typeof error?.output?.payload === 'object' - ) { - const payload = error?.output?.payload; - return response.notFound({ - body: { - message: payload.message, - attributes: payload, + let parsedFields: string[] = []; + let parsedMetaFields: string[] = []; + try { + parsedMetaFields = parseFields(metaFields); + parsedFields = parseFields(request.query.fields ?? []); + } catch (error) { + return response.badRequest(); + } + + try { + const { fields, indices } = await indexPatterns.getFieldsForWildcard({ + pattern, + metaFields: parsedMetaFields, + type, + rollupIndex, + fieldCapsOptions: { + allow_no_indices: allowNoIndex || false, + includeUnmapped, + }, + indexFilter, + ...(parsedFields.length > 0 ? { fields: parsedFields } : {}), + }); + + const body: { fields: FieldDescriptorRestResponse[]; indices: string[] } = { + fields, + indices, + }; + + return response.ok({ + body, + headers: { + 'content-type': 'application/json', }, }); - } else { - return response.notFound(); + } catch (error) { + if ( + typeof error === 'object' && + !!error?.isBoom && + !!error?.output?.payload && + typeof error?.output?.payload === 'object' + ) { + const payload = error?.output?.payload; + return response.notFound({ + body: { + message: payload.message, + attributes: payload, + }, + }); + } else { + return response.notFound(); + } } - } -}; + }; -export const registerFieldForWildcard = ( +export const registerFieldForWildcard = async ( router: IRouter, getStartServices: StartServicesAccessor< DataViewsServerPluginStartDependencies, DataViewsServerPluginStart - > + >, + isRollupsEnabled: () => boolean ) => { + const configuredHandler = handler(isRollupsEnabled); + // handler - router.versioned.put({ path, access }).addVersion({ version, validate }, handler); - router.versioned.post({ path, access }).addVersion({ version, validate }, handler); + router.versioned.put({ path, access }).addVersion({ version, validate }, configuredHandler); + router.versioned.post({ path, access }).addVersion({ version, validate }, configuredHandler); router.versioned .get({ path, access }) .addVersion( { version, validate: { request: { query: querySchema }, response: validate.response } }, - handler + configuredHandler ); }; diff --git a/src/plugins/data_views/server/routes.ts b/src/plugins/data_views/server/routes.ts index ef0f342ca4fc..9c1da30bc99e 100644 --- a/src/plugins/data_views/server/routes.ts +++ b/src/plugins/data_views/server/routes.ts @@ -20,12 +20,13 @@ export function registerRoutes( DataViewsServerPluginStartDependencies, DataViewsServerPluginStart >, + isRollupsEnabled: () => boolean, dataViewRestCounter?: UsageCounter ) { const router = http.createRouter(); routes.forEach((route) => route(router, getStartServices, dataViewRestCounter)); - registerFieldForWildcard(router, getStartServices); + registerFieldForWildcard(router, getStartServices, isRollupsEnabled); registerHasDataViewsRoute(router); } diff --git a/src/plugins/data_views/server/types.ts b/src/plugins/data_views/server/types.ts index 5b8757332237..d595f6e04b27 100644 --- a/src/plugins/data_views/server/types.ts +++ b/src/plugins/data_views/server/types.ts @@ -53,8 +53,9 @@ export interface DataViewsServerPluginStart { /** * DataViews server plugin setup api */ -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface DataViewsServerPluginSetup {} +export interface DataViewsServerPluginSetup { + enableRollups: () => void; +} /** * Data Views server setup dependencies diff --git a/x-pack/plugins/logs_shared/server/services/log_entries/log_entries_search_strategy.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/log_entries_search_strategy.test.ts index bb21053cfe9d..305f6292deb2 100644 --- a/x-pack/plugins/logs_shared/server/services/log_entries/log_entries_search_strategy.test.ts +++ b/x-pack/plugins/logs_shared/server/services/log_entries/log_entries_search_strategy.test.ts @@ -298,6 +298,7 @@ const createSearchStrategyDependenciesMock = (): SearchStrategyDependencies => ( savedObjectsClient: savedObjectsClientMock.create(), searchSessionsClient: createSearchSessionsClientMock(), request: httpServerMock.createKibanaRequest(), + rollupsEnabled: true, }); // using the official data mock from within x-pack doesn't type-check successfully, diff --git a/x-pack/plugins/rollup/kibana.jsonc b/x-pack/plugins/rollup/kibana.jsonc index 7bb5740ff8b2..73f0e76b16d7 100644 --- a/x-pack/plugins/rollup/kibana.jsonc +++ b/x-pack/plugins/rollup/kibana.jsonc @@ -13,13 +13,14 @@ "requiredPlugins": [ "management", "licensing", - "features" + "features", + "dataViews", + "data" ], "optionalPlugins": [ "home", "indexManagement", - "usageCollection", - "visTypeTimeseries" + "usageCollection" ], "requiredBundles": [ "kibanaUtils", diff --git a/x-pack/plugins/rollup/server/plugin.ts b/x-pack/plugins/rollup/server/plugin.ts index 06416685ab50..409c730385db 100644 --- a/x-pack/plugins/rollup/server/plugin.ts +++ b/x-pack/plugins/rollup/server/plugin.ts @@ -30,8 +30,8 @@ export class RollupPlugin implements Plugin { } public setup( - { http, uiSettings, savedObjects, getStartServices }: CoreSetup, - { features, licensing, indexManagement, visTypeTimeseries, usageCollection }: Dependencies + { http, uiSettings, getStartServices }: CoreSetup, + { features, licensing, indexManagement, usageCollection, dataViews, data }: Dependencies ) { this.license.setup( { @@ -103,6 +103,8 @@ export class RollupPlugin implements Plugin { if (indexManagement && indexManagement.indexDataEnricher) { indexManagement.indexDataEnricher.add(rollupDataEnricher); } + dataViews.enableRollups(); + data.search.enableRollups(); } start() {} diff --git a/x-pack/plugins/rollup/server/types.ts b/x-pack/plugins/rollup/server/types.ts index 177efe0915fc..29d2fe2e9977 100644 --- a/x-pack/plugins/rollup/server/types.ts +++ b/x-pack/plugins/rollup/server/types.ts @@ -12,6 +12,8 @@ import { VisTypeTimeseriesSetup } from '@kbn/vis-type-timeseries-plugin/server'; import { getCapabilitiesForRollupIndices } from '@kbn/data-plugin/server'; import { IndexManagementPluginSetup } from '@kbn/index-management-plugin/server'; import { PluginSetupContract as FeaturesPluginSetup } from '@kbn/features-plugin/server'; +import { DataViewsServerPluginSetup } from '@kbn/data-views-plugin/server'; +import { PluginSetup as DataPluginSetup } from '@kbn/data-plugin/server'; import { LicensingPluginSetup } from '@kbn/licensing-plugin/server'; import { License } from './services'; import { IndexPatternsFetcher } from './shared_imports'; @@ -24,6 +26,8 @@ export interface Dependencies { usageCollection?: UsageCollectionSetup; licensing: LicensingPluginSetup; features: FeaturesPluginSetup; + dataViews: DataViewsServerPluginSetup; + data: DataPluginSetup; } export interface RouteDependencies { diff --git a/x-pack/plugins/rollup/tsconfig.json b/x-pack/plugins/rollup/tsconfig.json index 151c5151a0c1..366b44b2c33b 100644 --- a/x-pack/plugins/rollup/tsconfig.json +++ b/x-pack/plugins/rollup/tsconfig.json @@ -32,6 +32,7 @@ "@kbn/i18n-react", "@kbn/config-schema", "@kbn/shared-ux-router", + "@kbn/data-views-plugin", ], "exclude": [ diff --git a/x-pack/test_serverless/api_integration/test_suites/common/index.ts b/x-pack/test_serverless/api_integration/test_suites/common/index.ts index 7f5c93b0dbaf..de30854beccf 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/index.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/index.ts @@ -12,5 +12,6 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./security_users')); loadTestFile(require.resolve('./spaces')); loadTestFile(require.resolve('./security_response_headers')); + loadTestFile(require.resolve('./rollups')); }); } diff --git a/x-pack/test_serverless/api_integration/test_suites/common/rollups.ts b/x-pack/test_serverless/api_integration/test_suites/common/rollups.ts new file mode 100644 index 000000000000..47dd58f24275 --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/common/rollups.ts @@ -0,0 +1,44 @@ +/* + * 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 expect from 'expect'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; +import { INITIAL_REST_VERSION_INTERNAL } from '@kbn/data-views-plugin/server/constants'; +import { X_ELASTIC_INTERNAL_ORIGIN_REQUEST } from '@kbn/core-http-common/src/constants'; +import { FIELDS_FOR_WILDCARD_PATH as BASE_URI } from '@kbn/data-views-plugin/common/constants'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + const esArchiver = getService('esArchiver'); + + describe('rollup data views - fields for wildcard', function () { + before(async () => { + await esArchiver.load('test/api_integration/fixtures/es_archiver/index_patterns/basic_index'); + }); + + after(async () => { + await esArchiver.unload( + 'test/api_integration/fixtures/es_archiver/index_patterns/basic_index' + ); + }); + it('returns 200 and best effort response despite lack of rollup support', async () => { + const response = await supertest + .get(BASE_URI) + .query({ + pattern: 'basic_index', + type: 'rollup', + rollup_index: 'bar', + }) + .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'true'); + + expect(response.status).toBe(200); + expect(response.body.fields.length).toEqual(5); + }); + }); +} diff --git a/x-pack/test_serverless/tsconfig.json b/x-pack/test_serverless/tsconfig.json index 0b9c8cb7792a..8c431b253798 100644 --- a/x-pack/test_serverless/tsconfig.json +++ b/x-pack/test_serverless/tsconfig.json @@ -44,5 +44,7 @@ "@kbn/fleet-plugin", "@kbn/cases-plugin", "@kbn/test-subj-selector", + "@kbn/core-http-common", + "@kbn/data-views-plugin", ] }