This document is to clarify the differences between the ideas of "deleting" a resource from Fedora and "purging" a resource from Fedora.
Delete
When you delete a resource from Fedora it is replaced by a "tombstone" that is returned when you try to access the resource.
Click here to expand...
For example
> curl -ufedoraAdmin:fedoraAdmin -XPOST -H"Slug: test-resource" http://localhost:8080/rest
http://localhost:8080/rest/test-resource
> curl -ufedoraAdmin:fedoraAdmin http://localhost:8080/rest/test-resource
<http://localhost:8080/rest/test-resource>
<http://fedora.info/definitions/v4/repository#created> "2023-07-14T14:15:03.983572Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> ;
<http://fedora.info/definitions/v4/repository#lastModified> "2023-07-14T14:15:03.983572Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> ;
<http://fedora.info/definitions/v4/repository#createdBy> "fedoraAdmin" ;
<http://fedora.info/definitions/v4/repository#lastModifiedBy> "fedoraAdmin" ;
a <http://www.w3.org/ns/ldp#BasicContainer> ;
a <http://www.w3.org/ns/ldp#Resource> ;
a <http://fedora.info/definitions/v4/repository#Resource> ;
a <http://www.w3.org/ns/ldp#RDFSource> ;
a <http://www.w3.org/ns/ldp#Container> ;
a <http://fedora.info/definitions/v4/repository#Container> .
> curl -ufedoraAdmin:fedoraAdmin -i -XDELETE http://localhost:8080/rest/test-resource
HTTP/1.1 204 No Content
Date: Fri, 14 Jul 2023 14:26:46 GMT
Set-Cookie: JSESSIONID=node0ey3immwbcxm49ixqt9un0vbv2.node0; Path=/
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Set-Cookie: rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Thu, 13-Jul-2023 14:26:46 GMT; SameSite=lax
Server: Jetty(9.4.44.v20210927)
> curl -ufedoraAdmin:fedoraAdmin -i http://localhost:8080/rest/test-resource
HTTP/1.1 410 Gone
Date: Fri, 14 Jul 2023 14:27:19 GMT
Set-Cookie: JSESSIONID=node01k1ft2kt2jxez1glanmybctn124.node0; Path=/
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Set-Cookie: rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Thu, 13-Jul-2023 14:27:19 GMT; SameSite=lax
Link: <http://localhost:8080/rest/test-resource/fcr:tombstone>; rel="hasTombstone"
Content-Type: text/plain
Content-Length: 89
Server: Jetty(9.4.44.v20210927)
Discovered tombstone resource at /test-resource, departed at: 2023-07-14T14:26:46.319886Z
The tombstone serves two purposes, the first is identify that a resource did exist at this URI but is no longer there and the second is to stop the reuse of the URI. Some of the reasons for this design decision come from the Tim Berners-Lee article Cool URIs don't change.
At the OCFL layer a tombstone is indicated as a change in the Fedora Header File for the deleted resource. Fedora uses these sidecar files to track information the application needs for each resource. Nothing is removed when the object is "deleted" instead the sidecar file fcr-root.json file is updated to change the value of the "deleted" key from "false" to "true" (as well as the "lastModifiedDate" value)
.
└── ocfl-root/5ce/631/395/5ce63139564a3a617705f0169f200433debd2dd4b63b3fb583a5fe9f7de76539/
├── 0=ocfl_object_1.1
├── inventory.json
├── inventory.json.sha512
├── v1/
│ ├── inventory.json
│ ├── inventory.json.sha512
│ └── content/
│ ├── fcr-container.nt
│ └── .fcrepo/
│ └── fcr-root.json
└── v2/
├── inventory.json
├── inventory.json.sha512
└── content/
└── .fcrepo/
└── fcr-root.json
Purge
It is understandable that in some situations you might want to completely remove a resource and rebuild it. In this situation you need to "purge" the object from your repository. To do this you make a "delete" request to the tombstone itself.
You can find the tombstone's URI by checking the headers returned on the deleted resource.
> curl -ufedoraAdmin:fedoraAdmin -i http://localhost:8080/rest/test-resource
HTTP/1.1 410 Gone
Date: Fri, 14 Jul 2023 14:27:19 GMT
Set-Cookie: JSESSIONID=node01k1ft2kt2jxez1glanmybctn124.node0; Path=/
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Set-Cookie: rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Thu, 13-Jul-2023 14:27:19 GMT; SameSite=lax
Link: <http://localhost:8080/rest/test-resource/fcr:tombstone>; rel="hasTombstone"
Content-Type: text/plain
Content-Length: 89
Server: Jetty(9.4.44.v20210927)
Discovered tombstone resource at /test-resource, departed at: 2023-07-14T14:26:46.319886Z
The Link header in the above response with the rel of hasTombstone gives you the address of the tombstone for the requested resource.
A tombstone only allows a DELETE method, no other interactions are allowed.
Click here to expand...
> curl -ufedoraAdmin:fedoraAdmin -i http://localhost:8080/rest/test-resource/fcr:tombstone
HTTP/1.1 405 Method Not Allowed
Set-Cookie: JSESSIONID=node01r8sh4f8ki6qy1p8yv2n9i0oy09.node0; Path=/
Set-Cookie: rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Thu, 13-Jul-2023 20:09:59 GMT; SameSite=lax
Allow: DELETE
Cache-Control: must-revalidate,no-cache,no-store
Content-Type: text/html;charset=iso-8859-1
Content-Length: 516
Server: Jetty(9.4.44.v20210927)
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/>
<title>Error 405 Method Not Allowed</title>
</head>
<body><h2>HTTP ERROR 405 Method Not Allowed</h2>
<table>
<tr><th>URI:</th><td>/rest/test-resource/fcr:tombstone</td></tr>
<tr><th>STATUS:</th><td>405</td></tr>
<tr><th>MESSAGE:</th><td>Method Not Allowed</td></tr>
<tr><th>SERVLET:</th><td>jersey-servlet</td></tr>
</table>
<hr/><a href="https://eclipse.org/jetty">Powered by Jetty:// 9.4.44.v20210927</a><hr/>
</body>
</html>
> curl -ufedoraAdmin:fedoraAdmin -XOPTIONS -i http://localhost:8080/rest/test-resource/fcr:tombstone
HTTP/1.1 200 OK
Date: Fri, 14 Jul 2023 20:07:43 GMT
Set-Cookie: JSESSIONID=node0ma3ljhdsbtgi1oz9twf9xk41o8.node0; Path=/
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Set-Cookie: rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Thu, 13-Jul-2023 20:07:43 GMT; SameSite=lax
Allow: DELETE
Content-Length: 0
Server: Jetty(9.4.44.v20210927)
Sending a DELETE request to the tombstone of an resource completely removes that resource.
Click here to expand...
For example
> curl -ufedoraAdmin:fedoraAdmin -XDELETE -i http://localhost:8080/rest/test-resource/fcr:tombstone
HTTP/1.1 204 No Content
Date: Fri, 14 Jul 2023 20:13:32 GMT
Set-Cookie: JSESSIONID=node0om6o2g9wena81lxv821x532cz10.node0; Path=/
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Set-Cookie: rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Thu, 13-Jul-2023 20:13:32 GMT; SameSite=lax
Server: Jetty(9.4.44.v20210927)
> curl -ufedoraAdmin:fedoraAdmin -i http://localhost:8080/rest/test-resource
HTTP/1.1 404 Not Found
Date: Fri, 14 Jul 2023 20:14:51 GMT
Set-Cookie: JSESSIONID=node0ged7v3eq1m1n1mtglgiorpq2r12.node0; Path=/
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Set-Cookie: rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Thu, 13-Jul-2023 20:14:51 GMT; SameSite=lax
Content-Type: text/turtle;charset=utf-8
Content-Length: 40
Server: Jetty(9.4.44.v20210927)
Error: Resource /test-resource not found
In contrast to a delete, a purge completely removes the resource from your OCFL file-system. It also removes any empty parent sub-directories up to the OCFL root directory (called "ocfl-root" by default).
For example looking at the OCFL root directory of a repository with only the deleted resource "test-resource" before the purge:
.
└── ocfl-root/
├── 0004-hashed-n-tuple-storage-layout.md
├── 0=ocfl_1.1
├── 141 <- the repository root resource
├── 5ce <- the deleted resource "test-resource"
├── extensions
├── ocfl_1.1.md
├── ocfl_extensions_1.0.md
└── ocfl_layout.json
After purging the resource "test-resource", the OCFL root looks like this:
.
└── ocfl-root/
├── 0004-hashed-n-tuple-storage-layout.md
├── 0=ocfl_1.1
├── 141 <- the repository root resource
├── extensions
├── ocfl_1.1.md
├── ocfl_extensions_1.0.md
└── ocfl_layout.json
Because no other resources in the repository were stored within the "5ce" directory in this example, the entire directory structure was removed. See Fedora OCFL Object Structure#StorageHierarchyLayout for details of how these subdirectories are named.