JBoss EAP 07: a repeatable lab for HTTP, database, MQ, and log comparison
Lesson 6 identified HTTP, database, MQ, and log evidence. Once those records exist, how do you avoid rereading everything? This lesson provides a local comparator. Start with synthetic cases, locate differences, then return to the original evidence to decide what changed.
This is the practical follow-up to the six foundation lessons. The download uses Python’s standard library and synthetic data, with no EAP installation, database, or MQ required. The tested result covers the comparator and fixtures; it does not execute an enterprise migration.
Download lesson 07: comparator, four cases, and review templateDefine what makes two runs comparable
The exercise assumes an MDB fails after a database write but before processing completes. Its hand-authored baseline expects rollback and a processing-failed event. That is a fixture assumption, not a guarantee for every MDB. Derive real expectations from the transaction boundary investigated in lesson 5. Red Hat’s transaction documentation explains configuration and recovery, not the validity of this synthetic outcome.
Both snapshots must declare the same case_id, input, start_state_id, and observation_rule. Together they identify input, starting state, and collection rules. An empty queue and a queue containing yesterday’s messages are not equivalent starting points. The tool rejects different declarations; a reviewer must still check whether actual execution followed them.
An empty result is different from missing evidence
"db": {
"state": "captured",
"evidence_ref": "synthetic:example-only",
"data": { "orders": [] }
}
"mq": {
"state": "missing",
"evidence_ref": null,
"data": null
}These are separate field excerpts; the complete JSON is in fixtures/baseline.json. The first declares an observed empty order set, while the second declares unavailable MQ evidence. Replacing unknown results with empty arrays can manufacture equality. All four surfaces must state their capture status, and two missing surfaces cannot match.
The MDB fixture records HTTP as not applicable with a reason, leaving that scope decision visible. A web case should capture relevant status, headers, and body. The case contract determines data coverage; the comparator cannot detect an important header or table that was never submitted.
Predict, then run four comparisons
python3 compare.py fixtures/baseline.json fixtures/match.json
python3 compare.py fixtures/baseline.json fixtures/db-difference.json
python3 compare.py fixtures/baseline.json fixtures/mq-duplicate.json
python3 compare.py fixtures/baseline.json fixtures/mq-missing.jsonRun each command separately inside the extracted migration-parity directory using Python 3.9 or newer. Do not chain them with &&: a detected difference intentionally returns a nonzero exit code. Before reading the answer, decide whether an extra DB row, a duplicate delivery, and uncollected MQ evidence deserve the same classification.
| Candidate | Status / exit | Where to look |
|---|---|---|
| match.json | match / 0 | All four submitted surfaces agree |
| db-difference.json | different / 1 | db → /orders |
| mq-duplicate.json | different / 1 | mq → /deliveries |
| mq-missing.json | incomplete / 2 | mq → missing_from |
The duplicate case reports path: /deliveries and kind: length_changed under mq. It does not diagnose an MDB redelivery configuration fault. Inspect the message records, business key, delivery count, transaction outcome, and logs to distinguish expected redelivery, duplicate side effects, or duplicate collection.
Unreadable files, malformed JSON, missing required fields, or different scenario declarations return invalid / 3. If the database differs while MQ evidence is missing, the overall result is different and has_missing_evidence remains true. One finding must not hide another gap.
Know exactly what the comparator preserves
Object key order is ignored; array order, counts, and duplicates remain. Missing keys differ from null, and true, 1, 1.0, and "1" are distinct. Decimal parsing preserves precision, while equal decimal spellings such as 1.0 and 1.00 compare equal. This is strict structured-data comparison, not a byte-for-byte JSON comparison.
The tool does not automatically drop timestamps or IDs, sort messages, or deduplicate records. If log times legitimately differ, define reviewed normalization that retains ordering and relationships, preserve raw evidence, and then produce comparable snapshots. Database exports also need a stable order or a reviewed sorting rule. Blanket sorting and deduplication can hide duplicate delivery.
Each surface lists at most 50 differences and marks truncation explicitly without changing the different status. Reports contain paths and difference kinds plus input SHA-256 hashes. Hashes identify the submitted files, not their authenticity or coverage. Evidence references are labels and are never opened or verified.
Turn the report into a short review handoff
REVIEW.md records the change, case, difference paths, original evidence, and next check. AI may help connect differences to code, while identifying supporting evidence and unknowns. Start a review with the case and its differences, then inspect relevant code. This is a workflow proposal, not a measured productivity claim.
The local kit passed 12 tests covering coexisting differences and gaps, duplicate messages, types, decimal precision, invalid inputs, and unchanged files. For a corporate environment, the next step is one known normal case and one known failing case that validate the collection process. Matching submitted content cannot replace that check.
Review lesson 06: define migration evidenceLesson 08: build and inspect a Spring Boot WAR