This is an automated email from the ASF dual-hosted git repository.

lzljs3620320 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git


The following commit(s) were added to refs/heads/master by this push:
     new b754fdb13 [cdc] Refactor codes cdcTimestampExtractor to separate 
different cdc dataSources. (#4144)
b754fdb13 is described below

commit b754fdb13c1c2a4f67f5d27a595e80986666ffc9
Author: HunterXHunter <[email protected]>
AuthorDate: Tue Sep 10 11:53:52 2024 +0800

    [cdc] Refactor codes cdcTimestampExtractor to separate different cdc 
dataSources. (#4144)
---
 .../cdc/MessageQueueSyncTableActionBase.java       |   7 +
 .../action/cdc/SynchronizationActionBase.java      |  11 +-
 .../action/cdc/kafka/KafkaSyncDatabaseAction.java  |   7 +
 .../action/cdc/mongodb/MongoDBActionUtils.java     |   5 +
 .../cdc/mongodb/MongoDBCdcTimestampExtractor.java  |  39 ++++++
 .../cdc/mongodb/MongoDBSyncDatabaseAction.java     |   6 +
 .../action/cdc/mongodb/MongoDBSyncTableAction.java |   6 +
 .../flink/action/cdc/mysql/MySqlActionUtils.java   |   5 +
 .../action/cdc/mysql/MySqlSyncDatabaseAction.java  |   6 +
 .../action/cdc/mysql/MySqlSyncTableAction.java     |   6 +
 .../cdc/mysql/MysqlCdcTimestampExtractor.java      |  38 ++++++
 .../cdc/pulsar/PulsarSyncDatabaseAction.java       |   7 +
 .../CdcDebeziumTimestampExtractor.java}            |  22 ++--
 .../CdcTimestampExtractor.java}                    |  21 ++-
 .../watermark/CdcTimestampExtractorFactory.java    | 144 ---------------------
 .../action/cdc/watermark/CdcWatermarkStrategy.java |   1 -
 .../MessageQueueCdcTimestampExtractor.java         |  63 +++++++++
 .../cdc/CdcDebeziumTimestampExtractorITCase.java   |  12 +-
 18 files changed, 227 insertions(+), 179 deletions(-)

diff --git 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/MessageQueueSyncTableActionBase.java
 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/MessageQueueSyncTableActionBase.java
index 28ad5b52a..9c629b5a5 100644
--- 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/MessageQueueSyncTableActionBase.java
+++ 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/MessageQueueSyncTableActionBase.java
@@ -19,6 +19,8 @@
 package org.apache.paimon.flink.action.cdc;
 
 import org.apache.paimon.flink.action.Action;
+import org.apache.paimon.flink.action.cdc.watermark.CdcTimestampExtractor;
+import 
org.apache.paimon.flink.action.cdc.watermark.MessageQueueCdcTimestampExtractor;
 import org.apache.paimon.schema.Schema;
 
 import java.util.Map;
@@ -69,6 +71,11 @@ public abstract class MessageQueueSyncTableActionBase 
extends SyncTableActionBas
         }
     }
 
+    @Override
+    protected CdcTimestampExtractor createCdcTimestampExtractor() {
+        return new MessageQueueCdcTimestampExtractor();
+    }
+
     @Override
     protected Schema buildPaimonSchema(Schema retrievedSchema) {
         return CdcActionCommonUtils.buildPaimonSchema(
diff --git 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/SynchronizationActionBase.java
 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/SynchronizationActionBase.java
index b42366d26..21f6c6b3e 100644
--- 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/SynchronizationActionBase.java
+++ 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/SynchronizationActionBase.java
@@ -24,6 +24,7 @@ import org.apache.paimon.catalog.Catalog;
 import org.apache.paimon.catalog.Identifier;
 import org.apache.paimon.flink.action.Action;
 import org.apache.paimon.flink.action.ActionBase;
+import org.apache.paimon.flink.action.cdc.watermark.CdcTimestampExtractor;
 import org.apache.paimon.flink.action.cdc.watermark.CdcWatermarkStrategy;
 import org.apache.paimon.flink.sink.cdc.EventParser;
 import org.apache.paimon.flink.sink.cdc.RichCdcMultiplexRecord;
@@ -52,7 +53,6 @@ import static 
org.apache.paimon.flink.FlinkConnectorOptions.SCAN_WATERMARK_ALIGN
 import static 
org.apache.paimon.flink.FlinkConnectorOptions.SCAN_WATERMARK_ALIGNMENT_MAX_DRIFT;
 import static 
org.apache.paimon.flink.FlinkConnectorOptions.SCAN_WATERMARK_ALIGNMENT_UPDATE_INTERVAL;
 import static 
org.apache.paimon.flink.FlinkConnectorOptions.SCAN_WATERMARK_IDLE_TIMEOUT;
-import static 
org.apache.paimon.flink.action.cdc.watermark.CdcTimestampExtractorFactory.createExtractor;
 
 /** Base {@link Action} for table/database synchronizing job. */
 public abstract class SynchronizationActionBase extends ActionBase {
@@ -132,6 +132,11 @@ public abstract class SynchronizationActionBase extends 
ActionBase {
         return syncJobHandler.provideSource();
     }
 
+    protected CdcTimestampExtractor createCdcTimestampExtractor() {
+        throw new IllegalArgumentException(
+                "Unsupported timestamp extractor for current cdc source.");
+    }
+
     private DataStreamSource<CdcSourceRecord> buildDataStreamSource(Object 
source) {
         if (source instanceof Source) {
             boolean isAutomaticWatermarkCreationEnabled =
@@ -146,13 +151,13 @@ public abstract class SynchronizationActionBase extends 
ActionBase {
             WatermarkStrategy<CdcSourceRecord> watermarkStrategy =
                     isAutomaticWatermarkCreationEnabled
                             ? watermarkAlignGroup != null
-                                    ? new 
CdcWatermarkStrategy(createExtractor(source))
+                                    ? new 
CdcWatermarkStrategy(createCdcTimestampExtractor())
                                             .withWatermarkAlignment(
                                                     watermarkAlignGroup,
                                                     
options.get(SCAN_WATERMARK_ALIGNMENT_MAX_DRIFT),
                                                     options.get(
                                                             
SCAN_WATERMARK_ALIGNMENT_UPDATE_INTERVAL))
-                                    : new 
CdcWatermarkStrategy(createExtractor(source))
+                                    : new 
CdcWatermarkStrategy(createCdcTimestampExtractor())
                             : WatermarkStrategy.noWatermarks();
             if (idleTimeout != null) {
                 watermarkStrategy = 
watermarkStrategy.withIdleness(idleTimeout);
diff --git 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/kafka/KafkaSyncDatabaseAction.java
 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/kafka/KafkaSyncDatabaseAction.java
index 4c87307e3..cce4c4e68 100644
--- 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/kafka/KafkaSyncDatabaseAction.java
+++ 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/kafka/KafkaSyncDatabaseAction.java
@@ -20,6 +20,8 @@ package org.apache.paimon.flink.action.cdc.kafka;
 
 import org.apache.paimon.flink.action.cdc.SyncDatabaseActionBase;
 import org.apache.paimon.flink.action.cdc.SyncJobHandler;
+import org.apache.paimon.flink.action.cdc.watermark.CdcTimestampExtractor;
+import 
org.apache.paimon.flink.action.cdc.watermark.MessageQueueCdcTimestampExtractor;
 
 import java.util.Map;
 
@@ -33,4 +35,9 @@ public class KafkaSyncDatabaseAction extends 
SyncDatabaseActionBase {
             Map<String, String> kafkaConfig) {
         super(warehouse, database, catalogConfig, kafkaConfig, 
SyncJobHandler.SourceType.KAFKA);
     }
+
+    @Override
+    protected CdcTimestampExtractor createCdcTimestampExtractor() {
+        return new MessageQueueCdcTimestampExtractor();
+    }
 }
diff --git 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mongodb/MongoDBActionUtils.java
 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mongodb/MongoDBActionUtils.java
index c86307fe7..848e96c69 100644
--- 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mongodb/MongoDBActionUtils.java
+++ 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mongodb/MongoDBActionUtils.java
@@ -20,6 +20,7 @@ package org.apache.paimon.flink.action.cdc.mongodb;
 
 import org.apache.paimon.flink.action.cdc.CdcSourceRecord;
 import 
org.apache.paimon.flink.action.cdc.serialization.CdcDebeziumDeserializationSchema;
+import org.apache.paimon.flink.action.cdc.watermark.CdcTimestampExtractor;
 
 import org.apache.flink.cdc.connectors.base.options.SourceOptions;
 import org.apache.flink.cdc.connectors.base.options.StartupOptions;
@@ -139,4 +140,8 @@ public class MongoDBActionUtils {
 
         return sourceBuilder.deserializer(schema).build();
     }
+
+    public static CdcTimestampExtractor createCdcTimestampExtractor() {
+        return new MongoDBCdcTimestampExtractor();
+    }
 }
diff --git 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mongodb/MongoDBCdcTimestampExtractor.java
 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mongodb/MongoDBCdcTimestampExtractor.java
new file mode 100644
index 000000000..08ca8ce79
--- /dev/null
+++ 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mongodb/MongoDBCdcTimestampExtractor.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.paimon.flink.action.cdc.mongodb;
+
+import org.apache.paimon.flink.action.cdc.CdcSourceRecord;
+import 
org.apache.paimon.flink.action.cdc.watermark.CdcDebeziumTimestampExtractor;
+import org.apache.paimon.utils.JsonSerdeUtil;
+
+import 
org.apache.paimon.shade.jackson2.com.fasterxml.jackson.core.JsonProcessingException;
+import 
org.apache.paimon.shade.jackson2.com.fasterxml.jackson.databind.JsonNode;
+
+/** Timestamp extractor for MongoDB sources in CDC applications. */
+public class MongoDBCdcTimestampExtractor extends 
CdcDebeziumTimestampExtractor {
+
+    private static final long serialVersionUID = 1L;
+
+    @Override
+    public long extractTimestamp(CdcSourceRecord record) throws 
JsonProcessingException {
+        JsonNode json = JsonSerdeUtil.fromJson((String) record.getValue(), 
JsonNode.class);
+        // If the record is a schema-change event return Long.MIN_VALUE as 
result.
+        return JsonSerdeUtil.extractValueOrDefault(json, Long.class, 
Long.MIN_VALUE, "ts_ms");
+    }
+}
diff --git 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mongodb/MongoDBSyncDatabaseAction.java
 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mongodb/MongoDBSyncDatabaseAction.java
index 4120aa1ba..589513960 100644
--- 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mongodb/MongoDBSyncDatabaseAction.java
+++ 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mongodb/MongoDBSyncDatabaseAction.java
@@ -22,6 +22,7 @@ import 
org.apache.paimon.flink.action.cdc.CdcActionCommonUtils;
 import org.apache.paimon.flink.action.cdc.CdcSourceRecord;
 import org.apache.paimon.flink.action.cdc.SyncDatabaseActionBase;
 import org.apache.paimon.flink.action.cdc.SyncJobHandler;
+import org.apache.paimon.flink.action.cdc.watermark.CdcTimestampExtractor;
 
 import org.apache.flink.cdc.connectors.mongodb.source.MongoDBSource;
 import 
org.apache.flink.cdc.connectors.mongodb.source.config.MongoDBSourceOptions;
@@ -58,6 +59,11 @@ public class MongoDBSyncDatabaseAction extends 
SyncDatabaseActionBase {
         super(warehouse, database, catalogConfig, mongodbConfig, 
SyncJobHandler.SourceType.MONGODB);
     }
 
+    @Override
+    protected CdcTimestampExtractor createCdcTimestampExtractor() {
+        return MongoDBActionUtils.createCdcTimestampExtractor();
+    }
+
     @Override
     protected MongoDBSource<CdcSourceRecord> buildSource() {
         return MongoDBActionUtils.buildMongodbSource(
diff --git 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mongodb/MongoDBSyncTableAction.java
 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mongodb/MongoDBSyncTableAction.java
index c1bf21b5b..16dbbadfd 100644
--- 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mongodb/MongoDBSyncTableAction.java
+++ 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mongodb/MongoDBSyncTableAction.java
@@ -21,6 +21,7 @@ package org.apache.paimon.flink.action.cdc.mongodb;
 import org.apache.paimon.flink.action.cdc.CdcSourceRecord;
 import org.apache.paimon.flink.action.cdc.SyncJobHandler;
 import org.apache.paimon.flink.action.cdc.SyncTableActionBase;
+import org.apache.paimon.flink.action.cdc.watermark.CdcTimestampExtractor;
 import org.apache.paimon.schema.Schema;
 
 import org.apache.flink.cdc.connectors.mongodb.source.MongoDBSource;
@@ -69,6 +70,11 @@ public class MongoDBSyncTableAction extends 
SyncTableActionBase {
         return MongodbSchemaUtils.getMongodbSchema(cdcSourceConfig);
     }
 
+    @Override
+    protected CdcTimestampExtractor createCdcTimestampExtractor() {
+        return MongoDBActionUtils.createCdcTimestampExtractor();
+    }
+
     @Override
     protected MongoDBSource<CdcSourceRecord> buildSource() {
         String tableList =
diff --git 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mysql/MySqlActionUtils.java
 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mysql/MySqlActionUtils.java
index 792b76311..6888f672e 100644
--- 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mysql/MySqlActionUtils.java
+++ 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mysql/MySqlActionUtils.java
@@ -24,6 +24,7 @@ import org.apache.paimon.flink.action.cdc.TypeMapping;
 import org.apache.paimon.flink.action.cdc.schema.JdbcSchemaUtils;
 import org.apache.paimon.flink.action.cdc.schema.JdbcSchemasInfo;
 import 
org.apache.paimon.flink.action.cdc.serialization.CdcDebeziumDeserializationSchema;
+import org.apache.paimon.flink.action.cdc.watermark.CdcTimestampExtractor;
 import org.apache.paimon.schema.Schema;
 
 import org.apache.flink.cdc.connectors.mysql.source.MySqlSource;
@@ -275,4 +276,8 @@ public class MySqlActionUtils {
             }
         }
     }
+
+    public static CdcTimestampExtractor createCdcTimestampExtractor() {
+        return new MysqlCdcTimestampExtractor();
+    }
 }
diff --git 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mysql/MySqlSyncDatabaseAction.java
 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mysql/MySqlSyncDatabaseAction.java
index ecdb6c65f..316168e1e 100644
--- 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mysql/MySqlSyncDatabaseAction.java
+++ 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mysql/MySqlSyncDatabaseAction.java
@@ -29,6 +29,7 @@ import org.apache.paimon.flink.action.cdc.SyncJobHandler;
 import org.apache.paimon.flink.action.cdc.TableNameConverter;
 import org.apache.paimon.flink.action.cdc.schema.JdbcSchemasInfo;
 import org.apache.paimon.flink.action.cdc.schema.JdbcTableInfo;
+import org.apache.paimon.flink.action.cdc.watermark.CdcTimestampExtractor;
 import org.apache.paimon.schema.Schema;
 import org.apache.paimon.schema.TableSchema;
 import org.apache.paimon.table.FileStoreTable;
@@ -180,6 +181,11 @@ public class MySqlSyncDatabaseAction extends 
SyncDatabaseActionBase {
                         + "MySQL database are not compatible with those of 
existed Paimon tables. Please check the log.");
     }
 
+    @Override
+    protected CdcTimestampExtractor createCdcTimestampExtractor() {
+        return MySqlActionUtils.createCdcTimestampExtractor();
+    }
+
     @Override
     protected MySqlSource<CdcSourceRecord> buildSource() {
         return MySqlActionUtils.buildMySqlSource(
diff --git 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mysql/MySqlSyncTableAction.java
 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mysql/MySqlSyncTableAction.java
index eeb273265..a05832b1d 100644
--- 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mysql/MySqlSyncTableAction.java
+++ 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mysql/MySqlSyncTableAction.java
@@ -25,6 +25,7 @@ import org.apache.paimon.flink.action.cdc.SyncJobHandler;
 import org.apache.paimon.flink.action.cdc.SyncTableActionBase;
 import org.apache.paimon.flink.action.cdc.schema.JdbcSchemasInfo;
 import org.apache.paimon.flink.action.cdc.schema.JdbcTableInfo;
+import org.apache.paimon.flink.action.cdc.watermark.CdcTimestampExtractor;
 import org.apache.paimon.schema.Schema;
 
 import org.apache.flink.cdc.connectors.mysql.source.MySqlSource;
@@ -109,6 +110,11 @@ public class MySqlSyncTableAction extends 
SyncTableActionBase {
         return MySqlActionUtils.buildMySqlSource(cdcSourceConfig, tableList, 
typeMapping);
     }
 
+    @Override
+    protected CdcTimestampExtractor createCdcTimestampExtractor() {
+        return MySqlActionUtils.createCdcTimestampExtractor();
+    }
+
     private void validateMySqlTableInfos(JdbcSchemasInfo mySqlSchemasInfo) {
         List<Identifier> nonPkTables = mySqlSchemasInfo.nonPkTables();
         checkArgument(
diff --git 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mysql/MysqlCdcTimestampExtractor.java
 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mysql/MysqlCdcTimestampExtractor.java
new file mode 100644
index 000000000..cb11120fd
--- /dev/null
+++ 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/mysql/MysqlCdcTimestampExtractor.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.paimon.flink.action.cdc.mysql;
+
+import org.apache.paimon.flink.action.cdc.CdcSourceRecord;
+import 
org.apache.paimon.flink.action.cdc.watermark.CdcDebeziumTimestampExtractor;
+import org.apache.paimon.utils.JsonSerdeUtil;
+
+import 
org.apache.paimon.shade.jackson2.com.fasterxml.jackson.core.JsonProcessingException;
+import 
org.apache.paimon.shade.jackson2.com.fasterxml.jackson.databind.JsonNode;
+
+/** Timestamp extractor for MySQL sources in CDC applications. */
+public class MysqlCdcTimestampExtractor extends CdcDebeziumTimestampExtractor {
+
+    @Override
+    public long extractTimestamp(CdcSourceRecord record) throws 
JsonProcessingException {
+        JsonNode json = JsonSerdeUtil.fromJson((String) record.getValue(), 
JsonNode.class);
+
+        return JsonSerdeUtil.extractValueOrDefault(
+                json, Long.class, Long.MIN_VALUE, "payload", "ts_ms");
+    }
+}
diff --git 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/pulsar/PulsarSyncDatabaseAction.java
 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/pulsar/PulsarSyncDatabaseAction.java
index fa7b7353e..d097feec6 100644
--- 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/pulsar/PulsarSyncDatabaseAction.java
+++ 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/pulsar/PulsarSyncDatabaseAction.java
@@ -20,6 +20,8 @@ package org.apache.paimon.flink.action.cdc.pulsar;
 
 import org.apache.paimon.flink.action.cdc.SyncDatabaseActionBase;
 import org.apache.paimon.flink.action.cdc.SyncJobHandler;
+import org.apache.paimon.flink.action.cdc.watermark.CdcTimestampExtractor;
+import 
org.apache.paimon.flink.action.cdc.watermark.MessageQueueCdcTimestampExtractor;
 
 import java.util.Map;
 
@@ -33,4 +35,9 @@ public class PulsarSyncDatabaseAction extends 
SyncDatabaseActionBase {
             Map<String, String> pulsarConfig) {
         super(warehouse, database, catalogConfig, pulsarConfig, 
SyncJobHandler.SourceType.PULSAR);
     }
+
+    @Override
+    protected CdcTimestampExtractor createCdcTimestampExtractor() {
+        return new MessageQueueCdcTimestampExtractor();
+    }
 }
diff --git 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/kafka/KafkaSyncDatabaseAction.java
 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/watermark/CdcDebeziumTimestampExtractor.java
similarity index 54%
copy from 
paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/kafka/KafkaSyncDatabaseAction.java
copy to 
paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/watermark/CdcDebeziumTimestampExtractor.java
index 4c87307e3..515b74bd4 100644
--- 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/kafka/KafkaSyncDatabaseAction.java
+++ 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/watermark/CdcDebeziumTimestampExtractor.java
@@ -16,21 +16,19 @@
  * limitations under the License.
  */
 
-package org.apache.paimon.flink.action.cdc.kafka;
+package org.apache.paimon.flink.action.cdc.watermark;
 
-import org.apache.paimon.flink.action.cdc.SyncDatabaseActionBase;
-import org.apache.paimon.flink.action.cdc.SyncJobHandler;
+import 
org.apache.paimon.shade.jackson2.com.fasterxml.jackson.databind.DeserializationFeature;
+import 
org.apache.paimon.shade.jackson2.com.fasterxml.jackson.databind.ObjectMapper;
 
-import java.util.Map;
+/** Timestamp extractor for Cdc debezium deserialization. */
+public abstract class CdcDebeziumTimestampExtractor implements 
CdcTimestampExtractor {
 
-/** Synchronize database from Kafka. */
-public class KafkaSyncDatabaseAction extends SyncDatabaseActionBase {
+    protected final ObjectMapper objectMapper = new ObjectMapper();
 
-    public KafkaSyncDatabaseAction(
-            String warehouse,
-            String database,
-            Map<String, String> catalogConfig,
-            Map<String, String> kafkaConfig) {
-        super(warehouse, database, catalogConfig, kafkaConfig, 
SyncJobHandler.SourceType.KAFKA);
+    public CdcDebeziumTimestampExtractor() {
+        objectMapper
+                .configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, 
true)
+                .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, 
false);
     }
 }
diff --git 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/kafka/KafkaSyncDatabaseAction.java
 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/watermark/CdcTimestampExtractor.java
similarity index 57%
copy from 
paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/kafka/KafkaSyncDatabaseAction.java
copy to 
paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/watermark/CdcTimestampExtractor.java
index 4c87307e3..647fd0115 100644
--- 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/kafka/KafkaSyncDatabaseAction.java
+++ 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/watermark/CdcTimestampExtractor.java
@@ -16,21 +16,16 @@
  * limitations under the License.
  */
 
-package org.apache.paimon.flink.action.cdc.kafka;
+package org.apache.paimon.flink.action.cdc.watermark;
 
-import org.apache.paimon.flink.action.cdc.SyncDatabaseActionBase;
-import org.apache.paimon.flink.action.cdc.SyncJobHandler;
+import org.apache.paimon.flink.action.cdc.CdcSourceRecord;
 
-import java.util.Map;
+import 
org.apache.paimon.shade.jackson2.com.fasterxml.jackson.core.JsonProcessingException;
 
-/** Synchronize database from Kafka. */
-public class KafkaSyncDatabaseAction extends SyncDatabaseActionBase {
+import java.io.Serializable;
 
-    public KafkaSyncDatabaseAction(
-            String warehouse,
-            String database,
-            Map<String, String> catalogConfig,
-            Map<String, String> kafkaConfig) {
-        super(warehouse, database, catalogConfig, kafkaConfig, 
SyncJobHandler.SourceType.KAFKA);
-    }
+/** Interface defining the contract for CDC timestamp extraction. */
+public interface CdcTimestampExtractor extends Serializable {
+
+    long extractTimestamp(CdcSourceRecord record) throws 
JsonProcessingException;
 }
diff --git 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/watermark/CdcTimestampExtractorFactory.java
 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/watermark/CdcTimestampExtractorFactory.java
deleted file mode 100644
index 26733465a..000000000
--- 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/watermark/CdcTimestampExtractorFactory.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.paimon.flink.action.cdc.watermark;
-
-import org.apache.paimon.flink.action.cdc.CdcSourceRecord;
-import org.apache.paimon.utils.JsonSerdeUtil;
-
-import 
org.apache.paimon.shade.jackson2.com.fasterxml.jackson.core.JsonProcessingException;
-import 
org.apache.paimon.shade.jackson2.com.fasterxml.jackson.databind.DeserializationFeature;
-import 
org.apache.paimon.shade.jackson2.com.fasterxml.jackson.databind.JsonNode;
-import 
org.apache.paimon.shade.jackson2.com.fasterxml.jackson.databind.ObjectMapper;
-
-import org.apache.flink.cdc.connectors.mongodb.source.MongoDBSource;
-import org.apache.flink.cdc.connectors.mysql.source.MySqlSource;
-import org.apache.flink.connector.kafka.source.KafkaSource;
-import org.apache.flink.connector.pulsar.source.PulsarSource;
-
-import java.io.Serializable;
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-import java.time.format.DateTimeFormatter;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Supplier;
-
-/** Factory for creating CDC timestamp extractors based on different source 
types. */
-public class CdcTimestampExtractorFactory implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    private static final Map<Class<?>, Supplier<CdcTimestampExtractor>> 
extractorMap =
-            new HashMap<>();
-
-    static {
-        extractorMap.put(MongoDBSource.class, 
MongoDBCdcTimestampExtractor::new);
-        extractorMap.put(MySqlSource.class, MysqlCdcTimestampExtractor::new);
-        extractorMap.put(PulsarSource.class, 
MessageQueueCdcTimestampExtractor::new);
-        extractorMap.put(KafkaSource.class, 
MessageQueueCdcTimestampExtractor::new);
-    }
-
-    public static CdcTimestampExtractor createExtractor(Object source) {
-        Supplier<CdcTimestampExtractor> extractorSupplier = 
extractorMap.get(source.getClass());
-        if (extractorSupplier != null) {
-            return extractorSupplier.get();
-        }
-        throw new IllegalArgumentException(
-                "Unsupported source type: " + source.getClass().getName());
-    }
-
-    /** Timestamp extractor for MongoDB sources in CDC applications. */
-    public static class MongoDBCdcTimestampExtractor extends 
CdcDebeziumTimestampExtractor {
-
-        private static final long serialVersionUID = 1L;
-
-        @Override
-        public long extractTimestamp(CdcSourceRecord record) throws 
JsonProcessingException {
-            JsonNode json = JsonSerdeUtil.fromJson((String) record.getValue(), 
JsonNode.class);
-            // If the record is a schema-change event return Long.MIN_VALUE as 
result.
-            return JsonSerdeUtil.extractValueOrDefault(json, Long.class, 
Long.MIN_VALUE, "ts_ms");
-        }
-    }
-
-    /** Timestamp extractor for Kafka/Pulsar sources in CDC applications. */
-    public static class MessageQueueCdcTimestampExtractor implements 
CdcTimestampExtractor {
-
-        private static final long serialVersionUID = 1L;
-
-        @Override
-        public long extractTimestamp(CdcSourceRecord cdcSourceRecord)
-                throws JsonProcessingException {
-            JsonNode record = (JsonNode) cdcSourceRecord.getValue();
-            if (JsonSerdeUtil.isNodeExists(record, "mysqlType")) {
-                // Canal json
-                return JsonSerdeUtil.extractValue(record, Long.class, "ts");
-            } else if (JsonSerdeUtil.isNodeExists(record, "pos")) {
-                // Ogg json
-                String dateTimeString = JsonSerdeUtil.extractValue(record, 
String.class, "op_ts");
-                DateTimeFormatter formatter =
-                        DateTimeFormatter.ofPattern("yyyy-MM-dd 
HH:mm:ss.SSSSSS");
-                LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, 
formatter);
-                return 
dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
-            } else if (JsonSerdeUtil.isNodeExists(record, "xid")) {
-                // Maxwell json
-                return JsonSerdeUtil.extractValue(record, Long.class, "ts") * 
1000;
-            } else if (JsonSerdeUtil.isNodeExists(record, "payload", "source", 
"connector")) {
-                // Dbz json
-                return JsonSerdeUtil.extractValue(record, Long.class, 
"payload", "ts_ms");
-            } else if (JsonSerdeUtil.isNodeExists(record, "source", 
"connector")) {
-                // Dbz json
-                return JsonSerdeUtil.extractValue(record, Long.class, "ts_ms");
-            }
-            throw new RuntimeException(
-                    String.format(
-                            "Failed to extract timestamp: The JSON format of 
the message queue is unsupported. Record details: %s",
-                            record));
-        }
-    }
-
-    /** Timestamp extractor for MySQL sources in CDC applications. */
-    public static class MysqlCdcTimestampExtractor extends 
CdcDebeziumTimestampExtractor {
-
-        @Override
-        public long extractTimestamp(CdcSourceRecord record) throws 
JsonProcessingException {
-            JsonNode json = JsonSerdeUtil.fromJson((String) record.getValue(), 
JsonNode.class);
-
-            return JsonSerdeUtil.extractValueOrDefault(
-                    json, Long.class, Long.MIN_VALUE, "payload", "ts_ms");
-        }
-    }
-
-    /** Timestamp extractor for Cdc debezium deserialization. */
-    public abstract static class CdcDebeziumTimestampExtractor implements 
CdcTimestampExtractor {
-
-        protected final ObjectMapper objectMapper = new ObjectMapper();
-
-        public CdcDebeziumTimestampExtractor() {
-            objectMapper
-                    
.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true)
-                    
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-        }
-    }
-
-    /** Interface defining the contract for CDC timestamp extraction. */
-    public interface CdcTimestampExtractor extends Serializable {
-
-        long extractTimestamp(CdcSourceRecord record) throws 
JsonProcessingException;
-    }
-}
diff --git 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/watermark/CdcWatermarkStrategy.java
 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/watermark/CdcWatermarkStrategy.java
index 964699a47..f7f868097 100644
--- 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/watermark/CdcWatermarkStrategy.java
+++ 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/watermark/CdcWatermarkStrategy.java
@@ -19,7 +19,6 @@
 package org.apache.paimon.flink.action.cdc.watermark;
 
 import org.apache.paimon.flink.action.cdc.CdcSourceRecord;
-import 
org.apache.paimon.flink.action.cdc.watermark.CdcTimestampExtractorFactory.CdcTimestampExtractor;
 
 import 
org.apache.paimon.shade.jackson2.com.fasterxml.jackson.core.JsonProcessingException;
 
diff --git 
a/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/watermark/MessageQueueCdcTimestampExtractor.java
 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/watermark/MessageQueueCdcTimestampExtractor.java
new file mode 100644
index 000000000..8a9a28453
--- /dev/null
+++ 
b/paimon-flink/paimon-flink-cdc/src/main/java/org/apache/paimon/flink/action/cdc/watermark/MessageQueueCdcTimestampExtractor.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.paimon.flink.action.cdc.watermark;
+
+import org.apache.paimon.flink.action.cdc.CdcSourceRecord;
+import org.apache.paimon.utils.JsonSerdeUtil;
+
+import 
org.apache.paimon.shade.jackson2.com.fasterxml.jackson.core.JsonProcessingException;
+import 
org.apache.paimon.shade.jackson2.com.fasterxml.jackson.databind.JsonNode;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+
+/** Timestamp extractor for Kafka/Pulsar sources in CDC applications. */
+public class MessageQueueCdcTimestampExtractor implements 
CdcTimestampExtractor {
+
+    private static final long serialVersionUID = 1L;
+
+    @Override
+    public long extractTimestamp(CdcSourceRecord cdcSourceRecord) throws 
JsonProcessingException {
+        JsonNode record = (JsonNode) cdcSourceRecord.getValue();
+        if (JsonSerdeUtil.isNodeExists(record, "mysqlType")) {
+            // Canal json
+            return JsonSerdeUtil.extractValue(record, Long.class, "ts");
+        } else if (JsonSerdeUtil.isNodeExists(record, "pos")) {
+            // Ogg json
+            String dateTimeString = JsonSerdeUtil.extractValue(record, 
String.class, "op_ts");
+            DateTimeFormatter formatter = 
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS");
+            LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, 
formatter);
+            return 
dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+        } else if (JsonSerdeUtil.isNodeExists(record, "xid")) {
+            // Maxwell json
+            return JsonSerdeUtil.extractValue(record, Long.class, "ts") * 1000;
+        } else if (JsonSerdeUtil.isNodeExists(record, "payload", "source", 
"connector")) {
+            // Dbz json
+            return JsonSerdeUtil.extractValue(record, Long.class, "payload", 
"ts_ms");
+        } else if (JsonSerdeUtil.isNodeExists(record, "source", "connector")) {
+            // Dbz json
+            return JsonSerdeUtil.extractValue(record, Long.class, "ts_ms");
+        }
+        throw new RuntimeException(
+                String.format(
+                        "Failed to extract timestamp: The JSON format of the 
message queue is unsupported. Record details: %s",
+                        record));
+    }
+}
diff --git 
a/paimon-flink/paimon-flink-cdc/src/test/java/org/apache/paimon/flink/action/cdc/CdcDebeziumTimestampExtractorITCase.java
 
b/paimon-flink/paimon-flink-cdc/src/test/java/org/apache/paimon/flink/action/cdc/CdcDebeziumTimestampExtractorITCase.java
index ea5bcfe12..71cb0edd0 100644
--- 
a/paimon-flink/paimon-flink-cdc/src/test/java/org/apache/paimon/flink/action/cdc/CdcDebeziumTimestampExtractorITCase.java
+++ 
b/paimon-flink/paimon-flink-cdc/src/test/java/org/apache/paimon/flink/action/cdc/CdcDebeziumTimestampExtractorITCase.java
@@ -18,8 +18,10 @@
 
 package org.apache.paimon.flink.action.cdc;
 
+import org.apache.paimon.flink.action.cdc.mongodb.MongoDBCdcTimestampExtractor;
 import org.apache.paimon.flink.action.cdc.mysql.DebeziumEventTest;
-import 
org.apache.paimon.flink.action.cdc.watermark.CdcTimestampExtractorFactory;
+import org.apache.paimon.flink.action.cdc.mysql.MysqlCdcTimestampExtractor;
+import 
org.apache.paimon.flink.action.cdc.watermark.CdcDebeziumTimestampExtractor;
 
 import org.apache.paimon.shade.jackson2.com.fasterxml.jackson.core.JsonParser;
 import 
org.apache.paimon.shade.jackson2.com.fasterxml.jackson.databind.DeserializationFeature;
@@ -33,7 +35,7 @@ import java.net.URL;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-/** IT cases for {@link 
CdcTimestampExtractorFactory.CdcDebeziumTimestampExtractor}. */
+/** IT cases for {@link CdcDebeziumTimestampExtractor}. */
 public class CdcDebeziumTimestampExtractorITCase {
 
     private ObjectMapper objectMapper;
@@ -49,8 +51,7 @@ public class CdcDebeziumTimestampExtractorITCase {
 
     @Test
     public void testMysqlCdcTimestampExtractor() throws Exception {
-        CdcTimestampExtractorFactory.MysqlCdcTimestampExtractor extractor =
-                new CdcTimestampExtractorFactory.MysqlCdcTimestampExtractor();
+        MysqlCdcTimestampExtractor extractor = new 
MysqlCdcTimestampExtractor();
 
         JsonNode data = objectMapper.readValue("{\"payload\" : {\"ts_ms\": 
1}}", JsonNode.class);
         CdcSourceRecord record = new CdcSourceRecord(data.toString());
@@ -69,8 +70,7 @@ public class CdcDebeziumTimestampExtractorITCase {
 
     @Test
     public void testMongodbCdcTimestampExtractor() throws Exception {
-        CdcTimestampExtractorFactory.MongoDBCdcTimestampExtractor extractor =
-                new 
CdcTimestampExtractorFactory.MongoDBCdcTimestampExtractor();
+        MongoDBCdcTimestampExtractor extractor = new 
MongoDBCdcTimestampExtractor();
 
         JsonNode data = objectMapper.readValue("{\"ts_ms\": 1}", 
JsonNode.class);
         CdcSourceRecord record = new CdcSourceRecord(data.toString());


Reply via email to