CLARIN-DSpace v9/Port #1384 (CMDI ResourceRef machine-actionable download links) to the v9 base - #1395
Merged
Merged
Conversation
…fal#1384) Emit ${dspace.server.url}/api/core/bitstreams/handle/<handle>/<filename> (the endpoint used by the item-page curl instructions) instead of the UI-only ${dspace.ui.url}/bitstream/handle/...?sequence=n link, which only worked through the Angular legacy-URL redirect in a browser. - URL-encode the filename (encode-for-uri), names with spaces were already broken for curl - list only ORIGINAL-bundle bitstreams; the download endpoint serves nothing else, so THUMBNAIL/TEXT entries would have been dead links - add CmdiDownloadLinkIT: harvests the CMDI record via OAI-PMH GetRecord, extracts the ResourceRef and downloads the file from it - restrict the ResourceRef XPath to bitstream proxies (id starting with "_") so source-URI proxies can't match; harden the test XML parser (secure processing, disallow DOCTYPE); NamespaceContext#getPrefixes returns an empty iterator, not null (cherry picked from commit 82e33e8 on ufal/clarin-dspace) (cherry picked from commit 6114281 on dtq-dev) Clean conflict-free pick, no v9 adaptations needed. Verified against the v9 base: - lindat_cmdi.xsl has an identical pre-image here ($dsURL declared at line 28 and used in exactly one place, ProcessBitstreams' ResourceRef), and the fnx prefix (http://www.w3.org/2005/xpath-functions) that encode-for-uri needs is already declared and listed in exclude-result-prefixes. - CmdiDownloadLinkIT.java is a new file and needs no javax->jakarta conversion: its javax.xml.* imports are JDK JAXP, not Java EE. - Every API the new IT touches exists on this branch: SolrOAIReindexer #reindexItem(Item) plus its solrServerResolver field, DSpaceItemRepositoryResolver's itemRepository field, MockSolrServer, XOAICacheService / SolrServerResolver / ItemRepositoryResolver, BitstreamBuilder#createBitstream(ctx, item, is, bundleName), Constants.LICENSE_BUNDLE_NAME / LICENSE_BITSTREAM_NAME, and BitstreamByHandleRestController serving GET /api/core/bitstreams/handle/{prefix}/ {suffix}/{filename} for ORIGINAL-bundle bitstreams only. - spring-boot 3.5.14 still ships @MockBean (deprecated since 3.4); the sibling OAIpmhIT on this branch uses it the same way, so no test-harness change. Co-authored-by: Ondřej Košarko <ko_ok@centrum.cz>
There was a problem hiding this comment.
Pull request overview
This PR ports CLARIN-DSpace change #1384 to the v9 base to ensure CMDI OAI-PMH cmd:ResourceRef values are machine-actionable download links pointing to the REST by-handle bitstream endpoint, instead of UI-only legacy bitstream URLs.
Changes:
- Updated the CMDI XSL crosswalk to emit
${dspace.server.url}/api/core/bitstreams/handle/<handle>/<url-encoded-filename>and to list only ORIGINAL-bundle bitstreams. - Added an end-to-end integration test which harvests a CMDI record via OAI-PMH, validates the emitted link(s), and downloads the referenced bitstream to verify content.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| dspace/config/crosswalks/oai/metadataFormats/lindat_cmdi.xsl | Switches CMDI ResourceRef output to REST by-handle download URLs with URL-encoded filenames, restricted to ORIGINAL bundle bitstreams. |
| dspace-server-webapp/src/test/java/org/dspace/app/oai/CmdiDownloadLinkIT.java | New integration test covering CMDI ResourceRef link format, exclusion of legacy links/LICENSE bitstream, and successful download/content verification. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Post-snapshot sync dtq-dev → dtq-dev-9-base
Port of dataquest-dev#1384 (itself a port of ufal#1384 by @kosarko, upstream commit
82e33e817a) to the v9 base.6114281c15(dtq-dev #1384) — CMDI ResourceRef machine-actionable download links — PORTProcessBitstreamsinlindat_cmdi.xslnow emits${dspace.server.url}/api/core/bitstreams/handle/<handle>/<url-encoded-filename>instead of the UI-only
${dspace.ui.url}/bitstream/handle/...?sequence=nlink, which only resolved through the Angular legacy-URL redirect in a browser and was useless to a machine client. Filenames are URL-encoded (fnx:encode-for-uri), and only ORIGINAL-bundle bitstreams are listed, since the download endpoint serves nothing else.Clean conflict-free cherry-pick — no v9 adaptations needed. Verified against the v9 base:
lindat_cmdi.xslhas an identical pre-image here ($dsURLdeclared at line 28, used in exactly one place —ProcessBitstreams'ResourceRef), and thefnxprefix (http://www.w3.org/2005/xpath-functions) thatencode-for-urineeds is already declared and listed inexclude-result-prefixes.CmdiDownloadLinkIT.javais a new file and needs no javax→jakarta conversion: itsjavax.xml.*imports are JDK JAXP, not Java EE.SolrOAIReindexer#reindexItem(Item)+ itssolrServerResolverfield,DSpaceItemRepositoryResolver'sitemRepositoryfield,MockSolrServer,XOAICacheService/SolrServerResolver/ItemRepositoryResolver,BitstreamBuilder#createBitstream(ctx, item, is, bundleName),Constants.LICENSE_BUNDLE_NAME/LICENSE_BITSTREAM_NAME, andBitstreamByHandleRestControllerservingGET /api/core/bitstreams/handle/{prefix}/{suffix}/{filename}for ORIGINAL-bundle bitstreams only.@MockBean(deprecated since 3.4); the siblingOAIpmhITon this branch uses it the same way, so no test-harness change.Gates
6114281c15(git diff 6114281c15 HEAD -- <both paths>is empty).mvn install -DskipTests— BUILD SUCCESS, 0 Checkstyle violations.CmdiDownloadLinkITrun against atestEnvironment.ziprebuilt from this tree (so the new XSL is the one under test): Tests run: 1, Failures: 0, Errors: 0, Skipped: 0. The test harvests the CMDI record via OAI-PMHGetRecord, asserts the ResourceRef equals the by-handle URL with a%20-encoded filename, asserts the legacy/bitstream/handle/+?sequence=forms and the LICENSE bitstream are absent, then downloads the file from that URL and compares content.ClarinRefBoxControllerITonly checks thecmdiexport-format URL/metadata, notResourceRef. CI Unit+Integration jobs are the record gate.Note
The prior v9-base port commits reference
CLARIN_V9_POST_SNAPSHOT_SYNC_ACCEPTANCE.md/CLARIN_V9_PARITY_BACKLOG.md, neither of which is tracked on this branch, so this port carries no "Fulfils §5 / card" line. If those planning docs should get a card for6114281c15, say so and I'll add it.🤖 Generated with Claude Code