Skip to content

Conversation

@dfcoffin
Copy link
Contributor

@dfcoffin dfcoffin commented Jan 5, 2026

Summary

Converts all XML marshalling tests from JAXB to Jackson 3 XmlMapper to match production code implementation. Fixes all test data UUIDs to use ESPI 4.0 compliant Version-5 format.

Changes

Tests Converted to Jackson 3 (27 total - all passing ✅)

  1. TimeConfigurationDtoTest - 11 tests

    • Replaced JAXB with Jackson 3 XmlMapper
    • Updated assertions to use AssertJ
    • Fixed namespace handling (Jackson 3 uses default namespace)
  2. Jackson3XmlMarshallingTest - 7 tests (renamed from SimpleXmlMarshallingTest)

    • Removed @disabled annotation
    • Converted from JAXB to Jackson 3
    • Enhanced assertions for XML validation
  3. XmlDebugTest - 3 tests

    • Converted to Jackson 3
    • Enhanced from 1 test to 3 tests
    • Added comprehensive XML structure validation
  4. DtoExportServiceImplTest - 6 tests

    • Added comprehensive XML structure assertions
    • Added Atom metadata validation
    • Added ESPI content validation
    • Added Version-5 UUID validation

UUID Compliance (Version-4 → Version-5)

All test data UUIDs converted to ESPI 4.0 compliant Version-5 format:

  • Feed ID: 15B0A4ED-CCF4-5521-A0A1-9FF650EC8A6B (was 4521, now 5521)
  • UsagePoint: 48C2A019-5598-5E16-B0F9-49E4FF27F5FB (was 4E16, now 5E16)
  • ReadingType: 3430B025-65D5-593A-BEC2-053603C91CD7 (was 493A, now 593A)
  • IntervalBlock: FE9A61BB-6913-52D4-88BE-9634A218EF53 (was 42D4, now 52D4)

Version-5 format: xxxxxxxx-xxxx-5xxx-xxxx-xxxxxxxxxxxx (note '5' in version field)

DTO Updates (Temporary Fix)

Added @XmlTransient annotations to utility methods:

  • TimeConfigurationDto: 6 methods (getTzOffsetInHours, getDstOffsetInHours, getEffectiveOffset, getEffectiveOffsetInHours, hasDstRules, isDstActive)
  • UsagePointDto: 4 methods (generateSelfHref, generateUpHref, getMeterReadingCount, getUsageSummaryCount)

Reason: POJOs with @XmlAccessorType(XmlAccessType.PROPERTY) serialize ALL public getters. Utility methods need @XmlTransient to exclude them.

Long-term solution: Convert to records with @XmlAccessorType(XmlAccessType.FIELD) (see #61)

Test Coverage

XML Structure Validation

  • XML declaration and encoding (UTF-8)
  • Atom namespace declarations
  • Feed and Entry metadata
  • ISO 8601 timestamp formats

ESPI Content Validation

  • UsagePoint with ServiceCategory
  • ReadingType with all ESPI fields (accumulationBehaviour, commodity, dataQualifier, etc.)
  • IntervalBlock with multiple IntervalReading elements
  • Proper ESPI namespace handling (http://naesb.org/espi)

UUID Validation

  • Version-5 UUID format pattern matching
  • All test data uses deterministic Version-5 UUIDs

Files Changed

Modified (5 files)

  • openespi-common/src/main/java/org/greenbuttonalliance/espi/common/dto/usage/TimeConfigurationDto.java
  • openespi-common/src/main/java/org/greenbuttonalliance/espi/common/dto/usage/UsagePointDto.java
  • openespi-common/src/test/java/org/greenbuttonalliance/espi/common/dto/usage/TimeConfigurationDtoTest.java
  • openespi-common/src/test/java/org/greenbuttonalliance/espi/common/XmlDebugTest.java
  • openespi-common/src/test/java/org/greenbuttonalliance/espi/common/service/impl/DtoExportServiceImplTest.java

Created (2 files)

  • openespi-common/src/test/java/org/greenbuttonalliance/espi/common/Jackson3XmlMarshallingTest.java
  • openespi-common/JACKSON3_XML_MARSHALLING_TEST_PLAN.md (comprehensive conversion plan)

Deleted (1 file)

  • openespi-common/src/test/java/org/greenbuttonalliance/espi/common/SimpleXmlMarshallingTest.java (replaced by Jackson3XmlMarshallingTest)

Test Results

Tests run: 27, Failures: 0, Errors: 0, Skipped: 0

Breakdown:
- TimeConfigurationDtoTest: 11 tests ✅
- Jackson3XmlMarshallingTest: 7 tests ✅
- XmlDebugTest: 3 tests ✅
- DtoExportServiceImplTest: 6 tests ✅

All tests validate that Jackson 3 XmlMapper correctly processes JAXB annotations and generates ESPI 4.0 compliant XML.

Technical Details

Jackson 3 XmlMapper Configuration

All tests use consistent XmlMapper configuration matching production code:

AnnotationIntrospector intr = XmlAnnotationIntrospector.Pair.instance(
    new JakartaXmlBindAnnotationIntrospector(),
    new JacksonAnnotationIntrospector()
);

xmlMapper = XmlMapper.xmlBuilder()
    .annotationIntrospector(intr)
    .addModule(new JakartaXmlBindAnnotationModule()
        .setNonNillableInclusion(JsonInclude.Include.NON_EMPTY))
    .enable(SerializationFeature.INDENT_OUTPUT)
    .enable(DateTimeFeature.WRITE_DATES_WITH_ZONE_ID)
    .disable(XmlWriteFeature.WRITE_NULLS_AS_XSI_NIL)
    .defaultDateFormat(new StdDateFormat())
    .build();

Key Differences: Jackson 3 vs JAXB

  1. Namespace Handling

    • JAXB: Prefixed namespaces (<espi:tzOffset>)
    • Jackson 3: Default namespace (<tzOffset> with xmlns="..." on root)
  2. API Changes

    • Marshalling: xmlMapper.writeValueAsString(object) vs marshaller.marshal(object, writer)
    • Unmarshalling: xmlMapper.readValue(xml, Type.class) vs unmarshaller.unmarshal(reader)
  3. Assertions

    • Now using AssertJ: assertThat().contains(), isEqualTo()
    • Previously JUnit: assertTrue, assertEquals

Documentation

Complete conversion plan documented in:

  • openespi-common/JACKSON3_XML_MARSHALLING_TEST_PLAN.md

Related Issues

Breaking Changes

None - all changes are test-only.

Checklist

  • All tests passing (27/27)
  • UUIDs converted to Version-5 format
  • Documentation complete
  • Related issues updated
  • Code follows project conventions
  • Commit message follows conventional commits

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 4.5 noreply@anthropic.com

dfcoffin and others added 2 commits January 5, 2026 15:02
Complete Jackson 3 XmlMapper conversion for all XML marshalling tests
to match production code implementation. All test data now uses ESPI 4.0
compliant Version-5 UUIDs.

Tests Converted (27 total):
- TimeConfigurationDtoTest: 11 tests
- Jackson3XmlMarshallingTest: 7 tests (renamed from SimpleXmlMarshallingTest)
- XmlDebugTest: 3 tests
- DtoExportServiceImplTest: 6 tests

UUID Compliance:
- Feed ID: 15B0A4ED-CCF4-5521-A0A1-9FF650EC8A6B (Version-5)
- UsagePoint: 48C2A019-5598-5E16-B0F9-49E4FF27F5FB (Version-5)
- ReadingType: 3430B025-65D5-593A-BEC2-053603C91CD7 (Version-5)
- IntervalBlock: FE9A61BB-6913-52D4-88BE-9634A218EF53 (Version-5)

DTO Updates (temporary @XmlTransient fixes):
- TimeConfigurationDto: 6 utility methods
- UsagePointDto: 4 utility methods

Test Coverage:
- XML structure and Atom feed metadata validation
- ESPI content validation (UsagePoint, ReadingType, IntervalBlock)
- Version-5 UUID compliance verification
- ISO 8601 timestamp format validation
- ESPI namespace handling

All 27 tests passing. Jackson 3 XmlMapper correctly processes JAXB
annotations and generates ESPI 4.0 compliant XML.

Related: #62, #61

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…e JAXB

The production code uses Jackson 3 XmlMapper with JAXB annotations (hybrid
approach), not pure JAXB. Updated the test to match production implementation.

This fixes the CI/CD failure where pure JAXB couldn't handle @XmlTransient
annotations on utility methods in POJOs with @XmlAccessorType(PROPERTY).

Jackson 3 handles this correctly, which is why all other tests pass.

Related: #62

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@dfcoffin dfcoffin merged commit ca41115 into main Jan 5, 2026
5 checks passed
@dfcoffin dfcoffin deleted the feature/jackson3-xml-marshalling-tests branch January 5, 2026 21:22
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.

Convert XML marshalling tests from JAXB to Jackson 3 XmlMapper

2 participants