Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
apache
pulsar
提交
bd5a6222
pulsar
项目概览
apache
/
pulsar
通知
129
Star
40
Fork
3
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Wiki
1
Wiki
分析
仓库
DevOps
项目成员
Pages
pulsar
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Pages
分析
分析
仓库分析
DevOps
Wiki
1
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
提交
体验新版 GitCode,发现更多精彩内容 >>
提交
bd5a6222
编写于
4月 13, 2017
作者:
R
Rajan
提交者:
Matteo Merli
4月 13, 2017
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
register listener on dynamic-config zpath even if deserialization fail on service startup (#351)
上级
fc109317
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
72 addition
and
34 deletion
+72
-34
pulsar-broker/src/main/java/com/yahoo/pulsar/broker/service/BrokerService.java
...n/java/com/yahoo/pulsar/broker/service/BrokerService.java
+36
-34
pulsar-broker/src/test/java/com/yahoo/pulsar/broker/admin/AdminApiTest.java
...test/java/com/yahoo/pulsar/broker/admin/AdminApiTest.java
+36
-0
未找到文件。
pulsar-broker/src/main/java/com/yahoo/pulsar/broker/service/BrokerService.java
浏览文件 @
bd5a6222
...
...
@@ -960,6 +960,7 @@ public class BrokerService implements Closeable, ZooKeeperCacheListener<Policies
}
private
void
updateDynamicServiceConfiguration
()
{
try
{
// create dynamic-config znode if not present
if
(
pulsar
.
getZkClient
().
exists
(
BROKER_SERVICE_CONFIGURATION_PATH
,
false
)
==
null
)
{
...
...
@@ -973,52 +974,53 @@ public class BrokerService implements Closeable, ZooKeeperCacheListener<Policies
}
Optional
<
Map
<
String
,
String
>>
data
=
dynamicConfigurationCache
.
get
(
BROKER_SERVICE_CONFIGURATION_PATH
);
if
(
data
.
isPresent
()
&&
data
.
get
()
!=
null
)
{
data
.
get
().
forEach
((
key
,
value
)
->
{
data
.
get
().
forEach
((
key
,
value
)
->
{
try
{
Field
field
=
ServiceConfiguration
.
class
.
getDeclaredField
(
key
);
if
(
field
!=
null
&&
field
.
isAnnotationPresent
(
FieldContext
.
class
))
{
field
.
setAccessible
(
true
);
field
.
set
(
pulsar
().
getConfiguration
(),
FieldParser
.
value
(
value
,
field
));
field
.
set
(
pulsar
().
getConfiguration
(),
FieldParser
.
value
(
value
,
field
));
log
.
info
(
"Successfully updated {}/{}"
,
key
,
value
);
}
}
catch
(
Exception
e
)
{
log
.
warn
(
"Failed to update service configuration {}/{}, {}"
,
key
,
value
,
e
.
getMessage
());
}
log
.
warn
(
"Failed to update service configuration {}/{}, {}"
,
key
,
value
,
e
.
getMessage
());
}
});
}
// register a listener: it updates field value and triggers appropriate registered field-listener only if
// field's value has been changed so, registered doesn't have to update field value in ServiceConfiguration
dynamicConfigurationCache
.
registerListener
(
new
ZooKeeperCacheListener
<
Map
<
String
,
String
>>()
{
@SuppressWarnings
(
"unchecked"
)
@Override
public
void
onUpdate
(
String
path
,
Map
<
String
,
String
>
data
,
Stat
stat
)
{
if
(
BROKER_SERVICE_CONFIGURATION_PATH
.
equalsIgnoreCase
(
path
)
&&
data
!=
null
)
{
data
.
forEach
((
configKey
,
value
)
->
{
Field
configField
=
dynamicConfigurationMap
.
get
(
configKey
);
Object
newValue
=
FieldParser
.
value
(
data
.
get
(
configKey
),
configField
);
if
(
configField
!=
null
)
{
Consumer
listener
=
configRegisteredListeners
.
get
(
configKey
);
try
{
Object
existingValue
=
configField
.
get
(
pulsar
.
getConfiguration
());
configField
.
set
(
pulsar
.
getConfiguration
(),
newValue
);
log
.
info
(
"Successfully updated configuration {}/{}"
,
configKey
,
data
.
get
(
configKey
));
if
(
listener
!=
null
&&
!
existingValue
.
equals
(
newValue
))
{
listener
.
accept
(
newValue
);
}
}
catch
(
Exception
e
)
{
log
.
error
(
"Failed to update config {}/{}"
,
configKey
,
newValue
);
}
}
else
{
log
.
error
(
"Found non-dynamic field in dynamicConfigMap {}/{}"
,
configKey
,
newValue
);
}
});
}
}
});
}
catch
(
Exception
e
)
{
log
.
warn
(
"Failed to read zookeeper path [{}]:"
,
BROKER_SERVICE_CONFIGURATION_PATH
,
e
);
}
// register a listener: it updates field value and triggers appropriate registered field-listener only if
// field's value has been changed so, registered doesn't have to update field value in ServiceConfiguration
dynamicConfigurationCache
.
registerListener
(
new
ZooKeeperCacheListener
<
Map
<
String
,
String
>>()
{
@SuppressWarnings
(
"unchecked"
)
@Override
public
void
onUpdate
(
String
path
,
Map
<
String
,
String
>
data
,
Stat
stat
)
{
if
(
BROKER_SERVICE_CONFIGURATION_PATH
.
equalsIgnoreCase
(
path
)
&&
data
!=
null
)
{
data
.
forEach
((
configKey
,
value
)
->
{
Field
configField
=
dynamicConfigurationMap
.
get
(
configKey
);
Object
newValue
=
FieldParser
.
value
(
data
.
get
(
configKey
),
configField
);
if
(
configField
!=
null
)
{
Consumer
listener
=
configRegisteredListeners
.
get
(
configKey
);
try
{
Object
existingValue
=
configField
.
get
(
pulsar
.
getConfiguration
());
configField
.
set
(
pulsar
.
getConfiguration
(),
newValue
);
log
.
info
(
"Successfully updated configuration {}/{}"
,
configKey
,
data
.
get
(
configKey
));
if
(
listener
!=
null
&&
!
existingValue
.
equals
(
newValue
))
{
listener
.
accept
(
newValue
);
}
}
catch
(
Exception
e
)
{
log
.
error
(
"Failed to update config {}/{}"
,
configKey
,
newValue
);
}
}
else
{
log
.
error
(
"Found non-dynamic field in dynamicConfigMap {}/{}"
,
configKey
,
newValue
);
}
});
}
}
});
}
public
static
ConcurrentOpenHashMap
<
String
,
Field
>
getDynamicConfigurationMap
()
{
...
...
pulsar-broker/src/test/java/com/yahoo/pulsar/broker/admin/AdminApiTest.java
浏览文件 @
bd5a6222
...
...
@@ -439,6 +439,42 @@ public class AdminApiTest extends MockedPulsarServiceBaseTest {
}
/**
* Verifies broker sets watch on dynamic-configuration map even with invalid init json data
* <pre>
* 1. Set invalid json at dynamic-config znode
* 2. Broker fails to deserialize znode content but sets the watch on znode
* 3. Update znode with valid json map
* 4. Broker should get watch and update the dynamic-config map
* </pre>
* @throws Exception
*/
@Test
public
void
testInvalidDynamicConfigContentInZK
()
throws
Exception
{
final
int
newValue
=
10
;
stopBroker
();
// set invalid data into dynamic-config znode so, broker startup fail to deserialize data
mockZookKeeper
.
setData
(
BrokerService
.
BROKER_SERVICE_CONFIGURATION_PATH
,
"$"
.
getBytes
(),
-
1
);
// start broker: it should have set watch even if with failure of deserialization
startBroker
();
Assert
.
assertNotEquals
(
pulsar
.
getConfiguration
().
getBrokerShutdownTimeoutMs
(),
newValue
);
// update zk with config-value which should fire watch and broker should update the config value
Map
<
String
,
String
>
configMap
=
Maps
.
newHashMap
();
configMap
.
put
(
"brokerShutdownTimeoutMs"
,
Integer
.
toString
(
newValue
));
mockZookKeeper
.
setData
(
BrokerService
.
BROKER_SERVICE_CONFIGURATION_PATH
,
ObjectMapperFactory
.
getThreadLocal
().
writeValueAsBytes
(
configMap
),
-
1
);
// wait config to be updated
for
(
int
i
=
0
;
i
<
5
;
i
++)
{
if
(
pulsar
.
getConfiguration
().
getBrokerShutdownTimeoutMs
()
!=
newValue
)
{
Thread
.
sleep
(
100
+
(
i
*
10
));
}
else
{
break
;
}
}
// verify value is updated
assertEquals
(
pulsar
.
getConfiguration
().
getBrokerShutdownTimeoutMs
(),
newValue
);
}
/**
* <pre>
* verifies: that registerListener updates pulsar.config value with newly updated zk-dynamic config
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录