Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
jportner committed Jul 29, 2021
1 parent 8b34af9 commit 69a8983
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 1 deletion.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion docs/developer/advanced/index.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
* <<development-es-snapshots>>
* <<development-basepath>>
* <<upgrading-nodejs>>
* <<sharing-saved-objects>>

include::development-es-snapshots.asciidoc[leveloffset=+1]

include::running-elasticsearch.asciidoc[leveloffset=+1]

include::development-basepath.asciidoc[leveloffset=+1]

include::upgrading-nodejs.asciidoc[leveloffset=+1]
include::upgrading-nodejs.asciidoc[leveloffset=+1]

include::sharing-saved-objects.asciidoc[leveloffset=+1]
165 changes: 165 additions & 0 deletions docs/developer/advanced/sharing-saved-objects.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
[[sharing-saved-objects]]
== Sharing Saved Objects

This guide describes the Sharing Saved Objects effort, and the breaking changes that plugin developers need to be aware of for the planned
8.0 release of {kib}.

[[sharing-saved-objects-overview]]
=== Overview

<<saved-objects-service, Saved objects>> (hereinafter "objects") are used to store all sorts of things in {kib}, from Dashboards to Index
Patterns to Machine Learning Jobs. The effort to make objects shareable can be summarized in a single picture:

image::images/sharing-saved-objects-overview.png["Sharing Saved Objects overview"]

Each plugin can register different object types to be used in {kib}. Historically, objects could be _isolated_ (existing in a single
<<xpack-spaces, space>>) or _global_ (existing in all spaces), there was no in-between. As of the 7.12 release, {kib} now supports two
additional types of objects:

|======================================================================================================
| | *Where it exists* | *Object IDs* | *Registered as:*
| Global | All spaces | Globally unique | `namespaceType: 'agnostic'`
| Isolated | 1 space | Unique in each space | `namespaceType: 'single'`
| (NEW) Share-capable | 1 space | Globally unique | `namespaceType: 'multiple-isolated'`
| (NEW) Shareable | 1 or more spaces | Globally unique | `namespaceType: 'multiple'`
|======================================================================================================

Ideally, most types of objects in {kib} will eventually be _shareable_; however, we have also introduced _share-capable_ objects as a
stepping stone for plugin developers to fully support this feature.

[[sharing-saved-objects-breaking-changes]]
=== Breaking changes

To implement this feature, we had to make a key change to how objects are serialized into raw {es} documents. As a result, this caused some
breaking changes to the way that consumers (plugin developers) interact with objects. We have implemented mitigations so that *these changes
will not affect end-users _if_ consumers implement the required steps.*

Existing, isolated object types will need to go through a special _conversion process_ to become share-capable upon upgrading {kib} to
version 8.0. Once objects are converted, they can easily be switched to become fully shareable in any future release. This conversion will
change the IDs of any existing objects that are not in the Default space. Changing object IDs itself has several knock-on effects:

* "Deep link" pages (URLs) to objects will break
* Nonstandard links to other objects can break
* Encrypted objects will not be able to be decrypted

*To be perfectly clear: these effects will all be mitigated _if and only if_ you follow the steps below!*

[[sharing-saved-objects-dev-flowchart]]
=== Developer Flowchart

If you're still reading this page, you're probably developing a {kib} plugin that registers an object type, and you want to know what steps
you need to take to prepare for the 8.0 release and mitigate any breaking changes! Depending on how you are using saved objects, you may
need to take up to 5 steps, which are detailed in separate sections below. Refer to this flowchart:

image::images/sharing-saved-objects-dev-flowchart.png["Sharing Saved Objects developer flowchart"]

[[sharing-saved-objects-q1]]
=== Question 1

> *Do these objects contain links to other objects?*

If your objects store _any_ links to other objects (with an object type/ID), you need to take specific steps to ensure that these links continue functioning after the 8.0 upgrade.

[[sharing-saved-objects-step-1]]
=== Step 1

> *Ensure all object links use the root-level `references` field*

If you answered "Yes" to <<sharing-saved-objects-dev-q1>> above, you need to make sure that your object links are _only_ stored in the root-level `references` field. When a given object's ID is changed, this field will be updated accordingly for other objects.

The image below shows two different examples of object links from a "case" object to an "action" object. The top shows the incorrect way to link to another object, and the bottom shows the correct way.

image::images/sharing-saved-objects-step-1.png["Sharing Saved Objects step 1"]

If your objects _do not_ use the root-level `references` field, you'll need to <<saved-objects-service-writing-migrations,add a migration>> _before the 8.0 release_ to fix that. Here's a migration function for the example above:

```ts
function migrateCaseToV716(
doc: SavedObjectUnsanitizedDoc<{ connector: { type: string; id: string } }>
): SavedObjectSanitizedDoc<unknown> {
const {
connector: { type: connectorType, id: connectorId, ...otherConnectorAttrs },
} = doc.attributes;
const { references = [] } = doc;
return {
...doc,
attributes: {
...doc.attributes,
connector: otherConnectorAttrs,
},
references: [...references, { type: connectorType, id: connectorId, name: 'connector' }],
};
}

...

// Use this migration function where the "case" object type is registered
migrations: {
'7.16.0': migrateCaseToV716,
},
```

NOTE: Reminder, don't forget to add unit tests and integration tests!

[[sharing-saved-objects-q2]]
=== Question 2

> *Are there any "deep links" to these objects?*

A deep link is a URL to a page that shows a specific object. End-users may bookmark these URLs or schedule reports with them, so it is
critical to ensure that these URLs continue working. The image below shows an example of a deep link.

image::images/sharing-saved-objects-q2.png["Sharing Saved Objects deep link example"]

[[sharing-saved-objects-step-2]]
=== Step 2

> *Update your code to use the new SavedObjectsClient `resolve()` method instead of `get()`*

If you answered "Yes" to <<sharing-saved-objects-dev-q2>> above, you need to make sure that when you use the SavedObjectsClient to fetch an
object using its ID, you use a different API to do so. The existing `get()` function will only find an object using its current ID. To make
sure your existing deep link URLs don't break, you should use the new `resolve()` function; this attempts to find an object using its old ID
_and_ its current ID.

If you had something like this before:

```ts
const savedObject = savedObjectsClient.get(objType, objId);
```

You'll need to change it to this:

```ts
const { savedObject, outcome, aliasTargetId } = savedObjectsClient.resolve(objType, objId);
```

The type definition can be found here: https://github.com/elastic/kibana/blob/master/docs/development/core/public/kibana-plugin-core-public.savedobjectsresolveresponse.md

You may be fetching the object on the server-side via a custom HTTP route, or you may be fetching it on the client-side directly. Either
way, the `outcome` and `aliasTargetId` fields need to be passed to your client-side code, and you should update your UI accordingly in the
next step.

NOTE: Reminder, don't forget to add unit tests and integration tests!

[[sharing-saved-objects-step-3]]
=== Step 3

> *Update your _client-side code_ to correctly handle the three different `resolve()` outcomes*

The Spaces plugin API exposes React components and functions that you should use to render your UI in a consistent manner for end-users.
First, you need to make sure your plugin has an optional dependency on the Spaces plugin.

Update your plugin's `kibana.json`:
```diff
```

Note that it is possible for one URL to contain deep links to multiple objects! This can happen when using Dashboards and Index Patterns,
for instance.


TIP: See the https://github.com/elastic/kibana/pull/95958/commits/afc34903624f169c6dc98313a6b2e299affc643f[proof-of-concept (commit `afc3490`)] for an example of how this is done for index patterns!

NOTE: Reminder, don't forget to add unit tests and functional tests!

[[sharing-saved-objects-faq]]
=== Frequently asked questions
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ 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

Saved Objects support schema changes between Kibana versions, which we call
Expand Down

0 comments on commit 69a8983

Please sign in to comment.