Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wrr-cat
apollo
提交
921a9b46
apollo
项目概览
wrr-cat
/
apollo
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
apollo
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
921a9b46
编写于
4月 28, 2016
作者:
Y
Yiming Liu
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #153 from nobodyiam/db-mq-merge
Use database as MQ, change separator to +
上级
39fb6a84
0be1e703
变更
32
隐藏空白更改
内联
并排
Showing
32 changed file
with
638 addition
and
311 deletion
+638
-311
apollo-adminservice/src/main/java/com/ctrip/apollo/adminservice/AdminServiceAutoConfiguration.java
...ip/apollo/adminservice/AdminServiceAutoConfiguration.java
+0
-56
apollo-adminservice/src/main/java/com/ctrip/apollo/adminservice/controller/ReleaseController.java
...rip/apollo/adminservice/controller/ReleaseController.java
+26
-19
apollo-adminservice/src/test/java/com/ctrip/apollo/AdminServiceTestConfiguration.java
.../java/com/ctrip/apollo/AdminServiceTestConfiguration.java
+2
-0
apollo-adminservice/src/test/java/com/ctrip/apollo/adminservice/controller/ReleaseControllerTest.java
...apollo/adminservice/controller/ReleaseControllerTest.java
+19
-15
apollo-adminservice/src/test/java/com/ctrip/apollo/adminservice/controller/TestWebSecurityConfig.java
...apollo/adminservice/controller/TestWebSecurityConfig.java
+4
-0
apollo-adminservice/src/test/resources/data.sql
apollo-adminservice/src/test/resources/data.sql
+7
-8
apollo-biz/pom.xml
apollo-biz/pom.xml
+0
-4
apollo-biz/src/main/java/com/ctrip/apollo/biz/entity/ReleaseMessage.java
...main/java/com/ctrip/apollo/biz/entity/ReleaseMessage.java
+58
-0
apollo-biz/src/main/java/com/ctrip/apollo/biz/message/DatabaseMessageSender.java
...a/com/ctrip/apollo/biz/message/DatabaseMessageSender.java
+46
-0
apollo-biz/src/main/java/com/ctrip/apollo/biz/message/DummyMessageSender.java
...java/com/ctrip/apollo/biz/message/DummyMessageSender.java
+0
-15
apollo-biz/src/main/java/com/ctrip/apollo/biz/message/ReleaseMessageScanner.java
...a/com/ctrip/apollo/biz/message/ReleaseMessageScanner.java
+145
-0
apollo-biz/src/main/java/com/ctrip/apollo/biz/repository/ReleaseMessageRepository.java
...ctrip/apollo/biz/repository/ReleaseMessageRepository.java
+16
-0
apollo-biz/src/test/java/com/ctrip/apollo/biz/AllTests.java
apollo-biz/src/test/java/com/ctrip/apollo/biz/AllTests.java
+3
-1
apollo-biz/src/test/java/com/ctrip/apollo/biz/message/DatabaseMessageSenderTest.java
...m/ctrip/apollo/biz/message/DatabaseMessageSenderTest.java
+55
-0
apollo-biz/src/test/java/com/ctrip/apollo/biz/message/RedisMessageSenderTest.java
.../com/ctrip/apollo/biz/message/RedisMessageSenderTest.java
+0
-49
apollo-biz/src/test/java/com/ctrip/apollo/biz/message/ReleaseMessageScannerTest.java
...m/ctrip/apollo/biz/message/ReleaseMessageScannerTest.java
+87
-0
apollo-client/src/main/java/com/ctrip/apollo/internals/AbstractConfigRepository.java
.../com/ctrip/apollo/internals/AbstractConfigRepository.java
+1
-1
apollo-client/src/main/java/com/ctrip/apollo/internals/LocalFileConfigRepository.java
...com/ctrip/apollo/internals/LocalFileConfigRepository.java
+6
-2
apollo-client/src/main/java/com/ctrip/apollo/internals/RemoteConfigRepository.java
...va/com/ctrip/apollo/internals/RemoteConfigRepository.java
+8
-6
apollo-client/src/test/java/com/ctrip/apollo/integration/ConfigIntegrationTest.java
...a/com/ctrip/apollo/integration/ConfigIntegrationTest.java
+3
-1
apollo-client/src/test/java/com/ctrip/apollo/internals/LocalFileConfigRepositoryTest.java
...ctrip/apollo/internals/LocalFileConfigRepositoryTest.java
+5
-3
apollo-configservice/src/main/java/com/ctrip/apollo/configservice/ConfigServiceAutoConfiguration.java
.../apollo/configservice/ConfigServiceAutoConfiguration.java
+11
-45
apollo-configservice/src/main/java/com/ctrip/apollo/configservice/controller/ConfigController.java
...rip/apollo/configservice/controller/ConfigController.java
+7
-6
apollo-configservice/src/main/java/com/ctrip/apollo/configservice/controller/NotificationController.java
...ollo/configservice/controller/NotificationController.java
+26
-15
apollo-configservice/src/test/java/com/ctrip/apollo/ConfigServiceTestConfiguration.java
...java/com/ctrip/apollo/ConfigServiceTestConfiguration.java
+3
-1
apollo-configservice/src/test/java/com/ctrip/apollo/configservice/controller/ConfigControllerTest.java
...apollo/configservice/controller/ConfigControllerTest.java
+3
-1
apollo-configservice/src/test/java/com/ctrip/apollo/configservice/controller/NotificationControllerTest.java
.../configservice/controller/NotificationControllerTest.java
+21
-15
apollo-configservice/src/test/java/com/ctrip/apollo/configservice/controller/TestWebSecurityConfig.java
...pollo/configservice/controller/TestWebSecurityConfig.java
+29
-0
apollo-configservice/src/test/java/com/ctrip/apollo/configservice/integration/ConfigControllerIntegrationTest.java
...gservice/integration/ConfigControllerIntegrationTest.java
+12
-7
apollo-configservice/src/test/java/com/ctrip/apollo/configservice/integration/NotificationControllerIntegrationTest.java
...ce/integration/NotificationControllerIntegrationTest.java
+31
-41
apollo-configservice/src/test/resources/application.properties
...o-configservice/src/test/resources/application.properties
+3
-0
apollo-core/src/main/java/com/ctrip/apollo/core/ConfigConsts.java
...ore/src/main/java/com/ctrip/apollo/core/ConfigConsts.java
+1
-0
未找到文件。
apollo-adminservice/src/main/java/com/ctrip/apollo/adminservice/AdminServiceAutoConfiguration.java
已删除
100644 → 0
浏览文件 @
39fb6a84
package
com.ctrip.apollo.adminservice
;
import
com.ctrip.apollo.biz.message.DummyMessageSender
;
import
com.ctrip.apollo.biz.message.MessageSender
;
import
com.ctrip.apollo.biz.message.RedisMessageSender
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.data.redis.connection.RedisConnectionFactory
;
import
org.springframework.data.redis.connection.jedis.JedisConnectionFactory
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.data.redis.core.StringRedisTemplate
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@Configuration
public
class
AdminServiceAutoConfiguration
{
@ConditionalOnProperty
(
value
=
"apollo.redis.enabled"
,
havingValue
=
"true"
,
matchIfMissing
=
false
)
public
static
class
AdminRedisConfiguration
{
@Value
(
"${apollo.redis.host}"
)
private
String
host
;
@Value
(
"${apollo.redis.port}"
)
private
int
port
;
@Bean
public
JedisConnectionFactory
redisConnectionFactory
()
{
JedisConnectionFactory
factory
=
new
JedisConnectionFactory
();
factory
.
setHostName
(
host
);
factory
.
setPort
(
port
);
return
factory
;
}
@Bean
public
RedisTemplate
<
String
,
String
>
redisTemplate
(
RedisConnectionFactory
factory
)
{
StringRedisTemplate
template
=
new
StringRedisTemplate
(
factory
);
return
template
;
}
@Bean
public
MessageSender
redisMessageSender
(
RedisTemplate
<
String
,
String
>
redisTemplate
)
{
return
new
RedisMessageSender
(
redisTemplate
);
}
}
@Configuration
@ConditionalOnProperty
(
value
=
"apollo.redis.enabled"
,
havingValue
=
"false"
,
matchIfMissing
=
true
)
public
static
class
ConfigDefaultConfiguration
{
@Bean
public
MessageSender
defaultMessageSender
()
{
return
new
DummyMessageSender
();
}
}
}
apollo-adminservice/src/main/java/com/ctrip/apollo/adminservice/controller/ReleaseController.java
浏览文件 @
921a9b46
package
com.ctrip.apollo.adminservice.controller
;
import
java.util.List
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.security.core.userdetails.UserDetails
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.RestController
;
import
com.google.common.base.Joiner
;
import
com.ctrip.apollo.biz.entity.Namespace
;
import
com.ctrip.apollo.biz.entity.Release
;
...
...
@@ -19,9 +11,20 @@ import com.ctrip.apollo.biz.service.NamespaceService;
import
com.ctrip.apollo.biz.service.ReleaseService
;
import
com.ctrip.apollo.common.auth.ActiveUser
;
import
com.ctrip.apollo.common.utils.BeanUtils
;
import
com.ctrip.apollo.core.ConfigConsts
;
import
com.ctrip.apollo.core.dto.ReleaseDTO
;
import
com.ctrip.apollo.core.exception.NotFoundException
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.security.core.userdetails.UserDetails
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.List
;
@RestController
public
class
ReleaseController
{
...
...
@@ -37,26 +40,29 @@ public class ReleaseController {
@Autowired
private
MessageSender
messageSender
;
private
static
final
Joiner
STRING_JOINER
=
Joiner
.
on
(
ConfigConsts
.
CLUSTER_NAMESPACE_SEPARATOR
);
@RequestMapping
(
"/release/{releaseId}"
)
public
ReleaseDTO
get
(
@PathVariable
(
"releaseId"
)
long
releaseId
)
{
Release
release
=
releaseService
.
findOne
(
releaseId
);
if
(
release
==
null
)
if
(
release
==
null
)
{
throw
new
NotFoundException
(
String
.
format
(
"release not found for %s"
,
releaseId
));
}
return
BeanUtils
.
transfrom
(
ReleaseDTO
.
class
,
release
);
}
@RequestMapping
(
"/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/releases"
)
public
List
<
ReleaseDTO
>
find
(
@PathVariable
(
"appId"
)
String
appId
,
@PathVariable
(
"clusterName"
)
String
clusterName
,
@PathVariable
(
"namespaceName"
)
String
namespaceName
)
{
@PathVariable
(
"clusterName"
)
String
clusterName
,
@PathVariable
(
"namespaceName"
)
String
namespaceName
)
{
List
<
Release
>
releases
=
releaseService
.
findReleases
(
appId
,
clusterName
,
namespaceName
);
return
BeanUtils
.
batchTransform
(
ReleaseDTO
.
class
,
releases
);
}
@RequestMapping
(
"/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/releases/latest"
)
public
ReleaseDTO
getLatest
(
@PathVariable
(
"appId"
)
String
appId
,
@PathVariable
(
"clusterName"
)
String
clusterName
,
@PathVariable
(
"namespaceName"
)
String
namespaceName
)
{
@PathVariable
(
"clusterName"
)
String
clusterName
,
@PathVariable
(
"namespaceName"
)
String
namespaceName
)
{
Release
release
=
configService
.
findRelease
(
appId
,
clusterName
,
namespaceName
);
if
(
release
==
null
)
{
throw
new
NotFoundException
(
String
.
format
(
"latest release not found for %s %s %s"
,
appId
,
...
...
@@ -68,10 +74,11 @@ public class ReleaseController {
@RequestMapping
(
path
=
"/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/releases"
,
method
=
RequestMethod
.
POST
)
public
ReleaseDTO
buildRelease
(
@PathVariable
(
"appId"
)
String
appId
,
@PathVariable
(
"clusterName"
)
String
clusterName
,
@PathVariable
(
"namespaceName"
)
String
namespaceName
,
@RequestParam
(
"name"
)
String
name
,
@RequestParam
(
name
=
"comment"
,
required
=
false
)
String
comment
,
@ActiveUser
UserDetails
user
)
{
@PathVariable
(
"clusterName"
)
String
clusterName
,
@PathVariable
(
"namespaceName"
)
String
namespaceName
,
@RequestParam
(
"name"
)
String
name
,
@RequestParam
(
name
=
"comment"
,
required
=
false
)
String
comment
,
@ActiveUser
UserDetails
user
)
{
Namespace
namespace
=
namespaceService
.
findOne
(
appId
,
clusterName
,
namespaceName
);
if
(
namespace
==
null
)
{
throw
new
NotFoundException
(
String
.
format
(
"Could not find namespace for %s %s %s"
,
appId
,
...
...
@@ -84,6 +91,6 @@ public class ReleaseController {
}
private
String
assembleKey
(
String
appId
,
String
cluster
,
String
namespace
)
{
return
S
tring
.
format
(
"%s-%s-%s"
,
appId
,
cluster
,
namespace
);
return
S
TRING_JOINER
.
join
(
appId
,
cluster
,
namespace
);
}
}
apollo-adminservice/src/test/java/com/ctrip/apollo/AdminServiceTestConfiguration.java
浏览文件 @
921a9b46
...
...
@@ -5,6 +5,8 @@ import org.springframework.context.annotation.ComponentScan;
import
org.springframework.context.annotation.ComponentScan.Filter
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.FilterType
;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;
import
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
;
@Configuration
@ComponentScan
(
excludeFilters
=
{
@Filter
(
type
=
FilterType
.
ASSIGNABLE_TYPE
,
value
=
{
...
...
apollo-adminservice/src/test/java/com/ctrip/apollo/adminservice/controller/ReleaseControllerTest.java
浏览文件 @
921a9b46
package
com.ctrip.apollo.adminservice.controller
;
import
java.util.HashMap
;
import
java.util.Map
;
import
com.google.common.base.Joiner
;
import
com.google.gson.Gson
;
import
com.ctrip.apollo.biz.entity.Namespace
;
import
com.ctrip.apollo.biz.message.MessageSender
;
import
com.ctrip.apollo.biz.message.Topics
;
import
com.ctrip.apollo.biz.repository.ReleaseRepository
;
import
com.ctrip.apollo.biz.service.NamespaceService
;
import
com.ctrip.apollo.biz.service.ReleaseService
;
import
com.ctrip.apollo.core.ConfigConsts
;
import
com.ctrip.apollo.core.dto.AppDTO
;
import
com.ctrip.apollo.core.dto.ClusterDTO
;
import
com.ctrip.apollo.core.dto.ItemDTO
;
import
com.ctrip.apollo.core.dto.NamespaceDTO
;
import
com.ctrip.apollo.core.dto.ReleaseDTO
;
import
org.junit.Assert
;
import
org.junit.Test
;
...
...
@@ -16,18 +29,8 @@ import org.springframework.test.util.ReflectionTestUtils;
import
org.springframework.util.LinkedMultiValueMap
;
import
org.springframework.util.MultiValueMap
;
import
com.ctrip.apollo.biz.entity.Namespace
;
import
com.ctrip.apollo.biz.message.MessageSender
;
import
com.ctrip.apollo.biz.message.Topics
;
import
com.ctrip.apollo.biz.repository.ReleaseRepository
;
import
com.ctrip.apollo.biz.service.NamespaceService
;
import
com.ctrip.apollo.biz.service.ReleaseService
;
import
com.ctrip.apollo.core.dto.AppDTO
;
import
com.ctrip.apollo.core.dto.ClusterDTO
;
import
com.ctrip.apollo.core.dto.ItemDTO
;
import
com.ctrip.apollo.core.dto.NamespaceDTO
;
import
com.ctrip.apollo.core.dto.ReleaseDTO
;
import
com.google.gson.Gson
;
import
java.util.HashMap
;
import
java.util.Map
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
times
;
...
...
@@ -119,7 +122,8 @@ public class ReleaseControllerTest extends AbstractControllerTest {
.
buildRelease
(
someAppId
,
someCluster
,
someNamespaceName
,
someName
,
someComment
,
someUser
);
verify
(
someMessageSender
,
times
(
1
))
.
sendMessage
(
String
.
format
(
"%s-%s-%s"
,
someAppId
,
someCluster
,
someNamespaceName
),
.
sendMessage
(
Joiner
.
on
(
ConfigConsts
.
CLUSTER_NAMESPACE_SEPARATOR
)
.
join
(
someAppId
,
someCluster
,
someNamespaceName
),
Topics
.
APOLLO_RELEASE_TOPIC
);
}
...
...
apollo-adminservice/src/test/java/com/ctrip/apollo/adminservice/controller/TestWebSecurityConfig.java
浏览文件 @
921a9b46
...
...
@@ -15,6 +15,10 @@ public class TestWebSecurityConfig extends WebSecurityConfigurerAdapter {
protected
void
configure
(
HttpSecurity
http
)
throws
Exception
{
http
.
httpBasic
();
http
.
csrf
().
disable
();
http
.
authorizeRequests
().
antMatchers
(
"/"
).
permitAll
().
and
()
.
authorizeRequests
().
antMatchers
(
"/console/**"
).
permitAll
();
http
.
headers
().
frameOptions
().
disable
();
}
@Autowired
...
...
apollo-adminservice/src/test/resources/data.sql
浏览文件 @
921a9b46
...
...
@@ -11,24 +11,23 @@ INSERT INTO Cluster (AppId, Name) VALUES ('100003173', 'default');
INSERT
INTO
Cluster
(
AppId
,
Name
)
VALUES
(
'100003173'
,
'cluster3'
);
INSERT
INTO
Cluster
(
AppId
,
Name
)
VALUES
(
'fxhermesproducer'
,
'default'
);
INSERT
INTO
AppNamespace
(
AppId
,
Name
)
VALUES
(
'100003171'
,
'
100003171
'
);
INSERT
INTO
AppNamespace
(
AppId
,
Name
)
VALUES
(
'100003171'
,
'
application
'
);
INSERT
INTO
AppNamespace
(
AppId
,
Name
)
VALUES
(
'100003171'
,
'fx.apollo.config'
);
INSERT
INTO
AppNamespace
(
AppId
,
Name
)
VALUES
(
'100003172'
,
'
100003172
'
);
INSERT
INTO
AppNamespace
(
AppId
,
Name
)
VALUES
(
'100003172'
,
'
application
'
);
INSERT
INTO
AppNamespace
(
AppId
,
Name
)
VALUES
(
'100003172'
,
'fx.apollo.admin'
);
INSERT
INTO
AppNamespace
(
AppId
,
Name
)
VALUES
(
'100003173'
,
'
100003173
'
);
INSERT
INTO
AppNamespace
(
AppId
,
Name
)
VALUES
(
'100003173'
,
'
application
'
);
INSERT
INTO
AppNamespace
(
AppId
,
Name
)
VALUES
(
'100003173'
,
'fx.apollo.portal'
);
INSERT
INTO
AppNamespace
(
AppID
,
Name
)
VALUES
(
'fxhermesproducer'
,
'fx.hermes.producer'
);
INSERT
INTO
Namespace
(
Id
,
AppId
,
ClusterName
,
NamespaceName
)
VALUES
(
1
,
'100003171'
,
'default'
,
'
100003171
'
);
INSERT
INTO
Namespace
(
Id
,
AppId
,
ClusterName
,
NamespaceName
)
VALUES
(
1
,
'100003171'
,
'default'
,
'
application
'
);
INSERT
INTO
Namespace
(
Id
,
AppId
,
ClusterName
,
NamespaceName
)
VALUES
(
2
,
'fxhermesproducer'
,
'default'
,
'fx.hermes.producer'
);
INSERT
INTO
Namespace
(
Id
,
AppId
,
ClusterName
,
NamespaceName
)
VALUES
(
3
,
'100003172'
,
'default'
,
'100003172'
);
INSERT
INTO
Namespace
(
Id
,
AppId
,
ClusterName
,
NamespaceName
)
VALUES
(
4
,
'100003173'
,
'default'
,
'100003173'
);
INSERT
INTO
Namespace
(
Id
,
AppId
,
ClusterName
,
NamespaceName
)
VALUES
(
5
,
'100003171'
,
'default'
,
'100003171'
);
INSERT
INTO
Namespace
(
Id
,
AppId
,
ClusterName
,
NamespaceName
)
VALUES
(
3
,
'100003172'
,
'default'
,
'application'
);
INSERT
INTO
Namespace
(
Id
,
AppId
,
ClusterName
,
NamespaceName
)
VALUES
(
4
,
'100003173'
,
'default'
,
'application'
);
INSERT
INTO
Item
(
NamespaceId
,
`Key`
,
Value
,
Comment
)
VALUES
(
1
,
'k1'
,
'v1'
,
'comment1'
);
INSERT
INTO
Item
(
NamespaceId
,
`Key`
,
Value
,
Comment
)
VALUES
(
1
,
'k2'
,
'v2'
,
'comment2'
);
INSERT
INTO
Item
(
NamespaceId
,
`Key`
,
Value
,
Comment
)
VALUES
(
2
,
'k3'
,
'v3'
,
'comment3'
);
INSERT
INTO
Item
(
NamespaceId
,
`Key`
,
Value
,
Comment
)
VALUES
(
5
,
'k3'
,
'v4'
,
'comment4'
);
INSERT
INTO
RELEASE
(
Name
,
Comment
,
AppId
,
ClusterName
,
NamespaceName
,
Configurations
)
VALUES
(
'REV1'
,
'First Release'
,
'100003171'
,
'default'
,
'
100003171
'
,
'{"k1":"v1"}'
);
INSERT
INTO
RELEASE
(
Name
,
Comment
,
AppId
,
ClusterName
,
NamespaceName
,
Configurations
)
VALUES
(
'REV1'
,
'First Release'
,
'100003171'
,
'default'
,
'
application
'
,
'{"k1":"v1"}'
);
apollo-biz/pom.xml
浏览文件 @
921a9b46
...
...
@@ -22,10 +22,6 @@
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-data-jpa
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-redis
</artifactId>
</dependency>
<dependency>
<groupId>
mysql
</groupId>
<artifactId>
mysql-connector-java
</artifactId>
...
...
apollo-biz/src/main/java/com/ctrip/apollo/biz/entity/ReleaseMessage.java
0 → 100644
浏览文件 @
921a9b46
package
com.ctrip.apollo.biz.entity
;
import
java.util.Date
;
import
javax.persistence.Column
;
import
javax.persistence.Entity
;
import
javax.persistence.GeneratedValue
;
import
javax.persistence.Id
;
import
javax.persistence.PrePersist
;
import
javax.persistence.Table
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@Entity
@Table
(
name
=
"ReleaseMessage"
)
public
class
ReleaseMessage
{
@Id
@GeneratedValue
@Column
(
name
=
"Id"
)
private
long
id
;
@Column
(
name
=
"Message"
,
nullable
=
false
)
private
String
message
;
@Column
(
name
=
"DataChange_LastTime"
)
private
Date
dataChangeLastModifiedTime
;
@PrePersist
protected
void
prePersist
()
{
if
(
this
.
dataChangeLastModifiedTime
==
null
)
{
dataChangeLastModifiedTime
=
new
Date
();
}
}
public
ReleaseMessage
()
{
}
public
ReleaseMessage
(
String
message
)
{
this
.
message
=
message
;
}
public
long
getId
()
{
return
id
;
}
public
void
setId
(
long
id
)
{
this
.
id
=
id
;
}
public
String
getMessage
()
{
return
message
;
}
public
void
setMessage
(
String
message
)
{
this
.
message
=
message
;
}
}
apollo-biz/src/main/java/com/ctrip/apollo/biz/message/
Redis
MessageSender.java
→
apollo-biz/src/main/java/com/ctrip/apollo/biz/message/
Database
MessageSender.java
浏览文件 @
921a9b46
package
com.ctrip.apollo.biz.message
;
import
com.ctrip.apollo.biz.entity.ReleaseMessage
;
import
com.ctrip.apollo.biz.repository.ReleaseMessageRepository
;
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.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
java.util.Objects
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
class
RedisMessageSender
implements
MessageSender
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
RedisMessageSender
.
class
);
private
RedisTemplate
<
String
,
String
>
redisTemplate
;
@Component
public
class
DatabaseMessageSender
implements
MessageSender
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
DatabaseMessageSender
.
class
)
;
public
RedisMessageSender
(
RedisTemplate
<
String
,
String
>
redisTemplate
)
{
this
.
redisTemplate
=
redisTemplate
;
}
@Autowired
private
ReleaseMessageRepository
releaseMessageRepository
;
@Override
public
void
sendMessage
(
String
message
,
String
channel
)
{
logger
.
info
(
"Sending message {} to channel {}"
,
message
,
channel
);
Transaction
transaction
=
Cat
.
newTransaction
(
"Apollo.AdminService"
,
"RedisMessageSender"
);
if
(!
Objects
.
equals
(
channel
,
Topics
.
APOLLO_RELEASE_TOPIC
))
{
logger
.
warn
(
"Channel {} not supported by DatabaseMessageSender!"
);
return
;
}
Cat
.
logEvent
(
"Apollo.AdminService.ReleaseMessage"
,
message
);
Transaction
transaction
=
Cat
.
newTransaction
(
"Apollo.AdminService"
,
"sendMessage"
);
try
{
re
disTemplate
.
convertAndSend
(
channel
,
message
);
re
leaseMessageRepository
.
save
(
new
ReleaseMessage
(
message
)
);
transaction
.
setStatus
(
Message
.
SUCCESS
);
}
catch
(
Throwable
ex
)
{
logger
.
error
(
"Sending message to
redis
failed"
,
ex
);
logger
.
error
(
"Sending message to
database
failed"
,
ex
);
transaction
.
setStatus
(
ex
);
}
finally
{
transaction
.
complete
();
...
...
apollo-biz/src/main/java/com/ctrip/apollo/biz/message/DummyMessageSender.java
已删除
100644 → 0
浏览文件 @
39fb6a84
package
com.ctrip.apollo.biz.message
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
class
DummyMessageSender
implements
MessageSender
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
DummyMessageSender
.
class
);
@Override
public
void
sendMessage
(
String
message
,
String
channel
)
{
logger
.
warn
(
"No message sender available! message: {}, channel: {}"
,
message
,
channel
);
}
}
apollo-biz/src/main/java/com/ctrip/apollo/biz/message/ReleaseMessageScanner.java
0 → 100644
浏览文件 @
921a9b46
package
com.ctrip.apollo.biz.message
;
import
com.google.common.collect.Lists
;
import
com.ctrip.apollo.biz.entity.ReleaseMessage
;
import
com.ctrip.apollo.biz.repository.ReleaseMessageRepository
;
import
com.ctrip.apollo.core.utils.ApolloThreadFactory
;
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.springframework.beans.factory.InitializingBean
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.core.env.Environment
;
import
org.springframework.util.CollectionUtils
;
import
java.util.List
;
import
java.util.Objects
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.ScheduledExecutorService
;
import
java.util.concurrent.TimeUnit
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
class
ReleaseMessageScanner
implements
InitializingBean
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
ReleaseMessageScanner
.
class
);
private
static
final
int
DEFAULT_SCAN_INTERVAL_IN_MS
=
1000
;
@Autowired
private
Environment
env
;
@Autowired
private
ReleaseMessageRepository
releaseMessageRepository
;
private
int
databaseScanInterval
;
private
List
<
MessageListener
>
listeners
;
private
ScheduledExecutorService
executorService
;
private
long
maxIdScanned
;
public
ReleaseMessageScanner
()
{
listeners
=
Lists
.
newLinkedList
();
executorService
=
Executors
.
newScheduledThreadPool
(
1
,
ApolloThreadFactory
.
create
(
"ReleaseMessageScanner"
,
true
));
}
@Override
public
void
afterPropertiesSet
()
throws
Exception
{
populateDataBaseInterval
();
maxIdScanned
=
loadLargestMessageId
();
executorService
.
scheduleWithFixedDelay
((
Runnable
)
()
->
{
Transaction
transaction
=
Cat
.
newTransaction
(
"Apollo.ReleaseMessageScanner"
,
"scanMessage"
);
try
{
scanMessages
();
transaction
.
setStatus
(
Message
.
SUCCESS
);
}
catch
(
Throwable
ex
)
{
transaction
.
setStatus
(
ex
);
logger
.
error
(
"Scan and send message failed"
,
ex
);
}
finally
{
transaction
.
complete
();
}
},
getDatabaseScanIntervalMs
(),
getDatabaseScanIntervalMs
(),
TimeUnit
.
MILLISECONDS
);
}
/**
* add message listeners for release message
* @param listener
*/
public
void
addMessageListener
(
MessageListener
listener
)
{
if
(!
listeners
.
contains
(
listener
))
{
listeners
.
add
(
listener
);
}
}
/**
* Scan messages, continue scanning until there is no more messages
*/
private
void
scanMessages
()
{
boolean
hasMoreMessages
=
true
;
while
(
hasMoreMessages
&&
!
Thread
.
currentThread
().
isInterrupted
())
{
hasMoreMessages
=
scanAndSendMessages
();
}
}
/**
* scan messages and send
*
* @return whether there are more messages
*/
private
boolean
scanAndSendMessages
()
{
//current batch is 500
List
<
ReleaseMessage
>
releaseMessages
=
releaseMessageRepository
.
findFirst500ByIdGreaterThanOrderByIdAsc
(
maxIdScanned
);
if
(
CollectionUtils
.
isEmpty
(
releaseMessages
))
{
return
false
;
}
fireMessageScanned
(
releaseMessages
);
int
messageScanned
=
releaseMessages
.
size
();
maxIdScanned
=
releaseMessages
.
get
(
messageScanned
-
1
).
getId
();
return
messageScanned
==
500
;
}
/**
* find largest message id as the current start point
* @return current largest message id
*/
private
long
loadLargestMessageId
()
{
ReleaseMessage
releaseMessage
=
releaseMessageRepository
.
findTopByOrderByIdDesc
();
return
releaseMessage
==
null
?
0
:
releaseMessage
.
getId
();
}
/**
* Notify listeners with messages loaded
* @param messages
*/
private
void
fireMessageScanned
(
List
<
ReleaseMessage
>
messages
)
{
for
(
ReleaseMessage
message
:
messages
)
{
for
(
MessageListener
listener
:
listeners
)
{
try
{
listener
.
handleMessage
(
message
.
getMessage
(),
Topics
.
APOLLO_RELEASE_TOPIC
);
}
catch
(
Throwable
ex
)
{
Cat
.
logError
(
ex
);
logger
.
error
(
"Failed to invoke message listener {}"
,
listener
.
getClass
(),
ex
);
}
}
}
}
private
void
populateDataBaseInterval
()
{
databaseScanInterval
=
DEFAULT_SCAN_INTERVAL_IN_MS
;
try
{
String
interval
=
env
.
getProperty
(
"apollo.message-scan.interval"
);
if
(!
Objects
.
isNull
(
interval
))
{
databaseScanInterval
=
Integer
.
parseInt
(
interval
);
}
}
catch
(
Throwable
ex
)
{
Cat
.
logError
(
ex
);
logger
.
error
(
"Load apollo message scan interval from system property failed"
,
ex
);
}
}
private
int
getDatabaseScanIntervalMs
()
{
return
databaseScanInterval
;
}
}
apollo-biz/src/main/java/com/ctrip/apollo/biz/repository/ReleaseMessageRepository.java
0 → 100644
浏览文件 @
921a9b46
package
com.ctrip.apollo.biz.repository
;
import
com.ctrip.apollo.biz.entity.ReleaseMessage
;
import
org.springframework.data.repository.PagingAndSortingRepository
;
import
java.util.List
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
interface
ReleaseMessageRepository
extends
PagingAndSortingRepository
<
ReleaseMessage
,
Long
>
{
List
<
ReleaseMessage
>
findFirst500ByIdGreaterThanOrderByIdAsc
(
Long
id
);
ReleaseMessage
findTopByOrderByIdDesc
();
}
apollo-biz/src/test/java/com/ctrip/apollo/biz/AllTests.java
浏览文件 @
921a9b46
package
com.ctrip.apollo.biz
;
import
com.ctrip.apollo.biz.message.DatabaseMessageSenderTest
;
import
com.ctrip.apollo.biz.repository.AppRepositoryTest
;
import
com.ctrip.apollo.biz.service.AdminServiceTest
;
import
com.ctrip.apollo.biz.service.AdminServiceTransactionTest
;
...
...
@@ -16,7 +17,8 @@ import org.junit.runners.Suite.SuiteClasses;
AdminServiceTest
.
class
,
ConfigServiceTest
.
class
,
PrivilegeServiceTest
.
class
,
AdminServiceTransactionTest
.
class
})
AdminServiceTransactionTest
.
class
,
DatabaseMessageSenderTest
.
class
})
public
class
AllTests
{
}
apollo-biz/src/test/java/com/ctrip/apollo/biz/message/DatabaseMessageSenderTest.java
0 → 100644
浏览文件 @
921a9b46
package
com.ctrip.apollo.biz.message
;
import
com.ctrip.apollo.biz.entity.ReleaseMessage
;
import
com.ctrip.apollo.biz.repository.ReleaseMessageRepository
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.mockito.ArgumentCaptor
;
import
org.mockito.Mock
;
import
org.mockito.runners.MockitoJUnitRunner
;
import
org.springframework.test.util.ReflectionTestUtils
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
mockito
.
Mockito
.
any
;
import
static
org
.
mockito
.
Mockito
.
never
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@RunWith
(
MockitoJUnitRunner
.
class
)
public
class
DatabaseMessageSenderTest
{
private
DatabaseMessageSender
messageSender
;
@Mock
private
ReleaseMessageRepository
releaseMessageRepository
;
@Before
public
void
setUp
()
throws
Exception
{
messageSender
=
new
DatabaseMessageSender
();
ReflectionTestUtils
.
setField
(
messageSender
,
"releaseMessageRepository"
,
releaseMessageRepository
);
}
@Test
public
void
testSendMessage
()
throws
Exception
{
String
someMessage
=
"some-message"
;
ArgumentCaptor
<
ReleaseMessage
>
captor
=
ArgumentCaptor
.
forClass
(
ReleaseMessage
.
class
);
messageSender
.
sendMessage
(
someMessage
,
Topics
.
APOLLO_RELEASE_TOPIC
);
verify
(
releaseMessageRepository
,
times
(
1
)).
save
(
captor
.
capture
());
assertEquals
(
someMessage
,
captor
.
getValue
().
getMessage
());
}
@Test
public
void
testSendUnsupportedMessage
()
throws
Exception
{
String
someMessage
=
"some-message"
;
String
someUnsupportedTopic
=
"some-invalid-topic"
;
messageSender
.
sendMessage
(
someMessage
,
someUnsupportedTopic
);
verify
(
releaseMessageRepository
,
never
()).
save
(
any
(
ReleaseMessage
.
class
));
}
}
apollo-biz/src/test/java/com/ctrip/apollo/biz/message/RedisMessageSenderTest.java
已删除
100644 → 0
浏览文件 @
39fb6a84
package
com.ctrip.apollo.biz.message
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.mockito.Mock
;
import
org.mockito.runners.MockitoJUnitRunner
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
static
org
.
mockito
.
Mockito
.
doThrow
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@RunWith
(
MockitoJUnitRunner
.
class
)
public
class
RedisMessageSenderTest
{
@Mock
private
RedisTemplate
<
String
,
String
>
redisTemplate
;
private
RedisMessageSender
redisMessageSender
;
@Before
public
void
setUp
()
throws
Exception
{
redisMessageSender
=
new
RedisMessageSender
(
redisTemplate
);
}
@Test
public
void
testSendMessage
()
throws
Exception
{
String
someMessage
=
"someMessage"
;
String
someChannel
=
"someChannel"
;
redisMessageSender
.
sendMessage
(
someMessage
,
someChannel
);
verify
(
redisTemplate
,
times
(
1
)).
convertAndSend
(
someChannel
,
someMessage
);
}
@Test
public
void
testSendMessageWithError
()
throws
Exception
{
String
someMessage
=
"someMessage"
;
String
someChannel
=
"someChannel"
;
doThrow
(
new
RuntimeException
()).
when
(
redisTemplate
).
convertAndSend
(
someChannel
,
someMessage
);
redisMessageSender
.
sendMessage
(
someMessage
,
someChannel
);
}
}
apollo-biz/src/test/java/com/ctrip/apollo/biz/message/ReleaseMessageScannerTest.java
0 → 100644
浏览文件 @
921a9b46
package
com.ctrip.apollo.biz.message
;
import
com.google.common.collect.Lists
;
import
com.google.common.util.concurrent.SettableFuture
;
import
com.ctrip.apollo.biz.entity.ReleaseMessage
;
import
com.ctrip.apollo.biz.repository.ReleaseMessageRepository
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.mockito.Mock
;
import
org.mockito.runners.MockitoJUnitRunner
;
import
org.springframework.core.env.Environment
;
import
org.springframework.test.util.ReflectionTestUtils
;
import
java.util.concurrent.TimeUnit
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
mockito
.
Mockito
.
when
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@RunWith
(
MockitoJUnitRunner
.
class
)
public
class
ReleaseMessageScannerTest
{
private
ReleaseMessageScanner
releaseMessageScanner
;
@Mock
private
ReleaseMessageRepository
releaseMessageRepository
;
@Mock
private
Environment
env
;
private
int
databaseScanInterval
;
@Before
public
void
setUp
()
throws
Exception
{
releaseMessageScanner
=
new
ReleaseMessageScanner
();
ReflectionTestUtils
.
setField
(
releaseMessageScanner
,
"releaseMessageRepository"
,
releaseMessageRepository
);
ReflectionTestUtils
.
setField
(
releaseMessageScanner
,
"env"
,
env
);
databaseScanInterval
=
100
;
//100 ms
when
(
env
.
getProperty
(
"apollo.message-scan.interval"
)).
thenReturn
(
String
.
valueOf
(
databaseScanInterval
));
releaseMessageScanner
.
afterPropertiesSet
();
}
@Test
public
void
testScanMessageAndNotifyMessageListener
()
throws
Exception
{
SettableFuture
<
String
>
someListenerFuture
=
SettableFuture
.
create
();
MessageListener
someListener
=
(
message
,
channel
)
->
someListenerFuture
.
set
(
message
);
releaseMessageScanner
.
addMessageListener
(
someListener
);
String
someMessage
=
"someMessage"
;
long
someId
=
100
;
ReleaseMessage
someReleaseMessage
=
assembleReleaseMessage
(
someId
,
someMessage
);
when
(
releaseMessageRepository
.
findFirst500ByIdGreaterThanOrderByIdAsc
(
0L
)).
thenReturn
(
Lists
.
newArrayList
(
someReleaseMessage
));
String
someListenerMessage
=
someListenerFuture
.
get
(
5000
,
TimeUnit
.
MILLISECONDS
);
assertEquals
(
someMessage
,
someListenerMessage
);
SettableFuture
<
String
>
anotherListenerFuture
=
SettableFuture
.
create
();
MessageListener
anotherListener
=
(
message
,
channel
)
->
anotherListenerFuture
.
set
(
message
);
releaseMessageScanner
.
addMessageListener
(
anotherListener
);
String
anotherMessage
=
"anotherMessage"
;
long
anotherId
=
someId
+
1
;
ReleaseMessage
anotherReleaseMessage
=
assembleReleaseMessage
(
anotherId
,
anotherMessage
);
when
(
releaseMessageRepository
.
findFirst500ByIdGreaterThanOrderByIdAsc
(
someId
)).
thenReturn
(
Lists
.
newArrayList
(
anotherReleaseMessage
));
String
anotherListenerMessage
=
anotherListenerFuture
.
get
(
5000
,
TimeUnit
.
MILLISECONDS
);
assertEquals
(
anotherMessage
,
anotherListenerMessage
);
}
private
ReleaseMessage
assembleReleaseMessage
(
long
id
,
String
message
)
{
ReleaseMessage
releaseMessage
=
new
ReleaseMessage
();
releaseMessage
.
setId
(
id
);
releaseMessage
.
setMessage
(
message
);
return
releaseMessage
;
}
}
apollo-client/src/main/java/com/ctrip/apollo/internals/AbstractConfigRepository.java
浏览文件 @
921a9b46
...
...
@@ -25,7 +25,7 @@ public abstract class AbstractConfigRepository implements ConfigRepository {
}
catch
(
Throwable
ex
)
{
Cat
.
logError
(
ex
);
logger
.
warn
(
"Sync config failed
with r
epository {}, reason: {}"
,
this
.
getClass
(),
ExceptionUtil
.
warn
(
"Sync config failed
, will retry. R
epository {}, reason: {}"
,
this
.
getClass
(),
ExceptionUtil
.
getDetailMessage
(
ex
));
}
return
false
;
...
...
apollo-client/src/main/java/com/ctrip/apollo/internals/LocalFileConfigRepository.java
浏览文件 @
921a9b46
package
com.ctrip.apollo.internals
;
import
com.google.common.base.Joiner
;
import
com.google.common.base.Preconditions
;
import
com.ctrip.apollo.core.ConfigConsts
;
import
com.ctrip.apollo.util.ConfigUtil
;
import
com.ctrip.apollo.util.ExceptionUtil
;
import
com.dianping.cat.Cat
;
...
...
@@ -202,8 +204,10 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
}
File
assembleLocalCacheFile
(
File
baseDir
,
String
namespace
)
{
String
fileName
=
String
.
format
(
"%s-%s-%s.properties"
,
m_configUtil
.
getAppId
(),
m_configUtil
.
getCluster
(),
namespace
);
String
fileName
=
String
.
format
(
"%s.properties"
,
Joiner
.
on
(
ConfigConsts
.
CLUSTER_NAMESPACE_SEPARATOR
)
.
join
(
m_configUtil
.
getAppId
(),
m_configUtil
.
getCluster
(),
namespace
));
return
new
File
(
baseDir
,
fileName
);
}
}
apollo-client/src/main/java/com/ctrip/apollo/internals/RemoteConfigRepository.java
浏览文件 @
921a9b46
...
...
@@ -7,6 +7,7 @@ import com.google.common.collect.Maps;
import
com.google.common.escape.Escaper
;
import
com.google.common.net.UrlEscapers
;
import
com.ctrip.apollo.core.ConfigConsts
;
import
com.ctrip.apollo.core.dto.ApolloConfig
;
import
com.ctrip.apollo.core.dto.ApolloConfigNotification
;
import
com.ctrip.apollo.core.dto.ServiceDTO
;
...
...
@@ -43,6 +44,8 @@ import java.util.concurrent.atomic.AtomicReference;
*/
public
class
RemoteConfigRepository
extends
AbstractConfigRepository
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
RemoteConfigRepository
.
class
);
private
static
final
Joiner
STRING_JOINER
=
Joiner
.
on
(
ConfigConsts
.
CLUSTER_NAMESPACE_SEPARATOR
);
private
static
final
Joiner
.
MapJoiner
MAP_JOINER
=
Joiner
.
on
(
"&"
).
withKeyValueSeparator
(
"="
);
private
PlexusContainer
m_container
;
private
final
ConfigServiceLocator
m_serviceLocator
;
private
final
HttpUtil
m_httpUtil
;
...
...
@@ -135,8 +138,7 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
String
appId
=
m_configUtil
.
getAppId
();
String
cluster
=
m_configUtil
.
getCluster
();
String
dataCenter
=
m_configUtil
.
getDataCenter
();
Cat
.
logEvent
(
"Apollo.Client.ConfigInfo"
,
String
.
format
(
"%s-%s-%s"
,
appId
,
cluster
,
m_namespace
));
Cat
.
logEvent
(
"Apollo.Client.ConfigInfo"
,
STRING_JOINER
.
join
(
appId
,
cluster
,
m_namespace
));
int
maxRetries
=
2
;
Throwable
exception
=
null
;
...
...
@@ -214,7 +216,7 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
String
pathExpanded
=
String
.
format
(
path
,
pathParams
.
toArray
());
if
(!
queryParams
.
isEmpty
())
{
pathExpanded
+=
"?"
+
Joiner
.
on
(
"&"
).
withKeyValueSeparator
(
"="
)
.
join
(
queryParams
);
pathExpanded
+=
"?"
+
MAP_JOINER
.
join
(
queryParams
);
}
if
(!
uri
.
endsWith
(
"/"
))
{
uri
+=
"/"
;
...
...
@@ -276,7 +278,7 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
transaction
.
addData
(
"StatusCode"
,
response
.
getStatusCode
());
transaction
.
setStatus
(
Message
.
SUCCESS
);
}
catch
(
Throwable
ex
)
{
logger
.
warn
(
"Long polling failed
for
appId: {}, cluster: {}, namespace: {}, reason: {}"
,
logger
.
warn
(
"Long polling failed
, will retry.
appId: {}, cluster: {}, namespace: {}, reason: {}"
,
appId
,
cluster
,
m_namespace
,
ExceptionUtil
.
getDetailMessage
(
ex
));
lastServiceDto
=
null
;
Cat
.
logError
(
ex
);
...
...
@@ -284,7 +286,7 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
transaction
.
setStatus
(
ex
);
}
try
{
TimeUnit
.
SECONDS
.
sleep
(
10
);
TimeUnit
.
SECONDS
.
sleep
(
5
);
}
catch
(
InterruptedException
ie
)
{
//ignore
}
...
...
@@ -314,7 +316,7 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
queryParams
.
put
(
"releaseId"
,
escaper
.
escape
(
previousConfig
.
getReleaseId
()));
}
String
params
=
Joiner
.
on
(
"&"
).
withKeyValueSeparator
(
"="
)
.
join
(
queryParams
);
String
params
=
MAP_JOINER
.
join
(
queryParams
);
if
(!
uri
.
endsWith
(
"/"
))
{
uri
+=
"/"
;
}
...
...
apollo-client/src/test/java/com/ctrip/apollo/integration/ConfigIntegrationTest.java
浏览文件 @
921a9b46
package
com.ctrip.apollo.integration
;
import
com.google.common.base.Joiner
;
import
com.google.common.collect.ImmutableMap
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Maps
;
...
...
@@ -350,6 +351,7 @@ public class ConfigIntegrationTest extends BaseIntegrationTest {
}
private
String
assembleLocalCacheFileName
()
{
return
String
.
format
(
"%s-%s-%s.properties"
,
someAppId
,
someClusterName
,
defaultNamespace
);
return
String
.
format
(
"%s.properties"
,
Joiner
.
on
(
ConfigConsts
.
CLUSTER_NAMESPACE_SEPARATOR
)
.
join
(
someAppId
,
someClusterName
,
defaultNamespace
));
}
}
apollo-client/src/test/java/com/ctrip/apollo/internals/LocalFileConfigRepositoryTest.java
浏览文件 @
921a9b46
package
com.ctrip.apollo.internals
;
import
com.google.common.base.Charsets
;
import
com.google.common.base.Joiner
;
import
com.google.common.io.Files
;
import
com.ctrip.apollo.core.ConfigConsts
;
import
com.ctrip.apollo.util.ConfigUtil
;
import
org.junit.After
;
...
...
@@ -73,8 +75,8 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase {
}
private
String
assembleLocalCacheFileName
()
{
return
String
.
format
(
"%s
-%s-%s.properties"
,
someAppId
,
someCluster
,
someNamespace
);
return
String
.
format
(
"%s
.properties"
,
Joiner
.
on
(
ConfigConsts
.
CLUSTER_NAMESPACE_SEPARATOR
)
.
join
(
someAppId
,
someCluster
,
someNamespace
)
);
}
...
...
@@ -144,7 +146,7 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase {
assertThat
(
"LocalFileConfigRepository should persist local cache files and return that afterwards"
,
someProperties
.
entrySet
(),
equalTo
(
anotherProperties
.
entrySet
()));
someProperties
.
entrySet
(),
equalTo
(
anotherProperties
.
entrySet
()));
}
...
...
apollo-configservice/src/main/java/com/ctrip/apollo/configservice/ConfigServiceAutoConfiguration.java
浏览文件 @
921a9b46
package
com.ctrip.apollo.configservice
;
import
com.ctrip.apollo.biz.message.
Topics
;
import
com.ctrip.apollo.biz.message.
ReleaseMessageScanner
;
import
com.ctrip.apollo.configservice.controller.NotificationController
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.data.redis.connection.RedisConnectionFactory
;
import
org.springframework.data.redis.connection.jedis.JedisConnectionFactory
;
import
org.springframework.data.redis.listener.ChannelTopic
;
import
org.springframework.data.redis.listener.RedisMessageListenerContainer
;
import
org.springframework.data.redis.listener.adapter.MessageListenerAdapter
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@Configuration
public
class
ConfigServiceAutoConfiguration
{
@ConditionalOnProperty
(
value
=
"apollo.redis.enabled"
,
havingValue
=
"true"
,
matchIfMissing
=
false
)
public
static
class
ConfigRedisConfiguration
{
@Value
(
"${apollo.redis.host}"
)
private
String
host
;
@Value
(
"${apollo.redis.port}"
)
private
int
port
;
@Bean
public
JedisConnectionFactory
redisConnectionFactory
()
{
JedisConnectionFactory
factory
=
new
JedisConnectionFactory
();
factory
.
setHostName
(
host
);
factory
.
setPort
(
port
);
return
factory
;
}
@Bean
public
RedisMessageListenerContainer
redisMessageListenerContainer
(
RedisConnectionFactory
factory
)
{
RedisMessageListenerContainer
container
=
new
RedisMessageListenerContainer
();
container
.
setConnectionFactory
(
factory
);
return
container
;
}
@Bean
public
ChannelTopic
apolloReleaseTopic
()
{
return
new
ChannelTopic
(
Topics
.
APOLLO_RELEASE_TOPIC
);
}
@Bean
public
MessageListenerAdapter
apolloMessageListener
(
RedisMessageListenerContainer
container
,
NotificationController
notification
,
ChannelTopic
topic
)
{
MessageListenerAdapter
adapter
=
new
MessageListenerAdapter
(
notification
);
container
.
addMessageListener
(
adapter
,
topic
);
return
adapter
;
}
@Autowired
private
NotificationController
notificationController
;
@Bean
public
ReleaseMessageScanner
releaseMessageScanner
()
{
ReleaseMessageScanner
releaseMessageScanner
=
new
ReleaseMessageScanner
();
releaseMessageScanner
.
addMessageListener
(
notificationController
);
return
releaseMessageScanner
;
}
}
apollo-configservice/src/main/java/com/ctrip/apollo/configservice/controller/ConfigController.java
浏览文件 @
921a9b46
...
...
@@ -42,10 +42,11 @@ public class ConfigController {
@Autowired
private
AppNamespaceService
appNamespaceService
;
private
Gson
gson
=
new
Gson
();
private
Type
configurationTypeReference
=
private
static
final
Gson
gson
=
new
Gson
();
private
static
final
Type
configurationTypeReference
=
new
TypeToken
<
Map
<
java
.
lang
.
String
,
java
.
lang
.
String
>>()
{
}.
getType
();
private
static
final
Joiner
STRING_JOINER
=
Joiner
.
on
(
ConfigConsts
.
CLUSTER_NAMESPACE_SEPARATOR
);
@RequestMapping
(
value
=
"/{appId}/{clusterName}"
,
method
=
RequestMethod
.
GET
)
public
ApolloConfig
queryConfig
(
@PathVariable
String
appId
,
@PathVariable
String
clusterName
,
...
...
@@ -89,7 +90,7 @@ public class ConfigController {
}
String
mergedReleaseId
=
FluentIterable
.
from
(
releases
).
transform
(
input
->
String
.
valueOf
(
input
.
getId
())).
join
(
Joiner
.
on
(
"|"
)
);
input
->
String
.
valueOf
(
input
.
getId
())).
join
(
STRING_JOINER
);
if
(
mergedReleaseId
.
equals
(
clientSideReleaseId
))
{
// Client side configuration is the same with server side, return 304
...
...
@@ -148,11 +149,11 @@ public class ConfigController {
}
private
String
assembleKey
(
String
appId
,
String
cluster
,
String
namespace
,
String
datacenter
)
{
String
key
=
String
.
format
(
"%s-%s-%s"
,
appId
,
cluster
,
namespace
);
List
<
String
>
keyParts
=
Lists
.
newArrayList
(
appId
,
cluster
,
namespace
);
if
(!
Strings
.
isNullOrEmpty
(
datacenter
))
{
key
+=
"-"
+
datacenter
;
key
Parts
.
add
(
datacenter
)
;
}
return
key
;
return
STRING_JOINER
.
join
(
keyParts
)
;
}
}
apollo-configservice/src/main/java/com/ctrip/apollo/configservice/controller/NotificationController.java
浏览文件 @
921a9b46
package
com.ctrip.apollo.configservice.controller
;
import
com.google.common.base.Joiner
;
import
com.google.common.base.Splitter
;
import
com.google.common.base.Strings
;
import
com.google.common.collect.HashMultimap
;
import
com.google.common.collect.Lists
;
...
...
@@ -29,8 +31,6 @@ import java.util.Collection;
import
java.util.List
;
import
java.util.Objects
;
import
javax.servlet.http.HttpServletResponse
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
...
...
@@ -40,8 +40,12 @@ public class NotificationController implements MessageListener {
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
NotificationController
.
class
);
private
static
final
long
TIMEOUT
=
360
*
60
*
1000
;
//6 hours
private
final
Multimap
<
String
,
DeferredResult
<
ResponseEntity
<
ApolloConfigNotification
>>>
deferredResults
=
Multimaps
.
synchronizedSetMultimap
(
HashMultimap
.
create
());
deferredResults
=
Multimaps
.
synchronizedSetMultimap
(
HashMultimap
.
create
());
private
static
final
ResponseEntity
<
ApolloConfigNotification
>
NOT_MODIFIED_RESPONSE
=
new
ResponseEntity
<>(
HttpStatus
.
NOT_MODIFIED
);
private
static
final
Joiner
STRING_JOINER
=
Joiner
.
on
(
ConfigConsts
.
CLUSTER_NAMESPACE_SEPARATOR
);
private
static
final
Splitter
STRING_SPLITTER
=
Splitter
.
on
(
ConfigConsts
.
CLUSTER_NAMESPACE_SEPARATOR
);
@Autowired
private
AppNamespaceService
appNamespaceService
;
...
...
@@ -52,8 +56,7 @@ public class NotificationController implements MessageListener {
@RequestParam
(
value
=
"cluster"
)
String
cluster
,
@RequestParam
(
value
=
"namespace"
,
defaultValue
=
ConfigConsts
.
NAMESPACE_DEFAULT
)
String
namespace
,
@RequestParam
(
value
=
"dataCenter"
,
required
=
false
)
String
dataCenter
,
@RequestParam
(
value
=
"releaseId"
,
defaultValue
=
"-1"
)
String
clientSideReleaseId
,
HttpServletResponse
response
)
{
@RequestParam
(
value
=
"releaseId"
,
defaultValue
=
"-1"
)
String
clientSideReleaseId
)
{
List
<
String
>
watchedKeys
=
Lists
.
newArrayList
(
assembleKey
(
appId
,
cluster
,
namespace
));
//Listen on more namespaces, since it's not the default namespace
...
...
@@ -61,30 +64,32 @@ public class NotificationController implements MessageListener {
watchedKeys
.
addAll
(
this
.
findPublicConfigWatchKey
(
appId
,
namespace
,
dataCenter
));
}
ResponseEntity
<
ApolloConfigNotification
>
body
=
new
ResponseEntity
<>(
HttpStatus
.
NOT_MODIFIED
);
DeferredResult
<
ResponseEntity
<
ApolloConfigNotification
>>
deferredResult
=
new
DeferredResult
<>(
TIMEOUT
,
body
);
new
DeferredResult
<>(
TIMEOUT
,
NOT_MODIFIED_RESPONSE
);
//register all keys
for
(
String
key
:
watchedKeys
)
{
this
.
deferredResults
.
put
(
key
,
deferredResult
);
}
deferredResult
.
onTimeout
(()
->
logWatchedKeysToCat
(
watchedKeys
,
"Apollo.LongPoll.TimeOutKeys"
));
deferredResult
.
onCompletion
(()
->
{
//unregister all keys
for
(
String
key
:
watchedKeys
)
{
deferredResults
.
remove
(
key
,
deferredResult
);
}
logWatchedKeysToCat
(
watchedKeys
,
"Apollo.LongPoll.CompletedKeys"
);
});
logWatchedKeysToCat
(
watchedKeys
,
"Apollo.LongPoll.RegisteredKeys"
);
logger
.
info
(
"Listening {} from appId: {}, cluster: {}, namespace: {}, datacenter: {}"
,
watchedKeys
,
appId
,
cluster
,
namespace
,
dataCenter
);
return
deferredResult
;
}
private
String
assembleKey
(
String
appId
,
String
cluster
,
String
namespace
)
{
return
S
tring
.
format
(
"%s-%s-%s"
,
appId
,
cluster
,
namespace
);
return
S
TRING_JOINER
.
join
(
appId
,
cluster
,
namespace
);
}
private
List
<
String
>
findPublicConfigWatchKey
(
String
applicationId
,
String
namespace
,
...
...
@@ -114,20 +119,20 @@ public class NotificationController implements MessageListener {
@Override
public
void
handleMessage
(
String
message
,
String
channel
)
{
logger
.
info
(
"message received - channel: {}, message: {}"
,
channel
,
message
);
Cat
.
logEvent
(
"Apollo.LongPoll.Message"
,
message
);
Cat
.
logEvent
(
"Apollo.LongPoll.Message
s
"
,
message
);
if
(!
Topics
.
APOLLO_RELEASE_TOPIC
.
equals
(
channel
)
||
Strings
.
isNullOrEmpty
(
message
))
{
return
;
}
String
[]
keys
=
message
.
split
(
"-"
);
//message should be appId
-cluster-
namespace
if
(
keys
.
length
!=
3
)
{
List
<
String
>
keys
=
STRING_SPLITTER
.
splitToList
(
message
);
//message should be appId
|cluster|
namespace
if
(
keys
.
size
()
!=
3
)
{
logger
.
error
(
"message format invalid - {}"
,
message
);
return
;
}
ResponseEntity
<
ApolloConfigNotification
>
notification
=
new
ResponseEntity
<>(
new
ApolloConfigNotification
(
keys
[
2
]
),
HttpStatus
.
OK
);
new
ApolloConfigNotification
(
keys
.
get
(
2
)
),
HttpStatus
.
OK
);
Collection
<
DeferredResult
<
ResponseEntity
<
ApolloConfigNotification
>>>
results
=
deferredResults
.
get
(
message
);
...
...
@@ -137,5 +142,11 @@ public class NotificationController implements MessageListener {
result
.
setResult
(
notification
);
}
}
private
void
logWatchedKeysToCat
(
List
<
String
>
watchedKeys
,
String
eventName
)
{
for
(
String
watchedKey
:
watchedKeys
)
{
Cat
.
logEvent
(
eventName
,
watchedKey
);
}
}
}
apollo-configservice/src/test/java/com/ctrip/apollo/ConfigServiceTestConfiguration.java
浏览文件 @
921a9b46
package
com.ctrip.apollo
;
import
com.ctrip.apollo.common.controller.WebSecurityConfig
;
import
org.springframework.boot.autoconfigure.EnableAutoConfiguration
;
import
org.springframework.context.annotation.ComponentScan
;
import
org.springframework.context.annotation.ComponentScan.Filter
;
...
...
@@ -8,7 +10,7 @@ import org.springframework.context.annotation.FilterType;
@Configuration
@ComponentScan
(
excludeFilters
=
{
@Filter
(
type
=
FilterType
.
ASSIGNABLE_TYPE
,
value
=
{
SampleConfigServiceApplication
.
class
,
ConfigServiceApplication
.
class
})})
SampleConfigServiceApplication
.
class
,
ConfigServiceApplication
.
class
,
WebSecurityConfig
.
class
})})
@EnableAutoConfiguration
public
class
ConfigServiceTestConfiguration
{
...
...
apollo-configservice/src/test/java/com/ctrip/apollo/configservice/controller/ConfigControllerTest.java
浏览文件 @
921a9b46
package
com.ctrip.apollo.configservice.controller
;
import
com.google.common.base.Joiner
;
import
com.google.common.collect.ImmutableMap
;
import
com.google.common.collect.Lists
;
import
com.google.gson.Gson
;
...
...
@@ -243,7 +244,8 @@ public class ConfigControllerTest {
.
queryConfig
(
someAppId
,
someClusterName
,
somePublicNamespaceName
,
someDataCenter
,
someAppSideReleaseId
,
someResponse
);
assertEquals
(
String
.
format
(
"%s|%s"
,
someAppSideReleaseId
,
somePublicAppSideReleaseId
),
assertEquals
(
Joiner
.
on
(
ConfigConsts
.
CLUSTER_NAMESPACE_SEPARATOR
)
.
join
(
someAppSideReleaseId
,
somePublicAppSideReleaseId
),
result
.
getReleaseId
());
assertEquals
(
someAppId
,
result
.
getAppId
());
assertEquals
(
someClusterName
,
result
.
getCluster
());
...
...
apollo-configservice/src/test/java/com/ctrip/apollo/configservice/controller/NotificationControllerTest.java
浏览文件 @
921a9b46
package
com.ctrip.apollo.configservice.controller
;
import
com.google.common.base.Joiner
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Multimap
;
...
...
@@ -40,8 +41,6 @@ public class NotificationControllerTest {
private
String
someDataCenter
;
private
String
someReleaseId
;
@Mock
private
HttpServletResponse
response
;
@Mock
private
AppNamespaceService
appNamespaceService
;
private
Multimap
<
String
,
DeferredResult
<
ResponseEntity
<
ApolloConfigNotification
>>>
deferredResults
;
...
...
@@ -67,10 +66,11 @@ public class NotificationControllerTest {
public
void
testPollNotificationWithDefaultNamespace
()
throws
Exception
{
DeferredResult
<
ResponseEntity
<
ApolloConfigNotification
>>
deferredResult
=
controller
.
pollNotification
(
someAppId
,
someCluster
,
defaultNamespace
,
someDataCenter
,
someReleaseId
,
response
);
.
pollNotification
(
someAppId
,
someCluster
,
defaultNamespace
,
someDataCenter
,
someReleaseId
);
String
key
=
String
.
format
(
"%s-%s-%s"
,
someAppId
,
someCluster
,
defaultNamespace
);
String
key
=
Joiner
.
on
(
ConfigConsts
.
CLUSTER_NAMESPACE_SEPARATOR
)
.
join
(
someAppId
,
someCluster
,
defaultNamespace
);
assertEquals
(
1
,
deferredResults
.
size
());
assertTrue
(
deferredResults
.
get
(
key
).
contains
(
deferredResult
));
}
...
...
@@ -87,18 +87,21 @@ public class NotificationControllerTest {
DeferredResult
<
ResponseEntity
<
ApolloConfigNotification
>>
deferredResult
=
controller
.
pollNotification
(
someAppId
,
someCluster
,
somePublicNamespace
,
someDataCenter
,
someReleaseId
,
response
);
someReleaseId
);
List
<
String
>
publicClusters
=
Lists
.
newArrayList
(
someDataCenter
,
ConfigConsts
.
CLUSTER_NAME_DEFAULT
);
assertEquals
(
3
,
deferredResults
.
size
());
String
key
=
String
.
format
(
"%s-%s-%s"
,
someAppId
,
someCluster
,
somePublicNamespace
);
String
key
=
Joiner
.
on
(
ConfigConsts
.
CLUSTER_NAMESPACE_SEPARATOR
)
.
join
(
someAppId
,
someCluster
,
somePublicNamespace
);
assertTrue
(
deferredResults
.
get
(
key
).
contains
(
deferredResult
));
for
(
String
cluster
:
publicClusters
)
{
String
publicKey
=
String
.
format
(
"%s-%s-%s"
,
somePublicAppId
,
cluster
,
somePublicNamespace
);
String
publicKey
=
Joiner
.
on
(
ConfigConsts
.
CLUSTER_NAMESPACE_SEPARATOR
)
.
join
(
somePublicAppId
,
cluster
,
somePublicNamespace
);
assertTrue
(
deferredResults
.
get
(
publicKey
).
contains
(
deferredResult
));
}
}
...
...
@@ -107,10 +110,11 @@ public class NotificationControllerTest {
public
void
testPollNotificationWithDefaultNamespaceAndHandleMessage
()
throws
Exception
{
DeferredResult
<
ResponseEntity
<
ApolloConfigNotification
>>
deferredResult
=
controller
.
pollNotification
(
someAppId
,
someCluster
,
defaultNamespace
,
someDataCenter
,
someReleaseId
,
response
);
.
pollNotification
(
someAppId
,
someCluster
,
defaultNamespace
,
someDataCenter
,
someReleaseId
);
String
key
=
String
.
format
(
"%s-%s-%s"
,
someAppId
,
someCluster
,
defaultNamespace
);
String
key
=
Joiner
.
on
(
ConfigConsts
.
CLUSTER_NAMESPACE_SEPARATOR
)
.
join
(
someAppId
,
someCluster
,
defaultNamespace
);
controller
.
handleMessage
(
key
,
Topics
.
APOLLO_RELEASE_TOPIC
);
...
...
@@ -133,10 +137,12 @@ public class NotificationControllerTest {
DeferredResult
<
ResponseEntity
<
ApolloConfigNotification
>>
deferredResult
=
controller
.
pollNotification
(
someAppId
,
someCluster
,
somePublicNamespace
,
someDataCenter
,
someReleaseId
,
response
);
.
pollNotification
(
someAppId
,
someCluster
,
somePublicNamespace
,
someDataCenter
,
someReleaseId
);
String
key
=
String
.
format
(
"%s-%s-%s"
,
somePublicAppId
,
someDataCenter
,
somePublicNamespace
);
String
key
=
Joiner
.
on
(
ConfigConsts
.
CLUSTER_NAMESPACE_SEPARATOR
)
.
join
(
somePublicAppId
,
someDataCenter
,
somePublicNamespace
);
controller
.
handleMessage
(
key
,
Topics
.
APOLLO_RELEASE_TOPIC
);
...
...
apollo-configservice/src/test/java/com/ctrip/apollo/configservice/controller/TestWebSecurityConfig.java
0 → 100644
浏览文件 @
921a9b46
package
com.ctrip.apollo.configservice.controller
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.core.annotation.Order
;
import
org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;
import
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
;
@Configuration
@Order
(
99
)
public
class
TestWebSecurityConfig
extends
WebSecurityConfigurerAdapter
{
@Override
protected
void
configure
(
HttpSecurity
http
)
throws
Exception
{
http
.
httpBasic
();
http
.
csrf
().
disable
();
http
.
authorizeRequests
().
antMatchers
(
"/"
).
permitAll
().
and
()
.
authorizeRequests
().
antMatchers
(
"/console/**"
).
permitAll
();
http
.
headers
().
frameOptions
().
disable
();
}
@Autowired
public
void
configureGlobal
(
AuthenticationManagerBuilder
auth
)
throws
Exception
{
auth
.
inMemoryAuthentication
().
withUser
(
"user"
).
password
(
""
).
roles
(
"USER"
);
auth
.
inMemoryAuthentication
().
withUser
(
"apollo"
).
password
(
""
).
roles
(
"USER"
,
"ADMIN"
);
}
}
apollo-configservice/src/test/java/com/ctrip/apollo/configservice/integration/ConfigControllerIntegrationTest.java
浏览文件 @
921a9b46
...
...
@@ -83,7 +83,8 @@ public class ConfigControllerIntegrationTest extends AbstractBaseIntegrationTest
public
void
testQueryConfigNotModified
()
throws
Exception
{
String
releaseId
=
String
.
valueOf
(
991
);
ResponseEntity
<
ApolloConfig
>
response
=
restTemplate
.
getForEntity
(
"{baseurl}/configs/{appId}/{clusterName}/{namespace}?releaseId={releaseId}"
,
ApolloConfig
.
class
,
.
getForEntity
(
"{baseurl}/configs/{appId}/{clusterName}/{namespace}?releaseId={releaseId}"
,
ApolloConfig
.
class
,
getHostUrl
(),
someAppId
,
someCluster
,
someNamespace
,
releaseId
);
assertEquals
(
HttpStatus
.
NOT_MODIFIED
,
response
.
getStatusCode
());
...
...
@@ -94,7 +95,8 @@ public class ConfigControllerIntegrationTest extends AbstractBaseIntegrationTest
@Sql
(
scripts
=
"/integration-test/cleanup.sql"
,
executionPhase
=
Sql
.
ExecutionPhase
.
AFTER_TEST_METHOD
)
public
void
testQueryPublicConfigWithDataCenterFoundAndNoOverride
()
throws
Exception
{
ResponseEntity
<
ApolloConfig
>
response
=
restTemplate
.
getForEntity
(
"{baseurl}/configs/{appId}/{clusterName}/{namespace}?dataCenter={dateCenter}"
,
ApolloConfig
.
class
,
.
getForEntity
(
"{baseurl}/configs/{appId}/{clusterName}/{namespace}?dataCenter={dateCenter}"
,
ApolloConfig
.
class
,
getHostUrl
(),
someAppId
,
someCluster
,
somePublicNamespace
,
someDC
);
ApolloConfig
result
=
response
.
getBody
();
...
...
@@ -111,11 +113,12 @@ public class ConfigControllerIntegrationTest extends AbstractBaseIntegrationTest
@Sql
(
scripts
=
"/integration-test/cleanup.sql"
,
executionPhase
=
Sql
.
ExecutionPhase
.
AFTER_TEST_METHOD
)
public
void
testQueryPublicConfigWithDataCenterFoundAndOverride
()
throws
Exception
{
ResponseEntity
<
ApolloConfig
>
response
=
restTemplate
.
getForEntity
(
"{baseurl}/configs/{appId}/{clusterName}/{namespace}?dataCenter={dateCenter}"
,
ApolloConfig
.
class
,
.
getForEntity
(
"{baseurl}/configs/{appId}/{clusterName}/{namespace}?dataCenter={dateCenter}"
,
ApolloConfig
.
class
,
getHostUrl
(),
someAppId
,
someDefaultCluster
,
somePublicNamespace
,
someDC
);
ApolloConfig
result
=
response
.
getBody
();
assertEquals
(
"994
|
993"
,
result
.
getReleaseId
());
assertEquals
(
"994
"
+
ConfigConsts
.
CLUSTER_NAMESPACE_SEPARATOR
+
"
993"
,
result
.
getReleaseId
());
assertEquals
(
someAppId
,
result
.
getAppId
());
assertEquals
(
someDefaultCluster
,
result
.
getCluster
());
assertEquals
(
somePublicNamespace
,
result
.
getNamespace
());
...
...
@@ -129,7 +132,8 @@ public class ConfigControllerIntegrationTest extends AbstractBaseIntegrationTest
public
void
testQueryPublicConfigWithDataCenterNotFoundAndNoOverride
()
throws
Exception
{
String
someDCNotFound
=
"someDCNotFound"
;
ResponseEntity
<
ApolloConfig
>
response
=
restTemplate
.
getForEntity
(
"{baseurl}/configs/{appId}/{clusterName}/{namespace}?dataCenter={dateCenter}"
,
ApolloConfig
.
class
,
.
getForEntity
(
"{baseurl}/configs/{appId}/{clusterName}/{namespace}?dataCenter={dateCenter}"
,
ApolloConfig
.
class
,
getHostUrl
(),
someAppId
,
someCluster
,
somePublicNamespace
,
someDCNotFound
);
ApolloConfig
result
=
response
.
getBody
();
...
...
@@ -147,11 +151,12 @@ public class ConfigControllerIntegrationTest extends AbstractBaseIntegrationTest
public
void
testQueryPublicConfigWithDataCenterNotFoundAndOverride
()
throws
Exception
{
String
someDCNotFound
=
"someDCNotFound"
;
ResponseEntity
<
ApolloConfig
>
response
=
restTemplate
.
getForEntity
(
"{baseurl}/configs/{appId}/{clusterName}/{namespace}?dataCenter={dateCenter}"
,
ApolloConfig
.
class
,
.
getForEntity
(
"{baseurl}/configs/{appId}/{clusterName}/{namespace}?dataCenter={dateCenter}"
,
ApolloConfig
.
class
,
getHostUrl
(),
someAppId
,
someDefaultCluster
,
somePublicNamespace
,
someDCNotFound
);
ApolloConfig
result
=
response
.
getBody
();
assertEquals
(
"994
|
992"
,
result
.
getReleaseId
());
assertEquals
(
"994
"
+
ConfigConsts
.
CLUSTER_NAMESPACE_SEPARATOR
+
"
992"
,
result
.
getReleaseId
());
assertEquals
(
someAppId
,
result
.
getAppId
());
assertEquals
(
someDefaultCluster
,
result
.
getCluster
());
assertEquals
(
somePublicNamespace
,
result
.
getNamespace
());
...
...
apollo-configservice/src/test/java/com/ctrip/apollo/configservice/integration/NotificationControllerIntegrationTest.java
浏览文件 @
921a9b46
package
com.ctrip.apollo.configservice.integration
;
import
com.ctrip.apollo.biz.message.Topics
;
import
com.google.common.base.Joiner
;
import
com.ctrip.apollo.biz.entity.ReleaseMessage
;
import
com.ctrip.apollo.biz.repository.ReleaseMessageRepository
;
import
com.ctrip.apollo.configservice.controller.NotificationController
;
import
com.ctrip.apollo.core.ConfigConsts
;
import
com.ctrip.apollo.core.dto.ApolloConfigNotification
;
...
...
@@ -14,7 +17,6 @@ import org.springframework.test.context.jdbc.Sql;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.Future
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.atomic.AtomicBoolean
;
...
...
@@ -26,6 +28,8 @@ import static org.junit.Assert.assertEquals;
public
class
NotificationControllerIntegrationTest
extends
AbstractBaseIntegrationTest
{
@Autowired
private
NotificationController
notificationController
;
@Autowired
private
ReleaseMessageRepository
releaseMessageRepository
;
private
String
someAppId
;
private
String
someCluster
;
private
String
defaultNamespace
;
...
...
@@ -43,20 +47,16 @@ public class NotificationControllerIntegrationTest extends AbstractBaseIntegrati
@Test
public
void
testPollNotificationWithDefaultNamespace
()
throws
Exception
{
Future
<
ResponseEntity
<
ApolloConfigNotification
>>
future
=
executorService
.
submit
(()
->
restTemplate
.
getForEntity
(
"{baseurl}/notifications?appId={appId}&cluster={clusterName}&namespace={namespace}"
,
ApolloConfigNotification
.
class
,
getHostUrl
(),
someAppId
,
someCluster
,
defaultNamespace
));
AtomicBoolean
stop
=
new
AtomicBoolean
();
perodicSendMessage
(
assembleKey
(
someAppId
,
someCluster
,
defaultNamespace
),
stop
);
//wait for the request connected to server
TimeUnit
.
MILLISECONDS
.
sleep
(
500
);
ResponseEntity
<
ApolloConfigNotification
>
result
=
restTemplate
.
getForEntity
(
"{baseurl}/notifications?appId={appId}&cluster={clusterName}&namespace={namespace}"
,
ApolloConfigNotification
.
class
,
getHostUrl
(),
someAppId
,
someCluster
,
defaultNamespace
);
notificationController
.
handleMessage
(
assembleKey
(
someAppId
,
someCluster
,
defaultNamespace
),
Topics
.
APOLLO_RELEASE_TOPIC
);
stop
.
set
(
true
);
ResponseEntity
<
ApolloConfigNotification
>
result
=
future
.
get
(
500
,
TimeUnit
.
MILLISECONDS
);
ApolloConfigNotification
notification
=
result
.
getBody
();
assertEquals
(
HttpStatus
.
OK
,
result
.
getStatusCode
());
assertEquals
(
defaultNamespace
,
notification
.
getNamespace
());
...
...
@@ -69,19 +69,7 @@ public class NotificationControllerIntegrationTest extends AbstractBaseIntegrati
String
publicAppId
=
"somePublicAppId"
;
AtomicBoolean
stop
=
new
AtomicBoolean
();
executorService
.
submit
((
Runnable
)
()
->
{
//wait for the request connected to server
while
(!
stop
.
get
()
&&
!
Thread
.
currentThread
().
isInterrupted
())
{
try
{
TimeUnit
.
MILLISECONDS
.
sleep
(
100
);
}
catch
(
InterruptedException
e
)
{
}
notificationController
.
handleMessage
(
assembleKey
(
publicAppId
,
ConfigConsts
.
CLUSTER_NAME_DEFAULT
,
somePublicNamespace
),
Topics
.
APOLLO_RELEASE_TOPIC
);
}
});
perodicSendMessage
(
assembleKey
(
publicAppId
,
ConfigConsts
.
CLUSTER_NAME_DEFAULT
,
somePublicNamespace
),
stop
);
ResponseEntity
<
ApolloConfigNotification
>
result
=
restTemplate
.
getForEntity
(
...
...
@@ -104,19 +92,7 @@ public class NotificationControllerIntegrationTest extends AbstractBaseIntegrati
String
someDC
=
"someDC"
;
AtomicBoolean
stop
=
new
AtomicBoolean
();
executorService
.
submit
((
Runnable
)
()
->
{
//wait for the request connected to server
while
(!
stop
.
get
()
&&
!
Thread
.
currentThread
().
isInterrupted
())
{
try
{
TimeUnit
.
MILLISECONDS
.
sleep
(
100
);
}
catch
(
InterruptedException
e
)
{
}
notificationController
.
handleMessage
(
assembleKey
(
publicAppId
,
someDC
,
somePublicNamespace
),
Topics
.
APOLLO_RELEASE_TOPIC
);
}
});
perodicSendMessage
(
assembleKey
(
publicAppId
,
someDC
,
somePublicNamespace
),
stop
);
ResponseEntity
<
ApolloConfigNotification
>
result
=
restTemplate
.
getForEntity
(
...
...
@@ -131,8 +107,22 @@ public class NotificationControllerIntegrationTest extends AbstractBaseIntegrati
assertEquals
(
somePublicNamespace
,
notification
.
getNamespace
());
}
private
String
assembleKey
(
String
appId
,
String
cluster
,
String
namespace
)
{
return
String
.
format
(
"%s-%s-%s"
,
appId
,
cluster
,
namespace
);
return
Joiner
.
on
(
ConfigConsts
.
CLUSTER_NAMESPACE_SEPARATOR
).
join
(
appId
,
cluster
,
namespace
);
}
private
void
perodicSendMessage
(
String
message
,
AtomicBoolean
stop
)
{
executorService
.
submit
((
Runnable
)
()
->
{
//wait for the request connected to server
while
(!
stop
.
get
()
&&
!
Thread
.
currentThread
().
isInterrupted
())
{
try
{
TimeUnit
.
MILLISECONDS
.
sleep
(
100
);
}
catch
(
InterruptedException
e
)
{
}
ReleaseMessage
releaseMessage
=
new
ReleaseMessage
(
message
);
releaseMessageRepository
.
save
(
releaseMessage
);
}
});
}
}
apollo-configservice/src/test/resources/application.properties
浏览文件 @
921a9b46
...
...
@@ -3,3 +3,6 @@ spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy
spring.h2.console.enabled
=
true
spring.h2.console.settings.web-allow-others
=
true
spring.jpa.properties.hibernate.show_sql
=
true
# for ReleaseMessageScanner test
apollo.message-scan.interval
=
100
apollo-core/src/main/java/com/ctrip/apollo/core/ConfigConsts.java
浏览文件 @
921a9b46
...
...
@@ -3,4 +3,5 @@ package com.ctrip.apollo.core;
public
interface
ConfigConsts
{
String
NAMESPACE_DEFAULT
=
"application"
;
String
CLUSTER_NAME_DEFAULT
=
"default"
;
String
CLUSTER_NAMESPACE_SEPARATOR
=
"+"
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录