feat: close overseas wallet and pallet cost flow

This commit is contained in:
2026-09-05 22:26:25 +08:00
parent f62283fb7f
commit 5fbd2bbd04
69 changed files with 1598 additions and 53 deletions
+2 -2
View File
@@ -13,10 +13,10 @@
|---|---|
| 接收、状态、人工补投 API | `src/main/java/com/baiyue/eventbridge/controller/EventBridgeController.java` |
| Inbox 接收与幂等 | `service/EventInboxService.java` |
| 按目标区域调度与重试 | `service/OverseasEventDispatcher.java`;`targetRegion=CN` 的 `BUSINESS_FEE_SOURCE_CHANGED` 定向投 Finance,其余国内回投 Firstleg;海外业务事件投 Lastleg 通用入口,三类 IAM 安全事件按 eventType 投 Lastleg `/internal/lastleg/security/v1/events`,传输层不解析 payload |
| 按目标区域调度与重试 | `service/OverseasEventDispatcher.java`;`targetRegion=CN` 的 `BUSINESS_FEE_SOURCE_CHANGED` 与 `WALLET_COMMAND_REQUESTED` 定向投 Finance,其余国内回投 Firstleg;海外业务事件及 `WALLET_COMMAND_COMPLETED` 投 Lastleg 通用入口,三类 IAM 安全事件按 eventType 投 Lastleg `/internal/lastleg/security/v1/events`,传输层不解析 payload |
| 尾程 HTTP 客户端 | `service/LastlegEventClient.java`、`HttpLastlegEventClient.java` |
| 国内头程 HTTP 客户端 | `service/FirstlegEventClient.java`、`HttpFirstlegEventClient.java`;默认内部入口 `/internal/firstleg/v1/container-events` |
| 国内 Finance 费用事件客户端 | `service/FinanceEventClient.java`、`HttpFinanceEventClient.java`;统一内部入口 `/internal/finance/v1/business-fee-source-events`,配置 `baiyue.event-dispatcher.finance-consumer-url`,不得误投 Firstleg |
| 国内 Finance 事件客户端 | `service/FinanceEventClient.java`、`HttpFinanceEventClient.java`;费用入口 `/internal/finance/v1/business-fee-source-events`,资金指令入口 `/internal/finance/v1/wallet-command-events`,分别配置 `finance-consumer-url`、`finance-wallet-consumer-url`,不得误投 Firstleg |
| 人工补投 | `service/EventReplayService.java`;只允许 `DEAD` 转回 `RETRY`,记录操作人与原因,并保留原 `eventId`、payload 与 `payloadHash` |
| Inbox 与投递记录 | `domain/BridgeInbox.java`、`BridgeDeliveryAttempt.java` 及对应 Mapper |
| 传输指标与 Inbox 采样 | `metrics/EventBridgeMetrics.java`、`EventBridgeInboxMetricsSampler.java`;SLO 与告警合同 `docs/development-observability-slo.md` |
@@ -1,6 +1,7 @@
package com.baiyue.eventbridge.service;
import com.baiyue.common.event.EventEnvelope;
import com.baiyue.common.event.EventTypes;
import com.baiyue.common.event.RegionCode;
import com.baiyue.eventbridge.config.EventDispatcherProperties;
import com.baiyue.eventbridge.domain.BridgeInbox;
@@ -24,6 +25,8 @@ public class HttpFinanceEventClient implements FinanceEventClient {
@Resource private EventBridgeHttpTracePropagation tracePropagation;
@Value("${baiyue.event-dispatcher.finance-consumer-url:http://127.0.0.1:9203/internal/finance/v1/business-fee-source-events}")
private URI consumerUrl;
@Value("${baiyue.event-dispatcher.finance-wallet-consumer-url:http://127.0.0.1:9203/internal/finance/v1/wallet-command-events}")
private URI walletConsumerUrl;
@Value("${baiyue.security.internal-service-token:}") private String serviceToken;
private HttpClient httpClient;
@@ -39,7 +42,9 @@ public class HttpFinanceEventClient implements FinanceEventClient {
row.getCustomerId(), row.getAggregateType(), row.getAggregateId(), row.getAggregateVersion(),
row.getHandoverVersion(), row.getTraceId(), row.getCorrelationId(), row.getCausationId(),
objectMapper.readTree(row.getPayloadJson()), row.getPayloadHash());
HttpRequest request = tracePropagation.apply(HttpRequest.newBuilder(consumerUrl)
URI target = EventTypes.WALLET_COMMAND_REQUESTED.equals(row.getEventType())
? walletConsumerUrl : consumerUrl;
HttpRequest request = tracePropagation.apply(HttpRequest.newBuilder(target)
.timeout(properties.requestTimeout()).header("Content-Type", "application/json")
.header("X-Internal-Service-Token", serviceToken))
.POST(HttpRequest.BodyPublishers.ofString(objectMapper.writeValueAsString(envelope))).build();
@@ -90,7 +90,7 @@ public class OverseasEventDispatcher {
throw new IllegalArgumentException("事件类型不能为空,无法选择下游消费者");
}
return switch (event.getTargetRegion()) {
case "CN" -> EventTypes.BUSINESS_FEE_SOURCE_CHANGED.equals(eventType)
case "CN" -> FINANCE_EVENT_TYPES.contains(eventType)
? financeEventClient.deliver(event) : firstlegEventClient.deliver(event);
case "OVERSEAS" -> SECURITY_EVENT_TYPES.contains(eventType)
? securityProjectionEventClient.deliver(event) : eventClient.deliver(event);
@@ -103,6 +103,10 @@ public class OverseasEventDispatcher {
EventTypes.IAM_TENANT_STATUS_CHANGED,
EventTypes.IAM_PERMISSION_VERSION_CHANGED);
private static final Set<String> FINANCE_EVENT_TYPES = Set.of(
EventTypes.BUSINESS_FEE_SOURCE_CHANGED,
EventTypes.WALLET_COMMAND_REQUESTED);
private BridgeDeliveryAttempt startAttempt(BridgeInbox event, int attemptNo) {
BridgeDeliveryAttempt attempt = new BridgeDeliveryAttempt();
attempt.setEventId(event.getEventId());