This is an automated email from the ASF dual-hosted git repository.
gosonzhang pushed a commit to branch TUBEMQ-570
in repository https://gitbox.apache.org/repos/asf/incubator-inlong.git
The following commit(s) were added to refs/heads/TUBEMQ-570 by this push:
new 797da0a [INLONG-611] Add FSM for broker configure manage
797da0a is described below
commit 797da0a69b77d35609d9e2714e14be56799a5c7e
Author: gosonzhang <[email protected]>
AuthorDate: Sun May 9 11:00:49 2021 +0800
[INLONG-611] Add FSM for broker configure manage
---
.../client/consumer/ConsumerSamplePrint.java | 9 +
.../tubemq/corebase/utils/AbstractSamplePrint.java | 5 +
.../org/apache/tubemq/corebase/utils/Tuple2.java | 3 +-
.../org/apache/tubemq/corebase/utils/Tuple3.java | 10 +-
.../corebase/utils/{Tuple3.java => Tuple4.java} | 26 +-
.../server/broker/utils/BrokerSamplePrint.java | 9 +
.../server/broker/utils/DiskSamplePrint.java | 9 +
.../tubemq/server/common/statusdef/StepStatus.java | 64 ++++
.../org/apache/tubemq/server/master/TMaster.java | 18 +-
.../server/master/metamanage/MetaDataManager.java | 57 +++-
.../nodemanage/nodebroker/BrokerPSInfoHolder.java | 181 ++++++++++
.../nodemanage/nodebroker/BrokerRunManager.java | 59 ++++
.../nodemanage/nodebroker/BrokerRunStatusInfo.java | 357 ++++++++++++++++++++
.../nodemanage/nodebroker/BrokerSyncData.java | 322 ++++++++++++++++++
.../nodemanage/nodebroker/BrokerTopicInfoView.java | 372 +++++++++++++++++++++
.../nodemanage/nodebroker/TargetValidResult.java | 32 --
.../server/master/utils/BdbStoreSamplePrint.java | 9 +
.../master/utils/BrokerStatusSamplePrint.java | 82 +++++
18 files changed, 1556 insertions(+), 68 deletions(-)
diff --git
a/tubemq-client/src/main/java/org/apache/tubemq/client/consumer/ConsumerSamplePrint.java
b/tubemq-client/src/main/java/org/apache/tubemq/client/consumer/ConsumerSamplePrint.java
index 0aadf2e..8d6911f 100644
---
a/tubemq-client/src/main/java/org/apache/tubemq/client/consumer/ConsumerSamplePrint.java
+++
b/tubemq-client/src/main/java/org/apache/tubemq/client/consumer/ConsumerSamplePrint.java
@@ -71,4 +71,13 @@ public class ConsumerSamplePrint extends AbstractSamplePrint
{
//
}
+ @Override
+ public void printWarn(String err) {
+ //
+ }
+
+ @Override
+ public void printError(String err) {
+ //
+ }
}
diff --git
a/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/AbstractSamplePrint.java
b/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/AbstractSamplePrint.java
index f009245..34f132f 100644
---
a/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/AbstractSamplePrint.java
+++
b/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/AbstractSamplePrint.java
@@ -51,4 +51,9 @@ public abstract class AbstractSamplePrint {
public abstract void printExceptionCaught(Throwable e);
public abstract void printExceptionCaught(Throwable e, String hostName,
String nodeName);
+
+ public abstract void printWarn(String err);
+
+ public abstract void printError(String err);
+
}
diff --git
a/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/Tuple2.java
b/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/Tuple2.java
index c9f16e5..5f2af74 100644
--- a/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/Tuple2.java
+++ b/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/Tuple2.java
@@ -47,8 +47,7 @@ public class Tuple2<T0, T1> {
* @param value1 The value for field 1
*/
public Tuple2(T0 value0, T1 value1) {
- this.f0 = value0;
- this.f1 = value1;
+ setF0AndF1(value0, value1);
}
public T0 getF0() {
diff --git
a/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/Tuple3.java
b/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/Tuple3.java
index 579b425..b7f744a 100644
--- a/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/Tuple3.java
+++ b/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/Tuple3.java
@@ -41,9 +41,7 @@ public class Tuple3<T0, T1, T2> {
* @param value2 The value for field 2
*/
public Tuple3(T0 value0, T1 value1, T2 value2) {
- this.f0 = value0;
- this.f1 = value1;
- this.f2 = value2;
+ setFieldsValue(value0, value1, value2);
}
public T0 getF0() {
@@ -57,4 +55,10 @@ public class Tuple3<T0, T1, T2> {
public T2 getF2() {
return f2;
}
+
+ public void setFieldsValue(T0 value0, T1 value1, T2 value2) {
+ this.f0 = value0;
+ this.f1 = value1;
+ this.f2 = value2;
+ }
}
diff --git
a/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/Tuple3.java
b/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/Tuple4.java
similarity index 75%
copy from tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/Tuple3.java
copy to tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/Tuple4.java
index 579b425..67ace7a 100644
--- a/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/Tuple3.java
+++ b/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/Tuple4.java
@@ -17,7 +17,7 @@
package org.apache.tubemq.corebase.utils;
-public class Tuple3<T0, T1, T2> {
+public class Tuple4<T0, T1, T2, T3> {
/** Field 0 of the tuple. */
private T0 f0 = null;
@@ -25,11 +25,12 @@ public class Tuple3<T0, T1, T2> {
private T1 f1 = null;
/** Field 2 of the tuple. */
private T2 f2 = null;
-
+ /** Field 3 of the tuple. */
+ private T3 f3 = null;
/**
* Creates a new tuple where all fields are null.
*/
- public Tuple3() {
+ public Tuple4() {
}
@@ -39,11 +40,10 @@ public class Tuple3<T0, T1, T2> {
* @param value0 The value for field 0
* @param value1 The value for field 1
* @param value2 The value for field 2
+ * @param value3 The value for field 3
*/
- public Tuple3(T0 value0, T1 value1, T2 value2) {
- this.f0 = value0;
- this.f1 = value1;
- this.f2 = value2;
+ public Tuple4(T0 value0, T1 value1, T2 value2, T3 value3) {
+ setFieldsValue(value0, value1, value2, value3);
}
public T0 getF0() {
@@ -57,4 +57,16 @@ public class Tuple3<T0, T1, T2> {
public T2 getF2() {
return f2;
}
+
+ public T3 getF3() {
+ return f3;
+ }
+
+ public void setFieldsValue(T0 value0, T1 value1, T2 value2, T3 value3) {
+ this.f0 = value0;
+ this.f1 = value1;
+ this.f2 = value2;
+ this.f3 = value3;
+ }
+
}
diff --git
a/tubemq-server/src/main/java/org/apache/tubemq/server/broker/utils/BrokerSamplePrint.java
b/tubemq-server/src/main/java/org/apache/tubemq/server/broker/utils/BrokerSamplePrint.java
index d0c32a1..54f2ceb 100644
---
a/tubemq-server/src/main/java/org/apache/tubemq/server/broker/utils/BrokerSamplePrint.java
+++
b/tubemq-server/src/main/java/org/apache/tubemq/server/broker/utils/BrokerSamplePrint.java
@@ -80,4 +80,13 @@ public class BrokerSamplePrint extends AbstractSamplePrint {
//
}
+ @Override
+ public void printWarn(String err) {
+ //
+ }
+
+ @Override
+ public void printError(String err) {
+ //
+ }
}
diff --git
a/tubemq-server/src/main/java/org/apache/tubemq/server/broker/utils/DiskSamplePrint.java
b/tubemq-server/src/main/java/org/apache/tubemq/server/broker/utils/DiskSamplePrint.java
index a1c29c0..2f4ac23 100644
---
a/tubemq-server/src/main/java/org/apache/tubemq/server/broker/utils/DiskSamplePrint.java
+++
b/tubemq-server/src/main/java/org/apache/tubemq/server/broker/utils/DiskSamplePrint.java
@@ -117,4 +117,13 @@ public class DiskSamplePrint extends AbstractSamplePrint {
}
}
+ @Override
+ public void printWarn(String err) {
+ //
+ }
+
+ @Override
+ public void printError(String err) {
+ //
+ }
}
diff --git
a/tubemq-server/src/main/java/org/apache/tubemq/server/common/statusdef/StepStatus.java
b/tubemq-server/src/main/java/org/apache/tubemq/server/common/statusdef/StepStatus.java
new file mode 100644
index 0000000..cfa4038
--- /dev/null
+++
b/tubemq-server/src/main/java/org/apache/tubemq/server/common/statusdef/StepStatus.java
@@ -0,0 +1,64 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.tubemq.server.common.statusdef;
+
+
+public enum StepStatus {
+
+ STEP_STATUS_UNDEFINED(-2, "idle", 0),
+ STEP_STATUS_LOAD_DATA(1, "load_data", 0),
+ STEP_STATUS_WAIT_ONLINE(2, "wait_online", 0),
+ STEP_STATUS_WAIT_SYNC(3, "wait_sync", 0),
+ STEP_STATUS_WAIT_SUBSCRIBE(4, "wait_sub", 60000),
+ STEP_STATUS_WAIT_PUBLISH(5, "wait_pub", 30000);
+
+ private int code;
+ private String description;
+ private long delayDurInMs;
+
+
+
+ StepStatus(int code, String description, long delayDurInMs) {
+ this.code = code;
+ this.description = description;
+ this.delayDurInMs = delayDurInMs;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public long getDelayDurInMs() {
+ return delayDurInMs;
+ }
+
+ public static StepStatus valueOf(int code) {
+ for (StepStatus status : StepStatus.values()) {
+ if (status.getCode() == code) {
+ return status;
+ }
+ }
+ throw new IllegalArgumentException(String.format(
+ "unknown broker step status code %s", code));
+ }
+
+}
diff --git
a/tubemq-server/src/main/java/org/apache/tubemq/server/master/TMaster.java
b/tubemq-server/src/main/java/org/apache/tubemq/server/master/TMaster.java
index 651e655..c8f99e4 100644
--- a/tubemq-server/src/main/java/org/apache/tubemq/server/master/TMaster.java
+++ b/tubemq-server/src/main/java/org/apache/tubemq/server/master/TMaster.java
@@ -1014,15 +1014,20 @@ public class TMaster extends HasThread implements
MasterService, Stoppable {
ConcurrentHashMap<Integer, BrokerSyncStatusInfo> brokerSyncStatusMap =
this.defMetaDataManager.getBrokerRunSyncManageMap();
// update broker status
- List<String> brokerTopicSetConfInfo =
+ Map<String, String> brokerTopicSetConfInfo =
this.defMetaDataManager.getBrokerTopicStrConfigInfo(brokerConfEntity,
strBuffer);
+ List<String> brokerTopicSetConfInfoList =
+ new ArrayList<>(brokerTopicSetConfInfo.size());
+ for (String topicItem : brokerTopicSetConfInfo.values()) {
+ brokerTopicSetConfInfoList.add(topicItem);
+ }
BrokerSyncStatusInfo brokerStatusInfo =
- new BrokerSyncStatusInfo(brokerConfEntity,
brokerTopicSetConfInfo);
+ new BrokerSyncStatusInfo(brokerConfEntity,
brokerTopicSetConfInfoList);
brokerSyncStatusMap.put(brokerConfEntity.getBrokerId(),
brokerStatusInfo);
brokerStatusInfo.updateCurrBrokerConfInfo(brokerConfEntity.getManageStatus().getCode(),
brokerConfEntity.isConfDataUpdated(),
brokerConfEntity.isBrokerLoaded(),
- brokerConfEntity.getBrokerDefaultConfInfo(),
brokerTopicSetConfInfo, false);
- if (brokerTopicSetConfInfo.isEmpty()) {
+ brokerConfEntity.getBrokerDefaultConfInfo(),
brokerTopicSetConfInfoList, false);
+ if (brokerTopicSetConfInfoList.isEmpty()) {
needFastStart = true;
}
brokerStatusInfo.setFastStart(needFastStart);
@@ -1035,7 +1040,7 @@ public class TMaster extends HasThread implements
MasterService, Stoppable {
brokerStatusInfo.setBrokerReportInfo(true,
brokerStatusInfo.getLastPushBrokerConfId(),
brokerStatusInfo.getLastPushBrokerCheckSumId(), true,
- brokerConfEntity.getBrokerDefaultConfInfo(),
brokerTopicSetConfInfo, true,
+ brokerConfEntity.getBrokerDefaultConfInfo(),
brokerTopicSetConfInfoList, true,
request.getBrokerOnline(), overtls);
}
this.defMetaDataManager.removeBrokerRunTopicInfoMap(brokerInfo.getBrokerId());
@@ -1197,6 +1202,7 @@ public class TMaster extends HasThread implements
MasterService, Stoppable {
builder.setErrMsg(e.getMessage());
return builder.build();
}
+
// update broker status
brokerSyncStatusInfo.setBrokerReportInfo(false,
request.getCurBrokerConfId(),
request.getConfCheckSumId(), request.getTakeConfInfo(),
@@ -1260,7 +1266,7 @@ public class TMaster extends HasThread implements
MasterService, Stoppable {
}
builder.setTakeRemoveTopicInfo(true);
builder.addAllRemoveTopicConfInfo(defMetaDataManager
- .getBrokerRemovedTopicStrConfigInfo(brokerConfigEntry,
strBuffer));
+ .getBrokerRemovedTopicStrConfigInfo(brokerConfigEntry,
strBuffer).values());
if (brokerSyncStatusInfo.needSyncConfDataToBroker()) {
builder.setTakeConfInfo(true);
builder.setBrokerDefaultConfInfo(brokerSyncStatusInfo
diff --git
a/tubemq-server/src/main/java/org/apache/tubemq/server/master/metamanage/MetaDataManager.java
b/tubemq-server/src/main/java/org/apache/tubemq/server/master/metamanage/MetaDataManager.java
index 1250f83..a34a13a 100644
---
a/tubemq-server/src/main/java/org/apache/tubemq/server/master/metamanage/MetaDataManager.java
+++
b/tubemq-server/src/main/java/org/apache/tubemq/server/master/metamanage/MetaDataManager.java
@@ -147,10 +147,15 @@ public class MetaDataManager implements Server {
boolean needFastStart = false;
BrokerSyncStatusInfo brokerSyncStatusInfo =
this.brokerRunSyncManageMap.get(entity.getBrokerId());
- List<String> brokerTopicSetConfInfo =
getBrokerTopicStrConfigInfo(entity, sBuffer);
+ Map<String, String> brokerTopicSetConfInfo =
getBrokerTopicStrConfigInfo(entity, sBuffer);
+ List<String> brokerTopicSetConfInfoList =
+ new ArrayList<>(brokerTopicSetConfInfo.size());
+ for (String topicItem : brokerTopicSetConfInfo.values()) {
+ brokerTopicSetConfInfoList.add(topicItem);
+ }
if (brokerSyncStatusInfo == null) {
brokerSyncStatusInfo =
- new BrokerSyncStatusInfo(entity,
brokerTopicSetConfInfo);
+ new BrokerSyncStatusInfo(entity,
brokerTopicSetConfInfoList);
BrokerSyncStatusInfo tmpBrokerSyncStatusInfo =
brokerRunSyncManageMap.putIfAbsent(entity.getBrokerId(),
brokerSyncStatusInfo);
@@ -164,7 +169,7 @@ public class MetaDataManager implements Server {
brokerSyncStatusInfo.setFastStart(needFastStart);
brokerSyncStatusInfo.updateCurrBrokerConfInfo(entity.getManageStatus().getCode(),
entity.isConfDataUpdated(), entity.isBrokerLoaded(),
- entity.getBrokerDefaultConfInfo(),
brokerTopicSetConfInfo, false);
+ entity.getBrokerDefaultConfInfo(),
brokerTopicSetConfInfoList, false);
}
}
isStarted = true;
@@ -866,13 +871,18 @@ public class MetaDataManager implements Server {
return result.isSuccess();
}
String curBrokerConfStr = curEntity.getBrokerDefaultConfInfo();
- List<String> curBrokerTopicConfStrSet =
+ Map<String, String> curBrokerTopicConfStrSet =
getBrokerTopicStrConfigInfo(curEntity, strBuffer);
+ List<String> brokerTopicSetConfInfoList =
+ new ArrayList<>(curBrokerTopicConfStrSet.size());
+ for (String topicItem : curBrokerTopicConfStrSet.values()) {
+ brokerTopicSetConfInfoList.add(topicItem);
+ }
BrokerSyncStatusInfo brokerSyncStatusInfo =
this.brokerRunSyncManageMap.get(entity.getBrokerId());
if (brokerSyncStatusInfo == null) {
brokerSyncStatusInfo =
- new BrokerSyncStatusInfo(entity, curBrokerTopicConfStrSet);
+ new BrokerSyncStatusInfo(entity,
brokerTopicSetConfInfoList);
BrokerSyncStatusInfo tmpBrokerSyncStatusInfo =
brokerRunSyncManageMap.putIfAbsent(entity.getBrokerId(),
brokerSyncStatusInfo);
if (tmpBrokerSyncStatusInfo != null) {
@@ -901,7 +911,7 @@ public class MetaDataManager implements Server {
|| oldManageStatus ==
TStatusConstants.STATUS_MANAGE_ONLINE_NOT_READ);
brokerSyncStatusInfo.updateCurrBrokerConfInfo(curManageStatus,
curEntity.isConfDataUpdated(), curEntity.isBrokerLoaded(),
curBrokerConfStr,
- curBrokerTopicConfStrSet, isOnlineUpdate);
+ brokerTopicSetConfInfoList, isOnlineUpdate);
} else {
brokerSyncStatusInfo.setBrokerOffline();
}
@@ -1085,10 +1095,15 @@ public class MetaDataManager implements Server {
BrokerSyncStatusInfo brokerSyncStatusInfo =
brokerRunSyncManageMap.get(curEntity.getBrokerId());
if (brokerSyncStatusInfo == null) {
- List<String> newBrokerTopicConfStrSet =
+ Map<String, String> newBrokerTopicConfStrSet =
getBrokerTopicStrConfigInfo(curEntity, strBuffer);
+ List<String> brokerTopicSetConfInfoList =
+ new ArrayList<>(newBrokerTopicConfStrSet.size());
+ for (String topicItem : newBrokerTopicConfStrSet.values())
{
+ brokerTopicSetConfInfoList.add(topicItem);
+ }
brokerSyncStatusInfo =
- new BrokerSyncStatusInfo(curEntity,
newBrokerTopicConfStrSet);
+ new BrokerSyncStatusInfo(curEntity,
brokerTopicSetConfInfoList);
BrokerSyncStatusInfo tmpBrokerSyncStatusInfo =
brokerRunSyncManageMap.putIfAbsent(curEntity.getBrokerId(),
brokerSyncStatusInfo);
if (tmpBrokerSyncStatusInfo != null) {
@@ -1111,10 +1126,15 @@ public class MetaDataManager implements Server {
BrokerSyncStatusInfo brokerSyncStatusInfo =
brokerRunSyncManageMap.get(curEntity.getBrokerId());
if (brokerSyncStatusInfo == null) {
- List<String> newBrokerTopicConfStrSet =
+ Map<String, String> newBrokerTopicConfStrSet =
getBrokerTopicStrConfigInfo(curEntity, strBuffer);
+ List<String> brokerTopicSetConfInfoList =
+ new ArrayList<>(newBrokerTopicConfStrSet.size());
+ for (String topicItem : newBrokerTopicConfStrSet.values())
{
+ brokerTopicSetConfInfoList.add(topicItem);
+ }
brokerSyncStatusInfo =
- new BrokerSyncStatusInfo(curEntity,
newBrokerTopicConfStrSet);
+ new BrokerSyncStatusInfo(curEntity,
brokerTopicSetConfInfoList);
BrokerSyncStatusInfo tmpBrokerSyncStatusInfo =
brokerRunSyncManageMap.putIfAbsent(curEntity.getBrokerId(),
brokerSyncStatusInfo);
@@ -1446,23 +1466,24 @@ public class MetaDataManager implements Server {
recordKey, strBuffer, result);
}
- public List<String> getBrokerTopicStrConfigInfo(
+ public Map<String, String> getBrokerTopicStrConfigInfo(
BrokerConfEntity brokerConfEntity, StringBuilder sBuffer) {
return inGetTopicConfStrInfo(brokerConfEntity, false, sBuffer);
}
- public List<String> getBrokerRemovedTopicStrConfigInfo(
+ public Map<String, String> getBrokerRemovedTopicStrConfigInfo(
BrokerConfEntity brokerConfEntity, StringBuilder sBuffer) {
return inGetTopicConfStrInfo(brokerConfEntity, true, sBuffer);
}
- private List<String> inGetTopicConfStrInfo(BrokerConfEntity brokerEntity,
- boolean isRemoved,
StringBuilder sBuffer) {
- List<String> topicConfStrs = new ArrayList<>();
+ private Map<String, String> inGetTopicConfStrInfo(BrokerConfEntity
brokerEntity,
+ boolean isRemoved,
+ StringBuilder sBuffer) {
+ Map<String, String> topicConfStrMap = new HashMap<>();
Map<String, TopicDeployEntity> topicEntityMap =
metaStoreService.getConfiguredTopicInfo(brokerEntity.getBrokerId());
if (topicEntityMap.isEmpty()) {
- return topicConfStrs;
+ return topicConfStrMap;
}
TopicPropGroup defTopicProps = brokerEntity.getTopicProps();
ClusterSettingEntity clusterDefConf =
@@ -1549,10 +1570,10 @@ public class MetaDataManager implements Server {
} else {
sBuffer.append(TokenConstants.ATTR_SEP).append(maxMsgSize);
}
- topicConfStrs.add(sBuffer.toString());
+ topicConfStrMap.put(topicEntity.getTopicName(),
sBuffer.toString());
sBuffer.delete(0, sBuffer.length());
}
- return topicConfStrs;
+ return topicConfStrMap;
}
//
/////////////////////////////////////////////////////////////////////////////////
diff --git
a/tubemq-server/src/main/java/org/apache/tubemq/server/master/nodemanage/nodebroker/BrokerPSInfoHolder.java
b/tubemq-server/src/main/java/org/apache/tubemq/server/master/nodemanage/nodebroker/BrokerPSInfoHolder.java
new file mode 100644
index 0000000..3fd9cd4
--- /dev/null
+++
b/tubemq-server/src/main/java/org/apache/tubemq/server/master/nodemanage/nodebroker/BrokerPSInfoHolder.java
@@ -0,0 +1,181 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.tubemq.server.master.nodemanage.nodebroker;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.tubemq.corebase.cluster.Partition;
+import org.apache.tubemq.corebase.cluster.TopicInfo;
+import org.apache.tubemq.corebase.utils.ConcurrentHashSet;
+import org.apache.tubemq.corebase.utils.Tuple2;
+import org.apache.tubemq.server.common.statusdef.ManageStatus;
+
+
+public class BrokerPSInfoHolder {
+ // broker manage status
+ private ConcurrentHashSet<Integer/* brokerId */> enablePubBrokerIdSet =
new ConcurrentHashSet<>();
+ private ConcurrentHashSet<Integer/* brokerId */> enableSubBrokerIdSet =
new ConcurrentHashSet<>();
+ // broker subscribe topic view info
+ private BrokerTopicInfoView subTopicInfoView = new BrokerTopicInfoView();
+ // broker publish topic view info
+ private BrokerTopicInfoView pubTopicInfoView = new BrokerTopicInfoView();
+
+
+ public BrokerPSInfoHolder() {
+
+ }
+
+ /**
+ * remove broker all configure info
+ *
+ * @param brokerId broker id index
+ */
+ public void rmvBrokerAllPushedInfo(int brokerId) {
+ // remove broker status Info
+ enablePubBrokerIdSet.remove(brokerId);
+ enableSubBrokerIdSet.remove(brokerId);
+ // remove broker topic info
+ subTopicInfoView.rmvBrokerTopicInfo(brokerId);
+ pubTopicInfoView.rmvBrokerTopicInfo(brokerId);
+ }
+
+ /**
+ * update broker manage status
+ *
+ * @param brokerId broker id index
+ * @param mngStatus broker's manage status
+ */
+ public void updBrokerMangeStatus(int brokerId, ManageStatus mngStatus) {
+ Tuple2<Boolean, Boolean> pubSubStatus = mngStatus.getPubSubStatus();
+ if (pubSubStatus.getF0() == Boolean.TRUE) {
+ enablePubBrokerIdSet.add(brokerId);
+ } else {
+ enablePubBrokerIdSet.remove(brokerId);
+ }
+ if (pubSubStatus.getF1() == Boolean.TRUE) {
+ enableSubBrokerIdSet.add(brokerId);
+ } else {
+ enableSubBrokerIdSet.remove(brokerId);
+ }
+ }
+
+ /**
+ * update broker's subscribe topicInfo configures
+ *
+ * @param brokerId broker id index
+ * @param topicInfoMap broker's topic configure info,
+ * if topicInfoMap is null, reserve current configure;
+ * if topicInfoMap is empty, clear current configure.
+ */
+ public void updBrokerSubTopicConfInfo(int brokerId,
+ Map<String, TopicInfo> topicInfoMap)
{
+ if (topicInfoMap == null) {
+ return;
+ }
+ subTopicInfoView.updBrokerTopicConfInfo(brokerId, topicInfoMap);
+ }
+
+ /**
+ * update broker's publish topicInfo configures
+ *
+ * @param brokerId broker id index
+ * @param topicInfoMap broker's topic configure info,
+ * if topicInfoMap is null, reserve current configure;
+ * if topicInfoMap is empty, clear current configure.
+ */
+ public void updBrokerPubTopicConfInfo(int brokerId,
+ Map<String, TopicInfo> topicInfoMap)
{
+ if (topicInfoMap == null) {
+ return;
+ }
+ pubTopicInfoView.updBrokerTopicConfInfo(brokerId, topicInfoMap);
+ }
+
+ /**
+ * update broker manage status and topicInfo configures
+ *
+ * @param brokerId broker id index
+ * @param mngStatus broker's manage status
+ * @param topicInfoMap broker's topic configure info
+ */
+ public void updateBrokerPushedInfo(int brokerId, ManageStatus mngStatus,
+ Map<String, TopicInfo> topicInfoMap) {
+ updBrokerMangeStatus(brokerId, mngStatus);
+ updBrokerSubTopicConfInfo(brokerId, topicInfoMap);
+ updBrokerPubTopicConfInfo(brokerId, topicInfoMap);
+ }
+
+ /**
+ * Get the maximum number of broker distributions of topic
+ *
+ * @param topicSet need query topic set
+ */
+ public int getTopicMaxSubBrokerCnt(Set<String> topicSet) {
+ return subTopicInfoView.getMaxTopicBrokerCnt(topicSet);
+ }
+
+ /**
+ * Gets the list of topic partitions whose subscribe status is enabled
+ *
+ * @param topicSet need query topic set
+ */
+ public List<Partition> getAcceptSubParts(Set<String> topicSet) {
+ return subTopicInfoView.getAcceptSubParts(topicSet,
enableSubBrokerIdSet);
+ }
+
+ /**
+ * Gets the list of topic partitions whose subscribe status is enabled
+ *
+ * @param topic need query topic set
+ */
+ public List<Partition> getAcceptSubParts(String topic) {
+ return subTopicInfoView.getAcceptSubParts(topic, enableSubBrokerIdSet);
+ }
+
+ /**
+ * Gets the string map of topic partitions whose publish status is enabled
+ *
+ * @param topicSet need query topic set
+ */
+ public Map<String, String> getAcceptPubPartInfo(Set<String> topicSet) {
+ return pubTopicInfoView.getAcceptPubPartInfo(topicSet,
enablePubBrokerIdSet);
+ }
+
+ /**
+ * Get the published TopicInfo information of topic in broker
+ *
+ * @param brokerId need query broker
+ * @param topic need query topic
+ *
+ * @return null or topicInfo configure
+ */
+ public TopicInfo getBrokerPubPushedTopicInfo(int brokerId, String topic) {
+ return pubTopicInfoView.getBrokerPushedTopicInfo(brokerId, topic);
+ }
+
+ /**
+ * Get all published TopicInfo information of broker
+ *
+ * @param brokerId need query broker
+ */
+ public List<TopicInfo> getPubBrokerPushedTopicInfo(int brokerId) {
+ return pubTopicInfoView.getBrokerPushedTopicInfo(brokerId);
+ }
+
+}
diff --git
a/tubemq-server/src/main/java/org/apache/tubemq/server/master/nodemanage/nodebroker/BrokerRunManager.java
b/tubemq-server/src/main/java/org/apache/tubemq/server/master/nodemanage/nodebroker/BrokerRunManager.java
new file mode 100644
index 0000000..b37e37a
--- /dev/null
+++
b/tubemq-server/src/main/java/org/apache/tubemq/server/master/nodemanage/nodebroker/BrokerRunManager.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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.tubemq.server.master.nodemanage.nodebroker;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.tubemq.corebase.cluster.TopicInfo;
+import org.apache.tubemq.corebase.utils.Tuple3;
+import org.apache.tubemq.server.common.statusdef.ManageStatus;
+import org.apache.tubemq.server.common.utils.ProcessResult;
+
+
+public interface BrokerRunManager {
+
+ boolean brokerRegister2M(String clientId, boolean enableTls,
+ int tlsPort, long reportConfigId,
+ int reportCheckSumId, boolean isTackData,
+ String repBrokerConfInfo,
+ List<String> repTopicConfInfo,
+ boolean isOnline, boolean isOverTLS,
+ StringBuilder sBuffer, ProcessResult result);
+
+ boolean brokerHeartBeat2M(int brokerId, long reportConfigId,
+ int reportCheckSumId, boolean isTackData,
+ String repBrokerConfInfo,
+ List<String> repTopicConfInfo, boolean isOnline,
+ StringBuilder sBuffer, ProcessResult result);
+
+ boolean brokerClose2M(int brokerId);
+
+ boolean brokerTimeout(int brokerId, long bookedId);
+
+
+ Tuple3<ManageStatus, String, Map<String, String>>
getBrokerMetaConfigInfo(int brokerId);
+
+ void updBrokerCsmConfInfo(int brokerId,
+ ManageStatus mngStatus,
+ Map<String, TopicInfo> topicInfoMap);
+
+ void updBrokerPrdConfInfo(int brokerId,
+ ManageStatus mngStatus,
+ Map<String, TopicInfo> topicInfoMap);
+
+}
diff --git
a/tubemq-server/src/main/java/org/apache/tubemq/server/master/nodemanage/nodebroker/BrokerRunStatusInfo.java
b/tubemq-server/src/main/java/org/apache/tubemq/server/master/nodemanage/nodebroker/BrokerRunStatusInfo.java
new file mode 100644
index 0000000..45c5459
--- /dev/null
+++
b/tubemq-server/src/main/java/org/apache/tubemq/server/master/nodemanage/nodebroker/BrokerRunStatusInfo.java
@@ -0,0 +1,357 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.tubemq.server.master.nodemanage.nodebroker;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+import org.apache.tubemq.corebase.TBaseConstants;
+import org.apache.tubemq.corebase.cluster.BrokerInfo;
+import org.apache.tubemq.corebase.cluster.TopicInfo;
+import org.apache.tubemq.corebase.utils.TStringUtils;
+import org.apache.tubemq.corebase.utils.Tuple2;
+import org.apache.tubemq.corebase.utils.Tuple3;
+import org.apache.tubemq.corebase.utils.Tuple4;
+import org.apache.tubemq.server.common.TServerConstants;
+import org.apache.tubemq.server.common.statusdef.ManageStatus;
+import org.apache.tubemq.server.common.statusdef.StepStatus;
+import org.apache.tubemq.server.master.utils.BrokerStatusSamplePrint;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class BrokerRunStatusInfo {
+
+ private static final Logger logger =
+ LoggerFactory.getLogger(BrokerRunStatusInfo.class);
+ private static final BrokerStatusSamplePrint statusFsmSamplePrint =
+ new BrokerStatusSamplePrint(logger);
+
+ private final BrokerRunManager brokerRunManager;
+
+ private BrokerInfo brokerInfo;
+ private long createId;
+ // config change flag
+ private AtomicBoolean isConfChanged = new AtomicBoolean(false);
+ private AtomicLong confChangeNo =
+ new AtomicLong(TBaseConstants.META_VALUE_UNDEFINED);
+ // data sync status
+ private StepStatus curStepStatus;
+ private volatile long nextStepOpTimeInMills = 0;
+ // current loaded change No.
+ private AtomicLong confLoadedNo =
+ new AtomicLong(TBaseConstants.META_VALUE_UNDEFINED);
+ // broker sync data info
+ BrokerSyncData brokerSyncData = new BrokerSyncData();
+ // broker status conditions
+ private boolean isOnline = false; // broker online flag
+ private boolean isDoneDataLoad = false;
+ private boolean isDoneDataSub = false;
+ private boolean isDoneDataPub = false;
+ private boolean isOverTLS = false; // enable tls
+ private long lastBrokerSyncTime = 0;
+ private long maxConfLoadedTimeInMs = 0;
+ private long curConfLoadTimeInMs = 0;
+
+
+
+ public BrokerRunStatusInfo(BrokerRunManager brokerRunManager, BrokerInfo
brokerInfo,
+ ManageStatus mngStatus, String brokerConfInfo,
+ Map<String, String> topicConfInfoMap, boolean
isOverTls) {
+ this.brokerRunManager = brokerRunManager;
+ reInitRunStatusInfo(brokerInfo, mngStatus,
+ brokerConfInfo, topicConfInfoMap, isOverTls);
+ }
+
+ public void reInitRunStatusInfo(BrokerInfo brokerInfo, ManageStatus
mngStatus,
+ String brokerConfInfo, Map<String, String>
topicConfInfoMap,
+ boolean isOverTls) {
+ resetStatusInfo();
+ this.createId = System.nanoTime();
+ this.brokerInfo = brokerInfo;
+ long curTime = System.currentTimeMillis();
+ this.isOverTLS = isOverTls;
+ this.isConfChanged.set(true);
+ this.confChangeNo.set(curTime);
+ this.brokerSyncData.updBrokerSyncData(true,
+ confChangeNo.get(), mngStatus, brokerConfInfo,
topicConfInfoMap);
+ this.curStepStatus = StepStatus.STEP_STATUS_WAIT_ONLINE;
+ this.nextStepOpTimeInMills = curTime + curStepStatus.getDelayDurInMs();
+ }
+
+ public void notifyDataChanged() {
+ this.isConfChanged.set(true);
+ this.confChangeNo.incrementAndGet();
+ }
+
+ public Tuple2<Boolean, Boolean> getDataSyncStatus() {
+ return new Tuple2<>(this.isConfChanged.get(),
+ this.confChangeNo.get() == this.confLoadedNo.get());
+ }
+
+ private boolean isDataChanged() {
+ return (this.isConfChanged.get()
+ || (this.curStepStatus == StepStatus.STEP_STATUS_UNDEFINED
+ && this.confChangeNo.get() != this.confLoadedNo.get()));
+ }
+
+ public long getCreateId() {
+ return this.createId;
+ }
+
+
+ /**
+ * Get need sync to broker's data
+ *
+ * @param retValue return data container, ** must not null **
+ * @return void
+ */
+ public void getNeedSyncData(Tuple4<Long,
+ Integer, String, Map<String, String>> retValue) {
+ brokerSyncData.getBrokerSyncData(retValue);
+ }
+
+ /**
+ * Book broker report info
+ *
+ * @param isRegister request method
+ * @param isOnline if broker is ready
+ * @param repConfigId report configure id
+ * @param repCheckSumId report configure check sum
+ * @param isTackData if tack data in request
+ * @param repBrokerConfInfo tacked broker configure
+ * @param repTopicConfs tacked topic configure
+ * @param sBuffer string process container
+ */
+ public void bookBrokerReportInfo(boolean isRegister, boolean isOnline,
+ long repConfigId, int repCheckSumId,
+ boolean isTackData, String
repBrokerConfInfo,
+ List<String> repTopicConfs,
+ StringBuilder sBuffer) {
+ boolean isSynchronized =
+ brokerSyncData.bookBrokerReportInfo(repConfigId,
+ repCheckSumId, isTackData, repBrokerConfInfo,
repTopicConfs);
+ this.isOnline = isOnline;
+ goNextStatus(isRegister, isSynchronized, sBuffer);
+ }
+
+ private void goNextStatus(boolean isRegister,
+ boolean isSynchronized,
+ StringBuilder sBuffer) {
+ if (isRegister) {
+ goRegNextStatus(isSynchronized);
+ } else {
+ goNonRegNextStatus(isSynchronized);
+ }
+ execEvent(sBuffer);
+ }
+
+ private void execEvent(StringBuilder sBuffer) {
+ switch (curStepStatus) {
+ case STEP_STATUS_LOAD_DATA: {
+ loadNewMetaData(sBuffer);
+ }
+ break;
+
+ case STEP_STATUS_WAIT_SUBSCRIBE: {
+ execSyncDataToSub();
+ }
+ break;
+
+ case STEP_STATUS_WAIT_PUBLISH: {
+ execSyncDataToPub();
+ }
+ break;
+
+ case STEP_STATUS_UNDEFINED:
+ case STEP_STATUS_WAIT_ONLINE:
+ case STEP_STATUS_WAIT_SYNC:
+ default: {
+ }
+ }
+ }
+
+ private void goRegNextStatus(boolean isSynchronized) {
+ resetStatusInfo();
+ if (isOnline) {
+ if (isSynchronized) {
+ curStepStatus = StepStatus.STEP_STATUS_WAIT_SUBSCRIBE;
+ } else {
+ curStepStatus = StepStatus.STEP_STATUS_WAIT_SYNC;
+ }
+ } else {
+ curStepStatus = StepStatus.STEP_STATUS_WAIT_ONLINE;
+ }
+ }
+
+ private void goNonRegNextStatus(boolean isSynchronized) {
+ switch (curStepStatus) {
+ case STEP_STATUS_UNDEFINED: {
+ if (!isSynchronized || isDataChanged() || needForceSyncData())
{
+ resetStatusInfo();
+ curStepStatus = StepStatus.STEP_STATUS_LOAD_DATA;
+ nextStepOpTimeInMills =
+ System.currentTimeMillis() +
curStepStatus.getDelayDurInMs();
+ }
+ }
+ break;
+
+ case STEP_STATUS_LOAD_DATA: {
+ if (isDoneDataLoad) {
+ if (isOnline) {
+ if (isSynchronized) {
+ curStepStatus =
StepStatus.STEP_STATUS_WAIT_SUBSCRIBE;
+ } else {
+ curStepStatus = StepStatus.STEP_STATUS_WAIT_SYNC;
+ }
+ nextStepOpTimeInMills =
+ System.currentTimeMillis() +
curStepStatus.getDelayDurInMs();
+ }
+ }
+ }
+ break;
+
+ case STEP_STATUS_WAIT_ONLINE: {
+ if (isOnline) {
+ if (isSynchronized) {
+ curStepStatus = StepStatus.STEP_STATUS_WAIT_SUBSCRIBE;
+ } else {
+ curStepStatus = StepStatus.STEP_STATUS_WAIT_SYNC;
+ }
+ nextStepOpTimeInMills =
+ System.currentTimeMillis() +
curStepStatus.getDelayDurInMs();
+ }
+ }
+ break;
+
+ case STEP_STATUS_WAIT_SYNC: {
+ if (isSynchronized) {
+ curStepStatus = StepStatus.STEP_STATUS_WAIT_SUBSCRIBE;
+ } else {
+ curStepStatus = StepStatus.STEP_STATUS_WAIT_SYNC;
+ }
+ nextStepOpTimeInMills =
+ System.currentTimeMillis() +
curStepStatus.getDelayDurInMs();
+ }
+ break;
+
+ case STEP_STATUS_WAIT_SUBSCRIBE: {
+ if (isDoneDataSub && System.currentTimeMillis() >
nextStepOpTimeInMills) {
+ curStepStatus = StepStatus.STEP_STATUS_WAIT_PUBLISH;
+ nextStepOpTimeInMills =
+ System.currentTimeMillis() +
curStepStatus.getDelayDurInMs();
+ }
+ }
+ break;
+
+ case STEP_STATUS_WAIT_PUBLISH:
+ default: {
+ if (isDoneDataPub && System.currentTimeMillis() >
nextStepOpTimeInMills) {
+ finishedDataSync();
+ }
+ }
+ }
+ }
+
+ private void loadNewMetaData(StringBuilder sBuffer) {
+ if (isDoneDataLoad) {
+ return;
+ }
+ boolean needForceSync = needForceSyncData();
+ Tuple3<ManageStatus, String, Map<String, String>> curConfTuple =
+
brokerRunManager.getBrokerMetaConfigInfo(brokerInfo.getBrokerId());
+ if (TStringUtils.isBlank(curConfTuple.getF1())) {
+ statusFsmSamplePrint.printWarn(sBuffer
+ .append("[Broker Sync] found broker(")
+ .append(brokerInfo.getBrokerId())
+ .append(") configure is null").toString());
+ sBuffer.delete(0, sBuffer.length());
+ return;
+ }
+ Tuple2<Boolean, Boolean> updResult =
+ brokerSyncData.updBrokerSyncData(needForceSync,
+ confChangeNo.get(), curConfTuple.getF0(),
+ curConfTuple.getF1(), curConfTuple.getF2());
+ if (updResult == null) {
+ return;
+ }
+ isDoneDataLoad = true;
+ this.lastBrokerSyncTime = System.currentTimeMillis();
+ if (!updResult.getF0() && !updResult.getF1()) {
+ finishedDataSync();
+ }
+ }
+
+ private void execSyncDataToSub() {
+ if (isDoneDataSub) {
+ return;
+ }
+ Tuple2<ManageStatus, Map<String, TopicInfo>> syncData =
+ brokerSyncData.getBrokerPublishInfo(brokerInfo);
+ brokerRunManager.updBrokerCsmConfInfo(brokerInfo.getBrokerId(),
+ syncData.getF0(), syncData.getF1());
+ isDoneDataSub = true;
+ }
+
+ private void execSyncDataToPub() {
+ if (isDoneDataPub) {
+ return;
+ }
+ Tuple2<ManageStatus, Map<String, TopicInfo>> syncData =
+ brokerSyncData.getBrokerPublishInfo(brokerInfo);
+ brokerRunManager.updBrokerPrdConfInfo(brokerInfo.getBrokerId(),
+ syncData.getF0(), syncData.getF1());
+ isDoneDataPub = true;
+ }
+
+ private void finishedDataSync() {
+ this.confLoadedNo.set(brokerSyncData.getDataPushId());
+ if (this.confLoadedNo.get() == this.confChangeNo.get()) {
+ this.isConfChanged.set(false);
+ }
+ curStepStatus = StepStatus.STEP_STATUS_UNDEFINED;
+ nextStepOpTimeInMills = 0;
+ long tmpDuration = System.currentTimeMillis() - curConfLoadTimeInMs;
+ if (maxConfLoadedTimeInMs < tmpDuration) {
+ maxConfLoadedTimeInMs = tmpDuration;
+ }
+ }
+
+ private void resetStatusInfo() {
+ isDoneDataLoad = false;
+ isDoneDataSub = false;
+ isDoneDataPub = false;
+ nextStepOpTimeInMills = 0;
+ curConfLoadTimeInMs = System.currentTimeMillis();
+ }
+
+ /**
+ * According to last report time and current time to decide if need to
report data
+ *
+ * @return true if need report data otherwise false
+ */
+ private boolean needForceSyncData() {
+ if (System.currentTimeMillis() - this.lastBrokerSyncTime
+ > TServerConstants.CFG_REPORT_DEFAULT_SYNC_DURATION) {
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git
a/tubemq-server/src/main/java/org/apache/tubemq/server/master/nodemanage/nodebroker/BrokerSyncData.java
b/tubemq-server/src/main/java/org/apache/tubemq/server/master/nodemanage/nodebroker/BrokerSyncData.java
new file mode 100644
index 0000000..09de48d
--- /dev/null
+++
b/tubemq-server/src/main/java/org/apache/tubemq/server/master/nodemanage/nodebroker/BrokerSyncData.java
@@ -0,0 +1,322 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.tubemq.server.master.nodemanage.nodebroker;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicLong;
+import org.apache.commons.codec.binary.StringUtils;
+import org.apache.tubemq.corebase.TBaseConstants;
+import org.apache.tubemq.corebase.TokenConstants;
+import org.apache.tubemq.corebase.cluster.BrokerInfo;
+import org.apache.tubemq.corebase.cluster.TopicInfo;
+import org.apache.tubemq.corebase.utils.CheckSum;
+import org.apache.tubemq.corebase.utils.TStringUtils;
+import org.apache.tubemq.corebase.utils.Tuple2;
+import org.apache.tubemq.corebase.utils.Tuple4;
+import org.apache.tubemq.server.common.TServerConstants;
+import org.apache.tubemq.server.common.statusdef.ManageStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+public class BrokerSyncData {
+ private static final Logger logger =
+ LoggerFactory.getLogger(BrokerSyncData.class);
+ // current data push id
+ private long dataPushId;
+ // data need to sync
+ private AtomicLong syncDownDataConfId =
+ new AtomicLong(System.currentTimeMillis());
+ private int syncDownDataChkSumId;
+ private ManageStatus mngStatus;
+ private String syncDownBrokerConfInfo;
+ private Map<String, String> syncDownTopicConfInfoMap = new HashMap<>();
+ private boolean isStatusChanged = false;
+ private boolean isConfChanged = false;
+
+ // report info
+ private long syncUpDataConfId = TBaseConstants.META_VALUE_UNDEFINED;
+ private int syncUpDataChkSumId = TBaseConstants.META_VALUE_UNDEFINED;
+ private String syncUpBrokerConfInfo;
+ private List<String> syncUpTopicConfInfos = new ArrayList<>();
+ private long lastDataUpTime = 0;
+
+ public BrokerSyncData() {
+
+ }
+
+ public BrokerSyncData(long dataPushId,
+ ManageStatus mngStatus,
+ String brokerConfInfo,
+ Map<String, String> topicConfInfoMap) {
+ updBrokerSyncData(true, dataPushId,
+ mngStatus, brokerConfInfo, topicConfInfoMap);
+ }
+
+ /**
+ * Update current sync data
+ *
+ * @param isForceSync if force sync data to broker
+ * @param dataPushId data push id for verify
+ * @param mngStatus new broker manage status
+ * @param brokerConfInfo broker default configure
+ * @param topicConfInfoMap topic configure set
+ *
+ * @return whether changed, if null: input brokerConfInfo data is illegal
+ * f0 : manage status changed
+ * f1 : configure changed
+ */
+ public Tuple2<Boolean, Boolean> updBrokerSyncData(boolean isForceSync,
long dataPushId,
+ ManageStatus mngStatus,
+ String brokerConfInfo,
+ Map<String, String>
topicConfInfoMap) {
+ isStatusChanged = false;
+ isConfChanged = false;
+ // check parameters
+ if (TStringUtils.isBlank(brokerConfInfo)) {
+ return null;
+ }
+ this.dataPushId = dataPushId;
+ if (isForceSync || this.mngStatus != mngStatus) {
+ this.mngStatus = mngStatus;
+ isStatusChanged = true;
+ }
+
+ if (isForceSync || isSyncDataChanged(brokerConfInfo,
topicConfInfoMap)) {
+ this.syncDownBrokerConfInfo = brokerConfInfo;
+ if (topicConfInfoMap == null) {
+ this.syncDownTopicConfInfoMap = new HashMap<>();
+ } else {
+ this.syncDownTopicConfInfoMap = topicConfInfoMap;
+ }
+ this.syncDownDataChkSumId =
+ calculateConfigCrc32Value(syncDownBrokerConfInfo,
syncDownTopicConfInfoMap);
+ isConfChanged = true;
+ }
+ if (isStatusChanged && isConfChanged) {
+ this.syncDownDataConfId.incrementAndGet();
+ }
+ return new Tuple2<>(isStatusChanged, isConfChanged);
+ }
+
+ /**
+ * Book the report data by broker
+ * @param syncDataConfId data configure id
+ * @param syncDataChkSumId data check-sum id
+ * @param isTakeData if carry the data info
+ * @param syncBrokerConfInfo broker default config
+ * @param syncTopicConfInfos topic config set
+ *
+ * @return whether the broker data synchronized
+ */
+ public boolean bookBrokerReportInfo(long syncDataConfId, int
syncDataChkSumId,
+ boolean isTakeData, String
syncBrokerConfInfo,
+ List<String> syncTopicConfInfos) {
+ this.syncUpDataConfId = syncDataConfId;
+ this.syncUpDataChkSumId = syncDataChkSumId;
+ if (isTakeData) {
+ this.syncUpBrokerConfInfo = syncBrokerConfInfo;
+ if (syncTopicConfInfos == null) {
+ this.syncUpTopicConfInfos = new ArrayList<>();
+ } else {
+ this.syncUpTopicConfInfos = syncTopicConfInfos;
+ }
+ this.lastDataUpTime = System.currentTimeMillis();
+ }
+ return isConfSynchronized();
+ }
+
+ /**
+ * whether the broker data is synchronized
+ *
+ * @return true: the configure is synchronized;
+ * false: not synchronized
+ */
+ public boolean isConfSynchronized() {
+ return (this.syncDownDataConfId.get() == this.syncUpDataConfId
+ && this.syncDownDataChkSumId == this.syncUpDataChkSumId);
+ }
+
+ public boolean isDownTopicConfEmpty() {
+ return this.syncDownTopicConfInfoMap.isEmpty();
+ }
+
+ /**
+ * Get need sync to broker's data
+ *
+ * @param retValue return data container, ** must not null **
+ * @return void
+ */
+ public void getBrokerSyncData(Tuple4<Long,
+ Integer, String, Map<String, String>> retValue) {
+ if (isConfSynchronized()) {
+ retValue.setFieldsValue(syncDownDataConfId.get(),
syncDownDataChkSumId,
+ syncDownBrokerConfInfo, syncDownTopicConfInfoMap);
+ } else {
+ retValue.setFieldsValue(syncDownDataConfId.get(),
+ syncDownDataChkSumId, null, null);
+ }
+ }
+
+ /**
+ * Get the broker publish info
+ * @param brokerInfo broker info
+ * @return need sync data
+ * f0 : manage status
+ * f1 : topic configure
+ */
+ public Tuple2<ManageStatus, Map<String, TopicInfo>> getBrokerPublishInfo(
+ final BrokerInfo brokerInfo) {
+ Map<String, TopicInfo> topicInfoMap = parseTopicInfoConf(brokerInfo);
+ return new Tuple2<>(mngStatus, topicInfoMap);
+ }
+
+ public long getDataPushId() {
+ return dataPushId;
+ }
+
+ public long getLastDataReportTime() {
+ return lastDataUpTime;
+ }
+
+ /**
+ * Judge the sync-data is change
+ * @param brokerConfInfo broker default config
+ * @param topicConfInfoMap topic config set
+ *
+ * @return whether the sync-data is change
+ */
+ private boolean isSyncDataChanged(String brokerConfInfo,
+ Map<String, String> topicConfInfoMap) {
+ return !Objects.equals(syncDownBrokerConfInfo, brokerConfInfo)
+ || !Objects.equals(syncDownTopicConfInfoMap, topicConfInfoMap);
+ }
+
+ /**
+ * parse broker report configure to topicInfo
+ *
+ * @param brokerInfo broker info
+ */
+ private Map<String, TopicInfo> parseTopicInfoConf(final BrokerInfo
brokerInfo) {
+ // check broker configure
+ if (TStringUtils.isBlank(this.syncUpBrokerConfInfo)) {
+ return null;
+ }
+ // get broker status and topic default configure
+ String[] brokerConfInfoAttrs =
+ this.syncUpBrokerConfInfo.split(TokenConstants.ATTR_SEP);
+ int numPartitions = Integer.parseInt(brokerConfInfoAttrs[0]);
+ boolean cfgAcceptPublish =
Boolean.parseBoolean(brokerConfInfoAttrs[1]);
+ boolean cfgAcceptSubscribe =
Boolean.parseBoolean(brokerConfInfoAttrs[2]);
+ int numTopicStores = 1;
+ if (brokerConfInfoAttrs.length > 7) {
+ if (!TStringUtils.isBlank(brokerConfInfoAttrs[7])) {
+ numTopicStores = Integer.parseInt(brokerConfInfoAttrs[7]);
+ }
+ }
+ int unFlushDataHold = TServerConstants.CFG_DEFAULT_DATA_UNFLUSH_HOLD;
+ if (brokerConfInfoAttrs.length > 8) {
+ if (!TStringUtils.isBlank(brokerConfInfoAttrs[8])) {
+ unFlushDataHold = Integer.parseInt(brokerConfInfoAttrs[8]);
+ }
+ }
+ Map<String, TopicInfo> topicInfoMap = new HashMap<>();
+ // make up topicInfo info according to broker default configure
+ for (String strTopicConfInfo : this.syncUpTopicConfInfos) {
+ if (TStringUtils.isBlank(strTopicConfInfo)) {
+ continue;
+ }
+ String[] topicConfAttrs =
+ strTopicConfInfo.split(TokenConstants.ATTR_SEP);
+ final String tmpTopic = topicConfAttrs[0];
+ int tmpPartNum = numPartitions;
+ if (!TStringUtils.isBlank(topicConfAttrs[1])) {
+ tmpPartNum = Integer.parseInt(topicConfAttrs[1]);
+ }
+ boolean tmpAcceptPublish = cfgAcceptPublish;
+ if (!TStringUtils.isBlank(topicConfAttrs[2])) {
+ tmpAcceptPublish = Boolean.parseBoolean(topicConfAttrs[2]);
+ }
+ int tmpNumTopicStores = numTopicStores;
+ if (!TStringUtils.isBlank(topicConfAttrs[8])) {
+ tmpNumTopicStores = Integer.parseInt(topicConfAttrs[8]);
+ tmpNumTopicStores = tmpNumTopicStores > 0 ? tmpNumTopicStores
: numTopicStores;
+ }
+ boolean tmpAcceptSubscribe = cfgAcceptSubscribe;
+ if (!TStringUtils.isBlank(topicConfAttrs[3])) {
+ tmpAcceptSubscribe = Boolean.parseBoolean(topicConfAttrs[3]);
+ }
+ topicInfoMap.put(tmpTopic, new TopicInfo(brokerInfo, tmpTopic,
+ tmpPartNum, tmpNumTopicStores, tmpAcceptPublish,
tmpAcceptSubscribe));
+ }
+ return topicInfoMap;
+ }
+
+ /**
+ * Calculate the sync-data's crc32 value
+ *
+ * @param brokerConfInfo broker default config
+ * @param topicConfInfoMap topic config set
+ *
+ * @return the crc32 value
+ */
+ private int calculateConfigCrc32Value(String brokerConfInfo,
+ Map<String, String>
topicConfInfoMap) {
+ int result = -1;
+ int capacity = 0;
+ List<String> topicConfInfoLst =
+ new ArrayList<>(topicConfInfoMap.values());
+ Collections.sort(topicConfInfoLst);
+ capacity += brokerConfInfo.length();
+ for (String itemStr : topicConfInfoLst) {
+ capacity += itemStr.length();
+ }
+ capacity *= 2;
+ for (int i = 1; i < 3; i++) {
+ result = inCalcBufferResult(capacity, brokerConfInfo,
topicConfInfoLst);
+ if (result >= 0) {
+ return result;
+ }
+ capacity *= i + 1;
+ }
+ logger.error("Calculate the CRC32 value of Broker Configure error!");
+ return 0;
+ }
+
+ private int inCalcBufferResult(int capacity, String brokerConfInfo,
+ List<String> topicConfInfoLst) {
+ final ByteBuffer buffer = ByteBuffer.allocate(capacity);
+ buffer.put(StringUtils.getBytesUtf8(brokerConfInfo));
+ for (String itemStr : topicConfInfoLst) {
+ byte[] itemData = StringUtils.getBytesUtf8(itemStr);
+ if (itemData.length > buffer.remaining()) {
+ return -1;
+ }
+ buffer.put(itemData);
+ }
+ return CheckSum.crc32(buffer.array());
+ }
+
+}
diff --git
a/tubemq-server/src/main/java/org/apache/tubemq/server/master/nodemanage/nodebroker/BrokerTopicInfoView.java
b/tubemq-server/src/main/java/org/apache/tubemq/server/master/nodemanage/nodebroker/BrokerTopicInfoView.java
new file mode 100644
index 0000000..ddfca1e
--- /dev/null
+++
b/tubemq-server/src/main/java/org/apache/tubemq/server/master/nodemanage/nodebroker/BrokerTopicInfoView.java
@@ -0,0 +1,372 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.tubemq.server.master.nodemanage.nodebroker;
+
+import java.util.ArrayList;
+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.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import org.apache.tubemq.corebase.TBaseConstants;
+import org.apache.tubemq.corebase.TokenConstants;
+import org.apache.tubemq.corebase.cluster.Partition;
+import org.apache.tubemq.corebase.cluster.TopicInfo;
+import org.apache.tubemq.corebase.utils.ConcurrentHashSet;
+
+public class BrokerTopicInfoView {
+ private ConcurrentHashMap<String/* topicName */, TopicInfoView>
+ topicConfInfoMap = new ConcurrentHashMap<>();
+ private ConcurrentHashMap<Integer/* brokerId */,
ConcurrentHashSet<String/* topicName */>>
+ brokerIdIndexMap = new ConcurrentHashMap<>();
+
+ public BrokerTopicInfoView() {
+
+ }
+
+ // remove broker all topic info
+ public void rmvBrokerTopicInfo(int brokerId) {
+ TopicInfoView topicInfoView;
+ // remove pub info
+ ConcurrentHashSet<String> topicSet =
+ brokerIdIndexMap.remove(brokerId);
+ if (topicSet == null || topicSet.isEmpty()) {
+ return;
+ }
+ for (String topic : topicSet) {
+ if (topic == null) {
+ continue;
+ }
+ topicInfoView = topicConfInfoMap.get(topic);
+ if (topicInfoView == null
+ || topicInfoView.brokerTopicInfoMap.isEmpty()) {
+ continue;
+ }
+ topicInfoView.rmvBrokerTopicInfo(brokerId);
+ }
+ }
+
+ /**
+ * update broker's topicInfo configures
+ *
+ * @param brokerId broker id index
+ * @param topicInfoMap broker's topic configure info,
+ * if topicInfoMap is null, reserve current configure;
+ * if topicInfoMap is empty, clear current configure.
+ */
+ public void updBrokerTopicConfInfo(int brokerId,
+ Map<String, TopicInfo> topicInfoMap) {
+ if (topicInfoMap == null) {
+ return;
+ }
+ // get removed topic info
+ Set<String> delTopicSet = new HashSet<>();
+ ConcurrentHashSet<String> curTopicSet = brokerIdIndexMap.get(brokerId);
+ if (curTopicSet != null) {
+ for (String topic : curTopicSet) {
+ if (!topicInfoMap.containsKey(topic)) {
+ delTopicSet.add(topic);
+ }
+ }
+ }
+ rmvBrokerTopicInfo(brokerId, delTopicSet);
+ // add or update TopicInfo
+ repBrokerTopicInfo(brokerId, topicInfoMap);
+ }
+
+ /**
+ * Get the maximum number of broker distributions of topic
+ *
+ * @param topicSet need query topic set
+ */
+ public int getMaxTopicBrokerCnt(Set<String> topicSet) {
+ int maxCount = -1;
+ int tmpSize;
+ TopicInfoView topicInfoView;
+ if (topicSet == null || topicSet.isEmpty()) {
+ return maxCount;
+ }
+ for (String topic : topicSet) {
+ if (topic == null) {
+ continue;
+ }
+ topicInfoView = topicConfInfoMap.get(topic);
+ if (topicInfoView == null
+ || topicInfoView.brokerTopicInfoMap.isEmpty()) {
+ continue;
+ }
+ tmpSize = topicInfoView.curMapSize.get();
+ if (maxCount < tmpSize) {
+ maxCount = tmpSize;
+ }
+ }
+ return maxCount;
+ }
+
+ /**
+ * Gets the list of topic partitions whose subscribe status is enabled
+ *
+ * @param topicSet need query topic set
+ */
+ public List<Partition> getAcceptSubParts(Set<String> topicSet,
+ Set<Integer>
enableSubBrokerIdSet) {
+ List<Partition> partList = new ArrayList<>();
+ if (topicSet == null || topicSet.isEmpty()) {
+ return partList;
+ }
+ for (String topic : topicSet) {
+ partList.addAll(getAcceptSubParts(topic, enableSubBrokerIdSet));
+ }
+ return partList;
+ }
+
+ /**
+ * Gets the list of topic partitions whose subscribe status is enabled
+ *
+ * @param topic need query topic set
+ */
+ public List<Partition> getAcceptSubParts(String topic,
+ Set<Integer>
enableSubBrokerIdSet) {
+ TopicInfo topicInfo;
+ List<Partition> partList = new ArrayList<>();
+ if (topic == null) {
+ return partList;
+ }
+ TopicInfoView topicInfoView = topicConfInfoMap.get(topic);
+ if (topicInfoView == null
+ || topicInfoView.brokerTopicInfoMap.isEmpty()) {
+ return partList;
+ }
+ for (Map.Entry<Integer, TopicInfo> entry
+ : topicInfoView.brokerTopicInfoMap.entrySet()) {
+ if (entry.getKey() == null
+ || entry.getValue() == null
+ || !enableSubBrokerIdSet.contains(entry.getKey())) {
+ continue;
+ }
+ topicInfo = entry.getValue();
+ if (topicInfo.isAcceptSubscribe()) {
+ for (int j = 0; j < topicInfo.getTopicStoreNum(); j++) {
+ int baseValue = j * TBaseConstants.META_STORE_INS_BASE;
+ for (int i = 0; i < topicInfo.getPartitionNum(); i++) {
+ partList.add(new Partition(topicInfo.getBroker(),
+ topicInfo.getTopic(), baseValue + i));
+ }
+ }
+ }
+ }
+ return partList;
+ }
+
+ /**
+ * Gets the string map of topic partitions whose publish status is enabled
+ *
+ * @param topicSet need query topic set
+ */
+ public Map<String, String> getAcceptPubPartInfo(Set<String> topicSet,
+ Set<Integer>
enablePubBrokerIdSet) {
+ TopicInfo topicInfo;
+ TopicInfoView topicInfoView;
+ Map<String, String> topicPartStrMap = new HashMap<>();
+ Map<String, StringBuilder> topicPartBufferMap =
+ new HashMap<>();
+ for (String topic : topicSet) {
+ if (topic == null) {
+ continue;
+ }
+ topicInfoView = topicConfInfoMap.get(topic);
+ if (topicInfoView == null
+ || topicInfoView.brokerTopicInfoMap.isEmpty()) {
+ continue;
+ }
+ for (Map.Entry<Integer, TopicInfo> entry
+ : topicInfoView.brokerTopicInfoMap.entrySet()) {
+ if (entry.getKey() == null
+ || entry.getValue() == null
+ || !enablePubBrokerIdSet.contains(entry.getKey())) {
+ continue;
+ }
+ topicInfo = entry.getValue();
+ if (topicInfo.isAcceptPublish()) {
+ StringBuilder tmpValue = topicPartBufferMap.get(topic);
+ if (tmpValue == null) {
+ StringBuilder strBuffer =
+ new StringBuilder(512).append(topic)
+ .append(TokenConstants.SEGMENT_SEP)
+ .append(topicInfo.getSimpleValue());
+ topicPartBufferMap.put(topic, strBuffer);
+ } else {
+ tmpValue.append(TokenConstants.ARRAY_SEP)
+ .append(topicInfo.getSimpleValue());
+ }
+ }
+ }
+ }
+ for (Map.Entry<String, StringBuilder> entry :
topicPartBufferMap.entrySet()) {
+ if (entry.getValue() != null) {
+ topicPartStrMap.put(entry.getKey(),
entry.getValue().toString());
+ }
+ }
+ topicPartBufferMap.clear();
+ return topicPartStrMap;
+ }
+
+ /**
+ * Get the TopicInfo information of topic in broker
+ *
+ * @param brokerId need query broker
+ * @param topic need query topic
+ *
+ * @return null or topicInfo configure
+ */
+ public TopicInfo getBrokerPushedTopicInfo(int brokerId, String topic) {
+ TopicInfoView topicInfoView = topicConfInfoMap.get(topic);
+ if (topicInfoView == null) {
+ return null;
+ }
+ return topicInfoView.brokerTopicInfoMap.get(brokerId);
+ }
+
+ /**
+ * Get all TopicInfo information of broker
+ *
+ * @param brokerId need query broker
+ */
+ public List<TopicInfo> getBrokerPushedTopicInfo(int brokerId) {
+ TopicInfo topicInfo;
+ TopicInfoView topicInfoView;
+ List<TopicInfo> topicInfoList = new ArrayList<>();
+ ConcurrentHashSet<String> topicSet = brokerIdIndexMap.get(brokerId);
+ if (topicSet == null) {
+ return topicInfoList;
+ }
+ for (String topic : topicSet) {
+ if (topic == null) {
+ continue;
+ }
+ topicInfoView = topicConfInfoMap.get(topic);
+ if (topicInfoView == null
+ || topicInfoView.brokerTopicInfoMap.isEmpty()) {
+ continue;
+ }
+ topicInfo = topicInfoView.brokerTopicInfoMap.get(brokerId);
+ if (topicInfo == null) {
+ continue;
+ }
+ topicInfoList.add(topicInfo);
+ }
+ return topicInfoList;
+ }
+
+ // remove broker special topic info
+ private void rmvBrokerTopicInfo(int brokerId,
+ Set<String> delTopicSet) {
+ if (delTopicSet == null || delTopicSet.isEmpty()) {
+ return;
+ }
+ ConcurrentHashSet<String> topicSet =
+ brokerIdIndexMap.get(brokerId);
+ TopicInfoView topicInfoView;
+ if (topicSet == null || topicSet.isEmpty()) {
+ return;
+ }
+ for (String topic : delTopicSet) {
+ topicSet.remove(topic);
+ topicInfoView = topicConfInfoMap.get(topic);
+ if ((topicInfoView == null)
+ || topicInfoView.brokerTopicInfoMap.isEmpty()) {
+ continue;
+ }
+ topicInfoView.rmvBrokerTopicInfo(brokerId);
+ }
+ }
+
+ // add or update broker special topic info
+ private void repBrokerTopicInfo(int brokerId,
+ Map<String, TopicInfo> topicInfoMap) {
+ if (topicInfoMap == null || topicInfoMap.isEmpty()) {
+ return;
+ }
+ // add topic info
+ TopicInfoView newTopicInfoView;
+ TopicInfoView curTopicInfoView;
+ for (TopicInfo topicInfo : topicInfoMap.values()) {
+ if (topicInfo == null) {
+ continue;
+ }
+ curTopicInfoView = topicConfInfoMap.get(topicInfo.getTopic());
+ if (curTopicInfoView == null) {
+ newTopicInfoView = new TopicInfoView();
+ curTopicInfoView = topicConfInfoMap.putIfAbsent(
+ topicInfo.getTopic(), newTopicInfoView);
+ if (curTopicInfoView == null) {
+ curTopicInfoView = newTopicInfoView;
+ }
+ }
+ curTopicInfoView.addOrUpdBrokerTopicInfo(brokerId, topicInfo);
+ }
+ // add broker index
+ ConcurrentHashSet<String> curTopicSet = brokerIdIndexMap.get(brokerId);
+ if (curTopicSet == null) {
+ ConcurrentHashSet<String> newTopicSet = new ConcurrentHashSet<>();
+ curTopicSet = brokerIdIndexMap.putIfAbsent(brokerId, newTopicSet);
+ if (curTopicSet == null) {
+ curTopicSet = newTopicSet;
+ }
+ }
+ curTopicSet.addAll(topicInfoMap.keySet());
+ }
+
+ private static class TopicInfoView {
+ public AtomicInteger curMapSize = new AtomicInteger(0);
+ public AtomicLong topicChangeId = new AtomicLong(0);
+ public ConcurrentHashMap<Integer/* brokerId */, TopicInfo>
brokerTopicInfoMap =
+ new ConcurrentHashMap<Integer/* brokerId */, TopicInfo>();
+
+ public TopicInfoView() {
+
+ }
+
+ public boolean rmvBrokerTopicInfo(int brokerId) {
+ TopicInfo topicInfo = brokerTopicInfoMap.remove(brokerId);
+ if (topicInfo == null) {
+ return false;
+ }
+ curMapSize.decrementAndGet();
+ topicChangeId.set(System.currentTimeMillis());
+ return true;
+ }
+
+ public boolean addOrUpdBrokerTopicInfo(int brokerId, TopicInfo
topicInfo) {
+ if (topicInfo == null) {
+ return false;
+ }
+ TopicInfo newTopicInfo = topicInfo.clone();
+ TopicInfo preTopicInfo =
+ brokerTopicInfoMap.put(brokerId, newTopicInfo);
+ if (preTopicInfo == null) {
+ curMapSize.incrementAndGet();
+ }
+ topicChangeId.set(System.currentTimeMillis());
+ return true;
+ }
+ }
+}
diff --git
a/tubemq-server/src/main/java/org/apache/tubemq/server/master/nodemanage/nodebroker/TargetValidResult.java
b/tubemq-server/src/main/java/org/apache/tubemq/server/master/nodemanage/nodebroker/TargetValidResult.java
deleted file mode 100644
index 6a44f97..0000000
---
a/tubemq-server/src/main/java/org/apache/tubemq/server/master/nodemanage/nodebroker/TargetValidResult.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.tubemq.server.master.nodemanage.nodebroker;
-
-
-public class TargetValidResult {
- public boolean result;
- public int errCode;
- public String errInfo;
-
- public TargetValidResult(boolean result, int errCode, final String
errInfo) {
- this.result = result;
- this.errCode = errCode;
- this.errInfo = errInfo;
- }
-
-}
diff --git
a/tubemq-server/src/main/java/org/apache/tubemq/server/master/utils/BdbStoreSamplePrint.java
b/tubemq-server/src/main/java/org/apache/tubemq/server/master/utils/BdbStoreSamplePrint.java
index a92acdc..7c5fb1b 100644
---
a/tubemq-server/src/main/java/org/apache/tubemq/server/master/utils/BdbStoreSamplePrint.java
+++
b/tubemq-server/src/main/java/org/apache/tubemq/server/master/utils/BdbStoreSamplePrint.java
@@ -96,4 +96,13 @@ public class BdbStoreSamplePrint extends AbstractSamplePrint
{
}
}
+ @Override
+ public void printWarn(String err) {
+ //
+ }
+
+ @Override
+ public void printError(String err) {
+ //
+ }
}
diff --git
a/tubemq-server/src/main/java/org/apache/tubemq/server/master/utils/BrokerStatusSamplePrint.java
b/tubemq-server/src/main/java/org/apache/tubemq/server/master/utils/BrokerStatusSamplePrint.java
new file mode 100644
index 0000000..b098eba
--- /dev/null
+++
b/tubemq-server/src/main/java/org/apache/tubemq/server/master/utils/BrokerStatusSamplePrint.java
@@ -0,0 +1,82 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.tubemq.server.master.utils;
+
+import org.apache.tubemq.corebase.utils.AbstractSamplePrint;
+import org.slf4j.Logger;
+
+
+public class BrokerStatusSamplePrint extends AbstractSamplePrint {
+ /**
+ * Log limit class
+ */
+ private final Logger logger;
+
+ public BrokerStatusSamplePrint(final Logger logger) {
+ super();
+ this.logger = logger;
+ }
+
+ public BrokerStatusSamplePrint(final Logger logger,
+ long sampleDetailDur, long sampleResetDur,
+ long maxDetailCount, long maxTotalCount) {
+ super(sampleDetailDur, sampleResetDur, maxDetailCount, maxTotalCount);
+ this.logger = logger;
+ }
+
+ @Override
+ public void printExceptionCaught(Throwable e) {
+ //
+ }
+
+ @Override
+ public void printExceptionCaught(Throwable e, String hostName, String
nodeName) {
+ //
+ }
+
+ @Override
+ public void printWarn(String err) {
+ printMsg(true, err);
+ }
+
+ @Override
+ public void printError(String err) {
+ printMsg(false, err);
+ }
+
+ private void printMsg(boolean isWarn, String err) {
+ final long now = System.currentTimeMillis();
+ final long diffTime = now - lastLogTime.get();
+ final long curPrintCnt = totalPrintCount.incrementAndGet();
+ if (curPrintCnt < maxTotalCount) {
+ if (diffTime < sampleDetailDur && curPrintCnt < maxDetailCount) {
+ if (isWarn) {
+ logger.warn(err);
+ } else {
+ logger.error(err);
+ }
+ }
+ }
+ if (diffTime > sampleResetDur) {
+ if (this.lastLogTime.compareAndSet(now - diffTime, now)) {
+ totalPrintCount.set(0);
+ }
+ }
+ }
+
+}