diff --git a/docs/apm/troubleshooting.asciidoc b/docs/apm/troubleshooting.asciidoc
index 65f7a378ec244..e00a67f6c78a4 100644
--- a/docs/apm/troubleshooting.asciidoc
+++ b/docs/apm/troubleshooting.asciidoc
@@ -49,7 +49,7 @@ GET /_template/apm-{version}
*Using Logstash, Kafka, etc.*
If you're not outputting data directly from APM Server to Elasticsearch (perhaps you're using Logstash or Kafka),
then the index template will not be set up automatically. Instead, you'll need to
-{apm-server-ref}/_manually_loading_template_configuration.html[load the template manually].
+{apm-server-ref}/configuration-template.html[load the template manually].
*Using a custom index names*
This problem can also occur if you've customized the index name that you write APM data to.
diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.md
index 6ef7b991bb159..650459bfdb435 100644
--- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.md
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.md
@@ -16,8 +16,6 @@ export interface SavedObjectsServiceSetup
When plugins access the Saved Objects client, a new client is created using the factory provided to `setClientFactory` and wrapped by all wrappers registered through `addClientWrapper`.
-All the setup APIs will throw if called after the service has started, and therefor cannot be used from legacy plugin code. Legacy plugins should use the legacy savedObject service until migrated.
-
## Example 1
diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.registertype.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.registertype.md
index 57c9e04966c1b..54e01d3110a2d 100644
--- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.registertype.md
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.registertype.md
@@ -14,10 +14,6 @@ See the [mappings format](./kibana-plugin-core-server.savedobjectstypemappingdef
registerType: (type: SavedObjectsType) => void;
```
-## Remarks
-
-The type definition is an aggregation of the legacy savedObjects `schema`, `mappings` and `migration` concepts. This API is the single entry point to register saved object types in the new platform.
-
## Example
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.getsearchparamsfromrequest.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.getsearchparamsfromrequest.md
index 337b4b3302cc3..d32e9a955f890 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.getsearchparamsfromrequest.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.getsearchparamsfromrequest.md
@@ -9,7 +9,6 @@
```typescript
export declare function getSearchParamsFromRequest(searchRequest: SearchRequest, dependencies: {
- esShardTimeout: number;
getConfig: GetConfigFn;
}): ISearchRequestParams;
```
@@ -19,7 +18,7 @@ export declare function getSearchParamsFromRequest(searchRequest: SearchRequest,
| Parameter | Type | Description |
| --- | --- | --- |
| searchRequest | SearchRequest
| |
-| dependencies | {
esShardTimeout: number;
getConfig: GetConfigFn;
}
| |
+| dependencies | {
getConfig: GetConfigFn;
}
| |
Returns:
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern._constructor_.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern._constructor_.md
index 2e078e3404fe6..a5bb15c963978 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern._constructor_.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern._constructor_.md
@@ -9,7 +9,7 @@ Constructs a new instance of the `IndexPattern` class
Signature:
```typescript
-constructor(id: string | undefined, { savedObjectsClient, apiClient, patternCache, fieldFormats, onNotification, onError, shortDotsEnable, metaFields, }: IndexPatternDeps);
+constructor(id: string | undefined, { savedObjectsClient, apiClient, patternCache, fieldFormats, indexPatternsService, onNotification, onError, shortDotsEnable, metaFields, }: IndexPatternDeps);
```
## Parameters
@@ -17,5 +17,5 @@ constructor(id: string | undefined, { savedObjectsClient, apiClient, patternCach
| Parameter | Type | Description |
| --- | --- | --- |
| id | string | undefined
| |
-| { savedObjectsClient, apiClient, patternCache, fieldFormats, onNotification, onError, shortDotsEnable, metaFields, } | IndexPatternDeps
| |
+| { savedObjectsClient, apiClient, patternCache, fieldFormats, indexPatternsService, onNotification, onError, shortDotsEnable, metaFields, } | IndexPatternDeps
| |
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md
index 4c53af3f8970e..87ce1e258712a 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md
@@ -14,7 +14,7 @@ export declare class IndexPattern implements IIndexPattern
| Constructor | Modifiers | Description |
| --- | --- | --- |
-| [(constructor)(id, { savedObjectsClient, apiClient, patternCache, fieldFormats, onNotification, onError, shortDotsEnable, metaFields, })](./kibana-plugin-plugins-data-public.indexpattern._constructor_.md) | | Constructs a new instance of the IndexPattern
class |
+| [(constructor)(id, { savedObjectsClient, apiClient, patternCache, fieldFormats, indexPatternsService, onNotification, onError, shortDotsEnable, metaFields, })](./kibana-plugin-plugins-data-public.indexpattern._constructor_.md) | | Constructs a new instance of the IndexPattern
class |
## Properties
@@ -29,11 +29,13 @@ export declare class IndexPattern implements IIndexPattern
| [id](./kibana-plugin-plugins-data-public.indexpattern.id.md) | | string
| |
| [intervalName](./kibana-plugin-plugins-data-public.indexpattern.intervalname.md) | | string | undefined
| |
| [metaFields](./kibana-plugin-plugins-data-public.indexpattern.metafields.md) | | string[]
| |
+| [originalBody](./kibana-plugin-plugins-data-public.indexpattern.originalbody.md) | | {
[key: string]: any;
}
| |
| [sourceFilters](./kibana-plugin-plugins-data-public.indexpattern.sourcefilters.md) | | SourceFilter[]
| |
| [timeFieldName](./kibana-plugin-plugins-data-public.indexpattern.timefieldname.md) | | string | undefined
| |
| [title](./kibana-plugin-plugins-data-public.indexpattern.title.md) | | string
| |
| [type](./kibana-plugin-plugins-data-public.indexpattern.type.md) | | string | undefined
| |
| [typeMeta](./kibana-plugin-plugins-data-public.indexpattern.typemeta.md) | | TypeMeta
| |
+| [version](./kibana-plugin-plugins-data-public.indexpattern.version.md) | | string | undefined
| |
## Methods
@@ -60,6 +62,5 @@ export declare class IndexPattern implements IIndexPattern
| [prepBody()](./kibana-plugin-plugins-data-public.indexpattern.prepbody.md) | | |
| [refreshFields()](./kibana-plugin-plugins-data-public.indexpattern.refreshfields.md) | | |
| [removeScriptedField(fieldName)](./kibana-plugin-plugins-data-public.indexpattern.removescriptedfield.md) | | |
-| [save(saveAttempts)](./kibana-plugin-plugins-data-public.indexpattern.save.md) | | |
| [toSpec()](./kibana-plugin-plugins-data-public.indexpattern.tospec.md) | | |
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.originalbody.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.originalbody.md
new file mode 100644
index 0000000000000..4bc3c76afbae9
--- /dev/null
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.originalbody.md
@@ -0,0 +1,13 @@
+
+
+[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPattern](./kibana-plugin-plugins-data-public.indexpattern.md) > [originalBody](./kibana-plugin-plugins-data-public.indexpattern.originalbody.md)
+
+## IndexPattern.originalBody property
+
+Signature:
+
+```typescript
+originalBody: {
+ [key: string]: any;
+ };
+```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.removescriptedfield.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.removescriptedfield.md
index 42c6dd72b8c4e..e902d9c42b082 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.removescriptedfield.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.removescriptedfield.md
@@ -7,7 +7,7 @@
Signature:
```typescript
-removeScriptedField(fieldName: string): Promise;
+removeScriptedField(fieldName: string): void;
```
## Parameters
@@ -18,5 +18,5 @@ removeScriptedField(fieldName: string): Promise;
Returns:
-`Promise`
+`void`
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.save.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.save.md
deleted file mode 100644
index d0b471cc2bc21..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.save.md
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPattern](./kibana-plugin-plugins-data-public.indexpattern.md) > [save](./kibana-plugin-plugins-data-public.indexpattern.save.md)
-
-## IndexPattern.save() method
-
-Signature:
-
-```typescript
-save(saveAttempts?: number): Promise;
-```
-
-## Parameters
-
-| Parameter | Type | Description |
-| --- | --- | --- |
-| saveAttempts | number
| |
-
-Returns:
-
-`Promise`
-
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.version.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.version.md
new file mode 100644
index 0000000000000..99d3bc4e7a04d
--- /dev/null
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.version.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPattern](./kibana-plugin-plugins-data-public.indexpattern.md) > [version](./kibana-plugin-plugins-data-public.indexpattern.version.md)
+
+## IndexPattern.version property
+
+Signature:
+
+```typescript
+version: string | undefined;
+```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md
index b651480a85899..0c493ca492953 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md
@@ -69,6 +69,7 @@
| [OptionedValueProp](./kibana-plugin-plugins-data-public.optionedvalueprop.md) | |
| [Query](./kibana-plugin-plugins-data-public.query.md) | |
| [QueryState](./kibana-plugin-plugins-data-public.querystate.md) | All query state service state |
+| [QueryStateChange](./kibana-plugin-plugins-data-public.querystatechange.md) | |
| [QuerySuggestionBasic](./kibana-plugin-plugins-data-public.querysuggestionbasic.md) | \* |
| [QuerySuggestionField](./kibana-plugin-plugins-data-public.querysuggestionfield.md) | \* |
| [QuerySuggestionGetFnArgs](./kibana-plugin-plugins-data-public.querysuggestiongetfnargs.md) | \* |
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystatechange.appfilters.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystatechange.appfilters.md
new file mode 100644
index 0000000000000..b358e9477e515
--- /dev/null
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystatechange.appfilters.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [QueryStateChange](./kibana-plugin-plugins-data-public.querystatechange.md) > [appFilters](./kibana-plugin-plugins-data-public.querystatechange.appfilters.md)
+
+## QueryStateChange.appFilters property
+
+Signature:
+
+```typescript
+appFilters?: boolean;
+```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystatechange.globalfilters.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystatechange.globalfilters.md
new file mode 100644
index 0000000000000..c395f169c35a5
--- /dev/null
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystatechange.globalfilters.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [QueryStateChange](./kibana-plugin-plugins-data-public.querystatechange.md) > [globalFilters](./kibana-plugin-plugins-data-public.querystatechange.globalfilters.md)
+
+## QueryStateChange.globalFilters property
+
+Signature:
+
+```typescript
+globalFilters?: boolean;
+```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystatechange.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystatechange.md
new file mode 100644
index 0000000000000..71fb211da11d2
--- /dev/null
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystatechange.md
@@ -0,0 +1,19 @@
+
+
+[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [QueryStateChange](./kibana-plugin-plugins-data-public.querystatechange.md)
+
+## QueryStateChange interface
+
+Signature:
+
+```typescript
+export interface QueryStateChange extends QueryStateChangePartial
+```
+
+## Properties
+
+| Property | Type | Description |
+| --- | --- | --- |
+| [appFilters](./kibana-plugin-plugins-data-public.querystatechange.appfilters.md) | boolean
| |
+| [globalFilters](./kibana-plugin-plugins-data-public.querystatechange.globalfilters.md) | boolean
| |
+
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinput.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinput.md
index 9f3ed8c1263ba..3dbfd9430e913 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinput.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinput.md
@@ -7,5 +7,5 @@
Signature:
```typescript
-QueryStringInput: React.FC>
+QueryStringInput: React.FC>
```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchbar.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchbar.md
index 498691c06285d..d1d20291a6799 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchbar.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchbar.md
@@ -7,7 +7,7 @@
Signature:
```typescript
-SearchBar: React.ComponentClass, "query" | "isLoading" | "filters" | "onRefresh" | "onRefreshChange" | "refreshInterval" | "indexPatterns" | "dataTestSubj" | "customSubmitButton" | "screenTitle" | "showQueryBar" | "showQueryInput" | "showFilterBar" | "showDatePicker" | "showAutoRefreshOnly" | "isRefreshPaused" | "dateRangeFrom" | "dateRangeTo" | "showSaveQuery" | "savedQuery" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated" | "onClearSavedQuery" | "indicateNoData" | "timeHistory" | "onFiltersUpdated">, any> & {
- WrappedComponent: React.ComponentType & ReactIntl.InjectedIntlProps>;
+SearchBar: React.ComponentClass, "query" | "isLoading" | "filters" | "onRefresh" | "onRefreshChange" | "refreshInterval" | "indexPatterns" | "dataTestSubj" | "timeHistory" | "customSubmitButton" | "screenTitle" | "showQueryBar" | "showQueryInput" | "showFilterBar" | "showDatePicker" | "showAutoRefreshOnly" | "isRefreshPaused" | "dateRangeFrom" | "dateRangeTo" | "showSaveQuery" | "savedQuery" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated" | "onClearSavedQuery" | "indicateNoData" | "onFiltersUpdated">, any> & {
+ WrappedComponent: React.ComponentType & ReactIntl.InjectedIntlProps>;
}
```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor._constructor_.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor._constructor_.md
index 6f5dd1076fb40..4c67639300883 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor._constructor_.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor._constructor_.md
@@ -4,12 +4,12 @@
## SearchInterceptor.(constructor)
-This class should be instantiated with a `requestTimeout` corresponding with how many ms after requests are initiated that they should automatically cancel.
+Constructs a new instance of the `SearchInterceptor` class
Signature:
```typescript
-constructor(deps: SearchInterceptorDeps, requestTimeout?: number | undefined);
+constructor(deps: SearchInterceptorDeps);
```
## Parameters
@@ -17,5 +17,4 @@ constructor(deps: SearchInterceptorDeps, requestTimeout?: number | undefined);
| Parameter | Type | Description |
| --- | --- | --- |
| deps | SearchInterceptorDeps
| |
-| requestTimeout | number | undefined
| |
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.md
index 32954927504ae..fd9f23a7f0052 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.md
@@ -14,21 +14,18 @@ export declare class SearchInterceptor
| Constructor | Modifiers | Description |
| --- | --- | --- |
-| [(constructor)(deps, requestTimeout)](./kibana-plugin-plugins-data-public.searchinterceptor._constructor_.md) | | This class should be instantiated with a requestTimeout
corresponding with how many ms after requests are initiated that they should automatically cancel. |
+| [(constructor)(deps)](./kibana-plugin-plugins-data-public.searchinterceptor._constructor_.md) | | Constructs a new instance of the SearchInterceptor
class |
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [deps](./kibana-plugin-plugins-data-public.searchinterceptor.deps.md) | | SearchInterceptorDeps
| |
-| [requestTimeout](./kibana-plugin-plugins-data-public.searchinterceptor.requesttimeout.md) | | number | undefined
| |
## Methods
| Method | Modifiers | Description |
| --- | --- | --- |
| [getPendingCount$()](./kibana-plugin-plugins-data-public.searchinterceptor.getpendingcount_.md) | | Returns an Observable
over the current number of pending searches. This could mean that one of the search requests is still in flight, or that it has only received partial responses. |
-| [runSearch(request, signal, strategy)](./kibana-plugin-plugins-data-public.searchinterceptor.runsearch.md) | | |
| [search(request, options)](./kibana-plugin-plugins-data-public.searchinterceptor.search.md) | | Searches using the given search
method. Overrides the AbortSignal
with one that will abort either when cancelPending
is called, when the request times out, or when the original AbortSignal
is aborted. Updates pendingCount$
when the request is started/finalized. |
-| [setupTimers(options)](./kibana-plugin-plugins-data-public.searchinterceptor.setuptimers.md) | | |
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.requesttimeout.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.requesttimeout.md
deleted file mode 100644
index 3123433762991..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.requesttimeout.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) > [requestTimeout](./kibana-plugin-plugins-data-public.searchinterceptor.requesttimeout.md)
-
-## SearchInterceptor.requestTimeout property
-
-Signature:
-
-```typescript
-protected readonly requestTimeout?: number | undefined;
-```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.runsearch.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.runsearch.md
deleted file mode 100644
index ad1d1dcb59d7b..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.runsearch.md
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) > [runSearch](./kibana-plugin-plugins-data-public.searchinterceptor.runsearch.md)
-
-## SearchInterceptor.runSearch() method
-
-Signature:
-
-```typescript
-protected runSearch(request: IEsSearchRequest, signal: AbortSignal, strategy?: string): Observable;
-```
-
-## Parameters
-
-| Parameter | Type | Description |
-| --- | --- | --- |
-| request | IEsSearchRequest
| |
-| signal | AbortSignal
| |
-| strategy | string
| |
-
-Returns:
-
-`Observable`
-
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.setuptimers.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.setuptimers.md
deleted file mode 100644
index fe35655258b4c..0000000000000
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.setuptimers.md
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) > [setupTimers](./kibana-plugin-plugins-data-public.searchinterceptor.setuptimers.md)
-
-## SearchInterceptor.setupTimers() method
-
-Signature:
-
-```typescript
-protected setupTimers(options?: ISearchOptions): {
- combinedSignal: AbortSignal;
- cleanup: () => void;
- };
-```
-
-## Parameters
-
-| Parameter | Type | Description |
-| --- | --- | --- |
-| options | ISearchOptions
| |
-
-Returns:
-
-`{
- combinedSignal: AbortSignal;
- cleanup: () => void;
- }`
-
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ui_settings.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ui_settings.md
index e515c3513df6c..6ed20beb396f1 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ui_settings.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ui_settings.md
@@ -20,6 +20,7 @@ UI_SETTINGS: {
readonly COURIER_MAX_CONCURRENT_SHARD_REQUESTS: "courier:maxConcurrentShardRequests";
readonly COURIER_BATCH_SEARCHES: "courier:batchSearches";
readonly SEARCH_INCLUDE_FROZEN: "search:includeFrozen";
+ readonly SEARCH_TIMEOUT: "search:timeout";
readonly HISTOGRAM_BAR_TARGET: "histogram:barTarget";
readonly HISTOGRAM_MAX_BARS: "histogram:maxBars";
readonly HISTORY_LIMIT: "history:limit";
diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getdefaultsearchparams.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getdefaultsearchparams.md
index 9de005c1fd0dd..e718ca42ca30f 100644
--- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getdefaultsearchparams.md
+++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getdefaultsearchparams.md
@@ -7,24 +7,26 @@
Signature:
```typescript
-export declare function getDefaultSearchParams(config: SharedGlobalConfig): {
- timeout: string;
+export declare function getDefaultSearchParams(uiSettingsClient: IUiSettingsClient): Promise<{
+ maxConcurrentShardRequests: number | undefined;
+ ignoreThrottled: boolean;
ignoreUnavailable: boolean;
- restTotalHitsAsInt: boolean;
-};
+ trackTotalHits: boolean;
+}>;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
-| config | SharedGlobalConfig
| |
+| uiSettingsClient | IUiSettingsClient
| |
Returns:
-`{
- timeout: string;
+`Promise<{
+ maxConcurrentShardRequests: number | undefined;
+ ignoreThrottled: boolean;
ignoreUnavailable: boolean;
- restTotalHitsAsInt: boolean;
-}`
+ trackTotalHits: boolean;
+}>`
diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getshardtimeout.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getshardtimeout.md
new file mode 100644
index 0000000000000..d7e2a597ff33d
--- /dev/null
+++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getshardtimeout.md
@@ -0,0 +1,30 @@
+
+
+[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [getShardTimeout](./kibana-plugin-plugins-data-server.getshardtimeout.md)
+
+## getShardTimeout() function
+
+Signature:
+
+```typescript
+export declare function getShardTimeout(config: SharedGlobalConfig): {
+ timeout: string;
+} | {
+ timeout?: undefined;
+};
+```
+
+## Parameters
+
+| Parameter | Type | Description |
+| --- | --- | --- |
+| config | SharedGlobalConfig
| |
+
+Returns:
+
+`{
+ timeout: string;
+} | {
+ timeout?: undefined;
+}`
+
diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md
index 70c32adeab9fd..f5b587d86b349 100644
--- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md
+++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md
@@ -26,11 +26,13 @@
| Function | Description |
| --- | --- |
-| [getDefaultSearchParams(config)](./kibana-plugin-plugins-data-server.getdefaultsearchparams.md) | |
+| [getDefaultSearchParams(uiSettingsClient)](./kibana-plugin-plugins-data-server.getdefaultsearchparams.md) | |
+| [getShardTimeout(config)](./kibana-plugin-plugins-data-server.getshardtimeout.md) | |
| [getTime(indexPattern, timeRange, options)](./kibana-plugin-plugins-data-server.gettime.md) | |
| [parseInterval(interval)](./kibana-plugin-plugins-data-server.parseinterval.md) | |
| [plugin(initializerContext)](./kibana-plugin-plugins-data-server.plugin.md) | Static code to be shared externally |
| [shouldReadFieldFromDocValues(aggregatable, esType)](./kibana-plugin-plugins-data-server.shouldreadfieldfromdocvalues.md) | |
+| [toSnakeCase(obj)](./kibana-plugin-plugins-data-server.tosnakecase.md) | |
| [usageProvider(core)](./kibana-plugin-plugins-data-server.usageprovider.md) | |
## Interfaces
diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md
index 2d9104ef894bc..455c5ecdd8195 100644
--- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md
+++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md
@@ -8,7 +8,7 @@
```typescript
start(core: CoreStart): {
- search: ISearchStart>;
+ search: ISearchStart>;
fieldFormats: {
fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise;
};
@@ -27,7 +27,7 @@ start(core: CoreStart): {
Returns:
`{
- search: ISearchStart>;
+ search: ISearchStart>;
fieldFormats: {
fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise;
};
diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.tosnakecase.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.tosnakecase.md
new file mode 100644
index 0000000000000..eda9e9c312e59
--- /dev/null
+++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.tosnakecase.md
@@ -0,0 +1,22 @@
+
+
+[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [toSnakeCase](./kibana-plugin-plugins-data-server.tosnakecase.md)
+
+## toSnakeCase() function
+
+Signature:
+
+```typescript
+export declare function toSnakeCase(obj: Record): import("lodash").Dictionary;
+```
+
+## Parameters
+
+| Parameter | Type | Description |
+| --- | --- | --- |
+| obj | Record<string, any>
| |
+
+Returns:
+
+`import("lodash").Dictionary`
+
diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ui_settings.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ui_settings.md
index e419b64cd43aa..2d4ce75b956df 100644
--- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ui_settings.md
+++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ui_settings.md
@@ -20,6 +20,7 @@ UI_SETTINGS: {
readonly COURIER_MAX_CONCURRENT_SHARD_REQUESTS: "courier:maxConcurrentShardRequests";
readonly COURIER_BATCH_SEARCHES: "courier:batchSearches";
readonly SEARCH_INCLUDE_FROZEN: "search:includeFrozen";
+ readonly SEARCH_TIMEOUT: "search:timeout";
readonly HISTOGRAM_BAR_TARGET: "histogram:barTarget";
readonly HISTOGRAM_MAX_BARS: "histogram:maxBars";
readonly HISTORY_LIMIT: "history:limit";
diff --git a/docs/management/advanced-options.asciidoc b/docs/management/advanced-options.asciidoc
index a64a0330ae43f..ed20166c87f29 100644
--- a/docs/management/advanced-options.asciidoc
+++ b/docs/management/advanced-options.asciidoc
@@ -225,6 +225,7 @@ be inconsistent because different shards might be in different refresh states.
`search:includeFrozen`:: Includes {ref}/frozen-indices.html[frozen indices] in results.
Searching through frozen indices
might increase the search time. This setting is off by default. Users must opt-in to include frozen indices.
+`search:timeout`:: Change the maximum timeout for a search session or set to 0 to disable the timeout and allow queries to run to completion.
[float]
[[kibana-siem-settings]]
diff --git a/docs/user/dashboard/dashboard.asciidoc b/docs/user/dashboard/dashboard.asciidoc
index 0c0151cc3ace2..d88a3eb5092df 100644
--- a/docs/user/dashboard/dashboard.asciidoc
+++ b/docs/user/dashboard/dashboard.asciidoc
@@ -4,9 +4,9 @@
[partintro]
--
-A _dashboard_ is a collection of panels that you use to analyze your data. On a dashboard, you can add a variety of panels that
-you can rearrange and tell a story about your data. Panels contain everything you need, including visualizations,
-interactive controls, markdown, and more.
+A _dashboard_ is a collection of panels that you use to analyze your data. On a dashboard, you can add a variety of panels that
+you can rearrange and tell a story about your data. Panels contain everything you need, including visualizations,
+interactive controls, markdown, and more.
With *Dashboard*s, you can:
@@ -18,7 +18,7 @@ With *Dashboard*s, you can:
* Create and apply filters to focus on the data you want to display.
-* Control who can use your data, and share the dashboard with a small or large audience.
+* Control who can use your data, and share the dashboard with a small or large audience.
* Generate reports based on your findings.
@@ -42,7 +42,7 @@ image::images/dashboard-read-only-badge.png[Example of Dashboard read only acces
[[types-of-panels]]
== Types of panels
-Panels contain everything you need to tell a story about you data, including visualizations,
+Panels contain everything you need to tell a story about you data, including visualizations,
interactive controls, Markdown, and more.
[cols="50, 50"]
@@ -50,30 +50,30 @@ interactive controls, Markdown, and more.
a| *Area*
-Displays data points, connected by a line, where the area between the line and axes are shaded.
+Displays data points, connected by a line, where the area between the line and axes are shaded.
Use area charts to compare two or more categories over time, and display the magnitude of trends.
| image:images/area.png[Area chart]
a| *Stacked area*
-Displays the evolution of the value of several data groups. The values of each group are displayed
-on top of each other. Use stacked area charts to visualize part-to-whole relationships, and to show
+Displays the evolution of the value of several data groups. The values of each group are displayed
+on top of each other. Use stacked area charts to visualize part-to-whole relationships, and to show
how each category contributes to the cumulative total.
| image:images/stacked_area.png[Stacked area chart]
a| *Bar*
-Displays bars side-by-side where each bar represents a category. Use bar charts to compare data across a
-large number of categories, display data that includes categories with negative values, and easily identify
+Displays bars side-by-side where each bar represents a category. Use bar charts to compare data across a
+large number of categories, display data that includes categories with negative values, and easily identify
the categories that represent the highest and lowest values. Kibana also supports horizontal bar charts.
| image:images/bar.png[Bar chart]
a| *Stacked bar*
-Displays numeric values across two or more categories. Use stacked bar charts to compare numeric values between
+Displays numeric values across two or more categories. Use stacked bar charts to compare numeric values between
levels of a categorical value. Kibana also supports stacked horizontal bar charts.
| image:images/stacked_bar.png[Stacked area chart]
@@ -81,15 +81,15 @@ levels of a categorical value. Kibana also supports stacked horizontal bar chart
a| *Line*
-Displays data points that are connected by a line. Use line charts to visualize a sequence of values, discover
+Displays data points that are connected by a line. Use line charts to visualize a sequence of values, discover
trends over time, and forecast future values.
| image:images/line.png[Line chart]
a| *Pie*
-Displays slices that represent a data category, where the slice size is proportional to the quantity it represents.
-Use pie charts to show comparisons between multiple categories, illustrate the dominance of one category over others,
+Displays slices that represent a data category, where the slice size is proportional to the quantity it represents.
+Use pie charts to show comparisons between multiple categories, illustrate the dominance of one category over others,
and show percentage or proportional data.
| image:images/pie.png[Pie chart]
@@ -103,7 +103,7 @@ Similar to the pie chart, but the central circle is removed. Use donut charts wh
a| *Tree map*
-Relates different segments of your data to the whole. Each rectangle is subdivided into smaller rectangles, or sub branches, based on
+Relates different segments of your data to the whole. Each rectangle is subdivided into smaller rectangles, or sub branches, based on
its proportion to the whole. Use treemaps to make efficient use of space to show percent total for each category.
| image:images/treemap.png[Tree map]
@@ -111,7 +111,7 @@ its proportion to the whole. Use treemaps to make efficient use of space to show
a| *Heat map*
-Displays graphical representations of data where the individual values are represented by colors. Use heat maps when your data set includes
+Displays graphical representations of data where the individual values are represented by colors. Use heat maps when your data set includes
categorical data. For example, use a heat map to see the flights of origin countries compared to destination countries using the sample flight data.
| image:images/heat_map.png[Heat map]
@@ -125,7 +125,7 @@ Displays how your metric progresses toward a fixed goal. Use the goal to display
a| *Gauge*
-Displays your data along a scale that changes color according to where your data falls on the expected scale. Use the gauge to show how metric
+Displays your data along a scale that changes color according to where your data falls on the expected scale. Use the gauge to show how metric
values relate to reference threshold values, or determine how a specified field is performing versus how it is expected to perform.
| image:images/gauge.png[Gauge]
@@ -133,7 +133,7 @@ values relate to reference threshold values, or determine how a specified field
a| *Metric*
-Displays a single numeric value for an aggregation. Use the metric visualization when you have a numeric value that is powerful enough to tell
+Displays a single numeric value for an aggregation. Use the metric visualization when you have a numeric value that is powerful enough to tell
a story about your data.
| image:images/metric.png[Metric]
@@ -141,7 +141,7 @@ a story about your data.
a| *Data table*
-Displays your raw data or aggregation results in a tabular format. Use data tables to display server configuration details, track counts, min,
+Displays your raw data or aggregation results in a tabular format. Use data tables to display server configuration details, track counts, min,
or max values for a specific field, and monitor the status of key services.
| image:images/data_table.png[Data table]
@@ -149,7 +149,7 @@ or max values for a specific field, and monitor the status of key services.
a| *Tag cloud*
-Graphical representations of how frequently a word appears in the source text. Use tag clouds to easily produce a summary of large documents and
+Graphical representations of how frequently a word appears in the source text. Use tag clouds to easily produce a summary of large documents and
create visual art for a specific topic.
| image:images/tag_cloud.png[Tag cloud]
@@ -168,16 +168,16 @@ For all your mapping needs, use <>.
[[create-panels]]
== Create panels
-To create a panel, make sure you have {ref}/getting-started-index.html[data indexed into {es}] and an <>
-to retrieve the data from {es}. If you aren’t ready to use your own data, {kib} comes with several pre-built dashboards that you can test out. For more information,
+To create a panel, make sure you have {ref}/getting-started-index.html[data indexed into {es}] and an <>
+to retrieve the data from {es}. If you aren’t ready to use your own data, {kib} comes with several pre-built dashboards that you can test out. For more information,
refer to <>.
-To begin, click *Create new*, then choose one of the following options on the
+To begin, click *Create new*, then choose one of the following options on the
*New Visualization* window:
-* Click on the type of panel you want to create, then configure the options.
+* Click on the type of panel you want to create, then configure the options.
-* Select an editor to help you create the panel.
+* Select an editor to help you create the panel.
[role="screenshot"]
image:images/Dashboard_add_new_visualization.png[Example add new visualization to dashboard]
@@ -188,19 +188,19 @@ image:images/Dashboard_add_new_visualization.png[Example add new visualization t
[[lens]]
=== Create panels with Lens
-*Lens* is the simplest and fastest way to create powerful visualizations of your data. To use *Lens*, you drag and drop as many data fields
+*Lens* is the simplest and fastest way to create powerful visualizations of your data. To use *Lens*, you drag and drop as many data fields
as you want onto the visualization builder pane, and *Lens* uses heuristics to decide how to apply each field to the visualization.
With *Lens*, you can:
* Use the automatically generated suggestions to change the visualization type.
-* Create visualizations with multiple layers and indices.
+* Create visualizations with multiple layers and indices.
* Change the aggregation and labels to customize the data.
[role="screenshot"]
image::images/lens_drag_drop.gif[Drag and drop]
-TIP: Drag-and-drop capabilities are available only when *Lens* knows how to use the data. If *Lens* is unable to automatically generate a
+TIP: Drag-and-drop capabilities are available only when *Lens* knows how to use the data. If *Lens* is unable to automatically generate a
visualization, configure the customization options for your visualization.
[float]
@@ -220,7 +220,7 @@ To filter the data fields:
[[view-data-summaries]]
==== View data summaries
-To help you decide exactly the data you want to display, get a quick summary of each field. The summary shows the distribution of
+To help you decide exactly the data you want to display, get a quick summary of each field. The summary shows the distribution of
values within the specified time range.
To view the data field summary information, navigate to the field, then click *i*.
@@ -250,10 +250,10 @@ When there is an exclamation point (!) next to a visualization type, *Lens* is u
[[customize-the-data]]
==== Customize the data
-For each visualization type, you can customize the aggregation and labels. The options available depend on the selected visualization type.
+For each visualization type, you can customize the aggregation and labels. The options available depend on the selected visualization type.
. Click a data field name in the editor, or click *Drop a field here*.
-. Change the options that appear.
+. Change the options that appear.
+
[role="screenshot"]
image::images/lens_aggregation_labels.png[Quick function options]
@@ -262,7 +262,7 @@ image::images/lens_aggregation_labels.png[Quick function options]
[[add-layers-and-indices]]
==== Add layers and indices
-To compare and analyze data from different sources, you can visualize multiple data layers and indices. Multiple layers and indices are
+To compare and analyze data from different sources, you can visualize multiple data layers and indices. Multiple layers and indices are
supported in area, line, and bar charts.
To add a layer, click *+*, then drag and drop the data fields for the new layer.
@@ -281,7 +281,7 @@ Ready to try out *Lens*? Refer to the <>.
[[tsvb]]
=== Create panels with TSVB
-*TSVB* is a time series data visualizer that allows you to use the full power of the Elasticsearch aggregation framework. To use *TSVB*,
+*TSVB* is a time series data visualizer that allows you to use the full power of the Elasticsearch aggregation framework. To use *TSVB*,
you can combine an infinite number of <> to display your data.
With *TSVB*, you can:
@@ -295,15 +295,15 @@ image::images/tsvb.png[TSVB UI]
[float]
[[configure-the-data]]
-==== Configure the data
+==== Configure the data
-With *TSVB*, you can add and display multiple data sets to compare and analyze. {kib} uses many types of <> that you can use to build
+With *TSVB*, you can add and display multiple data sets to compare and analyze. {kib} uses many types of <> that you can use to build
complex summaries of that data.
. Select *Data*. If you are using *Table*, select *Columns*.
-. From the *Aggregation* drop down, select the aggregation you want to visualize.
+. From the *Aggregation* drop down, select the aggregation you want to visualize.
+
-If you don’t see any data, change the <>.
+If you don’t see any data, change the <>.
+
To add multiple aggregations, click *+*.
. From the *Group by* drop down, select how you want to group or split the data.
@@ -315,14 +315,14 @@ When you have more than one aggregation, the last value is displayed, which is i
[[change-the-data-display]]
==== Change the data display
-To find the best way to display your data, *TSVB* supports several types of panels and charts.
+To find the best way to display your data, *TSVB* supports several types of panels and charts.
To change the *Time Series* chart type:
. Click *Data > Options*.
. Select the *Chart type*.
-To change the panel type, click on the panel options:
+To change the panel type, click on the panel options:
[role="screenshot"]
image::images/tsvb_change_display.gif[TSVB change the panel type]
@@ -331,7 +331,7 @@ image::images/tsvb_change_display.gif[TSVB change the panel type]
[[custommize-the-data]]
==== Customize the data
-View data in a different <>, and change the data label name and colors. The options available depend on the panel type.
+View data in a different <>, and change the data label name and colors. The options available depend on the panel type.
To change the index pattern, click *Panel options*, then enter the new *Index Pattern*.
@@ -361,7 +361,7 @@ image::images/tsvb_annotations.png[TSVB annotations]
[[filter-the-panel]]
==== Filter the panel
-The data that displays on the panel is based on the <> and <>.
+The data that displays on the panel is based on the <> and <>.
You can filter the data on the panels using the <>.
Click *Panel options*, then enter the syntax in the *Panel Filter* field.
@@ -372,7 +372,7 @@ If you want to ignore filters from all of {kib}, select *Yes* for *Ignore global
[[vega]]
=== Create custom panels with Vega
-Build custom visualizations using *Vega* and *Vega-Lite*, backed by one or more data sources including {es}, Elastic Map Service,
+Build custom visualizations using *Vega* and *Vega-Lite*, backed by one or more data sources including {es}, Elastic Map Service,
URL, or static data. Use the {kib} extensions to embed *Vega* in your dashboard, and add interactive tools.
Use *Vega* and *Vega-Lite* when you want to create a visualization for:
@@ -405,7 +405,7 @@ For more information about *Vega* and *Vega-Lite*, refer to:
[[timelion]]
=== Create panels with Timelion
-*Timelion* is a time series data visualizer that enables you to combine independent data sources within a single visualization.
+*Timelion* is a time series data visualizer that enables you to combine independent data sources within a single visualization.
*Timelion* is driven by a simple expression language that you use to:
@@ -422,9 +422,41 @@ Ready to try out Timelion? For step-by-step tutorials, refer to:
* <>
* <>
+[float]
+[[timelion-deprecation]]
+==== Timelion app deprecation
+
+Deprecated since 7.0, the Timelion app will be removed in 8.0. If you have any Timelion worksheets, you must migrate them to a dashboard.
+
+NOTE: Only the Timelion app is deprecated. {kib} continues to support Timelion
+visualizations on dashboards and in Visualize and Canvas.
+
+To migrate a Timelion worksheet to a dashboard:
+
+. Open the menu, click **Dashboard**, then click **Create dashboard**.
+
+. On the dashboard, click **Create New**, then select the Timelion visualization.
+
+. On a new tab, open the Timelion app, select the chart you want to copy, and copy its expression.
++
+[role="screenshot"]
+image::images/timelion-copy-expression.png[]
+
+. Return to the other tab and paste the copied expression to the *Timelion Expression* field and click **Update**.
++
+[role="screenshot"]
+image::images/timelion-vis-paste-expression.png[]
+
+. Save the new visualization, give it a name, and click **Save and Return**.
++
+Your Timelion visualization will appear on the dashboard. Repeat this for all your charts on each worksheet.
++
+[role="screenshot"]
+image::images/timelion-dashboard.png[]
+
[float]
[[save-panels]]
-=== Save panels
+== Save panels
When you’ve finished making changes, save the panels.
@@ -436,7 +468,7 @@ When you’ve finished making changes, save the panels.
[[add-existing-panels]]
== Add existing panels
-Add panels that you’ve already created to your dashboard.
+Add panels that you’ve already created to your dashboard.
On the dashboard, click *Add an existing*, then select the panel you want to add.
@@ -445,7 +477,7 @@ When a panel contains a stored query, both queries are applied.
[role="screenshot"]
image:images/Dashboard_add_visualization.png[Example add visualization to dashboard]
-To make changes to the panel, put the dashboard in *Edit* mode, then select the edit option from the panel menu.
+To make changes to the panel, put the dashboard in *Edit* mode, then select the edit option from the panel menu.
The changes you make appear in every dashboard that uses the panel, except if you edit the panel title. Changes to the panel title appear only on the dashboard where you made the change.
[float]
diff --git a/kibana.d.ts b/kibana.d.ts
index d64752abd8b60..517bda374af9d 100644
--- a/kibana.d.ts
+++ b/kibana.d.ts
@@ -39,8 +39,6 @@ export namespace Legacy {
export type KibanaConfig = LegacyKibanaServer.KibanaConfig;
export type Request = LegacyKibanaServer.Request;
export type ResponseToolkit = LegacyKibanaServer.ResponseToolkit;
- export type SavedObjectsClient = LegacyKibanaServer.SavedObjectsClient;
- export type SavedObjectsService = LegacyKibanaServer.SavedObjectsLegacyService;
export type Server = LegacyKibanaServer.Server;
export type InitPluginFunction = LegacyKibanaPluginSpec.InitPluginFunction;
diff --git a/packages/kbn-ui-shared-deps/webpack.config.js b/packages/kbn-ui-shared-deps/webpack.config.js
index c81da4689052a..fa80dfdeef20f 100644
--- a/packages/kbn-ui-shared-deps/webpack.config.js
+++ b/packages/kbn-ui-shared-deps/webpack.config.js
@@ -32,22 +32,10 @@ exports.getWebpackConfig = ({ dev = false } = {}) => ({
mode: dev ? 'development' : 'production',
entry: {
'kbn-ui-shared-deps': './entry.js',
- 'kbn-ui-shared-deps.v7.dark': [
- '@elastic/eui/dist/eui_theme_dark.css',
- '@elastic/charts/dist/theme_only_dark.css',
- ],
- 'kbn-ui-shared-deps.v7.light': [
- '@elastic/eui/dist/eui_theme_light.css',
- '@elastic/charts/dist/theme_only_light.css',
- ],
- 'kbn-ui-shared-deps.v8.dark': [
- '@elastic/eui/dist/eui_theme_amsterdam_dark.css',
- '@elastic/charts/dist/theme_only_dark.css',
- ],
- 'kbn-ui-shared-deps.v8.light': [
- '@elastic/eui/dist/eui_theme_amsterdam_light.css',
- '@elastic/charts/dist/theme_only_light.css',
- ],
+ 'kbn-ui-shared-deps.v7.dark': ['@elastic/eui/dist/eui_theme_dark.css'],
+ 'kbn-ui-shared-deps.v7.light': ['@elastic/eui/dist/eui_theme_light.css'],
+ 'kbn-ui-shared-deps.v8.dark': ['@elastic/eui/dist/eui_theme_amsterdam_dark.css'],
+ 'kbn-ui-shared-deps.v8.light': ['@elastic/eui/dist/eui_theme_amsterdam_light.css'],
},
context: __dirname,
devtool: dev ? '#cheap-source-map' : false,
diff --git a/src/core/public/core_app/styles/_globals_v7dark.scss b/src/core/public/core_app/styles/_globals_v7dark.scss
index 8ac841aab8469..9a4a965d63a38 100644
--- a/src/core/public/core_app/styles/_globals_v7dark.scss
+++ b/src/core/public/core_app/styles/_globals_v7dark.scss
@@ -3,9 +3,6 @@
// prepended to all .scss imports (from JS, when v7dark theme selected)
@import '@elastic/eui/src/themes/eui/eui_colors_dark';
-
-@import '@elastic/eui/src/global_styling/functions/index';
-@import '@elastic/eui/src/global_styling/variables/index';
-@import '@elastic/eui/src/global_styling/mixins/index';
+@import '@elastic/eui/src/themes/eui/eui_globals';
@import './mixins';
diff --git a/src/core/public/core_app/styles/_globals_v7light.scss b/src/core/public/core_app/styles/_globals_v7light.scss
index 701bbdfe03662..ddb4b5b31fa1f 100644
--- a/src/core/public/core_app/styles/_globals_v7light.scss
+++ b/src/core/public/core_app/styles/_globals_v7light.scss
@@ -3,9 +3,6 @@
// prepended to all .scss imports (from JS, when v7light theme selected)
@import '@elastic/eui/src/themes/eui/eui_colors_light';
-
-@import '@elastic/eui/src/global_styling/functions/index';
-@import '@elastic/eui/src/global_styling/variables/index';
-@import '@elastic/eui/src/global_styling/mixins/index';
+@import '@elastic/eui/src/themes/eui/eui_globals';
@import './mixins';
diff --git a/src/core/public/core_app/styles/_globals_v8dark.scss b/src/core/public/core_app/styles/_globals_v8dark.scss
index 972365e9e9d0e..9ad9108f350ff 100644
--- a/src/core/public/core_app/styles/_globals_v8dark.scss
+++ b/src/core/public/core_app/styles/_globals_v8dark.scss
@@ -3,14 +3,6 @@
// prepended to all .scss imports (from JS, when v8dark theme selected)
@import '@elastic/eui/src/themes/eui-amsterdam/eui_amsterdam_colors_dark';
-
-@import '@elastic/eui/src/global_styling/functions/index';
-@import '@elastic/eui/src/themes/eui-amsterdam/global_styling/functions/index';
-
-@import '@elastic/eui/src/global_styling/variables/index';
-@import '@elastic/eui/src/themes/eui-amsterdam/global_styling/variables/index';
-
-@import '@elastic/eui/src/global_styling/mixins/index';
-@import '@elastic/eui/src/themes/eui-amsterdam/global_styling/mixins/index';
+@import '@elastic/eui/src/themes/eui-amsterdam/eui_amsterdam_globals';
@import './mixins';
diff --git a/src/core/public/core_app/styles/_globals_v8light.scss b/src/core/public/core_app/styles/_globals_v8light.scss
index dc99f4d45082e..a6b2cb84c2062 100644
--- a/src/core/public/core_app/styles/_globals_v8light.scss
+++ b/src/core/public/core_app/styles/_globals_v8light.scss
@@ -3,14 +3,6 @@
// prepended to all .scss imports (from JS, when v8light theme selected)
@import '@elastic/eui/src/themes/eui-amsterdam/eui_amsterdam_colors_light';
-
-@import '@elastic/eui/src/global_styling/functions/index';
-@import '@elastic/eui/src/themes/eui-amsterdam/global_styling/functions/index';
-
-@import '@elastic/eui/src/global_styling/variables/index';
-@import '@elastic/eui/src/themes/eui-amsterdam/global_styling/variables/index';
-
-@import '@elastic/eui/src/global_styling/mixins/index';
-@import '@elastic/eui/src/themes/eui-amsterdam/global_styling/mixins/index';
+@import '@elastic/eui/src/themes/eui-amsterdam/eui_amsterdam_globals';
@import './mixins';
diff --git a/src/core/public/styles/_base.scss b/src/core/public/styles/_base.scss
index 9b06b526fc7dd..427c6b7735435 100644
--- a/src/core/public/styles/_base.scss
+++ b/src/core/public/styles/_base.scss
@@ -1,4 +1,10 @@
+// Charts themes available app-wide
+@import '@elastic/charts/dist/theme';
+@import '@elastic/eui/src/themes/charts/theme';
+
+// Grab some nav-specific EUI vars
@import '@elastic/eui/src/components/collapsible_nav/variables';
+
// Application Layout
// chrome-context
diff --git a/src/core/server/index.ts b/src/core/server/index.ts
index c17d3d7546779..97aca74bfd48f 100644
--- a/src/core/server/index.ts
+++ b/src/core/server/index.ts
@@ -266,9 +266,7 @@ export {
SavedObjectUnsanitizedDoc,
SavedObjectsRepositoryFactory,
SavedObjectsResolveImportErrorsOptions,
- SavedObjectsSchema,
SavedObjectsSerializer,
- SavedObjectsLegacyService,
SavedObjectsUpdateOptions,
SavedObjectsUpdateResponse,
SavedObjectsAddToNamespacesOptions,
diff --git a/src/core/server/legacy/legacy_service.mock.ts b/src/core/server/legacy/legacy_service.mock.ts
index 26ec52185a5d8..c27f5be04d965 100644
--- a/src/core/server/legacy/legacy_service.mock.ts
+++ b/src/core/server/legacy/legacy_service.mock.ts
@@ -24,13 +24,7 @@ type LegacyServiceMock = jest.Mocked & { legacyId
const createDiscoverPluginsMock = (): LegacyServiceDiscoverPlugins => ({
pluginSpecs: [],
- uiExports: {
- savedObjectSchemas: {},
- savedObjectMappings: [],
- savedObjectMigrations: {},
- savedObjectValidations: {},
- savedObjectsManagement: {},
- },
+ uiExports: {},
navLinks: [],
pluginExtendedConfig: {
get: jest.fn(),
diff --git a/src/core/server/legacy/legacy_service.ts b/src/core/server/legacy/legacy_service.ts
index 880011d2e1923..b95644590b4e9 100644
--- a/src/core/server/legacy/legacy_service.ts
+++ b/src/core/server/legacy/legacy_service.ts
@@ -341,11 +341,9 @@ export class LegacyService implements CoreService {
registerStaticDir: setupDeps.core.http.registerStaticDir,
},
hapiServer: setupDeps.core.http.server,
- kibanaMigrator: startDeps.core.savedObjects.migrator,
uiPlugins: setupDeps.uiPlugins,
elasticsearch: setupDeps.core.elasticsearch,
rendering: setupDeps.core.rendering,
- savedObjectsClientProvider: startDeps.core.savedObjects.clientProvider,
legacy: this.legacyInternals,
},
logger: this.coreContext.logger,
diff --git a/src/core/server/legacy/types.ts b/src/core/server/legacy/types.ts
index cf08689a6d0d4..1105308fd44cf 100644
--- a/src/core/server/legacy/types.ts
+++ b/src/core/server/legacy/types.ts
@@ -24,7 +24,6 @@ import { KibanaRequest, LegacyRequest } from '../http';
import { InternalCoreSetup, InternalCoreStart } from '../internal_types';
import { PluginsServiceSetup, PluginsServiceStart, UiPlugins } from '../plugins';
import { InternalRenderingServiceSetup } from '../rendering';
-import { SavedObjectsLegacyUiExports } from '../types';
/**
* @internal
@@ -128,13 +127,13 @@ export type LegacyNavLink = Omit;
unknown?: [{ pluginSpec: LegacyPluginSpec; type: unknown }];
-};
+}
/**
* @public
diff --git a/src/core/server/saved_objects/__snapshots__/utils.test.ts.snap b/src/core/server/saved_objects/__snapshots__/utils.test.ts.snap
deleted file mode 100644
index 7cd0297e57857..0000000000000
--- a/src/core/server/saved_objects/__snapshots__/utils.test.ts.snap
+++ /dev/null
@@ -1,184 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`convertLegacyTypes converts the legacy mappings using default values if no schemas are specified 1`] = `
-Array [
- Object {
- "convertToAliasScript": undefined,
- "hidden": false,
- "indexPattern": undefined,
- "management": undefined,
- "mappings": Object {
- "properties": Object {
- "fieldA": Object {
- "type": "text",
- },
- },
- },
- "migrations": Object {},
- "name": "typeA",
- "namespaceType": "single",
- },
- Object {
- "convertToAliasScript": undefined,
- "hidden": false,
- "indexPattern": undefined,
- "management": undefined,
- "mappings": Object {
- "properties": Object {
- "fieldB": Object {
- "type": "text",
- },
- },
- },
- "migrations": Object {},
- "name": "typeB",
- "namespaceType": "single",
- },
- Object {
- "convertToAliasScript": undefined,
- "hidden": false,
- "indexPattern": undefined,
- "management": undefined,
- "mappings": Object {
- "properties": Object {
- "fieldC": Object {
- "type": "text",
- },
- },
- },
- "migrations": Object {},
- "name": "typeC",
- "namespaceType": "single",
- },
-]
-`;
-
-exports[`convertLegacyTypes merges everything when all are present 1`] = `
-Array [
- Object {
- "convertToAliasScript": undefined,
- "hidden": true,
- "indexPattern": "myIndex",
- "management": undefined,
- "mappings": Object {
- "properties": Object {
- "fieldA": Object {
- "type": "text",
- },
- },
- },
- "migrations": Object {
- "1.0.0": [Function],
- "2.0.4": [Function],
- },
- "name": "typeA",
- "namespaceType": "agnostic",
- },
- Object {
- "convertToAliasScript": "some alias script",
- "hidden": false,
- "indexPattern": undefined,
- "management": undefined,
- "mappings": Object {
- "properties": Object {
- "anotherFieldB": Object {
- "type": "boolean",
- },
- "fieldB": Object {
- "type": "text",
- },
- },
- },
- "migrations": Object {},
- "name": "typeB",
- "namespaceType": "single",
- },
- Object {
- "convertToAliasScript": undefined,
- "hidden": false,
- "indexPattern": undefined,
- "management": undefined,
- "mappings": Object {
- "properties": Object {
- "fieldC": Object {
- "type": "text",
- },
- },
- },
- "migrations": Object {
- "1.5.3": [Function],
- },
- "name": "typeC",
- "namespaceType": "single",
- },
-]
-`;
-
-exports[`convertLegacyTypes merges the mappings and the schema to create the type when schema exists for the type 1`] = `
-Array [
- Object {
- "convertToAliasScript": undefined,
- "hidden": true,
- "indexPattern": "fooBar",
- "management": undefined,
- "mappings": Object {
- "properties": Object {
- "fieldA": Object {
- "type": "text",
- },
- },
- },
- "migrations": Object {},
- "name": "typeA",
- "namespaceType": "agnostic",
- },
- Object {
- "convertToAliasScript": undefined,
- "hidden": false,
- "indexPattern": "barBaz",
- "management": undefined,
- "mappings": Object {
- "properties": Object {
- "fieldB": Object {
- "type": "text",
- },
- },
- },
- "migrations": Object {},
- "name": "typeB",
- "namespaceType": "multiple",
- },
- Object {
- "convertToAliasScript": undefined,
- "hidden": false,
- "indexPattern": undefined,
- "management": undefined,
- "mappings": Object {
- "properties": Object {
- "fieldC": Object {
- "type": "text",
- },
- },
- },
- "migrations": Object {},
- "name": "typeC",
- "namespaceType": "single",
- },
- Object {
- "convertToAliasScript": undefined,
- "hidden": false,
- "indexPattern": "bazQux",
- "management": undefined,
- "mappings": Object {
- "properties": Object {
- "fieldD": Object {
- "type": "text",
- },
- },
- },
- "migrations": Object {},
- "name": "typeD",
- "namespaceType": "agnostic",
- },
-]
-`;
diff --git a/src/core/server/saved_objects/index.ts b/src/core/server/saved_objects/index.ts
index a294b28753f7b..f2bae29c4743b 100644
--- a/src/core/server/saved_objects/index.ts
+++ b/src/core/server/saved_objects/index.ts
@@ -19,8 +19,6 @@
export * from './service';
-export { SavedObjectsSchema } from './schema';
-
export * from './import';
export {
diff --git a/src/core/server/saved_objects/migrations/core/document_migrator.test.ts b/src/core/server/saved_objects/migrations/core/document_migrator.test.ts
index 4fc94d1992869..4cc4f696d307c 100644
--- a/src/core/server/saved_objects/migrations/core/document_migrator.test.ts
+++ b/src/core/server/saved_objects/migrations/core/document_migrator.test.ts
@@ -48,7 +48,6 @@ describe('DocumentMigrator', () => {
return {
kibanaVersion: '25.2.3',
typeRegistry: createRegistry(),
- validateDoc: _.noop,
log: mockLogger,
};
}
@@ -60,7 +59,6 @@ describe('DocumentMigrator', () => {
name: 'foo',
migrations: _.noop as any,
}),
- validateDoc: _.noop,
log: mockLogger,
};
expect(() => new DocumentMigrator(invalidDefinition)).toThrow(
@@ -77,7 +75,6 @@ describe('DocumentMigrator', () => {
bar: (doc) => doc,
},
}),
- validateDoc: _.noop,
log: mockLogger,
};
expect(() => new DocumentMigrator(invalidDefinition)).toThrow(
@@ -94,7 +91,6 @@ describe('DocumentMigrator', () => {
'1.2.3': 23 as any,
},
}),
- validateDoc: _.noop,
log: mockLogger,
};
expect(() => new DocumentMigrator(invalidDefinition)).toThrow(
@@ -633,27 +629,6 @@ describe('DocumentMigrator', () => {
bbb: '3.2.3',
});
});
-
- test('fails if the validate doc throws', () => {
- const migrator = new DocumentMigrator({
- ...testOpts(),
- typeRegistry: createRegistry({
- name: 'aaa',
- migrations: {
- '2.3.4': (d) => set(d, 'attributes.counter', 42),
- },
- }),
- validateDoc: (d) => {
- if ((d.attributes as any).counter === 42) {
- throw new Error('Meaningful!');
- }
- },
- });
-
- const doc = { id: '1', type: 'foo', attributes: {}, migrationVersion: {}, aaa: {} };
-
- expect(() => migrator.migrate(doc)).toThrow(/Meaningful/);
- });
});
function renameAttr(path: string, newPath: string) {
diff --git a/src/core/server/saved_objects/migrations/core/document_migrator.ts b/src/core/server/saved_objects/migrations/core/document_migrator.ts
index c50f755fda994..345704fbfd783 100644
--- a/src/core/server/saved_objects/migrations/core/document_migrator.ts
+++ b/src/core/server/saved_objects/migrations/core/document_migrator.ts
@@ -73,12 +73,9 @@ import { SavedObjectMigrationFn } from '../types';
export type TransformFn = (doc: SavedObjectUnsanitizedDoc) => SavedObjectUnsanitizedDoc;
-type ValidateDoc = (doc: SavedObjectUnsanitizedDoc) => void;
-
interface DocumentMigratorOptions {
kibanaVersion: string;
typeRegistry: ISavedObjectTypeRegistry;
- validateDoc: ValidateDoc;
log: Logger;
}
@@ -113,19 +110,16 @@ export class DocumentMigrator implements VersionedTransformer {
* @param {DocumentMigratorOptions} opts
* @prop {string} kibanaVersion - The current version of Kibana
* @prop {SavedObjectTypeRegistry} typeRegistry - The type registry to get type migrations from
- * @prop {ValidateDoc} validateDoc - A function which, given a document throws an error if it is
- * not up to date. This is used to ensure we don't let unmigrated documents slip through.
* @prop {Logger} log - The migration logger
* @memberof DocumentMigrator
*/
- constructor({ typeRegistry, kibanaVersion, log, validateDoc }: DocumentMigratorOptions) {
+ constructor({ typeRegistry, kibanaVersion, log }: DocumentMigratorOptions) {
validateMigrationDefinition(typeRegistry);
this.migrations = buildActiveMigrations(typeRegistry, log);
this.transformDoc = buildDocumentTransform({
kibanaVersion,
migrations: this.migrations,
- validateDoc,
});
}
@@ -231,21 +225,16 @@ function buildActiveMigrations(
* Creates a function which migrates and validates any document that is passed to it.
*/
function buildDocumentTransform({
- kibanaVersion,
migrations,
- validateDoc,
}: {
kibanaVersion: string;
migrations: ActiveMigrations;
- validateDoc: ValidateDoc;
}): TransformFn {
return function transformAndValidate(doc: SavedObjectUnsanitizedDoc) {
const result = doc.migrationVersion
? applyMigrations(doc, migrations)
: markAsUpToDate(doc, migrations);
- validateDoc(result);
-
// In order to keep tests a bit more stable, we won't
// tack on an empy migrationVersion to docs that have
// no migrations defined.
diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts
index cc443093e30a3..7eb2cfefe4620 100644
--- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts
+++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts
@@ -134,7 +134,6 @@ const mockOptions = () => {
const options: MockedOptions = {
logger: loggingSystemMock.create().get(),
kibanaVersion: '8.2.3',
- savedObjectValidations: {},
typeRegistry: createRegistry([
{
name: 'testtype',
diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts
index 85b9099308807..b9f24a75c01d2 100644
--- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts
+++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts
@@ -28,7 +28,6 @@ import { BehaviorSubject } from 'rxjs';
import { Logger } from '../../../logging';
import { IndexMapping, SavedObjectsTypeMappingDefinitions } from '../../mappings';
import { SavedObjectUnsanitizedDoc, SavedObjectsSerializer } from '../../serialization';
-import { docValidator, PropertyValidators } from '../../validation';
import { buildActiveMappings, IndexMigrator, MigrationResult, MigrationStatus } from '../core';
import { DocumentMigrator, VersionedTransformer } from '../core/document_migrator';
import { MigrationEsClient } from '../core/';
@@ -44,7 +43,6 @@ export interface KibanaMigratorOptions {
kibanaConfig: KibanaConfigType;
kibanaVersion: string;
logger: Logger;
- savedObjectValidations: PropertyValidators;
}
export type IKibanaMigrator = Pick;
@@ -80,7 +78,6 @@ export class KibanaMigrator {
typeRegistry,
kibanaConfig,
savedObjectsConfig,
- savedObjectValidations,
kibanaVersion,
logger,
}: KibanaMigratorOptions) {
@@ -94,7 +91,6 @@ export class KibanaMigrator {
this.documentMigrator = new DocumentMigrator({
kibanaVersion,
typeRegistry,
- validateDoc: docValidator(savedObjectValidations || {}),
log: this.log,
});
// Building the active mappings (and associated md5sums) is an expensive
diff --git a/src/core/server/saved_objects/saved_objects_service.mock.ts b/src/core/server/saved_objects/saved_objects_service.mock.ts
index 6f5ecb1eb464b..e3d44c20dd190 100644
--- a/src/core/server/saved_objects/saved_objects_service.mock.ts
+++ b/src/core/server/saved_objects/saved_objects_service.mock.ts
@@ -26,8 +26,7 @@ import {
SavedObjectsServiceSetup,
SavedObjectsServiceStart,
} from './saved_objects_service';
-import { mockKibanaMigrator } from './migrations/kibana/kibana_migrator.mock';
-import { savedObjectsClientProviderMock } from './service/lib/scoped_client_provider.mock';
+
import { savedObjectsRepositoryMock } from './service/lib/repository.mock';
import { savedObjectsClientMock } from './service/saved_objects_client.mock';
import { typeRegistryMock } from './saved_objects_type_registry.mock';
@@ -54,11 +53,7 @@ const createStartContractMock = () => {
};
const createInternalStartContractMock = () => {
- const internalStartContract: jest.Mocked = {
- ...createStartContractMock(),
- clientProvider: savedObjectsClientProviderMock.create(),
- migrator: mockKibanaMigrator.create(),
- };
+ const internalStartContract: jest.Mocked = createStartContractMock();
return internalStartContract;
};
diff --git a/src/core/server/saved_objects/saved_objects_service.test.ts b/src/core/server/saved_objects/saved_objects_service.test.ts
index 8df6a07318c45..d6b30889eba5f 100644
--- a/src/core/server/saved_objects/saved_objects_service.test.ts
+++ b/src/core/server/saved_objects/saved_objects_service.test.ts
@@ -33,7 +33,6 @@ import { Env } from '../config';
import { configServiceMock } from '../mocks';
import { elasticsearchServiceMock } from '../elasticsearch/elasticsearch_service.mock';
import { elasticsearchClientMock } from '../elasticsearch/client/mocks';
-import { legacyServiceMock } from '../legacy/legacy_service.mock';
import { httpServiceMock } from '../http/http_service.mock';
import { httpServerMock } from '../http/http_server.mocks';
import { SavedObjectsClientFactoryProvider } from './service/lib';
@@ -65,7 +64,6 @@ describe('SavedObjectsService', () => {
return {
http: httpServiceMock.createInternalSetupContract(),
elasticsearch: elasticsearchMock,
- legacyPlugins: legacyServiceMock.createDiscoverPlugins(),
};
};
@@ -239,8 +237,7 @@ describe('SavedObjectsService', () => {
await soService.setup(createSetupDeps());
expect(migratorInstanceMock.runMigrations).toHaveBeenCalledTimes(0);
- const startContract = await soService.start(createStartDeps());
- expect(startContract.migrator).toBe(migratorInstanceMock);
+ await soService.start(createStartDeps());
expect(migratorInstanceMock.runMigrations).toHaveBeenCalledTimes(1);
});
diff --git a/src/core/server/saved_objects/saved_objects_service.ts b/src/core/server/saved_objects/saved_objects_service.ts
index f05e912b12ad8..5cc59d55a254e 100644
--- a/src/core/server/saved_objects/saved_objects_service.ts
+++ b/src/core/server/saved_objects/saved_objects_service.ts
@@ -23,12 +23,10 @@ import { CoreService } from '../../types';
import {
SavedObjectsClient,
SavedObjectsClientProvider,
- ISavedObjectsClientProvider,
SavedObjectsClientProviderOptions,
} from './';
import { KibanaMigrator, IKibanaMigrator } from './migrations';
import { CoreContext } from '../core_context';
-import { LegacyServiceDiscoverPlugins } from '../legacy';
import {
ElasticsearchClient,
IClusterClient,
@@ -49,9 +47,7 @@ import {
SavedObjectsClientWrapperFactory,
} from './service/lib/scoped_client_provider';
import { Logger } from '../logging';
-import { convertLegacyTypes } from './utils';
import { SavedObjectTypeRegistry, ISavedObjectTypeRegistry } from './saved_objects_type_registry';
-import { PropertyValidators } from './validation';
import { SavedObjectsSerializer } from './serialization';
import { registerRoutes } from './routes';
import { ServiceStatus } from '../status';
@@ -67,9 +63,6 @@ import { createMigrationEsClient } from './migrations/core/';
* the factory provided to `setClientFactory` and wrapped by all wrappers
* registered through `addClientWrapper`.
*
- * All the setup APIs will throw if called after the service has started, and therefor cannot be used
- * from legacy plugin code. Legacy plugins should use the legacy savedObject service until migrated.
- *
* @example
* ```ts
* import { SavedObjectsClient, CoreSetup } from 'src/core/server';
@@ -155,9 +148,6 @@ export interface SavedObjectsServiceSetup {
* }
* }
* ```
- *
- * @remarks The type definition is an aggregation of the legacy savedObjects `schema`, `mappings` and `migration` concepts.
- * This API is the single entry point to register saved object types in the new platform.
*/
registerType: (type: SavedObjectsType) => void;
@@ -230,16 +220,7 @@ export interface SavedObjectsServiceStart {
getTypeRegistry: () => ISavedObjectTypeRegistry;
}
-export interface InternalSavedObjectsServiceStart extends SavedObjectsServiceStart {
- /**
- * @deprecated Exposed only for injecting into Legacy
- */
- migrator: IKibanaMigrator;
- /**
- * @deprecated Exposed only for injecting into Legacy
- */
- clientProvider: ISavedObjectsClientProvider;
-}
+export type InternalSavedObjectsServiceStart = SavedObjectsServiceStart;
/**
* Factory provided when invoking a {@link SavedObjectsClientFactoryProvider | client factory provider}
@@ -271,7 +252,6 @@ export interface SavedObjectsRepositoryFactory {
/** @internal */
export interface SavedObjectsSetupDeps {
http: InternalHttpServiceSetup;
- legacyPlugins: LegacyServiceDiscoverPlugins;
elasticsearch: InternalElasticsearchServiceSetup;
}
@@ -296,9 +276,8 @@ export class SavedObjectsService
private clientFactoryProvider?: SavedObjectsClientFactoryProvider;
private clientFactoryWrappers: WrappedClientFactoryWrapper[] = [];
- private migrator$ = new Subject();
+ private migrator$ = new Subject();
private typeRegistry = new SavedObjectTypeRegistry();
- private validations: PropertyValidators = {};
private started = false;
constructor(private readonly coreContext: CoreContext) {
@@ -310,13 +289,6 @@ export class SavedObjectsService
this.setupDeps = setupDeps;
- const legacyTypes = convertLegacyTypes(
- setupDeps.legacyPlugins.uiExports,
- setupDeps.legacyPlugins.pluginExtendedConfig
- );
- legacyTypes.forEach((type) => this.typeRegistry.registerType(type));
- this.validations = setupDeps.legacyPlugins.uiExports.savedObjectValidations || {};
-
const savedObjectsConfig = await this.coreContext.configService
.atPath('savedObjects')
.pipe(first())
@@ -471,8 +443,6 @@ export class SavedObjectsService
this.started = true;
return {
- migrator,
- clientProvider,
getScopedClient: clientProvider.getClient.bind(clientProvider),
createScopedRepository: repositoryFactory.createScopedRepository,
createInternalRepository: repositoryFactory.createInternalRepository,
@@ -488,13 +458,12 @@ export class SavedObjectsService
savedObjectsConfig: SavedObjectsMigrationConfigType,
client: IClusterClient,
migrationsRetryDelay?: number
- ): KibanaMigrator {
+ ): IKibanaMigrator {
return new KibanaMigrator({
typeRegistry: this.typeRegistry,
logger: this.logger,
kibanaVersion: this.coreContext.env.packageInfo.version,
savedObjectsConfig,
- savedObjectValidations: this.validations,
kibanaConfig,
client: createMigrationEsClient(client.asInternalUser, this.logger, migrationsRetryDelay),
});
diff --git a/src/core/server/saved_objects/schema/schema.test.ts b/src/core/server/saved_objects/schema/schema.test.ts
deleted file mode 100644
index f2daa13e43fce..0000000000000
--- a/src/core/server/saved_objects/schema/schema.test.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { SavedObjectsSchema, SavedObjectsSchemaDefinition } from './schema';
-
-describe('#isNamespaceAgnostic', () => {
- const expectResult = (expected: boolean, schemaDefinition?: SavedObjectsSchemaDefinition) => {
- const schema = new SavedObjectsSchema(schemaDefinition);
- const result = schema.isNamespaceAgnostic('foo');
- expect(result).toBe(expected);
- };
-
- it(`returns false when no schema is defined`, () => {
- expectResult(false);
- });
-
- it(`returns false for unknown types`, () => {
- expectResult(false, { bar: {} });
- });
-
- it(`returns false for non-namespace-agnostic type`, () => {
- expectResult(false, { foo: { isNamespaceAgnostic: false } });
- expectResult(false, { foo: { isNamespaceAgnostic: undefined } });
- });
-
- it(`returns true for explicitly namespace-agnostic type`, () => {
- expectResult(true, { foo: { isNamespaceAgnostic: true } });
- });
-});
-
-describe('#isSingleNamespace', () => {
- const expectResult = (expected: boolean, schemaDefinition?: SavedObjectsSchemaDefinition) => {
- const schema = new SavedObjectsSchema(schemaDefinition);
- const result = schema.isSingleNamespace('foo');
- expect(result).toBe(expected);
- };
-
- it(`returns true when no schema is defined`, () => {
- expectResult(true);
- });
-
- it(`returns true for unknown types`, () => {
- expectResult(true, { bar: {} });
- });
-
- it(`returns false for explicitly namespace-agnostic type`, () => {
- expectResult(false, { foo: { isNamespaceAgnostic: true } });
- });
-
- it(`returns false for explicitly multi-namespace type`, () => {
- expectResult(false, { foo: { multiNamespace: true } });
- });
-
- it(`returns true for non-namespace-agnostic and non-multi-namespace type`, () => {
- expectResult(true, { foo: { isNamespaceAgnostic: false, multiNamespace: false } });
- expectResult(true, { foo: { isNamespaceAgnostic: false, multiNamespace: undefined } });
- expectResult(true, { foo: { isNamespaceAgnostic: undefined, multiNamespace: false } });
- expectResult(true, { foo: { isNamespaceAgnostic: undefined, multiNamespace: undefined } });
- });
-});
-
-describe('#isMultiNamespace', () => {
- const expectResult = (expected: boolean, schemaDefinition?: SavedObjectsSchemaDefinition) => {
- const schema = new SavedObjectsSchema(schemaDefinition);
- const result = schema.isMultiNamespace('foo');
- expect(result).toBe(expected);
- };
-
- it(`returns false when no schema is defined`, () => {
- expectResult(false);
- });
-
- it(`returns false for unknown types`, () => {
- expectResult(false, { bar: {} });
- });
-
- it(`returns false for explicitly namespace-agnostic type`, () => {
- expectResult(false, { foo: { isNamespaceAgnostic: true } });
- });
-
- it(`returns false for non-multi-namespace type`, () => {
- expectResult(false, { foo: { multiNamespace: false } });
- expectResult(false, { foo: { multiNamespace: undefined } });
- });
-
- it(`returns true for non-namespace-agnostic and explicitly multi-namespace type`, () => {
- expectResult(true, { foo: { isNamespaceAgnostic: false, multiNamespace: true } });
- expectResult(true, { foo: { isNamespaceAgnostic: undefined, multiNamespace: true } });
- });
-});
diff --git a/src/core/server/saved_objects/schema/schema.ts b/src/core/server/saved_objects/schema/schema.ts
deleted file mode 100644
index ba1905158e822..0000000000000
--- a/src/core/server/saved_objects/schema/schema.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { LegacyConfig } from '../../legacy';
-
-/**
- * @deprecated
- * @internal
- **/
-interface SavedObjectsSchemaTypeDefinition {
- isNamespaceAgnostic?: boolean;
- multiNamespace?: boolean;
- hidden?: boolean;
- indexPattern?: ((config: LegacyConfig) => string) | string;
- convertToAliasScript?: string;
-}
-
-/**
- * @deprecated
- * @internal
- **/
-export interface SavedObjectsSchemaDefinition {
- [type: string]: SavedObjectsSchemaTypeDefinition;
-}
-
-/**
- * @deprecated This is only used by the {@link SavedObjectsLegacyService | legacy savedObjects service}
- * @internal
- **/
-export class SavedObjectsSchema {
- private readonly definition?: SavedObjectsSchemaDefinition;
- constructor(schemaDefinition?: SavedObjectsSchemaDefinition) {
- this.definition = schemaDefinition;
- }
-
- public isHiddenType(type: string) {
- if (this.definition && this.definition.hasOwnProperty(type)) {
- return Boolean(this.definition[type].hidden);
- }
-
- return false;
- }
-
- public getIndexForType(config: LegacyConfig, type: string): string | undefined {
- if (this.definition != null && this.definition.hasOwnProperty(type)) {
- const { indexPattern } = this.definition[type];
- return typeof indexPattern === 'function' ? indexPattern(config) : indexPattern;
- } else {
- return undefined;
- }
- }
-
- public getConvertToAliasScript(type: string): string | undefined {
- if (this.definition != null && this.definition.hasOwnProperty(type)) {
- return this.definition[type].convertToAliasScript;
- }
- }
-
- public isNamespaceAgnostic(type: string) {
- // if no plugins have registered a Saved Objects Schema,
- // this.schema will be undefined, and no types are namespace agnostic
- if (!this.definition) {
- return false;
- }
-
- const typeSchema = this.definition[type];
- if (!typeSchema) {
- return false;
- }
- return Boolean(typeSchema.isNamespaceAgnostic);
- }
-
- public isSingleNamespace(type: string) {
- // if no plugins have registered a Saved Objects Schema,
- // this.schema will be undefined, and all types are namespace isolated
- if (!this.definition) {
- return true;
- }
-
- const typeSchema = this.definition[type];
- if (!typeSchema) {
- return true;
- }
- return !Boolean(typeSchema.isNamespaceAgnostic) && !Boolean(typeSchema.multiNamespace);
- }
-
- public isMultiNamespace(type: string) {
- // if no plugins have registered a Saved Objects Schema,
- // this.schema will be undefined, and no types are multi-namespace
- if (!this.definition) {
- return false;
- }
-
- const typeSchema = this.definition[type];
- if (!typeSchema) {
- return false;
- }
- return !Boolean(typeSchema.isNamespaceAgnostic) && Boolean(typeSchema.multiNamespace);
- }
-}
diff --git a/src/core/server/saved_objects/service/index.ts b/src/core/server/saved_objects/service/index.ts
index 9f625b4732e26..271d4dd67d43e 100644
--- a/src/core/server/saved_objects/service/index.ts
+++ b/src/core/server/saved_objects/service/index.ts
@@ -17,37 +17,6 @@
* under the License.
*/
-import { Readable } from 'stream';
-import { SavedObjectsClientProvider } from './lib';
-import { SavedObjectsClient } from './saved_objects_client';
-import { SavedObjectsExportOptions } from '../export';
-import { SavedObjectsImportOptions, SavedObjectsImportResponse } from '../import';
-import { SavedObjectsSchema } from '../schema';
-import { SavedObjectsResolveImportErrorsOptions } from '../import/types';
-
-/**
- * @internal
- * @deprecated
- */
-export interface SavedObjectsLegacyService {
- // ATTENTION: these types are incomplete
- addScopedSavedObjectsClientWrapperFactory: SavedObjectsClientProvider['addClientWrapperFactory'];
- setScopedSavedObjectsClientFactory: SavedObjectsClientProvider['setClientFactory'];
- getScopedSavedObjectsClient: SavedObjectsClientProvider['getClient'];
- SavedObjectsClient: typeof SavedObjectsClient;
- types: string[];
- schema: SavedObjectsSchema;
- getSavedObjectsRepository(...rest: any[]): any;
- importExport: {
- objectLimit: number;
- importSavedObjects(options: SavedObjectsImportOptions): Promise;
- resolveImportErrors(
- options: SavedObjectsResolveImportErrorsOptions
- ): Promise;
- getSortedObjectsForExport(options: SavedObjectsExportOptions): Promise;
- };
-}
-
export {
SavedObjectsRepository,
SavedObjectsClientProvider,
diff --git a/src/core/server/saved_objects/service/lib/repository.test.js b/src/core/server/saved_objects/service/lib/repository.test.js
index b1d6028465713..f2e3b3e633cd6 100644
--- a/src/core/server/saved_objects/service/lib/repository.test.js
+++ b/src/core/server/saved_objects/service/lib/repository.test.js
@@ -153,7 +153,6 @@ describe('SavedObjectsRepository', () => {
typeRegistry: registry,
kibanaVersion: '2.0.0',
log: {},
- validateDoc: jest.fn(),
});
const getMockGetResponse = ({ type, id, references, namespace, originId }) => ({
diff --git a/src/core/server/saved_objects/service/lib/repository.ts b/src/core/server/saved_objects/service/lib/repository.ts
index dd25989725f3e..e3fb7d2306469 100644
--- a/src/core/server/saved_objects/service/lib/repository.ts
+++ b/src/core/server/saved_objects/service/lib/repository.ts
@@ -31,7 +31,7 @@ import { getSearchDsl } from './search_dsl';
import { includedFields } from './included_fields';
import { SavedObjectsErrorHelpers, DecoratedError } from './errors';
import { decodeRequestVersion, encodeVersion, encodeHitVersion } from '../../version';
-import { KibanaMigrator } from '../../migrations';
+import { IKibanaMigrator } from '../../migrations';
import {
SavedObjectsSerializer,
SavedObjectSanitizedDoc,
@@ -85,7 +85,7 @@ export interface SavedObjectsRepositoryOptions {
client: ElasticsearchClient;
typeRegistry: SavedObjectTypeRegistry;
serializer: SavedObjectsSerializer;
- migrator: KibanaMigrator;
+ migrator: IKibanaMigrator;
allowedTypes: string[];
}
@@ -120,7 +120,7 @@ export type ISavedObjectsRepository = Pick) => { path: string; uiCapabilitiesPath: string };
}
-
-/**
- * @internal
- * @deprecated
- */
-export interface SavedObjectsLegacyUiExports {
- savedObjectMappings: SavedObjectsLegacyMapping[];
- savedObjectMigrations: SavedObjectsLegacyMigrationDefinitions;
- savedObjectSchemas: SavedObjectsLegacySchemaDefinitions;
- savedObjectValidations: PropertyValidators;
- savedObjectsManagement: SavedObjectsLegacyManagementDefinition;
-}
-
-/**
- * @internal
- * @deprecated
- */
-export interface SavedObjectsLegacyMapping {
- pluginId: string;
- properties: SavedObjectsTypeMappingDefinitions;
-}
-
-/**
- * @internal
- * @deprecated Use {@link SavedObjectsTypeManagementDefinition | management definition} when registering
- * from new platform plugins
- */
-export interface SavedObjectsLegacyManagementDefinition {
- [key: string]: SavedObjectsLegacyManagementTypeDefinition;
-}
-
-/**
- * @internal
- * @deprecated
- */
-export interface SavedObjectsLegacyManagementTypeDefinition {
- isImportableAndExportable?: boolean;
- defaultSearchField?: string;
- icon?: string;
- getTitle?: (savedObject: SavedObject) => string;
- getEditUrl?: (savedObject: SavedObject) => string;
- getInAppUrl?: (savedObject: SavedObject) => { path: string; uiCapabilitiesPath: string };
-}
-
-/**
- * @internal
- * @deprecated
- */
-export interface SavedObjectsLegacyMigrationDefinitions {
- [type: string]: SavedObjectLegacyMigrationMap;
-}
-
-/**
- * @internal
- * @deprecated
- */
-export interface SavedObjectLegacyMigrationMap {
- [version: string]: SavedObjectLegacyMigrationFn;
-}
-
-/**
- * @internal
- * @deprecated
- */
-export type SavedObjectLegacyMigrationFn = (
- doc: SavedObjectUnsanitizedDoc,
- log: SavedObjectsMigrationLogger
-) => SavedObjectUnsanitizedDoc;
-
-/**
- * @internal
- * @deprecated
- */
-interface SavedObjectsLegacyTypeSchema {
- isNamespaceAgnostic?: boolean;
- /** Cannot be used in conjunction with `isNamespaceAgnostic` */
- multiNamespace?: boolean;
- hidden?: boolean;
- indexPattern?: ((config: LegacyConfig) => string) | string;
- convertToAliasScript?: string;
-}
-
-/**
- * @internal
- * @deprecated
- */
-export interface SavedObjectsLegacySchemaDefinitions {
- [type: string]: SavedObjectsLegacyTypeSchema;
-}
diff --git a/src/core/server/saved_objects/utils.test.ts b/src/core/server/saved_objects/utils.test.ts
deleted file mode 100644
index 21229bee489c2..0000000000000
--- a/src/core/server/saved_objects/utils.test.ts
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { legacyServiceMock } from '../legacy/legacy_service.mock';
-import { convertLegacyTypes, convertTypesToLegacySchema } from './utils';
-import { SavedObjectsLegacyUiExports, SavedObjectsType } from './types';
-import { LegacyConfig, SavedObjectMigrationContext } from 'kibana/server';
-import { SavedObjectUnsanitizedDoc } from './serialization';
-
-describe('convertLegacyTypes', () => {
- let legacyConfig: ReturnType;
-
- beforeEach(() => {
- legacyConfig = legacyServiceMock.createLegacyConfig();
- });
-
- it('converts the legacy mappings using default values if no schemas are specified', () => {
- const uiExports: SavedObjectsLegacyUiExports = {
- savedObjectMappings: [
- {
- pluginId: 'pluginA',
- properties: {
- typeA: {
- properties: {
- fieldA: { type: 'text' },
- },
- },
- typeB: {
- properties: {
- fieldB: { type: 'text' },
- },
- },
- },
- },
- {
- pluginId: 'pluginB',
- properties: {
- typeC: {
- properties: {
- fieldC: { type: 'text' },
- },
- },
- },
- },
- ],
- savedObjectMigrations: {},
- savedObjectSchemas: {},
- savedObjectValidations: {},
- savedObjectsManagement: {},
- };
-
- const converted = convertLegacyTypes(uiExports, legacyConfig);
- expect(converted).toMatchSnapshot();
- });
-
- it('merges the mappings and the schema to create the type when schema exists for the type', () => {
- const uiExports: SavedObjectsLegacyUiExports = {
- savedObjectMappings: [
- {
- pluginId: 'pluginA',
- properties: {
- typeA: {
- properties: {
- fieldA: { type: 'text' },
- },
- },
- },
- },
- {
- pluginId: 'pluginB',
- properties: {
- typeB: {
- properties: {
- fieldB: { type: 'text' },
- },
- },
- },
- },
- {
- pluginId: 'pluginC',
- properties: {
- typeC: {
- properties: {
- fieldC: { type: 'text' },
- },
- },
- },
- },
- {
- pluginId: 'pluginD',
- properties: {
- typeD: {
- properties: {
- fieldD: { type: 'text' },
- },
- },
- },
- },
- ],
- savedObjectMigrations: {},
- savedObjectSchemas: {
- typeA: {
- indexPattern: 'fooBar',
- hidden: true,
- isNamespaceAgnostic: true,
- },
- typeB: {
- indexPattern: 'barBaz',
- hidden: false,
- multiNamespace: true,
- },
- typeD: {
- indexPattern: 'bazQux',
- hidden: false,
- // if both isNamespaceAgnostic and multiNamespace are true, the resulting namespaceType is 'agnostic'
- isNamespaceAgnostic: true,
- multiNamespace: true,
- },
- },
- savedObjectValidations: {},
- savedObjectsManagement: {},
- };
-
- const converted = convertLegacyTypes(uiExports, legacyConfig);
- expect(converted).toMatchSnapshot();
- });
-
- it('invokes indexPattern to retrieve the index when it is a function', () => {
- const indexPatternAccessor: (config: LegacyConfig) => string = jest.fn((config) => {
- config.get('foo.bar');
- return 'myIndex';
- });
-
- const uiExports: SavedObjectsLegacyUiExports = {
- savedObjectMappings: [
- {
- pluginId: 'pluginA',
- properties: {
- typeA: {
- properties: {
- fieldA: { type: 'text' },
- },
- },
- },
- },
- ],
- savedObjectMigrations: {},
- savedObjectSchemas: {
- typeA: {
- indexPattern: indexPatternAccessor,
- hidden: true,
- isNamespaceAgnostic: true,
- },
- },
- savedObjectValidations: {},
- savedObjectsManagement: {},
- };
-
- const converted = convertLegacyTypes(uiExports, legacyConfig);
-
- expect(indexPatternAccessor).toHaveBeenCalledWith(legacyConfig);
- expect(legacyConfig.get).toHaveBeenCalledWith('foo.bar');
- expect(converted.length).toEqual(1);
- expect(converted[0].indexPattern).toEqual('myIndex');
- });
-
- it('import migrations from the uiExports', () => {
- const migrationsA = {
- '1.0.0': jest.fn(),
- '2.0.4': jest.fn(),
- };
- const migrationsB = {
- '1.5.3': jest.fn(),
- };
-
- const uiExports: SavedObjectsLegacyUiExports = {
- savedObjectMappings: [
- {
- pluginId: 'pluginA',
- properties: {
- typeA: {
- properties: {
- fieldA: { type: 'text' },
- },
- },
- },
- },
- {
- pluginId: 'pluginB',
- properties: {
- typeB: {
- properties: {
- fieldC: { type: 'text' },
- },
- },
- },
- },
- ],
- savedObjectMigrations: {
- typeA: migrationsA,
- typeB: migrationsB,
- },
- savedObjectSchemas: {},
- savedObjectValidations: {},
- savedObjectsManagement: {},
- };
-
- const converted = convertLegacyTypes(uiExports, legacyConfig);
- expect(converted.length).toEqual(2);
- expect(Object.keys(converted[0]!.migrations!)).toEqual(Object.keys(migrationsA));
- expect(Object.keys(converted[1]!.migrations!)).toEqual(Object.keys(migrationsB));
- });
-
- it('converts the migration to the new format', () => {
- const legacyMigration = jest.fn();
- const migrationsA = {
- '1.0.0': legacyMigration,
- };
-
- const uiExports: SavedObjectsLegacyUiExports = {
- savedObjectMappings: [
- {
- pluginId: 'pluginA',
- properties: {
- typeA: {
- properties: {
- fieldA: { type: 'text' },
- },
- },
- },
- },
- ],
- savedObjectMigrations: {
- typeA: migrationsA,
- },
- savedObjectSchemas: {},
- savedObjectValidations: {},
- savedObjectsManagement: {},
- };
-
- const converted = convertLegacyTypes(uiExports, legacyConfig);
- expect(Object.keys(converted[0]!.migrations!)).toEqual(['1.0.0']);
-
- const migration = converted[0]!.migrations!['1.0.0']!;
-
- const doc = {} as SavedObjectUnsanitizedDoc;
- const context = { log: {} } as SavedObjectMigrationContext;
- migration(doc, context);
-
- expect(legacyMigration).toHaveBeenCalledTimes(1);
- expect(legacyMigration).toHaveBeenCalledWith(doc, context.log);
- });
-
- it('imports type management information', () => {
- const uiExports: SavedObjectsLegacyUiExports = {
- savedObjectMappings: [
- {
- pluginId: 'pluginA',
- properties: {
- typeA: {
- properties: {
- fieldA: { type: 'text' },
- },
- },
- },
- },
- {
- pluginId: 'pluginB',
- properties: {
- typeB: {
- properties: {
- fieldB: { type: 'text' },
- },
- },
- typeC: {
- properties: {
- fieldC: { type: 'text' },
- },
- },
- },
- },
- ],
- savedObjectsManagement: {
- typeA: {
- isImportableAndExportable: true,
- icon: 'iconA',
- defaultSearchField: 'searchFieldA',
- getTitle: (savedObject) => savedObject.id,
- },
- typeB: {
- isImportableAndExportable: false,
- icon: 'iconB',
- getEditUrl: (savedObject) => `/some-url/${savedObject.id}`,
- getInAppUrl: (savedObject) => ({ path: 'path', uiCapabilitiesPath: 'ui-path' }),
- },
- },
- savedObjectMigrations: {},
- savedObjectSchemas: {},
- savedObjectValidations: {},
- };
-
- const converted = convertLegacyTypes(uiExports, legacyConfig);
- expect(converted.length).toEqual(3);
- const [typeA, typeB, typeC] = converted;
-
- expect(typeA.management).toEqual({
- importableAndExportable: true,
- icon: 'iconA',
- defaultSearchField: 'searchFieldA',
- getTitle: uiExports.savedObjectsManagement.typeA.getTitle,
- });
-
- expect(typeB.management).toEqual({
- importableAndExportable: false,
- icon: 'iconB',
- getEditUrl: uiExports.savedObjectsManagement.typeB.getEditUrl,
- getInAppUrl: uiExports.savedObjectsManagement.typeB.getInAppUrl,
- });
-
- expect(typeC.management).toBeUndefined();
- });
-
- it('merges everything when all are present', () => {
- const uiExports: SavedObjectsLegacyUiExports = {
- savedObjectMappings: [
- {
- pluginId: 'pluginA',
- properties: {
- typeA: {
- properties: {
- fieldA: { type: 'text' },
- },
- },
- typeB: {
- properties: {
- fieldB: { type: 'text' },
- anotherFieldB: { type: 'boolean' },
- },
- },
- },
- },
- {
- pluginId: 'pluginB',
- properties: {
- typeC: {
- properties: {
- fieldC: { type: 'text' },
- },
- },
- },
- },
- ],
- savedObjectMigrations: {
- typeA: {
- '1.0.0': jest.fn(),
- '2.0.4': jest.fn(),
- },
- typeC: {
- '1.5.3': jest.fn(),
- },
- },
- savedObjectSchemas: {
- typeA: {
- indexPattern: jest.fn((config) => {
- config.get('foo.bar');
- return 'myIndex';
- }),
- hidden: true,
- isNamespaceAgnostic: true,
- },
- typeB: {
- convertToAliasScript: 'some alias script',
- hidden: false,
- },
- },
- savedObjectValidations: {},
- savedObjectsManagement: {},
- };
-
- const converted = convertLegacyTypes(uiExports, legacyConfig);
- expect(converted).toMatchSnapshot();
- });
-});
-
-describe('convertTypesToLegacySchema', () => {
- it('converts types to the legacy schema format', () => {
- const types: SavedObjectsType[] = [
- {
- name: 'typeA',
- hidden: false,
- namespaceType: 'agnostic',
- mappings: { properties: {} },
- convertToAliasScript: 'some script',
- },
- {
- name: 'typeB',
- hidden: true,
- namespaceType: 'single',
- indexPattern: 'myIndex',
- mappings: { properties: {} },
- },
- {
- name: 'typeC',
- hidden: false,
- namespaceType: 'multiple',
- mappings: { properties: {} },
- },
- ];
- expect(convertTypesToLegacySchema(types)).toEqual({
- typeA: {
- hidden: false,
- isNamespaceAgnostic: true,
- multiNamespace: false,
- convertToAliasScript: 'some script',
- },
- typeB: {
- hidden: true,
- isNamespaceAgnostic: false,
- multiNamespace: false,
- indexPattern: 'myIndex',
- },
- typeC: {
- hidden: false,
- isNamespaceAgnostic: false,
- multiNamespace: true,
- },
- });
- });
-});
diff --git a/src/core/server/saved_objects/utils.ts b/src/core/server/saved_objects/utils.ts
deleted file mode 100644
index af7c08d1fbfcc..0000000000000
--- a/src/core/server/saved_objects/utils.ts
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { LegacyConfig } from '../legacy';
-import { SavedObjectMigrationMap } from './migrations';
-import {
- SavedObjectsNamespaceType,
- SavedObjectsType,
- SavedObjectsLegacyUiExports,
- SavedObjectLegacyMigrationMap,
- SavedObjectsLegacyManagementTypeDefinition,
- SavedObjectsTypeManagementDefinition,
-} from './types';
-import { SavedObjectsSchemaDefinition } from './schema';
-
-/**
- * Converts the legacy savedObjects mappings, schema, and migrations
- * to actual {@link SavedObjectsType | saved object types}
- */
-export const convertLegacyTypes = (
- {
- savedObjectMappings = [],
- savedObjectMigrations = {},
- savedObjectSchemas = {},
- savedObjectsManagement = {},
- }: SavedObjectsLegacyUiExports,
- legacyConfig: LegacyConfig
-): SavedObjectsType[] => {
- return savedObjectMappings.reduce((types, { properties }) => {
- return [
- ...types,
- ...Object.entries(properties).map(([type, mappings]) => {
- const schema = savedObjectSchemas[type];
- const migrations = savedObjectMigrations[type];
- const management = savedObjectsManagement[type];
- const namespaceType = (schema?.isNamespaceAgnostic
- ? 'agnostic'
- : schema?.multiNamespace
- ? 'multiple'
- : 'single') as SavedObjectsNamespaceType;
- return {
- name: type,
- hidden: schema?.hidden ?? false,
- namespaceType,
- mappings,
- indexPattern:
- typeof schema?.indexPattern === 'function'
- ? schema.indexPattern(legacyConfig)
- : schema?.indexPattern,
- convertToAliasScript: schema?.convertToAliasScript,
- migrations: convertLegacyMigrations(migrations ?? {}),
- management: management ? convertLegacyTypeManagement(management) : undefined,
- };
- }),
- ];
- }, [] as SavedObjectsType[]);
-};
-
-/**
- * Convert {@link SavedObjectsType | saved object types} to the legacy {@link SavedObjectsSchemaDefinition | schema} format
- */
-export const convertTypesToLegacySchema = (
- types: SavedObjectsType[]
-): SavedObjectsSchemaDefinition => {
- return types.reduce((schema, type) => {
- return {
- ...schema,
- [type.name]: {
- isNamespaceAgnostic: type.namespaceType === 'agnostic',
- multiNamespace: type.namespaceType === 'multiple',
- hidden: type.hidden,
- indexPattern: type.indexPattern,
- convertToAliasScript: type.convertToAliasScript,
- },
- };
- }, {} as SavedObjectsSchemaDefinition);
-};
-
-const convertLegacyMigrations = (
- legacyMigrations: SavedObjectLegacyMigrationMap
-): SavedObjectMigrationMap => {
- return Object.entries(legacyMigrations).reduce((migrated, [version, migrationFn]) => {
- return {
- ...migrated,
- [version]: (doc, context) => migrationFn(doc, context.log),
- };
- }, {} as SavedObjectMigrationMap);
-};
-
-const convertLegacyTypeManagement = (
- legacyTypeManagement: SavedObjectsLegacyManagementTypeDefinition
-): SavedObjectsTypeManagementDefinition => {
- return {
- importableAndExportable: legacyTypeManagement.isImportableAndExportable,
- defaultSearchField: legacyTypeManagement.defaultSearchField,
- icon: legacyTypeManagement.icon,
- getTitle: legacyTypeManagement.getTitle,
- getEditUrl: legacyTypeManagement.getEditUrl,
- getInAppUrl: legacyTypeManagement.getInAppUrl,
- };
-};
diff --git a/src/core/server/saved_objects/validation/index.ts b/src/core/server/saved_objects/validation/index.ts
deleted file mode 100644
index b1b33f91d3fd4..0000000000000
--- a/src/core/server/saved_objects/validation/index.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*
- * This is the core logic for validating saved object properties. The saved object client
- * and migrations consume this in order to validate saved object documents prior to
- * persisting them.
- */
-
-interface SavedObjectDoc {
- type: string;
- [prop: string]: any;
-}
-
-/**
- * A dictionary of property name -> validation function. The property name
- * is generally the document's type (e.g. "dashboard"), but will also
- * match other properties.
- *
- * For example, the "acl" and "dashboard" validators both apply to the
- * following saved object: { type: "dashboard", attributes: {}, acl: "sdlaj3w" }
- *
- * @export
- * @interface Validators
- */
-export interface PropertyValidators {
- [prop: string]: ValidateDoc;
-}
-
-export type ValidateDoc = (doc: SavedObjectDoc) => void;
-
-/**
- * Creates a function which uses a dictionary of property validators to validate
- * individual saved object documents.
- *
- * @export
- * @param {Validators} validators
- * @param {SavedObjectDoc} doc
- */
-export function docValidator(validators: PropertyValidators = {}): ValidateDoc {
- return function validateDoc(doc: SavedObjectDoc) {
- Object.keys(doc)
- .concat(doc.type)
- .forEach((prop) => {
- const validator = validators[prop];
- if (validator) {
- validator(doc);
- }
- });
- };
-}
diff --git a/src/core/server/saved_objects/validation/readme.md b/src/core/server/saved_objects/validation/readme.md
deleted file mode 100644
index 3b9f17c37fd0b..0000000000000
--- a/src/core/server/saved_objects/validation/readme.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# Saved Object Validations
-
-The saved object client supports validation of documents during create / bulkCreate operations.
-
-This allows us tighter control over what documents get written to the saved object index, and helps us keep the index in a healthy state.
-
-## Creating validations
-
-Plugin authors can write their own validations by adding a `validations` property to their uiExports. A validation is nothing more than a dictionary of `{[prop: string]: validationFunction}` where:
-
-* `prop` - a root-property on a saved object document
-* `validationFunction` - a function that takes a document and throws an error if it does not meet expectations.
-
-## Example
-
-```js
-// In myFanciPlugin...
-uiExports: {
- validations: {
- myProperty(doc) {
- if (doc.attributes.someField === undefined) {
- throw new Error(`Document ${doc.id} did not define "someField"`);
- }
- },
-
- someOtherProp(doc) {
- if (doc.attributes.counter < 0) {
- throw new Error(`Document ${doc.id} cannot have a negative counter.`);
- }
- },
- },
-},
-```
-
-In this example, `myFanciPlugin` defines validations for two properties: `myProperty` and `someOtherProp`.
-
-This means that no other plugin can define validations for myProperty or someOtherProp.
-
-The `myProperty` validation would run for any doc that has a `type="myProperty"` or for any doc that has a root-level property of `myProperty`. e.g. it would apply to all documents in the following array:
-
-```js
-[
- {
- type: 'foo',
- attributes: { stuff: 'here' },
- myProperty: 'shazm!',
- },
- {
- type: 'myProperty',
- attributes: { shazm: true },
- },
-];
-```
-
-Validating properties other than just 'type' allows us to support potential future saved object scenarios in which plugins might want to annotate other plugin documents, such as a security plugin adding an acl to another document:
-
-```js
-{
- type: 'dashboard',
- attributes: { stuff: 'here' },
- acl: '342343',
-}
-```
diff --git a/src/core/server/saved_objects/validation/validation.test.ts b/src/core/server/saved_objects/validation/validation.test.ts
deleted file mode 100644
index 71e220280ba5f..0000000000000
--- a/src/core/server/saved_objects/validation/validation.test.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { docValidator } from './index';
-
-describe('docValidator', () => {
- test('does not run validators that have no application to the doc', () => {
- const validators = {
- foo: () => {
- throw new Error('Boom!');
- },
- };
- expect(() => docValidator(validators)({ type: 'shoo', bar: 'hi' })).not.toThrow();
- });
-
- test('validates the doc type', () => {
- const validators = {
- foo: () => {
- throw new Error('Boom!');
- },
- };
- expect(() => docValidator(validators)({ type: 'foo' })).toThrow(/Boom!/);
- });
-
- test('validates various props', () => {
- const validators = {
- a: jest.fn(),
- b: jest.fn(),
- c: jest.fn(),
- };
- docValidator(validators)({ type: 'a', b: 'foo' });
-
- expect(validators.c).not.toHaveBeenCalled();
-
- expect(validators.a.mock.calls).toEqual([[{ type: 'a', b: 'foo' }]]);
- expect(validators.b.mock.calls).toEqual([[{ type: 'a', b: 'foo' }]]);
- });
-});
diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md
index 081554cd17f25..37023a0a8ef67 100644
--- a/src/core/server/server.api.md
+++ b/src/core/server/server.api.md
@@ -1411,19 +1411,30 @@ export interface LegacyServiceStartDeps {
plugins: Record;
}
-// Warning: (ae-forgotten-export) The symbol "SavedObjectsLegacyUiExports" needs to be exported by the entry point index.d.ts
-//
// @internal @deprecated (undocumented)
-export type LegacyUiExports = SavedObjectsLegacyUiExports & {
+export interface LegacyUiExports {
+ // Warning: (ae-forgotten-export) The symbol "VarsProvider" needs to be exported by the entry point index.d.ts
+ //
+ // (undocumented)
defaultInjectedVarProviders?: VarsProvider[];
+ // Warning: (ae-forgotten-export) The symbol "VarsReplacer" needs to be exported by the entry point index.d.ts
+ //
+ // (undocumented)
injectedVarsReplacers?: VarsReplacer[];
+ // Warning: (ae-forgotten-export) The symbol "LegacyNavLinkSpec" needs to be exported by the entry point index.d.ts
+ //
+ // (undocumented)
navLinkSpecs?: LegacyNavLinkSpec[] | null;
+ // Warning: (ae-forgotten-export) The symbol "LegacyAppSpec" needs to be exported by the entry point index.d.ts
+ //
+ // (undocumented)
uiAppSpecs?: Array;
+ // (undocumented)
unknown?: [{
pluginSpec: LegacyPluginSpec;
type: unknown;
}];
-};
+}
// Warning: (ae-forgotten-export) The symbol "lifecycleResponseFactory" needs to be exported by the entry point index.d.ts
//
@@ -2437,33 +2448,6 @@ export interface SavedObjectsIncrementCounterOptions extends SavedObjectsBaseOpt
refresh?: MutatingOperationRefreshSetting;
}
-// @internal @deprecated (undocumented)
-export interface SavedObjectsLegacyService {
- // Warning: (ae-forgotten-export) The symbol "SavedObjectsClientProvider" needs to be exported by the entry point index.d.ts
- //
- // (undocumented)
- addScopedSavedObjectsClientWrapperFactory: SavedObjectsClientProvider['addClientWrapperFactory'];
- // (undocumented)
- getSavedObjectsRepository(...rest: any[]): any;
- // (undocumented)
- getScopedSavedObjectsClient: SavedObjectsClientProvider['getClient'];
- // (undocumented)
- importExport: {
- objectLimit: number;
- importSavedObjects(options: SavedObjectsImportOptions): Promise;
- resolveImportErrors(options: SavedObjectsResolveImportErrorsOptions): Promise;
- getSortedObjectsForExport(options: SavedObjectsExportOptions): Promise;
- };
- // (undocumented)
- SavedObjectsClient: typeof SavedObjectsClient;
- // (undocumented)
- schema: SavedObjectsSchema;
- // (undocumented)
- setScopedSavedObjectsClientFactory: SavedObjectsClientProvider['setClientFactory'];
- // (undocumented)
- types: string[];
-}
-
// @public
export interface SavedObjectsMappingProperties {
// (undocumented)
@@ -2517,10 +2501,10 @@ export class SavedObjectsRepository {
bulkUpdate(objects: Array>, options?: SavedObjectsBulkUpdateOptions): Promise>;
checkConflicts(objects?: SavedObjectsCheckConflictsObject[], options?: SavedObjectsBaseOptions): Promise;
create(type: string, attributes: T, options?: SavedObjectsCreateOptions): Promise>;
- // Warning: (ae-forgotten-export) The symbol "KibanaMigrator" needs to be exported by the entry point index.d.ts
+ // Warning: (ae-forgotten-export) The symbol "IKibanaMigrator" needs to be exported by the entry point index.d.ts
//
// @internal
- static createRepository(migrator: KibanaMigrator, typeRegistry: SavedObjectTypeRegistry, indexName: string, client: ElasticsearchClient, includedHiddenTypes?: string[], injectedConstructor?: any): ISavedObjectsRepository;
+ static createRepository(migrator: IKibanaMigrator, typeRegistry: SavedObjectTypeRegistry, indexName: string, client: ElasticsearchClient, includedHiddenTypes?: string[], injectedConstructor?: any): ISavedObjectsRepository;
delete(type: string, id: string, options?: SavedObjectsDeleteOptions): Promise<{}>;
deleteByNamespace(namespace: string, options?: SavedObjectsDeleteByNamespaceOptions): Promise;
deleteFromNamespaces(type: string, id: string, namespaces: string[], options?: SavedObjectsDeleteFromNamespacesOptions): Promise;
@@ -2548,24 +2532,6 @@ export interface SavedObjectsResolveImportErrorsOptions {
typeRegistry: ISavedObjectTypeRegistry;
}
-// @internal @deprecated (undocumented)
-export class SavedObjectsSchema {
- // Warning: (ae-forgotten-export) The symbol "SavedObjectsSchemaDefinition" needs to be exported by the entry point index.d.ts
- constructor(schemaDefinition?: SavedObjectsSchemaDefinition);
- // (undocumented)
- getConvertToAliasScript(type: string): string | undefined;
- // (undocumented)
- getIndexForType(config: LegacyConfig, type: string): string | undefined;
- // (undocumented)
- isHiddenType(type: string): boolean;
- // (undocumented)
- isMultiNamespace(type: string): boolean;
- // (undocumented)
- isNamespaceAgnostic(type: string): boolean;
- // (undocumented)
- isSingleNamespace(type: string): boolean;
-}
-
// @public
export class SavedObjectsSerializer {
// @internal
@@ -2888,11 +2854,7 @@ export const validBodyOutput: readonly ["data", "stream"];
// Warnings were encountered during analysis:
//
// src/core/server/http/router/response.ts:316:3 - (ae-forgotten-export) The symbol "KibanaResponse" needs to be exported by the entry point index.d.ts
-// src/core/server/legacy/types.ts:132:3 - (ae-forgotten-export) The symbol "VarsProvider" needs to be exported by the entry point index.d.ts
-// src/core/server/legacy/types.ts:133:3 - (ae-forgotten-export) The symbol "VarsReplacer" needs to be exported by the entry point index.d.ts
-// src/core/server/legacy/types.ts:134:3 - (ae-forgotten-export) The symbol "LegacyNavLinkSpec" needs to be exported by the entry point index.d.ts
-// src/core/server/legacy/types.ts:135:3 - (ae-forgotten-export) The symbol "LegacyAppSpec" needs to be exported by the entry point index.d.ts
-// src/core/server/legacy/types.ts:136:16 - (ae-forgotten-export) The symbol "LegacyPluginSpec" needs to be exported by the entry point index.d.ts
+// src/core/server/legacy/types.ts:135:16 - (ae-forgotten-export) The symbol "LegacyPluginSpec" needs to be exported by the entry point index.d.ts
// src/core/server/plugins/types.ts:266:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts
// src/core/server/plugins/types.ts:266:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts
// src/core/server/plugins/types.ts:268:3 - (ae-forgotten-export) The symbol "PathConfigType" needs to be exported by the entry point index.d.ts
diff --git a/src/core/server/server.ts b/src/core/server/server.ts
index cc6d8171e7a03..278dd72d72bb1 100644
--- a/src/core/server/server.ts
+++ b/src/core/server/server.ts
@@ -142,7 +142,6 @@ export class Server {
const savedObjectsSetup = await this.savedObjects.setup({
http: httpSetup,
elasticsearch: elasticsearchServiceSetup,
- legacyPlugins,
});
const uiSettingsSetup = await this.uiSettings.setup({
diff --git a/src/core/server/ui_settings/create_or_upgrade_saved_config/integration_tests/create_or_upgrade.test.ts b/src/core/server/ui_settings/create_or_upgrade_saved_config/integration_tests/create_or_upgrade.test.ts
index 61b71f8c5de07..c7d5413ecca56 100644
--- a/src/core/server/ui_settings/create_or_upgrade_saved_config/integration_tests/create_or_upgrade.test.ts
+++ b/src/core/server/ui_settings/create_or_upgrade_saved_config/integration_tests/create_or_upgrade.test.ts
@@ -36,8 +36,6 @@ describe('createOrUpgradeSavedConfig()', () => {
let esServer: TestElasticsearchUtils;
let kbn: TestKibanaUtils;
- let kbnServer: TestKibanaUtils['kbnServer'];
-
beforeAll(async function () {
servers = createTestServers({
adjustTimeout: (t) => {
@@ -46,10 +44,8 @@ describe('createOrUpgradeSavedConfig()', () => {
});
esServer = await servers.startES();
kbn = await servers.startKibana();
- kbnServer = kbn.kbnServer;
- const savedObjects = kbnServer.server.savedObjects;
- savedObjectsClient = savedObjects.getScopedSavedObjectsClient(
+ savedObjectsClient = kbn.coreStart.savedObjects.getScopedClient(
httpServerMock.createKibanaRequest()
);
diff --git a/src/core/server/ui_settings/integration_tests/lib/servers.ts b/src/core/server/ui_settings/integration_tests/lib/servers.ts
index 297deb0233c57..0bdc821f42581 100644
--- a/src/core/server/ui_settings/integration_tests/lib/servers.ts
+++ b/src/core/server/ui_settings/integration_tests/lib/servers.ts
@@ -68,8 +68,7 @@ export function getServices() {
const callCluster = esServer.es.getCallCluster();
- const savedObjects = kbnServer.server.savedObjects;
- const savedObjectsClient = savedObjects.getScopedSavedObjectsClient(
+ const savedObjectsClient = kbn.coreStart.savedObjects.getScopedClient(
httpServerMock.createKibanaRequest()
);
diff --git a/src/core/test_helpers/kbn_server.ts b/src/core/test_helpers/kbn_server.ts
index a494c6aa31d6f..488c4b919d3e4 100644
--- a/src/core/test_helpers/kbn_server.ts
+++ b/src/core/test_helpers/kbn_server.ts
@@ -32,6 +32,7 @@ import { resolve } from 'path';
import { BehaviorSubject } from 'rxjs';
import supertest from 'supertest';
+import { CoreStart } from 'src/core/server';
import { LegacyAPICaller } from '../server/elasticsearch';
import { CliArgs, Env } from '../server/config';
import { Root } from '../server/root';
@@ -170,6 +171,7 @@ export interface TestElasticsearchUtils {
export interface TestKibanaUtils {
root: Root;
+ coreStart: CoreStart;
kbnServer: KbnServer;
stop: () => Promise;
}
@@ -289,13 +291,14 @@ export function createTestServers({
const root = createRootWithCorePlugins(kbnSettings);
await root.setup();
- await root.start();
+ const coreStart = await root.start();
const kbnServer = getKbnServer(root);
return {
root,
kbnServer,
+ coreStart,
stop: async () => await root.shutdown(),
};
},
diff --git a/src/fixtures/stubbed_saved_object_index_pattern.ts b/src/fixtures/stubbed_saved_object_index_pattern.ts
index 02e6cb85e341f..44b391f14cf9c 100644
--- a/src/fixtures/stubbed_saved_object_index_pattern.ts
+++ b/src/fixtures/stubbed_saved_object_index_pattern.ts
@@ -30,6 +30,7 @@ export function stubbedSavedObjectIndexPattern(id: string | null = null) {
timeFieldName: 'timestamp',
customFormats: '{}',
fields: mockLogstashFields,
+ title: 'title',
},
version: 2,
};
diff --git a/src/legacy/core_plugins/elasticsearch/index.js b/src/legacy/core_plugins/elasticsearch/index.js
index 599886788604b..f90f490d68035 100644
--- a/src/legacy/core_plugins/elasticsearch/index.js
+++ b/src/legacy/core_plugins/elasticsearch/index.js
@@ -16,18 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { first } from 'rxjs/operators';
import { Cluster } from './server/lib/cluster';
import { createProxy } from './server/lib/create_proxy';
export default function (kibana) {
- let defaultVars;
-
return new kibana.Plugin({
require: [],
- uiExports: { injectDefaultVars: () => defaultVars },
-
async init(server) {
// All methods that ES plugin exposes are synchronous so we should get the first
// value from all observables here to be able to synchronously return and create
@@ -36,16 +31,6 @@ export default function (kibana) {
const adminCluster = new Cluster(client);
const dataCluster = new Cluster(client);
- const esConfig = await server.newPlatform.__internals.elasticsearch.legacy.config$
- .pipe(first())
- .toPromise();
-
- defaultVars = {
- esRequestTimeout: esConfig.requestTimeout.asMilliseconds(),
- esShardTimeout: esConfig.shardTimeout.asMilliseconds(),
- esApiVersion: esConfig.apiVersion,
- };
-
const clusters = new Map();
server.expose('getCluster', (name) => {
if (name === 'admin') {
diff --git a/src/legacy/plugin_discovery/plugin_spec/plugin_spec_options.d.ts b/src/legacy/plugin_discovery/plugin_spec/plugin_spec_options.d.ts
index e51a355cbc8d2..e1ed2f57375a4 100644
--- a/src/legacy/plugin_discovery/plugin_spec/plugin_spec_options.d.ts
+++ b/src/legacy/plugin_discovery/plugin_spec/plugin_spec_options.d.ts
@@ -18,14 +18,10 @@
*/
import { Server } from '../../server/kbn_server';
import { Capabilities } from '../../../core/server';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { SavedObjectsLegacyManagementDefinition } from '../../../core/server/saved_objects/types';
export type InitPluginFunction = (server: Server) => void;
export interface UiExports {
injectDefaultVars?: (server: Server) => { [key: string]: any };
- savedObjectsManagement?: SavedObjectsLegacyManagementDefinition;
- mappings?: unknown;
}
export interface PluginSpecOptions {
diff --git a/src/legacy/plugin_discovery/types.ts b/src/legacy/plugin_discovery/types.ts
index 283806f69599a..700ca6fa68c95 100644
--- a/src/legacy/plugin_discovery/types.ts
+++ b/src/legacy/plugin_discovery/types.ts
@@ -19,11 +19,6 @@
import { Server } from '../server/kbn_server';
import { Capabilities } from '../../core/server';
-// Disable lint errors for imports from src/core/* until SavedObjects migration is complete
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { SavedObjectsSchemaDefinition } from '../../core/server/saved_objects/schema';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { SavedObjectsLegacyManagementDefinition } from '../../core/server/saved_objects/types';
import { AppCategory } from '../../core/types';
/**
@@ -70,8 +65,6 @@ export interface LegacyPluginOptions {
home: string[];
mappings: any;
migrations: any;
- savedObjectSchemas: SavedObjectsSchemaDefinition;
- savedObjectsManagement: SavedObjectsLegacyManagementDefinition;
visTypes: string[];
embeddableActions?: string[];
embeddableFactories?: string[];
diff --git a/src/legacy/server/kbn_server.d.ts b/src/legacy/server/kbn_server.d.ts
index 69fb63fbbd87f..663542618375a 100644
--- a/src/legacy/server/kbn_server.d.ts
+++ b/src/legacy/server/kbn_server.d.ts
@@ -17,33 +17,24 @@
* under the License.
*/
-import { ResponseObject, Server } from 'hapi';
-import { UnwrapPromise } from '@kbn/utility-types';
+import { Server } from 'hapi';
import { TelemetryCollectionManagerPluginSetup } from 'src/plugins/telemetry_collection_manager/server';
import {
- ConfigService,
CoreSetup,
CoreStart,
- ElasticsearchServiceSetup,
EnvironmentMode,
LoggerFactory,
- SavedObjectsClientContract,
- SavedObjectsLegacyService,
- SavedObjectsClientProviderOptions,
- IUiSettingsClient,
PackageInfo,
- LegacyRequest,
LegacyServiceSetupDeps,
- LegacyServiceStartDeps,
LegacyServiceDiscoverPlugins,
} from '../../core/server';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { LegacyConfig, ILegacyService, ILegacyInternals } from '../../core/server/legacy';
+import { LegacyConfig, ILegacyInternals } from '../../core/server/legacy';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { UiPlugins } from '../../core/server/plugins';
-import { CallClusterWithRequest, ElasticsearchPlugin } from '../core_plugins/elasticsearch';
+import { ElasticsearchPlugin } from '../core_plugins/elasticsearch';
import { UsageCollectionSetup } from '../../plugins/usage_collection/server';
import { HomeServerPluginSetup } from '../../plugins/home/server';
@@ -61,16 +52,9 @@ declare module 'hapi' {
interface Server {
config: () => KibanaConfig;
- savedObjects: SavedObjectsLegacyService;
logWithMetadata: (tags: string[], message: string, meta: Record) => void;
newPlatform: KbnServer['newPlatform'];
}
-
- interface Request {
- getSavedObjectsClient(options?: SavedObjectsClientProviderOptions): SavedObjectsClientContract;
- getBasePath(): string;
- getUiSettingsService(): IUiSettingsClient;
- }
}
type KbnMixinFunc = (kbnServer: KbnServer, server: Server, config: any) => Promise | void;
@@ -86,11 +70,9 @@ export interface KibanaCore {
__internals: {
elasticsearch: LegacyServiceSetupDeps['core']['elasticsearch'];
hapiServer: LegacyServiceSetupDeps['core']['http']['server'];
- kibanaMigrator: LegacyServiceStartDeps['core']['savedObjects']['migrator'];
legacy: ILegacyInternals;
rendering: LegacyServiceSetupDeps['core']['rendering'];
uiPlugins: UiPlugins;
- savedObjectsClientProvider: LegacyServiceStartDeps['core']['savedObjects']['clientProvider'];
};
env: {
mode: Readonly;
@@ -149,6 +131,3 @@ export default class KbnServer {
// Re-export commonly used hapi types.
export { Server, Request, ResponseToolkit } from 'hapi';
-
-// Re-export commonly accessed api types.
-export { SavedObjectsLegacyService, SavedObjectsClient } from 'src/core/server';
diff --git a/src/legacy/server/kbn_server.js b/src/legacy/server/kbn_server.js
index 4692262d99bb5..a5eefd140c8fa 100644
--- a/src/legacy/server/kbn_server.js
+++ b/src/legacy/server/kbn_server.js
@@ -33,7 +33,6 @@ import pidMixin from './pid';
import configCompleteMixin from './config/complete';
import { optimizeMixin } from '../../optimize';
import * as Plugins from './plugins';
-import { savedObjectsMixin } from './saved_objects/saved_objects_mixin';
import { uiMixin } from '../ui';
import { i18nMixin } from './i18n';
@@ -108,9 +107,6 @@ export default class KbnServer {
uiMixin,
- // setup saved object routes
- savedObjectsMixin,
-
// setup routes that serve the @kbn/optimizer output
optimizeMixin,
diff --git a/src/legacy/server/saved_objects/saved_objects_mixin.js b/src/legacy/server/saved_objects/saved_objects_mixin.js
deleted file mode 100644
index 96cf2058839cf..0000000000000
--- a/src/legacy/server/saved_objects/saved_objects_mixin.js
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-// Disable lint errors for imports from src/core/server/saved_objects until SavedObjects migration is complete
-/* eslint-disable @kbn/eslint/no-restricted-paths */
-import { SavedObjectsSchema } from '../../../core/server/saved_objects/schema';
-import {
- SavedObjectsClient,
- SavedObjectsRepository,
- exportSavedObjectsToStream,
- importSavedObjectsFromStream,
- resolveSavedObjectsImportErrors,
-} from '../../../core/server/saved_objects';
-import { convertTypesToLegacySchema } from '../../../core/server/saved_objects/utils';
-
-export function savedObjectsMixin(kbnServer, server) {
- const migrator = kbnServer.newPlatform.__internals.kibanaMigrator;
- const typeRegistry = kbnServer.newPlatform.start.core.savedObjects.getTypeRegistry();
- const mappings = migrator.getActiveMappings();
- const allTypes = typeRegistry.getAllTypes().map((t) => t.name);
- const visibleTypes = typeRegistry.getVisibleTypes().map((t) => t.name);
- const schema = new SavedObjectsSchema(convertTypesToLegacySchema(typeRegistry.getAllTypes()));
-
- server.decorate('server', 'kibanaMigrator', migrator);
-
- const serializer = kbnServer.newPlatform.start.core.savedObjects.createSerializer();
-
- const createRepository = (callCluster, includedHiddenTypes = []) => {
- if (typeof callCluster !== 'function') {
- throw new TypeError('Repository requires a "callCluster" function to be provided.');
- }
- // throw an exception if an extraType is not defined.
- includedHiddenTypes.forEach((type) => {
- if (!allTypes.includes(type)) {
- throw new Error(`Missing mappings for saved objects type '${type}'`);
- }
- });
- const combinedTypes = visibleTypes.concat(includedHiddenTypes);
- const allowedTypes = [...new Set(combinedTypes)];
-
- const config = server.config();
-
- return new SavedObjectsRepository({
- index: config.get('kibana.index'),
- migrator,
- mappings,
- typeRegistry,
- serializer,
- allowedTypes,
- callCluster,
- });
- };
-
- const provider = kbnServer.newPlatform.__internals.savedObjectsClientProvider;
-
- const service = {
- types: visibleTypes,
- SavedObjectsClient,
- SavedObjectsRepository,
- getSavedObjectsRepository: createRepository,
- getScopedSavedObjectsClient: (...args) => provider.getClient(...args),
- setScopedSavedObjectsClientFactory: (...args) => provider.setClientFactory(...args),
- addScopedSavedObjectsClientWrapperFactory: (...args) =>
- provider.addClientWrapperFactory(...args),
- importExport: {
- objectLimit: server.config().get('savedObjects.maxImportExportSize'),
- importSavedObjects: importSavedObjectsFromStream,
- resolveImportErrors: resolveSavedObjectsImportErrors,
- getSortedObjectsForExport: exportSavedObjectsToStream,
- },
- schema,
- };
- server.decorate('server', 'savedObjects', service);
-
- const savedObjectsClientCache = new WeakMap();
- server.decorate('request', 'getSavedObjectsClient', function (options) {
- const request = this;
-
- if (savedObjectsClientCache.has(request)) {
- return savedObjectsClientCache.get(request);
- }
-
- const savedObjectsClient = server.savedObjects.getScopedSavedObjectsClient(request, options);
-
- savedObjectsClientCache.set(request, savedObjectsClient);
- return savedObjectsClient;
- });
-}
diff --git a/src/legacy/server/saved_objects/saved_objects_mixin.test.js b/src/legacy/server/saved_objects/saved_objects_mixin.test.js
deleted file mode 100644
index d1d6c052ad589..0000000000000
--- a/src/legacy/server/saved_objects/saved_objects_mixin.test.js
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { savedObjectsMixin } from './saved_objects_mixin';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { mockKibanaMigrator } from '../../../core/server/saved_objects/migrations/kibana/kibana_migrator.mock';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { savedObjectsClientProviderMock } from '../../../core/server/saved_objects/service/lib/scoped_client_provider.mock';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { convertLegacyTypes } from '../../../core/server/saved_objects/utils';
-import { SavedObjectTypeRegistry } from '../../../core/server';
-import { coreMock } from '../../../core/server/mocks';
-
-const mockConfig = {
- get: jest.fn().mockReturnValue('anything'),
-};
-
-const savedObjectMappings = [
- {
- pluginId: 'testtype',
- properties: {
- testtype: {
- properties: {
- name: { type: 'keyword' },
- },
- },
- },
- },
- {
- pluginId: 'testtype2',
- properties: {
- doc1: {
- properties: {
- name: { type: 'keyword' },
- },
- },
- doc2: {
- properties: {
- name: { type: 'keyword' },
- },
- },
- },
- },
- {
- pluginId: 'secretPlugin',
- properties: {
- hiddentype: {
- properties: {
- secret: { type: 'keyword' },
- },
- },
- },
- },
-];
-
-const savedObjectSchemas = {
- hiddentype: {
- hidden: true,
- },
- doc1: {
- indexPattern: 'other-index',
- },
-};
-
-const savedObjectTypes = convertLegacyTypes(
- {
- savedObjectMappings,
- savedObjectSchemas,
- savedObjectMigrations: {},
- },
- mockConfig
-);
-
-const typeRegistry = new SavedObjectTypeRegistry();
-savedObjectTypes.forEach((type) => typeRegistry.registerType(type));
-
-const migrator = mockKibanaMigrator.create({
- types: savedObjectTypes,
-});
-
-describe('Saved Objects Mixin', () => {
- let mockKbnServer;
- let mockServer;
- const mockCallCluster = jest.fn();
- const stubCallCluster = jest.fn();
- const config = {
- 'kibana.index': 'kibana.index',
- 'savedObjects.maxImportExportSize': 10000,
- };
- const stubConfig = jest.fn((key) => {
- return config[key];
- });
-
- beforeEach(() => {
- const clientProvider = savedObjectsClientProviderMock.create();
- mockServer = {
- log: jest.fn(),
- route: jest.fn(),
- decorate: jest.fn(),
- config: () => {
- return {
- get: stubConfig,
- };
- },
- plugins: {
- elasticsearch: {
- getCluster: () => {
- return {
- callWithRequest: mockCallCluster,
- callWithInternalUser: stubCallCluster,
- };
- },
- waitUntilReady: jest.fn(),
- },
- },
- };
-
- const coreStart = coreMock.createStart();
- coreStart.savedObjects.getTypeRegistry.mockReturnValue(typeRegistry);
-
- mockKbnServer = {
- newPlatform: {
- __internals: {
- kibanaMigrator: migrator,
- savedObjectsClientProvider: clientProvider,
- },
- setup: {
- core: coreMock.createSetup(),
- },
- start: {
- core: coreStart,
- },
- },
- server: mockServer,
- ready: () => {},
- pluginSpecs: {
- some: () => {
- return true;
- },
- },
- uiExports: {
- savedObjectMappings,
- savedObjectSchemas,
- },
- };
- });
-
- describe('Saved object service', () => {
- let service;
-
- beforeEach(async () => {
- await savedObjectsMixin(mockKbnServer, mockServer);
- const call = mockServer.decorate.mock.calls.filter(
- ([objName, methodName]) => objName === 'server' && methodName === 'savedObjects'
- );
- service = call[0][2];
- });
-
- it('should return all but hidden types', async () => {
- expect(service).toBeDefined();
- expect(service.types).toEqual(['testtype', 'doc1', 'doc2']);
- });
-
- const mockCallEs = jest.fn();
- describe('repository creation', () => {
- it('should not allow a repository with an undefined type', () => {
- expect(() => {
- service.getSavedObjectsRepository(mockCallEs, ['extraType']);
- }).toThrow(new Error("Missing mappings for saved objects type 'extraType'"));
- });
-
- it('should create a repository without hidden types', () => {
- const repository = service.getSavedObjectsRepository(mockCallEs);
- expect(repository).toBeDefined();
- expect(repository._allowedTypes).toEqual(['testtype', 'doc1', 'doc2']);
- });
-
- it('should create a repository with a unique list of allowed types', () => {
- const repository = service.getSavedObjectsRepository(mockCallEs, ['doc1', 'doc1', 'doc1']);
- expect(repository._allowedTypes).toEqual(['testtype', 'doc1', 'doc2']);
- });
-
- it('should create a repository with extraTypes minus duplicate', () => {
- const repository = service.getSavedObjectsRepository(mockCallEs, [
- 'hiddentype',
- 'hiddentype',
- ]);
- expect(repository._allowedTypes).toEqual(['testtype', 'doc1', 'doc2', 'hiddentype']);
- });
-
- it('should not allow a repository without a callCluster function', () => {
- expect(() => {
- service.getSavedObjectsRepository({});
- }).toThrow(new Error('Repository requires a "callCluster" function to be provided.'));
- });
- });
-
- describe('get client', () => {
- it('should have a method to get the client', () => {
- expect(service).toHaveProperty('getScopedSavedObjectsClient');
- });
-
- it('should have a method to set the client factory', () => {
- expect(service).toHaveProperty('setScopedSavedObjectsClientFactory');
- });
-
- it('should have a method to add a client wrapper factory', () => {
- expect(service).toHaveProperty('addScopedSavedObjectsClientWrapperFactory');
- });
-
- it('should allow you to set a scoped saved objects client factory', () => {
- expect(() => {
- service.setScopedSavedObjectsClientFactory({});
- }).not.toThrowError();
- });
-
- it('should allow you to add a scoped saved objects client wrapper factory', () => {
- expect(() => {
- service.addScopedSavedObjectsClientWrapperFactory({});
- }).not.toThrowError();
- });
- });
-
- describe('#getSavedObjectsClient', () => {
- let getSavedObjectsClient;
-
- beforeEach(() => {
- savedObjectsMixin(mockKbnServer, mockServer);
- const call = mockServer.decorate.mock.calls.filter(
- ([objName, methodName]) => objName === 'request' && methodName === 'getSavedObjectsClient'
- );
- getSavedObjectsClient = call[0][2];
- });
-
- it('should be callable', () => {
- mockServer.savedObjects = service;
- getSavedObjectsClient = getSavedObjectsClient.bind({});
- expect(() => {
- getSavedObjectsClient();
- }).not.toThrowError();
- });
-
- it('should use cached request object', () => {
- mockServer.savedObjects = service;
- getSavedObjectsClient = getSavedObjectsClient.bind({ _test: 'me' });
- const savedObjectsClient = getSavedObjectsClient();
- expect(getSavedObjectsClient()).toEqual(savedObjectsClient);
- });
- });
- });
-});
diff --git a/src/legacy/ui/ui_exports/__tests__/collect_ui_exports.js b/src/legacy/ui/ui_exports/__tests__/collect_ui_exports.js
deleted file mode 100644
index 5b2af9f82333c..0000000000000
--- a/src/legacy/ui/ui_exports/__tests__/collect_ui_exports.js
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import expect from '@kbn/expect';
-
-import { PluginPack } from '../../../plugin_discovery';
-
-import { collectUiExports } from '../collect_ui_exports';
-
-const specs = new PluginPack({
- path: '/dev/null',
- pkg: {
- name: 'test',
- version: 'kibana',
- },
- provider({ Plugin }) {
- return [
- new Plugin({
- id: 'test',
- uiExports: {
- savedObjectSchemas: {
- foo: {
- isNamespaceAgnostic: true,
- },
- },
- },
- }),
- new Plugin({
- id: 'test2',
- uiExports: {
- savedObjectSchemas: {
- bar: {
- isNamespaceAgnostic: true,
- },
- },
- },
- }),
- ];
- },
-}).getPluginSpecs();
-
-describe('plugin discovery', () => {
- describe('collectUiExports()', () => {
- it('merges uiExports from all provided plugin specs', () => {
- const uiExports = collectUiExports(specs);
-
- expect(uiExports.savedObjectSchemas).to.eql({
- foo: {
- isNamespaceAgnostic: true,
- },
- bar: {
- isNamespaceAgnostic: true,
- },
- });
- });
-
- it(`throws an error when migrations and mappings aren't defined in the same plugin`, () => {
- const invalidSpecs = new PluginPack({
- path: '/dev/null',
- pkg: {
- name: 'test',
- version: 'kibana',
- },
- provider({ Plugin }) {
- return [
- new Plugin({
- id: 'test',
- uiExports: {
- mappings: {
- 'test-type': {
- properties: {},
- },
- },
- },
- }),
- new Plugin({
- id: 'test2',
- uiExports: {
- migrations: {
- 'test-type': {
- '1.2.3': (doc) => {
- return doc;
- },
- },
- },
- },
- }),
- ];
- },
- }).getPluginSpecs();
- expect(() => collectUiExports(invalidSpecs)).to.throwError((err) => {
- expect(err).to.be.a(Error);
- expect(err).to.have.property(
- 'message',
- 'Migrations and mappings must be defined together in the uiExports of a single plugin. ' +
- 'test2 defines migrations for types test-type but does not define their mappings.'
- );
- });
- });
- });
-});
diff --git a/src/legacy/ui/ui_render/ui_render_mixin.js b/src/legacy/ui/ui_render/ui_render_mixin.js
index cd8dcf5aff71d..e3b7c1e0c3ff9 100644
--- a/src/legacy/ui/ui_render/ui_render_mixin.js
+++ b/src/legacy/ui/ui_render/ui_render_mixin.js
@@ -193,13 +193,11 @@ export function uiRenderMixin(kbnServer, server, config) {
async function renderApp(h) {
const app = { getId: () => 'core' };
const { http } = kbnServer.newPlatform.setup.core;
- const {
- rendering,
- legacy,
- savedObjectsClientProvider: savedObjects,
- } = kbnServer.newPlatform.__internals;
+ const { savedObjects } = kbnServer.newPlatform.start.core;
+ const { rendering, legacy } = kbnServer.newPlatform.__internals;
+ const req = KibanaRequest.from(h.request);
const uiSettings = kbnServer.newPlatform.start.core.uiSettings.asScopedToClient(
- savedObjects.getClient(h.request)
+ savedObjects.getScopedClient(req)
);
const vars = await legacy.getVars(app.getId(), h.request, {
apmConfig: getApmConfig(h.request.path),
diff --git a/src/plugins/data/common/constants.ts b/src/plugins/data/common/constants.ts
index 22db1552e4303..43120583bd3a4 100644
--- a/src/plugins/data/common/constants.ts
+++ b/src/plugins/data/common/constants.ts
@@ -32,6 +32,7 @@ export const UI_SETTINGS = {
COURIER_MAX_CONCURRENT_SHARD_REQUESTS: 'courier:maxConcurrentShardRequests',
COURIER_BATCH_SEARCHES: 'courier:batchSearches',
SEARCH_INCLUDE_FROZEN: 'search:includeFrozen',
+ SEARCH_TIMEOUT: 'search:timeout',
HISTOGRAM_BAR_TARGET: 'histogram:barTarget',
HISTOGRAM_MAX_BARS: 'histogram:maxBars',
HISTORY_LIMIT: 'history:limit',
diff --git a/src/plugins/data/common/field_formats/converters/duration.test.ts b/src/plugins/data/common/field_formats/converters/duration.test.ts
index d6205d54bd702..69163842f3498 100644
--- a/src/plugins/data/common/field_formats/converters/duration.test.ts
+++ b/src/plugins/data/common/field_formats/converters/duration.test.ts
@@ -24,11 +24,16 @@ describe('Duration Format', () => {
inputFormat: 'seconds',
outputFormat: 'humanize',
outputPrecision: undefined,
+ showSuffix: undefined,
fixtures: [
{
input: -60,
output: 'minus a minute',
},
+ {
+ input: 1,
+ output: 'a few seconds',
+ },
{
input: 60,
output: 'a minute',
@@ -44,6 +49,7 @@ describe('Duration Format', () => {
inputFormat: 'minutes',
outputFormat: 'humanize',
outputPrecision: undefined,
+ showSuffix: undefined,
fixtures: [
{
input: -60,
@@ -64,6 +70,7 @@ describe('Duration Format', () => {
inputFormat: 'minutes',
outputFormat: 'asHours',
outputPrecision: undefined,
+ showSuffix: undefined,
fixtures: [
{
input: -60,
@@ -84,6 +91,7 @@ describe('Duration Format', () => {
inputFormat: 'seconds',
outputFormat: 'asSeconds',
outputPrecision: 0,
+ showSuffix: undefined,
fixtures: [
{
input: -60,
@@ -104,6 +112,7 @@ describe('Duration Format', () => {
inputFormat: 'seconds',
outputFormat: 'asSeconds',
outputPrecision: 2,
+ showSuffix: undefined,
fixtures: [
{
input: -60,
@@ -124,15 +133,34 @@ describe('Duration Format', () => {
],
});
+ testCase({
+ inputFormat: 'seconds',
+ outputFormat: 'asSeconds',
+ outputPrecision: 0,
+ showSuffix: true,
+ fixtures: [
+ {
+ input: -60,
+ output: '-60 Seconds',
+ },
+ {
+ input: -32.333,
+ output: '-32 Seconds',
+ },
+ ],
+ });
+
function testCase({
inputFormat,
outputFormat,
outputPrecision,
+ showSuffix,
fixtures,
}: {
inputFormat: string;
outputFormat: string;
outputPrecision: number | undefined;
+ showSuffix: boolean | undefined;
fixtures: any[];
}) {
fixtures.forEach((fixture: Record) => {
@@ -143,7 +171,7 @@ describe('Duration Format', () => {
outputPrecision ? `, ${outputPrecision} decimals` : ''
}`, () => {
const duration = new DurationFormat(
- { inputFormat, outputFormat, outputPrecision },
+ { inputFormat, outputFormat, outputPrecision, showSuffix },
jest.fn()
);
expect(duration.convert(input)).toBe(output);
diff --git a/src/plugins/data/common/field_formats/converters/duration.ts b/src/plugins/data/common/field_formats/converters/duration.ts
index 53c2aba98120e..a3ce3d4dfd795 100644
--- a/src/plugins/data/common/field_formats/converters/duration.ts
+++ b/src/plugins/data/common/field_formats/converters/duration.ts
@@ -190,6 +190,7 @@ export class DurationFormat extends FieldFormat {
const inputFormat = this.param('inputFormat');
const outputFormat = this.param('outputFormat') as keyof Duration;
const outputPrecision = this.param('outputPrecision');
+ const showSuffix = Boolean(this.param('showSuffix'));
const human = this.isHuman();
const prefix =
val < 0 && human
@@ -200,6 +201,9 @@ export class DurationFormat extends FieldFormat {
const duration = parseInputAsDuration(val, inputFormat) as Record;
const formatted = duration[outputFormat]();
const precise = human ? formatted : formatted.toFixed(outputPrecision);
- return prefix + precise;
+ const type = outputFormats.find(({ method }) => method === outputFormat);
+ const suffix = showSuffix && type ? ` ${type.text}` : '';
+
+ return prefix + precise + suffix;
};
}
diff --git a/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_pattern.test.ts.snap b/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_pattern.test.ts.snap
index a0c380ec55bf6..1871627da76de 100644
--- a/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_pattern.test.ts.snap
+++ b/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_pattern.test.ts.snap
@@ -631,7 +631,7 @@ Object {
"id": "test-pattern",
"sourceFilters": undefined,
"timeFieldName": "timestamp",
- "title": "test-pattern",
+ "title": "title",
"typeMeta": undefined,
"version": 2,
}
diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts
index f037a71b508a2..f49897c47d562 100644
--- a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts
+++ b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import { defaults, map, last, get } from 'lodash';
+import { defaults, map, last } from 'lodash';
import { IndexPattern } from './index_pattern';
@@ -29,7 +29,7 @@ import { stubbedSavedObjectIndexPattern } from '../../../../../fixtures/stubbed_
import { IndexPatternField } from '../fields';
import { fieldFormatsMock } from '../../field_formats/mocks';
-import { FieldFormat } from '../..';
+import { FieldFormat, IndexPatternsService } from '../..';
class MockFieldFormatter {}
@@ -116,6 +116,7 @@ function create(id: string, payload?: any): Promise {
apiClient,
patternCache,
fieldFormats: fieldFormatsMock,
+ indexPatternsService: {} as IndexPatternsService,
onNotification: () => {},
onError: () => {},
shortDotsEnable: false,
@@ -151,7 +152,6 @@ describe('IndexPattern', () => {
expect(indexPattern).toHaveProperty('getNonScriptedFields');
expect(indexPattern).toHaveProperty('addScriptedField');
expect(indexPattern).toHaveProperty('removeScriptedField');
- expect(indexPattern).toHaveProperty('save');
// properties
expect(indexPattern).toHaveProperty('fields');
@@ -389,60 +389,4 @@ describe('IndexPattern', () => {
});
});
});
-
- test('should handle version conflicts', async () => {
- setDocsourcePayload(null, {
- id: 'foo',
- version: 'foo',
- attributes: {
- title: 'something',
- },
- });
- // Create a normal index pattern
- const pattern = new IndexPattern('foo', {
- savedObjectsClient: savedObjectsClient as any,
- apiClient,
- patternCache,
- fieldFormats: fieldFormatsMock,
- onNotification: () => {},
- onError: () => {},
- shortDotsEnable: false,
- metaFields: [],
- });
- await pattern.init();
-
- expect(get(pattern, 'version')).toBe('fooa');
-
- // Create the same one - we're going to handle concurrency
- const samePattern = new IndexPattern('foo', {
- savedObjectsClient: savedObjectsClient as any,
- apiClient,
- patternCache,
- fieldFormats: fieldFormatsMock,
- onNotification: () => {},
- onError: () => {},
- shortDotsEnable: false,
- metaFields: [],
- });
- await samePattern.init();
-
- expect(get(samePattern, 'version')).toBe('fooaa');
-
- // This will conflict because samePattern did a save (from refreshFields)
- // but the resave should work fine
- pattern.title = 'foo2';
- await pattern.save();
-
- // This should not be able to recover
- samePattern.title = 'foo3';
-
- let result;
- try {
- await samePattern.save();
- } catch (err) {
- result = err;
- }
-
- expect(result.res.status).toBe(409);
- });
});
diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts
index 0558808573580..76f1a5e59d0ee 100644
--- a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts
+++ b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts
@@ -41,8 +41,8 @@ import { PatternCache } from './_pattern_cache';
import { expandShorthand, FieldMappingSpec, MappingObject } from '../../field_mapping';
import { IndexPatternSpec, TypeMeta, FieldSpec, SourceFilter } from '../types';
import { SerializedFieldFormat } from '../../../../expressions/common';
+import { IndexPatternsService } from '..';
-const MAX_ATTEMPTS_TO_RESOLVE_CONFLICTS = 3;
const savedObjectType = 'index-pattern';
interface IndexPatternDeps {
@@ -50,6 +50,7 @@ interface IndexPatternDeps {
apiClient: IIndexPatternsApiClient;
patternCache: PatternCache;
fieldFormats: FieldFormatsStartCommon;
+ indexPatternsService: IndexPatternsService;
onNotification: OnNotification;
onError: OnError;
shortDotsEnable: boolean;
@@ -70,17 +71,18 @@ export class IndexPattern implements IIndexPattern {
public flattenHit: any;
public metaFields: string[];
- private version: string | undefined;
+ public version: string | undefined;
private savedObjectsClient: SavedObjectsClientCommon;
private patternCache: PatternCache;
public sourceFilters?: SourceFilter[];
- private originalBody: { [key: string]: any } = {};
+ // todo make read only, update via method or factor out
+ public originalBody: { [key: string]: any } = {};
public fieldsFetcher: any; // probably want to factor out any direct usage and change to private
+ private indexPatternsService: IndexPatternsService;
private shortDotsEnable: boolean = false;
private fieldFormats: FieldFormatsStartCommon;
private onNotification: OnNotification;
private onError: OnError;
- private apiClient: IIndexPatternsApiClient;
private mapping: MappingObject = expandShorthand({
title: ES_FIELD_TYPES.TEXT,
@@ -111,6 +113,7 @@ export class IndexPattern implements IIndexPattern {
apiClient,
patternCache,
fieldFormats,
+ indexPatternsService,
onNotification,
onError,
shortDotsEnable = false,
@@ -121,6 +124,7 @@ export class IndexPattern implements IIndexPattern {
this.savedObjectsClient = savedObjectsClient;
this.patternCache = patternCache;
this.fieldFormats = fieldFormats;
+ this.indexPatternsService = indexPatternsService;
this.onNotification = onNotification;
this.onError = onError;
@@ -128,7 +132,6 @@ export class IndexPattern implements IIndexPattern {
this.metaFields = metaFields;
this.fields = fieldList([], this.shortDotsEnable);
- this.apiClient = apiClient;
this.fieldsFetcher = createFieldsFetcher(this, apiClient, metaFields);
this.flattenHit = flattenHitWrapper(this, metaFields);
this.formatHit = formatHitProvider(
@@ -392,8 +395,6 @@ export class IndexPattern implements IIndexPattern {
} else {
throw err;
}
-
- await this.save();
}
}
@@ -402,7 +403,6 @@ export class IndexPattern implements IIndexPattern {
if (field) {
this.fields.remove(field);
}
- return this.save();
}
async popularizeField(fieldName: string, unit = 1) {
@@ -523,92 +523,6 @@ export class IndexPattern implements IIndexPattern {
return await _create(potentialDuplicateByTitle.id);
}
- async save(saveAttempts: number = 0): Promise {
- if (!this.id) return;
- const body = this.prepBody();
-
- const originalChangedKeys: string[] = [];
- Object.entries(body).forEach(([key, value]) => {
- if (value !== this.originalBody[key]) {
- originalChangedKeys.push(key);
- }
- });
-
- return this.savedObjectsClient
- .update(savedObjectType, this.id, body, { version: this.version })
- .then((resp) => {
- this.id = resp.id;
- this.version = resp.version;
- })
- .catch((err) => {
- if (
- _.get(err, 'res.status') === 409 &&
- saveAttempts++ < MAX_ATTEMPTS_TO_RESOLVE_CONFLICTS
- ) {
- const samePattern = new IndexPattern(this.id, {
- savedObjectsClient: this.savedObjectsClient,
- apiClient: this.apiClient,
- patternCache: this.patternCache,
- fieldFormats: this.fieldFormats,
- onNotification: this.onNotification,
- onError: this.onError,
- shortDotsEnable: this.shortDotsEnable,
- metaFields: this.metaFields,
- });
-
- return samePattern.init().then(() => {
- // What keys changed from now and what the server returned
- const updatedBody = samePattern.prepBody();
-
- // Build a list of changed keys from the server response
- // and ensure we ignore the key if the server response
- // is the same as the original response (since that is expected
- // if we made a change in that key)
-
- const serverChangedKeys: string[] = [];
- Object.entries(updatedBody).forEach(([key, value]) => {
- if (value !== (body as any)[key] && value !== this.originalBody[key]) {
- serverChangedKeys.push(key);
- }
- });
-
- let unresolvedCollision = false;
- for (const originalKey of originalChangedKeys) {
- for (const serverKey of serverChangedKeys) {
- if (originalKey === serverKey) {
- unresolvedCollision = true;
- break;
- }
- }
- }
-
- if (unresolvedCollision) {
- const title = i18n.translate('data.indexPatterns.unableWriteLabel', {
- defaultMessage:
- 'Unable to write index pattern! Refresh the page to get the most up to date changes for this index pattern.',
- });
-
- this.onNotification({ title, color: 'danger' });
- throw err;
- }
-
- // Set the updated response on this object
- serverChangedKeys.forEach((key) => {
- (this as any)[key] = (samePattern as any)[key];
- });
- this.version = samePattern.version;
-
- // Clear cache
- this.patternCache.clear(this.id!);
-
- // Try the save again
- return this.save(saveAttempts);
- });
- }
- throw err;
- });
- }
-
async _fetchFields() {
const fields = await this.fieldsFetcher.fetch(this);
const scripted = this.getScriptedFields().map((field) => field.spec);
@@ -624,30 +538,37 @@ export class IndexPattern implements IIndexPattern {
}
refreshFields() {
- return this._fetchFields()
- .then(() => this.save())
- .catch((err) => {
- // https://github.com/elastic/kibana/issues/9224
- // This call will attempt to remap fields from the matching
- // ES index which may not actually exist. In that scenario,
- // we still want to notify the user that there is a problem
- // but we do not want to potentially make any pages unusable
- // so do not rethrow the error here
-
- if (err instanceof IndexPatternMissingIndices) {
- this.onNotification({ title: (err as any).message, color: 'danger', iconType: 'alert' });
- return [];
- }
+ return (
+ this._fetchFields()
+ // todo
+ .then(() => this.indexPatternsService.save(this))
+ .catch((err) => {
+ // https://github.com/elastic/kibana/issues/9224
+ // This call will attempt to remap fields from the matching
+ // ES index which may not actually exist. In that scenario,
+ // we still want to notify the user that there is a problem
+ // but we do not want to potentially make any pages unusable
+ // so do not rethrow the error here
+
+ if (err instanceof IndexPatternMissingIndices) {
+ this.onNotification({
+ title: (err as any).message,
+ color: 'danger',
+ iconType: 'alert',
+ });
+ return [];
+ }
- this.onError(err, {
- title: i18n.translate('data.indexPatterns.fetchFieldErrorTitle', {
- defaultMessage: 'Error fetching fields for index pattern {title} (ID: {id})',
- values: {
- id: this.id,
- title: this.title,
- },
- }),
- });
- });
+ this.onError(err, {
+ title: i18n.translate('data.indexPatterns.fetchFieldErrorTitle', {
+ defaultMessage: 'Error fetching fields for index pattern {title} (ID: {id})',
+ values: {
+ id: this.id,
+ title: this.title,
+ },
+ }),
+ });
+ })
+ );
}
}
diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts
index 8223b31042124..c79c7900148ea 100644
--- a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts
+++ b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts
@@ -17,28 +17,26 @@
* under the License.
*/
-import { IndexPatternsService } from './index_patterns';
+import { defaults } from 'lodash';
+import { IndexPatternsService } from '.';
import { fieldFormatsMock } from '../../field_formats/mocks';
-import {
- UiSettingsCommon,
- IIndexPatternsApiClient,
- SavedObjectsClientCommon,
- SavedObject,
-} from '../types';
+import { stubbedSavedObjectIndexPattern } from '../../../../../fixtures/stubbed_saved_object_index_pattern';
+import { UiSettingsCommon, SavedObjectsClientCommon, SavedObject } from '../types';
+
+const createFieldsFetcher = jest.fn().mockImplementation(() => ({
+ getFieldsForWildcard: jest.fn().mockImplementation(() => {
+ return new Promise((resolve) => resolve([]));
+ }),
+ every: jest.fn(),
+}));
const fieldFormats = fieldFormatsMock;
-jest.mock('./index_pattern', () => {
- class IndexPattern {
- init = async () => {
- return this;
- };
- }
+let object: any = {};
- return {
- IndexPattern,
- };
-});
+function setDocsourcePayload(id: string | null, providedPayload: any) {
+ object = defaults(providedPayload || {}, stubbedSavedObjectIndexPattern(id));
+}
describe('IndexPatterns', () => {
let indexPatterns: IndexPatternsService;
@@ -53,6 +51,25 @@ describe('IndexPatterns', () => {
>
);
savedObjectsClient.delete = jest.fn(() => Promise.resolve({}) as Promise);
+ savedObjectsClient.get = jest.fn().mockImplementation(() => object);
+ savedObjectsClient.create = jest.fn();
+ savedObjectsClient.update = jest
+ .fn()
+ .mockImplementation(async (type, id, body, { version }) => {
+ if (object.version !== version) {
+ throw new Object({
+ res: {
+ status: 409,
+ },
+ });
+ }
+ object.attributes.title = body.title;
+ object.version += 'a';
+ return {
+ id: object.id,
+ version: object.version,
+ };
+ });
indexPatterns = new IndexPatternsService({
uiSettings: ({
@@ -60,7 +77,7 @@ describe('IndexPatterns', () => {
getAll: () => {},
} as any) as UiSettingsCommon,
savedObjectsClient: (savedObjectsClient as unknown) as SavedObjectsClientCommon,
- apiClient: {} as IIndexPatternsApiClient,
+ apiClient: createFieldsFetcher(),
fieldFormats,
onNotification: () => {},
onError: () => {},
@@ -70,6 +87,14 @@ describe('IndexPatterns', () => {
test('does cache gets for the same id', async () => {
const id = '1';
+ setDocsourcePayload(id, {
+ id: 'foo',
+ version: 'foo',
+ attributes: {
+ title: 'something',
+ },
+ });
+
const indexPattern = await indexPatterns.get(id);
expect(indexPattern).toBeDefined();
@@ -107,4 +132,41 @@ describe('IndexPatterns', () => {
await indexPatterns.delete(id);
expect(indexPattern).not.toBe(await indexPatterns.get(id));
});
+
+ test('should handle version conflicts', async () => {
+ setDocsourcePayload(null, {
+ id: 'foo',
+ version: 'foo',
+ attributes: {
+ title: 'something',
+ },
+ });
+
+ // Create a normal index patterns
+ const pattern = await indexPatterns.make('foo');
+
+ expect(pattern.version).toBe('fooa');
+
+ // Create the same one - we're going to handle concurrency
+ const samePattern = await indexPatterns.make('foo');
+
+ expect(samePattern.version).toBe('fooaa');
+
+ // This will conflict because samePattern did a save (from refreshFields)
+ // but the resave should work fine
+ pattern.title = 'foo2';
+ await indexPatterns.save(pattern);
+
+ // This should not be able to recover
+ samePattern.title = 'foo3';
+
+ let result;
+ try {
+ await indexPatterns.save(samePattern);
+ } catch (err) {
+ result = err;
+ }
+
+ expect(result.res.status).toBe(409);
+ });
});
diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts
index fe0d14b2d9c19..88a7e9f6cef4c 100644
--- a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts
+++ b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts
@@ -17,6 +17,7 @@
* under the License.
*/
+import { i18n } from '@kbn/i18n';
import { SavedObjectsClientCommon } from '../..';
import { createIndexPatternCache } from '.';
@@ -37,6 +38,8 @@ import { FieldFormatsStartCommon } from '../../field_formats';
import { UI_SETTINGS, SavedObject } from '../../../common';
const indexPatternCache = createIndexPatternCache();
+const MAX_ATTEMPTS_TO_RESOLVE_CONFLICTS = 3;
+const savedObjectType = 'index-pattern';
type IndexPatternCachedFieldType = 'id' | 'title';
@@ -181,6 +184,7 @@ export class IndexPatternsService {
apiClient: this.apiClient,
patternCache: indexPatternCache,
fieldFormats: this.fieldFormats,
+ indexPatternsService: this,
onNotification: this.onNotification,
onError: this.onError,
shortDotsEnable,
@@ -191,6 +195,93 @@ export class IndexPatternsService {
return indexPattern;
}
+ async save(indexPattern: IndexPattern, saveAttempts: number = 0): Promise {
+ if (!indexPattern.id) return;
+ const shortDotsEnable = await this.config.get(UI_SETTINGS.SHORT_DOTS_ENABLE);
+ const metaFields = await this.config.get(UI_SETTINGS.META_FIELDS);
+
+ const body = indexPattern.prepBody();
+
+ const originalChangedKeys: string[] = [];
+ Object.entries(body).forEach(([key, value]) => {
+ if (value !== indexPattern.originalBody[key]) {
+ originalChangedKeys.push(key);
+ }
+ });
+
+ return this.savedObjectsClient
+ .update(savedObjectType, indexPattern.id, body, { version: indexPattern.version })
+ .then((resp) => {
+ indexPattern.id = resp.id;
+ indexPattern.version = resp.version;
+ })
+ .catch((err) => {
+ if (err?.res?.status === 409 && saveAttempts++ < MAX_ATTEMPTS_TO_RESOLVE_CONFLICTS) {
+ const samePattern = new IndexPattern(indexPattern.id, {
+ savedObjectsClient: this.savedObjectsClient,
+ apiClient: this.apiClient,
+ patternCache: indexPatternCache,
+ fieldFormats: this.fieldFormats,
+ indexPatternsService: this,
+ onNotification: this.onNotification,
+ onError: this.onError,
+ shortDotsEnable,
+ metaFields,
+ });
+
+ return samePattern.init().then(() => {
+ // What keys changed from now and what the server returned
+ const updatedBody = samePattern.prepBody();
+
+ // Build a list of changed keys from the server response
+ // and ensure we ignore the key if the server response
+ // is the same as the original response (since that is expected
+ // if we made a change in that key)
+
+ const serverChangedKeys: string[] = [];
+ Object.entries(updatedBody).forEach(([key, value]) => {
+ if (value !== (body as any)[key] && value !== indexPattern.originalBody[key]) {
+ serverChangedKeys.push(key);
+ }
+ });
+
+ let unresolvedCollision = false;
+ for (const originalKey of originalChangedKeys) {
+ for (const serverKey of serverChangedKeys) {
+ if (originalKey === serverKey) {
+ unresolvedCollision = true;
+ break;
+ }
+ }
+ }
+
+ if (unresolvedCollision) {
+ const title = i18n.translate('data.indexPatterns.unableWriteLabel', {
+ defaultMessage:
+ 'Unable to write index pattern! Refresh the page to get the most up to date changes for this index pattern.',
+ });
+
+ this.onNotification({ title, color: 'danger' });
+ throw err;
+ }
+
+ // Set the updated response on this object
+ serverChangedKeys.forEach((key) => {
+ (indexPattern as any)[key] = (samePattern as any)[key];
+ });
+ indexPattern.version = samePattern.version;
+
+ // Clear cache
+ indexPatternCache.clear(indexPattern.id!);
+
+ // Try the save again
+ return this.save(indexPattern, saveAttempts);
+ });
+ }
+ throw err;
+ });
+ }
+
async make(id?: string): Promise {
const shortDotsEnable = await this.config.get(UI_SETTINGS.SHORT_DOTS_ENABLE);
const metaFields = await this.config.get(UI_SETTINGS.META_FIELDS);
@@ -200,6 +291,7 @@ export class IndexPatternsService {
apiClient: this.apiClient,
patternCache: indexPatternCache,
fieldFormats: this.fieldFormats,
+ indexPatternsService: this,
onNotification: this.onNotification,
onError: this.onError,
shortDotsEnable,
diff --git a/src/plugins/data/common/search/es_search/index.ts b/src/plugins/data/common/search/es_search/index.ts
index 54757b53b8665..d8f7b5091eb8f 100644
--- a/src/plugins/data/common/search/es_search/index.ts
+++ b/src/plugins/data/common/search/es_search/index.ts
@@ -17,10 +17,4 @@
* under the License.
*/
-export {
- ISearchRequestParams,
- IEsSearchRequest,
- IEsSearchResponse,
- ES_SEARCH_STRATEGY,
- ISearchOptions,
-} from './types';
+export * from './types';
diff --git a/src/plugins/data/common/search/es_search/types.ts b/src/plugins/data/common/search/es_search/types.ts
index 89faa5b7119c8..81124c1e095f7 100644
--- a/src/plugins/data/common/search/es_search/types.ts
+++ b/src/plugins/data/common/search/es_search/types.ts
@@ -53,3 +53,6 @@ export interface IEsSearchResponse