Merge pull request #1540 from wurongjun/master

修复当适配器mapping文件修改时,无法生效的问题
This commit is contained in:
agapple
2019-02-28 10:32:07 +08:00
committed by GitHub

View File

@@ -1,169 +1,169 @@
package com.alibaba.otter.canal.client.adapter.rdb.monitor; package com.alibaba.otter.canal.client.adapter.rdb.monitor;
import java.io.File; import java.io.File;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.apache.commons.io.filefilter.FileFilterUtils; import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor; import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.apache.commons.io.monitor.FileAlterationMonitor; import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver; import org.apache.commons.io.monitor.FileAlterationObserver;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.Yaml;
import com.alibaba.otter.canal.client.adapter.rdb.RdbAdapter; import com.alibaba.otter.canal.client.adapter.rdb.RdbAdapter;
import com.alibaba.otter.canal.client.adapter.rdb.config.MappingConfig; import com.alibaba.otter.canal.client.adapter.rdb.config.MappingConfig;
import com.alibaba.otter.canal.client.adapter.rdb.config.MirrorDbConfig; import com.alibaba.otter.canal.client.adapter.rdb.config.MirrorDbConfig;
import com.alibaba.otter.canal.client.adapter.support.MappingConfigsLoader; import com.alibaba.otter.canal.client.adapter.support.MappingConfigsLoader;
import com.alibaba.otter.canal.client.adapter.support.Util; import com.alibaba.otter.canal.client.adapter.support.Util;
public class RdbConfigMonitor { public class RdbConfigMonitor {
private static final Logger logger = LoggerFactory.getLogger(RdbConfigMonitor.class); private static final Logger logger = LoggerFactory.getLogger(RdbConfigMonitor.class);
private static final String adapterName = "rdb"; private static final String adapterName = "rdb";
private String key; private String key;
private RdbAdapter rdbAdapter; private RdbAdapter rdbAdapter;
private FileAlterationMonitor fileMonitor; private FileAlterationMonitor fileMonitor;
public void init(String key, RdbAdapter rdbAdapter) { public void init(String key, RdbAdapter rdbAdapter) {
this.key = key; this.key = key;
this.rdbAdapter = rdbAdapter; this.rdbAdapter = rdbAdapter;
File confDir = Util.getConfDirPath(adapterName); File confDir = Util.getConfDirPath(adapterName);
try { try {
FileAlterationObserver observer = new FileAlterationObserver(confDir, FileAlterationObserver observer = new FileAlterationObserver(confDir,
FileFilterUtils.and(FileFilterUtils.fileFileFilter(), FileFilterUtils.suffixFileFilter("yml"))); FileFilterUtils.and(FileFilterUtils.fileFileFilter(), FileFilterUtils.suffixFileFilter("yml")));
FileListener listener = new FileListener(); FileListener listener = new FileListener();
observer.addListener(listener); observer.addListener(listener);
fileMonitor = new FileAlterationMonitor(3000, observer); fileMonitor = new FileAlterationMonitor(3000, observer);
fileMonitor.start(); fileMonitor.start();
} catch (Exception e) { } catch (Exception e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
} }
} }
public void destroy() { public void destroy() {
try { try {
fileMonitor.stop(); fileMonitor.stop();
} catch (Exception e) { } catch (Exception e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
} }
} }
private class FileListener extends FileAlterationListenerAdaptor { private class FileListener extends FileAlterationListenerAdaptor {
@Override @Override
public void onFileCreate(File file) { public void onFileCreate(File file) {
super.onFileCreate(file); super.onFileCreate(file);
try { try {
// 加载新增的配置文件 // 加载新增的配置文件
String configContent = MappingConfigsLoader.loadConfig(adapterName + File.separator + file.getName()); String configContent = MappingConfigsLoader.loadConfig(adapterName + File.separator + file.getName());
MappingConfig config = new Yaml().loadAs(configContent, MappingConfig.class); MappingConfig config = new Yaml().loadAs(configContent, MappingConfig.class);
config.validate(); config.validate();
if ((key == null && config.getOuterAdapterKey() == null) if ((key == null && config.getOuterAdapterKey() == null)
|| (key != null && key.equals(config.getOuterAdapterKey()))) { || (key != null && key.equals(config.getOuterAdapterKey()))) {
addConfigToCache(file, config); addConfigToCache(file, config);
logger.info("Add a new rdb mapping config: {} to canal adapter", file.getName()); logger.info("Add a new rdb mapping config: {} to canal adapter", file.getName());
} }
} catch (Exception e) { } catch (Exception e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
} }
} }
@Override @Override
public void onFileChange(File file) { public void onFileChange(File file) {
super.onFileChange(file); super.onFileChange(file);
try { try {
if (rdbAdapter.getRdbMapping().containsKey(file.getName())) { if (rdbAdapter.getRdbMapping().containsKey(file.getName())) {
// 加载配置文件 // 加载配置文件
String configContent = MappingConfigsLoader String configContent = MappingConfigsLoader
.loadConfig(adapterName + File.separator + file.getName()); .loadConfig(adapterName + File.separator + file.getName());
if (configContent == null) { if (configContent == null) {
onFileDelete(file); onFileDelete(file);
return; return;
} }
MappingConfig config = new Yaml().loadAs(configContent, MappingConfig.class); MappingConfig config = new Yaml().loadAs(configContent, MappingConfig.class);
config.validate(); config.validate();
if ((key == null && config.getOuterAdapterKey() == null) if ((key == null && config.getOuterAdapterKey() == null)
|| (key != null && key.equals(config.getOuterAdapterKey()))) { || (key != null && key.equals(config.getOuterAdapterKey()))) {
if (rdbAdapter.getRdbMapping().containsKey(file.getName())) { if (rdbAdapter.getRdbMapping().containsKey(file.getName())) {
deleteConfigFromCache(file); deleteConfigFromCache(file);
} }
addConfigToCache(file, config); addConfigToCache(file, config);
} else { } else {
// 不能修改outerAdapterKey // 不能修改outerAdapterKey
throw new RuntimeException("Outer adapter key not allowed modify"); throw new RuntimeException("Outer adapter key not allowed modify");
} }
logger.info("Change a rdb mapping config: {} of canal adapter", file.getName()); logger.info("Change a rdb mapping config: {} of canal adapter", file.getName());
} }
} catch (Exception e) { } catch (Exception e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
} }
} }
@Override @Override
public void onFileDelete(File file) { public void onFileDelete(File file) {
super.onFileDelete(file); super.onFileDelete(file);
try { try {
if (rdbAdapter.getRdbMapping().containsKey(file.getName())) { if (rdbAdapter.getRdbMapping().containsKey(file.getName())) {
deleteConfigFromCache(file); deleteConfigFromCache(file);
logger.info("Delete a rdb mapping config: {} of canal adapter", file.getName()); logger.info("Delete a rdb mapping config: {} of canal adapter", file.getName());
} }
} catch (Exception e) { } catch (Exception e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
} }
} }
private void addConfigToCache(File file, MappingConfig mappingConfig) { private void addConfigToCache(File file, MappingConfig mappingConfig) {
if (mappingConfig == null || mappingConfig.getDbMapping() == null) { if (mappingConfig == null || mappingConfig.getDbMapping() == null) {
return; return;
} }
rdbAdapter.getRdbMapping().put(file.getName(), mappingConfig); rdbAdapter.getRdbMapping().put(file.getName(), mappingConfig);
if (!mappingConfig.getDbMapping().getMirrorDb()) { if (!mappingConfig.getDbMapping().getMirrorDb()) {
Map<String, MappingConfig> configMap = rdbAdapter.getMappingConfigCache() Map<String, MappingConfig> configMap = rdbAdapter.getMappingConfigCache()
.computeIfAbsent(StringUtils.trimToEmpty(mappingConfig.getDestination()) + "." .computeIfAbsent(StringUtils.trimToEmpty(mappingConfig.getDestination()) + "_"
+ mappingConfig.getDbMapping().getDatabase() + "." + mappingConfig.getDbMapping().getDatabase() + "-"
+ mappingConfig.getDbMapping().getTable(), + mappingConfig.getDbMapping().getTable(),
k1 -> new HashMap<>()); k1 -> new HashMap<>());
configMap.put(file.getName(), mappingConfig); configMap.put(file.getName(), mappingConfig);
} else { } else {
Map<String, MirrorDbConfig> mirrorDbConfigCache = rdbAdapter.getMirrorDbConfigCache(); Map<String, MirrorDbConfig> mirrorDbConfigCache = rdbAdapter.getMirrorDbConfigCache();
mirrorDbConfigCache.put(StringUtils.trimToEmpty(mappingConfig.getDestination()) + "." mirrorDbConfigCache.put(StringUtils.trimToEmpty(mappingConfig.getDestination()) + "."
+ mappingConfig.getDbMapping().getDatabase(), + mappingConfig.getDbMapping().getDatabase(),
MirrorDbConfig.create(file.getName(), mappingConfig)); MirrorDbConfig.create(file.getName(), mappingConfig));
} }
} }
private void deleteConfigFromCache(File file) { private void deleteConfigFromCache(File file) {
MappingConfig mappingConfig = rdbAdapter.getRdbMapping().remove(file.getName()); MappingConfig mappingConfig = rdbAdapter.getRdbMapping().remove(file.getName());
if (mappingConfig == null || mappingConfig.getDbMapping() == null) { if (mappingConfig == null || mappingConfig.getDbMapping() == null) {
return; return;
} }
if (!mappingConfig.getDbMapping().getMirrorDb()) { if (!mappingConfig.getDbMapping().getMirrorDb()) {
for (Map<String, MappingConfig> configMap : rdbAdapter.getMappingConfigCache().values()) { for (Map<String, MappingConfig> configMap : rdbAdapter.getMappingConfigCache().values()) {
if (configMap != null) { if (configMap != null) {
configMap.remove(file.getName()); configMap.remove(file.getName());
} }
} }
} else { } else {
rdbAdapter.getMirrorDbConfigCache().forEach((key, mirrorDbConfig) -> { rdbAdapter.getMirrorDbConfigCache().forEach((key, mirrorDbConfig) -> {
if (mirrorDbConfig.getFileName().equals(file.getName())) { if (mirrorDbConfig.getFileName().equals(file.getName())) {
rdbAdapter.getMirrorDbConfigCache().remove(key); rdbAdapter.getMirrorDbConfigCache().remove(key);
} }
}); });
} }
} }
} }
} }