package phoenix.config; import java.io.File; import java.io.IOException; import java.nio.file.Paths; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicLong; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.eventbus.EventBus; public class WatchConfigFileService { private static Map<String, WatchConfigFileService> BOSS = new ConcurrentHashMap<String, WatchConfigFileService>(); private static final Logger LOGGER = LoggerFactory.getLogger(WatchConfigFileService.class); private AtomicLong lastChangeTimeStamp = new AtomicLong(0); private ExecutorService executor = Executors.newSingleThreadExecutor(); private final File file; private final String serviceName; private final EventBus eventBus; private final Long intervalTime; private volatile Context config; public WatchConfigFileService() { this("default", "/oneapm/etc/tomcat/config", 1000 * 5); } public WatchConfigFileService(String name) { this(name, "/oneapm/etc/tomcat/config", 1000 * 5); } public WatchConfigFileService(String name, String configPath) { this(name, configPath, 1000 * 5); } public WatchConfigFileService(String name, String configFilePath, long checkConfigFileInterval) { Validate.isTrue(StringUtils.isNotBlank(configFilePath), "ConfigFilePath is blank !"); Validate.isTrue(StringUtils.isNotBlank(name), "Name is blank !"); this.serviceName = name; Validate.isTrue(!BOSS.containsKey(serviceName)); this.eventBus = new EventBus(serviceName + "-event-bus"); this.file = Paths.get(configFilePath).toFile(); Validate.isTrue(this.file.exists(), "ConfigFile is not exist !"); Validate.isTrue(checkConfigFileInterval > 0); this.intervalTime = checkConfigFileInterval; try { work(); } catch (IOException e) { Validate.isTrue(false, "Init WatchConfigFileService Failed :" + name); } this.executor.submit(new Runnable() { @Override public void run() { while (true) { try { long lastModified = file.lastModified(); if (lastModified > lastChangeTimeStamp.get()) { LOGGER.info("ConfigFile is changed ! WatchConfigFileService-" + serviceName); work(); } Thread.sleep(intervalTime); } catch (Throwable e) { LOGGER.error("WatchConfigFileService-" + serviceName + " Error :", e); } } } }); BOSS.put(name, this); } public void work() throws IOException { config = new Context(file.getAbsolutePath()); eventBus.post(config); lastChangeTimeStamp.set(file.lastModified()); } public void regist(Object o) { eventBus.register(o); } public static WatchConfigFileService get(String name) { return BOSS.get(name); } public Context getConfig() { return config; } }