mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Management] Handle saved search import better (#14625)
* Handle saved search import better * Add functional test * Better comments
This commit is contained in:
parent
8a5fce43ac
commit
6ef803b34b
4 changed files with 119 additions and 28 deletions
|
@ -204,9 +204,15 @@ uiModules.get('apps/management')
|
|||
);
|
||||
})
|
||||
.then((overwriteAll) => {
|
||||
// Keep a record of the index patterns assigned to our imported saved objects that do not
|
||||
// exist. We will provide a way for the user to manually select a new index pattern for those
|
||||
// saved objects.
|
||||
const conflictedIndexPatterns = [];
|
||||
// We want to do the same for saved searches, but we want to keep them separate because they need
|
||||
// to be applied _first_ because other saved objects can be depedent on those saved searches existing
|
||||
const conflictedSearchDocs = [];
|
||||
|
||||
function importDocument(doc) {
|
||||
function importDocument(swallowErrors, doc) {
|
||||
const { service } = find($scope.services, { type: doc._type }) || {};
|
||||
|
||||
if (!service) {
|
||||
|
@ -228,11 +234,16 @@ uiModules.get('apps/management')
|
|||
return obj.save({ confirmOverwrite : !overwriteAll });
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err instanceof SavedObjectNotFound && err.savedObjectType === 'index-pattern') {
|
||||
conflictedIndexPatterns.push({ obj, doc });
|
||||
return;
|
||||
if (swallowErrors && err instanceof SavedObjectNotFound) {
|
||||
switch (err.savedObjectType) {
|
||||
case 'search':
|
||||
conflictedSearchDocs.push(doc);
|
||||
return;
|
||||
case 'index-pattern':
|
||||
conflictedIndexPatterns.push({ obj, doc });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// swallow errors here so that the remaining promise chain executes
|
||||
err.message = `Importing ${obj.title} (${obj.id}) failed: ${err.message}`;
|
||||
notify.error(err);
|
||||
|
@ -258,35 +269,39 @@ uiModules.get('apps/management')
|
|||
}, defaultDocTypes);
|
||||
}
|
||||
|
||||
function resolveConflicts(objs, { obj }) {
|
||||
const oldIndexId = obj.searchSource.getOwn('index');
|
||||
const newIndexId = objs.find(({ oldId }) => oldId === oldIndexId).newId;
|
||||
// If the user did not select a new index pattern in the modal, the id
|
||||
// will be same as before, so don't try to update it
|
||||
if (newIndexId === oldIndexId) {
|
||||
return;
|
||||
}
|
||||
return obj.hydrateIndexPattern(newIndexId)
|
||||
.then(() => obj.save({ confirmOverwrite : !overwriteAll }));
|
||||
}
|
||||
|
||||
const docTypes = groupByType(docs);
|
||||
|
||||
return Promise.map(docTypes.searches, importDocument)
|
||||
.then(() => Promise.map(docTypes.other, importDocument))
|
||||
return Promise.map(docTypes.searches, importDocument.bind(null, true))
|
||||
.then(() => Promise.map(docTypes.other, importDocument.bind(null, true)))
|
||||
.then(() => {
|
||||
if (conflictedIndexPatterns.length) {
|
||||
showChangeIndexModal(
|
||||
(objs) => {
|
||||
return Promise.map(
|
||||
conflictedIndexPatterns,
|
||||
({ obj }) => {
|
||||
const oldIndexId = obj.searchSource.getOwn('index');
|
||||
const newIndexId = objs.find(({ oldId }) => oldId === oldIndexId).newId;
|
||||
if (newIndexId === oldIndexId) {
|
||||
// Skip
|
||||
return;
|
||||
}
|
||||
return obj.hydrateIndexPattern(newIndexId)
|
||||
.then(() => obj.save({ confirmOverwrite : !overwriteAll }));
|
||||
}
|
||||
).then(refreshData);
|
||||
},
|
||||
conflictedIndexPatterns,
|
||||
$route.current.locals.indexPatterns,
|
||||
);
|
||||
} else {
|
||||
return refreshData();
|
||||
return new Promise((resolve, reject) => {
|
||||
showChangeIndexModal(
|
||||
(objs) => {
|
||||
Promise.map(conflictedIndexPatterns, resolveConflicts.bind(null, objs))
|
||||
.then(resolve)
|
||||
.catch(reject);
|
||||
},
|
||||
conflictedIndexPatterns,
|
||||
$route.current.locals.indexPatterns,
|
||||
);
|
||||
});
|
||||
}
|
||||
})
|
||||
.then(() => Promise.map(conflictedSearchDocs, importDocument.bind(null, false)))
|
||||
.then(refreshData)
|
||||
.catch(notify.error);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -89,5 +89,34 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
expect(rowCount).to.be(2);
|
||||
});
|
||||
|
||||
it('should handle saved searches and objects with saved searches properly', async function () {
|
||||
await PageObjects.settings.navigateTo();
|
||||
await PageObjects.settings.clickKibanaSavedObjects();
|
||||
await PageObjects.settings.importFile(path.join(__dirname, 'exports', '_import_objects_with_saved_searches.json'));
|
||||
await PageObjects.common.clickConfirmOnModal();
|
||||
await PageObjects.settings.setImportIndexFieldOption(2);
|
||||
await PageObjects.settings.clickChangeIndexConfirmButton();
|
||||
await PageObjects.settings.clickVisualizationsTab();
|
||||
|
||||
const vizRowCount = await retry.try(async () => {
|
||||
const rows = await PageObjects.settings.getVisualizationRows();
|
||||
if (rows.length !== 2) {
|
||||
throw 'Not loaded yet';
|
||||
}
|
||||
return rows.length;
|
||||
});
|
||||
expect(vizRowCount).to.be(2);
|
||||
|
||||
await PageObjects.settings.clickSearchesTab();
|
||||
const searchRowCount = await retry.try(async () => {
|
||||
const rows = await PageObjects.settings.getVisualizationRows();
|
||||
if (rows.length !== 1) {
|
||||
throw 'Not loaded yet';
|
||||
}
|
||||
return rows.length;
|
||||
});
|
||||
expect(searchRowCount).to.be(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
[
|
||||
{
|
||||
"_id": "c45e6c50-ba72-11e7-a8f9-ad70f02e633d",
|
||||
"_type": "search",
|
||||
"_source": {
|
||||
"title": "PHP saved search",
|
||||
"description": "",
|
||||
"hits": 0,
|
||||
"columns": [
|
||||
"_source"
|
||||
],
|
||||
"sort": [
|
||||
"@timestamp",
|
||||
"desc"
|
||||
],
|
||||
"version": 1,
|
||||
"kibanaSavedObjectMeta": {
|
||||
"searchSourceJSON": "{\"index\":\"f0df0960-ae8d-11e7-9c8d-53400275d89a\",\"highlightAll\":true,\"version\":true,\"query\":{\"language\":\"lucene\",\"query\":\"php\"},\"filter\":[]}"
|
||||
}
|
||||
},
|
||||
"_meta": {
|
||||
"savedObjectVersion": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"_id": "cbd520f0-ba72-11e7-a8f9-ad70f02e633d",
|
||||
"_type": "visualization",
|
||||
"_source": {
|
||||
"title": "PHP Viz",
|
||||
"visState": "{\"title\":\"PHP Viz\",\"type\":\"horizontal_bar\",\"params\":{\"type\":\"histogram\",\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":200},\"title\":{}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":75,\"filter\":true,\"truncate\":100},\"title\":{\"text\":\"Count\"}}],\"seriesParams\":[{\"show\":true,\"type\":\"histogram\",\"mode\":\"normal\",\"data\":{\"label\":\"Count\",\"id\":\"1\"},\"valueAxis\":\"ValueAxis-1\",\"drawLinesBetweenPoints\":true,\"showCircles\":true}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"times\":[],\"addTimeMarker\":false},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}}]}",
|
||||
"uiStateJSON": "{}",
|
||||
"description": "",
|
||||
"savedSearchId": "c45e6c50-ba72-11e7-a8f9-ad70f02e633d",
|
||||
"version": 1,
|
||||
"kibanaSavedObjectMeta": {
|
||||
"searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"}}"
|
||||
}
|
||||
},
|
||||
"_meta": {
|
||||
"savedObjectVersion": 2
|
||||
}
|
||||
}
|
||||
]
|
|
@ -508,6 +508,10 @@ export function SettingsPageProvider({ getService, getPageObjects }) {
|
|||
await (await testSubjects.find('objectsTab-visualizations')).click();
|
||||
}
|
||||
|
||||
async clickSearchesTab() {
|
||||
await (await testSubjects.find('objectsTab-searches')).click();
|
||||
}
|
||||
|
||||
async getVisualizationRows() {
|
||||
return await testSubjects.findAll(`objectsTableRow`);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue