Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
apollo
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
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
openSource
apollo
Commits
5bb2aaf1
Commit
5bb2aaf1
authored
Apr 12, 2016
by
Yiming Liu
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #79 from nobodyiam/client-refresh-merge
Add client side auto refresh capability
parents
b1c4b7d8
df474afd
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
684 additions
and
137 deletions
+684
-137
ReleaseRepository.java
...va/com/ctrip/apollo/biz/repository/ReleaseRepository.java
+1
-2
ConfigService.java
...main/java/com/ctrip/apollo/biz/service/ConfigService.java
+1
-1
Config.java
apollo-client/src/main/java/com/ctrip/apollo/Config.java
+2
-0
ConfigChangeListener.java
.../src/main/java/com/ctrip/apollo/ConfigChangeListener.java
+10
-0
AbstractConfig.java
.../main/java/com/ctrip/apollo/internals/AbstractConfig.java
+84
-0
AbstractConfigRepository.java
.../com/ctrip/apollo/internals/AbstractConfigRepository.java
+39
-0
ConfigRepository.java
...ain/java/com/ctrip/apollo/internals/ConfigRepository.java
+13
-1
DefaultConfig.java
...c/main/java/com/ctrip/apollo/internals/DefaultConfig.java
+74
-5
DefaultConfigManager.java
...java/com/ctrip/apollo/internals/DefaultConfigManager.java
+1
-1
LocalFileConfigRepository.java
...com/ctrip/apollo/internals/LocalFileConfigRepository.java
+44
-18
RemoteConfigRepository.java
...va/com/ctrip/apollo/internals/RemoteConfigRepository.java
+50
-15
RepositoryChangeListener.java
.../com/ctrip/apollo/internals/RepositoryChangeListener.java
+10
-0
SimpleConfig.java
...rc/main/java/com/ctrip/apollo/internals/SimpleConfig.java
+35
-7
ConfigChange.java
...nt/src/main/java/com/ctrip/apollo/model/ConfigChange.java
+28
-19
ConfigChangeEvent.java
...c/main/java/com/ctrip/apollo/model/ConfigChangeEvent.java
+38
-0
ConfigRefreshResult.java
...main/java/com/ctrip/apollo/model/ConfigRefreshResult.java
+0
-41
DefaultConfigFactory.java
.../main/java/com/ctrip/apollo/spi/DefaultConfigFactory.java
+1
-2
HttpUtil.java
...nt/src/main/java/com/ctrip/apollo/util/http/HttpUtil.java
+10
-9
ConfigServiceTest.java
...ent/src/test/java/com/ctrip/apollo/ConfigServiceTest.java
+5
-0
DefaultConfigManagerTest.java
.../com/ctrip/apollo/internals/DefaultConfigManagerTest.java
+7
-0
DefaultConfigTest.java
...st/java/com/ctrip/apollo/internals/DefaultConfigTest.java
+87
-4
LocalFileConfigRepositoryTest.java
...ctrip/apollo/internals/LocalFileConfigRepositoryTest.java
+34
-5
RemoteConfigRepositoryTest.java
...om/ctrip/apollo/internals/RemoteConfigRepositoryTest.java
+27
-2
SimpleConfigTest.java
...est/java/com/ctrip/apollo/internals/SimpleConfigTest.java
+62
-2
DefaultConfigFactoryTest.java
...t/java/com/ctrip/apollo/spi/DefaultConfigFactoryTest.java
+1
-1
ApolloConfigDemo.java
apollo-demo/src/main/java/ApolloConfigDemo.java
+20
-2
No files found.
apollo-biz/src/main/java/com/ctrip/apollo/biz/repository/ReleaseRepository.java
View file @
5bb2aaf1
...
@@ -13,8 +13,7 @@ import com.ctrip.apollo.biz.entity.Release;
...
@@ -13,8 +13,7 @@ import com.ctrip.apollo.biz.entity.Release;
*/
*/
public
interface
ReleaseRepository
extends
PagingAndSortingRepository
<
Release
,
Long
>
{
public
interface
ReleaseRepository
extends
PagingAndSortingRepository
<
Release
,
Long
>
{
@Query
(
"SELECT r FROM Release r WHERE r.appId = :appId AND r.clusterName = :clusterName AND r.namespaceName = :namespaceName order by r.id desc"
)
Release
findFirstByAppIdAndClusterNameAndNamespaceNameOrderByIdDesc
(
@Param
(
"appId"
)
String
appId
,
@Param
(
"clusterName"
)
String
clusterName
,
Release
findLatest
(
@Param
(
"appId"
)
String
appId
,
@Param
(
"clusterName"
)
String
clusterName
,
@Param
(
"namespaceName"
)
String
namespaceName
);
@Param
(
"namespaceName"
)
String
namespaceName
);
List
<
Release
>
findByAppIdAndClusterNameAndNamespaceName
(
String
appId
,
String
clusterName
,
List
<
Release
>
findByAppIdAndClusterNameAndNamespaceName
(
String
appId
,
String
clusterName
,
...
...
apollo-biz/src/main/java/com/ctrip/apollo/biz/service/ConfigService.java
View file @
5bb2aaf1
...
@@ -30,7 +30,7 @@ public class ConfigService {
...
@@ -30,7 +30,7 @@ public class ConfigService {
private
Type
configurationTypeReference
=
new
TypeToken
<
Map
<
String
,
String
>>(){}.
getType
();
private
Type
configurationTypeReference
=
new
TypeToken
<
Map
<
String
,
String
>>(){}.
getType
();
public
Release
findRelease
(
String
appId
,
String
clusterName
,
String
namespaceName
)
{
public
Release
findRelease
(
String
appId
,
String
clusterName
,
String
namespaceName
)
{
Release
release
=
releaseRepository
.
find
Latest
(
appId
,
clusterName
,
namespaceName
);
Release
release
=
releaseRepository
.
find
FirstByAppIdAndClusterNameAndNamespaceNameOrderByIdDesc
(
appId
,
clusterName
,
namespaceName
);
return
release
;
return
release
;
}
}
...
...
apollo-client/src/main/java/com/ctrip/apollo/Config.java
View file @
5bb2aaf1
...
@@ -12,4 +12,6 @@ public interface Config {
...
@@ -12,4 +12,6 @@ public interface Config {
* @return the property value
* @return the property value
*/
*/
public
String
getProperty
(
String
key
,
String
defaultValue
);
public
String
getProperty
(
String
key
,
String
defaultValue
);
public
void
addChangeListener
(
ConfigChangeListener
listener
);
}
}
apollo-client/src/main/java/com/ctrip/apollo/ConfigChangeListener.java
0 → 100644
View file @
5bb2aaf1
package
com
.
ctrip
.
apollo
;
import
com.ctrip.apollo.model.ConfigChangeEvent
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
interface
ConfigChangeListener
{
public
void
onChange
(
ConfigChangeEvent
changeEvent
);
}
apollo-client/src/main/java/com/ctrip/apollo/internals/AbstractConfig.java
0 → 100644
View file @
5bb2aaf1
package
com
.
ctrip
.
apollo
.
internals
;
import
com.google.common.base.Objects
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Sets
;
import
com.ctrip.apollo.Config
;
import
com.ctrip.apollo.ConfigChangeListener
;
import
com.ctrip.apollo.enums.PropertyChangeType
;
import
com.ctrip.apollo.model.ConfigChange
;
import
com.ctrip.apollo.model.ConfigChangeEvent
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.util.List
;
import
java.util.Properties
;
import
java.util.Set
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
abstract
class
AbstractConfig
implements
Config
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
AbstractConfig
.
class
);
private
List
<
ConfigChangeListener
>
m_listeners
=
Lists
.
newCopyOnWriteArrayList
();
@Override
public
void
addChangeListener
(
ConfigChangeListener
listener
)
{
if
(!
m_listeners
.
contains
(
listener
))
{
m_listeners
.
add
(
listener
);
}
}
protected
void
fireConfigChange
(
ConfigChangeEvent
changeEvent
)
{
for
(
ConfigChangeListener
listener
:
m_listeners
)
{
try
{
listener
.
onChange
(
changeEvent
);
}
catch
(
Throwable
t
)
{
logger
.
error
(
"Failed to invoke config change listener {}"
,
listener
.
getClass
(),
t
);
}
}
}
List
<
ConfigChange
>
calcPropertyChanges
(
Properties
previous
,
Properties
current
)
{
if
(
previous
==
null
)
{
previous
=
new
Properties
();
}
if
(
current
==
null
)
{
current
=
new
Properties
();
}
Set
<
String
>
previousKeys
=
previous
.
stringPropertyNames
();
Set
<
String
>
currentKeys
=
current
.
stringPropertyNames
();
Set
<
String
>
commonKeys
=
Sets
.
intersection
(
previousKeys
,
currentKeys
);
Set
<
String
>
newKeys
=
Sets
.
difference
(
currentKeys
,
commonKeys
);
Set
<
String
>
removedKeys
=
Sets
.
difference
(
previousKeys
,
commonKeys
);
List
<
ConfigChange
>
changes
=
Lists
.
newArrayList
();
for
(
String
newKey
:
newKeys
)
{
changes
.
add
(
new
ConfigChange
(
newKey
,
null
,
current
.
getProperty
(
newKey
),
PropertyChangeType
.
NEW
));
}
for
(
String
removedKey
:
removedKeys
)
{
changes
.
add
(
new
ConfigChange
(
removedKey
,
previous
.
getProperty
(
removedKey
),
null
,
PropertyChangeType
.
DELETED
));
}
for
(
String
commonKey
:
commonKeys
)
{
String
previousValue
=
previous
.
getProperty
(
commonKey
);
String
currentValue
=
current
.
getProperty
(
commonKey
);
if
(
Objects
.
equal
(
previousValue
,
currentValue
))
{
continue
;
}
changes
.
add
(
new
ConfigChange
(
commonKey
,
previousValue
,
currentValue
,
PropertyChangeType
.
MODIFIED
));
}
return
changes
;
}
}
apollo-client/src/main/java/com/ctrip/apollo/internals/AbstractConfigRepository.java
0 → 100644
View file @
5bb2aaf1
package
com
.
ctrip
.
apollo
.
internals
;
import
com.google.common.collect.Lists
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.util.List
;
import
java.util.Properties
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
abstract
class
AbstractConfigRepository
implements
ConfigRepository
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
AbstractConfigRepository
.
class
);
private
List
<
RepositoryChangeListener
>
m_listeners
=
Lists
.
newCopyOnWriteArrayList
();
@Override
public
void
addChangeListener
(
RepositoryChangeListener
listener
)
{
if
(!
m_listeners
.
contains
(
listener
))
{
m_listeners
.
add
(
listener
);
}
}
@Override
public
void
removeChangeListener
(
RepositoryChangeListener
listener
)
{
m_listeners
.
remove
(
listener
);
}
protected
void
fireRepositoryChange
(
String
namespace
,
Properties
newProperties
)
{
for
(
RepositoryChangeListener
listener
:
m_listeners
)
{
try
{
listener
.
onRepositoryChange
(
namespace
,
newProperties
);
}
catch
(
Throwable
t
)
{
logger
.
error
(
"Failed to invoke repository change listener {}"
,
listener
.
getClass
(),
t
);
}
}
}
}
apollo-client/src/main/java/com/ctrip/apollo/internals/ConfigRepository.java
View file @
5bb2aaf1
...
@@ -6,7 +6,19 @@ import java.util.Properties;
...
@@ -6,7 +6,19 @@ import java.util.Properties;
* @author Jason Song(song_s@ctrip.com)
* @author Jason Song(song_s@ctrip.com)
*/
*/
public
interface
ConfigRepository
{
public
interface
ConfigRepository
{
public
Properties
loadConfig
();
/**
* Get the config from this repository
* @return
*/
public
Properties
getConfig
();
/**
* Set the fallback repo for this repository
* @param fallbackConfigRepository
*/
public
void
setFallback
(
ConfigRepository
fallbackConfigRepository
);
public
void
setFallback
(
ConfigRepository
fallbackConfigRepository
);
public
void
addChangeListener
(
RepositoryChangeListener
listener
);
public
void
removeChangeListener
(
RepositoryChangeListener
listener
);
}
}
apollo-client/src/main/java/com/ctrip/apollo/internals/DefaultConfig.java
View file @
5bb2aaf1
package
com
.
ctrip
.
apollo
.
internals
;
package
com
.
ctrip
.
apollo
.
internals
;
import
com.ctrip.apollo.Config
;
import
com.google.common.collect.ImmutableMap
;
import
com.ctrip.apollo.core.utils.ClassLoaderUtil
;
import
com.ctrip.apollo.core.utils.ClassLoaderUtil
;
import
com.ctrip.apollo.enums.PropertyChangeType
;
import
com.ctrip.apollo.model.ConfigChange
;
import
com.ctrip.apollo.model.ConfigChangeEvent
;
import
com.dianping.cat.Cat
;
import
com.dianping.cat.Cat
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
...
@@ -9,12 +13,15 @@ import org.slf4j.LoggerFactory;
...
@@ -9,12 +13,15 @@ import org.slf4j.LoggerFactory;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStream
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Objects
;
import
java.util.Properties
;
import
java.util.Properties
;
/**
/**
* @author Jason Song(song_s@ctrip.com)
* @author Jason Song(song_s@ctrip.com)
*/
*/
public
class
DefaultConfig
implements
Config
{
public
class
DefaultConfig
extends
AbstractConfig
implements
RepositoryChangeListener
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
DefaultConfig
.
class
);
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
DefaultConfig
.
class
);
private
final
String
m_namespace
;
private
final
String
m_namespace
;
private
Properties
m_resourceProperties
;
private
Properties
m_resourceProperties
;
...
@@ -30,7 +37,8 @@ public class DefaultConfig implements Config {
...
@@ -30,7 +37,8 @@ public class DefaultConfig implements Config {
private
void
initialize
()
{
private
void
initialize
()
{
try
{
try
{
m_configProperties
=
m_configRepository
.
loadConfig
();
m_configProperties
=
m_configRepository
.
getConfig
();
m_configRepository
.
addChangeListener
(
this
);
}
catch
(
Throwable
ex
)
{
}
catch
(
Throwable
ex
)
{
String
message
=
String
.
format
(
"Init Apollo Local Config failed - namespace: %s"
,
String
message
=
String
.
format
(
"Init Apollo Local Config failed - namespace: %s"
,
m_namespace
);
m_namespace
);
...
@@ -68,6 +76,69 @@ public class DefaultConfig implements Config {
...
@@ -68,6 +76,69 @@ public class DefaultConfig implements Config {
return
value
==
null
?
defaultValue
:
value
;
return
value
==
null
?
defaultValue
:
value
;
}
}
@Override
public
synchronized
void
onRepositoryChange
(
String
namespace
,
Properties
newProperties
)
{
if
(
newProperties
.
equals
(
m_configProperties
))
{
return
;
}
Properties
newConfigProperties
=
new
Properties
();
newConfigProperties
.
putAll
(
newProperties
);
Map
<
String
,
ConfigChange
>
actualChanges
=
updateAndCalcConfigChanges
(
newConfigProperties
);
this
.
fireConfigChange
(
new
ConfigChangeEvent
(
m_namespace
,
actualChanges
));
}
private
Map
<
String
,
ConfigChange
>
updateAndCalcConfigChanges
(
Properties
newConfigProperties
)
{
List
<
ConfigChange
>
configChanges
=
calcPropertyChanges
(
m_configProperties
,
newConfigProperties
);
// List<ConfigChange> actualChanges = Lists.newArrayListWithCapacity(configChanges.size());
ImmutableMap
.
Builder
<
String
,
ConfigChange
>
actualChanges
=
new
ImmutableMap
.
Builder
<>();
/** === Double check since DefaultConfig has multiple config sources ==== **/
//1. use getProperty to update configChanges's old value
for
(
ConfigChange
change
:
configChanges
)
{
change
.
setOldValue
(
this
.
getProperty
(
change
.
getPropertyName
(),
change
.
getOldValue
()));
}
//2. update m_configProperties
m_configProperties
=
newConfigProperties
;
//3. use getProperty to update configChange's new value and calc the final changes
for
(
ConfigChange
change
:
configChanges
)
{
change
.
setNewValue
(
this
.
getProperty
(
change
.
getPropertyName
(),
change
.
getNewValue
()));
switch
(
change
.
getChangeType
())
{
case
NEW:
if
(
Objects
.
equals
(
change
.
getOldValue
(),
change
.
getNewValue
()))
{
break
;
}
if
(!
Objects
.
isNull
(
change
.
getOldValue
()))
{
change
.
setChangeType
(
PropertyChangeType
.
MODIFIED
);
}
actualChanges
.
put
(
change
.
getPropertyName
(),
change
);
break
;
case
MODIFIED:
if
(!
Objects
.
equals
(
change
.
getOldValue
(),
change
.
getNewValue
()))
{
actualChanges
.
put
(
change
.
getPropertyName
(),
change
);
}
break
;
case
DELETED:
if
(
Objects
.
equals
(
change
.
getOldValue
(),
change
.
getNewValue
()))
{
break
;
}
if
(!
Objects
.
isNull
(
change
.
getNewValue
()))
{
change
.
setChangeType
(
PropertyChangeType
.
MODIFIED
);
}
actualChanges
.
put
(
change
.
getPropertyName
(),
change
);
break
;
}
}
return
actualChanges
.
build
();
}
private
Properties
loadFromResource
(
String
namespace
)
{
private
Properties
loadFromResource
(
String
namespace
)
{
String
name
=
String
.
format
(
"META-INF/config/%s.properties"
,
namespace
);
String
name
=
String
.
format
(
"META-INF/config/%s.properties"
,
namespace
);
InputStream
in
=
ClassLoaderUtil
.
getLoader
().
getResourceAsStream
(
name
);
InputStream
in
=
ClassLoaderUtil
.
getLoader
().
getResourceAsStream
(
name
);
...
@@ -92,6 +163,4 @@ public class DefaultConfig implements Config {
...
@@ -92,6 +163,4 @@ public class DefaultConfig implements Config {
return
properties
;
return
properties
;
}
}
}
}
apollo-client/src/main/java/com/ctrip/apollo/internals/DefaultConfigManager.java
View file @
5bb2aaf1
...
@@ -19,7 +19,7 @@ public class DefaultConfigManager implements ConfigManager {
...
@@ -19,7 +19,7 @@ public class DefaultConfigManager implements ConfigManager {
@Inject
@Inject
private
ConfigFactoryManager
m_factoryManager
;
private
ConfigFactoryManager
m_factoryManager
;
private
Map
<
String
,
Config
>
m_configs
=
Maps
.
new
Hash
Map
();
private
Map
<
String
,
Config
>
m_configs
=
Maps
.
new
Concurrent
Map
();
@Override
@Override
public
Config
getConfig
(
String
namespace
)
{
public
Config
getConfig
(
String
namespace
)
{
...
...
apollo-client/src/main/java/com/ctrip/apollo/internals/LocalFileConfigRepository.java
View file @
5bb2aaf1
...
@@ -22,14 +22,15 @@ import java.util.Properties;
...
@@ -22,14 +22,15 @@ import java.util.Properties;
/**
/**
* @author Jason Song(song_s@ctrip.com)
* @author Jason Song(song_s@ctrip.com)
*/
*/
public
class
LocalFileConfigRepository
implements
ConfigRepository
{
public
class
LocalFileConfigRepository
extends
AbstractConfigRepository
implements
RepositoryChangeListener
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
LocalFileConfigRepository
.
class
);
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
LocalFileConfigRepository
.
class
);
private
PlexusContainer
m_container
;
private
final
PlexusContainer
m_container
;
private
final
String
m_namespace
;
private
final
String
m_namespace
;
private
final
File
m_baseDir
;
private
final
File
m_baseDir
;
private
final
ConfigUtil
m_configUtil
;
private
final
ConfigUtil
m_configUtil
;
private
Properties
m_fileProperties
;
private
volatile
Properties
m_fileProperties
;
private
ConfigRepository
m_fallback
;
private
volatile
ConfigRepository
m_fallback
;
public
LocalFileConfigRepository
(
File
baseDir
,
String
namespace
)
{
public
LocalFileConfigRepository
(
File
baseDir
,
String
namespace
)
{
m_baseDir
=
baseDir
;
m_baseDir
=
baseDir
;
...
@@ -43,7 +44,7 @@ public class LocalFileConfigRepository implements ConfigRepository {
...
@@ -43,7 +44,7 @@ public class LocalFileConfigRepository implements ConfigRepository {
}
}
@Override
@Override
public
Properties
load
Config
()
{
public
Properties
get
Config
()
{
if
(
m_fileProperties
==
null
)
{
if
(
m_fileProperties
==
null
)
{
initLocalConfig
();
initLocalConfig
();
}
}
...
@@ -54,26 +55,51 @@ public class LocalFileConfigRepository implements ConfigRepository {
...
@@ -54,26 +55,51 @@ public class LocalFileConfigRepository implements ConfigRepository {
@Override
@Override
public
void
setFallback
(
ConfigRepository
fallbackConfigRepository
)
{
public
void
setFallback
(
ConfigRepository
fallbackConfigRepository
)
{
//clear previous listener
if
(
m_fallback
!=
null
)
{
m_fallback
.
removeChangeListener
(
this
);
}
m_fallback
=
fallbackConfigRepository
;
m_fallback
=
fallbackConfigRepository
;
fallbackConfigRepository
.
addChangeListener
(
this
);
}
}
void
initLocalConfig
()
{
@Override
if
(
m_fallback
!=
null
)
{
public
synchronized
void
onRepositoryChange
(
String
namespace
,
Properties
newProperties
)
{
try
{
if
(
newProperties
.
equals
(
m_fileProperties
))
{
m_fileProperties
=
m_fallback
.
loadConfig
();
return
;
//TODO register change listener
persistLocalCacheFile
(
m_baseDir
,
m_namespace
);
return
;
}
catch
(
Throwable
ex
)
{
logger
.
error
(
"Load config from fallback loader failed"
,
ex
);
Cat
.
logError
(
ex
);
}
}
}
Properties
newFileProperties
=
new
Properties
();
newFileProperties
.
putAll
(
newProperties
);
this
.
m_fileProperties
=
newFileProperties
;
persistLocalCacheFile
(
m_baseDir
,
m_namespace
);
this
.
fireRepositoryChange
(
namespace
,
newProperties
);
}
void
initLocalConfig
()
{
try
{
try
{
m_fileProperties
=
this
.
loadFromLocalCacheFile
(
m_baseDir
,
m_namespace
);
m_fileProperties
=
this
.
loadFromLocalCacheFile
(
m_baseDir
,
m_namespace
);
}
catch
(
IOException
ex
)
{
}
catch
(
Throwable
ex
)
{
throw
new
RuntimeException
(
"Loading config from local cache file failed"
,
ex
);
logger
.
error
(
"Load config from local config cache file failed"
,
ex
);
}
//TODO check whether properties is expired or should we return after it's synced with fallback?
if
(
m_fileProperties
!=
null
)
{
return
;
}
if
(
m_fallback
==
null
)
{
throw
new
RuntimeException
(
"Load config from local config cache failed and there is no fallback repository!"
);
}
try
{
m_fileProperties
=
m_fallback
.
getConfig
();
persistLocalCacheFile
(
m_baseDir
,
m_namespace
);
}
catch
(
Throwable
ex
)
{
String
message
=
String
.
format
(
"Load config from fallback repository %s failed"
,
m_fallback
.
getClass
());
logger
.
error
(
message
,
ex
);
throw
new
RuntimeException
(
message
,
ex
);
}
}
}
}
...
...
apollo-client/src/main/java/com/ctrip/apollo/internals/RemoteConfigRepository.java
View file @
5bb2aaf1
...
@@ -5,6 +5,7 @@ import com.google.common.collect.Lists;
...
@@ -5,6 +5,7 @@ import com.google.common.collect.Lists;
import
com.ctrip.apollo.core.dto.ApolloConfig
;
import
com.ctrip.apollo.core.dto.ApolloConfig
;
import
com.ctrip.apollo.core.dto.ServiceDTO
;
import
com.ctrip.apollo.core.dto.ServiceDTO
;
import
com.ctrip.apollo.core.utils.ApolloThreadFactory
;
import
com.ctrip.apollo.util.ConfigUtil
;
import
com.ctrip.apollo.util.ConfigUtil
;
import
com.ctrip.apollo.util.http.HttpRequest
;
import
com.ctrip.apollo.util.http.HttpRequest
;
import
com.ctrip.apollo.util.http.HttpResponse
;
import
com.ctrip.apollo.util.http.HttpResponse
;
...
@@ -18,19 +19,22 @@ import org.unidal.lookup.ContainerLoader;
...
@@ -18,19 +19,22 @@ import org.unidal.lookup.ContainerLoader;
import
java.util.List
;
import
java.util.List
;
import
java.util.Properties
;
import
java.util.Properties
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.ScheduledExecutorService
;
import
java.util.concurrent.atomic.AtomicReference
;
import
java.util.concurrent.atomic.AtomicReference
;
/**
/**
* @author Jason Song(song_s@ctrip.com)
* @author Jason Song(song_s@ctrip.com)
*/
*/
public
class
RemoteConfigRepository
implements
ConfigRepository
{
public
class
RemoteConfigRepository
extends
AbstractConfigRepository
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
RemoteConfigRepository
.
class
);
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
RemoteConfigRepository
.
class
);
private
PlexusContainer
m_container
;
private
PlexusContainer
m_container
;
private
ConfigServiceLocator
m_serviceLocator
;
private
final
ConfigServiceLocator
m_serviceLocator
;
private
HttpUtil
m_httpUtil
;
private
final
HttpUtil
m_httpUtil
;
private
ConfigUtil
m_configUtil
;
private
final
ConfigUtil
m_configUtil
;
private
AtomicReference
<
ApolloConfig
>
m_configCache
;
private
volatile
AtomicReference
<
ApolloConfig
>
m_configCache
;
private
String
m_namespace
;
private
final
String
m_namespace
;
private
final
ScheduledExecutorService
m_executorService
;
public
RemoteConfigRepository
(
String
namespace
)
{
public
RemoteConfigRepository
(
String
namespace
)
{
m_namespace
=
namespace
;
m_namespace
=
namespace
;
...
@@ -43,12 +47,15 @@ public class RemoteConfigRepository implements ConfigRepository {
...
@@ -43,12 +47,15 @@ public class RemoteConfigRepository implements ConfigRepository {
}
catch
(
ComponentLookupException
e
)
{
}
catch
(
ComponentLookupException
e
)
{
throw
new
IllegalStateException
(
"Unable to load component!"
,
e
);
throw
new
IllegalStateException
(
"Unable to load component!"
,
e
);
}
}
this
.
m_executorService
=
Executors
.
newScheduledThreadPool
(
1
,
ApolloThreadFactory
.
create
(
"RemoteConfigRepository"
,
true
));
this
.
schedulePeriodicRefresh
();
}
}
@Override
@Override
public
Properties
load
Config
()
{
public
Properties
get
Config
()
{
if
(
m_configCache
.
get
()
==
null
)
{
if
(
m_configCache
.
get
()
==
null
)
{
init
RemoteConfig
();
this
.
load
RemoteConfig
();
}
}
return
transformApolloConfigToProperties
(
m_configCache
.
get
());
return
transformApolloConfigToProperties
(
m_configCache
.
get
());
}
}
...
@@ -58,8 +65,37 @@ public class RemoteConfigRepository implements ConfigRepository {
...
@@ -58,8 +65,37 @@ public class RemoteConfigRepository implements ConfigRepository {
//remote config doesn't need fallback
//remote config doesn't need fallback
}
}
private
void
initRemoteConfig
()
{
private
void
schedulePeriodicRefresh
()
{
m_configCache
.
set
(
this
.
loadApolloConfig
());
logger
.
info
(
"Schedule periodic refresh with interval: {} {}"
,
m_configUtil
.
getRefreshInterval
(),
m_configUtil
.
getRefreshTimeUnit
());
this
.
m_executorService
.
scheduleAtFixedRate
(
new
Runnable
()
{
@Override
public
void
run
()
{
try
{
loadRemoteConfig
();
}
catch
(
Throwable
ex
)
{
logger
.
error
(
"Refreshing config failed"
,
ex
);
}
}
},
m_configUtil
.
getRefreshInterval
(),
m_configUtil
.
getRefreshInterval
(),
m_configUtil
.
getRefreshTimeUnit
());
}
synchronized
void
loadRemoteConfig
()
{
ApolloConfig
previous
=
m_configCache
.
get
();
ApolloConfig
current
=
loadApolloConfig
();
//HTTP 304, nothing changed
if
(
previous
==
current
)
{
return
;
}
logger
.
info
(
"Remote Config changes!"
);
m_configCache
.
set
(
current
);
this
.
fireRepositoryChange
(
m_namespace
,
this
.
getConfig
());
}
}
private
Properties
transformApolloConfigToProperties
(
ApolloConfig
apolloConfig
)
{
private
Properties
transformApolloConfigToProperties
(
ApolloConfig
apolloConfig
)
{
...
@@ -72,16 +108,15 @@ public class RemoteConfigRepository implements ConfigRepository {
...
@@ -72,16 +108,15 @@ public class RemoteConfigRepository implements ConfigRepository {
private
ApolloConfig
loadApolloConfig
()
{
private
ApolloConfig
loadApolloConfig
()
{
String
appId
=
m_configUtil
.
getAppId
();
String
appId
=
m_configUtil
.
getAppId
();
String
cluster
=
m_configUtil
.
getCluster
();
String
cluster
=
m_configUtil
.
getCluster
();
String
ur
i
=
getConfigServiceUrl
(
);
String
ur
l
=
assembleUrl
(
getConfigServiceUrl
(),
appId
,
cluster
,
m_namespace
,
m_configCache
.
get
()
);
logger
.
info
(
"Loading config from {}, appId={}, cluster={}, namespace={}"
,
uri
,
appId
,
cluster
,
logger
.
info
(
"Loading config from {}"
,
url
);
m_namespace
);
HttpRequest
request
=
new
HttpRequest
(
url
);
HttpRequest
request
=
new
HttpRequest
(
assembleUrl
(
uri
,
appId
,
cluster
,
m_namespace
,
m_configCache
.
get
()));
try
{
try
{
HttpResponse
<
ApolloConfig
>
response
=
m_httpUtil
.
doGet
(
request
,
ApolloConfig
.
class
);
HttpResponse
<
ApolloConfig
>
response
=
m_httpUtil
.
doGet
(
request
,
ApolloConfig
.
class
);
if
(
response
.
getStatusCode
()
==
304
)
{
if
(
response
.
getStatusCode
()
==
304
)
{
logger
.
info
(
"Config server responds with 304 HTTP status code."
);
return
m_configCache
.
get
();
return
m_configCache
.
get
();
}
}
...
...
apollo-client/src/main/java/com/ctrip/apollo/internals/RepositoryChangeListener.java
0 → 100644
View file @
5bb2aaf1
package
com
.
ctrip
.
apollo
.
internals
;
import
java.util.Properties
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
interface
RepositoryChangeListener
{
public
void
onRepositoryChange
(
String
namespace
,
Properties
newProperties
);
}
apollo-client/src/main/java/com/ctrip/apollo/internals/SimpleConfig.java
View file @
5bb2aaf1
package
com
.
ctrip
.
apollo
.
internals
;
package
com
.
ctrip
.
apollo
.
internals
;
import
com.ctrip.apollo.Config
;
import
com.google.common.base.Function
;
import
com.google.common.collect.Maps
;
import
com.ctrip.apollo.model.ConfigChange
;
import
com.ctrip.apollo.model.ConfigChangeEvent
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Properties
;
import
java.util.Properties
;
/**
/**
* @author Jason Song(song_s@ctrip.com)
* @author Jason Song(song_s@ctrip.com)
*/
*/
public
class
SimpleConfig
implements
Config
{
public
class
SimpleConfig
extends
AbstractConfig
implements
RepositoryChangeListener
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
SimpleConfig
.
class
);
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
SimpleConfig
.
class
);
private
String
m_namespace
;
private
final
String
m_namespace
;
private
ConfigRepository
m_configRepository
;
private
final
ConfigRepository
m_configRepository
;
private
Properties
m_configProperties
;
private
volatile
Properties
m_configProperties
;
public
SimpleConfig
(
String
namespace
,
ConfigRepository
configRepository
)
{
public
SimpleConfig
(
String
namespace
,
ConfigRepository
configRepository
)
{
m_namespace
=
namespace
;
m_namespace
=
namespace
;
...
@@ -24,9 +30,10 @@ public class SimpleConfig implements Config {
...
@@ -24,9 +30,10 @@ public class SimpleConfig implements Config {
private
void
initialize
()
{
private
void
initialize
()
{
try
{
try
{
m_configProperties
=
m_configRepository
.
loadConfig
();
m_configProperties
=
m_configRepository
.
getConfig
();
m_configRepository
.
addChangeListener
(
this
);
}
catch
(
Throwable
ex
)
{
}
catch
(
Throwable
ex
)
{
String
message
=
String
.
format
(
"Init Apollo
Remot
e Config failed - namespace: %s"
,
String
message
=
String
.
format
(
"Init Apollo
Simpl
e Config failed - namespace: %s"
,
m_namespace
);
m_namespace
);
logger
.
error
(
message
,
ex
);
logger
.
error
(
message
,
ex
);
throw
new
RuntimeException
(
message
,
ex
);
throw
new
RuntimeException
(
message
,
ex
);
...
@@ -38,4 +45,25 @@ public class SimpleConfig implements Config {
...
@@ -38,4 +45,25 @@ public class SimpleConfig implements Config {
return
this
.
m_configProperties
.
getProperty
(
key
,
defaultValue
);
return
this
.
m_configProperties
.
getProperty
(
key
,
defaultValue
);
}
}
@Override
public
synchronized
void
onRepositoryChange
(
String
namespace
,
Properties
newProperties
)
{
if
(
newProperties
.
equals
(
m_configProperties
))
{
return
;
}
Properties
newConfigProperties
=
new
Properties
();
newConfigProperties
.
putAll
(
newProperties
);
List
<
ConfigChange
>
changes
=
calcPropertyChanges
(
m_configProperties
,
newConfigProperties
);
Map
<
String
,
ConfigChange
>
changeMap
=
Maps
.
uniqueIndex
(
changes
,
new
Function
<
ConfigChange
,
String
>()
{
@Override
public
String
apply
(
ConfigChange
input
)
{
return
input
.
getPropertyName
();
}
});
m_configProperties
=
newConfigProperties
;
this
.
fireConfigChange
(
new
ConfigChangeEvent
(
m_namespace
,
changeMap
));
}
}
}
apollo-client/src/main/java/com/ctrip/apollo/model/
Property
Change.java
→
apollo-client/src/main/java/com/ctrip/apollo/model/
Config
Change.java
View file @
5bb2aaf1
package
com
.
ctrip
.
apollo
.
model
;
package
com
.
ctrip
.
apollo
.
model
;
import
com.google.common.base.MoreObjects
;
import
com.ctrip.apollo.enums.PropertyChangeType
;
import
com.ctrip.apollo.enums.PropertyChangeType
;
/**
/**
* @author Jason Song(song_s@ctrip.com)
* @author Jason Song(song_s@ctrip.com)
*/
*/
public
class
Property
Change
{
public
class
Config
Change
{
private
String
propertyName
;
private
final
String
propertyName
;
private
Object
oldValue
;
private
String
oldValue
;
private
Object
newValue
;
private
String
newValue
;
private
PropertyChangeType
changeType
;
private
PropertyChangeType
changeType
;
public
PropertyChange
(
String
propertyName
,
Object
oldValue
,
Object
newValue
,
public
ConfigChange
(
String
propertyName
,
String
oldValue
,
String
newValue
,
PropertyChangeType
changeType
)
{
PropertyChangeType
changeType
)
{
this
.
propertyName
=
propertyName
;
this
.
propertyName
=
propertyName
;
this
.
oldValue
=
oldValue
;
this
.
oldValue
=
oldValue
;
this
.
newValue
=
newValue
;
this
.
newValue
=
newValue
;
...
@@ -24,31 +26,38 @@ public class PropertyChange {
...
@@ -24,31 +26,38 @@ public class PropertyChange {
return
propertyName
;
return
propertyName
;
}
}
public
void
setPropertyName
(
String
propertyName
)
{
public
String
getOldValue
()
{
this
.
propertyName
=
propertyName
;
}
public
Object
getOldValue
()
{
return
oldValue
;
return
oldValue
;
}
}
public
void
setOldValue
(
Object
oldValue
)
{
public
String
getNewValue
(
)
{
this
.
oldValue
=
old
Value
;
return
new
Value
;
}
}
public
Object
getNewValu
e
()
{
public
PropertyChangeType
getChangeTyp
e
()
{
return
newValu
e
;
return
changeTyp
e
;
}
}
public
void
set
NewValue
(
Object
new
Value
)
{
public
void
set
OldValue
(
String
old
Value
)
{
this
.
newValue
=
new
Value
;
this
.
oldValue
=
old
Value
;
}
}
public
PropertyChangeType
getChangeType
(
)
{
public
void
setNewValue
(
String
newValue
)
{
return
changeTyp
e
;
this
.
newValue
=
newValu
e
;
}
}
public
void
setChangeType
(
PropertyChangeType
changeType
)
{
public
void
setChangeType
(
PropertyChangeType
changeType
)
{
this
.
changeType
=
changeType
;
this
.
changeType
=
changeType
;
}
}
@Override
public
String
toString
()
{
return
MoreObjects
.
toStringHelper
(
this
)
.
omitNullValues
()
.
add
(
"propertyName"
,
propertyName
)
.
add
(
"oldValue"
,
oldValue
)
.
add
(
"newValue"
,
newValue
)
.
add
(
"changeType"
,
changeType
)
.
toString
();
}
}
}
apollo-client/src/main/java/com/ctrip/apollo/model/ConfigChangeEvent.java
0 → 100644
View file @
5bb2aaf1
package
com
.
ctrip
.
apollo
.
model
;
import
java.util.Map
;
import
java.util.Set
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
class
ConfigChangeEvent
{
private
final
String
m_namespace
;
private
final
Map
<
String
,
ConfigChange
>
changes
;
public
ConfigChangeEvent
(
String
m_namespace
,
Map
<
String
,
ConfigChange
>
changes
)
{
this
.
m_namespace
=
m_namespace
;
this
.
changes
=
changes
;
}
public
Set
<
String
>
changedKeys
()
{
return
changes
.
keySet
();
}
public
ConfigChange
getChange
(
String
key
)
{
return
changes
.
get
(
key
);
}
/**
* Please note that the returned Map is immutable
* @return changes
*/
public
Map
<
String
,
ConfigChange
>
getChanges
()
{
return
changes
;
}
public
String
getNamespace
()
{
return
m_namespace
;
}
}
apollo-client/src/main/java/com/ctrip/apollo/model/ConfigRefreshResult.java
deleted
100644 → 0
View file @
b1c4b7d8
package
com
.
ctrip
.
apollo
.
model
;
import
com.google.common.collect.Lists
;
import
java.util.List
;
import
java.util.Properties
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
class
ConfigRefreshResult
{
private
String
m_namespace
;
private
Properties
m_properties
;
private
List
<
PropertyChange
>
m_changes
;
public
ConfigRefreshResult
(
String
namespace
,
Properties
properties
)
{
this
.
m_namespace
=
namespace
;
this
.
m_properties
=
properties
;
m_changes
=
Lists
.
newArrayList
();
}
public
Properties
getProperties
()
{
return
m_properties
;
}
public
String
getNamespace
()
{
return
m_namespace
;
}
public
List
<
PropertyChange
>
getChanges
()
{
return
m_changes
;
}
public
void
setChanges
(
List
<
PropertyChange
>
changes
)
{
this
.
m_changes
=
changes
;
}
public
boolean
hasChanges
()
{
return
!
m_changes
.
isEmpty
();
}
}
apollo-client/src/main/java/com/ctrip/apollo/spi/DefaultConfigFactory.java
View file @
5bb2aaf1
...
@@ -33,8 +33,7 @@ public class DefaultConfigFactory implements ConfigFactory {
...
@@ -33,8 +33,7 @@ public class DefaultConfigFactory implements ConfigFactory {
}
}
LocalFileConfigRepository
createLocalConfigRepository
(
String
namespace
)
{
LocalFileConfigRepository
createLocalConfigRepository
(
String
namespace
)
{
LocalFileConfigRepository
LocalFileConfigRepository
localFileConfigLoader
=
localFileConfigLoader
=
new
LocalFileConfigRepository
(
m_baseDir
,
namespace
);
new
LocalFileConfigRepository
(
m_baseDir
,
namespace
);
localFileConfigLoader
.
setFallback
(
createRemoteConfigRepository
(
namespace
));
localFileConfigLoader
.
setFallback
(
createRemoteConfigRepository
(
namespace
));
return
localFileConfigLoader
;
return
localFileConfigLoader
;
...
...
apollo-client/src/main/java/com/ctrip/apollo/util/http/HttpUtil.java
View file @
5bb2aaf1
...
@@ -39,18 +39,19 @@ public class HttpUtil {
...
@@ -39,18 +39,19 @@ public class HttpUtil {
conn
.
setRequestMethod
(
"GET"
);
conn
.
setRequestMethod
(
"GET"
);
if
(
httpRequest
.
getConnectTimeout
()
<
0
)
{
int
connectTimeout
=
httpRequest
.
getConnectTimeout
();
conn
.
setConnectTimeout
(
m_configUtil
.
getConnectTimeout
());
if
(
connectTimeout
<
0
)
{
}
else
{
connectTimeout
=
m_configUtil
.
getConnectTimeout
();
conn
.
setConnectTimeout
(
httpRequest
.
getConnectTimeout
());
}
}
if
(
httpRequest
.
getReadTimeout
()
<
0
)
{
int
readTimeout
=
httpRequest
.
getReadTimeout
();
conn
.
setReadTimeout
(
m_configUtil
.
getReadTimeout
());
if
(
readTimeout
<
0
)
{
}
else
{
readTimeout
=
m_configUtil
.
getReadTimeout
();
conn
.
setReadTimeout
(
httpRequest
.
getReadTimeout
());
}
}
conn
.
setConnectTimeout
(
connectTimeout
);
conn
.
setReadTimeout
(
readTimeout
);
conn
.
connect
();
conn
.
connect
();
int
statusCode
=
conn
.
getResponseCode
();
int
statusCode
=
conn
.
getResponseCode
();
...
@@ -66,7 +67,7 @@ public class HttpUtil {
...
@@ -66,7 +67,7 @@ public class HttpUtil {
}
}
throw
new
RuntimeException
(
throw
new
RuntimeException
(
String
.
format
(
"Get operation failed
, status code - %d"
,
statusCode
));
String
.
format
(
"Get operation failed
for %s, status code - %d"
,
httpRequest
.
getUrl
()
,
statusCode
));
}
catch
(
Throwable
ex
)
{
}
catch
(
Throwable
ex
)
{
throw
new
RuntimeException
(
"Could not complete get operation"
,
ex
);
throw
new
RuntimeException
(
"Could not complete get operation"
,
ex
);
...
...
apollo-client/src/test/java/com/ctrip/apollo/ConfigServiceTest.java
View file @
5bb2aaf1
...
@@ -71,6 +71,11 @@ public class ConfigServiceTest extends ComponentTestCase {
...
@@ -71,6 +71,11 @@ public class ConfigServiceTest extends ComponentTestCase {
return
m_namespace
+
":"
+
key
;
return
m_namespace
+
":"
+
key
;
}
}
@Override
public
void
addChangeListener
(
ConfigChangeListener
listener
)
{
}
}
}
public
static
class
MockConfigFactory
implements
ConfigFactory
{
public
static
class
MockConfigFactory
implements
ConfigFactory
{
...
...
apollo-client/src/test/java/com/ctrip/apollo/internals/DefaultConfigManagerTest.java
View file @
5bb2aaf1
package
com
.
ctrip
.
apollo
.
internals
;
package
com
.
ctrip
.
apollo
.
internals
;
import
com.ctrip.apollo.Config
;
import
com.ctrip.apollo.Config
;
import
com.ctrip.apollo.ConfigChangeListener
;
import
com.ctrip.apollo.spi.ConfigFactory
;
import
com.ctrip.apollo.spi.ConfigFactory
;
import
com.ctrip.apollo.spi.ConfigFactoryManager
;
import
com.ctrip.apollo.spi.ConfigFactoryManager
;
...
@@ -60,6 +61,12 @@ public class DefaultConfigManagerTest extends ComponentTestCase {
...
@@ -60,6 +61,12 @@ public class DefaultConfigManagerTest extends ComponentTestCase {
public
String
getProperty
(
String
key
,
String
defaultValue
)
{
public
String
getProperty
(
String
key
,
String
defaultValue
)
{
return
namespace
+
":"
+
key
;
return
namespace
+
":"
+
key
;
}
}
@Override
public
void
addChangeListener
(
ConfigChangeListener
listener
)
{
}
};
};
}
}
};
};
...
...
apollo-client/src/test/java/com/ctrip/apollo/internals/DefaultConfigTest.java
View file @
5bb2aaf1
package
com
.
ctrip
.
apollo
.
internals
;
package
com
.
ctrip
.
apollo
.
internals
;
import
com.google.common.base.Charsets
;
import
com.google.common.base.Charsets
;
import
com.google.common.collect.ImmutableMap
;
import
com.google.common.io.Files
;
import
com.google.common.io.Files
;
import
com.ctrip.apollo.ConfigChangeListener
;
import
com.ctrip.apollo.core.utils.ClassLoaderUtil
;
import
com.ctrip.apollo.core.utils.ClassLoaderUtil
;
import
com.ctrip.apollo.enums.PropertyChangeType
;
import
com.ctrip.apollo.model.ConfigChange
;
import
com.ctrip.apollo.model.ConfigChangeEvent
;
import
org.junit.After
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.Test
;
import
org.mockito.ArgumentCaptor
;
import
java.io.File
;
import
java.io.File
;
import
java.util.Properties
;
import
java.util.Properties
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
static
org
.
mockito
.
Mockito
.
when
;
/**
/**
...
@@ -69,7 +77,7 @@ public class DefaultConfigTest {
...
@@ -69,7 +77,7 @@ public class DefaultConfigTest {
someProperties
=
new
Properties
();
someProperties
=
new
Properties
();
someProperties
.
setProperty
(
someKey
,
someLocalFileValue
);
someProperties
.
setProperty
(
someKey
,
someLocalFileValue
);
someProperties
.
setProperty
(
anotherKey
,
someLocalFileValue
);
someProperties
.
setProperty
(
anotherKey
,
someLocalFileValue
);
when
(
configRepository
.
load
Config
()).
thenReturn
(
someProperties
);
when
(
configRepository
.
get
Config
()).
thenReturn
(
someProperties
);
//set up resource file
//set up resource file
File
resourceFile
=
new
File
(
someResourceDir
,
someNamespace
+
".properties"
);
File
resourceFile
=
new
File
(
someResourceDir
,
someNamespace
+
".properties"
);
...
@@ -79,9 +87,8 @@ public class DefaultConfigTest {
...
@@ -79,9 +87,8 @@ public class DefaultConfigTest {
Files
.
append
(
System
.
getProperty
(
"line.separator"
),
resourceFile
,
Charsets
.
UTF_8
);
Files
.
append
(
System
.
getProperty
(
"line.separator"
),
resourceFile
,
Charsets
.
UTF_8
);
Files
.
append
(
lastKey
+
"="
+
someResourceValue
,
resourceFile
,
Charsets
.
UTF_8
);
Files
.
append
(
lastKey
+
"="
+
someResourceValue
,
resourceFile
,
Charsets
.
UTF_8
);
DefaultConfig
DefaultConfig
defaultConfig
=
defaultConfig
=
new
DefaultConfig
(
someNamespace
,
configRepository
);
new
DefaultConfig
(
someNamespace
,
configRepository
);
String
someKeyValue
=
defaultConfig
.
getProperty
(
someKey
,
null
);
String
someKeyValue
=
defaultConfig
.
getProperty
(
someKey
,
null
);
String
anotherKeyValue
=
defaultConfig
.
getProperty
(
anotherKey
,
null
);
String
anotherKeyValue
=
defaultConfig
.
getProperty
(
anotherKey
,
null
);
...
@@ -95,4 +102,80 @@ public class DefaultConfigTest {
...
@@ -95,4 +102,80 @@ public class DefaultConfigTest {
assertEquals
(
someResourceValue
,
lastKeyValue
);
assertEquals
(
someResourceValue
,
lastKeyValue
);
}
}
@Test
public
void
testOnRepositoryChange
()
throws
Exception
{
String
someKey
=
"someKey"
;
String
someSystemPropertyValue
=
"system-property-value"
;
String
anotherKey
=
"anotherKey"
;
String
someLocalFileValue
=
"local-file-value"
;
String
keyToBeDeleted
=
"keyToBeDeleted"
;
String
keyToBeDeletedValue
=
"keyToBeDeletedValue"
;
String
yetAnotherKey
=
"yetAnotherKey"
;
String
yetAnotherValue
=
"yetAnotherValue"
;
String
yetAnotherResourceValue
=
"yetAnotherResourceValue"
;
//set up system property
System
.
setProperty
(
someKey
,
someSystemPropertyValue
);
//set up config repo
someProperties
=
new
Properties
();
someProperties
.
putAll
(
ImmutableMap
.
of
(
someKey
,
someLocalFileValue
,
anotherKey
,
someLocalFileValue
,
keyToBeDeleted
,
keyToBeDeletedValue
,
yetAnotherKey
,
yetAnotherValue
));
when
(
configRepository
.
getConfig
()).
thenReturn
(
someProperties
);
//set up resource file
File
resourceFile
=
new
File
(
someResourceDir
,
someNamespace
+
".properties"
);
Files
.
append
(
yetAnotherKey
+
"="
+
yetAnotherResourceValue
,
resourceFile
,
Charsets
.
UTF_8
);
DefaultConfig
defaultConfig
=
new
DefaultConfig
(
someNamespace
,
configRepository
);
ConfigChangeListener
someListener
=
mock
(
ConfigChangeListener
.
class
);
defaultConfig
.
addChangeListener
(
someListener
);
Properties
newProperties
=
new
Properties
();
String
someKeyNewValue
=
"new-some-value"
;
String
anotherKeyNewValue
=
"another-new-value"
;
String
newKey
=
"newKey"
;
String
newValue
=
"newValue"
;
newProperties
.
putAll
(
ImmutableMap
.
of
(
someKey
,
someKeyNewValue
,
anotherKey
,
anotherKeyNewValue
,
newKey
,
newValue
));
final
ArgumentCaptor
<
ConfigChangeEvent
>
captor
=
ArgumentCaptor
.
forClass
(
ConfigChangeEvent
.
class
);
defaultConfig
.
onRepositoryChange
(
someNamespace
,
newProperties
);
verify
(
someListener
,
times
(
1
)).
onChange
(
captor
.
capture
());
ConfigChangeEvent
changeEvent
=
captor
.
getValue
();
assertEquals
(
someNamespace
,
changeEvent
.
getNamespace
());
assertEquals
(
4
,
changeEvent
.
getChanges
().
size
());
ConfigChange
anotherKeyChange
=
changeEvent
.
getChange
(
anotherKey
);
assertEquals
(
someLocalFileValue
,
anotherKeyChange
.
getOldValue
());
assertEquals
(
anotherKeyNewValue
,
anotherKeyChange
.
getNewValue
());
assertEquals
(
PropertyChangeType
.
MODIFIED
,
anotherKeyChange
.
getChangeType
());
ConfigChange
yetAnotherKeyChange
=
changeEvent
.
getChange
(
yetAnotherKey
);
assertEquals
(
yetAnotherValue
,
yetAnotherKeyChange
.
getOldValue
());
assertEquals
(
yetAnotherResourceValue
,
yetAnotherKeyChange
.
getNewValue
());
assertEquals
(
PropertyChangeType
.
MODIFIED
,
yetAnotherKeyChange
.
getChangeType
());
ConfigChange
keyToBeDeletedChange
=
changeEvent
.
getChange
(
keyToBeDeleted
);
assertEquals
(
keyToBeDeletedValue
,
keyToBeDeletedChange
.
getOldValue
());
assertEquals
(
null
,
keyToBeDeletedChange
.
getNewValue
());
assertEquals
(
PropertyChangeType
.
DELETED
,
keyToBeDeletedChange
.
getChangeType
());
ConfigChange
newKeyChange
=
changeEvent
.
getChange
(
newKey
);
assertEquals
(
null
,
newKeyChange
.
getOldValue
());
assertEquals
(
newValue
,
newKeyChange
.
getNewValue
());
assertEquals
(
PropertyChangeType
.
NEW
,
newKeyChange
.
getChangeType
());
}
}
}
apollo-client/src/test/java/com/ctrip/apollo/internals/LocalFileConfigRepositoryTest.java
View file @
5bb2aaf1
...
@@ -8,6 +8,7 @@ import com.ctrip.apollo.util.ConfigUtil;
...
@@ -8,6 +8,7 @@ import com.ctrip.apollo.util.ConfigUtil;
import
org.junit.After
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.Test
;
import
org.mockito.ArgumentCaptor
;
import
org.unidal.lookup.ComponentTestCase
;
import
org.unidal.lookup.ComponentTestCase
;
import
java.io.File
;
import
java.io.File
;
...
@@ -16,7 +17,11 @@ import java.util.Properties;
...
@@ -16,7 +17,11 @@ import java.util.Properties;
import
static
org
.
hamcrest
.
core
.
IsEqual
.
equalTo
;
import
static
org
.
hamcrest
.
core
.
IsEqual
.
equalTo
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
static
org
.
mockito
.
Matchers
.
eq
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
only
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
static
org
.
mockito
.
Mockito
.
when
;
/**
/**
...
@@ -40,7 +45,7 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase {
...
@@ -40,7 +45,7 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase {
someProperties
=
new
Properties
();
someProperties
=
new
Properties
();
someProperties
.
setProperty
(
"defaultKey"
,
"defaultValue"
);
someProperties
.
setProperty
(
"defaultKey"
,
"defaultValue"
);
fallbackRepo
=
mock
(
ConfigRepository
.
class
);
fallbackRepo
=
mock
(
ConfigRepository
.
class
);
when
(
fallbackRepo
.
load
Config
()).
thenReturn
(
someProperties
);
when
(
fallbackRepo
.
get
Config
()).
thenReturn
(
someProperties
);
defineComponent
(
ConfigUtil
.
class
,
MockConfigUtil
.
class
);
defineComponent
(
ConfigUtil
.
class
,
MockConfigUtil
.
class
);
}
}
...
@@ -83,7 +88,7 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase {
...
@@ -83,7 +88,7 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase {
Files
.
write
(
someKey
+
"="
+
someValue
,
file
,
Charsets
.
UTF_8
);
Files
.
write
(
someKey
+
"="
+
someValue
,
file
,
Charsets
.
UTF_8
);
LocalFileConfigRepository
localRepo
=
new
LocalFileConfigRepository
(
someBaseDir
,
someNamespace
);
LocalFileConfigRepository
localRepo
=
new
LocalFileConfigRepository
(
someBaseDir
,
someNamespace
);
Properties
properties
=
localRepo
.
load
Config
();
Properties
properties
=
localRepo
.
get
Config
();
assertEquals
(
someValue
,
properties
.
getProperty
(
someKey
));
assertEquals
(
someValue
,
properties
.
getProperty
(
someKey
));
...
@@ -97,7 +102,7 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase {
...
@@ -97,7 +102,7 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase {
localFileConfigRepository
.
setFallback
(
fallbackRepo
);
localFileConfigRepository
.
setFallback
(
fallbackRepo
);
Properties
result
=
localFileConfigRepository
.
load
Config
();
Properties
result
=
localFileConfigRepository
.
get
Config
();
assertThat
(
assertThat
(
"LocalFileConfigRepository's properties should be the same as fallback repo's when there is no local cache"
,
"LocalFileConfigRepository's properties should be the same as fallback repo's when there is no local cache"
,
...
@@ -111,13 +116,13 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase {
...
@@ -111,13 +116,13 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase {
localRepo
.
setFallback
(
fallbackRepo
);
localRepo
.
setFallback
(
fallbackRepo
);
Properties
someProperties
=
localRepo
.
load
Config
();
Properties
someProperties
=
localRepo
.
get
Config
();
LocalFileConfigRepository
LocalFileConfigRepository
anotherLocalRepoWithNoFallback
=
anotherLocalRepoWithNoFallback
=
new
LocalFileConfigRepository
(
someBaseDir
,
someNamespace
);
new
LocalFileConfigRepository
(
someBaseDir
,
someNamespace
);
Properties
anotherProperties
=
anotherLocalRepoWithNoFallback
.
load
Config
();
Properties
anotherProperties
=
anotherLocalRepoWithNoFallback
.
get
Config
();
assertThat
(
assertThat
(
"LocalFileConfigRepository should persist local cache files and return that afterwards"
,
"LocalFileConfigRepository should persist local cache files and return that afterwards"
,
...
@@ -125,6 +130,30 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase {
...
@@ -125,6 +130,30 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase {
}
}
@Test
public
void
testOnRepositoryChange
()
throws
Exception
{
RepositoryChangeListener
someListener
=
mock
(
RepositoryChangeListener
.
class
);
LocalFileConfigRepository
localFileConfigRepository
=
new
LocalFileConfigRepository
(
someBaseDir
,
someNamespace
);
localFileConfigRepository
.
setFallback
(
fallbackRepo
);
localFileConfigRepository
.
addChangeListener
(
someListener
);
localFileConfigRepository
.
getConfig
();
Properties
anotherProperties
=
new
Properties
();
anotherProperties
.
put
(
"anotherKey"
,
"anotherValue"
);
localFileConfigRepository
.
onRepositoryChange
(
someNamespace
,
anotherProperties
);
final
ArgumentCaptor
<
Properties
>
captor
=
ArgumentCaptor
.
forClass
(
Properties
.
class
);
verify
(
someListener
,
times
(
1
)).
onRepositoryChange
(
eq
(
someNamespace
),
captor
.
capture
());
assertEquals
(
anotherProperties
,
captor
.
getValue
());
}
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/apollo/internals/RemoteConfigRepositoryTest.java
View file @
5bb2aaf1
package
com
.
ctrip
.
apollo
.
internals
;
package
com
.
ctrip
.
apollo
.
internals
;
import
com.google.common.collect.ImmutableMap
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Maps
;
import
com.google.common.collect.Maps
;
...
@@ -13,6 +14,7 @@ import com.ctrip.apollo.util.http.HttpUtil;
...
@@ -13,6 +14,7 @@ import com.ctrip.apollo.util.http.HttpUtil;
import
org.junit.Before
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.junit.runner.RunWith
;
import
org.mockito.ArgumentCaptor
;
import
org.mockito.Mock
;
import
org.mockito.Mock
;
import
org.mockito.runners.MockitoJUnitRunner
;
import
org.mockito.runners.MockitoJUnitRunner
;
import
org.unidal.lookup.ComponentTestCase
;
import
org.unidal.lookup.ComponentTestCase
;
...
@@ -22,7 +24,10 @@ import java.util.Map;
...
@@ -22,7 +24,10 @@ import java.util.Map;
import
java.util.Properties
;
import
java.util.Properties
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
mockito
.
Matchers
.
eq
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
static
org
.
mockito
.
Mockito
.
when
;
/**
/**
...
@@ -60,7 +65,7 @@ public class RemoteConfigRepositoryTest extends ComponentTestCase {
...
@@ -60,7 +65,7 @@ public class RemoteConfigRepositoryTest extends ComponentTestCase {
when
(
someResponse
.
getBody
()).
thenReturn
(
someApolloConfig
);
when
(
someResponse
.
getBody
()).
thenReturn
(
someApolloConfig
);
RemoteConfigRepository
remoteConfigRepository
=
new
RemoteConfigRepository
(
someNamespace
);
RemoteConfigRepository
remoteConfigRepository
=
new
RemoteConfigRepository
(
someNamespace
);
Properties
config
=
remoteConfigRepository
.
load
Config
();
Properties
config
=
remoteConfigRepository
.
get
Config
();
assertEquals
(
configurations
,
config
);
assertEquals
(
configurations
,
config
);
}
}
...
@@ -71,7 +76,27 @@ public class RemoteConfigRepositoryTest extends ComponentTestCase {
...
@@ -71,7 +76,27 @@ public class RemoteConfigRepositoryTest extends ComponentTestCase {
when
(
someResponse
.
getStatusCode
()).
thenReturn
(
500
);
when
(
someResponse
.
getStatusCode
()).
thenReturn
(
500
);
RemoteConfigRepository
remoteConfigRepository
=
new
RemoteConfigRepository
(
someNamespace
);
RemoteConfigRepository
remoteConfigRepository
=
new
RemoteConfigRepository
(
someNamespace
);
remoteConfigRepository
.
loadConfig
();
remoteConfigRepository
.
getConfig
();
}
@Test
public
void
testRepositoryChangeListener
()
throws
Exception
{
Map
<
String
,
String
>
configurations
=
ImmutableMap
.
of
(
"someKey"
,
"someValue"
);
ApolloConfig
someApolloConfig
=
assembleApolloConfig
(
configurations
);
when
(
someResponse
.
getStatusCode
()).
thenReturn
(
200
);
when
(
someResponse
.
getBody
()).
thenReturn
(
someApolloConfig
);
RepositoryChangeListener
someListener
=
mock
(
RepositoryChangeListener
.
class
);
RemoteConfigRepository
remoteConfigRepository
=
new
RemoteConfigRepository
(
someNamespace
);
remoteConfigRepository
.
addChangeListener
(
someListener
);
final
ArgumentCaptor
<
Properties
>
captor
=
ArgumentCaptor
.
forClass
(
Properties
.
class
);
remoteConfigRepository
.
loadRemoteConfig
();
verify
(
someListener
,
times
(
1
)).
onRepositoryChange
(
eq
(
someNamespace
),
captor
.
capture
());
assertEquals
(
configurations
,
captor
.
getValue
());
}
}
private
ApolloConfig
assembleApolloConfig
(
Map
<
String
,
String
>
configurations
)
{
private
ApolloConfig
assembleApolloConfig
(
Map
<
String
,
String
>
configurations
)
{
...
...
apollo-client/src/test/java/com/ctrip/apollo/internals/SimpleConfigTest.java
View file @
5bb2aaf1
package
com
.
ctrip
.
apollo
.
internals
;
package
com
.
ctrip
.
apollo
.
internals
;
import
com.google.common.collect.ImmutableMap
;
import
com.ctrip.apollo.ConfigChangeListener
;
import
com.ctrip.apollo.enums.PropertyChangeType
;
import
com.ctrip.apollo.model.ConfigChange
;
import
com.ctrip.apollo.model.ConfigChangeEvent
;
import
org.junit.Before
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.junit.runner.RunWith
;
import
org.mockito.ArgumentCaptor
;
import
org.mockito.Mock
;
import
org.mockito.Mock
;
import
org.mockito.runners.MockitoJUnitRunner
;
import
org.mockito.runners.MockitoJUnitRunner
;
import
java.util.Properties
;
import
java.util.Properties
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
static
org
.
mockito
.
Mockito
.
when
;
/**
/**
...
@@ -32,7 +43,7 @@ public class SimpleConfigTest {
...
@@ -32,7 +43,7 @@ public class SimpleConfigTest {
String
someValue
=
"someValue"
;
String
someValue
=
"someValue"
;
someProperties
.
setProperty
(
someKey
,
someValue
);
someProperties
.
setProperty
(
someKey
,
someValue
);
when
(
configRepository
.
load
Config
()).
thenReturn
(
someProperties
);
when
(
configRepository
.
get
Config
()).
thenReturn
(
someProperties
);
SimpleConfig
config
=
new
SimpleConfig
(
someNamespace
,
configRepository
);
SimpleConfig
config
=
new
SimpleConfig
(
someNamespace
,
configRepository
);
...
@@ -41,8 +52,57 @@ public class SimpleConfigTest {
...
@@ -41,8 +52,57 @@ public class SimpleConfigTest {
@Test
(
expected
=
RuntimeException
.
class
)
@Test
(
expected
=
RuntimeException
.
class
)
public
void
testLoadConfigFromConfigRepositoryError
()
throws
Exception
{
public
void
testLoadConfigFromConfigRepositoryError
()
throws
Exception
{
when
(
configRepository
.
load
Config
()).
thenThrow
(
Throwable
.
class
);
when
(
configRepository
.
get
Config
()).
thenThrow
(
Throwable
.
class
);
new
SimpleConfig
(
someNamespace
,
configRepository
);
new
SimpleConfig
(
someNamespace
,
configRepository
);
}
}
@Test
public
void
testOnRepositoryChange
()
throws
Exception
{
Properties
someProperties
=
new
Properties
();
String
someKey
=
"someKey"
;
String
someValue
=
"someValue"
;
String
anotherKey
=
"anotherKey"
;
String
anotherValue
=
"anotherValue"
;
someProperties
.
putAll
(
ImmutableMap
.
of
(
someKey
,
someValue
,
anotherKey
,
anotherValue
));
Properties
anotherProperties
=
new
Properties
();
String
newKey
=
"newKey"
;
String
newValue
=
"newValue"
;
String
someValueNew
=
"someValueNew"
;
anotherProperties
.
putAll
(
ImmutableMap
.
of
(
someKey
,
someValueNew
,
newKey
,
newValue
));
when
(
configRepository
.
getConfig
()).
thenReturn
(
someProperties
);
ConfigChangeListener
someListener
=
mock
(
ConfigChangeListener
.
class
);
SimpleConfig
config
=
new
SimpleConfig
(
someNamespace
,
configRepository
);
config
.
addChangeListener
(
someListener
);
config
.
onRepositoryChange
(
someNamespace
,
anotherProperties
);
ArgumentCaptor
<
ConfigChangeEvent
>
captor
=
ArgumentCaptor
.
forClass
(
ConfigChangeEvent
.
class
);
verify
(
someListener
,
times
(
1
)).
onChange
(
captor
.
capture
());
ConfigChangeEvent
changeEvent
=
captor
.
getValue
();
assertEquals
(
someNamespace
,
changeEvent
.
getNamespace
());
assertEquals
(
3
,
changeEvent
.
getChanges
().
size
());
ConfigChange
someKeyChange
=
changeEvent
.
getChange
(
someKey
);
assertEquals
(
someValue
,
someKeyChange
.
getOldValue
());
assertEquals
(
someValueNew
,
someKeyChange
.
getNewValue
());
assertEquals
(
PropertyChangeType
.
MODIFIED
,
someKeyChange
.
getChangeType
());
ConfigChange
anotherKeyChange
=
changeEvent
.
getChange
(
anotherKey
);
assertEquals
(
anotherValue
,
anotherKeyChange
.
getOldValue
());
assertEquals
(
null
,
anotherKeyChange
.
getNewValue
());
assertEquals
(
PropertyChangeType
.
DELETED
,
anotherKeyChange
.
getChangeType
());
ConfigChange
newKeyChange
=
changeEvent
.
getChange
(
newKey
);
assertEquals
(
null
,
newKeyChange
.
getOldValue
());
assertEquals
(
newValue
,
newKeyChange
.
getNewValue
());
assertEquals
(
PropertyChangeType
.
NEW
,
newKeyChange
.
getChangeType
());
}
}
}
apollo-client/src/test/java/com/ctrip/apollo/spi/DefaultConfigFactoryTest.java
View file @
5bb2aaf1
...
@@ -40,7 +40,7 @@ public class DefaultConfigFactoryTest extends ComponentTestCase {
...
@@ -40,7 +40,7 @@ public class DefaultConfigFactoryTest extends ComponentTestCase {
someProperties
.
setProperty
(
someKey
,
someValue
);
someProperties
.
setProperty
(
someKey
,
someValue
);
LocalFileConfigRepository
someLocalConfigRepo
=
mock
(
LocalFileConfigRepository
.
class
);
LocalFileConfigRepository
someLocalConfigRepo
=
mock
(
LocalFileConfigRepository
.
class
);
when
(
someLocalConfigRepo
.
load
Config
()).
thenReturn
(
someProperties
);
when
(
someLocalConfigRepo
.
get
Config
()).
thenReturn
(
someProperties
);
doReturn
(
someLocalConfigRepo
).
when
(
defaultConfigFactory
).
createLocalConfigRepository
(
someNamespace
);
doReturn
(
someLocalConfigRepo
).
when
(
defaultConfigFactory
).
createLocalConfigRepository
(
someNamespace
);
...
...
apollo-demo/src/main/java/ApolloConfigDemo.java
View file @
5bb2aaf1
import
com.ctrip.apollo.Config
;
import
com.ctrip.apollo.Config
;
import
com.ctrip.apollo.ConfigChangeListener
;
import
com.ctrip.apollo.ConfigService
;
import
com.ctrip.apollo.ConfigService
;
import
com.ctrip.apollo.model.ConfigChange
;
import
com.ctrip.apollo.model.ConfigChangeEvent
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.io.BufferedReader
;
import
java.io.BufferedReader
;
import
java.io.IOException
;
import
java.io.IOException
;
...
@@ -9,16 +15,18 @@ import java.io.InputStreamReader;
...
@@ -9,16 +15,18 @@ import java.io.InputStreamReader;
/**
/**
* @author Jason Song(song_s@ctrip.com)
* @author Jason Song(song_s@ctrip.com)
*/
*/
public
class
ApolloConfigDemo
{
public
class
ApolloConfigDemo
implements
ConfigChangeListener
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
ApolloConfigDemo
.
class
);
private
Config
config
;
private
Config
config
;
public
ApolloConfigDemo
()
{
public
ApolloConfigDemo
()
{
config
=
ConfigService
.
getConfig
();
config
=
ConfigService
.
getConfig
();
config
.
addChangeListener
(
this
);
}
}
private
String
getConfig
(
String
key
)
{
private
String
getConfig
(
String
key
)
{
String
result
=
config
.
getProperty
(
key
,
"undefined"
);
String
result
=
config
.
getProperty
(
key
,
"undefined"
);
System
.
out
.
println
(
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
;
}
}
...
@@ -35,4 +43,14 @@ public class ApolloConfigDemo {
...
@@ -35,4 +43,14 @@ public class ApolloConfigDemo {
apolloConfigDemo
.
getConfig
(
input
);
apolloConfigDemo
.
getConfig
(
input
);
}
}
}
}
@Override
public
void
onChange
(
ConfigChangeEvent
changeEvent
)
{
logger
.
info
(
"Changes for namespace {}"
,
changeEvent
.
getNamespace
());
for
(
ConfigChange
change
:
changeEvent
.
getChanges
().
values
())
{
logger
.
info
(
"Change - key: {}, oldValue: {}, newValue: {}, changeType: {}"
,
change
.
getPropertyName
(),
change
.
getOldValue
(),
change
.
getNewValue
(),
change
.
getChangeType
());
}
}
}
}
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