diff --git a/broker/BUILD.bazel b/broker/BUILD.bazel
index fdf549d3e5..ffd2bea14c 100644
--- a/broker/BUILD.bazel
+++ b/broker/BUILD.bazel
@@ -31,7 +31,6 @@ java_library(
"//tieredstore",
"@maven//:org_slf4j_slf4j_api",
"@maven//:ch_qos_logback_logback_classic",
- "@maven//:com_alibaba_fastjson",
"@maven//:com_alibaba_fastjson2_fastjson2",
"@maven//:com_github_luben_zstd_jni",
"@maven//:com_google_guava_guava",
@@ -83,7 +82,6 @@ java_library(
"//remoting",
"//store",
"//tieredstore",
- "@maven//:com_alibaba_fastjson",
"@maven//:com_alibaba_fastjson2_fastjson2",
"@maven//:org_slf4j_slf4j_api",
"@maven//:com_google_guava_guava",
diff --git a/broker/pom.xml b/broker/pom.xml
index 1751852631..b94e596cc5 100644
--- a/broker/pom.xml
+++ b/broker/pom.xml
@@ -66,10 +66,6 @@
commons-io
commons-io
-
- com.alibaba
- fastjson
-
org.javassist
javassist
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/config/v1/RocksDBConfigManager.java b/broker/src/main/java/org/apache/rocketmq/broker/config/v1/RocksDBConfigManager.java
index e4827e2baf..e68cd20a9d 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/config/v1/RocksDBConfigManager.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/config/v1/RocksDBConfigManager.java
@@ -16,10 +16,7 @@
*/
package org.apache.rocketmq.broker.config.v1;
-import com.alibaba.fastjson.JSON;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.function.BiConsumer;
+import com.alibaba.fastjson2.JSON;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.common.config.ConfigRocksDBStorage;
import org.apache.rocketmq.common.constant.LoggerName;
@@ -33,6 +30,10 @@ import org.rocksdb.RocksDBException;
import org.rocksdb.Statistics;
import org.rocksdb.WriteBatch;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.function.BiConsumer;
+
public class RocksDBConfigManager {
protected static final Logger BROKER_LOG = LoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME);
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/config/v1/RocksDBConsumerOffsetManager.java b/broker/src/main/java/org/apache/rocketmq/broker/config/v1/RocksDBConsumerOffsetManager.java
index 6536f90a8d..45e1a2ab23 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/config/v1/RocksDBConsumerOffsetManager.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/config/v1/RocksDBConsumerOffsetManager.java
@@ -16,12 +16,8 @@
*/
package org.apache.rocketmq.broker.config.v1;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.serializer.SerializerFeature;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentMap;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONWriter;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.broker.BrokerController;
import org.apache.rocketmq.broker.BrokerPathConfigHelper;
@@ -35,6 +31,11 @@ import org.apache.rocketmq.remoting.protocol.DataVersion;
import org.rocksdb.CompressionType;
import org.rocksdb.WriteBatch;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentMap;
+
public class RocksDBConsumerOffsetManager extends ConsumerOffsetManager {
protected static final Logger log = LoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME);
@@ -184,7 +185,7 @@ public class RocksDBConsumerOffsetManager extends ConsumerOffsetManager {
byte[] keyBytes = topicGroupName.getBytes(DataConverter.CHARSET_UTF8);
RocksDBOffsetSerializeWrapper wrapper = new RocksDBOffsetSerializeWrapper();
wrapper.setOffsetTable(offsetMap);
- byte[] valueBytes = JSON.toJSONBytes(wrapper, SerializerFeature.BrowserCompatible);
+ byte[] valueBytes = JSON.toJSONBytes(wrapper, JSONWriter.Feature.BrowserCompatible);
rocksDBConfigManager.writeBatchPutOperation(writeBatch, keyBytes, valueBytes);
}
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/config/v1/RocksDBSubscriptionGroupManager.java b/broker/src/main/java/org/apache/rocketmq/broker/config/v1/RocksDBSubscriptionGroupManager.java
index f6ae3a3e59..b4392212a6 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/config/v1/RocksDBSubscriptionGroupManager.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/config/v1/RocksDBSubscriptionGroupManager.java
@@ -16,16 +16,9 @@
*/
package org.apache.rocketmq.broker.config.v1;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import com.alibaba.fastjson.serializer.SerializerFeature;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.function.BiConsumer;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONWriter;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.broker.BrokerController;
import org.apache.rocketmq.broker.BrokerPathConfigHelper;
@@ -35,6 +28,14 @@ import org.apache.rocketmq.remoting.protocol.DataVersion;
import org.apache.rocketmq.remoting.protocol.subscription.SubscriptionGroupConfig;
import org.rocksdb.CompressionType;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.BiConsumer;
+
public class RocksDBSubscriptionGroupManager extends SubscriptionGroupManager {
protected transient RocksDBConfigManager rocksDBConfigManager;
@@ -162,7 +163,7 @@ public class RocksDBSubscriptionGroupManager extends SubscriptionGroupManager {
try {
byte[] keyBytes = groupName.getBytes(RocksDBConfigManager.CHARSET);
- byte[] valueBytes = JSON.toJSONBytes(subscriptionGroupConfig, SerializerFeature.BrowserCompatible);
+ byte[] valueBytes = JSON.toJSONBytes(subscriptionGroupConfig, JSONWriter.Feature.BrowserCompatible);
this.rocksDBConfigManager.put(keyBytes, valueBytes);
} catch (Exception e) {
log.error("kv put sub Failed, {}", subscriptionGroupConfig.toString());
@@ -177,7 +178,7 @@ public class RocksDBSubscriptionGroupManager extends SubscriptionGroupManager {
if (oldConfig == null) {
try {
byte[] keyBytes = groupName.getBytes(RocksDBConfigManager.CHARSET);
- byte[] valueBytes = JSON.toJSONBytes(subscriptionGroupConfig, SerializerFeature.BrowserCompatible);
+ byte[] valueBytes = JSON.toJSONBytes(subscriptionGroupConfig, JSONWriter.Feature.BrowserCompatible);
this.rocksDBConfigManager.put(keyBytes, valueBytes);
} catch (Exception e) {
log.error("kv put sub Failed, {}", subscriptionGroupConfig.toString());
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/config/v1/RocksDBTopicConfigManager.java b/broker/src/main/java/org/apache/rocketmq/broker/config/v1/RocksDBTopicConfigManager.java
index 4a8d124e9b..96f12e6681 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/config/v1/RocksDBTopicConfigManager.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/config/v1/RocksDBTopicConfigManager.java
@@ -16,12 +16,8 @@
*/
package org.apache.rocketmq.broker.config.v1;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.serializer.SerializerFeature;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Map;
-import java.util.concurrent.ConcurrentMap;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONWriter;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.broker.BrokerController;
import org.apache.rocketmq.broker.BrokerPathConfigHelper;
@@ -32,6 +28,11 @@ import org.apache.rocketmq.common.utils.DataConverter;
import org.apache.rocketmq.remoting.protocol.DataVersion;
import org.rocksdb.CompressionType;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
+
public class RocksDBTopicConfigManager extends TopicConfigManager {
private static final String VERSION_COLUMN_FAMILY = "topicVersion";
private static final String TOPIC_COLUMN_FAMILY = "topic";
@@ -142,7 +143,7 @@ public class RocksDBTopicConfigManager extends TopicConfigManager {
TopicConfig oldTopicConfig = this.topicConfigTable.put(topicName, topicConfig);
try {
byte[] keyBytes = topicName.getBytes(DataConverter.CHARSET_UTF8);
- byte[] valueBytes = JSON.toJSONBytes(topicConfig, SerializerFeature.BrowserCompatible);
+ byte[] valueBytes = JSON.toJSONBytes(topicConfig, JSONWriter.Feature.BrowserCompatible);
this.rocksDBConfigManager.put(keyBytes, valueBytes);
} catch (Exception e) {
log.error("kv put topic Failed, {}", topicConfig.toString(), e);
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/pop/PopConsumerRecord.java b/broker/src/main/java/org/apache/rocketmq/broker/pop/PopConsumerRecord.java
index 1ee01fea1c..661ace9bcb 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/pop/PopConsumerRecord.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/pop/PopConsumerRecord.java
@@ -16,9 +16,9 @@
*/
package org.apache.rocketmq.broker.pop;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import com.alibaba.fastjson.annotation.JSONField;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.annotation.JSONField;
+
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
@@ -119,7 +119,7 @@ public class PopConsumerRecord {
}
public static PopConsumerRecord decode(byte[] body) {
- return JSONObject.parseObject(body, PopConsumerRecord.class);
+ return JSON.parseObject(body, PopConsumerRecord.class);
}
public long getPopTime() {
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/pop/PopConsumerService.java b/broker/src/main/java/org/apache/rocketmq/broker/pop/PopConsumerService.java
index 7678daa1d3..839c96e390 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/pop/PopConsumerService.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/pop/PopConsumerService.java
@@ -16,25 +16,9 @@
*/
package org.apache.rocketmq.broker.pop;
-import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson2.JSON;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Stopwatch;
-import java.nio.ByteBuffer;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Objects;
-import java.util.Queue;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CompletionException;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.apache.rocketmq.broker.BrokerController;
@@ -65,6 +49,23 @@ import org.apache.rocketmq.store.pop.PopCheckPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.nio.ByteBuffer;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Objects;
+import java.util.Queue;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+
public class PopConsumerService extends ServiceThread {
private static final Logger log = LoggerFactory.getLogger(LoggerName.ROCKETMQ_POP_LOGGER_NAME);
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/pop/orderly/QueueLevelConsumerManager.java b/broker/src/main/java/org/apache/rocketmq/broker/pop/orderly/QueueLevelConsumerManager.java
index 79bd59fb78..8a5ed6b150 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/pop/orderly/QueueLevelConsumerManager.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/pop/orderly/QueueLevelConsumerManager.java
@@ -16,7 +16,7 @@
*/
package org.apache.rocketmq.broker.pop.orderly;
-import com.alibaba.fastjson.annotation.JSONField;
+import com.alibaba.fastjson2.annotation.JSONField;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
import java.util.ArrayList;
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/processor/AckMessageProcessor.java b/broker/src/main/java/org/apache/rocketmq/broker/processor/AckMessageProcessor.java
index 864f40d296..1334693352 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/processor/AckMessageProcessor.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/processor/AckMessageProcessor.java
@@ -16,7 +16,7 @@
*/
package org.apache.rocketmq.broker.processor;
-import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson2.JSON;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import java.nio.charset.StandardCharsets;
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java b/broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java
index 298e239086..e7333ab91a 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java
@@ -16,8 +16,9 @@
*/
package org.apache.rocketmq.broker.processor;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONWriter;
import com.google.common.collect.Sets;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
@@ -2785,7 +2786,7 @@ public class AdminBrokerProcessor implements NettyRequestProcessor {
} else {
ConsumerFilterData filterData = this.brokerController.getConsumerFilterManager()
.get(requestHeader.getTopic(), requestHeader.getConsumerGroup());
- body.setFilterData(JSON.toJSONString(filterData, true));
+ body.setFilterData(JSON.toJSONString(filterData, JSONWriter.Feature.PrettyFormat));
messageFilter = new ExpressionMessageFilter(subscriptionData, filterData,
this.brokerController.getConsumerFilterManager());
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/processor/ChangeInvisibleTimeProcessor.java b/broker/src/main/java/org/apache/rocketmq/broker/processor/ChangeInvisibleTimeProcessor.java
index f104e76a52..332930cd78 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/processor/ChangeInvisibleTimeProcessor.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/processor/ChangeInvisibleTimeProcessor.java
@@ -16,7 +16,7 @@
*/
package org.apache.rocketmq.broker.processor;
-import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson2.JSON;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import java.nio.charset.StandardCharsets;
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/processor/PopBufferMergeService.java b/broker/src/main/java/org/apache/rocketmq/broker/processor/PopBufferMergeService.java
index 657adaa34d..06d89e047d 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/processor/PopBufferMergeService.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/processor/PopBufferMergeService.java
@@ -16,15 +16,7 @@
*/
package org.apache.rocketmq.broker.processor;
-import com.alibaba.fastjson.JSON;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.LinkedBlockingDeque;
-import java.util.concurrent.atomic.AtomicInteger;
+import com.alibaba.fastjson2.JSON;
import org.apache.rocketmq.broker.BrokerController;
import org.apache.rocketmq.common.KeyBuilder;
import org.apache.rocketmq.common.PopAckConstants;
@@ -43,6 +35,15 @@ import org.apache.rocketmq.store.pop.AckMsg;
import org.apache.rocketmq.store.pop.BatchAckMsg;
import org.apache.rocketmq.store.pop.PopCheckPoint;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.atomic.AtomicInteger;
+
public class PopBufferMergeService extends ServiceThread {
private static final Logger POP_LOGGER = LoggerFactory.getLogger(LoggerName.ROCKETMQ_POP_LOGGER_NAME);
ConcurrentHashMap
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/processor/PopMessageProcessor.java b/broker/src/main/java/org/apache/rocketmq/broker/processor/PopMessageProcessor.java
index 9967955656..3144eb973a 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/processor/PopMessageProcessor.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/processor/PopMessageProcessor.java
@@ -16,26 +16,13 @@
*/
package org.apache.rocketmq.broker.processor;
-import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson2.JSON;
import com.github.benmanes.caffeine.cache.Cache;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.FileRegion;
import io.opentelemetry.api.common.Attributes;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Random;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentSkipListSet;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
import org.apache.rocketmq.broker.BrokerController;
import org.apache.rocketmq.broker.filter.ConsumerFilterData;
import org.apache.rocketmq.broker.filter.ConsumerFilterManager;
@@ -89,6 +76,20 @@ import org.apache.rocketmq.store.pop.AckMsg;
import org.apache.rocketmq.store.pop.BatchAckMsg;
import org.apache.rocketmq.store.pop.PopCheckPoint;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Random;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListSet;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+
import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.LABEL_CONSUMER_GROUP;
import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.LABEL_IS_RETRY;
import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.LABEL_IS_SYSTEM;
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/processor/PopReviveService.java b/broker/src/main/java/org/apache/rocketmq/broker/processor/PopReviveService.java
index aa7d87505e..434812883e 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/processor/PopReviveService.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/processor/PopReviveService.java
@@ -16,18 +16,8 @@
*/
package org.apache.rocketmq.broker.processor;
-import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson2.JSON;
import io.opentelemetry.api.common.Attributes;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.NavigableMap;
-import java.util.TreeMap;
-import java.util.concurrent.CompletableFuture;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.apache.rocketmq.broker.BrokerController;
@@ -59,6 +49,17 @@ import org.apache.rocketmq.store.pop.AckMsg;
import org.apache.rocketmq.store.pop.BatchAckMsg;
import org.apache.rocketmq.store.pop.PopCheckPoint;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.TreeMap;
+import java.util.concurrent.CompletableFuture;
+
import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.LABEL_CONSUMER_GROUP;
import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.LABEL_IS_SYSTEM;
import static org.apache.rocketmq.broker.metrics.BrokerMetricsConstant.LABEL_TOPIC;
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/topic/TopicQueueMappingManager.java b/broker/src/main/java/org/apache/rocketmq/broker/topic/TopicQueueMappingManager.java
index 4b0714decb..9e20ecd9b6 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/topic/TopicQueueMappingManager.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/topic/TopicQueueMappingManager.java
@@ -16,7 +16,8 @@
*/
package org.apache.rocketmq.broker.topic;
-import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONWriter;
import com.google.common.collect.Maps;
import java.util.List;
import java.util.Map;
@@ -156,7 +157,10 @@ public class TopicQueueMappingManager extends ConfigManager {
TopicQueueMappingSerializeWrapper wrapper = new TopicQueueMappingSerializeWrapper();
wrapper.setTopicQueueMappingInfoMap(topicQueueMappingTable);
wrapper.setDataVersion(this.dataVersion);
- return JSON.toJSONString(wrapper, pretty);
+ if (pretty) {
+ return JSON.toJSONString(wrapper, JSONWriter.Feature.PrettyFormat);
+ }
+ return JSON.toJSONString(wrapper);
}
@Override
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/transaction/TransactionMetrics.java b/broker/src/main/java/org/apache/rocketmq/broker/transaction/TransactionMetrics.java
index 8a18218f53..17b0ac6774 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/transaction/TransactionMetrics.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/transaction/TransactionMetrics.java
@@ -16,9 +16,19 @@
*/
package org.apache.rocketmq.broker.transaction;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONWriter;
+import org.apache.rocketmq.common.ConfigManager;
+import org.apache.rocketmq.common.MixAll;
+import org.apache.rocketmq.common.constant.LoggerName;
+import org.apache.rocketmq.common.topic.TopicValidator;
+import org.apache.rocketmq.logging.org.slf4j.Logger;
+import org.apache.rocketmq.logging.org.slf4j.LoggerFactory;
+import org.apache.rocketmq.remoting.protocol.DataVersion;
+import org.apache.rocketmq.remoting.protocol.RemotingSerializable;
+
import java.io.File;
+import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.StringWriter;
import java.io.Writer;
@@ -32,14 +42,7 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
-import org.apache.rocketmq.common.ConfigManager;
-import org.apache.rocketmq.common.MixAll;
-import org.apache.rocketmq.common.constant.LoggerName;
-import org.apache.rocketmq.common.topic.TopicValidator;
-import org.apache.rocketmq.logging.org.slf4j.Logger;
-import org.apache.rocketmq.logging.org.slf4j.LoggerFactory;
-import org.apache.rocketmq.remoting.protocol.DataVersion;
-import org.apache.rocketmq.remoting.protocol.RemotingSerializable;
+
public class TransactionMetrics extends ConfigManager {
private static final Logger log = LoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME);
@@ -90,11 +93,11 @@ public class TransactionMetrics extends ConfigManager {
this.transactionCounts = transactionCounts;
}
- protected void write0(Writer writer) {
+ protected void write0(Writer writer) throws IOException {
TransactionMetricsSerializeWrapper wrapper = new TransactionMetricsSerializeWrapper();
wrapper.setTransactionCount(transactionCounts);
wrapper.setDataVersion(dataVersion);
- JSON.writeJSONString(writer, wrapper, SerializerFeature.BrowserCompatible);
+ writer.write(JSON.toJSONString(wrapper, JSONWriter.Feature.BrowserCompatible));
}
@Override
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/RocksDBConfigManagerTest.java b/broker/src/test/java/org/apache/rocketmq/broker/RocksDBConfigManagerTest.java
new file mode 100644
index 0000000000..1832902a76
--- /dev/null
+++ b/broker/src/test/java/org/apache/rocketmq/broker/RocksDBConfigManagerTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.rocketmq.broker;
+
+import org.apache.rocketmq.broker.config.v1.RocksDBConfigManager;
+import org.apache.rocketmq.common.config.ConfigRocksDBStorage;
+import org.apache.rocketmq.remoting.protocol.DataVersion;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.powermock.api.mockito.PowerMockito.mock;
+
+public class RocksDBConfigManagerTest {
+
+ private ConfigRocksDBStorage configRocksDBStorage;
+
+ private RocksDBConfigManager rocksDBConfigManager;
+
+ @Before
+ public void setUp() throws IllegalAccessException {
+ configRocksDBStorage = mock(ConfigRocksDBStorage.class);
+ rocksDBConfigManager = spy(new RocksDBConfigManager("testPath", 1000L, null));
+ rocksDBConfigManager.configRocksDBStorage = configRocksDBStorage;
+ }
+
+ @Test
+ public void testLoadDataVersion() throws Exception {
+ DataVersion expected = new DataVersion();
+ expected.nextVersion();
+
+ when(rocksDBConfigManager.getKvDataVersion()).thenReturn(expected);
+
+ boolean result = rocksDBConfigManager.loadDataVersion();
+
+ assertTrue(result);
+ assertEquals(expected.getCounter().get(), rocksDBConfigManager.getKvDataVersion().getCounter().get());
+ assertEquals(expected.getTimestamp(), rocksDBConfigManager.getKvDataVersion().getTimestamp());
+ }
+
+ @Test
+ public void testUpdateKvDataVersion() throws Exception {
+ rocksDBConfigManager.updateKvDataVersion();
+
+ verify(rocksDBConfigManager, times(1)).updateKvDataVersion();
+ }
+}
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/client/ConsumerManagerTest.java b/broker/src/test/java/org/apache/rocketmq/broker/client/ConsumerManagerTest.java
index 1b8293159d..5f2e96015d 100644
--- a/broker/src/test/java/org/apache/rocketmq/broker/client/ConsumerManagerTest.java
+++ b/broker/src/test/java/org/apache/rocketmq/broker/client/ConsumerManagerTest.java
@@ -20,6 +20,7 @@ package org.apache.rocketmq.broker.client;
import com.google.common.collect.ImmutableSet;
import io.netty.channel.Channel;
import org.apache.rocketmq.broker.BrokerController;
+import org.apache.rocketmq.broker.client.net.Broker2Client;
import org.apache.rocketmq.broker.filter.ConsumerFilterManager;
import org.apache.rocketmq.common.BrokerConfig;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
@@ -214,6 +215,9 @@ public class ConsumerManagerTest {
@Test
public void testRegisterConsumerWithoutSub() {
+ when(brokerController.getBrokerConfig()).thenReturn(brokerConfig);
+ Broker2Client broker2Client = mock(Broker2Client.class);
+ when(brokerController.getBroker2Client()).thenReturn(broker2Client);
ConsumerGroupInfo groupInfo = new ConsumerGroupInfo(GROUP, CONSUME_PASSIVELY,
MessageModel.CLUSTERING, ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
SubscriptionData subscriptionData = new SubscriptionData(TOPIC, "*");
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/config/v1/RocksDBSubscriptionGroupManagerTest.java b/broker/src/test/java/org/apache/rocketmq/broker/config/v1/RocksDBSubscriptionGroupManagerTest.java
new file mode 100644
index 0000000000..98d0e34219
--- /dev/null
+++ b/broker/src/test/java/org/apache/rocketmq/broker/config/v1/RocksDBSubscriptionGroupManagerTest.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.rocketmq.broker.config.v1;
+
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.rocketmq.broker.BrokerController;
+import org.apache.rocketmq.common.BrokerConfig;
+import org.apache.rocketmq.remoting.protocol.subscription.SubscriptionGroupConfig;
+import org.apache.rocketmq.store.config.MessageStoreConfig;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.ConcurrentMap;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class RocksDBSubscriptionGroupManagerTest {
+
+ @Mock
+ private BrokerController brokerController;
+
+ @Mock
+ private RocksDBConfigManager rocksDBConfigManager;
+
+ private RocksDBSubscriptionGroupManager rocksDBSubscriptionGroupManager;
+
+ @Mock
+ private MessageStoreConfig messageStoreConfig;
+
+ @Before
+ public void init() throws IllegalAccessException {
+ when(brokerController.getMessageStoreConfig()).thenReturn(messageStoreConfig);
+ when(messageStoreConfig.getMemTableFlushIntervalMs()).thenReturn(1000L);
+ when(messageStoreConfig.getRocksdbCompressionType()).thenReturn("LZ4_COMPRESSION");
+ when(messageStoreConfig.getStorePathRootDir()).thenReturn("/");
+ BrokerConfig brokerConfig = mock(BrokerConfig.class);
+ when(brokerConfig.isUseSingleRocksDBForAllConfigs()).thenReturn(true);
+ when(brokerController.getBrokerConfig()).thenReturn(brokerConfig);
+ rocksDBSubscriptionGroupManager = new RocksDBSubscriptionGroupManager(brokerController);
+ FieldUtils.writeDeclaredField(rocksDBSubscriptionGroupManager, "rocksDBConfigManager", rocksDBConfigManager, true);
+ }
+
+ @Test
+ public void testPutSubscriptionGroupConfig() {
+ SubscriptionGroupConfig newConfig = new SubscriptionGroupConfig();
+ newConfig.setGroupName("group");
+ SubscriptionGroupConfig oldConfig = new SubscriptionGroupConfig();
+ oldConfig.setGroupName("group");
+ rocksDBSubscriptionGroupManager.getSubscriptionGroupTable().put("group", oldConfig);
+
+ assertEquals(oldConfig, rocksDBSubscriptionGroupManager.putSubscriptionGroupConfig(newConfig));
+ assertEquals(newConfig, rocksDBSubscriptionGroupManager.getSubscriptionGroupTable().get("group"));
+ }
+
+ @Test
+ public void testPutSubscriptionGroupConfigIfAbsent() {
+ SubscriptionGroupConfig newConfig = new SubscriptionGroupConfig();
+ newConfig.setGroupName("group");
+ SubscriptionGroupConfig oldConfig = new SubscriptionGroupConfig();
+ oldConfig.setGroupName("group");
+
+ assertNull(rocksDBSubscriptionGroupManager.putSubscriptionGroupConfigIfAbsent(newConfig));
+ assertEquals(newConfig, rocksDBSubscriptionGroupManager.getSubscriptionGroupTable().get("group"));
+ }
+
+ @Test
+ public void testDecodeForbidden() {
+ String forbiddenGroupName = "group";
+ String bodyJson = "{\"topic1\":1,\"topic2\":2}";
+ byte[] key = forbiddenGroupName.getBytes(StandardCharsets.UTF_8);
+ byte[] body = bodyJson.getBytes(StandardCharsets.UTF_8);
+
+ rocksDBSubscriptionGroupManager.decodeForbidden(key, body);
+ ConcurrentMap> forbiddenTable = rocksDBSubscriptionGroupManager.getForbiddenTable();
+ assertTrue(forbiddenTable.containsKey(forbiddenGroupName));
+
+ ConcurrentMap forbiddenGroup = forbiddenTable.get(forbiddenGroupName);
+ assertEquals(2, forbiddenGroup.size());
+ assertEquals(Integer.valueOf(1), forbiddenGroup.get("topic1"));
+ assertEquals(Integer.valueOf(2), forbiddenGroup.get("topic2"));
+ }
+
+ @Test
+ public void testDecodeSubscriptionGroup() {
+ String groupName = "group";
+ String bodyJson = "{\"groupName\":\"group\",\"consumeEnable\":true}";
+ byte[] key = groupName.getBytes(StandardCharsets.UTF_8);
+ byte[] body = bodyJson.getBytes(StandardCharsets.UTF_8);
+
+ rocksDBSubscriptionGroupManager.decodeSubscriptionGroup(key, body);
+ ConcurrentMap subscriptionGroupTable = rocksDBSubscriptionGroupManager.getSubscriptionGroupTable();
+ assertEquals(1, subscriptionGroupTable.size());
+ SubscriptionGroupConfig config = subscriptionGroupTable.get(groupName);
+ assertEquals(groupName, config.getGroupName());
+ assertTrue(config.isConsumeEnable());
+ }
+}
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/config/v1/RocksDBTopicConfigManagerTest.java b/broker/src/test/java/org/apache/rocketmq/broker/config/v1/RocksDBTopicConfigManagerTest.java
new file mode 100644
index 0000000000..b2b742fb2f
--- /dev/null
+++ b/broker/src/test/java/org/apache/rocketmq/broker/config/v1/RocksDBTopicConfigManagerTest.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.rocketmq.broker.config.v1;
+
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.rocketmq.broker.BrokerController;
+import org.apache.rocketmq.common.BrokerConfig;
+import org.apache.rocketmq.common.TopicConfig;
+import org.apache.rocketmq.store.config.MessageStoreConfig;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.ConcurrentMap;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class RocksDBTopicConfigManagerTest {
+
+ @Mock
+ private BrokerController brokerController;
+
+ @Mock
+ private MessageStoreConfig messageStoreConfig;
+
+ @Mock
+ private RocksDBConfigManager rocksDBConfigManager;
+
+ private RocksDBTopicConfigManager rocksDBTopicConfigManager;
+
+ @Before
+ public void init() throws Exception {
+ when(brokerController.getMessageStoreConfig()).thenReturn(messageStoreConfig);
+ when(messageStoreConfig.getMemTableFlushIntervalMs()).thenReturn(1000L);
+ when(messageStoreConfig.getRocksdbCompressionType()).thenReturn("LZ4_COMPRESSION");
+ when(messageStoreConfig.getStorePathRootDir()).thenReturn("/");
+ BrokerConfig brokerConfig = mock(BrokerConfig.class);
+ when(brokerConfig.isUseSingleRocksDBForAllConfigs()).thenReturn(true);
+ when(brokerController.getBrokerConfig()).thenReturn(brokerConfig);
+ rocksDBTopicConfigManager = new RocksDBTopicConfigManager(brokerController);
+ FieldUtils.writeDeclaredField(rocksDBTopicConfigManager, "rocksDBConfigManager", rocksDBConfigManager, true);
+ }
+
+ @Test
+ public void testDecodeTopicConfig() {
+ String topicName = "testTopic";
+ String topicConfigJson = "{\"topicName\":\"testTopic\",\"readQueueNums\":10,\"writeQueueNums\":10}";
+ byte[] key = topicName.getBytes(StandardCharsets.UTF_8);
+ byte[] body = topicConfigJson.getBytes(StandardCharsets.UTF_8);
+
+ rocksDBTopicConfigManager.decodeTopicConfig(key, body);
+
+ ConcurrentMap topicConfigTable = rocksDBTopicConfigManager.getTopicConfigTable();
+ assertNotNull(topicConfigTable);
+ assertEquals(1, topicConfigTable.size());
+ TopicConfig topicConfig = topicConfigTable.get(topicName);
+ assertNotNull(topicConfig);
+ assertEquals(topicName, topicConfig.getTopicName());
+ assertEquals(10, topicConfig.getReadQueueNums());
+ assertEquals(10, topicConfig.getWriteQueueNums());
+ }
+
+ @Test
+ public void testPutTopicConfig() throws Exception {
+ TopicConfig newTopicConfig = new TopicConfig("newTopic");
+ newTopicConfig.setReadQueueNums(10);
+ newTopicConfig.setWriteQueueNums(10);
+
+ assertNull(rocksDBTopicConfigManager.putTopicConfig(newTopicConfig));
+ verify(rocksDBConfigManager, times(1)).put(any(byte[].class), any(byte[].class));
+ }
+}
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/pagecache/QueryMessageTransferTest.java b/broker/src/test/java/org/apache/rocketmq/broker/pagecache/QueryMessageTransferTest.java
new file mode 100644
index 0000000000..a10dd4efca
--- /dev/null
+++ b/broker/src/test/java/org/apache/rocketmq/broker/pagecache/QueryMessageTransferTest.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.rocketmq.broker.pagecache;
+
+import org.apache.rocketmq.store.QueryMessageResult;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.nio.ByteBuffer;
+import java.nio.channels.WritableByteChannel;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class QueryMessageTransferTest {
+
+ @Mock
+ private WritableByteChannel writableByteChannel;
+
+ @Mock
+ private QueryMessageResult queryMessageResult;
+
+ private QueryMessageTransfer queryMessageTransfer;
+
+ private ByteBuffer byteBufferHeader;
+
+ private ByteBuffer bb1;
+
+ private ByteBuffer bb2;
+
+ @Before
+ public void init() {
+ byteBufferHeader = ByteBuffer.allocate(4);
+ byteBufferHeader.putInt(1);
+ byteBufferHeader.flip();
+
+ bb1 = ByteBuffer.allocate(4);
+ bb1.putInt(2);
+ bb1.flip();
+
+ bb2 = ByteBuffer.allocate(4);
+ bb2.putInt(3);
+ bb2.flip();
+
+ when(queryMessageResult.getMessageBufferList()).thenReturn(Arrays.asList(bb1, bb2));
+
+ queryMessageTransfer = new QueryMessageTransfer(byteBufferHeader, queryMessageResult);
+ }
+
+ @Test
+ public void testPosition_WithHeaderAndMessageBuffers() {
+ byteBufferHeader.position(2);
+ bb1.position(1);
+ bb2.position(3);
+
+ long actual = queryMessageTransfer.position();
+
+ long expected = byteBufferHeader.position() + bb1.position() + bb2.position();
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testPosition_WithHeaderOnly() {
+ byteBufferHeader.position(2);
+
+ when(queryMessageResult.getMessageBufferList()).thenReturn(new ArrayList<>());
+
+ long actual = queryMessageTransfer.position();
+
+ long expected = byteBufferHeader.position();
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testPosition_WithMessageBuffersOnly() {
+ byteBufferHeader.clear();
+ byteBufferHeader.flip();
+
+ bb1.position(1);
+ bb2.position(3);
+
+ long actual = queryMessageTransfer.position();
+
+ long expected = bb1.position() + bb2.position();
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testTransferTo_OnlyHeaderData() throws Exception {
+ bb1.clear();
+ bb2.clear();
+
+ when(writableByteChannel.write(byteBufferHeader)).thenReturn(4);
+
+ long actual = queryMessageTransfer.transferTo(writableByteChannel, 0);
+
+ assertEquals(4, actual);
+ verify(writableByteChannel, times(1)).write(byteBufferHeader);
+ verify(writableByteChannel, never()).write(bb1);
+ verify(writableByteChannel, never()).write(bb2);
+ }
+
+ @Test
+ public void testTransferTo_OnlyMessageBuffersData() throws Exception {
+ byteBufferHeader.clear();
+ byteBufferHeader.flip();
+
+ when(writableByteChannel.write(bb1)).thenReturn(4);
+
+ long actual = queryMessageTransfer.transferTo(writableByteChannel, 0);
+
+ assertEquals(4, actual);
+ verify(writableByteChannel, never()).write(byteBufferHeader);
+ verify(writableByteChannel, times(1)).write(bb1);
+ }
+}
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessorTest.java b/broker/src/test/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessorTest.java
index 1bf99eadfb..572be63e3f 100644
--- a/broker/src/test/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessorTest.java
+++ b/broker/src/test/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessorTest.java
@@ -16,7 +16,8 @@
*/
package org.apache.rocketmq.broker.processor;
-import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
@@ -37,11 +38,11 @@ import org.apache.rocketmq.broker.client.ClientChannelInfo;
import org.apache.rocketmq.broker.client.ConsumerGroupInfo;
import org.apache.rocketmq.broker.client.ConsumerManager;
import org.apache.rocketmq.broker.client.net.Broker2Client;
+import org.apache.rocketmq.broker.config.v1.RocksDBSubscriptionGroupManager;
+import org.apache.rocketmq.broker.config.v1.RocksDBTopicConfigManager;
import org.apache.rocketmq.broker.metrics.BrokerMetricsManager;
import org.apache.rocketmq.broker.offset.ConsumerOffsetManager;
import org.apache.rocketmq.broker.schedule.ScheduleMessageService;
-import org.apache.rocketmq.broker.config.v1.RocksDBSubscriptionGroupManager;
-import org.apache.rocketmq.broker.config.v1.RocksDBTopicConfigManager;
import org.apache.rocketmq.broker.topic.TopicConfigManager;
import org.apache.rocketmq.common.BoundaryType;
import org.apache.rocketmq.common.BrokerConfig;
@@ -80,6 +81,7 @@ import org.apache.rocketmq.remoting.protocol.body.SubscriptionGroupWrapper;
import org.apache.rocketmq.remoting.protocol.body.TopicConfigSerializeWrapper;
import org.apache.rocketmq.remoting.protocol.body.UnlockBatchRequestBody;
import org.apache.rocketmq.remoting.protocol.body.UserInfo;
+import org.apache.rocketmq.remoting.protocol.header.CheckRocksdbCqWriteProgressRequestHeader;
import org.apache.rocketmq.remoting.protocol.header.CreateAclRequestHeader;
import org.apache.rocketmq.remoting.protocol.header.CreateTopicRequestHeader;
import org.apache.rocketmq.remoting.protocol.header.CreateUserRequestHeader;
@@ -97,11 +99,13 @@ import org.apache.rocketmq.remoting.protocol.header.GetConsumerStatusRequestHead
import org.apache.rocketmq.remoting.protocol.header.GetEarliestMsgStoretimeRequestHeader;
import org.apache.rocketmq.remoting.protocol.header.GetMaxOffsetRequestHeader;
import org.apache.rocketmq.remoting.protocol.header.GetMinOffsetRequestHeader;
+import org.apache.rocketmq.remoting.protocol.header.GetSubscriptionGroupConfigRequestHeader;
import org.apache.rocketmq.remoting.protocol.header.GetTopicConfigRequestHeader;
import org.apache.rocketmq.remoting.protocol.header.GetUserRequestHeader;
import org.apache.rocketmq.remoting.protocol.header.ListAclsRequestHeader;
import org.apache.rocketmq.remoting.protocol.header.ListUsersRequestHeader;
import org.apache.rocketmq.remoting.protocol.header.NotifyMinBrokerIdChangeRequestHeader;
+import org.apache.rocketmq.remoting.protocol.header.QueryConsumeQueueRequestHeader;
import org.apache.rocketmq.remoting.protocol.header.QueryCorrectionOffsetHeader;
import org.apache.rocketmq.remoting.protocol.header.QuerySubscriptionByConsumerRequestHeader;
import org.apache.rocketmq.remoting.protocol.header.QueryTopicConsumeByWhoRequestHeader;
@@ -114,6 +118,8 @@ import org.apache.rocketmq.remoting.protocol.header.UpdateAclRequestHeader;
import org.apache.rocketmq.remoting.protocol.header.UpdateUserRequestHeader;
import org.apache.rocketmq.remoting.protocol.heartbeat.ConsumeType;
import org.apache.rocketmq.remoting.protocol.heartbeat.MessageModel;
+import org.apache.rocketmq.remoting.protocol.heartbeat.SubscriptionData;
+import org.apache.rocketmq.remoting.protocol.statictopic.TopicConfigAndQueueMapping;
import org.apache.rocketmq.remoting.protocol.subscription.SubscriptionGroupConfig;
import org.apache.rocketmq.store.CommitLog;
import org.apache.rocketmq.store.DefaultMessageStore;
@@ -121,6 +127,7 @@ import org.apache.rocketmq.store.MessageStore;
import org.apache.rocketmq.store.SelectMappedBufferResult;
import org.apache.rocketmq.store.config.MessageStoreConfig;
import org.apache.rocketmq.store.logfile.DefaultMappedFile;
+import org.apache.rocketmq.store.queue.ConsumeQueueInterface;
import org.apache.rocketmq.store.stats.BrokerStats;
import org.apache.rocketmq.store.timer.TimerCheckpoint;
import org.apache.rocketmq.store.timer.TimerMessageStore;
@@ -159,6 +166,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.LongAdder;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
@@ -889,7 +898,7 @@ public class AdminBrokerProcessorTest {
consumerOffsetManager = mock(ConsumerOffsetManager.class);
when(brokerController.getConsumerOffsetManager()).thenReturn(consumerOffsetManager);
ConsumerOffsetManager consumerOffset = new ConsumerOffsetManager();
- when(consumerOffsetManager.encode()).thenReturn(JSON.toJSONString(consumerOffset, false));
+ when(consumerOffsetManager.encode()).thenReturn(JSON.toJSONString(consumerOffset));
RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.GET_ALL_CONSUMER_OFFSET, null);
RemotingCommand response = adminBrokerProcessor.processRequest(handlerContext, request);
assertThat(response.getCode()).isEqualTo(ResponseCode.SUCCESS);
@@ -1500,6 +1509,73 @@ public class AdminBrokerProcessorTest {
assertThat(response.getCode()).isEqualTo(ResponseCode.SUCCESS);
}
+ @Test
+ public void testGetSubscriptionGroup() throws RemotingCommandException {
+ brokerController.getSubscriptionGroupManager().getSubscriptionGroupTable().put("group", new SubscriptionGroupConfig());
+ GetSubscriptionGroupConfigRequestHeader requestHeader = new GetSubscriptionGroupConfigRequestHeader();
+ RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.GET_SUBSCRIPTIONGROUP_CONFIG, requestHeader);
+ requestHeader.setGroup("group");
+ request.makeCustomHeaderToNet();
+ RemotingCommand response = adminBrokerProcessor.processRequest(handlerContext, request);
+ assertEquals(ResponseCode.SUCCESS, response.getCode());
+ }
+
+ @Test
+ public void testCheckRocksdbCqWriteProgress() throws RemotingCommandException {
+ CheckRocksdbCqWriteProgressRequestHeader requestHeader = new CheckRocksdbCqWriteProgressRequestHeader();
+ RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.CHECK_ROCKSDB_CQ_WRITE_PROGRESS, requestHeader);
+ requestHeader.setTopic("topic");
+ request.makeCustomHeaderToNet();
+ RemotingCommand response = adminBrokerProcessor.processRequest(handlerContext, request);
+ assertEquals(ResponseCode.SUCCESS, response.getCode());
+ }
+
+ @Test
+ public void testQueryConsumeQueue() throws RemotingCommandException {
+ messageStore = mock(MessageStore.class);
+ ConsumeQueueInterface consumeQueue = mock(ConsumeQueueInterface.class);
+ when(consumeQueue.getMinOffsetInQueue()).thenReturn(0L);
+ when(consumeQueue.getMaxOffsetInQueue()).thenReturn(1L);
+ when(messageStore.getConsumeQueue(anyString(), anyInt())).thenReturn(consumeQueue);
+ when(brokerController.getMessageStore()).thenReturn(messageStore);
+ QueryConsumeQueueRequestHeader requestHeader = new QueryConsumeQueueRequestHeader();
+ RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.QUERY_CONSUME_QUEUE, requestHeader);
+ requestHeader.setTopic("topic");
+ requestHeader.setQueueId(0);
+ requestHeader.setConsumerGroup("testGroup");
+ request.makeCustomHeaderToNet();
+ SubscriptionData subscriptionData = mock(SubscriptionData.class);
+ when(brokerController.getConsumerManager()).thenReturn(consumerManager);
+ when(consumerManager.findSubscriptionData(any(), any())).thenReturn(subscriptionData);
+ RemotingCommand response = adminBrokerProcessor.processRequest(handlerContext, request);
+ assertEquals(ResponseCode.SUCCESS, response.getCode());
+ }
+
+ @Test
+ public void testProcessRequest_GetTopicConfig() throws Exception {
+ GetTopicConfigRequestHeader requestHeader = new GetTopicConfigRequestHeader();
+ requestHeader.setTopic("testTopic");
+
+ RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.GET_TOPIC_CONFIG, requestHeader);
+ request.makeCustomHeaderToNet();
+
+ TopicConfig topicConfig = new TopicConfig();
+ topicConfig.setTopicName("testTopic");
+ TopicConfigManager topicConfigManager = mock(TopicConfigManager.class);
+ when(brokerController.getTopicConfigManager()).thenReturn(topicConfigManager);
+ when(topicConfigManager.selectTopicConfig("testTopic"))
+ .thenReturn(topicConfig);
+
+ RemotingCommand response = adminBrokerProcessor.processRequest(handlerContext, request);
+
+ assertNotNull(response);
+ assertEquals(ResponseCode.SUCCESS, response.getCode());
+
+ String responseBody = new String(response.getBody(), StandardCharsets.UTF_8);
+ TopicConfigAndQueueMapping result = JSONObject.parseObject(responseBody, TopicConfigAndQueueMapping.class);
+ assertEquals("testTopic", result.getTopicName());
+ }
+
private ResetOffsetRequestHeader createRequestHeader(String topic,String group,long timestamp,boolean force,long offset,int queueId) {
ResetOffsetRequestHeader requestHeader = new ResetOffsetRequestHeader();
requestHeader.setTopic(topic);
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/processor/ChangeInvisibleTimeProcessorTest.java b/broker/src/test/java/org/apache/rocketmq/broker/processor/ChangeInvisibleTimeProcessorTest.java
index ca2529e319..7afd338dca 100644
--- a/broker/src/test/java/org/apache/rocketmq/broker/processor/ChangeInvisibleTimeProcessorTest.java
+++ b/broker/src/test/java/org/apache/rocketmq/broker/processor/ChangeInvisibleTimeProcessorTest.java
@@ -18,18 +18,15 @@ package org.apache.rocketmq.broker.processor;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
-import java.lang.reflect.Field;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ConcurrentHashMap;
import org.apache.rocketmq.broker.BrokerController;
import org.apache.rocketmq.broker.client.ClientChannelInfo;
import org.apache.rocketmq.broker.client.net.Broker2Client;
import org.apache.rocketmq.broker.failover.EscapeBridge;
import org.apache.rocketmq.broker.metrics.BrokerMetricsManager;
-import org.apache.rocketmq.store.stats.BrokerStatsManager;
+import org.apache.rocketmq.broker.metrics.PopMetricsManager;
+import org.apache.rocketmq.broker.topic.TopicConfigManager;
import org.apache.rocketmq.common.BrokerConfig;
import org.apache.rocketmq.common.TopicConfig;
-import org.apache.rocketmq.broker.topic.TopicConfigManager;
import org.apache.rocketmq.common.message.MessageConst;
import org.apache.rocketmq.common.message.MessageExtBrokerInner;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
@@ -41,13 +38,16 @@ import org.apache.rocketmq.remoting.protocol.RequestCode;
import org.apache.rocketmq.remoting.protocol.ResponseCode;
import org.apache.rocketmq.remoting.protocol.header.ChangeInvisibleTimeRequestHeader;
import org.apache.rocketmq.remoting.protocol.header.ExtraInfoUtil;
+import org.apache.rocketmq.remoting.protocol.heartbeat.ConsumerData;
import org.apache.rocketmq.store.AppendMessageResult;
import org.apache.rocketmq.store.AppendMessageStatus;
import org.apache.rocketmq.store.DefaultMessageStore;
+import org.apache.rocketmq.store.MessageStore;
import org.apache.rocketmq.store.PutMessageResult;
import org.apache.rocketmq.store.PutMessageStatus;
import org.apache.rocketmq.store.config.MessageStoreConfig;
import org.apache.rocketmq.store.exception.ConsumeQueueException;
+import org.apache.rocketmq.store.stats.BrokerStatsManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -55,10 +55,18 @@ import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
+import java.lang.reflect.Field;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static org.apache.rocketmq.broker.processor.PullMessageProcessorTest.createConsumerData;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -118,6 +126,17 @@ public class ChangeInvisibleTimeProcessorTest {
PopBufferMergeService popBufferMergeService = mock(PopBufferMergeService.class);
when(brokerController.getPopMessageProcessor()).thenReturn(popMessageProcessor);
when(popMessageProcessor.getPopBufferMergeService()).thenReturn(popBufferMergeService);
+
+ ConsumerData consumerData = createConsumerData(group, topic);
+ clientInfo = new ClientChannelInfo(channel, "127.0.0.1", LanguageCode.JAVA, 0);
+ brokerController.getConsumerManager().registerConsumer(
+ consumerData.getGroupName(),
+ clientInfo,
+ consumerData.getConsumeType(),
+ consumerData.getMessageModel(),
+ consumerData.getConsumeFromWhere(),
+ consumerData.getSubscriptionDataSet(),
+ false);
clientInfo = new ClientChannelInfo(channel, "127.0.0.1", LanguageCode.JAVA, 0);
changeInvisibleTimeProcessor = new ChangeInvisibleTimeProcessor(brokerController);
@@ -177,4 +196,58 @@ public class ChangeInvisibleTimeProcessorTest {
assertThat(responseToReturn.getCode()).isEqualTo(ResponseCode.NO_MESSAGE);
assertThat(responseToReturn.getOpaque()).isEqualTo(request.getOpaque());
}
+
+ @Test
+ public void testProcessRequestAsync_JsonParsing() throws Exception {
+ Channel mockChannel = mock(Channel.class);
+ RemotingCommand mockRequest = mock(RemotingCommand.class);
+ BrokerController mockBrokerController = mock(BrokerController.class);
+ TopicConfigManager mockTopicConfigManager = mock(TopicConfigManager.class);
+ MessageStore mockMessageStore = mock(MessageStore.class);
+ BrokerConfig mockBrokerConfig = mock(BrokerConfig.class);
+ BrokerStatsManager mockBrokerStatsManager = mock(BrokerStatsManager.class);
+ PopMessageProcessor mockPopMessageProcessor = mock(PopMessageProcessor.class);
+ PopBufferMergeService mockPopBufferMergeService = mock(PopBufferMergeService.class);
+ BrokerMetricsManager brokerMetricsManager = mock(BrokerMetricsManager.class);
+ PopMetricsManager popMetricsManager = mock(PopMetricsManager.class);
+
+ when(brokerMetricsManager.getPopMetricsManager()).thenReturn(popMetricsManager);
+ when(mockBrokerController.getBrokerMetricsManager()).thenReturn(brokerMetricsManager);
+ doNothing().when(popMetricsManager).incPopReviveCkPutCount(any(), any());
+ when(brokerMetricsManager.getPopMetricsManager()).thenReturn(popMetricsManager);
+ when(mockBrokerController.getTopicConfigManager()).thenReturn(mockTopicConfigManager);
+ when(mockBrokerController.getMessageStore()).thenReturn(mockMessageStore);
+ when(mockBrokerController.getBrokerConfig()).thenReturn(mockBrokerConfig);
+ when(mockBrokerController.getBrokerStatsManager()).thenReturn(mockBrokerStatsManager);
+ when(mockBrokerController.getPopMessageProcessor()).thenReturn(mockPopMessageProcessor);
+ when(mockPopMessageProcessor.getPopBufferMergeService()).thenReturn(mockPopBufferMergeService);
+ when(mockPopBufferMergeService.addAk(anyInt(), any())).thenReturn(false);
+ when(mockBrokerController.getEscapeBridge()).thenReturn(escapeBridge);
+ PutMessageResult mockPutMessageResult = new PutMessageResult(PutMessageStatus.PUT_OK, null, true);
+ when(mockBrokerController.getEscapeBridge().asyncPutMessageToSpecificQueue(any()))
+ .thenReturn(CompletableFuture.completedFuture(mockPutMessageResult));
+
+ TopicConfig topicConfig = new TopicConfig();
+ topicConfig.setReadQueueNums(4);
+ when(mockTopicConfigManager.selectTopicConfig(anyString())).thenReturn(topicConfig);
+ when(mockMessageStore.getMinOffsetInQueue(anyString(), anyInt())).thenReturn(0L);
+ when(mockMessageStore.getMaxOffsetInQueue(anyString(), anyInt())).thenReturn(10L);
+ when(mockBrokerConfig.isPopConsumerKVServiceEnable()).thenReturn(false);
+
+ ChangeInvisibleTimeRequestHeader requestHeader = new ChangeInvisibleTimeRequestHeader();
+ requestHeader.setTopic("TestTopic");
+ requestHeader.setQueueId(1);
+ requestHeader.setOffset(5L);
+ requestHeader.setConsumerGroup("TestGroup");
+ requestHeader.setExtraInfo("0 10000 10000 0 TestBroker 1");
+ requestHeader.setInvisibleTime(60000L);
+ when(mockRequest.decodeCommandCustomHeader(ChangeInvisibleTimeRequestHeader.class)).thenReturn(requestHeader);
+
+ ChangeInvisibleTimeProcessor processor = new ChangeInvisibleTimeProcessor(mockBrokerController);
+ CompletableFuture futureResponse = processor.processRequestAsync(mockChannel, mockRequest, true);
+
+ RemotingCommand response = futureResponse.get();
+ assertNotNull(response);
+ assertEquals(ResponseCode.SUCCESS, response.getCode());
+ }
}
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/processor/PopBufferMergeServiceTest.java b/broker/src/test/java/org/apache/rocketmq/broker/processor/PopBufferMergeServiceTest.java
index acc7a3da74..6cbbd9cfd9 100644
--- a/broker/src/test/java/org/apache/rocketmq/broker/processor/PopBufferMergeServiceTest.java
+++ b/broker/src/test/java/org/apache/rocketmq/broker/processor/PopBufferMergeServiceTest.java
@@ -16,19 +16,22 @@
*/
package org.apache.rocketmq.broker.processor;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandlerContext;
+import com.alibaba.fastjson2.JSON;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.rocketmq.broker.BrokerController;
-import org.apache.rocketmq.broker.client.ClientChannelInfo;
+import org.apache.rocketmq.broker.client.ConsumerManager;
+import org.apache.rocketmq.broker.failover.EscapeBridge;
+import org.apache.rocketmq.broker.metrics.BrokerMetricsManager;
+import org.apache.rocketmq.broker.metrics.PopMetricsManager;
import org.apache.rocketmq.broker.schedule.ScheduleMessageService;
+import org.apache.rocketmq.broker.topic.TopicConfigManager;
import org.apache.rocketmq.common.BrokerConfig;
import org.apache.rocketmq.common.MixAll;
import org.apache.rocketmq.common.TopicConfig;
-import org.apache.rocketmq.remoting.netty.NettyClientConfig;
-import org.apache.rocketmq.remoting.netty.NettyServerConfig;
-import org.apache.rocketmq.remoting.protocol.heartbeat.ConsumerData;
+import org.apache.rocketmq.common.message.MessageExtBrokerInner;
import org.apache.rocketmq.store.DefaultMessageStore;
+import org.apache.rocketmq.store.PutMessageResult;
+import org.apache.rocketmq.store.PutMessageStatus;
import org.apache.rocketmq.store.config.MessageStoreConfig;
import org.apache.rocketmq.store.pop.AckMsg;
import org.apache.rocketmq.store.pop.PopCheckPoint;
@@ -37,56 +40,83 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
-import static org.apache.rocketmq.broker.processor.PullMessageProcessorTest.createConsumerData;
+import java.lang.reflect.Method;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.Silent.class)
public class PopBufferMergeServiceTest {
- @Spy
- private BrokerController brokerController = new BrokerController(new BrokerConfig(), new NettyServerConfig(), new NettyClientConfig(), new MessageStoreConfig());
+
@Mock
+ private BrokerController brokerController;
+
private PopMessageProcessor popMessageProcessor;
+
@Mock
- private ChannelHandlerContext handlerContext;
+ private ScheduleMessageService scheduleMessageService;
+
+ @Mock
+ private TopicConfigManager topicConfigManager;
+
+ @Mock
+ private ConsumerManager consumerManager;
+
@Mock
private DefaultMessageStore messageStore;
- private ScheduleMessageService scheduleMessageService;
- private ClientChannelInfo clientChannelInfo;
- private String group = "FooBarGroup";
- private String topic = "FooBar";
+
+ @Mock
+ private MessageStoreConfig messageStoreConfig;
+
+ private String defaultGroup = "defaultGroup";
+
+ private String defaultTopic = "defaultTopic";
+
+ private PopBufferMergeService popBufferMergeService;
+
+ @Mock
+ private BrokerConfig brokerConfig;
+
+ @Mock
+ private EscapeBridge escapeBridge;
@Before
public void init() throws Exception {
- FieldUtils.writeField(brokerController.getBrokerConfig(), "enablePopBufferMerge", true, true);
- brokerController.setMessageStore(messageStore);
+ when(brokerConfig.getBrokerIP1()).thenReturn("127.0.0.1");
+ when(brokerConfig.isEnablePopBufferMerge()).thenReturn(true);
+ when(brokerConfig.getPopCkStayBufferTime()).thenReturn(10 * 1000);
+ when(brokerController.getBrokerConfig()).thenReturn(brokerConfig);
+ when(brokerController.getEscapeBridge()).thenReturn(escapeBridge);
+ when(brokerController.getMessageStore()).thenReturn(messageStore);
+ when(brokerController.getTopicConfigManager()).thenReturn(topicConfigManager);
+ when(brokerController.getScheduleMessageService()).thenReturn(scheduleMessageService);
+ when(brokerController.getConsumerManager()).thenReturn(consumerManager);
+ when(brokerController.getMessageStoreConfig()).thenReturn(messageStoreConfig);
popMessageProcessor = new PopMessageProcessor(brokerController);
- scheduleMessageService = new ScheduleMessageService(brokerController);
- scheduleMessageService.parseDelayLevel();
- Channel mockChannel = mock(Channel.class);
- brokerController.getTopicConfigManager().getTopicConfigTable().put(topic, new TopicConfig());
- clientChannelInfo = new ClientChannelInfo(mockChannel);
- ConsumerData consumerData = createConsumerData(group, topic);
- brokerController.getConsumerManager().registerConsumer(
- consumerData.getGroupName(),
- clientChannelInfo,
- consumerData.getConsumeType(),
- consumerData.getMessageModel(),
- consumerData.getConsumeFromWhere(),
- consumerData.getSubscriptionDataSet(),
- false);
+ popBufferMergeService = new PopBufferMergeService(brokerController, popMessageProcessor);
+ FieldUtils.writeDeclaredField(popBufferMergeService, "brokerController", brokerController, true);
+ ConcurrentMap topicConfigTable = new ConcurrentHashMap<>();
+ topicConfigTable.put(defaultTopic, new TopicConfig());
+ when(topicConfigManager.getTopicConfigTable()).thenReturn(topicConfigTable);
}
- @Test(timeout = 10_000)
+ @Test(timeout = 15_000)
public void testBasic() throws Exception {
// This test case fails on Windows in CI pipeline
// Disable it for later fix
Assume.assumeFalse(MixAll.isWindows());
- PopBufferMergeService popBufferMergeService = new PopBufferMergeService(brokerController, popMessageProcessor);
- popBufferMergeService.start();
PopCheckPoint ck = new PopCheckPoint();
ck.setBitMap(0);
int msgCnt = 1;
@@ -97,8 +127,8 @@ public class PopBufferMergeServiceTest {
ck.setInvisibleTime(invisibleTime);
int offset = 100;
ck.setStartOffset(offset);
- ck.setCId(group);
- ck.setTopic(topic);
+ ck.setCId(defaultGroup);
+ ck.setTopic(defaultTopic);
int queueId = 0;
ck.setQueueId(queueId);
@@ -108,18 +138,100 @@ public class PopBufferMergeServiceTest {
AckMsg ackMsg = new AckMsg();
ackMsg.setAckOffset(ackOffset);
ackMsg.setStartOffset(offset);
- ackMsg.setConsumerGroup(group);
- ackMsg.setTopic(topic);
+ ackMsg.setConsumerGroup(defaultGroup);
+ ackMsg.setTopic(defaultTopic);
ackMsg.setQueueId(queueId);
ackMsg.setPopTime(popTime);
try {
assertThat(popBufferMergeService.addCk(ck, reviveQid, ackOffset, nextBeginOffset)).isTrue();
- assertThat(popBufferMergeService.getLatestOffset(topic, group, queueId)).isEqualTo(nextBeginOffset);
+ assertThat(popBufferMergeService.getLatestOffset(defaultTopic, defaultGroup, queueId)).isEqualTo(nextBeginOffset);
Thread.sleep(1000); // wait background threads of PopBufferMergeService run for some time
assertThat(popBufferMergeService.addAk(reviveQid, ackMsg)).isTrue();
- assertThat(popBufferMergeService.getLatestOffset(topic, group, queueId)).isEqualTo(nextBeginOffset);
+ assertThat(popBufferMergeService.getLatestOffset(defaultTopic, defaultGroup, queueId)).isEqualTo(nextBeginOffset);
} finally {
popBufferMergeService.shutdown(true);
}
}
+
+ @Test
+ public void testAddCkJustOffset_MergeKeyConflict() {
+ PopCheckPoint point = mock(PopCheckPoint.class);
+ String mergeKey = "testMergeKey";
+ when(point.getTopic()).thenReturn(mergeKey);
+ when(point.getCId()).thenReturn("");
+ when(point.getQueueId()).thenReturn(0);
+ when(point.getStartOffset()).thenReturn(0L);
+ when(point.getPopTime()).thenReturn(0L);
+ when(point.getBrokerName()).thenReturn("");
+ popBufferMergeService.buffer.put(mergeKey + "000", mock(PopBufferMergeService.PopCheckPointWrapper.class));
+
+ assertFalse(popBufferMergeService.addCkJustOffset(point, 0, 0, 0));
+ }
+
+ @Test
+ public void testAddCkMock() {
+ int queueId = 0;
+ long startOffset = 100L;
+ long invisibleTime = 30_000L;
+ long popTime = System.currentTimeMillis();
+ int reviveQueueId = 0;
+ long nextBeginOffset = 101L;
+ String brokerName = "brokerName";
+ popBufferMergeService.addCkMock(defaultGroup, defaultTopic, queueId, startOffset, invisibleTime, popTime, reviveQueueId, nextBeginOffset, brokerName);
+ verify(brokerConfig, times(1)).isEnablePopLog();
+ }
+
+ @Test
+ public void testPutAckToStore() throws Exception {
+ PopCheckPoint point = new PopCheckPoint();
+ point.setStartOffset(100L);
+ point.setCId("testGroup");
+ point.setTopic("testTopic");
+ point.setQueueId(1);
+ point.setPopTime(System.currentTimeMillis());
+ point.setBrokerName("testBroker");
+
+ PopBufferMergeService.PopCheckPointWrapper pointWrapper = mock(PopBufferMergeService.PopCheckPointWrapper.class);
+ when(pointWrapper.getCk()).thenReturn(point);
+ when(pointWrapper.getReviveQueueId()).thenReturn(0);
+
+ AtomicInteger toStoreBits = new AtomicInteger(0);
+ when(pointWrapper.getToStoreBits()).thenReturn(toStoreBits);
+
+ byte msgIndex = 0;
+ AtomicInteger count = new AtomicInteger(0);
+
+ EscapeBridge escapeBridge = mock(EscapeBridge.class);
+ when(brokerController.getEscapeBridge()).thenReturn(escapeBridge);
+ when(brokerController.getBrokerConfig().isAppendAckAsync()).thenReturn(false);
+ BrokerMetricsManager brokerMetricsManager = mock(BrokerMetricsManager.class);
+ PopMetricsManager popMetricsManager = mock(PopMetricsManager.class);
+
+ when(brokerMetricsManager.getPopMetricsManager()).thenReturn(popMetricsManager);
+ when(brokerController.getBrokerMetricsManager()).thenReturn(brokerMetricsManager);
+ doNothing().when(popMetricsManager).incPopReviveCkPutCount(any(), any());
+ when(brokerMetricsManager.getPopMetricsManager()).thenReturn(popMetricsManager);
+
+ when(escapeBridge.putMessageToSpecificQueue(any())).thenAnswer(invocation -> {
+ MessageExtBrokerInner capturedMessage = invocation.getArgument(0);
+ AckMsg ackMsg = JSON.parseObject(capturedMessage.getBody(), AckMsg.class);
+
+ assertEquals(point.ackOffsetByIndex(msgIndex), ackMsg.getAckOffset());
+ assertEquals(point.getStartOffset(), ackMsg.getStartOffset());
+ assertEquals(point.getCId(), ackMsg.getConsumerGroup());
+ assertEquals(point.getTopic(), ackMsg.getTopic());
+ assertEquals(point.getQueueId(), ackMsg.getQueueId());
+ assertEquals(point.getPopTime(), ackMsg.getPopTime());
+ assertEquals(point.getBrokerName(), ackMsg.getBrokerName());
+
+ PutMessageResult result = mock(PutMessageResult.class);
+ when(result.getPutMessageStatus()).thenReturn(PutMessageStatus.PUT_OK);
+ return result;
+ });
+
+ Method method = PopBufferMergeService.class.getDeclaredMethod("putAckToStore", PopBufferMergeService.PopCheckPointWrapper.class, byte.class, AtomicInteger.class);
+ method.setAccessible(true);
+ method.invoke(popBufferMergeService, pointWrapper, msgIndex, count);
+ verify(escapeBridge, times(1)).putMessageToSpecificQueue(any(MessageExtBrokerInner.class));
+ }
}
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/processor/PopMessageProcessorTest.java b/broker/src/test/java/org/apache/rocketmq/broker/processor/PopMessageProcessorTest.java
index 59559d3cfd..5d7b97f229 100644
--- a/broker/src/test/java/org/apache/rocketmq/broker/processor/PopMessageProcessorTest.java
+++ b/broker/src/test/java/org/apache/rocketmq/broker/processor/PopMessageProcessorTest.java
@@ -16,10 +16,9 @@
*/
package org.apache.rocketmq.broker.processor;
+import com.alibaba.fastjson2.JSON;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.embedded.EmbeddedChannel;
-import java.nio.ByteBuffer;
-import java.util.concurrent.CompletableFuture;
import org.apache.rocketmq.broker.BrokerController;
import org.apache.rocketmq.broker.client.ClientChannelInfo;
import org.apache.rocketmq.broker.metrics.BrokerMetricsManager;
@@ -28,6 +27,7 @@ import org.apache.rocketmq.common.KeyBuilder;
import org.apache.rocketmq.common.TopicConfig;
import org.apache.rocketmq.common.constant.ConsumeInitMode;
import org.apache.rocketmq.common.message.MessageDecoder;
+import org.apache.rocketmq.common.message.MessageExtBrokerInner;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
import org.apache.rocketmq.remoting.netty.NettyClientConfig;
import org.apache.rocketmq.remoting.netty.NettyServerConfig;
@@ -43,7 +43,7 @@ import org.apache.rocketmq.store.SelectMappedBufferResult;
import org.apache.rocketmq.store.config.MessageStoreConfig;
import org.apache.rocketmq.store.exception.ConsumeQueueException;
import org.apache.rocketmq.store.logfile.DefaultMappedFile;
-import org.junit.Assert;
+import org.apache.rocketmq.store.pop.PopCheckPoint;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -51,8 +51,13 @@ import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.CompletableFuture;
+
import static org.apache.rocketmq.broker.processor.PullMessageProcessorTest.createConsumerData;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
@@ -171,17 +176,17 @@ public class PopMessageProcessorTest {
.thenReturn(CompletableFuture.completedFuture(getMessageResult));
long offset = brokerController.getConsumerOffsetManager().queryOffset(newGroup, retryTopic, 0);
- Assert.assertEquals(-1, offset);
+ assertEquals(-1, offset);
RemotingCommand request = createPopMsgCommand(newGroup, topic, 0, ConsumeInitMode.MAX);
popMessageProcessor.processRequest(handlerContext, request);
offset = brokerController.getConsumerOffsetManager().queryOffset(newGroup, retryTopic, 0);
- Assert.assertEquals(minOffset, offset);
+ assertEquals(minOffset, offset);
when(messageStore.getMinOffsetInQueue(retryTopic, 0)).thenReturn(minOffset * 2);
popMessageProcessor.processRequest(handlerContext, request);
offset = brokerController.getConsumerOffsetManager().queryOffset(newGroup, retryTopic, 0);
- Assert.assertEquals(minOffset, offset); // will not entry getInitOffset() again
+ assertEquals(minOffset, offset); // will not entry getInitOffset() again
messageStore.getMinOffsetInQueue(retryTopic, 0); // prevent UnnecessaryStubbingException
}
@@ -196,20 +201,47 @@ public class PopMessageProcessorTest {
.thenReturn(CompletableFuture.completedFuture(getMessageResult));
long offset = brokerController.getConsumerOffsetManager().queryOffset(newGroup, topic, 0);
- Assert.assertEquals(-1, offset);
+ assertEquals(-1, offset);
RemotingCommand request = createPopMsgCommand(newGroup, topic, 0, ConsumeInitMode.MAX);
popMessageProcessor.processRequest(handlerContext, request);
offset = brokerController.getConsumerOffsetManager().queryOffset(newGroup, topic, 0);
- Assert.assertEquals(maxOffset - 1, offset); // checkInMem return false
+ assertEquals(maxOffset - 1, offset); // checkInMem return false
when(messageStore.getMaxOffsetInQueue(topic, 0)).thenReturn(maxOffset * 2);
popMessageProcessor.processRequest(handlerContext, request);
offset = brokerController.getConsumerOffsetManager().queryOffset(newGroup, topic, 0);
- Assert.assertEquals(maxOffset - 1, offset); // will not entry getInitOffset() again
+ assertEquals(maxOffset - 1, offset); // will not entry getInitOffset() again
messageStore.getMaxOffsetInQueue(topic, 0); // prevent UnnecessaryStubbingException
}
+ @Test
+ public void testBuildCkMsgJsonParsing() {
+ PopCheckPoint ck = new PopCheckPoint();
+ ck.setTopic("TestTopic");
+ ck.setQueueId(1);
+ ck.setStartOffset(100L);
+ ck.setCId("TestConsumer");
+ ck.setPopTime(System.currentTimeMillis());
+ ck.setBrokerName("TestBroker");
+
+ int reviveQid = 0;
+ PopMessageProcessor processor = new PopMessageProcessor(brokerController);
+
+ MessageExtBrokerInner result = processor.buildCkMsg(ck, reviveQid);
+
+ String jsonBody = new String(result.getBody(), StandardCharsets.UTF_8);
+ PopCheckPoint actual = JSON.parseObject(jsonBody, PopCheckPoint.class);
+
+ assertEquals(ck.getTopic(), actual.getTopic());
+ assertEquals(ck.getQueueId(), actual.getQueueId());
+ assertEquals(ck.getStartOffset(), actual.getStartOffset());
+ assertEquals(ck.getCId(), actual.getCId());
+ assertEquals(ck.getPopTime(), actual.getPopTime());
+ assertEquals(ck.getBrokerName(), actual.getBrokerName());
+ assertEquals(ck.getReviveTime(), actual.getReviveTime());
+ }
+
private RemotingCommand createPopMsgCommand() {
return createPopMsgCommand(group, topic, -1, ConsumeInitMode.MAX);
}
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/processor/PopReviveServiceTest.java b/broker/src/test/java/org/apache/rocketmq/broker/processor/PopReviveServiceTest.java
index 6e77e7c557..fa7e9982e1 100644
--- a/broker/src/test/java/org/apache/rocketmq/broker/processor/PopReviveServiceTest.java
+++ b/broker/src/test/java/org/apache/rocketmq/broker/processor/PopReviveServiceTest.java
@@ -16,13 +16,7 @@
*/
package org.apache.rocketmq.broker.processor;
-import com.alibaba.fastjson.JSON;
-import java.net.SocketAddress;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
+import com.alibaba.fastjson2.JSON;
import org.apache.commons.lang3.tuple.Triple;
import org.apache.rocketmq.broker.BrokerController;
import org.apache.rocketmq.broker.failover.EscapeBridge;
@@ -42,12 +36,13 @@ import org.apache.rocketmq.common.message.MessageExtBrokerInner;
import org.apache.rocketmq.common.utils.DataConverter;
import org.apache.rocketmq.common.utils.NetworkUtil;
import org.apache.rocketmq.remoting.protocol.subscription.SubscriptionGroupConfig;
+import org.apache.rocketmq.store.AppendMessageResult;
+import org.apache.rocketmq.store.AppendMessageStatus;
import org.apache.rocketmq.store.MessageStore;
import org.apache.rocketmq.store.PutMessageResult;
import org.apache.rocketmq.store.PutMessageStatus;
-import org.apache.rocketmq.store.AppendMessageResult;
-import org.apache.rocketmq.store.AppendMessageStatus;
import org.apache.rocketmq.store.pop.AckMsg;
+import org.apache.rocketmq.store.pop.BatchAckMsg;
import org.apache.rocketmq.store.pop.PopCheckPoint;
import org.apache.rocketmq.store.timer.TimerMessageStore;
import org.junit.Assert;
@@ -58,18 +53,27 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
+import java.net.SocketAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.any;
import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.Silent.class)
public class PopReviveServiceTest {
@@ -139,7 +143,7 @@ public class PopReviveServiceTest {
long maxReviveOffset = 4;
when(consumerOffsetManager.queryOffset(PopAckConstants.REVIVE_GROUP, REVIVE_TOPIC, REVIVE_QUEUE_ID))
- .thenReturn(0L);
+ .thenReturn(0L);
List reviveMessageExtList = new ArrayList<>();
long basePopTime = System.currentTimeMillis();
{
@@ -176,7 +180,7 @@ public class PopReviveServiceTest {
long maxReviveOffset = 4;
when(consumerOffsetManager.queryOffset(PopAckConstants.REVIVE_GROUP, REVIVE_TOPIC, REVIVE_QUEUE_ID))
- .thenReturn(0L);
+ .thenReturn(0L);
List reviveMessageExtList = new ArrayList<>();
long basePopTime = System.currentTimeMillis() - brokerConfig.getReviveAckWaitMs() * 2;
{
@@ -213,7 +217,7 @@ public class PopReviveServiceTest {
long maxReviveOffset = 4;
when(consumerOffsetManager.queryOffset(PopAckConstants.REVIVE_GROUP, REVIVE_TOPIC, REVIVE_QUEUE_ID))
- .thenReturn(0L);
+ .thenReturn(0L);
List reviveMessageExtList = new ArrayList<>();
long basePopTime = System.currentTimeMillis() - brokerConfig.getReviveAckWaitMs() * 2;
{
@@ -419,6 +423,59 @@ public class PopReviveServiceTest {
verify(messageStore, times(1)).putMessage(any(MessageExtBrokerInner.class)); // rewrite CK
}
+ @Test
+ public void testReviveMsgFromBatchAck() throws Throwable {
+ brokerConfig.setEnableSkipLongAwaitingAck(true);
+ when(consumerOffsetManager.queryOffset(PopAckConstants.REVIVE_GROUP, REVIVE_TOPIC, REVIVE_QUEUE_ID)).thenReturn(0L);
+ List reviveMessageExtList = new ArrayList<>();
+ long basePopTime = System.currentTimeMillis();
+ reviveMessageExtList.add(buildBatchAckMsg(buildBatchAckMsg(Arrays.asList(1L, 2L, 3L), basePopTime), 1, 1, basePopTime));
+ doReturn(reviveMessageExtList, new ArrayList<>()).when(popReviveService).getReviveMessage(anyLong(), anyInt());
+
+ PopReviveService.ConsumeReviveObj consumeReviveObj = new PopReviveService.ConsumeReviveObj();
+ popReviveService.consumeReviveMessage(consumeReviveObj);
+ assertEquals(1, consumeReviveObj.map.size());
+
+ ArgumentCaptor commitOffsetCaptor = ArgumentCaptor.forClass(Long.class);
+ doNothing().when(consumerOffsetManager).commitOffset(anyString(), anyString(), anyString(), anyInt(), commitOffsetCaptor.capture());
+ popReviveService.mergeAndRevive(consumeReviveObj);
+ assertEquals(1, commitOffsetCaptor.getValue().longValue());
+ }
+
+ public static MessageExtBrokerInner buildBatchAckMsg(BatchAckMsg batchAckMsg, long deliverMs, long reviveOffset, long deliverTime) {
+ MessageExtBrokerInner result = buildBatchAckInnerMessage(REVIVE_TOPIC, batchAckMsg, REVIVE_QUEUE_ID, STORE_HOST, deliverMs, PopMessageProcessor.genAckUniqueId(batchAckMsg));
+ result.setQueueOffset(reviveOffset);
+ result.setDeliverTimeMs(deliverMs);
+ result.setStoreTimestamp(deliverTime);
+ return result;
+ }
+
+ public static BatchAckMsg buildBatchAckMsg(Collection offsets, long popTime) {
+ BatchAckMsg result = new BatchAckMsg();
+ result.setConsumerGroup(GROUP);
+ result.setTopic(TOPIC);
+ result.setQueueId(0);
+ result.setPopTime(popTime);
+ result.setBrokerName("broker-a");
+ result.getAckOffsetList().addAll(offsets);
+ return result;
+ }
+
+ public static MessageExtBrokerInner buildBatchAckInnerMessage(String reviveTopic, AckMsg ackMsg, int reviveQid, SocketAddress host, long deliverMs, String ackUniqueId) {
+ MessageExtBrokerInner result = new MessageExtBrokerInner();
+ result.setTopic(reviveTopic);
+ result.setBody(JSON.toJSONString(ackMsg).getBytes(DataConverter.CHARSET_UTF8));
+ result.setQueueId(reviveQid);
+ result.setTags(PopAckConstants.BATCH_ACK_TAG);
+ result.setBornTimestamp(System.currentTimeMillis());
+ result.setBornHost(host);
+ result.setStoreHost(host);
+ result.setDeliverTimeMs(deliverMs);
+ result.getProperties().put(MessageConst.PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX, ackUniqueId);
+ result.setPropertiesString(MessageDecoder.messageProperties2String(result.getProperties()));
+ return result;
+ }
+
public static PopCheckPoint buildPopCheckPoint(long startOffset, long popTime, long reviveOffset) {
PopCheckPoint ck = new PopCheckPoint();
ck.setStartOffset(startOffset);
@@ -467,14 +524,14 @@ public class PopReviveServiceTest {
}
public static MessageExtBrokerInner buildAckMsg(AckMsg ackMsg, long deliverMs, long reviveOffset,
- long deliverTime) {
+ long deliverTime) {
MessageExtBrokerInner messageExtBrokerInner = buildAckInnerMessage(
- REVIVE_TOPIC,
- ackMsg,
- REVIVE_QUEUE_ID,
- STORE_HOST,
- deliverMs,
- PopMessageProcessor.genAckUniqueId(ackMsg)
+ REVIVE_TOPIC,
+ ackMsg,
+ REVIVE_QUEUE_ID,
+ STORE_HOST,
+ deliverMs,
+ PopMessageProcessor.genAckUniqueId(ackMsg)
);
messageExtBrokerInner.setQueueOffset(reviveOffset);
messageExtBrokerInner.setDeliverTimeMs(deliverMs);
@@ -483,7 +540,7 @@ public class PopReviveServiceTest {
}
public static MessageExtBrokerInner buildAckInnerMessage(String reviveTopic, AckMsg ackMsg, int reviveQid,
- SocketAddress host, long deliverMs, String ackUniqueId) {
+ SocketAddress host, long deliverMs, String ackUniqueId) {
MessageExtBrokerInner msgInner = new MessageExtBrokerInner();
msgInner.setTopic(reviveTopic);
msgInner.setBody(JSON.toJSONString(ackMsg).getBytes(DataConverter.CHARSET_UTF8));
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/subscription/SubscriptionGroupManagerTest.java b/broker/src/test/java/org/apache/rocketmq/broker/subscription/SubscriptionGroupManagerTest.java
index 3c975a599b..bc34e26bf5 100644
--- a/broker/src/test/java/org/apache/rocketmq/broker/subscription/SubscriptionGroupManagerTest.java
+++ b/broker/src/test/java/org/apache/rocketmq/broker/subscription/SubscriptionGroupManagerTest.java
@@ -47,7 +47,6 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@RunWith(MockitoJUnitRunner.class)
@@ -101,13 +100,13 @@ public class SubscriptionGroupManagerTest {
subscriptionGroupConfig.setGroupName(group);
Map attr = ImmutableMap.of("+test", "true");
subscriptionGroupConfig.setAttributes(attr);
+ SubscriptionGroupManager subscriptionGroupManager = new SubscriptionGroupManager(brokerControllerMock);
subscriptionGroupManager.updateSubscriptionGroupConfig(subscriptionGroupConfig);
SubscriptionGroupConfig result = subscriptionGroupManager.getSubscriptionGroupTable().get(group);
assertThat(result).isNotNull();
assertThat(result.getGroupName()).isEqualTo(group);
assertThat(result.getAttributes().get("test")).isEqualTo("true");
-
SubscriptionGroupConfig subscriptionGroupConfig1 = new SubscriptionGroupConfig();
subscriptionGroupConfig1.setGroupName(group);
Map attrRemove = ImmutableMap.of("-test", "");
@@ -157,14 +156,11 @@ public class SubscriptionGroupManagerTest {
groupNames.add(groupName);
}
+ SubscriptionGroupManager subscriptionGroupManager = new SubscriptionGroupManager(brokerControllerMock);
subscriptionGroupManager.updateSubscriptionGroupConfigList(configList);
- // Verifying that persist() is called once
- verify(subscriptionGroupManager, times(1)).persist();
-
groupNames.forEach(groupName ->
assertThat(subscriptionGroupManager.getSubscriptionGroupTable().get(groupName)).isNotNull());
-
}
@Test
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/topic/TopicQueueMappingManagerTest.java b/broker/src/test/java/org/apache/rocketmq/broker/topic/TopicQueueMappingManagerTest.java
index b74e57ab93..9b25e0134c 100644
--- a/broker/src/test/java/org/apache/rocketmq/broker/topic/TopicQueueMappingManagerTest.java
+++ b/broker/src/test/java/org/apache/rocketmq/broker/topic/TopicQueueMappingManagerTest.java
@@ -17,15 +17,11 @@
package org.apache.rocketmq.broker.topic;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONWriter;
import org.apache.rocketmq.broker.BrokerController;
import org.apache.rocketmq.common.BrokerConfig;
+import org.apache.rocketmq.remoting.protocol.body.TopicQueueMappingSerializeWrapper;
import org.apache.rocketmq.remoting.protocol.statictopic.TopicQueueMappingDetail;
import org.apache.rocketmq.remoting.protocol.statictopic.TopicQueueMappingUtils;
import org.apache.rocketmq.remoting.protocol.statictopic.TopicRemappingDetailWrapper;
@@ -37,6 +33,16 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
@@ -79,9 +85,9 @@ public class TopicQueueMappingManagerTest {
String topic = UUID.randomUUID().toString();
int queueNum = 10;
TopicRemappingDetailWrapper topicRemappingDetailWrapper = TopicQueueMappingUtils.createTopicConfigMapping(topic, queueNum, brokers, new HashMap<>());
- Assert.assertEquals(1, topicRemappingDetailWrapper.getBrokerConfigMap().size());
+ assertEquals(1, topicRemappingDetailWrapper.getBrokerConfigMap().size());
TopicQueueMappingDetail topicQueueMappingDetail = topicRemappingDetailWrapper.getBrokerConfigMap().values().iterator().next().getMappingDetail();
- Assert.assertEquals(queueNum, topicQueueMappingDetail.getHostedQueues().size());
+ assertEquals(queueNum, topicQueueMappingDetail.getHostedQueues().size());
mappingDetailMap.put(topic, topicQueueMappingDetail);
}
}
@@ -89,7 +95,7 @@ public class TopicQueueMappingManagerTest {
{
topicQueueMappingManager = new TopicQueueMappingManager(brokerController);
Assert.assertTrue(topicQueueMappingManager.load());
- Assert.assertEquals(0, topicQueueMappingManager.getTopicQueueMappingTable().size());
+ assertEquals(0, topicQueueMappingManager.getTopicQueueMappingTable().size());
for (TopicQueueMappingDetail mappingDetail : mappingDetailMap.values()) {
for (int i = 0; i < 10; i++) {
topicQueueMappingManager.updateTopicQueueMapping(mappingDetail, false, false, true);
@@ -101,11 +107,49 @@ public class TopicQueueMappingManagerTest {
{
topicQueueMappingManager = new TopicQueueMappingManager(brokerController);
Assert.assertTrue(topicQueueMappingManager.load());
- Assert.assertEquals(mappingDetailMap.size(), topicQueueMappingManager.getTopicQueueMappingTable().size());
+ assertEquals(mappingDetailMap.size(), topicQueueMappingManager.getTopicQueueMappingTable().size());
for (TopicQueueMappingDetail topicQueueMappingDetail: topicQueueMappingManager.getTopicQueueMappingTable().values()) {
- Assert.assertEquals(topicQueueMappingDetail, mappingDetailMap.get(topicQueueMappingDetail.getTopic()));
+ assertEquals(topicQueueMappingDetail, mappingDetailMap.get(topicQueueMappingDetail.getTopic()));
}
}
delete(topicQueueMappingManager);
}
+
+ @Test
+ public void testEncodePretty() {
+ TopicQueueMappingManager topicQueueMappingManager = new TopicQueueMappingManager(null);
+ TopicQueueMappingDetail detail = new TopicQueueMappingDetail();
+ detail.setTopic("testTopic");
+ detail.setBname("testBroker");
+
+ topicQueueMappingManager.getTopicQueueMappingTable().put("testTopic", detail);
+ topicQueueMappingManager.getDataVersion().nextVersion();
+
+ String actual = topicQueueMappingManager.encode(true);
+ TopicQueueMappingSerializeWrapper expectedWrapper = new TopicQueueMappingSerializeWrapper();
+ expectedWrapper.setTopicQueueMappingInfoMap(new ConcurrentHashMap<>(topicQueueMappingManager.getTopicQueueMappingTable()));
+ expectedWrapper.setDataVersion(topicQueueMappingManager.getDataVersion());
+ String expected = JSON.toJSONString(expectedWrapper, JSONWriter.Feature.PrettyFormat);
+
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testEncodeNonPretty() {
+ TopicQueueMappingManager topicQueueMappingManager = new TopicQueueMappingManager(null);
+ TopicQueueMappingDetail detail = new TopicQueueMappingDetail();
+ detail.setTopic("testTopic");
+ detail.setBname("testBroker");
+
+ topicQueueMappingManager.getTopicQueueMappingTable().put("testTopic", detail);
+ topicQueueMappingManager.getDataVersion().nextVersion();
+
+ String actual = topicQueueMappingManager.encode(false);
+ TopicQueueMappingSerializeWrapper expectedWrapper = new TopicQueueMappingSerializeWrapper();
+ expectedWrapper.setTopicQueueMappingInfoMap(new ConcurrentHashMap<>(topicQueueMappingManager.getTopicQueueMappingTable()));
+ expectedWrapper.setDataVersion(topicQueueMappingManager.getDataVersion());
+ String expected = JSON.toJSONString(expectedWrapper);
+
+ assertEquals(expected, actual);
+ }
}
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/transaction/queue/TransactionMetricsTest.java b/broker/src/test/java/org/apache/rocketmq/broker/transaction/queue/TransactionMetricsTest.java
index 690b4eabb5..62a6ad8b5b 100644
--- a/broker/src/test/java/org/apache/rocketmq/broker/transaction/queue/TransactionMetricsTest.java
+++ b/broker/src/test/java/org/apache/rocketmq/broker/transaction/queue/TransactionMetricsTest.java
@@ -19,23 +19,40 @@ package org.apache.rocketmq.broker.transaction.queue;
import org.apache.rocketmq.broker.transaction.TransactionMetrics;
import org.apache.rocketmq.broker.transaction.TransactionMetrics.Metric;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.Collections;
+import java.util.UUID;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
@RunWith(MockitoJUnitRunner.class)
public class TransactionMetricsTest {
private TransactionMetrics transactionMetrics;
private String configPath;
+ private Path path;
@Before
- public void setUp() throws Exception {
- configPath = "configPath";
- transactionMetrics = new TransactionMetrics(configPath);
+ public void before() throws Exception {
+ configPath = createBaseDir();
+ path = Paths.get(configPath);
+ transactionMetrics = spy(new TransactionMetrics(configPath));
+ }
+
+ @After
+ public void after() throws Exception {
+ deleteFile(configPath);
+ assertFalse(path.toFile().exists());
}
/**
@@ -80,4 +97,40 @@ public class TransactionMetricsTest {
transactionMetrics.cleanMetrics(Collections.singleton(topic));
assert transactionMetrics.getTransactionCount(topic) == 0;
}
+
+ @Test
+ public void testPersist() {
+ assertFalse(path.toFile().exists());
+ transactionMetrics.persist();
+ assertTrue(path.toFile().exists());
+ verify(transactionMetrics).persist();
+ }
+
+ private String createBaseDir() {
+ String baseDir = System.getProperty("java.io.tmpdir") + File.separator + "unitteststore-" + UUID.randomUUID();
+ final File file = new File(baseDir);
+ if (file.exists()) {
+ System.exit(1);
+ }
+ return baseDir;
+ }
+
+ private void deleteFile(String fileName) {
+ deleteFile(new File(fileName));
+ }
+
+ private void deleteFile(File file) {
+ if (!file.exists()) {
+ return;
+ }
+ if (file.isFile()) {
+ file.delete();
+ } else if (file.isDirectory()) {
+ File[] files = file.listFiles();
+ for (File file1 : files) {
+ deleteFile(file1);
+ }
+ file.delete();
+ }
+ }
}
diff --git a/client/BUILD.bazel b/client/BUILD.bazel
index 31681f1029..3bd84606a2 100644
--- a/client/BUILD.bazel
+++ b/client/BUILD.bazel
@@ -27,7 +27,6 @@ java_library(
"@maven//:commons_validator_commons_validator",
"@maven//:com_github_luben_zstd_jni",
"@maven//:org_lz4_lz4_java",
- "@maven//:com_alibaba_fastjson",
"@maven//:com_alibaba_fastjson2_fastjson2",
"@maven//:io_netty_netty_all",
"@maven//:io_opentracing_opentracing_api",
diff --git a/client/src/main/java/org/apache/rocketmq/client/impl/MQClientAPIImpl.java b/client/src/main/java/org/apache/rocketmq/client/impl/MQClientAPIImpl.java
index 95bb0e8a96..11af6ecd4b 100644
--- a/client/src/main/java/org/apache/rocketmq/client/impl/MQClientAPIImpl.java
+++ b/client/src/main/java/org/apache/rocketmq/client/impl/MQClientAPIImpl.java
@@ -16,7 +16,7 @@
*/
package org.apache.rocketmq.client.impl;
-import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson2.JSON;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.client.ClientConfig;
diff --git a/client/src/main/java/org/apache/rocketmq/client/impl/factory/MQClientInstance.java b/client/src/main/java/org/apache/rocketmq/client/impl/factory/MQClientInstance.java
index 3055f2cdee..bb838a6265 100644
--- a/client/src/main/java/org/apache/rocketmq/client/impl/factory/MQClientInstance.java
+++ b/client/src/main/java/org/apache/rocketmq/client/impl/factory/MQClientInstance.java
@@ -16,26 +16,8 @@
*/
package org.apache.rocketmq.client.impl.factory;
-import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson2.JSON;
import io.netty.channel.Channel;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Random;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.client.ClientConfig;
import org.apache.rocketmq.client.admin.MQAdminExtInner;
@@ -86,6 +68,25 @@ import org.apache.rocketmq.remoting.protocol.route.BrokerData;
import org.apache.rocketmq.remoting.protocol.route.QueueData;
import org.apache.rocketmq.remoting.protocol.route.TopicRouteData;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
import static org.apache.rocketmq.remoting.rpc.ClientMetadata.topicRouteData2EndpointsForStaticTopic;
public class MQClientInstance {
diff --git a/client/src/main/java/org/apache/rocketmq/client/producer/SendResult.java b/client/src/main/java/org/apache/rocketmq/client/producer/SendResult.java
index d160eb4eae..5405275398 100644
--- a/client/src/main/java/org/apache/rocketmq/client/producer/SendResult.java
+++ b/client/src/main/java/org/apache/rocketmq/client/producer/SendResult.java
@@ -16,7 +16,7 @@
*/
package org.apache.rocketmq.client.producer;
-import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson2.JSON;
import org.apache.rocketmq.common.message.MessageQueue;
public class SendResult {
diff --git a/client/src/test/java/org/apache/rocketmq/client/consumer/DefaultLitePullConsumerTest.java b/client/src/test/java/org/apache/rocketmq/client/consumer/DefaultLitePullConsumerTest.java
index 592c247057..f57b3f80fe 100644
--- a/client/src/test/java/org/apache/rocketmq/client/consumer/DefaultLitePullConsumerTest.java
+++ b/client/src/test/java/org/apache/rocketmq/client/consumer/DefaultLitePullConsumerTest.java
@@ -17,17 +17,6 @@
package org.apache.rocketmq.client.consumer;
-import java.io.ByteArrayOutputStream;
-import java.lang.reflect.Field;
-import java.net.InetSocketAddress;
-import java.time.Duration;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.rocketmq.client.ClientConfig;
import org.apache.rocketmq.client.consumer.store.OffsetStore;
@@ -65,6 +54,18 @@ import org.mockito.invocation.InvocationOnMock;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
+import java.io.ByteArrayOutputStream;
+import java.lang.reflect.Field;
+import java.net.InetSocketAddress;
+import java.time.Duration;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Fail.failBecauseExceptionWasNotThrown;
import static org.awaitility.Awaitility.await;
@@ -75,6 +76,7 @@ import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
@@ -898,5 +900,6 @@ public class DefaultLitePullConsumerTest {
ConcurrentMap factoryTable = (ConcurrentMap) FieldUtils.readDeclaredField(MQClientManager.getInstance(), "factoryTable", true);
factoryTable.put(litePullConsumer.buildMQClientId(), mQClientFactory);
doReturn(false).when(mQClientFactory).updateTopicRouteInfoFromNameServer(anyString());
+ doNothing().when(mQClientFactory).updateTopicRouteInfoFromNameServer();
}
}
diff --git a/client/src/test/java/org/apache/rocketmq/client/impl/MQClientAPIImplTest.java b/client/src/test/java/org/apache/rocketmq/client/impl/MQClientAPIImplTest.java
index c12b23cb0d..c8d23274bd 100644
--- a/client/src/test/java/org/apache/rocketmq/client/impl/MQClientAPIImplTest.java
+++ b/client/src/test/java/org/apache/rocketmq/client/impl/MQClientAPIImplTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.rocketmq.client.impl;
+import com.alibaba.fastjson2.JSON;
import org.apache.rocketmq.client.ClientConfig;
import org.apache.rocketmq.client.consumer.AckCallback;
import org.apache.rocketmq.client.consumer.AckResult;
@@ -34,6 +35,7 @@ import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
+import org.apache.rocketmq.common.CheckRocksdbCqWriteResult;
import org.apache.rocketmq.common.MixAll;
import org.apache.rocketmq.common.ObjectCreator;
import org.apache.rocketmq.common.Pair;
@@ -2031,6 +2033,22 @@ public class MQClientAPIImplTest {
}
}
+ @Test
+ public void testCheckRocksdbCqWriteProgress() throws Exception {
+ RemotingCommand response = RemotingCommand.createResponseCommand(ResponseCode.SUCCESS, "Success");
+ CheckRocksdbCqWriteResult expectedResult = new CheckRocksdbCqWriteResult();
+ expectedResult.setCheckStatus(CheckRocksdbCqWriteResult.CheckStatus.CHECK_OK.getValue());
+ response.setBody(JSON.toJSONString(expectedResult).getBytes());
+
+ when(remotingClient.invokeSync(any(String.class), any(RemotingCommand.class), any(Long.class)))
+ .thenReturn(response);
+
+ CheckRocksdbCqWriteResult result = mqClientAPI.checkRocksdbCqWriteProgress(
+ "brokerAddr", "testTopic", 12345L, 3000L);
+
+ assertEquals(CheckRocksdbCqWriteResult.CheckStatus.CHECK_OK.getValue(), result.getCheckStatus());
+ }
+
private Properties createProperties() {
Properties result = new Properties();
result.put("key", "value");
diff --git a/client/src/test/java/org/apache/rocketmq/client/impl/admin/MqClientAdminImplTest.java b/client/src/test/java/org/apache/rocketmq/client/impl/admin/MqClientAdminImplTest.java
index 71682fb52c..520f4da5f2 100644
--- a/client/src/test/java/org/apache/rocketmq/client/impl/admin/MqClientAdminImplTest.java
+++ b/client/src/test/java/org/apache/rocketmq/client/impl/admin/MqClientAdminImplTest.java
@@ -206,7 +206,7 @@ public class MqClientAdminImplTest {
@Test
public void assertUpdateOrCreateSubscriptionGroupWithSuccess() throws Exception {
setResponseSuccess(null);
- SubscriptionGroupConfig config = mock(SubscriptionGroupConfig.class);
+ SubscriptionGroupConfig config = new SubscriptionGroupConfig();
CompletableFuture actual = mqClientAdminImpl.updateOrCreateSubscriptionGroup(defaultBrokerAddr, config, defaultTimeout);
assertNull(actual.get());
}
@@ -214,7 +214,7 @@ public class MqClientAdminImplTest {
@Test
public void assertUpdateOrCreateSubscriptionGroupWithError() {
setResponseError();
- SubscriptionGroupConfig config = mock(SubscriptionGroupConfig.class);
+ SubscriptionGroupConfig config = new SubscriptionGroupConfig();
CompletableFuture actual = mqClientAdminImpl.updateOrCreateSubscriptionGroup(defaultBrokerAddr, config, defaultTimeout);
Throwable thrown = assertThrows(ExecutionException.class, actual::get);
assertTrue(thrown.getCause() instanceof MQClientException);
diff --git a/client/src/test/java/org/apache/rocketmq/client/impl/consumer/PopProcessQueueTest.java b/client/src/test/java/org/apache/rocketmq/client/impl/consumer/PopProcessQueueTest.java
new file mode 100644
index 0000000000..0633342c59
--- /dev/null
+++ b/client/src/test/java/org/apache/rocketmq/client/impl/consumer/PopProcessQueueTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.rocketmq.client.impl.consumer;
+
+import org.apache.rocketmq.remoting.protocol.body.PopProcessQueueInfo;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(MockitoJUnitRunner.class)
+public class PopProcessQueueTest {
+
+ private final PopProcessQueueInfo popProcessQueueInfo = new PopProcessQueueInfo();
+
+ @Test
+ public void testPopProcessQueue() {
+ long currentTime = System.currentTimeMillis();
+ PopProcessQueue popRequest1 = createPopProcessQueue(currentTime);
+ PopProcessQueue popRequest2 = createPopProcessQueue(currentTime);
+ assertEquals(popRequest1.getLastPopTimestamp(), popRequest2.getLastPopTimestamp());
+ assertEquals(popRequest1.toString(), popRequest2.toString());
+ assertEquals(popRequest1.getWaiAckMsgCount(), popRequest2.getWaiAckMsgCount());
+ assertEquals(popRequest1.ack(), popRequest2.ack());
+ assertEquals(popRequest1.isPullExpired(), popRequest2.isPullExpired());
+ assertEquals(popProcessQueueInfo.getLastPopTimestamp(), popRequest1.getLastPopTimestamp());
+ assertEquals(popProcessQueueInfo.isDroped(), popRequest1.isDropped());
+ assertEquals(popProcessQueueInfo.getWaitAckCount(), popRequest1.getWaiAckMsgCount() + popRequest2.getWaiAckMsgCount());
+ }
+
+ private PopProcessQueue createPopProcessQueue(final long currentTime) {
+ PopProcessQueue result = new PopProcessQueue();
+ long curTime = System.currentTimeMillis();
+ result.setLastPopTimestamp(curTime);
+ result.incFoundMsg(1);
+ result.decFoundMsg(1);
+ result.setLastPopTimestamp(currentTime);
+ result.fillPopProcessQueueInfo(popProcessQueueInfo);
+ return result;
+ }
+}
diff --git a/client/src/test/java/org/apache/rocketmq/client/impl/consumer/ProcessQueueTest.java b/client/src/test/java/org/apache/rocketmq/client/impl/consumer/ProcessQueueTest.java
index dd7ffa757f..a12633be1b 100644
--- a/client/src/test/java/org/apache/rocketmq/client/impl/consumer/ProcessQueueTest.java
+++ b/client/src/test/java/org/apache/rocketmq/client/impl/consumer/ProcessQueueTest.java
@@ -16,11 +16,6 @@
*/
package org.apache.rocketmq.client.impl.consumer;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.TreeMap;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.exception.MQBrokerException;
@@ -34,6 +29,12 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.TreeMap;
+
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -164,6 +165,7 @@ public class ProcessQueueTest {
ProcessQueue result = new ProcessQueue();
result.setMsgAccCnt(1);
result.incTryUnlockTimes();
+ result.setLastPullTimestamp(10000L);
return result;
}
diff --git a/client/src/test/java/org/apache/rocketmq/client/producer/SendResultTest.java b/client/src/test/java/org/apache/rocketmq/client/producer/SendResultTest.java
new file mode 100644
index 0000000000..1ae8371a96
--- /dev/null
+++ b/client/src/test/java/org/apache/rocketmq/client/producer/SendResultTest.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.rocketmq.client.producer;
+
+import com.alibaba.fastjson2.JSON;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class SendResultTest {
+
+ @Test
+ public void testEncoderSendResultToJson() {
+ SendResult sendResult = new SendResult();
+ sendResult.setSendStatus(SendStatus.SEND_OK);
+ sendResult.setMsgId("12345");
+ sendResult.setQueueOffset(100L);
+ MessageQueue messageQueue = new MessageQueue("TestTopic", "BrokerA", 1);
+ sendResult.setMessageQueue(messageQueue);
+
+ String json = SendResult.encoderSendResultToJson(sendResult);
+
+ SendResult decodedResult = JSON.parseObject(json, SendResult.class);
+ assertEquals(sendResult.getSendStatus(), decodedResult.getSendStatus());
+ assertEquals(sendResult.getMsgId(), decodedResult.getMsgId());
+ assertEquals(sendResult.getQueueOffset(), decodedResult.getQueueOffset());
+ assertEquals(sendResult.getMessageQueue(), decodedResult.getMessageQueue());
+ }
+
+ @Test
+ public void testDecoderSendResultFromJson() {
+ String json = "{\"sendStatus\":\"SEND_OK\",\"msgId\":\"12345\",\"queueOffset\":100,\"messageQueue\":{\"topic\":\"TestTopic\",\"brokerName\":\"BrokerA\",\"queueId\":1}}";
+
+ SendResult sendResult = SendResult.decoderSendResultFromJson(json);
+
+ assertEquals(SendStatus.SEND_OK, sendResult.getSendStatus());
+ assertEquals("12345", sendResult.getMsgId());
+ assertEquals(100L, sendResult.getQueueOffset());
+ assertEquals("TestTopic", sendResult.getMessageQueue().getTopic());
+ assertEquals("BrokerA", sendResult.getMessageQueue().getBrokerName());
+ assertEquals(1, sendResult.getMessageQueue().getQueueId());
+ }
+}
diff --git a/common/BUILD.bazel b/common/BUILD.bazel
index 10c5d19fbe..8aeeb2f24f 100644
--- a/common/BUILD.bazel
+++ b/common/BUILD.bazel
@@ -21,7 +21,6 @@ java_library(
srcs = glob(["src/main/java/**/*.java"]),
visibility = ["//visibility:public"],
deps = [
- "@maven//:com_alibaba_fastjson",
"@maven//:com_alibaba_fastjson2_fastjson2",
"@maven//:com_github_luben_zstd_jni",
"@maven//:com_google_guava_guava",
@@ -55,7 +54,6 @@ java_library(
":common",
"//:test_deps",
"@maven//:com_google_guava_guava",
- "@maven//:com_alibaba_fastjson",
"@maven//:com_alibaba_fastjson2_fastjson2",
"@maven//:commons_codec_commons_codec",
"@maven//:io_netty_netty_all",
diff --git a/common/src/main/java/org/apache/rocketmq/common/TopicConfig.java b/common/src/main/java/org/apache/rocketmq/common/TopicConfig.java
index 0bf64905a0..ebb009c567 100644
--- a/common/src/main/java/org/apache/rocketmq/common/TopicConfig.java
+++ b/common/src/main/java/org/apache/rocketmq/common/TopicConfig.java
@@ -16,14 +16,15 @@
*/
package org.apache.rocketmq.common;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.TypeReference;
-import com.alibaba.fastjson.annotation.JSONField;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.TypeReference;
+import com.alibaba.fastjson2.annotation.JSONField;
+import org.apache.rocketmq.common.attribute.TopicMessageType;
+import org.apache.rocketmq.common.constant.PermName;
+
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
-import org.apache.rocketmq.common.attribute.TopicMessageType;
-import org.apache.rocketmq.common.constant.PermName;
import static org.apache.rocketmq.common.TopicAttributes.TOPIC_MESSAGE_TYPE_ATTRIBUTE;
diff --git a/common/src/main/java/org/apache/rocketmq/common/fastjson/GenericMapSuperclassDeserializer.java b/common/src/main/java/org/apache/rocketmq/common/fastjson/GenericMapSuperclassDeserializer.java
index 80a1554d12..f2639b51c1 100644
--- a/common/src/main/java/org/apache/rocketmq/common/fastjson/GenericMapSuperclassDeserializer.java
+++ b/common/src/main/java/org/apache/rocketmq/common/fastjson/GenericMapSuperclassDeserializer.java
@@ -17,11 +17,10 @@
package org.apache.rocketmq.common.fastjson;
-import com.alibaba.fastjson.JSONException;
-import com.alibaba.fastjson.parser.DefaultJSONParser;
-import com.alibaba.fastjson.parser.JSONToken;
-import com.alibaba.fastjson.parser.deserializer.MapDeserializer;
-import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
+import com.alibaba.fastjson2.JSONException;
+import com.alibaba.fastjson2.JSONReader;
+import com.alibaba.fastjson2.reader.ObjectReader;
+
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;
@@ -29,32 +28,40 @@ import java.util.Map;
/**
* workaround https://github.com/alibaba/fastjson/issues/3730
*/
-public class GenericMapSuperclassDeserializer implements ObjectDeserializer {
+public class GenericMapSuperclassDeserializer implements ObjectReader
-
- com.alibaba
- fastjson
-
org.apache.commons
commons-lang3
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtImpl.java b/tools/src/main/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtImpl.java
index 948c4430d5..f2e1cda2bd 100644
--- a/tools/src/main/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtImpl.java
+++ b/tools/src/main/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtImpl.java
@@ -16,7 +16,7 @@
*/
package org.apache.rocketmq.tools.admin;
-import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson2.JSON;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.client.QueryResult;
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/broker/GetColdDataFlowCtrInfoSubCommand.java b/tools/src/main/java/org/apache/rocketmq/tools/command/broker/GetColdDataFlowCtrInfoSubCommand.java
index 34b3ba7d30..76c111b95c 100644
--- a/tools/src/main/java/org/apache/rocketmq/tools/command/broker/GetColdDataFlowCtrInfoSubCommand.java
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/broker/GetColdDataFlowCtrInfoSubCommand.java
@@ -16,13 +16,9 @@
*/
package org.apache.rocketmq.tools.command.broker;
-import java.io.UnsupportedEncodingException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONWriter;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
@@ -37,6 +33,12 @@ import org.apache.rocketmq.tools.command.CommandUtil;
import org.apache.rocketmq.tools.command.SubCommand;
import org.apache.rocketmq.tools.command.SubCommandException;
+import java.io.UnsupportedEncodingException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
public class GetColdDataFlowCtrInfoSubCommand implements SubCommand {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@@ -116,7 +118,7 @@ public class GetColdDataFlowCtrInfoSubCommand implements SubCommand {
value.remove("createTimeMills");
});
- String formatStr = JSON.toJSONString(jsonObject, true);
+ String formatStr = JSON.toJSONString(jsonObject, JSONWriter.Feature.PrettyFormat);
System.out.printf(formatStr);
System.out.printf("%n");
}
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/consumer/UpdateSubGroupSubCommand.java b/tools/src/main/java/org/apache/rocketmq/tools/command/consumer/UpdateSubGroupSubCommand.java
index b17da4de45..d4782a0684 100644
--- a/tools/src/main/java/org/apache/rocketmq/tools/command/consumer/UpdateSubGroupSubCommand.java
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/consumer/UpdateSubGroupSubCommand.java
@@ -16,9 +16,7 @@
*/
package org.apache.rocketmq.tools.command.consumer;
-import com.alibaba.fastjson.JSON;
-import java.util.Map;
-import java.util.Set;
+import com.alibaba.fastjson2.JSON;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
@@ -32,6 +30,9 @@ import org.apache.rocketmq.tools.command.CommandUtil;
import org.apache.rocketmq.tools.command.SubCommand;
import org.apache.rocketmq.tools.command.SubCommandException;
+import java.util.Map;
+import java.util.Set;
+
public class UpdateSubGroupSubCommand implements SubCommand {
@Override
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportConfigsCommand.java b/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportConfigsCommand.java
index c3f96d5972..ebb1cf82ba 100644
--- a/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportConfigsCommand.java
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportConfigsCommand.java
@@ -16,15 +16,8 @@
*/
package org.apache.rocketmq.tools.command.export;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Arrays;
-import java.util.Properties;
-
-import com.alibaba.fastjson.JSON;
-
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONWriter;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
@@ -35,6 +28,13 @@ import org.apache.rocketmq.tools.command.CommandUtil;
import org.apache.rocketmq.tools.command.SubCommand;
import org.apache.rocketmq.tools.command.SubCommandException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+
public class ExportConfigsCommand implements SubCommand {
@Override
public String commandName() {
@@ -98,7 +98,7 @@ public class ExportConfigsCommand implements SubCommand {
result.put("clusterScale", clusterScaleMap);
String path = filePath + "/configs.json";
- MixAll.string2FileNotSafe(JSON.toJSONString(result, true), path);
+ MixAll.string2FileNotSafe(JSON.toJSONString(result, JSONWriter.Feature.PrettyFormat), path);
System.out.printf("export %s success", path);
} catch (Exception e) {
throw new SubCommandException(this.getClass().getSimpleName() + " command failed", e);
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportMetadataCommand.java b/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportMetadataCommand.java
index 748f7b16e1..559936bcb8 100644
--- a/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportMetadataCommand.java
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportMetadataCommand.java
@@ -16,10 +16,8 @@
*/
package org.apache.rocketmq.tools.command.export;
-import com.alibaba.fastjson.JSON;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONWriter;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
@@ -35,6 +33,10 @@ import org.apache.rocketmq.tools.command.CommandUtil;
import org.apache.rocketmq.tools.command.SubCommand;
import org.apache.rocketmq.tools.command.SubCommandException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
public class ExportMetadataCommand implements SubCommand {
private static final String DEFAULT_FILE_PATH = "/tmp/rocketmq/export";
@@ -99,13 +101,13 @@ public class ExportMetadataCommand implements SubCommand {
filePath = filePath + "/topic.json";
TopicConfigSerializeWrapper topicConfigSerializeWrapper = defaultMQAdminExt.getUserTopicConfig(
brokerAddr, specialTopic, 10000L);
- MixAll.string2FileNotSafe(JSON.toJSONString(topicConfigSerializeWrapper, true), filePath);
+ MixAll.string2FileNotSafe(JSON.toJSONString(topicConfigSerializeWrapper, JSONWriter.Feature.PrettyFormat), filePath);
System.out.printf("export %s success", filePath);
} else if (commandLine.hasOption('g')) {
filePath = filePath + "/subscriptionGroup.json";
SubscriptionGroupWrapper subscriptionGroupWrapper = defaultMQAdminExt.getUserSubscriptionGroup(
brokerAddr, 10000L);
- MixAll.string2FileNotSafe(JSON.toJSONString(subscriptionGroupWrapper, true), filePath);
+ MixAll.string2FileNotSafe(JSON.toJSONString(subscriptionGroupWrapper, JSONWriter.Feature.PrettyFormat), filePath);
System.out.printf("export %s success", filePath);
}
} else if (commandLine.hasOption('c')) {
@@ -163,7 +165,7 @@ public class ExportMetadataCommand implements SubCommand {
exportPath = filePath + "/metadata.json";
}
result.put("exportTime", System.currentTimeMillis());
- MixAll.string2FileNotSafe(JSON.toJSONString(result, true), exportPath);
+ MixAll.string2FileNotSafe(JSON.toJSONString(result, JSONWriter.Feature.PrettyFormat), exportPath);
System.out.printf("export %s success%n", exportPath);
} else {
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportMetadataInRocksDBCommand.java b/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportMetadataInRocksDBCommand.java
index 438d17d668..1a3e5e5a6a 100644
--- a/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportMetadataInRocksDBCommand.java
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportMetadataInRocksDBCommand.java
@@ -17,11 +17,9 @@
package org.apache.rocketmq.tools.command.export;
-import com.alibaba.fastjson.JSONObject;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.function.BiConsumer;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONWriter;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
@@ -34,6 +32,11 @@ import org.apache.rocketmq.tools.command.SubCommand;
import org.apache.rocketmq.tools.command.SubCommandException;
import org.rocksdb.RocksIterator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.BiConsumer;
+
public class ExportMetadataInRocksDBCommand implements SubCommand {
private static final String TOPICS_JSON_CONFIG = "topics";
private static final String SUBSCRIPTION_GROUP_JSON_CONFIG = "subscriptionGroups";
@@ -118,8 +121,8 @@ public class ExportMetadataInRocksDBCommand implements SubCommand {
);
jsonConfig.put(configType.equalsIgnoreCase(TOPICS_JSON_CONFIG) ? "topicConfigTable" : "subscriptionGroupTable",
- (JSONObject) JSONObject.toJSON(configTable));
- final String jsonConfigStr = JSONObject.toJSONString(jsonConfig, true);
+ (JSONObject) JSON.toJSON(configTable));
+ final String jsonConfigStr = JSONObject.toJSONString(jsonConfig, JSONWriter.Feature.PrettyFormat);
System.out.print(jsonConfigStr + "\n");
} else {
AtomicLong count = new AtomicLong(0);
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportMetricsCommand.java b/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportMetricsCommand.java
index 5d8bb37ba0..1b7d5d44e3 100644
--- a/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportMetricsCommand.java
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/export/ExportMetricsCommand.java
@@ -16,12 +16,8 @@
*/
package org.apache.rocketmq.tools.command.export;
-import com.alibaba.fastjson.JSON;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONWriter;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
@@ -47,6 +43,12 @@ import org.apache.rocketmq.tools.command.SubCommand;
import org.apache.rocketmq.tools.command.SubCommandException;
import org.apache.rocketmq.tools.command.stats.StatsAllSubCommand;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
public class ExportMetricsCommand implements SubCommand {
@Override
@@ -133,7 +135,7 @@ public class ExportMetricsCommand implements SubCommand {
result.put("evaluateReport", evaluateReportMap);
result.put("totalData", totalData);
- MixAll.string2FileNotSafe(JSON.toJSONString(result, true), path);
+ MixAll.string2FileNotSafe(JSON.toJSONString(result, JSONWriter.Feature.PrettyFormat), path);
System.out.printf("export %s success", path);
} catch (Exception e) {
throw new SubCommandException(this.getClass().getSimpleName() + " command failed", e);
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/metadata/RocksDBConfigToJsonCommand.java b/tools/src/main/java/org/apache/rocketmq/tools/command/metadata/RocksDBConfigToJsonCommand.java
index 94899fce08..d65a04136b 100644
--- a/tools/src/main/java/org/apache/rocketmq/tools/command/metadata/RocksDBConfigToJsonCommand.java
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/metadata/RocksDBConfigToJsonCommand.java
@@ -17,22 +17,8 @@
package org.apache.rocketmq.tools.command.metadata;
-import com.alibaba.fastjson.JSONObject;
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CompletionException;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.atomic.AtomicLong;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONWriter;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
@@ -49,6 +35,22 @@ import org.apache.rocketmq.tools.command.SubCommand;
import org.apache.rocketmq.tools.command.SubCommandException;
import org.rocksdb.RocksIterator;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicLong;
+
public class RocksDBConfigToJsonCommand implements SubCommand {
@Override
@@ -136,10 +138,10 @@ public class RocksDBConfigToJsonCommand implements SubCommand {
if (commandLine.hasOption("jsonEnable") && "false".equalsIgnoreCase(commandLine.getOptionValue("jsonEnable").trim())) {
printConfigMapJsonDisable(configMap);
} else {
- System.out.print(JSONObject.toJSONString(configMap, true) + "\n");
+ System.out.print(JSONObject.toJSONString(configMap, JSONWriter.Feature.PrettyFormat) + "\n");
}
} else {
- String jsonString = JSONObject.toJSONString(configMap, true);
+ String jsonString = JSONObject.toJSONString(configMap, JSONWriter.Feature.PrettyFormat);
try {
MixAll.string2File(jsonString, exportFile);
} catch (IOException e) {
diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/queue/QueryConsumeQueueCommand.java b/tools/src/main/java/org/apache/rocketmq/tools/command/queue/QueryConsumeQueueCommand.java
index 4902b8a881..24d9900b61 100644
--- a/tools/src/main/java/org/apache/rocketmq/tools/command/queue/QueryConsumeQueueCommand.java
+++ b/tools/src/main/java/org/apache/rocketmq/tools/command/queue/QueryConsumeQueueCommand.java
@@ -17,7 +17,8 @@
package org.apache.rocketmq.tools.command.queue;
-import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONWriter;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Option;
@@ -121,7 +122,7 @@ public class QueryConsumeQueueCommand implements SubCommand {
);
if (queryConsumeQueueResponseBody.getSubscriptionData() != null) {
- System.out.printf("Subscription data: \n%s\n", JSON.toJSONString(queryConsumeQueueResponseBody.getSubscriptionData(), true));
+ System.out.printf("Subscription data: \n%s\n", JSON.toJSONString(queryConsumeQueueResponseBody.getSubscriptionData(), JSONWriter.Feature.PrettyFormat));
System.out.print("======================================\n");
}
diff --git a/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtImplTest.java b/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtImplTest.java
new file mode 100644
index 0000000000..c5ea051ab4
--- /dev/null
+++ b/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtImplTest.java
@@ -0,0 +1,825 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.rocketmq.tools.admin;
+
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.rocketmq.client.exception.MQBrokerException;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.client.impl.MQAdminImpl;
+import org.apache.rocketmq.client.impl.MQClientAPIImpl;
+import org.apache.rocketmq.client.impl.factory.MQClientInstance;
+import org.apache.rocketmq.common.TopicConfig;
+import org.apache.rocketmq.common.constant.PermName;
+import org.apache.rocketmq.common.message.MessageExt;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.remoting.exception.RemotingConnectException;
+import org.apache.rocketmq.remoting.exception.RemotingException;
+import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
+import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
+import org.apache.rocketmq.remoting.protocol.ResponseCode;
+import org.apache.rocketmq.remoting.protocol.admin.ConsumeStats;
+import org.apache.rocketmq.remoting.protocol.admin.OffsetWrapper;
+import org.apache.rocketmq.remoting.protocol.admin.RollbackStats;
+import org.apache.rocketmq.remoting.protocol.admin.TopicOffset;
+import org.apache.rocketmq.remoting.protocol.admin.TopicStatsTable;
+import org.apache.rocketmq.remoting.protocol.body.ClusterInfo;
+import org.apache.rocketmq.remoting.protocol.body.ConsumeMessageDirectlyResult;
+import org.apache.rocketmq.remoting.protocol.body.ConsumerConnection;
+import org.apache.rocketmq.remoting.protocol.body.GroupList;
+import org.apache.rocketmq.remoting.protocol.body.QueueTimeSpan;
+import org.apache.rocketmq.remoting.protocol.body.SubscriptionGroupWrapper;
+import org.apache.rocketmq.remoting.protocol.body.TopicConfigSerializeWrapper;
+import org.apache.rocketmq.remoting.protocol.body.TopicList;
+import org.apache.rocketmq.remoting.protocol.header.UpdateConsumerOffsetRequestHeader;
+import org.apache.rocketmq.remoting.protocol.header.UpdateGroupForbiddenRequestHeader;
+import org.apache.rocketmq.remoting.protocol.heartbeat.SubscriptionData;
+import org.apache.rocketmq.remoting.protocol.route.BrokerData;
+import org.apache.rocketmq.remoting.protocol.route.QueueData;
+import org.apache.rocketmq.remoting.protocol.route.TopicRouteData;
+import org.apache.rocketmq.remoting.protocol.subscription.GroupForbidden;
+import org.apache.rocketmq.remoting.protocol.subscription.SubscriptionGroupConfig;
+import org.apache.rocketmq.tools.admin.api.BrokerOperatorResult;
+import org.apache.rocketmq.tools.admin.api.MessageTrack;
+import org.apache.rocketmq.tools.admin.common.AdminToolResult;
+import org.apache.rocketmq.tools.admin.common.AdminToolsResultCodeEnum;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class DefaultMQAdminExtImplTest {
+
+ private DefaultMQAdminExtImpl defaultMQAdminExtImpl;
+
+ @Mock
+ private DefaultMQAdminExt defaultMQAdminExt;
+
+ @Mock
+ private MQClientInstance mqClientInstance;
+
+ @Mock
+ private MQClientAPIImpl mqClientAPIImpl;
+
+ @Mock
+ private MQAdminImpl mqAdminImpl;
+
+ private final String defaultTopic = "defaultTopic";
+
+ private final String defaultCluster = "cluster";
+
+ private final String defaultBroker = "broker1";
+
+ private final String defaultGroup = "consumerGroup";
+
+ private final String defaultBrokerAddr = "127.0.0.1:10911";
+
+ private final long timeoutMillis = 3000L;
+
+ private final String defaultMsgId = "AC1A43AC00002A9F00008F214319C26B";
+
+ @Before
+ public void init() throws IllegalAccessException, RemotingException, InterruptedException, MQClientException, MQBrokerException {
+ defaultMQAdminExtImpl = new DefaultMQAdminExtImpl(defaultMQAdminExt, timeoutMillis);
+ FieldUtils.writeDeclaredField(defaultMQAdminExtImpl, "mqClientInstance", mqClientInstance, true);
+ FieldUtils.writeDeclaredField(defaultMQAdminExtImpl, "mqClientInstance", mqClientInstance, true);
+ FieldUtils.writeDeclaredField(defaultMQAdminExtImpl, "threadPoolExecutor", Executors.newFixedThreadPool(1), true);
+ when(mqClientInstance.getMQClientAPIImpl()).thenReturn(mqClientAPIImpl);
+ when(mqClientInstance.getMQAdminImpl()).thenReturn(mqAdminImpl);
+ when(mqClientAPIImpl.getTopicRouteInfoFromNameServer(any(), anyLong())).thenReturn(createTopicRouteData());
+ }
+
+ @Test
+ public void testExamineTopicStats() throws Exception {
+ TopicStatsTable topicStatsTable = mock(TopicStatsTable.class);
+ Map offsetTable = new ConcurrentHashMap<>();
+ offsetTable.put(new MessageQueue(), new TopicOffset());
+ when(topicStatsTable.getOffsetTable()).thenReturn(offsetTable);
+ when(mqClientAPIImpl.getTopicStatsInfo(any(), any(), anyLong())).thenReturn(topicStatsTable);
+ TopicStatsTable actual = defaultMQAdminExtImpl.examineTopicStats(defaultTopic);
+ assertNotNull(actual);
+ assertEquals(offsetTable.size(), actual.getOffsetTable().size());
+ }
+
+ @Test
+ public void testExamineTopicStatsConcurrentTopicRouteDataNull() throws Exception {
+ when(mqClientAPIImpl.getTopicRouteInfoFromNameServer(any(), anyLong())).thenReturn(null);
+ AdminToolResult actual = defaultMQAdminExtImpl.examineTopicStatsConcurrent(defaultTopic);
+ assertNotNull(actual);
+ assertEquals(200, actual.getCode());
+ assertEquals(0, actual.getData().getOffsetTable().size());
+ }
+
+ @Test
+ public void testExamineTopicStatsConcurrentBrokerDataEmpty() throws Exception {
+ TopicRouteData topicRouteData = mock(TopicRouteData.class);
+ when(topicRouteData.getBrokerDatas()).thenReturn(new ArrayList<>());
+ when(mqClientAPIImpl.getTopicRouteInfoFromNameServer(any(), anyLong())).thenReturn(topicRouteData);
+ AdminToolResult actual = defaultMQAdminExtImpl.examineTopicStatsConcurrent(defaultTopic);
+ assertNotNull(actual);
+ assertEquals(AdminToolsResultCodeEnum.SUCCESS.getCode(), actual.getCode());
+ assertEquals(0, actual.getData().getOffsetTable().size());
+ }
+
+ @Test
+ public void testExamineTopicStatsConcurrent() throws Exception {
+ CountDownLatch latch = new CountDownLatch(1);
+ doAnswer(invocation -> {
+ latch.countDown();
+ return null;
+ }).when(mqClientAPIImpl).getTopicStatsInfo(any(), any(), anyLong());
+ latch.await(1000, TimeUnit.MILLISECONDS);
+ AdminToolResult actual = defaultMQAdminExtImpl.examineTopicStatsConcurrent(defaultTopic);
+ assertNotNull(actual);
+ assertEquals(AdminToolsResultCodeEnum.SUCCESS.getCode(), actual.getCode());
+ assertEquals(0, actual.getData().getOffsetTable().size());
+ }
+
+ @Test
+ public void testExamineTopicStatsConcurrentException() throws Exception {
+ doThrow(new MQBrokerException(ResponseCode.SYSTEM_ERROR, "Test Exception")).when(mqClientAPIImpl).getTopicStatsInfo(any(), any(), anyLong());
+ assertNotNull(defaultMQAdminExtImpl.examineTopicStatsConcurrent(defaultTopic));
+ }
+
+ @Test
+ public void testExamineConsumeStatsConcurrentTopicRouteInfoNotExist() throws Exception {
+ when(mqClientAPIImpl.getTopicRouteInfoFromNameServer(any(), anyLong())).thenReturn(null);
+ AdminToolResult result = defaultMQAdminExtImpl.examineConsumeStatsConcurrent(defaultGroup, defaultTopic);
+ assertEquals(AdminToolsResultCodeEnum.TOPIC_ROUTE_INFO_NOT_EXIST.getCode(), result.getCode());
+ }
+
+ @Test
+ public void testExamineConsumeStatsConcurrent() throws Exception {
+ AtomicInteger count = new AtomicInteger(0);
+ AtomicInteger success = new AtomicInteger(0);
+ AtomicInteger fail = new AtomicInteger(0);
+ CountDownLatch latch = new CountDownLatch(10);
+ ExecutorService executorService = Executors.newFixedThreadPool(10);
+ List brokerDataList = new ArrayList<>();
+ for (int i = 0; i < 10; i++) {
+ BrokerData bd = new BrokerData();
+ bd.setBrokerName("brokerName" + i);
+ bd.setCluster(defaultCluster);
+ bd.setBrokerAddrs(createBrokerAddrs());
+ brokerDataList.add(bd);
+ }
+ TopicRouteData topicRouteData = new TopicRouteData();
+ topicRouteData.setBrokerDatas(brokerDataList);
+ for (int i = 0; i < 10; i++) {
+ executorService.submit(() -> {
+ try {
+ Thread.sleep(100);
+ if (count.incrementAndGet() % 2 == 0) {
+ success.incrementAndGet();
+ } else {
+ throw new RemotingException("Test Exception");
+ }
+ latch.countDown();
+ } catch (Exception e) {
+ fail.incrementAndGet();
+ }
+ });
+ }
+ latch.await(3000, TimeUnit.MILLISECONDS);
+ executorService.shutdown();
+ assertEquals(5, success.get());
+ assertEquals(5, fail.get());
+ assertEquals(10, count.get());
+ }
+
+ @Test
+ public void testExamineConsumeStatsConcurrentEmptyOffsetTable() throws Exception {
+ when(mqClientAPIImpl.getTopicRouteInfoFromNameServer(anyString(), anyLong())).thenReturn(createTopicRouteData());
+ when(mqClientAPIImpl.getConsumeStats(anyString(), anyString(), anyString(), anyLong())).thenReturn(new ConsumeStats());
+ AdminToolResult actual = defaultMQAdminExtImpl.examineConsumeStatsConcurrent(defaultGroup, defaultTopic);
+ assertEquals(AdminToolsResultCodeEnum.CONSUMER_NOT_ONLINE.getCode(), actual.getCode());
+ }
+
+ @Test
+ public void testViewMessageValidMsgIdReturnsMessageExt() throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
+ MessageExt expected = createMessageExt();
+ when(mqAdminImpl.viewMessage(anyString(), anyString())).thenReturn(expected);
+ when(mqClientInstance.getMQAdminImpl()).thenReturn(mqAdminImpl);
+ MessageExt actual = defaultMQAdminExtImpl.viewMessage(expected.getTopic(), expected.getMsgId());
+ assertNotNull(actual);
+ assertEquals(expected.getMsgId(), actual.getMsgId());
+ assertEquals(expected.getTopic(), actual.getTopic());
+ }
+
+ @Test
+ public void testViewMessageInvalidMsgIdQueriesByUniqKey() throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
+ MessageExt expected = createMessageExt();
+ expected.setMsgId("invalidMsgId");
+ when(mqAdminImpl.queryMessageByUniqKey(anyString(), anyString())).thenReturn(expected);
+ when(mqClientInstance.getMQAdminImpl()).thenReturn(mqAdminImpl);
+ MessageExt actual = defaultMQAdminExtImpl.viewMessage(expected.getTopic(), expected.getMsgId());
+ assertNotNull(actual);
+ assertEquals(expected.getMsgId(), actual.getMsgId());
+ assertEquals(expected.getTopic(), actual.getTopic());
+ }
+
+ @Test
+ public void testViewMessageExceptionInDecodeLogsWarningAndQueriesByUniqKey() throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
+ MessageExt expected = createMessageExt();
+ expected.setMsgId("exceptionMsgId");
+ when(mqAdminImpl.queryMessageByUniqKey(anyString(), anyString())).thenReturn(expected);
+ MessageExt actual = defaultMQAdminExtImpl.viewMessage(expected.getTopic(), expected.getMsgId());
+ assertNotNull(actual);
+ assertEquals(expected.getMsgId(), actual.getMsgId());
+ assertEquals(expected.getTopic(), actual.getTopic());
+ }
+
+ @Test
+ public void testQueryMessageInvalidMsgIdReturnsMessageExt() throws Exception {
+ MessageExt expected = createMessageExt();
+ expected.setMsgId("invalidMsgId");
+ when(mqAdminImpl.queryMessageByUniqKey(anyString(), anyString(), anyString())).thenReturn(expected);
+ MessageExt actual = defaultMQAdminExtImpl.queryMessage(defaultCluster, expected.getTopic(), expected.getMsgId());
+ assertNotNull(actual);
+ assertEquals(expected.getMsgId(), actual.getMsgId());
+ assertEquals(expected.getTopic(), actual.getTopic());
+ }
+
+ @Test
+ public void testQueryMessageRemotingException() throws MQBrokerException, RemotingException, InterruptedException, MQClientException {
+ when(mqAdminImpl.viewMessage(anyString(), anyString())).thenThrow(new RemotingException("Test Exception"));
+ assertNull(defaultMQAdminExtImpl.queryMessage(null, defaultTopic, defaultMsgId));
+ }
+
+ @Test
+ public void testDeleteTopicValidInput() throws Exception {
+ ClusterInfo clusterInfo = mock(ClusterInfo.class);
+ when(defaultMQAdminExt.examineBrokerClusterInfo()).thenReturn(clusterInfo);
+ Map> clusterAddrTable = new HashMap<>();
+ clusterAddrTable.put(defaultCluster, new HashSet<>(Arrays.asList("broker1", "broker2")));
+ when(clusterInfo.getClusterAddrTable()).thenReturn(clusterAddrTable);
+ Map brokerAddrTable = new HashMap<>();
+ BrokerData brokerData = new BrokerData();
+ brokerData.setBrokerName(defaultBroker);
+ HashMap brokerAddrs = new HashMap<>();
+ brokerAddrs.put(0L, defaultBrokerAddr);
+ brokerData.setBrokerAddrs(brokerAddrs);
+ brokerAddrTable.put(defaultBroker, brokerData);
+ when(clusterInfo.getBrokerAddrTable()).thenReturn(brokerAddrTable);
+ List nsAddrs = new ArrayList<>();
+ nsAddrs.add("127.0.0.1:9876");
+ when(mqClientAPIImpl.getNameServerAddressList()).thenReturn(nsAddrs);
+ List kvNamespaceToDeleteList = new ArrayList<>();
+ kvNamespaceToDeleteList.add("namespace");
+ FieldUtils.writeDeclaredField(defaultMQAdminExtImpl, "kvNamespaceToDeleteList", kvNamespaceToDeleteList, true);
+ defaultMQAdminExtImpl.deleteTopic(defaultTopic, defaultCluster);
+ verify(mqClientAPIImpl, times(1)).deleteTopicInBroker(any(), any(), anyLong());
+ verify(mqClientAPIImpl, times(1)).deleteTopicInNameServer(any(), any(), anyLong());
+ verify(mqClientAPIImpl, times(1)).deleteKVConfigValue(any(), any(), anyLong());
+ }
+
+ @Test
+ public void testDeleteTopicInBrokerConcurrent() throws InterruptedException, RemotingException, MQClientException {
+ Set addrs = Collections.singleton(defaultBrokerAddr);
+ doNothing().when(mqClientAPIImpl).deleteTopicInBroker(anyString(), anyString(), anyLong());
+ AdminToolResult result = defaultMQAdminExtImpl.deleteTopicInBrokerConcurrent(addrs, defaultTopic);
+ assertNotNull(result);
+ assertEquals(AdminToolsResultCodeEnum.SUCCESS.getCode(), result.getCode());
+ BrokerOperatorResult brokerResult = result.getData();
+ List successList = brokerResult.getSuccessList();
+ List failureList = brokerResult.getFailureList();
+ assertEquals(1, successList.size());
+ assertEquals(0, failureList.size());
+ assertEquals(addrs.iterator().next(), successList.get(0));
+ }
+
+ @Test
+ public void testDeleteTopicInBrokerConcurrentAllFailures() throws InterruptedException, RemotingException, MQClientException {
+ Set addrs = new HashSet<>(Collections.singleton(defaultBrokerAddr));
+ String anotherAddr = "anotherBrokerAddr:10911";
+ addrs.add(anotherAddr);
+ doThrow(new RuntimeException("deleteTopic error")).when(mqClientAPIImpl).deleteTopicInBroker(anyString(), anyString(), anyLong());
+ AdminToolResult result = defaultMQAdminExtImpl.deleteTopicInBrokerConcurrent(addrs, defaultTopic);
+ assertNotNull(result);
+ assertEquals(AdminToolsResultCodeEnum.SUCCESS.getCode(), result.getCode());
+ BrokerOperatorResult brokerResult = result.getData();
+ List successList = brokerResult.getSuccessList();
+ List failureList = brokerResult.getFailureList();
+ assertEquals(0, successList.size());
+ assertEquals(2, failureList.size());
+ assertTrue(failureList.contains(defaultBrokerAddr));
+ assertTrue(failureList.contains(anotherAddr));
+ }
+
+ @Test
+ public void testResetOffsetByTimestampOldThrowException() {
+ String topic = "nonExistentTopic";
+ long timestamp = System.currentTimeMillis();
+ assertThrows(NullPointerException.class, () -> defaultMQAdminExtImpl.resetOffsetByTimestampOld(defaultGroup, topic, timestamp, false));
+ }
+
+ @Test
+ public void testResetOffsetByTimestampOldValidInputShouldProcessCorrectly() throws Exception {
+ long timestamp = System.currentTimeMillis();
+ ConsumeStats consumeStats = mock(ConsumeStats.class);
+ Map offsetTable = new ConcurrentHashMap<>();
+ OffsetWrapper offsetWrapper = new OffsetWrapper();
+ offsetWrapper.setBrokerOffset(5L);
+ offsetWrapper.setConsumerOffset(5L);
+ offsetTable.put(new MessageQueue(defaultTopic, defaultBroker, 0), offsetWrapper);
+ when(consumeStats.getOffsetTable()).thenReturn(offsetTable);
+ when(mqClientAPIImpl.getConsumeStats(any(), any(), anyLong())).thenReturn(consumeStats);
+ List rollbackStatsList = defaultMQAdminExtImpl.resetOffsetByTimestampOld(defaultGroup, defaultTopic, timestamp, false);
+ assertNotNull(rollbackStatsList);
+ assertEquals(1, rollbackStatsList.size());
+ RollbackStats rollbackStats = rollbackStatsList.get(0);
+ assertEquals(defaultBroker, rollbackStats.getBrokerName());
+ assertEquals(0, rollbackStats.getQueueId());
+ assertEquals(5L, rollbackStats.getBrokerOffset());
+ assertEquals(5L, rollbackStats.getConsumerOffset());
+ }
+
+ @Test
+ public void testResetOffsetNew() throws Exception {
+ defaultMQAdminExtImpl.resetOffsetNew(defaultGroup, defaultTopic, timeoutMillis);
+ verify(mqClientAPIImpl, times(1)).invokeBrokerToResetOffset(
+ anyString(),
+ anyString(),
+ anyString(),
+ anyLong(),
+ anyBoolean(),
+ anyLong(),
+ anyBoolean());
+ }
+
+ @Test
+ public void testResetOffsetNewConcurrent() {
+ AdminToolResult actual = defaultMQAdminExtImpl.resetOffsetNewConcurrent(defaultGroup, defaultTopic, timeoutMillis);
+ assertEquals(AdminToolsResultCodeEnum.SUCCESS.getCode(), actual.getCode());
+ }
+
+ @Test
+ public void testResetOffsetNewConcurrentTopicRouteInfoNotExist() throws Exception {
+ when(mqClientAPIImpl.getTopicRouteInfoFromNameServer(any(), anyLong())).thenReturn(null);
+ AdminToolResult actual = defaultMQAdminExtImpl.resetOffsetNewConcurrent(defaultGroup, defaultTopic, timeoutMillis);
+ assertEquals(AdminToolsResultCodeEnum.TOPIC_ROUTE_INFO_NOT_EXIST.getCode(), actual.getCode());
+ }
+
+ @Test
+ public void testResetOffsetNewConcurrentException() throws Exception {
+ when(mqClientAPIImpl.getTopicRouteInfoFromNameServer(any(), anyLong())).thenThrow(new MQClientException(ResponseCode.SYSTEM_ERROR, "Test Exception"));
+ AdminToolResult actual = defaultMQAdminExtImpl.resetOffsetNewConcurrent(defaultGroup, defaultTopic, timeoutMillis);
+ assertEquals(AdminToolsResultCodeEnum.MQ_CLIENT_ERROR.getCode(), actual.getCode());
+ }
+
+ @Test
+ public void testCreateOrUpdateOrderConfClusterConfig() throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
+ String key = "key1";
+ String value = "value1";
+ doNothing().when(mqClientAPIImpl).putKVConfigValue(anyString(), anyString(), anyString(), anyLong());
+ defaultMQAdminExtImpl.createOrUpdateOrderConf(key, value, true);
+ verify(mqClientAPIImpl, times(1)).putKVConfigValue(anyString(), anyString(), anyString(), anyLong());
+ }
+
+ @Test
+ public void testCreateOrUpdateOrderConfNonClusterConfig() throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
+ String key = "key1";
+ String value = "value1:value2";
+ String oldOrderConfs = "key1:value1;key2:value2";
+ when(mqClientAPIImpl.getKVConfigValue(anyString(), anyString(), anyLong())).thenReturn(oldOrderConfs);
+ doNothing().when(mqClientAPIImpl).putKVConfigValue(anyString(), anyString(), anyString(), anyLong());
+ defaultMQAdminExtImpl.createOrUpdateOrderConf(key, value, false);
+ verify(mqClientAPIImpl, times(1)).putKVConfigValue(anyString(), anyString(), anyString(), anyLong());
+ }
+
+ @Test
+ public void testCreateOrUpdateOrderConfExceptionInPut() throws RemotingException, InterruptedException, MQClientException {
+ String key = "key1";
+ String value = "value1:value2";
+ String oldOrderConfs = "key1:value1;key2:value2";
+ when(mqClientAPIImpl.getKVConfigValue(anyString(), anyString(), anyLong())).thenReturn(oldOrderConfs);
+ doThrow(new RemotingException("Test Exception")).when(mqClientAPIImpl).putKVConfigValue(anyString(), anyString(), anyString(), anyLong());
+ assertThrows(RemotingException.class, () -> defaultMQAdminExtImpl.createOrUpdateOrderConf(key, value, false));
+ }
+
+ @Test
+ public void testCreateOrUpdateOrderConfNoOldConfs() throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
+ String key = "key1";
+ String value = "value1:value2";
+ when(mqClientAPIImpl.getKVConfigValue(anyString(), anyString(), anyLong())).thenReturn(null);
+ doNothing().when(mqClientAPIImpl).putKVConfigValue(anyString(), anyString(), anyString(), anyLong());
+ defaultMQAdminExtImpl.createOrUpdateOrderConf(key, value, false);
+ verify(mqClientAPIImpl, times(1)).putKVConfigValue(anyString(), anyString(), anyString(), anyLong());
+ }
+
+ @Test
+ public void testCreateOrUpdateOrderConfExceptionInGet() throws RemotingException, InterruptedException, MQClientException, MQBrokerException {
+ String key = "key1";
+ String value = "value1:value2";
+ when(mqClientAPIImpl.getKVConfigValue(anyString(), anyString(), anyLong())).thenThrow(new RemotingException("Test Exception"));
+ defaultMQAdminExtImpl.createOrUpdateOrderConf(key, value, false);
+ verify(mqClientAPIImpl, times(1)).getKVConfigValue(anyString(), anyString(), anyLong());
+ }
+
+ @Test
+ public void testQuerySubscriptionValidInput() throws InterruptedException, MQBrokerException, RemotingException, MQClientException {
+ when(mqClientAPIImpl.querySubscriptionByConsumer(anyString(), anyString(), anyString(), anyLong())).thenReturn(new SubscriptionData());
+ assertNotNull(defaultMQAdminExtImpl.querySubscription("group", "topic"));
+ }
+
+ @Test
+ public void testQueryTopicsByConsumer() throws Exception {
+ TopicList expected = new TopicList();
+ expected.getTopicList().add(defaultTopic);
+ when(mqClientAPIImpl.queryTopicsByConsumer(anyString(), anyString(), anyLong())).thenReturn(expected);
+ TopicList actual = defaultMQAdminExtImpl.queryTopicsByConsumer(defaultGroup);
+ assertEquals(1, actual.getTopicList().size());
+ assertEquals(expected.getTopicList().iterator().next(), actual.getTopicList().iterator().next());
+ verify(mqClientAPIImpl, times(1)).queryTopicsByConsumer(anyString(), anyString(), anyLong());
+ }
+
+ @Test
+ public void testQueryTopicsByConsumerRemotingTimeoutException() throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQBrokerException, InterruptedException {
+ when(mqClientAPIImpl.queryTopicsByConsumer(anyString(), anyString(), anyLong())).thenThrow(new RemotingTimeoutException("Test Exception"));
+ assertThrows(RemotingTimeoutException.class, () -> defaultMQAdminExtImpl.queryTopicsByConsumer(defaultGroup));
+ verify(mqClientAPIImpl, times(1)).queryTopicsByConsumer(anyString(), anyString(), anyLong());
+ }
+
+ @Test
+ public void testQueryTopicsByConsumerMQBrokerException() throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQBrokerException, InterruptedException {
+ when(mqClientAPIImpl.queryTopicsByConsumer(anyString(), anyString(), anyLong())).thenThrow(new MQBrokerException(ResponseCode.SYSTEM_ERROR, "Test Exception"));
+ assertThrows(MQBrokerException.class, () -> defaultMQAdminExtImpl.queryTopicsByConsumer(defaultGroup));
+ verify(mqClientAPIImpl, times(1)).queryTopicsByConsumer(anyString(), anyString(), anyLong());
+ }
+
+ @Test
+ public void testQueryTopicsByConsumerMQClientException() throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQBrokerException, InterruptedException {
+ when(mqClientAPIImpl.queryTopicsByConsumer(anyString(), anyString(), anyLong())).thenThrow(new MQBrokerException(ResponseCode.SYSTEM_ERROR, "Test Exception"));
+ assertThrows(MQBrokerException.class, () -> defaultMQAdminExtImpl.queryTopicsByConsumer(defaultGroup));
+ verify(mqClientAPIImpl, times(1)).queryTopicsByConsumer(anyString(), anyString(), anyLong());
+ }
+
+ @Test
+ public void testQueryTopicsByConsumerNoBrokers() throws Exception {
+ TopicRouteData topicRouteData = new TopicRouteData();
+ topicRouteData.setBrokerDatas(new ArrayList<>());
+ when(mqClientAPIImpl.getTopicRouteInfoFromNameServer(any(), anyLong())).thenReturn(topicRouteData);
+ TopicList actual = defaultMQAdminExtImpl.queryTopicsByConsumer(defaultGroup);
+ assertEquals(0, actual.getTopicList().size());
+ }
+
+ @Test
+ public void testQueryTopicsByConsumerConcurrentTopicRouteDataNull() throws Exception {
+ when(mqClientAPIImpl.getTopicRouteInfoFromNameServer(any(), anyLong())).thenReturn(null);
+ AdminToolResult actual = defaultMQAdminExtImpl.queryTopicsByConsumerConcurrent(defaultGroup);
+ assertEquals(AdminToolsResultCodeEnum.TOPIC_ROUTE_INFO_NOT_EXIST.getCode(), actual.getCode());
+ assertEquals("router info not found.", actual.getErrorMsg());
+ }
+
+ @Test
+ public void testQueryTopicsByConsumerConcurrentNoBrokers() throws Exception {
+ TopicRouteData topicRouteData = new TopicRouteData();
+ topicRouteData.setBrokerDatas(new ArrayList<>());
+ when(mqClientAPIImpl.getTopicRouteInfoFromNameServer(any(), anyLong())).thenReturn(topicRouteData);
+ AdminToolResult actual = defaultMQAdminExtImpl.queryTopicsByConsumerConcurrent(defaultGroup);
+ assertEquals(AdminToolsResultCodeEnum.TOPIC_ROUTE_INFO_NOT_EXIST.getCode(), actual.getCode());
+ assertEquals("router info not found.", actual.getErrorMsg());
+ }
+
+ @Test
+ public void testQueryTopicsByConsumerConcurrent() throws Exception {
+ TopicList expectedTopicList = new TopicList();
+ expectedTopicList.setTopicList(new HashSet<>(Arrays.asList(defaultTopic, "topic2")));
+ when(mqClientAPIImpl.queryTopicsByConsumer(any(), any(), anyLong())).thenReturn(expectedTopicList);
+ AdminToolResult result = defaultMQAdminExtImpl.queryTopicsByConsumerConcurrent(defaultGroup);
+ assertEquals(AdminToolsResultCodeEnum.SUCCESS.getCode(), result.getCode());
+ Set actual = result.getData().getTopicList();
+ assertFalse(actual.isEmpty());
+ assertTrue(actual.containsAll(expectedTopicList.getTopicList()));
+ }
+
+ @Test
+ public void testQueryConsumeTimeSpanConcurrentTopicRouteDataNull() throws Exception {
+ when(mqClientAPIImpl.getTopicRouteInfoFromNameServer(anyString(), anyLong())).thenReturn(null);
+ AdminToolResult> actual = defaultMQAdminExtImpl.queryConsumeTimeSpanConcurrent(defaultTopic, defaultGroup);
+ assertEquals(AdminToolsResultCodeEnum.SUCCESS.getCode(), actual.getCode());
+ assertEquals(0, actual.getData().size());
+ }
+
+ @Test
+ public void testQueryConsumeTimeSpanConcurrentNoBrokers() throws Exception {
+ TopicRouteData topicRouteData = new TopicRouteData();
+ topicRouteData.setBrokerDatas(new ArrayList<>());
+ when(mqClientAPIImpl.getTopicRouteInfoFromNameServer(anyString(), anyLong())).thenReturn(topicRouteData);
+ AdminToolResult> actual = defaultMQAdminExtImpl.queryConsumeTimeSpanConcurrent(defaultTopic, defaultGroup);
+ assertEquals(AdminToolsResultCodeEnum.SUCCESS.getCode(), actual.getCode());
+ assertEquals(0, actual.getData().size());
+ }
+
+ @Test
+ public void testQueryConsumeTimeSpanConcurrent() throws Exception {
+ List spans = new ArrayList<>();
+ QueueTimeSpan queueTimeSpan = new QueueTimeSpan();
+ queueTimeSpan.setMinTimeStamp(1000L);
+ queueTimeSpan.setMaxTimeStamp(2000L);
+ spans.add(queueTimeSpan);
+ when(mqClientAPIImpl.queryConsumeTimeSpan(anyString(), anyString(), anyString(), anyLong())).thenReturn(spans);
+ AdminToolResult> actual = defaultMQAdminExtImpl.queryConsumeTimeSpanConcurrent(defaultTopic, defaultGroup);
+ assertEquals(AdminToolsResultCodeEnum.SUCCESS.getCode(), actual.getCode());
+ assertEquals(1, actual.getData().size());
+ }
+
+ @Test
+ public void testDeleteExpiredCommitLog() throws Exception {
+ ClusterInfo clusterInfo = mock(ClusterInfo.class);
+ when(clusterInfo.retrieveAllAddrByCluster(defaultCluster)).thenReturn(new String[]{"addr1", "addr2"});
+ when(mqClientAPIImpl.getBrokerClusterInfo(anyLong())).thenReturn(clusterInfo);
+ when(mqClientAPIImpl.deleteExpiredCommitLog(anyString(), anyLong())).thenReturn(true);
+ boolean actual = defaultMQAdminExtImpl.deleteExpiredCommitLog(defaultCluster);
+ assertTrue(actual);
+ verify(mqClientAPIImpl, times(2)).deleteExpiredCommitLog(anyString(), anyLong());
+ }
+
+ @Test
+ public void testDeleteExpiredCommitLogByCluster() throws Exception {
+ ClusterInfo clusterInfo = mock(ClusterInfo.class);
+ when(clusterInfo.retrieveAllAddrByCluster(defaultCluster)).thenReturn(new String[]{"addr1", "addr2"});
+ when(mqClientAPIImpl.deleteExpiredCommitLog(anyString(), anyLong())).thenReturn(true);
+ boolean actual = defaultMQAdminExtImpl.deleteExpiredCommitLogByCluster(clusterInfo, defaultCluster);
+ assertTrue(actual);
+ verify(mqClientAPIImpl, times(2)).deleteExpiredCommitLog(anyString(), anyLong());
+ }
+
+ @Test
+ public void testDeleteExpiredCommitLogByAddr() throws Exception {
+ when(mqClientAPIImpl.deleteExpiredCommitLog(defaultBrokerAddr, timeoutMillis)).thenReturn(true);
+ boolean actual = defaultMQAdminExtImpl.deleteExpiredCommitLogByAddr(defaultBrokerAddr);
+ assertTrue(actual);
+ verify(mqClientAPIImpl, times(1)).deleteExpiredCommitLog(defaultBrokerAddr, timeoutMillis);
+ }
+
+ @Test
+ public void testConsumeMessageDirectly() throws Exception {
+ String clientId = "clientId";
+ MessageExt messageExt = createMessageExt();
+ when(mqAdminImpl.viewMessage(defaultTopic, defaultMsgId)).thenReturn(messageExt);
+ ConsumeMessageDirectlyResult consumeMessageDirectlyResult = mock(ConsumeMessageDirectlyResult.class);
+ when(mqClientAPIImpl.consumeMessageDirectly(
+ anyString(),
+ anyString(),
+ anyString(),
+ anyString(),
+ anyString(),
+ anyLong()))
+ .thenReturn(consumeMessageDirectlyResult);
+ ConsumeMessageDirectlyResult actual = defaultMQAdminExtImpl.consumeMessageDirectly(defaultGroup, clientId, defaultTopic, defaultMsgId);
+ assertNotNull(actual);
+ assertNull(actual.getRemark());
+ assertFalse(actual.isAutoCommit());
+ assertFalse(actual.isOrder());
+ }
+
+ @Test
+ public void testMessageTrackDetailConcurrent() throws Exception {
+ MessageExt messageExt = createMessageExt();
+ GroupList groupList = mock(GroupList.class);
+ HashSet groupSet = new HashSet<>();
+ groupSet.add(defaultGroup);
+ when(groupList.getGroupList()).thenReturn(groupSet);
+ when(mqClientAPIImpl.queryTopicConsumeByWho(anyString(), anyString(), anyLong())).thenReturn(groupList);
+ ConsumerConnection consumerConnection = mock(ConsumerConnection.class);
+ when(mqClientAPIImpl.getConsumerConnectionList(anyString(), anyString(), anyLong())).thenReturn(consumerConnection);
+ List actual = defaultMQAdminExtImpl.messageTrackDetailConcurrent(messageExt);
+ assertEquals(1, actual.size());
+ }
+
+// @Test
+// public void testConsumedConcurrent() throws Exception {
+// ConsumeStats consumeStats = mock(ConsumeStats.class);
+// ClusterInfo ci = mock(ClusterInfo.class);
+// Map brokerAddrTable = new HashMap<>();
+// BrokerData brokerData = mock(BrokerData.class);
+// HashMap brokerAddress = new HashMap<>();
+// brokerAddress.put(0L, defaultBrokerAddr);
+// when(brokerData.getBrokerAddrs()).thenReturn(brokerAddress);
+// brokerAddrTable.put(defaultBroker, brokerData);
+// when(ci.getBrokerAddrTable()).thenReturn(brokerAddrTable);
+// Map offsetTable = new HashMap<>();
+// OffsetWrapper offsetWrapper = new OffsetWrapper();
+// offsetWrapper.setConsumerOffset(1L);
+// offsetTable.put(new MessageQueue(defaultTopic, defaultBroker, 0), offsetWrapper);
+// when(consumeStats.getOffsetTable()).thenReturn(offsetTable);
+//// when(mqClientAPIImpl.getConsumeStats(any(), any(), any(), anyLong())).thenReturn(consumeStats);
+// when(mqClientAPIImpl.getBrokerClusterInfo(anyLong())).thenReturn(ci);
+//// assertTrue(defaultMQAdminExtImpl.consumedConcurrent(createMessageExt(), defaultGroup));
+// }
+
+ @Test
+ public void testCloneGroupOffsetValidInput() throws RemotingException, MQClientException, InterruptedException, MQBrokerException {
+ String srcGroup = "srcGroup";
+ String destGroup = "destGroup";
+ boolean isOffline = false;
+ defaultMQAdminExtImpl.cloneGroupOffset(srcGroup, destGroup, defaultTopic, isOffline);
+ verify(mqClientAPIImpl, times(1)).cloneGroupOffset(
+ anyString(),
+ anyString(),
+ anyString(),
+ anyString(),
+ anyBoolean(),
+ anyLong());
+ }
+
+ @Test
+ public void testGetUserSubscriptionGroup() throws Exception {
+ SubscriptionGroupWrapper subscriptionGroupWrapper = new SubscriptionGroupWrapper();
+ ConcurrentMap subscriptionGroupTable = new ConcurrentHashMap<>();
+ SubscriptionGroupConfig groupConfig1 = new SubscriptionGroupConfig();
+ groupConfig1.setGroupName("CID_RMQ_SYS_GROUP");
+ SubscriptionGroupConfig groupConfig2 = new SubscriptionGroupConfig();
+ groupConfig2.setGroupName("DEFAULT_CONSUMER");
+ SubscriptionGroupConfig groupConfig3 = new SubscriptionGroupConfig();
+ groupConfig3.setGroupName("SYS_CONSUMER_GROUP");
+ subscriptionGroupTable.put(groupConfig1.getGroupName(), groupConfig1);
+ subscriptionGroupTable.put(groupConfig2.getGroupName(), groupConfig2);
+ subscriptionGroupTable.put(groupConfig3.getGroupName(), groupConfig3);
+ subscriptionGroupWrapper.setSubscriptionGroupTable(subscriptionGroupTable);
+ when(mqClientAPIImpl.getAllSubscriptionGroup(any(), anyLong())).thenReturn(subscriptionGroupWrapper);
+ SubscriptionGroupWrapper actual = defaultMQAdminExtImpl.getUserSubscriptionGroup(defaultBrokerAddr, timeoutMillis);
+ assertEquals(1, actual.getSubscriptionGroupTable().size());
+ assertTrue(actual.getSubscriptionGroupTable().containsKey("SYS_CONSUMER_GROUP"));
+ }
+
+ @Test
+ public void testGetUserTopicConfig() throws Exception {
+ TopicConfigSerializeWrapper topicConfigSerializeWrapper = new TopicConfigSerializeWrapper();
+ ConcurrentMap topicConfigMap = new ConcurrentHashMap<>();
+ topicConfigMap.put("Topic1", new TopicConfig("Topic1", 1, 1, 0));
+ topicConfigMap.put("Topic2", new TopicConfig("Topic2", 1, 1, 1));
+ topicConfigSerializeWrapper.setTopicConfigTable(topicConfigMap);
+ TopicList topicList = new TopicList();
+ Set topicSet = new HashSet<>();
+ topicSet.add("Topic2");
+ topicList.setTopicList(topicSet);
+ when(mqClientAPIImpl.getAllTopicConfig(any(), anyLong())).thenReturn(topicConfigSerializeWrapper);
+ when(mqClientAPIImpl.getSystemTopicListFromBroker(anyString(), anyLong())).thenReturn(topicList);
+ TopicConfigSerializeWrapper actual = defaultMQAdminExtImpl.getUserTopicConfig("brokerAddr", false, timeoutMillis);
+ assertEquals(1, actual.getTopicConfigTable().size());
+ }
+
+ @Test
+ public void testUpdateConsumeOffset() throws Exception {
+ doNothing().when(mqClientAPIImpl).updateConsumerOffset(any(), any(UpdateConsumerOffsetRequestHeader.class), anyLong());
+ defaultMQAdminExtImpl.updateConsumeOffset(defaultBrokerAddr, defaultGroup, createMessageQueue(), 1L);
+ verify(mqClientAPIImpl, times(1)).updateConsumerOffset(any(), any(UpdateConsumerOffsetRequestHeader.class), anyLong());
+ }
+
+ @Test
+ public void testUpdateConsumeOffsetException() throws MQBrokerException, RemotingException, InterruptedException {
+ doThrow(new RemotingException("Test exception")).when(mqClientAPIImpl).updateConsumerOffset(anyString(), any(UpdateConsumerOffsetRequestHeader.class), anyLong());
+ assertThrows(RemotingException.class,
+ () -> defaultMQAdminExtImpl.updateConsumeOffset(defaultBrokerAddr, defaultGroup, createMessageQueue(), 1L));
+ }
+
+ @Test
+ public void testResetOffsetByQueueId() throws Exception {
+ long resetOffset = 100;
+ doNothing().when(mqClientAPIImpl).updateConsumerOffset(any(), any(UpdateConsumerOffsetRequestHeader.class), anyLong());
+ Map result = new HashMap<>();
+ result.put(createMessageQueue(), resetOffset);
+ when(mqClientAPIImpl.invokeBrokerToResetOffset(anyString(), anyString(), anyString(), anyLong(), anyInt(), anyLong(), anyLong())).thenReturn(result);
+ defaultMQAdminExtImpl.resetOffsetByQueueId(defaultBrokerAddr, defaultGroup, defaultTopic, 0, resetOffset);
+ verify(mqClientAPIImpl, times(1)).updateConsumerOffset(any(), any(UpdateConsumerOffsetRequestHeader.class), anyLong());
+ verify(mqClientAPIImpl, times(1)).invokeBrokerToResetOffset(
+ anyString(),
+ anyString(),
+ anyString(),
+ anyLong(),
+ anyInt(),
+ anyLong(),
+ anyLong());
+ }
+
+ @Test
+ public void testResetOffsetByQueueIdThrowsException() throws MQBrokerException, RemotingException, InterruptedException, MQClientException {
+ doNothing().when(mqClientAPIImpl).updateConsumerOffset(any(), any(UpdateConsumerOffsetRequestHeader.class), anyLong());
+ when(mqClientAPIImpl.invokeBrokerToResetOffset(
+ anyString(),
+ anyString(),
+ anyString(),
+ anyLong(),
+ anyInt(),
+ anyLong(),
+ anyLong()))
+ .thenThrow(new MQClientException(1, "Exception"));
+ assertThrows(MQBrokerException.class,
+ () -> defaultMQAdminExtImpl.resetOffsetByQueueId(defaultBrokerAddr, defaultGroup, defaultTopic, 0, 100));
+ }
+
+ @Test
+ public void testUpdateAndGetGroupReadForbidden() throws RemotingException, InterruptedException, MQBrokerException {
+ boolean readable = true;
+ GroupForbidden expectedResponse = new GroupForbidden();
+ expectedResponse.setGroup(defaultGroup);
+ expectedResponse.setTopic(defaultTopic);
+ expectedResponse.setReadable(readable);
+ when(mqClientAPIImpl.updateAndGetGroupForbidden(any(), any(UpdateGroupForbiddenRequestHeader.class), anyLong())).thenReturn(expectedResponse);
+ GroupForbidden actual = defaultMQAdminExtImpl.updateAndGetGroupReadForbidden(defaultBrokerAddr, defaultGroup, defaultTopic, readable);
+ assertNotNull(actual);
+ assertEquals(defaultGroup, actual.getGroup());
+ assertEquals(defaultTopic, actual.getTopic());
+ assertEquals(readable, actual.getReadable());
+ }
+
+ @Test
+ public void testUpdateAndGetGroupReadForbiddenException() throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQBrokerException, InterruptedException {
+ when(mqClientAPIImpl.updateAndGetGroupForbidden(any(), any(UpdateGroupForbiddenRequestHeader.class), anyLong()))
+ .thenThrow(new MQBrokerException(ResponseCode.SYSTEM_ERROR, "Test Exception"));
+ assertThrows(MQBrokerException.class,
+ () -> defaultMQAdminExtImpl.updateAndGetGroupReadForbidden(defaultBrokerAddr, defaultGroup, defaultTopic, true));
+ }
+
+ private HashMap createBrokerAddrs() {
+ HashMap result = new HashMap<>();
+ result.put(0L, defaultBrokerAddr);
+ return result;
+ }
+
+ private TopicRouteData createTopicRouteData() {
+ BrokerData bd = new BrokerData(defaultCluster, defaultBroker, new HashMap<>());
+ bd.setBrokerAddrs(new HashMap<>());
+ bd.getBrokerAddrs().put(0L, defaultBrokerAddr);
+ QueueData qd = new QueueData();
+ qd.setBrokerName(defaultBroker);
+ qd.setPerm(PermName.PERM_WRITE);
+ qd.setReadQueueNums(1);
+ qd.setTopicSysFlag(0);
+ qd.setWriteQueueNums(1);
+ TopicRouteData result = new TopicRouteData();
+ result.getBrokerDatas().add(bd);
+ result.getQueueDatas().add(qd);
+ return result;
+ }
+
+ private MessageQueue createMessageQueue() {
+ return new MessageQueue(defaultTopic, defaultBroker, 0);
+ }
+
+ private MessageExt createMessageExt() {
+ MessageExt result = new MessageExt();
+ result.setMsgId(defaultMsgId);
+ result.setTopic(defaultTopic);
+ result.setQueueId(0);
+ InetAddress inetAddress = mock(InetAddress.class);
+ InetSocketAddress address = new InetSocketAddress(inetAddress, 10911);
+ when(inetAddress.getHostAddress()).thenReturn("127.0.0.1");
+ result.setStoreHost(address);
+ return result;
+ }
+}
diff --git a/tools/src/test/java/org/apache/rocketmq/tools/command/connection/ConsumerConnectionSubCommandTest.java b/tools/src/test/java/org/apache/rocketmq/tools/command/connection/ConsumerConnectionSubCommandTest.java
index f5967f5a30..a2ad8c5d85 100644
--- a/tools/src/test/java/org/apache/rocketmq/tools/command/connection/ConsumerConnectionSubCommandTest.java
+++ b/tools/src/test/java/org/apache/rocketmq/tools/command/connection/ConsumerConnectionSubCommandTest.java
@@ -16,7 +16,6 @@
*/
package org.apache.rocketmq.tools.command.connection;
-import java.util.HashSet;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
@@ -30,7 +29,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import static org.mockito.Mockito.mock;
+import java.util.HashSet;
public class ConsumerConnectionSubCommandTest {
private ServerResponseMocker brokerMocker;
@@ -62,7 +61,7 @@ public class ConsumerConnectionSubCommandTest {
private ServerResponseMocker startOneBroker() {
ConsumerConnection consumerConnection = new ConsumerConnection();
HashSet connectionSet = new HashSet<>();
- Connection connection = mock(Connection.class);
+ Connection connection = new Connection();
connectionSet.add(connection);
consumerConnection.setConnectionSet(connectionSet);
// start broker
diff --git a/tools/src/test/java/org/apache/rocketmq/tools/command/connection/ProducerConnectionSubCommandTest.java b/tools/src/test/java/org/apache/rocketmq/tools/command/connection/ProducerConnectionSubCommandTest.java
index 672e4113d6..812edde9e0 100644
--- a/tools/src/test/java/org/apache/rocketmq/tools/command/connection/ProducerConnectionSubCommandTest.java
+++ b/tools/src/test/java/org/apache/rocketmq/tools/command/connection/ProducerConnectionSubCommandTest.java
@@ -16,7 +16,6 @@
*/
package org.apache.rocketmq.tools.command.connection;
-import java.util.HashSet;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
@@ -30,7 +29,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import static org.mockito.Mockito.mock;
+import java.util.HashSet;
public class ProducerConnectionSubCommandTest {
@@ -64,7 +63,7 @@ public class ProducerConnectionSubCommandTest {
private ServerResponseMocker startOneBroker() {
ProducerConnection producerConnection = new ProducerConnection();
HashSet connectionSet = new HashSet<>();
- Connection connection = mock(Connection.class);
+ Connection connection = new Connection();
connectionSet.add(connection);
producerConnection.setConnectionSet(connectionSet);
diff --git a/tools/src/test/java/org/apache/rocketmq/tools/command/consumer/ConsumerStatusSubCommandTest.java b/tools/src/test/java/org/apache/rocketmq/tools/command/consumer/ConsumerStatusSubCommandTest.java
index 4651113c68..9f4da15fa3 100644
--- a/tools/src/test/java/org/apache/rocketmq/tools/command/consumer/ConsumerStatusSubCommandTest.java
+++ b/tools/src/test/java/org/apache/rocketmq/tools/command/consumer/ConsumerStatusSubCommandTest.java
@@ -16,7 +16,6 @@
*/
package org.apache.rocketmq.tools.command.consumer;
-import java.util.HashSet;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
@@ -30,7 +29,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import static org.mockito.Mockito.mock;
+import java.util.HashSet;
public class ConsumerStatusSubCommandTest {
@@ -65,7 +64,7 @@ public class ConsumerStatusSubCommandTest {
private ServerResponseMocker startOneBroker() {
ConsumerConnection consumerConnection = new ConsumerConnection();
HashSet connectionSet = new HashSet<>();
- Connection connection = mock(Connection.class);
+ Connection connection = new Connection();
connectionSet.add(connection);
consumerConnection.setConnectionSet(connectionSet);
// start broker
diff --git a/tools/src/test/java/org/apache/rocketmq/tools/command/consumer/GetConsumerConfigSubCommandTest.java b/tools/src/test/java/org/apache/rocketmq/tools/command/consumer/GetConsumerConfigSubCommandTest.java
index e4e5e970c6..7ff4c42851 100644
--- a/tools/src/test/java/org/apache/rocketmq/tools/command/consumer/GetConsumerConfigSubCommandTest.java
+++ b/tools/src/test/java/org/apache/rocketmq/tools/command/consumer/GetConsumerConfigSubCommandTest.java
@@ -16,9 +16,6 @@
*/
package org.apache.rocketmq.tools.command.consumer;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
@@ -33,7 +30,9 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import static org.mockito.Mockito.mock;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
public class GetConsumerConfigSubCommandTest {
@@ -91,7 +90,7 @@ public class GetConsumerConfigSubCommandTest {
private ServerResponseMocker startOneBroker() {
ConsumerConnection consumerConnection = new ConsumerConnection();
HashSet connectionSet = new HashSet<>();
- Connection connection = mock(Connection.class);
+ Connection connection = new Connection();
connectionSet.add(connection);
consumerConnection.setConnectionSet(connectionSet);
// start broker
diff --git a/tools/src/test/java/org/apache/rocketmq/tools/command/producer/ProducerSubCommandTest.java b/tools/src/test/java/org/apache/rocketmq/tools/command/producer/ProducerSubCommandTest.java
index 7039c05fba..b1ebb924e7 100644
--- a/tools/src/test/java/org/apache/rocketmq/tools/command/producer/ProducerSubCommandTest.java
+++ b/tools/src/test/java/org/apache/rocketmq/tools/command/producer/ProducerSubCommandTest.java
@@ -17,13 +17,12 @@
package org.apache.rocketmq.tools.command.producer;
-import java.util.HashMap;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
-import org.apache.rocketmq.common.message.MessageQueue;
-import org.apache.rocketmq.remoting.protocol.admin.ConsumeStats;
-import org.apache.rocketmq.remoting.protocol.admin.OffsetWrapper;
+import org.apache.rocketmq.remoting.protocol.LanguageCode;
+import org.apache.rocketmq.remoting.protocol.body.ProducerInfo;
+import org.apache.rocketmq.remoting.protocol.body.ProducerTableInfo;
import org.apache.rocketmq.srvutil.ServerUtil;
import org.apache.rocketmq.tools.command.SubCommandException;
import org.apache.rocketmq.tools.command.server.NameServerMocker;
@@ -32,6 +31,10 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
public class ProducerSubCommandTest {
private ServerResponseMocker brokerMocker;
@@ -61,21 +64,16 @@ public class ProducerSubCommandTest {
}
private ServerResponseMocker startOneBroker() {
- ConsumeStats consumeStats = new ConsumeStats();
- HashMap offsetTable = new HashMap<>();
- MessageQueue messageQueue = new MessageQueue();
- messageQueue.setBrokerName("mockBrokerName");
- messageQueue.setQueueId(1);
- messageQueue.setBrokerName("mockTopicName");
+ ProducerTableInfo producerTableInfo = new ProducerTableInfo(new HashMap<>());
+ List producerInfo = new ArrayList<>();
+ producerInfo.add(new ProducerInfo(
+ "xxxx-client-id",
+ "127.0.0.1:18978",
+ LanguageCode.JAVA,
+ 400,
+ System.currentTimeMillis()));
- OffsetWrapper offsetWrapper = new OffsetWrapper();
- offsetWrapper.setBrokerOffset(1);
- offsetWrapper.setConsumerOffset(1);
- offsetWrapper.setLastTimestamp(System.currentTimeMillis());
-
- offsetTable.put(messageQueue, offsetWrapper);
- consumeStats.setOffsetTable(offsetTable);
- // start broker
- return ServerResponseMocker.startServer(consumeStats.encode());
+ producerTableInfo.getData().put("mockTopicName", producerInfo);
+ return ServerResponseMocker.startServer(producerTableInfo.encode());
}
}