|
@@ -1,10 +1,19 @@
|
|
|
package com.fs.fssync.listener;
|
|
|
|
|
|
+import cn.hutool.extra.spring.SpringUtil;
|
|
|
import com.alibaba.fastjson.JSON;
|
|
|
+import com.fs.fssync.config.SpringContextHolder;
|
|
|
+import com.fs.fssync.sink.CdcSinkStrategy;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.flink.configuration.Configuration;
|
|
|
import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.context.ApplicationContext;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
+import java.io.Serializable;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
/**
|
|
|
* Flink CDC 数据处理
|
|
|
*
|
|
@@ -12,23 +21,45 @@ import org.springframework.stereotype.Component;
|
|
|
* @since 2024-3-14
|
|
|
*/
|
|
|
@Slf4j
|
|
|
-@Component
|
|
|
-public class CustomSink extends RichSinkFunction<String> {
|
|
|
+public class CustomSink extends RichSinkFunction<String> implements Serializable {
|
|
|
|
|
|
@Override
|
|
|
public void invoke(String value, Context context) {
|
|
|
log.info("收到变更原始数据:{}", value);
|
|
|
+ try {
|
|
|
+ // 从JSON中提取表名信息
|
|
|
+ String source = JSON.parseObject(value).getString("source");
|
|
|
+ String table = JSON.parseObject(source).getString("table");
|
|
|
|
|
|
- String op = JSON.parseObject(value).getString("op");
|
|
|
- if ("c".equals(op)) {
|
|
|
- log.info("新增了一条数据 ...");
|
|
|
- } else if ("u".equals(op)) {
|
|
|
- log.info("更新了一条数据 ...");
|
|
|
- } else if ("d".equals(op)) {
|
|
|
- log.info("删除了一条数据 ...");
|
|
|
- } else {
|
|
|
- log.error("{} 未知的操作类型!", op);
|
|
|
+ // 根据表名查找对应的策略
|
|
|
+ processBySinkStrategy(table, value);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("处理CDC数据失败", e);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private void processBySinkStrategy(String table, String value) {
|
|
|
+ // 获取所有实现了CdcSinkStrategy的Bean
|
|
|
+ Map<String, CdcSinkStrategy> strategies =
|
|
|
+ SpringContextHolder.getApplicationContext().getBeansOfType(CdcSinkStrategy.class);
|
|
|
+
|
|
|
+
|
|
|
+ for (CdcSinkStrategy strategy : strategies.values()) {
|
|
|
+ try {
|
|
|
+ if (isStrategyForTable(strategy, table)) {
|
|
|
+ strategy.process(value);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("策略处理失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ log.warn("未找到表 {} 的处理策略", table);
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean isStrategyForTable(CdcSinkStrategy strategy, String table) {
|
|
|
+
|
|
|
+ return strategy.canHandle(table.toLowerCase());
|
|
|
+ }
|
|
|
}
|