Preserve a new version — custom Import Job
You don’t have to use an ImportJob generated by the platform as a diff.
You must always create a Deposit from which to run the job — it is what gives the job a context to be launched from, and an audit trail — but you can construct the ImportJob by hand, giving it any id you like.
The id properties of the Containers and Binaries listed must belong to the target Archival Group: even if they don’t exist yet, they must be under its path. But the origin from which a Binary is copied doesn’t have to be at the same relative path as its target under the Archival Group. So you can patch page 637 of a 1000-page manuscript without worrying about aligning the paths.
-
Create a Deposit for the Archival Group
Section titled “Create a Deposit for the Archival Group”POST /deposits{"type": "Deposit","archivalGroup": "https://preservation-api.example/repository/library/c18-printed-books/a-10000001","submissionText": "Replacing the scan of page 637"}No export, no template: you are not going to ask for a diff, so the Deposit is mainly a place to put the bytes and a record of what you did. It will not be empty, mind — a deposit made against an Archival Group that already has a METS gets that METS copied in, whatever template you asked for.
-
Upload only what you need
Section titled “Upload only what you need”Put the file (or files) anywhere in the workspace. It need not sit at the path it will occupy in the object.
s3://working-bucket/deposits/hn66d3s9b/patch-of-p637.tifs3://working-bucket/deposits/hn66d3s9b/mets.xml -
Write the job
Section titled “Write the job”POST /deposits/hn66d3s9b/importjobs{"id": "https://example.org/my-custom-unique-uri-for-this-job","type": "ImportJob","deposit": "https://preservation-api.example/deposits/hn66d3s9b","archivalGroup": "https://preservation-api.example/repository/library/c18-printed-books/a-10000001","isUpdate": true,"source": "s3://working-bucket/deposits/hn66d3s9b/","binariesToAdd": [{"id": "https://preservation-api.example/repository/library/c18-printed-books/a-10000001/objects/some/detailed/path/page-637.tiff","type": "Binary","name": "page-637.tiff","origin": "s3://working-bucket/deposits/hn66d3s9b/patch-of-p637.tif","contentType": "image/tiff","size": 4439518,"digest": "ca20043fc62c7215bfba9d0866b9e0e548b0ba70ab1b6e001a96d8a62a469f4d"}],"binariesToPatch": [{"id": "https://preservation-api.example/repository/library/c18-printed-books/a-10000001/mets.xml","type": "Binary","name": "mets.xml","origin": "s3://working-bucket/deposits/hn66d3s9b/mets.xml","contentType": "application/xml","size": 3278,"digest": "2274bfad9b5420043fc62c6c34441ae436a0caab12d8a62a4679f4dfb2599e53"}]}Here a file called
patch-of-p637.tifbecomes the Binary at.../objects/some/detailed/path/page-637.tiff. There was no need to ask for a diff; the client constructed and submitted this job directly. -
Poll the result until it has finished
Section titled “Poll the result until it has finished”As in every other workflow. What the job did is reported in
binariesAdded,binariesPatchedand the rest.
What a hand-written job must get right
Section titled “What a hand-written job must get right”deposit |
Required, and must be the Deposit you are POSTing to. Without it the job is 400 Bad Request. |
archivalGroup |
Required — and not checked against the Deposit’s own. The job runs against whatever it names, so a mistake here writes to a different object and reports success. Set it deliberately. |
isUpdate |
State it explicitly. False against an object that exists, or true against one that doesn’t, fails the job once it is running. |
archivalGroupName |
Required when isUpdate is false. A new Archival Group has to be given a name. |
origin |
Every Binary in binariesToAdd and binariesToPatch must have an origin inside the Deposit’s files location. An origin anywhere else is 400 Bad Request. |
digest |
Required, unless the platform can get a SHA256 for that file from the METS or from S3 object metadata. On a hand-written job, supply it. |
contentType |
Supply it on every Binary you add or patch. Nothing rejects a job without one: the header is simply omitted and the binary is stored with whatever the repository defaults to. |
id slugs |
Use only the permitted characters in every path segment. Only two things are checked on this path — a null id, and a # in one — so an unusable slug is left to the repository to refuse, or not. |
binariesToDelete, containersToDelete |
id is the only property needed. A Container must be empty already, or contain only Binaries deleted in the same job. |
sourceVersion on a hand-written job is informational; the platform works out for itself which version it is changing at the moment it changes it.