package com.ctrip.framework.apollo.util; import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.ctrip.framework.apollo.core.ConfigConsts; import com.ctrip.framework.apollo.core.MetaDomainConsts; import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.EnvUtils; import com.ctrip.framework.apollo.exceptions.ApolloConfigException; import com.ctrip.framework.foundation.Foundation; import com.google.common.base.Strings; /** * @author Jason Song(song_s@ctrip.com) */ public class ConfigUtil { private static final Logger logger = LoggerFactory.getLogger(ConfigUtil.class); private static final String TOOLING_CLUSTER = "tooling"; private int refreshInterval = 5; private TimeUnit refreshIntervalTimeUnit = TimeUnit.MINUTES; private int connectTimeout = 1000; //1 second private int readTimeout = 5000; //5 seconds private String cluster; private int loadConfigQPS = 2; //2 times per second private int longPollQPS = 2; //2 times per second //for on error retry private long onErrorRetryInterval = 1;//1 second private TimeUnit onErrorRetryIntervalTimeUnit = TimeUnit.SECONDS;//1 second //for typed config cache of parser result, e.g. integer, double, long, etc. private long maxConfigCacheSize = 500;//500 cache key private long configCacheExpireTime = 1;//1 minute private TimeUnit configCacheExpireTimeUnit = TimeUnit.MINUTES;//1 minute public ConfigUtil() { initRefreshInterval(); initConnectTimeout(); initReadTimeout(); initCluster(); initQPS(); initMaxConfigCacheSize(); } /** * Get the app id for the current application. * * @return the app id or ConfigConsts.NO_APPID_PLACEHOLDER if app id is not available */ public String getAppId() { String appId = Foundation.app().getAppId(); if (Strings.isNullOrEmpty(appId)) { appId = ConfigConsts.NO_APPID_PLACEHOLDER; logger.warn("app.id is not set, please make sure it is set in classpath:/META-INF/app.properties, now apollo " + "will only load public namespace configurations!"); } return appId; } /** * Get the data center info for the current application. * * @return the current data center, null if there is no such info. */ public String getDataCenter() { return Foundation.server().getDataCenter(); } private void initCluster() { //Load data center from system property cluster = System.getProperty(ConfigConsts.APOLLO_CLUSTER_KEY); String env = Foundation.server().getEnvType(); //LPT and DEV will be treated as a cluster(lower case) if (Strings.isNullOrEmpty(cluster) && (Env.DEV.name().equalsIgnoreCase(env) || Env.LPT.name().equalsIgnoreCase(env)) ) { cluster = env.toLowerCase(); } //Use TOOLING cluster if tooling=true in server.properties if (Strings.isNullOrEmpty(cluster) && isToolingZone()) { cluster = TOOLING_CLUSTER; } //Use data center as cluster if (Strings.isNullOrEmpty(cluster)) { cluster = getDataCenter(); } //Use default cluster if (Strings.isNullOrEmpty(cluster)) { cluster = ConfigConsts.CLUSTER_NAME_DEFAULT; } } private boolean isToolingZone() { //do not use the new isTooling method since it might not be available in the client side return "true".equalsIgnoreCase(Foundation.server().getProperty("tooling", "false").trim()); } /** * Get the cluster name for the current application. * * @return the cluster name, or "default" if not specified */ public String getCluster() { return cluster; } /** * Get the current environment. * * @return the env * @throws ApolloConfigException if env is set */ public Env getApolloEnv() { Env env = EnvUtils.transformEnv(Foundation.server().getEnvType()); if (env == null) { String path = isOSWindows() ? "C:\\opt\\settings\\server.properties" : "/opt/settings/server.properties"; String message = String.format("env is not set, please make sure it is set in %s!", path); logger.error(message); throw new ApolloConfigException(message); } return env; } public String getLocalIp() { return Foundation.net().getHostAddress(); } public String getMetaServerDomainName() { return MetaDomainConsts.getDomain(getApolloEnv()); } private void initConnectTimeout() { String customizedConnectTimeout = System.getProperty("apollo.connectTimeout"); if (!Strings.isNullOrEmpty(customizedConnectTimeout)) { try { connectTimeout = Integer.parseInt(customizedConnectTimeout); } catch (Throwable ex) { logger.error("Config for apollo.connectTimeout is invalid: {}", customizedConnectTimeout); } } } public int getConnectTimeout() { return connectTimeout; } private void initReadTimeout() { String customizedReadTimeout = System.getProperty("apollo.readTimeout"); if (!Strings.isNullOrEmpty(customizedReadTimeout)) { try { readTimeout = Integer.parseInt(customizedReadTimeout); } catch (Throwable ex) { logger.error("Config for apollo.readTimeout is invalid: {}", customizedReadTimeout); } } } public int getReadTimeout() { return readTimeout; } private void initRefreshInterval() { String customizedRefreshInterval = System.getProperty("apollo.refreshInterval"); if (!Strings.isNullOrEmpty(customizedRefreshInterval)) { try { refreshInterval = Integer.parseInt(customizedRefreshInterval); } catch (Throwable ex) { logger.error("Config for apollo.refreshInterval is invalid: {}", customizedRefreshInterval); } } } public int getRefreshInterval() { return refreshInterval; } public TimeUnit getRefreshIntervalTimeUnit() { return refreshIntervalTimeUnit; } private void initQPS() { String customizedLoadConfigQPS = System.getProperty("apollo.loadConfigQPS"); if (!Strings.isNullOrEmpty(customizedLoadConfigQPS)) { try { loadConfigQPS = Integer.parseInt(customizedLoadConfigQPS); } catch (Throwable ex) { logger.error("Config for apollo.loadConfigQPS is invalid: {}", customizedLoadConfigQPS); } } String customizedLongPollQPS = System.getProperty("apollo.longPollQPS"); if (!Strings.isNullOrEmpty(customizedLongPollQPS)) { try { longPollQPS = Integer.parseInt(customizedLongPollQPS); } catch (Throwable ex) { logger.error("Config for apollo.longPollQPS is invalid: {}", customizedLongPollQPS); } } } public int getLoadConfigQPS() { return loadConfigQPS; } public int getLongPollQPS() { return longPollQPS; } public long getOnErrorRetryInterval() { return onErrorRetryInterval; } public TimeUnit getOnErrorRetryIntervalTimeUnit() { return onErrorRetryIntervalTimeUnit; } public String getDefaultLocalCacheDir() { String cacheRoot = isOSWindows() ? "C:\\opt\\data\\%s" : "/opt/data/%s"; return String.format(cacheRoot, getAppId()); } public boolean isInLocalMode() { try { Env env = getApolloEnv(); return env == Env.LOCAL; } catch (Throwable ex) { //ignore } return false; } public boolean isOSWindows() { String osName = System.getProperty("os.name"); if (Strings.isNullOrEmpty(osName)) { return false; } return osName.startsWith("Windows"); } private void initMaxConfigCacheSize() { String customizedConfigCacheSize = System.getProperty("apollo.configCacheSize"); if (!Strings.isNullOrEmpty(customizedConfigCacheSize)) { try { maxConfigCacheSize = Long.valueOf(customizedConfigCacheSize); } catch (Throwable ex) { logger.error("Config for apollo.configCacheSize is invalid: {}", customizedConfigCacheSize); } } } public long getMaxConfigCacheSize() { return maxConfigCacheSize; } public long getConfigCacheExpireTime() { return configCacheExpireTime; } public TimeUnit getConfigCacheExpireTimeUnit() { return configCacheExpireTimeUnit; } }