|
@@ -18,10 +18,11 @@ package com.ctrip.framework.apollo.internals;
|
|
|
|
|
|
import com.ctrip.framework.apollo.core.utils.DeferredLoggerFactory;
|
|
import com.ctrip.framework.apollo.core.utils.DeferredLoggerFactory;
|
|
import com.ctrip.framework.apollo.enums.ConfigSourceType;
|
|
import com.ctrip.framework.apollo.enums.ConfigSourceType;
|
|
|
|
+import com.google.common.collect.Maps;
|
|
|
|
+import com.google.common.collect.Sets;
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InputStream;
|
|
import java.util.Collections;
|
|
import java.util.Collections;
|
|
-import java.util.LinkedHashMap;
|
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
import java.util.Objects;
|
|
import java.util.Objects;
|
|
@@ -38,6 +39,7 @@ import com.ctrip.framework.apollo.tracer.Tracer;
|
|
import com.ctrip.framework.apollo.util.ExceptionUtil;
|
|
import com.ctrip.framework.apollo.util.ExceptionUtil;
|
|
import com.google.common.collect.ImmutableMap;
|
|
import com.google.common.collect.ImmutableMap;
|
|
import com.google.common.util.concurrent.RateLimiter;
|
|
import com.google.common.util.concurrent.RateLimiter;
|
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -83,17 +85,84 @@ public class DefaultConfig extends AbstractConfig implements RepositoryChangeLis
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * get property from cached repository properties file
|
|
|
|
+ *
|
|
|
|
+ * @param key property key
|
|
|
|
+ * @return value
|
|
|
|
+ */
|
|
|
|
+ protected String getPropertyFromRepository(String key) {
|
|
|
|
+ Properties properties = m_configProperties.get();
|
|
|
|
+ if (properties != null) {
|
|
|
|
+ return properties.getProperty(key);
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * get property from additional properties file on classpath
|
|
|
|
+ *
|
|
|
|
+ * @param key property key
|
|
|
|
+ * @return value
|
|
|
|
+ */
|
|
|
|
+ protected String getPropertyFromAdditional(String key) {
|
|
|
|
+ Properties properties = this.m_resourceProperties;
|
|
|
|
+ if (properties != null) {
|
|
|
|
+ return properties.getProperty(key);
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * try to print a warn log when can not find a property
|
|
|
|
+ *
|
|
|
|
+ * @param value value
|
|
|
|
+ */
|
|
|
|
+ protected void tryWarnLog(String value) {
|
|
|
|
+ if (value == null && m_configProperties.get() == null && m_warnLogRateLimiter.tryAcquire()) {
|
|
|
|
+ logger.warn(
|
|
|
|
+ "Could not load config for namespace {} from Apollo, please check whether the configs are released in Apollo! Return default value now!",
|
|
|
|
+ m_namespace);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * get property names from cached repository properties file
|
|
|
|
+ *
|
|
|
|
+ * @return property names
|
|
|
|
+ */
|
|
|
|
+ protected Set<String> getPropertyNamesFromRepository() {
|
|
|
|
+ Properties properties = m_configProperties.get();
|
|
|
|
+ if (properties == null) {
|
|
|
|
+ return Collections.emptySet();
|
|
|
|
+ }
|
|
|
|
+ return this.stringPropertyNames(properties);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * get property names from additional properties file on classpath
|
|
|
|
+ *
|
|
|
|
+ * @return property names
|
|
|
|
+ */
|
|
|
|
+ protected Set<String> getPropertyNamesFromAdditional() {
|
|
|
|
+ Properties properties = m_resourceProperties;
|
|
|
|
+ if (properties == null) {
|
|
|
|
+ return Collections.emptySet();
|
|
|
|
+ }
|
|
|
|
+ return this.stringPropertyNames(properties);
|
|
|
|
+ }
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
public String getProperty(String key, String defaultValue) {
|
|
public String getProperty(String key, String defaultValue) {
|
|
// step 1: check system properties, i.e. -Dkey=value
|
|
// step 1: check system properties, i.e. -Dkey=value
|
|
String value = System.getProperty(key);
|
|
String value = System.getProperty(key);
|
|
|
|
|
|
// step 2: check local cached properties file
|
|
// step 2: check local cached properties file
|
|
- if (value == null && m_configProperties.get() != null) {
|
|
|
|
- value = m_configProperties.get().getProperty(key);
|
|
|
|
|
|
+ if (value == null) {
|
|
|
|
+ value = this.getPropertyFromRepository(key);
|
|
}
|
|
}
|
|
|
|
|
|
- /**
|
|
|
|
|
|
+ /*
|
|
* step 3: check env variable, i.e. PATH=...
|
|
* step 3: check env variable, i.e. PATH=...
|
|
* normally system environment variables are in UPPERCASE, however there might be exceptions.
|
|
* normally system environment variables are in UPPERCASE, however there might be exceptions.
|
|
* so the caller should provide the key in the right case
|
|
* so the caller should provide the key in the right case
|
|
@@ -103,27 +172,31 @@ public class DefaultConfig extends AbstractConfig implements RepositoryChangeLis
|
|
}
|
|
}
|
|
|
|
|
|
// step 4: check properties file from classpath
|
|
// step 4: check properties file from classpath
|
|
- if (value == null && m_resourceProperties != null) {
|
|
|
|
- value = m_resourceProperties.getProperty(key);
|
|
|
|
|
|
+ if (value == null) {
|
|
|
|
+ value = this.getPropertyFromAdditional(key);
|
|
}
|
|
}
|
|
|
|
|
|
- if (value == null && m_configProperties.get() == null && m_warnLogRateLimiter.tryAcquire()) {
|
|
|
|
- logger.warn(
|
|
|
|
- "Could not load config for namespace {} from Apollo, please check whether the configs are released in Apollo! Return default value now!",
|
|
|
|
- m_namespace);
|
|
|
|
- }
|
|
|
|
|
|
+ this.tryWarnLog(value);
|
|
|
|
|
|
return value == null ? defaultValue : value;
|
|
return value == null ? defaultValue : value;
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public Set<String> getPropertyNames() {
|
|
public Set<String> getPropertyNames() {
|
|
- Properties properties = m_configProperties.get();
|
|
|
|
- if (properties == null) {
|
|
|
|
- return Collections.emptySet();
|
|
|
|
|
|
+ // propertyNames include system property and system env might cause some compatibility issues, though that looks like the correct implementation.
|
|
|
|
+ Set<String> fromRepository = this.getPropertyNamesFromRepository();
|
|
|
|
+ Set<String> fromAdditional = this.getPropertyNamesFromAdditional();
|
|
|
|
+ if (CollectionUtils.isEmpty(fromRepository)) {
|
|
|
|
+ return fromAdditional;
|
|
}
|
|
}
|
|
-
|
|
|
|
- return stringPropertyNames(properties);
|
|
|
|
|
|
+ if (CollectionUtils.isEmpty(fromAdditional)) {
|
|
|
|
+ return fromRepository;
|
|
|
|
+ }
|
|
|
|
+ Set<String> propertyNames = Sets
|
|
|
|
+ .newLinkedHashSetWithExpectedSize(fromRepository.size() + fromAdditional.size());
|
|
|
|
+ propertyNames.addAll(fromRepository);
|
|
|
|
+ propertyNames.addAll(fromAdditional);
|
|
|
|
+ return propertyNames;
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -133,7 +206,7 @@ public class DefaultConfig extends AbstractConfig implements RepositoryChangeLis
|
|
|
|
|
|
private Set<String> stringPropertyNames(Properties properties) {
|
|
private Set<String> stringPropertyNames(Properties properties) {
|
|
//jdk9以下版本Properties#enumerateStringProperties方法存在性能问题,keys() + get(k) 重复迭代, jdk9之后改为entrySet遍历.
|
|
//jdk9以下版本Properties#enumerateStringProperties方法存在性能问题,keys() + get(k) 重复迭代, jdk9之后改为entrySet遍历.
|
|
- Map<String, String> h = new LinkedHashMap<>();
|
|
|
|
|
|
+ Map<String, String> h = Maps.newLinkedHashMapWithExpectedSize(properties.size());
|
|
for (Map.Entry<Object, Object> e : properties.entrySet()) {
|
|
for (Map.Entry<Object, Object> e : properties.entrySet()) {
|
|
Object k = e.getKey();
|
|
Object k = e.getKey();
|
|
Object v = e.getValue();
|
|
Object v = e.getValue();
|