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

[Management] Handle saved search import better #14625

Merged

Conversation

chrisronline
Copy link
Contributor

@chrisronline chrisronline commented Oct 26, 2017

Fixes #14592

This PR changes how we handle the new import conflict handling so we process saved searches separately from other objects (like dashboards and visualizations) to ensure that objects imported that reference saved searches resolve properly.

Specifically, this PR separates saved object import conflicts for saved searches from other saved objects (dashboards, visualizations). This separation then allows us to process the saved searches first to ensure those are written before we attempt to process other saved objects, which could rely on those saved searches to exist.

@tylersmalley
Copy link
Contributor

jenkins, test it

@bhavyarm bhavyarm self-requested a review October 26, 2017 23:29
@bhavyarm
Copy link
Contributor

bhavyarm commented Oct 26, 2017

Copied the src/core_plugins/kibana/public/management/sections/objects/_objects.js to my local and tested the blocker #14592. Import works fine now for my export.json in the bug 14592.

Copy link
Contributor

@bhavyarm bhavyarm left a comment

Choose a reason for hiding this comment

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

LGTM ( I tested the blocker)

Copy link
Contributor

@cjcenizal cjcenizal left a comment

Choose a reason for hiding this comment

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

I haven't tested this in the browser but overall this LGTM! I have some suggestions on ways to make the code more readable, but nothing here is a blocker.

return;
}
if (swallowErrors && err instanceof SavedObjectNotFound) {
if (err.savedObjectType === 'search') {
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor nit, but a switch seems to make slightly more sense here:

                      switch (err.savedObjectType) {
                        case 'search':
                          conflictedSearchDocs.push(doc);
                          return;
                        case 'index-pattern':
                          conflictedIndexPatterns.push({ obj, doc });
                          return;

@@ -205,8 +205,9 @@ uiModules.get('apps/management')
})
.then((overwriteAll) => {
const conflictedIndexPatterns = [];
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add a comment above these to provide some context?

// We'll collect all index patterns which {don't correspond to a saved object? are missing? I'm not sure},
// so we can ask the user to {resolve them? reassign them?}. We'll also collect all saved searches
// which {don't correspond exist?}, so we can ask the user to {resolve them? recreate them?}.
const conflictedIndexPatterns = [];
const conflictedSearchDocs = [];

Copy link

Choose a reason for hiding this comment

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

// Collect all index patterns and saved searches referenced in other documents, like visualizations,
// but which have not been imported yet.

Copy link

Choose a reason for hiding this comment

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

I think the naming here is a tad confusing. It makes more sense to call a set of index-patterns that could be associated with a savedsearch conflictedIndexPatterns, but doesn't make sense for savedsearches. The searchDocs are not conflicted. They just don't exist yet, haven't been imported yet, and so visualizations that reference them can't be imported.

Ideas:
referencedSavedSearches --> the viz references it. that's all we can say for sure.
notYetImportedSavedSearches --> this assumes that they will be imported. it could be that someone fucked with the id and the savedsearch doesn't actually exist.
referencedAndNotFoundSavedSearches -- verbose but accurate?

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 added some comments, does that help clarify this?


function importDocument(doc) {
function importDocument(swallowErrors, doc) {
Copy link
Contributor

@cjcenizal cjcenizal Oct 26, 2017

Choose a reason for hiding this comment

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

I mentioned this to @chrisronline on Slack. The side effects of pushing docs into conflictedIndexPatterns and conflictedSearchDocs into this function make it difficult to follow the flow of the code, especially since we call this function later and pass in conflictedSearchDocs.

It looks like the logic within the if (swallowErrors ...) conditional is the only part which changes from call site to call site. Can we extract this logic into its own function and pass that function in when we need it?

const oldIndexId = obj.searchSource.getOwn('index');
const newIndexId = objs.find(({ oldId }) => oldId === oldIndexId).newId;
if (newIndexId === oldIndexId) {
// Skip
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add a few words here to elaborate? e.g. The index hasn't changed (or whatever conclusion we can draw from this equality check) so we don't need to {do whatever it is we're doing on line 275}.

@rhoboat rhoboat self-requested a review October 26, 2017 23:49
@rhoboat
Copy link

rhoboat commented Oct 26, 2017

Please wait.. i'm testing this as well...

Copy link

@rhoboat rhoboat left a comment

Choose a reason for hiding this comment

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

Couple of naming things, but otherwise, looks good enough for solving this blocker. But I really don't like the code style. If I have some more time, I'll post a refactor PR.

@@ -205,8 +205,9 @@ uiModules.get('apps/management')
})
.then((overwriteAll) => {
const conflictedIndexPatterns = [];
Copy link

Choose a reason for hiding this comment

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

// Collect all index patterns and saved searches referenced in other documents, like visualizations,
// but which have not been imported yet.

@@ -205,8 +205,9 @@ uiModules.get('apps/management')
})
.then((overwriteAll) => {
const conflictedIndexPatterns = [];
Copy link

Choose a reason for hiding this comment

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

I think the naming here is a tad confusing. It makes more sense to call a set of index-patterns that could be associated with a savedsearch conflictedIndexPatterns, but doesn't make sense for savedsearches. The searchDocs are not conflicted. They just don't exist yet, haven't been imported yet, and so visualizations that reference them can't be imported.

Ideas:
referencedSavedSearches --> the viz references it. that's all we can say for sure.
notYetImportedSavedSearches --> this assumes that they will be imported. it could be that someone fucked with the id and the savedsearch doesn't actually exist.
referencedAndNotFoundSavedSearches -- verbose but accurate?

conflictedIndexPatterns.push({ obj, doc });
return;
}
}
// swallow errors here so that the remaining promise chain executes
Copy link

Choose a reason for hiding this comment

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

This is so confusing now. I get that we want to swallow errors in the original code--so we can continue execution and use notify. But the fact that we do that makes passing in a new arg called swallowErrors not make much sense. Its purpose is to avoid hitting the notify line. Maybe a better name for that arg is handleConflicts or collectDocsNotFound.

Copy link

@rhoboat rhoboat left a comment

Choose a reason for hiding this comment

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

Couple of naming things, but otherwise, looks good enough for solving this blocker. But I really don't like the code style. If I have some more time, I'll post a refactor PR.

@epixa
Copy link
Contributor

epixa commented Oct 27, 2017

@chrisronline Can you forward port this today?

chrisronline added a commit to chrisronline/kibana that referenced this pull request Oct 27, 2017
chrisronline added a commit to chrisronline/kibana that referenced this pull request Oct 27, 2017
@chrisronline
Copy link
Contributor Author

@epixa Sure thing. PRs open and will merge on green CI.

@chrisronline chrisronline deleted the fix/import_export_saved_searches branch October 27, 2017 14:08
chrisronline added a commit that referenced this pull request Oct 27, 2017
* Port fixes from #14625 to 6.x

* Adding missing test file

* Fix linting issue
chrisronline added a commit that referenced this pull request Oct 27, 2017
* Port fixes from #14625 to 7.0

* Fix linting issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants