Skip to content

Commit

Permalink
Merge branch 'master' into execution-context-discover-vega
Browse files Browse the repository at this point in the history
  • Loading branch information
mshustov committed Aug 12, 2021
2 parents 5674e05 + 1eae08e commit 2a3113f
Show file tree
Hide file tree
Showing 1,293 changed files with 23,718 additions and 14,580 deletions.
3 changes: 3 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,17 @@

# Maps
#CC# /x-pack/plugins/maps/ @elastic/kibana-gis
/x-pack/plugins/maps/ @elastic/kibana-gis
/x-pack/test/api_integration/apis/maps/ @elastic/kibana-gis
/x-pack/test/functional/apps/maps/ @elastic/kibana-gis
/x-pack/test/functional/es_archives/maps/ @elastic/kibana-gis
/x-pack/test/visual_regression/tests/maps/index.js @elastic/kibana-gis
/x-pack/plugins/stack_alerts/server/alert_types/geo_containment @elastic/kibana-gis
/x-pack/plugins/stack_alerts/public/alert_types/geo_containment @elastic/kibana-gis
#CC# /src/plugins/maps_legacy/ @elastic/kibana-gis
/src/plugins/maps_legacy/ @elastic/kibana-gis
#CC# /x-pack/plugins/file_upload @elastic/kibana-gis
/x-pack/plugins/file_upload @elastic/kibana-gis
/src/plugins/tile_map/ @elastic/kibana-gis
/src/plugins/region_map/ @elastic/kibana-gis
/packages/kbn-mapbox-gl @elastic/kibana-gis
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ report.asciidoc
# TS incremental build cache
*.tsbuildinfo

# Automatically generated and user-modifiable
/tsconfig.refs.json

# Yarn local mirror content
.yarn-local-mirror

Expand Down
2 changes: 2 additions & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
exports_files(
[
"tsconfig.base.json",
"tsconfig.bazel.json",
"tsconfig.browser.json",
"tsconfig.browser_bazel.json",
"tsconfig.json",
"package.json"
],
Expand Down
14 changes: 14 additions & 0 deletions dev_docs/key_concepts/saved_objects.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,17 @@ Sometimes Saved Objects end up persisted inside another Saved Object. We call th
issues with edits propagating - since an entity can only exist in a single place.
Note that from the end user stand point, we don’t use these terms “by reference” and “by value”.

## Sharing Saved Objects

Starting in Kibana 7.12, saved objects can be shared to multiple spaces. The "space behavior" is determined for each object type depending
on how it is registered.

If you are adding a **new** object type, when you register it:

1. Use `namespaceType: 'multiple-isolated'` to make these objects exist in exactly one space
2. Use `namespaceType: 'multiple'` to make these objects exist in one *or more* spaces
3. Use `namespaceType: 'agnostic'` if you want these objects to always exist in all spaces

If you have an **existing** "legacy" object type that is not shareable (using `namespaceType: 'single'`), see the [legacy developer guide
for Sharing Saved Objects](https://www.elastic.co/guide/en/kibana/master/sharing-saved-objects.html) for details on steps you need to take
to make sure this is converted to `namespaceType: 'multiple-isolated'` or `namespaceType: 'multiple'` in the 8.0 release.
27 changes: 17 additions & 10 deletions dev_docs/tutorials/saved_objects.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { SavedObjectsType } from 'src/core/server';
export const dashboardVisualization: SavedObjectsType = {
name: 'dashboard_visualization', [1]
hidden: false,
namespaceType: 'single',
namespaceType: 'multiple-isolated', [2]
mappings: {
dynamic: false,
properties: {
Expand All @@ -41,6 +41,10 @@ export const dashboardVisualization: SavedObjectsType = {
[1] Since the name of a Saved Object type forms part of the url path for the public Saved Objects HTTP API,
these should follow our API URL path convention and always be written as 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
<DocLink id="kibDevDocsSavedObjectsIntro" section="sharing-saved-objects" text="Sharing Saved Objects"/> for more information.

**src/plugins/my_plugin/server/saved_objects/index.ts**

```ts
Expand Down Expand Up @@ -122,7 +126,7 @@ Since Elasticsearch has a default limit of 1000 fields per index, plugins should
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.

## References
## References

Declare <DocLink id="kibDevDocsSavedObjectsIntro" section="References" text="Saved Object references"/> by adding an id, type and name to the
`references` array.
Expand Down Expand Up @@ -155,12 +159,14 @@ identify this reference. This guarantees that the id the reference points to alw
visualization id was directly stored in `dashboard.panels[0].visualization` there is a risk that this id gets updated without
updating the reference in the references array.

## Writing migrations
## Migrations

Saved Objects support schema changes between Kibana versions, which we call migrations. Migrations are
applied when a Kibana installation is upgraded from one version to the next, when exports are imported via
applied when a Kibana installation is upgraded from one version to a newer version, when exports are imported via
the Saved Objects Management UI, or when a new object is created via the HTTP API.

### Writing migrations

Each Saved Object type may define migrations for its schema. Migrations are specified by the Kibana version number, receive an input document,
and must return the fully migrated document to be persisted to Elasticsearch.

Expand Down Expand Up @@ -241,10 +247,11 @@ export const dashboardVisualization: SavedObjectsType = {
in which this migration was released. So if you are creating a migration which will
be part of the v7.10.0 release, but will also be backported and released as v7.9.3, the migration version should be: 7.9.3.

Migrations should be written defensively, an exception in a migration function will prevent a Kibana upgrade from succeeding and will cause downtime for our users.
Having said that, if a
document is encountered that is not in the expected shape, migrations are encouraged to throw an exception to abort the upgrade. In most scenarios, it is better to
fail an upgrade than to silently ignore a corrupt document which can cause unexpected behaviour at some future point in time.
Migrations should be written defensively, an exception in a migration function will prevent a Kibana upgrade from succeeding and will cause downtime for our users.
Having said that, if a document is encountered that is not in the expected shape, migrations are encouraged to throw an exception to abort the upgrade. In most scenarios, it is better to
fail an upgrade than to silently ignore a corrupt document which can cause unexpected behaviour at some future point in time. When such a scenario is encountered,
the error should be verbose and informative so that the corrupt document can be corrected, if possible.

### Testing Migrations

It is critical that you have extensive tests to ensure that migrations behave as expected with all possible input documents. Given how simple it is to test all the branch
conditions in a migration function and the high impact of a bug in this code, there’s really no reason not to aim for 100% test code coverage.
Bugs in a migration function cause downtime for our users and therefore have a very high impact. Follow the <DocLink id="kibDevTutorialTestingPlugins" section="saved-object-migrations" text="Saved Object migrations section in the plugin testing guide"/>.
188 changes: 187 additions & 1 deletion dev_docs/tutorials/testing_plugins.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ describe('renderApp', () => {
});
```
### SavedObjects
### SavedObjectsClient
#### Unit Tests
Expand Down Expand Up @@ -794,6 +794,192 @@ Kibana and esArchiver to load fixture data into Elasticsearch.
_todo: fully worked out example_
### Saved Objects migrations
_Also see <DocLink id="kibDevTutorialSavedObject" section="migrations" text="How to write a migration"/>._
It is critical that you have extensive tests to ensure that migrations behave as expected with all possible input
documents. Given how simple it is to test all the branch conditions in a migration function and the high impact of a
bug in this code, there’s really no reason not to aim for 100% test code coverage.
It's recommend that you primarily leverage unit testing with Jest for testing your migration function. Unit tests will
be a much more effective approach to testing all the different shapes of input data and edge cases that your migration
may need to handle. With more complex migrations that interact with several components or may behave different depending
on registry contents (such as Embeddable migrations), we recommend that you use the Jest Integration suite which allows
you to create a full instance Kibana and all plugins in memory and leverage the import API to test migrating documents.
#### Throwing exceptions
Keep in mind that any exception thrown by your migration function will cause Kibana to fail to upgrade. This should almost
never happen for our end users and we should be exhaustive in our testing to be sure to catch as many edge cases that we
could possibly handle. This entails ensuring that the migration is written defensively; we should try to avoid every bug
possible in our implementation.
In general, exceptions should only be thrown when the input data is corrupted and doesn't match the expected schema. In
such cases, it's important that an informative error message is included in the exception and we do not rely on implicit
runtime exceptions such as "null pointer exceptions" like `TypeError: Cannot read property 'foo' of undefined`.
#### Unit testing
Unit testing migration functions is typically pretty straight forward and comparable to other types of Jest testing. In
general, you should focus this tier of testing on validating output and testing input edge cases. One focus of this tier
should be trying to find edge cases that throw exceptions the migration shouldn't. As you can see in this simple
example, the coverage here is very exhaustive and verbose, which is intentional.
```ts
import { migrateCaseFromV7_9_0ToV7_10_0 } from './case_migrations';

const validInput_7_9_0 = {
id: '1',
type: 'case',
attributes: {
connector_id: '1234';
}
}

describe('Case migrations v7.7.0 -> v7.8.0', () => {
it('transforms the connector field', () => {
expect(migrateCaseFromV7_9_0ToV7_10_0(validInput_7_9_0)).toEqual({
id: '1',
type: 'case',
attributes: {
connector: {
id: '1234', // verify id was moved into subobject
name: 'none', // verify new default field was added
}
}
});
});

it('handles empty string', () => {
expect(migrateCaseFromV7_9_0ToV7_10_0({
id: '1',
type: 'case',
attributes: {
connector_id: ''
}
})).toEqual({
id: '1',
type: 'case',
attributes: {
connector: {
id: 'none',
name: 'none',
}
}
});
});

it('handles null', () => {
expect(migrateCaseFromV7_9_0ToV7_10_0({
id: '1',
type: 'case',
attributes: {
connector_id: null
}
})).toEqual({
id: '1',
type: 'case',
attributes: {
connector: {
id: 'none',
name: 'none',
}
}
});
});

it('handles undefined', () => {
expect(migrateCaseFromV7_9_0ToV7_10_0({
id: '1',
type: 'case',
attributes: {
// Even though undefined isn't a valid JSON or Elasticsearch value, we should test it anyways since there
// could be some JavaScript layer that casts the field to `undefined` for some reason.
connector_id: undefined
}
})).toEqual({
id: '1',
type: 'case',
attributes: {
connector: {
id: 'none',
name: 'none',
}
}
});

expect(migrateCaseFromV7_9_0ToV7_10_0({
id: '1',
type: 'case',
attributes: {
// also test without the field present at all
}
})).toEqual({
id: '1',
type: 'case',
attributes: {
connector: {
id: 'none',
name: 'none',
}
}
});
});
});
```
#### Integration testing
With more complicated migrations, the behavior of the migration may be dependent on values from other plugins which may
be difficult or even impossible to test with unit tests. You need to actually bootstrap Kibana, load the plugins, and
then test the full end-to-end migration. This type of set up will also test ingesting your documents into Elasticsearch
against the mappings defined by your Saved Object type.
This can be achieved using the `jest_integration` suite and the `kbnTestServer` utility for starting an in-memory
instance of Kibana. You can then leverage the import API to test migrations. This API applies the same migrations to
imported documents as are applied at Kibana startup and is much easier to work with for testing.
```ts
// You may need to adjust these paths depending on where your test file is located.
// The absolute path is src/core/test_helpers/so_migrations
import { createTestHarness, SavedObjectTestHarness } from '../../../../src/core/test_helpers/so_migrations';

describe('my plugin migrations', () => {
let testHarness: SavedObjectTestHarness;

beforeAll(async () => {
testHarness = createTestHarness();
await testHarness.start();
});

afterAll(async () => {
await testHarness.stop();
});

it('successfully migrates valid case documents', async () => {
expect(
await testHarness.migrate([
{ type: 'case', id: '1', attributes: { connector_id: '1234' }, references: [] },
{ type: 'case', id: '2', attributes: { connector_id: '' }, references: [] },
{ type: 'case', id: '3', attributes: { connector_id: null }, references: [] },
])
).toEqual([
expect.objectContaining(
{ type: 'case', id: '1', attributes: { connector: { id: '1234', name: 'none' } } }),
expect.objectContaining(
{ type: 'case', id: '2', attributes: { connector: { id: 'none', name: 'none' } } }),
expect.objectContaining(
{ type: 'case', id: '3', attributes: { connector: { id: 'none', name: 'none' } } }),
])
})
})
```
There are some caveats about using the import/export API for testing migrations:
- You cannot test the startup behavior of Kibana this way. This should not have any effect on type migrations but does
mean that this method cannot be used for testing the migration algorithm itself.
- While not yet supported, if support is added for migrations that affect multiple types, it's possible that the
behavior during import may vary slightly from the upgrade behavior.
### Elasticsearch
_How to test ES clients_
Expand Down
2 changes: 0 additions & 2 deletions docs/CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ This section summarizes the changes in each release.
[[release-notes-8.0.0-alpha1]]
== {kib} 8.0.0-alpha1

coming[8.0.0]

The following changes are released for the first time in {kib} 8.0.0-alpha1. Review the changes, then use the <<upgrade-assistant,Upgrade Assistant>> to complete the upgrade.

[float]
Expand Down
5 changes: 4 additions & 1 deletion docs/api/saved-objects/resolve.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ The `outcome` field may be any of the following:
* `"aliasMatch"` -- One document with a legacy URL alias matched the given ID; in this case the `saved_object.id` field is different than the given ID.
* `"conflict"` -- Two documents matched the given ID, one was an exact match and another with a legacy URL alias; in this case the `saved_object` object is the exact match, and the `saved_object.id` field is the same as the given ID.

If the outcome is `"aliasMatch"` or `"conflict"`, the response will also include an `alias_target_id` field. This means that an alias was found for another object, and it describes that other object's ID.

Retrieve a dashboard object in the `testspace` by ID:

[source,sh]
Expand Down Expand Up @@ -125,6 +127,7 @@ The API returns the following:
"dashboard": "7.0.0"
}
},
"outcome": "conflict"
"outcome": "conflict",
"alias_target_id": "05becb88-e214-439a-a2ac-15fc783b5d01"
}
--------------------------------------------------
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.
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]
Loading

0 comments on commit 2a3113f

Please sign in to comment.