Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow savedObjects types registration from NP #57430

Merged

Conversation

pgayvallet
Copy link
Contributor

@pgayvallet pgayvallet commented Feb 12, 2020

Summary

This PR officially makes the registerType API introduced in #55857 a public one, and allow plugins to register savedObjects types from the new platform.

PR does the following:

  • move the registerType SO setup API from internal to public
  • expose a new getTypeRegistry API to the SO start contract to allow plugin to get informations on the registered types (this was a need for a least security)
  • change the SavedObjectMigrationFn signature to have a context object as second parameter instead of only a logger. This context only exposes the logger atm, but makes any futur addition now way easier (thanks to @restrry for the suggestion). Legacy migration methods are wrapped to continue passing the logger as the second parameter to ensure BWC.
  • improve documentation on some SO types

Requires #56971 to be merged.

Fix #50313, #50311, #50309

Checklist

For maintainers

Dev Docs

A new registerType API has been added to the core savedObjects setup API, allowing to register savedObject types from new platform plugins

// src/plugins/my_plugin/server/saved_objects/types.ts
import { SavedObjectsType } from 'src/core/server';
import * as migrations from './migrations';

export const myType: SavedObjectsType = {
  name: 'MyType',
  hidden: false,
  namespaceAgnostic: true,
  mappings: {
    properties: {
      textField: {
        type: 'text',
      },
      boolField: {
        type: 'boolean',
      },
    },
  },
  migrations: {
    '2.0.0': migrations.migrateToV2,
    '2.1.0': migrations.migrateToV2_1
  },
};

// src/plugins/my_plugin/server/plugin.ts
import { SavedObjectsClient, CoreSetup } from 'src/core/server';
import { myType } from './saved_objects';

export class Plugin() {
  setup: (core: CoreSetup) => {
    core.savedObjects.registerType(myType);
  }
}

Please check the migration guide for more complete examples and migration procedure.

@pgayvallet pgayvallet added Feature:New Platform release_note:plugin_api_changes Contains a Plugin API changes section for the breaking plugin API changes section. Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v7.7.0 v8.0.0 labels Feb 12, 2020
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-platform (Team:Platform)

@pgayvallet pgayvallet marked this pull request as ready for review February 12, 2020 10:22
@pgayvallet pgayvallet requested a review from a team as a code owner February 12, 2020 10:22
Comment on lines -55 to -66
* Note: The Saved Object setup API's should only be used for creating and
* registering client wrappers. Constructing a Saved Objects client or
* repository for use within your own plugin won't have any of the registered
* wrappers applied and is considered an anti-pattern. Use the Saved Objects
* client from the
* {@link SavedObjectsServiceStart | SavedObjectsServiceStart#getScopedClient }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed outdated comment, as it's no longer possible to create clients or repository from the setup contract

Comment on lines 33 to 38
/**
* Registry holding information about all the registered {@link SavedObjectsType | savedObject types}.
*
* @internal
* @public
*/
export class SavedObjectTypeRegistry {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was 'forced' to expose this class as public to get proper doc generation for the associated ISavedObjectTypeRegistry interface. I'm starting to wonder if we really should use Pick-based interface when exposing public interfaces from internal implementations...

@@ -4,7 +4,7 @@

## SavedObjectsServiceSetup interface

Saved Objects is Kibana's data persistence mechanism allowing plugins to use Elasticsearch for storing and querying state. The SavedObjectsServiceSetup API exposes methods for creating and registering Saved Object client wrappers.
Saved Objects is Kibana's data persistence mechanism allowing plugins to use Elasticsearch for storing and querying state. The SavedObjectsServiceSetup API exposes methods for registering Saved Object types and creating and registering Saved Object client wrappers and factories
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SavedObjectsServiceSetup API exposes methods for registering Saved Object types, creating and registering Saved Object client wrappers and factories. 🤔 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be indeed better 😄


### Changes in structure compared to legacy

The NP `registerType` expected input is very close to the legacy format, However there are some minor changes:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The NP `registerType` expected input is very close to the legacy format, However there are some minor changes:
The NP `registerType` expected input is very close to the legacy format. However, there are some minor changes:

*
* @example
* ```ts
* // src/plugins/my_plugin/server/saved_objects/types.ts
Copy link
Contributor

@mshustov mshustov Feb 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a convention to place SO definition under the saved_objects folder? I can't see it in https://github.com/elastic/kibana/blob/ec31611911c8d7630d61361f6aa22d57f86a964f/src/core/CONVENTIONS.md Probably we should add one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should. Added a section and updated the example folder structure

expect(Object.keys(converted[1]!.migrations!)).toEqual(Object.keys(migrationsB));
});

it('migrates the migration to the new format', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
it('migrates the migration to the new format', () => {
it('converts the migration to the new format', () => {

@pgayvallet
Copy link
Contributor Author

retest

@jportner
Copy link
Contributor

From an offline discussion:

It would be great if we can expose the type registry (or just the getters) in the SavedObjectsClientWrapperOptions. Then this PR would resolve #58414.

Copy link
Contributor

@rudolf rudolf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some documentation nits, but otherwise 👍

@@ -4,10 +4,26 @@

## SavedObjectMigrationFn type

A migration function defined for a [saved objects type](./kibana-plugin-server.savedobjectstype.md) used to migrate it's
A migration function defined for a [saved objects type](./kibana-plugin-server.savedobjectstype.md) used to migrate it's to a given version
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
A migration function defined for a [saved objects type](./kibana-plugin-server.savedobjectstype.md) used to migrate it's to a given version
A migration function for a [saved object type](./kibana-plugin-server.savedobjectstype.md) used to migrate it to a given version


## Saved Objects types

In the legacy platform, saved object types were registered using static definitions in `uiExports` part
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In the legacy platform, saved object types were registered using static definitions in `uiExports` part
In the legacy platform, saved object types were registered using static definitions in the `uiExports` part of

- The `schema.indexPattern` was accepting either a `string` or a `(config: LegacyConfig) => string`. `SavedObjectsType.indexPattern` only accepts a string, as you can access the configuration during your plugin's setup phase.

- The migration function signature has changed:
In legacy, is was `(doc: SavedObjectUnsanitizedDoc, log: SavedObjectsMigrationLogger) => SavedObjectUnsanitizedDoc;`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In legacy, is was `(doc: SavedObjectUnsanitizedDoc, log: SavedObjectsMigrationLogger) => SavedObjectUnsanitizedDoc;`
In legacy, it was `(doc: SavedObjectUnsanitizedDoc, log: SavedObjectsMigrationLogger) => SavedObjectUnsanitizedDoc;`

* try {
* doc.attributes.someProp = migrateProperty(doc.attributes.someProp);
* } catch(e) {
* log.warn('Error migrating `someProp`');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catching migration exceptions is a common pattern in existing migrations but I think it's something we should discourage. It effectively causes a bug in some unknown place higher up in the stack when this object is eventually used. Also when we introduce "invalid" saved objects we want the migration system to catch and handle these migration exceptions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was mostly to demonstrate a use of the log context property. I will remove the try/catch and add another dummy check instead

*
* @example
* ```ts
* // src/plugins/my_plugin/server/saved_objects/types.ts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* // src/plugins/my_plugin/server/saved_objects/types.ts
* // src/plugins/my_plugin/server/saved_objects/my_type.ts

First type:

```typescript
// src/plugins/my-plugin/server/saved_objects/first_type.ts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// src/plugins/my-plugin/server/saved_objects/first_type.ts
// src/plugins/my_plugin/server/saved_objects/first_type.ts

```

```js
// src/legacy/core_plugins/my-plugin/migrations.js
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// src/legacy/core_plugins/my-plugin/migrations.js
// src/legacy/core_plugins/my_plugin/migrations.js

```

```json
// src/legacy/core_plugins/my-plugin/mappings.json
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// src/legacy/core_plugins/my-plugin/mappings.json
// src/legacy/core_plugins/my_plugin/mappings.json

Let say we have the following in a legacy plugin:

```js
// src/legacy/core_plugins/my-plugin/index.js
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// src/legacy/core_plugins/my-plugin/index.js
// src/legacy/core_plugins/my_plugin/index.js

Second type:

```typescript
// src/plugins/my-plugin/server/saved_objects/second_type.ts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// src/plugins/my-plugin/server/saved_objects/second_type.ts
// src/plugins/my_plugin/server/saved_objects/second_type.ts

Copy link
Contributor

@rudolf rudolf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more nits (unfortunately I couldn't always make suggestions on the source code)


## SavedObjectTypeRegistry class

Registry holding information about all the registered [savedObject types](./kibana-plugin-server.savedobjectstype.md)<!-- -->.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Registry holding information about all the registered [savedObject types](./kibana-plugin-server.savedobjectstype.md)<!-- -->.
Registry holding information about all the registered [saved object types](./kibana-plugin-server.savedobjectstype.md)<!-- -->.

@@ -158,6 +203,11 @@ export interface SavedObjectsServiceStart {
* Creates a {@link SavedObjectsSerializer | serializer} that is aware of all registered types.
*/
createSerializer: () => SavedObjectsSerializer;
/**
* Returns the {@link ISavedObjectTypeRegistry | registry} containing all registered
* {@link SavedObjectsType | savedObject types}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* {@link SavedObjectsType | savedObject types}
* {@link SavedObjectsType | saved object types}

@@ -27,6 +27,7 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [SavedObjectsErrorHelpers](./kibana-plugin-server.savedobjectserrorhelpers.md) | |
| [SavedObjectsRepository](./kibana-plugin-server.savedobjectsrepository.md) | |
| [SavedObjectsSerializer](./kibana-plugin-server.savedobjectsserializer.md) | A serializer that can be used to manually convert [raw](./kibana-plugin-server.savedobjectsrawdoc.md) or [sanitized](./kibana-plugin-server.savedobjectsanitizeddoc.md) documents to the other kind. |
| [SavedObjectTypeRegistry](./kibana-plugin-server.savedobjecttyperegistry.md) | Registry holding information about all the registered [savedObject types](./kibana-plugin-server.savedobjectstype.md)<!-- -->. |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| [SavedObjectTypeRegistry](./kibana-plugin-server.savedobjecttyperegistry.md) | Registry holding information about all the registered [savedObject types](./kibana-plugin-server.savedobjectstype.md)<!-- -->. |
| [SavedObjectTypeRegistry](./kibana-plugin-server.savedobjecttyperegistry.md) | Registry holding information about all the registered [saved object types](./kibana-plugin-server.savedobjectstype.md)<!-- -->. |

@pgayvallet
Copy link
Contributor Author

@jportner Added in 18f5c05, tell me if that looks alright to you

@jportner
Copy link
Contributor

@jportner Added in 18f5c05, tell me if that looks alright to you

Beautiful!

@jportner jportner linked an issue Feb 25, 2020 that may be closed by this pull request
@kibanamachine
Copy link
Contributor

💚 Build Succeeded

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@pgayvallet pgayvallet merged commit 8524303 into elastic:master Feb 26, 2020
pgayvallet added a commit to pgayvallet/kibana that referenced this pull request Feb 26, 2020
* expose `registerType` API

* expose `getTypeRegistry` API

* change SavedObjectMigrationFn signature to add context

* fix exported types

* update generated doc

* update migration documentation

* fix legacy service test

* fix typings

* update service setup description

* add saved_objects server folder convention

* fix unit test

* documentation NITs

* add typeRegistry to SavedObjectClientWrapperOptions
pgayvallet added a commit that referenced this pull request Feb 26, 2020
* expose `registerType` API

* expose `getTypeRegistry` API

* change SavedObjectMigrationFn signature to add context

* fix exported types

* update generated doc

* update migration documentation

* fix legacy service test

* fix typings

* update service setup description

* add saved_objects server folder convention

* fix unit test

* documentation NITs

* add typeRegistry to SavedObjectClientWrapperOptions
@spong spong mentioned this pull request Mar 3, 2020
26 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:New Platform release_note:plugin_api_changes Contains a Plugin API changes section for the breaking plugin API changes section. Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v7.7.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Expose getters for SavedObjectTypeRegistry type definitions [Platform] SavedObject Schemas
6 participants