[Maps] embeddable migrations (#101070)

* [Maps] embeddable migrations

* review feedback

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Nathan Reese 2021-06-04 08:00:41 -06:00 committed by GitHub
parent 8f83090d74
commit 93df9a32a4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 259 additions and 141 deletions

View file

@ -0,0 +1,21 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import semverGte from 'semver/functions/gte';
import { embeddableMigrations } from './embeddable_migrations';
// @ts-ignore
import { savedObjectMigrations } from './saved_objects/saved_object_migrations';
describe('saved object migrations and embeddable migrations', () => {
test('should have same versions registered (>7.12)', () => {
const savedObjectMigrationVersions = Object.keys(savedObjectMigrations).filter((version) => {
return semverGte(version, '7.13.0');
});
const embeddableMigrationVersions = Object.keys(embeddableMigrations);
expect(savedObjectMigrationVersions.sort()).toEqual(embeddableMigrationVersions.sort());
});
});

View file

@ -0,0 +1,26 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { SerializableState } from '../../../../src/plugins/kibana_utils/common';
import { MapSavedObjectAttributes } from '../common/map_saved_object_type';
import { moveAttribution } from '../common/migrations/move_attribution';
/*
* Embeddables such as Maps, Lens, and Visualize can be embedded by value or by reference on a dashboard.
* To ensure that any migrations (>7.12) are run correctly in both cases,
* the migration function must be registered as both a saved object migration and an embeddable migration
* This is the embeddable migration registry.
*/
export const embeddableMigrations = {
'7.14.0': (state: SerializableState) => {
return {
...state,
attributes: moveAttribution(state as { attributes: MapSavedObjectAttributes }),
} as SerializableState;
},
};

View file

@ -37,6 +37,8 @@ import { HomeServerPluginSetup } from '../../../../src/plugins/home/server';
import { MapsEmsPluginSetup } from '../../../../src/plugins/maps_ems/server';
import { EMSSettings } from '../common/ems_settings';
import { PluginStart as DataPluginStart } from '../../../../src/plugins/data/server';
import { EmbeddableSetup } from '../../../../src/plugins/embeddable/server';
import { embeddableMigrations } from './embeddable_migrations';
interface SetupDeps {
features: FeaturesPluginSetupContract;
@ -44,6 +46,7 @@ interface SetupDeps {
home: HomeServerPluginSetup;
licensing: LicensingPluginSetup;
mapsEms: MapsEmsPluginSetup;
embeddable: EmbeddableSetup;
}
export interface StartDeps {
@ -214,6 +217,11 @@ export class MapsPlugin implements Plugin {
core.savedObjects.registerType(mapSavedObjects);
registerMapsUsageCollector(usageCollection, currentConfig);
plugins.embeddable.registerEmbeddableFactory({
id: MAP_SAVED_OBJECT_TYPE,
migrations: embeddableMigrations,
});
return {
config: config$,
};

View file

@ -8,7 +8,7 @@
import { SavedObjectsType } from 'src/core/server';
import { APP_ICON, getExistingMapPath } from '../../common/constants';
// @ts-ignore
import { migrations } from './migrations';
import { savedObjectMigrations } from './saved_object_migrations';
export const mapSavedObjects: SavedObjectsType = {
name: 'map',
@ -39,5 +39,5 @@ export const mapSavedObjects: SavedObjectsType = {
};
},
},
migrations: migrations.map,
migrations: savedObjectMigrations,
};

View file

@ -1,107 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { extractReferences } from '../../common/migrations/references';
import { emsRasterTileToEmsVectorTile } from '../../common/migrations/ems_raster_tile_to_ems_vector_tile';
import { topHitsTimeToSort } from '../../common/migrations/top_hits_time_to_sort';
import { moveApplyGlobalQueryToSources } from '../../common/migrations/move_apply_global_query';
import { addFieldMetaOptions } from '../../common/migrations/add_field_meta_options';
import { migrateSymbolStyleDescriptor } from '../../common/migrations/migrate_symbol_style_descriptor';
import { migrateUseTopHitsToScalingType } from '../../common/migrations/scaling_type';
import { migrateJoinAggKey } from '../../common/migrations/join_agg_key';
import { removeBoundsFromSavedObject } from '../../common/migrations/remove_bounds';
import { setDefaultAutoFitToBounds } from '../../common/migrations/set_default_auto_fit_to_bounds';
import { addTypeToTermJoin } from '../../common/migrations/add_type_to_termjoin';
import { moveAttribution } from '../../common/migrations/move_attribution';
export const migrations = {
map: {
'7.2.0': (doc) => {
const { attributes, references } = extractReferences(doc);
return {
...doc,
attributes,
references,
};
},
'7.4.0': (doc) => {
const attributes = emsRasterTileToEmsVectorTile(doc);
return {
...doc,
attributes,
};
},
'7.5.0': (doc) => {
const attributes = topHitsTimeToSort(doc);
return {
...doc,
attributes,
};
},
'7.6.0': (doc) => {
const attributesPhase1 = moveApplyGlobalQueryToSources(doc);
const attributesPhase2 = addFieldMetaOptions({ attributes: attributesPhase1 });
return {
...doc,
attributes: attributesPhase2,
};
},
'7.7.0': (doc) => {
const attributesPhase1 = migrateSymbolStyleDescriptor(doc);
const attributesPhase2 = migrateUseTopHitsToScalingType({ attributes: attributesPhase1 });
return {
...doc,
attributes: attributesPhase2,
};
},
'7.8.0': (doc) => {
const attributes = migrateJoinAggKey(doc);
return {
...doc,
attributes,
};
},
'7.9.0': (doc) => {
const attributes = removeBoundsFromSavedObject(doc);
return {
...doc,
attributes,
};
},
'7.10.0': (doc) => {
const attributes = setDefaultAutoFitToBounds(doc);
return {
...doc,
attributes,
};
},
'7.12.0': (doc) => {
const attributes = addTypeToTermJoin(doc);
return {
...doc,
attributes,
};
},
'7.14.0': (doc) => {
const attributes = moveAttribution(doc);
return {
...doc,
attributes,
};
},
},
};

View file

@ -0,0 +1,112 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { extractReferences } from '../../common/migrations/references';
import { emsRasterTileToEmsVectorTile } from '../../common/migrations/ems_raster_tile_to_ems_vector_tile';
import { topHitsTimeToSort } from '../../common/migrations/top_hits_time_to_sort';
import { moveApplyGlobalQueryToSources } from '../../common/migrations/move_apply_global_query';
import { addFieldMetaOptions } from '../../common/migrations/add_field_meta_options';
import { migrateSymbolStyleDescriptor } from '../../common/migrations/migrate_symbol_style_descriptor';
import { migrateUseTopHitsToScalingType } from '../../common/migrations/scaling_type';
import { migrateJoinAggKey } from '../../common/migrations/join_agg_key';
import { removeBoundsFromSavedObject } from '../../common/migrations/remove_bounds';
import { setDefaultAutoFitToBounds } from '../../common/migrations/set_default_auto_fit_to_bounds';
import { addTypeToTermJoin } from '../../common/migrations/add_type_to_termjoin';
import { moveAttribution } from '../../common/migrations/move_attribution';
/*
* Embeddables such as Maps, Lens, and Visualize can be embedded by value or by reference on a dashboard.
* To ensure that any migrations (>7.12) are run correctly in both cases,
* the migration function must be registered as both a saved object migration and an embeddable migration
* This is the saved object migration registry.
*/
export const savedObjectMigrations = {
'7.2.0': (doc) => {
const { attributes, references } = extractReferences(doc);
return {
...doc,
attributes,
references,
};
},
'7.4.0': (doc) => {
const attributes = emsRasterTileToEmsVectorTile(doc);
return {
...doc,
attributes,
};
},
'7.5.0': (doc) => {
const attributes = topHitsTimeToSort(doc);
return {
...doc,
attributes,
};
},
'7.6.0': (doc) => {
const attributesPhase1 = moveApplyGlobalQueryToSources(doc);
const attributesPhase2 = addFieldMetaOptions({ attributes: attributesPhase1 });
return {
...doc,
attributes: attributesPhase2,
};
},
'7.7.0': (doc) => {
const attributesPhase1 = migrateSymbolStyleDescriptor(doc);
const attributesPhase2 = migrateUseTopHitsToScalingType({ attributes: attributesPhase1 });
return {
...doc,
attributes: attributesPhase2,
};
},
'7.8.0': (doc) => {
const attributes = migrateJoinAggKey(doc);
return {
...doc,
attributes,
};
},
'7.9.0': (doc) => {
const attributes = removeBoundsFromSavedObject(doc);
return {
...doc,
attributes,
};
},
'7.10.0': (doc) => {
const attributes = setDefaultAutoFitToBounds(doc);
return {
...doc,
attributes,
};
},
'7.12.0': (doc) => {
const attributes = addTypeToTermJoin(doc);
return {
...doc,
attributes,
};
},
'7.14.0': (doc) => {
const attributes = moveAttribution(doc);
return {
...doc,
attributes,
};
},
};

View file

@ -9,41 +9,71 @@ import expect from '@kbn/expect';
export default function ({ getService }) {
const supertest = getService('supertest');
const esArchiver = getService('esArchiver');
describe('migrations', () => {
it('should apply saved object reference migration when importing map saved objects prior to 7.2.0', async () => {
const resp = await supertest
.post(`/api/saved_objects/map`)
.set('kbn-xsrf', 'kibana')
.send({
attributes: {
title: '[Logs] Total Requests and Bytes',
layerListJSON:
'[{"id":"edh66","label":"Total Requests by Country","minZoom":0,"maxZoom":24,"alpha":0.5,"sourceDescriptor":{"type":"EMS_FILE","id":"world_countries"},"visible":true,"style":{"type":"VECTOR","properties":{"fillColor":{"type":"DYNAMIC","options":{"field":{"label":"count of kibana_sample_data_logs:geo.src","name":"__kbnjoin__count_groupby_kibana_sample_data_logs.geo.src","origin":"join"},"color":"Greys"}},"lineColor":{"type":"STATIC","options":{"color":"#FFFFFF"}},"lineWidth":{"type":"STATIC","options":{"size":1}},"iconSize":{"type":"STATIC","options":{"size":10}}}},"type":"VECTOR","joins":[{"leftField":"iso2","right":{"id":"673ff994-fc75-4c67-909b-69fcb0e1060e","indexPatternId":"90943e30-9a47-11e8-b64d-95841ca0b247","indexPatternTitle":"kibana_sample_data_logs","term":"geo.src"}}]},{"id":"gaxya","label":"Actual Requests","minZoom":9,"maxZoom":24,"alpha":1,"sourceDescriptor":{"id":"b7486535-171b-4d3b-bb2e-33c1a0a2854c","type":"ES_SEARCH","indexPatternId":"90943e30-9a47-11e8-b64d-95841ca0b247","geoField":"geo.coordinates","limit":2048,"filterByMapBounds":true,"tooltipProperties":["clientip","timestamp","host","request","response","machine.os","agent","bytes"]},"visible":true,"style":{"type":"VECTOR","properties":{"fillColor":{"type":"STATIC","options":{"color":"#2200ff"}},"lineColor":{"type":"STATIC","options":{"color":"#FFFFFF"}},"lineWidth":{"type":"STATIC","options":{"size":2}},"iconSize":{"type":"DYNAMIC","options":{"field":{"label":"bytes","name":"bytes","origin":"source"},"minSize":1,"maxSize":23}}}},"type":"VECTOR"},{"id":"tfi3f","label":"Total Requests and Bytes","minZoom":0,"maxZoom":9,"alpha":1,"sourceDescriptor":{"type":"ES_GEO_GRID","resolution":"COARSE","id":"8aaa65b5-a4e9-448b-9560-c98cb1c5ac5b","indexPatternId":"90943e30-9a47-11e8-b64d-95841ca0b247","geoField":"geo.coordinates","requestType":"point","metrics":[{"type":"count"},{"type":"sum","field":"bytes"}]},"visible":true,"style":{"type":"VECTOR","properties":{"fillColor":{"type":"DYNAMIC","options":{"field":{"label":"Count","name":"doc_count","origin":"source"},"color":"Blues"}},"lineColor":{"type":"STATIC","options":{"color":"#cccccc"}},"lineWidth":{"type":"STATIC","options":{"size":1}},"iconSize":{"type":"DYNAMIC","options":{"field":{"label":"sum of bytes","name":"sum_of_bytes","origin":"source"},"minSize":1,"maxSize":25}}}},"type":"VECTOR"}]',
},
migrationVersion: {},
})
.expect(200);
describe('saved object migrations', () => {
it('should apply saved object reference migration when importing map saved objects prior to 7.2.0', async () => {
const resp = await supertest
.post(`/api/saved_objects/map`)
.set('kbn-xsrf', 'kibana')
.send({
attributes: {
title: '[Logs] Total Requests and Bytes',
layerListJSON:
'[{"id":"edh66","label":"Total Requests by Country","minZoom":0,"maxZoom":24,"alpha":0.5,"sourceDescriptor":{"type":"EMS_FILE","id":"world_countries"},"visible":true,"style":{"type":"VECTOR","properties":{"fillColor":{"type":"DYNAMIC","options":{"field":{"label":"count of kibana_sample_data_logs:geo.src","name":"__kbnjoin__count_groupby_kibana_sample_data_logs.geo.src","origin":"join"},"color":"Greys"}},"lineColor":{"type":"STATIC","options":{"color":"#FFFFFF"}},"lineWidth":{"type":"STATIC","options":{"size":1}},"iconSize":{"type":"STATIC","options":{"size":10}}}},"type":"VECTOR","joins":[{"leftField":"iso2","right":{"id":"673ff994-fc75-4c67-909b-69fcb0e1060e","indexPatternId":"90943e30-9a47-11e8-b64d-95841ca0b247","indexPatternTitle":"kibana_sample_data_logs","term":"geo.src"}}]},{"id":"gaxya","label":"Actual Requests","minZoom":9,"maxZoom":24,"alpha":1,"sourceDescriptor":{"id":"b7486535-171b-4d3b-bb2e-33c1a0a2854c","type":"ES_SEARCH","indexPatternId":"90943e30-9a47-11e8-b64d-95841ca0b247","geoField":"geo.coordinates","limit":2048,"filterByMapBounds":true,"tooltipProperties":["clientip","timestamp","host","request","response","machine.os","agent","bytes"]},"visible":true,"style":{"type":"VECTOR","properties":{"fillColor":{"type":"STATIC","options":{"color":"#2200ff"}},"lineColor":{"type":"STATIC","options":{"color":"#FFFFFF"}},"lineWidth":{"type":"STATIC","options":{"size":2}},"iconSize":{"type":"DYNAMIC","options":{"field":{"label":"bytes","name":"bytes","origin":"source"},"minSize":1,"maxSize":23}}}},"type":"VECTOR"},{"id":"tfi3f","label":"Total Requests and Bytes","minZoom":0,"maxZoom":9,"alpha":1,"sourceDescriptor":{"type":"ES_GEO_GRID","resolution":"COARSE","id":"8aaa65b5-a4e9-448b-9560-c98cb1c5ac5b","indexPatternId":"90943e30-9a47-11e8-b64d-95841ca0b247","geoField":"geo.coordinates","requestType":"point","metrics":[{"type":"count"},{"type":"sum","field":"bytes"}]},"visible":true,"style":{"type":"VECTOR","properties":{"fillColor":{"type":"DYNAMIC","options":{"field":{"label":"Count","name":"doc_count","origin":"source"},"color":"Blues"}},"lineColor":{"type":"STATIC","options":{"color":"#cccccc"}},"lineWidth":{"type":"STATIC","options":{"size":1}},"iconSize":{"type":"DYNAMIC","options":{"field":{"label":"sum of bytes","name":"sum_of_bytes","origin":"source"},"minSize":1,"maxSize":25}}}},"type":"VECTOR"}]',
},
migrationVersion: {},
})
.expect(200);
expect(resp.body.references).to.eql([
{
id: '90943e30-9a47-11e8-b64d-95841ca0b247',
name: 'layer_0_join_0_index_pattern',
type: 'index-pattern',
},
{
id: '90943e30-9a47-11e8-b64d-95841ca0b247',
name: 'layer_1_source_index_pattern',
type: 'index-pattern',
},
{
id: '90943e30-9a47-11e8-b64d-95841ca0b247',
name: 'layer_2_source_index_pattern',
type: 'index-pattern',
},
]);
expect(resp.body.migrationVersion).to.eql({ map: '7.14.0' });
expect(resp.body.attributes.layerListJSON.includes('indexPatternRefName')).to.be(true);
expect(resp.body.references).to.eql([
{
id: '90943e30-9a47-11e8-b64d-95841ca0b247',
name: 'layer_0_join_0_index_pattern',
type: 'index-pattern',
},
{
id: '90943e30-9a47-11e8-b64d-95841ca0b247',
name: 'layer_1_source_index_pattern',
type: 'index-pattern',
},
{
id: '90943e30-9a47-11e8-b64d-95841ca0b247',
name: 'layer_2_source_index_pattern',
type: 'index-pattern',
},
]);
expect(resp.body.migrationVersion).to.eql({ map: '7.14.0' });
expect(resp.body.attributes.layerListJSON.includes('indexPatternRefName')).to.be(true);
});
});
describe('embeddable migrations', () => {
before(async () => {
await esArchiver.loadIfNeeded('maps/kibana');
});
after(async () => {
await esArchiver.unload('maps/kibana');
});
it('should apply embeddable migrations', async () => {
const resp = await supertest
.get(`/api/saved_objects/dashboard/4beb0d80-c2ef-11eb-b0cb-bd162d969e6b`)
.set('kbn-xsrf', 'kibana')
.expect(200);
let panels;
try {
panels = JSON.parse(resp.body.attributes.panelsJSON);
} catch (error) {
throw 'Unable to parse panelsJSON from dashboard saved object';
}
expect(panels.length).to.be(1);
expect(panels[0].type).to.be('map');
expect(panels[0].version).to.be('7.14.0');
});
});
});
}

View file

@ -1199,6 +1199,34 @@
}
}
{
"type": "doc",
"value": {
"id": "dashboard:4beb0d80-c2ef-11eb-b0cb-bd162d969e6b",
"index": ".kibana",
"source": {
"dashboard": {
"title" : "by value map",
"hits" : 0,
"description" : "",
"panelsJSON" : "[{\"version\":\"7.12.1-SNAPSHOT\",\"type\":\"map\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"cb82a9e3-2eb0-487f-9ade-0ffb921eb536\"},\"panelIndex\":\"cb82a9e3-2eb0-487f-9ade-0ffb921eb536\",\"embeddableConfig\":{\"attributes\":{\"title\":\"\",\"description\":\"\",\"layerListJSON\":\"[]\",\"mapStateJSON\":\"{\\\"zoom\\\":1.75,\\\"center\\\":{\\\"lon\\\":0,\\\"lat\\\":19.94277},\\\"timeFilters\\\":{\\\"from\\\":\\\"now-15m\\\",\\\"to\\\":\\\"now\\\"},\\\"refreshConfig\\\":{\\\"isPaused\\\":true,\\\"interval\\\":0},\\\"query\\\":{\\\"query\\\":\\\"\\\",\\\"language\\\":\\\"kuery\\\"},\\\"filters\\\":[],\\\"settings\\\":{\\\"autoFitToDataBounds\\\":false,\\\"backgroundColor\\\":\\\"#ffffff\\\",\\\"disableInteractive\\\":false,\\\"disableTooltipControl\\\":false,\\\"hideToolbarOverlay\\\":false,\\\"hideLayerControl\\\":false,\\\"hideViewControl\\\":false,\\\"initialLocation\\\":\\\"LAST_SAVED_LOCATION\\\",\\\"fixedLocation\\\":{\\\"lat\\\":0,\\\"lon\\\":0,\\\"zoom\\\":2},\\\"browserLocation\\\":{\\\"zoom\\\":2},\\\"maxZoom\\\":24,\\\"minZoom\\\":0,\\\"showScaleControl\\\":false,\\\"showSpatialFilters\\\":true,\\\"spatialFiltersAlpa\\\":0.3,\\\"spatialFiltersFillColor\\\":\\\"#DA8B45\\\",\\\"spatialFiltersLineColor\\\":\\\"#DA8B45\\\"}}\",\"uiStateJSON\":\"{\\\"isLayerTOCOpen\\\":true,\\\"openTOCDetails\\\":[]}\"},\"mapCenter\":{\"lat\":19.94277,\"lon\":0,\"zoom\":1.75},\"mapBuffer\":{\"minLon\":-211.13072,\"minLat\":-55.27145,\"maxLon\":211.13072,\"maxLat\":87.44135},\"isLayerTOCOpen\":true,\"openTOCDetails\":[],\"hiddenLayers\":[],\"enhancements\":{}}}]",
"optionsJSON" : "{\"hidePanelTitles\":false,\"useMargins\":true}",
"version" : 1,
"timeRestore" : false,
"kibanaSavedObjectMeta" : {
"searchSourceJSON" : "{\"query\":{\"language\":\"kuery\",\"query\":\"\"},\"filter\":[]}"
}
},
"type" : "dashboard",
"references" : [ ],
"migrationVersion" : {
"dashboard" : "7.11.0"
},
"updated_at" : "2021-06-01T15:37:39.198Z"
}
}
}
{
"type": "doc",
"value": {