Skip to content

Expands InternalExportDataProvider per dataverse-spi 2.1.0 and refactors the DDI exporter to utilize the new functionality - #11799

Open
landreev wants to merge 57 commits into
developfrom
11405-refactor-exports
Open

Expands InternalExportDataProvider per dataverse-spi 2.1.0 and refactors the DDI exporter to utilize the new functionality#11799
landreev wants to merge 57 commits into
developfrom
11405-refactor-exports

Conversation

@landreev

@landreev landreev commented Sep 8, 2025

Copy link
Copy Markdown
Contributor

Un-drafting the PR now!

What this PR does / why we need it:

See issue #11405. Short version: the current export data framework is prohibitively expensive for datasets with very large amounts of tabular data (i.e., "ingested" DataFiles that have associated DataTable entities , with large numbers of child DataVariable objects). This PR improves it, via adding code that retrieves the data in manageable chunks. This in turn relies on the new version of the ExportDataProvider interface from https://github.com/gdcc/dataverse-spi.

Which issue(s) this PR closes:

Special notes for your reviewer:

Note that the PR builds with a snapshot release of dataverse-spi:

            <groupId>io.gdcc</groupId>
            <artifactId>dataverse-spi</artifactId>
            <version>2.1.0-SNAPSHOT</version>

I.e., the version 2.1.0 still needs to be properly released under gdcc. But I don't think that should be stopping putting the PR into review and merging it rather sooner than later.

Note that this PR also removes modules/dataverse-spi, and the action that used to build snapshot releases of it (.github/workflows/spi_release.yml) from the main source tree; now that dataverse-spi lives under gdcc.

Note specifically the test for the functionality, TabularDataExportIT added in this PR. I have added it to the list of integration tests that are performed automatically by the workflow action (in tests/integration-tests.txt) even though, strictly speaking, it is not a real integration test. [update: No, it is not executed as an "integration test". It is run by the GitHub action via this change in the main pom.xml] I.e., it does not rely on calling a fully-functional Dataverse instance started remotely. It relies instead on the new test framework added in @poikilotherm's #12365 where a local Docker instance of the database is spun up in which some dummy objects - Datasets, Versions, Datatables and Variables etc are created instantly, allowing testing of complex functionality that requires real database access. Without this new framework, the only way to test an export of a dataset with N large tabular files would be to actually ingest these N files via the API in the remote Dataverse instance used by the RestAssured tests. Which would add to the ongoing bloating of the test suite, and still would not allow to test the underlying functionality as thoroughly (for example, there is no easy way to count the actual database queries under such scenario).

You can run the test in question in your own dev. environment via
mvn test -Dtest=TabularDataExportIT#exportTabularMetadata
If you do not have Docker running, the test will be politely skipped. Otherwise it will create a throwaway postgres instance and proceed to test tabular data exports and associated data retrieval, comparing the results produced using the legacy methods vs. the new and optimized versions added in this PR and more.

Suggestions on how to test this:

Please see the info under the "notes for the reviewer" and feel free to play and experiment with the new test described there. Please keep in mind that the test is still somewhat of a reference demonstrator of the new JpaEntityManagerService-based framework from #12365. It can be expanded and improved going forward.

The ultimate test would be to test before vs. after on some real-life monster datasets.
I would suggest these bad boys on qa:
https://qa.dataverse.org/dataset.xhtml?persistentId=doi:10.7910/DVN/KZW8R2 (207 ingested tab. files; 186906 variables total)
https://qa.dataverse.org/dataset.xhtml?persistentId=doi:10.7910/DVN/S5BRBO (134 tab. files; 536006 variables).

"ddi" (aka the "full" ddi) is the export format that needs to be tested.
Note that some extra steps will be required in order to test this on qa:

  • You will want to change the storage driver to local filesystem ("file") for the datasets in question - so that Dataverse can write the export files;
  • And make sure you are testing the export code vs. looking at a potentially existing cached export; i.e., the file export_ddi.cached will need to be erased between testing runs.
    Happy to assist with the above if needed.

Does this PR introduce a user interface change? If mockups are available, please link/include them here:

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

Additional documentation:

@landreev landreev self-assigned this Sep 8, 2025
@github-actions github-actions Bot added FY25 Sprint 24 FY25 Sprint 24 (2025-05-21 - 2025-06-04) FY25 Sprint 25 FY25 Sprint 25 (2025-06-04 - 2025-06-18) FY25 Sprint 26 FY25 Sprint 26 (2025-06-18 - 2025-07-02) FY26 Sprint 1 FY26 Sprint 1 (2025-07-02 - 2025-07-16) FY26 Sprint 2 FY26 Sprint 2 (2025-07-16 - 2025-07-30) FY26 Sprint 3 (2025-07-30 - 2025-08-13) FY26 Sprint 4 FY26 Sprint 4 (2025-08-13 - 2025-08-27) FY26 Sprint 5 FY26 Sprint 5 (2025-08-27 - 2025-09-10) Size: 80 A percentage of a sprint. 56 hours. labels Sep 8, 2025
@github-actions

This comment has been minimized.

@landreev

Copy link
Copy Markdown
Contributor Author

Note that the PR now builds under Jenkins (with a snapshot release of dataverse-spi that is now published).

@github-actions

This comment has been minimized.

@pdurbin pdurbin self-assigned this Aug 19, 2026
@pdurbin pdurbin moved this from Ready for QA ⏩ to QA ✅ in IQSS Dataverse Project Aug 19, 2026

@pdurbin pdurbin left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

A quick review.

DataFile dataFile = fileMetadata.getDataFile();
jab.add(JsonPrinter.json(dataFile, fileMetadata, true));
if (fileAndDataDetails == null) {
JsonArrayBuilder jab = Json.createArrayBuilder();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

When I run this...

mvn test -Dtest=TabularDataExportIT#exportTabularMetadata

... I get these errors:

[INFO] Reading API signatures: /Users/pdurbin/github/iqss/dataverse/src/maven/forbiddenapis.txt
[INFO] Loading classes to check...
[INFO] Scanning classes for violations...
[ERROR] Forbidden method invocation: jakarta.json.Json#createArrayBuilder() [Use edu.harvard.iq.dataverse.util.json.JsonUtil.createArrayBuilder(...) instead]
[ERROR]   in edu.harvard.iq.dataverse.export.InternalExportDataProvider (InternalExportDataProvider.java:148)
[ERROR] Forbidden method invocation: jakarta.json.Json#createArrayBuilder() [Use edu.harvard.iq.dataverse.util.json.JsonUtil.createArrayBuilder(...) instead]
[ERROR]   in edu.harvard.iq.dataverse.export.InternalExportDataProvider (InternalExportDataProvider.java:179)
[ERROR] Scanned 1225 class file(s) for forbidden API invocations (in 0.77s), 2 error(s).
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------

Comment thread src/main/java/edu/harvard/iq/dataverse/api/Metadata.java Outdated
Comment thread src/main/java/edu/harvard/iq/dataverse/api/Metadata.java Outdated
Comment thread src/main/java/edu/harvard/iq/dataverse/api/Metadata.java Outdated
assertTrue(false, "Unexpected XMLStreamException when attempting to parse the dataDscr section: " + xse.getMessage());
} finally {
if (xmlr != null) {
try {xmlr.close();} catch (XMLStreamException e) {}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚫 [reviewdog] <com.puppycrawl.tools.checkstyle.checks.blocks.LeftCurlyCheck> reported by reviewdog 🐶
'{' at column 21 should have line break after.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

landreev and others added 3 commits August 21, 2026 12:23
Co-authored-by: Philip Durbin <philip_durbin@harvard.edu>
Co-authored-by: Philip Durbin <philip_durbin@harvard.edu>
@github-actions

This comment has been minimized.

2 similar comments
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Comment on lines +1 to +2
Dataverse metadata export code has been re-factored to use the new and improved Data Export framework (note also that the relevant interface and the accompanying code have been moved out of the main Dataverse repository and into the dedicated [GDCC project](https://github.com/gdcc/dataverse-spi)). In this release this will result in a measurable improvement in exporting the DDI format. But it will be possible to take advantage of this refactoring in the exports of other data-rich formats in future releases.
An optional query parameter ``formats`` has been added to the ``reExportAll`` and ``reExportDataset``, allowing an administrator to force re-export of only the formats specified.

@pdurbin pdurbin Aug 21, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We can wordsmith this at release time but a few thoughts.

I'd probably pitch this as two related features:

## Highlights

### Export improvements

- Faster DDI export
- Ability to export only selected formats 

Then, further down:

## API updates

### Ability to export only selected formats

curl example, link to API Guide.

Still further down:

## Updates for developers

We've refactored, blah blah blah.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sure, makes sense. Will do.

Comment thread doc/sphinx-guides/source/api/changelog.rst Outdated
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
38.2% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@github-actions

Copy link
Copy Markdown

📦 Pushed preview images as

ghcr.io/gdcc/dataverse:11405-refactor-exports
ghcr.io/gdcc/configbaker:11405-refactor-exports

🚢 See on GHCR. Use by referencing with full name as printed above, mind the registry name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature: Performance & Stability FY25 Sprint 24 FY25 Sprint 24 (2025-05-21 - 2025-06-04) FY25 Sprint 25 FY25 Sprint 25 (2025-06-04 - 2025-06-18) FY25 Sprint 26 FY25 Sprint 26 (2025-06-18 - 2025-07-02) FY26 Sprint 1 FY26 Sprint 1 (2025-07-02 - 2025-07-16) FY26 Sprint 2 FY26 Sprint 2 (2025-07-16 - 2025-07-30) FY26 Sprint 3 (2025-07-30 - 2025-08-13) FY26 Sprint 4 FY26 Sprint 4 (2025-08-13 - 2025-08-27) FY26 Sprint 5 FY26 Sprint 5 (2025-08-27 - 2025-09-10) FY26 Sprint 9 FY26 Sprint 9 (2025-10-22 - 2025-11-05) FY26 Sprint 10 FY26 Sprint 10 (2025-11-05 - 2025-11-19) FY26 Sprint 11 FY26 Sprint 11 (2025-11-20 - 2025-12-03) FY26 Sprint 12 FY26 Sprint 12 (2025-12-03 - 2025-12-17) FY26 Sprint 13 FY26 Sprint 13 (2025-12-17 - 2025-12-31) FY26 Sprint 14 FY26 Sprint 14 (2025-12-31 - 2026-01-14) FY26 Sprint 15 FY26 Sprint 15 (2026-01-14 - 2026-01-28) FY26 Sprint 16 FY26 Sprint 16 (2026-01-28 - 2026-02-11) FY26 Sprint 17 FY26 Sprint 17 (2026-02-11 - 2026-02-25) FY26 Sprint 22 FY26 Sprint 22 (2026-04-22 - 2026-05-06) FY26 Sprint 23 FY26 Sprint 23 (2026-05-06 - 2026-05-20) FY26 Sprint 24 FY26 Sprint 24 (2026-05-20 - 2026-06-03) FY26 Sprint 25 FY26 Sprint 25 (2026-06-03 - 2026-06-17) FY26 Sprint 26 FY26 Sprint 26 (2026-06-17 - 2026-07-01) FY27 Sprint 1 FY27 Sprint 1 (2026-07-01 - 2026-07-15) FY27 Sprint 2 FY27 Sprint 2 (2026-07-15 - 2026-07-29) FY27 Sprint 3 FY27 Sprint 3 (2026-07-29 - 2026-08-12) FY27 Sprint 4 FY27 Sprint 4 (2026-08-12 - 2026-08-26) Size: 80 A percentage of a sprint. 56 hours.

Projects

Status: QA ✅

Development

Successfully merging this pull request may close these issues.

Refactor and optimize the Export metadata framework, especially for the data/variable-level metadata

5 participants