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;
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;
......@@ -98,19 +97,10 @@ public class ConfigUtil {
/**
* Get the current environment.
*
* @return the env
* @throws ApolloConfigException if env is set
* @return the env, UNKNOWN if env is not set or invalid
*/
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;
return EnvUtils.transformEnv(Foundation.server().getEnvType());
}
public String getLocalIp() {
......@@ -234,8 +224,7 @@ public class ConfigUtil {
public boolean isInLocalMode() {
try {
Env env = getApolloEnv();
return env == Env.LOCAL;
return Env.LOCAL == getApolloEnv();
} catch (Throwable ex) {
//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 {
public String getTitanUrl() {
Env env = EnvUtils.transformEnv(Foundation.server().getEnvType());
if (env == null) {
return "";
}
switch (env) {
case FAT:
case FWS:
......@@ -49,9 +46,6 @@ public class TitanSettings {
public String getTitanDbname() {
Env env = EnvUtils.transformEnv(Foundation.server().getEnvType());
if (env == null) {
return "";
}
switch (env) {
case FAT:
case FWS:
......
......@@ -5,6 +5,7 @@ public interface ConfigConsts {
String CLUSTER_NAME_DEFAULT = "default";
String CLUSTER_NAMESPACE_SEPARATOR = "+";
String APOLLO_CLUSTER_KEY = "apollo.cluster";
String APOLLO_META_KEY = "apollo.meta";
String CONFIG_FILE_CONTENT_KEY = "content";
String NO_APPID_PLACEHOLDER = "ApolloNoAppIdPlaceHolder";
long NOTIFICATION_ID_PLACEHOLDER = -1;
......
......@@ -19,11 +19,11 @@ import com.google.common.base.Preconditions;
* @author Jason Song(song_s@ctrip.com)
*/
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) {
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;
}
}
......@@ -6,7 +6,7 @@ public final class EnvUtils {
public static Env transformEnv(String envName) {
if (StringUtils.isBlank(envName)) {
return null;
return Env.UNKNOWN;
}
switch (envName.trim().toUpperCase()) {
case "LPT":
......@@ -26,7 +26,7 @@ public final class EnvUtils {
case "TOOLS":
return Env.TOOLS;
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 {
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);
return loader.iterator();
......
......@@ -5,6 +5,10 @@ import static org.junit.Assert.assertTrue;
import com.ctrip.framework.apollo.BaseIntegrationTest;
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 org.junit.After;
import org.junit.Test;
......@@ -15,10 +19,7 @@ public class MetaDomainTest extends BaseIntegrationTest {
@After
public void tearDown() throws Exception {
super.tearDown();
System.clearProperty("fat_meta");
System.clearProperty("uat_meta");
System.clearProperty("lpt_meta");
System.clearProperty("apollo.meta");
MockMetaServerProvider.clear();
}
@Test
......@@ -28,16 +29,6 @@ public class MetaDomainTest extends BaseIntegrationTest {
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
public void testGetValidAddress() throws Exception {
String someResponse = "some response";
......@@ -46,10 +37,8 @@ public class MetaDomainTest extends BaseIntegrationTest {
String validServer = " http://localhost:" + PORT + " ";
String invalidServer = "http://localhost:" + findFreePort();
System.setProperty("fat_meta", validServer + "," + invalidServer);
System.setProperty("uat_meta", invalidServer + "," + validServer);
MetaDomainConsts.initialize();
MockMetaServerProvider.mock(Env.FAT, validServer + "," + invalidServer);
MockMetaServerProvider.mock(Env.UAT, invalidServer + "," + validServer);
assertEquals(validServer.trim(), MetaDomainConsts.getDomain(Env.FAT));
assertEquals(validServer.trim(), MetaDomainConsts.getDomain(Env.UAT));
......@@ -60,12 +49,33 @@ public class MetaDomainTest extends BaseIntegrationTest {
String invalidServer = "http://localhost:" + findFreePort() + " ";
String anotherInvalidServer = "http://localhost:" + findFreePort() + " ";
System.setProperty("lpt_meta", invalidServer + "," + anotherInvalidServer);
MetaDomainConsts.initialize();
MockMetaServerProvider.mock(Env.LPT, invalidServer + "," + anotherInvalidServer);
String metaServer = MetaDomainConsts.getDomain(Env.LPT);
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;
import com.ctrip.framework.foundation.internals.ServiceBootstrap;
import org.junit.Test;
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;
import com.ctrip.framework.apollo.common.dto.NamespaceDTO;
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.utils.StringUtils;
import com.ctrip.framework.apollo.openapi.entity.Consumer;
......@@ -90,7 +91,7 @@ public class ConsumerController {
if (Strings.isNullOrEmpty(env)) {
continue;
}
if (null == EnvUtils.transformEnv(env)) {
if (Env.UNKNOWN == EnvUtils.transformEnv(env)) {
throw new BadRequestException(String.format("env: %s is illegal", env));
}
envList.add(env);
......
......@@ -98,7 +98,7 @@ public class PermissionController {
public NamespaceEnvRolesAssignedUsers getNamespaceEnvRoles(@PathVariable String appId, @PathVariable String env, @PathVariable String namespaceName) {
// validate env parameter
if (null == EnvUtils.transformEnv(env)) {
if (Env.UNKNOWN == EnvUtils.transformEnv(env)) {
throw new BadRequestException("env is illegal");
}
......@@ -130,7 +130,7 @@ public class PermissionController {
}
// validate env parameter
if (null == EnvUtils.transformEnv(env)) {
if (Env.UNKNOWN == EnvUtils.transformEnv(env)) {
throw new BadRequestException("env is illegal");
}
Set<String> assignedUser = rolePermissionService.assignRoleToUsers(RoleUtils.buildNamespaceRoleName(appId, namespaceName, roleType, env),
......@@ -152,7 +152,7 @@ public class PermissionController {
throw new BadRequestException("role type is illegal");
}
// validate env parameter
if (null == EnvUtils.transformEnv(env)) {
if (Env.UNKNOWN == EnvUtils.transformEnv(env)) {
throw new BadRequestException("env is illegal");
}
rolePermissionService.removeRoleFromUsers(RoleUtils.buildNamespaceRoleName(appId, namespaceName, roleType, env),
......
......@@ -378,29 +378,6 @@
</execution>
</executions>
</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>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
......@@ -462,10 +439,6 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
......@@ -531,7 +504,6 @@
<filtering>true</filtering>
<includes>
<include>application-github.properties</include>
<include>apollo-env.properties</include>
</includes>
</resource>
<resource>
......@@ -539,7 +511,6 @@
<filtering>false</filtering>
<excludes>
<exclude>application-github.properties</exclude>
<exclude>apollo-env.properties</exclude>
</excludes>
</resource>
</resources>
......
......@@ -37,10 +37,4 @@ call mvn clean package -DskipTests -pl apollo-portal -am -Dapollo_profile=github
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
......@@ -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
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