Skip to content

Allow replacing a draft file#7337

Merged
kcondon merged 26 commits intoIQSS:developfrom
QualitativeDataRepository:IQSS/7149-Replace_file_in_draft
Mar 22, 2021
Merged

Allow replacing a draft file#7337
kcondon merged 26 commits intoIQSS:developfrom
QualitativeDataRepository:IQSS/7149-Replace_file_in_draft

Conversation

@qqmyers
Copy link
Copy Markdown
Member

@qqmyers qqmyers commented Oct 16, 2020

What this PR does / why we need it: Enables replacing a file in draft, keeping the file metadata except label by default (user can then edit before saving if desired). (Note - not using the old file name is both because it is confusing and because one of the use cases is to, for example, replace a doc file with a pdf-a version that needs a different extension to get proper mimetyping).

Which issue(s) this PR closes:

Closes #7149
Closes #4380

Special notes for your reviewer: Also ties to #3913. There was some discussion about using a different name instead of 'replace' for this since the effect is slightly different for draft files when there is no prior released version (the new file gets the DOI of the old file because the old one is fully deleted, versus the new file getting a new DOI). Thinking through this further, it seems to be weirder to me to have ~replace on a draft file get called two different things depending on whether a released version exists, and it seems fairly natural to me for the DOI to be reused when it can. I also don't know what else I would call this. If there's still interest in making this a separate call and there's a name suggestion, I can update the PR.

Suggestions on how to test this: Replace of published files should work as before, but it should be possible to replace a file in a draft version as well. When doing so, metadata including description, tags, categories, path, on the file should remain by default (and be editable prior to hitting save as normal). Replacing a file that is only available in draft should delete the replaced file entry in the db and remove the physical file file from storage. The new file should retain the DOI of the one removed. Replacing a file in draft that has previously been released should not remove the old file (still available in prior versions) and it should get a new DOI.

Should work in both UI and API.

Should also text that #5847 (comment) doesn't reappear as this PR reverts one of the changes made in that issue (hopefully compensating to address the problem in a different way).

Does this PR introduce a user interface change? If mockups are available, please link/include them here: replace option available for draft files, file metadata is retained from replaced file by default.

Is there a release notes update needed for this change?:

Additional documentation:

@coveralls
Copy link
Copy Markdown

coveralls commented Oct 16, 2020

Coverage Status

Coverage decreased (-0.009%) to 19.472% when pulling 4ba1080 on QualitativeDataRepository:IQSS/7149-Replace_file_in_draft into d167418 on IQSS:develop.

@djbrooke djbrooke self-assigned this Oct 19, 2020
when replacing a draft-only file that was already a replacement itself
@djbrooke djbrooke removed their assignment Oct 20, 2020
@qqmyers
Copy link
Copy Markdown
Member Author

qqmyers commented Oct 20, 2020

OK some notes on integration test failures:

A couple were related to the PR code (a bug and a test that expected an error when trying to replace a draft file which now succeeds). The rest appear to be unrelated to the PR code (which was fun to debug since other branches appear to pass the tests - in some cases that appears to be timing and in others because build failures lead to IT tests not running without the green/red pass/fail indicator turning red.)

A couple appear to be intermittent and probably related to timing: a second call to update a dataset fails when the same API call works manually. E.g. test_006_ReplaceFileGood and testForceReplaceAndUpdate in a recent build. I suspect that these need the same type of UtilIT.sleepForLock() calls that some of the ingest methods have, though my guess would be that the delay would be shorter. These have been added. (testCuratorSendsCommentsToAuthor also failed that build with a wait for lock error so things were definitely slow).

Two others appear to be cases where the code and tests had ~matching minor errors (in 5.1.1 but the code in question is several years old so probably before that as well). In testAddFileBadJson and testReplaceFileBadJson, sending some types of bad json (such as a simple string in the tests) resulted in a 200/OK status and the file being added when it presumably should have failed due to bad json. The code was catching, logging, and ignoring a ClassCastException to do that. Other types of bad json, such as "{}:string" did fail but weren't tested. In the updated code, I stopped catching the ClassCastException in OptionalFileParams and then caught both that and the possible json parsing exception in the same clause in the calling classes to generate a 400 error (now with a Bundle message!). The behavior of the code and tests should match.

@qqmyers qqmyers marked this pull request as draft October 21, 2020 15:42
@qqmyers qqmyers marked this pull request as ready for review October 23, 2020 19:09
@qqmyers
Copy link
Copy Markdown
Member Author

qqmyers commented Oct 23, 2020

OK, after significantly more work this week, I think this is ready to go. To get the new and existing functionality to all work, I had to dig back into the merge issues brought up in #5847 and I think I understand more, if not all of the problems that could occur in that code/ all of the different input states (in terms of whether filemetadata, datafiles, datasetversions are persisted, merged, not merged coming into the code). The rewrite of the file delete code has more commenting that can hopefully guide anyone making changes after this.

To get all of the tests to work, I had to do some further tweaking to the sleepForLock code to handle null for the lock type. In doing that I realized that when the replace api call fails due to a lock it appears to still send an OK, but fails the test due to differences in what's in the "data" part of the response.

There, and a few other places, I've added a ToDo - if any of those are worth adding an issue for, they could probably be small ones.

@djbrooke
Copy link
Copy Markdown
Contributor

Thanks @qqmyers - moving to code review

@sekmiller sekmiller self-assigned this Oct 27, 2020
Comment thread src/main/webapp/file.xhtml Outdated
</ui:fragment>
<ui:fragment rendered="#{FilePage.fileMetadata.dataFile.released and FilePage.draftReplacementFile == false and !FilePage.fileMetadata.dataFile.filePackage}">
<ui:fragment rendered="#{FilePage.draftReplacementFile == false and !FilePage.fileMetadata.dataFile.filePackage}">
<li><!-- start: replace file link -->
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We're getting multiple replace file links here because of the change in render. Once a released file has been replaced it can be replaced again, so taking out the "isReleased" gets two Replace links to render

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Good catch. The problem is the next lines though - the second Replace button that would trigger the warning dialog to not replace a file that's already being replaced in the draft version was showing and it shouldn't have. For now, I've just adjusted the logic there (only show the dialog if there is a draft replacement for the file, which is not true for the replacing file.)

The logic is simpler too. FWIW, I went back about 4 years in github to see if I could find out why the current terms were in there and didn't find a clear reason, so perhaps someone else might have a better sense and be able to see if there's anything my change misses?

However, I'm also not sure that dialog is needed anymore - a file that has been replaced in the latest version now shows a dialog when you click the 'Edit' button itself, so you never get to the individual menu items like replace and delete and therefore can't trigger the dialogs related to them. If it's true that there is no way to get to those items for a file that has been replaced/deleted in the current version, they (those replace and delete items and the dialogs they trigger) should probably be deleted (new issue?).

// There are two datafile cases as well - the file has been released, so we're
// jsut removing it from the current draft version or it is only in the draft
// version and we completely remove the file.
if (!fmd.getDataFile().isReleased()) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Getting a null pointer here when I try to delete a file via the EditDataFilesPage from the Dataset Page. Will investigate further.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@sekmiller - The new commits should fix this - the test of the two dataset versions in line 208 needed to use ! .equals() instead of !=, and then an fmd merge was needed (removing the else around line 212.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ok. i'm able to delete a file from a draft version. Thanks!

Conflicts:
	src/main/java/edu/harvard/iq/dataverse/engine/command/impl/UpdateDatasetVersionCommand.java
// datafile
if (fmToDelete.getDataFile().getStorageIdentifier().equals(fmd.getDataFile().getStorageIdentifier())) {
// and a match on the datasetversion
if (fmToDelete.getDatasetVersion().getId() == null) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Getting a null pointer here when I try the uncommon, but previously supported, action of uploading a number of files, but then deleting one before saving the rest to the draft version

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Resolved - the new util method assumed that an fmd would always have an associated datasetversion which is not true for this case. - BTW - thanks for the thorough testing!

Copy link
Copy Markdown
Contributor

@sekmiller sekmiller left a comment

Choose a reason for hiding this comment

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

Looks good overall. Thanks Jim, for addressing the issues I've found. Gustavo asked me to keep it out of QA for now pending the merging of kebabs and any notes coming from design.

@djbrooke djbrooke assigned djbrooke and unassigned sekmiller Nov 2, 2020
qqmyers added a commit to QualitativeDataRepository/dataverse that referenced this pull request Nov 4, 2020
@kcondon sees a DB error persisting a file with null createtime during
the GlobalIDServiceBean.getBean call which uses a set namedQuery to find
the :DoiProvider. Create times for files are set above, but not merged
prior to calling registerFilePidsIfNeeded. Assuming the namedQuery is
forcing the file (without a merge) to persist which triggers the error.
In IQSS#7337, the code is reworked so there is a merge prior to
registerFilePidsIfNeeded. This commit adds one temporarily so this PR
works indepdently of the other.
IQSS/7149-Replace_file_in_draft

Conflicts:
	src/main/webapp/file.xhtml
IQSS/7149-Replace_file_in_draft

Conflicts:
	src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java
IQSS/7149-Replace_file_in_draft

Conflicts:
	src/main/java/edu/harvard/iq/dataverse/datasetutility/FileReplacePageHelper.java
	src/main/java/propertyFiles/Bundle.properties
@djbrooke
Copy link
Copy Markdown
Contributor

djbrooke commented Mar 8, 2021

@TaniaSchlatter at long last I've gotten the ability to spin up EC2 instances on my laptop, and I've stood up this branch on AWS. It works as I expect. A few weeks ago I had flagged this for UI/UX review as it enables the workflow to replace draft files and to retain metadata on replace, which @qqmyers has outlined above.

If you'd like to review let me know. I don't want to keep the instance up and incur cost, so I'll spin it down for now, but let me know when you're ready to take a look and I'll spin up another instance. I'll need ~20 min to get the instance going so just give me a little warning and we can step through it together or you can review independently.

@TaniaSchlatter
Copy link
Copy Markdown
Member

Reviewed the AWS instance. It would be consistent to have Replace in the kebab on the file table on the dataset page, as well as under "Edit" on the file page.
replace_draft_file_pages

@djbrooke
Copy link
Copy Markdown
Contributor

Thanks @TaniaSchlatter - that's covered in #7376 so we'll implement this with the current workflows and get the consistency on entry points across dataset kebab/file page in #7376.

@djbrooke
Copy link
Copy Markdown
Contributor

After some discussion, I'm going to move this to QA.

We'll reopen #7343 to add replace as a small, uncontroversial chunk towards the larger effort in #7376, which requires some research and decisions.

@djbrooke djbrooke removed their assignment Mar 18, 2021
@kcondon kcondon self-assigned this Mar 22, 2021
@kcondon kcondon merged commit 2e4fd4c into IQSS:develop Mar 22, 2021
@djbrooke djbrooke added this to the 5.4 milestone Mar 23, 2021
stevenwinship pushed a commit that referenced this pull request Aug 15, 2024
* file pid reservation

* add file pid reservation step to publish

(analogous to dataset pid register if needed)

Conflicts:
	src/main/java/edu/harvard/iq/dataverse/engine/command/impl/UpdateDatasetVersionCommand.java
	src/main/java/propertyFiles/Bundle.properties

* comment change

* check if file PIDs used once, use constants - per comments

* adding release note

* release notes, API doc update

* reflecting datasets and files for the PID endpoint

* removing release note about pre-reg for file PIDs as this is not supported

* file pid pre-reservation

Conflicts:
	src/main/java/edu/harvard/iq/dataverse/engine/command/impl/AbstractDatasetCommand.java
	src/main/java/propertyFiles/Bundle.properties

* avoid problem when GlobalIDServiceBean implicitly merges

@kcondon sees a DB error persisting a file with null createtime during
the GlobalIDServiceBean.getBean call which uses a set namedQuery to find
the :DoiProvider. Create times for files are set above, but not merged
prior to calling registerFilePidsIfNeeded. Assuming the namedQuery is
forcing the file (without a merge) to persist which triggers the error.
In #7337, the code is reworked so there is a merge prior to
registerFilePidsIfNeeded. This commit adds one temporarily so this PR
works indepdently of the other.

* update theDataset

* noting that PID reservation can cause old timeouts to be too short

* more specifics

* release note update

* cleanup reformatting

* further cleanup

* set createTime earlier

---------

Co-authored-by: Danny Brooke <danny_brooke@harvard.edu>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

7 participants