package com.taobao.tddl.config.diamond; import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.concurrent.Executor; import com.taobao.diamond.client.impl.DiamondEnv; import com.taobao.diamond.client.impl.DiamondEnvRepo; import com.taobao.diamond.client.impl.DiamondUnitSite; import com.taobao.diamond.common.Constants; import com.taobao.diamond.manager.ManagerListener; import com.taobao.diamond.manager.SkipInitialCallbackListener; import com.taobao.tddl.common.exception.TddlException; import com.taobao.tddl.common.utils.extension.Activate; import com.taobao.tddl.common.utils.mbean.TddlMBean; import com.taobao.tddl.common.utils.mbean.TddlMBeanServer; import com.taobao.tddl.config.ConfigDataListener; import com.taobao.tddl.config.impl.UnitConfigDataHandler; import com.taobao.tddl.common.utils.logger.Logger; import com.taobao.tddl.common.utils.logger.LoggerFactory; /** * 持久配置中心diamond实现 * * @author shenxun * @author <a href="zylicfc@gmail.com">junyu</a> * @version 1.0 * @since 1.6 * @date 2011-1-11 11:22:29 */ @Activate(order = 1) public class DiamondConfigDataHandler extends UnitConfigDataHandler { private static final Logger logger = LoggerFactory.getLogger(DiamondConfigDataHandler.class); public static final long TIMEOUT = 10 * 1000; private String mbeanId; private TddlMBean mbean; private DiamondEnv env; public void doInit() { mbean = new TddlMBean("Diamond Config Info " + System.currentTimeMillis()); mbeanId = dataId + System.currentTimeMillis(); // TODO 外部直接指定ip进行访问 if (unitName != null && !"".equals(unitName.trim())) { env = DiamondUnitSite.getDiamondUnitEnv(unitName); } else { env = DiamondEnvRepo.defaultEnv; } if (initialData == null) { initialData = getData(TIMEOUT, FIRST_SERVER_STRATEGY); } addListener0(listeners, (Executor) config.get("executor"), initialData); TddlMBeanServer.registerMBeanWithId(mbean, mbeanId); } public String getNullableData(long timeout, String strategy) { String data = null; try { data = env.getConfig(dataId, null, Constants.GETCONFIG_LOCAL_SNAPSHOT_SERVER, timeout); } catch (IOException e) { // 不抛异常,只记录一下 logger.error(e); } if (data != null) { mbean.setAttribute(dataId, data); } else { mbean.setAttribute(dataId, ""); } return data; } public String getData(long timeout, String strategy) { String data = null; try { data = env.getConfig(dataId, null, Constants.GETCONFIG_LOCAL_SNAPSHOT_SERVER, timeout); } catch (IOException e) { throw new RuntimeException("get diamond data error!dataId:" + dataId, e); } if (data != null) { mbean.setAttribute(dataId, data); } else { mbean.setAttribute(dataId, ""); } return data; } public void addListener(final ConfigDataListener configDataListener, final Executor executor) { if (configDataListener != null) { String data = getData(TIMEOUT, FIRST_SERVER_STRATEGY); addListener0(configDataListener, executor, data); } } public void addListeners(final List<ConfigDataListener> configDataListenerList, final Executor executor) { if (configDataListenerList != null) { String data = getData(TIMEOUT, FIRST_SERVER_STRATEGY); addListener0(configDataListenerList, executor, data); } } public void closeUnderManager() { List<ManagerListener> listeners = env.getListeners(dataId, null); for (ManagerListener l : listeners) { env.removeListener(dataId, null, l); } } protected void doDestory() throws TddlException { closeUnderManager(); } /** * 共用的addListener处理 * * @param configDataListenerList * @param executor * @param data */ private void addListener0(final ConfigDataListener configDataListener, final Executor executor, String data) { env.addListeners(dataId, null, Arrays.asList(new SkipInitialCallbackListener(data) { @Override public Executor getExecutor() { return executor; } @Override public void receiveConfigInfo0(String data) { configDataListener.onDataRecieved(dataId, data); if (data != null) { mbean.setAttribute(dataId, data); } else { mbean.setAttribute(dataId, ""); } } })); } /** * 共用的addListener处理 * * @param configDataListenerList * @param executor * @param data */ private void addListener0(final List<ConfigDataListener> configDataListenerList, final Executor executor, String data) { env.addListeners(dataId, null, Arrays.asList(new SkipInitialCallbackListener(data) { @Override public Executor getExecutor() { return executor; } @Override public void receiveConfigInfo0(String data) { for (ConfigDataListener configDataListener : configDataListenerList) { try { configDataListener.onDataRecieved(dataId, data); } catch (Exception e) { logger.error("one of listener failed", e); continue; } } if (data != null) { mbean.setAttribute(dataId, data); } else { mbean.setAttribute(dataId, ""); } } })); } public String getDataId() { return dataId; } public void setDataId(String dataId) { this.dataId = dataId; } }