package com.ctrip.platform.dal.dao.status; import java.lang.management.ManagementFactory; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import javax.management.MBeanServer; import javax.management.ObjectName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.ctrip.platform.dal.dao.Version; import com.ctrip.platform.dal.dao.configure.DalConfigure; import com.ctrip.platform.dal.dao.markdown.MarkdownManager; /** * TODO add logic DB level markdown control * @author jhhe * */ public class DalStatusManager { private static Logger logger = LoggerFactory.getLogger(Version.getLoggerName()); private static final String GLOBAL_CONFIG_DOMAIN_PREFIX = "com.ctrip.dal.client"; private static final String TYPE = "type"; private static final String LOGIC_DB_CONFIG_DOMAIN_PREFIX = "com.ctrip.dal.client.DatabaseSet"; private static final String DATASOURCE_CONFIG_DOMAIN_PREFIX = "com.ctrip.dal.client.DataSource"; private static AtomicBoolean initialized = new AtomicBoolean(false); private static AtomicReference<TimeoutMarkdown> timeoutMarkDownRef = new AtomicReference<>(); private static AtomicReference<HAStatus> haStatusRef = new AtomicReference<>(); private static AtomicReference<MarkdownStatus> markdownStatusRef = new AtomicReference<>(); private static Map<String, DatabaseSetStatus> logicDbs = new ConcurrentHashMap<>(); private static Map<String, DataSourceStatus> dataSources = new ConcurrentHashMap<>(); public static void initialize(DalConfigure config) throws Exception { if(initialized.get() == true) return; synchronized (DalStatusManager.class) { if(initialized.get() == true) return; verifyRegistration(); registerGlobal(); registerDatabaseSets(config.getDatabaseSetNames()); registerDataSources(config.getDataSourceNames()); MarkdownManager.init(); initialized.set(true);; } } private static void verifyRegistration() throws Exception{ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); if(mbs.isRegistered(getGlobalName(HAStatus.class))){ logger.warn("DAL Management Bean has already been initialized. Please make remove your application's Context registration in server.xml under Tomcat conf folder."); }; } private static void registerMBean(Object mBean, ObjectName name) throws Exception{ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); if(mbs.isRegistered(name)) mbs.unregisterMBean(name); mbs.registerMBean(mBean, name); } private static void registerGlobal() throws Exception{ haStatusRef.set(new HAStatus()); registerMBean(haStatusRef.get(), getGlobalName(HAStatus.class)); timeoutMarkDownRef.set(new TimeoutMarkdown()); registerMBean(timeoutMarkDownRef.get(), getGlobalName(TimeoutMarkdown.class)); markdownStatusRef.set(new MarkdownStatus()); registerMBean(markdownStatusRef.get(), getGlobalName(MarkdownStatus.class)); } private static void registerDatabaseSets(Set<String> logicDbNames) throws Exception { for(String name: logicDbNames) { DatabaseSetStatus status = new DatabaseSetStatus(name); registerMBean(status, new ObjectName(LOGIC_DB_CONFIG_DOMAIN_PREFIX, TYPE, name)); logicDbs.put(name, status); } } private static void registerDataSources(Set<String> datasourceNames) throws Exception { for(String name: datasourceNames) { DataSourceStatus status = new DataSourceStatus(name); registerMBean(status, new ObjectName(DATASOURCE_CONFIG_DOMAIN_PREFIX, TYPE, name)); dataSources.put(name, status); } } public static void shutdown() throws Exception { if(initialized.get() == false) return; synchronized (DalStatusManager.class) { if(initialized.get() == false) return; MarkdownManager.shutdown(); MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); mbs.unregisterMBean(getGlobalName(HAStatus.class)); mbs.unregisterMBean(getGlobalName(TimeoutMarkdown.class)); mbs.unregisterMBean(getGlobalName(MarkdownStatus.class)); for(String name: dataSources.keySet()) mbs.unregisterMBean(new ObjectName(DATASOURCE_CONFIG_DOMAIN_PREFIX, TYPE, name)); dataSources.clear(); for(String name: logicDbs.keySet()) mbs.unregisterMBean(new ObjectName(LOGIC_DB_CONFIG_DOMAIN_PREFIX, TYPE, name)); logicDbs.clear(); initialized.set(false); } } private static ObjectName getGlobalName(Class clazz) throws Exception { return new ObjectName(GLOBAL_CONFIG_DOMAIN_PREFIX, TYPE, clazz.getSimpleName()); } public static TimeoutMarkdown getTimeoutMarkdown() { return timeoutMarkDownRef.get(); } public static HAStatus getHaStatus() { return haStatusRef.get(); } public static MarkdownStatus getMarkdownStatus() { return markdownStatusRef.get(); } public static DatabaseSetStatus getDatabaseSetStatus(String dbName) { return logicDbs.get(dbName); } public static DataSourceStatus getDataSourceStatus(String dbName) { return dataSources.get(dbName); } public static boolean containsDataSourceStatus(String dbName) { return dataSources.containsKey(dbName); } }