From f87caf9dd1ec832302b585180632dd4228f90a43 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Wed, 30 Sep 2026 00:23:06 +0800 Subject: [PATCH] fix(lastleg): retry shipping nodes until loading handover exists --- .../ContainerShippingNodeConsumer.java | 2 -- .../ContainerShippingNodeConsumerTest.java | 22 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/lastleg-service/src/main/java/com/baiyue/lastleg/shipping/service/ContainerShippingNodeConsumer.java b/lastleg-service/src/main/java/com/baiyue/lastleg/shipping/service/ContainerShippingNodeConsumer.java index 1801f6c13..cb1d1b5de 100644 --- a/lastleg-service/src/main/java/com/baiyue/lastleg/shipping/service/ContainerShippingNodeConsumer.java +++ b/lastleg-service/src/main/java/com/baiyue/lastleg/shipping/service/ContainerShippingNodeConsumer.java @@ -53,8 +53,6 @@ public class ContainerShippingNodeConsumer { return DeliveryAck.of(envelope, DeliveryAck.Outcome.DUPLICATE); } - gates.initialize(payload.containerBookingId(), payload.oceanBookingId(), - payload.containerNo(), 0, 1); ContainerShippingGate gate = gates.lock(payload.containerBookingId()); if (gate == null) throw new EventDependencyNotReadyException("船节点柜级投影尚未就绪"); if (!payload.containerNo().equals(gate.getContainerNo())) { diff --git a/lastleg-service/src/test/java/com/baiyue/lastleg/shipping/service/ContainerShippingNodeConsumerTest.java b/lastleg-service/src/test/java/com/baiyue/lastleg/shipping/service/ContainerShippingNodeConsumerTest.java index a9ea0af18..f88a1b3d3 100644 --- a/lastleg-service/src/test/java/com/baiyue/lastleg/shipping/service/ContainerShippingNodeConsumerTest.java +++ b/lastleg-service/src/test/java/com/baiyue/lastleg/shipping/service/ContainerShippingNodeConsumerTest.java @@ -1,6 +1,7 @@ package com.baiyue.lastleg.shipping.service; import com.baiyue.common.event.EventEnvelope; +import com.baiyue.common.event.EventDependencyNotReadyException; import com.baiyue.common.event.EventPayloadCanonicalizer; import com.baiyue.common.event.EventPayloadHash; import com.baiyue.common.event.EventTypes; @@ -23,6 +24,8 @@ import java.time.Instant; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -42,6 +45,25 @@ class ContainerShippingNodeConsumerTest { ReflectionTestUtils.setField(consumer, "objectMapper", json); } + @Test + void shippingNodeBeforeLoadingHandoverRemainsRetryable() { + EventEnvelope event = event("123e4567-e89b-12d3-a456-426614174106", "PICKUP_READY", 80, 5, + Instant.parse("2026-08-21T10:00:00Z")); + + assertThatThrownBy(() -> consumer.consume(event)) + .isInstanceOf(EventDependencyNotReadyException.class); + verify(gates, never()).initialize(anyString(), anyString(), anyString(), anyLong(), anyLong()); + verify(gates, never()).updateById(any(ContainerShippingGate.class)); + verify(inboxes, never()).updateById(any(LastlegEventInbox.class)); + + ContainerShippingGate gate = gate("AWAITING_PICKUP_READY", 0, 0, + Instant.parse("2026-08-20T10:00:00Z")); + when(gates.lock("CB-1")).thenReturn(gate); + assertThat(consumer.consume(event).outcome()) + .isEqualTo(com.baiyue.common.event.DeliveryAck.Outcome.APPLIED); + assertThat(gate.getStatus()).isEqualTo("RECEIVING_AVAILABLE"); + } + @Test void pickupReadyMonotonicallyOpensReceivingGate() { ContainerShippingGate gate = gate("AWAITING_PICKUP_READY", 70, 4, Instant.parse("2026-08-20T10:00:00Z"));