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

add option to confirm overwrite on save #9659

Merged
merged 4 commits into from Dec 30, 2016

Conversation

stacey-gammon
Copy link
Contributor

fixes #9589 and adds tests

@@ -158,7 +158,7 @@ uiModules.get('apps/management')
return service.get().then(function (obj) {
obj.id = doc._id;
return obj.applyESResp(doc).then(function () {
return obj.save();
return obj.save(true);
Copy link
Member

Choose a reason for hiding this comment

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

I usually try to stick to having an options object parameter in a function definition, and have the calling code use something like:

obj.save({ confirmOverwrite: true });

It helps readability a ton, because a simple boolean parameter is always ambiguous. There are a lot of things the reader might think it means.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

makes a lot of sense, I like it. Updated!


/**
* @typedef {Object} SaveOptions
* @property {boolean} confirmOverwrite=false - If true, attempts to create the source so it
Copy link
Member

Choose a reason for hiding this comment

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

minor, but the comment isn't accurate any more

Copy link
Contributor Author

Choose a reason for hiding this comment

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

cleaned up

@stacey-gammon
Copy link
Contributor Author

stacey-gammon commented Dec 27, 2016

jenkins test this

Test failure looks irrelevant to this PR and probably a transitory failure:

ERROR: Build step failed with exception
com.amazonaws.SdkClientException: Unable to execute HTTP request: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
	at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:972)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:676)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:650)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:633)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$300(AmazonHttpClient.java:601)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:583)
	at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:447)
	at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4137)
	at com.amazonaws.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:1685)
	at com.amazonaws.services.s3.transfer.internal.UploadCallable.uploadInOneChunk(UploadCallable.java:133)
	at com.amazonaws.services.s3.transfer.internal.UploadCallable.call(UploadCallable.java:125)
	at com.amazonaws.services.s3.transfer.internal.UploadMonitor.call(UploadMonitor.java:139)
	at com.amazonaws.services.s3.transfer.internal.UploadMonitor.call(UploadMonitor.java:47)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
	at ......remote call to Channel to /10.34.148.136(Native Method)
	at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1537)
	at hudson.remoting.UserResponse.retrieve(UserRequest.java:253)
	at hudson.remoting.Channel.call(Channel.java:822)
	at hudson.FilePath.act(FilePath.java:985)
	at hudson.FilePath.act(FilePath.java:974)
	at hudson.plugins.s3.S3Profile.invoke(S3Profile.java:201)
	at hudson.plugins.s3.S3Profile.waitUploads(S3Profile.java:195)
	at hudson.plugins.s3.S3Profile.upload(S3Profile.java:174)
	at hudson.plugins.s3.S3BucketPublisher.perform(S3BucketPublisher.java:198)
	at hudson.tasks.BuildStepCompatibilityLayer.perform(BuildStepCompatibilityLayer.java:78)
	at hudson.tasks.BuildStepMonitor$2.perform(BuildStepMonitor.java:32)
	at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:779)
	at hudson.model.AbstractBuild$AbstractBuildExecution.performAllBuildSteps(AbstractBuild.java:720)
	at hudson.model.Build$BuildExecution.post2(Build.java:185)
	at hudson.model.AbstractBuild$AbstractBuildExecution.post(AbstractBuild.java:665)
	at hudson.model.Run.execute(Run.java:1754)
	at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
	at hudson.model.ResourceController.execute(ResourceController.java:98)
	at hudson.model.Executor.run(Executor.java:404)

@tsullivan
Copy link
Member

I haven't pulled this in to test, but it looks good to me code-wise

@tsullivan tsullivan removed their assignment Dec 29, 2016
.catch((err) => {
// record exists, confirm overwriting
if (_.get(err, 'origError.status') === 409) {
const confirmMessage = 'Are you sure you want to overwrite ' + this.title + '?';
Copy link
Contributor

Choose a reason for hiding this comment

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

this.title here is actually the title of the imported visualization, not the original one, so if the title in the imported JSON is different, the message is wrong. I poked at this quickly, but I'm not sure how to get the title of the record being replaced...

Copy link
Contributor

Choose a reason for hiding this comment

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

Huh, worse than the message being wrong, it will actually warn me it's going to override a document, and then it doesn't. Is the import still matching on the title instead of the id?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The import is matching on the id, not the title.

Good catch on the error message. What if it said Are you sure you want to overwrite the object with id 50416250-cdf6-11e6-8394-6511ff44915a and replace it with Newest Dashboard??

Pretty ugly and I hate exposing the id. :( I suppose I could change the logic and make a get query to es before the doCreate and check for document existence that way, but that might be overkill.

For what it's worth, this preserves the old logic which did the same exact thing, so at least we are no worse off than we were before. I'm leaning towards leaving it as is and filing an issue to improve the error message as a separate issue. This is at least better than no overwrite warning.

// the test environment to hang.
function ($provide) {
$provide.decorator('safeConfirm', () => {
return (message) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

"If your arrow function is only returning an object literal, then wrap the object in paranthesis rather than using an explicit return"

https://github.com/elastic/kibana/blob/master/style_guides/js_style_guide.md#arrow-functions

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Interesting, I didn't know you could do that. But does that fit here? I'm returning a function, not an object literal.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

nevermind, looks like it works on any single return, not just object literal. Though I wonder if the style guide applies to all or just object literals. Anyway, updated.

const confirmMessage = 'Are you sure you want to overwrite ' + this.title + '?';

return safeConfirm(confirmMessage).then(
() => { return docSource.doIndex(source); },
Copy link
Contributor

Choose a reason for hiding this comment

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

https://github.com/elastic/kibana/blob/master/style_guides/js_style_guide.md#arrow-functions

The styleguide seems to prefer implicit returns. I'd prefer to see this as a .then/.catch, but it's your call.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done! Didn't know about that.


return safeConfirm(confirmMessage).then(
() => { return docSource.doIndex(source); },
() => { throw { confirmRejected : true }; }
Copy link
Contributor

Choose a reason for hiding this comment

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

Throwing an object? Why not an error?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

guess I didn't want to do a string comparison, but it does look a bit weird. Done.

@@ -88,11 +88,11 @@ describe('Saved Object', function () {
// The default implementation of safeConfirm uses $timeout which will cause
// the test environment to hang.
function ($provide) {
$provide.decorator('safeConfirm', () => {
return (message) => {
$provide.decorator('safeConfirm', () =>
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this got really confusing now. The shortest form of what you have here would be:

$provide.decorator('safeConfirm', () => message => window.confirm(message) ? Promise.resolve() : Promise.reject());

If you're against the implicit return of a function (and I can see why you might be), something like this would also work:

const resolveConfirm = message => window.confirm(message) ? Promise.resolve() : Promise.reject();
$provide.decorator('safeConfirm', () => resolveConfirm);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah right, two implicit returns. :) yea, this is getting confusing, opted for the second version.

@w33ble
Copy link
Contributor

w33ble commented Dec 29, 2016

Our conversation on the importing got collapsed :(

Good catch on the error message. What if it said Are you sure you want to overwrite the object with id 50416250-cdf6-11e6-8394-6511ff44915a and replace it with Newest Dashboard?? Pretty ugly and I hate exposing the id. :(

I agree, exposing the ID isn't right either, we don't show that to the user, and it means nothing, so it's not helpful. As you point out, this isn't a new problem, I'm fine punting on it. I'll make a new issue.

The import is matching on the id, not the title.

Strange. I don't know what I did differently, the copying of saved objects isn't happening for me anymore now. Previously I did this:

  • Export a saved vis
  • Edit the exported JSON and change the title
  • Import the JSON file

I was prompted about overwriting the saved vis, which is expected, but when it got imported, I now had 2 saved visualizations, the old one and the renamed one I just imported.

@stacey-gammon
Copy link
Contributor Author

@w33ble That is really strange. So you are saying it wasn't working at first, but now you can't repro and it is working as expected? Is it possible you accidentally altered the id when you were changing the title? I know it sounds unlikely but those steps work as expected for me. If you can still repro the issue, let me know.

@w33ble
Copy link
Contributor

w33ble commented Dec 29, 2016

Correct, it was wonky before, but now I can't get it to happen again. I only had 1 saved thing, and only changed the title. I have no idea why the ID would have changed... maybe I updated the saved ID some other way or something? But that wouldn't really explain why I got an overwrite notification.

So strange, but since it's not happening anymore, 🤷‍♂️

@w33ble
Copy link
Contributor

w33ble commented Dec 29, 2016

LGTM!

@stacey-gammon
Copy link
Contributor Author

@ycombinator or @tsullivan, one of you able to give this a final look today? 🙏

@tsullivan
Copy link
Member

conflicts in the branch

- implicit returns from arrow function
- throw an error not an object

clean up implicit return confusion

use promise.reject instead of throw.
@tsullivan
Copy link
Member

  • Export a saved vis
  • Edit the exported JSON and change the title
  • Import the JSON file

FWIW I tried this (using a saved search instead of a vis), and the saved search I had in my system was overwritten with a saved search having the new title

@tsullivan
Copy link
Member

This is probably minor, but when I tried the steps above, the confirmation asks me if I want to overwrite the saved search, but it uses the changed name of the search in the confirm dialog.

image

The saved search in my system is titled Avocado Tweets, and the saved search I'm importing with the same ID is titled Avocado Tweets - RENAMED.

Could the message instead use the title of my existing search?

@stacey-gammon
Copy link
Contributor Author

@tsullivan Unfortunately it's not very simple to use the original name - I'd have to modify the es query to retrieve it. @w33ble mentioned the same issue above and created another ticket for it (#9680).
This is how Kibana always functioned, it's not a regression bug, so I decided to leave as is for this PR and address that issue separately.

@tsullivan
Copy link
Member

LGTM!

@stacey-gammon
Copy link
Contributor Author

aborted build

Aborted by unknown
Publish artifacts to S3 Bucket Skipping publishing on S3 because build aborted
Finished: ABORTED

jenkins test this

@stacey-gammon stacey-gammon merged commit e75e2a2 into elastic:master Dec 30, 2016
elastic-jasper added a commit that referenced this pull request Jan 2, 2017
Backports PR #9659

**Commit 1:**
add option to confirm overwrite on save

* Original sha: 5875c15
* Authored by Stacey Gammon <gammon@elastic.co> on 2016-12-27T14:29:48Z

**Commit 2:**
Make save options instead of using a boolean to increase readability.

* Original sha: 1701b9c
* Authored by Stacey Gammon <gammon@elastic.co> on 2016-12-27T21:07:56Z

**Commit 3:**
clean up comment

* Original sha: bc2b9b1
* Authored by Stacey Gammon <gammon@elastic.co> on 2016-12-27T21:14:43Z

**Commit 4:**
Address code comments

- implicit returns from arrow function
- throw an error not an object

clean up implicit return confusion

use promise.reject instead of throw.

* Original sha: 8e43346
* Authored by Stacey Gammon <gammon@elastic.co> on 2016-12-29T19:11:50Z
elastic-jasper added a commit that referenced this pull request Jan 3, 2017
Backports PR #9659

**Commit 1:**
add option to confirm overwrite on save

* Original sha: 5875c15
* Authored by Stacey Gammon <gammon@elastic.co> on 2016-12-27T14:29:48Z

**Commit 2:**
Make save options instead of using a boolean to increase readability.

* Original sha: 1701b9c
* Authored by Stacey Gammon <gammon@elastic.co> on 2016-12-27T21:07:56Z

**Commit 3:**
clean up comment

* Original sha: bc2b9b1
* Authored by Stacey Gammon <gammon@elastic.co> on 2016-12-27T21:14:43Z

**Commit 4:**
Address code comments

- implicit returns from arrow function
- throw an error not an object

clean up implicit return confusion

use promise.reject instead of throw.

* Original sha: 8e43346
* Authored by Stacey Gammon <gammon@elastic.co> on 2016-12-29T19:11:50Z
tylersmalley pushed a commit to tylersmalley/kibana that referenced this pull request Jan 3, 2017
* add option to confirm overwrite on save

* Make save options instead of using a boolean to increase readability.

* clean up comment

* Address code comments

- implicit returns from arrow function
- throw an error not an object

clean up implicit return confusion

use promise.reject instead of throw.
stacey-gammon pushed a commit that referenced this pull request Jan 4, 2017
* add option to confirm overwrite on save

* Make save options instead of using a boolean to increase readability.

* clean up comment

* Address code comments

- implicit returns from arrow function
- throw an error not an object

clean up implicit return confusion

use promise.reject instead of throw.
@stacey-gammon stacey-gammon deleted the confirm-overwrite-on-save branch January 19, 2017 20:20
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.

Importing a saved object no longer warns on conflict
5 participants