[Console] Update dynamic parameters for the new script (#162917)

## Summary
Fixes https://github.com/elastic/kibana/issues/160539

This PR updates the logic for dynamic parameters in the Console
autocomplete engine in preparation for the new script.

#### Changes
- The old script `packages/spec-to-console` contained some logic that
would rename parameters in the json specs: `{index} -> {indices`},
`{node_id} -> {nodes}, {metric} -> {metrics}`. I don't think we need
this anymore because such logic only introduces more hidden mechanics to
the script. There is no significant improvements to autocomplete
suggestions due to these replacements.
- The dynamic parameters defined in the Console autocomplete engine: 
- `indices` - is deleted and only `index` is used instead. Originally,
there was a minor difference between `indices` and `index`: the former
should accept several index names, the latter only 1. [But this logic is
not working for urls currently
anyways](https://github.com/elastic/kibana/issues/163000). I don't think
there is a significant improvement for UX to keep this distinction. The
main useful feature of this parameter is to display a list of indices in
the deployment.
- `type` and `types` - deleted because `index mapping types` is a
removed ES feature (see this
[doc](https://www.elastic.co/guide/en/elasticsearch/reference/6.0/removal-of-types.html))
- `id`, `transform_id`, `ids`, `task_id` - deleted as not working. Also
definitions using these parameters don't intend them to be autofilled.
For example, in the url `/_async_search/{id}` the parameter `{id}` can
be any string.
- `user` and `username` - deleted as incorrectly being resolved to a
list of indices. Also definitions using these parameters don't intend
them to be autofilled, for example `_security/user/{username}` when
creating a new user.
  - `node` - delete because it was just an empty list
- `nodes` - deleted because the suggestions of the form `['_local',
'_master', 'data:true', 'data:false', 'master:true', 'master:false']`
are not correct for definitions where a node ID is expected.
- Renamed `variables` to `dynamic parameters` in the Console README
file: I first used the word `variables` in readme for the values defined
in the file
[`kb.js`](6e1445b66a/src/plugins/console/public/lib/kb/kb.js).
But then variables support was added to Console and there were several
sections in the readme using the word `variables` for different
concepts. Since in the autocomplete engine code, the function is called
`parametrizedComponentFactories` I think calling these values `dynamic
parameters` makes more sense and avoids confusion.

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Alison Goryachev <alisonmllr20@gmail.com>
This commit is contained in:
Yulia Čech 2023-08-04 15:42:41 +02:00 committed by GitHub
parent 11958042bf
commit 04b3d1741c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
132 changed files with 237 additions and 500 deletions

View file

@ -38,7 +38,7 @@
],
"patterns": [
"_cluster/health",
"_cluster/health/{indices}"
"_cluster/health/{index}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/cluster-health.html"
}

View file

@ -11,7 +11,7 @@ const replacePattern = require('../replace_pattern');
module.exports = (parts) => {
const result = {};
Object.keys(parts).forEach((part) => {
const key = replacePattern(part, { exact: true });
const key = replacePattern(part);
const options = parts[part].options;
if (options && options.length) {
result[key] = options.sort();

View file

@ -10,6 +10,6 @@ const replacePattern = require('../replace_pattern');
module.exports = (patterns) => {
return patterns.map((patternObject) => {
return replacePattern(patternObject.path, { brackets: true });
return replacePattern(patternObject.path);
});
};

View file

@ -6,20 +6,6 @@
* Side Public License, v 1.
*/
const map = require('./static/map_interpolation.json');
module.exports = (pattern, { brackets, exact } = {}) => {
let newPattern = pattern;
Object.keys(map).forEach((key) => {
const replaceFrom = brackets ? `{${key}}` : key;
const replaceTo = brackets ? `{${map[key]}}` : map[key];
if (exact) {
const exactMatch = replaceFrom === newPattern;
newPattern = exactMatch ? replaceTo : newPattern;
} else {
newPattern = newPattern.replace(replaceFrom, replaceTo);
}
});
return newPattern.replace(/^\//, '');
module.exports = (pattern) => {
return pattern.replace(/^\//, '');
};

View file

@ -1,5 +0,0 @@
{
"index": "indices",
"node_id": "nodes",
"metric": "metrics"
}

View file

@ -73,7 +73,8 @@ Url to Elasticsearch REST API documentation for the endpoint (If the url contain
Allowed http methods (`GET`, `POST` etc)
#### `patterns`
Array of API endpoints that contain variables like `{indices}` or `{fields}`. For example, `{indices}/_rollup/{rollup_index}`. See the [Variables](#variables) section below for more info.
Array of API endpoints that contain dynamic parameters like `{index}` or `{fields}`. For example, `{index}/_rollup/{rollup_index}`. Dynamic parameters used in patterns are not always defined. For example, a pattern `_ilm/policy/{policy}` indicates that any string can be used as policy name.
See the [Dynamic parameters](#dynamic-parameters) section below for more info about dynamic parameters defined in the autocomplete engine, such as `{index}`.
#### `url_params`
Query url parameters and their values. See the [Query url parameters](#query-url-parameters) section below for more info. An example:
@ -141,7 +142,7 @@ GET /_some_endpoint?expand_wildcards=hi
```
"hidden" is displayed for autocompletion.
Variables such as `{indices}` or `{fields}` are accepted both as an url parameter and its value in the configuration object. See the [Variables](#variables) section below for more information.
Dynamic parameters such as `{index}` or `{fields}` are accepted both as an url parameter and its value in the configuration object. See the [Dynamic parameters](#dynamic-parameters) section below for more information.
### Request body parameters
Request body parameters are configured in form of an object, for example:
@ -175,7 +176,20 @@ PUT /_some_endpoint
```
Object's values can contain objects for nested configuration because the engine can work recursively while searching for autocomplete suggestions.
Following values can be used in the configuration object:
Upper case strings are used to indicate that the property's name is a dynamic value that the user needs to define. For example, the autocomplete suggestion for aggregations displays the following object:
```json
{
"aggs": {
"NAME": {
"AGG_TYPE": {}
}
}
}
```
Both upper case strings `NAME` and `AGG_TYPE` indicate that those values need to be filled in by the user.
**Following values can be used in the configuration object:**
#### One value from the list (`__one_of: [..., ...]`)
Use this configuration for a parameter with a list of allowed values, for example types of snapshot repository:
```
@ -262,11 +276,24 @@ For example:
To provide a different set of autocomplete suggestions based on the value configured in the request. For example, when creating a snapshot repository of different types (`fs`, `url` etc) different properties are displayed in the suggestions list based on the type. See [snapshot.create_repository.json](https://github.com/elastic/kibana/blob/main/src/plugins/console/server/lib/spec_definitions/json/overrides/snapshot.create_repository.json) for an example.
### Variables
### Dynamic parameters
Some autocomplete definitions need to be configured with dynamic values that can't be hard coded into a json or js file, for example a list of indices in the cluster.
A list of variables is defined in the `parametrizedComponentFactories` function in [`kb.js`](https://github.com/elastic/kibana/blob/main/src/plugins/console/public/lib/kb/kb.js) file. The values of these variables are assigned dynamically for every cluster.
Use these variables with curly braces, for example `{indices}`, `{types}`, `{id}`, `{username}`, `{template}`, `{nodes}` etc.
A list of dynamic parameters is defined in the `parametrizedComponentFactories` function in [`kb.js`](https://github.com/elastic/kibana/blob/main/src/plugins/console/public/lib/kb/kb.js) file. The values of these parameters are assigned dynamically for every cluster.
Use these dynamic parameters with curly braces, for example `{index}`, `{fields}`, `{template}` etc.
Dynamic parameters can be used in url patterns, for example `{index}/_search`. Url patterns can also contain unknown parameters just to indicate that any value can be used in the url, for example in the url `/_ilm/policy/{policy}` the value for `{policy}` can be any accepted policy name and the dynamic parameter `{policy}` is not defined in the autocomplete engine.
For request body parameters, only known dynamic properties are allowed. For example:
```json
{
"data_autocomplete_rules": {
"query": {
"field": "{field}"
}
}
}
```
If an unknown dynamic parameter (for example, `{my_param}`) is used in request body parameters, a warning will be logged in the browser: `[Console] no factory found for 'my_param'`.
### Architecture changes in 8.3 release (timeline: 07-04-2022 - 19-06-2022)
One of the main changes in architecture is refactoring the retrieval of autocomplete suggestions. Console used to send a separate request to ES for each autocomplete entity (mappings, aliases, templates, data-streams etc) to retrieve the autocomplete suggestions via the original [hand-rolled ES proxy](https://github.com/elastic/kibana/blob/main/src/plugins/console/server/routes/api/console/proxy/create_handler.ts). This had a few drawbacks:

View file

@ -196,7 +196,7 @@ describe('Integration', () => {
endpoints: {
_search: {
methods: ['GET', 'POST'],
patterns: ['{indices}/_search', '_search'],
patterns: ['{index}/_search', '_search'],
data_autocomplete_rules: {
query: {
match_all: {},
@ -948,6 +948,8 @@ describe('Integration', () => {
autoCompleteSet: [
tt('field1.1.1', { f: 1 }, 'string'),
tt('field1.1.2', { f: 1 }, 'string'),
tt('field2.1.1', { f: 1 }, 'string'),
tt('field2.1.2', { f: 1 }, 'string'),
],
},
{
@ -956,6 +958,8 @@ describe('Integration', () => {
autoCompleteSet: [
{ name: 'field1.1.1', meta: 'string' },
{ name: 'field1.1.2', meta: 'string' },
{ name: 'field2.1.1', meta: 'string' },
{ name: 'field2.1.2', meta: 'string' },
],
},
]
@ -996,7 +1000,7 @@ describe('Integration', () => {
const CLUSTER_KB = {
endpoints: {
_search: {
patterns: ['_search', '{indices}/_search'],
patterns: ['_search', '{index}/_search'],
url_params: {
search_type: ['count', 'query_then_fetch'],
scroll: '10m',

View file

@ -204,7 +204,9 @@ function compileParametrizedValue(value, compilingContext, template) {
value = value.substr(1, value.length - 2).toLowerCase();
let component = compilingContext.parametrizedComponentFactories.getComponent(value, true);
if (!component) {
throw new Error("no factory found for '" + value + "'");
console.warn("[Console] no factory found for '" + value + "'");
// using upper case as an indication that this value is a parameter
return new ConstantComponent(value.toUpperCase());
}
component = component(value, null, template);
if (!_.isUndefined(template)) {
@ -279,7 +281,7 @@ export function globalsOnlyAutocompleteComponents() {
* @param endpointComponentResolver a function (endpoint,context,editor) which should resolve an endpoint
* to it's list of compiled components.
* @param parametrizedComponentFactories a dict of the following structure
* that will be used as a fall back for pattern keys (i.e.: {type} ,resolved without the $s)
* that will be used as a fall back for pattern keys (i.e.: {index}, resolved without the {})
* {
* TYPE: function (part, parent, endpoint) {
* return new SharedComponent(part, parent)

View file

@ -1,36 +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
* 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 _ from 'lodash';
import { SharedComponent } from './shared_component';
export class IdAutocompleteComponent extends SharedComponent {
constructor(name, parent, multi) {
super(name, parent);
this.multi_match = multi;
}
match(token, context, editor) {
if (!token) {
return null;
}
if (!this.multi_match && Array.isArray(token)) {
return null;
}
token = Array.isArray(token) ? token : [token];
if (
_.find(token, function (t) {
return t.match(/[\/,]/);
})
) {
return null;
}
const r = super.match(token, context, editor);
r.context_values = r.context_values || {};
r.context_values.id = token;
return r;
}
}

View file

@ -18,9 +18,6 @@ export { AcceptEndpointComponent, URL_PATH_END_MARKER } from './accept_endpoint_
export { UrlPatternMatcher } from './url_pattern_matcher';
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 { UsernameAutocompleteComponent } from './username_autocomplete_component';
export { IndexTemplateAutocompleteComponent } from './index_template_autocomplete_component';
export { ComponentTemplateAutocompleteComponent } from './component_template_autocomplete_component';
export { DataStreamAutocompleteComponent } from './data_stream_autocomplete_component';

View file

@ -24,12 +24,4 @@ export class IndexAutocompleteComponent extends ListComponent {
}
return !_.find(tokens, nonValidIndexType);
}
getDefaultTermMeta() {
return 'index';
}
getContextKey() {
return 'indices';
}
}

View file

@ -1,37 +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
* 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 _ from 'lodash';
import { ListComponent } from './list_component';
import { getTypes } from '../../autocomplete_entities';
function TypeGenerator(context) {
return getTypes(context.indices);
}
function nonValidIndexType(token) {
return !(token === '_all' || token[0] !== '_');
}
export class TypeAutocompleteComponent extends ListComponent {
constructor(name, parent, multiValued) {
super(name, TypeGenerator, parent, multiValued);
}
validateTokens(tokens) {
if (!this.multiValued && tokens.length > 1) {
return false;
}
return !_.find(tokens, nonValidIndexType);
}
getDefaultTermMeta() {
return 'type';
}
getContextKey() {
return 'types';
}
}

View file

@ -19,7 +19,7 @@ import { FullRequestComponent } from './full_request_component';
/**
* @param parametrizedComponentFactories a dict of the following structure
* that will be used as a fall back for pattern parameters (i.e.: {indices})
* that will be used as a fall back for pattern parameters (i.e.: {index})
* {
* indices: function (part, parent) {
* return new SharedComponent(part, parent)

View file

@ -1,35 +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
* 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 _ from 'lodash';
import { getAutocompleteInfo, ENTITIES } from '../../../services';
import { ListComponent } from './list_component';
function nonValidUsernameType(token) {
return token[0] === '_';
}
export class UsernameAutocompleteComponent extends ListComponent {
constructor(name, parent, multiValued) {
super(name, getAutocompleteInfo().getEntityProvider(ENTITIES.INDICES), parent, multiValued);
}
validateTokens(tokens) {
if (!this.multiValued && tokens.length > 1) {
return false;
}
return !_.find(tokens, nonValidUsernameType);
}
getDefaultTermMeta() {
return 'username';
}
getContextKey() {
return 'username';
}
}

View file

@ -12,4 +12,3 @@ export { DataStream } from './data_stream';
export { LegacyTemplate } from './legacy';
export { IndexTemplate } from './index_template';
export { ComponentTemplate } from './component_template';
export { getTypes } from './type';

View file

@ -1,44 +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
* 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 _ from 'lodash';
import { getAutocompleteInfo } from '../../services';
import { expandAliases } from './expand_aliases';
export function getTypes(indices: string | string[]) {
let ret: string[] = [];
const perIndexTypes = getAutocompleteInfo().mapping.perIndexTypes;
indices = expandAliases(indices);
if (typeof indices === 'string') {
const typeDict = perIndexTypes[indices];
if (!typeDict) {
return [];
}
// filter what we need
if (Array.isArray(typeDict)) {
typeDict.forEach((type) => {
ret.push(type);
});
} else if (typeof typeDict === 'object') {
Object.keys(typeDict).forEach((type) => {
ret.push(type);
});
}
} else {
// multi index mode.
Object.keys(perIndexTypes).forEach((index) => {
if (!indices || indices.includes(index)) {
ret.push(getTypes(index) as unknown as string);
}
});
ret = ([] as string[]).concat.apply([], ret);
}
return _.uniq(ret);
}

View file

@ -17,7 +17,7 @@ import {
/**
*
* @param urlParametrizedComponentFactories a dictionary of factory functions
* that will be used as fallback for parametrized path part (i.e., {indices} )
* that will be used as fallback for parametrized path part (i.e., {index} )
* see UrlPatternMatcher
* @constructor
* @param bodyParametrizedComponentFactories same as urlParametrizedComponentFactories but used for body compilation

View file

@ -7,13 +7,10 @@
*/
import {
TypeAutocompleteComponent,
IdAutocompleteComponent,
IndexAutocompleteComponent,
FieldAutocompleteComponent,
ListComponent,
LegacyTemplateAutocompleteComponent,
UsernameAutocompleteComponent,
IndexTemplateAutocompleteComponent,
ComponentTemplateAutocompleteComponent,
DataStreamAutocompleteComponent,
@ -27,74 +24,38 @@ import Api from './api';
let ACTIVE_API = new Api();
const isNotAnIndexName = (name) => name[0] === '_' && name !== '_all';
const idAutocompleteComponentFactory = (name, parent) => {
return new IdAutocompleteComponent(name, parent);
};
const parametrizedComponentFactories = {
getComponent: function (name, parent, provideDefault) {
if (this[name]) {
return this[name];
} else if (provideDefault) {
return idAutocompleteComponentFactory;
return new ListComponent(name, [], parent, false);
}
},
index: function (name, parent) {
if (isNotAnIndexName(name)) return;
return new IndexAutocompleteComponent(name, parent, false);
},
indices: function (name, parent) {
if (isNotAnIndexName(name)) return;
return new IndexAutocompleteComponent(name, parent, true);
},
type: function (name, parent) {
return new TypeAutocompleteComponent(name, parent, false);
},
types: function (name, parent) {
return new TypeAutocompleteComponent(name, parent, true);
},
id: function (name, parent) {
return idAutocompleteComponentFactory(name, parent);
},
transform_id: function (name, parent) {
return idAutocompleteComponentFactory(name, parent);
},
username: function (name, parent) {
return new UsernameAutocompleteComponent(name, parent);
},
user: function (name, parent) {
return new UsernameAutocompleteComponent(name, parent);
},
template: function (name, parent) {
return new LegacyTemplateAutocompleteComponent(name, parent);
},
task_id: function (name, parent) {
return idAutocompleteComponentFactory(name, parent);
},
ids: function (name, parent) {
return idAutocompleteComponentFactory(name, parent, true);
},
fields: function (name, parent) {
return new FieldAutocompleteComponent(name, parent, true);
},
field: function (name, parent) {
return new FieldAutocompleteComponent(name, parent, false);
},
nodes: function (name, parent) {
return new ListComponent(
name,
['_local', '_master', 'data:true', 'data:false', 'master:true', 'master:false'],
parent
);
},
node: function (name, parent) {
return new ListComponent(name, [], parent, false);
// legacy index templates
template: function (name, parent) {
return new LegacyTemplateAutocompleteComponent(name, parent);
},
// composable index templates
// currently seems to be unused, but that is a useful functionality
index_template: function (name, parent) {
return new IndexTemplateAutocompleteComponent(name, parent);
},
// currently seems to be unused, but that is a useful functionality
component_template: function (name, parent) {
return new ComponentTemplateAutocompleteComponent(name, parent);
},
// currently seems to be unused, but that is a useful functionality
data_stream: function (name, parent) {
return new DataStreamAutocompleteComponent(name, parent);
},
@ -129,23 +90,27 @@ function loadApisFromJson(
urlParametrizedComponentFactories,
bodyParametrizedComponentFactories
) {
urlParametrizedComponentFactories =
urlParametrizedComponentFactories || parametrizedComponentFactories;
bodyParametrizedComponentFactories =
bodyParametrizedComponentFactories || urlParametrizedComponentFactories;
const api = new Api(urlParametrizedComponentFactories, bodyParametrizedComponentFactories);
const names = [];
_.each(json, function (apiJson, name) {
names.unshift(name);
_.each(apiJson.globals || {}, function (globalJson, globalName) {
api.addGlobalAutocompleteRules(globalName, globalJson);
try {
urlParametrizedComponentFactories =
urlParametrizedComponentFactories || parametrizedComponentFactories;
bodyParametrizedComponentFactories =
bodyParametrizedComponentFactories || urlParametrizedComponentFactories;
const api = new Api(urlParametrizedComponentFactories, bodyParametrizedComponentFactories);
const names = [];
_.each(json, function (apiJson, name) {
names.unshift(name);
_.each(apiJson.globals || {}, function (globalJson, globalName) {
api.addGlobalAutocompleteRules(globalName, globalJson);
});
_.each(apiJson.endpoints || {}, function (endpointJson, endpointName) {
api.addEndpointDescription(endpointName, endpointJson);
});
});
_.each(apiJson.endpoints || {}, function (endpointJson, endpointName) {
api.addEndpointDescription(endpointName, endpointJson);
});
});
api.name = names.join(',');
return api;
api.name = names.join(',');
return api;
} catch (e) {
console.error(e);
}
}
// TODO: clean up setting up of active API and use of jQuery.

View file

@ -29,22 +29,15 @@ describe('Knowledge base', () => {
const MAPPING = {
index1: {
'type1.1': {
properties: {
'field1.1.1': { type: 'string' },
'field1.1.2': { type: 'long' },
},
},
'type1.2': {
properties: {},
properties: {
'field1.1.1': { type: 'string' },
'field1.1.2': { type: 'long' },
},
},
index2: {
'type2.1': {
properties: {
'field2.1.1': { type: 'string' },
'field2.1.2': { type: 'string' },
},
properties: {
'field2.1.1': { type: 'string' },
'field2.1.2': { type: 'string' },
},
},
};
@ -95,10 +88,6 @@ describe('Knowledge base', () => {
expect(context).toEqual(expectedContext);
}
function t(term) {
return { name: term, meta: 'type' };
}
function i(term) {
return { name: term, meta: 'index' };
}
@ -111,7 +100,7 @@ describe('Knowledge base', () => {
indexTest: {
endpoints: {
_multi_indices: {
patterns: ['{indices}/_multi_indices'],
patterns: ['{index}/_multi_indices'],
},
_single_index: { patterns: ['{index}/_single_index'] },
_no_index: {
@ -144,71 +133,12 @@ describe('Knowledge base', () => {
);
indexTest('Index integration 2', ['index1'], [], {
indices: ['index1'],
index: ['index1'],
autoCompleteSet: ['_multi_indices', '_single_index'],
});
indexTest('Index integration 2', [['index1', 'index2']], [], {
indices: ['index1', 'index2'],
autoCompleteSet: ['_multi_indices'],
index: ['index1', 'index2'],
autoCompleteSet: ['_multi_indices', '_single_index'],
});
function typeTest(name, tokenPath, otherTokenValues, expectedContext) {
test(name, function () {
const testApi = kb._test.loadApisFromJson(
{
typeTest: {
endpoints: {
_multi_types: { patterns: ['{indices}/{types}/_multi_types'] },
_single_type: { patterns: ['{indices}/{type}/_single_type'] },
_no_types: { patterns: ['{indices}/_no_types'] },
},
},
},
kb._test.globalUrlComponentFactories
);
kb.setActiveApi(testApi);
autocompleteInfo.mapping.loadMappings(MAPPING);
testUrlContext(tokenPath, otherTokenValues, expectedContext);
});
}
typeTest('Type integration 1', ['index1'], [], {
indices: ['index1'],
autoCompleteSet: ['_no_types', t('type1.1'), t('type1.2')],
});
typeTest(
'Type integration 2',
['index1'],
['type1.2'],
// we are not yet comitted to type1.2, so _no_types is returned
{ indices: ['index1'], autoCompleteSet: ['_no_types', t('type1.1')] }
);
typeTest('Type integration 3', ['index2'], [], {
indices: ['index2'],
autoCompleteSet: ['_no_types', t('type2.1')],
});
typeTest('Type integration 4', ['index1', 'type1.2'], [], {
indices: ['index1'],
types: ['type1.2'],
autoCompleteSet: ['_multi_types', '_single_type'],
});
typeTest(
'Type integration 5',
[
['index1', 'index2'],
['type1.2', 'type1.1'],
],
[],
{
indices: ['index1', 'index2'],
types: ['type1.2', 'type1.1'],
autoCompleteSet: ['_multi_types'],
}
);
});

View file

@ -36,7 +36,6 @@ filters.ids = {
__template: {
values: ['ID'],
},
type: '{type}',
values: [''],
};
@ -175,7 +174,6 @@ filters.geo_shape = {
indexed_shape: {
id: '',
index: '{index}',
type: '{type}',
shape_field_name: 'shape',
},
relation: {
@ -189,7 +187,7 @@ filters.has_child = {
type: 'TYPE',
filter: {},
},
type: '{type}',
type: '',
query: {},
filter: {},
_scope: '',
@ -202,7 +200,7 @@ filters.has_parent = {
parent_type: 'TYPE',
filter: {},
},
parent_type: '{type}',
parent_type: '',
query: {},
filter: {},
_scope: '',

View file

@ -34,12 +34,6 @@ export const mappings = (specService: SpecDefinitionsService) => {
_index: {
enabled: BOOLEAN,
},
_parent: {
__template: {
type: '',
},
type: '{type}',
},
_timestamp: {
enabled: BOOLEAN,
format: 'YYYY-MM-dd',
@ -224,7 +218,7 @@ export const mappings = (specService: SpecDefinitionsService) => {
// objects
properties: {
__scope_link: 'put_mapping.{type}.properties',
__scope_link: 'put_mapping.type.properties',
},
// multi_field

View file

@ -360,7 +360,7 @@ export const query = (specService: SpecDefinitionsService) => {
query: {},
},
inner_hits: { ...innerHits },
type: '{type}',
type: '',
score_mode: {
__one_of: ['none', 'max', 'sum', 'avg'],
},
@ -374,7 +374,7 @@ export const query = (specService: SpecDefinitionsService) => {
parent_type: 'TYPE',
query: {},
},
parent_type: '{type}',
parent_type: '',
score_mode: {
__one_of: ['none', 'score'],
},
@ -407,7 +407,6 @@ export const query = (specService: SpecDefinitionsService) => {
docs: [
{
_index: '{index}',
_type: '{type}',
_id: '',
},
],

View file

@ -64,7 +64,7 @@
],
"patterns": [
"_async_search",
"{indices}/_async_search"
"{index}/_async_search"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/async-search.html"
}

View file

@ -22,7 +22,7 @@
],
"patterns": [
"_bulk",
"{indices}/_bulk"
"{index}/_bulk"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/docs-bulk.html"
}

View file

@ -27,7 +27,7 @@
],
"patterns": [
"_cat/allocation",
"_cat/allocation/{nodes}"
"_cat/allocation/{node_id}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/cat-allocation.html"
}

View file

@ -12,7 +12,7 @@
],
"patterns": [
"_cat/count",
"_cat/count/{indices}"
"_cat/count/{index}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/cat-count.html"
}

View file

@ -49,7 +49,7 @@
],
"patterns": [
"_cat/indices",
"_cat/indices/{indices}"
"_cat/indices/{index}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/cat-indices.html"
}

View file

@ -37,7 +37,7 @@
],
"patterns": [
"_cat/recovery",
"_cat/recovery/{indices}"
"_cat/recovery/{index}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/cat-recovery.html"
}

View file

@ -25,7 +25,7 @@
],
"patterns": [
"_cat/segments",
"_cat/segments/{indices}"
"_cat/segments/{index}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/cat-segments.html"
}

View file

@ -35,7 +35,7 @@
],
"patterns": [
"_cat/shards",
"_cat/shards/{indices}"
"_cat/shards/{index}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/cat-shards.html"
}

View file

@ -7,7 +7,7 @@
"PUT"
],
"patterns": [
"{indices}/_ccr/follow"
"{index}/_ccr/follow"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-put-follow.html"
}

View file

@ -4,7 +4,7 @@
"GET"
],
"patterns": [
"{indices}/_ccr/info"
"{index}/_ccr/info"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-info.html"
}

View file

@ -4,7 +4,7 @@
"GET"
],
"patterns": [
"{indices}/_ccr/stats"
"{index}/_ccr/stats"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-stats.html"
}

View file

@ -4,7 +4,7 @@
"POST"
],
"patterns": [
"{indices}/_ccr/forget_follower"
"{index}/_ccr/forget_follower"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-post-forget-follower.html"
}

View file

@ -4,7 +4,7 @@
"POST"
],
"patterns": [
"{indices}/_ccr/pause_follow"
"{index}/_ccr/pause_follow"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-post-pause-follow.html"
}

View file

@ -4,7 +4,7 @@
"POST"
],
"patterns": [
"{indices}/_ccr/resume_follow"
"{index}/_ccr/resume_follow"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-post-resume-follow.html"
}

View file

@ -4,7 +4,7 @@
"POST"
],
"patterns": [
"{indices}/_ccr/unfollow"
"{index}/_ccr/unfollow"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-post-unfollow.html"
}

View file

@ -39,7 +39,7 @@
],
"patterns": [
"_cluster/health",
"_cluster/health/{indices}"
"_cluster/health/{index}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/cluster-health.html"
}

View file

@ -21,11 +21,11 @@
],
"patterns": [
"_cluster/state",
"_cluster/state/{metrics}",
"_cluster/state/{metrics}/{indices}"
"_cluster/state/{metric}",
"_cluster/state/{metric}/{index}"
],
"url_components": {
"metrics": [
"metric": [
"_all",
"blocks",
"master_node",
@ -35,7 +35,7 @@
"routing_table",
"version"
],
"indices": null
"index": null
},
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/cluster-state.html"
}

View file

@ -9,7 +9,7 @@
],
"patterns": [
"_cluster/stats",
"_cluster/stats/nodes/{nodes}"
"_cluster/stats/nodes/{node_id}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/cluster-stats.html"
}

View file

@ -31,7 +31,7 @@
],
"patterns": [
"_count",
"{indices}/_count"
"{index}/_count"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/search-count.html"
}

View file

@ -22,7 +22,7 @@
"POST"
],
"patterns": [
"{indices}/_create/{id}"
"{index}/_create/{id}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/docs-index_.html"
}

View file

@ -22,7 +22,7 @@
"DELETE"
],
"patterns": [
"{indices}/_doc/{id}"
"{index}/_doc/{id}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/docs-delete.html"
}

View file

@ -50,7 +50,7 @@
"POST"
],
"patterns": [
"{indices}/_delete_by_query"
"{index}/_delete_by_query"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/docs-delete-by-query.html"
}

View file

@ -10,7 +10,7 @@
"POST"
],
"patterns": [
"{indices}/_eql/search"
"{index}/_eql/search"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/eql-search-api.html"
}

View file

@ -20,7 +20,7 @@
"HEAD"
],
"patterns": [
"{indices}/_doc/{id}"
"{index}/_doc/{id}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/docs-get.html"
}

View file

@ -19,7 +19,7 @@
"HEAD"
],
"patterns": [
"{indices}/_source/{id}"
"{index}/_source/{id}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/docs-get.html"
}

View file

@ -22,7 +22,7 @@
"POST"
],
"patterns": [
"{indices}/_explain/{id}"
"{index}/_explain/{id}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/search-explain.html"
}

View file

@ -21,7 +21,7 @@
],
"patterns": [
"_field_caps",
"{indices}/_field_caps"
"{index}/_field_caps"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/search-field-caps.html"
}

View file

@ -10,7 +10,7 @@
"GET"
],
"patterns": [
"{indices}/_fleet/global_checkpoints"
"{index}/_fleet/global_checkpoints"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/get-global-checkpoints.html"
}

View file

@ -6,7 +6,7 @@
],
"patterns": [
"_fleet/_fleet_msearch",
"{indices}/_fleet/_fleet_msearch"
"{index}/_fleet/_fleet_msearch"
]
}
}

View file

@ -10,7 +10,7 @@
"POST"
],
"patterns": [
"{indices}/_fleet/_fleet_search"
"{index}/_fleet/_fleet_search"
]
}
}

View file

@ -21,7 +21,7 @@
"GET"
],
"patterns": [
"{indices}/_doc/{id}"
"{index}/_doc/{id}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/docs-get.html"
}

View file

@ -19,7 +19,7 @@
"GET"
],
"patterns": [
"{indices}/_source/{id}"
"{index}/_source/{id}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/docs-get.html"
}

View file

@ -9,7 +9,7 @@
"POST"
],
"patterns": [
"{indices}/_graph/explore"
"{index}/_graph/explore"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/graph-explore-api.html"
}

View file

@ -8,7 +8,7 @@
"GET"
],
"patterns": [
"{indices}/_ilm/explain"
"{index}/_ilm/explain"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/ilm-explain-lifecycle.html"
}

View file

@ -4,7 +4,7 @@
"POST"
],
"patterns": [
"_ilm/move/{indices}"
"_ilm/move/{index}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/ilm-move-to-step.html"
}

View file

@ -4,7 +4,7 @@
"POST"
],
"patterns": [
"{indices}/_ilm/remove"
"{index}/_ilm/remove"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/ilm-remove-policy.html"
}

View file

@ -4,7 +4,7 @@
"POST"
],
"patterns": [
"{indices}/_ilm/retry"
"{index}/_ilm/retry"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/ilm-retry-policy.html"
}

View file

@ -29,8 +29,8 @@
"POST"
],
"patterns": [
"{indices}/_doc/{id}",
"{indices}/_doc"
"{index}/_doc/{id}",
"{index}/_doc"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/docs-index_.html"
}

View file

@ -17,7 +17,7 @@
"PUT"
],
"patterns": [
"{indices}/_block/{block}"
"{index}/_block/{block}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/index-modules-blocks.html"
}

View file

@ -9,7 +9,7 @@
],
"patterns": [
"_analyze",
"{indices}/_analyze"
"{index}/_analyze"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-analyze.html"
}

View file

@ -21,7 +21,7 @@
],
"patterns": [
"_cache/clear",
"{indices}/_cache/clear"
"{index}/_cache/clear"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-clearcache.html"
}

View file

@ -10,7 +10,7 @@
"POST"
],
"patterns": [
"{indices}/_clone/{target}"
"{index}/_clone/{target}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-clone-index.html"
}

View file

@ -18,7 +18,7 @@
"POST"
],
"patterns": [
"{indices}/_close"
"{index}/_close"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-open-close.html"
}

View file

@ -9,7 +9,7 @@
"PUT"
],
"patterns": [
"{indices}"
"{index}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-create-index.html"
}

View file

@ -17,7 +17,7 @@
"DELETE"
],
"patterns": [
"{indices}"
"{index}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-delete-index.html"
}

View file

@ -8,8 +8,8 @@
"DELETE"
],
"patterns": [
"{indices}/_alias/{name}",
"{indices}/_aliases/{name}"
"{index}/_alias/{name}",
"{index}/_aliases/{name}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-aliases.html"
}

View file

@ -17,6 +17,6 @@
"patterns": [
"_data_stream/{name}/_lifecycle"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/dlm-delete-lifecycle.html"
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/data-streams-delete-lifecycle.html"
}
}

View file

@ -17,7 +17,7 @@
"POST"
],
"patterns": [
"{indices}/_disk_usage"
"{index}/_disk_usage"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-disk-usage.html"
}

View file

@ -4,7 +4,7 @@
"POST"
],
"patterns": [
"{indices}/_downsample/{target_index}"
"{index}/_downsample/{target_index}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/xpack-rollup.html"
}

View file

@ -18,7 +18,7 @@
"HEAD"
],
"patterns": [
"{indices}"
"{index}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-exists.html"
}

View file

@ -17,7 +17,7 @@
],
"patterns": [
"_alias/{name}",
"{indices}/_alias/{name}"
"{index}/_alias/{name}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-aliases.html"
}

View file

@ -8,8 +8,8 @@
"GET"
],
"patterns": [
"{indices}/_lifecycle/explain"
"{index}/_lifecycle/explain"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/dlm-explain-lifecycle.html"
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/data-streams-explain-lifecycle.html"
}
}

View file

@ -16,7 +16,7 @@
"GET"
],
"patterns": [
"{indices}/_field_usage_stats"
"{index}/_field_usage_stats"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/field-usage-stats.html"
}

View file

@ -19,7 +19,7 @@
],
"patterns": [
"_flush",
"{indices}/_flush"
"{index}/_flush"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-flush.html"
}

View file

@ -20,7 +20,7 @@
],
"patterns": [
"_forcemerge",
"{indices}/_forcemerge"
"{index}/_forcemerge"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-forcemerge.html"
}

View file

@ -24,7 +24,7 @@
"GET"
],
"patterns": [
"{indices}"
"{index}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-get-index.html"
}

View file

@ -18,8 +18,8 @@
"patterns": [
"_alias",
"_alias/{name}",
"{indices}/_alias/{name}",
"{indices}/_alias"
"{index}/_alias/{name}",
"{index}/_alias"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-aliases.html"
}

View file

@ -16,6 +16,6 @@
"patterns": [
"_data_stream/{name}/_lifecycle"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/dlm-get-lifecycle.html"
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/data-streams-get-lifecycle.html"
}
}

View file

@ -18,7 +18,7 @@
],
"patterns": [
"_mapping/field/{fields}",
"{indices}/_mapping/field/{fields}"
"{index}/_mapping/field/{fields}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-get-field-mapping.html"
}

View file

@ -18,7 +18,7 @@
],
"patterns": [
"_mapping",
"{indices}/_mapping"
"{index}/_mapping"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-get-mapping.html"
}

View file

@ -20,8 +20,8 @@
],
"patterns": [
"_settings",
"{indices}/_settings",
"{indices}/_settings/{name}",
"{index}/_settings",
"{index}/_settings/{name}",
"_settings/{name}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-get-settings.html"

View file

@ -18,7 +18,7 @@
"POST"
],
"patterns": [
"{indices}/_open"
"{index}/_open"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-open-close.html"
}

View file

@ -9,8 +9,8 @@
"POST"
],
"patterns": [
"{indices}/_alias/{name}",
"{indices}/_aliases/{name}"
"{index}/_alias/{name}",
"{index}/_aliases/{name}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-aliases.html"
}

View file

@ -17,6 +17,6 @@
"patterns": [
"_data_stream/{name}/_lifecycle"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/dlm-put-lifecycle.html"
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/data-streams-put-lifecycle.html"
}
}

View file

@ -19,7 +19,7 @@
"POST"
],
"patterns": [
"{indices}/_mapping"
"{index}/_mapping"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-put-mapping.html"
}

View file

@ -20,7 +20,7 @@
],
"patterns": [
"_settings",
"{indices}/_settings"
"{index}/_settings"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-update-settings.html"
}

View file

@ -9,7 +9,7 @@
],
"patterns": [
"_recovery",
"{indices}/_recovery"
"{index}/_recovery"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-recovery.html"
}

View file

@ -17,7 +17,7 @@
],
"patterns": [
"_refresh",
"{indices}/_refresh"
"{index}/_refresh"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-refresh.html"
}

View file

@ -9,14 +9,15 @@
"hidden",
"none",
"all"
]
],
"resource": ""
},
"methods": [
"GET",
"POST"
],
"patterns": [
"{indices}/_reload_search_analyzers"
"{index}/_reload_search_analyzers"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-reload-analyzers.html"
}

View file

@ -17,7 +17,7 @@
],
"patterns": [
"_segments",
"{indices}/_segments"
"{index}/_segments"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-segments.html"
}

View file

@ -17,7 +17,7 @@
],
"patterns": [
"_shard_stores",
"{indices}/_shard_stores"
"{index}/_shard_stores"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-shards-stores.html"
}

View file

@ -10,7 +10,7 @@
"POST"
],
"patterns": [
"{indices}/_shrink/{target}"
"{index}/_shrink/{target}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-shrink-index.html"
}

View file

@ -10,7 +10,7 @@
"POST"
],
"patterns": [
"{indices}/_split/{target}"
"{index}/_split/{target}"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-split-index.html"
}

View file

@ -26,12 +26,12 @@
],
"patterns": [
"_stats",
"_stats/{metrics}",
"{indices}/_stats",
"{indices}/_stats/{metrics}"
"_stats/{metric}",
"{index}/_stats",
"{index}/_stats/{metric}"
],
"url_components": {
"metrics": [
"metric": [
"_all",
"bulk",
"completion",
@ -49,7 +49,7 @@
"store",
"warmer"
],
"indices": null
"index": null
},
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-stats.html"
}

View file

@ -29,7 +29,7 @@
],
"patterns": [
"_validate/query",
"{indices}/_validate/query"
"{index}/_validate/query"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/search-validate.html"
}

View file

@ -8,7 +8,7 @@
"POST"
],
"patterns": [
"{indices}/_knn_search"
"{index}/_knn_search"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/search-search.html"
}

View file

@ -17,7 +17,7 @@
],
"patterns": [
"_mget",
"{indices}/_mget"
"{index}/_mget"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/master/docs-multi-get.html"
}

View file

@ -5,7 +5,7 @@
],
"patterns": [
"_migration/deprecations",
"{indices}/_migration/deprecations"
"{index}/_migration/deprecations"
],
"documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/migration-api-deprecation.html"
}

Some files were not shown because too many files have changed in this diff Show more