Skip to content

CLARIN-DSpace v9/Restore the fork health checks taken wholesale from vanilla (23 of 26 report-diff mappings have no emitter) - #1439

Open
milanmajchrak wants to merge 1 commit into
dtq-dev-9-basefrom
ufal/fix-health-checks-vanilla-wholesale-9-base
Open

CLARIN-DSpace v9/Restore the fork health checks taken wholesale from vanilla (23 of 26 report-diff mappings have no emitter)#1439
milanmajchrak wants to merge 1 commit into
dtq-dev-9-basefrom
ufal/fix-health-checks-vanilla-wholesale-9-base

Conversation

@milanmajchrak

Copy link
Copy Markdown
Collaborator

References

  • Acceptance card X-08 (_sync3/cards/X-08.md); depends on BE-13, merged as ac1eeecd79
  • The fork hunks come from 3dc9cecf7d "Health report, report diff fixes (Health report, report diff fixes #1254)" on dtq-dev
  • Instance of guard X1 (vanilla-wholesale): ItemCheck and Report are the two largest entries in the BE X1 worklist

Description

InfoCheck, ItemCheck and UserCheck were byte-identical with vanilla dspace-9.3 on this branch
although the fork changes all three. Their setReportJson calls were therefore gone, and 23 of the 26
mappings in report-diff-fields.json addressed a value that nothing produced
. report-diff printed
those columns empty and no test failed.

Instructions for Reviewers

The defect

report-diff never reads the checks. It reads the JSON that a health-report run stored and addresses each
value by a path such as /checks/[name=Item summary]/report/collectionsSizesInfo/totalSize. Nothing links
that path back to the class that is supposed to emit it, so when the v9 upgrade took the three classes from
upstream whole, the mappings kept resolving to nothing and the only symptom was empty columns.

Measured on the base (6e8185521f):

$ for c in InfoCheck ItemCheck UserCheck; do f=.../health/$c.java;
    [ "$(git rev-parse origin/dtq-dev-9-base:$f)" = "$(git rev-parse dspace-9.3:$f)" ] && echo "STILL-VANILLA $c"; done
STILL-VANILLA InfoCheck
STILL-VANILLA ItemCheck
STILL-VANILLA UserCheck

$ git grep -l setReportJson origin/dtq-dev-9-base -- 'dspace-api/src/main/java/org/dspace/health/*.java' | wc -l
3        # Check.java (the setter), LicenseCheck, MetadataCheck

Breakdown of the 23: Item summary 17, User summary 4, General Information 2.

List of changes in this PR

  • InfoCheck - emits generated, fromTill, url and the directoryStats array. report-diff
    addresses that array positionally (directoryStats/0 assetstore, /1 log dir), so an entry is appended
    for every directory even when it cannot be read; dropping one would shift the other's index.
  • ItemCheck - emits communities, collectionsSizesInfo (with totalSize, deletedBitstreams,
    orphanBitstreamsCount, ...), publishedItems, withdrawnItems, notPublishedItems, stagesCounts,
    waitingForApproval and the eleven entity counts. All 17 Item summary mappings.
  • UserCheck - emits users, haveEmail, the camel-cased per-attribute counts (including
    selfRegistered), emptyGroups, subscribers and subscribedCollections. It also carries the fork's
    fix of the "Self registered" counter, which tested getNetid() twice and so reported a copy of
    "Have netid".
  • Report.java deleted, and its healthcheck command removed from launcher.xml - see below.
  • ReportDiffFieldMappingIT (new) - three tests that keep this from happening again.

Two deliberate deviations from the fork, both to avoid importing a defect:

  1. ItemCheck.getObjectSizesInfo keeps the v9 direct countTotal(context) calls instead of the fork's
    wrapSql + LinkedHashMap<String, CountInfo> refactor. wrapSql converts the checked SQLException
    into a RuntimeException, which run()'s catch (SQLException) cannot see - one failing count would
    abort the entire health report instead of being recorded by error(e) and the rest of the report
    finishing. The JSON keys, their order and the report text are the fork's.
  2. ReportInfo returns LocalDate on v9 and Date on the fork, so the dates are formatted directly with
    DateFormatConstants.DATE_FORMATTER rather than through Date.toInstant().atZone(...).

Minor: !s.isEmpty() kept where the fork writes s.length() > 0; instance service fields kept rather than
the fork's static final.

Why Report.java is in this PR

3dc9cecf7d deleted org/dspace/health/Report.java when the health-report DSpaceRunnable replaced it,
and removed the healthcheck command that pointed at it. The v9 base kept both: the class, and
launcher.xml:14 still declaring healthcheck with <class>org.dspace.health.Report</class>. So
dspace healthcheck on the CLI ran the pre-script class, which writes neither setReportJson output nor a
ReportResult row - report-diff would have had nothing to diff even after the three checks above were
fixed. The replacement is already wired on this branch
(dspace/config/spring/api/scripts.xml:115, bean health-report), and Report had no other reference in
the tree. It belongs to the same fork hunk and the same feature, so it goes in the same PR. The
matomo-report-generator command that sits in the same launcher.xml delta does not - that is card X-04.

How to test

mvn -o -pl dspace-api verify -DskipIntegrationTests=false -Dit.test=ReportDiffFieldMappingIT \
    -Denforcer.skip=true -Dcheckstyle.skip=true -Dlicense.skip=true -Dxml.skip=true
# Tests run: 3, Failures: 0, Errors: 0
Test What it pins down
everyMappedFieldIsEmittedByItsCheck runs a real health report and resolves every mapping in report-diff-fields.json against the JSON it stored
everyMappedCheckNameResolvesToACheckOnTheClasspath every [name=...] resolves to a Check plugin registered in config/modules/healthcheck.cfg
fieldMappingsAndFieldOrderDescribeTheSameFields ReportDiff iterates fieldOrder and only looks the label up in fieldMappings, so a field in one and not the other is silently dropped

Negative control - revert each class to its vanilla blob and the test names exactly the mappings that class
owns:

reverted to dspace-9.3 unresolved paths named
ItemCheck 17 all [name=Item summary]
UserCheck 4 all [name=User summary]
InfoCheck 2 both [name=General Information]/report/directoryStats/N/size_bytes

17 + 4 + 2 = the 23 mappings this PR restores.

Regression gate: HealthReportIT - Tests run: 12, Failures: 0, Errors: 0.
mvn clean install -P-assembly -DskipTests - BUILD SUCCESS, 0 Checkstyle violations.

Found while working, not fixed here

dspace-api/src/test/java/org/dspace/scripts/ReportDiffIT.java exists on dtq-dev (1016 lines) and is
absent from this branch, and no acceptance card owns it. The report-diff script itself is ported here;
only its test is missing. It needs its own card.

Checklist

  • My PR is created against the dtq-dev-9-base branch (fork's DSpace 9 base; not main).
  • My PR is small in size (not counting the deleted dead class and the new IT).
  • My PR passes Checkstyle validation.
  • My PR includes Javadoc for the new and modified non-trivial methods.
  • My PR passes all tests and includes a new Integration Test.
  • My PR includes details on how to test it.
  • My PR includes no new libraries/dependencies.
  • My PR does not modify REST API endpoints.
  • My PR includes no new configuration keys; it removes one dead launcher.xml command.

🤖 Generated with Claude Code

… report-diff mappings had no emitter)

InfoCheck, ItemCheck and UserCheck were byte-identical with vanilla dspace-9.3
on the v9 base although the fork changes all three. The upgrade took them from
upstream whole and the fork hunks never landed, so their setReportJson calls
were gone: only LicenseCheck and (since BE-13) MetadataCheck still emitted
report JSON, and 23 of the 26 mappings in report-diff-fields.json addressed a
value nothing produced - Item summary 17, User summary 4, General Information 2.
report-diff printed those columns empty and nothing failed.

The three checks now build the same JSON the fork does, alongside the unchanged
human-readable report. Two deliberate deviations from the fork, both recorded in
the PR: getObjectSizesInfo keeps the v9 direct calls instead of the fork's
wrapSql wrapper, which converts the checked SQLException into a RuntimeException
that run()'s catch cannot see and that would abort the whole report; and
ReportInfo returns LocalDate on v9, so the dates are formatted directly instead
of via Date.toInstant().atZone(). UserCheck also carries the fork's fix of the
"Self registered" counter, which tested getNetid() twice.

Report.java goes with them: the fork deleted it in 3dc9cec when the
health-report script replaced it, and launcher.xml still pointed the healthcheck
command at it, so `dspace healthcheck` ran the old class that writes no JSON and
no ReportResult at all.

ReportDiffFieldMappingIT walks every mapping in report-diff-fields.json against
a real health report, so a mapping that loses its emitter fails instead of
silently printing nothing.

Card X-08.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant