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
bf1b6374
Unverified
Commit
bf1b6374
authored
Feb 12, 2019
by
Jason Song
Committed by
GitHub
Feb 12, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1944 from nobodyiam/yml-support
add yaml support to apollo-client
parents
c8f84a63
b1ca961b
Changes
51
Hide whitespace changes
Inline
Side-by-side
Showing
51 changed files
with
1690 additions
and
38 deletions
+1690
-38
apollo-client/pom.xml
apollo-client/pom.xml
+6
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/PropertiesCompatibleConfigFile.java
...trip/framework/apollo/PropertiesCompatibleConfigFile.java
+18
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/DefaultInjector.java
...com/ctrip/framework/apollo/internals/DefaultInjector.java
+2
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/PropertiesCompatibleFileConfigRepository.java
...o/internals/PropertiesCompatibleFileConfigRepository.java
+56
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/PropertiesConfigFile.java
...trip/framework/apollo/internals/PropertiesConfigFile.java
+0
-1
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/YamlConfigFile.java
.../com/ctrip/framework/apollo/internals/YamlConfigFile.java
+60
-1
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/YmlConfigFile.java
...a/com/ctrip/framework/apollo/internals/YmlConfigFile.java
+1
-1
apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigFactory.java
.../com/ctrip/framework/apollo/spi/DefaultConfigFactory.java
+39
-3
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/PropertySourcesProcessor.java
...mework/apollo/spring/config/PropertySourcesProcessor.java
+6
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/util/yaml/YamlParser.java
...java/com/ctrip/framework/apollo/util/yaml/YamlParser.java
+182
-0
apollo-client/src/test/java/com/ctrip/framework/apollo/internals/PropertiesCompatibleFileConfigRepositoryTest.java
...ternals/PropertiesCompatibleFileConfigRepositoryTest.java
+118
-0
apollo-client/src/test/java/com/ctrip/framework/apollo/internals/YamlConfigFileTest.java
.../ctrip/framework/apollo/internals/YamlConfigFileTest.java
+183
-0
apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryTest.java
.../ctrip/framework/apollo/spi/DefaultConfigFactoryTest.java
+64
-0
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/AbstractSpringIntegrationTest.java
...ramework/apollo/spring/AbstractSpringIntegrationTest.java
+59
-6
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/BootstrapConfigTest.java
...om/ctrip/framework/apollo/spring/BootstrapConfigTest.java
+107
-3
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigAnnotationTest.java
...rip/framework/apollo/spring/JavaConfigAnnotationTest.java
+76
-0
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderAutoUpdateTest.java
...rk/apollo/spring/JavaConfigPlaceholderAutoUpdateTest.java
+184
-0
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderTest.java
...ip/framework/apollo/spring/JavaConfigPlaceholderTest.java
+90
-7
apollo-client/src/test/java/com/ctrip/framework/apollo/util/yaml/YamlParserTest.java
.../com/ctrip/framework/apollo/util/yaml/YamlParserTest.java
+81
-0
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest11.xml
.../src/test/resources/spring/XmlConfigPlaceholderTest11.xml
+12
-0
apollo-client/src/test/resources/spring/yaml/case1-new.yaml
apollo-client/src/test/resources/spring/yaml/case1-new.yaml
+2
-0
apollo-client/src/test/resources/spring/yaml/case1.yaml
apollo-client/src/test/resources/spring/yaml/case1.yaml
+2
-0
apollo-client/src/test/resources/spring/yaml/case2-new.yml
apollo-client/src/test/resources/spring/yaml/case2-new.yml
+1
-0
apollo-client/src/test/resources/spring/yaml/case2.yml
apollo-client/src/test/resources/spring/yaml/case2.yml
+1
-0
apollo-client/src/test/resources/spring/yaml/case3-new.yaml
apollo-client/src/test/resources/spring/yaml/case3-new.yaml
+2
-0
apollo-client/src/test/resources/spring/yaml/case3.yaml
apollo-client/src/test/resources/spring/yaml/case3.yaml
+1
-0
apollo-client/src/test/resources/spring/yaml/case4-new.yaml
apollo-client/src/test/resources/spring/yaml/case4-new.yaml
+0
-0
apollo-client/src/test/resources/spring/yaml/case4.yaml
apollo-client/src/test/resources/spring/yaml/case4.yaml
+2
-0
apollo-client/src/test/resources/spring/yaml/case5-new.yaml
apollo-client/src/test/resources/spring/yaml/case5-new.yaml
+2
-0
apollo-client/src/test/resources/spring/yaml/case5.yaml
apollo-client/src/test/resources/spring/yaml/case5.yaml
+2
-0
apollo-client/src/test/resources/spring/yaml/case6.yml
apollo-client/src/test/resources/spring/yaml/case6.yml
+1
-0
apollo-client/src/test/resources/spring/yaml/case7.yml
apollo-client/src/test/resources/spring/yaml/case7.yml
+1
-0
apollo-client/src/test/resources/spring/yaml/case8.yml
apollo-client/src/test/resources/spring/yaml/case8.yml
+0
-0
apollo-client/src/test/resources/spring/yaml/case9-new.yml
apollo-client/src/test/resources/spring/yaml/case9-new.yml
+1
-0
apollo-client/src/test/resources/spring/yaml/case9.yml
apollo-client/src/test/resources/spring/yaml/case9.yml
+1
-0
apollo-client/src/test/resources/yaml/case1.yaml
apollo-client/src/test/resources/yaml/case1.yaml
+25
-0
apollo-client/src/test/resources/yaml/case2.yaml
apollo-client/src/test/resources/yaml/case2.yaml
+4
-0
apollo-client/src/test/resources/yaml/case3.yaml
apollo-client/src/test/resources/yaml/case3.yaml
+3
-0
apollo-client/src/test/resources/yaml/case4.yaml
apollo-client/src/test/resources/yaml/case4.yaml
+148
-0
apollo-client/src/test/resources/yaml/case5.yaml
apollo-client/src/test/resources/yaml/case5.yaml
+42
-0
apollo-client/src/test/resources/yaml/case6.yaml
apollo-client/src/test/resources/yaml/case6.yaml
+36
-0
apollo-client/src/test/resources/yaml/case7.yaml
apollo-client/src/test/resources/yaml/case7.yaml
+1
-0
apollo-client/src/test/resources/yaml/case8.yaml
apollo-client/src/test/resources/yaml/case8.yaml
+1
-0
apollo-core/src/main/java/com/ctrip/framework/apollo/core/enums/ConfigFileFormat.java
...m/ctrip/framework/apollo/core/enums/ConfigFileFormat.java
+4
-0
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/api/ApolloConfigDemo.java
...com/ctrip/framework/apollo/demo/api/ApolloConfigDemo.java
+38
-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/springBootDemo/config/SampleRedisConfig.java
.../demo/spring/springBootDemo/config/SampleRedisConfig.java
+18
-0
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/springBootDemo/refresh/SpringBootApolloRefreshConfig.java
...springBootDemo/refresh/SpringBootApolloRefreshConfig.java
+2
-1
apollo-demo/src/main/resources/application.yml
apollo-demo/src/main/resources/application.yml
+1
-1
apollo-demo/src/main/resources/spring.xml
apollo-demo/src/main/resources/spring.xml
+1
-1
apollo-portal/src/main/resources/static/namespace.html
apollo-portal/src/main/resources/static/namespace.html
+2
-1
No files found.
apollo-client/pom.xml
View file @
bf1b6374
...
@@ -45,6 +45,12 @@
...
@@ -45,6 +45,12 @@
<groupId>
org.slf4j
</groupId>
<groupId>
org.slf4j
</groupId>
<artifactId>
slf4j-api
</artifactId>
<artifactId>
slf4j-api
</artifactId>
</dependency>
</dependency>
<!-- yml processing -->
<dependency>
<groupId>
org.yaml
</groupId>
<artifactId>
snakeyaml
</artifactId>
</dependency>
<!-- end of yml processing -->
<!-- optional spring dependency -->
<!-- optional spring dependency -->
<dependency>
<dependency>
<groupId>
org.springframework
</groupId>
<groupId>
org.springframework
</groupId>
...
...
apollo-client/src/main/java/com/ctrip/framework/apollo/PropertiesCompatibleConfigFile.java
0 → 100644
View file @
bf1b6374
package
com
.
ctrip
.
framework
.
apollo
;
import
java.util.Properties
;
/**
* Config files that are properties compatible, e.g. yaml
*
* @since 1.3.0
*/
public
interface
PropertiesCompatibleConfigFile
extends
ConfigFile
{
/**
* @return the properties form of the config file
*
* @throws RuntimeException if the content could not be transformed to properties
*/
Properties
asProperties
();
}
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/DefaultInjector.java
View file @
bf1b6374
...
@@ -11,6 +11,7 @@ import com.ctrip.framework.apollo.tracer.Tracer;
...
@@ -11,6 +11,7 @@ import com.ctrip.framework.apollo.tracer.Tracer;
import
com.ctrip.framework.apollo.util.ConfigUtil
;
import
com.ctrip.framework.apollo.util.ConfigUtil
;
import
com.ctrip.framework.apollo.util.http.HttpUtil
;
import
com.ctrip.framework.apollo.util.http.HttpUtil
;
import
com.ctrip.framework.apollo.util.yaml.YamlParser
;
import
com.google.inject.AbstractModule
;
import
com.google.inject.AbstractModule
;
import
com.google.inject.Guice
;
import
com.google.inject.Guice
;
import
com.google.inject.Singleton
;
import
com.google.inject.Singleton
;
...
@@ -60,6 +61,7 @@ public class DefaultInjector implements Injector {
...
@@ -60,6 +61,7 @@ public class DefaultInjector implements Injector {
bind
(
HttpUtil
.
class
).
in
(
Singleton
.
class
);
bind
(
HttpUtil
.
class
).
in
(
Singleton
.
class
);
bind
(
ConfigServiceLocator
.
class
).
in
(
Singleton
.
class
);
bind
(
ConfigServiceLocator
.
class
).
in
(
Singleton
.
class
);
bind
(
RemoteConfigLongPollService
.
class
).
in
(
Singleton
.
class
);
bind
(
RemoteConfigLongPollService
.
class
).
in
(
Singleton
.
class
);
bind
(
YamlParser
.
class
).
in
(
Singleton
.
class
);
}
}
}
}
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/PropertiesCompatibleFileConfigRepository.java
0 → 100644
View file @
bf1b6374
package
com
.
ctrip
.
framework
.
apollo
.
internals
;
import
java.util.Properties
;
import
com.ctrip.framework.apollo.ConfigFileChangeListener
;
import
com.ctrip.framework.apollo.PropertiesCompatibleConfigFile
;
import
com.ctrip.framework.apollo.enums.ConfigSourceType
;
import
com.ctrip.framework.apollo.model.ConfigFileChangeEvent
;
import
com.google.common.base.Preconditions
;
public
class
PropertiesCompatibleFileConfigRepository
extends
AbstractConfigRepository
implements
ConfigFileChangeListener
{
private
final
PropertiesCompatibleConfigFile
configFile
;
private
volatile
Properties
cachedProperties
;
public
PropertiesCompatibleFileConfigRepository
(
PropertiesCompatibleConfigFile
configFile
)
{
this
.
configFile
=
configFile
;
this
.
configFile
.
addChangeListener
(
this
);
this
.
trySync
();
}
@Override
protected
synchronized
void
sync
()
{
Properties
current
=
configFile
.
asProperties
();
Preconditions
.
checkState
(
current
!=
null
,
"PropertiesCompatibleConfigFile.asProperties should never return null"
);
if
(
cachedProperties
!=
current
)
{
cachedProperties
=
current
;
this
.
fireRepositoryChange
(
configFile
.
getNamespace
(),
cachedProperties
);
}
}
@Override
public
Properties
getConfig
()
{
if
(
cachedProperties
==
null
)
{
sync
();
}
return
cachedProperties
;
}
@Override
public
void
setUpstreamRepository
(
ConfigRepository
upstreamConfigRepository
)
{
//config file is the upstream, so no need to set up extra upstream
}
@Override
public
ConfigSourceType
getSourceType
()
{
return
configFile
.
getSourceType
();
}
@Override
public
void
onChange
(
ConfigFileChangeEvent
changeEvent
)
{
this
.
trySync
();
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/PropertiesConfigFile.java
View file @
bf1b6374
...
@@ -16,7 +16,6 @@ import com.ctrip.framework.apollo.util.ExceptionUtil;
...
@@ -16,7 +16,6 @@ import com.ctrip.framework.apollo.util.ExceptionUtil;
* @author Jason Song(song_s@ctrip.com)
* @author Jason Song(song_s@ctrip.com)
*/
*/
public
class
PropertiesConfigFile
extends
AbstractConfigFile
{
public
class
PropertiesConfigFile
extends
AbstractConfigFile
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
PropertiesConfigFile
.
class
);
protected
AtomicReference
<
String
>
m_contentCache
;
protected
AtomicReference
<
String
>
m_contentCache
;
public
PropertiesConfigFile
(
String
namespace
,
public
PropertiesConfigFile
(
String
namespace
,
...
...
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/YamlConfigFile.java
View file @
bf1b6374
package
com
.
ctrip
.
framework
.
apollo
.
internals
;
package
com
.
ctrip
.
framework
.
apollo
.
internals
;
import
com.ctrip.framework.apollo.util.ExceptionUtil
;
import
java.util.Properties
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
com.ctrip.framework.apollo.PropertiesCompatibleConfigFile
;
import
com.ctrip.framework.apollo.build.ApolloInjector
;
import
com.ctrip.framework.apollo.core.enums.ConfigFileFormat
;
import
com.ctrip.framework.apollo.core.enums.ConfigFileFormat
;
import
com.ctrip.framework.apollo.exceptions.ApolloConfigException
;
import
com.ctrip.framework.apollo.tracer.Tracer
;
import
com.ctrip.framework.apollo.util.yaml.YamlParser
;
/**
/**
* @author Jason Song(song_s@ctrip.com)
* @author Jason Song(song_s@ctrip.com)
*/
*/
public
class
YamlConfigFile
extends
PlainTextConfigFile
{
public
class
YamlConfigFile
extends
PlainTextConfigFile
implements
PropertiesCompatibleConfigFile
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
YamlConfigFile
.
class
);
private
volatile
Properties
cachedProperties
;
public
YamlConfigFile
(
String
namespace
,
ConfigRepository
configRepository
)
{
public
YamlConfigFile
(
String
namespace
,
ConfigRepository
configRepository
)
{
super
(
namespace
,
configRepository
);
super
(
namespace
,
configRepository
);
tryTransformToProperties
();
}
}
@Override
@Override
public
ConfigFileFormat
getConfigFileFormat
()
{
public
ConfigFileFormat
getConfigFileFormat
()
{
return
ConfigFileFormat
.
YAML
;
return
ConfigFileFormat
.
YAML
;
}
}
@Override
protected
void
update
(
Properties
newProperties
)
{
super
.
update
(
newProperties
);
tryTransformToProperties
();
}
@Override
public
Properties
asProperties
()
{
if
(
cachedProperties
==
null
)
{
transformToProperties
();
}
return
cachedProperties
;
}
private
boolean
tryTransformToProperties
()
{
try
{
transformToProperties
();
return
true
;
}
catch
(
Throwable
ex
)
{
Tracer
.
logEvent
(
"ApolloConfigException"
,
ExceptionUtil
.
getDetailMessage
(
ex
));
logger
.
warn
(
"yaml to properties failed, reason: {}"
,
ExceptionUtil
.
getDetailMessage
(
ex
));
}
return
false
;
}
private
synchronized
void
transformToProperties
()
{
cachedProperties
=
toProperties
();
}
private
Properties
toProperties
()
{
if
(!
this
.
hasContent
())
{
return
new
Properties
();
}
try
{
return
ApolloInjector
.
getInstance
(
YamlParser
.
class
).
yamlToProperties
(
getContent
());
}
catch
(
Throwable
ex
)
{
ApolloConfigException
exception
=
new
ApolloConfigException
(
"Parse yaml file content failed for namespace: "
+
m_namespace
,
ex
);
Tracer
.
logError
(
exception
);
throw
exception
;
}
}
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/YmlConfigFile.java
View file @
bf1b6374
...
@@ -5,7 +5,7 @@ import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
...
@@ -5,7 +5,7 @@ import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
/**
/**
* @author Jason Song(song_s@ctrip.com)
* @author Jason Song(song_s@ctrip.com)
*/
*/
public
class
YmlConfigFile
extends
PlainText
ConfigFile
{
public
class
YmlConfigFile
extends
Yaml
ConfigFile
{
public
YmlConfigFile
(
String
namespace
,
ConfigRepository
configRepository
)
{
public
YmlConfigFile
(
String
namespace
,
ConfigRepository
configRepository
)
{
super
(
namespace
,
configRepository
);
super
(
namespace
,
configRepository
);
}
}
...
...
apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigFactory.java
View file @
bf1b6374
package
com
.
ctrip
.
framework
.
apollo
.
spi
;
package
com
.
ctrip
.
framework
.
apollo
.
spi
;
import
com.ctrip.framework.apollo.ConfigService
;
import
com.ctrip.framework.apollo.PropertiesCompatibleConfigFile
;
import
com.ctrip.framework.apollo.internals.PropertiesCompatibleFileConfigRepository
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
...
@@ -31,9 +34,11 @@ public class DefaultConfigFactory implements ConfigFactory {
...
@@ -31,9 +34,11 @@ public class DefaultConfigFactory implements ConfigFactory {
@Override
@Override
public
Config
create
(
String
namespace
)
{
public
Config
create
(
String
namespace
)
{
DefaultConfig
defaultConfig
=
ConfigFileFormat
format
=
determineFileFormat
(
namespace
);
new
DefaultConfig
(
namespace
,
createLocalConfigRepository
(
namespace
));
if
(
ConfigFileFormat
.
isPropertiesCompatible
(
format
))
{
return
defaultConfig
;
return
new
DefaultConfig
(
namespace
,
createPropertiesCompatibleFileConfigRepository
(
namespace
,
format
));
}
return
new
DefaultConfig
(
namespace
,
createLocalConfigRepository
(
namespace
));
}
}
@Override
@Override
...
@@ -68,4 +73,35 @@ public class DefaultConfigFactory implements ConfigFactory {
...
@@ -68,4 +73,35 @@ public class DefaultConfigFactory implements ConfigFactory {
RemoteConfigRepository
createRemoteConfigRepository
(
String
namespace
)
{
RemoteConfigRepository
createRemoteConfigRepository
(
String
namespace
)
{
return
new
RemoteConfigRepository
(
namespace
);
return
new
RemoteConfigRepository
(
namespace
);
}
}
PropertiesCompatibleFileConfigRepository
createPropertiesCompatibleFileConfigRepository
(
String
namespace
,
ConfigFileFormat
format
)
{
String
actualNamespaceName
=
trimNamespaceFormat
(
namespace
,
format
);
PropertiesCompatibleConfigFile
configFile
=
(
PropertiesCompatibleConfigFile
)
ConfigService
.
getConfigFile
(
actualNamespaceName
,
format
);
return
new
PropertiesCompatibleFileConfigRepository
(
configFile
);
}
// for namespaces whose format are not properties, the file extension must be present, e.g. application.yaml
ConfigFileFormat
determineFileFormat
(
String
namespaceName
)
{
String
lowerCase
=
namespaceName
.
toLowerCase
();
for
(
ConfigFileFormat
format
:
ConfigFileFormat
.
values
())
{
if
(
lowerCase
.
endsWith
(
"."
+
format
.
getValue
()))
{
return
format
;
}
}
return
ConfigFileFormat
.
Properties
;
}
String
trimNamespaceFormat
(
String
namespaceName
,
ConfigFileFormat
format
)
{
String
extension
=
"."
+
format
.
getValue
();
if
(!
namespaceName
.
toLowerCase
().
endsWith
(
extension
))
{
return
namespaceName
;
}
return
namespaceName
.
substring
(
0
,
namespaceName
.
length
()
-
extension
.
length
());
}
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/PropertySourcesProcessor.java
View file @
bf1b6374
...
@@ -137,4 +137,10 @@ public class PropertySourcesProcessor implements BeanFactoryPostProcessor, Envir
...
@@ -137,4 +137,10 @@ public class PropertySourcesProcessor implements BeanFactoryPostProcessor, Envir
//make it as early as possible
//make it as early as possible
return
Ordered
.
HIGHEST_PRECEDENCE
;
return
Ordered
.
HIGHEST_PRECEDENCE
;
}
}
// for test only
static
void
reset
()
{
NAMESPACE_NAMES
.
clear
();
AUTO_UPDATE_INITIALIZED_BEAN_FACTORIES
.
clear
();
}
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/util/yaml/YamlParser.java
0 → 100644
View file @
bf1b6374
package
com
.
ctrip
.
framework
.
apollo
.
util
.
yaml
;
import
java.util.AbstractMap
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.LinkedHashMap
;
import
java.util.Map
;
import
java.util.Properties
;
import
java.util.Set
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.yaml.snakeyaml.Yaml
;
import
org.yaml.snakeyaml.constructor.Constructor
;
import
org.yaml.snakeyaml.nodes.MappingNode
;
import
org.yaml.snakeyaml.parser.ParserException
;
import
com.ctrip.framework.apollo.core.utils.StringUtils
;
/**
* Transplanted from org.springframework.beans.factory.config.YamlProcessor since apollo can't depend on Spring directly
*
* @since 1.3.0
*/
public
class
YamlParser
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
YamlParser
.
class
);
/**
* Transform yaml content to properties
*/
public
Properties
yamlToProperties
(
String
yamlContent
)
{
Yaml
yaml
=
createYaml
();
final
Properties
result
=
new
Properties
();
process
(
new
MatchCallback
()
{
@Override
public
void
process
(
Properties
properties
,
Map
<
String
,
Object
>
map
)
{
result
.
putAll
(
properties
);
}
},
yaml
,
yamlContent
);
return
result
;
}
/**
* Create the {@link Yaml} instance to use.
*/
private
Yaml
createYaml
()
{
return
new
Yaml
(
new
StrictMapAppenderConstructor
());
}
private
boolean
process
(
MatchCallback
callback
,
Yaml
yaml
,
String
content
)
{
int
count
=
0
;
if
(
logger
.
isDebugEnabled
())
{
logger
.
debug
(
"Loading from YAML: "
+
content
);
}
for
(
Object
object
:
yaml
.
loadAll
(
content
))
{
if
(
object
!=
null
&&
process
(
asMap
(
object
),
callback
))
{
count
++;
}
}
if
(
logger
.
isDebugEnabled
())
{
logger
.
debug
(
"Loaded "
+
count
+
" document"
+
(
count
>
1
?
"s"
:
""
)
+
" from YAML resource: "
+
content
);
}
return
(
count
>
0
);
}
@SuppressWarnings
(
"unchecked"
)
private
Map
<
String
,
Object
>
asMap
(
Object
object
)
{
// YAML can have numbers as keys
Map
<
String
,
Object
>
result
=
new
LinkedHashMap
<
String
,
Object
>();
if
(!(
object
instanceof
Map
))
{
// A document can be a text literal
result
.
put
(
"document"
,
object
);
return
result
;
}
Map
<
Object
,
Object
>
map
=
(
Map
<
Object
,
Object
>)
object
;
for
(
Map
.
Entry
<
Object
,
Object
>
entry
:
map
.
entrySet
())
{
Object
value
=
entry
.
getValue
();
if
(
value
instanceof
Map
)
{
value
=
asMap
(
value
);
}
Object
key
=
entry
.
getKey
();
if
(
key
instanceof
CharSequence
)
{
result
.
put
(
key
.
toString
(),
value
);
}
else
{
// It has to be a map key in this case
result
.
put
(
"["
+
key
.
toString
()
+
"]"
,
value
);
}
}
return
result
;
}
private
boolean
process
(
Map
<
String
,
Object
>
map
,
MatchCallback
callback
)
{
Properties
properties
=
new
Properties
();
properties
.
putAll
(
getFlattenedMap
(
map
));
if
(
logger
.
isDebugEnabled
())
{
logger
.
debug
(
"Merging document (no matchers set): "
+
map
);
}
callback
.
process
(
properties
,
map
);
return
true
;
}
private
Map
<
String
,
Object
>
getFlattenedMap
(
Map
<
String
,
Object
>
source
)
{
Map
<
String
,
Object
>
result
=
new
LinkedHashMap
<
String
,
Object
>();
buildFlattenedMap
(
result
,
source
,
null
);
return
result
;
}
private
void
buildFlattenedMap
(
Map
<
String
,
Object
>
result
,
Map
<
String
,
Object
>
source
,
String
path
)
{
for
(
Map
.
Entry
<
String
,
Object
>
entry
:
source
.
entrySet
())
{
String
key
=
entry
.
getKey
();
if
(!
StringUtils
.
isBlank
(
path
))
{
if
(
key
.
startsWith
(
"["
))
{
key
=
path
+
key
;
}
else
{
key
=
path
+
'.'
+
key
;
}
}
Object
value
=
entry
.
getValue
();
if
(
value
instanceof
String
)
{
result
.
put
(
key
,
value
);
}
else
if
(
value
instanceof
Map
)
{
// Need a compound key
@SuppressWarnings
(
"unchecked"
)
Map
<
String
,
Object
>
map
=
(
Map
<
String
,
Object
>)
value
;
buildFlattenedMap
(
result
,
map
,
key
);
}
else
if
(
value
instanceof
Collection
)
{
// Need a compound key
@SuppressWarnings
(
"unchecked"
)
Collection
<
Object
>
collection
=
(
Collection
<
Object
>)
value
;
int
count
=
0
;
for
(
Object
object
:
collection
)
{
buildFlattenedMap
(
result
,
Collections
.
singletonMap
(
"["
+
(
count
++)
+
"]"
,
object
),
key
);
}
}
else
{
result
.
put
(
key
,
(
value
!=
null
?
value
.
toString
()
:
""
));
}
}
}
private
interface
MatchCallback
{
void
process
(
Properties
properties
,
Map
<
String
,
Object
>
map
);
}
private
static
class
StrictMapAppenderConstructor
extends
Constructor
{
// Declared as public for use in subclasses
StrictMapAppenderConstructor
()
{
super
();
}
@Override
protected
Map
<
Object
,
Object
>
constructMapping
(
MappingNode
node
)
{
try
{
return
super
.
constructMapping
(
node
);
}
catch
(
IllegalStateException
ex
)
{
throw
new
ParserException
(
"while parsing MappingNode"
,
node
.
getStartMark
(),
ex
.
getMessage
(),
node
.
getEndMark
());
}
}
@Override
protected
Map
<
Object
,
Object
>
createDefaultMap
()
{
final
Map
<
Object
,
Object
>
delegate
=
super
.
createDefaultMap
();
return
new
AbstractMap
<
Object
,
Object
>()
{
@Override
public
Object
put
(
Object
key
,
Object
value
)
{
if
(
delegate
.
containsKey
(
key
))
{
throw
new
IllegalStateException
(
"Duplicate key: "
+
key
);
}
return
delegate
.
put
(
key
,
value
);
}
@Override
public
Set
<
Entry
<
Object
,
Object
>>
entrySet
()
{
return
delegate
.
entrySet
();
}
};
}
}
}
apollo-client/src/test/java/com/ctrip/framework/apollo/internals/PropertiesCompatibleFileConfigRepositoryTest.java
0 → 100644
View file @
bf1b6374
package
com
.
ctrip
.
framework
.
apollo
.
internals
;
import
static
org
.
junit
.
Assert
.*;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
reset
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
com.ctrip.framework.apollo.PropertiesCompatibleConfigFile
;
import
com.ctrip.framework.apollo.enums.ConfigSourceType
;
import
com.ctrip.framework.apollo.model.ConfigFileChangeEvent
;
import
java.util.Properties
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.mockito.Mock
;
import
org.mockito.runners.MockitoJUnitRunner
;
@RunWith
(
MockitoJUnitRunner
.
class
)
public
class
PropertiesCompatibleFileConfigRepositoryTest
{
@Mock
private
PropertiesCompatibleConfigFile
configFile
;
private
String
someNamespaceName
;
@Mock
private
Properties
someProperties
;
@Before
public
void
setUp
()
throws
Exception
{
someNamespaceName
=
"someNamespaceName"
;
when
(
configFile
.
getNamespace
()).
thenReturn
(
someNamespaceName
);
when
(
configFile
.
asProperties
()).
thenReturn
(
someProperties
);
}
@Test
public
void
testGetConfig
()
throws
Exception
{
PropertiesCompatibleFileConfigRepository
configFileRepository
=
new
PropertiesCompatibleFileConfigRepository
(
configFile
);
assertSame
(
someProperties
,
configFileRepository
.
getConfig
());
verify
(
configFile
,
times
(
1
)).
addChangeListener
(
configFileRepository
);
}
@Test
public
void
testGetConfigFailedAndThenRecovered
()
throws
Exception
{
RuntimeException
someException
=
new
RuntimeException
(
"some exception"
);
when
(
configFile
.
asProperties
()).
thenThrow
(
someException
);
PropertiesCompatibleFileConfigRepository
configFileRepository
=
new
PropertiesCompatibleFileConfigRepository
(
configFile
);
Throwable
exceptionThrown
=
null
;
try
{
configFileRepository
.
getConfig
();
}
catch
(
Throwable
ex
)
{
exceptionThrown
=
ex
;
}
assertSame
(
someException
,
exceptionThrown
);
// recovered
reset
(
configFile
);
Properties
someProperties
=
mock
(
Properties
.
class
);
when
(
configFile
.
asProperties
()).
thenReturn
(
someProperties
);
assertSame
(
someProperties
,
configFileRepository
.
getConfig
());
}
@Test
(
expected
=
IllegalStateException
.
class
)
public
void
testGetConfigWithConfigFileReturnNullProperties
()
throws
Exception
{
when
(
configFile
.
asProperties
()).
thenReturn
(
null
);
PropertiesCompatibleFileConfigRepository
configFileRepository
=
new
PropertiesCompatibleFileConfigRepository
(
configFile
);
configFileRepository
.
getConfig
();
}
@Test
public
void
testGetSourceType
()
throws
Exception
{
ConfigSourceType
someType
=
ConfigSourceType
.
REMOTE
;
when
(
configFile
.
getSourceType
()).
thenReturn
(
someType
);
PropertiesCompatibleFileConfigRepository
configFileRepository
=
new
PropertiesCompatibleFileConfigRepository
(
configFile
);
assertSame
(
someType
,
configFileRepository
.
getSourceType
());
}
@Test
public
void
testOnChange
()
throws
Exception
{
Properties
anotherProperties
=
mock
(
Properties
.
class
);
ConfigFileChangeEvent
someChangeEvent
=
mock
(
ConfigFileChangeEvent
.
class
);
RepositoryChangeListener
someListener
=
mock
(
RepositoryChangeListener
.
class
);
PropertiesCompatibleFileConfigRepository
configFileRepository
=
new
PropertiesCompatibleFileConfigRepository
(
configFile
);
configFileRepository
.
addChangeListener
(
someListener
);
assertSame
(
someProperties
,
configFileRepository
.
getConfig
());
when
(
configFile
.
asProperties
()).
thenReturn
(
anotherProperties
);
configFileRepository
.
onChange
(
someChangeEvent
);
assertSame
(
anotherProperties
,
configFileRepository
.
getConfig
());
verify
(
someListener
,
times
(
1
)).
onRepositoryChange
(
someNamespaceName
,
anotherProperties
);
}
}
apollo-client/src/test/java/com/ctrip/framework/apollo/internals/YamlConfigFileTest.java
0 → 100644
View file @
bf1b6374
package
com
.
ctrip
.
framework
.
apollo
.
internals
;
import
static
org
.
junit
.
Assert
.*;
import
static
org
.
mockito
.
Mockito
.
when
;
import
com.ctrip.framework.apollo.build.MockInjector
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
com.ctrip.framework.apollo.enums.ConfigSourceType
;
import
com.ctrip.framework.apollo.exceptions.ApolloConfigException
;
import
com.ctrip.framework.apollo.util.yaml.YamlParser
;
import
java.util.Properties
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.mockito.Mock
;
import
org.mockito.runners.MockitoJUnitRunner
;
@RunWith
(
MockitoJUnitRunner
.
class
)
public
class
YamlConfigFileTest
{
private
String
someNamespace
;
@Mock
private
ConfigRepository
configRepository
;
@Mock
private
YamlParser
yamlParser
;
private
ConfigSourceType
someSourceType
;
@Before
public
void
setUp
()
throws
Exception
{
someNamespace
=
"someName"
;
MockInjector
.
reset
();
MockInjector
.
setInstance
(
YamlParser
.
class
,
yamlParser
);
}
@Test
public
void
testWhenHasContent
()
throws
Exception
{
Properties
someProperties
=
new
Properties
();
String
key
=
ConfigConsts
.
CONFIG_FILE_CONTENT_KEY
;
String
someContent
=
"someKey: 'someValue'"
;
someProperties
.
setProperty
(
key
,
someContent
);
someSourceType
=
ConfigSourceType
.
LOCAL
;
Properties
yamlProperties
=
new
Properties
();
yamlProperties
.
setProperty
(
"someKey"
,
"someValue"
);
when
(
configRepository
.
getConfig
()).
thenReturn
(
someProperties
);
when
(
configRepository
.
getSourceType
()).
thenReturn
(
someSourceType
);
when
(
yamlParser
.
yamlToProperties
(
someContent
)).
thenReturn
(
yamlProperties
);
YamlConfigFile
configFile
=
new
YamlConfigFile
(
someNamespace
,
configRepository
);
assertSame
(
someContent
,
configFile
.
getContent
());
assertSame
(
yamlProperties
,
configFile
.
asProperties
());
}
@Test
public
void
testWhenHasNoContent
()
throws
Exception
{
when
(
configRepository
.
getConfig
()).
thenReturn
(
null
);
YamlConfigFile
configFile
=
new
YamlConfigFile
(
someNamespace
,
configRepository
);
assertFalse
(
configFile
.
hasContent
());
assertNull
(
configFile
.
getContent
());
Properties
properties
=
configFile
.
asProperties
();
assertTrue
(
properties
.
isEmpty
());
}
@Test
public
void
testWhenInvalidYamlContent
()
throws
Exception
{
Properties
someProperties
=
new
Properties
();
String
key
=
ConfigConsts
.
CONFIG_FILE_CONTENT_KEY
;
String
someInvalidContent
=
","
;
someProperties
.
setProperty
(
key
,
someInvalidContent
);
someSourceType
=
ConfigSourceType
.
LOCAL
;
when
(
configRepository
.
getConfig
()).
thenReturn
(
someProperties
);
when
(
configRepository
.
getSourceType
()).
thenReturn
(
someSourceType
);
when
(
yamlParser
.
yamlToProperties
(
someInvalidContent
)).
thenThrow
(
new
RuntimeException
(
"some exception"
));
YamlConfigFile
configFile
=
new
YamlConfigFile
(
someNamespace
,
configRepository
);
assertSame
(
someInvalidContent
,
configFile
.
getContent
());
Throwable
exceptionThrown
=
null
;
try
{
configFile
.
asProperties
();
}
catch
(
Throwable
ex
)
{
exceptionThrown
=
ex
;
}
assertTrue
(
exceptionThrown
instanceof
ApolloConfigException
);
assertNotNull
(
exceptionThrown
.
getCause
());
}
@Test
public
void
testWhenConfigRepositoryHasError
()
throws
Exception
{
when
(
configRepository
.
getConfig
()).
thenThrow
(
new
RuntimeException
(
"someError"
));
YamlConfigFile
configFile
=
new
YamlConfigFile
(
someNamespace
,
configRepository
);
assertFalse
(
configFile
.
hasContent
());
assertNull
(
configFile
.
getContent
());
assertEquals
(
ConfigSourceType
.
NONE
,
configFile
.
getSourceType
());
Properties
properties
=
configFile
.
asProperties
();
assertTrue
(
properties
.
isEmpty
());
}
@Test
public
void
testOnRepositoryChange
()
throws
Exception
{
Properties
someProperties
=
new
Properties
();
String
key
=
ConfigConsts
.
CONFIG_FILE_CONTENT_KEY
;
String
someValue
=
"someKey: 'someValue'"
;
String
anotherValue
=
"anotherKey: 'anotherValue'"
;
someProperties
.
setProperty
(
key
,
someValue
);
someSourceType
=
ConfigSourceType
.
LOCAL
;
Properties
someYamlProperties
=
new
Properties
();
someYamlProperties
.
setProperty
(
"someKey"
,
"someValue"
);
Properties
anotherYamlProperties
=
new
Properties
();
anotherYamlProperties
.
setProperty
(
"anotherKey"
,
"anotherValue"
);
when
(
configRepository
.
getConfig
()).
thenReturn
(
someProperties
);
when
(
configRepository
.
getSourceType
()).
thenReturn
(
someSourceType
);
when
(
yamlParser
.
yamlToProperties
(
someValue
)).
thenReturn
(
someYamlProperties
);
when
(
yamlParser
.
yamlToProperties
(
anotherValue
)).
thenReturn
(
anotherYamlProperties
);
YamlConfigFile
configFile
=
new
YamlConfigFile
(
someNamespace
,
configRepository
);
assertEquals
(
someValue
,
configFile
.
getContent
());
assertEquals
(
someSourceType
,
configFile
.
getSourceType
());
assertSame
(
someYamlProperties
,
configFile
.
asProperties
());
Properties
anotherProperties
=
new
Properties
();
anotherProperties
.
setProperty
(
key
,
anotherValue
);
ConfigSourceType
anotherSourceType
=
ConfigSourceType
.
REMOTE
;
when
(
configRepository
.
getSourceType
()).
thenReturn
(
anotherSourceType
);
configFile
.
onRepositoryChange
(
someNamespace
,
anotherProperties
);
assertEquals
(
anotherValue
,
configFile
.
getContent
());
assertEquals
(
anotherSourceType
,
configFile
.
getSourceType
());
assertSame
(
anotherYamlProperties
,
configFile
.
asProperties
());
}
@Test
public
void
testWhenConfigRepositoryHasErrorAndThenRecovered
()
throws
Exception
{
Properties
someProperties
=
new
Properties
();
String
key
=
ConfigConsts
.
CONFIG_FILE_CONTENT_KEY
;
String
someValue
=
"someKey: 'someValue'"
;
someProperties
.
setProperty
(
key
,
someValue
);
someSourceType
=
ConfigSourceType
.
LOCAL
;
Properties
someYamlProperties
=
new
Properties
();
someYamlProperties
.
setProperty
(
"someKey"
,
"someValue"
);
when
(
configRepository
.
getConfig
()).
thenThrow
(
new
RuntimeException
(
"someError"
));
when
(
configRepository
.
getSourceType
()).
thenReturn
(
someSourceType
);
when
(
yamlParser
.
yamlToProperties
(
someValue
)).
thenReturn
(
someYamlProperties
);
YamlConfigFile
configFile
=
new
YamlConfigFile
(
someNamespace
,
configRepository
);
assertFalse
(
configFile
.
hasContent
());
assertNull
(
configFile
.
getContent
());
assertEquals
(
ConfigSourceType
.
NONE
,
configFile
.
getSourceType
());
assertTrue
(
configFile
.
asProperties
().
isEmpty
());
configFile
.
onRepositoryChange
(
someNamespace
,
someProperties
);
assertTrue
(
configFile
.
hasContent
());
assertEquals
(
someValue
,
configFile
.
getContent
());
assertEquals
(
someSourceType
,
configFile
.
getSourceType
());
assertSame
(
someYamlProperties
,
configFile
.
asProperties
());
}
}
apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryTest.java
View file @
bf1b6374
...
@@ -10,6 +10,7 @@ import static org.mockito.Mockito.mock;
...
@@ -10,6 +10,7 @@ import static org.mockito.Mockito.mock;
import
static
org
.
mockito
.
Mockito
.
spy
;
import
static
org
.
mockito
.
Mockito
.
spy
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
com.ctrip.framework.apollo.internals.PropertiesCompatibleFileConfigRepository
;
import
java.util.Properties
;
import
java.util.Properties
;
import
org.junit.Before
;
import
org.junit.Before
;
...
@@ -78,6 +79,28 @@ public class DefaultConfigFactoryTest {
...
@@ -78,6 +79,28 @@ public class DefaultConfigFactoryTest {
assertNull
(
ReflectionTestUtils
.
getField
(
localFileConfigRepository
,
"m_upstream"
));
assertNull
(
ReflectionTestUtils
.
getField
(
localFileConfigRepository
,
"m_upstream"
));
}
}
@Test
public
void
testCreatePropertiesCompatibleFileConfigRepository
()
throws
Exception
{
ConfigFileFormat
somePropertiesCompatibleFormat
=
ConfigFileFormat
.
YML
;
String
someNamespace
=
"someName"
+
"."
+
somePropertiesCompatibleFormat
;
Properties
someProperties
=
new
Properties
();
String
someKey
=
"someKey"
;
String
someValue
=
"someValue"
;
someProperties
.
setProperty
(
someKey
,
someValue
);
PropertiesCompatibleFileConfigRepository
someRepository
=
mock
(
PropertiesCompatibleFileConfigRepository
.
class
);
when
(
someRepository
.
getConfig
()).
thenReturn
(
someProperties
);
doReturn
(
someRepository
).
when
(
defaultConfigFactory
)
.
createPropertiesCompatibleFileConfigRepository
(
someNamespace
,
somePropertiesCompatibleFormat
);
Config
result
=
defaultConfigFactory
.
create
(
someNamespace
);
assertThat
(
"DefaultConfigFactory should create DefaultConfig"
,
result
,
is
(
instanceOf
(
DefaultConfig
.
class
)));
assertEquals
(
someValue
,
result
.
getProperty
(
someKey
,
null
));
}
@Test
@Test
public
void
testCreateConfigFile
()
throws
Exception
{
public
void
testCreateConfigFile
()
throws
Exception
{
String
someNamespace
=
"someName"
;
String
someNamespace
=
"someName"
;
...
@@ -125,6 +148,47 @@ public class DefaultConfigFactoryTest {
...
@@ -125,6 +148,47 @@ public class DefaultConfigFactoryTest {
}
}
@Test
public
void
testDetermineFileFormat
()
throws
Exception
{
checkFileFormat
(
"abc"
,
ConfigFileFormat
.
Properties
);
checkFileFormat
(
"abc.properties"
,
ConfigFileFormat
.
Properties
);
checkFileFormat
(
"abc.pRopErties"
,
ConfigFileFormat
.
Properties
);
checkFileFormat
(
"abc.xml"
,
ConfigFileFormat
.
XML
);
checkFileFormat
(
"abc.xmL"
,
ConfigFileFormat
.
XML
);
checkFileFormat
(
"abc.json"
,
ConfigFileFormat
.
JSON
);
checkFileFormat
(
"abc.jsOn"
,
ConfigFileFormat
.
JSON
);
checkFileFormat
(
"abc.yaml"
,
ConfigFileFormat
.
YAML
);
checkFileFormat
(
"abc.yAml"
,
ConfigFileFormat
.
YAML
);
checkFileFormat
(
"abc.yml"
,
ConfigFileFormat
.
YML
);
checkFileFormat
(
"abc.yMl"
,
ConfigFileFormat
.
YML
);
checkFileFormat
(
"abc.properties.yml"
,
ConfigFileFormat
.
YML
);
}
@Test
public
void
testTrimNamespaceFormat
()
throws
Exception
{
checkNamespaceName
(
"abc"
,
ConfigFileFormat
.
Properties
,
"abc"
);
checkNamespaceName
(
"abc.properties"
,
ConfigFileFormat
.
Properties
,
"abc"
);
checkNamespaceName
(
"abcproperties"
,
ConfigFileFormat
.
Properties
,
"abcproperties"
);
checkNamespaceName
(
"abc.pRopErties"
,
ConfigFileFormat
.
Properties
,
"abc"
);
checkNamespaceName
(
"abc.xml"
,
ConfigFileFormat
.
XML
,
"abc"
);
checkNamespaceName
(
"abc.xmL"
,
ConfigFileFormat
.
XML
,
"abc"
);
checkNamespaceName
(
"abc.json"
,
ConfigFileFormat
.
JSON
,
"abc"
);
checkNamespaceName
(
"abc.jsOn"
,
ConfigFileFormat
.
JSON
,
"abc"
);
checkNamespaceName
(
"abc.yaml"
,
ConfigFileFormat
.
YAML
,
"abc"
);
checkNamespaceName
(
"abc.yAml"
,
ConfigFileFormat
.
YAML
,
"abc"
);
checkNamespaceName
(
"abc.yml"
,
ConfigFileFormat
.
YML
,
"abc"
);
checkNamespaceName
(
"abc.yMl"
,
ConfigFileFormat
.
YML
,
"abc"
);
checkNamespaceName
(
"abc.proPerties.yml"
,
ConfigFileFormat
.
YML
,
"abc.proPerties"
);
}
private
void
checkFileFormat
(
String
namespaceName
,
ConfigFileFormat
expectedFormat
)
{
assertEquals
(
expectedFormat
,
defaultConfigFactory
.
determineFileFormat
(
namespaceName
));
}
private
void
checkNamespaceName
(
String
namespaceName
,
ConfigFileFormat
format
,
String
expectedNamespaceName
)
{
assertEquals
(
expectedNamespaceName
,
defaultConfigFactory
.
trimNamespaceFormat
(
namespaceName
,
format
));
}
public
static
class
MockConfigUtil
extends
ConfigUtil
{
public
static
class
MockConfigUtil
extends
ConfigUtil
{
@Override
@Override
public
String
getAppId
()
{
public
String
getAppId
()
{
...
...
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/AbstractSpringIntegrationTest.java
View file @
bf1b6374
...
@@ -7,8 +7,13 @@ import com.ctrip.framework.apollo.core.ConfigConsts;
...
@@ -7,8 +7,13 @@ import com.ctrip.framework.apollo.core.ConfigConsts;
import
com.ctrip.framework.apollo.internals.ConfigRepository
;
import
com.ctrip.framework.apollo.internals.ConfigRepository
;
import
com.ctrip.framework.apollo.internals.DefaultInjector
;
import
com.ctrip.framework.apollo.internals.DefaultInjector
;
import
com.ctrip.framework.apollo.internals.SimpleConfig
;
import
com.ctrip.framework.apollo.internals.SimpleConfig
;
import
com.ctrip.framework.apollo.spring.property.SpringValueDefinitionProcessor
;
import
com.ctrip.framework.apollo.internals.YamlConfigFile
;
import
com.ctrip.framework.apollo.spring.config.PropertySourcesProcessor
;
import
com.ctrip.framework.apollo.util.ConfigUtil
;
import
com.ctrip.framework.apollo.util.ConfigUtil
;
import
com.google.common.base.Charsets
;
import
com.google.common.io.Files
;
import
java.io.File
;
import
java.io.IOException
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Method
;
import
java.util.Calendar
;
import
java.util.Calendar
;
import
java.util.Date
;
import
java.util.Date
;
...
@@ -25,7 +30,6 @@ import com.ctrip.framework.apollo.ConfigService;
...
@@ -25,7 +30,6 @@ import com.ctrip.framework.apollo.ConfigService;
import
com.ctrip.framework.apollo.build.MockInjector
;
import
com.ctrip.framework.apollo.build.MockInjector
;
import
com.ctrip.framework.apollo.core.enums.ConfigFileFormat
;
import
com.ctrip.framework.apollo.core.enums.ConfigFileFormat
;
import
com.ctrip.framework.apollo.internals.ConfigManager
;
import
com.ctrip.framework.apollo.internals.ConfigManager
;
import
com.ctrip.framework.apollo.spring.config.PropertySourcesProcessor
;
import
com.google.common.collect.Maps
;
import
com.google.common.collect.Maps
;
/**
/**
...
@@ -33,12 +37,16 @@ import com.google.common.collect.Maps;
...
@@ -33,12 +37,16 @@ import com.google.common.collect.Maps;
*/
*/
public
abstract
class
AbstractSpringIntegrationTest
{
public
abstract
class
AbstractSpringIntegrationTest
{
private
static
final
Map
<
String
,
Config
>
CONFIG_REGISTRY
=
Maps
.
newHashMap
();
private
static
final
Map
<
String
,
Config
>
CONFIG_REGISTRY
=
Maps
.
newHashMap
();
private
static
final
Map
<
String
,
ConfigFile
>
CONFIG_FILE_REGISTRY
=
Maps
.
newHashMap
();
private
static
Method
CONFIG_SERVICE_RESET
;
private
static
Method
CONFIG_SERVICE_RESET
;
private
static
Method
PROPERTY_SOURCES_PROCESSOR_RESET
;
static
{
static
{
try
{
try
{
CONFIG_SERVICE_RESET
=
ConfigService
.
class
.
getDeclaredMethod
(
"reset"
);
CONFIG_SERVICE_RESET
=
ConfigService
.
class
.
getDeclaredMethod
(
"reset"
);
ReflectionUtils
.
makeAccessible
(
CONFIG_SERVICE_RESET
);
ReflectionUtils
.
makeAccessible
(
CONFIG_SERVICE_RESET
);
PROPERTY_SOURCES_PROCESSOR_RESET
=
PropertySourcesProcessor
.
class
.
getDeclaredMethod
(
"reset"
);
ReflectionUtils
.
makeAccessible
(
PROPERTY_SOURCES_PROCESSOR_RESET
);
}
catch
(
NoSuchMethodException
e
)
{
}
catch
(
NoSuchMethodException
e
)
{
e
.
printStackTrace
();
e
.
printStackTrace
();
}
}
...
@@ -66,6 +74,29 @@ public abstract class AbstractSpringIntegrationTest {
...
@@ -66,6 +74,29 @@ public abstract class AbstractSpringIntegrationTest {
return
config
;
return
config
;
}
}
protected
static
Properties
readYamlContentAsConfigFileProperties
(
String
caseName
)
throws
IOException
{
File
file
=
new
File
(
"src/test/resources/spring/yaml/"
+
caseName
);
String
yamlContent
=
Files
.
toString
(
file
,
Charsets
.
UTF_8
);
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
ConfigConsts
.
CONFIG_FILE_CONTENT_KEY
,
yamlContent
);
return
properties
;
}
protected
static
YamlConfigFile
prepareYamlConfigFile
(
String
namespaceNameWithFormat
,
Properties
properties
)
{
ConfigRepository
configRepository
=
mock
(
ConfigRepository
.
class
);
when
(
configRepository
.
getConfig
()).
thenReturn
(
properties
);
YamlConfigFile
configFile
=
new
YamlConfigFile
(
namespaceNameWithFormat
,
configRepository
);
mockConfigFile
(
namespaceNameWithFormat
,
configFile
);
return
configFile
;
}
protected
Properties
assembleProperties
(
String
key
,
String
value
)
{
protected
Properties
assembleProperties
(
String
key
,
String
value
)
{
Properties
properties
=
new
Properties
();
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
key
,
value
);
properties
.
setProperty
(
key
,
value
);
...
@@ -105,12 +136,20 @@ public abstract class AbstractSpringIntegrationTest {
...
@@ -105,12 +136,20 @@ public abstract class AbstractSpringIntegrationTest {
CONFIG_REGISTRY
.
put
(
namespace
,
config
);
CONFIG_REGISTRY
.
put
(
namespace
,
config
);
}
}
protected
static
void
mockConfigFile
(
String
namespaceNameWithFormat
,
ConfigFile
configFile
)
{
CONFIG_FILE_REGISTRY
.
put
(
namespaceNameWithFormat
,
configFile
);
}
protected
static
void
doSetUp
()
{
protected
static
void
doSetUp
()
{
//as ConfigService is singleton, so we must manually clear its container
//as ConfigService is singleton, so we must manually clear its container
ReflectionUtils
.
invokeMethod
(
CONFIG_SERVICE_RESET
,
null
);
ReflectionUtils
.
invokeMethod
(
CONFIG_SERVICE_RESET
,
null
);
//as PropertySourcesProcessor has some static variables, so we must manually clear them
ReflectionUtils
.
invokeMethod
(
PROPERTY_SOURCES_PROCESSOR_RESET
,
null
);
DefaultInjector
defaultInjector
=
new
DefaultInjector
();
ConfigManager
defaultConfigManager
=
defaultInjector
.
getInstance
(
ConfigManager
.
class
);
MockInjector
.
reset
();
MockInjector
.
reset
();
MockInjector
.
setInstance
(
ConfigManager
.
class
,
new
MockConfigManager
());
MockInjector
.
setInstance
(
ConfigManager
.
class
,
new
MockConfigManager
(
defaultConfigManager
));
MockInjector
.
setDelegate
(
new
DefaultInjector
()
);
MockInjector
.
setDelegate
(
defaultInjector
);
}
}
protected
static
void
doTearDown
()
{
protected
static
void
doTearDown
()
{
...
@@ -119,14 +158,28 @@ public abstract class AbstractSpringIntegrationTest {
...
@@ -119,14 +158,28 @@ public abstract class AbstractSpringIntegrationTest {
private
static
class
MockConfigManager
implements
ConfigManager
{
private
static
class
MockConfigManager
implements
ConfigManager
{
private
final
ConfigManager
delegate
;
public
MockConfigManager
(
ConfigManager
delegate
)
{
this
.
delegate
=
delegate
;
}
@Override
@Override
public
Config
getConfig
(
String
namespace
)
{
public
Config
getConfig
(
String
namespace
)
{
return
CONFIG_REGISTRY
.
get
(
namespace
);
Config
config
=
CONFIG_REGISTRY
.
get
(
namespace
);
if
(
config
!=
null
)
{
return
config
;
}
return
delegate
.
getConfig
(
namespace
);
}
}
@Override
@Override
public
ConfigFile
getConfigFile
(
String
namespace
,
ConfigFileFormat
configFileFormat
)
{
public
ConfigFile
getConfigFile
(
String
namespace
,
ConfigFileFormat
configFileFormat
)
{
return
null
;
ConfigFile
configFile
=
CONFIG_FILE_REGISTRY
.
get
(
String
.
format
(
"%s.%s"
,
namespace
,
configFileFormat
.
getValue
()));
if
(
configFile
!=
null
)
{
return
configFile
;
}
return
delegate
.
getConfigFile
(
namespace
,
configFileFormat
);
}
}
}
}
...
...
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/BootstrapConfigTest.java
View file @
bf1b6374
...
@@ -138,6 +138,45 @@ public class BootstrapConfigTest {
...
@@ -138,6 +138,45 @@ public class BootstrapConfigTest {
}
}
}
}
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@SpringBootTest
(
classes
=
ConfigurationWithConditionalOnProperty
.
class
)
@DirtiesContext
public
static
class
TestWithBootstrapEnabledAndNamespacesAndConditionalOnWithYamlFile
extends
AbstractSpringIntegrationTest
{
@Autowired
(
required
=
false
)
private
TestBean
testBean
;
@BeforeClass
public
static
void
beforeClass
()
throws
Exception
{
doSetUp
();
System
.
setProperty
(
PropertySourcesConstants
.
APOLLO_BOOTSTRAP_ENABLED
,
"true"
);
System
.
setProperty
(
PropertySourcesConstants
.
APOLLO_BOOTSTRAP_NAMESPACES
,
String
.
format
(
"%s, %s"
,
"application.yml"
,
FX_APOLLO_NAMESPACE
));
prepareYamlConfigFile
(
"application.yml"
,
readYamlContentAsConfigFileProperties
(
"case6.yml"
));
Config
anotherConfig
=
mock
(
Config
.
class
);
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
anotherConfig
);
mockConfig
(
FX_APOLLO_NAMESPACE
,
anotherConfig
);
}
@AfterClass
public
static
void
afterClass
()
throws
Exception
{
System
.
clearProperty
(
PropertySourcesConstants
.
APOLLO_BOOTSTRAP_ENABLED
);
System
.
clearProperty
(
PropertySourcesConstants
.
APOLLO_BOOTSTRAP_NAMESPACES
);
doTearDown
();
}
@Test
public
void
test
()
throws
Exception
{
Assert
.
assertNotNull
(
testBean
);
Assert
.
assertTrue
(
testBean
.
execute
());
}
}
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@SpringBootTest
(
classes
=
ConfigurationWithConditionalOnProperty
.
class
)
@SpringBootTest
(
classes
=
ConfigurationWithConditionalOnProperty
.
class
)
@DirtiesContext
@DirtiesContext
...
@@ -174,6 +213,39 @@ public class BootstrapConfigTest {
...
@@ -174,6 +213,39 @@ public class BootstrapConfigTest {
}
}
}
}
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@SpringBootTest
(
classes
=
ConfigurationWithConditionalOnProperty
.
class
)
@DirtiesContext
public
static
class
TestWithBootstrapEnabledAndDefaultNamespacesAndConditionalOnFailedWithYamlFile
extends
AbstractSpringIntegrationTest
{
@Autowired
(
required
=
false
)
private
TestBean
testBean
;
@BeforeClass
public
static
void
beforeClass
()
throws
Exception
{
doSetUp
();
System
.
setProperty
(
PropertySourcesConstants
.
APOLLO_BOOTSTRAP_ENABLED
,
"true"
);
System
.
setProperty
(
PropertySourcesConstants
.
APOLLO_BOOTSTRAP_NAMESPACES
,
"application.yml"
);
prepareYamlConfigFile
(
"application.yml"
,
readYamlContentAsConfigFileProperties
(
"case7.yml"
));
}
@AfterClass
public
static
void
afterClass
()
throws
Exception
{
System
.
clearProperty
(
PropertySourcesConstants
.
APOLLO_BOOTSTRAP_ENABLED
);
System
.
clearProperty
(
PropertySourcesConstants
.
APOLLO_BOOTSTRAP_NAMESPACES
);
doTearDown
();
}
@Test
public
void
test
()
throws
Exception
{
Assert
.
assertNull
(
testBean
);
}
}
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@SpringBootTest
(
classes
=
ConfigurationWithoutConditionalOnProperty
.
class
)
@SpringBootTest
(
classes
=
ConfigurationWithoutConditionalOnProperty
.
class
)
@DirtiesContext
@DirtiesContext
...
@@ -208,6 +280,40 @@ public class BootstrapConfigTest {
...
@@ -208,6 +280,40 @@ public class BootstrapConfigTest {
}
}
}
}
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@SpringBootTest
(
classes
=
ConfigurationWithoutConditionalOnProperty
.
class
)
@DirtiesContext
public
static
class
TestWithBootstrapEnabledAndDefaultNamespacesAndConditionalOffWithYamlFile
extends
AbstractSpringIntegrationTest
{
@Autowired
(
required
=
false
)
private
TestBean
testBean
;
@BeforeClass
public
static
void
beforeClass
()
throws
Exception
{
doSetUp
();
System
.
setProperty
(
PropertySourcesConstants
.
APOLLO_BOOTSTRAP_ENABLED
,
"true"
);
System
.
setProperty
(
PropertySourcesConstants
.
APOLLO_BOOTSTRAP_NAMESPACES
,
"application.yml"
);
prepareYamlConfigFile
(
"application.yml"
,
readYamlContentAsConfigFileProperties
(
"case8.yml"
));
}
@AfterClass
public
static
void
afterClass
()
throws
Exception
{
System
.
clearProperty
(
PropertySourcesConstants
.
APOLLO_BOOTSTRAP_ENABLED
);
System
.
clearProperty
(
PropertySourcesConstants
.
APOLLO_BOOTSTRAP_NAMESPACES
);
doTearDown
();
}
@Test
public
void
test
()
throws
Exception
{
Assert
.
assertNotNull
(
testBean
);
Assert
.
assertTrue
(
testBean
.
execute
());
}
}
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@SpringBootTest
(
classes
=
ConfigurationWithConditionalOnProperty
.
class
)
@SpringBootTest
(
classes
=
ConfigurationWithConditionalOnProperty
.
class
)
@DirtiesContext
@DirtiesContext
...
@@ -272,7 +378,6 @@ public class BootstrapConfigTest {
...
@@ -272,7 +378,6 @@ public class BootstrapConfigTest {
}
}
}
}
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@SpringBootTest
(
classes
=
ConfigurationWithoutConditionalOnProperty
.
class
)
@SpringBootTest
(
classes
=
ConfigurationWithoutConditionalOnProperty
.
class
)
@DirtiesContext
@DirtiesContext
...
@@ -306,14 +411,13 @@ public class BootstrapConfigTest {
...
@@ -306,14 +411,13 @@ public class BootstrapConfigTest {
Boolean
containsApollo
=
!
Collections2
.
filter
(
processorList
,
new
Predicate
<
EnvironmentPostProcessor
>()
{
Boolean
containsApollo
=
!
Collections2
.
filter
(
processorList
,
new
Predicate
<
EnvironmentPostProcessor
>()
{
@Override
@Override
public
boolean
apply
(
EnvironmentPostProcessor
input
)
{
public
boolean
apply
(
EnvironmentPostProcessor
input
)
{
return
input
instanceof
ApolloApplicationContextInitializer
;
return
input
instanceof
ApolloApplicationContextInitializer
;
}
}
}).
isEmpty
();
}).
isEmpty
();
Assert
.
assertTrue
(
containsApollo
);
Assert
.
assertTrue
(
containsApollo
);
}
}
}
}
@EnableAutoConfiguration
@EnableAutoConfiguration
@Configuration
@Configuration
static
class
ConfigurationWithoutConditionalOnProperty
{
static
class
ConfigurationWithoutConditionalOnProperty
{
...
...
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigAnnotationTest.java
View file @
bf1b6374
...
@@ -3,12 +3,16 @@ package com.ctrip.framework.apollo.spring;
...
@@ -3,12 +3,16 @@ package com.ctrip.framework.apollo.spring;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.ConfigChangeListener
;
import
com.ctrip.framework.apollo.ConfigChangeListener
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
com.ctrip.framework.apollo.internals.YamlConfigFile
;
import
com.ctrip.framework.apollo.model.ConfigChange
;
import
com.ctrip.framework.apollo.model.ConfigChangeEvent
;
import
com.ctrip.framework.apollo.model.ConfigChangeEvent
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloConfig
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloConfig
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener
;
import
com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig
;
import
com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Sets
;
import
com.google.common.collect.Sets
;
import
com.google.common.util.concurrent.SettableFuture
;
import
java.util.concurrent.TimeUnit
;
import
org.junit.Test
;
import
org.junit.Test
;
import
org.mockito.ArgumentCaptor
;
import
org.mockito.ArgumentCaptor
;
import
org.mockito.invocation.InvocationOnMock
;
import
org.mockito.invocation.InvocationOnMock
;
...
@@ -23,6 +27,7 @@ import java.util.Set;
...
@@ -23,6 +27,7 @@ import java.util.Set;
import
static
java
.
util
.
Arrays
.
asList
;
import
static
java
.
util
.
Arrays
.
asList
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
mockito
.
Matchers
.
any
;
import
static
org
.
mockito
.
Matchers
.
any
;
import
static
org
.
mockito
.
Matchers
.
anySetOf
;
import
static
org
.
mockito
.
Matchers
.
anySetOf
;
import
static
org
.
mockito
.
Mockito
.
doAnswer
;
import
static
org
.
mockito
.
Mockito
.
doAnswer
;
...
@@ -35,20 +40,28 @@ import static org.mockito.Mockito.verify;
...
@@ -35,20 +40,28 @@ import static org.mockito.Mockito.verify;
*/
*/
public
class
JavaConfigAnnotationTest
extends
AbstractSpringIntegrationTest
{
public
class
JavaConfigAnnotationTest
extends
AbstractSpringIntegrationTest
{
private
static
final
String
FX_APOLLO_NAMESPACE
=
"FX.apollo"
;
private
static
final
String
FX_APOLLO_NAMESPACE
=
"FX.apollo"
;
private
static
final
String
APPLICATION_YAML_NAMESPACE
=
"application.yaml"
;
@Test
@Test
public
void
testApolloConfig
()
throws
Exception
{
public
void
testApolloConfig
()
throws
Exception
{
Config
applicationConfig
=
mock
(
Config
.
class
);
Config
applicationConfig
=
mock
(
Config
.
class
);
Config
fxApolloConfig
=
mock
(
Config
.
class
);
Config
fxApolloConfig
=
mock
(
Config
.
class
);
String
someKey
=
"someKey"
;
String
someValue
=
"someValue"
;
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
applicationConfig
);
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
applicationConfig
);
mockConfig
(
FX_APOLLO_NAMESPACE
,
fxApolloConfig
);
mockConfig
(
FX_APOLLO_NAMESPACE
,
fxApolloConfig
);
prepareYamlConfigFile
(
APPLICATION_YAML_NAMESPACE
,
readYamlContentAsConfigFileProperties
(
"case9.yml"
));
TestApolloConfigBean1
bean
=
getBean
(
TestApolloConfigBean1
.
class
,
AppConfig1
.
class
);
TestApolloConfigBean1
bean
=
getBean
(
TestApolloConfigBean1
.
class
,
AppConfig1
.
class
);
assertEquals
(
applicationConfig
,
bean
.
getConfig
());
assertEquals
(
applicationConfig
,
bean
.
getConfig
());
assertEquals
(
applicationConfig
,
bean
.
getAnotherConfig
());
assertEquals
(
applicationConfig
,
bean
.
getAnotherConfig
());
assertEquals
(
fxApolloConfig
,
bean
.
getYetAnotherConfig
());
assertEquals
(
fxApolloConfig
,
bean
.
getYetAnotherConfig
());
Config
yamlConfig
=
bean
.
getYamlConfig
();
assertEquals
(
someValue
,
yamlConfig
.
getProperty
(
someKey
,
null
));
}
}
@Test
(
expected
=
BeanCreationException
.
class
)
@Test
(
expected
=
BeanCreationException
.
class
)
...
@@ -239,6 +252,33 @@ public class JavaConfigAnnotationTest extends AbstractSpringIntegrationTest {
...
@@ -239,6 +252,33 @@ public class JavaConfigAnnotationTest extends AbstractSpringIntegrationTest {
assertEquals
(
asList
(
Sets
.
newHashSet
(
"anotherKey"
)),
fxApolloConfigInterestedKeys
.
getAllValues
());
assertEquals
(
asList
(
Sets
.
newHashSet
(
"anotherKey"
)),
fxApolloConfigInterestedKeys
.
getAllValues
());
}
}
@Test
public
void
testApolloConfigChangeListenerWithYamlFile
()
throws
Exception
{
String
someKey
=
"someKey"
;
String
someValue
=
"someValue"
;
String
anotherValue
=
"anotherValue"
;
YamlConfigFile
configFile
=
prepareYamlConfigFile
(
APPLICATION_YAML_NAMESPACE
,
readYamlContentAsConfigFileProperties
(
"case9.yml"
));
TestApolloConfigChangeListenerWithYamlFile
bean
=
getBean
(
TestApolloConfigChangeListenerWithYamlFile
.
class
,
AppConfig9
.
class
);
Config
yamlConfig
=
bean
.
getYamlConfig
();
SettableFuture
<
ConfigChangeEvent
>
future
=
bean
.
getConfigChangeEventFuture
();
assertEquals
(
someValue
,
yamlConfig
.
getProperty
(
someKey
,
null
));
assertFalse
(
future
.
isDone
());
configFile
.
onRepositoryChange
(
APPLICATION_YAML_NAMESPACE
,
readYamlContentAsConfigFileProperties
(
"case9-new.yml"
));
ConfigChangeEvent
configChangeEvent
=
future
.
get
(
100
,
TimeUnit
.
MILLISECONDS
);
ConfigChange
change
=
configChangeEvent
.
getChange
(
someKey
);
assertEquals
(
someValue
,
change
.
getOldValue
());
assertEquals
(
anotherValue
,
change
.
getNewValue
());
assertEquals
(
anotherValue
,
yamlConfig
.
getProperty
(
someKey
,
null
));
}
private
<
T
>
T
getBean
(
Class
<
T
>
beanClass
,
Class
<?>...
annotatedClasses
)
{
private
<
T
>
T
getBean
(
Class
<
T
>
beanClass
,
Class
<?>...
annotatedClasses
)
{
AnnotationConfigApplicationContext
context
=
new
AnnotationConfigApplicationContext
(
annotatedClasses
);
AnnotationConfigApplicationContext
context
=
new
AnnotationConfigApplicationContext
(
annotatedClasses
);
...
@@ -317,6 +357,15 @@ public class JavaConfigAnnotationTest extends AbstractSpringIntegrationTest {
...
@@ -317,6 +357,15 @@ public class JavaConfigAnnotationTest extends AbstractSpringIntegrationTest {
}
}
}
}
@Configuration
@EnableApolloConfig
(
APPLICATION_YAML_NAMESPACE
)
static
class
AppConfig9
{
@Bean
public
TestApolloConfigChangeListenerWithYamlFile
bean
()
{
return
new
TestApolloConfigChangeListenerWithYamlFile
();
}
}
static
class
TestApolloConfigBean1
{
static
class
TestApolloConfigBean1
{
@ApolloConfig
@ApolloConfig
private
Config
config
;
private
Config
config
;
...
@@ -324,6 +373,8 @@ public class JavaConfigAnnotationTest extends AbstractSpringIntegrationTest {
...
@@ -324,6 +373,8 @@ public class JavaConfigAnnotationTest extends AbstractSpringIntegrationTest {
private
Config
anotherConfig
;
private
Config
anotherConfig
;
@ApolloConfig
(
FX_APOLLO_NAMESPACE
)
@ApolloConfig
(
FX_APOLLO_NAMESPACE
)
private
Config
yetAnotherConfig
;
private
Config
yetAnotherConfig
;
@ApolloConfig
(
APPLICATION_YAML_NAMESPACE
)
private
Config
yamlConfig
;
public
Config
getConfig
()
{
public
Config
getConfig
()
{
return
config
;
return
config
;
...
@@ -336,6 +387,10 @@ public class JavaConfigAnnotationTest extends AbstractSpringIntegrationTest {
...
@@ -336,6 +387,10 @@ public class JavaConfigAnnotationTest extends AbstractSpringIntegrationTest {
public
Config
getYetAnotherConfig
()
{
public
Config
getYetAnotherConfig
()
{
return
yetAnotherConfig
;
return
yetAnotherConfig
;
}
}
public
Config
getYamlConfig
()
{
return
yamlConfig
;
}
}
}
static
class
TestApolloConfigBean2
{
static
class
TestApolloConfigBean2
{
...
@@ -425,4 +480,25 @@ public class JavaConfigAnnotationTest extends AbstractSpringIntegrationTest {
...
@@ -425,4 +480,25 @@ public class JavaConfigAnnotationTest extends AbstractSpringIntegrationTest {
}
}
}
}
static
class
TestApolloConfigChangeListenerWithYamlFile
{
private
SettableFuture
<
ConfigChangeEvent
>
configChangeEventFuture
=
SettableFuture
.
create
();
@ApolloConfig
(
APPLICATION_YAML_NAMESPACE
)
private
Config
yamlConfig
;
@ApolloConfigChangeListener
(
APPLICATION_YAML_NAMESPACE
)
private
void
onChange
(
ConfigChangeEvent
event
)
{
configChangeEventFuture
.
set
(
event
);
}
public
SettableFuture
<
ConfigChangeEvent
>
getConfigChangeEventFuture
()
{
return
configChangeEventFuture
;
}
public
Config
getYamlConfig
()
{
return
yamlConfig
;
}
}
}
}
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderAutoUpdateTest.java
View file @
bf1b6374
...
@@ -7,6 +7,7 @@ import static org.junit.Assert.assertTrue;
...
@@ -7,6 +7,7 @@ import static org.junit.Assert.assertTrue;
import
com.ctrip.framework.apollo.build.MockInjector
;
import
com.ctrip.framework.apollo.build.MockInjector
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
com.ctrip.framework.apollo.internals.SimpleConfig
;
import
com.ctrip.framework.apollo.internals.SimpleConfig
;
import
com.ctrip.framework.apollo.internals.YamlConfigFile
;
import
com.ctrip.framework.apollo.spring.JavaConfigPlaceholderTest.JsonBean
;
import
com.ctrip.framework.apollo.spring.JavaConfigPlaceholderTest.JsonBean
;
import
com.ctrip.framework.apollo.spring.XmlConfigPlaceholderTest.TestXmlBean
;
import
com.ctrip.framework.apollo.spring.XmlConfigPlaceholderTest.TestXmlBean
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue
;
...
@@ -71,6 +72,31 @@ public class JavaConfigPlaceholderAutoUpdateTest extends AbstractSpringIntegrati
...
@@ -71,6 +72,31 @@ public class JavaConfigPlaceholderAutoUpdateTest extends AbstractSpringIntegrati
assertEquals
(
newBatch
,
bean
.
getBatch
());
assertEquals
(
newBatch
,
bean
.
getBatch
());
}
}
@Test
public
void
testAutoUpdateWithOneYamlFile
()
throws
Exception
{
int
initialTimeout
=
1000
;
int
initialBatch
=
2000
;
int
newTimeout
=
1001
;
int
newBatch
=
2001
;
YamlConfigFile
configFile
=
prepareYamlConfigFile
(
"application.yaml"
,
readYamlContentAsConfigFileProperties
(
"case1.yaml"
));
AnnotationConfigApplicationContext
context
=
new
AnnotationConfigApplicationContext
(
AppConfig12
.
class
);
TestJavaConfigBean
bean
=
context
.
getBean
(
TestJavaConfigBean
.
class
);
assertEquals
(
initialTimeout
,
bean
.
getTimeout
());
assertEquals
(
initialBatch
,
bean
.
getBatch
());
configFile
.
onRepositoryChange
(
"application.yaml"
,
readYamlContentAsConfigFileProperties
(
"case1-new.yaml"
));
TimeUnit
.
MILLISECONDS
.
sleep
(
100
);
assertEquals
(
newTimeout
,
bean
.
getTimeout
());
assertEquals
(
newBatch
,
bean
.
getBatch
());
}
@Test
@Test
public
void
testAutoUpdateWithValueAndXmlProperty
()
throws
Exception
{
public
void
testAutoUpdateWithValueAndXmlProperty
()
throws
Exception
{
int
initialTimeout
=
1000
;
int
initialTimeout
=
1000
;
...
@@ -106,6 +132,36 @@ public class JavaConfigPlaceholderAutoUpdateTest extends AbstractSpringIntegrati
...
@@ -106,6 +132,36 @@ public class JavaConfigPlaceholderAutoUpdateTest extends AbstractSpringIntegrati
assertEquals
(
newBatch
,
xmlBean
.
getBatch
());
assertEquals
(
newBatch
,
xmlBean
.
getBatch
());
}
}
@Test
public
void
testAutoUpdateWithYamlFileWithValueAndXmlProperty
()
throws
Exception
{
int
initialTimeout
=
1000
;
int
initialBatch
=
2000
;
int
newTimeout
=
1001
;
int
newBatch
=
2001
;
YamlConfigFile
configFile
=
prepareYamlConfigFile
(
"application.yaml"
,
readYamlContentAsConfigFileProperties
(
"case1.yaml"
));
AnnotationConfigApplicationContext
context
=
new
AnnotationConfigApplicationContext
(
AppConfig13
.
class
);
TestJavaConfigBean
javaConfigBean
=
context
.
getBean
(
TestJavaConfigBean
.
class
);
TestXmlBean
xmlBean
=
context
.
getBean
(
TestXmlBean
.
class
);
assertEquals
(
initialTimeout
,
javaConfigBean
.
getTimeout
());
assertEquals
(
initialBatch
,
javaConfigBean
.
getBatch
());
assertEquals
(
initialTimeout
,
xmlBean
.
getTimeout
());
assertEquals
(
initialBatch
,
xmlBean
.
getBatch
());
configFile
.
onRepositoryChange
(
"application.yaml"
,
readYamlContentAsConfigFileProperties
(
"case1-new.yaml"
));
TimeUnit
.
MILLISECONDS
.
sleep
(
100
);
assertEquals
(
newTimeout
,
javaConfigBean
.
getTimeout
());
assertEquals
(
newBatch
,
javaConfigBean
.
getBatch
());
assertEquals
(
newTimeout
,
xmlBean
.
getTimeout
());
assertEquals
(
newBatch
,
xmlBean
.
getBatch
());
}
@Test
@Test
public
void
testAutoUpdateDisabled
()
throws
Exception
{
public
void
testAutoUpdateDisabled
()
throws
Exception
{
int
initialTimeout
=
1000
;
int
initialTimeout
=
1000
;
...
@@ -213,6 +269,35 @@ public class JavaConfigPlaceholderAutoUpdateTest extends AbstractSpringIntegrati
...
@@ -213,6 +269,35 @@ public class JavaConfigPlaceholderAutoUpdateTest extends AbstractSpringIntegrati
assertEquals
(
someBatch
,
bean
.
getBatch
());
assertEquals
(
someBatch
,
bean
.
getBatch
());
}
}
@Test
public
void
testAutoUpdateWithMultipleNamespacesWithSamePropertiesWithYamlFile
()
throws
Exception
{
int
someTimeout
=
1000
;
int
someBatch
=
2000
;
int
anotherBatch
=
3000
;
int
someNewBatch
=
2001
;
YamlConfigFile
configFile
=
prepareYamlConfigFile
(
"application.yml"
,
readYamlContentAsConfigFileProperties
(
"case2.yml"
));
Properties
fxApolloProperties
=
assembleProperties
(
TIMEOUT_PROPERTY
,
String
.
valueOf
(
someTimeout
),
BATCH_PROPERTY
,
String
.
valueOf
(
anotherBatch
));
prepareConfig
(
FX_APOLLO_NAMESPACE
,
fxApolloProperties
);
AnnotationConfigApplicationContext
context
=
new
AnnotationConfigApplicationContext
(
AppConfig14
.
class
);
TestJavaConfigBean
bean
=
context
.
getBean
(
TestJavaConfigBean
.
class
);
assertEquals
(
someTimeout
,
bean
.
getTimeout
());
assertEquals
(
someBatch
,
bean
.
getBatch
());
configFile
.
onRepositoryChange
(
"application.yml"
,
readYamlContentAsConfigFileProperties
(
"case2-new.yml"
));
TimeUnit
.
MILLISECONDS
.
sleep
(
100
);
assertEquals
(
someTimeout
,
bean
.
getTimeout
());
assertEquals
(
someNewBatch
,
bean
.
getBatch
());
}
@Test
@Test
public
void
testAutoUpdateWithNewProperties
()
throws
Exception
{
public
void
testAutoUpdateWithNewProperties
()
throws
Exception
{
int
initialTimeout
=
1000
;
int
initialTimeout
=
1000
;
...
@@ -241,6 +326,30 @@ public class JavaConfigPlaceholderAutoUpdateTest extends AbstractSpringIntegrati
...
@@ -241,6 +326,30 @@ public class JavaConfigPlaceholderAutoUpdateTest extends AbstractSpringIntegrati
assertEquals
(
newBatch
,
bean
.
getBatch
());
assertEquals
(
newBatch
,
bean
.
getBatch
());
}
}
@Test
public
void
testAutoUpdateWithNewPropertiesWithYamlFile
()
throws
Exception
{
int
initialTimeout
=
1000
;
int
newTimeout
=
1001
;
int
newBatch
=
2001
;
YamlConfigFile
configFile
=
prepareYamlConfigFile
(
"application.yaml"
,
readYamlContentAsConfigFileProperties
(
"case3.yaml"
));
AnnotationConfigApplicationContext
context
=
new
AnnotationConfigApplicationContext
(
AppConfig12
.
class
);
TestJavaConfigBean
bean
=
context
.
getBean
(
TestJavaConfigBean
.
class
);
assertEquals
(
initialTimeout
,
bean
.
getTimeout
());
assertEquals
(
DEFAULT_BATCH
,
bean
.
getBatch
());
configFile
.
onRepositoryChange
(
"application.yaml"
,
readYamlContentAsConfigFileProperties
(
"case3-new.yaml"
));
TimeUnit
.
MILLISECONDS
.
sleep
(
100
);
assertEquals
(
newTimeout
,
bean
.
getTimeout
());
assertEquals
(
newBatch
,
bean
.
getBatch
());
}
@Test
@Test
public
void
testAutoUpdateWithIrrelevantProperties
()
throws
Exception
{
public
void
testAutoUpdateWithIrrelevantProperties
()
throws
Exception
{
int
initialTimeout
=
1000
;
int
initialTimeout
=
1000
;
...
@@ -301,6 +410,29 @@ public class JavaConfigPlaceholderAutoUpdateTest extends AbstractSpringIntegrati
...
@@ -301,6 +410,29 @@ public class JavaConfigPlaceholderAutoUpdateTest extends AbstractSpringIntegrati
assertEquals
(
DEFAULT_BATCH
,
bean
.
getBatch
());
assertEquals
(
DEFAULT_BATCH
,
bean
.
getBatch
());
}
}
@Test
public
void
testAutoUpdateWithDeletedPropertiesWithYamlFile
()
throws
Exception
{
int
initialTimeout
=
1000
;
int
initialBatch
=
2000
;
YamlConfigFile
configFile
=
prepareYamlConfigFile
(
"application.yaml"
,
readYamlContentAsConfigFileProperties
(
"case4.yaml"
));
AnnotationConfigApplicationContext
context
=
new
AnnotationConfigApplicationContext
(
AppConfig12
.
class
);
TestJavaConfigBean
bean
=
context
.
getBean
(
TestJavaConfigBean
.
class
);
assertEquals
(
initialTimeout
,
bean
.
getTimeout
());
assertEquals
(
initialBatch
,
bean
.
getBatch
());
configFile
.
onRepositoryChange
(
"application.yaml"
,
readYamlContentAsConfigFileProperties
(
"case4-new.yaml"
));
TimeUnit
.
MILLISECONDS
.
sleep
(
100
);
assertEquals
(
DEFAULT_TIMEOUT
,
bean
.
getTimeout
());
assertEquals
(
DEFAULT_BATCH
,
bean
.
getBatch
());
}
@Test
@Test
public
void
testAutoUpdateWithMultipleNamespacesWithSamePropertiesDeleted
()
throws
Exception
{
public
void
testAutoUpdateWithMultipleNamespacesWithSamePropertiesDeleted
()
throws
Exception
{
int
someTimeout
=
1000
;
int
someTimeout
=
1000
;
...
@@ -389,6 +521,30 @@ public class JavaConfigPlaceholderAutoUpdateTest extends AbstractSpringIntegrati
...
@@ -389,6 +521,30 @@ public class JavaConfigPlaceholderAutoUpdateTest extends AbstractSpringIntegrati
assertEquals
(
initialBatch
,
bean
.
getBatch
());
assertEquals
(
initialBatch
,
bean
.
getBatch
());
}
}
@Test
public
void
testAutoUpdateWithTypeMismatchWithYamlFile
()
throws
Exception
{
int
initialTimeout
=
1000
;
int
initialBatch
=
2000
;
int
newTimeout
=
1001
;
YamlConfigFile
configFile
=
prepareYamlConfigFile
(
"application.yaml"
,
readYamlContentAsConfigFileProperties
(
"case5.yaml"
));
AnnotationConfigApplicationContext
context
=
new
AnnotationConfigApplicationContext
(
AppConfig12
.
class
);
TestJavaConfigBean
bean
=
context
.
getBean
(
TestJavaConfigBean
.
class
);
assertEquals
(
initialTimeout
,
bean
.
getTimeout
());
assertEquals
(
initialBatch
,
bean
.
getBatch
());
configFile
.
onRepositoryChange
(
"application.yaml"
,
readYamlContentAsConfigFileProperties
(
"case5-new.yaml"
));
TimeUnit
.
MILLISECONDS
.
sleep
(
100
);
assertEquals
(
newTimeout
,
bean
.
getTimeout
());
assertEquals
(
initialBatch
,
bean
.
getBatch
());
}
@Test
@Test
public
void
testAutoUpdateWithValueInjectedAsParameter
()
throws
Exception
{
public
void
testAutoUpdateWithValueInjectedAsParameter
()
throws
Exception
{
int
initialTimeout
=
1000
;
int
initialTimeout
=
1000
;
...
@@ -949,6 +1105,34 @@ public class JavaConfigPlaceholderAutoUpdateTest extends AbstractSpringIntegrati
...
@@ -949,6 +1105,34 @@ public class JavaConfigPlaceholderAutoUpdateTest extends AbstractSpringIntegrati
}
}
}
}
@Configuration
@EnableApolloConfig
(
"application.yaMl"
)
static
class
AppConfig12
{
@Bean
TestJavaConfigBean
testJavaConfigBean
()
{
return
new
TestJavaConfigBean
();
}
}
@Configuration
@EnableApolloConfig
(
"application.yaml"
)
@ImportResource
(
"spring/XmlConfigPlaceholderTest11.xml"
)
static
class
AppConfig13
{
@Bean
TestJavaConfigBean
testJavaConfigBean
()
{
return
new
TestJavaConfigBean
();
}
}
@Configuration
@EnableApolloConfig
({
"application.yml"
,
"FX.apollo"
})
static
class
AppConfig14
{
@Bean
TestJavaConfigBean
testJavaConfigBean
()
{
return
new
TestJavaConfigBean
();
}
}
static
class
TestJavaConfigBean
{
static
class
TestJavaConfigBean
{
@Value
(
"${timeout:100}"
)
@Value
(
"${timeout:100}"
)
...
...
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderTest.java
View file @
bf1b6374
...
@@ -7,10 +7,12 @@ import static org.mockito.Mockito.mock;
...
@@ -7,10 +7,12 @@ import static org.mockito.Mockito.mock;
import
static
org
.
mockito
.
Mockito
.
when
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.PropertiesCompatibleConfigFile
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue
;
import
com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig
;
import
com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Properties
;
import
org.junit.Test
;
import
org.junit.Test
;
import
org.springframework.beans.factory.BeanCreationException
;
import
org.springframework.beans.factory.BeanCreationException
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
...
@@ -70,6 +72,38 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest {
...
@@ -70,6 +72,38 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest {
check
(
someTimeout
,
someBatch
,
AppConfig2
.
class
);
check
(
someTimeout
,
someBatch
,
AppConfig2
.
class
);
}
}
@Test
public
void
testPropertiesCompatiblePropertySource
()
throws
Exception
{
int
someTimeout
=
1000
;
int
someBatch
=
2000
;
Properties
properties
=
mock
(
Properties
.
class
);
when
(
properties
.
getProperty
(
TIMEOUT_PROPERTY
)).
thenReturn
(
String
.
valueOf
(
someTimeout
));
when
(
properties
.
getProperty
(
BATCH_PROPERTY
)).
thenReturn
(
String
.
valueOf
(
someBatch
));
PropertiesCompatibleConfigFile
configFile
=
mock
(
PropertiesCompatibleConfigFile
.
class
);
when
(
configFile
.
asProperties
()).
thenReturn
(
properties
);
mockConfigFile
(
"application.yaml"
,
configFile
);
check
(
someTimeout
,
someBatch
,
AppConfig9
.
class
);
}
@Test
public
void
testPropertiesCompatiblePropertySourceWithNonNormalizedCase
()
throws
Exception
{
int
someTimeout
=
1000
;
int
someBatch
=
2000
;
Properties
properties
=
mock
(
Properties
.
class
);
when
(
properties
.
getProperty
(
TIMEOUT_PROPERTY
)).
thenReturn
(
String
.
valueOf
(
someTimeout
));
when
(
properties
.
getProperty
(
BATCH_PROPERTY
)).
thenReturn
(
String
.
valueOf
(
someBatch
));
PropertiesCompatibleConfigFile
configFile
=
mock
(
PropertiesCompatibleConfigFile
.
class
);
when
(
configFile
.
asProperties
()).
thenReturn
(
properties
);
mockConfigFile
(
"application.yaml"
,
configFile
);
check
(
someTimeout
,
someBatch
,
AppConfig10
.
class
);
}
@Test
@Test
public
void
testMultiplePropertySources
()
throws
Exception
{
public
void
testMultiplePropertySources
()
throws
Exception
{
int
someTimeout
=
1000
;
int
someTimeout
=
1000
;
...
@@ -87,24 +121,27 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest {
...
@@ -87,24 +121,27 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest {
}
}
@Test
@Test
public
void
testMultiplePropertySourcesWithSameProperties
()
throws
Exception
{
public
void
testMultiplePropert
iesCompatiblePropert
ySourcesWithSameProperties
()
throws
Exception
{
int
someTimeout
=
1000
;
int
someTimeout
=
1000
;
int
anotherTimeout
=
someTimeout
+
1
;
int
anotherTimeout
=
someTimeout
+
1
;
int
someBatch
=
2000
;
int
someBatch
=
2000
;
Config
application
=
mock
(
Config
.
class
);
Properties
properties
=
mock
(
Properties
.
class
);
when
(
application
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someTimeout
));
when
(
application
.
getProperty
(
eq
(
BATCH_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someBatch
));
when
(
properties
.
getProperty
(
TIMEOUT_PROPERTY
)).
thenReturn
(
String
.
valueOf
(
someTimeout
));
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
application
);
when
(
properties
.
getProperty
(
BATCH_PROPERTY
)).
thenReturn
(
String
.
valueOf
(
someBatch
));
PropertiesCompatibleConfigFile
configFile
=
mock
(
PropertiesCompatibleConfigFile
.
class
);
when
(
configFile
.
asProperties
()).
thenReturn
(
properties
);
mockConfigFile
(
"application.yml"
,
configFile
);
Config
fxApollo
=
mock
(
Config
.
class
);
Config
fxApollo
=
mock
(
Config
.
class
);
when
(
fxApollo
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
anotherTimeout
));
when
(
fxApollo
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
anotherTimeout
));
mockConfig
(
FX_APOLLO_NAMESPACE
,
fxApollo
);
mockConfig
(
FX_APOLLO_NAMESPACE
,
fxApollo
);
check
(
someTimeout
,
someBatch
,
AppConfig
3
.
class
);
check
(
someTimeout
,
someBatch
,
AppConfig
11
.
class
);
}
}
@Test
@Test
public
void
testMultiplePropertySourcesCoverWithSameProperties
()
throws
Exception
{
public
void
testMultiplePropertySourcesCoverWithSameProperties
()
throws
Exception
{
//Multimap does not maintain the strict input order of namespace.
//Multimap does not maintain the strict input order of namespace.
...
@@ -124,6 +161,25 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest {
...
@@ -124,6 +161,25 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest {
check
(
someTimeout
,
someBatch
,
AppConfig6
.
class
);
check
(
someTimeout
,
someBatch
,
AppConfig6
.
class
);
}
}
@Test
public
void
testMultiplePropertySourcesCoverWithSamePropertiesWithPropertiesCompatiblePropertySource
()
throws
Exception
{
//Multimap does not maintain the strict input order of namespace.
int
someTimeout
=
1000
;
int
anotherTimeout
=
someTimeout
+
1
;
int
someBatch
=
2000
;
Config
fxApollo
=
mock
(
Config
.
class
);
when
(
fxApollo
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someTimeout
));
when
(
fxApollo
.
getProperty
(
eq
(
BATCH_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someBatch
));
mockConfig
(
FX_APOLLO_NAMESPACE
,
fxApollo
);
Config
application
=
mock
(
Config
.
class
);
when
(
application
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
anotherTimeout
));
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
application
);
check
(
someTimeout
,
someBatch
,
AppConfig6
.
class
);
}
@Test
@Test
public
void
testMultiplePropertySourcesWithSamePropertiesWithWeight
()
throws
Exception
{
public
void
testMultiplePropertySourcesWithSamePropertiesWithWeight
()
throws
Exception
{
int
someTimeout
=
1000
;
int
someTimeout
=
1000
;
...
@@ -424,6 +480,33 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest {
...
@@ -424,6 +480,33 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest {
}
}
}
}
@Configuration
@EnableApolloConfig
(
"application.yaml"
)
static
class
AppConfig9
{
@Bean
TestJavaConfigBean
testJavaConfigBean
()
{
return
new
TestJavaConfigBean
();
}
}
@Configuration
@EnableApolloConfig
(
"application.yaMl"
)
static
class
AppConfig10
{
@Bean
TestJavaConfigBean
testJavaConfigBean
()
{
return
new
TestJavaConfigBean
();
}
}
@Configuration
@EnableApolloConfig
({
"application.yml"
,
"FX.apollo"
})
static
class
AppConfig11
{
@Bean
TestJavaConfigBean
testJavaConfigBean
()
{
return
new
TestJavaConfigBean
();
}
}
@Component
@Component
static
class
TestJavaConfigBean
{
static
class
TestJavaConfigBean
{
@Value
(
"${timeout:100}"
)
@Value
(
"${timeout:100}"
)
...
...
apollo-client/src/test/java/com/ctrip/framework/apollo/util/yaml/YamlParserTest.java
0 → 100644
View file @
bf1b6374
package
com
.
ctrip
.
framework
.
apollo
.
util
.
yaml
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
java.io.File
;
import
java.util.Properties
;
import
org.junit.Test
;
import
org.springframework.beans.factory.config.YamlPropertiesFactoryBean
;
import
org.springframework.core.io.ByteArrayResource
;
import
org.yaml.snakeyaml.parser.ParserException
;
import
com.google.common.base.Charsets
;
import
com.google.common.io.Files
;
public
class
YamlParserTest
{
private
YamlParser
parser
=
new
YamlParser
();
@Test
public
void
testValidCases
()
throws
Exception
{
test
(
"case1.yaml"
);
test
(
"case3.yaml"
);
test
(
"case4.yaml"
);
test
(
"case5.yaml"
);
test
(
"case6.yaml"
);
test
(
"case7.yaml"
);
}
@Test
(
expected
=
ParserException
.
class
)
public
void
testcase2
()
throws
Exception
{
testInvalid
(
"case2.yaml"
);
}
@Test
(
expected
=
ParserException
.
class
)
public
void
testcase8
()
throws
Exception
{
testInvalid
(
"case8.yaml"
);
}
private
void
test
(
String
caseName
)
throws
Exception
{
File
file
=
new
File
(
"src/test/resources/yaml/"
+
caseName
);
String
yamlContent
=
Files
.
toString
(
file
,
Charsets
.
UTF_8
);
check
(
yamlContent
);
}
private
void
testInvalid
(
String
caseName
)
throws
Exception
{
File
file
=
new
File
(
"src/test/resources/yaml/"
+
caseName
);
String
yamlContent
=
Files
.
toString
(
file
,
Charsets
.
UTF_8
);
parser
.
yamlToProperties
(
yamlContent
);
}
private
void
check
(
String
yamlContent
)
{
YamlPropertiesFactoryBean
yamlPropertiesFactoryBean
=
new
YamlPropertiesFactoryBean
();
yamlPropertiesFactoryBean
.
setResources
(
new
ByteArrayResource
(
yamlContent
.
getBytes
()));
Properties
expected
=
yamlPropertiesFactoryBean
.
getObject
();
Properties
actual
=
parser
.
yamlToProperties
(
yamlContent
);
assertTrue
(
"expected: "
+
expected
+
" actual: "
+
actual
,
checkPropertiesEquals
(
expected
,
actual
));
}
private
boolean
checkPropertiesEquals
(
Properties
expected
,
Properties
actual
)
{
if
(
expected
==
actual
)
return
true
;
if
(
expected
.
size
()
!=
actual
.
size
())
return
false
;
for
(
Object
key
:
expected
.
keySet
())
{
if
(!
expected
.
getProperty
((
String
)
key
).
equals
(
actual
.
getProperty
((
String
)
key
)))
{
return
false
;
}
}
return
true
;
}
}
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest11.xml
0 → 100644
View file @
bf1b6374
<?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"
>
<bean
class=
"com.ctrip.framework.apollo.spring.XmlConfigPlaceholderTest.TestXmlBean"
>
<property
name=
"timeout"
value=
"${timeout:100}"
/>
<property
name=
"batch"
value=
"${batch:200}"
/>
</bean>
</beans>
apollo-client/src/test/resources/spring/yaml/case1-new.yaml
0 → 100644
View file @
bf1b6374
timeout
:
1001
batch
:
2001
apollo-client/src/test/resources/spring/yaml/case1.yaml
0 → 100644
View file @
bf1b6374
timeout
:
1000
batch
:
2000
apollo-client/src/test/resources/spring/yaml/case2-new.yml
0 → 100644
View file @
bf1b6374
batch
:
2001
apollo-client/src/test/resources/spring/yaml/case2.yml
0 → 100644
View file @
bf1b6374
batch
:
2000
apollo-client/src/test/resources/spring/yaml/case3-new.yaml
0 → 100644
View file @
bf1b6374
timeout
:
1001
batch
:
2001
apollo-client/src/test/resources/spring/yaml/case3.yaml
0 → 100644
View file @
bf1b6374
timeout
:
1000
apollo-client/src/test/resources/spring/yaml/case4-new.yaml
0 → 100644
View file @
bf1b6374
apollo-client/src/test/resources/spring/yaml/case4.yaml
0 → 100644
View file @
bf1b6374
timeout
:
1000
batch
:
2000
apollo-client/src/test/resources/spring/yaml/case5-new.yaml
0 → 100644
View file @
bf1b6374
timeout
:
1001
batch
:
newBatch
apollo-client/src/test/resources/spring/yaml/case5.yaml
0 → 100644
View file @
bf1b6374
timeout
:
1000
batch
:
2000
apollo-client/src/test/resources/spring/yaml/case6.yml
0 → 100644
View file @
bf1b6374
apollo.test.testBean
:
true
apollo-client/src/test/resources/spring/yaml/case7.yml
0 → 100644
View file @
bf1b6374
apollo.test.testBean:false
apollo-client/src/test/resources/spring/yaml/case8.yml
0 → 100644
View file @
bf1b6374
apollo-client/src/test/resources/spring/yaml/case9-new.yml
0 → 100644
View file @
bf1b6374
someKey
:
anotherValue
apollo-client/src/test/resources/spring/yaml/case9.yml
0 → 100644
View file @
bf1b6374
someKey
:
someValue
apollo-client/src/test/resources/yaml/case1.yaml
0 → 100644
View file @
bf1b6374
root
:
key1
:
"
someValue"
key2
:
100
key3
:
key4
:
key5
:
'
(%sender%)
%message%'
key6
:
'
*
%sender%
%message%'
# commented: "xxx"
list
:
-
'
item
1'
-
'
item
2'
intList
:
-
100
-
200
listOfMap
:
-
key
:
'
#mychannel'
value
:
'
'
-
key
:
'
#myprivatechannel'
value
:
'
mypassword'
listOfList
:
-
-
'
a1'
-
'
a2'
-
-
'
b1'
-
'
b2'
listOfList2
:
[
[
'
a1'
,
'
a2'
],
[
'
b1'
,
'
b2'
]
]
apollo-client/src/test/resources/yaml/case2.yaml
0 → 100644
View file @
bf1b6374
root
:
key1
:
"
someValue"
key2
:
100
key1
:
"
anotherValue"
apollo-client/src/test/resources/yaml/case3.yaml
0 → 100644
View file @
bf1b6374
root
:
key1
:
"
someValue"
key2
:
100
apollo-client/src/test/resources/yaml/case4.yaml
0 → 100644
View file @
bf1b6374
---
# document start
# Comments in YAML look like this.
################
# SCALAR TYPES #
################
# Our root object (which continues for the entire document) will be a map,
# which is equivalent to a dictionary, hash or object in other languages.
key
:
value
another_key
:
Another value goes here.
a_number_value
:
100
scientific_notation
:
1e+12
# The number 1 will be interpreted as a number, not a boolean. if you want
# it to be interpreted as a boolean, use true
boolean
:
true
null_value
:
null
key with spaces
:
value
# Notice that strings don't need to be quoted. However, they can be.
however
:
'
A
string,
enclosed
in
quotes.'
'
Keys
can
be
quoted
too.'
:
"
Useful
if
you
want
to
put
a
':'
in
your
key."
single quotes
:
'
have
'
'
one'
'
escape
pattern'
double quotes
:
"
have
many:
\"
,
\0
,
\t
,
\u263A
,
\x0d\x0a
==
\r\n
,
and
more."
# Multiple-line strings can be written either as a 'literal block' (using |),
# or a 'folded block' (using '>').
literal_block
:
|
This entire block of text will be the value of the 'literal_block' key,
with line breaks being preserved.
The literal continues until de-dented, and the leading indentation is
stripped.
Any lines that are 'more-indented' keep the rest of their indentation -
these lines will be indented by 4 spaces.
folded_style
:
>
This entire block of text will be the value of 'folded_style', but this
time, all newlines will be replaced with a single space.
Blank lines, like above, are converted to a newline character.
'More-indented' lines keep their newlines, too -
this text will appear over two lines.
####################
# COLLECTION TYPES #
####################
# Nesting uses indentation. 2 space indent is preferred (but not required).
a_nested_map
:
key
:
value
another_key
:
Another Value
another_nested_map
:
hello
:
hello
# Maps don't have to have string keys.
0.25
:
a float key
# Keys can also be complex, like multi-line objects
# We use ? followed by a space to indicate the start of a complex key.
?
|
This is a key
that has multiple lines
:
and this is its value
# YAML also allows mapping between sequences with the complex key syntax
# Some language parsers might complain
# An example
?
-
Manchester United
-
Real Madrid
:
[
2001-01-01
,
2002-02-02
]
# Sequences (equivalent to lists or arrays) look like this
# (note that the '-' counts as indentation):
a_sequence
:
-
Item
1
-
Item
2
-
0.5
# sequences can contain disparate types.
-
Item
4
-
key
:
value
another_key
:
another_value
-
-
This is a sequence
-
inside another sequence
-
-
-
Nested sequence indicators
-
can be collapsed
# Since YAML is a superset of JSON, you can also write JSON-style maps and
# sequences:
json_map
:
{
"
key"
:
"
value"
}
json_seq
:
[
3
,
2
,
1
,
"
takeoff"
]
and quotes are optional
:
{
key
:
[
3
,
2
,
1
,
takeoff
]}
#######################
# EXTRA YAML FEATURES #
#######################
# YAML also has a handy feature called 'anchors', which let you easily duplicate
# content across your document. Both of these keys will have the same value:
anchored_content
:
&anchor_name
This string will appear as the value of two keys.
other_anchor
:
*anchor_name
# Anchors can be used to duplicate/inherit properties
base
:
&base
name
:
Everyone has same name
# The regexp << is called Merge Key Language-Independent Type. It is used to
# indicate that all the keys of one or more specified maps should be inserted
# into the current map.
foo
:
&foo
<<
:
*base
age
:
10
bar
:
&bar
<<
:
*base
age
:
20
# foo and bar would also have name: Everyone has same name
# YAML also has tags, which you can use to explicitly declare types.
explicit_string
:
!!str
0.5
####################
# EXTRA YAML TYPES #
####################
# Strings and numbers aren't the only scalars that YAML can understand.
# ISO-formatted date and datetime literals are also parsed.
datetime
:
2001-12-15T02:59:43.1Z
datetime_with_spaces
:
2001-12-14 21:59:43.10 -5
date
:
2002-12-14
# YAML also has a set type, which looks like this:
set
:
?
item1
?
item2
?
item3
or
:
{
item1
,
item2
,
item3
}
# Sets are just maps with null values; the above is equivalent to:
set2
:
item1
:
null
item2
:
null
item3
:
null
...
# document end
apollo-client/src/test/resources/yaml/case5.yaml
0 → 100644
View file @
bf1b6374
---
-
Ada
-
APL
-
ASP
-
Assembly
-
Awk
---
-
Basic
---
-
C
-
C#
# Note that comments are denoted with ' #' (space and #).
-
C++
-
Cold Fusion
-
-
HTML
-
LaTeX
-
SGML
-
VRML
-
XML
-
YAML
-
-
BSD
-
GNU Hurd
-
Linux
-
1.1
-
-
2.1
-
2.2
-
-
-
3.1
-
3.2
-
3.3
-
name
:
PyYAML
status
:
4
license
:
MIT
language
:
Python
-
name
:
PySyck
status
:
5
license
:
BSD
language
:
Python
apollo-client/src/test/resources/yaml/case6.yaml
0 → 100644
View file @
bf1b6374
left hand
:
-
Ring of Teleportation
-
Ring of Speed
right hand
:
-
Ring of Resist Fire
-
Ring of Resist Cold
-
Ring of Resist Poison
base armor class
:
0
base damage
:
[
4
,
4
]
plus to-hit
:
12
plus to-dam
:
16
plus to-ac
:
0
hero
:
hp
:
34
sp
:
8
level
:
4
orc
:
hp
:
12
sp
:
0
level
:
2
plain
:
Scroll of Remove Curse
single-quoted
:
'
EASY_KNOW'
double-quoted
:
"
?"
literal
:
|
# Borrowed from http://www.kersbergen.com/flump/religion.html
by hjw ___
__ /.-.\
/ )_____________\\ Y
/_ /=== == === === =\ _\_
( /)=== == === === == Y \
`-------------------( o )
\___/
folded
:
>
It removes all ordinary curses from all equipped items.
Heavy or permanent curses are unaffected.
apollo-client/src/test/resources/yaml/case7.yaml
0 → 100644
View file @
bf1b6374
xxx
apollo-client/src/test/resources/yaml/case8.yaml
0 → 100644
View file @
bf1b6374
,
apollo-core/src/main/java/com/ctrip/framework/apollo/core/enums/ConfigFileFormat.java
View file @
bf1b6374
...
@@ -45,4 +45,8 @@ public enum ConfigFileFormat {
...
@@ -45,4 +45,8 @@ public enum ConfigFileFormat {
return
false
;
return
false
;
}
}
}
}
public
static
boolean
isPropertiesCompatible
(
ConfigFileFormat
format
)
{
return
format
==
YAML
||
format
==
YML
;
}
}
}
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/api/ApolloConfigDemo.java
View file @
bf1b6374
package
com
.
ctrip
.
framework
.
apollo
.
demo
.
api
;
package
com
.
ctrip
.
framework
.
apollo
.
demo
.
api
;
import
com.ctrip.framework.apollo.internals.YamlConfigFile
;
import
com.google.common.base.Charsets
;
import
com.google.common.base.Charsets
;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.Config
;
...
@@ -27,9 +28,11 @@ public class ApolloConfigDemo {
...
@@ -27,9 +28,11 @@ public class ApolloConfigDemo {
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
ApolloConfigDemo
.
class
);
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
ApolloConfigDemo
.
class
);
private
String
DEFAULT_VALUE
=
"undefined"
;
private
String
DEFAULT_VALUE
=
"undefined"
;
private
Config
config
;
private
Config
config
;
private
Config
yamlConfig
;
private
Config
publicConfig
;
private
Config
publicConfig
;
private
ConfigFile
applicationConfigFile
;
private
ConfigFile
applicationConfigFile
;
private
ConfigFile
xmlConfigFile
;
private
ConfigFile
xmlConfigFile
;
private
YamlConfigFile
yamlConfigFile
;
public
ApolloConfigDemo
()
{
public
ApolloConfigDemo
()
{
ConfigChangeListener
changeListener
=
new
ConfigChangeListener
()
{
ConfigChangeListener
changeListener
=
new
ConfigChangeListener
()
{
...
@@ -46,9 +49,12 @@ public class ApolloConfigDemo {
...
@@ -46,9 +49,12 @@ public class ApolloConfigDemo {
};
};
config
=
ConfigService
.
getAppConfig
();
config
=
ConfigService
.
getAppConfig
();
config
.
addChangeListener
(
changeListener
);
config
.
addChangeListener
(
changeListener
);
yamlConfig
=
ConfigService
.
getConfig
(
"application.yaml"
);
yamlConfig
.
addChangeListener
(
changeListener
);
publicConfig
=
ConfigService
.
getConfig
(
"TEST1.apollo"
);
publicConfig
=
ConfigService
.
getConfig
(
"TEST1.apollo"
);
publicConfig
.
addChangeListener
(
changeListener
);
publicConfig
.
addChangeListener
(
changeListener
);
applicationConfigFile
=
ConfigService
.
getConfigFile
(
"application"
,
ConfigFileFormat
.
Properties
);
applicationConfigFile
=
ConfigService
.
getConfigFile
(
"application"
,
ConfigFileFormat
.
Properties
);
// datasources.xml
xmlConfigFile
=
ConfigService
.
getConfigFile
(
"datasources"
,
ConfigFileFormat
.
XML
);
xmlConfigFile
=
ConfigService
.
getConfigFile
(
"datasources"
,
ConfigFileFormat
.
XML
);
xmlConfigFile
.
addChangeListener
(
new
ConfigFileChangeListener
()
{
xmlConfigFile
.
addChangeListener
(
new
ConfigFileChangeListener
()
{
@Override
@Override
...
@@ -56,6 +62,8 @@ public class ApolloConfigDemo {
...
@@ -56,6 +62,8 @@ public class ApolloConfigDemo {
logger
.
info
(
changeEvent
.
toString
());
logger
.
info
(
changeEvent
.
toString
());
}
}
});
});
// application.yaml
yamlConfigFile
=
(
YamlConfigFile
)
ConfigService
.
getConfigFile
(
"application"
,
ConfigFileFormat
.
YAML
);
}
}
private
String
getConfig
(
String
key
)
{
private
String
getConfig
(
String
key
)
{
...
@@ -63,6 +71,9 @@ public class ApolloConfigDemo {
...
@@ -63,6 +71,9 @@ public class ApolloConfigDemo {
if
(
DEFAULT_VALUE
.
equals
(
result
))
{
if
(
DEFAULT_VALUE
.
equals
(
result
))
{
result
=
publicConfig
.
getProperty
(
key
,
DEFAULT_VALUE
);
result
=
publicConfig
.
getProperty
(
key
,
DEFAULT_VALUE
);
}
}
if
(
DEFAULT_VALUE
.
equals
(
result
))
{
result
=
yamlConfig
.
getProperty
(
key
,
DEFAULT_VALUE
);
}
logger
.
info
(
String
.
format
(
"Loading key : %s with value: %s"
,
key
,
result
));
logger
.
info
(
String
.
format
(
"Loading key : %s with value: %s"
,
key
,
result
));
return
result
;
return
result
;
}
}
...
@@ -75,6 +86,9 @@ public class ApolloConfigDemo {
...
@@ -75,6 +86,9 @@ public class ApolloConfigDemo {
case
"xml"
:
case
"xml"
:
print
(
xmlConfigFile
);
print
(
xmlConfigFile
);
return
;
return
;
case
"yaml"
:
printYaml
(
yamlConfigFile
);
return
;
}
}
}
}
...
@@ -87,6 +101,11 @@ public class ApolloConfigDemo {
...
@@ -87,6 +101,11 @@ public class ApolloConfigDemo {
System
.
out
.
println
(
configFile
.
getContent
());
System
.
out
.
println
(
configFile
.
getContent
());
}
}
private
void
printYaml
(
YamlConfigFile
configFile
)
{
System
.
out
.
println
(
"=== Properties for "
+
configFile
.
getNamespace
()
+
" is as follows: "
);
System
.
out
.
println
(
configFile
.
asProperties
());
}
private
void
printEnvInfo
()
{
private
void
printEnvInfo
()
{
String
message
=
String
.
format
(
"AppId: %s, Env: %s, DC: %s, IP: %s"
,
Foundation
.
app
()
String
message
=
String
.
format
(
"AppId: %s, Env: %s, DC: %s, IP: %s"
,
Foundation
.
app
()
.
getAppId
(),
Foundation
.
server
().
getEnvType
(),
Foundation
.
server
().
getDataCenter
(),
.
getAppId
(),
Foundation
.
server
().
getEnvType
(),
Foundation
.
server
().
getDataCenter
(),
...
@@ -106,18 +125,26 @@ public class ApolloConfigDemo {
...
@@ -106,18 +125,26 @@ public class ApolloConfigDemo {
continue
;
continue
;
}
}
input
=
input
.
trim
();
input
=
input
.
trim
();
if
(
input
.
equalsIgnoreCase
(
"application"
))
{
try
{
apolloConfigDemo
.
print
(
"application"
);
if
(
input
.
equalsIgnoreCase
(
"application"
))
{
continue
;
apolloConfigDemo
.
print
(
"application"
);
}
continue
;
if
(
input
.
equalsIgnoreCase
(
"xml"
))
{
}
apolloConfigDemo
.
print
(
"xml"
);
if
(
input
.
equalsIgnoreCase
(
"xml"
))
{
continue
;
apolloConfigDemo
.
print
(
"xml"
);
}
continue
;
if
(
input
.
equalsIgnoreCase
(
"quit"
))
{
}
System
.
exit
(
0
);
if
(
input
.
equalsIgnoreCase
(
"yaml"
)
||
input
.
equalsIgnoreCase
(
"yml"
))
{
apolloConfigDemo
.
print
(
"yaml"
);
continue
;
}
if
(
input
.
equalsIgnoreCase
(
"quit"
))
{
System
.
exit
(
0
);
}
apolloConfigDemo
.
getConfig
(
input
);
}
catch
(
Throwable
ex
)
{
logger
.
error
(
"some error occurred"
,
ex
);
}
}
apolloConfigDemo
.
getConfig
(
input
);
}
}
}
}
}
}
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/common/config/AnotherAppConfig.java
View file @
bf1b6374
...
@@ -8,6 +8,6 @@ import org.springframework.context.annotation.Configuration;
...
@@ -8,6 +8,6 @@ import org.springframework.context.annotation.Configuration;
* @author Jason Song(song_s@ctrip.com)
* @author Jason Song(song_s@ctrip.com)
*/
*/
@Configuration
@Configuration
@EnableApolloConfig
(
value
=
"TEST1.apollo"
,
order
=
11
)
@EnableApolloConfig
(
value
=
{
"TEST1.apollo"
,
"application.yaml"
}
,
order
=
11
)
public
class
AnotherAppConfig
{
public
class
AnotherAppConfig
{
}
}
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/springBootDemo/config/SampleRedisConfig.java
View file @
bf1b6374
...
@@ -15,6 +15,8 @@ import javax.annotation.PostConstruct;
...
@@ -15,6 +15,8 @@ import javax.annotation.PostConstruct;
/**
/**
* You may set up data like the following in Apollo:
* You may set up data like the following in Apollo:
* <br /><br />
* Properties Sample: application.properties
* <pre>
* <pre>
* redis.cache.enabled = true
* redis.cache.enabled = true
* redis.cache.expireSeconds = 100
* redis.cache.expireSeconds = 100
...
@@ -26,6 +28,22 @@ import javax.annotation.PostConstruct;
...
@@ -26,6 +28,22 @@ import javax.annotation.PostConstruct;
* redis.cache.someList[1] = d
* redis.cache.someList[1] = d
* </pre>
* </pre>
*
*
* Yaml Sample: application.yaml
* <pre>
* redis:
* cache:
* enabled: true
* expireSeconds: 100
* clusterNodes: 1,2
* commandTimeout: 50
* someMap:
* key1: a
* key2: b
* someList:
* - c
* - d
* </pre>
*
* To make <code>@ConditionalOnProperty</code> work properly, <code>apollo.bootstrap.enabled</code> should be set to true
* To make <code>@ConditionalOnProperty</code> work properly, <code>apollo.bootstrap.enabled</code> should be set to true
* and <code>redis.cache.enabled</code> should also be set to true. Check 'src/main/resources/application.yml' for more information.
* and <code>redis.cache.enabled</code> should also be set to true. Check 'src/main/resources/application.yml' for more information.
*
*
...
...
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/springBootDemo/refresh/SpringBootApolloRefreshConfig.java
View file @
bf1b6374
package
com
.
ctrip
.
framework
.
apollo
.
demo
.
spring
.
springBootDemo
.
refresh
;
package
com
.
ctrip
.
framework
.
apollo
.
demo
.
spring
.
springBootDemo
.
refresh
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
com.ctrip.framework.apollo.demo.spring.springBootDemo.config.SampleRedisConfig
;
import
com.ctrip.framework.apollo.demo.spring.springBootDemo.config.SampleRedisConfig
;
import
com.ctrip.framework.apollo.model.ConfigChangeEvent
;
import
com.ctrip.framework.apollo.model.ConfigChangeEvent
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener
;
...
@@ -27,7 +28,7 @@ public class SpringBootApolloRefreshConfig {
...
@@ -27,7 +28,7 @@ public class SpringBootApolloRefreshConfig {
this
.
refreshScope
=
refreshScope
;
this
.
refreshScope
=
refreshScope
;
}
}
@ApolloConfigChangeListener
@ApolloConfigChangeListener
({
ConfigConsts
.
NAMESPACE_APPLICATION
,
"TEST1.apollo"
,
"application.yaml"
})
public
void
onChange
(
ConfigChangeEvent
changeEvent
)
{
public
void
onChange
(
ConfigChangeEvent
changeEvent
)
{
boolean
redisCacheKeysChanged
=
false
;
boolean
redisCacheKeysChanged
=
false
;
for
(
String
changedKey
:
changeEvent
.
changedKeys
())
{
for
(
String
changedKey
:
changeEvent
.
changedKeys
())
{
...
...
apollo-demo/src/main/resources/application.yml
View file @
bf1b6374
...
@@ -2,4 +2,4 @@ apollo:
...
@@ -2,4 +2,4 @@ apollo:
bootstrap
:
bootstrap
:
enabled
:
true
enabled
:
true
# will inject 'application' and 'TEST1.apollo' namespaces in bootstrap phase
# will inject 'application' and 'TEST1.apollo' namespaces in bootstrap phase
namespaces
:
application,TEST1.apollo
namespaces
:
application,TEST1.apollo
,application.yaml
apollo-demo/src/main/resources/spring.xml
View file @
bf1b6374
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.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"
>
http://www.ctrip.com/schema/apollo http://www.ctrip.com/schema/apollo.xsd"
>
<apollo:config
order=
"10"
/>
<apollo:config
order=
"10"
/>
<apollo:config
namespaces=
"TEST1.apollo"
order=
"11"
/>
<apollo:config
namespaces=
"TEST1.apollo
,application.yaml
"
order=
"11"
/>
<bean
class=
"com.ctrip.framework.apollo.demo.spring.xmlConfigDemo.bean.XmlBean"
>
<bean
class=
"com.ctrip.framework.apollo.demo.spring.xmlConfigDemo.bean.XmlBean"
>
<property
name=
"timeout"
value=
"${timeout:200}"
/>
<property
name=
"timeout"
value=
"${timeout:200}"
/>
...
...
apollo-portal/src/main/resources/static/namespace.html
View file @
bf1b6374
...
@@ -57,7 +57,8 @@
...
@@ -57,7 +57,8 @@
<li>
<li>
通过创建一个私有的Namespace可以实现分组管理配置
通过创建一个私有的Namespace可以实现分组管理配置
</li>
</li>
<li>
私有Namespace的格式可以是xml、yml、yaml、json. 您可以通过Apollo-client中ConfigFile接口来获取非properties格式Namespace的内容
</li>
<li>
私有Namespace的格式可以是xml、yml、yaml、json. 您可以通过apollo-client中ConfigFile接口来获取非properties格式Namespace的内容
</li>
<li>
1.3.0及以上版本的apollo-client针对yaml/yml提供了更好的支持,可以通过ConfigService.getConfig("someNamespace.yaml")直接获取Config对象,也可以通过@EnableApolloConfig("someNamespace.yaml")注入yaml配置到Spring中去
</li>
</ul>
</ul>
</div>
</div>
<div
class=
"row text-right"
style=
"padding-right: 20px;"
>
<div
class=
"row text-right"
style=
"padding-right: 20px;"
>
...
...
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