diff --git a/apollo-adminservice/src/main/resources/application.yml b/apollo-adminservice/src/main/resources/application.yml index 45f90c9d44e41b2cbfead6e2d626cd297cb90894..4063c807fa4a5d0807a6b072882c7e03090c794f 100644 --- a/apollo-adminservice/src/main/resources/application.yml +++ b/apollo-adminservice/src/main/resources/application.yml @@ -3,10 +3,12 @@ spring: name: apollo-adminservice server: - port: ${port:8080} + port: ${port:23646} logging: level: org.springframework.cloud: 'DEBUG' file: /opt/logs/apollo-adminservice.log +ctrip: + appid: 100003172 diff --git a/apollo-client/pom.xml b/apollo-client/pom.xml index 5a2f3c4f3ea3216f3739e95b9a4e1eed4d30fc42..d80f9c606da21033f789c6f089466da8b40eea9a 100644 --- a/apollo-client/pom.xml +++ b/apollo-client/pom.xml @@ -39,13 +39,6 @@ guava - - - org.slf4j - slf4j-api - provided - - commons-logging diff --git a/apollo-client/src/main/java/com/ctrip/apollo/client/constants/Constants.java b/apollo-client/src/main/java/com/ctrip/apollo/client/constants/Constants.java index 249b80f3e07fbe780445d49fe3efafbf952d5a58..1328b60e1ab7e09f74c9c0cf8fc62bdb58f377a2 100644 --- a/apollo-client/src/main/java/com/ctrip/apollo/client/constants/Constants.java +++ b/apollo-client/src/main/java/com/ctrip/apollo/client/constants/Constants.java @@ -4,7 +4,8 @@ package com.ctrip.apollo.client.constants; * @author Jason Song(song_s@ctrip.com) */ public class Constants { - public static final String APP_ID = "appId"; + public static final String APP_ID = "app.id"; public static final String VERSION = "version"; public static final String DEFAULT_VERSION_NAME = "latest-release"; + public static final String ENV = "env"; } diff --git a/apollo-client/src/main/java/com/ctrip/apollo/client/env/ClientEnvironment.java b/apollo-client/src/main/java/com/ctrip/apollo/client/env/ClientEnvironment.java new file mode 100644 index 0000000000000000000000000000000000000000..808349d5a50473cdbb8dce81b0dab418464b6d26 --- /dev/null +++ b/apollo-client/src/main/java/com/ctrip/apollo/client/env/ClientEnvironment.java @@ -0,0 +1,100 @@ +package com.ctrip.apollo.client.env; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Enumeration; +import java.util.Properties; +import java.util.concurrent.atomic.AtomicReference; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.ctrip.apollo.Apollo; +import com.ctrip.apollo.Apollo.Env; +import com.ctrip.apollo.client.constants.Constants; +import com.ctrip.apollo.core.MetaDomainConsts; +import com.ctrip.apollo.core.utils.StringUtils; + +public class ClientEnvironment { + + private static final Logger logger = LoggerFactory.getLogger(ClientEnvironment.class); + + private final static String DEFAULT_FILE = "/apollo.properties"; + + private AtomicReference env = new AtomicReference(); + + private static ClientEnvironment instance = new ClientEnvironment(); + + private ClientEnvironment() { + + } + + public static ClientEnvironment getInstance() { + return instance; + } + + public Env getEnv() { + if (env.get() == null) { + Env resultEnv = Apollo.getEnv(); + Properties apolloProperties = null; + try { + apolloProperties = readConfigFile(DEFAULT_FILE, null); + } catch (IOException e) { + throw new IllegalArgumentException("Could not read Apollo properties"); + } + if (apolloProperties != null) { + String strEnv = apolloProperties.getProperty(Constants.ENV); + if (!StringUtils.isBlank(strEnv)) { + resultEnv = Env.valueOf(strEnv.trim().toUpperCase()); + } + } + env.compareAndSet(null, resultEnv); + } + + if (env.get() == null) { + throw new IllegalArgumentException("Apollo env is not set"); + } + + return env.get(); + } + + public String getMetaServerDomainName() { + return MetaDomainConsts.getDomain(getEnv()); + } + + @SuppressWarnings("unchecked") + private Properties readConfigFile(String configPath, Properties defaults) throws IOException { + InputStream in = this.getClass().getResourceAsStream(configPath); + logger.info("Reading config from resource {}", configPath); + if (in == null) { + // load outside resource under current user path + Path path = new File(System.getProperty("user.dir") + configPath).toPath(); + if (Files.isReadable(path)) { + in = new FileInputStream(path.toFile()); + logger.info("Reading config from file {} ", path); + } + } + Properties props = new Properties(); + if (defaults != null) { + props.putAll(defaults); + } + + if (in != null) { + props.load(in); + } + + StringBuilder sb = new StringBuilder(); + for (Enumeration e = (Enumeration) props.propertyNames(); e + .hasMoreElements();) { + String key = e.nextElement(); + String val = (String) props.getProperty(key); + sb.append(key).append('=').append(val).append('\n'); + } + logger.info("Reading properties: \n" + sb.toString()); + return props; + } +} diff --git a/apollo-client/src/main/java/com/ctrip/apollo/client/loader/ConfigLoaderFactory.java b/apollo-client/src/main/java/com/ctrip/apollo/client/loader/ConfigLoaderFactory.java index b09db152942855cad7a50803cd958905b5fc0833..6e872cca02336f77dac97965ec7019da6403fef2 100644 --- a/apollo-client/src/main/java/com/ctrip/apollo/client/loader/ConfigLoaderFactory.java +++ b/apollo-client/src/main/java/com/ctrip/apollo/client/loader/ConfigLoaderFactory.java @@ -2,6 +2,8 @@ package com.ctrip.apollo.client.loader; import com.ctrip.apollo.client.loader.impl.InMemoryConfigLoader; import com.ctrip.apollo.client.loader.impl.LocalFileConfigLoader; +import com.ctrip.apollo.Apollo.Env; +import com.ctrip.apollo.client.env.ClientEnvironment; import com.ctrip.apollo.client.loader.impl.RemoteConfigLoader; import com.ctrip.apollo.client.util.ConfigUtil; import org.springframework.web.client.RestTemplate; @@ -10,14 +12,13 @@ import org.springframework.web.client.RestTemplate; * @author Jason Song(song_s@ctrip.com) */ public class ConfigLoaderFactory { - private static ConfigLoaderFactory configLoaderFactory = new ConfigLoaderFactory(); + private static ConfigLoaderFactory configLoaderFactory = new ConfigLoaderFactory(); - private ConfigLoaderFactory() { - } + private ConfigLoaderFactory() {} - public static ConfigLoaderFactory getInstance() { - return configLoaderFactory; - } + public static ConfigLoaderFactory getInstance() { + return configLoaderFactory; + } public ConfigLoader getLocalFileConfigLoader() { ConfigLoader configLoader = new LocalFileConfigLoader(); @@ -31,12 +32,17 @@ public class ConfigLoaderFactory { } public ConfigLoader getRemoteConfigLoader() { - ConfigLoader remoteConfigLoader = new RemoteConfigLoader(new RestTemplate(), ConfigUtil.getInstance()); + ConfigLoader remoteConfigLoader = new RemoteConfigLoader(new RestTemplate(), ConfigUtil.getInstance(), new ConfigServiceLocator()); // remoteConfigLoader.setFallBackLoader(getInMemoryConfigLoader()); return remoteConfigLoader; } public ConfigLoaderManager getConfigLoaderManager() { + ClientEnvironment env = ClientEnvironment.getInstance(); + if (env.getEnv().equals(Env.LOCAL)) { + return new ConfigLoaderManager(getLocalFileConfigLoader(), ConfigUtil.getInstance()); + } else { return new ConfigLoaderManager(getRemoteConfigLoader(), ConfigUtil.getInstance()); + } } } diff --git a/apollo-client/src/main/java/com/ctrip/apollo/client/loader/ConfigServiceLocator.java b/apollo-client/src/main/java/com/ctrip/apollo/client/loader/ConfigServiceLocator.java new file mode 100644 index 0000000000000000000000000000000000000000..e2bf7de46dd1cb6635df9ba6ff1d93bd2b07060e --- /dev/null +++ b/apollo-client/src/main/java/com/ctrip/apollo/client/loader/ConfigServiceLocator.java @@ -0,0 +1,39 @@ +package com.ctrip.apollo.client.loader; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.client.RestTemplate; + +import com.ctrip.apollo.client.env.ClientEnvironment; +import com.ctrip.apollo.core.serivce.ApolloService; + +public class ConfigServiceLocator { + + private static final Logger logger = LoggerFactory.getLogger(ConfigServiceLocator.class); + + private RestTemplate restTemplate = new RestTemplate(); + + private List serviceCaches = new ArrayList<>(); + + public List getConfigServices() { + ClientEnvironment env = ClientEnvironment.getInstance(); + String domainName = env.getMetaServerDomainName(); + String url = domainName + "/services/config"; + try { + ApolloService[] services = restTemplate.getForObject(new URI(url), ApolloService[].class); + if (services != null && services.length > 0) { + serviceCaches.clear(); + for (ApolloService service : services) { + serviceCaches.add(service); + } + } + } catch (Exception e) { + logger.warn(e.getMessage()); + } + return serviceCaches; + } +} diff --git a/apollo-client/src/main/java/com/ctrip/apollo/client/loader/impl/RemoteConfigLoader.java b/apollo-client/src/main/java/com/ctrip/apollo/client/loader/impl/RemoteConfigLoader.java index d95fee41d4a51826b2b644594d05bbffd5de816f..15ac7cd5d7a73b5fd056695919f118d2e9acbc1a 100644 --- a/apollo-client/src/main/java/com/ctrip/apollo/client/loader/impl/RemoteConfigLoader.java +++ b/apollo-client/src/main/java/com/ctrip/apollo/client/loader/impl/RemoteConfigLoader.java @@ -1,8 +1,10 @@ package com.ctrip.apollo.client.loader.impl; +import com.ctrip.apollo.client.loader.ConfigServiceLocator; import com.ctrip.apollo.client.model.ApolloRegistry; import com.ctrip.apollo.client.util.ConfigUtil; import com.ctrip.apollo.core.dto.ApolloConfig; +import com.ctrip.apollo.core.serivce.ApolloService; import com.google.common.collect.Maps; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -13,6 +15,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.util.StringUtils; import org.springframework.web.client.RestTemplate; +import java.util.List; import java.util.Map; /** @@ -24,10 +27,12 @@ public class RemoteConfigLoader extends AbstractConfigLoader { private static final Logger logger = LoggerFactory.getLogger(RemoteConfigLoader.class); private final RestTemplate restTemplate; private final ConfigUtil configUtil; - - public RemoteConfigLoader(RestTemplate restTemplate, ConfigUtil configUtil) { + private final ConfigServiceLocator serviceLocator; + + public RemoteConfigLoader(RestTemplate restTemplate, ConfigUtil configUtil, ConfigServiceLocator locator) { this.restTemplate = restTemplate; this.configUtil = configUtil; + this.serviceLocator = locator; } ApolloConfig getRemoteConfig(RestTemplate restTemplate, String uri, String cluster, ApolloRegistry apolloRegistry, ApolloConfig previousConfig) { @@ -78,9 +83,17 @@ public class RemoteConfigLoader extends AbstractConfigLoader { @Override protected ApolloConfig doLoadApolloConfig(ApolloRegistry apolloRegistry, ApolloConfig previous) { ApolloConfig result = this.getRemoteConfig(restTemplate, - configUtil.getConfigServerUrl(), configUtil.getCluster(), + getConfigServiceUrl(), configUtil.getCluster(), apolloRegistry, previous); //When remote server return 304, we need to return the previous result return result == null ? previous : result; } -} + + private String getConfigServiceUrl() { + List services = serviceLocator.getConfigServices(); + if(services.size()==0){ + throw new RuntimeException("No available config service"); + } + return services.get(0).getHomepageUrl(); + } +} \ No newline at end of file diff --git a/apollo-client/src/main/java/com/ctrip/apollo/client/util/ConfigUtil.java b/apollo-client/src/main/java/com/ctrip/apollo/client/util/ConfigUtil.java index 81a7c857402caf7e67900890f78461ec94fa8a8b..65a11793e1df9225720fed0509b8b8bee65aa56a 100644 --- a/apollo-client/src/main/java/com/ctrip/apollo/client/util/ConfigUtil.java +++ b/apollo-client/src/main/java/com/ctrip/apollo/client/util/ConfigUtil.java @@ -23,7 +23,7 @@ public class ConfigUtil { public static final String APOLLO_PROPERTY = "apollo.properties"; private static ConfigUtil configUtil = new ConfigUtil(); private ApplicationContext applicationContext; - + private ConfigUtil() { } @@ -31,11 +31,6 @@ public class ConfigUtil { return configUtil; } - public String getConfigServerUrl() { - // TODO return the meta server url based on different environments - return "http://localhost"; - } - public String getCluster() { // TODO return the actual cluster return "default"; diff --git a/apollo-client/src/main/resources/apollo.properties b/apollo-client/src/main/resources/apollo.properties index f98824aeeafde51e1d19cc65c55f5be97f88ebb5..36299ed57b5863ef453c5c2dc09773e62ad9abf1 100644 --- a/apollo-client/src/main/resources/apollo.properties +++ b/apollo-client/src/main/resources/apollo.properties @@ -1,2 +1,3 @@ -appId=101 +app.id=101 version=1.0 +env=local \ No newline at end of file diff --git a/apollo-client/src/test/java/com/ctrip/apollo/client/loader/impl/RemoteConfigLoaderTest.java b/apollo-client/src/test/java/com/ctrip/apollo/client/loader/impl/RemoteConfigLoaderTest.java index 5a5ed517f4ca46a7e7dc544f30ec663da2bbba2f..74de357738c92f9df375258e3b85ee2816fa5ecb 100644 --- a/apollo-client/src/test/java/com/ctrip/apollo/client/loader/impl/RemoteConfigLoaderTest.java +++ b/apollo-client/src/test/java/com/ctrip/apollo/client/loader/impl/RemoteConfigLoaderTest.java @@ -1,29 +1,35 @@ package com.ctrip.apollo.client.loader.impl; -import com.ctrip.apollo.client.model.ApolloRegistry; -import com.ctrip.apollo.client.util.ConfigUtil; -import com.ctrip.apollo.core.dto.ApolloConfig; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyMap; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.List; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.MapPropertySource; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.*; +import com.ctrip.apollo.client.loader.ConfigServiceLocator; +import com.ctrip.apollo.client.model.ApolloRegistry; +import com.ctrip.apollo.client.util.ConfigUtil; +import com.ctrip.apollo.core.dto.ApolloConfig; +import com.ctrip.apollo.core.serivce.ApolloService; /** * @author Jason Song(song_s@ctrip.com) @@ -35,12 +41,14 @@ public class RemoteConfigLoaderTest { private RestTemplate restTemplate; private ConfigUtil configUtil; @Mock + private ConfigServiceLocator serviceLocater; + @Mock private ResponseEntity someResponse; @Before public void setUp() { configUtil = spy(ConfigUtil.getInstance()); - remoteConfigLoader = spy(new RemoteConfigLoader(restTemplate, configUtil)); + remoteConfigLoader = spy(new RemoteConfigLoader(restTemplate, configUtil, serviceLocater)); } @Test @@ -52,7 +60,12 @@ public class RemoteConfigLoaderTest { ApolloRegistry apolloRegistry = assembleSomeApolloRegistry(someAppId, "someVersion"); ApolloConfig previousConfig = null; - when(configUtil.getConfigServerUrl()).thenReturn(someServerUrl); + + ApolloService someService = new ApolloService(); + someService.setHomepageUrl(someServerUrl); + List someServices = new ArrayList<>(); + someServices.add(someService); + when(serviceLocater.getConfigServices()).thenReturn(someServices); when(configUtil.getCluster()).thenReturn(someCluster); doReturn(apolloConfig).when(remoteConfigLoader) .getRemoteConfig(restTemplate, someServerUrl, someCluster, apolloRegistry, previousConfig); @@ -115,7 +128,6 @@ public class RemoteConfigLoaderTest { ApolloConfig result = remoteConfigLoader.getRemoteConfig(restTemplate, someServerUrl, someClusterName, apolloRegistry, previousConfig); assertNull(result); - } private ApolloRegistry assembleSomeApolloRegistry(long someAppId, String someVersion) { diff --git a/apollo-configservice/src/main/java/com/ctrip/apollo/metaservice/controller/ServiceController.java b/apollo-configservice/src/main/java/com/ctrip/apollo/metaservice/controller/ServiceController.java index 90228653dda02594767c89905e9e30c80e407b8b..7a9526eb72fd268522ee4df26e22192928ca4186 100644 --- a/apollo-configservice/src/main/java/com/ctrip/apollo/metaservice/controller/ServiceController.java +++ b/apollo-configservice/src/main/java/com/ctrip/apollo/metaservice/controller/ServiceController.java @@ -1,11 +1,13 @@ package com.ctrip.apollo.metaservice.controller; +import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import com.ctrip.apollo.core.serivce.ApolloService; import com.ctrip.apollo.metaservice.service.DiscoveryService; import com.netflix.appinfo.InstanceInfo; @@ -18,17 +20,44 @@ public class ServiceController { @RequestMapping("/meta") - public List getMetaService() { - return discoveryService.getMetaServiceInstances(); + public List getMetaService() { + List instances = discoveryService.getMetaServiceInstances(); + List result = new ArrayList(); + for (InstanceInfo instance : instances) { + ApolloService service = new ApolloService(); + service.setAppName(instance.getAppName()); + service.setInstanceId(instance.getInstanceId()); + service.setHomepageUrl(instance.getHomePageUrl()); + result.add(service); + } + return result; } @RequestMapping("/config") - public List getConfigService() { - return discoveryService.getConfigServiceInstances(); + public List getConfigService() { + List instances = discoveryService.getConfigServiceInstances(); + List result = new ArrayList(); + for (InstanceInfo instance : instances) { + ApolloService service = new ApolloService(); + service.setAppName(instance.getAppName()); + service.setInstanceId(instance.getInstanceId()); + service.setHomepageUrl(instance.getHomePageUrl()); + result.add(service); + } + return result; } - + @RequestMapping("/admin") - public List getAdminService(){ - return discoveryService.getAdminServiceInstances(); + public List getAdminService() { + List instances = discoveryService.getAdminServiceInstances(); + List result = new ArrayList(); + for (InstanceInfo instance : instances) { + ApolloService service = new ApolloService(); + service.setAppName(instance.getAppName()); + service.setInstanceId(instance.getInstanceId()); + service.setHomepageUrl(instance.getHomePageUrl()); + result.add(service); + } + return result; } } diff --git a/apollo-configservice/src/main/java/com/ctrip/apollo/metaservice/service/DiscoveryService.java b/apollo-configservice/src/main/java/com/ctrip/apollo/metaservice/service/DiscoveryService.java index 56bc2995f684a04cc654396f598436657114ee16..cf15018904ef8dd15f8aabda63697bd8f81d8285 100644 --- a/apollo-configservice/src/main/java/com/ctrip/apollo/metaservice/service/DiscoveryService.java +++ b/apollo-configservice/src/main/java/com/ctrip/apollo/metaservice/service/DiscoveryService.java @@ -6,7 +6,7 @@ import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import com.ctrip.apollo.core.ServiceIdConsts; +import com.ctrip.apollo.core.ServiceNameConsts; import com.netflix.appinfo.InstanceInfo; import com.netflix.discovery.EurekaClient; import com.netflix.discovery.shared.Application; @@ -18,17 +18,17 @@ public class DiscoveryService { private EurekaClient eurekaClient; public List getConfigServiceInstances() { - Application application = eurekaClient.getApplication(ServiceIdConsts.APOLLO_CONFIGSERVICE); + Application application = eurekaClient.getApplication(ServiceNameConsts.APOLLO_CONFIGSERVICE); return application != null ? application.getInstances() : new ArrayList<>(); } public List getMetaServiceInstances() { - Application application = eurekaClient.getApplication(ServiceIdConsts.APOLLO_METASERVICE); + Application application = eurekaClient.getApplication(ServiceNameConsts.APOLLO_METASERVICE); return application != null ? application.getInstances() : new ArrayList<>(); } public List getAdminServiceInstances(){ - Application application = eurekaClient.getApplication(ServiceIdConsts.APOLLO_ADMINSERVICE); + Application application = eurekaClient.getApplication(ServiceNameConsts.APOLLO_ADMINSERVICE); return application != null ? application.getInstances() : new ArrayList<>(); } } diff --git a/apollo-configservice/src/main/resources/application.yml b/apollo-configservice/src/main/resources/application.yml index fd046ff8efbe44e92aa97143fc09aa4f254e1611..34033d34020d09682e91a3ac096bf9f89ee2499a 100644 --- a/apollo-configservice/src/main/resources/application.yml +++ b/apollo-configservice/src/main/resources/application.yml @@ -3,10 +3,12 @@ spring: name: apollo-configservice server: - port: ${port:80} + port: ${port:2756} logging: level: org.springframework.cloud: 'DEBUG' file: /opt/logs/apollo-configservice.log +ctrip: + appid: 100003171 \ No newline at end of file diff --git a/apollo-core/pom.xml b/apollo-core/pom.xml index 8bcba3a9d5da8a6847b95d29e56e1d6b60960b5f..d7800c69982061f1dfb6087833453ba256a31ed7 100644 --- a/apollo-core/pom.xml +++ b/apollo-core/pom.xml @@ -29,5 +29,11 @@ guava + + + org.slf4j + slf4j-api + + diff --git a/apollo-core/src/main/java/com/ctrip/apollo/Apollo.java b/apollo-core/src/main/java/com/ctrip/apollo/Apollo.java new file mode 100644 index 0000000000000000000000000000000000000000..8c27ebde21026d90eabe28bec67485951f52927c --- /dev/null +++ b/apollo-core/src/main/java/com/ctrip/apollo/Apollo.java @@ -0,0 +1,21 @@ +package com.ctrip.apollo; + +public class Apollo { + + public final static String VERSION = "java-0.0.1-SNAPSHOT"; + + private static Env m_env; + + public enum Env { + LOCAL, DEV, FWS, FAT, UAT, LPT, PROD, TOOLS + } + + public static void initialize(Env env) { + m_env = env; + } + + public static Env getEnv() { + return m_env; + } + +} diff --git a/apollo-core/src/main/java/com/ctrip/apollo/core/MetaDomainConsts.java b/apollo-core/src/main/java/com/ctrip/apollo/core/MetaDomainConsts.java new file mode 100644 index 0000000000000000000000000000000000000000..60c1edf327c5674629d2aebac1c1eac9b273b7e4 --- /dev/null +++ b/apollo-core/src/main/java/com/ctrip/apollo/core/MetaDomainConsts.java @@ -0,0 +1,42 @@ +package com.ctrip.apollo.core; + +import java.util.HashMap; +import java.util.Map; + +import com.ctrip.apollo.Apollo.Env; + +public class MetaDomainConsts { + + public static final String LOCAL = "http://localhost"; + + public static final String DEV = "http://ws.meta.apollo.fx.dev.nt.ctripcorp.com"; + + public static final String FAT = "http://ws.meta.apollo.fx.fat.nt.ctripcorp.com";; + + public static final String FWS = "http://ws.meta.apollo.fx.fws.nt.ctripcorp.com"; + + public static final String UAT = "http://ws.meta.apollo.fx.uat.nt.ctripcorp.com"; + + public static final String LPT = "http://ws.meta.apollo.fx.lpt.nt.ctripcorp.com"; + + public static final String TOOLS = "http://ws.meta.apollo.fx.tools.ctripcorp.com"; + + public static final String PRD = "http://ws.meta.apollo.fx.ctripcorp.com"; + + private static Map domains = new HashMap<>(); + + static { + domains.put(Env.LOCAL, LOCAL); + domains.put(Env.DEV, DEV); + domains.put(Env.FAT, FAT); + domains.put(Env.FWS, FWS); + domains.put(Env.UAT, UAT); + domains.put(Env.LPT, LPT); + domains.put(Env.TOOLS, TOOLS); + domains.put(Env.PROD, PRD); + } + + public static String getDomain(Env env) { + return domains.get(env); + } +} diff --git a/apollo-core/src/main/java/com/ctrip/apollo/core/ServiceIdConsts.java b/apollo-core/src/main/java/com/ctrip/apollo/core/ServiceNameConsts.java similarity index 90% rename from apollo-core/src/main/java/com/ctrip/apollo/core/ServiceIdConsts.java rename to apollo-core/src/main/java/com/ctrip/apollo/core/ServiceNameConsts.java index e5f0bdba7d0ebc0633c1180a04c319f6fdfae14c..744f24c815e15063914700ae0611aed83eb2210b 100644 --- a/apollo-core/src/main/java/com/ctrip/apollo/core/ServiceIdConsts.java +++ b/apollo-core/src/main/java/com/ctrip/apollo/core/ServiceNameConsts.java @@ -1,6 +1,6 @@ package com.ctrip.apollo.core; -public class ServiceIdConsts { +public class ServiceNameConsts { public static final String APOLLO_METASERVICE = "apollo-metaservice"; diff --git a/apollo-core/src/main/java/com/ctrip/apollo/core/serivce/ApolloService.java b/apollo-core/src/main/java/com/ctrip/apollo/core/serivce/ApolloService.java new file mode 100644 index 0000000000000000000000000000000000000000..23deff08dec063d06f3fbc693c692e23b5901585 --- /dev/null +++ b/apollo-core/src/main/java/com/ctrip/apollo/core/serivce/ApolloService.java @@ -0,0 +1,34 @@ +package com.ctrip.apollo.core.serivce; + +public class ApolloService { + + private String appName; + + private String instanceId; + + private String homepageUrl; + + public String getAppName() { + return appName; + } + + public String getHomepageUrl() { + return homepageUrl; + } + + public String getInstanceId() { + return instanceId; + } + + public void setAppName(String appName) { + this.appName = appName; + } + + public void setHomepageUrl(String homepageUrl) { + this.homepageUrl = homepageUrl; + } + + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } +} diff --git a/apollo-core/src/main/java/com/ctrip/apollo/core/utils/ApolloThreadFactory.java b/apollo-core/src/main/java/com/ctrip/apollo/core/utils/ApolloThreadFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..da36a2a5946e29161ca87c9cc07d8c4bcbe88296 --- /dev/null +++ b/apollo-core/src/main/java/com/ctrip/apollo/core/utils/ApolloThreadFactory.java @@ -0,0 +1,91 @@ +package com.ctrip.apollo.core.utils; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ApolloThreadFactory implements ThreadFactory { + private static Logger log = LoggerFactory.getLogger(ApolloThreadFactory.class); + + private final AtomicLong m_threadNumber = new AtomicLong(1); + + private final String m_namePrefix; + + private final boolean m_daemon; + + private final static ThreadGroup m_threadGroup = new ThreadGroup("Apollo"); + + public static ThreadGroup getThreadGroup() { + return m_threadGroup; + } + + public static ThreadFactory create(String namePrefix, boolean daemon) { + return new ApolloThreadFactory(namePrefix, daemon); + } + + public static boolean waitAllShutdown(int timeoutInMillis) { + ThreadGroup group = getThreadGroup(); + Thread[] activeThreads = new Thread[group.activeCount()]; + group.enumerate(activeThreads); + Set alives = new HashSet(Arrays.asList(activeThreads)); + Set dies = new HashSet(); + log.info("Current ACTIVE thread count is: {}", alives.size()); + long expire = System.currentTimeMillis() + timeoutInMillis; + while (System.currentTimeMillis() < expire) { + classify(alives, dies, new ClassifyStandard() { + @Override + public boolean satisfy(Thread t) { + return !t.isAlive() || t.isInterrupted() || t.isDaemon(); + } + }); + if (alives.size() > 0) { + log.info("Alive apollo threads: {}", alives); + try { + TimeUnit.SECONDS.sleep(2); + } catch (InterruptedException e) { + // ignore + } + } else { + log.info("All apollo threads are shutdown."); + return true; + } + } + log.warn("Some apollo threads are still alive but expire time has reached, alive threads: {}", alives); + return false; + } + + private static interface ClassifyStandard { + boolean satisfy(T t); + } + + private static void classify(Set src, Set des, ClassifyStandard standard) { + Set s = new HashSet<>(); + for (T t : src) { + if (standard.satisfy(t)) { + s.add(t); + } + } + src.removeAll(s); + des.addAll(s); + } + + private ApolloThreadFactory(String namePrefix, boolean daemon) { + m_namePrefix = namePrefix; + m_daemon = daemon; + } + + public Thread newThread(Runnable r) { + Thread t = new Thread(m_threadGroup, r,// + m_threadGroup.getName() + "-" + m_namePrefix + "-" + m_threadNumber.getAndIncrement()); + t.setDaemon(m_daemon); + if (t.getPriority() != Thread.NORM_PRIORITY) + t.setPriority(Thread.NORM_PRIORITY); + return t; + } +} diff --git a/apollo-core/src/main/java/com/ctrip/apollo/core/utils/DNSUtil.java b/apollo-core/src/main/java/com/ctrip/apollo/core/utils/DNSUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..89f8ea1eb1015d795c68163f6a3762b677736885 --- /dev/null +++ b/apollo-core/src/main/java/com/ctrip/apollo/core/utils/DNSUtil.java @@ -0,0 +1,23 @@ +package com.ctrip.apollo.core.utils; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; + +public class DNSUtil { + + public static List resolve(String domainName) throws UnknownHostException { + List result = new ArrayList(); + + InetAddress[] addresses = InetAddress.getAllByName(domainName); + if (addresses != null) { + for (InetAddress addr : addresses) { + result.add(addr.getHostAddress()); + } + } + + return result; + } + +} diff --git a/apollo-core/src/main/java/com/ctrip/apollo/core/utils/StringUtils.java b/apollo-core/src/main/java/com/ctrip/apollo/core/utils/StringUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..e596973cef91ada6e016335851ef836dd910c6dd --- /dev/null +++ b/apollo-core/src/main/java/com/ctrip/apollo/core/utils/StringUtils.java @@ -0,0 +1,373 @@ +package com.ctrip.apollo.core.utils; + +import java.util.Collection; +import java.util.Iterator; + +public class StringUtils { + + public static final String EMPTY = ""; + + /** + *

+ * Checks if a String is empty ("") or null. + *

+ * + *
+	 * StringUtils.isEmpty(null)      = true
+	 * StringUtils.isEmpty("")        = true
+	 * StringUtils.isEmpty(" ")       = false
+	 * StringUtils.isEmpty("bob")     = false
+	 * StringUtils.isEmpty("  bob  ") = false
+	 * 
+ * + *

+ * NOTE: This method changed in Lang version 2.0. It no longer trims the String. That functionality is available in isBlank(). + *

+ * + * @param str + * the String to check, may be null + * @return true if the String is empty or null + */ + public static boolean isEmpty(String str) { + return str == null || str.length() == 0; + } + + /** + *

+ * Checks if a String is whitespace, empty ("") or null. + *

+ * + *
+	 * StringUtils.isBlank(null)      = true
+	 * StringUtils.isBlank("")        = true
+	 * StringUtils.isBlank(" ")       = true
+	 * StringUtils.isBlank("bob")     = false
+	 * StringUtils.isBlank("  bob  ") = false
+	 * 
+ * + * @param str + * the String to check, may be null + * @return true if the String is null, empty or whitespace + */ + public static boolean isBlank(String str) { + int strLen; + if (str == null || (strLen = str.length()) == 0) { + return true; + } + for (int i = 0; i < strLen; i++) { + if ((Character.isWhitespace(str.charAt(i)) == false)) { + return false; + } + } + return true; + } + + /** + *

+ * Removes control characters (char <= 32) from both ends of this String returning null if the String is empty + * ("") after the trim or if it is null. + * + *

+ * The String is trimmed using {@link String#trim()}. Trim removes start and end characters <= 32. To strip whitespace use + * {@link #stripToNull(String)}. + *

+ * + *
+	 * StringUtils.trimToNull(null)          = null
+	 * StringUtils.trimToNull("")            = null
+	 * StringUtils.trimToNull("     ")       = null
+	 * StringUtils.trimToNull("abc")         = "abc"
+	 * StringUtils.trimToNull("    abc    ") = "abc"
+	 * 
+ * + * @param str + * the String to be trimmed, may be null + * @return the trimmed String, null if only chars <= 32, empty or null String input + * @since 2.0 + */ + public static String trimToNull(String str) { + String ts = trim(str); + return isEmpty(ts) ? null : ts; + } + + /** + *

+ * Removes control characters (char <= 32) from both ends of this String returning an empty String ("") if the String is empty + * ("") after the trim or if it is null. + * + *

+ * The String is trimmed using {@link String#trim()}. Trim removes start and end characters <= 32. To strip whitespace use + * {@link #stripToEmpty(String)}. + *

+ * + *
+	 * StringUtils.trimToEmpty(null)          = ""
+	 * StringUtils.trimToEmpty("")            = ""
+	 * StringUtils.trimToEmpty("     ")       = ""
+	 * StringUtils.trimToEmpty("abc")         = "abc"
+	 * StringUtils.trimToEmpty("    abc    ") = "abc"
+	 * 
+ * + * @param str + * the String to be trimmed, may be null + * @return the trimmed String, or an empty String if null input + * @since 2.0 + */ + public static String trimToEmpty(String str) { + return str == null ? EMPTY : str.trim(); + } + + /** + *

+ * Removes control characters (char <= 32) from both ends of this String, handling null by returning + * null. + *

+ * + *

+ * The String is trimmed using {@link String#trim()}. Trim removes start and end characters <= 32. To strip whitespace use + * {@link #strip(String)}. + *

+ * + *

+ * To trim your choice of characters, use the {@link #strip(String, String)} methods. + *

+ * + *
+	 * StringUtils.trim(null)          = null
+	 * StringUtils.trim("")            = ""
+	 * StringUtils.trim("     ")       = ""
+	 * StringUtils.trim("abc")         = "abc"
+	 * StringUtils.trim("    abc    ") = "abc"
+	 * 
+ * + * @param str + * the String to be trimmed, may be null + * @return the trimmed string, null if null String input + */ + public static String trim(String str) { + return str == null ? null : str.trim(); + } + + /** + *

+ * Compares two Strings, returning true if they are equal. + *

+ * + *

+ * nulls are handled without exceptions. Two null references are considered to be equal. The comparison + * is case sensitive. + *

+ * + *
+	 * StringUtils.equals(null, null)   = true
+	 * StringUtils.equals(null, "abc")  = false
+	 * StringUtils.equals("abc", null)  = false
+	 * StringUtils.equals("abc", "abc") = true
+	 * StringUtils.equals("abc", "ABC") = false
+	 * 
+ * + * @see java.lang.String#equals(Object) + * @param str1 + * the first String, may be null + * @param str2 + * the second String, may be null + * @return true if the Strings are equal, case sensitive, or both null + */ + public static boolean equals(String str1, String str2) { + return str1 == null ? str2 == null : str1.equals(str2); + } + + /** + *

+ * Compares two Strings, returning true if they are equal ignoring the case. + *

+ * + *

+ * nulls are handled without exceptions. Two null references are considered equal. Comparison is case + * insensitive. + *

+ * + *
+	 * StringUtils.equalsIgnoreCase(null, null)   = true
+	 * StringUtils.equalsIgnoreCase(null, "abc")  = false
+	 * StringUtils.equalsIgnoreCase("abc", null)  = false
+	 * StringUtils.equalsIgnoreCase("abc", "abc") = true
+	 * StringUtils.equalsIgnoreCase("abc", "ABC") = true
+	 * 
+ * + * @see java.lang.String#equalsIgnoreCase(String) + * @param str1 + * the first String, may be null + * @param str2 + * the second String, may be null + * @return true if the Strings are equal, case insensitive, or both null + */ + public static boolean equalsIgnoreCase(String str1, String str2) { + return str1 == null ? str2 == null : str1.equalsIgnoreCase(str2); + } + + /** + *

+ * Check if a String starts with a specified prefix. + *

+ * + *

+ * nulls are handled without exceptions. Two null references are considered to be equal. The comparison + * is case sensitive. + *

+ * + *
+	 * StringUtils.startsWith(null, null)      = true
+	 * StringUtils.startsWith(null, "abc")     = false
+	 * StringUtils.startsWith("abcdef", null)  = false
+	 * StringUtils.startsWith("abcdef", "abc") = true
+	 * StringUtils.startsWith("ABCDEF", "abc") = false
+	 * 
+ * + * @see java.lang.String#startsWith(String) + * @param str + * the String to check, may be null + * @param prefix + * the prefix to find, may be null + * @return true if the String starts with the prefix, case sensitive, or both null + * @since 2.4 + */ + public static boolean startsWith(String str, String prefix) { + return startsWith(str, prefix, false); + } + + /** + *

+ * Case insensitive check if a String starts with a specified prefix. + *

+ * + *

+ * nulls are handled without exceptions. Two null references are considered to be equal. The comparison + * is case insensitive. + *

+ * + *
+	 * StringUtils.startsWithIgnoreCase(null, null)      = true
+	 * StringUtils.startsWithIgnoreCase(null, "abc")     = false
+	 * StringUtils.startsWithIgnoreCase("abcdef", null)  = false
+	 * StringUtils.startsWithIgnoreCase("abcdef", "abc") = true
+	 * StringUtils.startsWithIgnoreCase("ABCDEF", "abc") = true
+	 * 
+ * + * @see java.lang.String#startsWith(String) + * @param str + * the String to check, may be null + * @param prefix + * the prefix to find, may be null + * @return true if the String starts with the prefix, case insensitive, or both null + * @since 2.4 + */ + public static boolean startsWithIgnoreCase(String str, String prefix) { + return startsWith(str, prefix, true); + } + + /** + *

+ * Checks if the String contains only unicode digits. A decimal point is not a unicode digit and returns false. + *

+ * + *

+ * null will return false. An empty String (length()=0) will return true. + *

+ * + *
+	 * StringUtils.isNumeric(null)   = false
+	 * StringUtils.isNumeric("")     = true
+	 * StringUtils.isNumeric("  ")   = false
+	 * StringUtils.isNumeric("123")  = true
+	 * StringUtils.isNumeric("12 3") = false
+	 * StringUtils.isNumeric("ab2c") = false
+	 * StringUtils.isNumeric("12-3") = false
+	 * StringUtils.isNumeric("12.3") = false
+	 * 
+ * + * @param str + * the String to check, may be null + * @return true if only contains digits, and is non-null + */ + public static boolean isNumeric(String str) { + if (str == null) { + return false; + } + int sz = str.length(); + for (int i = 0; i < sz; i++) { + if (Character.isDigit(str.charAt(i)) == false) { + return false; + } + } + return true; + } + + /** + *

+ * Check if a String starts with a specified prefix (optionally case insensitive). + *

+ * + * @see java.lang.String#startsWith(String) + * @param str + * the String to check, may be null + * @param prefix + * the prefix to find, may be null + * @param ignoreCase + * inidicates whether the compare should ignore case (case insensitive) or not. + * @return true if the String starts with the prefix or both null + */ + private static boolean startsWith(String str, String prefix, boolean ignoreCase) { + if (str == null || prefix == null) { + return (str == null && prefix == null); + } + if (prefix.length() > str.length()) { + return false; + } + return str.regionMatches(ignoreCase, 0, prefix, 0, prefix.length()); + } + + public static interface StringFormatter { + public String format(T obj); + } + + public static String join(Collection collection, String separator) { + return join(collection, separator, new StringFormatter() { + @Override + public String format(T obj) { + return obj.toString(); + } + }); + } + + public static String join(Collection collection, String separator, StringFormatter formatter) { + Iterator iterator = collection.iterator(); + // handle null, zero and one elements before building a buffer + if (iterator == null) { + return null; + } + if (!iterator.hasNext()) { + return EMPTY; + } + T first = iterator.next(); + if (!iterator.hasNext()) { + return first == null ? "" : formatter.format(first); + } + + // two or more elements + StringBuilder buf = new StringBuilder(256); // Java default is 16, probably too small + if (first != null) { + buf.append(formatter.format(first)); + } + + while (iterator.hasNext()) { + buf.append(separator); + T obj = iterator.next(); + if (obj != null) { + buf.append(formatter.format(obj)); + } + } + + return buf.toString(); + } +} diff --git a/apollo-portal/src/main/resources/application.yml b/apollo-portal/src/main/resources/application.yml index 6e79156ccdb424a4a96fbb2e35c42d2896ccd914..cb9e9397fffea59dd2d5f106620571b2c262880d 100644 --- a/apollo-portal/src/main/resources/application.yml +++ b/apollo-portal/src/main/resources/application.yml @@ -9,3 +9,5 @@ spring: username: sa password: sa +ctrip: + appid: 100003173 \ No newline at end of file