feature(namesrv&common):[RIP-29]Optimize RocketMQ NameServer (#3974)

This commit is contained in:
rongtong
2022-03-14 14:49:53 +08:00
committed by RongtongJin
parent 176e0d5c22
commit 467b382777
114 changed files with 8353 additions and 796 deletions
@@ -0,0 +1,42 @@
/*
* 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.common;
import org.apache.rocketmq.logging.InnerLoggerFactory;
public abstract class AbstractBrokerRunnable implements Runnable {
protected final BrokerIdentity brokerIdentity;
public AbstractBrokerRunnable(BrokerIdentity brokerIdentity) {
this.brokerIdentity = brokerIdentity;
}
/**
* real logic for running
*/
public abstract void run2();
@Override
public void run() {
if (brokerIdentity.isInBrokerContainer()) {
// set threadlocal broker identity to forward logging to corresponding broker
InnerLoggerFactory.brokerIdentity.set(brokerIdentity.getCanonicalName());
}
run2();
}
}
@@ -16,8 +16,6 @@
*/
package org.apache.rocketmq.common;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.apache.rocketmq.common.annotation.ImportantField;
import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.common.constant.PermName;
@@ -27,21 +25,25 @@ import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
import org.apache.rocketmq.remoting.common.RemotingUtil;
public class BrokerConfig {
public class BrokerConfig extends BrokerIdentity {
private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.COMMON_LOGGER_NAME);
private String brokerConfigPath = null;
private String rocketmqHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY, System.getenv(MixAll.ROCKETMQ_HOME_ENV));
@ImportantField
private String namesrvAddr = System.getProperty(MixAll.NAMESRV_ADDR_PROPERTY, System.getenv(MixAll.NAMESRV_ADDR_ENV));
/**
* Listen port for single broker
*/
@ImportantField
private int listenPort = 6888;
@ImportantField
private String brokerIP1 = RemotingUtil.getLocalAddress();
private String brokerIP2 = RemotingUtil.getLocalAddress();
@ImportantField
private String brokerName = localHostName();
@ImportantField
private String brokerClusterName = "DefaultCluster";
@ImportantField
private long brokerId = MixAll.MASTER_ID;
private int brokerPermission = PermName.PERM_READ | PermName.PERM_WRITE;
private int defaultTopicQueueNums = 8;
@ImportantField
@@ -53,6 +55,8 @@ public class BrokerConfig {
@ImportantField
private boolean autoCreateSubscriptionGroup = true;
private String messageStorePlugIn = "";
private static final int PROCESSOR_NUMBER = Runtime.getRuntime().availableProcessors();
@ImportantField
private String msgTraceTopicName = TopicValidator.RMQ_SYS_TRACE_TOPIC;
@ImportantField
@@ -60,24 +64,25 @@ public class BrokerConfig {
/**
* thread numbers for send message thread pool.
*/
private int sendMessageThreadPoolNums = Math.min(Runtime.getRuntime().availableProcessors(), 4);
private int putMessageFutureThreadPoolNums = Math.min(Runtime.getRuntime().availableProcessors(), 4);
private int pullMessageThreadPoolNums = 16 + Runtime.getRuntime().availableProcessors() * 2;
private int sendMessageThreadPoolNums = Math.min(PROCESSOR_NUMBER, 4);
private int putMessageFutureThreadPoolNums = Math.min(PROCESSOR_NUMBER, 4);
private int pullMessageThreadPoolNums = 16 + PROCESSOR_NUMBER * 2;
private int litePullMessageThreadPoolNums = 16 + PROCESSOR_NUMBER * 2;
private int ackMessageThreadPoolNums = 3;
private int processReplyMessageThreadPoolNums = 16 + Runtime.getRuntime().availableProcessors() * 2;
private int queryMessageThreadPoolNums = 8 + Runtime.getRuntime().availableProcessors();
private int processReplyMessageThreadPoolNums = 16 + PROCESSOR_NUMBER * 2;
private int queryMessageThreadPoolNums = 8 + PROCESSOR_NUMBER;
private int adminBrokerThreadPoolNums = 16;
private int clientManageThreadPoolNums = 32;
private int consumerManageThreadPoolNums = 32;
private int loadBalanceProcessorThreadPoolNums = 32;
private int heartbeatThreadPoolNums = Math.min(32, Runtime.getRuntime().availableProcessors());
private int heartbeatThreadPoolNums = Math.min(32, PROCESSOR_NUMBER);
/**
* Thread numbers for EndTransactionProcessor
*/
private int endTransactionThreadPoolNums = Math.max(8 + Runtime.getRuntime().availableProcessors() * 2,
sendMessageThreadPoolNums * 4);
private int endTransactionThreadPoolNums = Math.max(8 + PROCESSOR_NUMBER * 2,
sendMessageThreadPoolNums * 4);
private int flushConsumerOffsetInterval = 1000 * 5;
@@ -90,6 +95,7 @@ public class BrokerConfig {
private int sendThreadPoolQueueCapacity = 10000;
private int putThreadPoolQueueCapacity = 10000;
private int pullThreadPoolQueueCapacity = 100000;
private int litePullThreadPoolQueueCapacity = 100000;
private int ackThreadPoolQueueCapacity = 100000;
private int replyThreadPoolQueueCapacity = 10000;
private int queryThreadPoolQueueCapacity = 20000;
@@ -97,6 +103,8 @@ public class BrokerConfig {
private int consumerManagerThreadPoolQueueCapacity = 1000000;
private int heartbeatThreadPoolQueueCapacity = 50000;
private int endTransactionPoolQueueCapacity = 100000;
private int adminBrokerThreadPoolQueueCapacity = 10000;
private int loadBalanceThreadPoolQueueCapacity = 100000;
private int filterServerNums = 0;
@@ -108,17 +116,20 @@ public class BrokerConfig {
private boolean highSpeedMode = false;
private boolean commercialEnable = true;
private int commercialTimerCount = 1;
private int commercialTransCount = 1;
private int commercialBigCount = 1;
private int commercialBaseCount = 1;
private int commercialSizePerMsg = 4 * 1024;
private boolean accountStatsEnable = true;
private boolean accountStatsPrintZeroValues = true;
private boolean transferMsgByHeap = true;
private int maxDelayTime = 40;
private String regionId = MixAll.DEFAULT_TRACE_REGION_ID;
private int registerBrokerTimeoutMills = 6000;
private int registerBrokerTimeoutMills = 24000;
private int sendHeartbeatTimeoutMillis = 1000;
private boolean slaveReadEnable = false;
@@ -128,8 +139,10 @@ public class BrokerConfig {
private boolean brokerFastFailureEnable = true;
private long waitTimeMillsInSendQueue = 200;
private long waitTimeMillsInPullQueue = 5 * 1000;
private long waitTimeMillsInLitePullQueue = 5 * 1000;
private long waitTimeMillsInHeartbeatQueue = 31 * 1000;
private long waitTimeMillsInTransactionQueue = 3 * 1000;
private long waitTimeMillsInAckQueue = 3000;
private long startAcceptSendRequestTimeStamp = 0L;
@@ -141,6 +154,9 @@ public class BrokerConfig {
// 2. Filter bit map will be saved to consume queue extend file if allowed.
private boolean enableCalcFilterBitMap = false;
//Reject the pull consumer instance to pull messages from broker.
private boolean rejectPullConsumerEnable = false;
// Expect num of consumers will use filter.
private int expectConsumerNumUseFilter = 32;
@@ -160,10 +176,23 @@ public class BrokerConfig {
/**
* This configurable item defines interval of topics registration of broker to name server. Allowing values are
* between 10, 000 and 60, 000 milliseconds.
* between 10,000 and 60,000 milliseconds.
*/
private int registerNameServerPeriod = 1000 * 30;
/**
* the interval to send heartbeat to name server for liveness detection.
*/
private int brokerHeartbeatInterval = 1000;
/**
* How long the broker will be considered as inactive by nameserver since last heartbeat. Effective only if
* enableSlaveActingMaster is true
*/
private long brokerNotActiveTimeoutMillis = 10 * 1000;
private boolean netWorkFlowController = true;
private int popPollingSize = 1024;
private int popPollingMapSize = 100000;
// 20w cost 200M heap memory.
@@ -172,13 +201,20 @@ public class BrokerConfig {
private long reviveInterval = 1000;
private long reviveMaxSlow = 3;
private long reviveScanTime = 10000;
private boolean enablePopLog = true;
private boolean enablePopLog = false;
private boolean enablePopBufferMerge = false;
private int popCkStayBufferTime = 10 * 1000;
private int popCkStayBufferTimeOut = 3 * 1000;
private int popCkMaxBufferSize = 200000;
private int popCkOffsetMaxQueueSize = 20000;
private boolean realTimeNotifyConsumerChange = true;
private boolean litePullMessageEnable = true;
// The period to sync broker member group from namesrv, default value is 1 second
private int syncBrokerMemberGroupPeriod = 1000;
/**
* the interval of pulling topic information from the named server
*/
@@ -233,15 +269,31 @@ public class BrokerConfig {
private long forwardTimeout = 3 * 1000;
public static String localHostName() {
try {
return InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
log.error("Failed to obtain the host name", e);
}
/**
* Slave will act master when failover. For example, if master down, timer or transaction message which is expire in slave will
* put to master (master of the same process in broker container mode or other masters in cluster when enableFailoverRemotingActing is true)
* when enableSlaveActingMaster is true
*/
private boolean enableSlaveActingMaster = false;
return "DEFAULT_BROKER";
}
private boolean enableRemoteEscape = false;
private boolean skipPreOnline = false;
private boolean asyncSendEnable = true;
private long consumerOffsetUpdateVersionStep = 500;
private long delayOffsetUpdateVersionStep = 200;
/**
* Whether to lock quorum replicas.
*
* True: need to lock quorum replicas succeed. False: only need to lock one replica succeed.
*/
private boolean lockInStrictMode = false;
private String metaDataHosts = "";
public long getMaxPopPollingSize() {
return maxPopPollingSize;
@@ -451,22 +503,6 @@ public class BrokerConfig {
this.highSpeedMode = highSpeedMode;
}
public String getRocketmqHome() {
return rocketmqHome;
}
public void setRocketmqHome(String rocketmqHome) {
this.rocketmqHome = rocketmqHome;
}
public String getBrokerName() {
return brokerName;
}
public void setBrokerName(String brokerName) {
this.brokerName = brokerName;
}
public int getBrokerPermission() {
return brokerPermission;
}
@@ -491,14 +527,6 @@ public class BrokerConfig {
this.autoCreateTopicEnable = autoCreateTopic;
}
public String getBrokerClusterName() {
return brokerClusterName;
}
public void setBrokerClusterName(String brokerClusterName) {
this.brokerClusterName = brokerClusterName;
}
public String getBrokerIP1() {
return brokerIP1;
}
@@ -603,14 +631,6 @@ public class BrokerConfig {
this.namesrvAddr = namesrvAddr;
}
public long getBrokerId() {
return brokerId;
}
public void setBrokerId(long brokerId) {
this.brokerId = brokerId;
}
public boolean isAutoCreateSubscriptionGroup() {
return autoCreateSubscriptionGroup;
}
@@ -619,6 +639,94 @@ public class BrokerConfig {
this.autoCreateSubscriptionGroup = autoCreateSubscriptionGroup;
}
public String getBrokerConfigPath() {
return brokerConfigPath;
}
public void setBrokerConfigPath(String brokerConfigPath) {
this.brokerConfigPath = brokerConfigPath;
}
public String getRocketmqHome() {
return rocketmqHome;
}
public void setRocketmqHome(String rocketmqHome) {
this.rocketmqHome = rocketmqHome;
}
public int getListenPort() {
return listenPort;
}
public void setListenPort(int listenPort) {
this.listenPort = listenPort;
}
public int getLitePullMessageThreadPoolNums() {
return litePullMessageThreadPoolNums;
}
public void setLitePullMessageThreadPoolNums(int litePullMessageThreadPoolNums) {
this.litePullMessageThreadPoolNums = litePullMessageThreadPoolNums;
}
public int getLitePullThreadPoolQueueCapacity() {
return litePullThreadPoolQueueCapacity;
}
public void setLitePullThreadPoolQueueCapacity(int litePullThreadPoolQueueCapacity) {
this.litePullThreadPoolQueueCapacity = litePullThreadPoolQueueCapacity;
}
public int getAdminBrokerThreadPoolQueueCapacity() {
return adminBrokerThreadPoolQueueCapacity;
}
public void setAdminBrokerThreadPoolQueueCapacity(int adminBrokerThreadPoolQueueCapacity) {
this.adminBrokerThreadPoolQueueCapacity = adminBrokerThreadPoolQueueCapacity;
}
public int getLoadBalanceThreadPoolQueueCapacity() {
return loadBalanceThreadPoolQueueCapacity;
}
public void setLoadBalanceThreadPoolQueueCapacity(int loadBalanceThreadPoolQueueCapacity) {
this.loadBalanceThreadPoolQueueCapacity = loadBalanceThreadPoolQueueCapacity;
}
public int getSendHeartbeatTimeoutMillis() {
return sendHeartbeatTimeoutMillis;
}
public void setSendHeartbeatTimeoutMillis(int sendHeartbeatTimeoutMillis) {
this.sendHeartbeatTimeoutMillis = sendHeartbeatTimeoutMillis;
}
public long getWaitTimeMillsInLitePullQueue() {
return waitTimeMillsInLitePullQueue;
}
public void setWaitTimeMillsInLitePullQueue(long waitTimeMillsInLitePullQueue) {
this.waitTimeMillsInLitePullQueue = waitTimeMillsInLitePullQueue;
}
public boolean isLitePullMessageEnable() {
return litePullMessageEnable;
}
public void setLitePullMessageEnable(boolean litePullMessageEnable) {
this.litePullMessageEnable = litePullMessageEnable;
}
public int getSyncBrokerMemberGroupPeriod() {
return syncBrokerMemberGroupPeriod;
}
public void setSyncBrokerMemberGroupPeriod(int syncBrokerMemberGroupPeriod) {
this.syncBrokerMemberGroupPeriod = syncBrokerMemberGroupPeriod;
}
public boolean isRejectTransactionMessage() {
return rejectTransactionMessage;
}
@@ -731,38 +839,6 @@ public class BrokerConfig {
this.clientManageThreadPoolNums = clientManageThreadPoolNums;
}
public boolean isCommercialEnable() {
return commercialEnable;
}
public void setCommercialEnable(final boolean commercialEnable) {
this.commercialEnable = commercialEnable;
}
public int getCommercialTimerCount() {
return commercialTimerCount;
}
public void setCommercialTimerCount(final int commercialTimerCount) {
this.commercialTimerCount = commercialTimerCount;
}
public int getCommercialTransCount() {
return commercialTransCount;
}
public void setCommercialTransCount(final int commercialTransCount) {
this.commercialTransCount = commercialTransCount;
}
public int getCommercialBigCount() {
return commercialBigCount;
}
public void setCommercialBigCount(final int commercialBigCount) {
this.commercialBigCount = commercialBigCount;
}
public int getMaxDelayTime() {
return maxDelayTime;
}
@@ -1051,6 +1127,142 @@ public class BrokerConfig {
this.forwardTimeout = timeout;
}
public int getBrokerHeartbeatInterval() {
return brokerHeartbeatInterval;
}
public void setBrokerHeartbeatInterval(int brokerHeartbeatInterval) {
this.brokerHeartbeatInterval = brokerHeartbeatInterval;
}
public long getBrokerNotActiveTimeoutMillis() {
return brokerNotActiveTimeoutMillis;
}
public void setBrokerNotActiveTimeoutMillis(long brokerNotActiveTimeoutMillis) {
this.brokerNotActiveTimeoutMillis = brokerNotActiveTimeoutMillis;
}
public boolean isNetWorkFlowController() {
return netWorkFlowController;
}
public void setNetWorkFlowController(boolean netWorkFlowController) {
this.netWorkFlowController = netWorkFlowController;
}
public boolean isRealTimeNotifyConsumerChange() {
return realTimeNotifyConsumerChange;
}
public void setRealTimeNotifyConsumerChange(boolean realTimeNotifyConsumerChange) {
this.realTimeNotifyConsumerChange = realTimeNotifyConsumerChange;
}
public boolean isEnableSlaveActingMaster() {
return enableSlaveActingMaster;
}
public void setEnableSlaveActingMaster(boolean enableSlaveActingMaster) {
this.enableSlaveActingMaster = enableSlaveActingMaster;
}
public boolean isEnableRemoteEscape() {
return enableRemoteEscape;
}
public void setEnableRemoteEscape(boolean enableRemoteEscape) {
this.enableRemoteEscape = enableRemoteEscape;
}
public boolean isSkipPreOnline() {
return skipPreOnline;
}
public void setSkipPreOnline(boolean skipPreOnline) {
this.skipPreOnline = skipPreOnline;
}
public boolean isAsyncSendEnable() {
return asyncSendEnable;
}
public void setAsyncSendEnable(boolean asyncSendEnable) {
this.asyncSendEnable = asyncSendEnable;
}
public long getConsumerOffsetUpdateVersionStep() {
return consumerOffsetUpdateVersionStep;
}
public void setConsumerOffsetUpdateVersionStep(long consumerOffsetUpdateVersionStep) {
this.consumerOffsetUpdateVersionStep = consumerOffsetUpdateVersionStep;
}
public long getDelayOffsetUpdateVersionStep() {
return delayOffsetUpdateVersionStep;
}
public void setDelayOffsetUpdateVersionStep(long delayOffsetUpdateVersionStep) {
this.delayOffsetUpdateVersionStep = delayOffsetUpdateVersionStep;
}
public int getCommercialSizePerMsg() {
return commercialSizePerMsg;
}
public void setCommercialSizePerMsg(int commercialSizePerMsg) {
this.commercialSizePerMsg = commercialSizePerMsg;
}
public long getWaitTimeMillsInAckQueue() {
return waitTimeMillsInAckQueue;
}
public void setWaitTimeMillsInAckQueue(long waitTimeMillsInAckQueue) {
this.waitTimeMillsInAckQueue = waitTimeMillsInAckQueue;
}
public boolean isRejectPullConsumerEnable() {
return rejectPullConsumerEnable;
}
public void setRejectPullConsumerEnable(boolean rejectPullConsumerEnable) {
this.rejectPullConsumerEnable = rejectPullConsumerEnable;
}
public boolean isAccountStatsEnable() {
return accountStatsEnable;
}
public void setAccountStatsEnable(boolean accountStatsEnable) {
this.accountStatsEnable = accountStatsEnable;
}
public boolean isAccountStatsPrintZeroValues() {
return accountStatsPrintZeroValues;
}
public void setAccountStatsPrintZeroValues(boolean accountStatsPrintZeroValues) {
this.accountStatsPrintZeroValues = accountStatsPrintZeroValues;
}
public boolean isLockInStrictMode() {
return lockInStrictMode;
}
public void setLockInStrictMode(boolean lockInStrictMode) {
this.lockInStrictMode = lockInStrictMode;
}
public String getMetaDataHosts() {
return metaDataHosts;
}
public void setMetaDataHosts(String metaDataHosts) {
this.metaDataHosts = metaDataHosts;
}
public boolean isIsolateLogEnable() {
return isolateLogEnable;
}
@@ -0,0 +1,149 @@
/*
* 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.common;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.rocketmq.common.annotation.ImportantField;
import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.logging.InnerLoggerFactory;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
public class BrokerIdentity {
private static final String DEFAULT_CLUSTER_NAME = "DefaultCluster";
protected static final InternalLogger LOGGER = InternalLoggerFactory.getLogger(LoggerName.COMMON_LOGGER_NAME);
public static final BrokerIdentity BROKER_CONTAINER_IDENTITY = new BrokerIdentity(true);
@ImportantField
private String brokerName = localHostName();
@ImportantField
private String brokerClusterName = DEFAULT_CLUSTER_NAME;
@ImportantField
private volatile long brokerId = MixAll.MASTER_ID;
private boolean isBrokerContainer = false;
// Do not set it manually, it depends on the startup mode
// Broker start by BrokerStartup is false, start or add by BrokerContainer is true
private boolean isInBrokerContainer = false;
public BrokerIdentity() {
}
public BrokerIdentity(boolean isBrokerContainer) {
this.isBrokerContainer = isBrokerContainer;
}
public BrokerIdentity(String brokerClusterName, String brokerName, long brokerId) {
this.brokerName = brokerName;
this.brokerClusterName = brokerClusterName;
this.brokerId = brokerId;
}
public BrokerIdentity(String brokerClusterName, String brokerName, long brokerId, boolean isInBrokerContainer) {
this.brokerName = brokerName;
this.brokerClusterName = brokerClusterName;
this.brokerId = brokerId;
this.isInBrokerContainer = isInBrokerContainer;
}
public String getBrokerName() {
return brokerName;
}
public void setBrokerName(final String brokerName) {
this.brokerName = brokerName;
}
public String getBrokerClusterName() {
return brokerClusterName;
}
public void setBrokerClusterName(final String brokerClusterName) {
this.brokerClusterName = brokerClusterName;
}
public long getBrokerId() {
return brokerId;
}
public void setBrokerId(final long brokerId) {
this.brokerId = brokerId;
}
public boolean isInBrokerContainer() {
return isInBrokerContainer;
}
public void setInBrokerContainer(boolean inBrokerContainer) {
isInBrokerContainer = inBrokerContainer;
}
protected static String localHostName() {
try {
return InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
LOGGER.error("Failed to obtain the host name", e);
}
return "DEFAULT_BROKER";
}
public String getCanonicalName() {
if (isBrokerContainer) {
return InnerLoggerFactory.BROKER_CONTAINER_NAME;
}
return this.getBrokerClusterName() + "_" + this.getBrokerName() + "_" + this.getBrokerId();
}
public String getLoggerIdentifier() {
return "#" + getCanonicalName() + "#";
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final BrokerIdentity identity = (BrokerIdentity) o;
return new EqualsBuilder()
.append(brokerId, identity.brokerId)
.append(brokerName, identity.brokerName)
.append(brokerClusterName, identity.brokerClusterName)
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(brokerName)
.append(brokerClusterName)
.append(brokerId)
.toHashCode();
}
}
@@ -0,0 +1,70 @@
/*
* 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.common;
import org.apache.rocketmq.remoting.protocol.RemotingSerializable;
public class BrokerSyncInfo extends RemotingSerializable {
/**
* For slave online sync, retrieve HA address before register
*/
private String masterHaAddress;
private long masterFlushOffset;
private String masterAddress;
public BrokerSyncInfo(String masterHaAddress, long masterFlushOffset, String masterAddress) {
this.masterHaAddress = masterHaAddress;
this.masterFlushOffset = masterFlushOffset;
this.masterAddress = masterAddress;
}
public String getMasterHaAddress() {
return masterHaAddress;
}
public void setMasterHaAddress(String masterHaAddress) {
this.masterHaAddress = masterHaAddress;
}
public long getMasterFlushOffset() {
return masterFlushOffset;
}
public void setMasterFlushOffset(long masterFlushOffset) {
this.masterFlushOffset = masterFlushOffset;
}
public String getMasterAddress() {
return masterAddress;
}
public void setMasterAddress(String masterAddress) {
this.masterAddress = masterAddress;
}
@Override
public String toString() {
return "BrokerSyncInfo{" +
"masterHaAddress='" + masterHaAddress + '\'' +
", masterFlushOffset=" + masterFlushOffset +
", masterAddress=" + masterAddress +
'}';
}
}
@@ -55,6 +55,9 @@ public class Configuration {
return;
}
for (Object configObject : configObjects) {
if (configObject == null) {
continue;
}
registerConfig(configObject);
}
}
@@ -234,6 +237,24 @@ public class Configuration {
return null;
}
public String getClientConfigsFormatString(List<String> clientKeys) {
try {
readWriteLock.readLock().lockInterruptibly();
try {
return getClientConfigsInternal(clientKeys);
} finally {
readWriteLock.readLock().unlock();
}
} catch (InterruptedException e) {
log.error("getAllConfigsFormatString lock error");
}
return null;
}
public String getDataVersionJson() {
return this.dataVersion.toJson();
}
@@ -276,6 +297,26 @@ public class Configuration {
return stringBuilder.toString();
}
private String getClientConfigsInternal(List<String> clientConigKeys) {
StringBuilder stringBuilder = new StringBuilder();
Properties clientProperties = new Properties();
// reload from config object ?
for (Object configObject : this.configObjectList) {
Properties properties = MixAll.object2Properties(configObject);
for (String nameNow : clientConigKeys) {
if (properties.containsKey(nameNow)) {
clientProperties.put(nameNow, properties.get(nameNow));
}
}
}
stringBuilder.append(MixAll.properties2String(clientProperties));
return stringBuilder.toString();
}
private void merge(Properties from, Properties to) {
for (Entry<Object, Object> next : from.entrySet()) {
Object fromObj = next.getValue(), toObj = to.get(next.getKey());
@@ -20,19 +20,34 @@ import java.util.concurrent.atomic.AtomicLong;
import org.apache.rocketmq.remoting.protocol.RemotingSerializable;
public class DataVersion extends RemotingSerializable {
private long stateVersion = 0L;
private long timestamp = System.currentTimeMillis();
private AtomicLong counter = new AtomicLong(0);
public void assignNewOne(final DataVersion dataVersion) {
this.timestamp = dataVersion.timestamp;
this.stateVersion = dataVersion.stateVersion;
this.counter.set(dataVersion.counter.get());
}
public void nextVersion() {
this.nextVersion(0L);
}
public void nextVersion(long stateVersion) {
this.timestamp = System.currentTimeMillis();
this.stateVersion = stateVersion;
this.counter.incrementAndGet();
}
public long getStateVersion() {
return stateVersion;
}
public void setStateVersion(long stateVersion) {
this.stateVersion = stateVersion;
}
public long getTimestamp() {
return timestamp;
}
@@ -56,22 +71,25 @@ public class DataVersion extends RemotingSerializable {
if (o == null || getClass() != o.getClass())
return false;
final DataVersion that = (DataVersion) o;
DataVersion version = (DataVersion) o;
if (timestamp != that.timestamp) {
if (getStateVersion() != version.getStateVersion())
return false;
if (getTimestamp() != version.getTimestamp())
return false;
if (counter != null && version.counter != null) {
return counter.longValue() == version.counter.longValue();
}
if (counter != null && that.counter != null) {
return counter.longValue() == that.counter.longValue();
}
return (null == counter) && (null == version.counter);
return (null == counter) && (null == that.counter);
}
@Override
public int hashCode() {
int result = (int) (timestamp ^ (timestamp >>> 32));
int result = (int) (getStateVersion() ^ (getStateVersion() >>> 32));
result = 31 * result + (int) (getTimestamp() ^ (getTimestamp() >>> 32));
if (null != counter) {
long l = counter.get();
result = 31 * result + (int) (l ^ (l >>> 32));
@@ -87,4 +105,21 @@ public class DataVersion extends RemotingSerializable {
sb.append(']');
return sb.toString();
}
public int compare(DataVersion dataVersion) {
if (this.getStateVersion() > dataVersion.getStateVersion()) {
return 1;
} else if (this.getStateVersion() < dataVersion.getStateVersion()) {
return -1;
} else if (this.getCounter().get() > dataVersion.getCounter().get()) {
return 1;
} else if (this.getCounter().get() < dataVersion.getCounter().get()) {
return -1;
} else if (this.getTimestamp() > dataVersion.getTimestamp()) {
return 1;
} else if (this.getTimestamp() < dataVersion.getTimestamp()) {
return -1;
}
return 0;
}
}
@@ -34,4 +34,8 @@ public class KeyBuilder {
public static String buildPollingKey(String topic, String cid, int queueId) {
return topic + PopAckConstants.SPLIT + cid + PopAckConstants.SPLIT + queueId;
}
public static String buildPollingNotificationKey(String topic, int queueId) {
return topic + PopAckConstants.SPLIT + queueId;
}
}
@@ -0,0 +1,26 @@
/*
* 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.common;
import java.util.Set;
import org.apache.rocketmq.common.message.MessageQueue;
public interface LockCallback {
void onSuccess(final Set<MessageQueue> lockOKMQSet);
void onException(final Throwable e);
}
@@ -74,7 +74,10 @@ public class MixAll {
public static final String LOCALHOST = localhost();
public static final String DEFAULT_CHARSET = "UTF-8";
public static final long MASTER_ID = 0L;
public static final long FIRST_SLAVE_ID = 1L;
public static final long CURRENT_JVM_PID = getPID();
public final static int UNIT_PRE_SIZE_FOR_MSG = 28;
public static final String RETRY_GROUP_TOPIC_PREFIX = "%RETRY%";
public static final String DLQ_GROUP_TOPIC_PREFIX = "%DLQ%";
public static final String REPLY_TOPIC_POSTFIX = "REPLY_TOPIC";
@@ -90,6 +93,7 @@ public class MixAll {
public static final String LOGICAL_QUEUE_MOCK_BROKER_PREFIX = "__syslo__";
public static final String METADATA_SCOPE_GLOBAL = "__global__";
public static final String LOGICAL_QUEUE_MOCK_BROKER_NAME_NOT_EXIST = "__syslo__none__";
public static final String MULTI_PATH_SPLITTER = System.getProperty("rocketmq.broker.multiPathSplitter", ",");
public static String getWSAddr() {
String wsDomainName = System.getProperty("rocketmq.namesrv.domain", DEFAULT_NAMESRV_ADDR_LOOKUP);
@@ -32,4 +32,13 @@ public class PopAckConstants {
public static final String ACK_TAG = "ack";
public static final String SPLIT = "@";
/**
* Build cluster revive topic
*
* @param clusterName cluster name
* @return revive topic
*/
public static String buildClusterReviveTopic(String clusterName) {
return PopAckConstants.REVIVE_TOPIC + clusterName;
}
}
@@ -27,7 +27,7 @@ public abstract class ServiceThread implements Runnable {
private static final long JOIN_TIME = 90 * 1000;
private Thread thread;
protected Thread thread;
protected final CountDownLatch2 waitPoint = new CountDownLatch2(1);
protected volatile AtomicBoolean hasNotified = new AtomicBoolean(false);
protected volatile boolean stopped = false;
@@ -76,17 +76,17 @@ public abstract class ServiceThread implements Runnable {
long beginTime = System.currentTimeMillis();
if (!this.thread.isDaemon()) {
this.thread.join(this.getJointime());
this.thread.join(this.getJoinTime());
}
long elapsedTime = System.currentTimeMillis() - beginTime;
log.info("join thread " + this.getServiceName() + " elapsed time(ms) " + elapsedTime + " "
+ this.getJointime());
+ this.getJoinTime());
} catch (InterruptedException e) {
log.error("Interrupted", e);
}
}
public long getJointime() {
public long getJoinTime() {
return JOIN_TIME;
}
@@ -34,6 +34,19 @@ public class ThreadFactoryImpl implements ThreadFactory {
this.daemon = daemon;
}
public ThreadFactoryImpl(final String threadNamePrefix, BrokerIdentity brokerIdentity) {
this(threadNamePrefix, false, brokerIdentity);
}
public ThreadFactoryImpl(final String threadNamePrefix, boolean daemon, BrokerIdentity brokerIdentity) {
this.daemon = daemon;
if (brokerIdentity != null && brokerIdentity.isInBrokerContainer()) {
this.threadNamePrefix = brokerIdentity.getLoggerIdentifier() + threadNamePrefix;
} else {
this.threadNamePrefix = threadNamePrefix;
}
}
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, threadNamePrefix + this.threadIndex.incrementAndGet());
@@ -40,16 +40,6 @@ public class TopicConfig {
this.topicName = topicName;
}
public TopicConfig(TopicConfig other) {
this.topicName = other.topicName;
this.readQueueNums = other.readQueueNums;
this.writeQueueNums = other.writeQueueNums;
this.perm = other.perm;
this.topicFilterType = other.topicFilterType;
this.topicSysFlag = other.topicSysFlag;
this.order = other.order;
}
public TopicConfig(String topicName, int readQueueNums, int writeQueueNums) {
this.topicName = topicName;
this.readQueueNums = readQueueNums;
@@ -63,16 +53,38 @@ public class TopicConfig {
this.perm = perm;
}
public TopicConfig(String topicName, int readQueueNums, int writeQueueNums, int perm, int topicSysFlag) {
this.topicName = topicName;
this.readQueueNums = readQueueNums;
this.writeQueueNums = writeQueueNums;
this.perm = perm;
this.topicSysFlag = topicSysFlag;
}
public TopicConfig(TopicConfig other) {
this.topicName = other.topicName;
this.readQueueNums = other.readQueueNums;
this.writeQueueNums = other.writeQueueNums;
this.perm = other.perm;
this.topicFilterType = other.topicFilterType;
this.topicSysFlag = other.topicSysFlag;
this.order = other.order;
}
public String encode() {
StringBuilder sb = new StringBuilder();
//[0]
sb.append(this.topicName);
sb.append(SEPARATOR);
//[1]
sb.append(this.readQueueNums);
sb.append(SEPARATOR);
//[2]
sb.append(this.writeQueueNums);
sb.append(SEPARATOR);
//[3]
sb.append(this.perm);
sb.append(SEPARATOR);
//[4]
sb.append(this.topicFilterType);
// Leave the encode/decode [attributes] out for now
@@ -82,7 +94,7 @@ public class TopicConfig {
public boolean decode(final String in) {
String[] strs = in.split(SEPARATOR);
if (strs != null && strs.length == 5) {
if (strs != null && strs.length >= 5) {
this.topicName = strs[0];
this.readQueueNums = Integer.parseInt(strs[1]);
@@ -165,18 +177,27 @@ public class TopicConfig {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
TopicConfig that = (TopicConfig) o;
if (readQueueNums != that.readQueueNums) return false;
if (writeQueueNums != that.writeQueueNums) return false;
if (perm != that.perm) return false;
if (topicSysFlag != that.topicSysFlag) return false;
if (order != that.order) return false;
if (topicName != null ? !topicName.equals(that.topicName) : that.topicName != null) return false;
if (topicFilterType != that.topicFilterType) return false;
if (readQueueNums != that.readQueueNums)
return false;
if (writeQueueNums != that.writeQueueNums)
return false;
if (perm != that.perm)
return false;
if (topicSysFlag != that.topicSysFlag)
return false;
if (order != that.order)
return false;
if (topicName != null ? !topicName.equals(that.topicName) : that.topicName != null)
return false;
if (topicFilterType != that.topicFilterType)
return false;
return attributes != null ? attributes.equals(that.attributes) : that.attributes == null;
}
@@ -0,0 +1,23 @@
/*
* 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.common;
public interface UnlockCallback {
void onSuccess();
void onException(final Throwable e);
}
@@ -21,10 +21,14 @@ import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.nio.ByteBuffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -229,7 +233,6 @@ public class UtilAll {
return -1;
}
long totalSpace = file.getTotalSpace();
if (totalSpace > 0) {
@@ -251,6 +254,25 @@ public class UtilAll {
return -1;
}
public static long getDiskPartitionTotalSpace(final String path) {
if (null == path || path.isEmpty()) {
return -1;
}
try {
File file = new File(path);
if (!file.exists()) {
return -1;
}
return file.getTotalSpace() - file.getFreeSpace() + file.getUsableSpace();
} catch (Exception e) {
return -1;
}
}
public static int crc32(byte[] array) {
if (array != null) {
return crc32(array, 0, array.length);
@@ -619,4 +641,88 @@ public class UtilAll {
String[] addrArray = str.split(splitter);
return Arrays.asList(addrArray);
}
public static void deleteEmptyDirectory(File file) {
if (file == null || !file.exists()) {
return;
}
if (!file.isDirectory()) {
return;
}
File[] files = file.listFiles();
if (files == null || files.length <= 0) {
file.delete();
log.info("delete empty direct, {}", file.getPath());
}
}
public static void cleanBuffer(final ByteBuffer buffer) {
if (buffer == null || !buffer.isDirect() || buffer.capacity() == 0) {
return;
}
invoke(invoke(viewed(buffer), "cleaner"), "clean");
}
public static Object invoke(final Object target, final String methodName, final Class<?>... args) {
return AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
try {
Method method = method(target, methodName, args);
method.setAccessible(true);
return method.invoke(target);
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
});
}
public static Method method(Object target, String methodName, Class<?>[] args) throws NoSuchMethodException {
try {
return target.getClass().getMethod(methodName, args);
} catch (NoSuchMethodException e) {
return target.getClass().getDeclaredMethod(methodName, args);
}
}
private static ByteBuffer viewed(ByteBuffer buffer) {
String methodName = "viewedBuffer";
Method[] methods = buffer.getClass().getMethods();
for (Method method : methods) {
if (method.getName().equals("attachment")) {
methodName = "attachment";
break;
}
}
ByteBuffer viewedBuffer = (ByteBuffer) invoke(buffer, methodName);
if (viewedBuffer == null) {
return buffer;
} else {
return viewed(viewedBuffer);
}
}
public static void ensureDirOK(final String dirName) {
if (dirName != null) {
if (dirName.contains(MixAll.MULTI_PATH_SPLITTER)) {
String[] dirs = dirName.trim().split(MixAll.MULTI_PATH_SPLITTER);
for (String dir : dirs) {
createDirIfNotExist(dir);
}
} else {
createDirIfNotExist(dirName);
}
}
}
private static void createDirIfNotExist(String dirName) {
File f = new File(dirName);
if (!f.exists()) {
boolean result = f.mkdirs();
log.info(dirName + " mkdir " + (result ? "OK" : "Failed"));
}
}
}
@@ -19,7 +19,7 @@ package org.apache.rocketmq.common.constant;
public class LoggerName {
public static final String FILTERSRV_LOGGER_NAME = "RocketmqFiltersrv";
public static final String NAMESRV_LOGGER_NAME = "RocketmqNamesrv";
public static final String NAMESRV_CONSOLE_NAME = "RocketmqNamesrvConsole";
public static final String NAMESRV_WATER_MARK_LOGGER_NAME = "RocketmqNamesrvWaterMark";
public static final String BROKER_LOGGER_NAME = "RocketmqBroker";
public static final String BROKER_CONSOLE_NAME = "RocketmqConsole";
public static final String CLIENT_LOGGER_NAME = "RocketmqClient";
@@ -30,7 +30,11 @@ public class LoggerName {
public static final String TRANSACTION_LOGGER_NAME = "RocketmqTransaction";
public static final String REBALANCE_LOCK_LOGGER_NAME = "RocketmqRebalanceLock";
public static final String ROCKETMQ_STATS_LOGGER_NAME = "RocketmqStats";
public static final String DLQ_STATS_LOGGER_NAME = "RocketmqDLQStats";
public static final String DLQ_LOGGER_NAME = "RocketmqDLQ";
public static final String CONSUMER_STATS_LOGGER_NAME = "RocketmqConsumerStats";
public static final String COMMERCIAL_LOGGER_NAME = "RocketmqCommercial";
public static final String ACCOUNT_LOGGER_NAME = "RocketmqAccount";
public static final String FLOW_CONTROL_LOGGER_NAME = "RocketmqFlowControl";
public static final String ROCKETMQ_AUTHORIZE_LOGGER_NAME = "RocketmqAuthorize";
public static final String DUPLICATION_LOGGER_NAME = "RocketmqDuplication";
@@ -38,5 +42,6 @@ public class LoggerName {
public static final String WATER_MARK_LOGGER_NAME = "RocketmqWaterMark";
public static final String FILTER_LOGGER_NAME = "RocketmqFilter";
public static final String ROCKETMQ_POP_LOGGER_NAME = "RocketmqPop";
public static final String FAILOVER_LOGGER_NAME = "RocketmqFailover";
public static final String STDOUT_LOGGER_NAME = "STDOUT";
}
@@ -17,10 +17,16 @@
package org.apache.rocketmq.common.constant;
public class PermName {
public static final int PERM_PRIORITY = 0x1 << 3;
public static final int PERM_READ = 0x1 << 2;
public static final int PERM_WRITE = 0x1 << 1;
public static final int PERM_INHERIT = 0x1;
public static final int INDEX_PERM_PRIORITY = 3;
public static final int INDEX_PERM_READ = 2;
public static final int INDEX_PERM_WRITE = 1;
public static final int INDEX_PERM_INHERIT = 0;
public static final int PERM_PRIORITY = 0x1 << INDEX_PERM_PRIORITY;
public static final int PERM_READ = 0x1 << INDEX_PERM_READ;
public static final int PERM_WRITE = 0x1 << INDEX_PERM_WRITE;
public static final int PERM_INHERIT = 0x1 << INDEX_PERM_INHERIT;
public static String perm2String(final int perm) {
final StringBuilder sb = new StringBuilder("---");
@@ -50,4 +56,8 @@ public class PermName {
public static boolean isInherited(final int perm) {
return (perm & PERM_INHERIT) == PERM_INHERIT;
}
public static boolean isPriority(final int perm) {
return (perm & PERM_PRIORITY) == PERM_PRIORITY;
}
}
@@ -0,0 +1,39 @@
/*
* 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.common.future;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class FutureTaskExt<V> extends FutureTask<V> {
private final Runnable runnable;
public FutureTaskExt(final Callable<V> callable) {
super(callable);
this.runnable = null;
}
public FutureTaskExt(final Runnable runnable, final V result) {
super(runnable, result);
this.runnable = runnable;
}
public Runnable getRunnable() {
return runnable;
}
}
@@ -39,13 +39,16 @@ public class MessageConst {
public static final String PROPERTY_MSG_REGION = "MSG_REGION";
public static final String PROPERTY_TRACE_SWITCH = "TRACE_ON";
public static final String PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX = "UNIQ_KEY";
public static final String PROPERTY_EXTEND_UNIQ_INFO = "EXTEND_UNIQ_INFO";
public static final String PROPERTY_MAX_RECONSUME_TIMES = "MAX_RECONSUME_TIMES";
public static final String PROPERTY_CONSUME_START_TIMESTAMP = "CONSUME_START_TIME";
public static final String PROPERTY_INNER_NUM = "INNER_NUM";
public static final String PROPERTY_INNER_BASE = "INNER_BASE";
public static final String PROPERTY_TRANSACTION_PREPARED_QUEUE_OFFSET = "TRAN_PREPARED_QUEUE_OFFSET";
public static final String PROPERTY_TRANSACTION_CHECK_TIMES = "TRANSACTION_CHECK_TIMES";
public static final String DUP_INFO = "DUP_INFO";
public static final String PROPERTY_CHECK_IMMUNITY_TIME_IN_SECONDS = "CHECK_IMMUNITY_TIME_IN_SECONDS";
public static final String PROPERTY_TRANSACTION_PREPARED_QUEUE_OFFSET = "TRAN_PREPARED_QUEUE_OFFSET";
public static final String PROPERTY_TRANSACTION_ID = "__transactionId__";
public static final String PROPERTY_TRANSACTION_CHECK_TIMES = "TRANSACTION_CHECK_TIMES";
public static final String PROPERTY_INSTANCE_ID = "INSTANCE_ID";
public static final String PROPERTY_CORRELATION_ID = "CORRELATION_ID";
public static final String PROPERTY_MESSAGE_REPLY_TO_CLIENT = "REPLY_TO_CLIENT";
@@ -55,12 +58,29 @@ public class MessageConst {
public static final String PROPERTY_CLUSTER = "CLUSTER";
public static final String PROPERTY_MESSAGE_TYPE = "MSG_TYPE";
public static final String PROPERTY_POP_CK = "POP_CK";
public static final String PROPERTY_POP_CK_OFFSET = "POP_CK_OFFSET";
public static final String PROPERTY_FIRST_POP_TIME = "1ST_POP_TIME";
public static final String PROPERTY_SHARDING_KEY = "__SHARDINGKEY";
public static final String PROPERTY_FORWARD_QUEUE_ID = "PROPERTY_FORWARD_QUEUE_ID";
public static final String PROPERTY_REDIRECT = "REDIRECT";
public static final String PROPERTY_INNER_MULTI_DISPATCH = "INNER_MULTI_DISPATCH";
public static final String PROPERTY_INNER_MULTI_QUEUE_OFFSET = "INNER_MULTI_QUEUE_OFFSET";
/**
* property which name starts with "__RMQ.TRANSIENT." is called transient one that will not stored in broker disks.
*/
public static final String PROPERTY_TRANSIENT_PREFIX = "__RMQ.TRANSIENT.";
/**
* the transient property key of topicSysFlag (set by client when pulling messages)
*/
public static final String PROPERTY_TRANSIENT_TOPIC_CONFIG = PROPERTY_TRANSIENT_PREFIX + "TOPIC_SYS_FLAG";
/**
* the transient property key of groupSysFlag (set by client when pulling messages)
*/
public static final String PROPERTY_TRANSIENT_GROUP_CONFIG = PROPERTY_TRANSIENT_PREFIX + "GROUP_SYS_FLAG";
public static final String KEY_SEPARATOR = " ";
public static final HashSet<String> STRING_HASH_SET = new HashSet<>(64);
@@ -89,7 +109,11 @@ public class MessageConst {
STRING_HASH_SET.add(PROPERTY_MAX_RECONSUME_TIMES);
STRING_HASH_SET.add(PROPERTY_CONSUME_START_TIMESTAMP);
STRING_HASH_SET.add(PROPERTY_POP_CK);
STRING_HASH_SET.add(PROPERTY_POP_CK_OFFSET);
STRING_HASH_SET.add(PROPERTY_FIRST_POP_TIME);
STRING_HASH_SET.add(PROPERTY_TRANSACTION_PREPARED_QUEUE_OFFSET);
STRING_HASH_SET.add(DUP_INFO);
STRING_HASH_SET.add(PROPERTY_EXTEND_UNIQ_INFO);
STRING_HASH_SET.add(PROPERTY_INSTANCE_ID);
STRING_HASH_SET.add(PROPERTY_CORRELATION_ID);
STRING_HASH_SET.add(PROPERTY_MESSAGE_REPLY_TO_CLIENT);
@@ -16,6 +16,7 @@
*/
package org.apache.rocketmq.common.message;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@@ -263,13 +264,132 @@ public class MessageDecoder {
return byteBuffer.array();
}
/**
* Encode without store timestamp and store host, skip blank msg.
*
* @param messageExt msg
* @param needCompress need compress or not
* @return byte array
* @throws IOException when compress failed
*/
public static byte[] encodeUniquely(MessageExt messageExt, boolean needCompress) throws IOException {
byte[] body = messageExt.getBody();
byte[] topics = messageExt.getTopic().getBytes(CHARSET_UTF8);
byte topicLen = (byte) topics.length;
String properties = messageProperties2String(messageExt.getProperties());
byte[] propertiesBytes = properties.getBytes(CHARSET_UTF8);
short propertiesLength = (short) propertiesBytes.length;
int sysFlag = messageExt.getSysFlag();
int bornhostLength = (sysFlag & MessageSysFlag.BORNHOST_V6_FLAG) == 0 ? 8 : 20;
byte[] newBody = messageExt.getBody();
if (needCompress && (sysFlag & MessageSysFlag.COMPRESSED_FLAG) == MessageSysFlag.COMPRESSED_FLAG) {
newBody = UtilAll.compress(body, 5);
}
int bodyLength = newBody.length;
int storeSize = messageExt.getStoreSize();
ByteBuffer byteBuffer;
if (storeSize > 0) {
byteBuffer = ByteBuffer.allocate(storeSize - 8); // except size for store timestamp
} else {
storeSize = 4 + // 1 TOTALSIZE
4 + // 2 MAGICCODE
4 + // 3 BODYCRC
4 + // 4 QUEUEID
4 + // 5 FLAG
8 + // 6 QUEUEOFFSET
8 + // 7 PHYSICALOFFSET
4 + // 8 SYSFLAG
8 + // 9 BORNTIMESTAMP
bornhostLength + // 10 BORNHOST
4 + // 11 RECONSUMETIMES
8 + // 12 Prepared Transaction Offset
4 + bodyLength + // 13 BODY
+1 + topicLen + // 14 TOPIC
2 + propertiesLength // 15 propertiesLength
;
byteBuffer = ByteBuffer.allocate(storeSize);
}
// 1 TOTALSIZE
byteBuffer.putInt(storeSize);
// 2 MAGICCODE
byteBuffer.putInt(MESSAGE_MAGIC_CODE);
// 3 BODYCRC
int bodyCRC = messageExt.getBodyCRC();
byteBuffer.putInt(bodyCRC);
// 4 QUEUEID
int queueId = messageExt.getQueueId();
byteBuffer.putInt(queueId);
// 5 FLAG
int flag = messageExt.getFlag();
byteBuffer.putInt(flag);
// 6 QUEUEOFFSET
long queueOffset = messageExt.getQueueOffset();
byteBuffer.putLong(queueOffset);
// 7 PHYSICALOFFSET
long physicOffset = messageExt.getCommitLogOffset();
byteBuffer.putLong(physicOffset);
// 8 SYSFLAG
byteBuffer.putInt(sysFlag);
// 9 BORNTIMESTAMP
long bornTimeStamp = messageExt.getBornTimestamp();
byteBuffer.putLong(bornTimeStamp);
// 10 BORNHOST
InetSocketAddress bornHost = (InetSocketAddress) messageExt.getBornHost();
byteBuffer.put(bornHost.getAddress().getAddress());
byteBuffer.putInt(bornHost.getPort());
// 11 RECONSUMETIMES
int reconsumeTimes = messageExt.getReconsumeTimes();
byteBuffer.putInt(reconsumeTimes);
// 12 Prepared Transaction Offset
long preparedTransactionOffset = messageExt.getPreparedTransactionOffset();
byteBuffer.putLong(preparedTransactionOffset);
// 13 BODY
byteBuffer.putInt(bodyLength);
byteBuffer.put(newBody);
// 14 TOPIC
byteBuffer.put(topicLen);
byteBuffer.put(topics);
// 15 properties
byteBuffer.putShort(propertiesLength);
byteBuffer.put(propertiesBytes);
return byteBuffer.array();
}
public static MessageExt decode(
ByteBuffer byteBuffer, final boolean readBody, final boolean deCompressBody) {
return decode(byteBuffer, readBody, deCompressBody, false);
}
public static MessageExt decode(
ByteBuffer byteBuffer, final boolean readBody, final boolean deCompressBody, final boolean isClient) {
java.nio.ByteBuffer byteBuffer, final boolean readBody, final boolean deCompressBody, final boolean isClient) {
return decode(byteBuffer, readBody, deCompressBody, isClient, false, false);
}
public static MessageExt decode(
java.nio.ByteBuffer byteBuffer, final boolean readBody, final boolean deCompressBody, final boolean isClient,
final boolean isSetPropertiesString) {
return decode(byteBuffer, readBody, deCompressBody, isClient, isSetPropertiesString, false);
}
public static MessageExt decode(
java.nio.ByteBuffer byteBuffer, final boolean readBody, final boolean deCompressBody, final boolean isClient,
final boolean isSetPropertiesString, final boolean checkCRC) {
try {
MessageExt msgExt;
@@ -284,7 +404,10 @@ public class MessageDecoder {
msgExt.setStoreSize(storeSize);
// 2 MAGICCODE
byteBuffer.getInt();
int magicCode = byteBuffer.getInt();
if (magicCode != MESSAGE_MAGIC_CODE) {
throw new RuntimeException("Unknown magicCode: " + magicCode);
}
// 3 BODYCRC
int bodyCRC = byteBuffer.getInt();
@@ -347,6 +470,14 @@ public class MessageDecoder {
byte[] body = new byte[bodyLen];
byteBuffer.get(body);
if (checkCRC) {
//crc body
int crc = UtilAll.crc32(body, 0, bodyLen);
if (crc != bodyCRC) {
throw new Exception("Msg crc is error!");
}
}
// uncompress body
if (deCompressBody && (sysFlag & MessageSysFlag.COMPRESSED_FLAG) == MessageSysFlag.COMPRESSED_FLAG) {
body = UtilAll.uncompress(body);
@@ -370,8 +501,14 @@ public class MessageDecoder {
byte[] properties = new byte[propertiesLength];
byteBuffer.get(properties);
String propertiesString = new String(properties, CHARSET_UTF8);
Map<String, String> map = string2messageProperties(propertiesString);
msgExt.setProperties(map);
if (!isSetPropertiesString) {
Map<String, String> map = string2messageProperties(propertiesString);
msgExt.setProperties(map);
} else {
Map<String, String> map = string2messageProperties(propertiesString);
map.put("propertiesString", propertiesString);
msgExt.setProperties(map);
}
}
int msgIDLength = storehostIPLength + 4 + 8;
@@ -396,9 +533,9 @@ public class MessageDecoder {
}
public static List<MessageExt> decodesBatch(ByteBuffer byteBuffer,
final boolean readBody,
final boolean decompressBody,
final boolean isClient) {
final boolean readBody,
final boolean decompressBody,
final boolean isClient) {
List<MessageExt> msgExts = new ArrayList<MessageExt>();
while (byteBuffer.hasRemaining()) {
MessageExt msgExt = decode(byteBuffer, readBody, decompressBody, isClient);
@@ -494,10 +631,7 @@ public class MessageDecoder {
String properties = messageProperties2String(message.getProperties());
byte[] propertiesBytes = properties.getBytes(CHARSET_UTF8);
//note properties length must not more than Short.MAX
int propsLen = propertiesBytes.length;
if (propsLen > Short.MAX_VALUE)
throw new RuntimeException(String.format("Properties size of message exceeded, properties size: {}, maxSize: {}.", propsLen, Short.MAX_VALUE));
short propertiesLength = (short) propsLen;
short propertiesLength = (short) propertiesBytes.length;
int sysFlag = message.getFlag();
int storeSize = 4 // 1 TOTALSIZE
+ 4 // 2 MAGICCOD
@@ -249,6 +249,61 @@ public class MessageExt extends Message {
this.preparedTransactionOffset = preparedTransactionOffset;
}
/**
*
* achieves topicSysFlag value from transient properties
*
* @return
*/
public Integer getTopicSysFlag() {
String topicSysFlagString = getProperty(MessageConst.PROPERTY_TRANSIENT_TOPIC_CONFIG);
if (topicSysFlagString != null && topicSysFlagString.length() > 0) {
return Integer.valueOf(topicSysFlagString);
}
return null;
}
/**
* set topicSysFlag to transient properties, or clear it
*
* @param topicSysFlag
*/
public void setTopicSysFlag(Integer topicSysFlag) {
if (topicSysFlag == null) {
clearProperty(MessageConst.PROPERTY_TRANSIENT_TOPIC_CONFIG);
} else {
putProperty(MessageConst.PROPERTY_TRANSIENT_TOPIC_CONFIG, String.valueOf(topicSysFlag));
}
}
/**
*
* achieves groupSysFlag value from transient properties
*
* @return
*/
public Integer getGroupSysFlag() {
String groupSysFlagString = getProperty(MessageConst.PROPERTY_TRANSIENT_GROUP_CONFIG);
if (groupSysFlagString != null && groupSysFlagString.length() > 0) {
return Integer.valueOf(groupSysFlagString);
}
return null;
}
/**
*
* set groupSysFlag to transient properties, or clear it
*
* @param groupSysFlag
*/
public void setGroupSysFlag(Integer groupSysFlag) {
if (groupSysFlag == null) {
clearProperty(MessageConst.PROPERTY_TRANSIENT_GROUP_CONFIG);
} else {
putProperty(MessageConst.PROPERTY_TRANSIENT_GROUP_CONFIG, String.valueOf(groupSysFlag));
}
}
@Override
public String toString() {
return "MessageExt [brokerName=" + brokerName + ", queueId=" + queueId + ", storeSize=" + storeSize + ", queueOffset=" + queueOffset
@@ -0,0 +1,51 @@
/**
* 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.common.message;
import java.nio.ByteBuffer;
public class MessageExtBatch extends MessageExtBrokerInner {
private static final long serialVersionUID = -2353110995348498537L;
/**
* Inner batch means the batch dose not need to be unwrapped
*/
private boolean isInnerBatch = false;
public ByteBuffer wrap() {
assert getBody() != null;
return ByteBuffer.wrap(getBody(), 0, getBody().length);
}
public boolean isInnerBatch() {
return isInnerBatch;
}
public void setInnerBatch(boolean innerBatch) {
isInnerBatch = innerBatch;
}
private ByteBuffer encodedBuff;
public ByteBuffer getEncodedBuff() {
return encodedBuff;
}
public void setEncodedBuff(ByteBuffer encodedBuff) {
this.encodedBuff = encodedBuff;
}
}
@@ -0,0 +1,63 @@
/*
* 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.common.message;
import java.nio.ByteBuffer;
import org.apache.rocketmq.common.TopicFilterType;
public class MessageExtBrokerInner extends MessageExt {
private static final long serialVersionUID = 7256001576878700634L;
private String propertiesString;
private long tagsCode;
private ByteBuffer encodedBuff;
public ByteBuffer getEncodedBuff() {
return encodedBuff;
}
public void setEncodedBuff(ByteBuffer encodedBuff) {
this.encodedBuff = encodedBuff;
}
public static long tagsString2tagsCode(final TopicFilterType filter, final String tags) {
if (null == tags || tags.length() == 0) { return 0; }
return tags.hashCode();
}
public static long tagsString2tagsCode(final String tags) {
return tagsString2tagsCode(null, tags);
}
public String getPropertiesString() {
return propertiesString;
}
public void setPropertiesString(String propertiesString) {
this.propertiesString = propertiesString;
}
public long getTagsCode() {
return tagsCode;
}
public void setTagsCode(long tagsCode) {
this.tagsCode = tagsCode;
}
}
@@ -18,8 +18,28 @@
package org.apache.rocketmq.common.message;
public enum MessageType {
Normal_Msg,
Trans_Msg_Half,
Trans_msg_Commit,
Delay_Msg,
Normal_Msg("Normal"),
Order_Msg("Order"),
Trans_Msg_Half("Trans"),
Trans_msg_Commit("TransCommit"),
Delay_Msg("Delay");
private final String shortName;
MessageType(String shortName) {
this.shortName = shortName;
}
public String getShortName() {
return shortName;
}
public static MessageType getByShortName(String shortName) {
for (MessageType msgType : MessageType.values()) {
if (msgType.getShortName().equals(shortName)) {
return msgType;
}
}
return Normal_Msg;
}
}
@@ -0,0 +1,70 @@
/*
* 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.common.message;
import java.nio.ByteBuffer;
public enum MessageVersion {
MESSAGE_VERSION_V1(MessageDecoder.MESSAGE_MAGIC_CODE) {
@Override
public int getTopicLengthSize() {
return 1;
}
@Override
public int getTopicLength(ByteBuffer buffer) {
return buffer.get();
}
@Override
public int getTopicLength(ByteBuffer buffer, int index) {
return buffer.get(index);
}
@Override
public void putTopicLength(ByteBuffer buffer, int topicLength) {
buffer.put((byte) topicLength);
}
};
private final int magicCode;
MessageVersion(int magicCode) {
this.magicCode = magicCode;
}
public static MessageVersion valueOfMagicCode(int magicCode) {
for (MessageVersion version : MessageVersion.values()) {
if (version.getMagicCode() == magicCode) {
return version;
}
}
throw new IllegalArgumentException("Invalid magicCode " + magicCode);
}
public int getMagicCode() {
return magicCode;
}
public abstract int getTopicLengthSize();
public abstract int getTopicLength(java.nio.ByteBuffer buffer);
public abstract int getTopicLength(java.nio.ByteBuffer buffer, int index);
public abstract void putTopicLength(java.nio.ByteBuffer buffer, int topicLength);
}
@@ -0,0 +1,165 @@
/*
* 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.common.namesrv;
import com.google.common.base.Strings;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
import java.util.Map;
import org.apache.rocketmq.common.MixAll;
import org.apache.rocketmq.common.UtilAll;
import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.common.help.FAQUrl;
import org.apache.rocketmq.common.utils.HttpTinyClient;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
public class DefaultTopAddressing implements TopAddressing {
private static final InternalLogger LOGGER = InternalLoggerFactory.getLogger(LoggerName.COMMON_LOGGER_NAME);
private String nsAddr;
private String wsAddr;
private String unitName;
private Map<String, String> para;
private List<TopAddressing> topAddressingList;
public DefaultTopAddressing(final String wsAddr) {
this(wsAddr, null);
}
public DefaultTopAddressing(final String wsAddr, final String unitName) {
this.wsAddr = wsAddr;
this.unitName = unitName;
this.topAddressingList = loadCustomTopAddressing();
}
public DefaultTopAddressing(final String unitName, final Map<String, String> para, final String wsAddr) {
this.wsAddr = wsAddr;
this.unitName = unitName;
this.para = para;
this.topAddressingList = loadCustomTopAddressing();
}
private static String clearNewLine(final String str) {
String newString = str.trim();
int index = newString.indexOf("\r");
if (index != -1) {
return newString.substring(0, index);
}
index = newString.indexOf("\n");
if (index != -1) {
return newString.substring(0, index);
}
return newString;
}
private List<TopAddressing> loadCustomTopAddressing() {
ServiceLoader<TopAddressing> serviceLoader = ServiceLoader.load(TopAddressing.class);
Iterator<TopAddressing> iterator = serviceLoader.iterator();
List<TopAddressing> topAddressingList = new ArrayList<TopAddressing>();
if (iterator.hasNext()) {
topAddressingList.add(iterator.next());
}
return topAddressingList;
}
@Override
public final String fetchNSAddr() {
if (!topAddressingList.isEmpty()) {
for (TopAddressing topAddressing : topAddressingList) {
String nsAddress = topAddressing.fetchNSAddr();
if (!Strings.isNullOrEmpty(nsAddress)) {
return nsAddress;
}
}
}
// Return result of default implementation
return fetchNSAddr(true, 3000);
}
@Override
public void registerChangeCallBack(NameServerUpdateCallback changeCallBack) {
if (!topAddressingList.isEmpty()) {
for (TopAddressing topAddressing : topAddressingList) {
topAddressing.registerChangeCallBack(changeCallBack);
}
}
}
public final String fetchNSAddr(boolean verbose, long timeoutMills) {
String url = this.wsAddr;
try {
if (null != para && para.size() > 0) {
if (!UtilAll.isBlank(this.unitName)) {
url = url + "-" + this.unitName + "?nofix=1&";
}
else {
url = url + "?";
}
for (Map.Entry<String, String> entry : this.para.entrySet()) {
url += entry.getKey() + "=" + entry.getValue() + "&";
}
url = url.substring(0, url.length() - 1);
}
else {
if (!UtilAll.isBlank(this.unitName)) {
url = url + "-" + this.unitName + "?nofix=1";
}
}
HttpTinyClient.HttpResult result = HttpTinyClient.httpGet(url, null, null, "UTF-8", timeoutMills);
if (200 == result.code) {
String responseStr = result.content;
if (responseStr != null) {
return clearNewLine(responseStr);
} else {
LOGGER.error("fetch nameserver address is null");
}
} else {
LOGGER.error("fetch nameserver address failed. statusCode=" + result.code);
}
} catch (IOException e) {
if (verbose) {
LOGGER.error("fetch name server address exception", e);
}
}
if (verbose) {
String errorMsg =
"connect to " + url + " failed, maybe the domain name " + MixAll.getWSAddr() + " not bind in /etc/hosts";
errorMsg += FAQUrl.suggestTodo(FAQUrl.NAME_SERVER_ADDR_NOT_EXIST_URL);
LOGGER.warn(errorMsg);
}
return null;
}
public String getNsAddr() {
return nsAddr;
}
public void setNsAddr(String nsAddr) {
this.nsAddr = nsAddr;
}
}
@@ -0,0 +1,21 @@
/*
* 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.common.namesrv;
public interface NameServerUpdateCallback {
String onNameServerAddressChange(String namesrvAddress);
}
@@ -35,6 +35,51 @@ public class NamesrvConfig {
private String productEnvName = "center";
private boolean clusterTest = false;
private boolean orderMessageEnable = false;
private boolean returnOrderTopicConfigToBroker = true;
private volatile boolean remoteFaultTolerance = true;
/**
* Indicates the nums of thread to handle client requests, like GET_ROUTEINTO_BY_TOPIC.
*/
private int clientRequestThreadPoolNums = 8;
/**
* Indicates the nums of thread to handle broker or operation requests, like REGISTER_BROKER.
*/
private int defaultThreadPoolNums = 16;
/**
* Indicates the capacity of queue to hold client requests.
*/
private int clientRequestThreadPoolQueueCapacity = 50000;
/**
* Indicates the capacity of queue to hold broker or operation requests.
*/
private int defaultThreadPoolQueueCapacity = 10000;
/**
* Interval of periodic scanning for non-active broker;
*/
private long scanNotActiveBrokerInterval = 5 * 1000;
private int unRegisterBrokerQueueCapacity = 3000;
/**
* Support acting master or not.
*
* The slave can be an acting master when master node is down to support following operations:
* 1. support lock/unlock message queue operation.
* 2. support searchOffset, query maxOffset/minOffset operation.
* 3. support query earliest msg store time.
*/
private boolean supportActingMaster = false;
private volatile boolean enableAllTopicList = false;
public void setRemoteFaultTolerance(boolean remoteFaultTolerance) {
this.remoteFaultTolerance = remoteFaultTolerance;
}
public boolean isRemoteFaultTolerance() {
return remoteFaultTolerance;
}
public boolean isOrderMessageEnable() {
return orderMessageEnable;
@@ -83,4 +128,76 @@ public class NamesrvConfig {
public void setConfigStorePath(final String configStorePath) {
this.configStorePath = configStorePath;
}
public boolean isReturnOrderTopicConfigToBroker() {
return returnOrderTopicConfigToBroker;
}
public void setReturnOrderTopicConfigToBroker(boolean returnOrderTopicConfigToBroker) {
this.returnOrderTopicConfigToBroker = returnOrderTopicConfigToBroker;
}
public int getClientRequestThreadPoolNums() {
return clientRequestThreadPoolNums;
}
public void setClientRequestThreadPoolNums(final int clientRequestThreadPoolNums) {
this.clientRequestThreadPoolNums = clientRequestThreadPoolNums;
}
public int getDefaultThreadPoolNums() {
return defaultThreadPoolNums;
}
public void setDefaultThreadPoolNums(final int defaultThreadPoolNums) {
this.defaultThreadPoolNums = defaultThreadPoolNums;
}
public int getClientRequestThreadPoolQueueCapacity() {
return clientRequestThreadPoolQueueCapacity;
}
public void setClientRequestThreadPoolQueueCapacity(final int clientRequestThreadPoolQueueCapacity) {
this.clientRequestThreadPoolQueueCapacity = clientRequestThreadPoolQueueCapacity;
}
public int getDefaultThreadPoolQueueCapacity() {
return defaultThreadPoolQueueCapacity;
}
public void setDefaultThreadPoolQueueCapacity(final int defaultThreadPoolQueueCapacity) {
this.defaultThreadPoolQueueCapacity = defaultThreadPoolQueueCapacity;
}
public long getScanNotActiveBrokerInterval() {
return scanNotActiveBrokerInterval;
}
public void setScanNotActiveBrokerInterval(long scanNotActiveBrokerInterval) {
this.scanNotActiveBrokerInterval = scanNotActiveBrokerInterval;
}
public int getUnRegisterBrokerQueueCapacity() {
return unRegisterBrokerQueueCapacity;
}
public void setUnRegisterBrokerQueueCapacity(final int unRegisterBrokerQueueCapacity) {
this.unRegisterBrokerQueueCapacity = unRegisterBrokerQueueCapacity;
}
public boolean isSupportActingMaster() {
return supportActingMaster;
}
public void setSupportActingMaster(final boolean supportActingMaster) {
this.supportActingMaster = supportActingMaster;
}
public boolean isEnableAllTopicList() {
return enableAllTopicList;
}
public void setEnableAllTopicList(boolean enableAllTopicList) {
this.enableAllTopicList = enableAllTopicList;
}
}
@@ -14,94 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* $Id: TopAddressing.java 1831 2013-05-16 01:39:51Z vintagewang@apache.org $
*/
package org.apache.rocketmq.common.namesrv;
import java.io.IOException;
import org.apache.rocketmq.common.MixAll;
import org.apache.rocketmq.common.UtilAll;
import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.common.help.FAQUrl;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
import org.apache.rocketmq.common.utils.HttpTinyClient;
public class TopAddressing {
private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.COMMON_LOGGER_NAME);
public interface TopAddressing {
private String nsAddr;
private String wsAddr;
private String unitName;
String fetchNSAddr();
public TopAddressing(final String wsAddr) {
this(wsAddr, null);
}
public TopAddressing(final String wsAddr, final String unitName) {
this.wsAddr = wsAddr;
this.unitName = unitName;
}
private static String clearNewLine(final String str) {
String newString = str.trim();
int index = newString.indexOf("\r");
if (index != -1) {
return newString.substring(0, index);
}
index = newString.indexOf("\n");
if (index != -1) {
return newString.substring(0, index);
}
return newString;
}
public final String fetchNSAddr() {
return fetchNSAddr(true, 3000);
}
public final String fetchNSAddr(boolean verbose, long timeoutMills) {
String url = this.wsAddr;
try {
if (!UtilAll.isBlank(this.unitName)) {
url = url + "-" + this.unitName + "?nofix=1";
}
HttpTinyClient.HttpResult result = HttpTinyClient.httpGet(url, null, null, "UTF-8", timeoutMills);
if (200 == result.code) {
String responseStr = result.content;
if (responseStr != null) {
return clearNewLine(responseStr);
} else {
log.error("fetch nameserver address is null");
}
} else {
log.error("fetch nameserver address failed. statusCode=" + result.code);
}
} catch (IOException e) {
if (verbose) {
log.error("fetch name server address exception", e);
}
}
if (verbose) {
String errorMsg =
"connect to " + url + " failed, maybe the domain name " + MixAll.getWSAddr() + " not bind in /etc/hosts";
errorMsg += FAQUrl.suggestTodo(FAQUrl.NAME_SERVER_ADDR_NOT_EXIST_URL);
log.warn(errorMsg);
}
return null;
}
public String getNsAddr() {
return nsAddr;
}
public void setNsAddr(String nsAddr) {
this.nsAddr = nsAddr;
}
void registerChangeCallBack(NameServerUpdateCallback changeCallBack);
}
@@ -0,0 +1,48 @@
/*
* 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.common.protocol;
/**
*
* gives the reason for a no permission messaging pulling.
*
*/
public interface ForbiddenType {
/**
* 1=forbidden by broker
*/
int BROKER_FORBIDDEN = 1;
/**
* 2=forbidden by groupId
*/
int GROUP_FORBIDDEN = 2;
/**
* 3=forbidden by topic
*/
int TOPIC_FORBIDDEN = 3;
/**
* 4=forbidden by brocasting mode
*/
int BROADCASTING_DISABLE_FORBIDDEN = 4;
/**
* 5=forbidden for a substription(group with a topic)
*/
int SUBSCRIPTION_FORBIDDEN = 5;
}
@@ -70,6 +70,8 @@ public class RequestCode {
public static final int CHECK_CLIENT_CONFIG = 46;
public static final int GET_CLIENT_CONFIG = 47;
public static final int UPDATE_AND_CREATE_ACL_CONFIG = 50;
public static final int DELETE_ACL_CONFIG = 51;
@@ -82,7 +84,10 @@ public class RequestCode {
public static final int POP_MESSAGE = 200050;
public static final int ACK_MESSAGE = 200051;
public static final int PEEK_MESSAGE = 200052;
public static final int CHANGE_MESSAGE_INVISIBLETIME = 200053;
public static final int NOTIFICATION = 200054;
public static final int POLLING_INFO = 200055;
public static final int PUT_KV_CONFIG = 100;
@@ -121,6 +126,7 @@ public class RequestCode {
public static final int DELETE_TOPIC_IN_BROKER = 215;
public static final int DELETE_TOPIC_IN_NAMESRV = 216;
public static final int REGISTER_TOPIC_IN_NAMESRV = 217;
public static final int GET_KVLIST_BY_NAMESPACE = 219;
public static final int RESET_CONSUMER_CLIENT_OFFSET = 220;
@@ -135,6 +141,9 @@ public class RequestCode {
public static final int GET_TOPICS_BY_CLUSTER = 224;
public static final int QUERY_TOPICS_BY_CONSUMER = 343;
public static final int QUERY_SUBSCRIPTION_BY_CONSUMER = 345;
public static final int REGISTER_FILTER_SERVER = 301;
public static final int REGISTER_MESSAGE_FILTER_CLASS = 302;
@@ -195,11 +204,36 @@ public class RequestCode {
public static final int ADD_WRITE_PERM_OF_BROKER = 327;
public static final int GET_TOPIC_CONFIG = 351;
public static final int GET_SUBSCRIPTIONGROUP_CONFIG = 352;
public static final int UPDATE_AND_GET_GROUP_FORBIDDEN = 353;
public static final int LITE_PULL_MESSAGE = 361;
public static final int QUERY_ASSIGNMENT = 400;
public static final int SET_MESSAGE_REQUEST_MODE = 401;
public static final int UPDATE_AND_CREATE_STATIC_TOPIC = 513;
/**
* Below request codes are used by broker container,
* these request codes are started with '9'.
*/
public static final int GET_BROKER_MEMBER_GROUP = 901;
public static final int ADD_BROKER = 902;
public static final int REMOVE_BROKER = 903;
public static final int BROKER_HEARTBEAT = 904;
public static final int NOTIFY_MIN_BROKER_ID_CHANGE = 905;
public static final int EXCHANGE_BROKER_HA_INFO = 906;
public static final int GET_BROKER_HA_STATUS = 907;
public static final int RESET_MASTER_FLUSH_OFFSET = 908;
}
@@ -20,7 +20,6 @@ package org.apache.rocketmq.common.protocol;
import org.apache.rocketmq.remoting.protocol.RemotingSysResponseCode;
public class ResponseCode extends RemotingSysResponseCode {
public static final int ASYNC_AND_RETURN_NULL = -2;
public static final int FLUSH_DISK_TIMEOUT = 10;
@@ -85,6 +84,12 @@ public class ResponseCode extends RemotingSysResponseCode {
public static final int POLLING_TIMEOUT = 210;
public static final int BROKER_NOT_EXIST = 211;
public static final int BROKER_DISPATCH_NOT_COMPLETE = 212;
public static final int FLOW_CONTROL = 215;
public static final int NOT_LEADER_FOR_QUEUE = 501;
public static final int RPC_UNKNOWN = -1000;
@@ -0,0 +1,90 @@
/*
* 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.common.protocol.body;
import com.google.common.base.Objects;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class BrokerMemberGroup {
private String cluster;
private String brokerName;
private Map<Long/* brokerId */, String/* broker address */> brokerAddrs;
// Provide default constructor for serializer
public BrokerMemberGroup() {
this.brokerAddrs = new HashMap<Long, String>();
}
public BrokerMemberGroup(final String cluster, final String brokerName) {
this.cluster = cluster;
this.brokerName = brokerName;
this.brokerAddrs = new HashMap<Long, String>();
}
public long minimumBrokerId() {
if (this.brokerAddrs.isEmpty()) {
return 0;
}
return Collections.min(brokerAddrs.keySet());
}
public String getCluster() {
return cluster;
}
public void setCluster(final String cluster) {
this.cluster = cluster;
}
public String getBrokerName() {
return brokerName;
}
public void setBrokerName(final String brokerName) {
this.brokerName = brokerName;
}
public Map<Long, String> getBrokerAddrs() {
return brokerAddrs;
}
public void setBrokerAddrs(final Map<Long, String> brokerAddrs) {
this.brokerAddrs = brokerAddrs;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
BrokerMemberGroup that = (BrokerMemberGroup) o;
return Objects.equal(cluster, that.cluster) &&
Objects.equal(brokerName, that.brokerName) &&
Objects.equal(brokerAddrs, that.brokerAddrs);
}
@Override
public int hashCode() {
return Objects.hashCode(cluster, brokerName, brokerAddrs);
}
}
@@ -25,6 +25,7 @@ public class CheckClientRequestBody extends RemotingSerializable {
private String clientId;
private String group;
private SubscriptionData subscriptionData;
private String namespace;
public String getClientId() {
return clientId;
@@ -49,4 +50,12 @@ public class CheckClientRequestBody extends RemotingSerializable {
public void setSubscriptionData(SubscriptionData subscriptionData) {
this.subscriptionData = subscriptionData;
}
public String getNamespace() {
return namespace;
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
}
@@ -19,29 +19,29 @@ package org.apache.rocketmq.common.protocol.body;
import com.google.common.base.Objects;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.Set;
import org.apache.rocketmq.common.protocol.route.BrokerData;
import org.apache.rocketmq.remoting.protocol.RemotingSerializable;
public class ClusterInfo extends RemotingSerializable {
private HashMap<String/* brokerName */, BrokerData> brokerAddrTable;
private HashMap<String/* clusterName */, Set<String/* brokerName */>> clusterAddrTable;
private Map<String/* brokerName */, BrokerData> brokerAddrTable;
private Map<String/* clusterName */, Set<String/* brokerName */>> clusterAddrTable;
public HashMap<String, BrokerData> getBrokerAddrTable() {
public Map<String, BrokerData> getBrokerAddrTable() {
return brokerAddrTable;
}
public void setBrokerAddrTable(HashMap<String, BrokerData> brokerAddrTable) {
public void setBrokerAddrTable(Map<String, BrokerData> brokerAddrTable) {
this.brokerAddrTable = brokerAddrTable;
}
public HashMap<String, Set<String>> getClusterAddrTable() {
public Map<String, Set<String>> getClusterAddrTable() {
return clusterAddrTable;
}
public void setClusterAddrTable(HashMap<String, Set<String>> clusterAddrTable) {
public void setClusterAddrTable(Map<String, Set<String>> clusterAddrTable) {
this.clusterAddrTable = clusterAddrTable;
}
@@ -19,11 +19,13 @@ package org.apache.rocketmq.common.protocol.body;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.rocketmq.common.DataVersion;
import org.apache.rocketmq.remoting.protocol.RemotingSerializable;
public class ConsumerOffsetSerializeWrapper extends RemotingSerializable {
private ConcurrentMap<String/* topic@group */, ConcurrentMap<Integer, Long>> offsetTable =
new ConcurrentHashMap<String, ConcurrentMap<Integer, Long>>(512);
private DataVersion dataVersion;
public ConcurrentMap<String, ConcurrentMap<Integer, Long>> getOffsetTable() {
return offsetTable;
@@ -32,4 +34,12 @@ public class ConsumerOffsetSerializeWrapper extends RemotingSerializable {
public void setOffsetTable(ConcurrentMap<String, ConcurrentMap<Integer, Long>> offsetTable) {
this.offsetTable = offsetTable;
}
public DataVersion getDataVersion() {
return dataVersion;
}
public void setDataVersion(DataVersion dataVersion) {
this.dataVersion = dataVersion;
}
}
@@ -45,6 +45,8 @@ public class ConsumerRunningInfo extends RemotingSerializable {
private TreeMap<String/* Topic */, ConsumeStatus> statusTable = new TreeMap<String, ConsumeStatus>();
private TreeMap<String, String> userConsumerInfo = new TreeMap<String, String>();
private String jstack;
public static boolean analyzeSubscription(final TreeMap<String/* clientId */, ConsumerRunningInfo> criTable) {
@@ -87,13 +89,14 @@ public class ConsumerRunningInfo extends RemotingSerializable {
prev = next.getValue();
}
if (prev != null) {
if (prev.getSubscriptionSet().isEmpty()) {
// Subscription empty!
return false;
}
}
// after consumer.unsubscribe , SubscriptionSet is Empty
//if (prev != null) {
//
// if (prev.getSubscriptionSet().isEmpty()) {
// // Subscription empty!
// return false;
// }
//}
}
}
@@ -193,6 +196,10 @@ public class ConsumerRunningInfo extends RemotingSerializable {
this.statusTable = statusTable;
}
public TreeMap<String, String> getUserConsumerInfo() {
return userConsumerInfo;
}
public String formatString() {
StringBuilder sb = new StringBuilder();
@@ -318,6 +325,16 @@ public class ConsumerRunningInfo extends RemotingSerializable {
}
}
if (this.userConsumerInfo != null) {
sb.append("\n\n#User Consume Info#\n");
Iterator<Entry<String, String>> it = this.userConsumerInfo.entrySet().iterator();
while (it.hasNext()) {
Entry<String, String> next = it.next();
String item = String.format("%-40s: %s%n", next.getKey(), next.getValue());
sb.append(item);
}
}
if (this.jstack != null) {
sb.append("\n\n#Consumer jstack#\n");
sb.append(this.jstack);
@@ -0,0 +1,33 @@
/*
* 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.common.protocol.body;
import org.apache.rocketmq.remoting.protocol.RemotingSerializable;
public class GetBrokerMemberGroupResponseBody extends RemotingSerializable {
// Contains the broker member info of the same broker group
private BrokerMemberGroup brokerMemberGroup;
public BrokerMemberGroup getBrokerMemberGroup() {
return brokerMemberGroup;
}
public void setBrokerMemberGroup(final BrokerMemberGroup brokerMemberGroup) {
this.brokerMemberGroup = brokerMemberGroup;
}
}
@@ -0,0 +1,34 @@
/*
* 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.common.protocol.body;
import org.apache.rocketmq.remoting.protocol.RemotingSerializable;
import java.util.ArrayList;
import java.util.List;
public class GetRemoteClientConfigBody extends RemotingSerializable {
private List<String> keys = new ArrayList<String>();
public List<String> getKeys() {
return keys;
}
public void setKeys(List<String> keys) {
this.keys = keys;
}
}
@@ -0,0 +1,188 @@
/*
* 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.common.protocol.body;
import java.util.ArrayList;
import java.util.List;
import org.apache.rocketmq.remoting.protocol.RemotingSerializable;
public class HARuntimeInfo extends RemotingSerializable {
private boolean master;
private long masterCommitLogMaxOffset;
private int inSyncSlaveNums;
private List<HAConnectionRuntimeInfo> haConnectionInfo = new ArrayList<HARuntimeInfo.HAConnectionRuntimeInfo>();
private HAClientRuntimeInfo haClientRuntimeInfo = new HAClientRuntimeInfo();
public boolean isMaster() {
return this.master;
}
public void setMaster(boolean master) {
this.master = master;
}
public long getMasterCommitLogMaxOffset() {
return this.masterCommitLogMaxOffset;
}
public void setMasterCommitLogMaxOffset(long masterCommitLogMaxOffset) {
this.masterCommitLogMaxOffset = masterCommitLogMaxOffset;
}
public int getInSyncSlaveNums() {
return this.inSyncSlaveNums;
}
public void setInSyncSlaveNums(int inSyncSlaveNums) {
this.inSyncSlaveNums = inSyncSlaveNums;
}
public List<HAConnectionRuntimeInfo> getHaConnectionInfo() {
return this.haConnectionInfo;
}
public void setHaConnectionInfo(List<HAConnectionRuntimeInfo> haConnectionInfo) {
this.haConnectionInfo = haConnectionInfo;
}
public HAClientRuntimeInfo getHaClientRuntimeInfo() {
return this.haClientRuntimeInfo;
}
public void setHaClientRuntimeInfo(HAClientRuntimeInfo haClientRuntimeInfo) {
this.haClientRuntimeInfo = haClientRuntimeInfo;
}
public static class HAConnectionRuntimeInfo extends RemotingSerializable {
private String addr;
private long slaveAckOffset;
private long diff;
private boolean inSync;
private long transferredByteInSecond;
private long transferFromWhere;
public String getAddr() {
return this.addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
public long getSlaveAckOffset() {
return this.slaveAckOffset;
}
public void setSlaveAckOffset(long slaveAckOffset) {
this.slaveAckOffset = slaveAckOffset;
}
public long getDiff() {
return this.diff;
}
public void setDiff(long diff) {
this.diff = diff;
}
public boolean isInSync() {
return this.inSync;
}
public void setInSync(boolean inSync) {
this.inSync = inSync;
}
public long getTransferredByteInSecond() {
return this.transferredByteInSecond;
}
public void setTransferredByteInSecond(long transferredByteInSecond) {
this.transferredByteInSecond = transferredByteInSecond;
}
public long getTransferFromWhere() {
return transferFromWhere;
}
public void setTransferFromWhere(long transferFromWhere) {
this.transferFromWhere = transferFromWhere;
}
}
public static class HAClientRuntimeInfo extends RemotingSerializable {
private String masterAddr;
private long transferredByteInSecond;
private long maxOffset;
private long lastReadTimestamp;
private long lastWriteTimestamp;
private long masterFlushOffset;
private boolean isActivated = false;
public String getMasterAddr() {
return this.masterAddr;
}
public void setMasterAddr(String masterAddr) {
this.masterAddr = masterAddr;
}
public long getTransferredByteInSecond() {
return this.transferredByteInSecond;
}
public void setTransferredByteInSecond(long transferredByteInSecond) {
this.transferredByteInSecond = transferredByteInSecond;
}
public long getMaxOffset() {
return this.maxOffset;
}
public void setMaxOffset(long maxOffset) {
this.maxOffset = maxOffset;
}
public long getLastReadTimestamp() {
return this.lastReadTimestamp;
}
public void setLastReadTimestamp(long lastReadTimestamp) {
this.lastReadTimestamp = lastReadTimestamp;
}
public long getLastWriteTimestamp() {
return this.lastWriteTimestamp;
}
public void setLastWriteTimestamp(long lastWriteTimestamp) {
this.lastWriteTimestamp = lastWriteTimestamp;
}
public long getMasterFlushOffset() {
return masterFlushOffset;
}
public void setMasterFlushOffset(long masterFlushOffset) {
this.masterFlushOffset = masterFlushOffset;
}
}
}
@@ -25,6 +25,7 @@ import org.apache.rocketmq.remoting.protocol.RemotingSerializable;
public class LockBatchRequestBody extends RemotingSerializable {
private String consumerGroup;
private String clientId;
private boolean onlyThisBroker = false;
private Set<MessageQueue> mqSet = new HashSet<MessageQueue>();
public String getConsumerGroup() {
@@ -43,6 +44,14 @@ public class LockBatchRequestBody extends RemotingSerializable {
this.clientId = clientId;
}
public boolean isOnlyThisBroker() {
return onlyThisBroker;
}
public void setOnlyThisBroker(boolean onlyThisBroker) {
this.onlyThisBroker = onlyThisBroker;
}
public Set<MessageQueue> getMqSet() {
return mqSet;
}
@@ -0,0 +1,52 @@
/*
* 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.common.protocol.body;
import org.apache.rocketmq.common.protocol.heartbeat.SubscriptionData;
import org.apache.rocketmq.remoting.protocol.RemotingSerializable;
public class QuerySubscriptionResponseBody extends RemotingSerializable {
private SubscriptionData subscriptionData;
private String group;
private String topic;
public SubscriptionData getSubscriptionData() {
return subscriptionData;
}
public void setSubscriptionData(SubscriptionData subscriptionData) {
this.subscriptionData = subscriptionData;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
}
@@ -25,6 +25,7 @@ import org.apache.rocketmq.remoting.protocol.RemotingSerializable;
public class UnlockBatchRequestBody extends RemotingSerializable {
private String consumerGroup;
private String clientId;
private boolean onlyThisBroker = false;
private Set<MessageQueue> mqSet = new HashSet<MessageQueue>();
public String getConsumerGroup() {
@@ -43,6 +44,14 @@ public class UnlockBatchRequestBody extends RemotingSerializable {
this.clientId = clientId;
}
public boolean isOnlyThisBroker() {
return onlyThisBroker;
}
public void setOnlyThisBroker(boolean onlyThisBroker) {
this.onlyThisBroker = onlyThisBroker;
}
public Set<MessageQueue> getMqSet() {
return mqSet;
}
@@ -0,0 +1,40 @@
/*
* 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.common.protocol.header;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNullable;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class AddBrokerRequestHeader implements CommandCustomHeader {
@CFNullable
private String configPath;
@Override public void checkFields() throws RemotingCommandException {
}
public String getConfigPath() {
return configPath;
}
public void setConfigPath(String configPath) {
this.configPath = configPath;
}
}
@@ -31,6 +31,12 @@ public class ConsumeMessageDirectlyResultRequestHeader implements CommandCustomH
private String msgId;
@CFNullable
private String brokerName;
@CFNullable
private String topic;
@CFNullable
private Integer topicSysFlag;
@CFNullable
private Integer groupSysFlag;
@Override
public void checkFields() throws RemotingCommandException {
@@ -67,4 +73,28 @@ public class ConsumeMessageDirectlyResultRequestHeader implements CommandCustomH
public void setMsgId(String msgId) {
this.msgId = msgId;
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
public Integer getTopicSysFlag() {
return topicSysFlag;
}
public void setTopicSysFlag(Integer topicSysFlag) {
this.topicSysFlag = topicSysFlag;
}
public Integer getGroupSysFlag() {
return groupSysFlag;
}
public void setGroupSysFlag(Integer groupSysFlag) {
this.groupSysFlag = groupSysFlag;
}
}
@@ -25,7 +25,7 @@ public class DeleteSubscriptionGroupRequestHeader implements CommandCustomHeader
@CFNotNull
private String groupName;
private boolean removeOffset;
private boolean cleanOffset = false;
@Override
public void checkFields() throws RemotingCommandException {
@@ -39,11 +39,11 @@ public class DeleteSubscriptionGroupRequestHeader implements CommandCustomHeader
this.groupName = groupName;
}
public boolean isRemoveOffset() {
return removeOffset;
public boolean isCleanOffset() {
return cleanOffset;
}
public void setRemoveOffset(boolean removeOffset) {
this.removeOffset = removeOffset;
public void setCleanOffset(boolean cleanOffset) {
this.cleanOffset = cleanOffset;
}
}
@@ -0,0 +1,62 @@
/*
* 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.common.protocol.header;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNullable;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class ExchangeHAInfoRequestHeader implements CommandCustomHeader {
@CFNullable
public String masterHaAddress;
@CFNullable
public Long masterFlushOffset;
@CFNullable
public String masterAddress;
@Override
public void checkFields() throws RemotingCommandException {
}
public String getMasterHaAddress() {
return masterHaAddress;
}
public void setMasterHaAddress(String masterHaAddress) {
this.masterHaAddress = masterHaAddress;
}
public Long getMasterFlushOffset() {
return masterFlushOffset;
}
public void setMasterFlushOffset(Long masterFlushOffset) {
this.masterFlushOffset = masterFlushOffset;
}
public String getMasterAddress() {
return masterAddress;
}
public void setMasterAddress(String masterAddress) {
this.masterAddress = masterAddress;
}
}
@@ -0,0 +1,62 @@
/*
* 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.common.protocol.header;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNullable;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class ExchangeHAInfoResponseHeader implements CommandCustomHeader {
@CFNullable
public String masterHaAddress;
@CFNullable
public Long masterFlushOffset;
@CFNullable
public String masterAddress;
@Override
public void checkFields() throws RemotingCommandException {
}
public String getMasterHaAddress() {
return masterHaAddress;
}
public void setMasterHaAddress(String masterHaAddress) {
this.masterHaAddress = masterHaAddress;
}
public Long getMasterFlushOffset() {
return masterFlushOffset;
}
public void setMasterFlushOffset(Long masterFlushOffset) {
this.masterFlushOffset = masterFlushOffset;
}
public String getMasterAddress() {
return masterAddress;
}
public void setMasterAddress(String masterAddress) {
this.masterAddress = masterAddress;
}
}
@@ -0,0 +1,51 @@
/*
* 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.common.protocol.header;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNotNull;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class GetBrokerMemberGroupRequestHeader implements CommandCustomHeader {
@CFNotNull
private String clusterName;
@CFNotNull
private String brokerName;
public String getClusterName() {
return clusterName;
}
public void setClusterName(final String clusterName) {
this.clusterName = clusterName;
}
public String getBrokerName() {
return brokerName;
}
public void setBrokerName(final String brokerName) {
this.brokerName = brokerName;
}
@Override
public void checkFields() throws RemotingCommandException {
}
}
@@ -22,6 +22,7 @@ package org.apache.rocketmq.common.protocol.header;
import org.apache.rocketmq.common.rpc.TopicQueueRequestHeader;
import org.apache.rocketmq.remoting.annotation.CFNotNull;
import org.apache.rocketmq.remoting.annotation.CFNullable;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class GetMaxOffsetRequestHeader extends TopicQueueRequestHeader {
@@ -30,6 +31,15 @@ public class GetMaxOffsetRequestHeader extends TopicQueueRequestHeader {
@CFNotNull
private Integer queueId;
/**
* A message at committed offset has been dispatched from Topic to MessageQueue, so it can be consumed immediately,
* while a message at inflight offset is not visible for a consumer temporarily.
* Set this flag true if the max committed offset is needed, or false if the max inflight offset is preferred.
* The default value is true.
*/
@CFNullable
private boolean committed = true;
@Override
public void checkFields() throws RemotingCommandException {
}
@@ -54,4 +64,11 @@ public class GetMaxOffsetRequestHeader extends TopicQueueRequestHeader {
this.queueId = queueId;
}
public boolean isCommitted() {
return committed;
}
public void setCommitted(final boolean committed) {
this.committed = committed;
}
}
@@ -0,0 +1,49 @@
/*
* 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.
*/
/**
* $Id: GetAllTopicConfigResponseHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $
*/
package org.apache.rocketmq.common.protocol.header;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNotNull;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class GetSubscriptionGroupConfigRequestHeader implements CommandCustomHeader {
@Override
public void checkFields() throws RemotingCommandException {
}
@CFNotNull
private String group;
/**
* @return the group
*/
public String getGroup() {
return group;
}
/**
* @param group the group to set
*/
public void setGroup(String group) {
this.group = group;
}
}
@@ -0,0 +1,48 @@
/*
* 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.common.protocol.header;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class InitConsumerOffsetRequestHeader implements CommandCustomHeader {
private String topic;
// @see ConsumeInitMode
private int initMode;
@Override
public void checkFields() throws RemotingCommandException {
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
public int getInitMode() {
return initMode;
}
public void setInitMode(int initMode) {
this.initMode = initMode;
}
}
@@ -0,0 +1,84 @@
/*
* 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.common.protocol.header;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNotNull;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class NotificationRequestHeader implements CommandCustomHeader {
@CFNotNull
private String consumerGroup;
@CFNotNull
private String topic;
@CFNotNull
private int queueId;
@CFNotNull
private long pollTime;
@CFNotNull
private long bornTime;
@CFNotNull
@Override
public void checkFields() throws RemotingCommandException {
}
public long getPollTime() {
return pollTime;
}
public void setPollTime(long pollTime) {
this.pollTime = pollTime;
}
public String getConsumerGroup() {
return consumerGroup;
}
public void setConsumerGroup(String consumerGroup) {
this.consumerGroup = consumerGroup;
}
public long getBornTime() {
return bornTime;
}
public void setBornTime(long bornTime) {
this.bornTime = bornTime;
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
public int getQueueId() {
if (queueId < 0) {
return -1;
}
return queueId;
}
public void setQueueId(int queueId) {
this.queueId = queueId;
}
}
@@ -0,0 +1,40 @@
/*
* 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.common.protocol.header;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNotNull;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class NotificationResponseHeader implements CommandCustomHeader {
@CFNotNull
private boolean hasMsg = false;
public boolean isHasMsg() {
return hasMsg;
}
public void setHasMsg(boolean hasMsg) {
this.hasMsg = hasMsg;
}
@Override
public void checkFields() throws RemotingCommandException {
}
}
@@ -0,0 +1,84 @@
/*
* 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.common.protocol.header;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNullable;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class NotifyMinBrokerIdChangeRequestHeader implements CommandCustomHeader {
@CFNullable
private Long minBrokerId;
@CFNullable
private String brokerName;
@CFNullable
private String minBrokerAddr;
@CFNullable
private String offlineBrokerAddr;
@CFNullable
private String haBrokerAddr;
@Override
public void checkFields() throws RemotingCommandException {
}
public Long getMinBrokerId() {
return minBrokerId;
}
public void setMinBrokerId(Long minBrokerId) {
this.minBrokerId = minBrokerId;
}
public String getBrokerName() {
return brokerName;
}
public void setBrokerName(String brokerName) {
this.brokerName = brokerName;
}
public String getMinBrokerAddr() {
return minBrokerAddr;
}
public void setMinBrokerAddr(String minBrokerAddr) {
this.minBrokerAddr = minBrokerAddr;
}
public String getOfflineBrokerAddr() {
return offlineBrokerAddr;
}
public void setOfflineBrokerAddr(String offlineBrokerAddr) {
this.offlineBrokerAddr = offlineBrokerAddr;
}
public String getHaBrokerAddr() {
return haBrokerAddr;
}
public void setHaBrokerAddr(String haBrokerAddr) {
this.haBrokerAddr = haBrokerAddr;
}
}
@@ -0,0 +1,70 @@
/*
* 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.common.protocol.header;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNotNull;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class PeekMessageRequestHeader implements CommandCustomHeader {
@CFNotNull
private String topic;
@CFNotNull
private int queueId;
@CFNotNull
private int maxMsgNums;
@CFNotNull
private String consumerGroup;
@Override
public void checkFields() throws RemotingCommandException {
}
public String getConsumerGroup() {
return consumerGroup;
}
public void setConsumerGroup(String consumerGroup) {
this.consumerGroup = consumerGroup;
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
public int getQueueId() {
return queueId;
}
public void setQueueId(int queueId) {
this.queueId = queueId;
}
public int getMaxMsgNums() {
return maxMsgNums;
}
public void setMaxMsgNums(int maxMsgNums) {
this.maxMsgNums = maxMsgNums;
}
}
@@ -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
*
* 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.common.protocol.header;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNotNull;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class PollingInfoRequestHeader implements CommandCustomHeader {
@CFNotNull
private String consumerGroup;
@CFNotNull
private String topic;
@CFNotNull
private int queueId;
@Override
public void checkFields() throws RemotingCommandException {
}
public String getConsumerGroup() {
return consumerGroup;
}
public void setConsumerGroup(String consumerGroup) {
this.consumerGroup = consumerGroup;
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
public int getQueueId() {
if (queueId < 0) {
return -1;
}
return queueId;
}
public void setQueueId(int queueId) {
this.queueId = queueId;
}
}
@@ -0,0 +1,41 @@
/*
* 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.common.protocol.header;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNotNull;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class PollingInfoResponseHeader implements CommandCustomHeader {
@CFNotNull
private int pollingNum;
public int getPollingNum() {
return pollingNum;
}
public void setPollingNum(int pollingNum) {
this.pollingNum = pollingNum;
}
@Override
public void checkFields() throws RemotingCommandException {
}
}
@@ -36,6 +36,12 @@ public class PullMessageResponseHeader implements CommandCustomHeader {
private Long maxOffset;
@CFNullable
private Long offsetDelta;
@CFNullable
private Integer topicSysFlag;
@CFNullable
private Integer groupSysFlag;
@CFNullable
private Integer forbiddenType;
@Override
public void checkFields() throws RemotingCommandException {
@@ -73,6 +79,33 @@ public class PullMessageResponseHeader implements CommandCustomHeader {
this.suggestWhichBrokerId = suggestWhichBrokerId;
}
public Integer getTopicSysFlag() {
return topicSysFlag;
}
public void setTopicSysFlag(Integer topicSysFlag) {
this.topicSysFlag = topicSysFlag;
}
public Integer getGroupSysFlag() {
return groupSysFlag;
}
public void setGroupSysFlag(Integer groupSysFlag) {
this.groupSysFlag = groupSysFlag;
}
/**
* @return the forbiddenType
*/
public Integer getForbiddenType() {
return forbiddenType;
}
/**
*/
public void setForbiddenType(Integer forbiddenType) {
this.forbiddenType = forbiddenType;
}
public Long getOffsetDelta() {
return offsetDelta;
}
@@ -0,0 +1,52 @@
/*
* 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.
*/
/**
* $Id: QueryMessageRequestHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $
*/
package org.apache.rocketmq.common.protocol.header;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNotNull;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class QuerySubscriptionByConsumerRequestHeader implements CommandCustomHeader {
@CFNotNull
private String group;
private String topic;
@Override
public void checkFields() throws RemotingCommandException {
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
}
@@ -0,0 +1,43 @@
/*
* 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.
*/
/**
* $Id: QueryMessageRequestHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $
*/
package org.apache.rocketmq.common.protocol.header;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNotNull;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class QueryTopicsByConsumerRequestHeader implements CommandCustomHeader {
@CFNotNull
private String group;
@Override
public void checkFields() throws RemotingCommandException {
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
}
@@ -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.common.protocol.header;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNotNull;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class RemoveBrokerRequestHeader implements CommandCustomHeader {
@CFNotNull
private String brokerName;
@CFNotNull
private String brokerClusterName;
@CFNotNull
private Long brokerId;
@Override public void checkFields() throws RemotingCommandException {
}
public String getBrokerName() {
return brokerName;
}
public void setBrokerName(String brokerName) {
this.brokerName = brokerName;
}
public String getBrokerClusterName() {
return brokerClusterName;
}
public void setBrokerClusterName(String brokerClusterName) {
this.brokerClusterName = brokerClusterName;
}
public Long getBrokerId() {
return brokerId;
}
public void setBrokerId(Long brokerId) {
this.brokerId = brokerId;
}
}
@@ -0,0 +1,40 @@
/*
* 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.common.protocol.header;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNotNull;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class ResetMasterFlushOffsetHeader implements CommandCustomHeader {
@CFNotNull
private Long masterFlushOffset;
@Override
public void checkFields() throws RemotingCommandException {
}
public Long getMasterFlushOffset() {
return masterFlushOffset;
}
public void setMasterFlushOffset(Long masterFlushOffset) {
this.masterFlushOffset = masterFlushOffset;
}
}
@@ -0,0 +1,81 @@
/*
* 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.common.protocol.header;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNotNull;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class StatisticsMessagesRequestHeader implements CommandCustomHeader {
@CFNotNull
private String consumerGroup;
@CFNotNull
private String topic;
@CFNotNull
private int queueId;
private long fromTime;
private long toTime;
@Override
public void checkFields() throws RemotingCommandException {
}
public String getConsumerGroup() {
return consumerGroup;
}
public void setConsumerGroup(String consumerGroup) {
this.consumerGroup = consumerGroup;
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
public int getQueueId() {
if (queueId < 0) {
return -1;
}
return queueId;
}
public void setQueueId(int queueId) {
this.queueId = queueId;
}
public long getFromTime() {
return fromTime;
}
public void setFromTime(long fromTime) {
this.fromTime = fromTime;
}
public long getToTime() {
return toTime;
}
public void setToTime(long toTime) {
this.toTime = toTime;
}
}
@@ -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
*
* 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.
*/
/**
* $Id: CreateTopicRequestHeader.java 1835 2013-05-16 02:00:50Z vintagewang@apache.org $
*/
package org.apache.rocketmq.common.protocol.header;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNotNull;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class UpdateGroupForbiddenRequestHeader implements CommandCustomHeader {
@CFNotNull
private String group;
@CFNotNull
private String topic;
private Boolean readable;
@Override
public void checkFields() throws RemotingCommandException {
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public Boolean getReadable() {
return readable;
}
public void setReadable(Boolean readable) {
this.readable = readable;
}
}
@@ -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.common.protocol.header.namesrv;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNotNull;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class BrokerHeartbeatRequestHeader implements CommandCustomHeader {
@CFNotNull
private String clusterName;
@CFNotNull
private String brokerAddr;
@CFNotNull
private String brokerName;
@Override public void checkFields() throws RemotingCommandException {
}
public String getBrokerAddr() {
return brokerAddr;
}
public void setBrokerAddr(String brokerAddr) {
this.brokerAddr = brokerAddr;
}
public String getClusterName() {
return clusterName;
}
public void setClusterName(String clusterName) {
this.clusterName = clusterName;
}
public String getBrokerName() {
return brokerName;
}
public void setBrokerName(String brokerName) {
this.brokerName = brokerName;
}
}
@@ -24,6 +24,8 @@ public class DeleteTopicFromNamesrvRequestHeader implements CommandCustomHeader
@CFNotNull
private String topic;
private String clusterName;
@Override
public void checkFields() throws RemotingCommandException {
}
@@ -35,4 +37,12 @@ public class DeleteTopicFromNamesrvRequestHeader implements CommandCustomHeader
public void setTopic(String topic) {
this.topic = topic;
}
public String getClusterName() {
return clusterName;
}
public void setClusterName(String clusterName) {
this.clusterName = clusterName;
}
}
@@ -25,6 +25,8 @@ import org.apache.rocketmq.remoting.annotation.CFNotNull;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class GetRouteInfoRequestHeader implements CommandCustomHeader {
public static char split = 1;
@CFNotNull
private String topic;
@@ -22,6 +22,7 @@ package org.apache.rocketmq.common.protocol.header.namesrv;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNotNull;
import org.apache.rocketmq.remoting.annotation.CFNullable;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class RegisterBrokerRequestHeader implements CommandCustomHeader {
@@ -35,11 +36,16 @@ public class RegisterBrokerRequestHeader implements CommandCustomHeader {
private String haServerAddr;
@CFNotNull
private Long brokerId;
@CFNullable
private Long heartbeatTimeoutMillis;
@CFNullable
private Boolean enableActingMaster;
private boolean compressed;
private Integer bodyCrc32 = 0;
@Override
public void checkFields() throws RemotingCommandException {
}
@@ -83,6 +89,14 @@ public class RegisterBrokerRequestHeader implements CommandCustomHeader {
this.brokerId = brokerId;
}
public Long getHeartbeatTimeoutMillis() {
return heartbeatTimeoutMillis;
}
public void setHeartbeatTimeoutMillis(Long heartbeatTimeoutMillis) {
this.heartbeatTimeoutMillis = heartbeatTimeoutMillis;
}
public boolean isCompressed() {
return compressed;
}
@@ -98,4 +112,12 @@ public class RegisterBrokerRequestHeader implements CommandCustomHeader {
public void setBodyCrc32(Integer bodyCrc32) {
this.bodyCrc32 = bodyCrc32;
}
public Boolean getEnableActingMaster() {
return enableActingMaster;
}
public void setEnableActingMaster(Boolean enableActingMaster) {
this.enableActingMaster = enableActingMaster;
}
}
@@ -0,0 +1,38 @@
/*
* 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.common.protocol.header.namesrv;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNotNull;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
public class RegisterTopicRequestHeader implements CommandCustomHeader {
@CFNotNull
private String topic;
@Override
public void checkFields() throws RemotingCommandException {
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
}
@@ -20,6 +20,7 @@ package org.apache.rocketmq.common.protocol.route;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.apache.rocketmq.common.MixAll;
@@ -30,10 +31,27 @@ public class BrokerData implements Comparable<BrokerData> {
private final Random random = new Random();
/**
* Enable acting master or not, used for old version HA adaption,
*/
private boolean enableActingMaster = false;
public BrokerData() {
}
public BrokerData(BrokerData brokerData) {
this.cluster = brokerData.cluster;
this.brokerName = brokerData.brokerName;
if (brokerData.brokerAddrs != null) {
this.brokerAddrs = new HashMap<Long, String>();
for (final Map.Entry<Long, String> brokerEntry : brokerData.brokerAddrs.entrySet()) {
this.brokerAddrs.put(brokerEntry.getKey(), brokerEntry.getValue());
}
}
this.enableActingMaster = brokerData.enableActingMaster;
}
public BrokerData(String cluster, String brokerName, HashMap<Long, String> brokerAddrs) {
this.cluster = cluster;
this.brokerName = brokerName;
@@ -73,6 +91,14 @@ public class BrokerData implements Comparable<BrokerData> {
this.cluster = cluster;
}
public boolean isEnableActingMaster() {
return enableActingMaster;
}
public void setEnableActingMaster(boolean enableActingMaster) {
this.enableActingMaster = enableActingMaster;
}
@Override
public int hashCode() {
final int prime = 31;
@@ -84,29 +110,33 @@ public class BrokerData implements Comparable<BrokerData> {
@Override
public boolean equals(Object obj) {
if (this == obj)
if (this == obj) {
return true;
if (obj == null)
}
if (obj == null) {
return false;
if (getClass() != obj.getClass())
}
if (getClass() != obj.getClass()) {
return false;
}
BrokerData other = (BrokerData) obj;
if (brokerAddrs == null) {
if (other.brokerAddrs != null)
if (other.brokerAddrs != null) {
return false;
} else if (!brokerAddrs.equals(other.brokerAddrs))
}
} else if (!brokerAddrs.equals(other.brokerAddrs)) {
return false;
}
if (brokerName == null) {
if (other.brokerName != null)
return false;
} else if (!brokerName.equals(other.brokerName))
return false;
return true;
return other.brokerName == null;
} else {
return brokerName.equals(other.brokerName);
}
}
@Override
public String toString() {
return "BrokerData [brokerName=" + brokerName + ", brokerAddrs=" + brokerAddrs + "]";
return "BrokerData [brokerName=" + brokerName + ", brokerAddrs=" + brokerAddrs + ", enableActingMaster=" + enableActingMaster + "]";
}
@Override
@@ -27,6 +27,19 @@ public class QueueData implements Comparable<QueueData> {
private int perm;
private int topicSysFlag;
public QueueData() {
}
// Deep copy QueueData
public QueueData(QueueData queueData) {
this.brokerName = queueData.brokerName;
this.readQueueNums = queueData.readQueueNums;
this.writeQueueNums = queueData.writeQueueNums;
this.perm = queueData.perm;
this.topicSysFlag = queueData.topicSysFlag;
}
public int getReadQueueNums() {
return readQueueNums;
}
@@ -25,6 +25,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.rocketmq.common.statictopic.TopicQueueMappingInfo;
import org.apache.rocketmq.remoting.protocol.RemotingSerializable;
@@ -37,6 +39,9 @@ public class TopicRouteData extends RemotingSerializable {
private Map<String/*brokerName*/, TopicQueueMappingInfo> topicQueueMappingByBroker;
public TopicRouteData() {
queueDatas = new ArrayList<QueueData>();
brokerDatas = new ArrayList<BrokerData>();
filterServerTable = new HashMap<String, List<String>>();
}
public TopicRouteData(TopicRouteData topicRouteData) {
@@ -62,6 +67,54 @@ public class TopicRouteData extends RemotingSerializable {
}
}
public TopicRouteData cloneTopicRouteData() {
TopicRouteData topicRouteData = new TopicRouteData();
topicRouteData.setOrderTopicConf(this.orderTopicConf);
topicRouteData.getQueueDatas().addAll(this.queueDatas);
topicRouteData.getBrokerDatas().addAll(this.brokerDatas);
topicRouteData.getFilterServerTable().putAll(this.filterServerTable);
if (this.topicQueueMappingByBroker != null) {
Map<String, TopicQueueMappingInfo> cloneMap = new HashMap<>(this.topicQueueMappingByBroker);
topicRouteData.setTopicQueueMappingByBroker(cloneMap);
}
return topicRouteData;
}
public TopicRouteData deepCloneTopicRouteData() {
TopicRouteData topicRouteData = new TopicRouteData();
topicRouteData.setOrderTopicConf(this.orderTopicConf);
for (final QueueData queueData : this.queueDatas) {
topicRouteData.getQueueDatas().add(new QueueData(queueData));
}
for (final BrokerData brokerData : this.brokerDatas) {
topicRouteData.getBrokerDatas().add(new BrokerData(brokerData));
}
for (final Map.Entry<String, List<String>> listEntry : this.filterServerTable.entrySet()) {
topicRouteData.getFilterServerTable().put(listEntry.getKey(),
new ArrayList<String>(listEntry.getValue()));
}
if (this.topicQueueMappingByBroker != null) {
Map<String, TopicQueueMappingInfo> cloneMap = new HashMap<>(this.topicQueueMappingByBroker.size());
for (final Map.Entry<String, TopicQueueMappingInfo> entry : this.getTopicQueueMappingByBroker().entrySet()) {
TopicQueueMappingInfo topicQueueMappingInfo = new TopicQueueMappingInfo(entry.getValue().getTopic(), entry.getValue().getTotalQueues(), entry.getValue().getBname(), entry.getValue().getEpoch());
topicQueueMappingInfo.setDirty(entry.getValue().isDirty());
topicQueueMappingInfo.setScope(entry.getValue().getScope());
ConcurrentMap<Integer, Integer> concurrentMap = new ConcurrentHashMap<Integer, Integer>(entry.getValue().getCurrIdMap());
topicQueueMappingInfo.setCurrIdMap(concurrentMap);
cloneMap.put(entry.getKey(), topicQueueMappingInfo);
}
topicRouteData.setTopicQueueMappingByBroker(cloneMap);
}
return topicRouteData;
}
public List<QueueData> getQueueDatas() {
return queueDatas;
}
@@ -0,0 +1,36 @@
/*
* 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.common.protocol.route;
import org.apache.rocketmq.remoting.protocol.RemotingSerializable;
import java.util.HashMap;
import java.util.Map;
public class TopicRouteDatas extends RemotingSerializable {
private Map<String, TopicRouteData> topics = new HashMap<String, TopicRouteData>();
public Map<String, TopicRouteData> getTopics() {
return topics;
}
public void setTopics(Map<String, TopicRouteData> topics) {
this.topics = topics;
}
}
@@ -0,0 +1,53 @@
/*
* 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.common.statistics;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
public class FutureHolder<T> {
private ConcurrentMap<T, BlockingQueue<Future>> futureMap = new ConcurrentHashMap<T, BlockingQueue<Future>>(8);
public void addFuture(T t, Future future) {
BlockingQueue<Future> list = futureMap.get(t);
if (list == null) {
list = new LinkedBlockingQueue<Future>();
BlockingQueue<Future> old = futureMap.putIfAbsent(t, list);
if (old != null) {
list = old;
}
}
list.add(future);
}
public void removeAllFuture(T t) {
cancelAll(t, false);
futureMap.remove(t);
}
private void cancelAll(T t, boolean mayInterruptIfRunning) {
BlockingQueue<Future> list = futureMap.get(t);
if (list != null) {
for (Future future : list) {
future.cancel(mayInterruptIfRunning);
}
}
}
}
@@ -0,0 +1,31 @@
/*
* 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.common.statistics;
/**
* interceptor
*/
public interface Interceptor {
/**
* increase multiple values
*
* @param deltas
*/
void inc(long... deltas);
void reset();
}
@@ -0,0 +1,184 @@
/*
* 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.common.statistics;
import org.apache.commons.lang3.ArrayUtils;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
public class StatisticsBrief {
public static final int META_RANGE_INDEX = 0;
public static final int META_SLOT_NUM_INDEX = 1;
// TopPercentile
private long[][] topPercentileMeta;
private AtomicInteger[] counts;
private AtomicLong totalCount;
// max min avg total
private long max;
private long min;
private long total;
public StatisticsBrief(long[][] topPercentileMeta) {
if (!isLegalMeta(topPercentileMeta)) {
throw new IllegalArgumentException("illegal topPercentileMeta");
}
this.topPercentileMeta = topPercentileMeta;
this.counts = new AtomicInteger[slotNum(topPercentileMeta)];
this.totalCount = new AtomicLong(0);
reset();
}
public void reset() {
for (int i = 0; i < counts.length; i++) {
if (counts[i] == null) {
counts[i] = new AtomicInteger(0);
} else {
counts[i].set(0);
}
}
totalCount.set(0);
synchronized (this) {
max = 0;
min = Long.MAX_VALUE;
total = 0;
}
}
private static boolean isLegalMeta(long[][] meta) {
if (ArrayUtils.isEmpty(meta)) {
return false;
}
for (long[] line : meta) {
if (ArrayUtils.isEmpty(line) || line.length != 2) {
return false;
}
}
return true;
}
private static int slotNum(long[][] meta) {
int ret = 1;
for (long[] line : meta) {
ret += line[META_SLOT_NUM_INDEX];
}
return ret;
}
public void sample(long value) {
int index = getSlotIndex(value);
counts[index].incrementAndGet();
totalCount.incrementAndGet();
synchronized (this) {
max = Math.max(max, value);
min = Math.min(min, value);
total += value;
}
}
public long tp999() {
return getTPValue(0.999f);
}
public long getTPValue(float ratio) {
if (ratio <= 0 || ratio >= 1) {
ratio = 0.99f;
}
long count = totalCount.get();
long excludes = (long)(count - count * ratio);
if (excludes == 0) {
return getMax();
}
int tmp = 0;
for (int i = counts.length - 1; i > 0; i--) {
tmp += counts[i].get();
if (tmp > excludes) {
return Math.min(getSlotTPValue(i), getMax());
}
}
return 0;
}
private long getSlotTPValue(int index) {
int slotNumLeft = index;
for (int i = 0; i < topPercentileMeta.length; i++) {
int slotNum = (int)topPercentileMeta[i][META_SLOT_NUM_INDEX];
if (slotNumLeft < slotNum) {
long metaRangeMax = topPercentileMeta[i][META_RANGE_INDEX];
long metaRangeMin = 0;
if (i > 0) {
metaRangeMin = topPercentileMeta[i - 1][META_RANGE_INDEX];
}
return metaRangeMin + (metaRangeMax - metaRangeMin) / slotNum * (slotNumLeft + 1);
} else {
slotNumLeft -= slotNum;
}
}
// MAX_VALUE: the last slot
return Integer.MAX_VALUE;
}
private int getSlotIndex(long num) {
int index = 0;
for (int i = 0; i < topPercentileMeta.length; i++) {
long rangeMax = topPercentileMeta[i][META_RANGE_INDEX];
int slotNum = (int)topPercentileMeta[i][META_SLOT_NUM_INDEX];
long rangeMin = (i > 0) ? topPercentileMeta[i - 1][META_RANGE_INDEX] : 0;
if (rangeMin <= num && num < rangeMax) {
index += (num - rangeMin) / ((rangeMax - rangeMin) / slotNum);
break;
}
index += slotNum;
}
return index;
}
/**
* Getters
*
* @return
*/
public long getMax() {
return max;
}
public long getMin() {
return totalCount.get() > 0 ? min : 0;
}
public long getTotal() {
return total;
}
public long getCnt() {
return totalCount.get();
}
public double getAvg() {
return totalCount.get() != 0 ? ((double)total) / totalCount.get() : 0;
}
}
@@ -0,0 +1,76 @@
/*
* 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.common.statistics;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.tuple.Pair;
/**
* interceptor to generate statistics brief
*/
public class StatisticsBriefInterceptor implements Interceptor {
private int[] indexOfItems;
private StatisticsBrief[] statisticsBriefs;
public StatisticsBriefInterceptor(StatisticsItem item, Pair<String, long[][]>[] briefMetas) {
indexOfItems = new int[briefMetas.length];
statisticsBriefs = new StatisticsBrief[briefMetas.length];
for (int i = 0; i < briefMetas.length; i++) {
String name = briefMetas[i].getKey();
int index = ArrayUtils.indexOf(item.getItemNames(), name);
if (index < 0) {
throw new IllegalArgumentException("illegal breifItemName: " + name);
}
indexOfItems[i] = index;
statisticsBriefs[i] = new StatisticsBrief(briefMetas[i].getValue());
}
}
@Override
public void inc(long... itemValues) {
for (int i = 0; i < indexOfItems.length; i++) {
int indexOfItem = indexOfItems[i];
if (indexOfItem < itemValues.length) {
statisticsBriefs[i].sample(itemValues[indexOfItem]);
}
}
}
@Override
public void reset() {
for (StatisticsBrief brief : statisticsBriefs) {
brief.reset();
}
}
public int[] getIndexOfItems() {
return indexOfItems;
}
public void setIndexOfItems(int[] indexOfItems) {
this.indexOfItems = indexOfItems;
}
public StatisticsBrief[] getStatisticsBriefs() {
return statisticsBriefs;
}
public void setStatisticsBriefs(StatisticsBrief[] statisticsBriefs) {
this.statisticsBriefs = statisticsBriefs;
}
}
@@ -0,0 +1,175 @@
/*
* 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.common.statistics;
import java.security.InvalidParameterException;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.commons.lang3.ArrayUtils;
/**
* Statistics Item
*/
public class StatisticsItem {
private String statKind;
private String statObject;
private String[] itemNames;
private AtomicLong[] itemAccumulates;
private AtomicLong invokeTimes;
private Interceptor interceptor;
/**
* last timestamp when the item was updated
*/
private AtomicLong lastTimeStamp;
public StatisticsItem(String statKind, String statObject, String... itemNames) {
if (itemNames == null || itemNames.length <= 0) {
throw new InvalidParameterException("StatisticsItem \"itemNames\" is empty");
}
this.statKind = statKind;
this.statObject = statObject;
this.itemNames = itemNames;
AtomicLong[] accs = new AtomicLong[itemNames.length];
for (int i = 0; i < itemNames.length; i++) {
accs[i] = new AtomicLong(0);
}
this.itemAccumulates = accs;
this.invokeTimes = new AtomicLong();
this.lastTimeStamp = new AtomicLong(System.currentTimeMillis());
}
public void incItems(long... itemIncs) {
int len = Math.min(itemIncs.length, itemAccumulates.length);
for (int i = 0; i < len; i++) {
itemAccumulates[i].addAndGet(itemIncs[i]);
}
invokeTimes.addAndGet(1);
lastTimeStamp.set(System.currentTimeMillis());
if (interceptor != null) {
interceptor.inc(itemIncs);
}
}
public boolean allZeros() {
if (invokeTimes.get() == 0) {
return true;
}
for (AtomicLong acc : itemAccumulates) {
if (acc.get() != 0) {
return false;
}
}
return true;
}
public String getStatKind() {
return statKind;
}
public String getStatObject() {
return statObject;
}
public String[] getItemNames() {
return itemNames;
}
public AtomicLong[] getItemAccumulates() {
return itemAccumulates;
}
public AtomicLong getInvokeTimes() {
return invokeTimes;
}
public AtomicLong getLastTimeStamp() {
return lastTimeStamp;
}
public AtomicLong getItemAccumulate(String itemName) {
int index = ArrayUtils.indexOf(itemNames, itemName);
if (index < 0) {
return new AtomicLong(0);
}
return itemAccumulates[index];
}
/**
* get snapshot
* <p>
* Warning: no guarantee of itemAccumulates consistency
*
* @return
*/
public StatisticsItem snapshot() {
StatisticsItem ret = new StatisticsItem(statKind, statObject, itemNames);
ret.itemAccumulates = new AtomicLong[itemAccumulates.length];
for (int i = 0; i < itemAccumulates.length; i++) {
ret.itemAccumulates[i] = new AtomicLong(itemAccumulates[i].get());
}
ret.invokeTimes = new AtomicLong(invokeTimes.longValue());
ret.lastTimeStamp = new AtomicLong(lastTimeStamp.longValue());
return ret;
}
/**
* subtract another StatisticsItem
*
* @param item
* @return
*/
public StatisticsItem subtract(StatisticsItem item) {
if (item == null) {
return snapshot();
}
if (!statKind.equals(item.statKind) || !statObject.equals(item.statObject) || !Arrays.equals(itemNames,
item.itemNames)) {
throw new IllegalArgumentException("StatisticsItem's kind, key and itemNames must be exactly the same");
}
StatisticsItem ret = new StatisticsItem(statKind, statObject, itemNames);
ret.invokeTimes = new AtomicLong(invokeTimes.get() - item.invokeTimes.get());
ret.itemAccumulates = new AtomicLong[itemAccumulates.length];
for (int i = 0; i < itemAccumulates.length; i++) {
ret.itemAccumulates[i] = new AtomicLong(itemAccumulates[i].get() - item.itemAccumulates[i].get());
}
return ret;
}
public Interceptor getInterceptor() {
return interceptor;
}
public void setInterceptor(Interceptor interceptor) {
this.interceptor = interceptor;
}
}
@@ -0,0 +1,33 @@
/*
* 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.common.statistics;
import java.util.concurrent.atomic.AtomicLong;
public class StatisticsItemFormatter {
public String format(StatisticsItem statItem) {
final String seperator = "|";
StringBuilder sb = new StringBuilder();
sb.append(statItem.getStatKind()).append(seperator);
sb.append(statItem.getStatObject()).append(seperator);
for (AtomicLong acc : statItem.getItemAccumulates()) {
sb.append(acc.get()).append(seperator);
}
sb.append(statItem.getInvokeTimes());
return sb.toString();
}
}
@@ -0,0 +1,50 @@
/*
* 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.common.statistics;
import org.apache.rocketmq.logging.InternalLogger;
public class StatisticsItemPrinter {
private InternalLogger log;
private StatisticsItemFormatter formatter;
public StatisticsItemPrinter(StatisticsItemFormatter formatter, InternalLogger log) {
this.formatter = formatter;
this.log = log;
}
public void log(InternalLogger log) {
this.log = log;
}
public void formatter(StatisticsItemFormatter formatter) {
this.formatter = formatter;
}
public void print(String prefix, StatisticsItem statItem, String... suffixs) {
StringBuilder suffix = new StringBuilder();
for (String str : suffixs) {
suffix.append(str);
}
if (log != null) {
log.info("{}{}{}", prefix, formatter.format(statItem), suffix.toString());
}
// System.out.printf("%s %s%s%s\n", new Date().toString(), prefix, formatter.format(statItem), suffix.toString());
}
}
@@ -0,0 +1,290 @@
/*
* 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.common.statistics;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
public class StatisticsItemScheduledIncrementPrinter extends StatisticsItemScheduledPrinter {
private String[] tpsItemNames;
public static final int TPS_INITIAL_DELAY = 0;
public static final int TPS_INTREVAL = 1000;
public static final String SEPERATOR = "|";
/**
* last snapshots of all scheduled items
*/
private final ConcurrentHashMap<String, ConcurrentHashMap<String, StatisticsItem>> lastItemSnapshots
= new ConcurrentHashMap<String, ConcurrentHashMap<String, StatisticsItem>>();
private final ConcurrentHashMap<String, ConcurrentHashMap<String, StatisticsItemSampleBrief>> sampleBriefs
= new ConcurrentHashMap<String, ConcurrentHashMap<String, StatisticsItemSampleBrief>>();
public StatisticsItemScheduledIncrementPrinter(String name, StatisticsItemPrinter printer,
ScheduledExecutorService executor, InitialDelay initialDelay,
long interval, String[] tpsItemNames, Valve valve) {
super(name, printer, executor, initialDelay, interval, valve);
this.tpsItemNames = tpsItemNames;
}
/**
* schedule a StatisticsItem to print the Increments periodically
*/
@Override
public void schedule(final StatisticsItem item) {
setItemSampleBrief(item.getStatKind(), item.getStatObject(), new StatisticsItemSampleBrief(item, tpsItemNames));
// print log every ${interval} miliseconds
ScheduledFuture future = executor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
if (!enabled()) {
return;
}
StatisticsItem snapshot = item.snapshot();
StatisticsItem lastSnapshot = getItemSnapshot(lastItemSnapshots, item.getStatKind(),
item.getStatObject());
StatisticsItem increment = snapshot.subtract(lastSnapshot);
Interceptor inteceptor = item.getInterceptor();
String inteceptorStr = formatInterceptor(inteceptor);
if (inteceptor != null) {
inteceptor.reset();
}
StatisticsItemSampleBrief brief = getSampleBrief(item.getStatKind(), item.getStatObject());
if (brief != null && (!increment.allZeros() || printZeroLine())) {
printer.print(name, increment, inteceptorStr, brief.toString());
}
setItemSnapshot(lastItemSnapshots, snapshot);
if (brief != null) {
brief.reset();
}
}
}, getInitialDelay(), interval, TimeUnit.MILLISECONDS);
addFuture(item, future);
// sample every TPS_INTREVAL
ScheduledFuture futureSample = executor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
if (!enabled()) {
return;
}
StatisticsItem snapshot = item.snapshot();
StatisticsItemSampleBrief brief = getSampleBrief(item.getStatKind(), item.getStatObject());
if (brief != null) {
brief.sample(snapshot);
}
}
}, TPS_INTREVAL, TPS_INTREVAL, TimeUnit.MILLISECONDS);
addFuture(item, futureSample);
}
@Override
public void remove(StatisticsItem item) {
// remove task
removeAllFuture(item);
String kind = item.getStatKind();
String key = item.getStatObject();
ConcurrentHashMap<String, StatisticsItem> lastItemMap = lastItemSnapshots.get(kind);
if (lastItemMap != null) {
lastItemMap.remove(key);
}
ConcurrentHashMap<String, StatisticsItemSampleBrief> briefMap = sampleBriefs.get(kind);
if (briefMap != null) {
briefMap.remove(key);
}
}
private StatisticsItem getItemSnapshot(
ConcurrentHashMap<String, ConcurrentHashMap<String, StatisticsItem>> snapshots,
String kind, String key) {
ConcurrentHashMap<String, StatisticsItem> itemMap = snapshots.get(kind);
return (itemMap != null) ? itemMap.get(key) : null;
}
private StatisticsItemSampleBrief getSampleBrief(String kind, String key) {
ConcurrentHashMap<String, StatisticsItemSampleBrief> itemMap = sampleBriefs.get(kind);
return (itemMap != null) ? itemMap.get(key) : null;
}
private void setItemSnapshot(ConcurrentHashMap<String, ConcurrentHashMap<String, StatisticsItem>> snapshots,
StatisticsItem item) {
String kind = item.getStatKind();
String key = item.getStatObject();
ConcurrentHashMap<String, StatisticsItem> itemMap = snapshots.get(kind);
if (itemMap == null) {
itemMap = new ConcurrentHashMap<String, StatisticsItem>();
ConcurrentHashMap<String, StatisticsItem> oldItemMap = snapshots.putIfAbsent(kind, itemMap);
if (oldItemMap != null) {
itemMap = oldItemMap;
}
}
itemMap.put(key, item);
}
private void setItemSampleBrief(String kind, String key,
StatisticsItemSampleBrief brief) {
ConcurrentHashMap<String, StatisticsItemSampleBrief> itemMap = sampleBriefs.get(kind);
if (itemMap == null) {
itemMap = new ConcurrentHashMap<String, StatisticsItemSampleBrief>();
ConcurrentHashMap<String, StatisticsItemSampleBrief> oldItemMap = sampleBriefs.putIfAbsent(kind, itemMap);
if (oldItemMap != null) {
itemMap = oldItemMap;
}
}
itemMap.put(key, brief);
}
private String formatInterceptor(Interceptor interceptor) {
if (interceptor == null) {
return "";
}
if (interceptor instanceof StatisticsBriefInterceptor) {
StringBuilder sb = new StringBuilder();
StatisticsBriefInterceptor briefInterceptor = (StatisticsBriefInterceptor)interceptor;
for (StatisticsBrief brief : briefInterceptor.getStatisticsBriefs()) {
long max = brief.getMax();
long tp999 = Math.min(brief.tp999(), max);
//sb.append(SEPERATOR).append(brief.getTotal());
sb.append(SEPERATOR).append(max);
//sb.append(SEPERATOR).append(brief.getMin());
sb.append(SEPERATOR).append(String.format("%.2f", brief.getAvg()));
sb.append(SEPERATOR).append(tp999);
}
return sb.toString();
}
return "";
}
public static class StatisticsItemSampleBrief {
private StatisticsItem lastSnapshot;
public String[] itemNames;
public ItemSampleBrief[] briefs;
public StatisticsItemSampleBrief(StatisticsItem statItem, String[] itemNames) {
this.lastSnapshot = statItem.snapshot();
this.itemNames = itemNames;
this.briefs = new ItemSampleBrief[itemNames.length];
for (int i = 0; i < itemNames.length; i++) {
this.briefs[i] = new ItemSampleBrief();
}
}
public synchronized void reset() {
for (ItemSampleBrief brief : briefs) {
brief.reset();
}
}
public synchronized void sample(StatisticsItem snapshot) {
if (snapshot == null) {
return;
}
for (int i = 0; i < itemNames.length; i++) {
String name = itemNames[i];
long lastValue = lastSnapshot != null ? lastSnapshot.getItemAccumulate(name).get() : 0;
long increment = snapshot.getItemAccumulate(name).get() - lastValue;
briefs[i].sample(increment);
}
lastSnapshot = snapshot;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < briefs.length; i++) {
ItemSampleBrief brief = briefs[i];
sb.append(SEPERATOR).append(brief.getMax());
//sb.append(SEPERATOR).append(brief.getMin());
sb.append(SEPERATOR).append(String.format("%.2f", brief.getAvg()));
}
return sb.toString();
}
}
/**
* sample brief of a item for a period of time
*/
public static class ItemSampleBrief {
private long max;
private long min;
private long total;
private long cnt;
public ItemSampleBrief() {
reset();
}
public void sample(long value) {
max = Math.max(max, value);
min = Math.min(min, value);
total += value;
cnt++;
}
public void reset() {
max = 0;
min = Long.MAX_VALUE;
total = 0;
cnt = 0;
}
/**
* Getters
*
* @return
*/
public long getMax() {
return max;
}
public long getMin() {
return cnt > 0 ? min : 0;
}
public long getTotal() {
return total;
}
public long getCnt() {
return cnt;
}
public double getAvg() {
return cnt != 0 ? ((double)total) / cnt : 0;
}
}
}
@@ -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.common.statistics;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
public class StatisticsItemScheduledPrinter extends FutureHolder {
protected String name;
protected StatisticsItemPrinter printer;
protected ScheduledExecutorService executor;
protected long interval;
protected InitialDelay initialDelay;
protected Valve valve;
public StatisticsItemScheduledPrinter(String name, StatisticsItemPrinter printer,
ScheduledExecutorService executor, InitialDelay initialDelay,
long interval, Valve valve) {
this.name = name;
this.printer = printer;
this.executor = executor;
this.initialDelay = initialDelay;
this.interval = interval;
this.valve = valve;
}
/**
* schedule a StatisticsItem to print all the values periodically
*/
public void schedule(final StatisticsItem statisticsItem) {
ScheduledFuture future = executor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
if (enabled()) {
printer.print(name, statisticsItem);
}
}
}, getInitialDelay(), interval, TimeUnit.MILLISECONDS);
addFuture(statisticsItem, future);
}
public void remove(final StatisticsItem statisticsItem) {
removeAllFuture(statisticsItem);
}
public interface InitialDelay {
/**
* Get inital delay value
* @return
*/
long get();
}
public interface Valve {
/**
* whether enabled
* @return
*/
boolean enabled();
/**
* whether print zero lines
* @return
*/
boolean printZeroLine();
}
protected long getInitialDelay() {
return initialDelay != null ? initialDelay.get() : 0;
}
protected boolean enabled() {
return valve != null ? valve.enabled() : false;
}
protected boolean printZeroLine() {
return valve != null ? valve.printZeroLine() : false;
}
}
@@ -0,0 +1,21 @@
/*
* 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.common.statistics;
public interface StatisticsItemStateGetter {
boolean online(StatisticsItem item);
}
@@ -0,0 +1,50 @@
/*
* 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.common.statistics;
/**
* Statistics Kind Metadata
*/
public class StatisticsKindMeta {
private String name;
private String[] itemNames;
private StatisticsItemScheduledPrinter scheduledPrinter;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getItemNames() {
return itemNames;
}
public void setItemNames(String[] itemNames) {
this.itemNames = itemNames;
}
public StatisticsItemScheduledPrinter getScheduledPrinter() {
return scheduledPrinter;
}
public void setScheduledPrinter(StatisticsItemScheduledPrinter scheduledPrinter) {
this.scheduledPrinter = scheduledPrinter;
}
}
@@ -0,0 +1,157 @@
/*
* 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.common.statistics;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.rocketmq.common.utils.ThreadUtils;
public class StatisticsManager {
/**
* Set of Statistics Kind Metadata
*/
private Map<String, StatisticsKindMeta> kindMetaMap;
/**
* item names to calculate statistics brief
*/
private Pair<String, long[][]>[] briefMetas;
/**
* Statistics
*/
private final ConcurrentHashMap<String, ConcurrentHashMap<String, StatisticsItem>> statsTable
= new ConcurrentHashMap<String, ConcurrentHashMap<String, StatisticsItem>>();
private static final int MAX_IDLE_TIME = 10 * 60 * 1000;
private final ScheduledExecutorService executor = ThreadUtils.newSingleThreadScheduledExecutor(
"StatisticsManagerCleaner", true);
private StatisticsItemStateGetter statisticsItemStateGetter;
public StatisticsManager() {
kindMetaMap = new HashMap<String, StatisticsKindMeta>();
start();
}
public StatisticsManager(Map<String, StatisticsKindMeta> kindMeta) {
this.kindMetaMap = kindMeta;
start();
}
public void addStatisticsKindMeta(StatisticsKindMeta kindMeta) {
kindMetaMap.put(kindMeta.getName(), kindMeta);
statsTable.putIfAbsent(kindMeta.getName(), new ConcurrentHashMap<String, StatisticsItem>(16));
}
public void setBriefMeta(Pair<String, long[][]>[] briefMetas) {
this.briefMetas = briefMetas;
}
private void start() {
int maxIdleTime = MAX_IDLE_TIME;
executor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
Iterator<Map.Entry<String, ConcurrentHashMap<String, StatisticsItem>>> iter
= statsTable.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, ConcurrentHashMap<String, StatisticsItem>> entry = iter.next();
String kind = entry.getKey();
ConcurrentHashMap<String, StatisticsItem> itemMap = entry.getValue();
if (itemMap == null || itemMap.isEmpty()) {
continue;
}
HashMap<String, StatisticsItem> tmpItemMap = new HashMap<String, StatisticsItem>(itemMap);
for (StatisticsItem item : tmpItemMap.values()) {
// remove when expired
if (System.currentTimeMillis() - item.getLastTimeStamp().get() > MAX_IDLE_TIME
&& (statisticsItemStateGetter == null || !statisticsItemStateGetter.online(item))) {
remove(item);
}
}
}
}
}, maxIdleTime, maxIdleTime / 3, TimeUnit.MILLISECONDS);
}
/**
* Increment a StatisticsItem
*
* @param kind
* @param key
* @param itemAccumulates
*/
public boolean inc(String kind, String key, long... itemAccumulates) {
ConcurrentHashMap<String, StatisticsItem> itemMap = statsTable.get(kind);
if (itemMap != null) {
StatisticsItem item = itemMap.get(key);
// if not exist, create and schedule
if (item == null) {
item = new StatisticsItem(kind, key, kindMetaMap.get(kind).getItemNames());
item.setInterceptor(new StatisticsBriefInterceptor(item, briefMetas));
StatisticsItem oldItem = itemMap.putIfAbsent(key, item);
if (oldItem != null) {
item = oldItem;
} else {
scheduleStatisticsItem(item);
}
}
// do increment
item.incItems(itemAccumulates);
return true;
}
return false;
}
private void scheduleStatisticsItem(StatisticsItem item) {
kindMetaMap.get(item.getStatKind()).getScheduledPrinter().schedule(item);
}
public void remove(StatisticsItem item) {
ConcurrentHashMap<String, StatisticsItem> itemMap = statsTable.get(item.getStatKind());
if (itemMap != null) {
itemMap.remove(item.getStatObject(), item);
}
StatisticsKindMeta kindMeta = kindMetaMap.get(item.getStatKind());
if (kindMeta != null && kindMeta.getScheduledPrinter() != null) {
kindMeta.getScheduledPrinter().remove(item);
}
}
public StatisticsItemStateGetter getStatisticsItemStateGetter() {
return statisticsItemStateGetter;
}
public void setStatisticsItemStateGetter(StatisticsItemStateGetter statisticsItemStateGetter) {
this.statisticsItemStateGetter = statisticsItemStateGetter;
}
}
@@ -0,0 +1,86 @@
/*
* 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.common.subscription;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.rocketmq.remoting.protocol.RemotingSerializable;
/**
*
*/
public class GroupForbidden extends RemotingSerializable {
private String topic;
private String group;
private Boolean readable;
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public Boolean getReadable() {
return readable;
}
public void setReadable(Boolean readable) {
this.readable = readable;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((group == null) ? 0 : group.hashCode());
result = prime * result + ((readable == null) ? 0 : readable.hashCode());
result = prime * result + ((topic == null) ? 0 : topic.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
GroupForbidden other = (GroupForbidden) obj;
return new EqualsBuilder()
.append(topic, other.topic)
.append(group, other.group)
.append(readable, other.readable)
.isEquals();
}
@Override
public String toString() {
return "GroupForbidden [topic=" + topic + ", group=" + group + ", readable=" + readable + "]";
}
}
@@ -17,6 +17,7 @@
package org.apache.rocketmq.common.subscription;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.rocketmq.common.MixAll;
public class SubscriptionGroupConfig {
@@ -38,6 +39,8 @@ public class SubscriptionGroupConfig {
private boolean notifyConsumerIdsChangedEnable = true;
private int groupSysFlag = 0;
public String getGroupName() {
return groupName;
}
@@ -110,6 +113,14 @@ public class SubscriptionGroupConfig {
this.notifyConsumerIdsChangedEnable = notifyConsumerIdsChangedEnable;
}
public int getGroupSysFlag() {
return groupSysFlag;
}
public void setGroupSysFlag(int groupSysFlag) {
this.groupSysFlag = groupSysFlag;
}
@Override
public int hashCode() {
final int prime = 31;
@@ -136,28 +147,18 @@ public class SubscriptionGroupConfig {
if (getClass() != obj.getClass())
return false;
SubscriptionGroupConfig other = (SubscriptionGroupConfig) obj;
if (brokerId != other.brokerId)
return false;
if (consumeBroadcastEnable != other.consumeBroadcastEnable)
return false;
if (consumeEnable != other.consumeEnable)
return false;
if (consumeFromMinEnable != other.consumeFromMinEnable)
return false;
if (groupName == null) {
if (other.groupName != null)
return false;
} else if (!groupName.equals(other.groupName))
return false;
if (retryMaxTimes != other.retryMaxTimes)
return false;
if (retryQueueNums != other.retryQueueNums)
return false;
if (whichBrokerWhenConsumeSlowly != other.whichBrokerWhenConsumeSlowly)
return false;
if (notifyConsumerIdsChangedEnable != other.notifyConsumerIdsChangedEnable)
return false;
return true;
return new EqualsBuilder()
.append(groupName, other.groupName)
.append(consumeEnable, other.consumeEnable)
.append(consumeFromMinEnable, other.consumeFromMinEnable)
.append(consumeBroadcastEnable, other.consumeBroadcastEnable)
.append(retryQueueNums, other.retryQueueNums)
.append(retryMaxTimes, other.retryMaxTimes)
.append(brokerId, other.brokerId)
.append(whichBrokerWhenConsumeSlowly, other.whichBrokerWhenConsumeSlowly)
.append(notifyConsumerIdsChangedEnable, other.notifyConsumerIdsChangedEnable)
.append(groupSysFlag, other.groupSysFlag)
.isEquals();
}
@Override
@@ -167,6 +168,6 @@ public class SubscriptionGroupConfig {
+ consumeBroadcastEnable + ", retryQueueNums=" + retryQueueNums + ", retryMaxTimes="
+ retryMaxTimes + ", brokerId=" + brokerId + ", whichBrokerWhenConsumeSlowly="
+ whichBrokerWhenConsumeSlowly + ", notifyConsumerIdsChangedEnable="
+ notifyConsumerIdsChangedEnable + "]";
+ notifyConsumerIdsChangedEnable + ", groupSysFlag=" + groupSysFlag + "]";
}
}
@@ -36,6 +36,8 @@ public class TopicValidator {
public static final String RMQ_SYS_OFFSET_MOVED_EVENT = "OFFSET_MOVED_EVENT";
public static final String SYSTEM_TOPIC_PREFIX = "rmq_sys_";
public static final String SYNC_BROKER_MEMBER_GROUP_PREFIX = SYSTEM_TOPIC_PREFIX + "SYNC_BROKER_MEMBER_";
public static final boolean[] VALID_CHAR_BIT_MAP = new boolean[128];
private static final int TOPIC_MAX_LENGTH = 127;
@@ -0,0 +1,49 @@
/*
* 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.common.utils;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import com.google.common.hash.Hashing;
import org.apache.rocketmq.common.message.MessageConst;
import org.apache.rocketmq.common.message.MessageExt;
public class MessageUtils {
public static int getShardingKeyIndex(String shardingKey, int indexSize) {
return Math.abs(Hashing.murmur3_32().hashBytes(shardingKey.getBytes()).asInt() % indexSize);
}
public static int getShardingKeyIndexByMsg(MessageExt msg, int indexSize) {
String shardingKey = msg.getProperty(MessageConst.PROPERTY_SHARDING_KEY);
if (shardingKey == null) {
shardingKey = "";
}
return getShardingKeyIndex(shardingKey, indexSize);
}
public static Set<Integer> getShardingKeyIndexes(Collection<MessageExt> msgs, int indexSize) {
Set<Integer> indexSet = new HashSet<Integer>(indexSize);
for (MessageExt msg : msgs) {
indexSet.add(getShardingKeyIndexByMsg(msg, indexSize));
}
return indexSet;
}
}
@@ -0,0 +1,40 @@
/*
* 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.common.utils;
import java.util.concurrent.atomic.AtomicInteger;
public class PositiveAtomicCounter {
private static final int MASK = 0x7FFFFFFF;
private final AtomicInteger atom;
public PositiveAtomicCounter() {
atom = new AtomicInteger(0);
}
public final int incrementAndGet() {
final int rt = atom.incrementAndGet();
return rt & MASK;
}
public int intValue() {
return atom.intValue();
}
}
@@ -0,0 +1,211 @@
/*
* 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.common.utils;
import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class ServiceProvider {
private static final InternalLogger LOG = InternalLoggerFactory.getLogger(LoggerName.COMMON_LOGGER_NAME);
/**
* A reference to the classloader that loaded this class. It's more efficient to compute it once and cache it here.
*/
private static ClassLoader thisClassLoader;
/**
* JDK1.3+ <a href= "http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#Service%20Provider" > 'Service Provider' specification</a>.
*/
public static final String TRANSACTION_SERVICE_ID = "META-INF/service/org.apache.rocketmq.broker.transaction.TransactionalMessageService";
public static final String TRANSACTION_LISTENER_ID = "META-INF/service/org.apache.rocketmq.broker.transaction.AbstractTransactionalMessageCheckListener";
public static final String HA_SERVICE_ID = "META-INF/service/org.apache.rocketmq.store.ha.HAService";
public static final String RPC_HOOK_ID = "META-INF/service/org.apache.rocketmq.remoting.RPCHook";
public static final String ACL_VALIDATOR_ID = "META-INF/service/org.apache.rocketmq.acl.AccessValidator";
static {
thisClassLoader = getClassLoader(ServiceProvider.class);
}
/**
* Returns a string that uniquely identifies the specified object, including its class.
* <p>
* The returned string is of form "classname@hashcode", ie is the same as the return value of the Object.toString() method, but works even when the specified object's class has overidden the toString method.
*
* @param o may be null.
* @return a string of form classname@hashcode, or "null" if param o is null.
*/
protected static String objectId(Object o) {
if (o == null) {
return "null";
} else {
return o.getClass().getName() + "@" + System.identityHashCode(o);
}
}
protected static ClassLoader getClassLoader(Class<?> clazz) {
try {
return clazz.getClassLoader();
} catch (SecurityException e) {
LOG.error("Unable to get classloader for class {} due to security restrictions !",
clazz, e.getMessage());
throw e;
}
}
protected static ClassLoader getContextClassLoader() {
ClassLoader classLoader = null;
try {
classLoader = Thread.currentThread().getContextClassLoader();
} catch (SecurityException ex) {
/**
* The getContextClassLoader() method throws SecurityException when the context
* class loader isn't an ancestor of the calling class's class
* loader, or if security permissions are restricted.
*/
}
return classLoader;
}
protected static InputStream getResourceAsStream(ClassLoader loader, String name) {
if (loader != null) {
return loader.getResourceAsStream(name);
} else {
return ClassLoader.getSystemResourceAsStream(name);
}
}
public static <T> List<T> load(String name, Class<?> clazz) {
LOG.info("Looking for a resource file of name [{}] ...", name);
List<T> services = new ArrayList<T>();
try {
ArrayList<String> names = new ArrayList<String>();
final InputStream is = getResourceAsStream(getContextClassLoader(), name);
if (is != null) {
BufferedReader reader;
try {
reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
} catch (java.io.UnsupportedEncodingException e) {
reader = new BufferedReader(new InputStreamReader(is));
}
String serviceName = reader.readLine();
while (serviceName != null && !"".equals(serviceName)) {
LOG.info(
"Creating an instance as specified by file {} which was present in the path of the context classloader.",
name);
if (!names.contains(serviceName)) {
names.add(serviceName);
}
services.add((T)initService(getContextClassLoader(), serviceName, clazz));
serviceName = reader.readLine();
}
reader.close();
} else {
// is == null
LOG.warn("No resource file with name [{}] found.", name);
}
} catch (Exception e) {
LOG.error("Error occured when looking for resource file " + name, e);
}
return services;
}
public static <T> T loadClass(String name, Class<?> clazz) {
final InputStream is = getResourceAsStream(getContextClassLoader(), name);
if (is != null) {
BufferedReader reader;
try {
try {
reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
} catch (java.io.UnsupportedEncodingException e) {
reader = new BufferedReader(new InputStreamReader(is));
}
String serviceName = reader.readLine();
reader.close();
if (serviceName != null && !"".equals(serviceName)) {
return initService(getContextClassLoader(), serviceName, clazz);
} else {
LOG.warn("ServiceName is empty!");
return null;
}
} catch (Exception e) {
LOG.warn("Error occurred when looking for resource file " + name, e);
}
}
return null;
}
protected static <T> T initService(ClassLoader classLoader, String serviceName, Class<?> clazz) {
Class<?> serviceClazz = null;
try {
if (classLoader != null) {
try {
// Warning: must typecast here & allow exception to be generated/caught & recast properly
serviceClazz = classLoader.loadClass(serviceName);
if (clazz.isAssignableFrom(serviceClazz)) {
LOG.info("Loaded class {} from classloader {}", serviceClazz.getName(),
objectId(classLoader));
} else {
// This indicates a problem with the ClassLoader tree. An incompatible ClassLoader was used to load the implementation.
LOG.error(
"Class {} loaded from classloader {} does not extend {} as loaded by this classloader.",
new Object[] {serviceClazz.getName(),
objectId(serviceClazz.getClassLoader()), clazz.getName()});
}
return (T)serviceClazz.newInstance();
} catch (ClassNotFoundException ex) {
if (classLoader == thisClassLoader) {
// Nothing more to try, onwards.
LOG.warn("Unable to locate any class {} via classloader", serviceName,
objectId(classLoader));
throw ex;
}
// Ignore exception, continue
} catch (NoClassDefFoundError e) {
if (classLoader == thisClassLoader) {
// Nothing more to try, onwards.
LOG.warn(
"Class {} cannot be loaded via classloader {}.it depends on some other class that cannot be found.",
serviceClazz, objectId(classLoader));
throw e;
}
// Ignore exception, continue
}
}
} catch (Exception e) {
LOG.error("Unable to init service.", e);
}
return (T)serviceClazz;
}
}
@@ -30,7 +30,7 @@ import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
public final class ThreadUtils {
private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.TOOLS_LOGGER_NAME);
private static final InternalLogger LOGGER = InternalLoggerFactory.getLogger(LoggerName.TOOLS_LOGGER_NAME);
public static ExecutorService newThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue, String processName, boolean isDaemon) {
@@ -102,7 +102,7 @@ public final class ThreadUtils {
thread.setDaemon(daemon);
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
log.error("Uncaught exception in thread '" + t.getName() + "':", e);
LOGGER.error("Uncaught exception in thread '" + t.getName() + "':", e);
}
});
return thread;
@@ -153,7 +153,7 @@ public final class ThreadUtils {
executor.shutdownNow();
// Wait a while for tasks to respond to being cancelled.
if (!executor.awaitTermination(timeout, timeUnit)) {
log.warn(String.format("%s didn't terminate!", executor));
LOGGER.warn(String.format("%s didn't terminate!", executor));
}
}
} catch (InterruptedException ie) {
@@ -164,6 +164,17 @@ public final class ThreadUtils {
}
}
/**
* Shutdown the specific ExecutorService
*
* @param executorService the executor
*/
public static void shutdown(ExecutorService executorService) {
if (executorService != null) {
executorService.shutdown();
}
}
/**
* A constructor to stop this class being constructed.
*/
@@ -67,4 +67,11 @@ public class DataVersionTest {
other.setTimestamp(dataVersion.getTimestamp());
Assert.assertTrue(dataVersion.equals(other));
}
@Test
public void testEncode() {
DataVersion dataVersion = new DataVersion();
Assert.assertTrue(dataVersion.encode().length > 0);
Assert.assertNotNull(dataVersion.toJson());
}
}
@@ -22,7 +22,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.rocketmq.common.protocol.body.RegisterBrokerBody;
import org.apache.rocketmq.common.protocol.body.TopicConfigAndMappingSerializeWrapper;
import org.apache.rocketmq.common.protocol.body.TopicConfigSerializeWrapper;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
@@ -19,13 +19,11 @@ package org.apache.rocketmq.common;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
@@ -174,4 +172,21 @@ public class UtilAllTest {
'}';
}
}
@Test
public void testCleanBuffer() {
UtilAll.cleanBuffer(null);
UtilAll.cleanBuffer(ByteBuffer.allocate(10));
UtilAll.cleanBuffer(ByteBuffer.allocate(0));
}
@Test(expected = NoSuchMethodException.class)
public void testMethod() throws NoSuchMethodException {
UtilAll.method(new Object(), "noMethod", null);
}
@Test(expected = IllegalStateException.class)
public void testInvoke() throws Exception {
UtilAll.invoke(new Object(), "noMethod");
}
}
@@ -17,6 +17,7 @@
package org.apache.rocketmq.common.message;
import org.apache.rocketmq.common.UtilAll;
import org.apache.rocketmq.common.sysflag.MessageSysFlag;
import org.junit.Test;
@@ -163,6 +164,8 @@ public class MessageDecoderTest {
messageExt.putUserProperty("b", "hello");
messageExt.putUserProperty("c", "3.14");
messageExt.setBodyCRC(UtilAll.crc32(messageExt.getBody()));
byte[] msgBytes = new byte[0];
try {
msgBytes = MessageDecoder.encode(messageExt, false);
@@ -174,7 +177,7 @@ public class MessageDecoderTest {
ByteBuffer byteBuffer = ByteBuffer.allocate(msgBytes.length);
byteBuffer.put(msgBytes);
byteBuffer.clear();
byteBuffer.flip();
MessageExt decodedMsg = MessageDecoder.decode(byteBuffer);
assertThat(decodedMsg).isNotNull();
@@ -222,6 +225,8 @@ public class MessageDecoderTest {
messageExt.putUserProperty("b", "hello");
messageExt.putUserProperty("c", "3.14");
messageExt.setBodyCRC(UtilAll.crc32(messageExt.getBody()));
byte[] msgBytes = new byte[0];
try {
msgBytes = MessageDecoder.encode(messageExt, false);
@@ -233,7 +238,7 @@ public class MessageDecoderTest {
ByteBuffer byteBuffer = ByteBuffer.allocate(msgBytes.length);
byteBuffer.put(msgBytes);
byteBuffer.clear();
byteBuffer.flip();
MessageExt decodedMsg = MessageDecoder.decode(byteBuffer);
assertThat(decodedMsg).isNotNull();
@@ -20,7 +20,6 @@ import org.junit.Assert;
import org.junit.Test;
import static org.apache.rocketmq.common.message.MessageConst.PROPERTY_TRACE_SWITCH;
import static org.junit.Assert.*;
public class MessageTest {
@Test(expected = RuntimeException.class)
@@ -18,7 +18,6 @@
package org.apache.rocketmq.common.protocol.body;
import org.apache.rocketmq.remoting.protocol.RemotingSerializable;
import org.junit.Assert;
import org.junit.Test;
import java.util.HashMap;
@@ -21,11 +21,9 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.ImmutableList;
import org.apache.rocketmq.common.protocol.header.GetMinOffsetRequestHeader;
import org.apache.rocketmq.remoting.protocol.RemotingSerializable;
import org.junit.Assert;
import org.junit.Test;
import org.junit.experimental.theories.suppliers.TestedOn;
import java.util.Map;

Some files were not shown because too many files have changed in this diff Show More