mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
## Summary This PR aims at relocating some of the Kibana modules (plugins and packages) into a new folder structure, according to the _Sustainable Kibana Architecture_ initiative. > [!IMPORTANT] > * We kindly ask you to: > * Manually fix the errors in the error section below (if there are any). > * Search for the `packages[\/\\]` and `plugins[\/\\]` patterns in the source code (Babel and Eslint config files), and update them appropriately. > * Manually review `.buildkite/scripts/pipelines/pull_request/pipeline.ts` to ensure that any CI pipeline customizations continue to be correctly applied after the changed path names > * Review all of the updated files, specially the `.ts` and `.js` files listed in the sections below, as some of them contain relative paths that have been updated. > * Think of potential impact of the move, including tooling and configuration files that can be pointing to the relocated modules. E.g.: > * customised eslint rules > * docs pointing to source code > [!NOTE] > * This PR has been auto-generated. > * Any manual contributions will be lost if the 'relocate' script is re-run. > * Try to obtain the missing reviews / approvals before applying manual fixes, and/or keep your changes in a .patch / git stash. > * Please use [#sustainable_kibana_architecture](https://elastic.slack.com/archives/C07TCKTA22E) Slack channel for feedback. Are you trying to rebase this PR to solve merge conflicts? Please follow the steps describe [here](https://elastic.slack.com/archives/C07TCKTA22E/p1734019532879269?thread_ts=1734019339.935419&cid=C07TCKTA22E). #### 12 plugin(s) are going to be relocated: | Id | Target folder | | -- | ------------- | | `@kbn/data-view-editor-plugin` | `src/platform/plugins/shared/data_view_editor` | | `@kbn/data-view-field-editor-plugin` | `src/platform/plugins/shared/data_view_field_editor` | | `@kbn/data-view-management-plugin` | `src/platform/plugins/shared/data_view_management` | | `@kbn/data-views-plugin` | `src/platform/plugins/shared/data_views` | | `@kbn/discover-enhanced-plugin` | `x-pack/platform/plugins/private/discover_enhanced` | | `@kbn/discover-plugin` | `src/platform/plugins/shared/discover` | | `@kbn/discover-shared-plugin` | `src/platform/plugins/shared/discover_shared` | | `@kbn/field-formats-plugin` | `src/platform/plugins/shared/field_formats` | | `@kbn/saved-objects-finder-plugin` | `src/platform/plugins/shared/saved_objects_finder` | | `@kbn/saved-search-plugin` | `src/platform/plugins/shared/saved_search` | | `@kbn/unified-doc-viewer-plugin` | `src/platform/plugins/shared/unified_doc_viewer` | | `@kbn/unified-histogram-plugin` | `src/platform/plugins/shared/unified_histogram` | #### 18 packages(s) are going to be relocated: | Id | Target folder | | -- | ------------- | | `@kbn/content-management-utils` | `src/platform/packages/shared/kbn-content-management-utils` | | `@kbn/data-view-utils` | `src/platform/packages/shared/kbn-data-view-utils` | | `@kbn/datemath` | `src/platform/packages/shared/kbn-datemath` | | `@kbn/deeplinks-analytics` | `src/platform/packages/shared/deeplinks/analytics` | | `@kbn/default-nav-analytics` | `src/platform/packages/private/default-nav/analytics` | | `@kbn/discover-utils` | `src/platform/packages/shared/kbn-discover-utils` | | `@kbn/es-query` | `src/platform/packages/shared/kbn-es-query` | | `@kbn/field-types` | `src/platform/packages/shared/kbn-field-types` | | `@kbn/field-utils` | `src/platform/packages/shared/kbn-field-utils` | | `@kbn/react-field` | `src/platform/packages/shared/kbn-react-field` | | `@kbn/resizable-layout` | `src/platform/packages/shared/kbn-resizable-layout` | | `@kbn/search-errors` | `src/platform/packages/shared/kbn-search-errors` | | `@kbn/search-response-warnings` | `src/platform/packages/shared/kbn-search-response-warnings` | | `@kbn/search-types` | `src/platform/packages/shared/kbn-search-types` | | `@kbn/unified-data-table` | `src/platform/packages/shared/kbn-unified-data-table` | | `@kbn/unified-doc-viewer` | `src/platform/packages/shared/kbn-unified-doc-viewer` | | `@kbn/unified-field-list` | `src/platform/packages/shared/kbn-unified-field-list` | | `@kbn/unsaved-changes-badge` | `src/platform/packages/private/kbn-unsaved-changes-badge` | <details > <summary>Updated references</summary> ``` ./.buildkite/scripts/steps/functional/scout_ui_tests.sh ./.eslintrc.js ./.i18nrc.json ./docs/developer/advanced/sharing-saved-objects.asciidoc ./docs/developer/architecture/core/saved-objects-service.asciidoc ./docs/developer/best-practices/navigation.asciidoc ./docs/developer/contributing/development-unit-tests.asciidoc ./docs/developer/plugin-list.asciidoc ./examples/unified_doc_viewer/README.md ./examples/unified_field_list_examples/public/plugin.ts ./legacy_rfcs/text/0015_bazel.md ./oas_docs/scripts/merge_ess_oas.js ./oas_docs/scripts/merge_serverless_oas.js ./package.json ./packages/kbn-repo-packages/package-map.json ./packages/kbn-synthetic-package-map/synthetic-packages.json ./packages/kbn-test/src/functional_tests/lib/babel_register_for_test_plugins.js ./packages/kbn-ts-projects/config-paths.json ./packages/kbn-ui-shared-deps-src/BUILD.bazel ./packages/kbn-unified-field-list/src/services/field_examples_calculator/field_examples_calculator.ts ./packages/shared-ux/prompt/no_data_views/types/index.d.ts ./src/dev/code_coverage/ingest_coverage/__tests__/mocks/team_assign_mock.txt ./src/dev/storybook/aliases.ts ./src/platform/packages/private/default-nav/analytics/jest.config.js ./src/platform/packages/private/kbn-unsaved-changes-badge/jest.config.js ./src/platform/packages/shared/deeplinks/analytics/jest.config.js ./src/platform/packages/shared/kbn-content-management-utils/jest.config.js ./src/platform/packages/shared/kbn-data-view-utils/jest.config.js ./src/platform/packages/shared/kbn-datemath/jest.config.js ./src/platform/packages/shared/kbn-discover-utils/jest.config.js ./src/platform/packages/shared/kbn-es-query/jest.config.js ./src/platform/packages/shared/kbn-field-types/jest.config.js ./src/platform/packages/shared/kbn-field-utils/jest.config.js ./src/platform/packages/shared/kbn-react-field/jest.config.js ./src/platform/packages/shared/kbn-resizable-layout/jest.config.js ./src/platform/packages/shared/kbn-search-errors/jest.config.js ./src/platform/packages/shared/kbn-search-response-warnings/jest.config.js ./src/platform/packages/shared/kbn-search-types/jest.config.js ./src/platform/packages/shared/kbn-unified-data-table/jest.config.js ./src/platform/packages/shared/kbn-unified-doc-viewer/jest.config.js ./src/platform/packages/shared/kbn-unified-field-list/jest.config.js ./src/platform/plugins/shared/data_view_editor/jest.config.js ./src/platform/plugins/shared/data_view_field_editor/jest.config.js ./src/platform/plugins/shared/data_view_management/jest.config.js ./src/platform/plugins/shared/data_views/jest.config.js ./src/platform/plugins/shared/discover/README.md ./src/platform/plugins/shared/discover/jest.config.js ./src/platform/plugins/shared/discover/public/context_awareness/README.md ./src/platform/plugins/shared/discover_shared/README.md ./src/platform/plugins/shared/discover_shared/jest.config.js ./src/platform/plugins/shared/field_formats/jest.config.js ./src/platform/plugins/shared/saved_objects_finder/jest.config.js ./src/platform/plugins/shared/saved_search/jest.config.js ./src/platform/plugins/shared/unified_doc_viewer/jest.config.js ./src/platform/plugins/shared/unified_histogram/jest.config.js ./tsconfig.base.json ./tsconfig.refs.json ./x-pack/.i18nrc.json ./x-pack/platform/plugins/private/discover_enhanced/jest.config.js ./x-pack/platform/plugins/private/discover_enhanced/ui_tests/README.md ./x-pack/solutions/security/plugins/timelines/common/search_strategy/index_fields/index.ts ./yarn.lock .github/CODEOWNERS ``` </details><details > <summary>Updated relative paths</summary> ``` src/platform/packages/private/default-nav/analytics/jest.config.js:12 src/platform/packages/private/default-nav/analytics/tsconfig.json:2 src/platform/packages/private/kbn-unsaved-changes-badge/jest.config.js:12 src/platform/packages/private/kbn-unsaved-changes-badge/tsconfig.json:2 src/platform/packages/shared/deeplinks/analytics/jest.config.js:12 src/platform/packages/shared/deeplinks/analytics/tsconfig.json:2 src/platform/packages/shared/kbn-content-management-utils/jest.config.js:12 src/platform/packages/shared/kbn-content-management-utils/tsconfig.json:2 src/platform/packages/shared/kbn-data-view-utils/jest.config.js:12 src/platform/packages/shared/kbn-data-view-utils/tsconfig.json:2 src/platform/packages/shared/kbn-datemath/jest.config.js:22 src/platform/packages/shared/kbn-datemath/tsconfig.json:2 src/platform/packages/shared/kbn-discover-utils/jest.config.js:12 src/platform/packages/shared/kbn-discover-utils/tsconfig.json:2 src/platform/packages/shared/kbn-es-query/jest.config.js:12 src/platform/packages/shared/kbn-es-query/tsconfig.json:2 src/platform/packages/shared/kbn-field-types/jest.config.js:12 src/platform/packages/shared/kbn-field-types/tsconfig.json:2 src/platform/packages/shared/kbn-field-utils/jest.config.js:12 src/platform/packages/shared/kbn-field-utils/tsconfig.json:2 src/platform/packages/shared/kbn-react-field/jest.config.js:12 src/platform/packages/shared/kbn-react-field/tsconfig.json:2 src/platform/packages/shared/kbn-resizable-layout/jest.config.js:12 src/platform/packages/shared/kbn-resizable-layout/tsconfig.json:2 src/platform/packages/shared/kbn-search-errors/jest.config.js:12 src/platform/packages/shared/kbn-search-errors/tsconfig.json:2 src/platform/packages/shared/kbn-search-response-warnings/jest.config.js:12 src/platform/packages/shared/kbn-search-response-warnings/tsconfig.json:2 src/platform/packages/shared/kbn-search-types/jest.config.js:12 src/platform/packages/shared/kbn-search-types/tsconfig.json:2 src/platform/packages/shared/kbn-unified-data-table/jest.config.js:12 src/platform/packages/shared/kbn-unified-data-table/tsconfig.json:2 src/platform/packages/shared/kbn-unified-doc-viewer/jest.config.js:12 src/platform/packages/shared/kbn-unified-doc-viewer/tsconfig.json:2 src/platform/packages/shared/kbn-unified-field-list/jest.config.js:12 src/platform/packages/shared/kbn-unified-field-list/tsconfig.json:2 src/platform/plugins/shared/data_view_editor/jest.config.js:12 src/platform/plugins/shared/data_view_editor/tsconfig.json:2 src/platform/plugins/shared/data_view_field_editor/jest.config.js:12 src/platform/plugins/shared/data_view_field_editor/tsconfig.json:2 src/platform/plugins/shared/data_view_field_editor/tsconfig.json:7 src/platform/plugins/shared/data_view_management/jest.config.js:12 src/platform/plugins/shared/data_view_management/tsconfig.json:2 src/platform/plugins/shared/data_views/jest.config.js:12 src/platform/plugins/shared/data_views/tsconfig.json:2 src/platform/plugins/shared/discover/jest.config.js:12 src/platform/plugins/shared/discover/public/application/context/context_app.scss:1 src/platform/plugins/shared/discover/public/application/main/components/layout/discover_layout.scss:1 src/platform/plugins/shared/discover/public/context_awareness/README.md:118 src/platform/plugins/shared/discover/public/context_awareness/README.md:119 src/platform/plugins/shared/discover/tsconfig.json:10 src/platform/plugins/shared/discover/tsconfig.json:2 src/platform/plugins/shared/discover_shared/jest.config.js:12 src/platform/plugins/shared/discover_shared/tsconfig.json:10 src/platform/plugins/shared/discover_shared/tsconfig.json:2 src/platform/plugins/shared/field_formats/jest.config.js:12 src/platform/plugins/shared/field_formats/tsconfig.json:2 src/platform/plugins/shared/saved_objects_finder/jest.config.js:12 src/platform/plugins/shared/saved_objects_finder/tsconfig.json:2 src/platform/plugins/shared/saved_search/jest.config.js:12 src/platform/plugins/shared/saved_search/tsconfig.json:2 src/platform/plugins/shared/saved_search/tsconfig.json:6 src/platform/plugins/shared/unified_doc_viewer/jest.config.js:12 src/platform/plugins/shared/unified_doc_viewer/tsconfig.json:2 src/platform/plugins/shared/unified_doc_viewer/tsconfig.json:6 src/platform/plugins/shared/unified_histogram/jest.config.js:12 src/platform/plugins/shared/unified_histogram/tsconfig.json:2 src/platform/plugins/shared/unified_histogram/tsconfig.json:6 x-pack/platform/plugins/private/discover_enhanced/jest.config.js:10 x-pack/platform/plugins/private/discover_enhanced/tsconfig.json:2 ``` </details> --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
493 lines
16 KiB
Text
493 lines
16 KiB
Text
[[saved-objects-service]]
|
||
== Saved Objects service
|
||
|
||
NOTE: The Saved Objects service is available both server and client side.
|
||
|
||
`Saved Objects service` allows {kib} plugins to use {es} like a primary
|
||
database. Think of it as an Object Document Mapper for {es}. Once a
|
||
plugin has registered one or more Saved Object types, the Saved Objects client
|
||
can be used to query or perform create, read, update and delete operations on
|
||
each type.
|
||
|
||
By using Saved Objects your plugin can take advantage of the following
|
||
features:
|
||
|
||
* Migrations can evolve your document's schema by transforming documents and
|
||
ensuring that the field mappings on the index are always up to date.
|
||
* a <<saved-objects-api,HTTP API>> is automatically exposed for each type (unless
|
||
`hidden=true` is specified).
|
||
* a Saved Objects client that can be used from both the server and the browser.
|
||
* Users can import or export Saved Objects using the Saved Objects management
|
||
UI or the Saved Objects import/export API.
|
||
* By declaring `references`, an object's entire reference graph will be
|
||
exported. This makes it easy for users to export e.g. a `dashboard` object and
|
||
have all the `visualization` objects required to display the dashboard
|
||
included in the export.
|
||
* When the X-Pack security and spaces plugins are enabled these transparently
|
||
provide RBAC access control and the ability to organize Saved Objects into
|
||
spaces.
|
||
|
||
This document contains developer guidelines and best-practices for plugins
|
||
wanting to use Saved Objects.
|
||
|
||
=== Server side usage
|
||
|
||
[[saved-objects-type-registration]]
|
||
==== Registering a Saved Object type
|
||
Saved object type definitions should be defined in their own `my_plugin/server/saved_objects` directory.
|
||
|
||
The folder should contain a file per type, named after the snake_case name of the type, and an `index.ts` file exporting all the types.
|
||
|
||
.src/plugins/my_plugin/server/saved_objects/dashboard_visualization.ts
|
||
[source,typescript]
|
||
----
|
||
import { SavedObjectsType } from 'src/core/server';
|
||
|
||
export const dashboardVisualization: SavedObjectsType = {
|
||
name: 'dashboard_visualization', // <1>
|
||
hidden: true,
|
||
namespaceType: 'multiple-isolated', // <2>
|
||
switchToModelVersionAt: '8.10.0',
|
||
modelVersions: {
|
||
1: modelVersion1,
|
||
2: modelVersion2,
|
||
},
|
||
mappings: {
|
||
dynamic: false,
|
||
properties: {
|
||
description: {
|
||
type: 'text',
|
||
},
|
||
hits: {
|
||
type: 'integer',
|
||
},
|
||
},
|
||
},
|
||
// ...other mandatory properties
|
||
};
|
||
----
|
||
<1> Since the name of a Saved Object type may form part of the URL path for the
|
||
public Saved Objects HTTP API, these should follow our API URL path convention
|
||
and always be written in snake case.
|
||
<2> This field determines "space behavior" -- whether these objects can exist in one space, multiple spaces, or all spaces. This value means
|
||
that objects of this type can only exist in a single space. See <<sharing-saved-objects,Sharing Saved Objects>> for more information.
|
||
|
||
.src/plugins/my_plugin/server/saved_objects/index.ts
|
||
[source,typescript]
|
||
----
|
||
export { dashboardVisualization } from './dashboard_visualization';
|
||
export { dashboard } from './dashboard';
|
||
----
|
||
|
||
.src/plugins/my_plugin/server/plugin.ts
|
||
[source,typescript]
|
||
----
|
||
import { dashboard, dashboardVisualization } from './saved_objects';
|
||
|
||
export class MyPlugin implements Plugin {
|
||
setup({ savedObjects }) {
|
||
savedObjects.registerType(dashboard);
|
||
savedObjects.registerType(dashboardVisualization);
|
||
}
|
||
}
|
||
----
|
||
|
||
==== Mappings
|
||
Each Saved Object type can define it's own {es} field mappings.
|
||
Because multiple Saved Object types can share the same index, mappings defined
|
||
by a type will be nested under a top-level field that matches the type name.
|
||
|
||
For example, the mappings defined by the `search` Saved
|
||
Object type:
|
||
|
||
https://github.com/elastic/kibana/blob/main/src/platform/plugins/shared/saved_search/server/saved_objects/search.ts#L19-L70[.src/platform/plugins/shared/saved_search/server/saved_objects/search.ts]
|
||
[source,typescript]
|
||
----
|
||
import { SavedObjectsType } from 'src/core/server';
|
||
// ... other imports
|
||
export function getSavedSearchObjectType: SavedObjectsType = { // <1>
|
||
name: 'search',
|
||
hidden: false,
|
||
namespaceType: 'multiple-isolated',
|
||
mappings: {
|
||
dynamic: false,
|
||
properties: {
|
||
title: { type: 'text' },
|
||
description: { type: 'text' },
|
||
},
|
||
},
|
||
modelVersions: { ... },
|
||
// ...other optional properties
|
||
};
|
||
----
|
||
<1> Simplification
|
||
|
||
Will result in the following mappings being applied to the `.kibana_analytics` index:
|
||
[source,json]
|
||
----
|
||
{
|
||
"mappings": {
|
||
"dynamic": "strict",
|
||
"properties": {
|
||
...
|
||
"search": {
|
||
"dynamic": false,
|
||
"properties": {
|
||
"title": {
|
||
"type": "text",
|
||
},
|
||
"description": {
|
||
"type": "text",
|
||
},
|
||
},
|
||
}
|
||
}
|
||
}
|
||
}
|
||
----
|
||
|
||
Do not use field mappings like you would use data types for the columns of a
|
||
SQL database. Instead, field mappings are analogous to a SQL index. Only
|
||
specify field mappings for the fields you wish to search on or query. By
|
||
specifying `dynamic: false` in any level of your mappings, {es} will
|
||
accept and store any other fields even if they are not specified in your mappings.
|
||
|
||
Since {es} has a default limit of 1000 fields per index, plugins
|
||
should carefully consider the fields they add to the mappings. Similarly,
|
||
Saved Object types should never use `dynamic: true` as this can cause an
|
||
arbitrary amount of fields to be added to the `.kibana` index.
|
||
|
||
[[saved-objects-service-writing-migrations]]
|
||
==== Writing Migrations by defining model versions
|
||
|
||
Saved Objects support changes using `modelVersions``. The modelVersion API is a new way to define transformations
|
||
(_``migrations''_) for your savedObject types, and will replace the
|
||
``legacy'' migration API after Kibana version `8.10.0`. The legacy migration API has been deprecated, meaning it is no longer possible to register migrations using the legacy system.
|
||
|
||
Model versions are decoupled from the stack version and satisfy the requirements for zero downtime and backward-compatibility.
|
||
|
||
Each Saved Object type may define model versions for its schema and are bound to a given https://github.com/elastic/kibana/blob/9b330e493216e8dde3166451e4714966f63f5ab7/packages/core/saved-objects/core-saved-objects-server/src/saved_objects_type.ts#L22-L27[savedObject type]. Changes to a saved object type are
|
||
specified by defining a new model.
|
||
|
||
=== Defining model versions
|
||
|
||
As for old migrations, model versions are bound to a given
|
||
https://github.com/elastic/kibana/blob/9b330e493216e8dde3166451e4714966f63f5ab7/packages/core/saved-objects/core-saved-objects-server/src/saved_objects_type.ts#L22-L27[savedObject
|
||
type]
|
||
|
||
When registering a SO type, a new
|
||
https://github.com/elastic/kibana/blob/9a6a2ccdff619f827b31c40dd9ed30cb27203da7/packages/core/saved-objects/core-saved-objects-server/src/saved_objects_type.ts#L138-L177[modelVersions]
|
||
property is available. This attribute is a map of
|
||
https://github.com/elastic/kibana/blob/9a6a2ccdff619f827b31c40dd9ed30cb27203da7/packages/core/saved-objects/core-saved-objects-server/src/model_version/model_version.ts#L12-L20[SavedObjectsModelVersion]
|
||
which is the top-level type/container to define model versions.
|
||
|
||
This map follows a similar `{ [version number] => version definition }`
|
||
format as the old migration map, however a given SO type’s model version
|
||
is now identified by a single integer.
|
||
|
||
The first version must be numbered as version 1, incrementing by one for
|
||
each new version.
|
||
|
||
That way: - SO type versions are decoupled from stack versioning - SO
|
||
type versions are independent between types
|
||
|
||
_a *valid* version numbering:_
|
||
|
||
[source,ts]
|
||
----
|
||
const myType: SavedObjectsType = {
|
||
name: 'test',
|
||
switchToModelVersionAt: '8.10.0',
|
||
modelVersions: {
|
||
1: modelVersion1, // valid: start with version 1
|
||
2: modelVersion2, // valid: no gap between versions
|
||
},
|
||
// ...other mandatory properties
|
||
};
|
||
----
|
||
|
||
_an *invalid* version numbering:_
|
||
|
||
[source,ts]
|
||
----
|
||
const myType: SavedObjectsType = {
|
||
name: 'test',
|
||
switchToModelVersionAt: '8.10.0',
|
||
modelVersions: {
|
||
2: modelVersion2, // invalid: first version must be 1
|
||
4: modelVersion3, // invalid: skipped version 3
|
||
},
|
||
// ...other mandatory properties
|
||
};
|
||
----
|
||
|
||
=== Structure of a model version
|
||
|
||
https://github.com/elastic/kibana/blob/9b330e493216e8dde3166451e4714966f63f5ab7/packages/core/saved-objects/core-saved-objects-server/src/model_version/model_version.ts#L12-L20[Model
|
||
versions] are not just functions as the previous migrations were, but
|
||
structured objects describing how the version behaves and what changed
|
||
since the last one.
|
||
|
||
_A base example of what a model version can look like:_
|
||
|
||
[source,ts]
|
||
----
|
||
const myType: SavedObjectsType = {
|
||
name: 'test',
|
||
switchToModelVersionAt: '8.10.0',
|
||
modelVersions: {
|
||
1: {
|
||
changes: [
|
||
{
|
||
type: 'mappings_addition',
|
||
addedMappings: {
|
||
someNewField: { type: 'text' },
|
||
},
|
||
},
|
||
{
|
||
type: 'data_backfill',
|
||
transform: someBackfillFunction,
|
||
},
|
||
],
|
||
schemas: {
|
||
forwardCompatibility: fcSchema,
|
||
create: createSchema,
|
||
},
|
||
},
|
||
},
|
||
// ...other mandatory properties
|
||
};
|
||
----
|
||
|
||
*Note:* Having multiple changes of the same type for a given version is
|
||
supported by design to allow merging different sources (to prepare for
|
||
an eventual higher-level API)
|
||
|
||
_This definition would be perfectly valid:_
|
||
|
||
[source,ts]
|
||
----
|
||
const version1: SavedObjectsModelVersion = {
|
||
changes: [
|
||
{
|
||
type: 'mappings_addition',
|
||
addedMappings: {
|
||
someNewField: { type: 'text' },
|
||
},
|
||
},
|
||
{
|
||
type: 'mappings_addition',
|
||
addedMappings: {
|
||
anotherNewField: { type: 'text' },
|
||
},
|
||
},
|
||
],
|
||
};
|
||
----
|
||
|
||
It’s currently composed of two main properties:
|
||
|
||
==== changes
|
||
|
||
https://github.com/elastic/kibana/blob/9b330e493216e8dde3166451e4714966f63f5ab7/packages/core/saved-objects/core-saved-objects-server/src/model_version/model_version.ts#L21-L51[link
|
||
to the TS doc for `changes`]
|
||
|
||
Describes the list of changes applied during this version.
|
||
|
||
*Important:* This is the part that replaces the old migration system,
|
||
and allows defining when a version adds new mapping, mutates the
|
||
documents, or other type-related changes.
|
||
|
||
The current types of changes are:
|
||
|
||
===== - mappings_addition
|
||
|
||
Used to define new mappings introduced in a given version.
|
||
|
||
_Usage example:_
|
||
|
||
[source,ts]
|
||
----
|
||
const change: SavedObjectsModelMappingsAdditionChange = {
|
||
type: 'mappings_addition',
|
||
addedMappings: {
|
||
newField: { type: 'text' },
|
||
existingNestedField: {
|
||
properties: {
|
||
newNestedProp: { type: 'keyword' },
|
||
},
|
||
},
|
||
},
|
||
};
|
||
----
|
||
|
||
*note:* _When adding mappings, the root `type.mappings` must also be
|
||
updated accordingly (as it was done previously)._
|
||
|
||
===== - mappings_deprecation
|
||
|
||
Used to flag mappings as no longer being used and ready to be removed.
|
||
|
||
_Usage example:_
|
||
|
||
[source,ts]
|
||
----
|
||
let change: SavedObjectsModelMappingsDeprecationChange = {
|
||
type: 'mappings_deprecation',
|
||
deprecatedMappings: ['someDeprecatedField', 'someNested.deprecatedField'],
|
||
};
|
||
----
|
||
|
||
*note:* _It is currently not possible to remove fields from an existing
|
||
index’s mapping (without reindexing into another index), so the mappings
|
||
flagged with this change type won’t be deleted for now, but this should
|
||
still be used to allow our system to clean the mappings once upstream
|
||
(ES) unblock us._
|
||
|
||
===== - data_backfill
|
||
|
||
Used to populate fields (indexed or not) added in the same version.
|
||
|
||
_Usage example:_
|
||
|
||
[source,ts]
|
||
----
|
||
let change: SavedObjectsModelDataBackfillChange = {
|
||
type: 'data_backfill',
|
||
transform: (document) => {
|
||
return { attributes: { someAddedField: 'defaultValue' } };
|
||
},
|
||
};
|
||
----
|
||
|
||
*note:* _Even if no check is performed to ensure it, this type of model
|
||
change should only be used to backfill newly introduced fields._
|
||
|
||
===== - data_removal
|
||
|
||
Used to remove data (unset fields) from all documents of the type.
|
||
|
||
_Usage example:_
|
||
|
||
[source,ts]
|
||
----
|
||
let change: SavedObjectsModelDataRemovalChange = {
|
||
type: 'data_removal',
|
||
attributePaths: ['someRootAttributes', 'some.nested.attribute'],
|
||
};
|
||
----
|
||
|
||
*note:* _Due to backward compatibility, field utilization must be
|
||
stopped in a prior release before actual data removal (in case of
|
||
rollback). Please refer to the field removal migration example below in
|
||
this document_
|
||
|
||
===== - unsafe_transform
|
||
|
||
Used to execute an arbitrary transformation function.
|
||
|
||
_Usage example:_
|
||
|
||
[source,ts]
|
||
----
|
||
let change: SavedObjectsModelUnsafeTransformChange = {
|
||
type: 'unsafe_transform',
|
||
transformFn: (document) => {
|
||
document.attributes.someAddedField = 'defaultValue';
|
||
return { document };
|
||
},
|
||
};
|
||
----
|
||
|
||
*note:* _Using such transformations is potentially unsafe, given the
|
||
migration system will have no knowledge of which kind of operations will
|
||
effectively be executed against the documents. Those should only be used
|
||
when there’s no other way to cover one’s migration needs._ *Please reach
|
||
out to the development team if you think you need to use this, as you
|
||
theoretically shouldn’t.*
|
||
|
||
==== schemas
|
||
|
||
https://github.com/elastic/kibana/blob/9b330e493216e8dde3166451e4714966f63f5ab7/packages/core/saved-objects/core-saved-objects-server/src/model_version/schemas.ts#L11-L16[link
|
||
to the TS doc for `schemas`]
|
||
|
||
The schemas associated with this version. Schemas are used to validate
|
||
or convert SO documents at various stages of their lifecycle.
|
||
|
||
The currently available schemas are:
|
||
|
||
===== forwardCompatibility
|
||
|
||
This is a new concept introduced by model versions. This schema is used
|
||
for inter-version compatibility.
|
||
|
||
When retrieving a savedObject document from an index, if the version of
|
||
the document is higher than the latest version known of the Kibana
|
||
instance, the document will go through the `forwardCompatibility` schema
|
||
of the associated model version.
|
||
|
||
*Important:* These conversion mechanism shouldn’t assert the data
|
||
itself, and only strip unknown fields to convert the document to the
|
||
*shape* of the document at the given version.
|
||
|
||
Basically, this schema should keep all the known fields of a given
|
||
version, and remove all the unknown fields, without throwing.
|
||
|
||
Forward compatibility schema can be implemented in two different ways.
|
||
|
||
[arabic]
|
||
. Using `config-schema`
|
||
|
||
_Example of schema for a version having two fields: someField and
|
||
anotherField_
|
||
|
||
[source,ts]
|
||
----
|
||
const versionSchema = schema.object(
|
||
{
|
||
someField: schema.maybe(schema.string()),
|
||
anotherField: schema.maybe(schema.string()),
|
||
},
|
||
{ unknowns: 'ignore' }
|
||
);
|
||
----
|
||
|
||
*Important:* Note the `{ unknowns: 'ignore' }` in the schema’s options.
|
||
This is required when using `config-schema` based schemas, as this what
|
||
will evict the additional fields without throwing an error.
|
||
|
||
[arabic, start=2]
|
||
. Using a plain javascript function
|
||
|
||
_Example of schema for a version having two fields: someField and
|
||
anotherField_
|
||
|
||
[source,ts]
|
||
----
|
||
const versionSchema: SavedObjectModelVersionEvictionFn = (attributes) => {
|
||
const knownFields = ['someField', 'anotherField'];
|
||
return pick(attributes, knownFields);
|
||
}
|
||
----
|
||
|
||
*note:* _Even if highly recommended, implementing this schema is not
|
||
strictly required. Type owners can manage unknown fields and
|
||
inter-version compatibility themselves in their service layer instead._
|
||
|
||
===== create
|
||
|
||
This is a direct replacement for
|
||
https://github.com/elastic/kibana/blob/9b330e493216e8dde3166451e4714966f63f5ab7/packages/core/saved-objects/core-saved-objects-server/src/saved_objects_type.ts#L75-L82[the
|
||
old SavedObjectType.schemas] definition, now directly included in the
|
||
model version definition.
|
||
|
||
As a refresher the `create` schema is a `@kbn/config-schema` object-type
|
||
schema, and is used to validate the properties of the document during
|
||
`create` and `bulkCreate` operations.
|
||
|
||
*note:* _Implementing this schema is optional, but still recommended, as
|
||
otherwise there will be no validating when importing objects_
|
||
|
||
For implementation examples, refer to <<saved-objects-service-use-case-examples, Use case examples>>.
|
||
|
||
include::saved-objects-service-use-case-examples.asciidoc[leveloffset=+1]
|