【Bug Report】报告 rocketmq-v5-client-spring-boot 的 3 个 Bug
ldcsaa opened this issue · 0 comments
ldcsaa commented
BUG REPORT
在使用的过程中,发现了 rocketmq-v5-client-spring-boot 的以下 3 个Bug:
String.format 应该用 '%' 而不是 '{}' 作为占位符;另外,也不存在文本中提到的 '@ExtTemplateConfiguration' 注解
private void validate(ExtProducerResetConfiguration annotation,
GenericApplicationContext genericApplicationContext) {
if (genericApplicationContext.isBeanNameInUse(annotation.value())) {
// ! BUG !
// String.format 应该用 '%' 而不是 '{}' 作为占位符;另外,也不存在文本中提到的 '@ExtTemplateConfiguration' 注解
throw new BeanDefinitionValidationException(String.format("Bean {} has been used in Spring Application Context, " +
"please check the @ExtTemplateConfiguration",
annotation.value()));
}
}
private void registerTemplate(String beanName, Object bean)
中调用 validate(annotation, genericApplicationContext)
检测beanName 是否已存在:
private void validate(ExtProducerResetConfiguration annotation,
GenericApplicationContext genericApplicationContext) {
if (genericApplicationContext.isBeanNameInUse(annotation.value())) {
throw new BeanDefinitionValidationException(String.format("Bean {} has been used in Spring Application Context, " +
"please check the @ExtTemplateConfiguration",
annotation.value()));
}
}
以下 template 定义会导致导致 validate() 校验失败:
@ExtProducerResetConfiguration(value = FifoPruducerTemplate.BEAN_NAME, topic = "${rocketmq-fifo.simple-consumer.topic}")
public class FifoPruducerTemplate extends RocketMQClientTemplate
{
public static final String BEAN_NAME = "fifoPruducerTemplate";
}
@ExtConsumerResetConfiguration
(
value = FifoConsumerTemplate.BEAN_NAME,
topic = "${rocketmq-fifo.simple-consumer.topic}"
)
public class FifoConsumerTemplate extends SoaRocketMQClientTemplate
{
public static final String BEAN_NAME = "fifoConsumerTemplate";
}
因为 FifoPruducerTemplate、FifoConsumerTemplate 使用了 fifoPruducerTemplate
和 fifoConsumerTemplate
这个beanName,validate()
检测到存在这个beanName。因此报错。
唯一的处理办法就是不能定义注解的value属性,因为只要value有值就过不了validate()
校验。
validate()
校验似乎是多余的,可以去掉;即使不去掉也应排除自身的 beanName。
调用 keys.toString() 有问题:意味着无论 keys 参数是逗号分隔的字符串,或者是字符串数组,传入 messageBuilder.setKeys() 后都变为单个字符串。这似乎与 messageBuilder.setKeys() 的设计目标不一致。
public static org.apache.rocketmq.client.apis.message.Message getAndWrapMessage(
String destination, MessageHeaders headers, byte[] payloads, Duration messageDelayTime, String messageGroup) {
if (payloads == null || payloads.length < 1) {
return null;
}
if (destination == null || destination.length() < 1) {
return null;
}
String[] tempArr = destination.split(":", 2);
final ClientServiceProvider provider = ClientServiceProvider.loadService();
org.apache.rocketmq.client.apis.message.MessageBuilder messageBuilder = null;
// resolve header
if (Objects.nonNull(headers) && !headers.isEmpty()) {
Object keys = headers.get(RocketMQHeaders.KEYS);
if (ObjectUtils.isEmpty(keys)) {
keys = headers.get(toRocketHeaderKey(RocketMQHeaders.KEYS));
}
messageBuilder = provider.newMessageBuilder()
.setTopic(tempArr[0]);
if (tempArr.length > 1) {
messageBuilder.setTag(tempArr[1]);
}
if (StringUtils.hasLength(messageGroup)) {
messageBuilder.setMessageGroup(messageGroup);
}
if (!ObjectUtils.isEmpty(keys)) {
// ! BUG !
// 这里调用 keys.toString() 有问题:意味着无论 keys 参数是逗号分隔的字符串,或者是字符串数组,传入 messageBuilder.setKeys() 后都变为单个字符串。这似乎与 messageBuilder.setKeys() 的设计目标不一致。
messageBuilder.setKeys(keys.toString());
}
if (Objects.nonNull(messageDelayTime)) {
messageBuilder.setDeliveryTimestamp(System.currentTimeMillis() + messageDelayTime.toMillis());
}
messageBuilder.setBody(payloads);
org.apache.rocketmq.client.apis.message.MessageBuilder builder = messageBuilder;
headers.forEach((key, value) -> builder.addProperty(key, String.valueOf(value)));
}
return messageBuilder.build();
}