Unverified Commit 45290409 by wiston1988 Committed by GitHub

Merge pull request #1 from ctripcorp/master

new version
parents e7b9f0d6 7edfb1aa
...@@ -10,7 +10,7 @@ Apollo(配置中心) ...@@ -10,7 +10,7 @@ Apollo(配置中心)
</a> </a>
[![codecov.io](https://codecov.io/github/ctripcorp/apollo/coverage.svg?branch=master)](https://codecov.io/github/ctripcorp/apollo?branch=master) [![codecov.io](https://codecov.io/github/ctripcorp/apollo/coverage.svg?branch=master)](https://codecov.io/github/ctripcorp/apollo?branch=master)
Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置场景。 Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
服务端基于Spring Boot和Spring Cloud开发,打包后可以直接运行,不需要额外安装Tomcat等应用容器。 服务端基于Spring Boot和Spring Cloud开发,打包后可以直接运行,不需要额外安装Tomcat等应用容器。
...@@ -93,6 +93,9 @@ Java客户端不依赖任何框架,能够运行于所有Java运行时环境, ...@@ -93,6 +93,9 @@ Java客户端不依赖任何框架,能够运行于所有Java运行时环境,
* [携程开源配置中心Apollo的设计与实现](http://www.itdks.com/dakalive/detail/3420) * [携程开源配置中心Apollo的设计与实现](http://www.itdks.com/dakalive/detail/3420)
* [Slides](http://techshow.ctrip.com/wp-content/uploads/2017/08/%E5%BC%80%E6%BA%90%E9%85%8D%E7%BD%AE%E4%B8%AD%E5%BF%83Apollo%E7%9A%84%E8%AE%BE%E8%AE%A1%E4%B8%8E%E5%AE%9E%E7%8E%B0-%E6%90%BA%E7%A8%8B%E5%AE%8B%E9%A1%BA.pdf) * [Slides](http://techshow.ctrip.com/wp-content/uploads/2017/08/%E5%BC%80%E6%BA%90%E9%85%8D%E7%BD%AE%E4%B8%AD%E5%BF%83Apollo%E7%9A%84%E8%AE%BE%E8%AE%A1%E4%B8%8E%E5%AE%9E%E7%8E%B0-%E6%90%BA%E7%A8%8B%E5%AE%8B%E9%A1%BA.pdf)
# Publication
* [开源配置中心Apollo的设计与实现](http://www.infoq.com/cn/articles/open-source-configuration-center-apollo)
# Support # Support
![tech-support-qq](https://raw.githubusercontent.com/ctripcorp/apollo/master/doc/images/tech-support-qq.png) ![tech-support-qq](https://raw.githubusercontent.com/ctripcorp/apollo/master/doc/images/tech-support-qq.png)
...@@ -105,7 +108,7 @@ The project is licensed under the [Apache 2 license](https://github.com/ctripcor ...@@ -105,7 +108,7 @@ The project is licensed under the [Apache 2 license](https://github.com/ctripcor
# Known Users # Known Users
> 按照登记顺序排序,更多接入公司,欢迎在[https://github.com/ctripcorp/apollo/issues/451](https://github.com/ctripcorp/apollo/issues/451)登记 > 按照登记顺序排序,更多接入公司,欢迎在[https://github.com/ctripcorp/apollo/issues/451](https://github.com/ctripcorp/apollo/issues/451)登记(仅供开源用户参考)
![携程](https://github.com/ctripcorp/apollo/blob/master/doc/images/known-users/ctrip.png) ![携程](https://github.com/ctripcorp/apollo/blob/master/doc/images/known-users/ctrip.png)
![青石证券](https://github.com/ctripcorp/apollo/blob/master/doc/images/known-users/bluestone.png) ![青石证券](https://github.com/ctripcorp/apollo/blob/master/doc/images/known-users/bluestone.png)
...@@ -142,3 +145,8 @@ The project is licensed under the [Apache 2 license](https://github.com/ctripcor ...@@ -142,3 +145,8 @@ The project is licensed under the [Apache 2 license](https://github.com/ctripcor
![投投金融](https://github.com/ctripcorp/apollo/blob/master/doc/images/known-users/toutoujinrong.png) ![投投金融](https://github.com/ctripcorp/apollo/blob/master/doc/images/known-users/toutoujinrong.png)
![每天健康](https://github.com/ctripcorp/apollo/blob/master/doc/images/known-users/mytijian.png) ![每天健康](https://github.com/ctripcorp/apollo/blob/master/doc/images/known-users/mytijian.png)
![麦芽金服](https://github.com/ctripcorp/apollo/blob/master/doc/images/known-users/maiyabank.png) ![麦芽金服](https://github.com/ctripcorp/apollo/blob/master/doc/images/known-users/maiyabank.png)
![蜂向科技](https://github.com/ctripcorp/apollo/blob/master/doc/images/known-users/fengunion.png)
![即科金融](https://github.com/ctripcorp/apollo/blob/master/doc/images/known-users/geex-logo.png)
![贝壳网](https://github.com/ctripcorp/apollo/blob/master/doc/images/known-users/beike.png)
![有赞](https://github.com/ctripcorp/apollo/blob/master/doc/images/known-users/youzan.png)
![云集汇通](https://github.com/ctripcorp/apollo/blob/master/doc/images/known-users/yunjihuitong.png)
...@@ -59,7 +59,7 @@ public class ApolloSpringApplicationRunListener implements SpringApplicationRunL ...@@ -59,7 +59,7 @@ public class ApolloSpringApplicationRunListener implements SpringApplicationRunL
logger.debug("Apollo bootstrap config is not enabled for context {}, see property: ${{}}", context, PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED); logger.debug("Apollo bootstrap config is not enabled for context {}, see property: ${{}}", context, PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED);
return; return;
} }
logger.debug("Apollo bootstrap config is enabled for context {}", context, PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED); logger.debug("Apollo bootstrap config is enabled for context {}", context);
if (environment.getPropertySources().contains(PropertySourcesConstants.APOLLO_BOOTSTRAP_PROPERTY_SOURCE_NAME)) { if (environment.getPropertySources().contains(PropertySourcesConstants.APOLLO_BOOTSTRAP_PROPERTY_SOURCE_NAME)) {
//already initialized //already initialized
......
package com.ctrip.framework.apollo.spring.config; package com.ctrip.framework.apollo.spring.config;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import com.ctrip.framework.apollo.Config; import com.ctrip.framework.apollo.Config;
...@@ -31,7 +31,7 @@ import java.util.Iterator; ...@@ -31,7 +31,7 @@ import java.util.Iterator;
* @author Jason Song(song_s@ctrip.com) * @author Jason Song(song_s@ctrip.com)
*/ */
public class PropertySourcesProcessor implements BeanFactoryPostProcessor, EnvironmentAware, PriorityOrdered { public class PropertySourcesProcessor implements BeanFactoryPostProcessor, EnvironmentAware, PriorityOrdered {
private static final Multimap<Integer, String> NAMESPACE_NAMES = HashMultimap.create(); private static final Multimap<Integer, String> NAMESPACE_NAMES = LinkedHashMultimap.create();
private ConfigurableEnvironment environment; private ConfigurableEnvironment environment;
......
...@@ -96,6 +96,26 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest { ...@@ -96,6 +96,26 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest {
check(someTimeout, someBatch, AppConfig3.class); check(someTimeout, someBatch, AppConfig3.class);
} }
@Test
public void testMultiplePropertySourcesCoverWithSameProperties() throws Exception {
//Multimap does not maintain the strict input order of namespace.
int someTimeout = 1000;
int anotherTimeout = someTimeout + 1;
int someBatch = 2000;
Config fxApollo = mock(Config.class);
when(fxApollo.getProperty(eq(TIMEOUT_PROPERTY), anyString())).thenReturn(String.valueOf(someTimeout));
when(fxApollo.getProperty(eq(BATCH_PROPERTY), anyString())).thenReturn(String.valueOf(someBatch));
mockConfig(FX_APOLLO_NAMESPACE, fxApollo);
Config application = mock(Config.class);
when(application.getProperty(eq(TIMEOUT_PROPERTY), anyString())).thenReturn(String.valueOf(anotherTimeout));
mockConfig(ConfigConsts.NAMESPACE_APPLICATION, application);
check(someTimeout, someBatch, AppConfig6.class);
}
@Test @Test
public void testMultiplePropertySourcesWithSamePropertiesWithWeight() throws Exception { public void testMultiplePropertySourcesWithSamePropertiesWithWeight() throws Exception {
int someTimeout = 1000; int someTimeout = 1000;
...@@ -133,6 +153,112 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest { ...@@ -133,6 +153,112 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest {
assertEquals(someBatch, bean.getBatch()); assertEquals(someBatch, bean.getBatch());
} }
@Test
public void testNestedProperty() throws Exception {
String a = "a";
String b = "b";
int someValue = 1234;
Config config = mock(Config.class);
when(config.getProperty(eq(a), anyString())).thenReturn(a);
when(config.getProperty(eq(b), anyString())).thenReturn(b);
when(config.getProperty(eq(String.format("%s.%s", a, b)), anyString()))
.thenReturn(String.valueOf(someValue));
mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config);
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(NestedPropertyConfig1.class);
TestNestedPropertyBean bean = context.getBean(TestNestedPropertyBean.class);
assertEquals(someValue, bean.getNestedProperty());
}
@Test
public void testNestedPropertyWithDefaultValue() throws Exception {
String a = "a";
String b = "b";
String c = "c";
int someValue = 1234;
Config config = mock(Config.class);
when(config.getProperty(eq(a), anyString())).thenReturn(a);
when(config.getProperty(eq(b), anyString())).thenReturn(b);
when(config.getProperty(eq(c), anyString())).thenReturn(String.valueOf(someValue));
mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config);
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(NestedPropertyConfig1.class);
TestNestedPropertyBean bean = context.getBean(TestNestedPropertyBean.class);
assertEquals(someValue, bean.getNestedProperty());
}
@Test
public void testNestedPropertyWithNestedDefaultValue() throws Exception {
String a = "a";
String b = "b";
Config config = mock(Config.class);
when(config.getProperty(eq(a), anyString())).thenReturn(a);
when(config.getProperty(eq(b), anyString())).thenReturn(b);
mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config);
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(NestedPropertyConfig1.class);
TestNestedPropertyBean bean = context.getBean(TestNestedPropertyBean.class);
assertEquals(100, bean.getNestedProperty());
}
@Test
public void testMultipleNestedProperty() throws Exception {
String a = "a";
String b = "b";
String nestedKey = "c.d";
String nestedProperty = String.format("${%s}", nestedKey);
int someValue = 1234;
Config config = mock(Config.class);
when(config.getProperty(eq(a), anyString())).thenReturn(a);
when(config.getProperty(eq(b), anyString())).thenReturn(b);
when(config.getProperty(eq(String.format("%s.%s", a, b)), anyString())).thenReturn(nestedProperty);
when(config.getProperty(eq(nestedKey), anyString())).thenReturn(String.valueOf(someValue));
mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config);
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(NestedPropertyConfig1.class);
TestNestedPropertyBean bean = context.getBean(TestNestedPropertyBean.class);
assertEquals(someValue, bean.getNestedProperty());
}
@Test
public void testMultipleNestedPropertyWithDefaultValue() throws Exception {
String a = "a";
String b = "b";
String nestedKey = "c.d";
int someValue = 1234;
String nestedProperty = String.format("${%s:%d}", nestedKey, someValue);
Config config = mock(Config.class);
when(config.getProperty(eq(a), anyString())).thenReturn(a);
when(config.getProperty(eq(b), anyString())).thenReturn(b);
when(config.getProperty(eq(String.format("%s.%s", a, b)), anyString())).thenReturn(nestedProperty);
mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config);
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(NestedPropertyConfig1.class);
TestNestedPropertyBean bean = context.getBean(TestNestedPropertyBean.class);
assertEquals(someValue, bean.getNestedProperty());
}
private void check(int expectedTimeout, int expectedBatch, Class<?>... annotatedClasses) { private void check(int expectedTimeout, int expectedBatch, Class<?>... annotatedClasses) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(annotatedClasses); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(annotatedClasses);
...@@ -188,6 +314,25 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest { ...@@ -188,6 +314,25 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest {
} }
} }
@Configuration
@EnableApolloConfig({"FX.apollo", "application"})
static class AppConfig6 {
@Bean
TestJavaConfigBean testJavaConfigBean() {
return new TestJavaConfigBean();
}
}
@Configuration
@EnableApolloConfig
static class NestedPropertyConfig1 {
@Bean
TestNestedPropertyBean testNestedPropertyBean() {
return new TestNestedPropertyBean();
}
}
@Component @Component
static class TestJavaConfigBean { static class TestJavaConfigBean {
@Value("${timeout:100}") @Value("${timeout:100}")
...@@ -228,4 +373,15 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest { ...@@ -228,4 +373,15 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest {
this.batch = batch; this.batch = batch;
} }
} }
static class TestNestedPropertyBean {
@Value("${${a}.${b}:${c:100}}")
private int nestedProperty;
public int getNestedProperty() {
return nestedProperty;
}
}
} }
...@@ -93,6 +93,24 @@ public class XmlConfigPlaceholderTest extends AbstractSpringIntegrationTest { ...@@ -93,6 +93,24 @@ public class XmlConfigPlaceholderTest extends AbstractSpringIntegrationTest {
} }
@Test @Test
public void testMultiplePropertySourcesWithSameProperties2() throws Exception {
int someTimeout = 1000;
int anotherTimeout = someTimeout + 1;
int someBatch = 2000;
Config application = mock(Config.class);
when(application.getProperty(eq(TIMEOUT_PROPERTY), anyString())).thenReturn(String.valueOf(someTimeout));
when(application.getProperty(eq(BATCH_PROPERTY), anyString())).thenReturn(String.valueOf(someBatch));
mockConfig(ConfigConsts.NAMESPACE_APPLICATION, application);
Config fxApollo = mock(Config.class);
when(fxApollo.getProperty(eq(TIMEOUT_PROPERTY), anyString())).thenReturn(String.valueOf(anotherTimeout));
mockConfig(FX_APOLLO_NAMESPACE, fxApollo);
check("spring/XmlConfigPlaceholderTest6.xml", anotherTimeout, someBatch);
}
@Test
public void testMultiplePropertySourcesWithSamePropertiesWithWeight() throws Exception { public void testMultiplePropertySourcesWithSamePropertiesWithWeight() throws Exception {
int someTimeout = 1000; int someTimeout = 1000;
int anotherTimeout = someTimeout + 1; int anotherTimeout = someTimeout + 1;
......
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:apollo="http://www.ctrip.com/schema/apollo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.ctrip.com/schema/apollo http://www.ctrip.com/schema/apollo.xsd">
<apollo:config namespaces="FX.apollo,application"/>
<bean class="com.ctrip.framework.apollo.spring.XmlConfigPlaceholderTest.TestXmlBean">
<property name="timeout" value="${timeout:100}"/>
<property name="batch" value="${batch:200}"/>
</bean>
</beans>
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