Revert "Index patterns api - load field list on server (#81218)"

This reverts commit e683ece777.
This commit is contained in:
spalger 2020-11-04 09:52:15 -07:00
parent c1b7830470
commit af73961646
49 changed files with 386 additions and 484 deletions

View file

@ -9,5 +9,5 @@ Get field list by providing an index patttern (or spec)
<b>Signature:</b>
```typescript
getFieldsForIndexPattern: (indexPattern: IndexPattern | IndexPatternSpec, options?: GetFieldsOptions | undefined) => Promise<any>;
getFieldsForIndexPattern: (indexPattern: IndexPattern | IndexPatternSpec, options?: GetFieldsOptions) => Promise<any>;
```

View file

@ -9,5 +9,5 @@ Get field list by providing { pattern }
<b>Signature:</b>
```typescript
getFieldsForWildcard: (options: GetFieldsOptions) => Promise<any>;
getFieldsForWildcard: (options?: GetFieldsOptions) => Promise<any>;
```

View file

@ -26,8 +26,8 @@ export declare class IndexPatternsService
| [get](./kibana-plugin-plugins-data-public.indexpatternsservice.get.md) | | <code>(id: string) =&gt; Promise&lt;IndexPattern&gt;</code> | Get an index pattern by id. Cache optimized |
| [getCache](./kibana-plugin-plugins-data-public.indexpatternsservice.getcache.md) | | <code>() =&gt; Promise&lt;SavedObject&lt;IndexPatternSavedObjectAttrs&gt;[] &#124; null &#124; undefined&gt;</code> | |
| [getDefault](./kibana-plugin-plugins-data-public.indexpatternsservice.getdefault.md) | | <code>() =&gt; Promise&lt;IndexPattern &#124; null&gt;</code> | Get default index pattern |
| [getFieldsForIndexPattern](./kibana-plugin-plugins-data-public.indexpatternsservice.getfieldsforindexpattern.md) | | <code>(indexPattern: IndexPattern &#124; IndexPatternSpec, options?: GetFieldsOptions &#124; undefined) =&gt; Promise&lt;any&gt;</code> | Get field list by providing an index patttern (or spec) |
| [getFieldsForWildcard](./kibana-plugin-plugins-data-public.indexpatternsservice.getfieldsforwildcard.md) | | <code>(options: GetFieldsOptions) =&gt; Promise&lt;any&gt;</code> | Get field list by providing { pattern } |
| [getFieldsForIndexPattern](./kibana-plugin-plugins-data-public.indexpatternsservice.getfieldsforindexpattern.md) | | <code>(indexPattern: IndexPattern &#124; IndexPatternSpec, options?: GetFieldsOptions) =&gt; Promise&lt;any&gt;</code> | Get field list by providing an index patttern (or spec) |
| [getFieldsForWildcard](./kibana-plugin-plugins-data-public.indexpatternsservice.getfieldsforwildcard.md) | | <code>(options?: GetFieldsOptions) =&gt; Promise&lt;any&gt;</code> | Get field list by providing { pattern } |
| [getIds](./kibana-plugin-plugins-data-public.indexpatternsservice.getids.md) | | <code>(refresh?: boolean) =&gt; Promise&lt;string[]&gt;</code> | Get list of index pattern ids |
| [getIdsWithTitle](./kibana-plugin-plugins-data-public.indexpatternsservice.getidswithtitle.md) | | <code>(refresh?: boolean) =&gt; Promise&lt;Array&lt;{</code><br/><code> id: string;</code><br/><code> title: string;</code><br/><code> }&gt;&gt;</code> | Get list of index pattern ids with titles |
| [getTitles](./kibana-plugin-plugins-data-public.indexpatternsservice.gettitles.md) | | <code>(refresh?: boolean) =&gt; Promise&lt;string[]&gt;</code> | Get list of index pattern titles |

View file

@ -1,28 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) &gt; [getCapabilitiesForRollupIndices](./kibana-plugin-plugins-data-server.getcapabilitiesforrollupindices.md)
## getCapabilitiesForRollupIndices() function
<b>Signature:</b>
```typescript
export declare function getCapabilitiesForRollupIndices(indices: {
[key: string]: any;
}): {
[key: string]: any;
};
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| indices | <code>{</code><br/><code> [key: string]: any;</code><br/><code>}</code> | |
<b>Returns:</b>
`{
[key: string]: any;
}`

View file

@ -15,8 +15,6 @@ getFieldsForWildcard(options: {
fieldCapsOptions?: {
allow_no_indices: boolean;
};
type?: string;
rollupIndex?: string;
}): Promise<FieldDescriptor[]>;
```
@ -24,7 +22,7 @@ getFieldsForWildcard(options: {
| Parameter | Type | Description |
| --- | --- | --- |
| options | <code>{</code><br/><code> pattern: string &#124; string[];</code><br/><code> metaFields?: string[];</code><br/><code> fieldCapsOptions?: {</code><br/><code> allow_no_indices: boolean;</code><br/><code> };</code><br/><code> type?: string;</code><br/><code> rollupIndex?: string;</code><br/><code> }</code> | |
| options | <code>{</code><br/><code> pattern: string &#124; string[];</code><br/><code> metaFields?: string[];</code><br/><code> fieldCapsOptions?: {</code><br/><code> allow_no_indices: boolean;</code><br/><code> };</code><br/><code> }</code> | |
<b>Returns:</b>

View file

@ -8,7 +8,7 @@
```typescript
start(core: CoreStart, { fieldFormats, logger }: IndexPatternsServiceStartDeps): {
indexPatternsServiceFactory: (savedObjectsClient: SavedObjectsClientContract, elasticsearchClient: ElasticsearchClient) => Promise<IndexPatternsCommonService>;
indexPatternsServiceFactory: (savedObjectsClient: SavedObjectsClientContract) => Promise<IndexPatternsCommonService>;
};
```
@ -22,6 +22,6 @@ start(core: CoreStart, { fieldFormats, logger }: IndexPatternsServiceStartDeps):
<b>Returns:</b>
`{
indexPatternsServiceFactory: (savedObjectsClient: SavedObjectsClientContract, elasticsearchClient: ElasticsearchClient) => Promise<IndexPatternsCommonService>;
indexPatternsServiceFactory: (savedObjectsClient: SavedObjectsClientContract) => Promise<IndexPatternsCommonService>;
}`

View file

@ -28,7 +28,6 @@
| Function | Description |
| --- | --- |
| [getCapabilitiesForRollupIndices(indices)](./kibana-plugin-plugins-data-server.getcapabilitiesforrollupindices.md) | |
| [getDefaultSearchParams(uiSettingsClient)](./kibana-plugin-plugins-data-server.getdefaultsearchparams.md) | |
| [getShardTimeout(config)](./kibana-plugin-plugins-data-server.getshardtimeout.md) | |
| [getTime(indexPattern, timeRange, options)](./kibana-plugin-plugins-data-server.gettime.md) | |
@ -77,7 +76,6 @@
| [esQuery](./kibana-plugin-plugins-data-server.esquery.md) | |
| [fieldFormats](./kibana-plugin-plugins-data-server.fieldformats.md) | |
| [indexPatterns](./kibana-plugin-plugins-data-server.indexpatterns.md) | |
| [mergeCapabilitiesWithFields](./kibana-plugin-plugins-data-server.mergecapabilitieswithfields.md) | |
| [search](./kibana-plugin-plugins-data-server.search.md) | |
| [UI\_SETTINGS](./kibana-plugin-plugins-data-server.ui_settings.md) | |

View file

@ -1,15 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) &gt; [mergeCapabilitiesWithFields](./kibana-plugin-plugins-data-server.mergecapabilitieswithfields.md)
## mergeCapabilitiesWithFields variable
<b>Signature:</b>
```typescript
mergeCapabilitiesWithFields: (rollupIndexCapabilities: {
[key: string]: any;
}, fieldsFromFieldCapsApi: {
[key: string]: any;
}, previousFields?: FieldDescriptor[]) => FieldDescriptor[]
```

View file

@ -12,7 +12,7 @@ start(core: CoreStart): {
fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise<import("../common").FieldFormatsRegistry>;
};
indexPatterns: {
indexPatternsServiceFactory: (savedObjectsClient: Pick<import("../../../core/server").SavedObjectsClient, "update" | "find" | "get" | "delete" | "errors" | "create" | "bulkCreate" | "checkConflicts" | "bulkGet" | "addToNamespaces" | "deleteFromNamespaces" | "bulkUpdate" | "removeReferencesTo">, elasticsearchClient: import("../../../core/server").ElasticsearchClient) => Promise<import("../public").IndexPatternsService>;
indexPatternsServiceFactory: (savedObjectsClient: Pick<import("../../../core/server").SavedObjectsClient, "update" | "find" | "get" | "delete" | "errors" | "create" | "bulkCreate" | "checkConflicts" | "bulkGet" | "addToNamespaces" | "deleteFromNamespaces" | "bulkUpdate" | "removeReferencesTo">) => Promise<import("../public").IndexPatternsService>;
};
search: ISearchStart<import("./search").IEsSearchRequest, import("./search").IEsSearchResponse<any>>;
};
@ -31,7 +31,7 @@ start(core: CoreStart): {
fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise<import("../common").FieldFormatsRegistry>;
};
indexPatterns: {
indexPatternsServiceFactory: (savedObjectsClient: Pick<import("../../../core/server").SavedObjectsClient, "update" | "find" | "get" | "delete" | "errors" | "create" | "bulkCreate" | "checkConflicts" | "bulkGet" | "addToNamespaces" | "deleteFromNamespaces" | "bulkUpdate" | "removeReferencesTo">, elasticsearchClient: import("../../../core/server").ElasticsearchClient) => Promise<import("../public").IndexPatternsService>;
indexPatternsServiceFactory: (savedObjectsClient: Pick<import("../../../core/server").SavedObjectsClient, "update" | "find" | "get" | "delete" | "errors" | "create" | "bulkCreate" | "checkConflicts" | "bulkGet" | "addToNamespaces" | "deleteFromNamespaces" | "bulkUpdate" | "removeReferencesTo">) => Promise<import("../public").IndexPatternsService>;
};
search: ISearchStart<import("./search").IEsSearchRequest, import("./search").IEsSearchResponse<any>>;
}`

View file

@ -215,13 +215,13 @@ export class IndexPatternsService {
* Get field list by providing { pattern }
* @param options
*/
getFieldsForWildcard = async (options: GetFieldsOptions) => {
getFieldsForWildcard = async (options: GetFieldsOptions = {}) => {
const metaFields = await this.config.get(UI_SETTINGS.META_FIELDS);
return this.apiClient.getFieldsForWildcard({
pattern: options.pattern,
metaFields,
type: options.type,
rollupIndex: options.rollupIndex,
params: options.params || {},
});
};
@ -231,13 +231,13 @@ export class IndexPatternsService {
*/
getFieldsForIndexPattern = async (
indexPattern: IndexPattern | IndexPatternSpec,
options?: GetFieldsOptions
options: GetFieldsOptions = {}
) =>
this.getFieldsForWildcard({
type: indexPattern.type,
rollupIndex: indexPattern?.typeMeta?.params?.rollup_index,
...options,
pattern: indexPattern.title as string,
...options,
type: indexPattern.type,
params: indexPattern.typeMeta && indexPattern.typeMeta.params,
});
/**
@ -374,10 +374,10 @@ export class IndexPatternsService {
try {
spec.fields = isFieldRefreshRequired
? await this.refreshFieldSpecMap(spec.fields || {}, id, spec.title as string, {
pattern: title as string,
pattern: title,
metaFields: await this.config.get(UI_SETTINGS.META_FIELDS),
type,
rollupIndex: typeMeta?.params?.rollupIndex,
params: typeMeta && typeMeta.params,
})
: spec.fields;
} catch (err) {

View file

@ -86,22 +86,15 @@ export interface SavedObjectsClientCommon {
}
export interface GetFieldsOptions {
pattern: string;
pattern?: string;
type?: string;
params?: any;
lookBack?: boolean;
metaFields?: string[];
rollupIndex?: string;
}
export interface GetFieldsOptionsTimePattern {
pattern: string;
metaFields: string[];
lookBack: number;
interval: string;
}
export interface IIndexPatternsApiClient {
getFieldsForTimePattern: (options: GetFieldsOptionsTimePattern) => Promise<any>;
getFieldsForTimePattern: (options: GetFieldsOptions) => Promise<any>;
getFieldsForWildcard: (options: GetFieldsOptions) => Promise<any>;
}

View file

@ -32,12 +32,7 @@ describe('IndexPatternsApiClient', () => {
test('uses the right URI to fetch fields for time patterns', async function () {
const expectedPath = '/api/index_patterns/_fields_for_time_pattern';
await indexPatternsApiClient.getFieldsForTimePattern({
pattern: 'blah',
metaFields: [],
lookBack: 5,
interval: '',
});
await indexPatternsApiClient.getFieldsForTimePattern();
expect(fetchSpy).toHaveBeenCalledWith(expectedPath, expect.any(Object));
});
@ -45,7 +40,15 @@ describe('IndexPatternsApiClient', () => {
test('uses the right URI to fetch fields for wildcard', async function () {
const expectedPath = '/api/index_patterns/_fields_for_wildcard';
await indexPatternsApiClient.getFieldsForWildcard({ pattern: 'blah' });
await indexPatternsApiClient.getFieldsForWildcard();
expect(fetchSpy).toHaveBeenCalledWith(expectedPath, expect.any(Object));
});
test('uses the right URI to fetch fields for wildcard given a type', async function () {
const expectedPath = '/api/index_patterns/rollup/_fields_for_wildcard';
await indexPatternsApiClient.getFieldsForWildcard({ type: 'rollup' });
expect(fetchSpy).toHaveBeenCalledWith(expectedPath, expect.any(Object));
});

View file

@ -19,11 +19,7 @@
import { HttpSetup } from 'src/core/public';
import { IndexPatternMissingIndices } from '../../../common/index_patterns/lib';
import {
GetFieldsOptions,
IIndexPatternsApiClient,
GetFieldsOptionsTimePattern,
} from '../../../common/index_patterns/types';
import { GetFieldsOptions, IIndexPatternsApiClient } from '../../../common/index_patterns/types';
const API_BASE_URL: string = `/api/index_patterns/`;
@ -52,7 +48,7 @@ export class IndexPatternsApiClient implements IIndexPatternsApiClient {
return API_BASE_URL + path.filter(Boolean).map(encodeURIComponent).join('/');
}
getFieldsForTimePattern(options: GetFieldsOptionsTimePattern) {
getFieldsForTimePattern(options: GetFieldsOptions = {}) {
const { pattern, lookBack, metaFields } = options;
const url = this._getUrl(['_fields_for_time_pattern']);
@ -64,12 +60,27 @@ export class IndexPatternsApiClient implements IIndexPatternsApiClient {
}).then((resp: any) => resp.fields);
}
getFieldsForWildcard({ pattern, metaFields, type, rollupIndex }: GetFieldsOptions) {
return this._request(this._getUrl(['_fields_for_wildcard']), {
pattern,
meta_fields: metaFields,
type,
rollup_index: rollupIndex,
}).then((resp: any) => resp.fields);
getFieldsForWildcard(options: GetFieldsOptions = {}) {
const { pattern, metaFields, type, params } = options;
let url;
let query;
if (type) {
url = this._getUrl([type, '_fields_for_wildcard']);
query = {
pattern,
meta_fields: metaFields,
params: JSON.stringify(params),
};
} else {
url = this._getUrl(['_fields_for_wildcard']);
query = {
pattern,
meta_fields: metaFields,
};
}
return this._request(url, query).then((resp: any) => resp.fields);
}
}

View file

@ -1339,9 +1339,9 @@ export class IndexPatternsService {
// (undocumented)
getCache: () => Promise<SavedObject<IndexPatternSavedObjectAttrs>[] | null | undefined>;
getDefault: () => Promise<IndexPattern | null>;
getFieldsForIndexPattern: (indexPattern: IndexPattern | IndexPatternSpec, options?: GetFieldsOptions | undefined) => Promise<any>;
getFieldsForIndexPattern: (indexPattern: IndexPattern | IndexPatternSpec, options?: GetFieldsOptions) => Promise<any>;
// Warning: (ae-forgotten-export) The symbol "GetFieldsOptions" needs to be exported by the entry point index.d.ts
getFieldsForWildcard: (options: GetFieldsOptions) => Promise<any>;
getFieldsForWildcard: (options?: GetFieldsOptions) => Promise<any>;
getIds: (refresh?: boolean) => Promise<string[]>;
getIdsWithTitle: (refresh?: boolean) => Promise<Array<{
id: string;

View file

@ -134,8 +134,6 @@ export {
FieldDescriptor as IndexPatternFieldDescriptor,
shouldReadFieldFromDocValues, // used only in logstash_fields fixture
FieldDescriptor,
mergeCapabilitiesWithFields,
getCapabilitiesForRollupIndices,
} from './index_patterns';
export {

View file

@ -18,8 +18,4 @@
*/
export * from './index_patterns_fetcher';
export {
shouldReadFieldFromDocValues,
mergeCapabilitiesWithFields,
getCapabilitiesForRollupIndices,
} from './lib';
export { shouldReadFieldFromDocValues } from './lib';

View file

@ -18,15 +18,8 @@
*/
import { ElasticsearchClient } from 'kibana/server';
import { keyBy } from 'lodash';
import {
getFieldCapabilities,
resolveTimePattern,
createNoMatchingIndicesError,
getCapabilitiesForRollupIndices,
mergeCapabilitiesWithFields,
} from './lib';
import { getFieldCapabilities, resolveTimePattern, createNoMatchingIndicesError } from './lib';
export interface FieldDescriptor {
aggregatable: boolean;
@ -65,44 +58,11 @@ export class IndexPatternsFetcher {
pattern: string | string[];
metaFields?: string[];
fieldCapsOptions?: { allow_no_indices: boolean };
type?: string;
rollupIndex?: string;
}): Promise<FieldDescriptor[]> {
const { pattern, metaFields, fieldCapsOptions, type, rollupIndex } = options;
const fieldCapsResponse = await getFieldCapabilities(
this.elasticsearchClient,
pattern,
metaFields,
{
allow_no_indices: fieldCapsOptions
? fieldCapsOptions.allow_no_indices
: this.allowNoIndices,
}
);
if (type === 'rollup' && rollupIndex) {
const rollupFields: FieldDescriptor[] = [];
const rollupIndexCapabilities = getCapabilitiesForRollupIndices(
(
await this.elasticsearchClient.rollup.getRollupIndexCaps({
index: rollupIndex,
})
).body
)[rollupIndex].aggs;
const fieldCapsResponseObj = keyBy(fieldCapsResponse, 'name');
// Keep meta fields
metaFields!.forEach(
(field: string) =>
fieldCapsResponseObj[field] && rollupFields.push(fieldCapsResponseObj[field])
);
return mergeCapabilitiesWithFields(
rollupIndexCapabilities,
fieldCapsResponseObj,
rollupFields
);
}
return fieldCapsResponse;
const { pattern, metaFields, fieldCapsOptions } = options;
return await getFieldCapabilities(this.elasticsearchClient, pattern, metaFields, {
allow_no_indices: fieldCapsOptions ? fieldCapsOptions.allow_no_indices : this.allowNoIndices,
});
}
/**

View file

@ -1,20 +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.
*/
export { jobs } from './jobs';

View file

@ -20,5 +20,3 @@
export { getFieldCapabilities, shouldReadFieldFromDocValues } from './field_capabilities';
export { resolveTimePattern } from './resolve_time_pattern';
export { createNoMatchingIndicesError } from './errors';
export * from './merge_capabilities_with_fields';
export * from './map_capabilities';

View file

@ -1,37 +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 { mergeJobConfigurations } from './jobs_compatibility';
export function getCapabilitiesForRollupIndices(indices: { [key: string]: any }) {
const indexNames = Object.keys(indices);
const capabilities = {} as { [key: string]: any };
indexNames.forEach((index) => {
try {
capabilities[index] = mergeJobConfigurations(indices[index].rollup_jobs);
} catch (e) {
capabilities[index] = {
error: e.message,
};
}
});
return capabilities;
}

View file

@ -17,11 +17,5 @@
* under the License.
*/
export * from './utils';
export {
IndexPatternsFetcher,
FieldDescriptor,
shouldReadFieldFromDocValues,
mergeCapabilitiesWithFields,
getCapabilitiesForRollupIndices,
} from './fetcher';
export { IndexPatternsFetcher, FieldDescriptor, shouldReadFieldFromDocValues } from './fetcher';
export { IndexPatternsService, IndexPatternsServiceStart } from './index_patterns_service';

View file

@ -17,30 +17,13 @@
* under the License.
*/
import { ElasticsearchClient } from 'kibana/server';
import {
GetFieldsOptions,
IIndexPatternsApiClient,
GetFieldsOptionsTimePattern,
} from '../../common/index_patterns/types';
import { IndexPatternsFetcher } from './fetcher';
import { GetFieldsOptions, IIndexPatternsApiClient } from '../../common/index_patterns/types';
export class IndexPatternsApiServer implements IIndexPatternsApiClient {
esClient: ElasticsearchClient;
constructor(elasticsearchClient: ElasticsearchClient) {
this.esClient = elasticsearchClient;
async getFieldsForTimePattern(options: GetFieldsOptions = {}) {
throw new Error('IndexPatternsApiServer - getFieldsForTimePattern not defined');
}
async getFieldsForWildcard({ pattern, metaFields, type, rollupIndex }: GetFieldsOptions) {
const indexPatterns = new IndexPatternsFetcher(this.esClient);
return await indexPatterns.getFieldsForWildcard({
pattern,
metaFields,
type,
rollupIndex,
});
}
async getFieldsForTimePattern(options: GetFieldsOptionsTimePattern) {
const indexPatterns = new IndexPatternsFetcher(this.esClient);
return await indexPatterns.getFieldsForTimePattern(options);
async getFieldsForWildcard(options: GetFieldsOptions = {}) {
throw new Error('IndexPatternsApiServer - getFieldsForWildcard not defined');
}
}

View file

@ -17,14 +17,7 @@
* under the License.
*/
import {
CoreSetup,
CoreStart,
Plugin,
Logger,
SavedObjectsClientContract,
ElasticsearchClient,
} from 'kibana/server';
import { CoreSetup, CoreStart, Plugin, Logger, SavedObjectsClientContract } from 'kibana/server';
import { registerRoutes } from './routes';
import { indexPatternSavedObjectType } from '../saved_objects';
import { capabilitiesProvider } from './capabilities_provider';
@ -36,8 +29,7 @@ import { SavedObjectsClientServerToCommon } from './saved_objects_client_wrapper
export interface IndexPatternsServiceStart {
indexPatternsServiceFactory: (
savedObjectsClient: SavedObjectsClientContract,
elasticsearchClient: ElasticsearchClient
savedObjectsClient: SavedObjectsClientContract
) => Promise<IndexPatternsCommonService>;
}
@ -58,17 +50,14 @@ export class IndexPatternsService implements Plugin<void, IndexPatternsServiceSt
const { uiSettings } = core;
return {
indexPatternsServiceFactory: async (
savedObjectsClient: SavedObjectsClientContract,
elasticsearchClient: ElasticsearchClient
) => {
indexPatternsServiceFactory: async (savedObjectsClient: SavedObjectsClientContract) => {
const uiSettingsClient = uiSettings.asScopedToClient(savedObjectsClient);
const formats = await fieldFormats.fieldFormatServiceFactory(uiSettingsClient);
return new IndexPatternsCommonService({
uiSettings: new UiSettingsServerToCommon(uiSettingsClient),
savedObjectsClient: new SavedObjectsClientServerToCommon(savedObjectsClient),
apiClient: new IndexPatternsApiServer(elasticsearchClient),
apiClient: new IndexPatternsApiServer(),
fieldFormats: formats,
onError: (error) => {
logger.error(error);

View file

@ -42,15 +42,13 @@ export function registerRoutes(http: HttpServiceSetup) {
meta_fields: schema.oneOf([schema.string(), schema.arrayOf(schema.string())], {
defaultValue: [],
}),
type: schema.maybe(schema.string()),
rollup_index: schema.maybe(schema.string()),
}),
},
},
async (context, request, response) => {
const { asCurrentUser } = context.core.elasticsearch.client;
const indexPatterns = new IndexPatternsFetcher(asCurrentUser);
const { pattern, meta_fields: metaFields, type, rollup_index: rollupIndex } = request.query;
const { pattern, meta_fields: metaFields } = request.query;
let parsedFields: string[] = [];
try {
@ -63,8 +61,6 @@ export function registerRoutes(http: HttpServiceSetup) {
const fields = await indexPatterns.getFieldsForWildcard({
pattern,
metaFields: parsedFields,
type,
rollupIndex,
});
return response.ok({

View file

@ -17,7 +17,7 @@
* under the License.
*/
import { KibanaRequest, ElasticsearchClient } from 'src/core/server';
import { KibanaRequest } from 'src/core/server';
import { coreMock } from '../../../../../core/server/mocks';
import { expressionsPluginMock } from '../../../../../plugins/expressions/server/mocks';
@ -63,8 +63,7 @@ describe('AggsService - server', () => {
expect(start).toHaveProperty('asScopedToClient');
const contract = await start.asScopedToClient(
savedObjects.getScopedClient({} as KibanaRequest),
{} as ElasticsearchClient
savedObjects.getScopedClient({} as KibanaRequest)
);
expect(contract).toHaveProperty('calculateAutoTimeExpression');
expect(contract).toHaveProperty('createAggConfigs');
@ -75,10 +74,7 @@ describe('AggsService - server', () => {
service.setup(setupDeps);
const start = await service
.start(startDeps)
.asScopedToClient(
savedObjects.getScopedClient({} as KibanaRequest),
{} as ElasticsearchClient
);
.asScopedToClient(savedObjects.getScopedClient({} as KibanaRequest));
expect(start.types.get('terms').name).toBe('terms');
});
@ -87,10 +83,7 @@ describe('AggsService - server', () => {
service.setup(setupDeps);
const start = await service
.start(startDeps)
.asScopedToClient(
savedObjects.getScopedClient({} as KibanaRequest),
{} as ElasticsearchClient
);
.asScopedToClient(savedObjects.getScopedClient({} as KibanaRequest));
const aggTypes = getAggTypes();
expect(start.types.getAll().buckets.length).toBe(aggTypes.buckets.length);
@ -110,10 +103,7 @@ describe('AggsService - server', () => {
const start = await service
.start(startDeps)
.asScopedToClient(
savedObjects.getScopedClient({} as KibanaRequest),
{} as ElasticsearchClient
);
.asScopedToClient(savedObjects.getScopedClient({} as KibanaRequest));
const aggTypes = getAggTypes();
expect(start.types.getAll().buckets.length).toBe(aggTypes.buckets.length + 1);

View file

@ -19,11 +19,7 @@
import { pick } from 'lodash';
import {
UiSettingsServiceStart,
SavedObjectsClientContract,
ElasticsearchClient,
} from 'src/core/server';
import { UiSettingsServiceStart, SavedObjectsClientContract } from 'src/core/server';
import { ExpressionsServiceSetup } from 'src/plugins/expressions/common';
import {
AggsCommonService,
@ -69,10 +65,7 @@ export class AggsService {
public start({ fieldFormats, uiSettings, indexPatterns }: AggsStartDependencies): AggsStart {
return {
asScopedToClient: async (
savedObjectsClient: SavedObjectsClientContract,
elasticsearchClient: ElasticsearchClient
) => {
asScopedToClient: async (savedObjectsClient: SavedObjectsClientContract) => {
const uiSettingsClient = uiSettings.asScopedToClient(savedObjectsClient);
const formats = await fieldFormats.fieldFormatServiceFactory(uiSettingsClient);
@ -89,9 +82,8 @@ export class AggsService {
types,
} = this.aggsCommonService.start({
getConfig,
getIndexPattern: (
await indexPatterns.indexPatternsServiceFactory(savedObjectsClient, elasticsearchClient)
).get,
getIndexPattern: (await indexPatterns.indexPatternsServiceFactory(savedObjectsClient))
.get,
isDefaultTimezone,
});

View file

@ -17,14 +17,11 @@
* under the License.
*/
import { SavedObjectsClientContract, ElasticsearchClient } from 'src/core/server';
import { SavedObjectsClientContract } from 'src/core/server';
import { AggsCommonSetup, AggsStart as Start } from '../../../common';
export type AggsSetup = AggsCommonSetup;
export interface AggsStart {
asScopedToClient: (
savedObjectsClient: SavedObjectsClientContract,
elasticsearchClient: ElasticsearchClient
) => Promise<Start>;
asScopedToClient: (savedObjectsClient: SavedObjectsClientContract) => Promise<Start>;
}

View file

@ -149,11 +149,7 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
{ fieldFormats, indexPatterns }: SearchServiceStartDependencies
): ISearchStart {
return {
aggs: this.aggsService.start({
fieldFormats,
uiSettings,
indexPatterns,
}),
aggs: this.aggsService.start({ fieldFormats, uiSettings, indexPatterns }),
getSearchStrategy: this.getSearchStrategy,
search: this.search.bind(this),
searchSource: {
@ -161,8 +157,7 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
const esClient = elasticsearch.client.asScoped(request);
const savedObjectsClient = savedObjects.getScopedClient(request);
const scopedIndexPatterns = await indexPatterns.indexPatternsServiceFactory(
savedObjectsClient,
esClient.asCurrentUser
savedObjectsClient
);
const uiSettingsClient = uiSettings.asScopedToClient(savedObjectsClient);

View file

@ -15,8 +15,7 @@ import { CoreStart } from 'src/core/server';
import { CoreStart as CoreStart_2 } from 'kibana/server';
import { DatatableColumn } from 'src/plugins/expressions';
import { Duration } from 'moment';
import { ElasticsearchClient } from 'src/core/server';
import { ElasticsearchClient as ElasticsearchClient_2 } from 'kibana/server';
import { ElasticsearchClient } from 'kibana/server';
import { Ensure } from '@kbn/utility-types';
import { EnvironmentMode } from '@kbn/config';
import { ErrorToastOptions } from 'src/core/public/notifications';
@ -361,15 +360,6 @@ export type Filter = {
query?: any;
};
// Warning: (ae-missing-release-tag) "getCapabilitiesForRollupIndices" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export function getCapabilitiesForRollupIndices(indices: {
[key: string]: any;
}): {
[key: string]: any;
};
// Warning: (ae-forgotten-export) The symbol "IUiSettingsClient" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "getDefaultSearchParams" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
@ -669,7 +659,7 @@ export const indexPatterns: {
//
// @public (undocumented)
export class IndexPatternsFetcher {
constructor(elasticsearchClient: ElasticsearchClient_2, allowNoIndices?: boolean);
constructor(elasticsearchClient: ElasticsearchClient, allowNoIndices?: boolean);
getFieldsForTimePattern(options: {
pattern: string;
metaFields: string[];
@ -682,8 +672,6 @@ export class IndexPatternsFetcher {
fieldCapsOptions?: {
allow_no_indices: boolean;
};
type?: string;
rollupIndex?: string;
}): Promise<FieldDescriptor[]>;
}
@ -698,7 +686,7 @@ export class IndexPatternsService implements Plugin_3<void, IndexPatternsService
//
// (undocumented)
start(core: CoreStart_2, { fieldFormats, logger }: IndexPatternsServiceStartDeps): {
indexPatternsServiceFactory: (savedObjectsClient: SavedObjectsClientContract_2, elasticsearchClient: ElasticsearchClient_2) => Promise<IndexPatternsService_2>;
indexPatternsServiceFactory: (savedObjectsClient: SavedObjectsClientContract_2) => Promise<IndexPatternsService_2>;
};
}
@ -800,15 +788,6 @@ export interface KueryNode {
type: keyof NodeTypes;
}
// Warning: (ae-missing-release-tag) "mergeCapabilitiesWithFields" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const mergeCapabilitiesWithFields: (rollupIndexCapabilities: {
[key: string]: any;
}, fieldsFromFieldCapsApi: {
[key: string]: any;
}, previousFields?: FieldDescriptor[]) => FieldDescriptor[];
// Warning: (ae-missing-release-tag) "METRIC_TYPES" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
@ -912,7 +891,7 @@ export class Plugin implements Plugin_2<PluginSetup, PluginStart, DataPluginSetu
fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise<import("../common").FieldFormatsRegistry>;
};
indexPatterns: {
indexPatternsServiceFactory: (savedObjectsClient: Pick<import("../../../core/server").SavedObjectsClient, "update" | "find" | "get" | "delete" | "errors" | "create" | "bulkCreate" | "checkConflicts" | "bulkGet" | "addToNamespaces" | "deleteFromNamespaces" | "bulkUpdate" | "removeReferencesTo">, elasticsearchClient: import("../../../core/server").ElasticsearchClient) => Promise<import("../public").IndexPatternsService>;
indexPatternsServiceFactory: (savedObjectsClient: Pick<import("../../../core/server").SavedObjectsClient, "update" | "find" | "get" | "delete" | "errors" | "create" | "bulkCreate" | "checkConflicts" | "bulkGet" | "addToNamespaces" | "deleteFromNamespaces" | "bulkUpdate" | "removeReferencesTo">) => Promise<import("../public").IndexPatternsService>;
};
search: ISearchStart<import("./search").IEsSearchRequest, import("./search").IEsSearchResponse<any>>;
};
@ -1168,22 +1147,22 @@ export function usageProvider(core: CoreSetup_2): SearchUsage;
// src/plugins/data/server/index.ts:101:26 - (ae-forgotten-export) The symbol "TruncateFormat" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:127:27 - (ae-forgotten-export) The symbol "isFilterable" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:127:27 - (ae-forgotten-export) The symbol "isNestedField" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:236:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:236:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:236:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:236:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:251:5 - (ae-forgotten-export) The symbol "getTotalLoaded" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:252:5 - (ae-forgotten-export) The symbol "toSnakeCase" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:256:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:257:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:266:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:267:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:268:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:272:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:273:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:277:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:280:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index_patterns/index_patterns_service.ts:58:14 - (ae-forgotten-export) The symbol "IndexPatternsService" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:234:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:234:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:234:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:234:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:249:5 - (ae-forgotten-export) The symbol "getTotalLoaded" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:250:5 - (ae-forgotten-export) The symbol "toSnakeCase" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:254:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:255:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:264:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:265:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:266:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:270:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:271:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:275:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:278:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index_patterns/index_patterns_service.ts:50:14 - (ae-forgotten-export) The symbol "IndexPatternsService" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/plugin.ts:88:66 - (ae-forgotten-export) The symbol "DataEnhancements" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/search/types.ts:91:5 - (ae-forgotten-export) The symbol "ISearchStartSearchSource" needs to be exported by the entry point index.d.ts

View file

@ -62,12 +62,10 @@ export async function getFields(
let indexPatternString = indexPattern;
if (!indexPatternString) {
const [{ savedObjects, elasticsearch }, { data }] = await framework.core.getStartServices();
const [{ savedObjects }, { data }] = await framework.core.getStartServices();
const savedObjectsClient = savedObjects.getScopedClient(request);
const clusterClient = elasticsearch.client.asScoped(request).asCurrentUser;
const indexPatternsService = await data.indexPatterns.indexPatternsServiceFactory(
savedObjectsClient,
clusterClient
savedObjectsClient
);
const defaultIndexPattern = await indexPatternsService.getDefault();
indexPatternString = get(defaultIndexPattern, 'title', '');

View file

@ -350,7 +350,6 @@ export function SettingsPageProvider({ getService, getPageObjects }: FtrProvider
if (timefield) {
await this.selectTimeFieldOption(timefield);
}
await new Promise((r) => setTimeout(r, 5000 * 60));
await (await this.getCreateIndexPatternButton()).click();
});
await PageObjects.header.waitUntilLoadingHasFinished();

View file

@ -58,16 +58,14 @@ export class DataSearchTestPlugin
},
},
async (context, req, res) => {
const [{ savedObjects, elasticsearch }, { data }] = await core.getStartServices();
const [{ savedObjects }, { data }] = await core.getStartServices();
const service = await data.search.searchSource.asScoped(req);
const clusterClient = elasticsearch.client.asScoped(req).asCurrentUser;
const savedObjectsClient = savedObjects.getScopedClient(req);
// Since the index pattern ID can change on each test run, we need
// to look it up on the fly and insert it into the request.
const indexPatterns = await data.indexPatterns.indexPatternsServiceFactory(
savedObjectsClient,
clusterClient
savedObjectsClient
);
const ids = await indexPatterns.getIds();
// @ts-expect-error Force overwriting the request

View file

@ -36,34 +36,12 @@ export class IndexPatternsTestPlugin
public setup(core: CoreSetup<IndexPatternsTestStartDeps>) {
const router = core.http.createRouter();
router.post(
{
path: '/api/index-patterns-plugin/create',
validate: {
body: schema.object({}, { unknowns: 'allow' }),
},
},
async (context, req, res) => {
const [{ savedObjects, elasticsearch }, { data }] = await core.getStartServices();
const savedObjectsClient = savedObjects.getScopedClient(req);
const service = await data.indexPatterns.indexPatternsServiceFactory(
savedObjectsClient,
elasticsearch.client.asScoped(req).asCurrentUser
);
const ids = await service.createAndSave(req.body);
return res.ok({ body: ids });
}
);
router.get(
{ path: '/api/index-patterns-plugin/get-all', validate: false },
async (context, req, res) => {
const [{ savedObjects, elasticsearch }, { data }] = await core.getStartServices();
const [{ savedObjects }, { data }] = await core.getStartServices();
const savedObjectsClient = savedObjects.getScopedClient(req);
const service = await data.indexPatterns.indexPatternsServiceFactory(
savedObjectsClient,
elasticsearch.client.asScoped(req).asCurrentUser
);
const service = await data.indexPatterns.indexPatternsServiceFactory(savedObjectsClient);
const ids = await service.getIds();
return res.ok({ body: ids });
}
@ -80,12 +58,9 @@ export class IndexPatternsTestPlugin
},
async (context, req, res) => {
const id = (req.params as Record<string, string>).id;
const [{ savedObjects, elasticsearch }, { data }] = await core.getStartServices();
const [{ savedObjects }, { data }] = await core.getStartServices();
const savedObjectsClient = savedObjects.getScopedClient(req);
const service = await data.indexPatterns.indexPatternsServiceFactory(
savedObjectsClient,
elasticsearch.client.asScoped(req).asCurrentUser
);
const service = await data.indexPatterns.indexPatternsServiceFactory(savedObjectsClient);
const ip = await service.get(id);
return res.ok({ body: ip.toSpec() });
}
@ -101,13 +76,10 @@ export class IndexPatternsTestPlugin
},
},
async (context, req, res) => {
const [{ savedObjects, elasticsearch }, { data }] = await core.getStartServices();
const [{ savedObjects }, { data }] = await core.getStartServices();
const id = (req.params as Record<string, string>).id;
const savedObjectsClient = savedObjects.getScopedClient(req);
const service = await data.indexPatterns.indexPatternsServiceFactory(
savedObjectsClient,
elasticsearch.client.asScoped(req).asCurrentUser
);
const service = await data.indexPatterns.indexPatternsServiceFactory(savedObjectsClient);
const ip = await service.get(id);
await service.updateSavedObject(ip);
return res.ok();
@ -124,13 +96,10 @@ export class IndexPatternsTestPlugin
},
},
async (context, req, res) => {
const [{ savedObjects, elasticsearch }, { data }] = await core.getStartServices();
const [{ savedObjects }, { data }] = await core.getStartServices();
const id = (req.params as Record<string, string>).id;
const savedObjectsClient = savedObjects.getScopedClient(req);
const service = await data.indexPatterns.indexPatternsServiceFactory(
savedObjectsClient,
elasticsearch.client.asScoped(req).asCurrentUser
);
const service = await data.indexPatterns.indexPatternsServiceFactory(savedObjectsClient);
await service.delete(id);
return res.ok();
}

View file

@ -25,30 +25,13 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
// skipping the tests as it deletes index patterns created by other test causing unexpected failures
// https://github.com/elastic/kibana/issues/79886
describe('index patterns', function () {
describe.skip('index patterns', function () {
let indexPatternId = '';
it('can create an index pattern', async () => {
const title = 'shakes*';
const fieldFormats = { bytes: { id: 'bytes' } };
const body = await (
await supertest
.post('/api/index-patterns-plugin/create')
.set('kbn-xsrf', 'anything')
.send({ title, fieldFormats })
.expect(200)
).body;
indexPatternId = body.id;
expect(body.id).not.empty();
expect(body.title).to.equal(title);
expect(body.fields.length).to.equal(15);
expect(body.fieldFormatMap).to.eql(fieldFormats);
});
it('can get all ids', async () => {
const body = await (await supertest.get('/api/index-patterns-plugin/get-all').expect(200))
.body;
indexPatternId = body[0];
expect(body.length > 0).to.equal(true);
});

View file

@ -161,7 +161,9 @@ export class RollupIndexPatternCreationConfig extends IndexPatternCreationConfig
getFetchForWildcardOptions = () => {
return {
type: this.type,
rollupIndex: this.rollupIndex,
params: {
rollup_index: this.rollupIndex,
},
};
};
}

View file

@ -0,0 +1,7 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export { jobs } from './jobs';

View file

@ -1,20 +1,7 @@
/*
* 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.
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export const jobs = [

View file

@ -1,22 +1,8 @@
/*
* 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.
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import expect from '@kbn/expect';
import { areJobsCompatible, mergeJobConfigurations } from '../jobs_compatibility';
import { jobs } from './fixtures';

View file

@ -1,20 +1,7 @@
/*
* 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.
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { isEqual } from 'lodash';

View file

@ -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;
* you may not use this file except in compliance with the Elastic License.
*/
import { mergeJobConfigurations } from './jobs_compatibility';
export function getCapabilitiesForRollupIndices(indices: { [key: string]: any }) {
const indexNames = Object.keys(indices);
const capabilities = {} as { [key: string]: any };
indexNames.forEach((index) => {
try {
capabilities[index] = mergeJobConfigurations(indices[index].rollup_jobs);
} catch (e) {
capabilities[index] = {
error: e.message,
};
}
});
return capabilities;
}

View file

@ -1,30 +1,20 @@
/*
* 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.
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
// Merge rollup capabilities information with field information
import { FieldDescriptor } from '../index_patterns_fetcher';
export interface Field {
name?: string;
[key: string]: any;
}
export const mergeCapabilitiesWithFields = (
rollupIndexCapabilities: { [key: string]: any },
fieldsFromFieldCapsApi: { [key: string]: any },
previousFields: FieldDescriptor[] = []
previousFields: Field[] = []
) => {
const rollupFields = [...previousFields];
const rollupFieldNames: string[] = [];

View file

@ -6,11 +6,8 @@
import { keyBy, isString } from 'lodash';
import { ILegacyScopedClusterClient } from 'src/core/server';
import { ReqFacade } from '../../../../../../src/plugins/vis_type_timeseries/server';
import {
mergeCapabilitiesWithFields,
getCapabilitiesForRollupIndices,
} from '../../../../../../src/plugins/data/server';
import { mergeCapabilitiesWithFields } from '../merge_capabilities_with_fields';
import { getCapabilitiesForRollupIndices } from '../map_capabilities';
const getRollupIndices = (rollupData: { [key: string]: any }) => Object.keys(rollupData);

View file

@ -36,7 +36,8 @@ import { registerRollupSearchStrategy } from './lib/search_strategies';
import { elasticsearchJsPlugin } from './client/elasticsearch_rollup';
import { isEsError } from './shared_imports';
import { formatEsError } from './lib/format_es_error';
import { getCapabilitiesForRollupIndices } from '../../../../src/plugins/data/server';
import { getCapabilitiesForRollupIndices } from './lib/map_capabilities';
import { mergeCapabilitiesWithFields } from './lib/merge_capabilities_with_fields';
interface RollupContext {
client: ILegacyScopedClusterClient;
@ -106,6 +107,7 @@ export class RollupPlugin implements Plugin<void, void, any, any> {
isEsError,
formatEsError,
getCapabilitiesForRollupIndices,
mergeCapabilitiesWithFields,
},
sharedImports: {
IndexPatternsFetcher,

View file

@ -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;
* you may not use this file except in compliance with the Elastic License.
*/
import { RouteDependencies } from '../../../types';
import { registerFieldsForWildcardRoute } from './register_fields_for_wildcard_route';
export function registerIndexPatternsRoutes(dependencies: RouteDependencies) {
registerFieldsForWildcardRoute(dependencies);
}

View file

@ -0,0 +1,142 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { keyBy } from 'lodash';
import { schema } from '@kbn/config-schema';
import { Field } from '../../../lib/merge_capabilities_with_fields';
import { RouteDependencies } from '../../../types';
import type { IndexPatternsFetcher as IndexPatternsFetcherType } from '../../../../../../../src/plugins/data/server';
const parseMetaFields = (metaFields: string | string[]) => {
let parsedFields: string[] = [];
if (typeof metaFields === 'string') {
parsedFields = JSON.parse(metaFields);
} else {
parsedFields = metaFields;
}
return parsedFields;
};
const getFieldsForWildcardRequest = async (
context: any,
request: any,
response: any,
IndexPatternsFetcher: typeof IndexPatternsFetcherType
) => {
const { asCurrentUser } = context.core.elasticsearch.client;
const indexPatterns = new IndexPatternsFetcher(asCurrentUser);
const { pattern, meta_fields: metaFields } = request.query;
let parsedFields: string[] = [];
try {
parsedFields = parseMetaFields(metaFields);
} catch (error) {
return response.badRequest({
body: error,
});
}
try {
const fields = await indexPatterns.getFieldsForWildcard({
pattern,
metaFields: parsedFields,
});
return response.ok({
body: { fields },
headers: {
'content-type': 'application/json',
},
});
} catch (error) {
return response.notFound();
}
};
/**
* Get list of fields for rollup index pattern, in the format of regular index pattern fields
*/
export const registerFieldsForWildcardRoute = ({
router,
license,
lib: { isEsError, formatEsError, getCapabilitiesForRollupIndices, mergeCapabilitiesWithFields },
sharedImports: { IndexPatternsFetcher },
}: RouteDependencies) => {
const querySchema = schema.object({
pattern: schema.string(),
meta_fields: schema.arrayOf(schema.string(), {
defaultValue: [],
}),
params: schema.string({
validate(value) {
try {
const params = JSON.parse(value);
const keys = Object.keys(params);
const { rollup_index: rollupIndex } = params;
if (!rollupIndex) {
return '[request query.params]: "rollup_index" is required';
} else if (keys.length > 1) {
const invalidParams = keys.filter((key) => key !== 'rollup_index');
return `[request query.params]: ${invalidParams.join(', ')} is not allowed`;
}
} catch (err) {
return '[request query.params]: expected JSON string';
}
},
}),
});
router.get(
{
path: '/api/index_patterns/rollup/_fields_for_wildcard',
validate: {
query: querySchema,
},
},
license.guardApiRoute(async (context, request, response) => {
const { params, meta_fields: metaFields } = request.query;
try {
// Make call and use field information from response
const { payload } = await getFieldsForWildcardRequest(
context,
request,
response,
IndexPatternsFetcher
);
const fields = payload.fields;
const parsedParams = JSON.parse(params);
const rollupIndex = parsedParams.rollup_index;
const rollupFields: Field[] = [];
const fieldsFromFieldCapsApi: { [key: string]: any } = keyBy(fields, 'name');
const rollupIndexCapabilities = getCapabilitiesForRollupIndices(
await context.rollup!.client.callAsCurrentUser('rollup.rollupIndexCapabilities', {
indexPattern: rollupIndex,
})
)[rollupIndex].aggs;
// Keep meta fields
metaFields.forEach(
(field: string) =>
fieldsFromFieldCapsApi[field] && rollupFields.push(fieldsFromFieldCapsApi[field])
);
const mergedRollupFields = mergeCapabilitiesWithFields(
rollupIndexCapabilities,
fieldsFromFieldCapsApi,
rollupFields
);
return response.ok({ body: { fields: mergedRollupFields } });
} catch (err) {
if (isEsError(err)) {
return response.customError({ statusCode: err.statusCode, body: err });
}
return response.internalError({ body: err });
}
})
);
};

View file

@ -6,11 +6,13 @@
import { RouteDependencies } from '../types';
import { registerIndexPatternsRoutes } from './api/index_patterns';
import { registerIndicesRoutes } from './api/indices';
import { registerJobsRoutes } from './api/jobs';
import { registerSearchRoutes } from './api/search';
export function registerApiRoutes(dependencies: RouteDependencies) {
registerIndexPatternsRoutes(dependencies);
registerIndicesRoutes(dependencies);
registerJobsRoutes(dependencies);
registerSearchRoutes(dependencies);

View file

@ -8,7 +8,6 @@ import { IRouter } from 'src/core/server';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { VisTypeTimeseriesSetup } from 'src/plugins/vis_type_timeseries/server';
import { getCapabilitiesForRollupIndices } from 'src/plugins/data/server';
import { IndexManagementPluginSetup } from '../../index_management/server';
import { PluginSetupContract as FeaturesPluginSetup } from '../../features/server';
import { LicensingPluginSetup } from '../../licensing/server';
@ -16,6 +15,8 @@ import { License } from './services';
import { IndexPatternsFetcher } from './shared_imports';
import { isEsError } from './shared_imports';
import { formatEsError } from './lib/format_es_error';
import { getCapabilitiesForRollupIndices } from './lib/map_capabilities';
import { mergeCapabilitiesWithFields } from './lib/merge_capabilities_with_fields';
export interface Dependencies {
indexManagement?: IndexManagementPluginSetup;
@ -32,6 +33,7 @@ export interface RouteDependencies {
isEsError: typeof isEsError;
formatEsError: typeof formatEsError;
getCapabilitiesForRollupIndices: typeof getCapabilitiesForRollupIndices;
mergeCapabilitiesWithFields: typeof mergeCapabilitiesWithFields;
};
sharedImports: {
IndexPatternsFetcher: typeof IndexPatternsFetcher;

View file

@ -5,7 +5,7 @@
*/
export const API_BASE_PATH = '/api/rollup';
export const INDEX_PATTERNS_EXTENSION_BASE_PATH = '/api/index_patterns';
export const INDEX_PATTERNS_EXTENSION_BASE_PATH = '/api/index_patterns/rollup';
export const ROLLUP_INDEX_NAME = 'rollup_index';
export const INDEX_TO_ROLLUP_MAPPINGS = {
properties: {

View file

@ -26,6 +26,7 @@ export default function ({ getService }) {
describe('query params validation', () => {
let uri;
let body;
let params;
it('"pattern" is required', async () => {
uri = `${BASE_URI}`;
@ -35,17 +36,62 @@ export default function ({ getService }) {
);
});
it('"params" is required', async () => {
params = { pattern: 'foo' };
uri = `${BASE_URI}?${stringify(params, { sort: false })}`;
({ body } = await supertest.get(uri).expect(400));
expect(body.message).to.contain(
'[request query.params]: expected value of type [string]'
);
});
it('"params" must be a valid JSON string', async () => {
params = { pattern: 'foo', params: 'foobarbaz' };
uri = `${BASE_URI}?${stringify(params, { sort: false })}`;
({ body } = await supertest.get(uri).expect(400));
expect(body.message).to.contain('[request query.params]: expected JSON string');
});
it('"params" requires a "rollup_index" property', async () => {
params = { pattern: 'foo', params: JSON.stringify({}) };
uri = `${BASE_URI}?${stringify(params, { sort: false })}`;
({ body } = await supertest.get(uri).expect(400));
expect(body.message).to.contain('[request query.params]: "rollup_index" is required');
});
it('"params" only accepts a "rollup_index" property', async () => {
params = {
pattern: 'foo',
params: JSON.stringify({ rollup_index: 'my_index', someProp: 'bar' }),
};
uri = `${BASE_URI}?${stringify(params, { sort: false })}`;
({ body } = await supertest.get(uri).expect(400));
expect(body.message).to.contain('[request query.params]: someProp is not allowed');
});
it('"meta_fields" must be an Array', async () => {
params = {
pattern: 'foo',
params: JSON.stringify({ rollup_index: 'bar' }),
meta_fields: 'stringValue',
};
uri = `${BASE_URI}?${stringify(params, { sort: false })}`;
({ body } = await supertest.get(uri).expect(400));
expect(body.message).to.contain(
'[request query.meta_fields]: could not parse array value from json input'
);
});
it('should return 404 the rollup index to query does not exist', async () => {
uri = `${BASE_URI}?${stringify(
{
pattern: 'foo',
type: 'rollup',
rollup_index: 'bar',
params: JSON.stringify({ rollup_index: 'bar' }),
},
{ sort: false }
)}`;
({ body } = await supertest.get(uri).expect(404));
expect(body.message).to.contain('No indices match pattern "foo"');
expect(body.message).to.contain('[index_not_found_exception] no such index [bar]');
});
});
@ -59,8 +105,7 @@ export default function ({ getService }) {
// Query for wildcard
const params = {
pattern: indexName,
type: 'rollup',
rollup_index: rollupIndex,
params: JSON.stringify({ rollup_index: rollupIndex }),
};
const uri = `${BASE_URI}?${stringify(params, { sort: false })}`;
const { body } = await supertest.get(uri).expect(200);