package com.alibaba.jstorm.config; import backtype.storm.utils.NimbusClientWrapper; import com.alibaba.jstorm.callback.RunnableCallback; import com.alibaba.jstorm.utils.JStormUtils; import com.alibaba.jstorm.utils.LoadConf; import java.io.File; import java.io.IOException; import java.util.Map; import java.util.Random; import org.apache.commons.io.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Cody (weiyue.wy@alibaba-inc.com) * @since 16/5/21 */ public class SupervisorRefreshConfig extends RunnableCallback { private static final Logger LOG = LoggerFactory.getLogger(SupervisorRefreshConfig.class); /** * storm conf, excluding yarn config */ private Map stormConf; /** * storm yaml string, excluding yarn config */ private String stormYaml; private NimbusClientWrapper nimbusClientWrapper; private final Random random = new Random(System.currentTimeMillis()); private final Integer refreshInterval; private final YarnConfigBlacklist yarnConfigBlacklist; /** * yarn config */ private final String retainedYarnConfig; public SupervisorRefreshConfig(Map conf) { LOG.info("init SupervisorRefreshConfig thread..."); this.yarnConfigBlacklist = YarnConfigBlacklist.getInstance(conf); try { String rawYaml = FileUtils.readFileToString(new File(LoadConf.getStormYamlPath())); this.stormYaml = JStormUtils.trimEnd(yarnConfigBlacklist.filterConfigIfNecessary(rawYaml)); this.stormConf = LoadConf.loadYamlFromString(this.stormYaml); this.retainedYarnConfig = yarnConfigBlacklist.getRetainedConfig(rawYaml); LOG.info("retained yarn config:\n============================\n{}", retainedYarnConfig); } catch (IOException ex) { LOG.error("failed to read local storm.yaml!", ex); throw new RuntimeException(ex); } // check nimbus config every 20 ~ 30 sec this.refreshInterval = random.nextInt(10) + 20; LOG.info("done."); } @Override public void run() { try { if (this.nimbusClientWrapper == null) { this.nimbusClientWrapper = new NimbusClientWrapper(); try { this.nimbusClientWrapper.init(this.stormConf); } catch (Exception ex) { LOG.error("init nimbus client wrapper error, maybe nimbus is not alive."); } } String nimbusYaml = JStormUtils.trimEnd(yarnConfigBlacklist.filterConfigIfNecessary( this.nimbusClientWrapper.getClient().getStormRawConf())); Map nimbusConf = LoadConf.loadYamlFromString(nimbusYaml); if (nimbusYaml != null && !this.stormConf.equals(nimbusConf)) { Map newConf = LoadConf.loadYamlFromString(nimbusYaml); if (newConf == null) { LOG.error("received invalid storm.yaml, skip..."); } else { LOG.debug("received nimbus config update, new config:\n{}", nimbusYaml); this.stormYaml = nimbusYaml; // append yarn config nimbusYaml = JStormUtils.trimEnd(nimbusYaml + "\n" + retainedYarnConfig); // backup config & overwrite current storm.yaml RefreshableComponents.refresh(newConf); LoadConf.backupAndOverwriteStormYaml(nimbusYaml); } } } catch (Exception ex) { LOG.error("failed to get nimbus conf, maybe nimbus is not alive."); this.nimbusClientWrapper.reconnect(); } } @Override public Object getResult() { return refreshInterval; } }