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
bb68324d
Commit
bb68324d
authored
Apr 18, 2016
by
Jason Song
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Client side retry and logging to CAT
parent
7795a848
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
330 additions
and
93 deletions
+330
-93
ConfigService.java
...-client/src/main/java/com/ctrip/apollo/ConfigService.java
+6
-2
PropertyChangeType.java
.../main/java/com/ctrip/apollo/enums/PropertyChangeType.java
+1
-13
ClientEnvironment.java
...src/main/java/com/ctrip/apollo/env/ClientEnvironment.java
+2
-1
AbstractConfig.java
.../main/java/com/ctrip/apollo/internals/AbstractConfig.java
+2
-0
AbstractConfigRepository.java
.../com/ctrip/apollo/internals/AbstractConfigRepository.java
+4
-0
ConfigServiceLocator.java
...java/com/ctrip/apollo/internals/ConfigServiceLocator.java
+50
-15
DefaultConfig.java
...c/main/java/com/ctrip/apollo/internals/DefaultConfig.java
+2
-1
LocalFileConfigRepository.java
...com/ctrip/apollo/internals/LocalFileConfigRepository.java
+10
-10
RemoteConfigRepository.java
...va/com/ctrip/apollo/internals/RemoteConfigRepository.java
+56
-15
SimpleConfig.java
...rc/main/java/com/ctrip/apollo/internals/SimpleConfig.java
+2
-0
DefaultConfigFactory.java
.../main/java/com/ctrip/apollo/spi/DefaultConfigFactory.java
+14
-3
ConfigUtil.java
...lient/src/main/java/com/ctrip/apollo/util/ConfigUtil.java
+4
-4
HttpUtil.java
...nt/src/main/java/com/ctrip/apollo/util/http/HttpUtil.java
+38
-4
BaseIntegrationTest.java
...ava/com/ctrip/apollo/integration/BaseIntegrationTest.java
+48
-3
ConfigIntegrationTest.java
...a/com/ctrip/apollo/integration/ConfigIntegrationTest.java
+68
-21
Apollo.java
apollo-core/src/main/java/com/ctrip/apollo/Apollo.java
+8
-0
ServiceDTO.java
...e/src/main/java/com/ctrip/apollo/core/dto/ServiceDTO.java
+12
-0
ApolloConfigDemo.java
apollo-demo/src/main/java/ApolloConfigDemo.java
+3
-1
No files found.
apollo-client/src/main/java/com/ctrip/apollo/ConfigService.java
View file @
bb68324d
...
@@ -4,6 +4,7 @@ import com.ctrip.apollo.core.ConfigConsts;
...
@@ -4,6 +4,7 @@ import com.ctrip.apollo.core.ConfigConsts;
import
com.ctrip.apollo.internals.ConfigManager
;
import
com.ctrip.apollo.internals.ConfigManager
;
import
com.ctrip.apollo.spi.ConfigFactory
;
import
com.ctrip.apollo.spi.ConfigFactory
;
import
com.ctrip.apollo.spi.ConfigRegistry
;
import
com.ctrip.apollo.spi.ConfigRegistry
;
import
com.dianping.cat.Cat
;
import
org.codehaus.plexus.PlexusContainer
;
import
org.codehaus.plexus.PlexusContainer
;
import
org.codehaus.plexus.component.repository.exception.ComponentLookupException
;
import
org.codehaus.plexus.component.repository.exception.ComponentLookupException
;
...
@@ -36,6 +37,7 @@ public class ConfigService {
...
@@ -36,6 +37,7 @@ public class ConfigService {
* @return config instance
* @return config instance
*/
*/
public
static
Config
getConfig
(
String
namespace
)
{
public
static
Config
getConfig
(
String
namespace
)
{
Cat
.
logEvent
(
"Apollo.Client.Version"
,
Apollo
.
VERSION
);
return
getManager
().
getConfig
(
namespace
);
return
getManager
().
getConfig
(
namespace
);
}
}
...
@@ -43,6 +45,7 @@ public class ConfigService {
...
@@ -43,6 +45,7 @@ public class ConfigService {
try
{
try
{
return
s_instance
.
m_container
.
lookup
(
ConfigManager
.
class
);
return
s_instance
.
m_container
.
lookup
(
ConfigManager
.
class
);
}
catch
(
ComponentLookupException
ex
)
{
}
catch
(
ComponentLookupException
ex
)
{
Cat
.
logError
(
ex
);
throw
new
IllegalStateException
(
"Unable to load ConfigManager!"
,
ex
);
throw
new
IllegalStateException
(
"Unable to load ConfigManager!"
,
ex
);
}
}
}
}
...
@@ -51,6 +54,7 @@ public class ConfigService {
...
@@ -51,6 +54,7 @@ public class ConfigService {
try
{
try
{
return
s_instance
.
m_container
.
lookup
(
ConfigRegistry
.
class
);
return
s_instance
.
m_container
.
lookup
(
ConfigRegistry
.
class
);
}
catch
(
ComponentLookupException
ex
)
{
}
catch
(
ComponentLookupException
ex
)
{
Cat
.
logError
(
ex
);
throw
new
IllegalStateException
(
"Unable to load ConfigRegistry!"
,
ex
);
throw
new
IllegalStateException
(
"Unable to load ConfigRegistry!"
,
ex
);
}
}
}
}
...
@@ -60,7 +64,7 @@ public class ConfigService {
...
@@ -60,7 +64,7 @@ public class ConfigService {
}
}
/**
/**
* Manually set the config for the namespace specified, use with caution
!
* Manually set the config for the namespace specified, use with caution
.
* @param namespace the namespace
* @param namespace the namespace
* @param config the config instance
* @param config the config instance
*/
*/
...
@@ -78,7 +82,7 @@ public class ConfigService {
...
@@ -78,7 +82,7 @@ public class ConfigService {
}
}
/**
/**
* Manually set the config factory for the namespace specified, use with caution
!
* Manually set the config factory for the namespace specified, use with caution
.
* @param namespace the namespace
* @param namespace the namespace
* @param factory the factory instance
* @param factory the factory instance
*/
*/
...
...
apollo-client/src/main/java/com/ctrip/apollo/enums/PropertyChangeType.java
View file @
bb68324d
...
@@ -5,17 +5,5 @@ package com.ctrip.apollo.enums;
...
@@ -5,17 +5,5 @@ package com.ctrip.apollo.enums;
* @author Jason Song(song_s@ctrip.com)
* @author Jason Song(song_s@ctrip.com)
*/
*/
public
enum
PropertyChangeType
{
public
enum
PropertyChangeType
{
NEW
(
"New"
),
NEW
,
MODIFIED
,
DELETED
MODIFIED
(
"Modified"
),
DELETED
(
"Deleted"
);
private
String
type
;
PropertyChangeType
(
String
type
)
{
this
.
type
=
type
;
}
public
String
getType
()
{
return
type
;
}
}
}
apollo-client/src/main/java/com/ctrip/apollo/env/
Apollo
.java
→
apollo-client/src/main/java/com/ctrip/apollo/env/
ClientEnvironment
.java
View file @
bb68324d
...
@@ -5,7 +5,7 @@ import com.google.common.base.Strings;
...
@@ -5,7 +5,7 @@ import com.google.common.base.Strings;
import
com.ctrip.apollo.core.enums.Env
;
import
com.ctrip.apollo.core.enums.Env
;
import
com.ctrip.framework.foundation.Foundation
;
import
com.ctrip.framework.foundation.Foundation
;
public
class
Apollo
{
public
class
ClientEnvironment
{
private
static
Env
s_env
;
private
static
Env
s_env
;
private
static
String
s_appId
;
private
static
String
s_appId
;
private
static
String
s_cluster
;
private
static
String
s_cluster
;
...
@@ -39,6 +39,7 @@ public class Apollo {
...
@@ -39,6 +39,7 @@ public class Apollo {
s_env
=
Env
.
LPT
;
s_env
=
Env
.
LPT
;
break
;
break
;
case
"FAT"
:
case
"FAT"
:
case
"FWS"
:
s_env
=
Env
.
FAT
;
s_env
=
Env
.
FAT
;
break
;
break
;
case
"UAT"
:
case
"UAT"
:
...
...
apollo-client/src/main/java/com/ctrip/apollo/internals/AbstractConfig.java
View file @
bb68324d
...
@@ -9,6 +9,7 @@ import com.ctrip.apollo.ConfigChangeListener;
...
@@ -9,6 +9,7 @@ import com.ctrip.apollo.ConfigChangeListener;
import
com.ctrip.apollo.enums.PropertyChangeType
;
import
com.ctrip.apollo.enums.PropertyChangeType
;
import
com.ctrip.apollo.model.ConfigChange
;
import
com.ctrip.apollo.model.ConfigChange
;
import
com.ctrip.apollo.model.ConfigChangeEvent
;
import
com.ctrip.apollo.model.ConfigChangeEvent
;
import
com.dianping.cat.Cat
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
...
@@ -36,6 +37,7 @@ public abstract class AbstractConfig implements Config {
...
@@ -36,6 +37,7 @@ public abstract class AbstractConfig implements Config {
try
{
try
{
listener
.
onChange
(
changeEvent
);
listener
.
onChange
(
changeEvent
);
}
catch
(
Throwable
ex
)
{
}
catch
(
Throwable
ex
)
{
Cat
.
logError
(
ex
);
logger
.
error
(
"Failed to invoke config change listener {}"
,
listener
.
getClass
(),
ex
);
logger
.
error
(
"Failed to invoke config change listener {}"
,
listener
.
getClass
(),
ex
);
}
}
}
}
...
...
apollo-client/src/main/java/com/ctrip/apollo/internals/AbstractConfigRepository.java
View file @
bb68324d
...
@@ -2,6 +2,8 @@ package com.ctrip.apollo.internals;
...
@@ -2,6 +2,8 @@ package com.ctrip.apollo.internals;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Lists
;
import
com.dianping.cat.Cat
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
...
@@ -19,6 +21,7 @@ public abstract class AbstractConfigRepository implements ConfigRepository {
...
@@ -19,6 +21,7 @@ public abstract class AbstractConfigRepository implements ConfigRepository {
try
{
try
{
sync
();
sync
();
}
catch
(
Throwable
ex
)
{
}
catch
(
Throwable
ex
)
{
Cat
.
logError
(
ex
);
logger
.
error
(
"Sync config failed with repository {}"
,
this
.
getClass
(),
ex
);
logger
.
error
(
"Sync config failed with repository {}"
,
this
.
getClass
(),
ex
);
}
}
}
}
...
@@ -42,6 +45,7 @@ public abstract class AbstractConfigRepository implements ConfigRepository {
...
@@ -42,6 +45,7 @@ public abstract class AbstractConfigRepository implements ConfigRepository {
try
{
try
{
listener
.
onRepositoryChange
(
namespace
,
newProperties
);
listener
.
onRepositoryChange
(
namespace
,
newProperties
);
}
catch
(
Throwable
ex
)
{
}
catch
(
Throwable
ex
)
{
Cat
.
logError
(
ex
);
logger
.
error
(
"Failed to invoke repository change listener {}"
,
listener
.
getClass
(),
ex
);
logger
.
error
(
"Failed to invoke repository change listener {}"
,
listener
.
getClass
(),
ex
);
}
}
}
}
...
...
apollo-client/src/main/java/com/ctrip/apollo/internals/ConfigServiceLocator.java
View file @
bb68324d
package
com
.
ctrip
.
apollo
.
internals
;
package
com
.
ctrip
.
apollo
.
internals
;
import
com.google.common.collect.Lists
;
import
com.google.gson.reflect.TypeToken
;
import
com.ctrip.apollo.core.dto.ServiceDTO
;
import
com.ctrip.apollo.core.dto.ServiceDTO
;
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
;
import
com.ctrip.apollo.util.http.HttpUtil
;
import
com.ctrip.apollo.util.http.HttpUtil
;
import
com.dianping.cat.Cat
;
import
com.dianping.cat.message.Message
;
import
com.dianping.cat.message.Transaction
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.unidal.lookup.annotation.Inject
;
import
org.unidal.lookup.annotation.Inject
;
import
org.unidal.lookup.annotation.Named
;
import
org.unidal.lookup.annotation.Named
;
import
java.
util.ArrayList
;
import
java.
lang.reflect.Type
;
import
java.util.List
;
import
java.util.List
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.atomic.AtomicReference
;
@Named
(
type
=
ConfigServiceLocator
.
class
)
@Named
(
type
=
ConfigServiceLocator
.
class
)
public
class
ConfigServiceLocator
{
public
class
ConfigServiceLocator
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
ConfigServiceLocator
.
class
);
@Inject
@Inject
private
HttpUtil
m_httpUtil
;
private
HttpUtil
m_httpUtil
;
@Inject
@Inject
private
ConfigUtil
m_configUtil
;
private
ConfigUtil
m_configUtil
;
private
List
<
ServiceDTO
>
serviceCaches
=
new
ArrayList
<>();
private
AtomicReference
<
List
<
ServiceDTO
>>
m_configServices
;
private
Type
m_responseType
;
public
ConfigServiceLocator
()
{
List
<
ServiceDTO
>
initial
=
Lists
.
newArrayList
();
m_configServices
=
new
AtomicReference
<>(
initial
);
m_responseType
=
new
TypeToken
<
List
<
ServiceDTO
>>()
{
}.
getType
();
}
/**
/**
* Get the config service info from remote meta server.
* Get the config service info from remote meta server.
*
* @return the services dto
* @return the services dto
*/
*/
public
List
<
ServiceDTO
>
getConfigServices
()
{
public
List
<
ServiceDTO
>
getConfigServices
()
{
if
(
m_configServices
.
get
().
isEmpty
())
{
updateConfigServices
();
}
return
m_configServices
.
get
();
}
//TODO periodically update config services
private
void
updateConfigServices
()
{
String
domainName
=
m_configUtil
.
getMetaServerDomainName
();
String
domainName
=
m_configUtil
.
getMetaServerDomainName
();
String
url
=
domainName
+
"/services/config"
;
String
url
=
domainName
+
"/services/config"
;
HttpRequest
request
=
new
HttpRequest
(
url
);
HttpRequest
request
=
new
HttpRequest
(
url
);
int
maxRetries
=
5
;
Throwable
exception
=
null
;
for
(
int
i
=
0
;
i
<
maxRetries
;
i
++)
{
Transaction
transaction
=
Cat
.
newTransaction
(
"Apollo.MetaService"
,
"getConfigService"
);
transaction
.
addData
(
"Url"
,
url
);
try
{
try
{
HttpResponse
<
ServiceDTO
[]>
response
=
m_httpUtil
.
doGet
(
request
,
ServiceDTO
[].
class
);
HttpResponse
<
List
<
ServiceDTO
>>
response
=
m_httpUtil
.
doGet
(
request
,
m_responseType
);
ServiceDTO
[]
services
=
response
.
getBody
();
m_configServices
.
set
(
response
.
getBody
());
if
(
services
!=
null
&&
services
.
length
>
0
)
{
Cat
.
logEvent
(
"Apollo.Config.Services"
,
response
.
getBody
().
toString
());
serviceCaches
.
clear
();
transaction
.
setStatus
(
Message
.
SUCCESS
);
for
(
ServiceDTO
service
:
services
)
{
return
;
serviceCaches
.
add
(
service
);
}
catch
(
Throwable
ex
)
{
Cat
.
logError
(
ex
);
transaction
.
setStatus
(
ex
);
exception
=
ex
;
}
finally
{
transaction
.
complete
();
}
}
try
{
TimeUnit
.
SECONDS
.
sleep
(
1
);
}
catch
(
InterruptedException
e
)
{
//ignore
}
}
}
catch
(
Throwable
ex
)
{
logger
.
error
(
"Get config services failed"
,
ex
);
throw
new
RuntimeException
(
"Get config services failed"
,
ex
);
}
}
return
serviceCaches
;
throw
new
RuntimeException
(
"Get config services failed"
,
exception
)
;
}
}
}
}
apollo-client/src/main/java/com/ctrip/apollo/internals/DefaultConfig.java
View file @
bb68324d
...
@@ -50,6 +50,7 @@ public class DefaultConfig extends AbstractConfig implements RepositoryChangeLis
...
@@ -50,6 +50,7 @@ public class DefaultConfig extends AbstractConfig implements RepositoryChangeLis
}
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
);
Cat
.
logError
(
ex
);
logger
.
error
(
message
,
ex
);
logger
.
error
(
message
,
ex
);
}
}
}
}
...
@@ -161,8 +162,8 @@ public class DefaultConfig extends AbstractConfig implements RepositoryChangeLis
...
@@ -161,8 +162,8 @@ public class DefaultConfig extends AbstractConfig implements RepositoryChangeLis
try
{
try
{
properties
.
load
(
in
);
properties
.
load
(
in
);
}
catch
(
IOException
ex
)
{
}
catch
(
IOException
ex
)
{
logger
.
error
(
"Load resource config for namespace {} failed"
,
namespace
,
ex
);
Cat
.
logError
(
ex
);
Cat
.
logError
(
ex
);
logger
.
error
(
"Load resource config for namespace {} failed"
,
namespace
,
ex
);
}
finally
{
}
finally
{
try
{
try
{
in
.
close
();
in
.
close
();
...
...
apollo-client/src/main/java/com/ctrip/apollo/internals/LocalFileConfigRepository.java
View file @
bb68324d
...
@@ -34,6 +34,7 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
...
@@ -34,6 +34,7 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
/**
/**
* Constructor.
* Constructor.
*
* @param baseDir the base dir for this local file config repository
* @param baseDir the base dir for this local file config repository
* @param namespace the namespace
* @param namespace the namespace
*/
*/
...
@@ -44,6 +45,7 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
...
@@ -44,6 +45,7 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
try
{
try
{
m_configUtil
=
m_container
.
lookup
(
ConfigUtil
.
class
);
m_configUtil
=
m_container
.
lookup
(
ConfigUtil
.
class
);
}
catch
(
ComponentLookupException
ex
)
{
}
catch
(
ComponentLookupException
ex
)
{
Cat
.
logError
(
ex
);
throw
new
IllegalStateException
(
"Unable to load component!"
,
ex
);
throw
new
IllegalStateException
(
"Unable to load component!"
,
ex
);
}
}
this
.
trySync
();
this
.
trySync
();
...
@@ -86,6 +88,7 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
...
@@ -86,6 +88,7 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
try
{
try
{
m_fileProperties
=
this
.
loadFromLocalCacheFile
(
m_baseDir
,
m_namespace
);
m_fileProperties
=
this
.
loadFromLocalCacheFile
(
m_baseDir
,
m_namespace
);
}
catch
(
Throwable
ex
)
{
}
catch
(
Throwable
ex
)
{
Cat
.
logError
(
ex
);
ex
.
printStackTrace
();
ex
.
printStackTrace
();
//ignore
//ignore
}
}
...
@@ -107,9 +110,8 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
...
@@ -107,9 +110,8 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
Properties
properties
=
m_fallback
.
getConfig
();
Properties
properties
=
m_fallback
.
getConfig
();
updateFileProperties
(
properties
);
updateFileProperties
(
properties
);
}
catch
(
Throwable
ex
)
{
}
catch
(
Throwable
ex
)
{
String
message
=
Cat
.
logError
(
ex
);
String
.
format
(
"Sync config from fallback repository %s failed"
,
m_fallback
.
getClass
());
logger
.
warn
(
"Sync config from fallback repository {} failed"
,
m_fallback
.
getClass
(),
ex
);
logger
.
warn
(
message
,
ex
);
}
}
}
}
...
@@ -136,9 +138,9 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
...
@@ -136,9 +138,9 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
properties
=
new
Properties
();
properties
=
new
Properties
();
properties
.
load
(
in
);
properties
.
load
(
in
);
}
catch
(
IOException
ex
)
{
}
catch
(
IOException
ex
)
{
logger
.
error
(
"Loading config from local cache file {} failed"
,
file
.
getAbsolutePath
(),
ex
);
Cat
.
logError
(
ex
);
Cat
.
logError
(
ex
);
throw
ex
;
throw
new
RuntimeException
(
String
.
format
(
"Loading config from local cache file %s failed"
,
file
.
getAbsolutePath
()),
ex
);
}
finally
{
}
finally
{
try
{
try
{
if
(
in
!=
null
)
{
if
(
in
!=
null
)
{
...
@@ -149,10 +151,8 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
...
@@ -149,10 +151,8 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
}
}
}
}
}
else
{
}
else
{
String
message
=
throw
new
RuntimeException
(
String
.
format
(
"Cannot read from local cache file %s"
,
file
.
getAbsolutePath
());
String
.
format
(
"Cannot read from local cache file %s"
,
file
.
getAbsolutePath
()));
logger
.
error
(
message
);
throw
new
RuntimeException
(
message
);
}
}
return
properties
;
return
properties
;
...
@@ -170,8 +170,8 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
...
@@ -170,8 +170,8 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
out
=
new
FileOutputStream
(
file
);
out
=
new
FileOutputStream
(
file
);
m_fileProperties
.
store
(
out
,
"Persisted by DefaultConfig"
);
m_fileProperties
.
store
(
out
,
"Persisted by DefaultConfig"
);
}
catch
(
IOException
ex
)
{
}
catch
(
IOException
ex
)
{
logger
.
error
(
"Persist local cache file {} failed"
,
file
.
getAbsolutePath
(),
ex
);
Cat
.
logError
(
ex
);
Cat
.
logError
(
ex
);
logger
.
error
(
"Persist local cache file {} failed"
,
file
.
getAbsolutePath
(),
ex
);
}
finally
{
}
finally
{
if
(
out
!=
null
)
{
if
(
out
!=
null
)
{
try
{
try
{
...
...
apollo-client/src/main/java/com/ctrip/apollo/internals/RemoteConfigRepository.java
View file @
bb68324d
...
@@ -10,6 +10,9 @@ import com.ctrip.apollo.util.ConfigUtil;
...
@@ -10,6 +10,9 @@ 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
;
import
com.ctrip.apollo.util.http.HttpUtil
;
import
com.ctrip.apollo.util.http.HttpUtil
;
import
com.dianping.cat.Cat
;
import
com.dianping.cat.message.Message
;
import
com.dianping.cat.message.Transaction
;
import
org.codehaus.plexus.PlexusContainer
;
import
org.codehaus.plexus.PlexusContainer
;
import
org.codehaus.plexus.component.repository.exception.ComponentLookupException
;
import
org.codehaus.plexus.component.repository.exception.ComponentLookupException
;
...
@@ -17,10 +20,12 @@ import org.slf4j.Logger;
...
@@ -17,10 +20,12 @@ import org.slf4j.Logger;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
import
org.unidal.lookup.ContainerLoader
;
import
org.unidal.lookup.ContainerLoader
;
import
java.util.Collections
;
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.Executors
;
import
java.util.concurrent.ScheduledExecutorService
;
import
java.util.concurrent.ScheduledExecutorService
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.atomic.AtomicReference
;
import
java.util.concurrent.atomic.AtomicReference
;
/**
/**
...
@@ -38,6 +43,7 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
...
@@ -38,6 +43,7 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
/**
/**
* Constructor.
* Constructor.
*
* @param namespace the namespace
* @param namespace the namespace
*/
*/
public
RemoteConfigRepository
(
String
namespace
)
{
public
RemoteConfigRepository
(
String
namespace
)
{
...
@@ -49,6 +55,7 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
...
@@ -49,6 +55,7 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
m_httpUtil
=
m_container
.
lookup
(
HttpUtil
.
class
);
m_httpUtil
=
m_container
.
lookup
(
HttpUtil
.
class
);
m_serviceLocator
=
m_container
.
lookup
(
ConfigServiceLocator
.
class
);
m_serviceLocator
=
m_container
.
lookup
(
ConfigServiceLocator
.
class
);
}
catch
(
ComponentLookupException
ex
)
{
}
catch
(
ComponentLookupException
ex
)
{
Cat
.
logError
(
ex
);
throw
new
IllegalStateException
(
"Unable to load component!"
,
ex
);
throw
new
IllegalStateException
(
"Unable to load component!"
,
ex
);
}
}
this
.
m_executorService
=
Executors
.
newScheduledThreadPool
(
1
,
this
.
m_executorService
=
Executors
.
newScheduledThreadPool
(
1
,
...
@@ -110,35 +117,65 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
...
@@ -110,35 +117,65 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
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
Cat
.
logEvent
(
"Apollo.Client.Config"
,
String
.
format
(
"%s-%s-%s"
,
appId
,
cluster
,
m_namespace
));
url
=
int
maxRetries
=
2
;
assembleUrl
(
getConfigServiceUrl
(),
appId
,
cluster
,
m_namespace
,
m_configCache
.
get
())
;
Throwable
exception
=
null
;
logger
.
info
(
"Loading config from {}"
,
url
);
List
<
ServiceDTO
>
configServices
=
getConfigServices
();
for
(
int
i
=
0
;
i
<
maxRetries
;
i
++)
{
List
<
ServiceDTO
>
randomConfigServices
=
Lists
.
newArrayList
(
configServices
);
Collections
.
shuffle
(
randomConfigServices
);
for
(
ServiceDTO
configService
:
randomConfigServices
)
{
String
url
=
assembleUrl
(
configService
.
getHomepageUrl
(),
appId
,
cluster
,
m_namespace
,
m_configCache
.
get
());
logger
.
debug
(
"Loading config from {}"
,
url
);
HttpRequest
request
=
new
HttpRequest
(
url
);
HttpRequest
request
=
new
HttpRequest
(
url
);
Transaction
transaction
=
Cat
.
newTransaction
(
"Apollo.ConfigService"
,
"queryConfig"
);
transaction
.
addData
(
"Url"
,
url
);
try
{
try
{
HttpResponse
<
ApolloConfig
>
response
=
m_httpUtil
.
doGet
(
request
,
ApolloConfig
.
class
);
HttpResponse
<
ApolloConfig
>
response
=
m_httpUtil
.
doGet
(
request
,
ApolloConfig
.
class
);
transaction
.
addData
(
"StatusCode"
,
response
.
getStatusCode
());
transaction
.
setStatus
(
Message
.
SUCCESS
);
if
(
response
.
getStatusCode
()
==
304
)
{
if
(
response
.
getStatusCode
()
==
304
)
{
logger
.
info
(
"Config server responds with 304 HTTP status code."
);
logger
.
debug
(
"Config server responds with 304 HTTP status code."
);
return
m_configCache
.
get
();
return
m_configCache
.
get
();
}
}
logger
.
debug
(
"Loaded config: {}"
,
response
.
getBody
());
logger
.
info
(
"Loaded config: {}"
,
response
.
getBody
());
return
response
.
getBody
();
return
response
.
getBody
();
}
catch
(
Throwable
ex
)
{
}
catch
(
Throwable
ex
)
{
String
message
=
Cat
.
logError
(
ex
);
String
.
format
(
"Load Apollo Config failed - appId: %s, cluster: %s, namespace: %s"
,
appId
,
transaction
.
setStatus
(
ex
);
cluster
,
m_namespace
);
exception
=
ex
;
logger
.
error
(
message
,
ex
);
}
finally
{
throw
new
RuntimeException
(
message
,
ex
);
transaction
.
complete
();
}
}
try
{
TimeUnit
.
SECONDS
.
sleep
(
1
);
}
catch
(
InterruptedException
e
)
{
//ignore
}
}
}
}
String
message
=
String
.
format
(
"Load Apollo Config failed - appId: %s, cluster: %s, namespace: %s, services: %s"
,
appId
,
cluster
,
m_namespace
,
configServices
);
logger
.
error
(
message
,
exception
);
throw
new
RuntimeException
(
message
,
exception
);
}
private
String
assembleUrl
(
String
uri
,
String
appId
,
String
cluster
,
String
namespace
,
private
String
assembleUrl
(
String
uri
,
String
appId
,
String
cluster
,
String
namespace
,
ApolloConfig
previousConfig
)
{
ApolloConfig
previousConfig
)
{
String
path
=
"
/
config/%s/%s"
;
String
path
=
"config/%s/%s"
;
List
<
String
>
params
=
Lists
.
newArrayList
(
appId
,
cluster
);
List
<
String
>
params
=
Lists
.
newArrayList
(
appId
,
cluster
);
if
(!
Strings
.
isNullOrEmpty
(
namespace
))
{
if
(!
Strings
.
isNullOrEmpty
(
namespace
))
{
...
@@ -151,14 +188,18 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
...
@@ -151,14 +188,18 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
}
}
String
pathExpanded
=
String
.
format
(
path
,
params
.
toArray
());
String
pathExpanded
=
String
.
format
(
path
,
params
.
toArray
());
if
(!
uri
.
endsWith
(
"/"
))
{
uri
+=
"/"
;
}
return
uri
+
pathExpanded
;
return
uri
+
pathExpanded
;
}
}
private
String
getConfigServiceUrl
()
{
private
List
<
ServiceDTO
>
getConfigServices
()
{
List
<
ServiceDTO
>
services
=
m_serviceLocator
.
getConfigServices
();
List
<
ServiceDTO
>
services
=
m_serviceLocator
.
getConfigServices
();
if
(
services
.
size
()
==
0
)
{
if
(
services
.
size
()
==
0
)
{
throw
new
RuntimeException
(
"No available config service"
);
throw
new
RuntimeException
(
"No available config service"
);
}
}
return
services
.
get
(
0
).
getHomepageUrl
();
return
services
;
}
}
}
}
apollo-client/src/main/java/com/ctrip/apollo/internals/SimpleConfig.java
View file @
bb68324d
...
@@ -5,6 +5,7 @@ import com.google.common.collect.Maps;
...
@@ -5,6 +5,7 @@ import com.google.common.collect.Maps;
import
com.ctrip.apollo.model.ConfigChange
;
import
com.ctrip.apollo.model.ConfigChange
;
import
com.ctrip.apollo.model.ConfigChangeEvent
;
import
com.ctrip.apollo.model.ConfigChangeEvent
;
import
com.dianping.cat.Cat
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
...
@@ -40,6 +41,7 @@ public class SimpleConfig extends AbstractConfig implements RepositoryChangeList
...
@@ -40,6 +41,7 @@ public class SimpleConfig extends AbstractConfig implements RepositoryChangeList
}
catch
(
Throwable
ex
)
{
}
catch
(
Throwable
ex
)
{
String
message
=
String
.
format
(
"Init Apollo Simple Config failed - namespace: %s"
,
String
message
=
String
.
format
(
"Init Apollo Simple Config failed - namespace: %s"
,
m_namespace
);
m_namespace
);
Cat
.
logError
(
message
,
ex
);
logger
.
error
(
message
,
ex
);
logger
.
error
(
message
,
ex
);
}
}
}
}
...
...
apollo-client/src/main/java/com/ctrip/apollo/spi/DefaultConfigFactory.java
View file @
bb68324d
...
@@ -5,12 +5,15 @@ import com.ctrip.apollo.core.utils.ClassLoaderUtil;
...
@@ -5,12 +5,15 @@ import com.ctrip.apollo.core.utils.ClassLoaderUtil;
import
com.ctrip.apollo.internals.DefaultConfig
;
import
com.ctrip.apollo.internals.DefaultConfig
;
import
com.ctrip.apollo.internals.LocalFileConfigRepository
;
import
com.ctrip.apollo.internals.LocalFileConfigRepository
;
import
com.ctrip.apollo.internals.RemoteConfigRepository
;
import
com.ctrip.apollo.internals.RemoteConfigRepository
;
import
com.dianping.cat.Cat
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
import
org.unidal.lookup.annotation.Named
;
import
org.unidal.lookup.annotation.Named
;
import
java.io.File
;
import
java.io.File
;
import
java.io.IOException
;
import
java.nio.file.Files
;
/**
/**
* @author Jason Song(song_s@ctrip.com)
* @author Jason Song(song_s@ctrip.com)
...
@@ -26,10 +29,18 @@ public class DefaultConfigFactory implements ConfigFactory {
...
@@ -26,10 +29,18 @@ public class DefaultConfigFactory implements ConfigFactory {
*/
*/
public
DefaultConfigFactory
()
{
public
DefaultConfigFactory
()
{
m_baseDir
=
new
File
(
ClassLoaderUtil
.
getClassPath
()
+
CONFIG_DIR
);
m_baseDir
=
new
File
(
ClassLoaderUtil
.
getClassPath
()
+
CONFIG_DIR
);
if
(!
m_baseDir
.
exists
())
{
this
.
checkLocalConfigCacheDir
(
m_baseDir
);
if
(!
m_baseDir
.
mkdir
()){
logger
.
error
(
"Creating local cache dir failed."
);
}
}
private
void
checkLocalConfigCacheDir
(
File
baseDir
)
{
if
(
baseDir
.
exists
())
{
return
;
}
try
{
Files
.
createDirectory
(
baseDir
.
toPath
());
}
catch
(
IOException
ex
)
{
Cat
.
logError
(
ex
);
logger
.
error
(
"Unable to create directory: "
+
baseDir
,
ex
);
}
}
}
}
...
...
apollo-client/src/main/java/com/ctrip/apollo/util/ConfigUtil.java
View file @
bb68324d
...
@@ -5,7 +5,7 @@ import com.google.common.base.Preconditions;
...
@@ -5,7 +5,7 @@ import com.google.common.base.Preconditions;
import
com.ctrip.apollo.core.ConfigConsts
;
import
com.ctrip.apollo.core.ConfigConsts
;
import
com.ctrip.apollo.core.MetaDomainConsts
;
import
com.ctrip.apollo.core.MetaDomainConsts
;
import
com.ctrip.apollo.core.enums.Env
;
import
com.ctrip.apollo.core.enums.Env
;
import
com.ctrip.apollo.env.
Apollo
;
import
com.ctrip.apollo.env.
ClientEnvironment
;
import
org.unidal.lookup.annotation.Named
;
import
org.unidal.lookup.annotation.Named
;
...
@@ -28,7 +28,7 @@ public class ConfigUtil {
...
@@ -28,7 +28,7 @@ public class ConfigUtil {
* @throws IllegalStateException if app id is not set
* @throws IllegalStateException if app id is not set
*/
*/
public
String
getAppId
()
{
public
String
getAppId
()
{
String
appId
=
Apollo
.
getAppId
();
String
appId
=
ClientEnvironment
.
getAppId
();
Preconditions
.
checkState
(
appId
!=
null
,
"app.id is not set"
);
Preconditions
.
checkState
(
appId
!=
null
,
"app.id is not set"
);
return
appId
;
return
appId
;
}
}
...
@@ -38,7 +38,7 @@ public class ConfigUtil {
...
@@ -38,7 +38,7 @@ public class ConfigUtil {
* @return the cluster name, or "default" if not specified
* @return the cluster name, or "default" if not specified
*/
*/
public
String
getCluster
()
{
public
String
getCluster
()
{
String
cluster
=
Apollo
.
getCluster
();
String
cluster
=
ClientEnvironment
.
getCluster
();
if
(
cluster
==
null
)
{
if
(
cluster
==
null
)
{
cluster
=
ConfigConsts
.
CLUSTER_NAME_DEFAULT
;
cluster
=
ConfigConsts
.
CLUSTER_NAME_DEFAULT
;
}
}
...
@@ -51,7 +51,7 @@ public class ConfigUtil {
...
@@ -51,7 +51,7 @@ public class ConfigUtil {
* @throws IllegalStateException if env is set
* @throws IllegalStateException if env is set
*/
*/
public
Env
getApolloEnv
()
{
public
Env
getApolloEnv
()
{
Env
env
=
Apollo
.
getEnv
();
Env
env
=
ClientEnvironment
.
getEnv
();
Preconditions
.
checkState
(
env
!=
null
,
"env is not set"
);
Preconditions
.
checkState
(
env
!=
null
,
"env is not set"
);
return
env
;
return
env
;
}
}
...
...
apollo-client/src/main/java/com/ctrip/apollo/util/http/HttpUtil.java
View file @
bb68324d
package
com
.
ctrip
.
apollo
.
util
.
http
;
package
com
.
ctrip
.
apollo
.
util
.
http
;
import
com.google.common.base.Charsets
;
import
com.google.common.base.Charsets
;
import
com.google.common.base.Function
;
import
com.google.gson.Gson
;
import
com.google.gson.Gson
;
import
com.ctrip.apollo.util.ConfigUtil
;
import
com.ctrip.apollo.util.ConfigUtil
;
...
@@ -11,6 +12,7 @@ import org.unidal.lookup.annotation.Named;
...
@@ -11,6 +12,7 @@ import org.unidal.lookup.annotation.Named;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStream
;
import
java.lang.reflect.Type
;
import
java.net.HttpURLConnection
;
import
java.net.HttpURLConnection
;
import
java.net.URL
;
import
java.net.URL
;
...
@@ -30,10 +32,43 @@ public class HttpUtil {
...
@@ -30,10 +32,43 @@ public class HttpUtil {
/**
/**
* Do get operation for the http request.
* Do get operation for the http request.
*
*
* @return the http response
* @param httpRequest the request
* @param responseType the response type
* @return the response
* @throws RuntimeException if any error happened or response code is neither 200 nor 304
* @throws RuntimeException if any error happened or response code is neither 200 nor 304
*/
*/
public
<
T
>
HttpResponse
<
T
>
doGet
(
HttpRequest
httpRequest
,
Class
<
T
>
responseType
)
{
public
<
T
>
HttpResponse
<
T
>
doGet
(
HttpRequest
httpRequest
,
final
Class
<
T
>
responseType
)
{
Function
<
String
,
T
>
convertResponse
=
new
Function
<
String
,
T
>()
{
@Override
public
T
apply
(
String
input
)
{
return
gson
.
fromJson
(
input
,
responseType
);
}
};
return
doGetWithSerializeFunction
(
httpRequest
,
convertResponse
);
}
/**
* Do get operation for the http request.
*
* @param httpRequest the request
* @param responseType the response type
* @return the response
* @throws RuntimeException if any error happened or response code is neither 200 nor 304
*/
public
<
T
>
HttpResponse
<
T
>
doGet
(
HttpRequest
httpRequest
,
final
Type
responseType
)
{
Function
<
String
,
T
>
convertResponse
=
new
Function
<
String
,
T
>()
{
@Override
public
T
apply
(
String
input
)
{
return
gson
.
fromJson
(
input
,
responseType
);
}
};
return
doGetWithSerializeFunction
(
httpRequest
,
convertResponse
);
}
private
<
T
>
HttpResponse
<
T
>
doGetWithSerializeFunction
(
HttpRequest
httpRequest
,
Function
<
String
,
T
>
serializeFunction
)
{
InputStream
is
=
null
;
InputStream
is
=
null
;
try
{
try
{
HttpURLConnection
conn
=
(
HttpURLConnection
)
new
URL
(
httpRequest
.
getUrl
()).
openConnection
();
HttpURLConnection
conn
=
(
HttpURLConnection
)
new
URL
(
httpRequest
.
getUrl
()).
openConnection
();
...
@@ -60,7 +95,7 @@ public class HttpUtil {
...
@@ -60,7 +95,7 @@ public class HttpUtil {
if
(
statusCode
==
200
)
{
if
(
statusCode
==
200
)
{
is
=
conn
.
getInputStream
();
is
=
conn
.
getInputStream
();
String
content
=
Files
.
IO
.
INSTANCE
.
readFrom
(
is
,
Charsets
.
UTF_8
.
name
());
String
content
=
Files
.
IO
.
INSTANCE
.
readFrom
(
is
,
Charsets
.
UTF_8
.
name
());
return
new
HttpResponse
<>(
statusCode
,
gson
.
fromJson
(
content
,
responseType
));
return
new
HttpResponse
<>(
statusCode
,
serializeFunction
.
apply
(
content
));
}
}
if
(
statusCode
==
304
)
{
if
(
statusCode
==
304
)
{
...
@@ -82,7 +117,6 @@ public class HttpUtil {
...
@@ -82,7 +117,6 @@ public class HttpUtil {
}
}
}
}
}
}
}
}
}
}
apollo-client/src/test/java/com/ctrip/apollo/integration/BaseIntegrationTest.java
View file @
bb68324d
...
@@ -23,7 +23,9 @@ import org.unidal.lookup.ComponentTestCase;
...
@@ -23,7 +23,9 @@ import org.unidal.lookup.ComponentTestCase;
import
java.io.File
;
import
java.io.File
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.net.ServerSocket
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
javax.servlet.ServletException
;
import
javax.servlet.ServletException
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletRequest
;
...
@@ -33,7 +35,7 @@ import javax.servlet.http.HttpServletResponse;
...
@@ -33,7 +35,7 @@ import javax.servlet.http.HttpServletResponse;
* @author Jason Song(song_s@ctrip.com)
* @author Jason Song(song_s@ctrip.com)
*/
*/
public
class
BaseIntegrationTest
extends
ComponentTestCase
{
public
class
BaseIntegrationTest
extends
ComponentTestCase
{
private
static
final
int
PORT
=
5678
;
private
static
final
int
PORT
=
findFreePort
()
;
private
static
final
String
metaServiceUrl
=
"http://localhost:"
+
PORT
;
private
static
final
String
metaServiceUrl
=
"http://localhost:"
+
PORT
;
private
static
final
String
someAppName
=
"someAppName"
;
private
static
final
String
someAppName
=
"someAppName"
;
private
static
final
String
someInstanceId
=
"someInstanceId"
;
private
static
final
String
someInstanceId
=
"someInstanceId"
;
...
@@ -86,23 +88,33 @@ public class BaseIntegrationTest extends ComponentTestCase {
...
@@ -86,23 +88,33 @@ public class BaseIntegrationTest extends ComponentTestCase {
@After
@After
public
void
tearDown
()
throws
Exception
{
public
void
tearDown
()
throws
Exception
{
super
.
tearDown
();
if
(
server
!=
null
&&
server
.
isStarted
())
{
if
(
server
!=
null
&&
server
.
isStarted
())
{
server
.
stop
();
server
.
stop
();
}
}
super
.
tearDown
();
}
protected
ContextHandler
mockMetaServerHandler
()
{
return
mockMetaServerHandler
(
false
);
}
}
pr
ivate
ContextHandler
mockMetaServerHandler
(
)
{
pr
otected
ContextHandler
mockMetaServerHandler
(
final
boolean
failedAtFirstTime
)
{
final
ServiceDTO
someServiceDTO
=
new
ServiceDTO
();
final
ServiceDTO
someServiceDTO
=
new
ServiceDTO
();
someServiceDTO
.
setAppName
(
someAppName
);
someServiceDTO
.
setAppName
(
someAppName
);
someServiceDTO
.
setInstanceId
(
someInstanceId
);
someServiceDTO
.
setInstanceId
(
someInstanceId
);
someServiceDTO
.
setHomepageUrl
(
configServiceURL
);
someServiceDTO
.
setHomepageUrl
(
configServiceURL
);
final
AtomicInteger
counter
=
new
AtomicInteger
(
0
);
ContextHandler
context
=
new
ContextHandler
(
"/services/config"
);
ContextHandler
context
=
new
ContextHandler
(
"/services/config"
);
context
.
setHandler
(
new
AbstractHandler
()
{
context
.
setHandler
(
new
AbstractHandler
()
{
@Override
@Override
public
void
handle
(
String
target
,
Request
baseRequest
,
HttpServletRequest
request
,
public
void
handle
(
String
target
,
Request
baseRequest
,
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
IOException
,
ServletException
{
HttpServletResponse
response
)
throws
IOException
,
ServletException
{
if
(
failedAtFirstTime
&&
counter
.
incrementAndGet
()
==
1
)
{
response
.
setStatus
(
HttpServletResponse
.
SC_INTERNAL_SERVER_ERROR
);
baseRequest
.
setHandled
(
true
);
return
;
}
response
.
setContentType
(
"application/json;charset=UTF-8"
);
response
.
setContentType
(
"application/json;charset=UTF-8"
);
response
.
setStatus
(
HttpServletResponse
.
SC_OK
);
response
.
setStatus
(
HttpServletResponse
.
SC_OK
);
...
@@ -150,4 +162,37 @@ public class BaseIntegrationTest extends ComponentTestCase {
...
@@ -150,4 +162,37 @@ public class BaseIntegrationTest extends ComponentTestCase {
}
}
}
}
/**
* Returns a free port number on localhost.
*
* Heavily inspired from org.eclipse.jdt.launching.SocketUtil (to avoid a dependency to JDT just because of this).
* Slightly improved with close() missing in JDT. And throws exception instead of returning -1.
*
* @return a free port number on localhost
* @throws IllegalStateException if unable to find a free port
*/
private
static
int
findFreePort
()
{
ServerSocket
socket
=
null
;
try
{
socket
=
new
ServerSocket
(
0
);
socket
.
setReuseAddress
(
true
);
int
port
=
socket
.
getLocalPort
();
try
{
socket
.
close
();
}
catch
(
IOException
e
)
{
// Ignore IOException on close()
}
return
port
;
}
catch
(
IOException
e
)
{
}
finally
{
if
(
socket
!=
null
)
{
try
{
socket
.
close
();
}
catch
(
IOException
e
)
{
}
}
}
throw
new
IllegalStateException
(
"Could not find a free TCP/IP port to start embedded Jetty HTTP Server on"
);
}
}
}
apollo-client/src/test/java/com/ctrip/apollo/integration/ConfigIntegrationTest.java
View file @
bb68324d
package
com
.
ctrip
.
apollo
.
integration
;
package
com
.
ctrip
.
apollo
.
integration
;
import
static
org
.
hamcrest
.
core
.
IsEqual
.
equalTo
;
import
com.google.common.collect.ImmutableMap
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
com.google.common.collect.Lists
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
com.google.common.collect.Maps
;
import
com.ctrip.apollo.Config
;
import
com.ctrip.apollo.ConfigChangeListener
;
import
com.ctrip.apollo.ConfigService
;
import
com.ctrip.apollo.core.ConfigConsts
;
import
com.ctrip.apollo.core.dto.ApolloConfig
;
import
com.ctrip.apollo.core.utils.ClassLoaderUtil
;
import
com.ctrip.apollo.model.ConfigChangeEvent
;
import
org.eclipse.jetty.server.Request
;
import
org.eclipse.jetty.server.handler.AbstractHandler
;
import
org.eclipse.jetty.server.handler.ContextHandler
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.Test
;
import
java.io.File
;
import
java.io.File
;
import
java.io.FileOutputStream
;
import
java.io.FileOutputStream
;
...
@@ -12,28 +27,15 @@ import java.util.List;
...
@@ -12,28 +27,15 @@ import java.util.List;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.Properties
;
import
java.util.Properties
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
javax.servlet.ServletException
;
import
javax.servlet.ServletException
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.servlet.http.HttpServletResponse
;
import
org.eclipse.jetty.server.Request
;
import
static
org
.
hamcrest
.
core
.
IsEqual
.
equalTo
;
import
org.eclipse.jetty.server.handler.AbstractHandler
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
org.eclipse.jetty.server.handler.ContextHandler
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.Test
;
import
com.ctrip.apollo.Config
;
import
com.ctrip.apollo.ConfigChangeListener
;
import
com.ctrip.apollo.ConfigService
;
import
com.ctrip.apollo.core.ConfigConsts
;
import
com.ctrip.apollo.core.dto.ApolloConfig
;
import
com.ctrip.apollo.core.utils.ClassLoaderUtil
;
import
com.ctrip.apollo.model.ConfigChangeEvent
;
import
com.google.common.collect.ImmutableMap
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Maps
;
/**
/**
* @author Jason Song(song_s@ctrip.com)
* @author Jason Song(song_s@ctrip.com)
...
@@ -142,6 +144,36 @@ public class ConfigIntegrationTest extends BaseIntegrationTest {
...
@@ -142,6 +144,36 @@ public class ConfigIntegrationTest extends BaseIntegrationTest {
}
}
@Test
@Test
public
void
testGetConfigWithNoLocalFileAndRemoteMetaServiceRetry
()
throws
Exception
{
String
someKey
=
"someKey"
;
String
someValue
=
"someValue"
;
ApolloConfig
apolloConfig
=
assembleApolloConfig
(
ImmutableMap
.
of
(
someKey
,
someValue
));
ContextHandler
configHandler
=
mockConfigServerHandler
(
HttpServletResponse
.
SC_OK
,
apolloConfig
);
boolean
failAtFirstTime
=
true
;
ContextHandler
metaServerHandler
=
mockMetaServerHandler
(
failAtFirstTime
);
startServerWithHandlers
(
metaServerHandler
,
configHandler
);
Config
config
=
ConfigService
.
getConfig
();
assertEquals
(
someValue
,
config
.
getProperty
(
someKey
,
null
));
}
@Test
public
void
testGetConfigWithNoLocalFileAndRemoteConfigServiceRetry
()
throws
Exception
{
String
someKey
=
"someKey"
;
String
someValue
=
"someValue"
;
ApolloConfig
apolloConfig
=
assembleApolloConfig
(
ImmutableMap
.
of
(
someKey
,
someValue
));
boolean
failedAtFirstTime
=
true
;
ContextHandler
handler
=
mockConfigServerHandler
(
HttpServletResponse
.
SC_OK
,
apolloConfig
,
failedAtFirstTime
);
startServerWithHandlers
(
handler
);
Config
config
=
ConfigService
.
getConfig
();
assertEquals
(
someValue
,
config
.
getProperty
(
someKey
,
null
));
}
@Test
public
void
testRefreshConfig
()
throws
Exception
{
public
void
testRefreshConfig
()
throws
Exception
{
final
String
someKey
=
"someKey"
;
final
String
someKey
=
"someKey"
;
final
String
someValue
=
"someValue"
;
final
String
someValue
=
"someValue"
;
...
@@ -183,12 +215,21 @@ public class ConfigIntegrationTest extends BaseIntegrationTest {
...
@@ -183,12 +215,21 @@ public class ConfigIntegrationTest extends BaseIntegrationTest {
assertEquals
(
anotherValue
,
config
.
getProperty
(
someKey
,
null
));
assertEquals
(
anotherValue
,
config
.
getProperty
(
someKey
,
null
));
}
}
private
ContextHandler
mockConfigServerHandler
(
final
int
statusCode
,
final
ApolloConfig
result
)
{
private
ContextHandler
mockConfigServerHandler
(
final
int
statusCode
,
final
ApolloConfig
result
,
final
boolean
failedAtFirstTime
)
{
ContextHandler
context
=
new
ContextHandler
(
"/config/*"
);
ContextHandler
context
=
new
ContextHandler
(
"/config/*"
);
context
.
setHandler
(
new
AbstractHandler
()
{
context
.
setHandler
(
new
AbstractHandler
()
{
AtomicInteger
counter
=
new
AtomicInteger
(
0
);
@Override
@Override
public
void
handle
(
String
target
,
Request
baseRequest
,
HttpServletRequest
request
,
public
void
handle
(
String
target
,
Request
baseRequest
,
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
IOException
,
ServletException
{
HttpServletResponse
response
)
throws
IOException
,
ServletException
{
if
(
failedAtFirstTime
&&
counter
.
incrementAndGet
()
==
1
)
{
response
.
setStatus
(
HttpServletResponse
.
SC_INTERNAL_SERVER_ERROR
);
baseRequest
.
setHandled
(
true
);
return
;
}
response
.
setContentType
(
"application/json;charset=UTF-8"
);
response
.
setContentType
(
"application/json;charset=UTF-8"
);
response
.
setStatus
(
statusCode
);
response
.
setStatus
(
statusCode
);
...
@@ -199,6 +240,12 @@ public class ConfigIntegrationTest extends BaseIntegrationTest {
...
@@ -199,6 +240,12 @@ public class ConfigIntegrationTest extends BaseIntegrationTest {
});
});
return
context
;
return
context
;
}
private
ContextHandler
mockConfigServerHandler
(
int
statusCode
,
ApolloConfig
result
)
{
return
mockConfigServerHandler
(
statusCode
,
result
,
false
);
}
}
private
ApolloConfig
assembleApolloConfig
(
Map
<
String
,
String
>
configurations
)
{
private
ApolloConfig
assembleApolloConfig
(
Map
<
String
,
String
>
configurations
)
{
...
...
apollo-core/src/main/java/com/ctrip/apollo/Apollo.java
0 → 100644
View file @
bb68324d
package
com
.
ctrip
.
apollo
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
class
Apollo
{
public
final
static
String
VERSION
=
"java-0.0.1-SNAPSHOT"
;
}
apollo-core/src/main/java/com/ctrip/apollo/core/dto/ServiceDTO.java
View file @
bb68324d
package
com
.
ctrip
.
apollo
.
core
.
dto
;
package
com
.
ctrip
.
apollo
.
core
.
dto
;
import
com.google.common.base.MoreObjects
;
public
class
ServiceDTO
{
public
class
ServiceDTO
{
private
String
appName
;
private
String
appName
;
...
@@ -31,4 +33,14 @@ public class ServiceDTO {
...
@@ -31,4 +33,14 @@ public class ServiceDTO {
public
void
setInstanceId
(
String
instanceId
)
{
public
void
setInstanceId
(
String
instanceId
)
{
this
.
instanceId
=
instanceId
;
this
.
instanceId
=
instanceId
;
}
}
@Override
public
String
toString
()
{
return
MoreObjects
.
toStringHelper
(
this
)
.
omitNullValues
()
.
add
(
"appName"
,
appName
)
.
add
(
"instanceId"
,
instanceId
)
.
add
(
"homepageUrl"
,
homepageUrl
)
.
toString
();
}
}
}
apollo-demo/src/main/java/ApolloConfigDemo.java
View file @
bb68324d
import
com.google.common.base.Strings
;
import
com.ctrip.apollo.Config
;
import
com.ctrip.apollo.Config
;
import
com.ctrip.apollo.ConfigChangeListener
;
import
com.ctrip.apollo.ConfigChangeListener
;
import
com.ctrip.apollo.ConfigService
;
import
com.ctrip.apollo.ConfigService
;
...
@@ -37,7 +39,7 @@ public class ApolloConfigDemo implements ConfigChangeListener {
...
@@ -37,7 +39,7 @@ public class ApolloConfigDemo implements ConfigChangeListener {
while
(
true
)
{
while
(
true
)
{
System
.
out
.
print
(
"> "
);
System
.
out
.
print
(
"> "
);
String
input
=
new
BufferedReader
(
new
InputStreamReader
(
System
.
in
)).
readLine
();
String
input
=
new
BufferedReader
(
new
InputStreamReader
(
System
.
in
)).
readLine
();
if
(
input
==
null
)
{
if
(
Strings
.
isNullOrEmpty
(
input
)
)
{
continue
;
continue
;
}
}
input
=
input
.
trim
();
input
=
input
.
trim
();
...
...
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