Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions doc/release-notes/12167-ore-bag-archiving-changes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
## Archiving, OAI-ORE, and BagIt Export

This release includes multiple updates to the OAI-ORE metadata export and the process of creating archival bags, improving performance, fixing bugs, and adding significant new functionality.

### General Archiving Improvements
- Multiple performance and scaling improvements have been made for creating archival bags for large datasets, including:
- The duration of archiving tasks triggered from the version table or API are no longer limited by the transaction time limit.
- Temporary storage space requirements have increased by `1/:BagGeneratorThreads` of the zipped bag size. (This is a consequence of changes to avoid timeout errors on larger files/datasets.)
- The size of individual data files and the total dataset size that will be included in an archival bag can now be limited. Admins can choose whether files above these limits are transferred along with, but outside, the zipped bag (creating a complete archival copy) or are just referenced (using the concept of a "holey" bag and just listing the oversized files and the Dataverse URLs from which they can be retrieved in a `fetch.txt` file). In the holey bag case, an active service on the archiving platform must retrieve the oversized files (using appropriate credentials as needed) to make a complete copy.
- Superusers can now see a pending status in the dataset version table while archiving is active.
- Workflows are now triggered outside the transactions related to publication, assuring that workflow locks and status updates are always recorded.
- Potential conflicts between archiving/workflows, indexing, and metadata exports after publication have been resolved, avoiding cases where the status/last update times for these actions were not recorded.
- A bug has been fixed where superusers would incorrectly see the "Submit" button to launch archiving from the dataset page version table.
- The local, S3, and Google archivers have been updated to support deleting existing archival files for a version to allow re-creating the bag for a given version.
- For archivers that support file deletion, it is now possible to recreate an archival bag after "Update Current Version" has been used (replacing the original bag). By default, Dataverse will mark the current version's archive as out-of-date, but will not automatically re-archive it.
- A new 'obsolete' status has been added to indicate when an archival bag exists for a version but it was created prior to an "Update Current Version" change.
- Improvements have been made to file retrieval for bagging, including retries on errors and when download requests are being throttled.
- A bug causing `:BagGeneratorThreads` to be ignored has been fixed, and the default has been reduced to 2.
- Retrieval of files for inclusion in an archival bag is no longer counted as a download.
- It is now possible to require that all previous versions have been successfully archived before archiving of a newly published version can succeed. (This is intended to support use cases where deduplication of files between dataset versions will be done and is a step towards supporting the Oxford Common File Layout (OCFL).)
- The pending status has changed to use the same JSON format as other statuses

### OAI-ORE Export Updates
- The export now uses URIs for checksum algorithms, conforming with JSON-LD requirements.
- A bug causing failures with deaccessioned versions has been fixed. This occurred when the deaccession note ("Deaccession Reason" in the UI) was null, which is permissible via the API.
- The `https://schema.org/additionalType` has been updated to "Dataverse OREMap Format v1.0.2" to reflect format changes.

### Archival Bag (BagIt) Updates
- The `bag-info.txt` file now correctly includes information for dataset contacts, fixing a bug where nothing was included when multiple contacts were defined. (Multiple contacts were always included in the OAI-ORE file in the bag; only the baginfo file was affected).
- Values used in the `bag-info.txt` file that may be multi-line (i.e. with embedded CR or LF characters) are now properly indented and wrapped per the BagIt specification (`Internal-Sender-Identifier`, `External-Description`, `Source-Organization`, `Organization-Address`).
- The dataset name is no longer used as a subdirectory within the `data/` directory to reduce issues with unzipping long paths on some filesystems.
- For dataset versions with no files, the empty `manifest-<alg>.txt` file will now use the algorithm from the `:FileFixityChecksumAlgorithm` setting instead of defaulting to MD5.
- A new key, `Dataverse-Bag-Version`, has been added to `bag-info.txt` with the value "1.0" to allow for tracking changes to Dataverse's archival bag generation over time.
- When using the `holey` bag option discussed above, the required `fetch.txt` file will be included.


### New Configuration Settings

This release introduces several new settings to control archival and bagging behavior.

- `:ArchiveOnlyIfEarlierVersionsAreArchived` (Default: `false`)
When set to `true`, dataset versions must be archived in order. That is, all prior versions of a dataset must be archived before the latest version can be archived.

The following JVM options (MicroProfile Config Settings) control bag size and holey bag support:
- `dataverse.bagit.zip.holey`
- `dataverse.bagit.zip.max-data-size`
- `dataverse.bagit.zip.max-file-size`

- `dataverse.bagit.archive-on-version-update` (Default: `false`)
Indicates whether archival bag creation should be triggered (if configured) when a version is updated and was already successfully archived, i.e., via the Update-Current-Version publication option. Setting the flag to `true` only works if the archiver being used supports deleting existing archival bags.

###Backward Incompatibility

The name of archival zipped bag produced by the LocalSubmitToArchiveCommand archiver now has a '.' character before the version number mirror the name used by other archivers, e.g. the name will be like doi-10-5072-fk2-fosg5q.v1.0.zip rather than doi-10-5072-fk2-fosg5qv1.0.zip
1 change: 1 addition & 0 deletions doc/sphinx-guides/source/admin/big-data-administration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ There are a broad range of options (that are not turned on by default) for impro
- :ref:`:DisableSolrFacetsWithoutJsession` - disables facets for users who have disabled cookies (e.g. for bots)
- :ref:`:DisableUncheckedTypesFacet` - only disables the facet showing the number of collections, datasets, files matching the query (this facet is potentially less useful than others)
- :ref:`:StoreIngestedTabularFilesWithVarHeaders` - by default, Dataverse stores ingested files without headers and dynamically adds them back at download time. Once this setting is enabled, Dataverse will leave the headers in place (for newly ingested files), reducing the cost of downloads
- :ref:`dataverse.bagit.zip.max-file-size`, :ref:`dataverse.bagit.zip.max-data-size`, and :ref:`dataverse.bagit.zip.holey` - options to control the size and temporary storage requirements when generating archival Bags - see :ref:`BagIt Export`


Scaling Infrastructure
Expand Down
40 changes: 40 additions & 0 deletions doc/sphinx-guides/source/installation/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2259,10 +2259,22 @@ These archival Bags include all of the files and metadata in a given dataset ver

The Dataverse Software offers an internal archive workflow which may be configured as a PostPublication workflow via an admin API call to manually submit previously published Datasets and prior versions to a configured archive such as Chronopolis. The workflow creates a `JSON-LD <http://www.openarchives.org/ore/0.9/jsonld>`_ serialized `OAI-ORE <https://www.openarchives.org/ore/>`_ map file, which is also available as a metadata export format in the Dataverse Software web interface.

The size of the zipped archival Bag can be limited, and files that don't fit within that limit can either be transferred separately (placed so that they are correctly positioned according to the BagIt specification when the zipped bag in unzipped in place) or just referenced for later download (using the BagIt concept of a 'holey' bag with a list of files in a ``fetch.txt`` file) can now be configured for all archivers. These settings allow for managing large datasets by excluding files over a certain size or total data size, which can be useful for archivers with size limitations or to reduce transfer times. See the :ref:`dataverse.bagit.zip.max-file-size`, :ref:`dataverse.bagit.zip.max-data-size`, and :ref:`dataverse.bagit.zip.holey` JVM options for more details.

At present, archiving classes include the DuraCloudSubmitToArchiveCommand, LocalSubmitToArchiveCommand, GoogleCloudSubmitToArchive, and S3SubmitToArchiveCommand , which all extend the AbstractSubmitToArchiveCommand and use the configurable mechanisms discussed below. (A DRSSubmitToArchiveCommand, which works with Harvard's DRS also exists and, while specific to DRS, is a useful example of how Archivers can support single-version-only semantics and support archiving only from specified collections (with collection specific parameters)).

All current options support the :ref:`Archival Status API` calls and the same status is available in the dataset page version table (for contributors/those who could view the unpublished dataset, with more detail available to superusers).

Two settings that can be used with all current Archivers are:

- \:BagGeneratorThreads - the number of threads to use when adding data files to the zipped bag. The default is 2. Values of 4 or more may increase performance on larger machines but may cause problems if file access is throttled
- \:ArchiveOnlyIfEarlierVersionsAreArchived - when true, requires dataset versions to be archived in order by confirming that all prior versions have been successfully archived before allowing a new version to be archived. Default is false

These must be included in the \:ArchiverSettings for the Archiver to work

Archival Bags are created per dataset version. By default, if a version is republished (via the superuser-only 'Update Current Version' publication option in the UI/API), a new archival bag is not created for the version.
If the archiver used is capable of deleting existing bags (Google, S3, and File Archivers) superusers can trigger a manual update of the archival bag, and, if the :ref:`dataverse.bagit.archive-on-version-update` flag is set to true, this will be done automatically when 'Update Current Version' is used.

.. _Duracloud Configuration:

Duracloud Configuration
Expand Down Expand Up @@ -3715,6 +3727,14 @@ The email for your institution that you'd like to appear in bag-info.txt. See :r

Can also be set via *MicroProfile Config API* sources, e.g. the environment variable ``DATAVERSE_BAGIT_SOURCEORG_EMAIL``.

.. _dataverse.bagit.archive-on-version-update:

dataverse.bagit.archive-on-version-update
+++++++++++++++++++++++++++++++++++++++++

Indicates whether archival bag creation should be triggered (if configured) when a version is updated and was already successfully archived,
i.e via the Update-Current-Version publication option. Setting the flag true only works if the archiver being used supports deleting existing archival bags.

.. _dataverse.files.globus-monitoring-server:

dataverse.files.globus-monitoring-server
Expand Down Expand Up @@ -3877,6 +3897,21 @@ This can instead be restricted to only superusers who can publish the dataset us

Example: ``dataverse.coar-notify.relationship-announcement.notify-superusers-only=true``

.. _dataverse.bagit.zip.holey:

``dataverse.bagit.zip.holey``
A boolean that, if true, will cause the BagIt archiver to create a "holey" bag. In a holey bag, files that are not included in the bag are listed in the ``fetch.txt`` file with a URL from which they can be downloaded. This is used in conjunction with ``dataverse.bagit.zip.max-file-size`` and/or ``dataverse.bagit.zip.max-data-size``. Default: false.

.. _dataverse.bagit.zip.max-data-size:

``dataverse.bagit.zip.max-data-size``
The maximum total (uncompressed) size of data files (in bytes) to include in a BagIt zip archive. If the total size of the dataset files exceeds this limit, files will be excluded from the zipped bag (starting from the largest) until the total size is under the limit. Excluded files will be handled as defined by ``dataverse.bagit.zip.holey`` - just listed if that setting is true or being transferred separately and placed next to the zipped bag. When not set, there is no limit.

.. _dataverse.bagit.zip.max-file-size:

``dataverse.bagit.zip.max-file-size``
The maximum (uncompressed) size of a single file (in bytes) to include in a BagIt zip archive. Any file larger than this will be excluded. Excluded files will be handled as defined by ``dataverse.bagit.zip.holey`` - just listed if that setting is true or being transferred separately and placed next to the zipped bag. When not set, there is no limit.

.. _feature-flags:

Feature Flags
Expand Down Expand Up @@ -5378,6 +5413,11 @@ This setting specifies which storage system to use by identifying the particular

For examples, see the specific configuration above in :ref:`BagIt Export`.

:ArchiveOnlyIfEarlierVersionsAreArchived
++++++++++++++++++++++++++++++++++++++++

This setting, if true, only allows creation of an archival Bag for a dataset version if all prior versions have been successfully archived. The default is false (any version can be archived independently as long as other settings allow it)

:ArchiverSettings
+++++++++++++++++

Expand Down
33 changes: 27 additions & 6 deletions src/main/java/edu/harvard/iq/dataverse/DataFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,18 +109,22 @@ public class DataFile extends DvObject implements Comparable {
* The list of types should be limited to the list above in the technote
* because the string gets passed into MessageDigest.getInstance() and you
* can't just pass in any old string.
*
* The URIs are used in the OAI_ORE export. They are taken from the associated XML Digital Signature standards.
*/
public enum ChecksumType {

MD5("MD5"),
SHA1("SHA-1"),
SHA256("SHA-256"),
SHA512("SHA-512");
MD5("MD5", "http://www.w3.org/2001/04/xmldsig-more#md5"),
SHA1("SHA-1", "http://www.w3.org/2000/09/xmldsig#sha1"),
SHA256("SHA-256", "http://www.w3.org/2001/04/xmlenc#sha256"),
SHA512("SHA-512", "http://www.w3.org/2001/04/xmlenc#sha512");

private final String text;
private final String uri;

private ChecksumType(final String text) {
private ChecksumType(final String text, final String uri) {
this.text = text;
this.uri = uri;
}

public static ChecksumType fromString(String text) {
Expand All @@ -131,13 +135,30 @@ public static ChecksumType fromString(String text) {
}
}
}
throw new IllegalArgumentException("ChecksumType must be one of these values: " + Arrays.asList(ChecksumType.values()) + ".");
throw new IllegalArgumentException(
"ChecksumType must be one of these values: " + Arrays.asList(ChecksumType.values()) + ".");
}

public static ChecksumType fromUri(String uri) {
if (uri != null) {
for (ChecksumType checksumType : ChecksumType.values()) {
if (uri.equals(checksumType.uri)) {
return checksumType;
}
}
}
throw new IllegalArgumentException(
"ChecksumType must be one of these values: " + Arrays.asList(ChecksumType.values()) + ".");
}

@Override
public String toString() {
return text;
}

public String toUri() {
return uri;
}
}

//@Expose
Expand Down
Loading
Loading