|
@@ -1,9 +1,12 @@
|
|
|
package com.alibaba.otter.canal.client.adapter.es;
|
|
|
|
|
|
import java.net.InetAddress;
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.LinkedHashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
+import java.util.regex.Matcher;
|
|
|
+import java.util.regex.Pattern;
|
|
|
|
|
|
import javax.sql.DataSource;
|
|
|
|
|
@@ -13,10 +16,13 @@ import org.elasticsearch.common.settings.Settings;
|
|
|
import org.elasticsearch.common.transport.TransportAddress;
|
|
|
import org.elasticsearch.transport.client.PreBuiltTransportClient;
|
|
|
|
|
|
+import com.alibaba.druid.pool.DruidDataSource;
|
|
|
import com.alibaba.otter.canal.client.adapter.OuterAdapter;
|
|
|
import com.alibaba.otter.canal.client.adapter.es.config.ESSyncConfig;
|
|
|
import com.alibaba.otter.canal.client.adapter.es.config.ESSyncConfig.ESMapping;
|
|
|
import com.alibaba.otter.canal.client.adapter.es.config.ESSyncConfigLoader;
|
|
|
+import com.alibaba.otter.canal.client.adapter.es.config.SchemaItem;
|
|
|
+import com.alibaba.otter.canal.client.adapter.es.config.SqlParser;
|
|
|
import com.alibaba.otter.canal.client.adapter.es.service.ESEtlService;
|
|
|
import com.alibaba.otter.canal.client.adapter.es.service.ESSyncService;
|
|
|
import com.alibaba.otter.canal.client.adapter.es.support.ESTemplate;
|
|
@@ -31,9 +37,12 @@ import com.alibaba.otter.canal.client.adapter.support.*;
|
|
|
@SPI("es")
|
|
|
public class ESAdapter implements OuterAdapter {
|
|
|
|
|
|
- private TransportClient transportClient;
|
|
|
+ private Map<String, ESSyncConfig> esSyncConfig = new LinkedHashMap<>(); // 文件名对应配置
|
|
|
+ private Map<String, List<ESSyncConfig>> dbTableEsSyncConfig = new LinkedHashMap<>(); // schema-table对应配置
|
|
|
|
|
|
- private ESSyncService esSyncService;
|
|
|
+ private TransportClient transportClient;
|
|
|
+
|
|
|
+ private ESSyncService esSyncService;
|
|
|
|
|
|
public TransportClient getTransportClient() {
|
|
|
return transportClient;
|
|
@@ -43,10 +52,48 @@ public class ESAdapter implements OuterAdapter {
|
|
|
return esSyncService;
|
|
|
}
|
|
|
|
|
|
+ public Map<String, ESSyncConfig> getEsSyncConfig() {
|
|
|
+ return esSyncConfig;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Map<String, List<ESSyncConfig>> getDbTableEsSyncConfig() {
|
|
|
+ return dbTableEsSyncConfig;
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public void init(OuterAdapterConfig configuration) {
|
|
|
try {
|
|
|
- ESSyncConfigLoader.load();
|
|
|
+ SPI spi = this.getClass().getAnnotation(SPI.class);
|
|
|
+ Map<String, ESSyncConfig> esSyncConfigTmp = ESSyncConfigLoader.load(spi.value());
|
|
|
+ // 过滤不匹配的key的配置
|
|
|
+ esSyncConfigTmp.forEach((key, config) -> {
|
|
|
+ if ((config.getOuterAdapterKey() == null && configuration.getKey() == null)
|
|
|
+ || config.getOuterAdapterKey().equalsIgnoreCase(configuration.getKey())) {
|
|
|
+ esSyncConfig.put(key, config);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ for (ESSyncConfig config : esSyncConfig.values()) {
|
|
|
+ SchemaItem schemaItem = SqlParser.parse(config.getEsMapping().getSql());
|
|
|
+ config.getEsMapping().setSchemaItem(schemaItem);
|
|
|
+
|
|
|
+ DruidDataSource dataSource = DatasourceConfig.DATA_SOURCES.get(config.getDataSourceKey());
|
|
|
+ if (dataSource == null || dataSource.getUrl() == null) {
|
|
|
+ throw new RuntimeException("No data source found: " + config.getDataSourceKey());
|
|
|
+ }
|
|
|
+ Pattern pattern = Pattern.compile(".*:(.*)://.*/(.*)\\?.*$");
|
|
|
+ Matcher matcher = pattern.matcher(dataSource.getUrl());
|
|
|
+ if (!matcher.find()) {
|
|
|
+ throw new RuntimeException("Not found the schema of jdbc-url: " + config.getDataSourceKey());
|
|
|
+ }
|
|
|
+ String schema = matcher.group(2);
|
|
|
+
|
|
|
+ schemaItem.getAliasTableItems().values().forEach(tableItem -> {
|
|
|
+ List<ESSyncConfig> esSyncConfigs = dbTableEsSyncConfig
|
|
|
+ .computeIfAbsent(schema + "-" + tableItem.getTableName(), k -> new ArrayList<>());
|
|
|
+ esSyncConfigs.add(config);
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
Map<String, String> properties = configuration.getProperties();
|
|
|
Settings.Builder settingBuilder = Settings.builder();
|
|
@@ -68,13 +115,16 @@ public class ESAdapter implements OuterAdapter {
|
|
|
|
|
|
@Override
|
|
|
public void sync(Dml dml) {
|
|
|
- esSyncService.sync(dml);
|
|
|
+ String database = dml.getDatabase();
|
|
|
+ String table = dml.getTable();
|
|
|
+ List<ESSyncConfig> esSyncConfigs = dbTableEsSyncConfig.get(database + "-" + table);
|
|
|
+ esSyncService.sync(esSyncConfigs, dml);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public EtlResult etl(String task, List<String> params) {
|
|
|
EtlResult etlResult = new EtlResult();
|
|
|
- ESSyncConfig config = ESSyncConfigLoader.getEsSyncConfig().get(task);
|
|
|
+ ESSyncConfig config = esSyncConfig.get(task);
|
|
|
if (config != null) {
|
|
|
DataSource dataSource = DatasourceConfig.DATA_SOURCES.get(config.getDataSourceKey());
|
|
|
ESEtlService esEtlService = new ESEtlService(transportClient, config);
|
|
@@ -89,7 +139,7 @@ public class ESAdapter implements OuterAdapter {
|
|
|
StringBuilder resultMsg = new StringBuilder();
|
|
|
boolean resSuccess = true;
|
|
|
// ds不为空说明传入的是datasourceKey
|
|
|
- for (ESSyncConfig configTmp : ESSyncConfigLoader.getEsSyncConfig().values()) {
|
|
|
+ for (ESSyncConfig configTmp : esSyncConfig.values()) {
|
|
|
// 取所有的destination为task的配置
|
|
|
if (configTmp.getDestination().equals(task)) {
|
|
|
ESEtlService esEtlService = new ESEtlService(transportClient, configTmp);
|
|
@@ -119,7 +169,7 @@ public class ESAdapter implements OuterAdapter {
|
|
|
|
|
|
@Override
|
|
|
public Map<String, Object> count(String task) {
|
|
|
- ESSyncConfig config = ESSyncConfigLoader.getEsSyncConfig().get(task);
|
|
|
+ ESSyncConfig config = esSyncConfig.get(task);
|
|
|
ESMapping mapping = config.getEsMapping();
|
|
|
SearchResponse response = transportClient.prepareSearch(mapping.get_index())
|
|
|
.setTypes(mapping.get_type())
|
|
@@ -142,7 +192,7 @@ public class ESAdapter implements OuterAdapter {
|
|
|
|
|
|
@Override
|
|
|
public String getDestination(String task) {
|
|
|
- ESSyncConfig config = ESSyncConfigLoader.getEsSyncConfig().get(task);
|
|
|
+ ESSyncConfig config = esSyncConfig.get(task);
|
|
|
if (config != null) {
|
|
|
return config.getDestination();
|
|
|
}
|