-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Maps] implement references for saved objects (#31745)
* [Maps] implement references for saved objects * add source to ref name, check that source type is ES_SEARCH or ES_GEO_GRID * extract out common find reference into a function * add migration version to sample data objects * joins are on layer descriptor and not source descriptor * update one es_archive saved object to have layerListJSON stored in references to ensure injectReferences is really working in SavedGisMap * update sample data saved objects to include applied migration * add API test to verify migration is applied when imported saved object
- Loading branch information
Showing
16 changed files
with
488 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
// Can not use public Layer classes to extract references since this logic must run in both client and server. | ||
|
||
import _ from 'lodash'; | ||
import { ES_GEO_GRID, ES_SEARCH } from '../constants'; | ||
|
||
function doesSourceUseIndexPattern(layerDescriptor) { | ||
const sourceType = _.get(layerDescriptor, 'sourceDescriptor.type'); | ||
return sourceType === ES_GEO_GRID || sourceType === ES_SEARCH; | ||
} | ||
|
||
export function extractReferences({ attributes, references = [] }) { | ||
if (!attributes.layerListJSON) { | ||
return { attributes, references }; | ||
} | ||
|
||
const extractedReferences = []; | ||
|
||
const layerList = JSON.parse(attributes.layerListJSON); | ||
layerList.forEach((layer, layerIndex) => { | ||
|
||
// Extract index-pattern references from source descriptor | ||
if (doesSourceUseIndexPattern(layer) && _.has(layer, 'sourceDescriptor.indexPatternId')) { | ||
const refName = `layer_${layerIndex}_source_index_pattern`; | ||
extractedReferences.push({ | ||
name: refName, | ||
type: 'index-pattern', | ||
id: layer.sourceDescriptor.indexPatternId, | ||
}); | ||
delete layer.sourceDescriptor.indexPatternId; | ||
layer.sourceDescriptor.indexPatternRefName = refName; | ||
} | ||
|
||
// Extract index-pattern references from join | ||
const joins = _.get(layer, 'joins', []); | ||
joins.forEach((join, joinIndex) => { | ||
if (_.has(join, 'right.indexPatternId')) { | ||
const refName = `layer_${layerIndex}_join_${joinIndex}_index_pattern`; | ||
extractedReferences.push({ | ||
name: refName, | ||
type: 'index-pattern', | ||
id: join.right.indexPatternId, | ||
}); | ||
delete join.right.indexPatternId; | ||
join.right.indexPatternRefName = refName; | ||
} | ||
}); | ||
}); | ||
|
||
return { | ||
attributes: { | ||
...attributes, | ||
layerListJSON: JSON.stringify(layerList), | ||
}, | ||
references: references.concat(extractedReferences), | ||
}; | ||
} | ||
|
||
function findReference(targetName, references) { | ||
const reference = references.find(reference => reference.name === targetName); | ||
if (!reference) { | ||
throw new Error(`Could not find reference "${targetName}"`); | ||
} | ||
return reference; | ||
} | ||
|
||
export function injectReferences({ attributes, references }) { | ||
if (!attributes.layerListJSON) { | ||
return { attributes }; | ||
} | ||
|
||
const layerList = JSON.parse(attributes.layerListJSON); | ||
layerList.forEach((layer) => { | ||
|
||
// Inject index-pattern references into source descriptor | ||
if (doesSourceUseIndexPattern(layer) && _.has(layer, 'sourceDescriptor.indexPatternRefName')) { | ||
const reference = findReference(layer.sourceDescriptor.indexPatternRefName, references); | ||
layer.sourceDescriptor.indexPatternId = reference.id; | ||
delete layer.sourceDescriptor.indexPatternRefName; | ||
} | ||
|
||
// Inject index-pattern references into join | ||
const joins = _.get(layer, 'joins', []); | ||
joins.forEach((join) => { | ||
if (_.has(join, 'right.indexPatternRefName')) { | ||
const reference = findReference(join.right.indexPatternRefName, references); | ||
join.right.indexPatternId = reference.id; | ||
delete join.right.indexPatternRefName; | ||
} | ||
}); | ||
}); | ||
|
||
return { | ||
attributes: { | ||
...attributes, | ||
layerListJSON: JSON.stringify(layerList), | ||
}, | ||
}; | ||
} |
173 changes: 173 additions & 0 deletions
173
x-pack/plugins/maps/common/migrations/references.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
/* eslint max-len: 0 */ | ||
|
||
import { extractReferences, injectReferences } from './references'; | ||
import { ES_GEO_GRID, ES_SEARCH } from '../constants'; | ||
|
||
const layerListJSON = { | ||
esSearchSource: { | ||
withIndexPatternId: `[{\"sourceDescriptor\":{\"type\":\"${ES_SEARCH}\",\"indexPatternId\":\"c698b940-e149-11e8-a35a-370a8516603a\"}}]`, | ||
withIndexPatternRef: `[{\"sourceDescriptor\":{\"type\":\"${ES_SEARCH}\",\"indexPatternRefName\":\"layer_0_source_index_pattern\"}}]`, | ||
}, | ||
esGeoGridSource: { | ||
withIndexPatternId: `[{\"sourceDescriptor\":{\"type\":\"${ES_GEO_GRID}\",\"indexPatternId\":\"c698b940-e149-11e8-a35a-370a8516603a\"}}]`, | ||
withIndexPatternRef: `[{\"sourceDescriptor\":{\"type\":\"${ES_GEO_GRID}\",\"indexPatternRefName\":\"layer_0_source_index_pattern\"}}]`, | ||
}, | ||
join: { | ||
withIndexPatternId: '[{\"joins\":[{\"right\":{\"indexPatternId\":\"e20b2a30-f735-11e8-8ce0-9723965e01e3\"}}]}]', | ||
withIndexPatternRef: '[{\"joins\":[{\"right\":{\"indexPatternRefName\":\"layer_0_join_0_index_pattern\"}}]}]', | ||
} | ||
}; | ||
|
||
describe('extractReferences', () => { | ||
|
||
test('Should handle missing layerListJSON attribute', () => { | ||
const attributes = { | ||
title: 'my map', | ||
}; | ||
expect(extractReferences({ attributes })).toEqual({ | ||
attributes: { | ||
title: 'my map', | ||
}, | ||
references: [], | ||
}); | ||
}); | ||
|
||
test('Should extract index-pattern reference from ES search source descriptor', () => { | ||
const attributes = { | ||
title: 'my map', | ||
layerListJSON: layerListJSON.esSearchSource.withIndexPatternId, | ||
}; | ||
expect(extractReferences({ attributes })).toEqual({ | ||
attributes: { | ||
title: 'my map', | ||
layerListJSON: layerListJSON.esSearchSource.withIndexPatternRef, | ||
}, | ||
references: [ | ||
{ | ||
id: 'c698b940-e149-11e8-a35a-370a8516603a', | ||
name: 'layer_0_source_index_pattern', | ||
type: 'index-pattern', | ||
} | ||
], | ||
}); | ||
}); | ||
|
||
test('Should extract index-pattern reference from ES geo grid source descriptor', () => { | ||
const attributes = { | ||
title: 'my map', | ||
layerListJSON: layerListJSON.esGeoGridSource.withIndexPatternId, | ||
}; | ||
expect(extractReferences({ attributes })).toEqual({ | ||
attributes: { | ||
title: 'my map', | ||
layerListJSON: layerListJSON.esGeoGridSource.withIndexPatternRef, | ||
}, | ||
references: [ | ||
{ | ||
id: 'c698b940-e149-11e8-a35a-370a8516603a', | ||
name: 'layer_0_source_index_pattern', | ||
type: 'index-pattern', | ||
} | ||
], | ||
}); | ||
}); | ||
|
||
test('Should extract index-pattern reference from joins', () => { | ||
const attributes = { | ||
title: 'my map', | ||
layerListJSON: layerListJSON.join.withIndexPatternId, | ||
}; | ||
expect(extractReferences({ attributes })).toEqual({ | ||
attributes: { | ||
title: 'my map', | ||
layerListJSON: layerListJSON.join.withIndexPatternRef, | ||
}, | ||
references: [ | ||
{ | ||
id: 'e20b2a30-f735-11e8-8ce0-9723965e01e3', | ||
name: 'layer_0_join_0_index_pattern', | ||
type: 'index-pattern', | ||
} | ||
], | ||
}); | ||
}); | ||
}); | ||
|
||
describe('injectReferences', () => { | ||
test('Should handle missing layerListJSON attribute', () => { | ||
const attributes = { | ||
title: 'my map', | ||
}; | ||
expect(injectReferences({ attributes })).toEqual({ | ||
attributes: { | ||
title: 'my map', | ||
} | ||
}); | ||
}); | ||
|
||
test('Should inject index-pattern reference into ES search source descriptor', () => { | ||
const attributes = { | ||
title: 'my map', | ||
layerListJSON: layerListJSON.esSearchSource.withIndexPatternRef, | ||
}; | ||
const references = [ | ||
{ | ||
id: 'c698b940-e149-11e8-a35a-370a8516603a', | ||
name: 'layer_0_source_index_pattern', | ||
type: 'index-pattern', | ||
} | ||
]; | ||
expect(injectReferences({ attributes, references })).toEqual({ | ||
attributes: { | ||
title: 'my map', | ||
layerListJSON: layerListJSON.esSearchSource.withIndexPatternId, | ||
} | ||
}); | ||
}); | ||
|
||
test('Should inject index-pattern reference into ES geo grid source descriptor', () => { | ||
const attributes = { | ||
title: 'my map', | ||
layerListJSON: layerListJSON.esGeoGridSource.withIndexPatternRef, | ||
}; | ||
const references = [ | ||
{ | ||
id: 'c698b940-e149-11e8-a35a-370a8516603a', | ||
name: 'layer_0_source_index_pattern', | ||
type: 'index-pattern', | ||
} | ||
]; | ||
expect(injectReferences({ attributes, references })).toEqual({ | ||
attributes: { | ||
title: 'my map', | ||
layerListJSON: layerListJSON.esGeoGridSource.withIndexPatternId, | ||
} | ||
}); | ||
}); | ||
|
||
test('Should inject index-pattern reference into joins', () => { | ||
const attributes = { | ||
title: 'my map', | ||
layerListJSON: layerListJSON.join.withIndexPatternRef, | ||
}; | ||
const references = [ | ||
{ | ||
id: 'e20b2a30-f735-11e8-8ce0-9723965e01e3', | ||
name: 'layer_0_join_0_index_pattern', | ||
type: 'index-pattern', | ||
} | ||
]; | ||
expect(injectReferences({ attributes, references })).toEqual({ | ||
attributes: { | ||
title: 'my map', | ||
layerListJSON: layerListJSON.join.withIndexPatternId, | ||
} | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import { extractReferences } from './common/migrations/references'; | ||
|
||
export const migrations = { | ||
'map': { | ||
'7.1.0': (doc) => { | ||
const { attributes, references } = extractReferences(doc); | ||
|
||
return { | ||
...doc, | ||
attributes, | ||
references, | ||
}; | ||
}, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.