The server side index patterns api can now load the field list. Previously it would error if a field list refresh was required. The regular and rollup index pattern field list loading methods were merged. Rollup index patterns require additional functionality over regular index patterns when it comes to loading the field list, but this won't be necessary once rollups v2 is released.
This commit is contained in:
parent
6825c27bf1
commit
a3d2afd58f
|
@ -9,5 +9,5 @@ Get field list by providing an index patttern (or spec)
|
|||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
getFieldsForIndexPattern: (indexPattern: IndexPattern | IndexPatternSpec, options?: GetFieldsOptions) => Promise<any>;
|
||||
getFieldsForIndexPattern: (indexPattern: IndexPattern | IndexPatternSpec, options?: GetFieldsOptions | undefined) => Promise<any>;
|
||||
```
|
||||
|
|
|
@ -9,5 +9,5 @@ Get field list by providing { pattern }
|
|||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
getFieldsForWildcard: (options?: GetFieldsOptions) => Promise<any>;
|
||||
getFieldsForWildcard: (options: GetFieldsOptions) => Promise<any>;
|
||||
```
|
||||
|
|
|
@ -26,8 +26,8 @@ export declare class IndexPatternsService
|
|||
| [get](./kibana-plugin-plugins-data-public.indexpatternsservice.get.md) | | <code>(id: string) => Promise<IndexPattern></code> | Get an index pattern by id. Cache optimized |
|
||||
| [getCache](./kibana-plugin-plugins-data-public.indexpatternsservice.getcache.md) | | <code>() => Promise<SavedObject<IndexPatternSavedObjectAttrs>[] | null | undefined></code> | |
|
||||
| [getDefault](./kibana-plugin-plugins-data-public.indexpatternsservice.getdefault.md) | | <code>() => Promise<IndexPattern | null></code> | Get default index pattern |
|
||||
| [getFieldsForIndexPattern](./kibana-plugin-plugins-data-public.indexpatternsservice.getfieldsforindexpattern.md) | | <code>(indexPattern: IndexPattern | IndexPatternSpec, options?: GetFieldsOptions) => Promise<any></code> | Get field list by providing an index patttern (or spec) |
|
||||
| [getFieldsForWildcard](./kibana-plugin-plugins-data-public.indexpatternsservice.getfieldsforwildcard.md) | | <code>(options?: GetFieldsOptions) => Promise<any></code> | Get field list by providing { pattern } |
|
||||
| [getFieldsForIndexPattern](./kibana-plugin-plugins-data-public.indexpatternsservice.getfieldsforindexpattern.md) | | <code>(indexPattern: IndexPattern | IndexPatternSpec, options?: GetFieldsOptions | undefined) => Promise<any></code> | Get field list by providing an index patttern (or spec) |
|
||||
| [getFieldsForWildcard](./kibana-plugin-plugins-data-public.indexpatternsservice.getfieldsforwildcard.md) | | <code>(options: GetFieldsOptions) => Promise<any></code> | Get field list by providing { pattern } |
|
||||
| [getIds](./kibana-plugin-plugins-data-public.indexpatternsservice.getids.md) | | <code>(refresh?: boolean) => Promise<string[]></code> | Get list of index pattern ids |
|
||||
| [getIdsWithTitle](./kibana-plugin-plugins-data-public.indexpatternsservice.getidswithtitle.md) | | <code>(refresh?: boolean) => Promise<Array<{</code><br/><code> id: string;</code><br/><code> title: string;</code><br/><code> }>></code> | Get list of index pattern ids with titles |
|
||||
| [getTitles](./kibana-plugin-plugins-data-public.indexpatternsservice.gettitles.md) | | <code>(refresh?: boolean) => Promise<string[]></code> | Get list of index pattern titles |
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [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;
|
||||
}`
|
||||
|
|
@ -15,6 +15,8 @@ getFieldsForWildcard(options: {
|
|||
fieldCapsOptions?: {
|
||||
allow_no_indices: boolean;
|
||||
};
|
||||
type?: string;
|
||||
rollupIndex?: string;
|
||||
}): Promise<FieldDescriptor[]>;
|
||||
```
|
||||
|
||||
|
@ -22,7 +24,7 @@ getFieldsForWildcard(options: {
|
|||
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| options | <code>{</code><br/><code> pattern: string | string[];</code><br/><code> metaFields?: string[];</code><br/><code> fieldCapsOptions?: {</code><br/><code> allow_no_indices: boolean;</code><br/><code> };</code><br/><code> }</code> | |
|
||||
| options | <code>{</code><br/><code> pattern: string | 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> | |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
```typescript
|
||||
start(core: CoreStart, { fieldFormats, logger }: IndexPatternsServiceStartDeps): {
|
||||
indexPatternsServiceFactory: (savedObjectsClient: SavedObjectsClientContract) => Promise<IndexPatternsCommonService>;
|
||||
indexPatternsServiceFactory: (savedObjectsClient: SavedObjectsClientContract, elasticsearchClient: ElasticsearchClient) => Promise<IndexPatternsCommonService>;
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -22,6 +22,6 @@ start(core: CoreStart, { fieldFormats, logger }: IndexPatternsServiceStartDeps):
|
|||
<b>Returns:</b>
|
||||
|
||||
`{
|
||||
indexPatternsServiceFactory: (savedObjectsClient: SavedObjectsClientContract) => Promise<IndexPatternsCommonService>;
|
||||
indexPatternsServiceFactory: (savedObjectsClient: SavedObjectsClientContract, elasticsearchClient: ElasticsearchClient) => Promise<IndexPatternsCommonService>;
|
||||
}`
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
| 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,6 +78,7 @@
|
|||
| [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) | |
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [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[]
|
||||
```
|
|
@ -12,7 +12,7 @@ start(core: CoreStart): {
|
|||
fieldFormatServiceFactory: (uiSettings: import("src/core/server").IUiSettingsClient) => Promise<import("../common").FieldFormatsRegistry>;
|
||||
};
|
||||
indexPatterns: {
|
||||
indexPatternsServiceFactory: (savedObjectsClient: Pick<import("src/core/server").SavedObjectsClient, "update" | "find" | "get" | "delete" | "errors" | "create" | "bulkCreate" | "checkConflicts" | "bulkGet" | "addToNamespaces" | "deleteFromNamespaces" | "bulkUpdate" | "removeReferencesTo">) => Promise<import("../common").IndexPatternsService>;
|
||||
indexPatternsServiceFactory: (savedObjectsClient: Pick<import("src/core/server").SavedObjectsClient, "update" | "find" | "get" | "delete" | "errors" | "create" | "bulkCreate" | "checkConflicts" | "bulkGet" | "addToNamespaces" | "deleteFromNamespaces" | "bulkUpdate" | "removeReferencesTo">, elasticsearchClient: import("src/core/server").ElasticsearchClient) => Promise<import("../common").IndexPatternsService>;
|
||||
};
|
||||
search: ISearchStart<import("./search").IEsSearchRequest, import("./search").IEsSearchResponse<any>>;
|
||||
};
|
||||
|
@ -31,7 +31,7 @@ start(core: CoreStart): {
|
|||
fieldFormatServiceFactory: (uiSettings: import("src/core/server").IUiSettingsClient) => Promise<import("../common").FieldFormatsRegistry>;
|
||||
};
|
||||
indexPatterns: {
|
||||
indexPatternsServiceFactory: (savedObjectsClient: Pick<import("src/core/server").SavedObjectsClient, "update" | "find" | "get" | "delete" | "errors" | "create" | "bulkCreate" | "checkConflicts" | "bulkGet" | "addToNamespaces" | "deleteFromNamespaces" | "bulkUpdate" | "removeReferencesTo">) => Promise<import("../common").IndexPatternsService>;
|
||||
indexPatternsServiceFactory: (savedObjectsClient: Pick<import("src/core/server").SavedObjectsClient, "update" | "find" | "get" | "delete" | "errors" | "create" | "bulkCreate" | "checkConflicts" | "bulkGet" | "addToNamespaces" | "deleteFromNamespaces" | "bulkUpdate" | "removeReferencesTo">, elasticsearchClient: import("src/core/server").ElasticsearchClient) => Promise<import("../common").IndexPatternsService>;
|
||||
};
|
||||
search: ISearchStart<import("./search").IEsSearchRequest, import("./search").IEsSearchResponse<any>>;
|
||||
}`
|
||||
|
|
|
@ -103,11 +103,12 @@ export class IndexPatternsService {
|
|||
* Refresh cache of index pattern ids and titles
|
||||
*/
|
||||
private async refreshSavedObjectsCache() {
|
||||
this.savedObjectsCache = await this.savedObjectsClient.find<IndexPatternSavedObjectAttrs>({
|
||||
const so = await this.savedObjectsClient.find<IndexPatternSavedObjectAttrs>({
|
||||
type: 'index-pattern',
|
||||
fields: ['title'],
|
||||
perPage: 10000,
|
||||
});
|
||||
this.savedObjectsCache = so;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -220,13 +221,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,
|
||||
params: options.params || {},
|
||||
rollupIndex: options.rollupIndex,
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -236,13 +237,13 @@ export class IndexPatternsService {
|
|||
*/
|
||||
getFieldsForIndexPattern = async (
|
||||
indexPattern: IndexPattern | IndexPatternSpec,
|
||||
options: GetFieldsOptions = {}
|
||||
options?: GetFieldsOptions
|
||||
) =>
|
||||
this.getFieldsForWildcard({
|
||||
pattern: indexPattern.title as string,
|
||||
...options,
|
||||
type: indexPattern.type,
|
||||
params: indexPattern.typeMeta && indexPattern.typeMeta.params,
|
||||
rollupIndex: indexPattern?.typeMeta?.params?.rollup_index,
|
||||
...options,
|
||||
pattern: indexPattern.title as string,
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -379,10 +380,10 @@ export class IndexPatternsService {
|
|||
try {
|
||||
spec.fields = isFieldRefreshRequired
|
||||
? await this.refreshFieldSpecMap(spec.fields || {}, id, spec.title as string, {
|
||||
pattern: title,
|
||||
pattern: title as string,
|
||||
metaFields: await this.config.get(UI_SETTINGS.META_FIELDS),
|
||||
type,
|
||||
params: typeMeta && typeMeta.params,
|
||||
rollupIndex: typeMeta?.params?.rollupIndex,
|
||||
})
|
||||
: spec.fields;
|
||||
} catch (err) {
|
||||
|
|
|
@ -97,15 +97,22 @@ 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: GetFieldsOptions) => Promise<any>;
|
||||
getFieldsForTimePattern: (options: GetFieldsOptionsTimePattern) => Promise<any>;
|
||||
getFieldsForWildcard: (options: GetFieldsOptions) => Promise<any>;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,12 @@ 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();
|
||||
await indexPatternsApiClient.getFieldsForTimePattern({
|
||||
pattern: 'blah',
|
||||
metaFields: [],
|
||||
lookBack: 5,
|
||||
interval: '',
|
||||
});
|
||||
|
||||
expect(fetchSpy).toHaveBeenCalledWith(expectedPath, expect.any(Object));
|
||||
});
|
||||
|
@ -40,15 +45,7 @@ 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();
|
||||
|
||||
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' });
|
||||
await indexPatternsApiClient.getFieldsForWildcard({ pattern: 'blah' });
|
||||
|
||||
expect(fetchSpy).toHaveBeenCalledWith(expectedPath, expect.any(Object));
|
||||
});
|
||||
|
|
|
@ -19,7 +19,11 @@
|
|||
|
||||
import { HttpSetup } from 'src/core/public';
|
||||
import { IndexPatternMissingIndices } from '../../../common/index_patterns/lib';
|
||||
import { GetFieldsOptions, IIndexPatternsApiClient } from '../../../common/index_patterns/types';
|
||||
import {
|
||||
GetFieldsOptions,
|
||||
IIndexPatternsApiClient,
|
||||
GetFieldsOptionsTimePattern,
|
||||
} from '../../../common/index_patterns/types';
|
||||
|
||||
const API_BASE_URL: string = `/api/index_patterns/`;
|
||||
|
||||
|
@ -48,7 +52,7 @@ export class IndexPatternsApiClient implements IIndexPatternsApiClient {
|
|||
return API_BASE_URL + path.filter(Boolean).map(encodeURIComponent).join('/');
|
||||
}
|
||||
|
||||
getFieldsForTimePattern(options: GetFieldsOptions = {}) {
|
||||
getFieldsForTimePattern(options: GetFieldsOptionsTimePattern) {
|
||||
const { pattern, lookBack, metaFields } = options;
|
||||
|
||||
const url = this._getUrl(['_fields_for_time_pattern']);
|
||||
|
@ -60,27 +64,12 @@ export class IndexPatternsApiClient implements IIndexPatternsApiClient {
|
|||
}).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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1373,9 +1373,9 @@ export class IndexPatternsService {
|
|||
// (undocumented)
|
||||
getCache: () => Promise<SavedObject<IndexPatternSavedObjectAttrs>[] | null | undefined>;
|
||||
getDefault: () => Promise<IndexPattern | null>;
|
||||
getFieldsForIndexPattern: (indexPattern: IndexPattern | IndexPatternSpec, options?: GetFieldsOptions) => Promise<any>;
|
||||
getFieldsForIndexPattern: (indexPattern: IndexPattern | IndexPatternSpec, options?: GetFieldsOptions | undefined) => 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;
|
||||
|
|
|
@ -134,6 +134,8 @@ export {
|
|||
FieldDescriptor as IndexPatternFieldDescriptor,
|
||||
shouldReadFieldFromDocValues, // used only in logstash_fields fixture
|
||||
FieldDescriptor,
|
||||
mergeCapabilitiesWithFields,
|
||||
getCapabilitiesForRollupIndices,
|
||||
} from './index_patterns';
|
||||
|
||||
export {
|
||||
|
|
|
@ -18,4 +18,8 @@
|
|||
*/
|
||||
|
||||
export * from './index_patterns_fetcher';
|
||||
export { shouldReadFieldFromDocValues } from './lib';
|
||||
export {
|
||||
shouldReadFieldFromDocValues,
|
||||
mergeCapabilitiesWithFields,
|
||||
getCapabilitiesForRollupIndices,
|
||||
} from './lib';
|
||||
|
|
|
@ -18,8 +18,15 @@
|
|||
*/
|
||||
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import { keyBy } from 'lodash';
|
||||
|
||||
import { getFieldCapabilities, resolveTimePattern, createNoMatchingIndicesError } from './lib';
|
||||
import {
|
||||
getFieldCapabilities,
|
||||
resolveTimePattern,
|
||||
createNoMatchingIndicesError,
|
||||
getCapabilitiesForRollupIndices,
|
||||
mergeCapabilitiesWithFields,
|
||||
} from './lib';
|
||||
|
||||
export interface FieldDescriptor {
|
||||
aggregatable: boolean;
|
||||
|
@ -58,11 +65,44 @@ export class IndexPatternsFetcher {
|
|||
pattern: string | string[];
|
||||
metaFields?: string[];
|
||||
fieldCapsOptions?: { allow_no_indices: boolean };
|
||||
type?: string;
|
||||
rollupIndex?: string;
|
||||
}): Promise<FieldDescriptor[]> {
|
||||
const { pattern, metaFields, fieldCapsOptions } = options;
|
||||
return await getFieldCapabilities(this.elasticsearchClient, pattern, metaFields, {
|
||||
allow_no_indices: fieldCapsOptions ? fieldCapsOptions.allow_no_indices : this.allowNoIndices,
|
||||
});
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +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.
|
||||
*/
|
||||
|
||||
export { jobs } from './jobs';
|
|
@ -1,7 +1,20 @@
|
|||
/*
|
||||
* 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.
|
||||
* 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 const jobs = [
|
|
@ -1,8 +1,22 @@
|
|||
/*
|
||||
* 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.
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { areJobsCompatible, mergeJobConfigurations } from '../jobs_compatibility';
|
||||
import { jobs } from './fixtures';
|
|
@ -20,3 +20,5 @@
|
|||
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';
|
||||
|
|
|
@ -1,7 +1,20 @@
|
|||
/*
|
||||
* 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.
|
||||
* 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 { isEqual } from 'lodash';
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -1,20 +1,30 @@
|
|||
/*
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Merge rollup capabilities information with field information
|
||||
|
||||
export interface Field {
|
||||
name?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
import { FieldDescriptor } from '../index_patterns_fetcher';
|
||||
|
||||
export const mergeCapabilitiesWithFields = (
|
||||
rollupIndexCapabilities: { [key: string]: any },
|
||||
fieldsFromFieldCapsApi: { [key: string]: any },
|
||||
previousFields: Field[] = []
|
||||
previousFields: FieldDescriptor[] = []
|
||||
) => {
|
||||
const rollupFields = [...previousFields];
|
||||
const rollupFieldNames: string[] = [];
|
|
@ -17,5 +17,11 @@
|
|||
* under the License.
|
||||
*/
|
||||
export * from './utils';
|
||||
export { IndexPatternsFetcher, FieldDescriptor, shouldReadFieldFromDocValues } from './fetcher';
|
||||
export {
|
||||
IndexPatternsFetcher,
|
||||
FieldDescriptor,
|
||||
shouldReadFieldFromDocValues,
|
||||
mergeCapabilitiesWithFields,
|
||||
getCapabilitiesForRollupIndices,
|
||||
} from './fetcher';
|
||||
export { IndexPatternsService, IndexPatternsServiceStart } from './index_patterns_service';
|
||||
|
|
|
@ -17,13 +17,30 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { GetFieldsOptions, IIndexPatternsApiClient } from '../../common/index_patterns/types';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import {
|
||||
GetFieldsOptions,
|
||||
IIndexPatternsApiClient,
|
||||
GetFieldsOptionsTimePattern,
|
||||
} from '../../common/index_patterns/types';
|
||||
import { IndexPatternsFetcher } from './fetcher';
|
||||
|
||||
export class IndexPatternsApiServer implements IIndexPatternsApiClient {
|
||||
async getFieldsForTimePattern(options: GetFieldsOptions = {}) {
|
||||
throw new Error('IndexPatternsApiServer - getFieldsForTimePattern not defined');
|
||||
esClient: ElasticsearchClient;
|
||||
constructor(elasticsearchClient: ElasticsearchClient) {
|
||||
this.esClient = elasticsearchClient;
|
||||
}
|
||||
async getFieldsForWildcard(options: GetFieldsOptions = {}) {
|
||||
throw new Error('IndexPatternsApiServer - getFieldsForWildcard 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,14 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { CoreSetup, CoreStart, Plugin, Logger, SavedObjectsClientContract } from 'kibana/server';
|
||||
import {
|
||||
CoreSetup,
|
||||
CoreStart,
|
||||
Plugin,
|
||||
Logger,
|
||||
SavedObjectsClientContract,
|
||||
ElasticsearchClient,
|
||||
} from 'kibana/server';
|
||||
import { registerRoutes } from './routes';
|
||||
import { indexPatternSavedObjectType } from '../saved_objects';
|
||||
import { capabilitiesProvider } from './capabilities_provider';
|
||||
|
@ -29,7 +36,8 @@ import { SavedObjectsClientServerToCommon } from './saved_objects_client_wrapper
|
|||
|
||||
export interface IndexPatternsServiceStart {
|
||||
indexPatternsServiceFactory: (
|
||||
savedObjectsClient: SavedObjectsClientContract
|
||||
savedObjectsClient: SavedObjectsClientContract,
|
||||
elasticsearchClient: ElasticsearchClient
|
||||
) => Promise<IndexPatternsCommonService>;
|
||||
}
|
||||
|
||||
|
@ -50,14 +58,17 @@ export class IndexPatternsService implements Plugin<void, IndexPatternsServiceSt
|
|||
const { uiSettings } = core;
|
||||
|
||||
return {
|
||||
indexPatternsServiceFactory: async (savedObjectsClient: SavedObjectsClientContract) => {
|
||||
indexPatternsServiceFactory: async (
|
||||
savedObjectsClient: SavedObjectsClientContract,
|
||||
elasticsearchClient: ElasticsearchClient
|
||||
) => {
|
||||
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(),
|
||||
apiClient: new IndexPatternsApiServer(elasticsearchClient),
|
||||
fieldFormats: formats,
|
||||
onError: (error) => {
|
||||
logger.error(error);
|
||||
|
|
|
@ -42,13 +42,15 @@ 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 } = request.query;
|
||||
const { pattern, meta_fields: metaFields, type, rollup_index: rollupIndex } = request.query;
|
||||
|
||||
let parsedFields: string[] = [];
|
||||
try {
|
||||
|
@ -61,6 +63,8 @@ export function registerRoutes(http: HttpServiceSetup) {
|
|||
const fields = await indexPatterns.getFieldsForWildcard({
|
||||
pattern,
|
||||
metaFields: parsedFields,
|
||||
type,
|
||||
rollupIndex,
|
||||
});
|
||||
|
||||
return response.ok({
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { KibanaRequest } from 'src/core/server';
|
||||
import { KibanaRequest, ElasticsearchClient } from 'src/core/server';
|
||||
|
||||
import { coreMock } from '../../../../../core/server/mocks';
|
||||
import { expressionsPluginMock } from '../../../../../plugins/expressions/server/mocks';
|
||||
|
@ -63,7 +63,8 @@ describe('AggsService - server', () => {
|
|||
expect(start).toHaveProperty('asScopedToClient');
|
||||
|
||||
const contract = await start.asScopedToClient(
|
||||
savedObjects.getScopedClient({} as KibanaRequest)
|
||||
savedObjects.getScopedClient({} as KibanaRequest),
|
||||
{} as ElasticsearchClient
|
||||
);
|
||||
expect(contract).toHaveProperty('calculateAutoTimeExpression');
|
||||
expect(contract).toHaveProperty('createAggConfigs');
|
||||
|
@ -74,7 +75,10 @@ describe('AggsService - server', () => {
|
|||
service.setup(setupDeps);
|
||||
const start = await service
|
||||
.start(startDeps)
|
||||
.asScopedToClient(savedObjects.getScopedClient({} as KibanaRequest));
|
||||
.asScopedToClient(
|
||||
savedObjects.getScopedClient({} as KibanaRequest),
|
||||
{} as ElasticsearchClient
|
||||
);
|
||||
|
||||
expect(start.types.get('terms').name).toBe('terms');
|
||||
});
|
||||
|
@ -83,7 +87,10 @@ describe('AggsService - server', () => {
|
|||
service.setup(setupDeps);
|
||||
const start = await service
|
||||
.start(startDeps)
|
||||
.asScopedToClient(savedObjects.getScopedClient({} as KibanaRequest));
|
||||
.asScopedToClient(
|
||||
savedObjects.getScopedClient({} as KibanaRequest),
|
||||
{} as ElasticsearchClient
|
||||
);
|
||||
|
||||
const aggTypes = getAggTypes();
|
||||
expect(start.types.getAll().buckets.length).toBe(aggTypes.buckets.length);
|
||||
|
@ -103,7 +110,10 @@ describe('AggsService - server', () => {
|
|||
|
||||
const start = await service
|
||||
.start(startDeps)
|
||||
.asScopedToClient(savedObjects.getScopedClient({} as KibanaRequest));
|
||||
.asScopedToClient(
|
||||
savedObjects.getScopedClient({} as KibanaRequest),
|
||||
{} as ElasticsearchClient
|
||||
);
|
||||
|
||||
const aggTypes = getAggTypes();
|
||||
expect(start.types.getAll().buckets.length).toBe(aggTypes.buckets.length + 1);
|
||||
|
|
|
@ -19,7 +19,11 @@
|
|||
|
||||
import { pick } from 'lodash';
|
||||
|
||||
import { UiSettingsServiceStart, SavedObjectsClientContract } from 'src/core/server';
|
||||
import {
|
||||
UiSettingsServiceStart,
|
||||
SavedObjectsClientContract,
|
||||
ElasticsearchClient,
|
||||
} from 'src/core/server';
|
||||
import { ExpressionsServiceSetup } from 'src/plugins/expressions/common';
|
||||
import {
|
||||
AggsCommonService,
|
||||
|
@ -65,7 +69,10 @@ export class AggsService {
|
|||
|
||||
public start({ fieldFormats, uiSettings, indexPatterns }: AggsStartDependencies): AggsStart {
|
||||
return {
|
||||
asScopedToClient: async (savedObjectsClient: SavedObjectsClientContract) => {
|
||||
asScopedToClient: async (
|
||||
savedObjectsClient: SavedObjectsClientContract,
|
||||
elasticsearchClient: ElasticsearchClient
|
||||
) => {
|
||||
const uiSettingsClient = uiSettings.asScopedToClient(savedObjectsClient);
|
||||
const formats = await fieldFormats.fieldFormatServiceFactory(uiSettingsClient);
|
||||
|
||||
|
@ -82,8 +89,9 @@ export class AggsService {
|
|||
types,
|
||||
} = this.aggsCommonService.start({
|
||||
getConfig,
|
||||
getIndexPattern: (await indexPatterns.indexPatternsServiceFactory(savedObjectsClient))
|
||||
.get,
|
||||
getIndexPattern: (
|
||||
await indexPatterns.indexPatternsServiceFactory(savedObjectsClient, elasticsearchClient)
|
||||
).get,
|
||||
isDefaultTimezone,
|
||||
});
|
||||
|
||||
|
|
|
@ -17,11 +17,14 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { SavedObjectsClientContract } from 'src/core/server';
|
||||
import { SavedObjectsClientContract, ElasticsearchClient } from 'src/core/server';
|
||||
import { AggsCommonSetup, AggsStart as Start } from '../../../common';
|
||||
|
||||
export type AggsSetup = AggsCommonSetup;
|
||||
|
||||
export interface AggsStart {
|
||||
asScopedToClient: (savedObjectsClient: SavedObjectsClientContract) => Promise<Start>;
|
||||
asScopedToClient: (
|
||||
savedObjectsClient: SavedObjectsClientContract,
|
||||
elasticsearchClient: ElasticsearchClient
|
||||
) => Promise<Start>;
|
||||
}
|
||||
|
|
|
@ -177,7 +177,11 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
|
|||
const { elasticsearch, savedObjects, uiSettings } = core;
|
||||
const asScoped = this.asScopedProvider(core);
|
||||
return {
|
||||
aggs: this.aggsService.start({ fieldFormats, uiSettings, indexPatterns }),
|
||||
aggs: this.aggsService.start({
|
||||
fieldFormats,
|
||||
uiSettings,
|
||||
indexPatterns,
|
||||
}),
|
||||
getSearchStrategy: this.getSearchStrategy,
|
||||
asScoped,
|
||||
searchSource: {
|
||||
|
@ -185,7 +189,8 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
|
|||
const esClient = elasticsearch.client.asScoped(request);
|
||||
const savedObjectsClient = savedObjects.getScopedClient(request);
|
||||
const scopedIndexPatterns = await indexPatterns.indexPatternsServiceFactory(
|
||||
savedObjectsClient
|
||||
savedObjectsClient,
|
||||
esClient.asCurrentUser
|
||||
);
|
||||
const uiSettingsClient = uiSettings.asScopedToClient(savedObjectsClient);
|
||||
|
||||
|
|
|
@ -17,7 +17,8 @@ import { CoreStart as CoreStart_2 } from 'kibana/server';
|
|||
import { Datatable } from 'src/plugins/expressions/common';
|
||||
import { DatatableColumn } from 'src/plugins/expressions';
|
||||
import { Duration } from 'moment';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'src/core/server';
|
||||
import { ElasticsearchClient as ElasticsearchClient_2 } from 'kibana/server';
|
||||
import { Ensure } from '@kbn/utility-types';
|
||||
import { EnvironmentMode } from '@kbn/config';
|
||||
import { ErrorToastOptions } from 'src/core/public/notifications';
|
||||
|
@ -389,6 +390,15 @@ 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)
|
||||
//
|
||||
|
@ -692,7 +702,7 @@ export const indexPatterns: {
|
|||
//
|
||||
// @public (undocumented)
|
||||
export class IndexPatternsFetcher {
|
||||
constructor(elasticsearchClient: ElasticsearchClient, allowNoIndices?: boolean);
|
||||
constructor(elasticsearchClient: ElasticsearchClient_2, allowNoIndices?: boolean);
|
||||
getFieldsForTimePattern(options: {
|
||||
pattern: string;
|
||||
metaFields: string[];
|
||||
|
@ -705,6 +715,8 @@ export class IndexPatternsFetcher {
|
|||
fieldCapsOptions?: {
|
||||
allow_no_indices: boolean;
|
||||
};
|
||||
type?: string;
|
||||
rollupIndex?: string;
|
||||
}): Promise<FieldDescriptor[]>;
|
||||
}
|
||||
|
||||
|
@ -719,7 +731,7 @@ export class IndexPatternsService implements Plugin_3<void, IndexPatternsService
|
|||
//
|
||||
// (undocumented)
|
||||
start(core: CoreStart_2, { fieldFormats, logger }: IndexPatternsServiceStartDeps): {
|
||||
indexPatternsServiceFactory: (savedObjectsClient: SavedObjectsClientContract_2) => Promise<IndexPatternsService_2>;
|
||||
indexPatternsServiceFactory: (savedObjectsClient: SavedObjectsClientContract_2, elasticsearchClient: ElasticsearchClient_2) => Promise<IndexPatternsService_2>;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -828,6 +840,15 @@ 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)
|
||||
|
@ -931,7 +952,7 @@ export class Plugin implements Plugin_2<PluginSetup, PluginStart, DataPluginSetu
|
|||
fieldFormatServiceFactory: (uiSettings: import("src/core/server").IUiSettingsClient) => Promise<import("../common").FieldFormatsRegistry>;
|
||||
};
|
||||
indexPatterns: {
|
||||
indexPatternsServiceFactory: (savedObjectsClient: Pick<import("src/core/server").SavedObjectsClient, "update" | "find" | "get" | "delete" | "errors" | "create" | "bulkCreate" | "checkConflicts" | "bulkGet" | "addToNamespaces" | "deleteFromNamespaces" | "bulkUpdate" | "removeReferencesTo">) => Promise<import("../common").IndexPatternsService>;
|
||||
indexPatternsServiceFactory: (savedObjectsClient: Pick<import("src/core/server").SavedObjectsClient, "update" | "find" | "get" | "delete" | "errors" | "create" | "bulkCreate" | "checkConflicts" | "bulkGet" | "addToNamespaces" | "deleteFromNamespaces" | "bulkUpdate" | "removeReferencesTo">, elasticsearchClient: import("src/core/server").ElasticsearchClient) => Promise<import("../common").IndexPatternsService>;
|
||||
};
|
||||
search: ISearchStart<import("./search").IEsSearchRequest, import("./search").IEsSearchResponse<any>>;
|
||||
};
|
||||
|
@ -1199,22 +1220,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:241:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:241:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:241:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:241:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:256:5 - (ae-forgotten-export) The symbol "getTotalLoaded" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:257:5 - (ae-forgotten-export) The symbol "toSnakeCase" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:261:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:262:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:271:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:272:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:273:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:277:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:278:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:282:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:285: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/index.ts:243:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:243:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:243:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:243:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:258:5 - (ae-forgotten-export) The symbol "getTotalLoaded" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:259:5 - (ae-forgotten-export) The symbol "toSnakeCase" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:263:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:264:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:273:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:274:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:275:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:279:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:280:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:284:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/server/index.ts:287: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/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:104:5 - (ae-forgotten-export) The symbol "ISearchStartSearchSource" needs to be exported by the entry point index.d.ts
|
||||
|
||||
|
|
|
@ -62,10 +62,12 @@ export async function getFields(
|
|||
let indexPatternString = indexPattern;
|
||||
|
||||
if (!indexPatternString) {
|
||||
const [{ savedObjects }, { data }] = await framework.core.getStartServices();
|
||||
const [{ savedObjects, elasticsearch }, { data }] = await framework.core.getStartServices();
|
||||
const savedObjectsClient = savedObjects.getScopedClient(request);
|
||||
const clusterClient = elasticsearch.client.asScoped(request).asCurrentUser;
|
||||
const indexPatternsService = await data.indexPatterns.indexPatternsServiceFactory(
|
||||
savedObjectsClient
|
||||
savedObjectsClient,
|
||||
clusterClient
|
||||
);
|
||||
const defaultIndexPattern = await indexPatternsService.getDefault();
|
||||
indexPatternString = get(defaultIndexPattern, 'title', '');
|
||||
|
|
|
@ -58,14 +58,16 @@ export class DataSearchTestPlugin
|
|||
},
|
||||
},
|
||||
async (context, req, res) => {
|
||||
const [{ savedObjects }, { data }] = await core.getStartServices();
|
||||
const [{ savedObjects, elasticsearch }, { 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
|
||||
savedObjectsClient,
|
||||
clusterClient
|
||||
);
|
||||
const ids = await indexPatterns.getIds();
|
||||
// @ts-expect-error Force overwriting the request
|
||||
|
|
|
@ -36,13 +36,35 @@ 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 }, { data }] = await core.getStartServices();
|
||||
const [{ savedObjects, elasticsearch }, { data }] = await core.getStartServices();
|
||||
const savedObjectsClient = savedObjects.getScopedClient(req);
|
||||
const service = await data.indexPatterns.indexPatternsServiceFactory(savedObjectsClient);
|
||||
const ids = await service.getIds();
|
||||
const service = await data.indexPatterns.indexPatternsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearch.client.asScoped(req).asCurrentUser
|
||||
);
|
||||
const ids = await service.getIds(true);
|
||||
return res.ok({ body: ids });
|
||||
}
|
||||
);
|
||||
|
@ -58,9 +80,12 @@ export class IndexPatternsTestPlugin
|
|||
},
|
||||
async (context, req, res) => {
|
||||
const id = (req.params as Record<string, string>).id;
|
||||
const [{ savedObjects }, { data }] = await core.getStartServices();
|
||||
const [{ savedObjects, elasticsearch }, { data }] = await core.getStartServices();
|
||||
const savedObjectsClient = savedObjects.getScopedClient(req);
|
||||
const service = await data.indexPatterns.indexPatternsServiceFactory(savedObjectsClient);
|
||||
const service = await data.indexPatterns.indexPatternsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearch.client.asScoped(req).asCurrentUser
|
||||
);
|
||||
const ip = await service.get(id);
|
||||
return res.ok({ body: ip.toSpec() });
|
||||
}
|
||||
|
@ -76,10 +101,13 @@ export class IndexPatternsTestPlugin
|
|||
},
|
||||
},
|
||||
async (context, req, res) => {
|
||||
const [{ savedObjects }, { data }] = await core.getStartServices();
|
||||
const [{ savedObjects, elasticsearch }, { 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);
|
||||
const service = await data.indexPatterns.indexPatternsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearch.client.asScoped(req).asCurrentUser
|
||||
);
|
||||
const ip = await service.get(id);
|
||||
await service.updateSavedObject(ip);
|
||||
return res.ok();
|
||||
|
@ -96,10 +124,13 @@ export class IndexPatternsTestPlugin
|
|||
},
|
||||
},
|
||||
async (context, req, res) => {
|
||||
const [{ savedObjects }, { data }] = await core.getStartServices();
|
||||
const [{ savedObjects, elasticsearch }, { 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);
|
||||
const service = await data.indexPatterns.indexPatternsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearch.client.asScoped(req).asCurrentUser
|
||||
);
|
||||
await service.delete(id);
|
||||
return res.ok();
|
||||
}
|
||||
|
|
|
@ -23,16 +23,25 @@ import '../../plugins/core_provider_plugin/types';
|
|||
export default function ({ getService }: PluginFunctionalProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
|
||||
// skipping the tests as it deletes index patterns created by other test causing unexpected failures
|
||||
// https://github.com/elastic/kibana/issues/79886
|
||||
describe.skip('index patterns', function () {
|
||||
describe('index patterns', function () {
|
||||
let indexPatternId = '';
|
||||
|
||||
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);
|
||||
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 index pattern by id', async () => {
|
||||
|
|
|
@ -161,9 +161,7 @@ export class RollupIndexPatternCreationConfig extends IndexPatternCreationConfig
|
|||
getFetchForWildcardOptions = () => {
|
||||
return {
|
||||
type: this.type,
|
||||
params: {
|
||||
rollup_index: this.rollupIndex,
|
||||
},
|
||||
rollupIndex: this.rollupIndex,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
/*
|
||||
* 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';
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -6,8 +6,11 @@
|
|||
import { keyBy, isString } from 'lodash';
|
||||
import { ILegacyScopedClusterClient } from 'src/core/server';
|
||||
import { ReqFacade } from '../../../../../../src/plugins/vis_type_timeseries/server';
|
||||
import { mergeCapabilitiesWithFields } from '../merge_capabilities_with_fields';
|
||||
import { getCapabilitiesForRollupIndices } from '../map_capabilities';
|
||||
|
||||
import {
|
||||
mergeCapabilitiesWithFields,
|
||||
getCapabilitiesForRollupIndices,
|
||||
} from '../../../../../../src/plugins/data/server';
|
||||
|
||||
const getRollupIndices = (rollupData: { [key: string]: any }) => Object.keys(rollupData);
|
||||
|
||||
|
|
|
@ -36,8 +36,7 @@ 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 './lib/map_capabilities';
|
||||
import { mergeCapabilitiesWithFields } from './lib/merge_capabilities_with_fields';
|
||||
import { getCapabilitiesForRollupIndices } from '../../../../src/plugins/data/server';
|
||||
|
||||
interface RollupContext {
|
||||
client: ILegacyScopedClusterClient;
|
||||
|
@ -107,7 +106,6 @@ export class RollupPlugin implements Plugin<void, void, any, any> {
|
|||
isEsError,
|
||||
formatEsError,
|
||||
getCapabilitiesForRollupIndices,
|
||||
mergeCapabilitiesWithFields,
|
||||
},
|
||||
sharedImports: {
|
||||
IndexPatternsFetcher,
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
|
@ -1,142 +0,0 @@
|
|||
/*
|
||||
* 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 });
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
|
@ -6,13 +6,11 @@
|
|||
|
||||
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);
|
||||
|
|
|
@ -8,6 +8,7 @@ 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';
|
||||
|
@ -15,8 +16,6 @@ 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;
|
||||
|
@ -33,7 +32,6 @@ export interface RouteDependencies {
|
|||
isEsError: typeof isEsError;
|
||||
formatEsError: typeof formatEsError;
|
||||
getCapabilitiesForRollupIndices: typeof getCapabilitiesForRollupIndices;
|
||||
mergeCapabilitiesWithFields: typeof mergeCapabilitiesWithFields;
|
||||
};
|
||||
sharedImports: {
|
||||
IndexPatternsFetcher: typeof IndexPatternsFetcher;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
export const API_BASE_PATH = '/api/rollup';
|
||||
export const INDEX_PATTERNS_EXTENSION_BASE_PATH = '/api/index_patterns/rollup';
|
||||
export const INDEX_PATTERNS_EXTENSION_BASE_PATH = '/api/index_patterns';
|
||||
export const ROLLUP_INDEX_NAME = 'rollup_index';
|
||||
export const INDEX_TO_ROLLUP_MAPPINGS = {
|
||||
properties: {
|
||||
|
|
|
@ -26,7 +26,6 @@ export default function ({ getService }) {
|
|||
describe('query params validation', () => {
|
||||
let uri;
|
||||
let body;
|
||||
let params;
|
||||
|
||||
it('"pattern" is required', async () => {
|
||||
uri = `${BASE_URI}`;
|
||||
|
@ -36,62 +35,17 @@ 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',
|
||||
params: JSON.stringify({ rollup_index: 'bar' }),
|
||||
type: 'rollup',
|
||||
rollup_index: 'bar',
|
||||
},
|
||||
{ sort: false }
|
||||
)}`;
|
||||
({ body } = await supertest.get(uri).expect(404));
|
||||
expect(body.message).to.contain('[index_not_found_exception] no such index [bar]');
|
||||
expect(body.message).to.contain('No indices match pattern "foo"');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -105,7 +59,8 @@ export default function ({ getService }) {
|
|||
// Query for wildcard
|
||||
const params = {
|
||||
pattern: indexName,
|
||||
params: JSON.stringify({ rollup_index: rollupIndex }),
|
||||
type: 'rollup',
|
||||
rollup_index: rollupIndex,
|
||||
};
|
||||
const uri = `${BASE_URI}?${stringify(params, { sort: false })}`;
|
||||
const { body } = await supertest.get(uri).expect(200);
|
||||
|
|
Loading…
Reference in a new issue