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
Disallow tombstone purge in AG and allow PUT overtop of tombstones #2044
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works as described. I did note that the OPTIONS for tombstones of AG children still only show DELETE
.
> curl -u fedoraAdmin:fedoraAdmin -XOPTIONS -i http://localhost:8080/rest/new_ag2/ag_child_delete/fcr:tombstone
HTTP/1.1 200 OK
Date: Fri, 15 Sep 2023 20:44:33 GMT
Set-Cookie: JSESSIONID=node0vx6o8r0p1s67b4937oddb5km22.node0; Path=/
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Set-Cookie: rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Thu, 14-Sep-2023 20:44:33 GMT; SameSite=lax
Allow: DELETE
Content-Length: 0
Server: Jetty(9.4.44.v20210927)
I'm not sure but it should probably be PUT, except it only works with the required header.
@whikloj the PUT is going on the resource so do we need to update the allow header for the tombstone? I guess it's a little odd because you get the tombstone back from querying the resource, and that's also where I put the logic doing a PUT over top of the tombstone. I think it's ok to omit PUT as it isn't happening on the tombstone itself. Actually another odd thing with the allow headers, for archive groups DELETE won't be allowed so I think we would want to remove it for that case. Otherwise I suppose we could change the response code, even though 405 does seem to make the most sense. |
@whikloj I just pushed a commit to update the OPTIONS when querying on
For both of these I'm not sure if we want to update to maybe return a 204 (or 200) + empty Allow header, or leave as is. I also checked for deleting the tombstone of an archive group and saw it is tested for in FedoraTombstonesIT. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Functionally this works, just some questions.
fcrepo-http-api/src/main/java/org/fcrepo/http/api/ContentExposingResource.java
Outdated
Show resolved
Hide resolved
final var created = new AtomicBoolean(false); | ||
|
||
if ((resourceExists && resource() instanceof Binary) || | ||
(!resourceExists && isBinary(interactionModel, | ||
if ((resourceExists && (isBinaryTombstone(overwriteTombstone) || resource() instanceof Binary)) || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isBinaryTombstone()
replicates the actions above (line 480-483) and then compares resource instanceof Binary
.
Here we are testing resource()
and resource
could we just do
if ((resourceExists && resource instanceof Binary) ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the use of resource()
everywhere made me want to stick with that, but overall I see what you're saying. I'll see about refactoring a bit so that we can use resource
so that we don't need to re-check for conditions we've already met.
response.allow("DELETE"); | ||
} | ||
|
||
return response.build(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works for OPTIONS requests, though for Archival Group members you get a blank header
Allow:
But we still return
Allow: DELETE
for all the other methods that return a 406 Method Not Allowed
. This is built in the methodNotAllowed()
on lines 147-149.
@whikloj I just finished making changes based on your feedback, everything should be resolved now. I double checked the headers when returning the 405 on fcr:tombstone and things look good (DELETE exists for non-ag; omitted for ag). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry @mikejritter this one has many layers.
Everything works... except PUT over the tombstone of an archivalgroup.
That results in a 500 Server Error with a stacktrace of
WARN 08:23:35.896 [qtp1756600221-526] (WildcardExceptionMapper) Unmapped exception
org.fcrepo.storage.ocfl.exception.ValidationException: Resource info:fedora/test_archival_groups/5d35f634-ce53-4706-9578-2965fa21dbba is not a valid Fedora 6 resource. The following problems were identified:
1. Must define property 'archivalGroupId' as 'null' but was 'info:fedora/test_archival_groups/5d35f634-ce53-4706-9578-2965fa21dbba'
at org.fcrepo.storage.ocfl.exception.ValidationException.createForResource(ValidationException.java:39)
at org.fcrepo.storage.ocfl.DefaultOcflObjectSession.validateHeaders(DefaultOcflObjectSession.java:650)
at org.fcrepo.storage.ocfl.DefaultOcflObjectSession.stageHeaders(DefaultOcflObjectSession.java:631)
at org.fcrepo.storage.ocfl.DefaultOcflObjectSession.writeResource(DefaultOcflObjectSession.java:205)
at org.fcrepo.persistence.ocfl.impl.FcrepoOcflObjectSessionWrapper.lambda$writeResource$0(FcrepoOcflObjectSessionWrapper.java:69)
at org.fcrepo.persistence.ocfl.impl.FcrepoOcflObjectSessionWrapper.exec(FcrepoOcflObjectSessionWrapper.java:195)
at org.fcrepo.persistence.ocfl.impl.FcrepoOcflObjectSessionWrapper.lambda$writeResource$1(FcrepoOcflObjectSessionWrapper.java:69)
I realize that the above was me trying to put a normal RDFResource over top the tombstone of an ArchivalGroup, so I also tried PUTting an ArchivalGroup on the tombstone of the ArchivalGroup and that returns 409 Conflict with the stacktrace of
|
In case it helps, I have a Python based set of some tests. I used to use it with Fedora 4 and 5. Trying to get it sorted out for F6, but I added an https://github.com/whikloj/fcrepo4-tests/blob/fcrepo-6/archival_group_tests.py#L149-L190 |
@whikloj I pushed some commits to handle the case of putting over top of an ArchivalGroup's tombstone. I opted to create a new A quick overview of the changes:
|
@@ -527,7 +538,7 @@ public Response createOrReplaceObjectRdf( | |||
} | |||
|
|||
doInDbTx(() -> { | |||
if (resourceExists) { | |||
if (resourceExists && !(resource() instanceof Tombstone)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the future in the interest of speed, would it be faster to set something like
boolean $isTombstone = resource instanceof Tombstone;
up at line 482, then we won't have to reload the object here or below to determine if the original resource was a tombstone?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe just adding a TODO:
to check this out, because it is possible that the caching in the OCFL layer makes this a non-issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like I was going to use isTombstoneOverwrite
here. Not sure why I didn't, we know it should have been checked because both places also rely on resourceExists
to be true. IDK I might look into this a bit more and make a new ticket/PR.
JIRA Ticket:
https://fedora-repository.atlassian.net/browse/FCREPO-3881
https://fedora-repository.atlassian.net/browse/FCREPO-3883
Other Relevant Links (Mailing list discussion, related pull requests, etc.)
https://fedora-repository.atlassian.net/browse/FCREPO-3866
What does this Pull Request do?
This PR covers two tickets for updating the behavior of tombstones, which came from discussions of how Archive Groups behave and how to update for certain scenarios (e.g. PUT-DEL-PUT). The main behavior changes are disallowing DELETEs of tombstones in Archival Groups and allowing PUT overtop of tombstones for both AGs and Atomic resources.
How should this be tested?
I had a couple of test cases for validating behavior:
3881 - DELETE of Tombstone in an AG
3883 - PUT overtop of Tombstone
Overwrite-Tombstone: true
header set - should return 201Overwrite-Tombstone: false
header set - should return 410 (this is the response we currently give)Link: <http://www.w3.org/ns/ldp#DirectContainer>;rel=\"type\"
Interested parties
Tag (@ mention) interested parties or, if unsure, @fcrepo/committers