mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
* [Index Patterns] Runtime fields CRUD REST API (#101164) Part of index pattern REST API # Conflicts: # docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md # docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.md * fix bad docs merge
This commit is contained in:
parent
e4a251d043
commit
af45343bee
59 changed files with 1993 additions and 19 deletions
|
@ -20,6 +20,12 @@ The following index patterns APIs are available:
|
|||
** <<index-patterns-api-default-set, Set default index pattern API>> to set a default index pattern
|
||||
* Fields
|
||||
** <<index-patterns-fields-api-update, Update index pattern field>> to change field metadata, such as `count`, `customLabel` and `format`
|
||||
* Runtime fields
|
||||
** <<index-patterns-runtime-field-api-get, Get runtime field API>> to retrieve a runtime field
|
||||
** <<index-patterns-runtime-field-api-create, Create runtime field API>> to create a runtime field
|
||||
** <<index-patterns-runtime-field-api-upsert, Upsert runtime field API>> to create or update a runtime field
|
||||
** <<index-patterns-runtime-field-api-update, Update runtime field API>> to partially update an existing runtime field
|
||||
** <<index-patterns-runtime-field-api-delete, Delete runtime field API>> to delete a runtime field
|
||||
|
||||
include::index-patterns/get.asciidoc[]
|
||||
include::index-patterns/create.asciidoc[]
|
||||
|
@ -28,3 +34,9 @@ include::index-patterns/delete.asciidoc[]
|
|||
include::index-patterns/default-get.asciidoc[]
|
||||
include::index-patterns/default-set.asciidoc[]
|
||||
include::index-patterns/update-fields.asciidoc[]
|
||||
include::index-patterns/runtime-fields/get.asciidoc[]
|
||||
include::index-patterns/runtime-fields/create.asciidoc[]
|
||||
include::index-patterns/runtime-fields/upsert.asciidoc[]
|
||||
include::index-patterns/runtime-fields/update.asciidoc[]
|
||||
include::index-patterns/runtime-fields/delete.asciidoc[]
|
||||
|
||||
|
|
|
@ -84,6 +84,7 @@ $ curl -X POST api/index_patterns/index_pattern
|
|||
"typeMeta": {},
|
||||
"fieldFormats": {},
|
||||
"fieldAttrs": {},
|
||||
"runtimeFieldMap": {}
|
||||
"allowNoIndex": "..."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ The API returns an index pattern object:
|
|||
"typeMeta": {},
|
||||
"fieldFormats": {},
|
||||
"fieldAttrs": {},
|
||||
"runtimeFieldMap" {},
|
||||
"allowNoIndex: "..."
|
||||
}
|
||||
}
|
||||
|
|
61
docs/api/index-patterns/runtime-fields/create.asciidoc
Normal file
61
docs/api/index-patterns/runtime-fields/create.asciidoc
Normal file
|
@ -0,0 +1,61 @@
|
|||
[[index-patterns-runtime-field-api-create]]
|
||||
=== Create runtime field API
|
||||
++++
|
||||
<titleabbrev>Create runtime field</titleabbrev>
|
||||
++++
|
||||
|
||||
experimental[] Create a runtime field
|
||||
|
||||
[[index-patterns-runtime-field-create-request]]
|
||||
==== Request
|
||||
|
||||
`POST <kibana host>:<port>/api/index_patterns/index_pattern/<index_pattern_id>/runtime_field`
|
||||
|
||||
`POST <kibana host>:<port>/s/<space_id>/api/index_patterns/index_pattern/<index_pattern_id>/runtime_field`
|
||||
|
||||
[[index-patterns-runtime-field-create-params]]
|
||||
==== Path parameters
|
||||
|
||||
`space_id`::
|
||||
(Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used.
|
||||
|
||||
`index_pattern_id`::
|
||||
(Required, string) The ID of the index pattern.
|
||||
|
||||
[[index-patterns-runtime-field-create-body]]
|
||||
==== Request body
|
||||
|
||||
`name`:: (Required, string) The name for a runtime field.
|
||||
|
||||
`runtimeField`:: (Required, object) The runtime field definition object.
|
||||
|
||||
|
||||
[[index-patterns-runtime-field-create-example]]
|
||||
==== Examples
|
||||
|
||||
Create a runtime field on an index pattern:
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ curl -X POST api/index_patterns/index_pattern/<index_pattern_id>/runtime_field
|
||||
{
|
||||
"name": "runtimeFoo",
|
||||
"runtimeField": {
|
||||
"type": "long",
|
||||
"script": {
|
||||
"source": "emit(doc["foo"].value)"
|
||||
}
|
||||
}
|
||||
}
|
||||
--------------------------------------------------
|
||||
// KIBANA
|
||||
|
||||
The API returns created runtime field object and update index pattern object:
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
{
|
||||
"index_pattern": {...},
|
||||
"field": {...}
|
||||
}
|
||||
--------------------------------------------------
|
37
docs/api/index-patterns/runtime-fields/delete.asciidoc
Normal file
37
docs/api/index-patterns/runtime-fields/delete.asciidoc
Normal file
|
@ -0,0 +1,37 @@
|
|||
[[index-patterns-runtime-field-api-delete]]
|
||||
=== Delete runtime field API
|
||||
++++
|
||||
<titleabbrev>Delete runtime field</titleabbrev>
|
||||
++++
|
||||
|
||||
experimental[] Delete a runtime field from an index pattern.
|
||||
|
||||
[[index-patterns-runtime-field-api-delete-request]]
|
||||
==== Request
|
||||
|
||||
`DELETE <kibana host>:<port>/api/index_patterns/index_pattern/<index_pattern_id>/runtime_field/<name>`
|
||||
|
||||
`DELETE <kibana host>:<port>/s/<space_id>/api/index_patterns/index_pattern/<index_pattern_id>/runtime_field/<name>`
|
||||
|
||||
[[index-patterns-runtime-field-api-delete-path-params]]
|
||||
==== Path parameters
|
||||
|
||||
`space_id`::
|
||||
(Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used.
|
||||
|
||||
`index_pattern_id`::
|
||||
(Required, string) The ID of the index pattern your want to delete a runtime field from.
|
||||
|
||||
`name`::
|
||||
(Required, string) The name of the runtime field you want to delete.
|
||||
|
||||
|
||||
==== Example
|
||||
|
||||
Delete a runtime field from an index pattern:
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ curl -X DELETE api/index_patterns/index_pattern/<my-pattern>/runtime_field/<runtime-field-name>
|
||||
--------------------------------------------------
|
||||
// KIBANA
|
52
docs/api/index-patterns/runtime-fields/get.asciidoc
Normal file
52
docs/api/index-patterns/runtime-fields/get.asciidoc
Normal file
|
@ -0,0 +1,52 @@
|
|||
[[index-patterns-runtime-field-api-get]]
|
||||
=== Get runtime field API
|
||||
++++
|
||||
<titleabbrev>Get runtime field</titleabbrev>
|
||||
++++
|
||||
|
||||
experimental[] Get a runtime field
|
||||
|
||||
[[index-patterns-runtime-field-get-request]]
|
||||
==== Request
|
||||
|
||||
`GET <kibana host>:<port>/api/index_patterns/index_pattern/<index_pattern_id>/runtime_field/<name>`
|
||||
|
||||
`GET <kibana host>:<port>/s/<space_id>/api/index_patterns/index_pattern/<index_pattern_id>/runtime_field/<name>`
|
||||
|
||||
[[index-patterns-runtime-field-get-params]]
|
||||
==== Path parameters
|
||||
|
||||
`space_id`::
|
||||
(Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used.
|
||||
|
||||
`index_pattern_id`::
|
||||
(Required, string) The ID of the index pattern.
|
||||
|
||||
`name`::
|
||||
(Required, string) The name of the runtime field you want to retrieve.
|
||||
|
||||
|
||||
[[index-patterns-runtime-field-get-example]]
|
||||
==== Example
|
||||
|
||||
Retrieve a runtime field named `foo` of index pattern with the `my-pattern` ID:
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ curl -X GET api/index_patterns/index_pattern/my-pattern/runtime_field/foo
|
||||
--------------------------------------------------
|
||||
// KIBANA
|
||||
|
||||
The API returns a runtime `field` object, and a `runtimeField` definition object:
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
{
|
||||
"field": {
|
||||
...
|
||||
},
|
||||
"runtimeField": {
|
||||
...
|
||||
}
|
||||
}
|
||||
--------------------------------------------------
|
66
docs/api/index-patterns/runtime-fields/update.asciidoc
Normal file
66
docs/api/index-patterns/runtime-fields/update.asciidoc
Normal file
|
@ -0,0 +1,66 @@
|
|||
[[index-patterns-runtime-field-api-update]]
|
||||
=== Update runtime field API
|
||||
++++
|
||||
<titleabbrev>Update runtime field</titleabbrev>
|
||||
++++
|
||||
|
||||
experimental[] Update an existing runtime field
|
||||
|
||||
[[index-patterns-runtime-field-update-request]]
|
||||
==== Request
|
||||
|
||||
`POST <kibana host>:<port>/api/index_patterns/index_pattern/<index_pattern_id>/runtime_field/<name>`
|
||||
|
||||
`POST <kibana host>:<port>/s/<space_id>/api/index_patterns/index_pattern/<index_pattern_id>/runtime_field/<name>`
|
||||
|
||||
[[index-patterns-runtime-field-update-params]]
|
||||
==== Path parameters
|
||||
|
||||
`space_id`::
|
||||
(Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used.
|
||||
|
||||
`index_pattern_id`::
|
||||
(Required, string) The ID of the index pattern.
|
||||
|
||||
`name`::
|
||||
(Required, string) The name of the runtime field you want to update.
|
||||
|
||||
[[index-patterns-runtime-field-update-body]]
|
||||
==== Request body
|
||||
|
||||
`runtimeField`:: (Required, object) The runtime field definition object.
|
||||
|
||||
You can update following fields:
|
||||
|
||||
* `type`
|
||||
* `script`
|
||||
|
||||
|
||||
|
||||
[[index-patterns-runtime-field-update-example]]
|
||||
==== Examples
|
||||
|
||||
Update an existing runtime field on an index pattern:
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ curl -X POST api/index_patterns/index_pattern/<index_pattern_id>/runtime_field/<runtime_field_name>
|
||||
{
|
||||
"runtimeField": {
|
||||
"script": {
|
||||
"source": "emit(doc["bar"].value)"
|
||||
}
|
||||
}
|
||||
}
|
||||
--------------------------------------------------
|
||||
// KIBANA
|
||||
|
||||
The API returns updated runtime field object and updated index pattern object:
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
{
|
||||
"index_pattern": {...},
|
||||
"field": {...}
|
||||
}
|
||||
--------------------------------------------------
|
61
docs/api/index-patterns/runtime-fields/upsert.asciidoc
Normal file
61
docs/api/index-patterns/runtime-fields/upsert.asciidoc
Normal file
|
@ -0,0 +1,61 @@
|
|||
[[index-patterns-runtime-field-api-upsert]]
|
||||
=== Upsert runtime field API
|
||||
++++
|
||||
<titleabbrev>Upsert runtime field</titleabbrev>
|
||||
++++
|
||||
|
||||
experimental[] Create or update an existing runtime field
|
||||
|
||||
[[index-patterns-runtime-field-upsert-request]]
|
||||
==== Request
|
||||
|
||||
`PUT <kibana host>:<port>/api/index_patterns/index_pattern/<index_pattern_id>/runtime_field`
|
||||
|
||||
`PUT <kibana host>:<port>/s/<space_id>/api/index_patterns/index_pattern/<index_pattern_id>/runtime_field`
|
||||
|
||||
[[index-patterns-runtime-field-upsert-params]]
|
||||
==== Path parameters
|
||||
|
||||
`space_id`::
|
||||
(Optional, string) An identifier for the space. If `space_id` is not provided in the URL, the default space is used.
|
||||
|
||||
`index_pattern_id`::
|
||||
(Required, string) The ID of the index pattern.
|
||||
|
||||
[[index-patterns-runtime-field-upsert-body]]
|
||||
==== Request body
|
||||
|
||||
`name`:: (Required, string) The name for a new runtime field or a name of an existing runtime field.
|
||||
|
||||
`runtimeField`:: (Required, object) The runtime field definition object.
|
||||
|
||||
|
||||
[[index-patterns-runtime-field-upsert-example]]
|
||||
==== Examples
|
||||
|
||||
Create or update an existing runtime field on an index pattern:
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
$ curl -X PUT api/index_patterns/index_pattern/<index_pattern_id>/runtime_field
|
||||
{
|
||||
"name": "runtimeFoo",
|
||||
"runtimeField": {
|
||||
"type": "long",
|
||||
"script": {
|
||||
"source": "emit(doc["foo"].value)"
|
||||
}
|
||||
}
|
||||
}
|
||||
--------------------------------------------------
|
||||
// KIBANA
|
||||
|
||||
The API returns created or updated runtime field object and updated index pattern object:
|
||||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
{
|
||||
"index_pattern": {...},
|
||||
"field": {...}
|
||||
}
|
||||
--------------------------------------------------
|
|
@ -93,7 +93,8 @@ $ curl -X POST api/saved_objects/index-pattern/my-pattern
|
|||
"fieldFormats": {},
|
||||
"type": "...",
|
||||
"typeMeta": {},
|
||||
"fields": {}
|
||||
"fields": {},
|
||||
"runtimeFieldMap": {}
|
||||
}
|
||||
}
|
||||
--------------------------------------------------
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPattern](./kibana-plugin-plugins-data-public.indexpattern.md) > [getRuntimeField](./kibana-plugin-plugins-data-public.indexpattern.getruntimefield.md)
|
||||
|
||||
## IndexPattern.getRuntimeField() method
|
||||
|
||||
Returns runtime field if exists
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
getRuntimeField(name: string): RuntimeField | null;
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| name | <code>string</code> | |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
`RuntimeField | null`
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPattern](./kibana-plugin-plugins-data-public.indexpattern.md) > [hasRuntimeField](./kibana-plugin-plugins-data-public.indexpattern.hasruntimefield.md)
|
||||
|
||||
## IndexPattern.hasRuntimeField() method
|
||||
|
||||
Checks if runtime field exists
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
hasRuntimeField(name: string): boolean;
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| name | <code>string</code> | |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
`boolean`
|
||||
|
|
@ -55,14 +55,17 @@ export declare class IndexPattern implements IIndexPattern
|
|||
| [getFormatterForFieldNoDefault(fieldname)](./kibana-plugin-plugins-data-public.indexpattern.getformatterforfieldnodefault.md) | | Get formatter for a given field name. Return undefined if none exists |
|
||||
| [getIndex()](./kibana-plugin-plugins-data-public.indexpattern.getindex.md) | | |
|
||||
| [getNonScriptedFields()](./kibana-plugin-plugins-data-public.indexpattern.getnonscriptedfields.md) | | |
|
||||
| [getRuntimeField(name)](./kibana-plugin-plugins-data-public.indexpattern.getruntimefield.md) | | Returns runtime field if exists |
|
||||
| [getScriptedFields()](./kibana-plugin-plugins-data-public.indexpattern.getscriptedfields.md) | | |
|
||||
| [getSourceFiltering()](./kibana-plugin-plugins-data-public.indexpattern.getsourcefiltering.md) | | Get the source filtering configuration for that index. |
|
||||
| [getTimeField()](./kibana-plugin-plugins-data-public.indexpattern.gettimefield.md) | | |
|
||||
| [hasRuntimeField(name)](./kibana-plugin-plugins-data-public.indexpattern.hasruntimefield.md) | | Checks if runtime field exists |
|
||||
| [isTimeBased()](./kibana-plugin-plugins-data-public.indexpattern.istimebased.md) | | |
|
||||
| [isTimeNanosBased()](./kibana-plugin-plugins-data-public.indexpattern.istimenanosbased.md) | | |
|
||||
| [isUnsupportedTimePattern()](./kibana-plugin-plugins-data-public.indexpattern.isunsupportedtimepattern.md) | | |
|
||||
| [removeRuntimeField(name)](./kibana-plugin-plugins-data-public.indexpattern.removeruntimefield.md) | | Remove a runtime field - removed from mapped field or removed unmapped field as appropriate |
|
||||
| [removeRuntimeField(name)](./kibana-plugin-plugins-data-public.indexpattern.removeruntimefield.md) | | Remove a runtime field - removed from mapped field or removed unmapped field as appropriate. Doesn't clear associated field attributes. |
|
||||
| [removeScriptedField(fieldName)](./kibana-plugin-plugins-data-public.indexpattern.removescriptedfield.md) | | Remove scripted field from field list |
|
||||
| [replaceAllRuntimeFields(newFields)](./kibana-plugin-plugins-data-public.indexpattern.replaceallruntimefields.md) | | Replaces all existing runtime fields with new fields |
|
||||
| [setFieldAttrs(fieldName, attrName, value)](./kibana-plugin-plugins-data-public.indexpattern.setfieldattrs.md) | | |
|
||||
| [setFieldCount(fieldName, count)](./kibana-plugin-plugins-data-public.indexpattern.setfieldcount.md) | | |
|
||||
| [setFieldCustomLabel(fieldName, customLabel)](./kibana-plugin-plugins-data-public.indexpattern.setfieldcustomlabel.md) | | |
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
## IndexPattern.removeRuntimeField() method
|
||||
|
||||
Remove a runtime field - removed from mapped field or removed unmapped field as appropriate
|
||||
Remove a runtime field - removed from mapped field or removed unmapped field as appropriate. Doesn't clear associated field attributes.
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
|
@ -16,7 +16,7 @@ removeRuntimeField(name: string): void;
|
|||
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| name | <code>string</code> | |
|
||||
| name | <code>string</code> | Field name to remove |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPattern](./kibana-plugin-plugins-data-public.indexpattern.md) > [replaceAllRuntimeFields](./kibana-plugin-plugins-data-public.indexpattern.replaceallruntimefields.md)
|
||||
|
||||
## IndexPattern.replaceAllRuntimeFields() method
|
||||
|
||||
Replaces all existing runtime fields with new fields
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
replaceAllRuntimeFields(newFields: Record<string, RuntimeField>): void;
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| newFields | <code>Record<string, RuntimeField></code> | |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
`void`
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<!-- 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) > [IndexPattern](./kibana-plugin-plugins-data-server.indexpattern.md) > [getRuntimeField](./kibana-plugin-plugins-data-server.indexpattern.getruntimefield.md)
|
||||
|
||||
## IndexPattern.getRuntimeField() method
|
||||
|
||||
Returns runtime field if exists
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
getRuntimeField(name: string): RuntimeField | null;
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| name | <code>string</code> | |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
`RuntimeField | null`
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<!-- 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) > [IndexPattern](./kibana-plugin-plugins-data-server.indexpattern.md) > [hasRuntimeField](./kibana-plugin-plugins-data-server.indexpattern.hasruntimefield.md)
|
||||
|
||||
## IndexPattern.hasRuntimeField() method
|
||||
|
||||
Checks if runtime field exists
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
hasRuntimeField(name: string): boolean;
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| name | <code>string</code> | |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
`boolean`
|
||||
|
|
@ -55,14 +55,17 @@ export declare class IndexPattern implements IIndexPattern
|
|||
| [getFormatterForFieldNoDefault(fieldname)](./kibana-plugin-plugins-data-server.indexpattern.getformatterforfieldnodefault.md) | | Get formatter for a given field name. Return undefined if none exists |
|
||||
| [getIndex()](./kibana-plugin-plugins-data-server.indexpattern.getindex.md) | | |
|
||||
| [getNonScriptedFields()](./kibana-plugin-plugins-data-server.indexpattern.getnonscriptedfields.md) | | |
|
||||
| [getRuntimeField(name)](./kibana-plugin-plugins-data-server.indexpattern.getruntimefield.md) | | Returns runtime field if exists |
|
||||
| [getScriptedFields()](./kibana-plugin-plugins-data-server.indexpattern.getscriptedfields.md) | | |
|
||||
| [getSourceFiltering()](./kibana-plugin-plugins-data-server.indexpattern.getsourcefiltering.md) | | Get the source filtering configuration for that index. |
|
||||
| [getTimeField()](./kibana-plugin-plugins-data-server.indexpattern.gettimefield.md) | | |
|
||||
| [hasRuntimeField(name)](./kibana-plugin-plugins-data-server.indexpattern.hasruntimefield.md) | | Checks if runtime field exists |
|
||||
| [isTimeBased()](./kibana-plugin-plugins-data-server.indexpattern.istimebased.md) | | |
|
||||
| [isTimeNanosBased()](./kibana-plugin-plugins-data-server.indexpattern.istimenanosbased.md) | | |
|
||||
| [isUnsupportedTimePattern()](./kibana-plugin-plugins-data-server.indexpattern.isunsupportedtimepattern.md) | | |
|
||||
| [removeRuntimeField(name)](./kibana-plugin-plugins-data-server.indexpattern.removeruntimefield.md) | | Remove a runtime field - removed from mapped field or removed unmapped field as appropriate |
|
||||
| [removeRuntimeField(name)](./kibana-plugin-plugins-data-server.indexpattern.removeruntimefield.md) | | Remove a runtime field - removed from mapped field or removed unmapped field as appropriate. Doesn't clear associated field attributes. |
|
||||
| [removeScriptedField(fieldName)](./kibana-plugin-plugins-data-server.indexpattern.removescriptedfield.md) | | Remove scripted field from field list |
|
||||
| [replaceAllRuntimeFields(newFields)](./kibana-plugin-plugins-data-server.indexpattern.replaceallruntimefields.md) | | Replaces all existing runtime fields with new fields |
|
||||
| [setFieldAttrs(fieldName, attrName, value)](./kibana-plugin-plugins-data-server.indexpattern.setfieldattrs.md) | | |
|
||||
| [setFieldCount(fieldName, count)](./kibana-plugin-plugins-data-server.indexpattern.setfieldcount.md) | | |
|
||||
| [setFieldCustomLabel(fieldName, customLabel)](./kibana-plugin-plugins-data-server.indexpattern.setfieldcustomlabel.md) | | |
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
## IndexPattern.removeRuntimeField() method
|
||||
|
||||
Remove a runtime field - removed from mapped field or removed unmapped field as appropriate
|
||||
Remove a runtime field - removed from mapped field or removed unmapped field as appropriate. Doesn't clear associated field attributes.
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
|
@ -16,7 +16,7 @@ removeRuntimeField(name: string): void;
|
|||
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| name | <code>string</code> | |
|
||||
| name | <code>string</code> | Field name to remove |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<!-- 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) > [IndexPattern](./kibana-plugin-plugins-data-server.indexpattern.md) > [replaceAllRuntimeFields](./kibana-plugin-plugins-data-server.indexpattern.replaceallruntimefields.md)
|
||||
|
||||
## IndexPattern.replaceAllRuntimeFields() method
|
||||
|
||||
Replaces all existing runtime fields with new fields
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
replaceAllRuntimeFields(newFields: Record<string, RuntimeField>): void;
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| newFields | <code>Record<string, RuntimeField></code> | |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
`void`
|
||||
|
|
@ -387,7 +387,6 @@ export class IndexPattern implements IIndexPattern {
|
|||
* @param name Field name
|
||||
* @param runtimeField Runtime field definition
|
||||
*/
|
||||
|
||||
addRuntimeField(name: string, runtimeField: RuntimeField) {
|
||||
const existingField = this.getFieldByName(name);
|
||||
if (existingField) {
|
||||
|
@ -407,11 +406,41 @@ export class IndexPattern implements IIndexPattern {
|
|||
}
|
||||
|
||||
/**
|
||||
* Remove a runtime field - removed from mapped field or removed unmapped
|
||||
* field as appropriate
|
||||
* @param name Field name
|
||||
* Checks if runtime field exists
|
||||
* @param name
|
||||
*/
|
||||
hasRuntimeField(name: string): boolean {
|
||||
return !!this.runtimeFieldMap[name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns runtime field if exists
|
||||
* @param name
|
||||
*/
|
||||
getRuntimeField(name: string): RuntimeField | null {
|
||||
return this.runtimeFieldMap[name] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces all existing runtime fields with new fields
|
||||
* @param newFields
|
||||
*/
|
||||
replaceAllRuntimeFields(newFields: Record<string, RuntimeField>) {
|
||||
const oldRuntimeFieldNames = Object.keys(this.runtimeFieldMap);
|
||||
oldRuntimeFieldNames.forEach((name) => {
|
||||
this.removeRuntimeField(name);
|
||||
});
|
||||
|
||||
Object.entries(newFields).forEach(([name, field]) => {
|
||||
this.addRuntimeField(name, field);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a runtime field - removed from mapped field or removed unmapped
|
||||
* field as appropriate. Doesn't clear associated field attributes.
|
||||
* @param name - Field name to remove
|
||||
*/
|
||||
removeRuntimeField(name: string) {
|
||||
const existingField = this.getFieldByName(name);
|
||||
if (existingField) {
|
||||
|
@ -419,9 +448,6 @@ export class IndexPattern implements IIndexPattern {
|
|||
// mapped field, remove runtimeField def
|
||||
existingField.runtimeField = undefined;
|
||||
} else {
|
||||
// runtimeField only
|
||||
this.setFieldCustomLabel(name, null);
|
||||
this.deleteFieldFormat(name);
|
||||
this.fields.remove(existingField);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1417,6 +1417,7 @@ export class IndexPattern implements IIndexPattern {
|
|||
typeMeta?: string | undefined;
|
||||
type?: string | undefined;
|
||||
};
|
||||
getRuntimeField(name: string): RuntimeField | null;
|
||||
// @deprecated (undocumented)
|
||||
getScriptedFields(): IndexPatternField[];
|
||||
getSourceFiltering(): {
|
||||
|
@ -1424,6 +1425,7 @@ export class IndexPattern implements IIndexPattern {
|
|||
};
|
||||
// (undocumented)
|
||||
getTimeField(): IndexPatternField | undefined;
|
||||
hasRuntimeField(name: string): boolean;
|
||||
// (undocumented)
|
||||
id?: string;
|
||||
// @deprecated (undocumented)
|
||||
|
@ -1439,6 +1441,7 @@ export class IndexPattern implements IIndexPattern {
|
|||
removeRuntimeField(name: string): void;
|
||||
// @deprecated
|
||||
removeScriptedField(fieldName: string): void;
|
||||
replaceAllRuntimeFields(newFields: Record<string, RuntimeField>): void;
|
||||
resetOriginalSavedObjectBody: () => void;
|
||||
// (undocumented)
|
||||
protected setFieldAttrs<K extends keyof FieldAttrSet>(fieldName: string, attrName: K, value: FieldAttrSet[K]): void;
|
||||
|
|
|
@ -21,6 +21,11 @@ import { registerDeleteScriptedFieldRoute } from './routes/scripted_fields/delet
|
|||
import { registerUpdateScriptedFieldRoute } from './routes/scripted_fields/update_scripted_field';
|
||||
import type { DataPluginStart, DataPluginStartDependencies } from '../plugin';
|
||||
import { registerManageDefaultIndexPatternRoutes } from './routes/default_index_pattern';
|
||||
import { registerCreateRuntimeFieldRoute } from './routes/runtime_fields/create_runtime_field';
|
||||
import { registerGetRuntimeFieldRoute } from './routes/runtime_fields/get_runtime_field';
|
||||
import { registerDeleteRuntimeFieldRoute } from './routes/runtime_fields/delete_runtime_field';
|
||||
import { registerPutRuntimeFieldRoute } from './routes/runtime_fields/put_runtime_field';
|
||||
import { registerUpdateRuntimeFieldRoute } from './routes/runtime_fields/update_runtime_field';
|
||||
|
||||
export function registerRoutes(
|
||||
http: HttpServiceSetup,
|
||||
|
@ -55,6 +60,13 @@ export function registerRoutes(
|
|||
registerDeleteScriptedFieldRoute(router, getStartServices);
|
||||
registerUpdateScriptedFieldRoute(router, getStartServices);
|
||||
|
||||
// Runtime Fields API
|
||||
registerCreateRuntimeFieldRoute(router, getStartServices);
|
||||
registerGetRuntimeFieldRoute(router, getStartServices);
|
||||
registerDeleteRuntimeFieldRoute(router, getStartServices);
|
||||
registerPutRuntimeFieldRoute(router, getStartServices);
|
||||
registerUpdateRuntimeFieldRoute(router, getStartServices);
|
||||
|
||||
router.get(
|
||||
{
|
||||
path: '/api/index_patterns/_fields_for_wildcard',
|
||||
|
|
|
@ -9,7 +9,11 @@
|
|||
import { schema } from '@kbn/config-schema';
|
||||
import { IndexPatternSpec } from 'src/plugins/data/common';
|
||||
import { handleErrors } from './util/handle_errors';
|
||||
import { fieldSpecSchema, serializedFieldFormatSchema } from './util/schemas';
|
||||
import {
|
||||
fieldSpecSchema,
|
||||
runtimeFieldSpecSchema,
|
||||
serializedFieldFormatSchema,
|
||||
} from './util/schemas';
|
||||
import { IRouter, StartServicesAccessor } from '../../../../../core/server';
|
||||
import type { DataPluginStart, DataPluginStartDependencies } from '../../plugin';
|
||||
|
||||
|
@ -39,6 +43,7 @@ const indexPatternSpecSchema = schema.object({
|
|||
)
|
||||
),
|
||||
allowNoIndex: schema.maybe(schema.boolean()),
|
||||
runtimeFieldMap: schema.maybe(schema.recordOf(schema.string(), runtimeFieldSpecSchema)),
|
||||
});
|
||||
|
||||
export const registerCreateIndexPatternRoute = (
|
||||
|
@ -66,6 +71,7 @@ export const registerCreateIndexPatternRoute = (
|
|||
elasticsearchClient
|
||||
);
|
||||
const body = req.body;
|
||||
|
||||
const indexPattern = await indexPatternsService.createAndSave(
|
||||
body.index_pattern as IndexPatternSpec,
|
||||
body.override,
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* 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 { schema } from '@kbn/config-schema';
|
||||
import { handleErrors } from '../util/handle_errors';
|
||||
import { runtimeFieldSpecSchema } from '../util/schemas';
|
||||
import { IRouter, StartServicesAccessor } from '../../../../../../core/server';
|
||||
import type { DataPluginStart, DataPluginStartDependencies } from '../../../plugin';
|
||||
|
||||
export const registerCreateRuntimeFieldRoute = (
|
||||
router: IRouter,
|
||||
getStartServices: StartServicesAccessor<DataPluginStartDependencies, DataPluginStart>
|
||||
) => {
|
||||
router.post(
|
||||
{
|
||||
path: '/api/index_patterns/index_pattern/{id}/runtime_field',
|
||||
validate: {
|
||||
params: schema.object({
|
||||
id: schema.string({
|
||||
minLength: 1,
|
||||
maxLength: 1_000,
|
||||
}),
|
||||
}),
|
||||
body: schema.object({
|
||||
name: schema.string({
|
||||
minLength: 1,
|
||||
maxLength: 1_000,
|
||||
}),
|
||||
runtimeField: runtimeFieldSpecSchema,
|
||||
}),
|
||||
},
|
||||
},
|
||||
|
||||
handleErrors(async (ctx, req, res) => {
|
||||
const savedObjectsClient = ctx.core.savedObjects.client;
|
||||
const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser;
|
||||
const [, , { indexPatterns }] = await getStartServices();
|
||||
const indexPatternsService = await indexPatterns.indexPatternsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearchClient
|
||||
);
|
||||
const id = req.params.id;
|
||||
const { name, runtimeField } = req.body;
|
||||
|
||||
const indexPattern = await indexPatternsService.get(id);
|
||||
|
||||
if (indexPattern.fields.getByName(name)) {
|
||||
throw new Error(`Field [name = ${name}] already exists.`);
|
||||
}
|
||||
|
||||
indexPattern.addRuntimeField(name, runtimeField);
|
||||
|
||||
const addedField = indexPattern.fields.getByName(name);
|
||||
if (!addedField) throw new Error(`Could not create a field [name = ${name}].`);
|
||||
|
||||
await indexPatternsService.updateSavedObject(indexPattern);
|
||||
|
||||
const savedField = indexPattern.fields.getByName(name);
|
||||
if (!savedField) throw new Error(`Could not create a field [name = ${name}].`);
|
||||
|
||||
return res.ok({
|
||||
body: {
|
||||
field: savedField.toSpec(),
|
||||
index_pattern: indexPattern.toSpec(),
|
||||
},
|
||||
});
|
||||
})
|
||||
);
|
||||
};
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* 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 { schema } from '@kbn/config-schema';
|
||||
import { ErrorIndexPatternFieldNotFound } from '../../error';
|
||||
import { handleErrors } from '../util/handle_errors';
|
||||
import { IRouter, StartServicesAccessor } from '../../../../../../core/server';
|
||||
import type { DataPluginStart, DataPluginStartDependencies } from '../../../plugin';
|
||||
|
||||
export const registerDeleteRuntimeFieldRoute = (
|
||||
router: IRouter,
|
||||
getStartServices: StartServicesAccessor<DataPluginStartDependencies, DataPluginStart>
|
||||
) => {
|
||||
router.delete(
|
||||
{
|
||||
path: '/api/index_patterns/index_pattern/{id}/runtime_field/{name}',
|
||||
validate: {
|
||||
params: schema.object({
|
||||
id: schema.string({
|
||||
minLength: 1,
|
||||
maxLength: 1_000,
|
||||
}),
|
||||
name: schema.string({
|
||||
minLength: 1,
|
||||
maxLength: 1_000,
|
||||
}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
handleErrors(async (ctx, req, res) => {
|
||||
const savedObjectsClient = ctx.core.savedObjects.client;
|
||||
const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser;
|
||||
const [, , { indexPatterns }] = await getStartServices();
|
||||
const indexPatternsService = await indexPatterns.indexPatternsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearchClient
|
||||
);
|
||||
const id = req.params.id;
|
||||
const name = req.params.name;
|
||||
|
||||
const indexPattern = await indexPatternsService.get(id);
|
||||
const field = indexPattern.fields.getByName(name);
|
||||
|
||||
if (!field) {
|
||||
throw new ErrorIndexPatternFieldNotFound(id, name);
|
||||
}
|
||||
|
||||
if (!field.runtimeField) {
|
||||
throw new Error('Only runtime fields can be deleted.');
|
||||
}
|
||||
|
||||
indexPattern.removeRuntimeField(name);
|
||||
|
||||
await indexPatternsService.updateSavedObject(indexPattern);
|
||||
|
||||
return res.ok();
|
||||
})
|
||||
);
|
||||
};
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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 { schema } from '@kbn/config-schema';
|
||||
import { ErrorIndexPatternFieldNotFound } from '../../error';
|
||||
import { handleErrors } from '../util/handle_errors';
|
||||
import { IRouter, StartServicesAccessor } from '../../../../../../core/server';
|
||||
import type { DataPluginStart, DataPluginStartDependencies } from '../../../plugin';
|
||||
|
||||
export const registerGetRuntimeFieldRoute = (
|
||||
router: IRouter,
|
||||
getStartServices: StartServicesAccessor<DataPluginStartDependencies, DataPluginStart>
|
||||
) => {
|
||||
router.get(
|
||||
{
|
||||
path: '/api/index_patterns/index_pattern/{id}/runtime_field/{name}',
|
||||
validate: {
|
||||
params: schema.object({
|
||||
id: schema.string({
|
||||
minLength: 1,
|
||||
maxLength: 1_000,
|
||||
}),
|
||||
name: schema.string({
|
||||
minLength: 1,
|
||||
maxLength: 1_000,
|
||||
}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
|
||||
handleErrors(async (ctx, req, res) => {
|
||||
const savedObjectsClient = ctx.core.savedObjects.client;
|
||||
const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser;
|
||||
const [, , { indexPatterns }] = await getStartServices();
|
||||
const indexPatternsService = await indexPatterns.indexPatternsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearchClient
|
||||
);
|
||||
const id = req.params.id;
|
||||
const name = req.params.name;
|
||||
|
||||
const indexPattern = await indexPatternsService.get(id);
|
||||
|
||||
const field = indexPattern.fields.getByName(name);
|
||||
|
||||
if (!field) {
|
||||
throw new ErrorIndexPatternFieldNotFound(id, name);
|
||||
}
|
||||
|
||||
if (!field.runtimeField) {
|
||||
throw new Error('Only runtime fields can be retrieved.');
|
||||
}
|
||||
|
||||
return res.ok({
|
||||
body: {
|
||||
field: field.toSpec(),
|
||||
runtimeField: indexPattern.getRuntimeField(name),
|
||||
},
|
||||
});
|
||||
})
|
||||
);
|
||||
};
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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 { schema } from '@kbn/config-schema';
|
||||
import { handleErrors } from '../util/handle_errors';
|
||||
import { runtimeFieldSpecSchema } from '../util/schemas';
|
||||
import { IRouter, StartServicesAccessor } from '../../../../../../core/server';
|
||||
import type { DataPluginStart, DataPluginStartDependencies } from '../../../plugin';
|
||||
|
||||
export const registerPutRuntimeFieldRoute = (
|
||||
router: IRouter,
|
||||
getStartServices: StartServicesAccessor<DataPluginStartDependencies, DataPluginStart>
|
||||
) => {
|
||||
router.put(
|
||||
{
|
||||
path: '/api/index_patterns/index_pattern/{id}/runtime_field',
|
||||
validate: {
|
||||
params: schema.object({
|
||||
id: schema.string({
|
||||
minLength: 1,
|
||||
maxLength: 1_000,
|
||||
}),
|
||||
}),
|
||||
body: schema.object({
|
||||
name: schema.string({
|
||||
minLength: 1,
|
||||
maxLength: 1_000,
|
||||
}),
|
||||
runtimeField: runtimeFieldSpecSchema,
|
||||
}),
|
||||
},
|
||||
},
|
||||
handleErrors(async (ctx, req, res) => {
|
||||
const savedObjectsClient = ctx.core.savedObjects.client;
|
||||
const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser;
|
||||
const [, , { indexPatterns }] = await getStartServices();
|
||||
const indexPatternsService = await indexPatterns.indexPatternsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearchClient
|
||||
);
|
||||
const id = req.params.id;
|
||||
const { name, runtimeField } = req.body;
|
||||
|
||||
const indexPattern = await indexPatternsService.get(id);
|
||||
|
||||
const oldFieldObject = indexPattern.fields.getByName(name);
|
||||
|
||||
if (oldFieldObject && !oldFieldObject.runtimeField) {
|
||||
throw new Error('Only runtime fields can be updated');
|
||||
}
|
||||
|
||||
if (oldFieldObject) {
|
||||
indexPattern.removeRuntimeField(name);
|
||||
}
|
||||
|
||||
indexPattern.addRuntimeField(name, runtimeField);
|
||||
|
||||
await indexPatternsService.updateSavedObject(indexPattern);
|
||||
|
||||
const fieldObject = indexPattern.fields.getByName(name);
|
||||
if (!fieldObject) throw new Error(`Could not create a field [name = ${name}].`);
|
||||
|
||||
return res.ok({
|
||||
body: {
|
||||
field: fieldObject.toSpec(),
|
||||
index_pattern: indexPattern.toSpec(),
|
||||
},
|
||||
});
|
||||
})
|
||||
);
|
||||
};
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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 { schema } from '@kbn/config-schema';
|
||||
import { RuntimeField } from 'src/plugins/data/common';
|
||||
import { ErrorIndexPatternFieldNotFound } from '../../error';
|
||||
import { handleErrors } from '../util/handle_errors';
|
||||
import { runtimeFieldSpec, runtimeFieldSpecTypeSchema } from '../util/schemas';
|
||||
import { IRouter, StartServicesAccessor } from '../../../../../../core/server';
|
||||
import type { DataPluginStart, DataPluginStartDependencies } from '../../../plugin';
|
||||
|
||||
export const registerUpdateRuntimeFieldRoute = (
|
||||
router: IRouter,
|
||||
getStartServices: StartServicesAccessor<DataPluginStartDependencies, DataPluginStart>
|
||||
) => {
|
||||
router.post(
|
||||
{
|
||||
path: '/api/index_patterns/index_pattern/{id}/runtime_field/{name}',
|
||||
validate: {
|
||||
params: schema.object({
|
||||
id: schema.string({
|
||||
minLength: 1,
|
||||
maxLength: 1_000,
|
||||
}),
|
||||
name: schema.string({
|
||||
minLength: 1,
|
||||
maxLength: 1_000,
|
||||
}),
|
||||
}),
|
||||
body: schema.object({
|
||||
name: schema.never(),
|
||||
runtimeField: schema.object({
|
||||
...runtimeFieldSpec,
|
||||
// We need to overwrite the below fields on top of `runtimeFieldSpec`,
|
||||
// because some fields would be optional
|
||||
type: schema.maybe(runtimeFieldSpecTypeSchema),
|
||||
}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
handleErrors(async (ctx, req, res) => {
|
||||
const savedObjectsClient = ctx.core.savedObjects.client;
|
||||
const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser;
|
||||
const [, , { indexPatterns }] = await getStartServices();
|
||||
const indexPatternsService = await indexPatterns.indexPatternsServiceFactory(
|
||||
savedObjectsClient,
|
||||
elasticsearchClient
|
||||
);
|
||||
const id = req.params.id;
|
||||
const name = req.params.name;
|
||||
const runtimeField = req.body.runtimeField as Partial<RuntimeField>;
|
||||
|
||||
const indexPattern = await indexPatternsService.get(id);
|
||||
const existingRuntimeField = indexPattern.getRuntimeField(name);
|
||||
|
||||
if (!existingRuntimeField) {
|
||||
throw new ErrorIndexPatternFieldNotFound(id, name);
|
||||
}
|
||||
|
||||
indexPattern.removeRuntimeField(name);
|
||||
indexPattern.addRuntimeField(name, {
|
||||
...existingRuntimeField,
|
||||
...runtimeField,
|
||||
});
|
||||
|
||||
await indexPatternsService.updateSavedObject(indexPattern);
|
||||
|
||||
const fieldObject = indexPattern.fields.getByName(name);
|
||||
if (!fieldObject) throw new Error(`Could not create a field [name = ${name}].`);
|
||||
|
||||
return res.ok({
|
||||
body: {
|
||||
field: fieldObject.toSpec(),
|
||||
index_pattern: indexPattern.toSpec(),
|
||||
},
|
||||
});
|
||||
})
|
||||
);
|
||||
};
|
|
@ -8,7 +8,11 @@
|
|||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { handleErrors } from './util/handle_errors';
|
||||
import { fieldSpecSchema, serializedFieldFormatSchema } from './util/schemas';
|
||||
import {
|
||||
fieldSpecSchema,
|
||||
runtimeFieldSpecSchema,
|
||||
serializedFieldFormatSchema,
|
||||
} from './util/schemas';
|
||||
import { IRouter, StartServicesAccessor } from '../../../../../core/server';
|
||||
import type { DataPluginStart, DataPluginStartDependencies } from '../../plugin';
|
||||
|
||||
|
@ -28,6 +32,7 @@ const indexPatternUpdateSchema = schema.object({
|
|||
fieldFormats: schema.maybe(schema.recordOf(schema.string(), serializedFieldFormatSchema)),
|
||||
fields: schema.maybe(schema.recordOf(schema.string(), fieldSpecSchema)),
|
||||
allowNoIndex: schema.maybe(schema.boolean()),
|
||||
runtimeFieldMap: schema.maybe(schema.recordOf(schema.string(), runtimeFieldSpecSchema)),
|
||||
});
|
||||
|
||||
export const registerUpdateIndexPatternRoute = (
|
||||
|
@ -78,6 +83,7 @@ export const registerUpdateIndexPatternRoute = (
|
|||
type,
|
||||
typeMeta,
|
||||
fields,
|
||||
runtimeFieldMap,
|
||||
},
|
||||
} = req.body;
|
||||
|
||||
|
@ -131,6 +137,11 @@ export const registerUpdateIndexPatternRoute = (
|
|||
);
|
||||
}
|
||||
|
||||
if (runtimeFieldMap !== undefined) {
|
||||
changeCount++;
|
||||
indexPattern.replaceAllRuntimeFields(runtimeFieldMap);
|
||||
}
|
||||
|
||||
if (changeCount < 1) {
|
||||
throw new Error('Index pattern change set is empty.');
|
||||
}
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { schema, Type } from '@kbn/config-schema';
|
||||
import { RUNTIME_FIELD_TYPES, RuntimeType } from '../../../../common';
|
||||
|
||||
export const serializedFieldFormatSchema = schema.object({
|
||||
id: schema.maybe(schema.string()),
|
||||
|
@ -52,4 +53,24 @@ export const fieldSpecSchemaFields = {
|
|||
shortDotsEnable: schema.maybe(schema.boolean()),
|
||||
};
|
||||
|
||||
export const fieldSpecSchema = schema.object(fieldSpecSchemaFields);
|
||||
export const fieldSpecSchema = schema.object(fieldSpecSchemaFields, {
|
||||
// Allow and ignore unknowns to make fields transient.
|
||||
// Because `fields` have a bunch of calculated fields
|
||||
// this allows to retrieve an index pattern and then to re-create by using the retrieved payload
|
||||
unknowns: 'ignore',
|
||||
});
|
||||
|
||||
export const runtimeFieldSpecTypeSchema = schema.oneOf(
|
||||
RUNTIME_FIELD_TYPES.map((runtimeFieldType) => schema.literal(runtimeFieldType)) as [
|
||||
Type<RuntimeType>
|
||||
]
|
||||
);
|
||||
export const runtimeFieldSpec = {
|
||||
type: runtimeFieldSpecTypeSchema,
|
||||
script: schema.maybe(
|
||||
schema.object({
|
||||
source: schema.string(),
|
||||
})
|
||||
),
|
||||
};
|
||||
export const runtimeFieldSpecSchema = schema.object(runtimeFieldSpec);
|
||||
|
|
|
@ -818,6 +818,7 @@ export class IndexPattern implements IIndexPattern {
|
|||
typeMeta?: string | undefined;
|
||||
type?: string | undefined;
|
||||
};
|
||||
getRuntimeField(name: string): RuntimeField | null;
|
||||
// @deprecated (undocumented)
|
||||
getScriptedFields(): IndexPatternField[];
|
||||
getSourceFiltering(): {
|
||||
|
@ -825,6 +826,7 @@ export class IndexPattern implements IIndexPattern {
|
|||
};
|
||||
// (undocumented)
|
||||
getTimeField(): IndexPatternField | undefined;
|
||||
hasRuntimeField(name: string): boolean;
|
||||
// (undocumented)
|
||||
id?: string;
|
||||
// @deprecated (undocumented)
|
||||
|
@ -840,6 +842,7 @@ export class IndexPattern implements IIndexPattern {
|
|||
removeRuntimeField(name: string): void;
|
||||
// @deprecated
|
||||
removeScriptedField(fieldName: string): void;
|
||||
replaceAllRuntimeFields(newFields: Record<string, RuntimeField>): void;
|
||||
resetOriginalSavedObjectBody: () => void;
|
||||
// (undocumented)
|
||||
protected setFieldAttrs<K extends keyof FieldAttrSet>(fieldName: string, attrName: K, value: FieldAttrSet[K]): void;
|
||||
|
|
|
@ -22,6 +22,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
indexPattern = (
|
||||
await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title: basicIndex,
|
||||
},
|
||||
|
|
|
@ -15,5 +15,7 @@ export default function ({ loadTestFile }) {
|
|||
loadTestFile(require.resolve('./scripted_fields_crud'));
|
||||
loadTestFile(require.resolve('./fields_api'));
|
||||
loadTestFile(require.resolve('./default_index_pattern'));
|
||||
loadTestFile(require.resolve('./runtime_fields_crud'));
|
||||
loadTestFile(require.resolve('./integration'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
expect(response.body.index_pattern.fields.bar.type).to.be('boolean');
|
||||
});
|
||||
|
||||
it('Can add scripted fields, other fields created from es index', async () => {
|
||||
it('can add scripted fields, other fields created from es index', async () => {
|
||||
const title = `basic_index*`;
|
||||
const response = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
|
@ -159,6 +159,32 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
expect(response.body.index_pattern.fields.bar.esTypes[0]).to.be('test-type');
|
||||
expect(response.body.index_pattern.fields.bar.scripted).to.be(true);
|
||||
});
|
||||
|
||||
it('can add runtime fields', async () => {
|
||||
const title = `basic_index*`;
|
||||
const response = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
runtimeFieldMap: {
|
||||
runtimeFoo: {
|
||||
type: 'keyword',
|
||||
script: {
|
||||
source: 'emit(doc["foo"].value)',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).to.be(200);
|
||||
expect(response.body.index_pattern.title).to.be(title);
|
||||
|
||||
expect(response.body.index_pattern.runtimeFieldMap.runtimeFoo.type).to.be('keyword');
|
||||
expect(response.body.index_pattern.runtimeFieldMap.runtimeFoo.script.source).to.be(
|
||||
'emit(doc["foo"].value)'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('can specify optional typeMeta attribute when creating an index pattern', async () => {
|
||||
|
|
|
@ -64,5 +64,25 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
'[request body.refresh_fields]: expected value of type [boolean] but got [number]'
|
||||
);
|
||||
});
|
||||
|
||||
it('returns an error when unknown runtime field type', async () => {
|
||||
const title = `basic_index*`;
|
||||
const response = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
runtimeFieldMap: {
|
||||
runtimeFoo: {
|
||||
type: 'wrong-type',
|
||||
script: {
|
||||
source: 'emit(doc["foo"].value)',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).to.be(400);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -284,5 +284,53 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
expect(response3.body.index_pattern.intervalName).to.be('intervalName2');
|
||||
expect(response3.body.index_pattern.typeMeta.baz).to.be('qux');
|
||||
});
|
||||
|
||||
it('can update runtime fields', async () => {
|
||||
const title = `basic_index*`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
runtimeFieldMap: {
|
||||
runtimeFoo: {
|
||||
type: 'keyword',
|
||||
script: {
|
||||
source: 'emit(doc["foo"].value)',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response1.status).to.be(200);
|
||||
expect(response1.body.index_pattern.title).to.be(title);
|
||||
|
||||
expect(response1.body.index_pattern.runtimeFieldMap.runtimeFoo.type).to.be('keyword');
|
||||
expect(response1.body.index_pattern.runtimeFieldMap.runtimeFoo.script.source).to.be(
|
||||
'emit(doc["foo"].value)'
|
||||
);
|
||||
|
||||
const id = response1.body.index_pattern.id;
|
||||
const response2 = await supertest.post('/api/index_patterns/index_pattern/' + id).send({
|
||||
index_pattern: {
|
||||
runtimeFieldMap: {
|
||||
runtimeBar: {
|
||||
type: 'keyword',
|
||||
script: {
|
||||
source: 'emit(doc["foo"].value)',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response2.body.index_pattern.runtimeFieldMap.runtimeBar.type).to.be('keyword');
|
||||
expect(response2.body.index_pattern.runtimeFieldMap.runtimeFoo).to.be(undefined);
|
||||
|
||||
const response3 = await supertest.get('/api/index_patterns/index_pattern/' + id);
|
||||
|
||||
expect(response3.body.index_pattern.runtimeFieldMap.runtimeBar.type).to.be('keyword');
|
||||
expect(response3.body.index_pattern.runtimeFieldMap.runtimeFoo).to.be(undefined);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* 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 { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
|
||||
/**
|
||||
* Test usage of different index patterns APIs in combination
|
||||
*/
|
||||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('integration', () => {
|
||||
loadTestFile(require.resolve('./integration'));
|
||||
});
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import _ from 'lodash';
|
||||
import { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
|
||||
/**
|
||||
* Test usage of different index patterns APIs in combination
|
||||
*/
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
||||
describe('integration', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('test/api_integration/fixtures/es_archiver/index_patterns/basic_index');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload(
|
||||
'test/api_integration/fixtures/es_archiver/index_patterns/basic_index'
|
||||
);
|
||||
});
|
||||
|
||||
it('create an index pattern, add a runtime field, add a field formatter, then re-create the same index pattern', async () => {
|
||||
const title = `basic_index*`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
},
|
||||
});
|
||||
const id = response1.body.index_pattern.id;
|
||||
const response2 = await supertest
|
||||
.post(`/api/index_patterns/index_pattern/${id}/runtime_field`)
|
||||
.send({
|
||||
name: 'runtimeBar',
|
||||
runtimeField: {
|
||||
type: 'long',
|
||||
script: {
|
||||
source: "emit(doc['field_name'].value)",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response2.status).to.be(200);
|
||||
|
||||
const response3 = await supertest
|
||||
.post(`/api/index_patterns/index_pattern/${response1.body.index_pattern.id}/fields`)
|
||||
.send({
|
||||
fields: {
|
||||
runtimeBar: {
|
||||
count: 123,
|
||||
customLabel: 'test',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response3.status).to.be(200);
|
||||
|
||||
const response4 = await supertest
|
||||
.post(`/api/index_patterns/index_pattern/${response1.body.index_pattern.id}/fields`)
|
||||
.send({
|
||||
fields: {
|
||||
runtimeBar: {
|
||||
format: {
|
||||
id: 'duration',
|
||||
params: { inputFormat: 'milliseconds', outputFormat: 'humanizePrecise' },
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response4.status).to.be(200);
|
||||
|
||||
const response5 = await supertest.get(
|
||||
'/api/index_patterns/index_pattern/' + response1.body.index_pattern.id
|
||||
);
|
||||
|
||||
expect(response5.status).to.be(200);
|
||||
|
||||
const resultIndexPattern = response5.body.index_pattern;
|
||||
|
||||
const runtimeField = resultIndexPattern.fields.runtimeBar;
|
||||
expect(runtimeField.name).to.be('runtimeBar');
|
||||
expect(runtimeField.runtimeField.type).to.be('long');
|
||||
expect(runtimeField.runtimeField.script.source).to.be("emit(doc['field_name'].value)");
|
||||
expect(runtimeField.scripted).to.be(false);
|
||||
|
||||
expect(resultIndexPattern.fieldFormats.runtimeBar.id).to.be('duration');
|
||||
expect(resultIndexPattern.fieldFormats.runtimeBar.params.inputFormat).to.be('milliseconds');
|
||||
expect(resultIndexPattern.fieldFormats.runtimeBar.params.outputFormat).to.be(
|
||||
'humanizePrecise'
|
||||
);
|
||||
|
||||
expect(resultIndexPattern.fieldAttrs.runtimeBar.count).to.be(123);
|
||||
expect(resultIndexPattern.fieldAttrs.runtimeBar.customLabel).to.be('test');
|
||||
|
||||
// check that retrieved object is transient and a clone can be created
|
||||
const response6 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: resultIndexPattern,
|
||||
});
|
||||
|
||||
expect(response6.status).to.be(200);
|
||||
const recreatedIndexPattern = response6.body.index_pattern;
|
||||
|
||||
expect(_.omit(recreatedIndexPattern, 'version')).to.eql(
|
||||
_.omit(resultIndexPattern, 'version')
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
|
||||
describe('errors', () => {
|
||||
it('returns an error field object is not provided', async () => {
|
||||
const title = `foo-${Date.now()}-${Math.random()}*`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
index_pattern: {
|
||||
title,
|
||||
},
|
||||
});
|
||||
const id = response1.body.index_pattern.id;
|
||||
const response2 = await supertest
|
||||
.post(`/api/index_patterns/index_pattern/${id}/runtime_field`)
|
||||
.send({});
|
||||
|
||||
expect(response2.status).to.be(400);
|
||||
expect(response2.body.statusCode).to.be(400);
|
||||
expect(response2.body.message).to.be(
|
||||
'[request body.name]: expected value of type [string] but got [undefined]'
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* 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 { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('create_runtime_field', () => {
|
||||
loadTestFile(require.resolve('./errors'));
|
||||
loadTestFile(require.resolve('./main'));
|
||||
});
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
||||
describe('main', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('test/api_integration/fixtures/es_archiver/index_patterns/basic_index');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload(
|
||||
'test/api_integration/fixtures/es_archiver/index_patterns/basic_index'
|
||||
);
|
||||
});
|
||||
|
||||
it('can create a new runtime field', async () => {
|
||||
const title = `basic_index*`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
},
|
||||
});
|
||||
const id = response1.body.index_pattern.id;
|
||||
const response2 = await supertest
|
||||
.post(`/api/index_patterns/index_pattern/${id}/runtime_field`)
|
||||
.send({
|
||||
name: 'runtimeBar',
|
||||
runtimeField: {
|
||||
type: 'long',
|
||||
script: {
|
||||
source: "emit(doc['field_name'].value)",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response2.status).to.be(200);
|
||||
expect(response2.body.field.name).to.be('runtimeBar');
|
||||
expect(response2.body.field.runtimeField.type).to.be('long');
|
||||
expect(response2.body.field.runtimeField.script.source).to.be(
|
||||
"emit(doc['field_name'].value)"
|
||||
);
|
||||
expect(response2.body.field.scripted).to.be(false);
|
||||
});
|
||||
|
||||
it('newly created runtime field is available in the index_pattern object', async () => {
|
||||
const title = `basic_index`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
},
|
||||
});
|
||||
|
||||
await supertest
|
||||
.post(`/api/index_patterns/index_pattern/${response1.body.index_pattern.id}/runtime_field`)
|
||||
.send({
|
||||
name: 'runtimeBar',
|
||||
runtimeField: {
|
||||
type: 'long',
|
||||
script: {
|
||||
source: "emit(doc['field_name'].value)",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const response2 = await supertest.get(
|
||||
'/api/index_patterns/index_pattern/' + response1.body.index_pattern.id
|
||||
);
|
||||
|
||||
expect(response2.status).to.be(200);
|
||||
|
||||
const field = response2.body.index_pattern.fields.runtimeBar;
|
||||
|
||||
expect(field.name).to.be('runtimeBar');
|
||||
expect(field.runtimeField.type).to.be('long');
|
||||
expect(field.runtimeField.script.source).to.be("emit(doc['field_name'].value)");
|
||||
expect(field.scripted).to.be(false);
|
||||
await supertest.delete(
|
||||
'/api/index_patterns/index_pattern/' + response1.body.index_pattern.id
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const esArchiver = getService('esArchiver');
|
||||
const supertest = getService('supertest');
|
||||
|
||||
describe('errors', () => {
|
||||
const basicIndex = 'b*sic_index';
|
||||
let indexPattern: any;
|
||||
|
||||
before(async () => {
|
||||
await esArchiver.load('test/api_integration/fixtures/es_archiver/index_patterns/basic_index');
|
||||
|
||||
indexPattern = (
|
||||
await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
index_pattern: {
|
||||
title: basicIndex,
|
||||
},
|
||||
})
|
||||
).body.index_pattern;
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload(
|
||||
'test/api_integration/fixtures/es_archiver/index_patterns/basic_index'
|
||||
);
|
||||
|
||||
if (indexPattern) {
|
||||
await supertest.delete('/api/index_patterns/index_pattern/' + indexPattern.id);
|
||||
}
|
||||
});
|
||||
|
||||
it('returns 404 error on non-existing index_pattern', async () => {
|
||||
const id = `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx-${Date.now()}`;
|
||||
const response = await supertest.delete(
|
||||
`/api/index_patterns/index_pattern/${id}/runtime_field/foo`
|
||||
);
|
||||
|
||||
expect(response.status).to.be(404);
|
||||
});
|
||||
|
||||
it('returns 404 error on non-existing runtime field', async () => {
|
||||
const response1 = await supertest.delete(
|
||||
`/api/index_patterns/index_pattern/${indexPattern.id}/runtime_field/test`
|
||||
);
|
||||
|
||||
expect(response1.status).to.be(404);
|
||||
});
|
||||
|
||||
it('returns error when attempting to delete a field which is not a runtime field', async () => {
|
||||
const response2 = await supertest.delete(
|
||||
`/api/index_patterns/index_pattern/${indexPattern.id}/runtime_field/foo`
|
||||
);
|
||||
|
||||
expect(response2.status).to.be(400);
|
||||
expect(response2.body.statusCode).to.be(400);
|
||||
expect(response2.body.message).to.be('Only runtime fields can be deleted.');
|
||||
});
|
||||
|
||||
it('returns error when ID is too long', async () => {
|
||||
const id = `xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx`;
|
||||
const response = await supertest.delete(
|
||||
`/api/index_patterns/index_pattern/${id}/runtime_field/foo`
|
||||
);
|
||||
|
||||
expect(response.status).to.be(400);
|
||||
expect(response.body.message).to.be(
|
||||
'[request params.id]: value has length [1759] but it must have a maximum length of [1000].'
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* 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 { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('delete_runtime_field', () => {
|
||||
loadTestFile(require.resolve('./errors'));
|
||||
loadTestFile(require.resolve('./main'));
|
||||
});
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
||||
describe('main', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('test/api_integration/fixtures/es_archiver/index_patterns/basic_index');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload(
|
||||
'test/api_integration/fixtures/es_archiver/index_patterns/basic_index'
|
||||
);
|
||||
});
|
||||
|
||||
it('can delete a runtime field', async () => {
|
||||
const title = `basic_index*`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
runtimeFieldMap: {
|
||||
runtimeBar: {
|
||||
type: 'long',
|
||||
script: {
|
||||
source: "emit(doc['field_name'].value)",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const response2 = await supertest.get(
|
||||
'/api/index_patterns/index_pattern/' + response1.body.index_pattern.id
|
||||
);
|
||||
|
||||
expect(typeof response2.body.index_pattern.fields.runtimeBar).to.be('object');
|
||||
|
||||
const response3 = await supertest.delete(
|
||||
`/api/index_patterns/index_pattern/${response1.body.index_pattern.id}/runtime_field/runtimeBar`
|
||||
);
|
||||
|
||||
expect(response3.status).to.be(200);
|
||||
|
||||
const response4 = await supertest.get(
|
||||
'/api/index_patterns/index_pattern/' + response1.body.index_pattern.id
|
||||
);
|
||||
|
||||
expect(typeof response4.body.index_pattern.fields.runtimeBar).to.be('undefined');
|
||||
await supertest.delete(
|
||||
'/api/index_patterns/index_pattern/' + response1.body.index_pattern.id
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const esArchiver = getService('esArchiver');
|
||||
const supertest = getService('supertest');
|
||||
|
||||
describe('errors', () => {
|
||||
const basicIndex = '*asic_index';
|
||||
let indexPattern: any;
|
||||
|
||||
before(async () => {
|
||||
await esArchiver.load('test/api_integration/fixtures/es_archiver/index_patterns/basic_index');
|
||||
|
||||
indexPattern = (
|
||||
await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
index_pattern: {
|
||||
title: basicIndex,
|
||||
},
|
||||
})
|
||||
).body.index_pattern;
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload(
|
||||
'test/api_integration/fixtures/es_archiver/index_patterns/basic_index'
|
||||
);
|
||||
|
||||
if (indexPattern) {
|
||||
await supertest.delete('/api/index_patterns/index_pattern/' + indexPattern.id);
|
||||
}
|
||||
});
|
||||
|
||||
it('returns 404 error on non-existing index_pattern', async () => {
|
||||
const id = `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx-${Date.now()}`;
|
||||
const response = await supertest.get(
|
||||
`/api/index_patterns/index_pattern/${id}/runtime_field/foo`
|
||||
);
|
||||
|
||||
expect(response.status).to.be(404);
|
||||
});
|
||||
|
||||
it('returns 404 error on non-existing runtime field', async () => {
|
||||
const response1 = await supertest.get(
|
||||
`/api/index_patterns/index_pattern/${indexPattern.id}/runtime_field/sf`
|
||||
);
|
||||
|
||||
expect(response1.status).to.be(404);
|
||||
});
|
||||
|
||||
it('returns error when ID is too long', async () => {
|
||||
const id = `xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx`;
|
||||
const response = await supertest.get(
|
||||
`/api/index_patterns/index_pattern/${id}/runtime_field/foo`
|
||||
);
|
||||
|
||||
expect(response.status).to.be(400);
|
||||
expect(response.body.message).to.be(
|
||||
'[request params.id]: value has length [1759] but it must have a maximum length of [1000].'
|
||||
);
|
||||
});
|
||||
|
||||
it('returns error when attempting to fetch a field which is not a runtime field', async () => {
|
||||
const response2 = await supertest.get(
|
||||
`/api/index_patterns/index_pattern/${indexPattern.id}/runtime_field/foo`
|
||||
);
|
||||
|
||||
expect(response2.status).to.be(400);
|
||||
expect(response2.body.statusCode).to.be(400);
|
||||
expect(response2.body.message).to.be('Only runtime fields can be retrieved.');
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* 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 { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('get_runtime_field', () => {
|
||||
loadTestFile(require.resolve('./errors'));
|
||||
loadTestFile(require.resolve('./main'));
|
||||
});
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
||||
describe('main', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('test/api_integration/fixtures/es_archiver/index_patterns/basic_index');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload(
|
||||
'test/api_integration/fixtures/es_archiver/index_patterns/basic_index'
|
||||
);
|
||||
});
|
||||
|
||||
it('can fetch a runtime field', async () => {
|
||||
const title = `basic_index*`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
runtimeFieldMap: {
|
||||
runtimeFoo: {
|
||||
type: 'keyword',
|
||||
script: {
|
||||
source: "emit(doc['field_name'].value)",
|
||||
},
|
||||
},
|
||||
runtimeBar: {
|
||||
type: 'keyword',
|
||||
script: {
|
||||
source: "emit(doc['field_name'].value)",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response1.status).to.be(200);
|
||||
|
||||
const response2 = await supertest.get(
|
||||
'/api/index_patterns/index_pattern/' +
|
||||
response1.body.index_pattern.id +
|
||||
'/runtime_field/runtimeFoo'
|
||||
);
|
||||
|
||||
expect(response2.status).to.be(200);
|
||||
expect(typeof response2.body.field).to.be('object');
|
||||
expect(response2.body.field.name).to.be('runtimeFoo');
|
||||
expect(response2.body.field.type).to.be('string');
|
||||
expect(response2.body.field.scripted).to.be(false);
|
||||
expect(response2.body.field.runtimeField.script.source).to.be(
|
||||
"emit(doc['field_name'].value)"
|
||||
);
|
||||
await supertest.delete(
|
||||
'/api/index_patterns/index_pattern/' + response1.body.index_pattern.id
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -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 { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
|
||||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('runtime_fields_crud', () => {
|
||||
loadTestFile(require.resolve('./create_runtime_field'));
|
||||
loadTestFile(require.resolve('./get_runtime_field'));
|
||||
loadTestFile(require.resolve('./delete_runtime_field'));
|
||||
loadTestFile(require.resolve('./put_runtime_field'));
|
||||
loadTestFile(require.resolve('./update_runtime_field'));
|
||||
});
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
||||
describe('errors', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('test/api_integration/fixtures/es_archiver/index_patterns/basic_index');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload(
|
||||
'test/api_integration/fixtures/es_archiver/index_patterns/basic_index'
|
||||
);
|
||||
});
|
||||
|
||||
it('returns 404 error on non-existing index_pattern', async () => {
|
||||
const id = `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx-${Date.now()}`;
|
||||
const response = await supertest
|
||||
.put(`/api/index_patterns/index_pattern/${id}/runtime_field`)
|
||||
.send({
|
||||
name: 'runtimeBar',
|
||||
runtimeField: {
|
||||
type: 'long',
|
||||
script: {
|
||||
source: "emit(doc['field_name'].value)",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).to.be(404);
|
||||
});
|
||||
|
||||
it('returns error on non-runtime field update attempt', async () => {
|
||||
const title = `basic_index`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
},
|
||||
});
|
||||
|
||||
const response2 = await supertest
|
||||
.put(`/api/index_patterns/index_pattern/${response1.body.index_pattern.id}/runtime_field`)
|
||||
.send({
|
||||
name: 'bar',
|
||||
runtimeField: {
|
||||
type: 'long',
|
||||
script: {
|
||||
source: "emit(doc['field_name'].value)",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response2.status).to.be(400);
|
||||
expect(response2.body.message).to.be('Only runtime fields can be updated');
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* 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 { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('put_runtime_field', () => {
|
||||
loadTestFile(require.resolve('./errors'));
|
||||
loadTestFile(require.resolve('./main'));
|
||||
});
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
||||
describe('main', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('test/api_integration/fixtures/es_archiver/index_patterns/basic_index');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload(
|
||||
'test/api_integration/fixtures/es_archiver/index_patterns/basic_index'
|
||||
);
|
||||
});
|
||||
|
||||
it('can overwrite an existing field', async () => {
|
||||
const title = `basic_index`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
runtimeFieldMap: {
|
||||
runtimeFoo: {
|
||||
type: 'keyword',
|
||||
script: {
|
||||
source: "doc['field_name'].value",
|
||||
},
|
||||
},
|
||||
runtimeBar: {
|
||||
type: 'keyword',
|
||||
script: {
|
||||
source: "doc['field_name'].value",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const response2 = await supertest
|
||||
.put(`/api/index_patterns/index_pattern/${response1.body.index_pattern.id}/runtime_field`)
|
||||
.send({
|
||||
name: 'runtimeFoo',
|
||||
runtimeField: {
|
||||
type: 'long',
|
||||
script: {
|
||||
source: "doc['field_name'].value",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response2.status).to.be(200);
|
||||
|
||||
const response3 = await supertest.get(
|
||||
'/api/index_patterns/index_pattern/' +
|
||||
response1.body.index_pattern.id +
|
||||
'/runtime_field/runtimeFoo'
|
||||
);
|
||||
|
||||
expect(response3.status).to.be(200);
|
||||
expect(response3.body.field.type).to.be('number');
|
||||
|
||||
const response4 = await supertest.get(
|
||||
'/api/index_patterns/index_pattern/' +
|
||||
response1.body.index_pattern.id +
|
||||
'/runtime_field/runtimeBar'
|
||||
);
|
||||
|
||||
expect(response4.status).to.be(200);
|
||||
expect(response4.body.field.type).to.be('string');
|
||||
});
|
||||
|
||||
it('can add a new runtime field', async () => {
|
||||
const title = `basic_index`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
runtimeFieldMap: {
|
||||
runtimeFoo: {
|
||||
type: 'keyword',
|
||||
script: {
|
||||
source: "doc['field_name'].value",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await supertest
|
||||
.put(`/api/index_patterns/index_pattern/${response1.body.index_pattern.id}/runtime_field`)
|
||||
.send({
|
||||
name: 'runtimeBar',
|
||||
runtimeField: {
|
||||
type: 'long',
|
||||
script: {
|
||||
source: "doc['field_name'].value",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const response2 = await supertest.get(
|
||||
'/api/index_patterns/index_pattern/' +
|
||||
response1.body.index_pattern.id +
|
||||
'/runtime_field/runtimeBar'
|
||||
);
|
||||
|
||||
expect(response2.status).to.be(200);
|
||||
expect(typeof response2.body.field.runtimeField).to.be('object');
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
|
||||
describe('errors', () => {
|
||||
it('returns 404 error on non-existing index_pattern', async () => {
|
||||
const id = `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx-${Date.now()}`;
|
||||
const response = await supertest
|
||||
.post(`/api/index_patterns/index_pattern/${id}/runtime_field/foo`)
|
||||
.send({
|
||||
runtimeField: {
|
||||
script: {
|
||||
source: "doc['something_new'].value",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).to.be(404);
|
||||
});
|
||||
|
||||
it('returns error when field name is specified', async () => {
|
||||
const id = `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx-${Date.now()}`;
|
||||
const response = await supertest
|
||||
.post(`/api/index_patterns/index_pattern/${id}/runtime_field/foo`)
|
||||
.send({
|
||||
name: 'foo',
|
||||
runtimeField: {
|
||||
script: {
|
||||
source: "doc['something_new'].value",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).to.be(400);
|
||||
expect(response.body.statusCode).to.be(400);
|
||||
expect(response.body.message).to.be(
|
||||
"[request body.name]: a value wasn't expected to be present"
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* 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 { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('update_runtime_field', () => {
|
||||
loadTestFile(require.resolve('./errors'));
|
||||
loadTestFile(require.resolve('./main'));
|
||||
});
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
||||
describe('main', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('test/api_integration/fixtures/es_archiver/index_patterns/basic_index');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload(
|
||||
'test/api_integration/fixtures/es_archiver/index_patterns/basic_index'
|
||||
);
|
||||
});
|
||||
|
||||
it('can update an existing field', async () => {
|
||||
const title = `basic_index`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
runtimeFieldMap: {
|
||||
runtimeFoo: {
|
||||
type: 'keyword',
|
||||
script: {
|
||||
source: "doc['field_name'].value",
|
||||
},
|
||||
},
|
||||
runtimeBar: {
|
||||
type: 'keyword',
|
||||
script: {
|
||||
source: "doc['field_name'].value",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const response2 = await supertest
|
||||
.post(
|
||||
`/api/index_patterns/index_pattern/${response1.body.index_pattern.id}/runtime_field/runtimeFoo`
|
||||
)
|
||||
.send({
|
||||
runtimeField: {
|
||||
script: {
|
||||
source: "doc['something_new'].value",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response2.status).to.be(200);
|
||||
|
||||
const response3 = await supertest.get(
|
||||
'/api/index_patterns/index_pattern/' +
|
||||
response1.body.index_pattern.id +
|
||||
'/runtime_field/runtimeFoo'
|
||||
);
|
||||
|
||||
expect(response3.status).to.be(200);
|
||||
expect(response3.body.field.type).to.be('string');
|
||||
expect(response3.body.field.runtimeField.type).to.be('keyword');
|
||||
expect(response3.body.field.runtimeField.script.source).to.be("doc['something_new'].value");
|
||||
});
|
||||
});
|
||||
}
|
|
@ -54,6 +54,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
it('newly created scripted field is materialized in the index_pattern object', async () => {
|
||||
const title = `basic_index`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
},
|
||||
|
|
|
@ -27,6 +27,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
it('can remove a scripted field', async () => {
|
||||
const title = `basic_index`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
fields: {
|
||||
|
|
|
@ -27,6 +27,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
it('can fetch a scripted field', async () => {
|
||||
const title = `basic_index`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
fields: {
|
||||
|
|
|
@ -27,6 +27,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
it('can overwrite an existing field', async () => {
|
||||
const title = `basic_index`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
fields: {
|
||||
|
|
|
@ -27,6 +27,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
it('can update an existing field', async () => {
|
||||
const title = `basic_index`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
fields: {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue