[Console] Support suggesting index templates v2 (#124655)

* Add autocomplete suggestions for index template api

* Add support for component templates

* Add unit tests

Co-authored-by: Muhammad Ibragimov <muhammad.ibragimov@elastic.co>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Muhammad Ibragimov 2022-02-15 13:58:41 +05:00 committed by GitHub
parent f5041b43ac
commit 75ac8e515b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 181 additions and 44 deletions

View file

@ -0,0 +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
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { getComponentTemplates } from '../../mappings/mappings';
import { ListComponent } from './list_component';
export class ComponentTemplateAutocompleteComponent extends ListComponent {
constructor(name, parent) {
super(name, getComponentTemplates, parent, true, true);
}
getContextKey() {
return 'component_template';
}
}

View file

@ -20,5 +20,7 @@ export { IndexAutocompleteComponent } from './index_autocomplete_component';
export { FieldAutocompleteComponent } from './field_autocomplete_component';
export { TypeAutocompleteComponent } from './type_autocomplete_component';
export { IdAutocompleteComponent } from './id_autocomplete_component';
export { TemplateAutocompleteComponent } from './template_autocomplete_component';
export { UsernameAutocompleteComponent } from './username_autocomplete_component';
export { IndexTemplateAutocompleteComponent } from './index_template_autocomplete_component';
export { ComponentTemplateAutocompleteComponent } from './component_template_autocomplete_component';
export * from './legacy';

View file

@ -6,14 +6,15 @@
* Side Public License, v 1.
*/
import { getTemplates } from '../../mappings/mappings';
import { getIndexTemplates } from '../../mappings/mappings';
import { ListComponent } from './list_component';
export class TemplateAutocompleteComponent extends ListComponent {
export class IndexTemplateAutocompleteComponent extends ListComponent {
constructor(name, parent) {
super(name, getTemplates, parent, true, true);
super(name, getIndexTemplates, parent, true, true);
}
getContextKey() {
return 'template';
return 'index_template';
}
}

View file

@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export { LegacyTemplateAutocompleteComponent } from './legacy_template_autocomplete_component';

View file

@ -0,0 +1,19 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { getLegacyTemplates } from '../../../mappings/mappings';
import { ListComponent } from '../list_component';
export class LegacyTemplateAutocompleteComponent extends ListComponent {
constructor(name, parent) {
super(name, getLegacyTemplates, parent, true, true);
}
getContextKey() {
return 'template';
}
}

View file

@ -12,8 +12,10 @@ import {
IndexAutocompleteComponent,
FieldAutocompleteComponent,
ListComponent,
TemplateAutocompleteComponent,
LegacyTemplateAutocompleteComponent,
UsernameAutocompleteComponent,
IndexTemplateAutocompleteComponent,
ComponentTemplateAutocompleteComponent,
} from '../autocomplete/components';
import $ from 'jquery';
@ -62,7 +64,7 @@ const parametrizedComponentFactories = {
return new UsernameAutocompleteComponent(name, parent);
},
template: function (name, parent) {
return new TemplateAutocompleteComponent(name, parent);
return new LegacyTemplateAutocompleteComponent(name, parent);
},
task_id: function (name, parent) {
return idAutocompleteComponentFactory(name, parent);
@ -86,6 +88,12 @@ const parametrizedComponentFactories = {
node: function (name, parent) {
return new ListComponent(name, [], parent, false);
},
index_template: function (name, parent) {
return new IndexTemplateAutocompleteComponent(name, parent);
},
component_template: function (name, parent) {
return new ComponentTemplateAutocompleteComponent(name, parent);
},
};
export function getUnmatchedEndpointComponents() {

View file

@ -240,4 +240,30 @@ describe('Mappings', () => {
]);
expect(mappings.expandAliases('alias2')).toEqual('test_index2');
});
test('Templates', function () {
mappings.loadLegacyTemplates({
test_index1: { order: 0 },
test_index2: { order: 0 },
test_index3: { order: 0 },
});
mappings.loadIndexTemplates({
index_templates: [{ name: 'test_index1' }, { name: 'test_index2' }, { name: 'test_index3' }],
});
mappings.loadComponentTemplates({
component_templates: [
{ name: 'test_index1' },
{ name: 'test_index2' },
{ name: 'test_index3' },
],
});
const expectedResult = ['test_index1', 'test_index2', 'test_index3'];
expect(mappings.getLegacyTemplates()).toEqual(expectedResult);
expect(mappings.getIndexTemplates()).toEqual(expectedResult);
expect(mappings.getComponentTemplates()).toEqual(expectedResult);
});
});

View file

@ -14,7 +14,9 @@ let pollTimeoutId;
let perIndexTypes = {};
let perAliasIndexes = [];
let templates = [];
let legacyTemplates = [];
let indexTemplates = [];
let componentTemplates = [];
const mappingObj = {};
@ -46,8 +48,16 @@ export function expandAliases(indicesOrAliases) {
return ret.length > 1 ? ret : ret[0];
}
export function getTemplates() {
return [...templates];
export function getLegacyTemplates() {
return [...legacyTemplates];
}
export function getIndexTemplates() {
return [...indexTemplates];
}
export function getComponentTemplates() {
return [...componentTemplates];
}
export function getFields(indices, types) {
@ -182,8 +192,16 @@ function getFieldNamesFromProperties(properties = {}) {
});
}
function loadTemplates(templatesObject = {}) {
templates = Object.keys(templatesObject);
export function loadLegacyTemplates(templatesObject = {}) {
legacyTemplates = Object.keys(templatesObject);
}
export function loadIndexTemplates(data) {
indexTemplates = (data.index_templates ?? []).map(({ name }) => name);
}
export function loadComponentTemplates(data) {
componentTemplates = (data.component_templates ?? []).map(({ name }) => name);
}
export function loadMappings(mappings) {
@ -235,14 +253,18 @@ export function loadAliases(aliases) {
export function clear() {
perIndexTypes = {};
perAliasIndexes = {};
templates = [];
legacyTemplates = [];
indexTemplates = [];
componentTemplates = [];
}
function retrieveSettings(settingsKey, settingsToRetrieve) {
const settingKeyToPathMap = {
fields: '_mapping',
indices: '_aliases',
templates: '_template',
legacyTemplates: '_template',
indexTemplates: '_index_template',
componentTemplates: '_component_template',
};
// Fetch autocomplete info if setting is set to true, and if user has made changes.
@ -289,36 +311,66 @@ export function clearSubscriptions() {
export function retrieveAutoCompleteInfo(settings, settingsToRetrieve) {
clearSubscriptions();
const templatesSettingToRetrieve = {
...settingsToRetrieve,
legacyTemplates: settingsToRetrieve.templates,
indexTemplates: settingsToRetrieve.templates,
componentTemplates: settingsToRetrieve.templates,
};
const mappingPromise = retrieveSettings('fields', settingsToRetrieve);
const aliasesPromise = retrieveSettings('indices', settingsToRetrieve);
const templatesPromise = retrieveSettings('templates', settingsToRetrieve);
const legacyTemplatesPromise = retrieveSettings('legacyTemplates', templatesSettingToRetrieve);
const indexTemplatesPromise = retrieveSettings('indexTemplates', templatesSettingToRetrieve);
const componentTemplatesPromise = retrieveSettings(
'componentTemplates',
templatesSettingToRetrieve
);
$.when(mappingPromise, aliasesPromise, templatesPromise).done((mappings, aliases, templates) => {
$.when(
mappingPromise,
aliasesPromise,
legacyTemplatesPromise,
indexTemplatesPromise,
componentTemplatesPromise
).done((mappings, aliases, legacyTemplates, indexTemplates, componentTemplates) => {
let mappingsResponse;
if (mappings) {
const maxMappingSize = mappings[0].length > 10 * 1024 * 1024;
if (maxMappingSize) {
console.warn(
`Mapping size is larger than 10MB (${mappings[0].length / 1024 / 1024} MB). Ignoring...`
);
mappingsResponse = '[{}]';
} else {
mappingsResponse = mappings[0];
try {
if (mappings && mappings.length) {
const maxMappingSize = mappings[0].length > 10 * 1024 * 1024;
if (maxMappingSize) {
console.warn(
`Mapping size is larger than 10MB (${mappings[0].length / 1024 / 1024} MB). Ignoring...`
);
mappingsResponse = '[{}]';
} else {
mappingsResponse = mappings[0];
}
loadMappings(JSON.parse(mappingsResponse));
}
loadMappings(JSON.parse(mappingsResponse));
}
if (aliases) {
loadAliases(JSON.parse(aliases[0]));
}
if (aliases) {
loadAliases(JSON.parse(aliases[0]));
}
if (templates) {
loadTemplates(JSON.parse(templates[0]));
}
if (legacyTemplates) {
loadLegacyTemplates(JSON.parse(legacyTemplates[0]));
}
if (mappings && aliases) {
// Trigger an update event with the mappings, aliases
$(mappingObj).trigger('update', [mappingsResponse, aliases[0]]);
if (indexTemplates) {
loadIndexTemplates(JSON.parse(indexTemplates[0]));
}
if (componentTemplates) {
loadComponentTemplates(JSON.parse(componentTemplates[0]));
}
if (mappings && aliases) {
// Trigger an update event with the mappings, aliases
$(mappingObj).trigger('update', [mappingsResponse, aliases[0]]);
}
} catch (error) {
console.error(error);
}
// Schedule next request.

View file

@ -8,7 +8,7 @@
"DELETE"
],
"patterns": [
"_component_template/{name}"
"_component_template/{component_template}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-component-template.html"
}

View file

@ -8,7 +8,7 @@
"HEAD"
],
"patterns": [
"_component_template/{name}"
"_component_template/{component_template}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-component-template.html"
}

View file

@ -10,7 +10,7 @@
],
"patterns": [
"_component_template",
"_component_template/{name}"
"_component_template/{component_template}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/getting-component-templates.html"
}

View file

@ -9,7 +9,7 @@
"POST"
],
"patterns": [
"_component_template/{name}"
"_component_template/{component_template}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-component-template.html"
}

View file

@ -8,7 +8,7 @@
"DELETE"
],
"patterns": [
"_index_template/{name}"
"_index_template/{index_template}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-templates.html"
}

View file

@ -9,7 +9,7 @@
"HEAD"
],
"patterns": [
"_index_template/{name}"
"_index_template/{index_template}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-templates.html"
}

View file

@ -10,7 +10,7 @@
],
"patterns": [
"_index_template",
"_index_template/{name}"
"_index_template/{index_template}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-templates.html"
}

View file

@ -10,7 +10,7 @@
"POST"
],
"patterns": [
"_index_template/{name}"
"_index_template/{index_template}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-templates.html"
}