|
@@ -1,5 +1,9 @@
|
|
|
package com.alibaba.otter.canal.client.adapter.loader;
|
|
|
|
|
|
+import com.alibaba.otter.canal.client.adapter.CanalOuterAdapter;
|
|
|
+import com.alibaba.otter.canal.client.adapter.support.CanalClientConfig;
|
|
|
+import com.alibaba.otter.canal.client.adapter.support.CanalOuterAdapterConfiguration;
|
|
|
+import com.alibaba.otter.canal.client.adapter.support.ExtensionLoader;
|
|
|
import java.net.InetSocketAddress;
|
|
|
import java.net.SocketAddress;
|
|
|
import java.util.ArrayList;
|
|
@@ -8,44 +12,38 @@ import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.concurrent.ExecutorService;
|
|
|
import java.util.concurrent.Executors;
|
|
|
-
|
|
|
+import org.apache.commons.lang.StringUtils;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
-import com.alibaba.otter.canal.client.adapter.CanalOuterAdapter;
|
|
|
-import com.alibaba.otter.canal.client.adapter.support.CanalClientConfig;
|
|
|
-import com.alibaba.otter.canal.client.adapter.support.CanalOuterAdapterConfiguration;
|
|
|
-import com.alibaba.otter.canal.client.adapter.support.ExtensionLoader;
|
|
|
-
|
|
|
/**
|
|
|
- * 外部适配器的加载器
|
|
|
+ * MQ外部适配器的加载器
|
|
|
*
|
|
|
- * @author machengyuan 2018-8-19 下午11:45:49
|
|
|
* @version 1.0.0
|
|
|
*/
|
|
|
public class CanalAdapterLoader {
|
|
|
|
|
|
- private static final Logger logger = LoggerFactory.getLogger(CanalAdapterLoader.class);
|
|
|
+ private static final Logger logger = LoggerFactory.getLogger(CanalAdapterLoader.class);
|
|
|
|
|
|
- private CanalClientConfig canalClientConfig;
|
|
|
+ private CanalClientConfig canalClientConfig;
|
|
|
|
|
|
- private Map<String, CanalAdapterWorker> canalWorkers = new HashMap<>();
|
|
|
+ private Map<String, CanalAdapterWorker> canalWorkers = new HashMap<>();
|
|
|
|
|
|
- private Map<String, CanalAdapterKafkaWorker> canalKafkaWorkers = new HashMap<>();
|
|
|
+ private Map<String, AbstractCanalAdapterWorker> canalMQWorker = new HashMap<>();
|
|
|
|
|
|
- private ExtensionLoader<CanalOuterAdapter> loader;
|
|
|
+ private ExtensionLoader<CanalOuterAdapter> loader;
|
|
|
|
|
|
- public CanalAdapterLoader(CanalClientConfig canalClientConfig){
|
|
|
+ public CanalAdapterLoader(CanalClientConfig canalClientConfig) {
|
|
|
this.canalClientConfig = canalClientConfig;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 初始化canal-client、 canal-client-kafka的适配器
|
|
|
+ * 初始化canal-client、 canal-client-rocketmq的适配器
|
|
|
*/
|
|
|
public void init() {
|
|
|
- // canal instances 和 kafka topics 配置不能同时为空
|
|
|
- if (canalClientConfig.getCanalInstances() == null && canalClientConfig.getKafkaTopics() == null) {
|
|
|
- throw new RuntimeException("Blank config property: canalInstances or canalKafkaTopics");
|
|
|
+ // canal instances 和 mq topics 配置不能同时为空
|
|
|
+ if (canalClientConfig.getCanalInstances() == null && canalClientConfig.getMqTopics() == null) {
|
|
|
+ throw new RuntimeException("Blank config property: canalInstances or canalMQTopics");
|
|
|
}
|
|
|
|
|
|
loader = ExtensionLoader.getExtensionLoader(CanalOuterAdapter.class,
|
|
@@ -59,13 +57,6 @@ public class CanalAdapterLoader {
|
|
|
}
|
|
|
String zkHosts = this.canalClientConfig.getZookeeperHosts();
|
|
|
|
|
|
- boolean flatMessage = this.canalClientConfig.getFlatMessage();
|
|
|
-
|
|
|
- // if (zkHosts == null && sa == null) {
|
|
|
- // throw new RuntimeException("Blank config property: canalServerHost or
|
|
|
- // zookeeperHosts");
|
|
|
- // }
|
|
|
-
|
|
|
// 初始化canal-client的适配器
|
|
|
if (canalClientConfig.getCanalInstances() != null) {
|
|
|
for (CanalClientConfig.CanalInstance instance : canalClientConfig.getCanalInstances()) {
|
|
@@ -90,32 +81,38 @@ public class CanalAdapterLoader {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 初始化canal-client-kafka的适配器
|
|
|
- if (canalClientConfig.getKafkaTopics() != null) {
|
|
|
- for (CanalClientConfig.KafkaTopic kafkaTopic : canalClientConfig.getKafkaTopics()) {
|
|
|
- for (CanalClientConfig.Group group : kafkaTopic.getGroups()) {
|
|
|
+ // 初始化canal-client-mq的适配器
|
|
|
+ if (canalClientConfig.getMqTopics() != null) {
|
|
|
+ for (CanalClientConfig.MQTopic topic : canalClientConfig.getMqTopics()) {
|
|
|
+ for (CanalClientConfig.Group group : topic.getGroups()) {
|
|
|
List<List<CanalOuterAdapter>> canalOuterAdapterGroups = new ArrayList<>();
|
|
|
|
|
|
List<CanalOuterAdapter> canalOuterAdapters = new ArrayList<>();
|
|
|
|
|
|
for (CanalOuterAdapterConfiguration config : group.getOutAdapters()) {
|
|
|
- // for (CanalOuterAdapterConfiguration config : adaptor.getOutAdapters()) {
|
|
|
loadConnector(config, canalOuterAdapters);
|
|
|
- // }
|
|
|
}
|
|
|
canalOuterAdapterGroups.add(canalOuterAdapters);
|
|
|
+ if (StringUtils.isBlank(topic.getMqMode()) || "rocketmq".equalsIgnoreCase(topic.getMqMode())) {
|
|
|
+ CanalAdapterRocketMQWorker rocketMQWorker = new CanalAdapterRocketMQWorker(
|
|
|
+ canalClientConfig.getBootstrapServers(),
|
|
|
+ topic.getTopic(),
|
|
|
+ group.getGroupId(),
|
|
|
+ canalOuterAdapterGroups);
|
|
|
+ canalMQWorker.put(topic.getTopic() + "-rocketmq-" + group.getGroupId(), rocketMQWorker);
|
|
|
+ rocketMQWorker.start();
|
|
|
+ } else if ("kafka".equalsIgnoreCase(topic.getMqMode())) {
|
|
|
+ CanalAdapterKafkaWorker canalKafkaWorker = new CanalAdapterKafkaWorker(
|
|
|
+ canalClientConfig.getBootstrapServers(),
|
|
|
+ topic.getTopic(),
|
|
|
+ group.getGroupId(),
|
|
|
+ canalOuterAdapterGroups,canalClientConfig.getFlatMessage());
|
|
|
+ canalMQWorker.put(topic.getTopic() + "-kafka-" + group.getGroupId(), canalKafkaWorker);
|
|
|
+ canalKafkaWorker.start();
|
|
|
+ }
|
|
|
+ logger.info("Start adapter for canal-client rocketmq topic: {} succeed",
|
|
|
+ topic.getTopic() + "-" + group.getGroupId());
|
|
|
|
|
|
- // String zkServers = canalClientConfig.getZookeeperHosts();
|
|
|
- CanalAdapterKafkaWorker canalKafkaWorker = new CanalAdapterKafkaWorker(
|
|
|
- canalClientConfig.getBootstrapServers(),
|
|
|
- kafkaTopic.getTopic(),
|
|
|
- group.getGroupId(),
|
|
|
- canalOuterAdapterGroups,
|
|
|
- flatMessage);
|
|
|
- canalKafkaWorkers.put(kafkaTopic.getTopic() + "-" + group.getGroupId(), canalKafkaWorker);
|
|
|
- canalKafkaWorker.start();
|
|
|
- logger.info("Start adapter for canal-client kafka topic: {} succeed",
|
|
|
- kafkaTopic.getTopic() + "-" + group.getGroupId());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -154,19 +151,18 @@ public class CanalAdapterLoader {
|
|
|
}
|
|
|
stopExecutorService.shutdown();
|
|
|
}
|
|
|
- if (canalKafkaWorkers.size() > 0) {
|
|
|
- ExecutorService stopKafkaExecutorService = Executors.newFixedThreadPool(canalKafkaWorkers.size());
|
|
|
- for (CanalAdapterKafkaWorker v : canalKafkaWorkers.values()) {
|
|
|
- final CanalAdapterKafkaWorker cakw = v;
|
|
|
- stopKafkaExecutorService.submit(new Runnable() {
|
|
|
-
|
|
|
+ if (canalMQWorker.size() > 0) {
|
|
|
+ ExecutorService stopMQWokerService = Executors.newFixedThreadPool(canalMQWorker.size());
|
|
|
+ for (AbstractCanalAdapterWorker tmp : canalMQWorker.values()) {
|
|
|
+ final AbstractCanalAdapterWorker worker = tmp;
|
|
|
+ stopMQWokerService.submit(new Runnable() {
|
|
|
@Override
|
|
|
public void run() {
|
|
|
- cakw.stop();
|
|
|
+ worker.stop();
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
- stopKafkaExecutorService.shutdown();
|
|
|
+ stopMQWokerService.shutdown();
|
|
|
}
|
|
|
logger.info("All canal adapters destroyed");
|
|
|
}
|