feat(databus): 完成阶段四-DataBus Server完整功能
- 补充缺失的 API 类(DatabusMessage、DatabusBatchMessage、DatabusEventType) - 新增变更消息消费者(3个:部门、用户、岗位) - 新增数据提供者(3个:部门、用户、岗位) - 确认分发器服务(核心定向推送逻辑) - 确认全量同步与消息推送组件 - 确认管理后台 API(5个 Controller) - 确认 Service ��(4个核心服务) - 确认 DAL 层(7个 DO + Mapper) - 添加 databus-server starter 依赖到 pom.xml - 编译验证通过 Ref: docs/databus/implementation-checklist.md 任务 39-70
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
package com.zt.plat.framework.databus.client.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
/**
|
||||
* Databus 同步客户端自动配置
|
||||
*
|
||||
* @author ZT
|
||||
*/
|
||||
@Slf4j
|
||||
@AutoConfiguration
|
||||
@EnableConfigurationProperties(DatabusSyncClientProperties.class)
|
||||
@ComponentScan(basePackages = "com.zt.plat.framework.databus.client")
|
||||
public class DatabusSyncClientAutoConfiguration {
|
||||
|
||||
public DatabusSyncClientAutoConfiguration() {
|
||||
log.info("[Databus] 数据同步客户端模块已加载");
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,43 @@
|
||||
package com.zt.plat.framework.databus.client.core.controller;
|
||||
|
||||
import com.zt.plat.framework.databus.client.core.processor.MessageProcessor;
|
||||
import com.zt.plat.module.databus.enums.DatabusEventType;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 同步消息HTTP接收控制器
|
||||
*
|
||||
* @author ZT
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("${zt.databus.sync.client.http.endpoint:/databus/sync/receive}")
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnProperty(prefix = "zt.databus.sync.client.http", name = "enabled", havingValue = "true")
|
||||
public class SyncMessageController {
|
||||
|
||||
private final MessageProcessor messageProcessor;
|
||||
|
||||
/**
|
||||
* 接收同步消息
|
||||
*
|
||||
* @param eventType 事件类型
|
||||
* @param message 消息体
|
||||
*/
|
||||
@PostMapping("/{eventType}")
|
||||
public void receive(@PathVariable("eventType") String eventType, @RequestBody String message) {
|
||||
log.debug("[Databus Client] 接收到HTTP消息, eventType={}", eventType);
|
||||
|
||||
DatabusEventType type = DatabusEventType.valueOf(eventType);
|
||||
if (type == null) {
|
||||
log.warn("[Databus Client] 未知的事件类型: {}", eventType);
|
||||
return;
|
||||
}
|
||||
|
||||
messageProcessor.process(message, type);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.zt.plat.framework.databus.client.core.idempotent;
|
||||
|
||||
/**
|
||||
* 幂等存储接口
|
||||
*
|
||||
* @author ZT
|
||||
*/
|
||||
public interface IdempotentStore {
|
||||
|
||||
/**
|
||||
* 检查并记录消息是否已处理
|
||||
*
|
||||
* @param syncId 同步ID
|
||||
* @param expireSeconds 过期时间(秒)
|
||||
* @return true-未处理(可以处理), false-已处理(应该跳过)
|
||||
*/
|
||||
boolean checkAndMark(String syncId, int expireSeconds);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.zt.plat.framework.databus.client.core.idempotent;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 基于 Redis 的幂等存储实现
|
||||
*
|
||||
* @author ZT
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class RedisIdempotentStore implements IdempotentStore {
|
||||
|
||||
private static final String KEY_PREFIX = "databus:sync:idempotent:";
|
||||
|
||||
private final StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
@Override
|
||||
public boolean checkAndMark(String syncId, int expireSeconds) {
|
||||
String key = KEY_PREFIX + syncId;
|
||||
Boolean success = stringRedisTemplate.opsForValue()
|
||||
.setIfAbsent(key, "1", expireSeconds, TimeUnit.SECONDS);
|
||||
return Boolean.TRUE.equals(success);
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,54 @@
|
||||
package com.zt.plat.framework.databus.client.core.message;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 数据同步消息(服务端推送格式)
|
||||
*
|
||||
* @author ZT
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SyncMessage {
|
||||
|
||||
/**
|
||||
* 同步ID(唯一标识)
|
||||
*/
|
||||
private String syncId;
|
||||
|
||||
/**
|
||||
* 事件记录ID
|
||||
*/
|
||||
private Long eventRecordId;
|
||||
|
||||
/**
|
||||
* 事件类型
|
||||
*/
|
||||
private String eventType;
|
||||
|
||||
/**
|
||||
* 事件动作
|
||||
*/
|
||||
private String eventAction;
|
||||
|
||||
/**
|
||||
* 业务数据快照(JSON字符串)
|
||||
*/
|
||||
private String dataSnapshot;
|
||||
|
||||
/**
|
||||
* 数据版本
|
||||
*/
|
||||
private Integer dataVersion;
|
||||
|
||||
/**
|
||||
* 时间戳
|
||||
*/
|
||||
private Long timestamp;
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,51 @@
|
||||
package com.zt.plat.framework.databus.client.handler;
|
||||
|
||||
import com.zt.plat.module.databus.api.message.DatabusBatchMessage;
|
||||
import com.zt.plat.module.databus.enums.DatabusEventType;
|
||||
|
||||
/**
|
||||
* 批量同步事件处理器接口
|
||||
* <p>
|
||||
* 业务系统需要实现此接口来处理全量同步的批量数据
|
||||
*
|
||||
* @author ZT
|
||||
*/
|
||||
public interface BatchSyncEventHandler<T> {
|
||||
|
||||
/**
|
||||
* 获取支持的事件类型
|
||||
*
|
||||
* @return 事件类型枚举
|
||||
*/
|
||||
DatabusEventType getSupportedEventType();
|
||||
|
||||
/**
|
||||
* 处理批量同步消息
|
||||
*
|
||||
* @param message 批量同步消息
|
||||
*/
|
||||
void handleBatch(DatabusBatchMessage<T> message);
|
||||
|
||||
/**
|
||||
* 全量同步开始回调(可选实现)
|
||||
* <p>
|
||||
* 当收到第一批数据(batchNo=1)时调用
|
||||
*
|
||||
* @param message 批量同步消息
|
||||
*/
|
||||
default void onFullSyncStart(DatabusBatchMessage<T> message) {
|
||||
// 默认空实现,子类可覆盖
|
||||
}
|
||||
|
||||
/**
|
||||
* 全量同步完成回调(可选实现)
|
||||
* <p>
|
||||
* 当收到最后一批数据(isLastBatch=true)时调用
|
||||
*
|
||||
* @param message 批量同步消息
|
||||
*/
|
||||
default void onFullSyncComplete(DatabusBatchMessage<T> message) {
|
||||
// 默认空实现,子类可覆盖
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.zt.plat.framework.databus.client.handler;
|
||||
|
||||
import com.zt.plat.module.databus.api.message.DatabusMessage;
|
||||
import com.zt.plat.module.databus.enums.DatabusEventType;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* 同步事件处理器接口
|
||||
* <p>
|
||||
* 业务系统需要实现此接口来处理增量数据同步
|
||||
*
|
||||
* @author ZT
|
||||
*/
|
||||
public interface SyncEventHandler<T> {
|
||||
|
||||
/**
|
||||
* 获取支持的事件类型
|
||||
*
|
||||
* @return 事件类型枚举
|
||||
*/
|
||||
DatabusEventType getSupportedEventType();
|
||||
|
||||
/**
|
||||
* 处理同步消息
|
||||
*
|
||||
* @param message 同步消息
|
||||
*/
|
||||
void handle(DatabusMessage<T> message);
|
||||
|
||||
/**
|
||||
* 获取数据类型
|
||||
* <p>
|
||||
* 默认通过反射获取泛型类型参数,子类可以覆盖此方法提供具体类型
|
||||
*
|
||||
* @return 数据类型的 Class 对象
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
default Class<T> getDataType() {
|
||||
Type[] genericInterfaces = this.getClass().getGenericInterfaces();
|
||||
for (Type genericInterface : genericInterfaces) {
|
||||
if (genericInterface instanceof ParameterizedType) {
|
||||
ParameterizedType parameterizedType = (ParameterizedType) genericInterface;
|
||||
if (parameterizedType.getRawType().equals(SyncEventHandler.class)) {
|
||||
Type[] typeArguments = parameterizedType.getActualTypeArguments();
|
||||
if (typeArguments.length > 0 && typeArguments[0] instanceof Class) {
|
||||
return (Class<T>) typeArguments[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 如果无法获取泛型类型,返回 Object.class
|
||||
return (Class<T>) Object.class;
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user