Commit ae487e0d authored by nobodyiam's avatar nobodyiam

Refactor meta server related logic so that apollo-core is common enough to go...

Refactor meta server related logic so that apollo-core is common enough to go maven central repository.

1. Remove apollo-env.properties from apollo-core, so that it's possible
to deploy apollo-client to maven central repository.
2. Add MetaServerProvider spi so that users could customize how they
find apollo meta servers.
3. Refactor env related utils so that Env.UNKNOWN is returned for
invalid env string instead of null.
parent 48282186
package com.ctrip.framework.apollo.internals;
import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.spi.MetaServerProvider;
import com.ctrip.framework.foundation.Foundation;
import com.google.common.base.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DefaultMetaServerProvider implements MetaServerProvider {
public static final int ORDER = 0;
private static final Logger logger = LoggerFactory.getLogger(DefaultMetaServerProvider.class);
private final String metaServerAddress;
public DefaultMetaServerProvider() {
metaServerAddress = initMetaServerAddress();
}
private String initMetaServerAddress() {
// 1. Get from System Property
String metaAddress = System.getProperty(ConfigConsts.APOLLO_META_KEY);
if (Strings.isNullOrEmpty(metaAddress)) {
// 2. Get from OS environment variable, which could not contain dot and is normally in UPPER case
metaAddress = System.getenv("APOLLO_META");
}
if (Strings.isNullOrEmpty(metaAddress)) {
// 3. Get from server.properties
metaAddress = Foundation.server().getProperty(ConfigConsts.APOLLO_META_KEY, null);
}
if (Strings.isNullOrEmpty(metaAddress)) {
// 4. Get from app.properties
metaAddress = Foundation.app().getProperty(ConfigConsts.APOLLO_META_KEY, null);
}
if (Strings.isNullOrEmpty(metaAddress)) {
logger.warn("Could not find meta server address, because it is not available in neither (1) JVM system property 'apollo.meta', (2) OS env variable 'APOLLO_META' (3) property 'apollo.meta' from server.properties nor (4) property 'apollo.meta' from app.properties");
} else {
metaAddress = metaAddress.trim();
logger.warn("Located meta services from apollo.meta configuration: {}!", metaAddress);
}
return metaAddress;
}
@Override
public String getMetaServerAddress(Env targetEnv) {
//for default meta server provider, we don't care the actual environment
return metaServerAddress;
}
@Override
public int getOrder() {
return ORDER;
}
}
...@@ -10,7 +10,6 @@ import com.ctrip.framework.apollo.core.ConfigConsts; ...@@ -10,7 +10,6 @@ import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.core.MetaDomainConsts; import com.ctrip.framework.apollo.core.MetaDomainConsts;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.enums.EnvUtils; import com.ctrip.framework.apollo.core.enums.EnvUtils;
import com.ctrip.framework.apollo.exceptions.ApolloConfigException;
import com.ctrip.framework.foundation.Foundation; import com.ctrip.framework.foundation.Foundation;
import com.google.common.base.Strings; import com.google.common.base.Strings;
...@@ -98,19 +97,10 @@ public class ConfigUtil { ...@@ -98,19 +97,10 @@ public class ConfigUtil {
/** /**
* Get the current environment. * Get the current environment.
* *
* @return the env * @return the env, UNKNOWN if env is not set or invalid
* @throws ApolloConfigException if env is set
*/ */
public Env getApolloEnv() { public Env getApolloEnv() {
Env env = EnvUtils.transformEnv(Foundation.server().getEnvType()); return 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() { public String getLocalIp() {
...@@ -234,8 +224,7 @@ public class ConfigUtil { ...@@ -234,8 +224,7 @@ public class ConfigUtil {
public boolean isInLocalMode() { public boolean isInLocalMode() {
try { try {
Env env = getApolloEnv(); return Env.LOCAL == getApolloEnv();
return env == Env.LOCAL;
} catch (Throwable ex) { } catch (Throwable ex) {
//ignore //ignore
} }
......
package com.ctrip.framework.apollo.internals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.core.enums.Env;
import org.junit.After;
import org.junit.Test;
public class DefaultMetaServerProviderTest {
@After
public void tearDown() throws Exception {
System.clearProperty(ConfigConsts.APOLLO_META_KEY);
}
@Test
public void testWithSystemProperty() throws Exception {
String someMetaAddress = "someMetaAddress";
Env someEnv = Env.DEV;
System.setProperty(ConfigConsts.APOLLO_META_KEY, " " + someMetaAddress + " ");
DefaultMetaServerProvider defaultMetaServerProvider = new DefaultMetaServerProvider();
assertEquals(someMetaAddress, defaultMetaServerProvider.getMetaServerAddress(someEnv));
}
@Test
public void testWithNoSystemProperty() throws Exception {
Env someEnv = Env.DEV;
DefaultMetaServerProvider defaultMetaServerProvider = new DefaultMetaServerProvider();
assertNull(defaultMetaServerProvider.getMetaServerAddress(someEnv));
}
}
...@@ -30,9 +30,6 @@ public class TitanSettings { ...@@ -30,9 +30,6 @@ public class TitanSettings {
public String getTitanUrl() { public String getTitanUrl() {
Env env = EnvUtils.transformEnv(Foundation.server().getEnvType()); Env env = EnvUtils.transformEnv(Foundation.server().getEnvType());
if (env == null) {
return "";
}
switch (env) { switch (env) {
case FAT: case FAT:
case FWS: case FWS:
...@@ -49,9 +46,6 @@ public class TitanSettings { ...@@ -49,9 +46,6 @@ public class TitanSettings {
public String getTitanDbname() { public String getTitanDbname() {
Env env = EnvUtils.transformEnv(Foundation.server().getEnvType()); Env env = EnvUtils.transformEnv(Foundation.server().getEnvType());
if (env == null) {
return "";
}
switch (env) { switch (env) {
case FAT: case FAT:
case FWS: case FWS:
......
...@@ -5,6 +5,7 @@ public interface ConfigConsts { ...@@ -5,6 +5,7 @@ public interface ConfigConsts {
String CLUSTER_NAME_DEFAULT = "default"; String CLUSTER_NAME_DEFAULT = "default";
String CLUSTER_NAMESPACE_SEPARATOR = "+"; String CLUSTER_NAMESPACE_SEPARATOR = "+";
String APOLLO_CLUSTER_KEY = "apollo.cluster"; String APOLLO_CLUSTER_KEY = "apollo.cluster";
String APOLLO_META_KEY = "apollo.meta";
String CONFIG_FILE_CONTENT_KEY = "content"; String CONFIG_FILE_CONTENT_KEY = "content";
String NO_APPID_PLACEHOLDER = "ApolloNoAppIdPlaceHolder"; String NO_APPID_PLACEHOLDER = "ApolloNoAppIdPlaceHolder";
long NOTIFICATION_ID_PLACEHOLDER = -1; long NOTIFICATION_ID_PLACEHOLDER = -1;
......
package com.ctrip.framework.apollo.core; package com.ctrip.framework.apollo.core;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory;
import com.ctrip.framework.apollo.core.utils.NetUtil;
import com.ctrip.framework.apollo.core.utils.ResourceUtils;
import com.ctrip.framework.apollo.tracer.Tracer;
import com.ctrip.framework.apollo.tracer.spi.Transaction;
import com.ctrip.framework.foundation.Foundation;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.Comparator;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.ctrip.framework.apollo.core.spi.MetaServerProvider;
import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory;
import com.ctrip.framework.apollo.core.utils.NetUtil;
import com.ctrip.framework.apollo.tracer.Tracer;
import com.ctrip.framework.apollo.tracer.spi.Transaction;
import com.ctrip.framework.foundation.internals.ServiceBootstrap;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
/** /**
* The meta domain will load the meta server from System environment first, if not exist, will load from * The meta domain will try to load the meta server address from MetaServerProviders, the default ones are:
* apollo-env.properties. If neither exists, will load the default meta url. *
* <ul>
* <li>com.ctrip.framework.apollo.core.internals.LegacyMetaServerProvider</li>
* </ul>
* *
* Currently, apollo supports local/dev/fat/uat/lpt/pro environments. * If no provider could provide the meta server url, the default meta url will be used(http://apollo.meta).
* <br />
*
* 3rd party MetaServerProvider could be injected by typical Java Service Loader pattern.
*
* @see com.ctrip.framework.apollo.core.internals.LegacyMetaServerProvider
*/ */
public class MetaDomainConsts { public class MetaDomainConsts {
public static final String DEFAULT_META_URL = "http://apollo.meta";
public static final String DEFAULT_META_URL = "http://config.local"; // env -> meta server address cache
private static final Map<Env, String> metaServerAddressCache = Maps.newConcurrentMap();
private static volatile List<MetaServerProvider> metaServerProviders = null;
private static final long REFRESH_INTERVAL_IN_SECOND = 60;//1 min private static final long REFRESH_INTERVAL_IN_SECOND = 60;// 1 min
private static final Logger logger = LoggerFactory.getLogger(MetaDomainConsts.class); private static final Logger logger = LoggerFactory.getLogger(MetaDomainConsts.class);
// comma separated meta server address -> selected single meta server address cache
private static final Map<Env, String> domains = new HashMap<>(); private static final Map<String, String> selectedMetaServerAddressCache = Maps.newConcurrentMap();
private static final Map<String, String> metaServerAddressCache = Maps.newConcurrentMap();
private static final AtomicBoolean periodicRefreshStarted = new AtomicBoolean(false); private static final AtomicBoolean periodicRefreshStarted = new AtomicBoolean(false);
private static final AtomicBoolean customizedMetaServiceLogged = new AtomicBoolean(false);
static { private static final Object LOCK = new Object();
initialize();
}
static void initialize() {
Properties prop = new Properties();
prop = ResourceUtils.readConfigFile("apollo-env.properties", prop);
Properties env = System.getProperties();
domains.put(Env.LOCAL,
env.getProperty("local_meta", prop.getProperty("local.meta", DEFAULT_META_URL)));
domains.put(Env.DEV,
env.getProperty("dev_meta", prop.getProperty("dev.meta", DEFAULT_META_URL)));
domains.put(Env.FAT,
env.getProperty("fat_meta", prop.getProperty("fat.meta", DEFAULT_META_URL)));
domains.put(Env.UAT,
env.getProperty("uat_meta", prop.getProperty("uat.meta", DEFAULT_META_URL)));
domains.put(Env.LPT,
env.getProperty("lpt_meta", prop.getProperty("lpt.meta", DEFAULT_META_URL)));
domains.put(Env.PRO,
env.getProperty("pro_meta", prop.getProperty("pro.meta", DEFAULT_META_URL)));
}
public static String getDomain(Env env) { public static String getDomain(Env env) {
// 1. Get meta server address from run time configurations String metaServerAddress = getMetaServerAddress(env);
String metaAddress = getCustomizedMetaServerAddress(); // if there is more than one address, need to select one
if (Strings.isNullOrEmpty(metaAddress)) { if (metaServerAddress.contains(",")) {
// 2. Get meta server address from environment return selectMetaServerAddress(metaServerAddress);
metaAddress = domains.get(env);
}
// 3. if there is more than one address, need to select one
if (metaAddress != null && metaAddress.contains(",")) {
return selectMetaServerAddress(metaAddress);
} }
// 4. trim if necessary return metaServerAddress;
if (metaAddress != null) { }
metaAddress = metaAddress.trim();
private static String getMetaServerAddress(Env env) {
if (!metaServerAddressCache.containsKey(env)) {
initMetaServerAddress(env);
} }
return metaAddress;
return metaServerAddressCache.get(env);
} }
private static String getCustomizedMetaServerAddress() { private static void initMetaServerAddress(Env env) {
// 1. Get from System Property if (metaServerProviders == null) {
String metaAddress = System.getProperty("apollo.meta"); synchronized (LOCK) {
if (Strings.isNullOrEmpty(metaAddress)) { if (metaServerProviders == null) {
// 2. Get from OS environment variable metaServerProviders = initMetaServerProviders();
metaAddress = System.getenv("APOLLO_META"); }
}
} }
if (Strings.isNullOrEmpty(metaAddress)) {
metaAddress = Foundation.server().getProperty("apollo.meta", null); String metaAddress = null;
for (MetaServerProvider provider : metaServerProviders) {
metaAddress = provider.getMetaServerAddress(env);
if (!Strings.isNullOrEmpty(metaAddress)) {
logger.info("Located meta server address {} for env {} from {}", metaAddress, env,
provider.getClass().getName());
break;
}
} }
if (!Strings.isNullOrEmpty(metaAddress) && customizedMetaServiceLogged.compareAndSet(false, true)) { if (Strings.isNullOrEmpty(metaAddress)) {
logger.warn("Located meta services from apollo.meta configuration: {}, will not use meta services defined in apollo-env.properties!", metaAddress); // Fallback to default meta address
metaAddress = DEFAULT_META_URL;
logger.warn(
"Meta server address fallback to {} for env {}, because it is not available in all MetaServerProviders",
metaAddress, env);
} }
return metaAddress; metaServerAddressCache.put(env, metaAddress.trim());
}
private static List<MetaServerProvider> initMetaServerProviders() {
Iterator<MetaServerProvider> metaServerProviderIterator = ServiceBootstrap.loadAll(MetaServerProvider.class);
List<MetaServerProvider> metaServerProviders = Lists.newArrayList(metaServerProviderIterator);
Collections.sort(metaServerProviders, new Comparator<MetaServerProvider>() {
@Override
public int compare(MetaServerProvider o1, MetaServerProvider o2) {
// the smaller order has higher priority
return Integer.compare(o1.getOrder(), o2.getOrder());
}
});
return metaServerProviders;
} }
/** /**
...@@ -104,18 +123,18 @@ public class MetaDomainConsts { ...@@ -104,18 +123,18 @@ public class MetaDomainConsts {
* *
* <br /> * <br />
* *
* In production environment, we still suggest using one single domain * In production environment, we still suggest using one single domain like http://config.xxx.com(backed by software
* like http://config.xxx.com(backed by software load balancers like nginx) instead of multiple ip addresses * load balancers like nginx) instead of multiple ip addresses
*/ */
private static String selectMetaServerAddress(String metaServerAddresses) { private static String selectMetaServerAddress(String metaServerAddresses) {
String metaAddressSelected = metaServerAddressCache.get(metaServerAddresses); String metaAddressSelected = selectedMetaServerAddressCache.get(metaServerAddresses);
if (metaAddressSelected == null) { if (metaAddressSelected == null) {
//initialize // initialize
if (periodicRefreshStarted.compareAndSet(false, true)) { if (periodicRefreshStarted.compareAndSet(false, true)) {
schedulePeriodicRefresh(); schedulePeriodicRefresh();
} }
updateMetaServerAddresses(metaServerAddresses); updateMetaServerAddresses(metaServerAddresses);
metaAddressSelected = metaServerAddressCache.get(metaServerAddresses); metaAddressSelected = selectedMetaServerAddressCache.get(metaServerAddresses);
} }
return metaAddressSelected; return metaAddressSelected;
...@@ -129,7 +148,7 @@ public class MetaDomainConsts { ...@@ -129,7 +148,7 @@ public class MetaDomainConsts {
try { try {
List<String> metaServers = Lists.newArrayList(metaServerAddresses.split(",")); List<String> metaServers = Lists.newArrayList(metaServerAddresses.split(","));
//random load balancing // random load balancing
Collections.shuffle(metaServers); Collections.shuffle(metaServers);
boolean serverAvailable = false; boolean serverAvailable = false;
...@@ -137,22 +156,22 @@ public class MetaDomainConsts { ...@@ -137,22 +156,22 @@ public class MetaDomainConsts {
for (String address : metaServers) { for (String address : metaServers) {
address = address.trim(); address = address.trim();
if (NetUtil.pingUrl(address)) { if (NetUtil.pingUrl(address)) {
//select the first available meta server // select the first available meta server
metaServerAddressCache.put(metaServerAddresses, address); selectedMetaServerAddressCache.put(metaServerAddresses, address);
serverAvailable = true; serverAvailable = true;
logger.debug("Selected meta server address {} for {}", address, metaServerAddresses); logger.debug("Selected meta server address {} for {}", address, metaServerAddresses);
break; break;
} }
} }
//we need to make sure the map is not empty, e.g. the first update might be failed // we need to make sure the map is not empty, e.g. the first update might be failed
if (!metaServerAddressCache.containsKey(metaServerAddresses)) { if (!selectedMetaServerAddressCache.containsKey(metaServerAddresses)) {
metaServerAddressCache.put(metaServerAddresses, metaServers.get(0).trim()); selectedMetaServerAddressCache.put(metaServerAddresses, metaServers.get(0).trim());
} }
if (!serverAvailable) { if (!serverAvailable) {
logger.warn("Could not find available meta server for configured meta server addresses: {}, fallback to: {}", metaServerAddresses, logger.warn("Could not find available meta server for configured meta server addresses: {}, fallback to: {}",
metaServerAddressCache.get(metaServerAddresses)); metaServerAddresses, selectedMetaServerAddressCache.get(metaServerAddresses));
} }
transaction.setStatus(Transaction.SUCCESS); transaction.setStatus(Transaction.SUCCESS);
...@@ -165,21 +184,19 @@ public class MetaDomainConsts { ...@@ -165,21 +184,19 @@ public class MetaDomainConsts {
} }
private static void schedulePeriodicRefresh() { private static void schedulePeriodicRefresh() {
ScheduledExecutorService scheduledExecutorService = Executors ScheduledExecutorService scheduledExecutorService =
.newScheduledThreadPool(1, ApolloThreadFactory.create("MetaServiceLocator", true)); Executors.newScheduledThreadPool(1, ApolloThreadFactory.create("MetaServiceLocator", true));
scheduledExecutorService.scheduleAtFixedRate(new Runnable() { scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
for (String metaServerAddresses : metaServerAddressCache.keySet()) { for (String metaServerAddresses : selectedMetaServerAddressCache.keySet()) {
updateMetaServerAddresses(metaServerAddresses); updateMetaServerAddresses(metaServerAddresses);
} }
} catch (Throwable ex) { } catch (Throwable ex) {
logger.warn( logger.warn(String.format("Refreshing meta server address failed, will retry in %d seconds",
String.format("Refreshing meta server address failed, will retry in %d seconds", REFRESH_INTERVAL_IN_SECOND), ex);
REFRESH_INTERVAL_IN_SECOND), ex
);
} }
} }
}, REFRESH_INTERVAL_IN_SECOND, REFRESH_INTERVAL_IN_SECOND, TimeUnit.SECONDS); }, REFRESH_INTERVAL_IN_SECOND, REFRESH_INTERVAL_IN_SECOND, TimeUnit.SECONDS);
......
...@@ -19,11 +19,11 @@ import com.google.common.base.Preconditions; ...@@ -19,11 +19,11 @@ import com.google.common.base.Preconditions;
* @author Jason Song(song_s@ctrip.com) * @author Jason Song(song_s@ctrip.com)
*/ */
public enum Env{ public enum Env{
LOCAL, DEV, FWS, FAT, UAT, LPT, PRO, TOOLS; LOCAL, DEV, FWS, FAT, UAT, LPT, PRO, TOOLS, UNKNOWN;
public static Env fromString(String env) { public static Env fromString(String env) {
Env environment = EnvUtils.transformEnv(env); Env environment = EnvUtils.transformEnv(env);
Preconditions.checkArgument(environment != null, String.format("Env %s is invalid", env)); Preconditions.checkArgument(environment != UNKNOWN, String.format("Env %s is invalid", env));
return environment; return environment;
} }
} }
...@@ -6,7 +6,7 @@ public final class EnvUtils { ...@@ -6,7 +6,7 @@ public final class EnvUtils {
public static Env transformEnv(String envName) { public static Env transformEnv(String envName) {
if (StringUtils.isBlank(envName)) { if (StringUtils.isBlank(envName)) {
return null; return Env.UNKNOWN;
} }
switch (envName.trim().toUpperCase()) { switch (envName.trim().toUpperCase()) {
case "LPT": case "LPT":
...@@ -26,7 +26,7 @@ public final class EnvUtils { ...@@ -26,7 +26,7 @@ public final class EnvUtils {
case "TOOLS": case "TOOLS":
return Env.TOOLS; return Env.TOOLS;
default: default:
return null; return Env.UNKNOWN;
} }
} }
} }
package com.ctrip.framework.apollo.core.internals;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.spi.MetaServerProvider;
import com.ctrip.framework.apollo.core.utils.ResourceUtils;
/**
* For legacy meta server configuration use, i.e. apollo-env.properties
*/
public class LegacyMetaServerProvider implements MetaServerProvider {
// make it as lowest as possible, yet not the lowest
public static final int ORDER = MetaServerProvider.LOWEST_PRECEDENCE - 1;
private static final Map<Env, String> domains = new HashMap<>();
public LegacyMetaServerProvider() {
initialize();
}
private void initialize() {
Properties prop = new Properties();
prop = ResourceUtils.readConfigFile("apollo-env.properties", prop);
Properties env = System.getProperties();
domains.put(Env.LOCAL,
env.getProperty("local_meta", prop.getProperty("local.meta")));
domains.put(Env.DEV,
env.getProperty("dev_meta", prop.getProperty("dev.meta")));
domains.put(Env.FAT,
env.getProperty("fat_meta", prop.getProperty("fat.meta")));
domains.put(Env.UAT,
env.getProperty("uat_meta", prop.getProperty("uat.meta")));
domains.put(Env.LPT,
env.getProperty("lpt_meta", prop.getProperty("lpt.meta")));
domains.put(Env.PRO,
env.getProperty("pro_meta", prop.getProperty("pro.meta")));
}
@Override
public String getMetaServerAddress(Env targetEnv) {
String metaServerAddress = domains.get(targetEnv);
return metaServerAddress == null ? null : metaServerAddress.trim();
}
@Override
public int getOrder() {
return ORDER;
}
}
package com.ctrip.framework.apollo.core.spi;
import com.ctrip.framework.apollo.core.enums.Env;
public interface MetaServerProvider extends Ordered {
/**
* Provide the Apollo meta server address, could be a domain url or comma separated ip addresses, like http://1.2.3.4:8080,http://2.3.4.5:8080.
* <br/>
* In production environment, we suggest using one single domain like http://config.xxx.com(backed by software load balancers like nginx) instead of multiple ip addresses
*/
String getMetaServerAddress(Env targetEnv);
}
package com.ctrip.framework.apollo.core.spi;
/**
* {@code Ordered} is an interface that can be implemented by objects that
* should be <em>orderable</em>, for example in a {@code Collection}.
*
* <p>The actual {@link #getOrder() order} can be interpreted as prioritization,
* with the first object (with the lowest order value) having the highest
* priority.
*/
public interface Ordered {
/**
* Useful constant for the highest precedence value.
* @see java.lang.Integer#MIN_VALUE
*/
int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;
/**
* Useful constant for the lowest precedence value.
* @see java.lang.Integer#MAX_VALUE
*/
int LOWEST_PRECEDENCE = Integer.MAX_VALUE;
/**
* Get the order value of this object.
* <p>Higher values are interpreted as lower priority. As a consequence,
* the object with the lowest value has the highest priority (somewhat
* analogous to Servlet {@code load-on-startup} values).
* <p>Same order values will result in arbitrary sort positions for the
* affected objects.
* @return the order value
* @see #HIGHEST_PRECEDENCE
* @see #LOWEST_PRECEDENCE
*/
int getOrder();
}
...@@ -14,7 +14,7 @@ public class ServiceBootstrap { ...@@ -14,7 +14,7 @@ public class ServiceBootstrap {
return iterator.next(); return iterator.next();
} }
private static <S> Iterator<S> loadAll(Class<S> clazz) { public static <S> Iterator<S> loadAll(Class<S> clazz) {
ServiceLoader<S> loader = ServiceLoader.load(clazz); ServiceLoader<S> loader = ServiceLoader.load(clazz);
return loader.iterator(); return loader.iterator();
......
...@@ -5,6 +5,10 @@ import static org.junit.Assert.assertTrue; ...@@ -5,6 +5,10 @@ import static org.junit.Assert.assertTrue;
import com.ctrip.framework.apollo.BaseIntegrationTest; import com.ctrip.framework.apollo.BaseIntegrationTest;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.internals.LegacyMetaServerProvider;
import com.ctrip.framework.apollo.core.spi.MetaServerProvider;
import com.google.common.collect.Maps;
import java.util.Map;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.junit.After; import org.junit.After;
import org.junit.Test; import org.junit.Test;
...@@ -15,10 +19,7 @@ public class MetaDomainTest extends BaseIntegrationTest { ...@@ -15,10 +19,7 @@ public class MetaDomainTest extends BaseIntegrationTest {
@After @After
public void tearDown() throws Exception { public void tearDown() throws Exception {
super.tearDown(); super.tearDown();
System.clearProperty("fat_meta"); MockMetaServerProvider.clear();
System.clearProperty("uat_meta");
System.clearProperty("lpt_meta");
System.clearProperty("apollo.meta");
} }
@Test @Test
...@@ -28,16 +29,6 @@ public class MetaDomainTest extends BaseIntegrationTest { ...@@ -28,16 +29,6 @@ public class MetaDomainTest extends BaseIntegrationTest {
assertEquals(MetaDomainConsts.DEFAULT_META_URL, MetaDomainConsts.getDomain(Env.PRO)); assertEquals(MetaDomainConsts.DEFAULT_META_URL, MetaDomainConsts.getDomain(Env.PRO));
} }
@Test
public void testGetMetaDomainWithSystemProperty() throws Exception {
String someMeta = "some-meta";
Env someEnv = Env.DEV;
System.setProperty("apollo.meta", someMeta);
assertEquals(someMeta, MetaDomainConsts.getDomain(someEnv));
}
@Test @Test
public void testGetValidAddress() throws Exception { public void testGetValidAddress() throws Exception {
String someResponse = "some response"; String someResponse = "some response";
...@@ -46,10 +37,8 @@ public class MetaDomainTest extends BaseIntegrationTest { ...@@ -46,10 +37,8 @@ public class MetaDomainTest extends BaseIntegrationTest {
String validServer = " http://localhost:" + PORT + " "; String validServer = " http://localhost:" + PORT + " ";
String invalidServer = "http://localhost:" + findFreePort(); String invalidServer = "http://localhost:" + findFreePort();
System.setProperty("fat_meta", validServer + "," + invalidServer); MockMetaServerProvider.mock(Env.FAT, validServer + "," + invalidServer);
System.setProperty("uat_meta", invalidServer + "," + validServer); MockMetaServerProvider.mock(Env.UAT, invalidServer + "," + validServer);
MetaDomainConsts.initialize();
assertEquals(validServer.trim(), MetaDomainConsts.getDomain(Env.FAT)); assertEquals(validServer.trim(), MetaDomainConsts.getDomain(Env.FAT));
assertEquals(validServer.trim(), MetaDomainConsts.getDomain(Env.UAT)); assertEquals(validServer.trim(), MetaDomainConsts.getDomain(Env.UAT));
...@@ -60,12 +49,33 @@ public class MetaDomainTest extends BaseIntegrationTest { ...@@ -60,12 +49,33 @@ public class MetaDomainTest extends BaseIntegrationTest {
String invalidServer = "http://localhost:" + findFreePort() + " "; String invalidServer = "http://localhost:" + findFreePort() + " ";
String anotherInvalidServer = "http://localhost:" + findFreePort() + " "; String anotherInvalidServer = "http://localhost:" + findFreePort() + " ";
System.setProperty("lpt_meta", invalidServer + "," + anotherInvalidServer); MockMetaServerProvider.mock(Env.LPT, invalidServer + "," + anotherInvalidServer);
MetaDomainConsts.initialize();
String metaServer = MetaDomainConsts.getDomain(Env.LPT); String metaServer = MetaDomainConsts.getDomain(Env.LPT);
assertTrue(metaServer.equals(invalidServer.trim()) || metaServer.equals(anotherInvalidServer.trim())); assertTrue(metaServer.equals(invalidServer.trim()) || metaServer.equals(anotherInvalidServer.trim()));
} }
public static class MockMetaServerProvider implements MetaServerProvider {
private static Map<Env, String> mockMetaServerAddress = Maps.newHashMap();
private static void mock(Env env, String metaServerAddress) {
mockMetaServerAddress.put(env, metaServerAddress);
}
private static void clear() {
mockMetaServerAddress.clear();
}
@Override
public String getMetaServerAddress(Env targetEnv) {
return mockMetaServerAddress.get(targetEnv);
}
@Override
public int getOrder() {
return LegacyMetaServerProvider.ORDER - 1;// just in front of LegacyMetaServerProvider
}
}
} }
package com.ctrip.framework.apollo.core.enums;
import static org.junit.Assert.*;
import org.junit.Test;
public class EnvUtilsTest {
@Test
public void testTransformEnv() throws Exception {
assertEquals(Env.DEV, EnvUtils.transformEnv(Env.DEV.name()));
assertEquals(Env.FAT, EnvUtils.transformEnv(Env.FAT.name().toLowerCase()));
assertEquals(Env.UAT, EnvUtils.transformEnv(" " + Env.UAT.name().toUpperCase() + ""));
assertEquals(Env.UNKNOWN, EnvUtils.transformEnv("someInvalidEnv"));
}
@Test
public void testFromString() throws Exception {
assertEquals(Env.DEV, Env.fromString(Env.DEV.name()));
assertEquals(Env.FAT, Env.fromString(Env.FAT.name().toLowerCase()));
assertEquals(Env.UAT, Env.fromString(" " + Env.UAT.name().toUpperCase() + ""));
}
@Test(expected = IllegalArgumentException.class)
public void testFromInvalidString() throws Exception {
Env.fromString("someInvalidEnv");
}
}
package com.ctrip.framework.apollo.core.internals;
import static org.junit.Assert.assertEquals;
import com.ctrip.framework.apollo.core.enums.Env;
import org.junit.After;
import org.junit.Test;
public class LegacyMetaServerProviderTest {
@After
public void tearDown() throws Exception {
System.clearProperty("dev_meta");
}
@Test
public void testFromPropertyFile() {
LegacyMetaServerProvider legacyMetaServerProvider = new LegacyMetaServerProvider();
assertEquals("http://localhost:8080", legacyMetaServerProvider.getMetaServerAddress(Env.LOCAL));
assertEquals("http://dev:8080", legacyMetaServerProvider.getMetaServerAddress(Env.DEV));
assertEquals(null, legacyMetaServerProvider.getMetaServerAddress(Env.PRO));
}
@Test
public void testWithSystemProperty() throws Exception {
String someDevMetaAddress = "someMetaAddress";
String someFatMetaAddress = "someFatMetaAddress";
System.setProperty("dev_meta", someDevMetaAddress);
System.setProperty("fat_meta", someFatMetaAddress);
LegacyMetaServerProvider legacyMetaServerProvider = new LegacyMetaServerProvider();
assertEquals(someDevMetaAddress, legacyMetaServerProvider.getMetaServerAddress(Env.DEV));
assertEquals(someFatMetaAddress, legacyMetaServerProvider.getMetaServerAddress(Env.FAT));
}
}
package com.ctrip.framework.foundation.internals; package com.ctrip.framework.foundation.internals;
import com.ctrip.framework.foundation.internals.ServiceBootstrap;
import org.junit.Test; import org.junit.Test;
import java.util.ServiceConfigurationError; import java.util.ServiceConfigurationError;
......
local.meta=http://localhost:8080
dev.meta=${dev_meta}
fat.meta=${fat_meta}
uat.meta=${uat_meta}
lpt.meta=${lpt_meta}
pro.meta=${pro_meta}
...@@ -2,6 +2,7 @@ package com.ctrip.framework.apollo.portal.controller; ...@@ -2,6 +2,7 @@ package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.common.dto.NamespaceDTO; import com.ctrip.framework.apollo.common.dto.NamespaceDTO;
import com.ctrip.framework.apollo.common.exception.BadRequestException; import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.enums.EnvUtils; import com.ctrip.framework.apollo.core.enums.EnvUtils;
import com.ctrip.framework.apollo.core.utils.StringUtils; import com.ctrip.framework.apollo.core.utils.StringUtils;
import com.ctrip.framework.apollo.openapi.entity.Consumer; import com.ctrip.framework.apollo.openapi.entity.Consumer;
...@@ -90,7 +91,7 @@ public class ConsumerController { ...@@ -90,7 +91,7 @@ public class ConsumerController {
if (Strings.isNullOrEmpty(env)) { if (Strings.isNullOrEmpty(env)) {
continue; continue;
} }
if (null == EnvUtils.transformEnv(env)) { if (Env.UNKNOWN == EnvUtils.transformEnv(env)) {
throw new BadRequestException(String.format("env: %s is illegal", env)); throw new BadRequestException(String.format("env: %s is illegal", env));
} }
envList.add(env); envList.add(env);
......
...@@ -98,7 +98,7 @@ public class PermissionController { ...@@ -98,7 +98,7 @@ public class PermissionController {
public NamespaceEnvRolesAssignedUsers getNamespaceEnvRoles(@PathVariable String appId, @PathVariable String env, @PathVariable String namespaceName) { public NamespaceEnvRolesAssignedUsers getNamespaceEnvRoles(@PathVariable String appId, @PathVariable String env, @PathVariable String namespaceName) {
// validate env parameter // validate env parameter
if (null == EnvUtils.transformEnv(env)) { if (Env.UNKNOWN == EnvUtils.transformEnv(env)) {
throw new BadRequestException("env is illegal"); throw new BadRequestException("env is illegal");
} }
...@@ -130,7 +130,7 @@ public class PermissionController { ...@@ -130,7 +130,7 @@ public class PermissionController {
} }
// validate env parameter // validate env parameter
if (null == EnvUtils.transformEnv(env)) { if (Env.UNKNOWN == EnvUtils.transformEnv(env)) {
throw new BadRequestException("env is illegal"); throw new BadRequestException("env is illegal");
} }
Set<String> assignedUser = rolePermissionService.assignRoleToUsers(RoleUtils.buildNamespaceRoleName(appId, namespaceName, roleType, env), Set<String> assignedUser = rolePermissionService.assignRoleToUsers(RoleUtils.buildNamespaceRoleName(appId, namespaceName, roleType, env),
...@@ -152,7 +152,7 @@ public class PermissionController { ...@@ -152,7 +152,7 @@ public class PermissionController {
throw new BadRequestException("role type is illegal"); throw new BadRequestException("role type is illegal");
} }
// validate env parameter // validate env parameter
if (null == EnvUtils.transformEnv(env)) { if (Env.UNKNOWN == EnvUtils.transformEnv(env)) {
throw new BadRequestException("env is illegal"); throw new BadRequestException("env is illegal");
} }
rolePermissionService.removeRoleFromUsers(RoleUtils.buildNamespaceRoleName(appId, namespaceName, roleType, env), rolePermissionService.removeRoleFromUsers(RoleUtils.buildNamespaceRoleName(appId, namespaceName, roleType, env),
......
...@@ -378,29 +378,6 @@ ...@@ -378,29 +378,6 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.17</version>
<dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>6.18</version>
</dependency>
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-buildtools</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<configuration>
<configLocation>google_checks.xml</configLocation>
<headerLocation>LICENSE-2.0.txt</headerLocation>
<failOnViolation>false</failOnViolation>
<consoleOutput>true</consoleOutput>
</configuration>
</plugin>
<plugin> <plugin>
<groupId>org.codehaus.mojo</groupId> <groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId> <artifactId>findbugs-maven-plugin</artifactId>
...@@ -462,10 +439,6 @@ ...@@ -462,10 +439,6 @@
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId> <artifactId>maven-deploy-plugin</artifactId>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
<plugin> <plugin>
<groupId>org.codehaus.mojo</groupId> <groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId> <artifactId>findbugs-maven-plugin</artifactId>
...@@ -531,7 +504,6 @@ ...@@ -531,7 +504,6 @@
<filtering>true</filtering> <filtering>true</filtering>
<includes> <includes>
<include>application-github.properties</include> <include>application-github.properties</include>
<include>apollo-env.properties</include>
</includes> </includes>
</resource> </resource>
<resource> <resource>
...@@ -539,7 +511,6 @@ ...@@ -539,7 +511,6 @@
<filtering>false</filtering> <filtering>false</filtering>
<excludes> <excludes>
<exclude>application-github.properties</exclude> <exclude>application-github.properties</exclude>
<exclude>apollo-env.properties</exclude>
</excludes> </excludes>
</resource> </resource>
</resources> </resources>
......
...@@ -37,10 +37,4 @@ call mvn clean package -DskipTests -pl apollo-portal -am -Dapollo_profile=github ...@@ -37,10 +37,4 @@ call mvn clean package -DskipTests -pl apollo-portal -am -Dapollo_profile=github
echo "==== building portal finished ====" echo "==== building portal finished ===="
echo "==== starting to build client ===="
call mvn clean install -DskipTests -pl apollo-client -am %META_SERVERS_OPTS%
echo "==== building client finished ===="
pause pause
...@@ -36,10 +36,3 @@ echo "==== starting to build portal ====" ...@@ -36,10 +36,3 @@ echo "==== starting to build portal ===="
mvn clean package -DskipTests -pl apollo-portal -am -Dapollo_profile=github,auth -Dspring_datasource_url=$apollo_portal_db_url -Dspring_datasource_username=$apollo_portal_db_username -Dspring_datasource_password=$apollo_portal_db_password $META_SERVERS_OPTS mvn clean package -DskipTests -pl apollo-portal -am -Dapollo_profile=github,auth -Dspring_datasource_url=$apollo_portal_db_url -Dspring_datasource_username=$apollo_portal_db_username -Dspring_datasource_password=$apollo_portal_db_password $META_SERVERS_OPTS
echo "==== building portal finished ====" echo "==== building portal finished ===="
echo "==== starting to build client ===="
mvn clean install -DskipTests -pl apollo-client -am $META_SERVERS_OPTS
echo "==== building client finished ===="
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment