Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
apollo
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
apollo
Commits
72a37b66
Unverified
Commit
72a37b66
authored
Mar 23, 2018
by
wiston1988
Committed by
GitHub
Mar 23, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2 from ctripcorp/master
new version
parents
45290409
8ffa3bf2
Changes
84
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
84 changed files
with
3586 additions
and
513 deletions
+3586
-513
README.md
README.md
+8
-3
apollo-adminservice/src/main/docker/Dockerfile
apollo-adminservice/src/main/docker/Dockerfile
+1
-1
apollo-adminservice/src/test/java/com/ctrip/framework/apollo/adminservice/AllTests.java
...ava/com/ctrip/framework/apollo/adminservice/AllTests.java
+0
-26
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/AbstractIntegrationTest.java
...m/ctrip/framework/apollo/biz/AbstractIntegrationTest.java
+1
-1
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/AbstractUnitTest.java
...java/com/ctrip/framework/apollo/biz/AbstractUnitTest.java
+1
-1
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/AllTests.java
...rc/test/java/com/ctrip/framework/apollo/biz/AllTests.java
+0
-49
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/DefaultInjector.java
...com/ctrip/framework/apollo/internals/DefaultInjector.java
+6
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RemoteConfigLongPollService.java
...amework/apollo/internals/RemoteConfigLongPollService.java
+3
-2
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloAnnotationProcessor.java
...k/apollo/spring/annotation/ApolloAnnotationProcessor.java
+40
-62
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloConfigRegistrar.java
...ework/apollo/spring/annotation/ApolloConfigRegistrar.java
+7
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloJsonValue.java
...p/framework/apollo/spring/annotation/ApolloJsonValue.java
+34
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloJsonValueProcessor.java
...rk/apollo/spring/annotation/ApolloJsonValueProcessor.java
+125
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloProcessor.java
...p/framework/apollo/spring/annotation/ApolloProcessor.java
+74
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/SpringValueProcessor.java
...mework/apollo/spring/annotation/SpringValueProcessor.java
+150
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/boot/ApolloApplicationContextInitializer.java
...ollo/spring/boot/ApolloApplicationContextInitializer.java
+11
-33
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/ConfigPropertySource.java
.../framework/apollo/spring/config/ConfigPropertySource.java
+6
-1
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/ConfigPropertySourceFactory.java
...ork/apollo/spring/config/ConfigPropertySourceFactory.java
+23
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/ConfigPropertySourcesProcessor.java
.../apollo/spring/config/ConfigPropertySourcesProcessor.java
+19
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/PropertySourcesProcessor.java
...mework/apollo/spring/config/PropertySourcesProcessor.java
+31
-3
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/property/AutoUpdateConfigChangeListener.java
...pollo/spring/property/AutoUpdateConfigChangeListener.java
+131
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/property/PlaceholderHelper.java
...p/framework/apollo/spring/property/PlaceholderHelper.java
+163
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/property/SpringValue.java
...m/ctrip/framework/apollo/spring/property/SpringValue.java
+115
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/property/SpringValueDefinition.java
...amework/apollo/spring/property/SpringValueDefinition.java
+26
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/property/SpringValueDefinitionProcessor.java
...pollo/spring/property/SpringValueDefinitionProcessor.java
+96
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/property/SpringValueRegistry.java
...framework/apollo/spring/property/SpringValueRegistry.java
+17
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/util/ConfigUtil.java
...main/java/com/ctrip/framework/apollo/util/ConfigUtil.java
+18
-0
apollo-client/src/main/resources/META-INF/spring.factories
apollo-client/src/main/resources/META-INF/spring.factories
+2
-2
apollo-client/src/test/java/com/ctrip/framework/apollo/AllTests.java
...nt/src/test/java/com/ctrip/framework/apollo/AllTests.java
+0
-43
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/AbstractSpringIntegrationTest.java
...ramework/apollo/spring/AbstractSpringIntegrationTest.java
+80
-1
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigAnnotationTest.java
...rip/framework/apollo/spring/JavaConfigAnnotationTest.java
+2
-1
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderAutoUpdateTest.java
...rk/apollo/spring/JavaConfigPlaceholderAutoUpdateTest.java
+1149
-0
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderTest.java
...ip/framework/apollo/spring/JavaConfigPlaceholderTest.java
+192
-4
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XMLConfigAnnotationTest.java
...trip/framework/apollo/spring/XMLConfigAnnotationTest.java
+2
-1
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XmlConfigPlaceholderAutoUpdateTest.java
...ork/apollo/spring/XmlConfigPlaceholderAutoUpdateTest.java
+606
-0
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/config/ConfigPropertySourceTest.java
...mework/apollo/spring/config/ConfigPropertySourceTest.java
+98
-0
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/property/PlaceholderHelperTest.java
...amework/apollo/spring/property/PlaceholderHelperTest.java
+62
-0
apollo-client/src/test/java/com/ctrip/framework/apollo/util/ConfigUtilTest.java
.../java/com/ctrip/framework/apollo/util/ConfigUtilTest.java
+14
-2
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest10.xml
.../src/test/resources/spring/XmlConfigPlaceholderTest10.xml
+21
-0
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest7.xml
...t/src/test/resources/spring/XmlConfigPlaceholderTest7.xml
+13
-0
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest8.xml
...t/src/test/resources/spring/XmlConfigPlaceholderTest8.xml
+13
-0
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest9.xml
...t/src/test/resources/spring/XmlConfigPlaceholderTest9.xml
+16
-0
apollo-common/src/test/java/com/ctrip/framework/apollo/common/AllTests.java
...test/java/com/ctrip/framework/apollo/common/AllTests.java
+0
-16
apollo-configservice/src/main/docker/Dockerfile
apollo-configservice/src/main/docker/Dockerfile
+1
-1
apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/wrapper/DeferredResultWrapper.java
...k/apollo/configservice/wrapper/DeferredResultWrapper.java
+1
-1
apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/AllTests.java
...va/com/ctrip/framework/apollo/configservice/AllTests.java
+0
-36
apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/controller/NotificationControllerV2Test.java
...onfigservice/controller/NotificationControllerV2Test.java
+5
-2
apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/integration/AbstractBaseIntegrationTest.java
...onfigservice/integration/AbstractBaseIntegrationTest.java
+2
-1
apollo-core/src/test/java/com/ctrip/framework/apollo/AllTests.java
...re/src/test/java/com/ctrip/framework/apollo/AllTests.java
+0
-24
apollo-core/src/test/resources/META-INF/some-invalid-app.properties
...e/src/test/resources/META-INF/some-invalid-app.properties
+1
-1
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/api/ApolloConfigDemo.java
...com/ctrip/framework/apollo/demo/api/ApolloConfigDemo.java
+1
-1
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/common/bean/AnnotatedBean.java
...amework/apollo/demo/spring/common/bean/AnnotatedBean.java
+42
-11
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/common/config/AnotherAppConfig.java
...rk/apollo/demo/spring/common/config/AnotherAppConfig.java
+1
-1
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/common/refresh/ApolloRefreshConfig.java
...pollo/demo/spring/common/refresh/ApolloRefreshConfig.java
+0
-37
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/javaConfigDemo/AnnotationApplication.java
...llo/demo/spring/javaConfigDemo/AnnotationApplication.java
+20
-8
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/javaConfigDemo/config/RefreshScopeConfig.java
...demo/spring/javaConfigDemo/config/RefreshScopeConfig.java
+0
-14
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/springBootDemo/SpringBootSampleApplication.java
...mo/spring/springBootDemo/SpringBootSampleApplication.java
+32
-8
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/springBootDemo/refresh/SpringBootApolloRefreshConfig.java
...springBootDemo/refresh/SpringBootApolloRefreshConfig.java
+15
-8
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/xmlConfigDemo/XmlApplication.java
...work/apollo/demo/spring/xmlConfigDemo/XmlApplication.java
+21
-8
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/xmlConfigDemo/bean/XmlBean.java
...mework/apollo/demo/spring/xmlConfigDemo/bean/XmlBean.java
+5
-0
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/xmlConfigDemo/refresh/ManualRefreshUtil.java
.../demo/spring/xmlConfigDemo/refresh/ManualRefreshUtil.java
+0
-37
apollo-demo/src/main/resources/application.yml
apollo-demo/src/main/resources/application.yml
+2
-2
apollo-demo/src/main/resources/spring.xml
apollo-demo/src/main/resources/spring.xml
+2
-8
apollo-portal/src/main/docker/Dockerfile
apollo-portal/src/main/docker/Dockerfile
+1
-1
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/ctrip/CtripSsoHeartbeatHandler.java
...ork/apollo/portal/spi/ctrip/CtripSsoHeartbeatHandler.java
+2
-0
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultSsoHeartbeatHandler.java
...lo/portal/spi/defaultimpl/DefaultSsoHeartbeatHandler.java
+3
-2
apollo-portal/src/main/resources/application.yml
apollo-portal/src/main/resources/application.yml
+2
-0
apollo-portal/src/main/resources/static/app.html
apollo-portal/src/main/resources/static/app.html
+3
-2
apollo-portal/src/main/resources/static/app/setting.html
apollo-portal/src/main/resources/static/app/setting.html
+1
-0
apollo-portal/src/main/resources/static/cluster.html
apollo-portal/src/main/resources/static/cluster.html
+1
-0
apollo-portal/src/main/resources/static/config/history.html
apollo-portal/src/main/resources/static/config/history.html
+1
-0
apollo-portal/src/main/resources/static/config/sync.html
apollo-portal/src/main/resources/static/config/sync.html
+2
-0
apollo-portal/src/main/resources/static/default_sso_heartbeat.html
...rtal/src/main/resources/static/default_sso_heartbeat.html
+19
-0
apollo-portal/src/main/resources/static/index.html
apollo-portal/src/main/resources/static/index.html
+2
-1
apollo-portal/src/main/resources/static/scripts/directive/directive.js
.../src/main/resources/static/scripts/directive/directive.js
+8
-3
apollo-portal/src/main/resources/static/server_config.html
apollo-portal/src/main/resources/static/server_config.html
+3
-1
apollo-portal/src/main/resources/static/user-manage.html
apollo-portal/src/main/resources/static/user-manage.html
+1
-0
apollo-portal/src/main/resources/static/views/common/nav.html
...lo-portal/src/main/resources/static/views/common/nav.html
+10
-0
apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/AllTests.java
...test/java/com/ctrip/framework/apollo/portal/AllTests.java
+0
-37
doc/images/known-users/huli-logo.png
doc/images/known-users/huli-logo.png
+0
-0
doc/images/known-users/mandao.png
doc/images/known-users/mandao.png
+0
-0
doc/images/known-users/mgzf.png
doc/images/known-users/mgzf.png
+0
-0
doc/images/known-users/nxin.png
doc/images/known-users/nxin.png
+0
-0
doc/images/known-users/rhinotech.png
doc/images/known-users/rhinotech.png
+0
-0
pom.xml
pom.xml
+0
-5
No files found.
README.md
View file @
72a37b66
...
...
@@ -147,6 +147,11 @@ The project is licensed under the [Apache 2 license](https://github.com/ctripcor














apollo-adminservice/src/main/docker/Dockerfile
View file @
72a37b66
...
...
@@ -7,7 +7,7 @@
FROM
openjdk:8-jre-alpine
MAINTAINER
ameizi <sxyx2008@163.com>
ENV
VERSION 0.
9.0
ENV
VERSION 0.
10.0-SNAPSHOT
RUN
echo
"http://mirrors.aliyun.com/alpine/v3.6/main"
>
/etc/apk/repositories
\
&&
echo
"http://mirrors.aliyun.com/alpine/v3.6/community"
>>
/etc/apk/repositories
\
...
...
apollo-adminservice/src/test/java/com/ctrip/framework/apollo/adminservice/AllTests.java
deleted
100644 → 0
View file @
45290409
package
com
.
ctrip
.
framework
.
apollo
.
adminservice
;
import
com.ctrip.framework.apollo.adminservice.aop.NamespaceLockTest
;
import
com.ctrip.framework.apollo.adminservice.aop.NamespaceUnlockAspectTest
;
import
com.ctrip.framework.apollo.adminservice.controller.AppControllerTest
;
import
com.ctrip.framework.apollo.adminservice.controller.AppNamespaceControllerTest
;
import
com.ctrip.framework.apollo.adminservice.controller.ControllerExceptionTest
;
import
com.ctrip.framework.apollo.adminservice.controller.ControllerIntegrationExceptionTest
;
import
com.ctrip.framework.apollo.adminservice.controller.InstanceConfigControllerTest
;
import
com.ctrip.framework.apollo.adminservice.controller.ItemSetControllerTest
;
import
com.ctrip.framework.apollo.adminservice.controller.ReleaseControllerTest
;
import
org.junit.runner.RunWith
;
import
org.junit.runners.Suite
;
import
org.junit.runners.Suite.SuiteClasses
;
@RunWith
(
Suite
.
class
)
@SuiteClasses
({
AppControllerTest
.
class
,
ReleaseControllerTest
.
class
,
ItemSetControllerTest
.
class
,
ControllerExceptionTest
.
class
,
ControllerIntegrationExceptionTest
.
class
,
NamespaceLockTest
.
class
,
InstanceConfigControllerTest
.
class
,
AppNamespaceControllerTest
.
class
,
NamespaceUnlockAspectTest
.
class
})
public
class
AllTests
{
}
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/AbstractIntegrationTest.java
View file @
72a37b66
...
...
@@ -12,6 +12,6 @@ import org.springframework.transaction.annotation.Transactional;
@Transactional
@WebIntegrationTest
(
randomPort
=
true
)
@SpringApplicationConfiguration
(
classes
=
BizTestConfiguration
.
class
)
public
class
AbstractIntegrationTest
{
public
abstract
class
AbstractIntegrationTest
{
}
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/AbstractUnitTest.java
View file @
72a37b66
...
...
@@ -4,6 +4,6 @@ import org.junit.runner.RunWith;
import
org.mockito.runners.MockitoJUnitRunner
;
@RunWith
(
MockitoJUnitRunner
.
class
)
public
class
AbstractUnitTest
{
public
abstract
class
AbstractUnitTest
{
}
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/AllTests.java
deleted
100644 → 0
View file @
45290409
package
com
.
ctrip
.
framework
.
apollo
.
biz
;
import
com.ctrip.framework.apollo.biz.config.BizConfigTest
;
import
com.ctrip.framework.apollo.biz.grayReleaseRule.GrayReleaseRulesHolderTest
;
import
com.ctrip.framework.apollo.biz.message.DatabaseMessageSenderTest
;
import
com.ctrip.framework.apollo.biz.message.ReleaseMessageScannerTest
;
import
com.ctrip.framework.apollo.biz.repository.AppNamespaceRepositoryTest
;
import
com.ctrip.framework.apollo.biz.repository.AppRepositoryTest
;
import
com.ctrip.framework.apollo.biz.service.AdminServiceTest
;
import
com.ctrip.framework.apollo.biz.service.AdminServiceTransactionTest
;
import
com.ctrip.framework.apollo.biz.service.ClusterServiceTest
;
import
com.ctrip.framework.apollo.biz.service.InstanceServiceTest
;
import
com.ctrip.framework.apollo.biz.service.NamespaceBranchServiceTest
;
import
com.ctrip.framework.apollo.biz.service.NamespacePublishInfoTest
;
import
com.ctrip.framework.apollo.biz.service.NamespaceServiceIntegrationTest
;
import
com.ctrip.framework.apollo.biz.service.NamespaceServiceTest
;
import
com.ctrip.framework.apollo.biz.service.ReleaseCreationTest
;
import
com.ctrip.framework.apollo.biz.service.ReleaseServiceTest
;
import
com.ctrip.framework.apollo.biz.service.BizDBPropertySourceTest
;
import
com.ctrip.framework.apollo.biz.utils.ReleaseKeyGeneratorTest
;
import
org.junit.runner.RunWith
;
import
org.junit.runners.Suite
;
import
org.junit.runners.Suite.SuiteClasses
;
@RunWith
(
Suite
.
class
)
@SuiteClasses
({
AppRepositoryTest
.
class
,
AppNamespaceRepositoryTest
.
class
,
AdminServiceTest
.
class
,
AdminServiceTransactionTest
.
class
,
DatabaseMessageSenderTest
.
class
,
BizDBPropertySourceTest
.
class
,
ReleaseServiceTest
.
class
,
ReleaseMessageScannerTest
.
class
,
ClusterServiceTest
.
class
,
ReleaseKeyGeneratorTest
.
class
,
InstanceServiceTest
.
class
,
GrayReleaseRulesHolderTest
.
class
,
NamespaceBranchServiceTest
.
class
,
ReleaseCreationTest
.
class
,
NamespacePublishInfoTest
.
class
,
NamespaceServiceIntegrationTest
.
class
,
BizConfigTest
.
class
,
NamespaceServiceTest
.
class
})
public
class
AllTests
{
}
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/DefaultInjector.java
View file @
72a37b66
...
...
@@ -7,6 +7,9 @@ import com.ctrip.framework.apollo.spi.ConfigRegistry;
import
com.ctrip.framework.apollo.spi.DefaultConfigFactory
;
import
com.ctrip.framework.apollo.spi.DefaultConfigFactoryManager
;
import
com.ctrip.framework.apollo.spi.DefaultConfigRegistry
;
import
com.ctrip.framework.apollo.spring.config.ConfigPropertySourceFactory
;
import
com.ctrip.framework.apollo.spring.property.PlaceholderHelper
;
import
com.ctrip.framework.apollo.spring.property.SpringValueRegistry
;
import
com.ctrip.framework.apollo.tracer.Tracer
;
import
com.ctrip.framework.apollo.util.ConfigUtil
;
import
com.ctrip.framework.apollo.util.http.HttpUtil
;
...
...
@@ -60,6 +63,9 @@ public class DefaultInjector implements Injector {
bind
(
HttpUtil
.
class
).
in
(
Singleton
.
class
);
bind
(
ConfigServiceLocator
.
class
).
in
(
Singleton
.
class
);
bind
(
RemoteConfigLongPollService
.
class
).
in
(
Singleton
.
class
);
bind
(
PlaceholderHelper
.
class
).
in
(
Singleton
.
class
);
bind
(
ConfigPropertySourceFactory
.
class
).
in
(
Singleton
.
class
);
bind
(
SpringValueRegistry
.
class
).
in
(
Singleton
.
class
);
}
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RemoteConfigLongPollService.java
View file @
72a37b66
...
...
@@ -54,6 +54,8 @@ public class RemoteConfigLongPollService {
private
static
final
Joiner
.
MapJoiner
MAP_JOINER
=
Joiner
.
on
(
"&"
).
withKeyValueSeparator
(
"="
);
private
static
final
Escaper
queryParamEscaper
=
UrlEscapers
.
urlFormParameterEscaper
();
private
static
final
long
INIT_NOTIFICATION_ID
=
ConfigConsts
.
NOTIFICATION_ID_PLACEHOLDER
;
//90 seconds, should be longer than server side's long polling timeout, which is now 60 seconds
private
static
final
int
LONG_POLLING_READ_TIMEOUT
=
90
*
1000
;
private
final
ExecutorService
m_longPollingService
;
private
final
AtomicBoolean
m_longPollingStopped
;
private
SchedulePolicy
m_longPollFailSchedulePolicyInSecond
;
...
...
@@ -161,8 +163,7 @@ public class RemoteConfigLongPollService {
logger
.
debug
(
"Long polling from {}"
,
url
);
HttpRequest
request
=
new
HttpRequest
(
url
);
//longer timeout for read - 10 minutes
request
.
setReadTimeout
(
600000
);
request
.
setReadTimeout
(
LONG_POLLING_READ_TIMEOUT
);
transaction
.
addData
(
"Url"
,
url
);
...
...
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloAnnotationProcessor.java
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
annotation
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.config.BeanPostProcessor
;
import
org.springframework.core.Ordered
;
import
org.springframework.core.PriorityOrdered
;
import
org.springframework.core.annotation.AnnotationUtils
;
import
org.springframework.util.ReflectionUtils
;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.ConfigChangeListener
;
import
com.ctrip.framework.apollo.ConfigService
;
import
com.ctrip.framework.apollo.model.ConfigChangeEvent
;
import
com.google.common.base.Preconditions
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
org.springframework.core.annotation.AnnotationUtils
;
import
org.springframework.util.ReflectionUtils
;
/**
* Apollo Annotation Processor for Spring Application
*
* @author Jason Song(song_s@ctrip.com)
*/
public
class
ApolloAnnotationProcessor
implements
BeanPostProcessor
,
PriorityOrdered
{
@Override
public
Object
postProcessBeforeInitialization
(
Object
bean
,
String
beanName
)
throws
BeansException
{
Class
clazz
=
bean
.
getClass
();
processFields
(
bean
,
clazz
.
getDeclaredFields
());
processMethods
(
bean
,
clazz
.
getDeclaredMethods
());
return
bean
;
}
public
class
ApolloAnnotationProcessor
extends
ApolloProcessor
{
@Override
public
Object
postProcessAfterInitialization
(
Object
bean
,
String
beanName
)
throws
BeansException
{
return
bean
;
}
protected
void
processField
(
Object
bean
,
String
beanName
,
Field
field
)
{
ApolloConfig
annotation
=
AnnotationUtils
.
getAnnotation
(
field
,
ApolloConfig
.
class
);
if
(
annotation
==
null
)
{
return
;
}
private
void
processFields
(
Object
bean
,
Field
[]
declaredFields
)
{
for
(
Field
field
:
declaredFields
)
{
ApolloConfig
annotation
=
AnnotationUtils
.
getAnnotation
(
field
,
ApolloConfig
.
class
);
if
(
annotation
==
null
)
{
continue
;
}
Preconditions
.
checkArgument
(
Config
.
class
.
isAssignableFrom
(
field
.
getType
()),
"Invalid type: %s for field: %s, should be Config"
,
field
.
getType
(),
field
);
Preconditions
.
checkArgument
(
Config
.
class
.
isAssignableFrom
(
field
.
getType
()),
"Invalid type: %s for field: %s, should be Config"
,
field
.
getType
(),
field
);
String
namespace
=
annotation
.
value
();
Config
config
=
ConfigService
.
getConfig
(
namespace
);
String
namespace
=
annotation
.
value
();
Config
config
=
ConfigService
.
getConfig
(
namespace
);
ReflectionUtils
.
makeAccessible
(
field
);
ReflectionUtils
.
setField
(
field
,
bean
,
config
);
}
ReflectionUtils
.
makeAccessible
(
field
);
ReflectionUtils
.
setField
(
field
,
bean
,
config
);
@Override
protected
void
processMethod
(
final
Object
bean
,
String
beanName
,
final
Method
method
)
{
ApolloConfigChangeListener
annotation
=
AnnotationUtils
.
findAnnotation
(
method
,
ApolloConfigChangeListener
.
class
);
if
(
annotation
==
null
)
{
return
;
}
}
Class
<?>[]
parameterTypes
=
method
.
getParameterTypes
();
Preconditions
.
checkArgument
(
parameterTypes
.
length
==
1
,
"Invalid number of parameters: %s for method: %s, should be 1"
,
parameterTypes
.
length
,
method
);
Preconditions
.
checkArgument
(
ConfigChangeEvent
.
class
.
isAssignableFrom
(
parameterTypes
[
0
]),
"Invalid parameter type: %s for method: %s, should be ConfigChangeEvent"
,
parameterTypes
[
0
],
method
);
private
void
processMethods
(
final
Object
bean
,
Method
[]
declaredMethods
)
{
for
(
final
Method
method
:
declaredMethods
)
{
ApolloConfigChangeListener
annotation
=
AnnotationUtils
.
findAnnotation
(
method
,
ApolloConfigChangeListener
.
class
);
if
(
annotation
==
null
)
{
continue
;
ReflectionUtils
.
makeAccessible
(
method
);
String
[]
namespaces
=
annotation
.
value
();
ConfigChangeListener
configChangeListener
=
new
ConfigChangeListener
()
{
@Override
public
void
onChange
(
ConfigChangeEvent
changeEvent
)
{
ReflectionUtils
.
invokeMethod
(
method
,
bean
,
changeEvent
);
}
};
Class
<?>[]
parameterTypes
=
method
.
getParameterTypes
();
Preconditions
.
checkArgument
(
parameterTypes
.
length
==
1
,
"Invalid number of parameters: %s for method: %s, should be 1"
,
parameterTypes
.
length
,
method
);
Preconditions
.
checkArgument
(
ConfigChangeEvent
.
class
.
isAssignableFrom
(
parameterTypes
[
0
]),
"Invalid parameter type: %s for method: %s, should be ConfigChangeEvent"
,
parameterTypes
[
0
],
method
);
ReflectionUtils
.
makeAccessible
(
method
);
String
[]
namespaces
=
annotation
.
value
();
for
(
String
namespace
:
namespaces
)
{
Config
config
=
ConfigService
.
getConfig
(
namespace
);
for
(
String
namespace
:
namespaces
)
{
Config
config
=
ConfigService
.
getConfig
(
namespace
);
config
.
addChangeListener
(
new
ConfigChangeListener
()
{
@Override
public
void
onChange
(
ConfigChangeEvent
changeEvent
)
{
ReflectionUtils
.
invokeMethod
(
method
,
bean
,
changeEvent
);
}
});
}
config
.
addChangeListener
(
configChangeListener
);
}
}
@Override
public
int
getOrder
()
{
//make it as late as possible
return
Ordered
.
LOWEST_PRECEDENCE
;
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloConfigRegistrar.java
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
annotation
;
import
com.ctrip.framework.apollo.spring.property.SpringValueDefinitionProcessor
;
import
org.springframework.beans.factory.support.BeanDefinitionRegistry
;
import
org.springframework.context.annotation.ImportBeanDefinitionRegistrar
;
import
org.springframework.context.support.PropertySourcesPlaceholderConfigurer
;
...
...
@@ -30,5 +31,11 @@ public class ApolloConfigRegistrar implements ImportBeanDefinitionRegistrar {
BeanRegistrationUtil
.
registerBeanDefinitionIfNotExists
(
registry
,
ApolloAnnotationProcessor
.
class
.
getName
(),
ApolloAnnotationProcessor
.
class
);
BeanRegistrationUtil
.
registerBeanDefinitionIfNotExists
(
registry
,
SpringValueProcessor
.
class
.
getName
(),
SpringValueProcessor
.
class
);
BeanRegistrationUtil
.
registerBeanDefinitionIfNotExists
(
registry
,
SpringValueDefinitionProcessor
.
class
.
getName
(),
SpringValueDefinitionProcessor
.
class
);
BeanRegistrationUtil
.
registerBeanDefinitionIfNotExists
(
registry
,
ApolloJsonValueProcessor
.
class
.
getName
(),
ApolloJsonValueProcessor
.
class
);
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloJsonValue.java
0 → 100644
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
annotation
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* Use this annotation to inject json property from Apollo, support the same format as Spring @Value.
*
* <p>Usage example:</p>
* <pre class="code">
* // Inject the json property value for type SomeObject.
* // Suppose SomeObject has 2 properties, someString and someInt, then the possible config
* // in Apollo is someJsonPropertyKey={"someString":"someValue", "someInt":10}.
* @ApolloJsonValue("${someJsonPropertyKey:someDefaultValue}")
* private SomeObject someObject;
* </pre>
*
* Create by zhangzheng on 2018/3/6
*
* @see org.springframework.beans.factory.annotation.Value
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
FIELD
,
ElementType
.
METHOD
})
@Documented
public
@interface
ApolloJsonValue
{
/**
* The actual value expression: e.g. "${someJsonPropertyKey:someDefaultValue}".
*/
String
value
();
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloJsonValueProcessor.java
0 → 100644
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
annotation
;
import
com.ctrip.framework.apollo.build.ApolloInjector
;
import
com.ctrip.framework.apollo.spring.property.AutoUpdateConfigChangeListener
;
import
com.ctrip.framework.apollo.spring.property.PlaceholderHelper
;
import
com.ctrip.framework.apollo.spring.property.SpringValue
;
import
com.ctrip.framework.apollo.spring.property.SpringValueRegistry
;
import
com.ctrip.framework.apollo.util.ConfigUtil
;
import
com.google.common.base.Preconditions
;
import
com.google.gson.Gson
;
import
com.google.gson.reflect.TypeToken
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Type
;
import
java.util.Set
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.BeanFactory
;
import
org.springframework.beans.factory.BeanFactoryAware
;
import
org.springframework.beans.factory.config.ConfigurableBeanFactory
;
import
org.springframework.core.annotation.AnnotationUtils
;
import
org.springframework.util.ReflectionUtils
;
/**
* Create by zhangzheng on 2018/2/6
*/
public
class
ApolloJsonValueProcessor
extends
ApolloProcessor
implements
BeanFactoryAware
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
ApolloJsonValueProcessor
.
class
);
private
static
final
Gson
gson
=
new
Gson
();
private
final
ConfigUtil
configUtil
;
private
final
PlaceholderHelper
placeholderHelper
;
private
final
SpringValueRegistry
springValueRegistry
;
private
ConfigurableBeanFactory
beanFactory
;
public
ApolloJsonValueProcessor
()
{
configUtil
=
ApolloInjector
.
getInstance
(
ConfigUtil
.
class
);
placeholderHelper
=
ApolloInjector
.
getInstance
(
PlaceholderHelper
.
class
);
springValueRegistry
=
ApolloInjector
.
getInstance
(
SpringValueRegistry
.
class
);
}
@Override
protected
void
processField
(
Object
bean
,
String
beanName
,
Field
field
)
{
ApolloJsonValue
apolloJsonValue
=
AnnotationUtils
.
getAnnotation
(
field
,
ApolloJsonValue
.
class
);
if
(
apolloJsonValue
==
null
)
{
return
;
}
String
placeholder
=
apolloJsonValue
.
value
();
Object
propertyValue
=
placeholderHelper
.
resolvePropertyValue
(
beanFactory
,
beanName
,
placeholder
);
// propertyValue will never be null, as @ApolloJsonValue will not allow that
if
(!(
propertyValue
instanceof
String
))
{
return
;
}
boolean
accessible
=
field
.
isAccessible
();
field
.
setAccessible
(
true
);
ReflectionUtils
.
setField
(
field
,
bean
,
parseJsonValue
((
String
)
propertyValue
,
field
.
getGenericType
()));
field
.
setAccessible
(
accessible
);
if
(
configUtil
.
isAutoUpdateInjectedSpringPropertiesEnabled
())
{
Set
<
String
>
keys
=
placeholderHelper
.
extractPlaceholderKeys
(
placeholder
);
for
(
String
key
:
keys
)
{
SpringValue
springValue
=
new
SpringValue
(
key
,
placeholder
,
bean
,
beanName
,
field
,
true
);
springValueRegistry
.
register
(
key
,
springValue
);
logger
.
debug
(
"Monitoring {}"
,
springValue
);
}
}
}
@Override
protected
void
processMethod
(
Object
bean
,
String
beanName
,
Method
method
)
{
ApolloJsonValue
apolloJsonValue
=
AnnotationUtils
.
getAnnotation
(
method
,
ApolloJsonValue
.
class
);
if
(
apolloJsonValue
==
null
)
{
return
;
}
String
placeHolder
=
apolloJsonValue
.
value
();
Object
propertyValue
=
placeholderHelper
.
resolvePropertyValue
(
beanFactory
,
beanName
,
placeHolder
);
// propertyValue will never be null, as @ApolloJsonValue will not allow that
if
(!(
propertyValue
instanceof
String
))
{
return
;
}
Type
[]
types
=
method
.
getGenericParameterTypes
();
Preconditions
.
checkArgument
(
types
.
length
==
1
,
"Ignore @Value setter {}.{}, expecting 1 parameter, actual {} parameters"
,
bean
.
getClass
().
getName
(),
method
.
getName
(),
method
.
getParameterTypes
().
length
);
boolean
accessible
=
method
.
isAccessible
();
method
.
setAccessible
(
true
);
ReflectionUtils
.
invokeMethod
(
method
,
bean
,
parseJsonValue
((
String
)
propertyValue
,
types
[
0
]));
method
.
setAccessible
(
accessible
);
if
(
configUtil
.
isAutoUpdateInjectedSpringPropertiesEnabled
())
{
Set
<
String
>
keys
=
placeholderHelper
.
extractPlaceholderKeys
(
placeHolder
);
for
(
String
key
:
keys
)
{
SpringValue
springValue
=
new
SpringValue
(
key
,
apolloJsonValue
.
value
(),
bean
,
beanName
,
method
,
true
);
springValueRegistry
.
register
(
key
,
springValue
);
logger
.
debug
(
"Monitoring {}"
,
springValue
);
}
}
}
private
Object
parseJsonValue
(
String
json
,
Type
targetType
)
{
try
{
return
gson
.
fromJson
(
json
,
targetType
);
}
catch
(
Throwable
ex
)
{
logger
.
error
(
"Parsing json '{}' to type {} failed!"
,
json
,
targetType
,
ex
);
throw
ex
;
}
}
@Override
public
void
setBeanFactory
(
BeanFactory
beanFactory
)
throws
BeansException
{
this
.
beanFactory
=
(
ConfigurableBeanFactory
)
beanFactory
;
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloProcessor.java
0 → 100644
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
annotation
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
java.util.LinkedList
;
import
java.util.List
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.config.BeanPostProcessor
;
import
org.springframework.core.Ordered
;
import
org.springframework.core.PriorityOrdered
;
import
org.springframework.util.ReflectionUtils
;
/**
* Create by zhangzheng on 2018/2/6
*/
public
abstract
class
ApolloProcessor
implements
BeanPostProcessor
,
PriorityOrdered
{
@Override
public
Object
postProcessBeforeInitialization
(
Object
bean
,
String
beanName
)
throws
BeansException
{
Class
clazz
=
bean
.
getClass
();
for
(
Field
field
:
findAllField
(
clazz
))
{
processField
(
bean
,
beanName
,
field
);
}
for
(
Method
method
:
findAllMethod
(
clazz
))
{
processMethod
(
bean
,
beanName
,
method
);
}
return
bean
;
}
@Override
public
Object
postProcessAfterInitialization
(
Object
bean
,
String
beanName
)
throws
BeansException
{
return
bean
;
}
/**
* subclass should implement this method to process field
*/
protected
abstract
void
processField
(
Object
bean
,
String
beanName
,
Field
field
);
/**
* subclass should implement this method to process method
*/
protected
abstract
void
processMethod
(
Object
bean
,
String
beanName
,
Method
method
);
@Override
public
int
getOrder
()
{
//make it as late as possible
return
Ordered
.
LOWEST_PRECEDENCE
;
}
private
List
<
Field
>
findAllField
(
Class
clazz
)
{
final
List
<
Field
>
res
=
new
LinkedList
<>();
ReflectionUtils
.
doWithFields
(
clazz
,
new
ReflectionUtils
.
FieldCallback
()
{
@Override
public
void
doWith
(
Field
field
)
throws
IllegalArgumentException
,
IllegalAccessException
{
res
.
add
(
field
);
}
});
return
res
;
}
private
List
<
Method
>
findAllMethod
(
Class
clazz
)
{
final
List
<
Method
>
res
=
new
LinkedList
<>();
ReflectionUtils
.
doWithMethods
(
clazz
,
new
ReflectionUtils
.
MethodCallback
()
{
@Override
public
void
doWith
(
Method
method
)
throws
IllegalArgumentException
,
IllegalAccessException
{
res
.
add
(
method
);
}
});
return
res
;
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/SpringValueProcessor.java
0 → 100644
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
annotation
;
import
com.ctrip.framework.apollo.build.ApolloInjector
;
import
com.ctrip.framework.apollo.spring.property.AutoUpdateConfigChangeListener
;
import
com.ctrip.framework.apollo.spring.property.PlaceholderHelper
;
import
com.ctrip.framework.apollo.spring.property.SpringValue
;
import
com.ctrip.framework.apollo.spring.property.SpringValueDefinition
;
import
com.ctrip.framework.apollo.spring.property.SpringValueDefinitionProcessor
;
import
com.ctrip.framework.apollo.spring.property.SpringValueRegistry
;
import
com.ctrip.framework.apollo.util.ConfigUtil
;
import
com.google.common.collect.LinkedListMultimap
;
import
com.google.common.collect.Multimap
;
import
java.beans.PropertyDescriptor
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
java.util.Collection
;
import
java.util.Set
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.beans.factory.config.BeanFactoryPostProcessor
;
import
org.springframework.beans.factory.config.ConfigurableListableBeanFactory
;
import
org.springframework.context.annotation.Bean
;
/**
* Spring value processor of field or method which has @Value and xml config placeholders.
*
* @author github.com/zhegexiaohuozi seimimaster@gmail.com
* @since 2017/12/20.
*/
public
class
SpringValueProcessor
extends
ApolloProcessor
implements
BeanFactoryPostProcessor
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
SpringValueProcessor
.
class
);
private
final
ConfigUtil
configUtil
;
private
final
PlaceholderHelper
placeholderHelper
;
private
final
SpringValueRegistry
springValueRegistry
;
private
static
Multimap
<
String
,
SpringValueDefinition
>
beanName2SpringValueDefinitions
=
LinkedListMultimap
.
create
();
public
SpringValueProcessor
()
{
configUtil
=
ApolloInjector
.
getInstance
(
ConfigUtil
.
class
);
placeholderHelper
=
ApolloInjector
.
getInstance
(
PlaceholderHelper
.
class
);
springValueRegistry
=
ApolloInjector
.
getInstance
(
SpringValueRegistry
.
class
);
}
@Override
public
void
postProcessBeanFactory
(
ConfigurableListableBeanFactory
beanFactory
)
throws
BeansException
{
if
(
configUtil
.
isAutoUpdateInjectedSpringPropertiesEnabled
())
{
beanName2SpringValueDefinitions
=
SpringValueDefinitionProcessor
.
getBeanName2SpringValueDefinitions
();
}
}
@Override
public
Object
postProcessBeforeInitialization
(
Object
bean
,
String
beanName
)
throws
BeansException
{
if
(
configUtil
.
isAutoUpdateInjectedSpringPropertiesEnabled
())
{
super
.
postProcessBeforeInitialization
(
bean
,
beanName
);
processBeanPropertyValues
(
bean
,
beanName
);
}
return
bean
;
}
@Override
protected
void
processField
(
Object
bean
,
String
beanName
,
Field
field
)
{
// register @Value on field
Value
value
=
field
.
getAnnotation
(
Value
.
class
);
if
(
value
==
null
)
{
return
;
}
Set
<
String
>
keys
=
placeholderHelper
.
extractPlaceholderKeys
(
value
.
value
());
if
(
keys
.
isEmpty
())
{
return
;
}
for
(
String
key
:
keys
)
{
SpringValue
springValue
=
new
SpringValue
(
key
,
value
.
value
(),
bean
,
beanName
,
field
,
false
);
springValueRegistry
.
register
(
key
,
springValue
);
logger
.
debug
(
"Monitoring {}"
,
springValue
);
}
}
@Override
protected
void
processMethod
(
Object
bean
,
String
beanName
,
Method
method
)
{
//register @Value on method
Value
value
=
method
.
getAnnotation
(
Value
.
class
);
if
(
value
==
null
)
{
return
;
}
//skip Configuration bean methods
if
(
method
.
getAnnotation
(
Bean
.
class
)
!=
null
)
{
return
;
}
if
(
method
.
getParameterTypes
().
length
!=
1
)
{
logger
.
error
(
"Ignore @Value setter {}.{}, expecting 1 parameter, actual {} parameters"
,
bean
.
getClass
().
getName
(),
method
.
getName
(),
method
.
getParameterTypes
().
length
);
return
;
}
Set
<
String
>
keys
=
placeholderHelper
.
extractPlaceholderKeys
(
value
.
value
());
if
(
keys
.
isEmpty
())
{
return
;
}
for
(
String
key
:
keys
)
{
SpringValue
springValue
=
new
SpringValue
(
key
,
value
.
value
(),
bean
,
beanName
,
method
,
false
);
springValueRegistry
.
register
(
key
,
springValue
);
logger
.
debug
(
"Monitoring {}"
,
springValue
);
}
}
private
void
processBeanPropertyValues
(
Object
bean
,
String
beanName
)
{
Collection
<
SpringValueDefinition
>
propertySpringValues
=
beanName2SpringValueDefinitions
.
get
(
beanName
);
if
(
propertySpringValues
==
null
||
propertySpringValues
.
isEmpty
())
{
return
;
}
for
(
SpringValueDefinition
definition
:
propertySpringValues
)
{
try
{
PropertyDescriptor
pd
=
BeanUtils
.
getPropertyDescriptor
(
bean
.
getClass
(),
definition
.
getPropertyName
());
Method
method
=
pd
.
getWriteMethod
();
if
(
method
==
null
)
{
continue
;
}
SpringValue
springValue
=
new
SpringValue
(
definition
.
getKey
(),
definition
.
getPlaceholder
(),
bean
,
beanName
,
method
,
false
);
springValueRegistry
.
register
(
definition
.
getKey
(),
springValue
);
logger
.
debug
(
"Monitoring {}"
,
springValue
);
}
catch
(
Throwable
ex
)
{
logger
.
error
(
"Failed to enable auto update feature for {}.{}"
,
bean
.
getClass
(),
definition
.
getPropertyName
());
}
}
// clear
beanName2SpringValueDefinitions
.
removeAll
(
beanName
);
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/boot/Apollo
SpringApplicationRunListen
er.java
→
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/boot/Apollo
ApplicationContextInitializ
er.java
View file @
72a37b66
...
...
@@ -2,18 +2,16 @@ package com.ctrip.framework.apollo.spring.boot;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.ConfigService
;
import
com.ctrip.framework.apollo.build.ApolloInjector
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
com.ctrip.framework.apollo.spring.config.ConfigPropertySourceFactory
;
import
com.ctrip.framework.apollo.spring.config.PropertySourcesConstants
;
import
com.ctrip.framework.apollo.spring.config.ConfigPropertySource
;
import
com.google.common.base.Splitter
;
import
java.util.List
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.SpringApplicationRunListener
;
import
org.springframework.context.ApplicationContextInitializer
;
import
org.springframework.context.ConfigurableApplicationContext
;
import
org.springframework.core.Ordered
;
import
org.springframework.core.PriorityOrdered
;
import
org.springframework.core.env.CompositePropertySource
;
import
org.springframework.core.env.ConfigurableEnvironment
;
...
...
@@ -34,25 +32,16 @@ import org.springframework.core.env.ConfigurableEnvironment;
* apollo.bootstrap.namespaces = application,FX.apollo
* </pre>
*/
public
class
Apollo
SpringApplicationRunListener
implements
SpringApplicationRunListener
,
PriorityOrdered
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
Apollo
SpringApplicationRunListen
er
.
class
);
public
class
Apollo
ApplicationContextInitializer
implements
ApplicationContextInitializer
<
ConfigurableApplicationContext
>
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
Apollo
ApplicationContextInitializ
er
.
class
);
private
static
final
Splitter
NAMESPACE_SPLITTER
=
Splitter
.
on
(
","
).
omitEmptyStrings
().
trimResults
();
public
ApolloSpringApplicationRunListener
(
SpringApplication
application
,
String
[]
args
)
{
//ignore
}
public
void
starting
()
{
}
public
void
started
()
{
}
public
void
environmentPrepared
(
ConfigurableEnvironment
environment
)
{
}
private
final
ConfigPropertySourceFactory
configPropertySourceFactory
=
ApolloInjector
.
getInstance
(
ConfigPropertySourceFactory
.
class
);
public
void
contextPrepared
(
ConfigurableApplicationContext
context
)
{
@Override
public
void
initialize
(
ConfigurableApplicationContext
context
)
{
ConfigurableEnvironment
environment
=
context
.
getEnvironment
();
String
enabled
=
environment
.
getProperty
(
PropertySourcesConstants
.
APOLLO_BOOTSTRAP_ENABLED
,
"false"
);
if
(!
Boolean
.
valueOf
(
enabled
))
{
...
...
@@ -74,20 +63,9 @@ public class ApolloSpringApplicationRunListener implements SpringApplicationRunL
for
(
String
namespace
:
namespaceList
)
{
Config
config
=
ConfigService
.
getConfig
(
namespace
);
composite
.
addPropertySource
(
new
ConfigPropertySource
(
namespace
,
config
));
composite
.
addPropertySource
(
configPropertySourceFactory
.
get
ConfigPropertySource
(
namespace
,
config
));
}
environment
.
getPropertySources
().
addFirst
(
composite
);
}
public
void
contextLoaded
(
ConfigurableApplicationContext
context
)
{
}
public
void
finished
(
ConfigurableApplicationContext
configurableApplicationContext
,
Throwable
throwable
)
{
}
public
int
getOrder
()
{
return
Ordered
.
LOWEST_PRECEDENCE
;
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/ConfigPropertySource.java
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
config
;
import
com.ctrip.framework.apollo.ConfigChangeListener
;
import
java.util.Set
;
import
org.springframework.core.env.EnumerablePropertySource
;
...
...
@@ -14,7 +15,7 @@ import com.ctrip.framework.apollo.Config;
public
class
ConfigPropertySource
extends
EnumerablePropertySource
<
Config
>
{
private
static
final
String
[]
EMPTY_ARRAY
=
new
String
[
0
];
public
ConfigPropertySource
(
String
name
,
Config
source
)
{
ConfigPropertySource
(
String
name
,
Config
source
)
{
super
(
name
,
source
);
}
...
...
@@ -31,4 +32,8 @@ public class ConfigPropertySource extends EnumerablePropertySource<Config> {
public
Object
getProperty
(
String
name
)
{
return
this
.
source
.
getProperty
(
name
,
null
);
}
public
void
addChangeListener
(
ConfigChangeListener
listener
)
{
this
.
source
.
addChangeListener
(
listener
);
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/ConfigPropertySourceFactory.java
0 → 100644
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
config
;
import
java.util.List
;
import
com.ctrip.framework.apollo.Config
;
import
com.google.common.collect.Lists
;
public
class
ConfigPropertySourceFactory
{
private
final
List
<
ConfigPropertySource
>
configPropertySources
=
Lists
.
newLinkedList
();
public
ConfigPropertySource
getConfigPropertySource
(
String
name
,
Config
source
)
{
ConfigPropertySource
configPropertySource
=
new
ConfigPropertySource
(
name
,
source
);
configPropertySources
.
add
(
configPropertySource
);
return
configPropertySource
;
}
public
List
<
ConfigPropertySource
>
getAllConfigPropertySources
()
{
return
Lists
.
newLinkedList
(
configPropertySources
);
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/ConfigPropertySourcesProcessor.java
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
config
;
import
com.ctrip.framework.apollo.spring.annotation.SpringValueProcessor
;
import
com.ctrip.framework.apollo.spring.property.SpringValueDefinitionProcessor
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloJsonValueProcessor
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.support.BeanDefinitionRegistry
;
import
org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor
;
...
...
@@ -22,5 +25,21 @@ public class ConfigPropertySourcesProcessor extends PropertySourcesProcessor
PropertySourcesPlaceholderConfigurer
.
class
);
BeanRegistrationUtil
.
registerBeanDefinitionIfNotExists
(
registry
,
ApolloAnnotationProcessor
.
class
.
getName
(),
ApolloAnnotationProcessor
.
class
);
BeanRegistrationUtil
.
registerBeanDefinitionIfNotExists
(
registry
,
SpringValueProcessor
.
class
.
getName
(),
SpringValueProcessor
.
class
);
BeanRegistrationUtil
.
registerBeanDefinitionIfNotExists
(
registry
,
ApolloJsonValueProcessor
.
class
.
getName
(),
ApolloJsonValueProcessor
.
class
);
processSpringValueDefinition
(
registry
);
}
/**
* For Spring 3.x versions, the BeanDefinitionRegistryPostProcessor would not be
* instantiated if it is added in postProcessBeanDefinitionRegistry phase, so we have to manually
* call the postProcessBeanDefinitionRegistry method of SpringValueDefinitionProcessor here...
*/
private
void
processSpringValueDefinition
(
BeanDefinitionRegistry
registry
)
{
SpringValueDefinitionProcessor
springValueDefinitionProcessor
=
new
SpringValueDefinitionProcessor
();
springValueDefinitionProcessor
.
postProcessBeanDefinitionRegistry
(
registry
);
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/PropertySourcesProcessor.java
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
config
;
import
com.ctrip.framework.apollo.build.ApolloInjector
;
import
com.ctrip.framework.apollo.spring.property.AutoUpdateConfigChangeListener
;
import
com.ctrip.framework.apollo.util.ConfigUtil
;
import
com.google.common.collect.ImmutableSortedSet
;
import
com.google.common.collect.LinkedHashMultimap
;
import
com.google.common.collect.Multimap
;
...
...
@@ -7,6 +10,8 @@ import com.google.common.collect.Multimap;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.ConfigService
;
import
java.util.List
;
import
java.util.concurrent.atomic.AtomicBoolean
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.config.BeanFactoryPostProcessor
;
import
org.springframework.beans.factory.config.ConfigurableListableBeanFactory
;
...
...
@@ -32,7 +37,11 @@ import java.util.Iterator;
*/
public
class
PropertySourcesProcessor
implements
BeanFactoryPostProcessor
,
EnvironmentAware
,
PriorityOrdered
{
private
static
final
Multimap
<
Integer
,
String
>
NAMESPACE_NAMES
=
LinkedHashMultimap
.
create
();
private
static
final
AtomicBoolean
INITIALIZED
=
new
AtomicBoolean
(
false
);
private
final
ConfigPropertySourceFactory
configPropertySourceFactory
=
ApolloInjector
.
getInstance
(
ConfigPropertySourceFactory
.
class
);
private
final
ConfigUtil
configUtil
=
ApolloInjector
.
getInstance
(
ConfigUtil
.
class
);
private
ConfigurableEnvironment
environment
;
public
static
boolean
addNamespaces
(
Collection
<
String
>
namespaces
,
int
order
)
{
...
...
@@ -41,10 +50,14 @@ public class PropertySourcesProcessor implements BeanFactoryPostProcessor, Envir
@Override
public
void
postProcessBeanFactory
(
ConfigurableListableBeanFactory
beanFactory
)
throws
BeansException
{
initializePropertySources
();
if
(
INITIALIZED
.
compareAndSet
(
false
,
true
))
{
initializePropertySources
();
initializeAutoUpdatePropertiesFeature
(
beanFactory
);
}
}
pr
otected
void
initializePropertySources
()
{
pr
ivate
void
initializePropertySources
()
{
if
(
environment
.
getPropertySources
().
contains
(
PropertySourcesConstants
.
APOLLO_PROPERTY_SOURCE_NAME
))
{
//already initialized
return
;
...
...
@@ -60,7 +73,7 @@ public class PropertySourcesProcessor implements BeanFactoryPostProcessor, Envir
for
(
String
namespace
:
NAMESPACE_NAMES
.
get
(
order
))
{
Config
config
=
ConfigService
.
getConfig
(
namespace
);
composite
.
addPropertySource
(
new
ConfigPropertySource
(
namespace
,
config
));
composite
.
addPropertySource
(
configPropertySourceFactory
.
get
ConfigPropertySource
(
namespace
,
config
));
}
}
...
...
@@ -74,6 +87,20 @@ public class PropertySourcesProcessor implements BeanFactoryPostProcessor, Envir
}
}
private
void
initializeAutoUpdatePropertiesFeature
(
ConfigurableListableBeanFactory
beanFactory
)
{
if
(!
configUtil
.
isAutoUpdateInjectedSpringPropertiesEnabled
())
{
return
;
}
AutoUpdateConfigChangeListener
autoUpdateConfigChangeListener
=
new
AutoUpdateConfigChangeListener
(
environment
,
beanFactory
);
List
<
ConfigPropertySource
>
configPropertySources
=
configPropertySourceFactory
.
getAllConfigPropertySources
();
for
(
ConfigPropertySource
configPropertySource
:
configPropertySources
)
{
configPropertySource
.
addChangeListener
(
autoUpdateConfigChangeListener
);
}
}
@Override
public
void
setEnvironment
(
Environment
environment
)
{
//it is safe enough to cast as all known environment is derived from ConfigurableEnvironment
...
...
@@ -83,6 +110,7 @@ public class PropertySourcesProcessor implements BeanFactoryPostProcessor, Envir
//only for test
private
static
void
reset
()
{
NAMESPACE_NAMES
.
clear
();
INITIALIZED
.
set
(
false
);
}
@Override
...
...
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/property/AutoUpdateConfigChangeListener.java
0 → 100644
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
property
;
import
com.ctrip.framework.apollo.ConfigChangeListener
;
import
com.ctrip.framework.apollo.build.ApolloInjector
;
import
com.ctrip.framework.apollo.model.ConfigChange
;
import
com.ctrip.framework.apollo.model.ConfigChangeEvent
;
import
com.ctrip.framework.apollo.spring.annotation.SpringValueProcessor
;
import
com.google.gson.Gson
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Type
;
import
java.util.Collection
;
import
java.util.Objects
;
import
java.util.Set
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.TypeConverter
;
import
org.springframework.beans.factory.config.ConfigurableBeanFactory
;
import
org.springframework.beans.factory.config.ConfigurableListableBeanFactory
;
import
org.springframework.core.env.Environment
;
import
org.springframework.util.CollectionUtils
;
/**
* Create by zhangzheng on 2018/3/6
*/
public
class
AutoUpdateConfigChangeListener
implements
ConfigChangeListener
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
SpringValueProcessor
.
class
);
private
final
boolean
typeConverterHasConvertIfNecessaryWithFieldParameter
;
private
final
Environment
environment
;
private
final
ConfigurableBeanFactory
beanFactory
;
private
final
TypeConverter
typeConverter
;
private
final
PlaceholderHelper
placeholderHelper
;
private
final
SpringValueRegistry
springValueRegistry
;
private
final
Gson
gson
;
public
AutoUpdateConfigChangeListener
(
Environment
environment
,
ConfigurableListableBeanFactory
beanFactory
){
this
.
typeConverterHasConvertIfNecessaryWithFieldParameter
=
testTypeConverterHasConvertIfNecessaryWithFieldParameter
();
this
.
beanFactory
=
beanFactory
;
this
.
typeConverter
=
this
.
beanFactory
.
getTypeConverter
();
this
.
environment
=
environment
;
this
.
placeholderHelper
=
ApolloInjector
.
getInstance
(
PlaceholderHelper
.
class
);
this
.
springValueRegistry
=
ApolloInjector
.
getInstance
(
SpringValueRegistry
.
class
);
this
.
gson
=
new
Gson
();
}
@Override
public
void
onChange
(
ConfigChangeEvent
changeEvent
)
{
Set
<
String
>
keys
=
changeEvent
.
changedKeys
();
if
(
CollectionUtils
.
isEmpty
(
keys
))
{
return
;
}
for
(
String
key
:
keys
)
{
// 1. check whether the changed key is relevant
Collection
<
SpringValue
>
targetValues
=
springValueRegistry
.
get
(
key
);
if
(
targetValues
==
null
||
targetValues
.
isEmpty
())
{
continue
;
}
// 2. check whether the value is really changed or not (since spring property sources have hierarchies)
ConfigChange
configChange
=
changeEvent
.
getChange
(
key
);
if
(!
Objects
.
equals
(
environment
.
getProperty
(
key
),
configChange
.
getNewValue
()))
{
continue
;
}
// 3. update the value
for
(
SpringValue
val
:
targetValues
)
{
updateSpringValue
(
val
);
}
}
}
private
void
updateSpringValue
(
SpringValue
springValue
)
{
try
{
Object
value
=
resolvePropertyValue
(
springValue
);
springValue
.
update
(
value
);
logger
.
debug
(
"Auto update apollo changed value successfully, new value: {}, {}"
,
value
,
springValue
.
toString
());
}
catch
(
Throwable
ex
)
{
logger
.
error
(
"Auto update apollo changed value failed, {}"
,
springValue
.
toString
(),
ex
);
}
}
/**
* Logic transplanted from DefaultListableBeanFactory
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency(org.springframework.beans.factory.config.DependencyDescriptor, java.lang.String, java.util.Set, org.springframework.beans.TypeConverter)
*/
private
Object
resolvePropertyValue
(
SpringValue
springValue
)
{
// value will never be null, as @Value and @ApolloJsonValue will not allow that
Object
value
=
placeholderHelper
.
resolvePropertyValue
(
beanFactory
,
springValue
.
getBeanName
(),
springValue
.
getPlaceholder
());
if
(
springValue
.
isJson
())
{
value
=
parseJsonValue
((
String
)
value
,
springValue
.
getGenericType
());
}
else
{
if
(
springValue
.
isField
())
{
// org.springframework.beans.TypeConverter#convertIfNecessary(java.lang.Object, java.lang.Class, java.lang.reflect.Field) is available from Spring 3.2.0+
if
(
typeConverterHasConvertIfNecessaryWithFieldParameter
)
{
value
=
this
.
typeConverter
.
convertIfNecessary
(
value
,
springValue
.
getTargetType
(),
springValue
.
getField
());
}
else
{
value
=
this
.
typeConverter
.
convertIfNecessary
(
value
,
springValue
.
getTargetType
());
}
}
else
{
value
=
this
.
typeConverter
.
convertIfNecessary
(
value
,
springValue
.
getTargetType
(),
springValue
.
getMethodParameter
());
}
}
return
value
;
}
private
Object
parseJsonValue
(
String
json
,
Type
targetType
)
{
try
{
return
gson
.
fromJson
(
json
,
targetType
);
}
catch
(
Throwable
ex
)
{
logger
.
error
(
"Parsing json '{}' to type {} failed!"
,
json
,
targetType
,
ex
);
throw
ex
;
}
}
private
boolean
testTypeConverterHasConvertIfNecessaryWithFieldParameter
()
{
try
{
TypeConverter
.
class
.
getMethod
(
"convertIfNecessary"
,
Object
.
class
,
Class
.
class
,
Field
.
class
);
}
catch
(
Throwable
ex
)
{
return
false
;
}
return
true
;
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/property/PlaceholderHelper.java
0 → 100644
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
property
;
import
com.google.common.base.Strings
;
import
com.google.common.collect.Sets
;
import
java.util.Set
;
import
java.util.Stack
;
import
org.springframework.beans.factory.BeanFactory
;
import
org.springframework.beans.factory.config.BeanDefinition
;
import
org.springframework.beans.factory.config.BeanExpressionContext
;
import
org.springframework.beans.factory.config.ConfigurableBeanFactory
;
import
org.springframework.beans.factory.config.Scope
;
import
org.springframework.util.StringUtils
;
/**
* Placeholder helper functions.
*/
public
class
PlaceholderHelper
{
private
static
final
String
PLACEHOLDER_PREFIX
=
"${"
;
private
static
final
String
PLACEHOLDER_SUFFIX
=
"}"
;
private
static
final
String
VALUE_SEPARATOR
=
":"
;
private
static
final
String
SIMPLE_PLACEHOLDER_PREFIX
=
"{"
;
private
static
final
String
EXPRESSION_PREFIX
=
"#{"
;
private
static
final
String
EXPRESSION_SUFFIX
=
"}"
;
/**
* Resolve placeholder property values, e.g.
* <br />
* <br />
* "${somePropertyValue}" -> "the actual property value"
*/
public
Object
resolvePropertyValue
(
ConfigurableBeanFactory
beanFactory
,
String
beanName
,
String
placeholder
)
{
// resolve string value
String
strVal
=
beanFactory
.
resolveEmbeddedValue
(
placeholder
);
BeanDefinition
bd
=
(
beanFactory
.
containsBean
(
beanName
)
?
beanFactory
.
getMergedBeanDefinition
(
beanName
)
:
null
);
// resolve expressions like "#{systemProperties.myProp}"
return
evaluateBeanDefinitionString
(
beanFactory
,
strVal
,
bd
);
}
private
Object
evaluateBeanDefinitionString
(
ConfigurableBeanFactory
beanFactory
,
String
value
,
BeanDefinition
beanDefinition
)
{
if
(
beanFactory
.
getBeanExpressionResolver
()
==
null
)
{
return
value
;
}
Scope
scope
=
(
beanDefinition
!=
null
?
beanFactory
.
getRegisteredScope
(
beanDefinition
.
getScope
())
:
null
);
return
beanFactory
.
getBeanExpressionResolver
()
.
evaluate
(
value
,
new
BeanExpressionContext
(
beanFactory
,
scope
));
}
/**
* Extract keys from placeholder, e.g.
* <ul>
* <li>${some.key} => "some.key"</li>
* <li>${some.key:${some.other.key:100}} => "some.key", "some.other.key"</li>
* <li>${${some.key}} => "some.key"</li>
* <li>${${some.key:other.key}} => "some.key"</li>
* <li>${${some.key}:${another.key}} => "some.key", "another.key"</li>
* <li>#{new java.text.SimpleDateFormat('${some.key}').parse('${another.key}')} => "some.key", "another.key"</li>
* </ul>
*/
public
Set
<
String
>
extractPlaceholderKeys
(
String
propertyString
)
{
Set
<
String
>
placeholderKeys
=
Sets
.
newHashSet
();
if
(!
isNormalizedPlaceholder
(
propertyString
)
&&
!
isExpressionWithPlaceholder
(
propertyString
))
{
return
placeholderKeys
;
}
Stack
<
String
>
stack
=
new
Stack
<>();
stack
.
push
(
propertyString
);
while
(!
stack
.
isEmpty
())
{
String
strVal
=
stack
.
pop
();
int
startIndex
=
strVal
.
indexOf
(
PLACEHOLDER_PREFIX
);
if
(
startIndex
==
-
1
)
{
placeholderKeys
.
add
(
strVal
);
continue
;
}
int
endIndex
=
findPlaceholderEndIndex
(
strVal
,
startIndex
);
if
(
endIndex
==
-
1
)
{
// invalid placeholder?
continue
;
}
String
placeholderCandidate
=
strVal
.
substring
(
startIndex
+
PLACEHOLDER_PREFIX
.
length
(),
endIndex
);
// ${some.key:other.key}
if
(
placeholderCandidate
.
startsWith
(
PLACEHOLDER_PREFIX
))
{
stack
.
push
(
placeholderCandidate
);
}
else
{
// some.key:${some.other.key:100}
int
separatorIndex
=
placeholderCandidate
.
indexOf
(
VALUE_SEPARATOR
);
if
(
separatorIndex
==
-
1
)
{
stack
.
push
(
placeholderCandidate
);
}
else
{
stack
.
push
(
placeholderCandidate
.
substring
(
0
,
separatorIndex
));
String
defaultValuePart
=
normalizeToPlaceholder
(
placeholderCandidate
.
substring
(
separatorIndex
+
VALUE_SEPARATOR
.
length
()));
if
(!
Strings
.
isNullOrEmpty
(
defaultValuePart
))
{
stack
.
push
(
defaultValuePart
);
}
}
}
// has remaining part, e.g. ${a}.${b}
if
(
endIndex
+
PLACEHOLDER_SUFFIX
.
length
()
<
strVal
.
length
()
-
1
)
{
String
remainingPart
=
normalizeToPlaceholder
(
strVal
.
substring
(
endIndex
+
PLACEHOLDER_SUFFIX
.
length
()));
if
(!
Strings
.
isNullOrEmpty
(
remainingPart
))
{
stack
.
push
(
remainingPart
);
}
}
}
return
placeholderKeys
;
}
private
boolean
isNormalizedPlaceholder
(
String
propertyString
)
{
return
propertyString
.
startsWith
(
PLACEHOLDER_PREFIX
)
&&
propertyString
.
endsWith
(
PLACEHOLDER_SUFFIX
);
}
private
boolean
isExpressionWithPlaceholder
(
String
propertyString
)
{
return
propertyString
.
startsWith
(
EXPRESSION_PREFIX
)
&&
propertyString
.
endsWith
(
EXPRESSION_SUFFIX
)
&&
propertyString
.
contains
(
PLACEHOLDER_PREFIX
);
}
private
String
normalizeToPlaceholder
(
String
strVal
)
{
int
startIndex
=
strVal
.
indexOf
(
PLACEHOLDER_PREFIX
);
if
(
startIndex
==
-
1
)
{
return
null
;
}
int
endIndex
=
strVal
.
lastIndexOf
(
PLACEHOLDER_SUFFIX
);
if
(
endIndex
==
-
1
)
{
return
null
;
}
return
strVal
.
substring
(
startIndex
,
endIndex
+
PLACEHOLDER_SUFFIX
.
length
());
}
private
int
findPlaceholderEndIndex
(
CharSequence
buf
,
int
startIndex
)
{
int
index
=
startIndex
+
PLACEHOLDER_PREFIX
.
length
();
int
withinNestedPlaceholder
=
0
;
while
(
index
<
buf
.
length
())
{
if
(
StringUtils
.
substringMatch
(
buf
,
index
,
PLACEHOLDER_SUFFIX
))
{
if
(
withinNestedPlaceholder
>
0
)
{
withinNestedPlaceholder
--;
index
=
index
+
PLACEHOLDER_SUFFIX
.
length
();
}
else
{
return
index
;
}
}
else
if
(
StringUtils
.
substringMatch
(
buf
,
index
,
SIMPLE_PLACEHOLDER_PREFIX
))
{
withinNestedPlaceholder
++;
index
=
index
+
SIMPLE_PLACEHOLDER_PREFIX
.
length
();
}
else
{
index
++;
}
}
return
-
1
;
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/property/SpringValue.java
0 → 100644
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
property
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Type
;
import
org.springframework.core.MethodParameter
;
/**
* Spring @Value method info
*
* @author github.com/zhegexiaohuozi seimimaster@gmail.com
* @since 2018/2/6.
*/
public
class
SpringValue
{
private
MethodParameter
methodParameter
;
private
Field
field
;
private
Object
bean
;
private
String
beanName
;
private
String
key
;
private
String
placeholder
;
private
Class
<?>
targetType
;
private
Type
genericType
;
private
boolean
isJson
;
public
SpringValue
(
String
key
,
String
placeholder
,
Object
bean
,
String
beanName
,
Field
field
,
boolean
isJson
)
{
this
.
bean
=
bean
;
this
.
beanName
=
beanName
;
this
.
field
=
field
;
this
.
key
=
key
;
this
.
placeholder
=
placeholder
;
this
.
targetType
=
field
.
getType
();
this
.
isJson
=
isJson
;
if
(
isJson
){
this
.
genericType
=
field
.
getGenericType
();
}
}
public
SpringValue
(
String
key
,
String
placeholder
,
Object
bean
,
String
beanName
,
Method
method
,
boolean
isJson
)
{
this
.
bean
=
bean
;
this
.
beanName
=
beanName
;
this
.
methodParameter
=
new
MethodParameter
(
method
,
0
);
this
.
key
=
key
;
this
.
placeholder
=
placeholder
;
Class
<?>[]
paramTps
=
method
.
getParameterTypes
();
this
.
targetType
=
paramTps
[
0
];
this
.
isJson
=
isJson
;
if
(
isJson
){
this
.
genericType
=
method
.
getGenericParameterTypes
()[
0
];
}
}
public
void
update
(
Object
newVal
)
throws
IllegalAccessException
,
InvocationTargetException
{
if
(
isField
())
{
injectField
(
newVal
);
}
else
{
injectMethod
(
newVal
);
}
}
private
void
injectField
(
Object
newVal
)
throws
IllegalAccessException
{
boolean
accessible
=
field
.
isAccessible
();
field
.
setAccessible
(
true
);
field
.
set
(
bean
,
newVal
);
field
.
setAccessible
(
accessible
);
}
private
void
injectMethod
(
Object
newVal
)
throws
InvocationTargetException
,
IllegalAccessException
{
methodParameter
.
getMethod
().
invoke
(
bean
,
newVal
);
}
public
String
getBeanName
()
{
return
beanName
;
}
public
Class
<?>
getTargetType
()
{
return
targetType
;
}
public
String
getPlaceholder
()
{
return
this
.
placeholder
;
}
public
MethodParameter
getMethodParameter
()
{
return
methodParameter
;
}
public
boolean
isField
()
{
return
this
.
field
!=
null
;
}
public
Field
getField
()
{
return
field
;
}
public
Type
getGenericType
()
{
return
genericType
;
}
public
boolean
isJson
()
{
return
isJson
;
}
@Override
public
String
toString
()
{
if
(
isField
())
{
return
String
.
format
(
"key: %s, beanName: %s, field: %s.%s"
,
key
,
beanName
,
bean
.
getClass
().
getName
(),
field
.
getName
());
}
return
String
.
format
(
"key: %s, beanName: %s, method: %s.%s"
,
key
,
beanName
,
bean
.
getClass
().
getName
(),
methodParameter
.
getMethod
().
getName
());
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/property/SpringValueDefinition.java
0 → 100644
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
property
;
public
class
SpringValueDefinition
{
private
final
String
key
;
private
final
String
placeholder
;
private
final
String
propertyName
;
public
SpringValueDefinition
(
String
key
,
String
placeholder
,
String
propertyName
)
{
this
.
key
=
key
;
this
.
placeholder
=
placeholder
;
this
.
propertyName
=
propertyName
;
}
public
String
getKey
()
{
return
key
;
}
public
String
getPlaceholder
()
{
return
placeholder
;
}
public
String
getPropertyName
()
{
return
propertyName
;
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/property/SpringValueDefinitionProcessor.java
0 → 100644
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
property
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.concurrent.atomic.AtomicBoolean
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.MutablePropertyValues
;
import
org.springframework.beans.PropertyValue
;
import
org.springframework.beans.factory.config.BeanDefinition
;
import
org.springframework.beans.factory.config.ConfigurableListableBeanFactory
;
import
org.springframework.beans.factory.config.TypedStringValue
;
import
org.springframework.beans.factory.support.BeanDefinitionRegistry
;
import
org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor
;
import
com.ctrip.framework.apollo.build.ApolloInjector
;
import
com.ctrip.framework.apollo.util.ConfigUtil
;
import
com.google.common.collect.LinkedListMultimap
;
import
com.google.common.collect.Multimap
;
/**
* To process xml config placeholders, e.g.
*
* <pre>
* <bean class="com.ctrip.framework.apollo.demo.spring.xmlConfigDemo.bean.XmlBean">
* <property name="timeout" value="${timeout:200}"/>
* <property name="batch" value="${batch:100}"/>
* </bean>
* </pre>
*/
public
class
SpringValueDefinitionProcessor
implements
BeanDefinitionRegistryPostProcessor
{
private
static
final
Multimap
<
String
,
SpringValueDefinition
>
beanName2SpringValueDefinitions
=
LinkedListMultimap
.
create
();
private
static
final
AtomicBoolean
initialized
=
new
AtomicBoolean
(
false
);
private
final
ConfigUtil
configUtil
;
private
final
PlaceholderHelper
placeholderHelper
;
public
SpringValueDefinitionProcessor
()
{
configUtil
=
ApolloInjector
.
getInstance
(
ConfigUtil
.
class
);
placeholderHelper
=
ApolloInjector
.
getInstance
(
PlaceholderHelper
.
class
);
}
@Override
public
void
postProcessBeanDefinitionRegistry
(
BeanDefinitionRegistry
registry
)
throws
BeansException
{
if
(
configUtil
.
isAutoUpdateInjectedSpringPropertiesEnabled
())
{
processPropertyValues
(
registry
);
}
}
@Override
public
void
postProcessBeanFactory
(
ConfigurableListableBeanFactory
beanFactory
)
throws
BeansException
{
}
public
static
Multimap
<
String
,
SpringValueDefinition
>
getBeanName2SpringValueDefinitions
()
{
return
beanName2SpringValueDefinitions
;
}
private
void
processPropertyValues
(
BeanDefinitionRegistry
beanRegistry
)
{
if
(!
initialized
.
compareAndSet
(
false
,
true
))
{
// already initialized
return
;
}
String
[]
beanNames
=
beanRegistry
.
getBeanDefinitionNames
();
for
(
String
beanName
:
beanNames
)
{
BeanDefinition
beanDefinition
=
beanRegistry
.
getBeanDefinition
(
beanName
);
MutablePropertyValues
mutablePropertyValues
=
beanDefinition
.
getPropertyValues
();
List
<
PropertyValue
>
propertyValues
=
mutablePropertyValues
.
getPropertyValueList
();
for
(
PropertyValue
propertyValue
:
propertyValues
)
{
Object
value
=
propertyValue
.
getValue
();
if
(!(
value
instanceof
TypedStringValue
))
{
continue
;
}
String
placeholder
=
((
TypedStringValue
)
value
).
getValue
();
Set
<
String
>
keys
=
placeholderHelper
.
extractPlaceholderKeys
(
placeholder
);
if
(
keys
.
isEmpty
())
{
continue
;
}
for
(
String
key
:
keys
)
{
beanName2SpringValueDefinitions
.
put
(
beanName
,
new
SpringValueDefinition
(
key
,
placeholder
,
propertyValue
.
getName
()));
}
}
}
}
//only for test
private
static
void
reset
()
{
initialized
.
set
(
false
);
beanName2SpringValueDefinitions
.
clear
();
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/property/SpringValueRegistry.java
0 → 100644
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
property
;
import
com.google.common.collect.LinkedListMultimap
;
import
com.google.common.collect.Multimap
;
import
java.util.Collection
;
public
class
SpringValueRegistry
{
private
final
Multimap
<
String
,
SpringValue
>
registry
=
LinkedListMultimap
.
create
();
public
void
register
(
String
key
,
SpringValue
springValue
)
{
registry
.
put
(
key
,
springValue
);
}
public
Collection
<
SpringValue
>
get
(
String
key
)
{
return
registry
.
get
(
key
);
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/util/ConfigUtil.java
View file @
72a37b66
...
...
@@ -33,6 +33,7 @@ public class ConfigUtil {
private
long
configCacheExpireTime
=
1
;
//1 minute
private
TimeUnit
configCacheExpireTimeUnit
=
TimeUnit
.
MINUTES
;
//1 minute
private
long
longPollingInitialDelayInMills
=
2000
;
//2 seconds
private
boolean
autoUpdateInjectedSpringProperties
=
true
;
public
ConfigUtil
()
{
initRefreshInterval
();
...
...
@@ -42,6 +43,7 @@ public class ConfigUtil {
initQPS
();
initMaxConfigCacheSize
();
initLongPollingInitialDelayInMills
();
initAutoUpdateInjectedSpringProperties
();
}
/**
...
...
@@ -263,4 +265,20 @@ public class ConfigUtil {
public
long
getLongPollingInitialDelayInMills
()
{
return
longPollingInitialDelayInMills
;
}
private
void
initAutoUpdateInjectedSpringProperties
()
{
// 1. Get from System Property
String
enableAutoUpdate
=
System
.
getProperty
(
"apollo.autoUpdateInjectedSpringProperties"
);
if
(
Strings
.
isNullOrEmpty
(
enableAutoUpdate
))
{
// 2. Get from app.properties
enableAutoUpdate
=
Foundation
.
app
().
getProperty
(
"apollo.autoUpdateInjectedSpringProperties"
,
null
);
}
if
(!
Strings
.
isNullOrEmpty
(
enableAutoUpdate
))
{
autoUpdateInjectedSpringProperties
=
Boolean
.
parseBoolean
(
enableAutoUpdate
.
trim
());
}
}
public
boolean
isAutoUpdateInjectedSpringPropertiesEnabled
()
{
return
autoUpdateInjectedSpringProperties
;
}
}
apollo-client/src/main/resources/META-INF/spring.factories
View file @
72a37b66
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.ctrip.framework.apollo.spring.boot.ApolloAutoConfiguration
org.springframework.
boot.SpringApplicationRunListen
er=\
com.ctrip.framework.apollo.spring.boot.Apollo
SpringApplicationRunListen
er
org.springframework.
context.ApplicationContextInitializ
er=\
com.ctrip.framework.apollo.spring.boot.Apollo
ApplicationContextInitializ
er
apollo-client/src/test/java/com/ctrip/framework/apollo/AllTests.java
deleted
100644 → 0
View file @
45290409
package
com
.
ctrip
.
framework
.
apollo
;
import
com.ctrip.framework.apollo.spring.BootstrapConfigTest
;
import
org.junit.runner.RunWith
;
import
org.junit.runners.Suite
;
import
org.junit.runners.Suite.SuiteClasses
;
import
com.ctrip.framework.apollo.integration.ConfigIntegrationTest
;
import
com.ctrip.framework.apollo.internals.DefaultConfigManagerTest
;
import
com.ctrip.framework.apollo.internals.DefaultConfigTest
;
import
com.ctrip.framework.apollo.internals.JsonConfigFileTest
;
import
com.ctrip.framework.apollo.internals.LocalFileConfigRepositoryTest
;
import
com.ctrip.framework.apollo.internals.PropertiesConfigFileTest
;
import
com.ctrip.framework.apollo.internals.RemoteConfigLongPollServiceTest
;
import
com.ctrip.framework.apollo.internals.RemoteConfigRepositoryTest
;
import
com.ctrip.framework.apollo.internals.SimpleConfigTest
;
import
com.ctrip.framework.apollo.internals.XmlConfigFileTest
;
import
com.ctrip.framework.apollo.spi.DefaultConfigFactoryManagerTest
;
import
com.ctrip.framework.apollo.spi.DefaultConfigFactoryTest
;
import
com.ctrip.framework.apollo.spi.DefaultConfigRegistryTest
;
import
com.ctrip.framework.apollo.spring.JavaConfigAnnotationTest
;
import
com.ctrip.framework.apollo.spring.JavaConfigPlaceholderTest
;
import
com.ctrip.framework.apollo.spring.XMLConfigAnnotationTest
;
import
com.ctrip.framework.apollo.spring.XmlConfigPlaceholderTest
;
import
com.ctrip.framework.apollo.util.ConfigUtilTest
;
import
com.ctrip.framework.apollo.util.ExceptionUtilTest
;
import
com.ctrip.framework.apollo.util.parser.DateParserTest
;
import
com.ctrip.framework.apollo.util.parser.DurationParserTest
;
@RunWith
(
Suite
.
class
)
@SuiteClasses
({
ConfigServiceTest
.
class
,
DefaultConfigRegistryTest
.
class
,
DefaultConfigFactoryManagerTest
.
class
,
DefaultConfigManagerTest
.
class
,
DefaultConfigTest
.
class
,
LocalFileConfigRepositoryTest
.
class
,
RemoteConfigRepositoryTest
.
class
,
SimpleConfigTest
.
class
,
DefaultConfigFactoryTest
.
class
,
ConfigIntegrationTest
.
class
,
ExceptionUtilTest
.
class
,
XmlConfigFileTest
.
class
,
PropertiesConfigFileTest
.
class
,
RemoteConfigLongPollServiceTest
.
class
,
DateParserTest
.
class
,
DurationParserTest
.
class
,
JsonConfigFileTest
.
class
,
XmlConfigPlaceholderTest
.
class
,
JavaConfigPlaceholderTest
.
class
,
XMLConfigAnnotationTest
.
class
,
JavaConfigAnnotationTest
.
class
,
ConfigUtilTest
.
class
,
BootstrapConfigTest
.
class
})
public
class
AllTests
{
}
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/AbstractSpringIntegrationTest.java
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
spring
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
com.ctrip.framework.apollo.internals.ConfigRepository
;
import
com.ctrip.framework.apollo.internals.DefaultInjector
;
import
com.ctrip.framework.apollo.internals.SimpleConfig
;
import
com.ctrip.framework.apollo.spring.property.SpringValueDefinitionProcessor
;
import
com.ctrip.framework.apollo.util.ConfigUtil
;
import
java.lang.reflect.Method
;
import
java.util.Calendar
;
import
java.util.Date
;
import
java.util.Map
;
import
java.util.Properties
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.springframework.util.ReflectionUtils
;
...
...
@@ -22,12 +34,15 @@ import com.google.common.collect.Maps;
public
abstract
class
AbstractSpringIntegrationTest
{
private
static
final
Map
<
String
,
Config
>
CONFIG_REGISTRY
=
Maps
.
newHashMap
();
private
static
Method
PROPERTY_SOURCES_PROCESSOR_CLEAR
;
private
static
Method
SPRING_VALUE_DEFINITION_PROCESS_CLEAR
;
private
static
Method
CONFIG_SERVICE_RESET
;
static
{
try
{
PROPERTY_SOURCES_PROCESSOR_CLEAR
=
PropertySourcesProcessor
.
class
.
getDeclaredMethod
(
"reset"
);
ReflectionUtils
.
makeAccessible
(
PROPERTY_SOURCES_PROCESSOR_CLEAR
);
SPRING_VALUE_DEFINITION_PROCESS_CLEAR
=
SpringValueDefinitionProcessor
.
class
.
getDeclaredMethod
(
"reset"
);
ReflectionUtils
.
makeAccessible
(
SPRING_VALUE_DEFINITION_PROCESS_CLEAR
);
CONFIG_SERVICE_RESET
=
ConfigService
.
class
.
getDeclaredMethod
(
"reset"
);
ReflectionUtils
.
makeAccessible
(
CONFIG_SERVICE_RESET
);
}
catch
(
NoSuchMethodException
e
)
{
...
...
@@ -45,6 +60,53 @@ public abstract class AbstractSpringIntegrationTest {
doTearDown
();
}
protected
SimpleConfig
prepareConfig
(
String
namespaceName
,
Properties
properties
)
{
ConfigRepository
configRepository
=
mock
(
ConfigRepository
.
class
);
when
(
configRepository
.
getConfig
()).
thenReturn
(
properties
);
SimpleConfig
config
=
new
SimpleConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
configRepository
);
mockConfig
(
namespaceName
,
config
);
return
config
;
}
protected
Properties
assembleProperties
(
String
key
,
String
value
)
{
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
key
,
value
);
return
properties
;
}
protected
Properties
assembleProperties
(
String
key
,
String
value
,
String
key2
,
String
value2
)
{
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
key
,
value
);
properties
.
setProperty
(
key2
,
value2
);
return
properties
;
}
protected
Properties
assembleProperties
(
String
key
,
String
value
,
String
key2
,
String
value2
,
String
key3
,
String
value3
)
{
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
key
,
value
);
properties
.
setProperty
(
key2
,
value2
);
properties
.
setProperty
(
key3
,
value3
);
return
properties
;
}
protected
Date
assembleDate
(
int
year
,
int
month
,
int
day
,
int
hour
,
int
minute
,
int
second
,
int
millisecond
)
{
Calendar
date
=
Calendar
.
getInstance
();
date
.
set
(
year
,
month
-
1
,
day
,
hour
,
minute
,
second
);
//Month in Calendar is 0 based
date
.
set
(
Calendar
.
MILLISECOND
,
millisecond
);
return
date
.
getTime
();
}
protected
static
void
mockConfig
(
String
namespace
,
Config
config
)
{
CONFIG_REGISTRY
.
put
(
namespace
,
config
);
}
...
...
@@ -52,17 +114,20 @@ public abstract class AbstractSpringIntegrationTest {
protected
static
void
doSetUp
()
{
//as PropertySourcesProcessor has some static states, so we must manually clear its state
ReflectionUtils
.
invokeMethod
(
PROPERTY_SOURCES_PROCESSOR_CLEAR
,
null
);
//as SpringValueDefinitionProcessor has some static states, so we must manually clear its state
ReflectionUtils
.
invokeMethod
(
SPRING_VALUE_DEFINITION_PROCESS_CLEAR
,
null
);
//as ConfigService is singleton, so we must manually clear its container
ReflectionUtils
.
invokeMethod
(
CONFIG_SERVICE_RESET
,
null
);
MockInjector
.
reset
();
MockInjector
.
setInstance
(
ConfigManager
.
class
,
new
MockConfigManager
());
MockInjector
.
setDelegate
(
new
DefaultInjector
());
}
protected
static
void
doTearDown
()
{
CONFIG_REGISTRY
.
clear
();
}
p
ublic
static
class
MockConfigManager
implements
ConfigManager
{
p
rivate
static
class
MockConfigManager
implements
ConfigManager
{
@Override
public
Config
getConfig
(
String
namespace
)
{
...
...
@@ -74,4 +139,18 @@ public abstract class AbstractSpringIntegrationTest {
return
null
;
}
}
protected
static
class
MockConfigUtil
extends
ConfigUtil
{
private
boolean
isAutoUpdateInjectedSpringProperties
;
public
void
setAutoUpdateInjectedSpringProperties
(
boolean
autoUpdateInjectedSpringProperties
)
{
isAutoUpdateInjectedSpringProperties
=
autoUpdateInjectedSpringProperties
;
}
@Override
public
boolean
isAutoUpdateInjectedSpringPropertiesEnabled
()
{
return
isAutoUpdateInjectedSpringProperties
;
}
}
}
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigAnnotationTest.java
View file @
72a37b66
...
...
@@ -88,7 +88,8 @@ public class JavaConfigAnnotationTest extends AbstractSpringIntegrationTest {
TestApolloConfigChangeListenerBean1
bean
=
getBean
(
TestApolloConfigChangeListenerBean1
.
class
,
AppConfig3
.
class
);
assertEquals
(
3
,
applicationListeners
.
size
());
//PropertySourcesProcessor add listeners to listen config changed of all namespace
assertEquals
(
4
,
applicationListeners
.
size
());
assertEquals
(
1
,
fxApolloListeners
.
size
());
for
(
ConfigChangeListener
listener
:
applicationListeners
)
{
...
...
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderAutoUpdateTest.java
0 → 100644
View file @
72a37b66
This diff is collapsed.
Click to expand it.
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderTest.java
View file @
72a37b66
...
...
@@ -6,17 +6,23 @@ import static org.mockito.Matchers.eq;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue
;
import
com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig
;
import
java.util.List
;
import
org.junit.Test
;
import
org.springframework.beans.factory.BeanCreationException
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.annotation.AnnotationConfigApplicationContext
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.ComponentScan
;
import
org.springframework.context.annotation.ComponentScan.Filter
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.FilterType
;
import
org.springframework.stereotype.Component
;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
...
...
@@ -26,6 +32,8 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest {
private
static
final
String
BATCH_PROPERTY
=
"batch"
;
private
static
final
int
DEFAULT_BATCH
=
200
;
private
static
final
String
FX_APOLLO_NAMESPACE
=
"FX.apollo"
;
private
static
final
String
JSON_PROPERTY
=
"jsonProperty"
;
private
static
final
String
OTHER_JSON_PROPERTY
=
"otherJsonProperty"
;
@Test
public
void
testPropertySourceWithNoNamespace
()
throws
Exception
{
...
...
@@ -153,6 +161,25 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest {
assertEquals
(
someBatch
,
bean
.
getBatch
());
}
@Test
public
void
testApplicationPropertySourceWithValueInjectedAsConstructorArgs
()
throws
Exception
{
int
someTimeout
=
1000
;
int
someBatch
=
2000
;
Config
config
=
mock
(
Config
.
class
);
when
(
config
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someTimeout
));
when
(
config
.
getProperty
(
eq
(
BATCH_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someBatch
));
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
config
);
AnnotationConfigApplicationContext
context
=
new
AnnotationConfigApplicationContext
(
AppConfig7
.
class
);
TestJavaConfigBean3
bean
=
context
.
getBean
(
TestJavaConfigBean3
.
class
);
assertEquals
(
someTimeout
,
bean
.
getTimeout
());
assertEquals
(
someBatch
,
bean
.
getBatch
());
}
@Test
public
void
testNestedProperty
()
throws
Exception
{
String
a
=
"a"
;
...
...
@@ -258,6 +285,53 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest {
assertEquals
(
someValue
,
bean
.
getNestedProperty
());
}
@Test
public
void
testApolloJsonValue
()
{
String
someJson
=
"[{\"a\":\"astring\", \"b\":10},{\"a\":\"astring2\", \"b\":20}]"
;
String
otherJson
=
"[{\"a\":\"otherString\", \"b\":10},{\"a\":\"astring2\", \"b\":20}]"
;
Config
config
=
mock
(
Config
.
class
);
when
(
config
.
getProperty
(
eq
(
JSON_PROPERTY
),
anyString
())).
thenReturn
(
someJson
);
when
(
config
.
getProperty
(
eq
(
OTHER_JSON_PROPERTY
),
anyString
())).
thenReturn
(
otherJson
);
when
(
config
.
getProperty
(
eq
(
"a"
),
anyString
())).
thenReturn
(
JSON_PROPERTY
);
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
config
);
AnnotationConfigApplicationContext
context
=
new
AnnotationConfigApplicationContext
(
AppConfig8
.
class
);
TestJsonPropertyBean
testJsonPropertyBean
=
context
.
getBean
(
TestJsonPropertyBean
.
class
);
assertEquals
(
2
,
testJsonPropertyBean
.
getJsonBeanList
().
size
());
assertEquals
(
"astring"
,
testJsonPropertyBean
.
getJsonBeanList
().
get
(
0
).
getA
());
assertEquals
(
10
,
testJsonPropertyBean
.
getJsonBeanList
().
get
(
0
).
getB
());
assertEquals
(
"astring2"
,
testJsonPropertyBean
.
getJsonBeanList
().
get
(
1
).
getA
());
assertEquals
(
20
,
testJsonPropertyBean
.
getJsonBeanList
().
get
(
1
).
getB
());
assertEquals
(
testJsonPropertyBean
.
getJsonBeanList
(),
testJsonPropertyBean
.
getEmbeddedJsonBeanList
());
assertEquals
(
"otherString"
,
testJsonPropertyBean
.
getOtherJsonBeanList
().
get
(
0
).
getA
());
assertEquals
(
10
,
testJsonPropertyBean
.
getOtherJsonBeanList
().
get
(
0
).
getB
());
assertEquals
(
"astring2"
,
testJsonPropertyBean
.
getOtherJsonBeanList
().
get
(
1
).
getA
());
assertEquals
(
20
,
testJsonPropertyBean
.
getOtherJsonBeanList
().
get
(
1
).
getB
());
}
@Test
(
expected
=
BeanCreationException
.
class
)
public
void
testApolloJsonValueWithInvalidJson
()
throws
Exception
{
String
someInvalidJson
=
"someInvalidJson"
;
Config
config
=
mock
(
Config
.
class
);
when
(
config
.
getProperty
(
eq
(
JSON_PROPERTY
),
anyString
())).
thenReturn
(
someInvalidJson
);
when
(
config
.
getProperty
(
eq
(
OTHER_JSON_PROPERTY
),
anyString
())).
thenReturn
(
someInvalidJson
);
when
(
config
.
getProperty
(
eq
(
"a"
),
anyString
())).
thenReturn
(
JSON_PROPERTY
);
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
config
);
new
AnnotationConfigApplicationContext
(
AppConfig8
.
class
).
getBean
(
TestJsonPropertyBean
.
class
);
}
@Test
(
expected
=
BeanCreationException
.
class
)
public
void
testApolloJsonValueWithNoPropertyValue
()
throws
Exception
{
Config
config
=
mock
(
Config
.
class
);
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
config
);
new
AnnotationConfigApplicationContext
(
AppConfig8
.
class
);
}
private
void
check
(
int
expectedTimeout
,
int
expectedBatch
,
Class
<?>...
annotatedClasses
)
{
AnnotationConfigApplicationContext
context
=
new
AnnotationConfigApplicationContext
(
annotatedClasses
);
...
...
@@ -323,6 +397,14 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest {
}
}
@Configuration
@ComponentScan
(
includeFilters
=
{
@Filter
(
type
=
FilterType
.
ANNOTATION
,
value
=
{
Component
.
class
})},
excludeFilters
=
{
@Filter
(
type
=
FilterType
.
ANNOTATION
,
value
=
{
Configuration
.
class
})})
@EnableApolloConfig
static
class
AppConfig7
{
}
@Configuration
@EnableApolloConfig
static
class
NestedPropertyConfig1
{
...
...
@@ -332,6 +414,15 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest {
}
}
@Configuration
@EnableApolloConfig
static
class
AppConfig8
{
@Bean
TestJsonPropertyBean
testJavaConfigBean
()
{
return
new
TestJsonPropertyBean
();
}
}
@Component
static
class
TestJavaConfigBean
{
...
...
@@ -374,6 +465,27 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest {
}
}
@Component
static
class
TestJavaConfigBean3
{
private
final
int
timeout
;
private
final
int
batch
;
@Autowired
public
TestJavaConfigBean3
(
@Value
(
"${timeout:100}"
)
int
timeout
,
@Value
(
"${batch:200}"
)
int
batch
)
{
this
.
timeout
=
timeout
;
this
.
batch
=
batch
;
}
public
int
getTimeout
()
{
return
timeout
;
}
public
int
getBatch
()
{
return
batch
;
}
}
static
class
TestNestedPropertyBean
{
@Value
(
"${${a}.${b}:${c:100}}"
)
...
...
@@ -384,4 +496,80 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest {
}
}
static
class
TestJsonPropertyBean
{
@ApolloJsonValue
(
"${jsonProperty}"
)
private
List
<
JsonBean
>
jsonBeanList
;
private
List
<
JsonBean
>
otherJsonBeanList
;
@ApolloJsonValue
(
"${${a}}"
)
private
List
<
JsonBean
>
embeddedJsonBeanList
;
public
List
<
JsonBean
>
getJsonBeanList
()
{
return
jsonBeanList
;
}
@ApolloJsonValue
(
"${otherJsonProperty}"
)
public
void
setOtherJsonBeanList
(
List
<
JsonBean
>
otherJsonBeanList
)
{
this
.
otherJsonBeanList
=
otherJsonBeanList
;
}
public
List
<
JsonBean
>
getOtherJsonBeanList
()
{
return
otherJsonBeanList
;
}
public
List
<
JsonBean
>
getEmbeddedJsonBeanList
()
{
return
embeddedJsonBeanList
;
}
}
static
class
JsonBean
{
private
String
a
;
private
int
b
;
String
getA
()
{
return
a
;
}
public
void
setA
(
String
a
)
{
this
.
a
=
a
;
}
int
getB
()
{
return
b
;
}
public
void
setB
(
int
b
)
{
this
.
b
=
b
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
{
return
true
;
}
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
{
return
false
;
}
JsonBean
jsonBean
=
(
JsonBean
)
o
;
if
(
b
!=
jsonBean
.
b
)
{
return
false
;
}
return
a
!=
null
?
a
.
equals
(
jsonBean
.
a
)
:
jsonBean
.
a
==
null
;
}
@Override
public
int
hashCode
()
{
int
result
=
a
!=
null
?
a
.
hashCode
()
:
0
;
result
=
31
*
result
+
b
;
return
result
;
}
}
}
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XMLConfigAnnotationTest.java
View file @
72a37b66
...
...
@@ -86,7 +86,8 @@ public class XMLConfigAnnotationTest extends AbstractSpringIntegrationTest {
TestApolloConfigChangeListenerBean1
bean
=
getBean
(
"spring/XmlConfigAnnotationTest3.xml"
,
TestApolloConfigChangeListenerBean1
.
class
);
assertEquals
(
3
,
applicationListeners
.
size
());
//PropertySourcesProcessor add listeners to listen config changed of all namespace
assertEquals
(
4
,
applicationListeners
.
size
());
assertEquals
(
1
,
fxApolloListeners
.
size
());
for
(
ConfigChangeListener
listener
:
applicationListeners
)
{
...
...
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XmlConfigPlaceholderAutoUpdateTest.java
0 → 100644
View file @
72a37b66
This diff is collapsed.
Click to expand it.
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/config/ConfigPropertySourceTest.java
0 → 100644
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
config
;
import
static
org
.
junit
.
Assert
.
assertArrayEquals
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
mockito
.
Matchers
.
any
;
import
static
org
.
mockito
.
Mockito
.
doAnswer
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.ConfigChangeListener
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Sets
;
import
java.util.List
;
import
java.util.Set
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.mockito.Mock
;
import
org.mockito.invocation.InvocationOnMock
;
import
org.mockito.runners.MockitoJUnitRunner
;
import
org.mockito.stubbing.Answer
;
@RunWith
(
MockitoJUnitRunner
.
class
)
public
class
ConfigPropertySourceTest
{
private
ConfigPropertySource
configPropertySource
;
@Mock
private
Config
someConfig
;
@Before
public
void
setUp
()
throws
Exception
{
String
someName
=
"someName"
;
configPropertySource
=
new
ConfigPropertySource
(
someName
,
someConfig
);
}
@Test
public
void
testGetPropertyNames
()
throws
Exception
{
String
somePropertyName
=
"somePropertyName"
;
String
anotherPropertyName
=
"anotherPropertyName"
;
Set
<
String
>
somePropertyNames
=
Sets
.
newHashSet
(
somePropertyName
,
anotherPropertyName
);
when
(
someConfig
.
getPropertyNames
()).
thenReturn
(
somePropertyNames
);
String
[]
result
=
configPropertySource
.
getPropertyNames
();
verify
(
someConfig
,
times
(
1
)).
getPropertyNames
();
assertArrayEquals
(
somePropertyNames
.
toArray
(),
result
);
}
@Test
public
void
testGetEmptyPropertyNames
()
throws
Exception
{
when
(
someConfig
.
getPropertyNames
()).
thenReturn
(
Sets
.<
String
>
newHashSet
());
assertEquals
(
0
,
configPropertySource
.
getPropertyNames
().
length
);
}
@Test
public
void
testGetProperty
()
throws
Exception
{
String
somePropertyName
=
"somePropertyName"
;
String
someValue
=
"someValue"
;
when
(
someConfig
.
getProperty
(
somePropertyName
,
null
)).
thenReturn
(
someValue
);
assertEquals
(
someValue
,
configPropertySource
.
getProperty
(
somePropertyName
));
verify
(
someConfig
,
times
(
1
)).
getProperty
(
somePropertyName
,
null
);
}
@Test
public
void
testAddChangeListener
()
throws
Exception
{
ConfigChangeListener
someListener
=
mock
(
ConfigChangeListener
.
class
);
ConfigChangeListener
anotherListener
=
mock
(
ConfigChangeListener
.
class
);
final
List
<
ConfigChangeListener
>
listeners
=
Lists
.
newArrayList
();
doAnswer
(
new
Answer
()
{
@Override
public
Object
answer
(
InvocationOnMock
invocation
)
throws
Throwable
{
listeners
.
add
(
invocation
.
getArgumentAt
(
0
,
ConfigChangeListener
.
class
));
return
Void
.
class
;
}
}).
when
(
someConfig
).
addChangeListener
(
any
(
ConfigChangeListener
.
class
));
configPropertySource
.
addChangeListener
(
someListener
);
configPropertySource
.
addChangeListener
(
anotherListener
);
assertEquals
(
2
,
listeners
.
size
());
assertTrue
(
listeners
.
containsAll
(
Lists
.
newArrayList
(
someListener
,
anotherListener
)));
}
}
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/property/PlaceholderHelperTest.java
0 → 100644
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
property
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
com.google.common.collect.Sets
;
import
org.junit.Before
;
import
org.junit.Test
;
public
class
PlaceholderHelperTest
{
private
PlaceholderHelper
placeholderHelper
;
@Before
public
void
setUp
()
throws
Exception
{
placeholderHelper
=
new
PlaceholderHelper
();
}
@Test
public
void
testExtractPlaceholderKeys
()
throws
Exception
{
check
(
"${some.key}"
,
"some.key"
);
check
(
"${some.key:100}"
,
"some.key"
);
check
(
"${some.key:${some.other.key}}"
,
"some.key"
,
"some.other.key"
);
check
(
"${some.key:${some.other.key:100}}"
,
"some.key"
,
"some.other.key"
);
}
@Test
public
void
testExtractNestedPlaceholderKeys
()
throws
Exception
{
check
(
"${${some.key}}"
,
"some.key"
);
check
(
"${${some.key:other.key}}"
,
"some.key"
);
check
(
"${${some.key}:100}"
,
"some.key"
);
check
(
"${${some.key}:${another.key}}"
,
"some.key"
,
"another.key"
);
}
@Test
public
void
testExtractComplexNestedPlaceholderKeys
()
throws
Exception
{
check
(
"${${a}1${b}:3.${c:${d:100}}}"
,
"a"
,
"b"
,
"c"
,
"d"
);
check
(
"${1${a}2${b}3:4.${c:5${d:100}6}7}"
,
"a"
,
"b"
,
"c"
,
"d"
);
}
@Test
public
void
testExtractPlaceholderKeysFromExpression
()
throws
Exception
{
check
(
"#{new java.text.SimpleDateFormat('${some.key}').parse('${another.key}')}"
,
"some.key"
,
"another.key"
);
check
(
"#{new java.text.SimpleDateFormat('${some.key:abc}').parse('${another.key:100}')}"
,
"some.key"
,
"another.key"
);
check
(
"#{new java.text.SimpleDateFormat('${some.key:${some.other.key}}').parse('${another.key}')}"
,
"some.key"
,
"another.key"
,
"some.other.key"
);
check
(
"#{new java.text.SimpleDateFormat('${some.key:${some.other.key:abc}}').parse('${another.key}')}"
,
"some.key"
,
"another.key"
,
"some.other.key"
);
check
(
"#{new java.text.SimpleDateFormat('${${some.key}}').parse('${${another.key:other.key}}')}"
,
"some.key"
,
"another.key"
);
assertTrue
(
placeholderHelper
.
extractPlaceholderKeys
(
"#{systemProperties[some.key] ?: 123}"
).
isEmpty
());
assertTrue
(
placeholderHelper
.
extractPlaceholderKeys
(
"#{ T(java.lang.Math).random() * 100.0 }"
).
isEmpty
());
}
@Test
public
void
testExtractInvalidPlaceholderKeys
()
throws
Exception
{
assertTrue
(
placeholderHelper
.
extractPlaceholderKeys
(
"some.key"
).
isEmpty
());
assertTrue
(
placeholderHelper
.
extractPlaceholderKeys
(
"some.key:100"
).
isEmpty
());
}
private
void
check
(
String
propertyString
,
String
...
expectedPlaceholders
)
{
assertEquals
(
Sets
.
newHashSet
(
expectedPlaceholders
),
placeholderHelper
.
extractPlaceholderKeys
(
propertyString
));
}
}
apollo-client/src/test/java/com/ctrip/framework/apollo/util/ConfigUtilTest.java
View file @
72a37b66
...
...
@@ -3,7 +3,6 @@ package com.ctrip.framework.apollo.util;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.Test
;
import
static
org
.
junit
.
Assert
.*;
...
...
@@ -22,6 +21,7 @@ public class ConfigUtilTest {
System
.
clearProperty
(
"apollo.longPollQPS"
);
System
.
clearProperty
(
"apollo.configCacheSize"
);
System
.
clearProperty
(
"apollo.longPollingInitialDelayInMills"
);
System
.
clearProperty
(
"apollo.autoUpdateInjectedSpringProperties"
);
}
@Test
...
...
@@ -173,4 +173,16 @@ public class ConfigUtilTest {
assertTrue
(
configUtil
.
getLongPollingInitialDelayInMills
()
>
0
);
}
}
\ No newline at end of file
@Test
public
void
testCustomizeAutoUpdateInjectedSpringProperties
()
throws
Exception
{
boolean
someAutoUpdateInjectedSpringProperties
=
false
;
System
.
setProperty
(
"apollo.autoUpdateInjectedSpringProperties"
,
String
.
valueOf
(
someAutoUpdateInjectedSpringProperties
));
ConfigUtil
configUtil
=
new
ConfigUtil
();
assertEquals
(
someAutoUpdateInjectedSpringProperties
,
configUtil
.
isAutoUpdateInjectedSpringPropertiesEnabled
());
}
}
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest10.xml
0 → 100644
View file @
72a37b66
<?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
/>
<bean
class=
"com.ctrip.framework.apollo.spring.XmlConfigPlaceholderAutoUpdateTest.TestAllKindsOfDataTypesBean"
>
<property
name=
"intProperty"
value=
"${intProperty}"
/>
<property
name=
"intArrayProperty"
value=
"${intArrayProperty}"
/>
<property
name=
"longProperty"
value=
"${longProperty}"
/>
<property
name=
"shortProperty"
value=
"${shortProperty}"
/>
<property
name=
"floatProperty"
value=
"${floatProperty}"
/>
<property
name=
"doubleProperty"
value=
"${doubleProperty}"
/>
<property
name=
"byteProperty"
value=
"${byteProperty}"
/>
<property
name=
"booleanProperty"
value=
"${booleanProperty}"
/>
<property
name=
"stringProperty"
value=
"${stringProperty}"
/>
<property
name=
"dateProperty"
value=
"#{new java.text.SimpleDateFormat('${dateFormat}').parse('${dateProperty}')}"
/>
</bean>
</beans>
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest7.xml
0 → 100644
View file @
72a37b66
<?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
/>
<bean
class=
"com.ctrip.framework.apollo.spring.XmlConfigPlaceholderTest.TestXmlBean"
>
<property
name=
"timeout"
value=
"${timeout}"
/>
<property
name=
"batch"
value=
"${batch}"
/>
</bean>
</beans>
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest8.xml
0 → 100644
View file @
72a37b66
<?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
/>
<bean
class=
"com.ctrip.framework.apollo.spring.XmlConfigPlaceholderAutoUpdateTest.TestXmlBeanWithConstructorArgs"
>
<constructor-arg
index=
"0"
value=
"${timeout}"
/>
<constructor-arg
index=
"1"
value=
"${batch}"
/>
</bean>
</beans>
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest9.xml
0 → 100644
View file @
72a37b66
<?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:context=
"http://www.springframework.org/schema/context"
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.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.ctrip.com/schema/apollo http://www.ctrip.com/schema/apollo.xsd"
>
<context:annotation-config
/>
<apollo:config/>
<bean
class=
"com.ctrip.framework.apollo.spring.XmlConfigPlaceholderAutoUpdateTest.TestXmlBeanWithInjectedValue"
>
<property
name=
"batch"
value=
"${batch}"
/>
</bean>
</beans>
apollo-common/src/test/java/com/ctrip/framework/apollo/common/AllTests.java
deleted
100644 → 0
View file @
45290409
package
com
.
ctrip
.
framework
.
apollo
.
common
;
import
com.ctrip.framework.apollo.common.conditional.ConditionalOnProfileTest
;
import
com.ctrip.framework.apollo.common.utils.InputValidatorTest
;
import
org.junit.runner.RunWith
;
import
org.junit.runners.Suite
;
import
org.junit.runners.Suite.SuiteClasses
;
@RunWith
(
Suite
.
class
)
@SuiteClasses
({
InputValidatorTest
.
class
,
ConditionalOnProfileTest
.
class
})
public
class
AllTests
{
}
apollo-configservice/src/main/docker/Dockerfile
View file @
72a37b66
...
...
@@ -7,7 +7,7 @@
FROM
openjdk:8-jre-alpine
MAINTAINER
ameizi <sxyx2008@163.com>
ENV
VERSION 0.
9.0
ENV
VERSION 0.
10.0-SNAPSHOT
RUN
echo
"http://mirrors.aliyun.com/alpine/v3.6/main"
>
/etc/apk/repositories
\
&&
echo
"http://mirrors.aliyun.com/alpine/v3.6/community"
>>
/etc/apk/repositories
\
...
...
apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/wrapper/DeferredResultWrapper.java
View file @
72a37b66
...
...
@@ -17,7 +17,7 @@ import java.util.Map;
* @author Jason Song(song_s@ctrip.com)
*/
public
class
DeferredResultWrapper
{
private
static
final
long
TIMEOUT
=
30
*
1000
;
//3
0 seconds
private
static
final
long
TIMEOUT
=
60
*
1000
;
//6
0 seconds
private
static
final
ResponseEntity
<
List
<
ApolloConfigNotification
>>
NOT_MODIFIED_RESPONSE_LIST
=
new
ResponseEntity
<>(
HttpStatus
.
NOT_MODIFIED
);
...
...
apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/AllTests.java
deleted
100644 → 0
View file @
45290409
package
com
.
ctrip
.
framework
.
apollo
.
configservice
;
import
com.ctrip.framework.apollo.configservice.controller.ConfigControllerTest
;
import
com.ctrip.framework.apollo.configservice.controller.ConfigFileControllerTest
;
import
com.ctrip.framework.apollo.configservice.controller.NotificationControllerTest
;
import
com.ctrip.framework.apollo.configservice.controller.NotificationControllerV2Test
;
import
com.ctrip.framework.apollo.configservice.integration.ConfigControllerIntegrationTest
;
import
com.ctrip.framework.apollo.configservice.integration.ConfigFileControllerIntegrationTest
;
import
com.ctrip.framework.apollo.configservice.integration.NotificationControllerIntegrationTest
;
import
com.ctrip.framework.apollo.configservice.integration.NotificationControllerV2IntegrationTest
;
import
com.ctrip.framework.apollo.configservice.service.AppNamespaceServiceWithCacheTest
;
import
com.ctrip.framework.apollo.configservice.service.ReleaseMessageServiceWithCacheTest
;
import
com.ctrip.framework.apollo.configservice.service.config.ConfigServiceWithCacheTest
;
import
com.ctrip.framework.apollo.configservice.service.config.DefaultConfigServiceTest
;
import
com.ctrip.framework.apollo.configservice.util.InstanceConfigAuditUtilTest
;
import
com.ctrip.framework.apollo.configservice.util.NamespaceUtilTest
;
import
com.ctrip.framework.apollo.configservice.util.WatchKeysUtilTest
;
import
com.ctrip.framework.apollo.configservice.wrapper.CaseInsensitiveMapWrapperTest
;
import
org.junit.runner.RunWith
;
import
org.junit.runners.Suite
;
import
org.junit.runners.Suite.SuiteClasses
;
@RunWith
(
Suite
.
class
)
@SuiteClasses
({
ConfigControllerTest
.
class
,
NotificationControllerTest
.
class
,
ConfigControllerIntegrationTest
.
class
,
NotificationControllerIntegrationTest
.
class
,
NamespaceUtilTest
.
class
,
ConfigFileControllerTest
.
class
,
ConfigFileControllerIntegrationTest
.
class
,
WatchKeysUtilTest
.
class
,
NotificationControllerV2Test
.
class
,
NotificationControllerV2IntegrationTest
.
class
,
InstanceConfigAuditUtilTest
.
class
,
AppNamespaceServiceWithCacheTest
.
class
,
ReleaseMessageServiceWithCacheTest
.
class
,
DefaultConfigServiceTest
.
class
,
ConfigServiceWithCacheTest
.
class
,
CaseInsensitiveMapWrapperTest
.
class
})
public
class
AllTests
{
}
apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/controller/NotificationControllerV2Test.java
View file @
72a37b66
...
...
@@ -35,6 +35,7 @@ import java.util.Objects;
import
java.util.concurrent.TimeUnit
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
times
;
...
...
@@ -342,11 +343,13 @@ public class NotificationControllerV2Test {
controller
.
handleMessage
(
someReleaseMessage
,
Topics
.
APOLLO_RELEASE_TOPIC
);
assertTrue
(!
anotherDeferredResult
.
hasResult
());
//in batch mode, at most one of them should have result
assertFalse
(
deferredResult
.
hasResult
()
&&
anotherDeferredResult
.
hasResult
());
TimeUnit
.
MILLISECONDS
.
sleep
(
someBatchInterval
*
10
);
assertTrue
(
anotherDeferredResult
.
hasResult
());
//now both of them should have result
assertTrue
(
deferredResult
.
hasResult
()
&&
anotherDeferredResult
.
hasResult
());
}
private
String
transformApolloConfigNotificationsToString
(
...
...
apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/integration/AbstractBaseIntegrationTest.java
View file @
72a37b66
...
...
@@ -114,7 +114,8 @@ public abstract class AbstractBaseIntegrationTest {
private
static
class
TestBizConfig
extends
BizConfig
{
@Override
public
int
appNamespaceCacheScanInterval
()
{
return
50
;
//should be short enough to update the AppNamespace cache in time
return
1
;
}
@Override
...
...
apollo-core/src/test/java/com/ctrip/framework/apollo/AllTests.java
deleted
100644 → 0
View file @
45290409
package
com
.
ctrip
.
framework
.
apollo
;
import
com.ctrip.framework.apollo.foundation.FoundationTest
;
import
com.ctrip.framework.apollo.foundation.internals.ServiceBootstrapTest
;
import
org.junit.runner.RunWith
;
import
org.junit.runners.Suite
;
import
org.junit.runners.Suite.SuiteClasses
;
import
com.ctrip.framework.apollo.core.MetaDomainTest
;
import
com.ctrip.framework.apollo.foundation.internals.provider.DefaultApplicationProviderTest
;
import
com.ctrip.framework.apollo.foundation.internals.provider.DefaultServerProviderTest
;
import
com.ctrip.framework.apollo.tracer.TracerTest
;
import
com.ctrip.framework.apollo.tracer.internals.DefaultMessageProducerManagerTest
;
import
com.ctrip.framework.apollo.tracer.internals.NullMessageProducerManagerTest
;
import
com.ctrip.framework.apollo.tracer.internals.NullMessageProducerTest
;
@RunWith
(
Suite
.
class
)
@SuiteClasses
({
MetaDomainTest
.
class
,
ServiceBootstrapTest
.
class
,
NullMessageProducerManagerTest
.
class
,
NullMessageProducerTest
.
class
,
DefaultMessageProducerManagerTest
.
class
,
TracerTest
.
class
,
DefaultApplicationProviderTest
.
class
,
DefaultServerProviderTest
.
class
,
FoundationTest
.
class
})
public
class
AllTests
{
}
apollo-core/src/test/resources/META-INF/some-invalid-app.properties
View file @
72a37b66
appid
=
110402
\ No newline at end of file
appid
=
110402
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/api/ApolloConfigDemo.java
View file @
72a37b66
...
...
@@ -46,7 +46,7 @@ public class ApolloConfigDemo {
};
config
=
ConfigService
.
getAppConfig
();
config
.
addChangeListener
(
changeListener
);
publicConfig
=
ConfigService
.
getConfig
(
"
FX
.apollo"
);
publicConfig
=
ConfigService
.
getConfig
(
"
TEST1
.apollo"
);
publicConfig
.
addChangeListener
(
changeListener
);
applicationConfigFile
=
ConfigService
.
getConfigFile
(
"application"
,
ConfigFileFormat
.
Properties
);
xmlConfigFile
=
ConfigService
.
getConfigFile
(
"datasources"
,
ConfigFileFormat
.
XML
);
...
...
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/common/bean/AnnotatedBean.java
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
demo
.
spring
.
common
.
bean
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue
;
import
java.util.List
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.cloud.context.config.annotation.RefreshScope
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.PostConstruct
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@RefreshScope
@Component
(
"annotatedBean"
)
public
class
AnnotatedBean
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
AnnotatedBean
.
class
);
@Value
(
"${timeout:200}"
)
private
int
timeout
;
private
int
batch
;
private
List
<
JsonBean
>
jsonBeans
;
@PostConstruct
void
initialize
()
{
logger
.
info
(
"timeout is initialized as {}"
,
timeout
);
logger
.
info
(
"batch is initialized as {}"
,
batch
);
}
/**
* ApolloJsonValue annotated on fields example, the default value is specified as empty list - []
* <br />
* jsonBeanProperty=[{"someString":"hello","someInt":100},{"someString":"world!","someInt":200}]
*/
@ApolloJsonValue
(
"${jsonBeanProperty:[]}"
)
private
List
<
JsonBean
>
anotherJsonBeans
;
@Value
(
"${batch:100}"
)
public
void
setBatch
(
int
batch
)
{
logger
.
info
(
"updating batch, old value: {}, new value: {}"
,
this
.
batch
,
batch
);
this
.
batch
=
batch
;
}
@Value
(
"${timeout:200}"
)
public
void
setTimeout
(
int
timeout
)
{
logger
.
info
(
"updating timeout, old value: {}, new value: {}"
,
this
.
timeout
,
timeout
);
this
.
timeout
=
timeout
;
}
/**
* ApolloJsonValue annotated on methods example, the default value is specified as empty list - []
* <br />
* jsonBeanProperty=[{"someString":"hello","someInt":100},{"someString":"world!","someInt":200}]
*/
@ApolloJsonValue
(
"${jsonBeanProperty:[]}"
)
public
void
setJsonBeans
(
List
<
JsonBean
>
jsonBeans
)
{
logger
.
info
(
"updating json beans, old value: {}, new value: {}"
,
this
.
jsonBeans
,
jsonBeans
);
this
.
jsonBeans
=
jsonBeans
;
}
@Override
public
String
toString
()
{
return
String
.
format
(
"[AnnotatedBean] timeout: %d, batch: %d"
,
timeout
,
batch
);
return
String
.
format
(
"[AnnotatedBean] timeout: %d, batch: %d, jsonBeans: %s"
,
timeout
,
batch
,
jsonBeans
);
}
private
static
class
JsonBean
{
private
String
someString
;
private
int
someInt
;
@Override
public
String
toString
()
{
return
"JsonBean{"
+
"someString='"
+
someString
+
'\''
+
", someInt="
+
someInt
+
'}'
;
}
}
}
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/common/config/AnotherAppConfig.java
View file @
72a37b66
...
...
@@ -8,6 +8,6 @@ import org.springframework.context.annotation.Configuration;
* @author Jason Song(song_s@ctrip.com)
*/
@Configuration
@EnableApolloConfig
(
value
=
"
FX
.apollo"
,
order
=
11
)
@EnableApolloConfig
(
value
=
"
TEST1
.apollo"
,
order
=
11
)
public
class
AnotherAppConfig
{
}
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/common/refresh/ApolloRefreshConfig.java
deleted
100644 → 0
View file @
45290409
package
com
.
ctrip
.
framework
.
apollo
.
demo
.
spring
.
common
.
refresh
;
import
com.ctrip.framework.apollo.demo.spring.common.bean.AnnotatedBean
;
import
com.ctrip.framework.apollo.model.ConfigChangeEvent
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.cloud.context.scope.refresh.RefreshScope
;
import
org.springframework.stereotype.Component
;
/**
* To refresh the config bean when config is changed
*
* @author Jason Song(song_s@ctrip.com)
*/
@Component
public
class
ApolloRefreshConfig
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
ApolloRefreshConfig
.
class
);
@Autowired
private
RefreshScope
refreshScope
;
@Autowired
private
AnnotatedBean
annotatedBean
;
@ApolloConfigChangeListener
({
"application"
,
"FX.apollo"
})
private
void
onChange
(
ConfigChangeEvent
changeEvent
)
{
if
(
changeEvent
.
isChanged
(
"timeout"
)
||
changeEvent
.
isChanged
(
"batch"
))
{
logger
.
info
(
"before refresh {}"
,
annotatedBean
.
toString
());
//could also call refreshScope.refreshAll();
refreshScope
.
refresh
(
"annotatedBean"
);
logger
.
info
(
"after refresh {}"
,
annotatedBean
.
toString
());
}
}
}
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/javaConfigDemo/AnnotationApplication.java
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
demo
.
spring
.
javaConfigDemo
;
import
com.ctrip.framework.apollo.demo.spring.common.bean.AnnotatedBean
;
import
com.google.common.base.Charsets
;
import
com.google.common.base.Strings
;
import
java.io.BufferedReader
;
import
java.io.IOException
;
import
java.io.InputStreamReader
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.annotation.AnnotationConfigApplicationContext
;
import
java.util.Scanner
;
...
...
@@ -8,14 +15,19 @@ import java.util.Scanner;
* @author Jason Song(song_s@ctrip.com)
*/
public
class
AnnotationApplication
{
public
static
void
main
(
String
[]
args
)
{
new
AnnotationConfigApplicationContext
(
"com.ctrip.framework.apollo.demo.spring.common"
,
"com.ctrip.framework.apollo.demo.spring.javaConfigDemo"
);
onKeyExit
();
}
public
static
void
main
(
String
[]
args
)
throws
IOException
{
ApplicationContext
context
=
new
AnnotationConfigApplicationContext
(
"com.ctrip.framework.apollo.demo.spring.common"
);
AnnotatedBean
annotatedBean
=
context
.
getBean
(
AnnotatedBean
.
class
);
System
.
out
.
println
(
"AnnotationApplication Demo. Input any key except quit to print the values. Input quit to exit."
);
while
(
true
)
{
System
.
out
.
print
(
"> "
);
String
input
=
new
BufferedReader
(
new
InputStreamReader
(
System
.
in
,
Charsets
.
UTF_8
)).
readLine
();
if
(!
Strings
.
isNullOrEmpty
(
input
)
&&
input
.
trim
().
equalsIgnoreCase
(
"quit"
))
{
System
.
exit
(
0
);
}
private
static
void
onKeyExit
()
{
System
.
out
.
println
(
"Press Enter to exit..."
);
new
Scanner
(
System
.
in
).
nextLine
();
System
.
out
.
println
(
annotatedBean
.
toString
());
}
}
}
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/javaConfigDemo/config/RefreshScopeConfig.java
deleted
100644 → 0
View file @
45290409
package
com
.
ctrip
.
framework
.
apollo
.
demo
.
spring
.
javaConfigDemo
.
config
;
import
org.springframework.cloud.autoconfigure.RefreshAutoConfiguration
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Import
;
/**
* to support RefreshScope
* @author Jason Song(song_s@ctrip.com)
*/
@Configuration
@Import
(
RefreshAutoConfiguration
.
class
)
public
class
RefreshScopeConfig
{
}
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/springBootDemo/SpringBootSampleApplication.java
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
demo
.
spring
.
springBootDemo
;
import
com.ctrip.framework.apollo.demo.spring.springBootDemo.config.SampleRedisConfig
;
import
java.io.BufferedReader
;
import
java.io.IOException
;
import
java.io.InputStreamReader
;
import
org.springframework.beans.factory.NoSuchBeanDefinitionException
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
import
org.springframework.boot.builder.SpringApplicationBuilder
;
import
org.springframework.context.ApplicationContext
;
import
java.util.Scanner
;
import
com.ctrip.framework.apollo.demo.spring.common.bean.AnnotatedBean
;
import
com.google.common.base.Charsets
;
import
com.google.common.base.Strings
;
/**
* @author Jason Song(song_s@ctrip.com)
...
...
@@ -13,13 +22,28 @@ import java.util.Scanner;
})
public
class
SpringBootSampleApplication
{
public
static
void
main
(
String
[]
args
)
{
new
SpringApplicationBuilder
(
SpringBootSampleApplication
.
class
).
run
(
args
);
onKeyExit
();
}
public
static
void
main
(
String
[]
args
)
throws
IOException
{
ApplicationContext
context
=
new
SpringApplicationBuilder
(
SpringBootSampleApplication
.
class
).
run
(
args
);
AnnotatedBean
annotatedBean
=
context
.
getBean
(
AnnotatedBean
.
class
);
SampleRedisConfig
redisConfig
=
null
;
try
{
redisConfig
=
context
.
getBean
(
SampleRedisConfig
.
class
);
}
catch
(
NoSuchBeanDefinitionException
ex
)
{
System
.
out
.
println
(
"SampleRedisConfig is null, 'redis.cache.enabled' must have been set to false."
);
}
System
.
out
.
println
(
"SpringBootSampleApplication Demo. Input any key except quit to print the values. Input quit to exit."
);
while
(
true
)
{
System
.
out
.
print
(
"> "
);
String
input
=
new
BufferedReader
(
new
InputStreamReader
(
System
.
in
,
Charsets
.
UTF_8
)).
readLine
();
if
(!
Strings
.
isNullOrEmpty
(
input
)
&&
input
.
trim
().
equalsIgnoreCase
(
"quit"
))
{
System
.
exit
(
0
);
}
private
static
void
onKeyExit
()
{
System
.
out
.
println
(
"Press Enter to exit..."
);
new
Scanner
(
System
.
in
).
nextLine
();
System
.
out
.
println
(
annotatedBean
.
toString
());
if
(
redisConfig
!=
null
)
{
System
.
out
.
println
(
redisConfig
.
toString
());
}
}
}
}
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/springBootDemo/refresh/SpringBootApolloRefreshConfig.java
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
demo
.
spring
.
springBootDemo
.
refresh
;
import
com.ctrip.framework.apollo.demo.spring.common.refresh.ApolloRefreshConfig
;
import
com.ctrip.framework.apollo.demo.spring.springBootDemo.config.SampleRedisConfig
;
import
com.ctrip.framework.apollo.model.ConfigChangeEvent
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
...
...
@@ -12,6 +7,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import
org.springframework.cloud.context.scope.refresh.RefreshScope
;
import
org.springframework.stereotype.Component
;
import
com.ctrip.framework.apollo.demo.spring.springBootDemo.config.SampleRedisConfig
;
import
com.ctrip.framework.apollo.model.ConfigChangeEvent
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
...
...
@@ -20,9 +19,6 @@ import org.springframework.stereotype.Component;
public
class
SpringBootApolloRefreshConfig
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
SpringBootApolloRefreshConfig
.
class
);
@Autowired
private
ApolloRefreshConfig
apolloRefreshConfig
;
@Autowired
private
SampleRedisConfig
sampleRedisConfig
;
...
...
@@ -31,6 +27,17 @@ public class SpringBootApolloRefreshConfig {
@ApolloConfigChangeListener
public
void
onChange
(
ConfigChangeEvent
changeEvent
)
{
boolean
redisCacheKeysChanged
=
false
;
for
(
String
changedKey
:
changeEvent
.
changedKeys
())
{
if
(
changedKey
.
startsWith
(
"redis.cache"
))
{
redisCacheKeysChanged
=
true
;
break
;
}
}
if
(!
redisCacheKeysChanged
)
{
return
;
}
logger
.
info
(
"before refresh {}"
,
sampleRedisConfig
.
toString
());
refreshScope
.
refresh
(
"sampleRedisConfig"
);
logger
.
info
(
"after refresh {}"
,
sampleRedisConfig
.
toString
());
...
...
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/xmlConfigDemo/XmlApplication.java
View file @
72a37b66
package
com
.
ctrip
.
framework
.
apollo
.
demo
.
spring
.
xmlConfigDemo
;
import
com.google.common.base.Strings
;
import
java.io.BufferedReader
;
import
java.io.IOException
;
import
java.io.InputStreamReader
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.support.ClassPathXmlApplicationContext
;
import
java.util.Scanner
;
import
com.ctrip.framework.apollo.demo.spring.xmlConfigDemo.bean.XmlBean
;
import
com.google.common.base.Charsets
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
class
XmlApplication
{
public
static
void
main
(
String
[]
args
)
{
new
ClassPathXmlApplicationContext
(
"spring.xml"
);
onKeyExit
();
}
public
static
void
main
(
String
[]
args
)
throws
IOException
{
ApplicationContext
context
=
new
ClassPathXmlApplicationContext
(
"spring.xml"
);
XmlBean
xmlBean
=
context
.
getBean
(
XmlBean
.
class
);
System
.
out
.
println
(
"XmlApplication Demo. Input any key except quit to print the values. Input quit to exit."
);
while
(
true
)
{
System
.
out
.
print
(
"> "
);
String
input
=
new
BufferedReader
(
new
InputStreamReader
(
System
.
in
,
Charsets
.
UTF_8
)).
readLine
();
if
(!
Strings
.
isNullOrEmpty
(
input
)
&&
input
.
trim
().
equalsIgnoreCase
(
"quit"
))
{
System
.
exit
(
0
);
}
private
static
void
onKeyExit
()
{
System
.
out
.
println
(
"Press Enter to exit..."
);
new
Scanner
(
System
.
in
).
nextLine
();
System
.
out
.
println
(
xmlBean
.
toString
());
}
}
}
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/xmlConfigDemo/bean/XmlBean.java
View file @
72a37b66
...
...
@@ -29,4 +29,9 @@ public class XmlBean {
public
int
getBatch
()
{
return
batch
;
}
@Override
public
String
toString
()
{
return
String
.
format
(
"[XmlBean] timeout: %d, batch: %d"
,
timeout
,
batch
);
}
}
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/xmlConfigDemo/refresh/ManualRefreshUtil.java
deleted
100644 → 0
View file @
45290409
package
com
.
ctrip
.
framework
.
apollo
.
demo
.
spring
.
xmlConfigDemo
.
refresh
;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.demo.spring.xmlConfigDemo.bean.XmlBean
;
import
com.ctrip.framework.apollo.model.ConfigChangeEvent
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloConfig
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
class
ManualRefreshUtil
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
ManualRefreshUtil
.
class
);
@ApolloConfig
private
Config
config
;
@Autowired
private
XmlBean
xmlBean
;
@ApolloConfigChangeListener
private
void
onChange
(
ConfigChangeEvent
changeEvent
)
{
if
(
changeEvent
.
isChanged
(
"timeout"
))
{
logger
.
info
(
"Manually refreshing xmlBean.timeout"
);
xmlBean
.
setTimeout
(
config
.
getIntProperty
(
"timeout"
,
xmlBean
.
getTimeout
()));
}
if
(
changeEvent
.
isChanged
(
"batch"
))
{
logger
.
info
(
"Manually refreshing xmlBean.batch"
);
xmlBean
.
setBatch
(
config
.
getIntProperty
(
"batch"
,
xmlBean
.
getBatch
()));
}
}
}
apollo-demo/src/main/resources/application.yml
View file @
72a37b66
apollo
:
bootstrap
:
enabled
:
true
# will inject 'application' and '
FX
.apollo' namespaces in bootstrap phase
namespaces
:
application,
FX
.apollo
# will inject 'application' and '
TEST1
.apollo' namespaces in bootstrap phase
namespaces
:
application,
TEST1
.apollo
apollo-demo/src/main/resources/spring.xml
View file @
72a37b66
...
...
@@ -7,18 +7,12 @@
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.ctrip.com/schema/apollo http://www.ctrip.com/schema/apollo.xsd"
>
<apollo:config
order=
"10"
/>
<apollo:config
namespaces=
"
FX
.apollo"
order=
"11"
/>
<apollo:config
namespaces=
"
TEST1
.apollo"
order=
"11"
/>
<bean
class=
"com.ctrip.framework.apollo.demo.spring.xmlConfigDemo.bean.XmlBean"
>
<property
name=
"timeout"
value=
"${timeout:200}"
/>
<property
name=
"batch"
value=
"${batch:100}"
/>
</bean>
<bean
class=
"com.ctrip.framework.apollo.demo.spring.xmlConfigDemo.refresh.ManualRefreshUtil"
/>
<!-- to support RefreshScope -->
<bean
class=
"org.springframework.cloud.autoconfigure.RefreshAutoConfiguration"
/>
<context:component-scan
base-package=
"com.ctrip.framework.apollo.demo.spring.common.bean,com.ctrip.framework.apollo.demo.spring.common.refresh"
/>
<context:annotation-config
/>
</beans>
apollo-portal/src/main/docker/Dockerfile
View file @
72a37b66
...
...
@@ -9,7 +9,7 @@
FROM
openjdk:8-jre-alpine
MAINTAINER
ameizi <sxyx2008@163.com>
ENV
VERSION 0.
9.0
ENV
VERSION 0.
10.0-SNAPSHOT
RUN
echo
"http://mirrors.aliyun.com/alpine/v3.6/main"
>
/etc/apk/repositories
\
&&
echo
"http://mirrors.aliyun.com/alpine/v3.6/community"
>>
/etc/apk/repositories
\
...
...
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/ctrip/CtripSsoHeartbeatHandler.java
View file @
72a37b66
...
...
@@ -11,6 +11,7 @@ import javax.servlet.http.HttpServletResponse;
* @author Jason Song(song_s@ctrip.com)
*/
public
class
CtripSsoHeartbeatHandler
implements
SsoHeartbeatHandler
{
@Override
public
void
doHeartbeat
(
HttpServletRequest
request
,
HttpServletResponse
response
)
{
try
{
...
...
@@ -18,4 +19,5 @@ public class CtripSsoHeartbeatHandler implements SsoHeartbeatHandler {
}
catch
(
IOException
e
)
{
}
}
}
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultSsoHeartbeatHandler.java
View file @
72a37b66
...
...
@@ -11,12 +11,13 @@ import javax.servlet.http.HttpServletResponse;
* @author Jason Song(song_s@ctrip.com)
*/
public
class
DefaultSsoHeartbeatHandler
implements
SsoHeartbeatHandler
{
@Override
public
void
doHeartbeat
(
HttpServletRequest
request
,
HttpServletResponse
response
)
{
try
{
response
.
setContentType
(
"text/plain;charset=utf-8"
);
response
.
getWriter
().
write
(
"default sso heartbeat handler"
);
response
.
sendRedirect
(
"default_sso_heartbeat.html"
);
}
catch
(
IOException
e
)
{
}
}
}
apollo-portal/src/main/resources/application.yml
View file @
72a37b66
...
...
@@ -3,6 +3,8 @@ spring:
name
:
apollo-portal
profiles
:
active
:
${apollo_profile}
resources
:
cache-period
:
3600
server
:
port
:
8080
...
...
apollo-portal/src/main/resources/static/app.html
View file @
72a37b66
...
...
@@ -119,10 +119,11 @@
<script
type=
"application/javascript"
src=
"scripts/services/EnvService.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/services/UserService.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/services/CommonService.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/
AppUtils
.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/
services/PermissionService
.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/services/OrganizationService.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/directive/directive.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/AppUtils.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/directive/directive.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/controller/AppController.js"
></script>
<script
src=
"scripts/valdr.js"
type=
"text/javascript"
></script>
...
...
apollo-portal/src/main/resources/static/app/setting.html
View file @
72a37b66
...
...
@@ -189,6 +189,7 @@
<script
type=
"application/javascript"
src=
"../scripts/services/CommonService.js"
></script>
<script
type=
"application/javascript"
src=
"../scripts/services/PermissionService.js"
></script>
<script
type=
"application/javascript"
src=
"../scripts/services/OrganizationService.js"
></script>
<script
type=
"application/javascript"
src=
"../scripts/services/PermissionService.js"
></script>
<script
type=
"application/javascript"
src=
"../scripts/AppUtils.js"
></script>
...
...
apollo-portal/src/main/resources/static/cluster.html
View file @
72a37b66
...
...
@@ -131,6 +131,7 @@
<script
type=
"application/javascript"
src=
"scripts/services/ClusterService.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/AppUtils.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/directive/directive.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/services/PermissionService.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/controller/ClusterController.js"
></script>
...
...
apollo-portal/src/main/resources/static/config/history.html
View file @
72a37b66
...
...
@@ -270,6 +270,7 @@
<script
type=
"application/javascript"
src=
"../scripts/services/CommonService.js"
></script>
<script
type=
"application/javascript"
src=
"../scripts/services/ReleaseHistoryService.js"
></script>
<script
type=
"application/javascript"
src=
"../scripts/services/ConfigService.js"
></script>
<script
type=
"application/javascript"
src=
"../scripts/services/PermissionService.js"
></script>
<script
type=
"application/javascript"
src=
"../scripts/AppUtils.js"
></script>
<script
type=
"application/javascript"
src=
"../scripts/controller/config/ReleaseHistoryController.js"
></script>
...
...
apollo-portal/src/main/resources/static/config/sync.html
View file @
72a37b66
...
...
@@ -235,6 +235,8 @@
<script
type=
"application/javascript"
src=
"../scripts/services/ConfigService.js"
></script>
<script
type=
"application/javascript"
src=
"../scripts/services/UserService.js"
></script>
<script
type=
"application/javascript"
src=
"../scripts/services/CommonService.js"
></script>
<script
type=
"application/javascript"
src=
"../scripts/services/PermissionService.js"
></script>
<script
type=
"application/javascript"
src=
"../scripts/AppUtils.js"
></script>
<script
type=
"application/javascript"
src=
"../scripts/controller/config/SyncConfigController.js"
></script>
...
...
apollo-portal/src/main/resources/static/default_sso_heartbeat.html
0 → 100644
View file @
72a37b66
<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<meta
charset=
"UTF-8"
>
<title>
SSO Heartbeat
</title>
<script
type=
"text/javascript"
>
var
reloading
=
false
;
setInterval
(
function
()
{
if
(
reloading
)
{
return
;
}
reloading
=
true
;
location
.
reload
(
true
);
},
60000
);
</script>
</head>
<body>
</body>
</html>
apollo-portal/src/main/resources/static/index.html
View file @
72a37b66
...
...
@@ -81,7 +81,7 @@
</div>
</div>
<div
class=
"no-favorites text-center"
ng-show=
"!favorites || favorites.length == 0"
>
<h4>
您还没有收藏过任何项目
,
在项目主页可以收藏项目哟~
</h4>
<h4>
您还没有收藏过任何项目
,
在项目主页可以收藏项目哟~
</h4>
</div>
</aside>
...
...
@@ -128,6 +128,7 @@
<script
type=
"application/javascript"
src=
"scripts/services/UserService.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/services/CommonService.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/services/FavoriteService.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/services/PermissionService.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/AppUtils.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/directive/directive.js"
></script>
...
...
apollo-portal/src/main/resources/static/scripts/directive/directive.js
View file @
72a37b66
/** navbar */
directive_module
.
directive
(
'
apollonav
'
,
function
(
$compile
,
$window
,
toastr
,
AppUtil
,
AppService
,
EnvService
,
UserService
,
CommonService
)
{
function
(
$compile
,
$window
,
toastr
,
AppUtil
,
AppService
,
EnvService
,
UserService
,
CommonService
,
PermissionService
)
{
return
{
restrict
:
'
E
'
,
templateUrl
:
'
../../views/common/nav.html
'
,
...
...
@@ -82,7 +83,7 @@ directive_module.directive('apollonav',
}
//强制刷新
scope
.
$apply
(
function
()
{
scope
.
cop
yedApps
=
scope
.
copy
edApps
;
scope
.
cop
iedApps
=
scope
.
copi
edApps
;
});
});
...
...
@@ -97,7 +98,7 @@ directive_module.directive('apollonav',
});
function
clearAppsSelectedStatus
()
{
scope
.
cop
y
edApps
.
forEach
(
function
(
app
)
{
scope
.
cop
i
edApps
.
forEach
(
function
(
app
)
{
app
.
selected
=
false
;
})
...
...
@@ -117,6 +118,10 @@ directive_module.directive('apollonav',
},
function
(
result
)
{
});
PermissionService
.
has_root_permission
().
then
(
function
(
result
)
{
scope
.
hasRootPermission
=
result
.
hasPermission
;
})
}
}
...
...
apollo-portal/src/main/resources/static/server_config.html
View file @
72a37b66
...
...
@@ -21,6 +21,7 @@
<div
class=
"panel"
>
<header
class=
"panel-heading"
>
应用配置
<small>
(维护ServerConfig表数据,如果已存在配置项则会覆盖,否则会创建配置项。配置更新后,一分钟后自动生效)
</small>
</header>
<div
class=
"panel-body"
>
...
...
@@ -53,7 +54,7 @@
<div
class=
"form-group"
>
<div
class=
"col-sm-offset-2 col-sm-10"
>
<button
type=
"submit"
class=
"btn btn-
default
"
>
提交
</button>
<button
type=
"submit"
class=
"btn btn-
primary
"
>
提交
</button>
</div>
</div>
</form>
...
...
@@ -86,6 +87,7 @@
<script
type=
"application/javascript"
src=
"scripts/services/UserService.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/services/CommonService.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/services/ServerConfigService.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/services/PermissionService.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/controller/ServerConfigController.js"
></script>
</body>
...
...
apollo-portal/src/main/resources/static/user-manage.html
View file @
72a37b66
...
...
@@ -95,6 +95,7 @@
<script
type=
"application/javascript"
src=
"scripts/AppUtils.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/services/OrganizationService.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/directive/directive.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/services/PermissionService.js"
></script>
<script
type=
"application/javascript"
src=
"scripts/controller/UserController.js"
></script>
...
...
apollo-portal/src/main/resources/static/views/common/nav.html
View file @
72a37b66
...
...
@@ -25,6 +25,16 @@
<span
class=
"glyphicon glyphicon-question-sign"
></span>
帮助
</a>
</li>
<li
class=
"dropdown"
ng-if=
"hasRootPermission"
>
<a
href=
"#"
class=
"dropdown-toggle"
data-toggle=
"dropdown"
role=
"button"
aria-haspopup=
"true"
aria-expanded=
"false"
>
<span
class=
"glyphicon glyphicon-cog"
></span>
管理员工具
<span
class=
"caret"
></span></a>
<ul
class=
"dropdown-menu"
>
<li><a
href=
"/user-manage.html"
target=
"_blank"
>
用户管理
</a></li>
<li><a
href=
"/open/manage.html"
target=
"_blank"
>
开放平台授权管理
</a></li>
<li><a
href=
"/server_config.html"
target=
"_blank"
>
系统参数
</a></li>
</ul>
</li>
<li
class=
"dropdown"
>
<a
href=
"#"
class=
"dropdown-toggle"
data-toggle=
"dropdown"
role=
"button"
aria-haspopup=
"true"
aria-expanded=
"false"
>
<span
class=
"glyphicon glyphicon-user"
></span>
{{userName}}
...
...
apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/AllTests.java
deleted
100644 → 0
View file @
45290409
package
com
.
ctrip
.
framework
.
apollo
.
portal
;
import
com.ctrip.framework.apollo.openapi.filter.ConsumerAuthenticationFilterTest
;
import
com.ctrip.framework.apollo.openapi.service.ConsumerRolePermissionServiceTest
;
import
com.ctrip.framework.apollo.openapi.service.ConsumerServiceTest
;
import
com.ctrip.framework.apollo.openapi.util.ConsumerAuditUtilTest
;
import
com.ctrip.framework.apollo.openapi.util.ConsumerAuthUtilTest
;
import
com.ctrip.framework.apollo.portal.component.txtresolver.FileTextResolverTest
;
import
com.ctrip.framework.apollo.portal.component.txtresolver.PropertyResolverTest
;
import
com.ctrip.framework.apollo.portal.config.ConfigTest
;
import
com.ctrip.framework.apollo.portal.service.AppNamespaceServiceTest
;
import
com.ctrip.framework.apollo.portal.service.ConfigServiceTest
;
import
com.ctrip.framework.apollo.portal.service.FavoriteServiceTest
;
import
com.ctrip.framework.apollo.portal.service.NamespaceServiceTest
;
import
com.ctrip.framework.apollo.portal.spi.defaultImpl.RoleInitializationServiceTest
;
import
com.ctrip.framework.apollo.portal.spi.defaultImpl.RolePermissionServiceTest
;
import
com.ctrip.framework.apollo.portal.spi.ctrip.CtripUserServiceTest
;
import
org.junit.runner.RunWith
;
import
org.junit.runners.Suite
;
import
org.junit.runners.Suite.SuiteClasses
;
@RunWith
(
Suite
.
class
)
@SuiteClasses
({
ConfigServiceTest
.
class
,
PropertyResolverTest
.
class
,
NamespaceServiceTest
.
class
,
ServiceExceptionTest
.
class
,
RolePermissionServiceTest
.
class
,
AppNamespaceServiceTest
.
class
,
RoleInitializationServiceTest
.
class
,
FileTextResolverTest
.
class
,
RetryableRestTemplateTest
.
class
,
ConsumerRolePermissionServiceTest
.
class
,
ConsumerAuthenticationFilterTest
.
class
,
ConsumerAuthUtilTest
.
class
,
ConsumerServiceTest
.
class
,
ConsumerAuditUtilTest
.
class
,
ConfigTest
.
class
,
FavoriteServiceTest
.
class
,
CtripUserServiceTest
.
class
})
public
class
AllTests
{
}
doc/images/known-users/huli-logo.png
0 → 100644
View file @
72a37b66
6.79 KB
doc/images/known-users/mandao.png
0 → 100644
View file @
72a37b66
10.1 KB
doc/images/known-users/mgzf.png
0 → 100644
View file @
72a37b66
16.1 KB
doc/images/known-users/nxin.png
0 → 100644
View file @
72a37b66
7.03 KB
doc/images/known-users/rhinotech.png
0 → 100644
View file @
72a37b66
14.3 KB
pom.xml
View file @
72a37b66
...
...
@@ -329,11 +329,6 @@
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-surefire-plugin
</artifactId>
<version>
${maven-surefire-plugin.version}
</version>
<configuration>
<includes>
<include>
**/AllTests.java
</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment