CLARIN-DSpace v9/Port #1307 (metadata health check) to the v9 base - #1436
Conversation
…ata health check (#1307) Source: 6e0ed0c (dtq-dev PR #1307) Adds the health check org.dspace.health.MetadataCheck, registered as "Metadata check". It runs the `metadataqa` curation task (ItemMetadataQAChecker) over the whole repository through a Curator, classifies every reported line against metadata-check-patterns.json, prints per-type error/warning statistics plus a size-capped list of messages, and writes errorCount / warningCount and the per-type errors / warnings arrays into the health-report JSON. Report size is bounded by four healthcheck.metadata.* keys, all read with the two-argument getIntProperty(key, default), so no further configuration is required. MetadataCheck.java and metadata-check-patterns.json are copied verbatim: both blobs are identical to origin/dtq-dev tip (f3793e6, fb2ba73) and every API they use is unchanged on this branch -- Check.run(ReportInfo) (protected abstract, widened to public here, which is legal), Curator.addTask/setReporter/curate(Context,String)/getResult, Check.getReportJson/setReportJson, and org.json:json:20231013, an explicit dspace-api dependency. org.apache.commons.collections.ListUtils (collections 3) is left as the source has it; swapping it for collections4 is a repo-wide cleanup, not part of this port. healthcheck.cfg is hand-merged, not taken from the source hunk. The source hunk also renames License -> License summary and Embargo info -> Embargo check and drops Checksum from the enabled list, because dtq-dev (7.6.x) and this branch (vanilla 9.3 plus two CLARIN entries) name and order the checks differently. This branch's names are kept and "Metadata check" is appended to both lists, so it becomes -c 7 here, not -c 5 as on dtq-dev. HealthReportIT gains this commit's two tests (testMetadataCheck, testMetadataCheckWithRestrictedReportSize) and its three helpers (findItemUri, and the package-private findLastReportResult and findCheckByName), reaching 12 @test. The one adaptation: the source tests hardcode -c 5, which addresses the License check here, so both resolve the index through the checkIndex(String) helper this branch already carries, via a new METADATA_CHECK constant. Everything else in the two tests is byte-identical with the source; the only other difference in the whole file is the added constant and its javadoc. report-diff-fields.json is deliberately untouched. It was restored in full by card X-01 (#1425), is byte-identical with dtq-dev and already contains the four "Metadata check" lines this commit would otherwise add; this port is what makes those mappings resolve. Co-authored-by: Milan Kuchtiak <kuchtiak@ufal.mff.cuni.cz> Co-authored-by: Ondrej Kosarko <kosarko@ufal.mff.cuni.cz> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Local gate outputs (per sync rule 2.5)Base: B1 — CI-equivalent compile + checkstyle + license + enforcer Integration tests Negative control — the two new tests are not vacuous Reverting only All 12 still run; exactly the two tests this PR adds fail, and only when the registration is Observed once, not caused by this PR: an earlier |
What
Ports
dataquest-dev/DSpacePR #1307 ("metadata health check", commit6e0ed0c6cc;originally
ufal/clarin-dspace#1338, issueufal/clarin-dspace#1317) todtq-dev-9-base.Adds the health check
org.dspace.health.MetadataCheck, registered asMetadata check:it runs the
metadataqacuration task (ItemMetadataQAChecker) over the whole repositorythrough a
Curator, classifies each reported line againstmetadata-check-patterns.json,prints per-type error/warning statistics plus a size-capped list of messages, and writes
errorCount/warningCount(and the per-typeerrors/warningsarrays) into thehealth-reportJSON.Sync card: BE-13 (
_sync3/cards/BE-13.md, tranche T4, disposition ADAPT, size M, risk low,depends_on: X-01).Why
ItemMetadataQACheckerand itscurate.cfgmetadataqaregistration are already on thisbranch, but nothing surfaces their output in the health report, and
report-diff-fields.jsonalready carries twoMetadata checkmappings that can never resolvebecause no check by that name is registered. This PR is what makes those mappings live.
Changes
dspace-api/src/main/java/org/dspace/health/MetadataCheck.java(new, 495 lines)dspace-api/src/main/resources/metadata-check-patterns.json(new, 52 lines)dspace-api/src/test/java/org/dspace/scripts/HealthReportIT.java@Testdspace/config/modules/healthcheck.cfgdspace-api/src/main/resources/report-diff-fields.jsonBoth new files are byte-identical with
origin/dtq-devtip (f3793e6a9356,fb2ba7329276),so "verbatim" is unambiguous. Every API they use exists unchanged on this branch:
Check.run(ReportInfo)(protected abstract, widened topublicinMetadataCheck— legal),Curator.addTask/setReporter/curate(Context,String)/getResult,Check.getReportJson/setReportJson,and
org.json:json:20231013, which is an explicitdspace-apidependency. All fourhealthcheck.metadata.*knobs are read with the two-argumentgetIntProperty(key, default),so no further config keys are needed.
healthcheck.cfg— hand-merged, deliberately not the source hunkThe source hunk cannot be applied as-is: it renames
License->License summaryandEmbargo info->Embargo checkand dropsChecksumfrom the enabled list, becausedtq-dev(7.6.x) and this branch (vanilla 9.3 + 2 CLARIN entries) name and order the checksdifferently. This branch's names are kept and
Metadata checkis appended to both lists:Consequence for operators:
Metadata checkis-c 7here, not-c 5as ondtq-dev.HealthReportIT— the two tests are rewritten onto the name-based indexThe source tests hardcode
new String[]{"health-report", "-c", "5"}. On this branch index 5 isLicense, so taken wholesale both tests would run the licence check and fail everyassertion. They use the
checkIndex(String)helper this branch already has (added when theclass was restored), plus a new
METADATA_CHECK = "Metadata check"constant:Everything else in the two tests, and all three helpers the source commit adds
(
findItemUriprivate,findLastReportResultandfindCheckByNamepackage-private), iscarried over unchanged.
report-diff-fields.json— pre-existing gap, already closedThe card lists this file as missing on the target. That is stale: it was restored in full by
the test-parity card X-01 (#1425) and is byte-identical with
dtq-dev, so it alreadycontains all four
Metadata checklines. This PR does not touch it.Related, and not folded in here: that resource addresses the licence row as
/checks/[name=License summary]/report/licenseswhile this branch registers the check asLicense, so the licences row is silently dropped fromreport-diff. That is fixedseparately in #1433; the two changes touch different lines of different files and do not
conflict in either merge order.
Testing
mvn --no-transfer-progress -V clean install -P-assembly -DskipTests(full reactor,cleanfirst) ->
BUILD SUCCESS,Total time: 06:42 min, 0 checkstyle violations in every moduleincluding
dspace-api, where the new 495-line class lives.Integration tests,
dspace-api, run locally on Windows (they do run — the card's "may need CI"caveat did not apply):
HealthReportITgoes 10 -> 12@Testand all 12 pass;ItemMetadataQACheckerIT(17 tests)is the regression check for the
metadataqatask this check drives, and is unaffected.Numbers read from
dspace-api/target/failsafe-reports/*.txtwith their mtimes (11:30:54 and11:31:10), not from the console tail.
Negative control. Reverting only the
healthcheck.cfgregistration — leaving both new testsin place, rebuilding the test environment (
rm -rf dspace-api/target/testing, reinstall) andre-running
HealthReportIT— turnstestMetadataCheckandtestMetadataCheckWithRestrictedReportSizered, becausecheckIndex("Metadata check")no longerresolves. So the two lines of config are load-bearing and the tests are not vacuous. Full output
in the gate comment below.
Static checks (card AC-BE-13-1):
Resulting check order (
Metadata checkis index 7):Not verified here: the
[shell-gated]live check on dev-6(
docker exec dspace8603 /dspace/bin/dspace health-report -c 7) — I have no shell on that host.HealthReportIT#testMetadataCheckcovers the same path in-process: it reads the persistedReportResultJSON, finds theMetadata checkentry by name and asserts integererrorCount(4) and
warningCount(1) plus the per-typeerrors/warningsarrays.One thing a reviewer should know: most of
report-diff-fields.jsonis inert on this branch foran unrelated reason.
InfoCheck,ItemCheckandUserCheckare byte-identical with vanilladspace-9.3and callsetReportJsonnowhere, so 23 of the resource's 26 mappings have noemitter. This PR adds the third emitter (
MetadataCheck, afterLicenseCheck) and makes 2 ofthose mappings live. The other 23 are a separate defect, not addressed here.
🤖 Generated with Claude Code