From 44bcee112e1494fa44d8d60570ca90bfaf4cd2b7 Mon Sep 17 00:00:00 2001 From: "Donald F. Coffin" Date: Fri, 9 Jan 2026 16:06:53 -0500 Subject: [PATCH] refactor: Phase 8 - PnodeRef ESPI 4.0 schema compliance Per ESPI 4.0 specification, PnodeRef extends Object (not IdentifiedObject), so it has NO Atom metadata fields. This phase aligns the mapper, repository, and tests with the XSD definition. Entity and DTO were already compliant. Changes: - PnodeRefMapper: Remove updateEntity method (read-only operations) - PnodeRefMapper: Remove MappingTarget import - PnodeRefRepository: Keep only indexed queries (findAllIds, findAllByUsagePointId) - PnodeRefRepository: Remove 9 non-indexed custom queries - PnodeRefRepository: Remove unused UsagePointEntity import - PnodeRefRepositoryTest: Add test for findAllIds() - PnodeRefRepositoryTest: Update test for renamed findAllByUsagePointId - PnodeRefRepositoryTest: Remove 9 tests for deleted queries All 529 tests pass. Entity and DTO already match XSD structure correctly. Co-Authored-By: Claude Sonnet 4.5 --- .../common/mapper/usage/PnodeRefMapper.java | 10 - .../usage/PnodeRefRepository.java | 88 +------- .../usage/PnodeRefRepositoryTest.java | 209 ++---------------- 3 files changed, 17 insertions(+), 290 deletions(-) diff --git a/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/mapper/usage/PnodeRefMapper.java b/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/mapper/usage/PnodeRefMapper.java index 7aff365e..fc3433b9 100644 --- a/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/mapper/usage/PnodeRefMapper.java +++ b/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/mapper/usage/PnodeRefMapper.java @@ -23,7 +23,6 @@ import org.greenbuttonalliance.espi.common.dto.usage.PnodeRefDto; import org.mapstruct.Mapper; import org.mapstruct.Mapping; -import org.mapstruct.MappingTarget; /** * MapStruct mapper for converting between PnodeRefEntity and PnodeRefDto. @@ -60,13 +59,4 @@ public interface PnodeRefMapper { @Mapping(target = "endEffectiveDate", source = "endEffectiveDate") PnodeRefEntity toEntity(PnodeRefDto dto); - /** - * Updates an existing PnodeRefEntity with data from a PnodeRefDto. - * - * @param dto the source DTO - * @param entity the target entity to update - */ - @Mapping(target = "id", ignore = true) - @Mapping(target = "usagePoint", ignore = true) - void updateEntity(PnodeRefDto dto, @MappingTarget PnodeRefEntity entity); } \ No newline at end of file diff --git a/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/repositories/usage/PnodeRefRepository.java b/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/repositories/usage/PnodeRefRepository.java index f9829f60..059f78f3 100644 --- a/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/repositories/usage/PnodeRefRepository.java +++ b/openespi-common/src/main/java/org/greenbuttonalliance/espi/common/repositories/usage/PnodeRefRepository.java @@ -20,7 +20,6 @@ package org.greenbuttonalliance.espi.common.repositories.usage; import org.greenbuttonalliance.espi.common.domain.usage.PnodeRefEntity; -import org.greenbuttonalliance.espi.common.domain.usage.UsagePointEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -34,92 +33,13 @@ *

* PnodeRef extends Object (not IdentifiedObject) in ESPI 4.0 XSD, * so it uses Long ID (not UUID). - *

- * Provides CRUD operations and custom queries for pricing node references. */ @Repository public interface PnodeRefRepository extends JpaRepository { - /** - * Find all pricing node references for a specific usage point. - * - * @param usagePoint the usage point - * @return list of pricing node references - */ - List findByUsagePoint(UsagePointEntity usagePoint); - - /** - * Find pricing node references by usage point ID. - * - * @param usagePointId the usage point ID (UUID for UsagePoint which extends IdentifiedObject) - * @return list of pricing node references - */ - List findByUsagePointId(UUID usagePointId); - - /** - * Find pricing node references by type. - * - * @param apnodeType the pricing node type - * @return list of pricing node references - */ - List findByApnodeType(String apnodeType); - - /** - * Find pricing node references by usage point and type. - * - * @param usagePoint the usage point - * @param apnodeType the pricing node type - * @return list of pricing node references - */ - List findByUsagePointAndApnodeType(UsagePointEntity usagePoint, String apnodeType); - - /** - * Find pricing node references by reference identifier. - * - * @param ref the reference identifier - * @return list of pricing node references - */ - List findByRef(String ref); - - /** - * Find currently valid pricing node references for a usage point. - * - * @param usagePointId the usage point ID - * @param currentTime current time in epoch seconds - * @return list of valid pricing node references - */ - @Query("SELECT p FROM PnodeRefEntity p WHERE p.usagePoint.id = :usagePointId " + - "AND (p.startEffectiveDate IS NULL OR p.startEffectiveDate <= :currentTime) " + - "AND (p.endEffectiveDate IS NULL OR p.endEffectiveDate >= :currentTime)") - List findValidByUsagePointId(@Param("usagePointId") UUID usagePointId, - @Param("currentTime") Long currentTime); - - /** - * Find currently valid pricing node references by type. - * - * @param apnodeType the pricing node type - * @param currentTime current time in epoch seconds - * @return list of valid pricing node references - */ - @Query("SELECT p FROM PnodeRefEntity p WHERE p.apnodeType = :apnodeType " + - "AND (p.startEffectiveDate IS NULL OR p.startEffectiveDate <= :currentTime) " + - "AND (p.endEffectiveDate IS NULL OR p.endEffectiveDate >= :currentTime)") - List findValidByApnodeType(@Param("apnodeType") String apnodeType, - @Param("currentTime") Long currentTime); - - /** - * Delete all pricing node references for a usage point. - * - * @param usagePoint the usage point - * @return number of deleted records - */ - Long deleteByUsagePoint(UsagePointEntity usagePoint); + @Query("SELECT p.id FROM PnodeRefEntity p") + List findAllIds(); - /** - * Delete pricing node references by usage point ID. - * - * @param usagePointId the usage point ID - * @return number of deleted records - */ - Long deleteByUsagePointId(UUID usagePointId); + @Query("SELECT p FROM PnodeRefEntity p WHERE p.usagePoint.id = :usagePointId") + List findAllByUsagePointId(@Param("usagePointId") UUID usagePointId); } \ No newline at end of file diff --git a/openespi-common/src/test/java/org/greenbuttonalliance/espi/common/repositories/usage/PnodeRefRepositoryTest.java b/openespi-common/src/test/java/org/greenbuttonalliance/espi/common/repositories/usage/PnodeRefRepositoryTest.java index ee9f8e4a..a2cec5d6 100644 --- a/openespi-common/src/test/java/org/greenbuttonalliance/espi/common/repositories/usage/PnodeRefRepositoryTest.java +++ b/openespi-common/src/test/java/org/greenbuttonalliance/espi/common/repositories/usage/PnodeRefRepositoryTest.java @@ -112,235 +112,52 @@ void shouldSavePricingNodeRefWithEffectiveDates() { class CustomQueryMethodsTest { @Test - @DisplayName("Should find pricing node refs by usage point") - void shouldFindPricingNodeRefsByUsagePoint() { + @DisplayName("Should find all IDs") + void shouldFindAllIds() { // Arrange UsagePointEntity usagePoint = TestDataBuilders.createValidUsagePoint(); UsagePointEntity savedUsagePoint = usagePointRepository.save(usagePoint); - + PnodeRefEntity pnodeRef1 = new PnodeRefEntity("HUB", "HUB_1", savedUsagePoint); PnodeRefEntity pnodeRef2 = new PnodeRefEntity("LOAD_ZONE", "ZONE_1", savedUsagePoint); - - pnodeRefRepository.save(pnodeRef1); - pnodeRefRepository.save(pnodeRef2); + + PnodeRefEntity saved1 = pnodeRefRepository.save(pnodeRef1); + PnodeRefEntity saved2 = pnodeRefRepository.save(pnodeRef2); flushAndClear(); // Act - List pnodeRefs = pnodeRefRepository.findByUsagePoint(savedUsagePoint); + List allIds = pnodeRefRepository.findAllIds(); // Assert - assertThat(pnodeRefs).hasSize(2); - assertThat(pnodeRefs).extracting(PnodeRefEntity::getRef) - .containsExactlyInAnyOrder("HUB_1", "ZONE_1"); + assertThat(allIds).contains(saved1.getId(), saved2.getId()); } @Test - @DisplayName("Should find pricing node refs by usage point ID") - void shouldFindPricingNodeRefsByUsagePointId() { + @DisplayName("Should find all pricing node refs by usage point ID") + void shouldFindAllPricingNodeRefsByUsagePointId() { // Arrange UsagePointEntity usagePoint1 = TestDataBuilders.createValidUsagePoint(); UsagePointEntity usagePoint2 = TestDataBuilders.createValidUsagePoint(); UsagePointEntity savedUsagePoint1 = usagePointRepository.save(usagePoint1); UsagePointEntity savedUsagePoint2 = usagePointRepository.save(usagePoint2); - + PnodeRefEntity pnodeRef1 = new PnodeRefEntity("HUB", "HUB_1", savedUsagePoint1); PnodeRefEntity pnodeRef2 = new PnodeRefEntity("HUB", "HUB_2", savedUsagePoint1); PnodeRefEntity pnodeRef3 = new PnodeRefEntity("HUB", "HUB_3", savedUsagePoint2); - + pnodeRefRepository.save(pnodeRef1); pnodeRefRepository.save(pnodeRef2); pnodeRefRepository.save(pnodeRef3); flushAndClear(); // Act - List pnodeRefs = pnodeRefRepository.findByUsagePointId(savedUsagePoint1.getId()); + List pnodeRefs = pnodeRefRepository.findAllByUsagePointId(savedUsagePoint1.getId()); // Assert assertThat(pnodeRefs).hasSize(2); assertThat(pnodeRefs).extracting(PnodeRefEntity::getRef) .containsExactlyInAnyOrder("HUB_1", "HUB_2"); } - - @Test - @DisplayName("Should find pricing node refs by apnode type") - void shouldFindPricingNodeRefsByApnodeType() { - // Arrange - UsagePointEntity usagePoint = TestDataBuilders.createValidUsagePoint(); - UsagePointEntity savedUsagePoint = usagePointRepository.save(usagePoint); - - PnodeRefEntity pnodeRef1 = new PnodeRefEntity("HUB", "HUB_1", savedUsagePoint); - PnodeRefEntity pnodeRef2 = new PnodeRefEntity("HUB", "HUB_2", savedUsagePoint); - PnodeRefEntity pnodeRef3 = new PnodeRefEntity("LOAD_ZONE", "ZONE_1", savedUsagePoint); - - pnodeRefRepository.save(pnodeRef1); - pnodeRefRepository.save(pnodeRef2); - pnodeRefRepository.save(pnodeRef3); - flushAndClear(); - - // Act - List hubRefs = pnodeRefRepository.findByApnodeType("HUB"); - - // Assert - assertThat(hubRefs).hasSize(2); - assertThat(hubRefs).extracting(PnodeRefEntity::getRef) - .containsExactlyInAnyOrder("HUB_1", "HUB_2"); - } - - @Test - @DisplayName("Should find pricing node refs by usage point and apnode type") - void shouldFindPricingNodeRefsByUsagePointAndApnodeType() { - // Arrange - UsagePointEntity usagePoint = TestDataBuilders.createValidUsagePoint(); - UsagePointEntity savedUsagePoint = usagePointRepository.save(usagePoint); - - PnodeRefEntity pnodeRef1 = new PnodeRefEntity("HUB", "HUB_1", savedUsagePoint); - PnodeRefEntity pnodeRef2 = new PnodeRefEntity("LOAD_ZONE", "ZONE_1", savedUsagePoint); - - pnodeRefRepository.save(pnodeRef1); - pnodeRefRepository.save(pnodeRef2); - flushAndClear(); - - // Act - List hubRefs = pnodeRefRepository.findByUsagePointAndApnodeType(savedUsagePoint, "HUB"); - - // Assert - assertThat(hubRefs).hasSize(1); - assertThat(hubRefs.get(0).getRef()).isEqualTo("HUB_1"); - } - - @Test - @DisplayName("Should find pricing node refs by ref") - void shouldFindPricingNodeRefsByRef() { - // Arrange - UsagePointEntity usagePoint = TestDataBuilders.createValidUsagePoint(); - UsagePointEntity savedUsagePoint = usagePointRepository.save(usagePoint); - - PnodeRefEntity pnodeRef1 = new PnodeRefEntity("HUB", "UNIQUE_HUB", savedUsagePoint); - PnodeRefEntity pnodeRef2 = new PnodeRefEntity("LOAD_ZONE", "COMMON_REF", savedUsagePoint); - - pnodeRefRepository.save(pnodeRef1); - pnodeRefRepository.save(pnodeRef2); - flushAndClear(); - - // Act - List refs = pnodeRefRepository.findByRef("UNIQUE_HUB"); - - // Assert - assertThat(refs).hasSize(1); - assertThat(refs.get(0).getApnodeType()).isEqualTo("HUB"); - } - - @Test - @DisplayName("Should find valid pricing node refs by usage point ID") - void shouldFindValidPricingNodeRefsByUsagePointId() { - // Arrange - UsagePointEntity usagePoint = TestDataBuilders.createValidUsagePoint(); - UsagePointEntity savedUsagePoint = usagePointRepository.save(usagePoint); - - long currentTime = System.currentTimeMillis() / 1000; - long pastTime = currentTime - 3600; // 1 hour ago - long futureTime = currentTime + 3600; // 1 hour from now - - // Valid: no dates set (always valid) - PnodeRefEntity validRef1 = new PnodeRefEntity("HUB", "ALWAYS_VALID", savedUsagePoint); - - // Valid: started in past, no end date - PnodeRefEntity validRef2 = new PnodeRefEntity("HUB", "STARTED_VALID", pastTime, null, savedUsagePoint); - - // Invalid: starts in future - PnodeRefEntity invalidRef = new PnodeRefEntity("HUB", "FUTURE_START", futureTime, null, savedUsagePoint); - - pnodeRefRepository.save(validRef1); - pnodeRefRepository.save(validRef2); - pnodeRefRepository.save(invalidRef); - flushAndClear(); - - // Act - List validRefs = pnodeRefRepository.findValidByUsagePointId(savedUsagePoint.getId(), currentTime); - - // Assert - assertThat(validRefs).hasSize(2); - assertThat(validRefs).extracting(PnodeRefEntity::getRef) - .containsExactlyInAnyOrder("ALWAYS_VALID", "STARTED_VALID"); - } - - @Test - @DisplayName("Should find valid pricing node refs by apnode type") - void shouldFindValidPricingNodeRefsByApnodeType() { - // Arrange - UsagePointEntity usagePoint = TestDataBuilders.createValidUsagePoint(); - UsagePointEntity savedUsagePoint = usagePointRepository.save(usagePoint); - - long currentTime = System.currentTimeMillis() / 1000; - long pastTime = currentTime - 3600; // 1 hour ago - long futureTime = currentTime + 3600; // 1 hour from now - - // Valid HUB - PnodeRefEntity validHub = new PnodeRefEntity("HUB", "VALID_HUB", pastTime, futureTime, savedUsagePoint); - - // Invalid HUB (expired) - PnodeRefEntity expiredHub = new PnodeRefEntity("HUB", "EXPIRED_HUB", pastTime, pastTime + 1800, savedUsagePoint); - - // Valid LOAD_ZONE - PnodeRefEntity validZone = new PnodeRefEntity("LOAD_ZONE", "VALID_ZONE", savedUsagePoint); - - pnodeRefRepository.save(validHub); - pnodeRefRepository.save(expiredHub); - pnodeRefRepository.save(validZone); - flushAndClear(); - - // Act - List validHubs = pnodeRefRepository.findValidByApnodeType("HUB", currentTime); - - // Assert - assertThat(validHubs).hasSize(1); - assertThat(validHubs.get(0).getRef()).isEqualTo("VALID_HUB"); - } - - @Test - @DisplayName("Should delete pricing node refs by usage point") - void shouldDeletePricingNodeRefsByUsagePoint() { - // Arrange - UsagePointEntity usagePoint = TestDataBuilders.createValidUsagePoint(); - UsagePointEntity savedUsagePoint = usagePointRepository.save(usagePoint); - - PnodeRefEntity pnodeRef1 = new PnodeRefEntity("HUB", "HUB_1", savedUsagePoint); - PnodeRefEntity pnodeRef2 = new PnodeRefEntity("HUB", "HUB_2", savedUsagePoint); - - pnodeRefRepository.save(pnodeRef1); - pnodeRefRepository.save(pnodeRef2); - flushAndClear(); - - // Act - Long deletedCount = pnodeRefRepository.deleteByUsagePoint(savedUsagePoint); - flushAndClear(); - - // Assert - assertThat(deletedCount).isEqualTo(2L); - List remainingRefs = pnodeRefRepository.findByUsagePoint(savedUsagePoint); - assertThat(remainingRefs).isEmpty(); - } - - @Test - @DisplayName("Should delete pricing node refs by usage point ID") - void shouldDeletePricingNodeRefsByUsagePointId() { - // Arrange - UsagePointEntity usagePoint = TestDataBuilders.createValidUsagePoint(); - UsagePointEntity savedUsagePoint = usagePointRepository.save(usagePoint); - - PnodeRefEntity pnodeRef = new PnodeRefEntity("HUB", "DELETE_TEST", savedUsagePoint); - pnodeRefRepository.save(pnodeRef); - flushAndClear(); - - // Act - Long deletedCount = pnodeRefRepository.deleteByUsagePointId(savedUsagePoint.getId()); - flushAndClear(); - - // Assert - assertThat(deletedCount).isEqualTo(1L); - List remainingRefs = pnodeRefRepository.findByUsagePointId(savedUsagePoint.getId()); - assertThat(remainingRefs).isEmpty(); - } } @Nested