This commit is contained in:
2026-09-29 18:06:18 +08:00
parent 54ad26c607
commit 2c60a29e0f
30 changed files with 384 additions and 139 deletions
@@ -1,6 +1,8 @@
package com.baiyue.lastleg.shipping.service;
import com.baiyue.common.event.EventEnvelope;
import com.baiyue.common.event.EventProtocolException;
import com.baiyue.common.event.EventDependencyNotReadyException;
import com.baiyue.common.event.DeliveryAck;
import com.baiyue.common.event.EventPayloadCanonicalizer;
import com.baiyue.common.event.EventPayloadHash;
@@ -36,7 +38,7 @@ public class ContainerShippingNodeConsumer {
LastlegEventInbox existing = inboxes.selectById(envelope.eventId());
if (existing != null) {
if (!existing.getPayloadHash().equalsIgnoreCase(envelope.payloadHash())) {
throw new IllegalArgumentException("船节点事件摘要冲突");
throw new EventProtocolException("船节点事件摘要冲突");
}
if (!"PROCESSED".equals(existing.getStatus())) throw new IllegalStateException("事件尚未完成消费");
return DeliveryAck.of(envelope, DeliveryAck.Outcome.DUPLICATE);
@@ -46,7 +48,7 @@ public class ContainerShippingNodeConsumer {
catch (DuplicateKeyException raced) {
LastlegEventInbox concurrent = inboxes.selectById(envelope.eventId());
if (concurrent == null || !concurrent.getPayloadHash().equalsIgnoreCase(envelope.payloadHash())) {
throw new IllegalArgumentException("船节点事件摘要冲突", raced);
throw new EventProtocolException("船节点事件摘要冲突", raced);
}
if (!"PROCESSED".equals(concurrent.getStatus())) throw new IllegalStateException("事件尚未完成消费");
return DeliveryAck.of(envelope, DeliveryAck.Outcome.DUPLICATE);
@@ -55,8 +57,9 @@ public class ContainerShippingNodeConsumer {
gates.initialize(payload.containerBookingId(), payload.oceanBookingId(),
payload.containerNo(), 0, 1);
ContainerShippingGate gate = gates.lock(payload.containerBookingId());
if (gate == null || !payload.containerNo().equals(gate.getContainerNo())) {
throw new IllegalArgumentException("船节点柜号快照与装柜交接不一致");
if (gate == null) throw new EventDependencyNotReadyException("船节点柜级投影尚未就绪");
if (!payload.containerNo().equals(gate.getContainerNo())) {
throw new EventProtocolException("船节点柜号快照与装柜交接不一致");
}
boolean applied = apply(gate, envelope, payload);
gates.updateById(gate);
@@ -98,7 +101,7 @@ public class ContainerShippingNodeConsumer {
envelope.requireValid();
if (!EventPayloadHash.matches(EventPayloadCanonicalizer.canonicalize(envelope.payload()),
envelope.payloadHash())) {
throw new IllegalArgumentException("payloadHash 与船节点事件负载不一致");
throw new EventProtocolException("payloadHash 与船节点事件负载不一致");
}
if (!EventTypes.FIRST_LEG_CONTAINER_SHIPPING_NODE_RECORDED.equals(envelope.eventType())
|| envelope.eventVersion() != 1 || envelope.sourceRegion() != RegionCode.CN
@@ -106,19 +109,19 @@ public class ContainerShippingNodeConsumer {
|| !"CONTAINER_BOOKING".equals(envelope.aggregateType())
|| envelope.handoverVersion() == null
|| envelope.handoverVersion() != envelope.aggregateVersion() + 1) {
throw new IllegalArgumentException("船节点交接信封无效");
throw new EventProtocolException("船节点交接信封无效");
}
}
private void validateEnvelopePayload(EventEnvelope envelope, FirstLegContainerShippingNodeRecordedV1 payload) {
if (!"0".equals(envelope.tenantId()) || !envelope.aggregateId().equals(payload.containerBookingId())) {
throw new IllegalArgumentException("船节点交接平台作用域或聚合标识不一致");
throw new EventProtocolException("船节点交接平台作用域或聚合标识不一致");
}
}
private FirstLegContainerShippingNodeRecordedV1 payload(EventEnvelope envelope) {
try { return objectMapper.treeToValue(envelope.payload(), FirstLegContainerShippingNodeRecordedV1.class); }
catch (Exception exception) { throw new IllegalArgumentException("船节点交接负载无效", exception); }
catch (Exception exception) { throw new EventProtocolException("船节点交接负载无效", exception); }
}
private LastlegEventInbox inbox(EventEnvelope envelope) {